Reputation: 2124
I need to use the following C++ function in my WPF application:
/****************************************
* BOOL WINAPI SetWindowFeedbackSetting(
* _In_ HWND hwnd,
* _In_ FEEDBACK_TYPE feedback,
* _In_ DWORD dwFlags,
* _In_ UINT32 size,
* _In_opt_ const VOID *configuration
*);
*****************************************/
But I'm not sure how to Marshal it and how to PInvoke it. This is what I have so far:
public enum FEEDBACK_TYPE : uint {
FEEDBACK_TOUCH_CONTACTVISUALIZATION = 1,
FEEDBACK_PEN_BARRELVISUALIZATION = 2,
FEEDBACK_PEN_TAP = 3,
FEEDBACK_PEN_DOUBLETAP = 4,
FEEDBACK_PEN_PRESSANDHOLD = 5,
FEEDBACK_PEN_RIGHTTAP = 6,
FEEDBACK_TOUCH_TAP = 7,
FEEDBACK_TOUCH_DOUBLETAP = 8,
FEEDBACK_TOUCH_PRESSANDHOLD = 9,
FEEDBACK_TOUCH_RIGHTTAP = 10,
FEEDBACK_GESTURE_PRESSANDTAP = 11,
FEEDBACK_MAX = 0xFFFFFFFF
}
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] // (1)
public static extern bool SetWindowFeedbackSetting(
[In] IntPtr hwnd,
[In] FEEDBACK_TYPE feedback,
[In] uint dwFlags,
[In] uint size, // (2)
[In, Optional] IntPtr configuration // (3)
);
So first, is (1),(2),(3) correct?
Second, if I want to PInvoke this function according to this C++ function call:
BOOL fEnabled = FALSE;
BOOL res = SetWindowFeedbackSetting(
hwnd,
FEEDBACK_TOUCH_CONTACTVISUALIZATION,
0,
sizeof(fEnabled),
&fEnabled
);
What it the way to send the HWND and the boolean?
I'm asking this question to better understand the pinvoke\Marshal mechanism and also since the way I tried is not working.
Thanks
Upvotes: 0
Views: 1304
Reputation: 612963
Your translation is accurate. But personally, for convenience, I'd make one overload for each type you need to use. For a boolean:
[DllImport("user32.dll"])
public static extern bool SetWindowFeedbackSetting(
IntPtr hwnd,
FEEDBACK_TYPE feedback,
uint dwFlags,
uint size,
[In] ref bool configuration
);
I removed the attributes that were not needed because they restate default values.
Remember that the Win32 BOOL
type, the default marshalling option for C# bool
is a 4 byte type. So you must pass 4 as the size.
See this question to learn how to obtain a window handle for your WPF window: How to get the hWnd of Window instance?
Upvotes: 1
Reputation: 25927
From what I remember, P/Invoke mechanism has problems with passing/returning .NET's bool. I'd do:
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] // (1)
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWindowFeedbackSetting(
[In] IntPtr hwnd,
[In] FEEDBACK_TYPE feedback,
[In] uint dwFlags,
[In] uint size, // (2)
[In, Optional] IntPtr configuration // (3)
);
Then, you have to get HWND for current window in WPF. This question: How to get the hWnd of Window instance? should help in this matter.
For your convenience:
Window window = Window.GetWindow(this);
var wih = new WindowInteropHelper(window);
IntPtr hWnd = wih.Handle;
(credit goes to Drahcir)
Finally, to get address of the boolean, I'd do the following:
int myBool; // Win32's BOOL is actually an 4-byte integral number, 0 or non-zero
GCHandle handle = GCHandle.Alloc(myBool, GCHandleType.Pinned);
try
{
IntPtr ptr = handle.AddrOfPinnedObject();
// use ptr
}
finally
{
handle.Free();
}
Upvotes: 0