SendMessage後のWin32LastError
WM_COPYDATAを扱うために、C#で以下のようなコードを書いているのだが最後のMarshal.GetLastWin32Error()の戻り値がが0x00000002とか0x00000005で戻るケースが発生していることに最近気が付いた。
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] private extern static int SendMessage( IntPtr hwnd, int wMsg, int wParam, ref COPYDATASTRUCT lParam ); [StructLayout(LayoutKind.Sequential)][Serializable] private struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; public IntPtr lpData; } private const int WM_COPYDATA = 0x4A; COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds.cbData = dataSize; cds.dwData = IntPtr.Zero; cds.lpData = マーシャルされたデータへのポインタ; int res = SendMessage(ターゲットウインドウのハンドル, WM_COPYDATA, 現在使用しているNativeWindowのハンドル, ref cds); int win32Err = Marshal.GetLastWin32Error();
ターゲットウインドウのハンドルはEnumWindowsで収集したハンドルのうちの一つ。
win32Errの0x00000002 と0x00000005 はそれぞれ
0x00000002 : 指定されたファイルが見つかりません。(ERROR_FILE_NOT_FOUND)
0x00000005 : アクセスが拒否されました。(ERROR_ACCESS_DENIED)
だが、発生するシチュエーションが解らない。エラーが発生した直後に同じハンドルにSendMessageすると今度はエラー0だったりするし。あと、後者はまだ解るが前者に関してはファイルが見つからないといわれてもなぁ。
追記:
試しに、SendMessageを行う前に対象のハンドルを持つ側のウインドウに対してSetForegroundWindowしてやると、上記エラーは消えたようだ。(ようだ、と書いたのはまだ再現していないだけかもしれないから)
WM_COPYDATAをSendMessageする前にはなんらかの条件が必要なのか、もしくは他のAPIを挿入したことでWin32LastErrorがリセットされたか、どちらかなのだろう。