I have three struct's:
[StructLayout(LayoutKind.Sequential)] internal struct COPYDATASTRUCT { public IntPtr dwData; // Specifies data to be passed public int cbData; // Specifies the data size in bytes public IntPtr lpData; // Pointer to data to be passed } public struct SHELLTRAYDATA { public UInt32 dwUnknown; public UInt32 dwMessage; public NID_XX nid; } public struct NID_XX { public UInt32 cbSize; public IntPtr hWnd; public uint uID; public uint uFlags; public uint uCallbackMessage; public IntPtr hIcon; } In my WndProc I do the following:
case WM_COPYDATA: { COPYDATASTRUCT cp = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT)); if(cp.dwData == SH_TRAY_DATA) { var shellTrayData = (SHELLTRAYDATA)Marshal.PtrToStructure(cp.lpData,typeof(SHELLTRAYDATA)); HandleNotification(shellTrayData); } } When my application is running on x86 it works fine. When I run it on x64 I don't get an hIcon and moreover the hWnd is invalid. When I target the application to x86 and run on x64 it works fine though. I know the problem lies in Marshalling. Do I have to manually Marshal the structure? Need help on this. I would prefer to have the same struct for both x64 and x86
EDIT:
The Unmanaged structures are as follows:
typedef struct tagCOPYDATASTRUCT { ULONG_PTR dwData; DWORD cbData; _Field_size_bytes_(cbData) PVOID lpData; } COPYDATASTRUCT, *PCOPYDATASTRUCT; // data sent by shell via Shell_NotifyIcon typedef struct _SHELLTRAYDATA { DWORD dwUnknown; DWORD dwMessage; NID_XX nid; } *PSHELLTRAYDATA; // sub structure common to all others typedef struct { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; } NID_XX, *PNID_XX; typedef const NID_XX * PCNID_XX; EDIT: Sizes of the structs are as follows:
Unmanaged:
- COPYDATASTRUCT: 12(X86) and 24(x64)
- SHELLTRAYDATA: 32(X86) and 48(X64)
- NID_XX: 24(X86) and 40(X64)
Managed:
- COPYDATASTRUCT: 12(X86) and 24(x64)
- SHELLTRAYDATA: 32(X86) and 48(X64)
- NID_XX: 24(X86) and 40(X64)
It's the same on both the sides.
IntPtrs with 32 bit integers, or the other way round. Compare the definition of these structs in C and C# and figure out the correct integer sizes using the table at Windows Data Types on MSDN. 2) Alignment differences are another potential problem, but shouldn't affect your case.WM_COPYDATAright? Do you have a 32 bit process sending a message to a 64 bit process? Or vice versa?