2

これを適切に機能させる方法を見つけようとして、かなりの調査を行いました。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;
    

私の本当の質問は、どうすればこれを適切に行うことができるかということだと思います。リンクをURLとして実行するためにSyslinkが適切にフィルタリングされる方法を示す良い例は見当たりません。

4

3 に答える 3

3

明確にするために、マネージ 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 call open の呼び出しで使用する必要がある URL です。

于 2012-05-23T22:22:01.283 に答える
2

再帰せずにこれを機能させるための成功した方法を見つけました。メッセージループは連続ループで読み取りを続けるようであり、正しい構造を使用してフィルタリングしないと、無限再帰に陥ります。これは私のために働きます。ぜひ、より良い入力があれば、アドオンを実行してください。

取るべき正しいステップ。

  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構造を使用してください。

于 2012-05-24T18:48:35.253 に答える
1

また

  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;
于 2012-05-24T18:06:28.533 に答える