我正在寻找一种方法来检查给定窗口是否有任务栏按钮.也就是说,给定窗口的句柄,如果窗口在任务栏中,我需要为TRUE,否则为FALSE.
相反,我想知道是否有办法获得属于给定任务栏按钮的窗口的句柄,我想这需要一种方法来枚举任务栏按钮.
(第一个前者是我需要的部分,后者是可选的.)
非常感谢.
Joh*_*ler 11
Windows使用启发式方法来决定是否向窗口提供任务栏按钮,有时候在确定之前会有一个延迟,所以100%准确地执行此操作会非常困难.这是规则的粗略开始.有现代风格的标志,使其易于知道,但当缺少这些样式时,任务栏减少到猜测.
首先,您将需要两个窗口样式标志.
LONG Style = GetWindowLong(hwnd, GWL_STYLE);
LONG ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
Run Code Online (Sandbox Code Playgroud)
现在的规则,有三个规则是肯定的.
ExStyle & WS_EX_APPWINDOW,那么TASKBARExStyle & WS_EX_TOOLWINDOW,然后NOT_TASKBARStyle & WS_CHILD那么NOT_TASKBAR剩下的就是猜测:
Style & WS_OVERLAPPED 建议TASKBARStyle & WS_POPUP 建议NOT_TASKBAR特别是如果 GetParent() != NULLExStyle & WS_EX_OVERLAPPEDWINDOW 建议TASKBARExStyle & WS_EX_CLIENTEDGE 建议NOT_TASKBARExStyle & WS_EX_DLGMODALFRAME 建议NOT_TASKBAR我确信还有其他猜测规则,实际上猜测规则已经从Windows版本变为版本.
Toplevel窗口
WS_EX_APPWINDOW - >任务栏,无论其他样式!
OWNER必须为NULL(GetWindow(窗口,GW_OWNER))
no:WS_EX_NOACTIVATE或WS_EX_TOOLWINDOW:
订单很重要.
第二个问题:在windows xp/vista中,可以进入任务栏的进程并获取所有窗口ID:
void EnumTasklistWindows()
{
int b2 = 0;
TBBUTTON tbButton;
DWORD dwProcessId = 0, dwThreadId = 0;
HWND hDesktop =::GetDesktopWindow();
HWND hTray =::FindWindowEx(hDesktop, 0, ("Shell_TrayWnd"), NULL);
HWND hReBar =::FindWindowEx(hTray, 0, ("ReBarWindow32"), NULL);
HWND hTask =::FindWindowEx(hReBar, 0, ("MSTaskSwWClass"), NULL);
HWND hToolbar =::FindWindowEx(hTask, 0, ("ToolbarWindow32"), NULL);
LRESULT count =::SendMessage(hToolbar, TB_BUTTONCOUNT, 0, 0);
dwThreadId = GetWindowThreadProcessId(hToolbar, &dwProcessId);
shared_ptr<void> hProcess (OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId), CloseHandle);
if (NULL == hProcess.get())
{
return;
}
memset(&tbButton, 0, sizeof(TBBUTTON));
for (int i = 0; i < count; i++)
{
memset(&tbButton, 0, sizeof(TBBUTTON));
shared_ptr<void> lpRemoteBuffer (
VirtualAllocEx(hProcess.get(), NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE),
bind<BOOL>(VirtualFreeEx, hProcess.get(), _1, 0, MEM_RELEASE));
if (NULL == lpRemoteBuffer.get())
{
return;
}
SendMessage(hToolbar, TB_GETBUTTON, i, (LPARAM) lpRemoteBuffer.get());
b2 = ReadProcessMemory(hProcess.get(), lpRemoteBuffer.get(),
(LPVOID) & tbButton, sizeof(TBBUTTON), NULL);
if (0 == b2)
{
continue;
}
BYTE localBuffer[0x1000];
BYTE *pLocalBuffer = localBuffer;
DWORD_PTR ipLocalBuffer = (DWORD_PTR) pLocalBuffer;
pLocalBuffer = localBuffer;
ipLocalBuffer = (DWORD_PTR) pLocalBuffer;
DWORD_PTR lpRemoteData = (DWORD_PTR) tbButton.dwData;
ReadProcessMemory(hProcess.get(), (LPVOID) lpRemoteData, (LPVOID) ipLocalBuffer,
sizeof(DWORD_PTR), NULL);
HWND windowHandle;
memcpy(&windowHandle, (void *) ipLocalBuffer, 4);
if (windowHandle != NULL)
{
trace ("adding button: %x\n", windowHandle);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不再适用于Windows 7了.所以你需要遍历所有的顶层窗户.
| 归档时间: |
|
| 查看次数: |
2122 次 |
| 最近记录: |