防止RTL TListView镜像复选框和/或图形 [英] Prevent RTL TListView from mirroring check boxes and/or graphics

查看:86
本文介绍了防止RTL TListView镜像复选框和/或图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使ListView的列从右到左显示.已经提出并回答了.但是问题出在图标和复选框上.当我使用SetWindowLong制作ListView RTL时,它也会镜像图形和复选框,因此不需要.我可以使用编辑工具来镜像图形,既麻烦又可行,但是我不知道如何处理复选框.

I'm trying to make columns of a ListView appear from right to left. This has already been asked and answered. But the problem is about icons and check boxes. When I make a ListView RTL using SetWindowLong, it mirrors graphics and checkboxes as well, wich is not wanted. I can mirror graphics using editing tools, bothering but doable, but I don't know how to handle check boxes.

我认为这两个原因相同,因此我进行了搜索,并在 激活每个设备上下文的镜像 部分指出了图形问题.建议使用LAYOUT_RTLLAYOUT_BITMAPORIENTATIONPRESERVED标志更改DC的布局样式.

I think both of them have same reason, so I searched about it and found an entire article about RTL layout in Microsoft Docs. In Activating Mirroring per Device Context section it points out the graphics problem. It suggests to change layout style of DC with LAYOUT_RTL and LAYOUT_BITMAPORIENTATIONPRESERVED flags.

这是我结合本文中建议的方法和上面提到的答案实现的功能:

This is the function I implemented with combining methods suggested in the article and the answer mentioned above:

const
  LAYOUT_RTL = 1;
  LAYOUT_BITMAPORIENTATIONPRESERVED = 8;

function GetLayout(DC: HDC): DWORD; stdcall; external 'gdi32.dll';
function SetLayout(DC: HDC; dwLayout: DWORD): DWORD; stdcall; external 'gdi32.dll';

procedure MakeRTL(const Handle: HWND);
var
  DC: HDC;
begin
  SetWindowLong(Handle, GWL_EXSTYLE,
    GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYOUTRTL);

  DC := GetWindowDC(Handle);
  if DC <> 0 then
    SetLayout(DC, GetLayout(DC) or LAYOUT_RTL or LAYOUT_ORIENTATIONMASK);

  InvalidateRect(Handle, nil, True);
end;

但是它并没有改变任何东西.我试图阻止它们中的任何一个,更改它们的顺序,并更改其调用的不同位置,但是没有成功.

But it doesn't change anything. I tried blocking either of them, changing order of them and changing different places to call it, but no success.

现在的问题是,如何使ListView的列从右到左显示,而不镜像图形或复选框?

Now the question is, how to make columns of a ListView appear from right to left, without mirroring graphics or checkboxes?

我正在使用Win10 x64和Delphi 2010.

I'm using Win10 x64 and Delphi 2010.

如果您想重现此问题,这是我的delphi代码:

here is my delphi codes if you want to reproduce the problem:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ImgList, StdCtrls, CommCtrl, ShellAPI;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    ImageList1: TImageList;
    ListView2: TListView;
    Button1: TButton;
    Label1: TLabel;
    procedure FormActivate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Label1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  LAYOUT_RTL = 1;
  LAYOUT_BTT = 2;
  LAYOUT_VBH = 4;
  LAYOUT_ORIENTATIONMASK = LAYOUT_RTL or LAYOUT_BTT or LAYOUT_VBH;
  LAYOUT_BITMAPORIENTATIONPRESERVED = 8;

function GetLayout(DC: HDC): DWORD; stdcall; external 'gdi32.dll';
function SetLayout(DC: HDC; dwLayout: DWORD): DWORD; stdcall; external 'gdi32.dll';

procedure MakeRTL(const Handle: HWND);
var
  DC: HDC;
begin
  SetWindowLong(Handle, GWL_EXSTYLE,
    GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYOUTRTL);

  DC := GetWindowDC(Handle);
  if DC <> 0 then
    SetLayout(DC, GetLayout(DC) or LAYOUT_RTL or LAYOUT_ORIENTATIONMASK);

  InvalidateRect(Handle, nil, True);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MakeRTL(ListView_GetHeader(ListView1.Handle));
  MakeRTL(ListView1.Handle);
end;

