アプリケーションのトレイアイコンへのドラッグアンドドロップを許可しようとしています。
ドラッグイベントをサポートしていないため、高レベルの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
私がいくつかのフォーラムで遭遇したが、役に立たなかった)が、そのような「単純な」ユースケースにはやり過ぎだと感じ始めます。
したがって、百万ドルの質問は次のとおりです。
- DLLへのフックをオフロードする必要が本当にありますか?
- これを達成するために、本当に共有メモリに頼る必要がありますか?
- (ボーナス質問)WM_DROPFILESはファイルに対してのみ機能します。テキストに対してドロップイベントを発生させるにはどうすればよいですか?
これは、.NET、C#、およびWin32を使用した最初のショットです(1週間未満)。理由を説明する詳細な回答は、単に述べるだけでなく、大いに感謝されます!
ありがとう。