【问题标题】:WinApi - How to obtain SHELLDLL_DefViewWinApi - 如何获取 SHELLDLL_DefView
【发布时间】:2016-04-12 07:40:56
【问题描述】:

我正在尝试获取 SHELLDLL_DefView 的句柄。

所以,我有这个代码。

HWND hProgman = FindWindow(L"Progman", NULL);
HWND hWnd = FindWindowEx(hProgman, 0, L"SHELLDLL_DefView", NULL);

Eveyrtihing 工作正常,直到我将 Windows 桌面背景更改为幻灯片。然后,当我使用窗口的 spy++ 层次结构搜索时,SHELLDLL_DefView 有另一个父级。现在是#32769(桌面)-> WorkerW -> SHELLDLL_DefView。所以我找不到它。问题是当我尝试时

HWND desktop = GetDesktopWindow();
HWND hWnd = FindWindowEx(desktop , 0, L"WorkerW", NULL);
HWND hWnd = FindWindowEx(hWnd, 0, L"SHELLDLL_DefView", NULL);

没有找到比 SHELLDLL_DefView。 WorkerW 是的。

有人可以帮忙吗?

【问题讨论】:

  • 为什么需要找到这个?该外壳具有丰富的自动化接口。您是否评估过它不符合您的要求?
  • 我需要完成 SHELLDLL_DefView 的句柄
  • “我需要找到 X,因为我需要找到 X” 不是问题的答案,为什么你认为你会这样做。
  • 我在下面给出答案,如何解决我的问题。
  • 但是,一旦拥有了 HWND,您将如何处理它?您在这里要达到的最终目标是什么?通常情况下,与 shell 交互比通过随机窗口句柄更好的方式。

标签: c++ windows winapi spy++


【解决方案1】:

我找到了答案。需要遍历所有的WorkerW。

HWND destop = GetDesktopWindow();
HWND hWorkerW = NULL;
HWND hShellViewWin = NULL;
do
{
    hWorkerW = FindWindowEx(destop, hWorkerW, L"WorkerW", NULL);
    hShellViewWin = FindWindowEx(hWorkerW, 0, L"SHELLDLL_DefView", 0);
} while (hShellViewWin == NULL && hWorkerW != NULL);

【讨论】:

  • 谢谢,这解决了我的问题。我注意到虽然没有必要传递 desktop HWND,因为这是传递 null 时的默认值(MSDN:If hwndParent is NULL, the function uses the desktop window as the parent window. The function searches among windows that are child windows of the desktop.)。
【解决方案2】:

您的代码仅适用于某些 Windows 版本,因为“SHELLDLL_DefView”可以在“WorkerW”或“Progman”下找到,并且您发现“WorkerW”类下可以有许多窗口(在 Win7 中正常)。

Microsoft Docs 报告 EnumWindows() 比在循环中调用 GetWindow()/FindWindowEx() 函数更可靠,因此更通用的代码(在 Windows 98/Windows 7 上测试)看起来像这样(假设你想刷新桌面):

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
    HWND hNextWin;
    hNextWin = FindWindowExA(hwnd, 0, "SHELLDLL_DefView", 0);
    if ( hNextWin ) {
    // The correct desktop shell window under Progman/WorkerW will have only 1 child window!
        if ( GetNextWindow(hNextWin, GW_HWNDNEXT) || GetNextWindow(hNextWin, GW_HWNDPREV) )
            return true;
    // We found correct handle
        PostMessageA(hNextWin, WM_KEYDOWN, VK_F5, 0);
        return false;
    }
    return true;
}

void main() {
   EnumWindows(&EnumWindowsProc, 0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 2012-12-04
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多