Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Вопросик .. для наших Win32 гуру [solved] (https://forum.antichat.xyz/showthread.php?t=30055)

Deem3n® 27.12.2006 22:39

Вопросик .. для наших Win32 гуру [solved]
 
Второй день мучаюсь и не могу найти нормальное решение проблемы.

Так вот:
1) есть таскбар и на таскбаре кнопки
2) возьмем к примеру кнопку окна stuff

http://img380.imageshack.us/img380/49/1la8.jpg

3) суть проблемы: нужно получить хэндл окна, которому принадлежит кнопка на таскбаре, над которой в данный момент курсор мыши

http://img164.imageshack.us/img164/7610/2sf2.jpg

Если у кого есть какие-нибудь идеи, скидывайте сюда, язык программирования не имеет значения.

зы: WindowFromPoint и ChildWindowFromPoint не помогли

a1nt 28.12.2006 00:55

Ааа, ясно)
Тогда нужно перехватывать события на кнопке. В часности wm_mousemove, wm_setcursor.
Кстати, дло таких исследований удобно использовать утилиту WinSight32 из комплекта Delphi. Покажет все окна, события.

_Great_ 28.12.2006 01:03

топикстартер предлагал сэмулировать нажатие мыши и получить хендл текущего активного окна, потом вернуть окна обратно

Deem3n® 28.12.2006 12:54

Цитата:

Сообщение от a1nt
Ааа, ясно)
Тогда нужно перехватывать события на кнопке. В часности wm_mousemove, wm_setcursor.

=
Цитата:

Сообщение от _Great_
топикстартер предлагал сэмулировать нажатие мыши и получить хендл текущего активного окна, потом вернуть окна обратно

Цитата:

10:01 ------: мля .. видимо прийдется действовать примитивным способом:
10:01 Great: каким)
10:01 ------: налошить хук на мышь, и если мышь находится над таскбаром, симулировать нажание левой кнопки, а потом GetTopWindow :)
10:01 Great: ну это слишком)
Этот способ не практичен.

Имхо кнопки на таскбаре не реализованы как кнопки. Spy++ видит только ToolbarWindow32. Утром созрело возможное решение проблемы - tooltips_class32:

http://img216.imageshack.us/img216/4701/untitledkz6.jpg

Сейчас ищу возможность узнать заголовок окна, а потом уж - FindWindow :)

Deem3n® 06.01.2007 23:46

Всем спасибо, проблему решил.

Решение:
1) посылаю окну таскбара сообщение TB_GETBUTTON для того чтоб получить структуру TBBUTTON которая описывает кнопку на таскбаре.
2) Хэндл окна - это первые четыре байта поля dwData структуры TB_GETBUTTON. Мля, а в мсдн про это ничего не сказано...

Если нужны сорцы, могу выложить =)

_Great_ 07.01.2007 00:22

Цитата:

2) Хэндл окна - это первые четыре байта поля dwData структуры TB_GETBUTTON. Мля, а в мсдн про это ничего не сказано...
как догадался?
зы. в мсдн вообще мало чего полезного сказано))

Deem3n® 07.01.2007 00:24

Цитата:

как догадался?
доэкспериментировался =))

Ch3ck 22.01.2007 12:16

Кстати, ничё такая статейка "Дреcсированные окна".
_http://www.xakep.ru/magazine/xa/086/116/1.asp

Deem3n® 23.01.2007 10:37

Дабы расставить все точки над ё, привожу кусок кода решающий часть данной проблемы (извините за английские комменты)

Код:

// find Windows Taskbar (Note: works under XP and 2k3)
HWND hwndTaskbar = FindWindow("Shell_TrayWnd", NULL);
hwndTaskbar = FindWindowEx(hwndTaskbar, NULL, "ReBarWindow32", NULL);
hwndTaskbar = FindWindowEx(hwndTaskbar, NULL, "MSTaskSwWClass", NULL);
hwndTaskbar = FindWindowEx(hwndTaskbar, NULL, "ToolbarWindow32", NULL);

i - это индекс кнопки на таскбаре
Код:

// variables that needed to open taskbar (explorer) process
DWORD taskbarProcessID;
const int BUFFER_SIZE = 0x1000;

// obtain taskbar process id - by window
GetWindowThreadProcessId(hwndTaskbar, &taskbarProcessID);
// open taskbar process
HANDLE taskbarProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, taskbarProcessID);

// variable that helds pointer to a remote buffer in taskbar process
DWORD_PTR taskbarProcessBuffer;

// allocate space for remote buffer in taskbar process
taskbarProcessBuffer = (DWORD_PTR)VirtualAllocEx(taskbarProcessHandle, NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
                               
// declare and prepare variables that will held data
// about PRESSED button in a taskbar
TBBUTTON tbButton;
TBBUTTON* pTBButton = &tbButton;
DWORD_PTR lpTBButton = (DWORD_PTR)pTBButton;

// Now, retrieve information about the PRESSED button in a taskbar
// Note: data is placed in remote buffer
SendMessage(hwndTaskbar, TB_GETBUTTON, i, taskbarProcessBuffer);

// And now, the remote data about PRESSED button is transferred to a local variable
DWORD dwBytesRead = 0;
ReadProcessMemory(taskbarProcessHandle, (LPVOID)taskbarProcessBuffer, (LPVOID)lpTBButton, sizeof(TBBUTTON), &dwBytesRead);

// ------------------------------------------------------------------
// Where is keeped the window handle?
// It is in dwData field of TBBUTTON structure (the first 4 bytes) :))
// MSDN doesn't specify anything about this!
// ------------------------------------------------------------------
                               
// Retrieve window handle of pressed btn
BYTE localBuffer[BUFFER_SIZE];
BYTE* pLocalBuffer = localBuffer;
DWORD_PTR ipLocalBuffer = (DWORD_PTR)pLocalBuffer;

// window handle
pLocalBuffer = localBuffer;
ipLocalBuffer = (DWORD_PTR)pLocalBuffer;

// initialize remote buffer
DWORD_PTR lpRemoteData = (DWORD_PTR)tbButton.dwData;
       
// and read the dwData fields of a TBBUTTON from remote process
ReadProcessMemory(taskbarProcessHandle, (LPVOID)lpRemoteData, (LPVOID)ipLocalBuffer, sizeof(DWORD_PTR), &dwBytesRead);

// obtain window handle
// copy first 4 bytes
HWND windowHandle;
memcpy(&windowHandle, (void *)ipLocalBuffer, 4);


_Great_ 23.01.2007 11:08

Вообщем-то это уже недокументированные возможности Gui :)


Время: 14:32