子类化SHBrowseForFolder并处理WM_NOTIFY

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了子类化SHBrowseForFolder并处理WM_NOTIFY相关的知识,希望对你有一定的参考价值。

我正在尝试修复SHBrowseForFolder对话框,因为它没有对文件夹重命名做出反应(BFFM_SELCHANGED没有被发送,并且无法确定路径现在是否正确)。我用谷歌搜索了一个解决方案,就像我必须继承dlg的wndproc并抓住TVN_ENDLABELEDIT自己发送BFFM_SELCHANGED

以下是我在获取BFFM_INITIALIZED时设置新wndproc的方法:

for (HWND hChild = GetWindow(hWnd, GW_CHILD); hChild != 0; hChild = GetWindow(hChild, GW_HWNDNEXT)) {
    szClassName[256];
    GetClassName(hChild, szClassName, sizeof(szClassName));
    if (!stricmp(szClassName, "SHBROWSEFORFOLDER SHELLNAMESPACE CONTROL")) {
        oldWndProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(hChild, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(_SubclassWndProc)));
        break;
    }
}

这是_SubclassWndProc:

static LRESULT _SubclassWndProc(HWND hWnd, UINT uMsg, WPARAM lParam, LPARAM lpData) {
  switch (uMsg) {
     case WM_NOTIFY:
        switch (((LPNMHDR)lParam)->code) {
           case TVN_ENDLABELEDIT:
              break;
        }
        break;
  }
  return CallWindowProc(oldWndProc, hWnd, uMsg, lParam, lpData);
}

它只有在我评论WM_NOTIFY块时才有用。甚至访问lParam中断对话框(它包含带有空标签的损坏的树)。如果我在切换之前调用oldWndProc,那么它可以工作,但在WM_NOTIFY情况下,lParam显然不包含指向NMHDR的指针,它包含一个小的整数值,如1,2,100等。

编辑:问题可以缩短为“为什么WM_NOTIFY没有指向NMHDR的指针?”

答案

这个错误是由于我的疏忽造成的:我从一些例子中复制了wndproc签名,这个例子混淆了agrument。 lParam通常是最后一个并且具有类型LPARAM。所以我试图抛出通常称为wParam的arg,它包含一个不是LPNMHDR的控件ID。

以上是关于子类化SHBrowseForFolder并处理WM_NOTIFY的主要内容,如果未能解决你的问题,请参考以下文章

将 SHBrowseForFolder 和 struct BROWSEINFO 的使用更改为 - IFileOpenDialog

Delphi的子类化控件消息, 消息子类化

访问表单子类以捕获 WM_MOVING 消息

子类化并覆盖 PySide2 小部件方法;我在哪里可以找到参考资料?

使用插座子类化主视图控制器

C#'static abstract'方法替代实例化子类