Конференция "WinAPI" » Управление SysListView32 другого приложения [D7, WinXP]
 
  • blacksus (26.03.08 07:35) [0]
    Доброго времени суток всем! Такая проблема, пытаюсь программно кликнуть по колонке в ListView проводника. Почему-то сообщение не срабатывает, кто сможет помочь хоть чем заранее спасибо!


    function GetListViewHandle: THandle; //функция работает только на XP
    begin
     Result := FindWindow('CabinetWClass', PAnsiChar(Form1.Edit1.Text)); // в edit1.text заранее вписать заголовок окна проводника
     if Result = 0 then
       raise Exception.Create('Не найден CabinetWClass');
     Result := FindWindowEx(Result, 0, 'SHELLDLL_DefView', nil);
     if Result = 0 then
       raise Exception.Create('Не найден SHELLDLL_DefView');
     Result := FindWindowEx(Result, 0, 'DUIViewWndClassName', nil);
     if Result = 0 then
       raise Exception.Create('Не найден DUIViewWndClassName');
     Result := FindWindowEx(Result, 0, 'DirectUIHWND', nil);
     if Result = 0 then
       raise Exception.Create('Не найден DirectUIHWND');
     Result := FindWindowEx(Result, 0, 'CtrlNotifySink', nil);
     if Result = 0 then
       raise Exception.Create('Не найден CtrlNotifySink');
     Result := FindWindowEx(Result, 0, 'SysListView32', nil);
     if Result = 0 then
       raise Exception.Create('Не найден SysListView32');
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
     _temp: PNMLISTVIEW;
     temp: TNMLISTVIEW;
     pid: longint;
     proc, Wind: HWND;
     null: cardinal;
    begin
     Wind := GetListViewHandle;
     SendMessage(Wind, 4238, 1, 0); //установка вида "таблица"
     GetWindowThreadProcessId(Wind, @pid);
     proc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
                         PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION, FALSE, pid);
     try
       _temp := VirtualAllocEx(proc, nil, SizeOf(TNMLISTVIEW), MEM_COMMIT, PAGE_READWRITE);
       null := 0;
       FillChar(temp, SizeOf(temp), 0);
       temp.iItem := -1;
       temp.iSubItem := 1;
       WriteProcessMemory(proc, _temp, @temp, SizeOf(TNMLISTVIEW), null);
       SendMessage(Wind, WM_NOTIFY, LVN_COLUMNCLICK, lParam(_Temp)); //!!!вот это сообщение не срабатывает!!!
     finally
       VirtualFreeEx(proc, _temp, 0, MEM_RELEASE);
     end;
    end;

  • han_malign © (26.03.08 09:47) [1]
    WM_NOTIFY - шлется контролом родительскому окну...
  • han_malign © (26.03.08 09:53) [2]
    к тому же заполняется NMHDR и wParam - отнюдь не LVN_COLUMNCLICK - а идентификатор контрола
  • blacksus (26.03.08 11:31) [3]
    Тогда у меня 2 вопроса:
    1. Реально ли вообще послать сообщение для клика из моего приложения родительскому окну, или это не сработает?
    2. Непонятно, зачем тогда вообще существует LVN_COLUMNCLICK?
  • Leonid Troyanovsky © (28.03.08 22:51) [4]

    > blacksus   (26.03.08 11:31) [3]

    > 2. Непонятно, зачем тогда вообще существует LVN_COLUMNCLICK?

    Notifies a list-view control's parent window that a column was clicked.

    Можно даже уяснить, что этот парент есть некоторое окно проводника.

    --
    КRegards, LVT.
  • blacksus (29.03.08 11:21) [5]
    Большое спасибо. Тем не менее проблема все еще висит. Может кто подскажет, что я не правильно в этом коде:

    var
     _temp: PNMHDR;
     temp: TNMHDR;
    begin
     Wind := GetListViewHandle;
     GetWindowThreadProcessId(Wind, @pid);
     proc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
                         PROCESS_VM_WRITE or PROCESS_QUERY_INFORMATION, FALSE, pid);
     _temp := VirtualAllocEx(proc, nil, SizeOf(TNMHDR), MEM_COMMIT, PAGE_READWRITE);
     null := 0;
     temp.hwndFrom := GetListViewHandle;
     temp.idFrom := 0;
     Wind := GetListViewOwnerHandle;
     temp.code := LVN_COLUMNCLICK;
     WriteProcessMemory(proc, _temp, @temp, SizeOf(TNMHDR), null);
     SendMessage(Wind, WM_NOTIFY, wParam(0), lParam(_Temp));

 
Конференция "WinAPI" » Управление SysListView32 другого приложения [D7, WinXP]
Есть новые Нет новых   [134432   +20][b:0][p:0.003]