简体   繁体   中英

PInvoke WPF HWND and const void*

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

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?

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM