function GetHandleFromButtonIndex(ButtonIndex: Word): HWND;
const
BUFFER_SIZE = $1000;
var
hwndTaskbar: HWND;
// variables that needed to open taskbar (explorer) process
taskbarProcessID: DWORD;
taskbarProcessHandle: THandle;
// variable that helds pointer to a remote buffer in taskbar process
taskbarProcessBuffer: Pointer;
i: Integer;
dwBytesRead: DWORD;
lpRemoteData: Pointer;
tbButton: TTBBUTTON;
PtbButton: Pointer;
localBuffer:
array[0..BUFFER_SIZE - 1]
of Byte;
pLocalBuffer: ^Byte;
ipLocalBuffer: Pointer;
btnWindowHandle: HWND;
begin
Result := 0;
// find Windows Taskbar
hwndTaskbar := getTaskbarHWND;
if hwndTaskbar <> 0
then
begin
// obtain taskbar process id - by window
GetWindowThreadProcessId(hwndTaskbar, @taskbarProcessID);
// open taskbar process
taskbarProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, taskbarProcessID);
if taskbarProcessHandle <> 0
then
try
// allocate space for remote buffer in taskbar process
taskbarProcessBuffer := VirtualAllocEx(taskbarProcessHandle,
nil, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
if Assigned(taskbarProcessBuffer)
then
begin
// declare and prepare variables that will held data
// about PRESSED button in a taskbar
PtbButton := @tbButton;
// Now, retrieve information about the PRESSED button in a taskbar / data is placed in remote buffer
SendMessage(hwndTaskbar, TB_GETBUTTON, ButtonIndex, Integer(taskbarProcessBuffer));
// And now, the remote data about PRESSED button is transferred to a local variable
dwBytesRead := 0;
ReadProcessMemory(taskbarProcessHandle, taskbarProcessBuffer, PtbButton, SizeOf(TBBUTTON), dwBytesRead);
// the window handle is in dwData field of TBBUTTON structure (the first 4 bytes)
pLocalBuffer := @localBuffer[0];
ipLocalBuffer := pLocalBuffer;
// initialize remote buffer
lpRemoteData := @tbButton.dwData;
// and read the dwData fields of a TBBUTTON from remote process
dwBytesRead := 0;
ReadProcessMemory(taskbarProcessHandle, lpRemoteData, ipLocalBuffer, SizeOf(Pointer), dwBytesRead);
// obtain window handle, copy first 4 bytes
Move(ipLocalBuffer, btnWindowHandle, 4);
Result := btnWindowHandle;
if Assigned(taskbarProcessBuffer)
then
VirtualFreeEx(taskbarProcessHandle, taskbarProcessBuffer, 0, MEM_RELEASE);
end;
finally
CloseHandle(taskbarProcessHandle);
end;
end;
end;