Delphi изменить цвет текста для элемента SysListView32 другого окна

#delphi

#delphi

Вопрос:

как изменить цвет текста элемента SysListView32 в другом приложении

Приведенный ниже код изменяет цвет текста элемента SysListView32 в другом приложении

 procedure TMainForm.btn1Click(Sender: TObject);
begin
ChangingTextColor([Here is the SysListView32 hwnd],22,RGB(0,0,0));
end;
 

Полная процедура выполняется следующим образом:

 procedure ChangingTextColor(LVHandle: HWND; N: Integer;ClrCode:Integer);
var
  lvi: LV_ITEM;
  _lvi: PLVITEM;
  Item: array[0..1000] of char;
  _Item, _subitem: PChar;
  pid: Cardinal;
  process: THANDLE;
  writebytes,readbytes:ULONG_PTR;
begin
  GetWindowThreadProcessId(LVHandle, @pid);

  process := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION, FALSE, pid);
  Win32Check(process<>0);
  try
    _lvi := PLVITEM(VirtualAllocEx(process, Nil, sizeof(TLVITEM), MEM_COMMIT, PAGE_READWRITE));
    Win32Check(_lvi<>nil);
    try
      _item := PChar(VirtualAllocEx(process, Nil, 512, MEM_COMMIT, PAGE_READWRITE));
      Win32Check(_item<>nil);
      try
        _subitem :=PChar(VirtualAllocEx(process, Nil, 512, MEM_COMMIT, PAGE_READWRITE));
        Win32Check(_subitem<>nil);
        try
          lvi.cchTextMax := 512;
          lvi.iSubItem := 0;
          lvi.pszText := '55';
          lvi.mask := LVIF_STATE;
          lvi.iItem := N;
          lvi.state := LVIS_FOCUSED or LVIS_SELECTED;
          lvi.stateMask := LVIS_FOCUSED or LVIS_SELECTED;

          Win32Check(WriteProcessMemory(process, _lvi, @lvi, sizeof(TLVITEM), writebytes));
          Win32Check(ReadProcessMemory(process, _item, @item, 512, readbytes));

          **SendMessage(LVHandle, LVM_SETTEXTCOLOR, LPARAM(_lvi), ClrCode);
          SendMessage(LVHandle, WM_SETTINGCHANGE, 0, 0);**

        finally
          Win32Check(VirtualFreeEx(process, _subitem, 0, MEM_RELEASE));
        end;
      finally
        Win32Check(VirtualFreeEx(process, _item, 0, MEM_RELEASE));
      end;
    finally
      Win32Check(VirtualFreeEx(process, _lvi, 0, MEM_RELEASE));
    end;
  finally
    CloseHandle(process);
  end;

end;
 

Вопрос: Должен ли цвет (ClrCode) быть целым или TColor ?

Комментарии:

1. Вы не можете просто создать функциональность стороннего кода. Вы должны прочитать документацию и прислушаться к ней.

Ответ №1:

Прочитайте документацию. LVM_SETTEXTCOLOR не принимает a LVITEM в качестве входных данных, WParam должно быть 0, поэтому все ваши виртуальные выделения бесполезны (не то, чтобы они были правильными с самого начала):

 procedure ChangingTextColor(LVHandle: HWND; ClrCode:Integer);
begin
    SendMessage(LVHandle, LVM_SETTEXTCOLOR, 0, ClrCode);
end;
 

В этом случае вы можете просто использовать ListView_SetTextColor() вместо:

 ListView_SetTextColor(LVHandle, ClrCode);
 

Вы не можете установить цвет текста для каждого элемента с помощью ListView API, для этой цели нет команды. Для настройки каждого элемента требуется пользовательское рисование приложением-владельцем ListView. Это вне вашего контроля, если только вы не должны были внедрить свой собственный код в другое приложение и взять под контроль чертеж ListView, подклассировав его сообщения о рисовании.

Комментарии:

1. если я введу DLL в процесс traget с этим procedure ChangingTextColor , это будет работать?

2. ListView_SetTextColor() это просто оболочка для SendMessage(LVM_SETTEXTCOLOR) . Любое оконное сообщение, которое не содержит указателей, будет отлично работать через границы процесса. Реальный вопрос в том, что принимающее приложение делает с сообщением, когда оно получено. Пока приложение позволяет ListView обрабатывать его нормально, оно должно работать нормально.