procedure TForm1.FormActivate(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ListView1.Items.Count - 1 do
  begin
    ListView1.Items[I].Checked := True;
    ListView2.Items[I].Checked := True;
  end;
end;

procedure TForm1.Label1Click(Sender: TObject);
begin
  ShellExecute(0, 'open', 'https://icons8.com/icons/set/check', '', '', SW_SHOWNORMAL);
end;

end.

dfm:

object Form1: TForm1
  Left = 0
  Top = 0
  BiDiMode = bdLeftToRight
  Caption = 'Form1'
  ClientHeight = 169
  ClientWidth = 353
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  ParentBiDiMode = False
  OnActivate = FormActivate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 277
    Top = 128
    Width = 47
    Height = 26
    Cursor = crHandPoint
    Alignment = taCenter
    Caption = 'graphics by Icons8'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clBlue
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = [fsUnderline]
    ParentFont = False
    WordWrap = True
    OnClick = Label1Click
  end
  object ListView1: TListView
    Left = 8
    Top = 8
    Width = 250
    Height = 73
    Checkboxes = True
    Columns = <
      item
        Caption = 'Cap'
        Width = 100
      end
      item
        Caption = 'Sub1'
        Width = 100
      end>
    Items.ItemData = {
      03620000000200000000000000FFFFFFFFFFFFFFFF01000000FFFFFFFF000000
      00054900740065006D00310005500072006F007000310001000000FFFFFFFFFF
      FFFFFF01000000FFFFFFFF00000000054900740065006D00320005500072006F
      0070003200FFFFFFFF}
    LargeImages = ImageList1
    SmallImages = ImageList1
    TabOrder = 0
    ViewStyle = vsReport
  end
  object ListView2: TListView
    Left = 8
    Top = 87
    Width = 250
    Height = 73
    Checkboxes = True
    Columns = <
      item
        Caption = 'Cap'
        Width = 100
      end
      item
        Caption = 'Sub1'
        Width = 100
      end>
    Items.ItemData = {
      03620000000200000000000000FFFFFFFFFFFFFFFF01000000FFFFFFFF000000
      00054900740065006D00310005500072006F007000310001000000FFFFFFFFFF
      FFFFFF01000000FFFFFFFF00000000054900740065006D00320005500072006F
      0070003200FFFFFFFF}
    SmallImages = ImageList1
    TabOrder = 1
    ViewStyle = vsReport
  end
  object Button1: TButton
    Left = 264
    Top = 8
    Width = 75
    Height = 25
    Caption = 'RTL'
    TabOrder = 2
    OnClick = Button1Click
  end
  object ImageList1: TImageList
    ColorDepth = cd32Bit
    DrawingStyle = dsTransparent
    Left = 272
    Top = 40
    Bitmap = {
      494C0101020008003C0010001000FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600
      0000000000003600000028000000400000001000000001002000000000000010
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000618062C0E3E0E741557159F1557159F0E3F0E730617062B0000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000000000000000000001456149E218A
      21FE218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B
      21FF218A21FE1455149C00000000000000000000000000000000000000000107
      010D145814A1218A21FE218B21FF218B21FF218B21FF218B21FF218A21FE1557
      159F0207020C0000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218A21FD218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B
      21FF218B21FF218921FC000000000000000000000000000000000107010D1B71
      1BCF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B
      21FF1A701ACE0207020C00000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF218B
      21FF218B21FF218B21FF155915A4208520F4218B21FF218B21FF218B21FF218B
      21FF218B21FF218B21FF00000000000000000000000000000000165816A2218B
      21FF218B21FF218B21FF155915A4208520F4218B21FF218B21FF218B21FF218B
      21FF218B21FF1456149E00000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF218B
      21FF218B21FF124E128F000100010929094B208720F8218B21FF218B21FF218B
      21FF218B21FF218B21FF00000000000000000000000005160528218A21FD218B
      21FF218B21FF114A1187000000000722073E208520F4218B21FF218B21FF218B
      21FF218B21FF218A21FD05150526000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF218B
      21FF114A1187000000000D3B0D6C010901110722073E208520F4218B21FF218B
      21FF218B21FF218B21FF0000000000000000000000000F430F7B218B21FF218B
      21FF114A1187000000000D3B0D6C010901110722073E208520F4218B21FF218B
      21FF218B21FF218B21FF0F410F78000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF1A6B
      1AC400000000114A1187218B21FF1B6F1BCC010901110722073E208420F3218B
      21FF218B21FF218B21FF0000000000000000000000001557159F218B21FF1A6B
      1AC400000000114A1187218B21FF1B6F1BCC010901110722073E208420F3218B
      21FF218B21FF218B21FF1456149E000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF218B
      21FF196919C1218B21FF218B21FF218B21FF1B6F1BCC010901110722073E2084
      20F3218B21FF218B21FF0000000000000000000000001456149E218B21FF218B
      21FF196919C1218B21FF218B21FF218B21FF1B6F1BCC010901110722073E2084
      20F3218B21FF218B21FF1456149D000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF1A691AC00006000B0925
      0944208620F6218B21FF0000000000000000000000001044107C218B21FF218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF1A6F1ACB010901110722
      073E208420F3218B21FF10421079000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF1A6F1ACB0310
      031E1B711BD0218B21FF0000000000000000000000000519052D218A21FE218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF1A6F1ACB0310
      031E1B711BD0218A21FE0617062B000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218B21FF218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF2087
      20F8218B21FF218B21FF00000000000000000000000000000000165E16AC218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF2087
      20F8218B21FF155C15A800000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000218A21FD218B
      21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B
      21FF218B21FF218921FC00000000000000000000000000000000020902101B72
      1BD1218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B
      21FF1B711BD00108010F00000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      00000000000000000000000000000000000000000000000000001456149E2188
      21F9218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B21FF218B
      21FF218821F91455149C00000000000000000000000000000000000000000209
      0210165E16AD218B21FF218B21FF218B21FF218B21FF218B21FF218A21FE165D
      16AB0108010F0000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000061A062F10471082155915A4155915A4114611810519052E0000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000000000000000000000000000424D3E000000000000003E000000
      2800000040000000100000000100010000000000800000000000000000000000
      000000000000000000000000FFFFFF0000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
      000000000000}
  end
end

推荐答案

您的调用没有效果的原因是,根本不使用您检索到的设备上下文.您应该对此有所怀疑,因为在您当前的设计中,您甚至无法调用ReleaseDC且DC泄漏.

The reason your calls doesn't have an effect is that the device context you retrieved is not used in any way at all. You should suspect this since, in your current design, you can't even call ReleaseDC and the DC leaks.

当系统通过发送绘画消息来触发绘画时,所有绘画均在绘画周期中完成.您可以截取消息以修改要使用的设备上下文的布局-VCL设计允许您首先检索上下文.

All painting is done in a painting cycle when the system triggers it by sending a paint message. You can intercept the message to modify the layout of the device context to be used - VCL design allows that you retrieve the context first.

下面是使用中介程序类修改listview的消息处理方式相应修改的完整示例代码.

Below is your full example code accordingly modified, using an interposer class to modify listview's message handling.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ImgList, StdCtrls, CommCtrl, ShellAPI;

type
  TListView = class(comctrls.TListView)
  protected
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;

  end;

  TForm1 = class(TForm)
    ListView1: TListView;
    ImageList1: TImageList;
    ListView2: TListView;
    Button1: TButton;
    Label1: TLabel;
    procedure FormActivate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Label1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetLayout(DC: HDC): DWORD; stdcall; external 'gdi32.dll';
function SetLayout(DC: HDC; dwLayout: DWORD): DWORD; stdcall; external 'gdi32.dll';

procedure MakeRTL(const Handle: HWND);
begin
  SetWindowLong(Handle, GWL_EXSTYLE,
    GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYOUTRTL);
  InvalidateRect(Handle, nil, True);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MakeRTL(ListView_GetHeader(ListView1.Handle));
  MakeRTL(ListView1.Handle);
end;

procedure TForm1.FormActivate(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ListView1.Items.Count - 1 do
  begin
    ListView1.Items[I].Checked := True;
    ListView2.Items[I].Checked := True;
  end;
end;

procedure TForm1.Label1Click(Sender: TObject);
begin
  ShellExecute(0, 'open', 'https://icons8.com/icons/set/check', '', '', SW_SHOWNORMAL);
end;

{ TListView }

const
  LAYOUT_RTL = 1;
  LAYOUT_BITMAPORIENTATIONPRESERVED = 8;

procedure TListView.WMPaint(var Message: TWMPaint);
var
  Layout: DWORD;
  PS: TPaintStruct;
begin
  Message.DC := BeginPaint(Handle, PS);
  Layout := GetLayout(Message.DC);
  if (Layout and LAYOUT_RTL) <> 0 then
    SetLayout(Message.DC, Layout or LAYOUT_BITMAPORIENTATIONPRESERVED);
  inherited;
  EndPaint(Handle, PS);
end;

end.

这篇关于防止RTL TListView镜像复选框和/或图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