I need to call some native C functions from C # using p / invoke. So far, I have had no problems marshaling various methods and structures in C #. Where my problem is that many of the methods I have to call are asynchronous and return their final results to my WinForms application via Windows messages. For example, I have a method call that has the following signature in C:
HRESULT AsyncOpenSession( LPSTR lpszLogicalName, HANDLE hApp, LPSTR lpszAppID, DWORD dwTraceLevel, DWORD dwTimeOut, USHORT lphService, HWND hWnd, DWORD dwSrvcVersionsRequired, LPWFSVERSION lpSrvcVersion, LPWFSVERSION lpSPIVersion, ULONG lpRequestID );
Where lpszAppID expects to receive the NAME of my application (MyApp.exe), and hWnd is a pointer to the HANDLE of the WINDOW window of my application, which I receive with a call
[DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); public static IntPtr GetCurrentWindowHandle() { IntPtr handle = GetForegroundWindow(); return handle; }
Imported Signature:
[DllImport("MSXFS.DLL", BestFitMapping = true, CharSet = CharSet.Auto, SetLastError = true)] private static extern int AsyncOpenSession([MarshalAs(UnmanagedType.LPStr)] string lpszLogicalName, IntPtr hApp, [MarshalAs(UnmanagedType.LPStr)] string lpszAppID, UInt32 dwTraceLevel, UInt32 dwTimeOut, out Int32 lphService, IntPtr hWnd, UInt32 dwSrvcVersionsRequired, out WFSVersion lpSrvcVersion, out WFSVersion lpSPIVersion, out Int32 lpRequestID);
I call the method as follows:
Int32 r = AsyncOpenSession(lpszLogicalName, appHanlder, "MyApp.exe", dwTraceLevel, dwTimeOut, out hServ, GetCurrentWindowHandle(), dwSrvcVersionsRequired, out srvcVersion, out spiVersion, out requestID);
Initially, a method call returns a result code that indicates that the requested call has been placed in the execution queue. At any time after the initial call, the native Dll terminates the request and sends a Windows message to the application using the Windows handle and name. The Windows message code for this method is defined as follows:
#define WM_USER 0x0400 #define OPEN_SESSION_COMPLETE (WM_USER + 1)
More information about Windows messages here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644931(v=vs.85).aspx
In my application, I overridden the WndProc method to be able to manage Windows messages as follows:
protected override void WndProc(ref Message m) { const int wm_user = 0x0400; const int OPEN_SESSION_COMPLETE = wm_user + 1; switch (m.Msg) { case OPEN_SESSION_COMPLETE: txtEventsState.Text = m.ToString(); break; } base.WndProc(ref m); }
But I never get a Windows message with this code. There are no errors in the logs or event viewer. I know that my method call succeeded because I do not have an error code, and because I need to open a session before calling other methods, and I can call other methods that need a session handler successfully (without an error code too).
My imported signature and method call are in the class library project that my application references. Am I something wrong here? Can anyone talk about what could happen? I donβt have access to my own code, itβs just a test application that shows that Windows messages are sent using native C Dll.
Thanks to everyone in advance.