微软SysLink控件WM_NOTIFY处理示例else分支未校验hwndFrom原因问询
结论
这段示例代码不是错误,是省略了默认场景前提的简化写法,本身在示例设定的场景下可以正常运行。
原因说明
- 这段代码对应的示例场景默认对话框内仅存在
g_hLink这一个SysLink控件,没有其他控件会发送NM_CLICK/NM_RETURN类型的WM_NOTIFY通知,所以只要进入这两个case的处理逻辑,消息必然来自g_hLink,不需要重复判断。 - 从结构体定义来看,
NMLINK的首个成员就是NMHDR类型,所以PNMLINK和LPNMHDR指针指向的是同一块内存的起始地址,前面的if条件已经对当前通知的hwndFrom做过校验,同一个通知内的else分支自然不需要重复判断。
注意事项
如果你的项目中对话框存在多个SysLink控件,这个写法就会出现逻辑问题:其他SysLink控件如果存在ID为idInfo的链接,点击后也会触发这段代码中的MessageBox。这种场景下更严谨的写法是提前过滤控件句柄,不需要在每个分支重复判断:
case WM_NOTIFY: { LPNMHDR pNMHdr = (LPNMHDR)lParam; // 非目标SysLink控件的消息直接交给默认逻辑处理 if (pNMHdr->hwndFrom != g_hLink) { return DefWindowProc(hDlg, uMsg, wParam, lParam); } switch (pNMHdr->code) { case NM_CLICK: case NM_RETURN: { PNMLINK pNMLink = (PNMLINK)pNMHdr; LITEM item = pNMLink->item; if (item.iLink == 0) { ShellExecute(NULL, L"open", item.szUrl, NULL, NULL, SW_SHOW); } else if (wcscmp(item.szID, L"idInfo") == 0) { MessageBox(hDlg, L"This isn't much help.", L"Example", MB_OK); } break; } } break; }
内容的提问来源于stack exchange,提问作者Jabberwocky
相关产品推荐
相关产品推荐

