Посмотреть список; Нет всплывающей подсказки с RTL макетом - PullRequest
0 голосов
/ 02 июля 2019

Я установил свой TListView в RTL (справа налево), используя код ниже. Теперь я понял, что подсказка не отображается. Если я удаляю WS_EX_LAYOUTRTL (и, таким образом, управление больше не является RTL), проблема решается, и отображается подсказка.

Я хочу, чтобы всплывающая подсказка отображалась, пока Listview находится в формате RTL.

Я думаю, что, возможно, одним из решений является изменение окна всплывающей подсказки (если оно имеет окно) на формат RTL, но я не знаю как.

procedure SetControlLayout(Control: TWinControl; RTL: Boolean);
const
  LVM_FIRST = $1000;
  LVM_GETHEADER = LVM_FIRST + 31;   // ListView header messages
var
  Header: thandle;
  NewLong: NativeInt;
begin
  if Control is TListView then
  begin
    Header:= SendMessage(Control.Handle, LVM_GETHEADER, 0, 0);
    if RTL then
      NewLong:= GetWindowLong (Header, GWL_EXSTYLE) or WS_EX_LAYOUTRTL
        //or WS_EX_NOINHERITLAYOUT
    else
      NewLong:= 0;

    SetWindowLongPtr(Header, GWL_EXSTYLE, NewLong);
  end;

  if RTL then
    NewLong:= GetWindowLong(Control.Handle, GWL_EXSTYLE)  or
      WS_EX_LAYOUTRTL or
      WS_EX_RTLREADING or
      WS_EX_LEFT
      //or WS_EX_NOINHERITLAYOUT
  else
    NewLong:= 0;

  SetWindowLongPtr(Control.Handle, GWL_EXSTYLE, NewLong );

  Control.invalidate; 
end;

1 Ответ

0 голосов
/ 02 июля 2019

Я вижу одну проблему, когда RTL имеет значение false, вы устанавливаете GWL_EXSTYLE в 0, стирая ВСЕ расширенные стили окна, включая LVS_EX_INFOTIP.Вам нужно сохранить стили, которые вы не хотите менять, например:

procedure SetControlLayout(Control: TWinControl; RTL: Boolean);
const
  LVM_FIRST = $1000;
  LVM_GETHEADER = LVM_FIRST + 31; // ListView header messages
  HeaderRTLStyles = WS_EX_LAYOUTRTL
    //or WS_EX_NOINHERITLAYOUT
    ;
  ControlRTLStyles = WS_EX_LAYOUTRTL
    or WS_EX_RTLREADING
    or WS_EX_LEFT
    //or WS_EX_NOINHERITLAYOUT
    ;
var
  Header: HWND;
  ExStyles: LONG_PTR;
begin
  if Control is TListView then
  begin
    Header := SendMessage(Control.Handle, LVM_GETHEADER, 0, 0);
    if Header <> 0 then
    begin
      ExStyles := GetWindowLongPtr(Header, GWL_EXSTYLE);
      if RTL then
        ExStyles := ExStyles or HeaderRTLStyles
      else
        ExStyles := ExStyles and not HeaderRTLStyles;

      SetWindowLongPtr(Header, GWL_EXSTYLE, ExStyles);
    end;
  end;

  ExStyles := GetWindowLongPtr(Control.Handle, GWL_EXSTYLE);
  if RTL then
    ExStyles := ExStyles or ControlRTLStyles
  else
    ExStyles := ExStyles and not ControlRTLStyles;

  SetWindowLongPtr(Control.Handle, GWL_EXSTYLE, ExStyles);

  Control.Invalidate;
end;

Другая проблема, которую я вижу, состоит в том, что WS_EX_LAYOUTRTL имеет то же числовое значение, что и LVS_EX_TRANSPARENTBKGND.Расширенные стили окна ListView не могут быть установлены с помощью CreateWindow/Ex() или SetWindowLong/Ptr(GWL_EXSTYLE), они должны быть установлены с помощью сообщения окна LVM_SETEXTENDEDLISTVIEWSTYLE.Поэтому вам, возможно, придется повторно включить стиль LVS_EX_INFOTIP после установки WS_EX_LAYOUTRTL:

procedure SetControlLayout(Control: TWinControl; RTL: Boolean);
const
  LVM_FIRST = $1000;
  LVM_GETHEADER = LVM_FIRST + 31; // ListView header messages
  HeaderRTLStyles = WS_EX_LAYOUTRTL
    //or WS_EX_NOINHERITLAYOUT
    ;
  ControlRTLStyles = WS_EX_LAYOUTRTL
    or WS_EX_RTLREADING
    or WS_EX_LEFT
    //or WS_EX_NOINHERITLAYOUT
    ;
var
  IsListView: boolean;
  Header: HWND;
  ExStyles: LONG_PTR;
begin
  IsListView := Control is TListView;
  if IsListView then
  begin
    Header := SendMessage(Control.Handle, LVM_GETHEADER, 0, 0);
    if Header <> 0 then
    begin
      ExStyles := GetWindowLongPtr(Header, GWL_EXSTYLE);
      if RTL then
        ExStyles := ExStyles or HeaderRTLStyles
      else
        ExStyles := ExStyles and not HeaderRTLStyles;

      SetWindowLongPtr(Header, GWL_EXSTYLE, ExStyles);
    end;
  end;

  ExStyles := GetWindowLongPtr(Control.Handle, GWL_EXSTYLE);
  if RTL then
    ExStyles := ExStyles or ControlRTLStyles
  else
    ExStyles := ExStyles and not ControlRTLStyles;

  SetWindowLongPtr(Control.Handle, GWL_EXSTYLE, ExStyles);

  if IsListView then
    Control.Perform(LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_INFOTIP, LVS_EX_INFOTIP);

  Control.Invalidate;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...