做了相当多的研究试图弄清楚如何让它正常工作。我读过如果你过滤WM_NOTIFY - > NM_CLICK,它会捕获syslink的实际click事件。麻烦的是它抓住了这个事件,虽然它被卡在无休止的递归中,几秒钟内你就有了数百个浏览器窗口或者没有链接打开了。
采取的措施:
为NM_CLICK事件过滤WM_NOTIFY
case WM_NOTIFY:
//case NM_CLICK:
switch(LOWORD(wParam))
{
case NM_CLICK:
switch(LOWORD(wParam))
{
case IDC_LINK1:
// Standard ShellExecute with added check for IsLinkCtrl to make sure its the right kind of control.
OpenLink(hWndDlg, LOWORD(wParam));
break;
}
break;
}
break;
我想我真正的问题是我该如何正确地做到这一点?我没有看到任何好的示例显示如何正确过滤Syslink以将链接作为URL执行。
答案 0 :(得分:3)
为了澄清,我不认为您使用的是托管C ++,因为我不确定您为什么将NM_CLICK通知代码称为事件。 此外,您不必捕获任何内容,您不处理任何异常,您只是处理WM_NOTIFY消息。
无论如何,我不确定为什么你会遇到这种特殊的行为,因为我没有看到你在代码片段之外做了什么,但我知道是什么导致了它。 在我们的代码段中,您使用wParam来确定通知代码,这是不正确的。此控件不使用wParam。要确定通知代码,您应该执行以下操作:
NMHDR* pHeader = (NMHDR*)lParam;
switch (pHeader->code)
pHeader->代码包含您应使用的通知代码值, pHeader-> hwndFrom 是所单击控件的句柄。
此外,您再次使用LOWORD(wParam)并将其作为参数传递给函数调用。您没有显示您在此函数中执行的操作,但我可以断定代码也不正确。 相同的lParam是指向NMLINK结构的指针。 该结构的第一个成员在NMHDR上面提到,下一个成员是LITEM结构,应该用来确定URL是什么。
NMLINK* pNMLink = (NMLINK*)lParam;
LITEM iItem = pNMLink->item;
item.szUrl 是您在调用ShellExecute调用open时应使用的URL。
答案 1 :(得分:2)
我发现了一种成功的方法,可以在不进行递归的情况下使其工作。消息循环似乎在连续循环中继续读取,如果不使用正确的结构进行过滤,它将陷入无限递归。这适合我。如果你有更好的输入请做插件。
采取正确的步骤。
使用了以下代码。
case WM_NOTIFY:
//NMHDR* pHeader = (NMHDR*)lParam;
//NMLINK* pNMLink = (NMLINK*)lParam;
//LITEM iItem = pNMLink->item;
switch(((NMHDR *)lParam)->code)
{
case NM_CLICK:
{ // Included to avoid "case" skip statements.
times++;
NMLINK* pNMLink = (NMLINK*)lParam;
LITEM iItem = pNMLink->item;
// Custom OutputDebugString
winapi::Output("NM_CLICK: Fired %d time%s!\n", times, (times <= 1) ? L"" : L"s");
#ifdef DEBUG
assert(iItem.szID);
MessageBox(NULL, (LPCWSTR)lParam, L"Assert", MB_OK|MB_ICONINFORMATION);
#endif
if(wParam == IDC_LINK1)
{
winapi::Output("Success!");
OpenLink(hWndDlg, LOWORD(wParam));
}
注意:如果您依赖包含HTML属性的链接(链接或此处)来提供Shellexecute其网址路径,请使用NMLINK结构。
答案 2 :(得分:1)
无论
您的OpenLink
功能导致发送另一条消息(最有可能),或
这不是调用OpenLink
的唯一代码,或
您的代码不是来自WM_NOTIFY
,而是来自上述案例,或
即使您已经处理过该消息,也请致电DefWindowProc
。
尝试
break; // make sure there's no fall-through here
case NM_CLICK:
switch(LOWORD(wParam))
{
case IDC_LINK1:
// Standard ShellExecute with added check for IsLinkCtrl to make sure its the right kind of control.
OpenLink(hWndDlg, LOWORD(wParam));
return TRUE; // handled, don't pass to DefWindowProc
}
break;