簡體   English   中英

如何處理NM_CLICK的Syslink控件

[英]How to handle NM_CLICK for Syslink control

做了大量的研究,試圖弄清楚如何使其正常工作。 我了解到,如果您過濾WM_NOTIFY-> NM_CLICK,它將捕獲syslink的實際單擊事件。 問題是它捕獲了事件,盡管它陷入了無休止的遞歸中,並且在幾秒鍾內您有數百個瀏覽器窗口,或者打開了鏈接。

采取的步驟

  1. 在對話框上創建Syslink
  2. 將標題添加到Syslink控件鏈接,並將IDD更改為IDC_LINK1
  3. 為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。

我找到了一種成功的方法,無需進行遞歸即可使其工作。 消息循環似乎在連續循環中進行讀取,如果不使用正確的結構進行過濾,它將陷入無限遞歸。 這對我有用。 如果您一定有更好的輸入,請添加插件。

正確的步驟。

  1. 創建WM_NOTIFY郵件篩選器事件。
  2. 使用NMHDR創建Switch語句以解析NM_CLICK的代碼。
  3. 檢查wParam以確定是否單擊了正確的控件。
  4. 使用ShellExecute執行鏈接。

使用了以下代碼。

       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結構。

要么

  1. 您的OpenLink函數導致發送另一條消息(很有可能),或者

  2. 這不是調用OpenLink的唯一代碼,或者

  3. 您不是通過WM_NOTIFY而是通過上述情況的失敗而獲得此代碼,或者

  4. 即使已經處理過消息,也可以調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM