[英]CListCtrl. When double click ALWAYS receive NM_CLICK + NM_DBLCLK
[英]How to handle NM_CLICK for Syslink control
做了大量的研究,試圖弄清楚如何使其正常工作。 我了解到,如果您過濾WM_NOTIFY-> NM_CLICK,它將捕獲syslink的實際單擊事件。 問題是它捕獲了事件,盡管它陷入了無休止的遞歸中,並且在幾秒鍾內您有數百個瀏覽器窗口,或者打開了鏈接。
采取的步驟 :
為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。
為了澄清起見,我不認為您使用的是托管C ++,因為我不確定您為什么將NM_CLICK通知代碼稱為事件。 此外,您不必捕獲任何內容,無需處理任何異常,而僅需要處理WM_NOTIFY消息。
無論如何,我不確定您為什么會遇到這種特殊行為,因為在代碼段之外看不到您在做什么,但我知道是什么原因造成的。 在我們的代碼段中,您使用wParam確定了一個通知代碼,這是不正確的。 此控件不使用wParam。 要確定通知代碼,您應該執行以下操作:
NMHDR* pHeader = (NMHDR*)lParam;
switch (pHeader->code)
pHeader-> code包含您應使用的通知代碼值,而pHeader-> hwndFrom是單擊的控件的句柄。
此外,您再次使用LOWORD(wParam)並將其作為參數傳遞給函數調用。 您沒有顯示該函數的功能,但是我可以得出結論,該代碼也不正確。 相同的lParam是指向NMLINK結構的指針。 NMHDR上面提到了該結構的第一個成員,下一個成員是LITEM結構,應使用該結構確定URL是什么。
NMLINK* pNMLink = (NMLINK*)lParam;
LITEM iItem = pNMLink->item;
item.szUrl是在打開ShellExecute調用時應使用的URL。
我找到了一種成功的方法,無需進行遞歸即可使其工作。 消息循環似乎在連續循環中進行讀取,如果不使用正確的結構進行過濾,它將陷入無限遞歸。 這對我有用。 如果您一定有更好的輸入,請添加插件。
正確的步驟。
使用了以下代碼。
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其URL路徑, 請使用NMLINK結構。
要么
您的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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.