#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 обрабатывать его нормально, оно должно работать нормально.