5

アプリケーションのトレイアイコンへのドラッグアンドドロップを許可しようとしています。

ドラッグイベントをサポートしていないため、高レベルのC#WindowsFormsAPIでこれを行うことは不可能です。NotifyIcon

そこで、Windowsの経験が豊富な友人の助けを借りて、Win32APIを介してこれを試してみました。アイデアは、トレイウィンドウハンドラーにフックを登録することでした(DragAcceptFiles(hWnd,TRUE);「SysPager」ウィンドウハンドラーで設定した後)。

フックアンドドロップ部分は、トレイからDLLまで機能しています。

LRESULT CALLBACK myHookProc (int code, WPARAM wParam, LPARAM lParam){
  if (code == HC_ACTION)
  {
    PMSG msg = (PMSG) lParam;
    switch(msg->message){
      case WM_DROPFILES:
        ::MessageBox(NULL, L"Dropped files!", L"Test", MB_OK);
        // call my app's registered hook
        break;
  }
  return CallNextHookEx(oldHookProc, code, wParam, lParam);
}

予想通り、メッセージボックスがポップアップ表示されます。

問題は、このイベントを通知するために、C#(WindowsForms)アプリケーションで関数を呼び出す必要があることです。ここで私はレンガの壁に出くわしました。

アプリケーションからのコールバックをDLLに登録すると、それが保存されます。ただし、myHookProcが呼び出されると、その値はNULLになります。

DLLがどのように機能するかを誤解していたことがわかりました。私のアプリケーションとトレイ領域の間に共有インスタンスがないので(それらはコピーされているか、それを呼び出すことができればそれぞれが独自の「インスタンス」を持っています)、静的変数などを使用して保持することはできませんアプリケーションへのコールバック参照。

これを調査するのに数時間を費やし、唯一の解決策は共有メモリのようです(#pragma data_seg私がいくつかのフォーラムで遭遇したが、役に立たなかった)が、そのような「単純な」ユースケースにはやり過ぎだと感じ始めます。

したがって、百万ドルの質問は次のとおりです。

  1. DLLへのフックをオフロードする必要が本当にありますか?
  2. これを達成するために、本当に共有メモリに頼る必要がありますか?
  3. (ボーナス質問)WM_DROPFILESはファイルに対してのみ機能します。テキストに対してドロップイベントを発生させるにはどうすればよいですか?

これは、.NET、C#、およびWin32を使用した最初のショットです(1週間未満)。理由を説明する詳細な回答は、単に述べるだけでなく、大いに感謝されます!

ありがとう。

4

1 に答える 1

3

はい、ウィンドウは別のプロセスによって所有されているため、実際にこれらのことを行う必要があります。グローバルフックには、挿入可能なDLLが必要です。D + Dを完全にサポートするには、RegisterDragDropとCOMコードが必要です。IckyCOMコード。

いいえ、他の誰かがあなたと同じ考えをすでに持っているかもしれないので、あなたは本当にこれをするべきではありません。そして彼のプログラムを最初に出荷しました。MSFTのappcompatチームには、悪夢が必要です。レイモンド・チェンに注意して、彼は悪い気性を持っています。

于 2010-10-13T18:41:04.787 に答える