2

I'm working on Windows 8 and I want to try to disable the default edge gesture behaviors when my desktop app is fullscreen.

I've found this page which explains how to do it in C++.

My app is a WPF/C# application and I've found the Windows Code API Pack and the SetWindowProperty method to to the job.

Problem

I don't know how to pass the right parameter, which is a boolean :

PropertyKey key = new PropertyKey("32CE38B2-2C9A-41B1-9BC5-B3784394AA44", 2); WindowProperties.SetWindowProperty(this, key, "true");

PropertyKey key = new PropertyKey("32CE38B2-2C9A-41B1-9BC5-B3784394AA44", 2); WindowProperties.SetWindowProperty(this, key, "-1");

PropertyKey key = new PropertyKey("32CE38B2-2C9A-41B1-9BC5-B3784394AA44", 2); WindowProperties.SetWindowProperty(this, key, "VARIANT_TRUE");

As you can see, the parameter has to be a string but no one works.

If someone has an idea, thanks in advance !

Max
  • 1,810
  • 3
  • 26
  • 37

3 Answers3

2

An easier solution would be using Windows API Code Pack.

The code setting System.AppUserModel.PreventPinning property would be as easy as:

public static void PreventPinning(Window window)
{
    var preventPinningProperty = new PropertyKey(new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"), 9);
    WindowProperties.SetWindowProperty(window, preventPinningProperty, "1");
}
Vitaliy Ulantikov
  • 10,157
  • 3
  • 61
  • 54
0

If you look at the original signature, the function needs an IntPtr handle, a Guid id and an PropertyStore object that will be populated by the data.

HRESULT SHGetPropertyStoreForWindow(
  _In_   HWND hwnd,
  _In_   REFIID riid,
  _Out_  void **ppv
);

Translating this into c# would look like this:

[DllImport("shell32.dll", SetLastError = true)]
 static extern int SHGetPropertyStoreForWindow(
        IntPtr handle,
        ref Guid riid,
        out IPropertyStore propertyStore);

And you can grab the IPropertyStore interface from PInvoke.net:

[ComImport, Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IPropertyStore
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetCount([Out] out uint cProps);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetAt([In] uint iProp, out PropertyKey pkey);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void GetValue([In] ref PropertyKey key, out object pv);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void SetValue([In] ref PropertyKey key, [In] ref object pv);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void Commit();
    }

The only thing left is to actually implement the PropertyStore. Similar implementations in the .net framework can be found in e.g. PrintSystemObject.

After implementing this you should be able to simply call the method and set the property:

IPropertyStore store = new PropertyStore(); 

//your propery id in guid
var g = new Guid("32CE38B2-2C9A-41B1-9BC5-B3784394AA44");
SHGetPropertyStoreForWindow(this.Handle, ref g, out store);
dsfgsho
  • 2,731
  • 2
  • 22
  • 39
  • Thanks for your answer ! I've implemented the PropertyStore (thanks to a Dictionary). I've used your last three lines in my MainWindow.xaml.cs (so this.Handle became new WindowInteropHelper(this).Handle). But the store returned by SHGetPropertyStoreForWindow is null whereas my three parameters aren't... Any idea ? – Max May 29 '13 at 15:22
  • You can start by capturing the return value of the function and comparing that to common results: `int result = SHGetPropertyStoreForWindow(this.Handle, ref g, out store);` And compare that to common [HRESULTS](http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137(v=vs.85).aspx) – dsfgsho May 29 '13 at 15:41
  • The result is -2147024809, "Invalid argument". My handle is always 0, maybe it comes from it. – Max May 29 '13 at 15:47
  • Ah right, the example code is still for old winforms. For wpf you need: `IntPtr windowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;` – dsfgsho May 29 '13 at 15:51
  • Yeah I've already tried it. I've moved my code in the "Loaded" event of my window and I haven't this error anymore. But I have a new one, "No such interface supported" :) – Max May 29 '13 at 16:02
  • Ah, this seems a problem with the implementation of the Interface (which is a different problem:)). Check this Q&A on ["C# wrapper interface error: E_NOINTERFACE"](http://stackoverflow.com/questions/935768/c-sharp-wrapper-interface-error-e-nointerface) – dsfgsho May 29 '13 at 16:29
  • @Max, can you provide any direction on your implementation of the PropertyStore class. Not sure where to go with this one. – Tim Friesen Mar 28 '14 at 17:02
  • 1
    The `IPropertyStore store = new PropertyStore();` is unnecessary because the variable is overwritten by the out-parameter anyways, as such implementing the interface yourself is unnecessary as well. -- the whole point of the API is to get access to the Windows property store, not writing your own. – Zarat Dec 21 '16 at 22:22
0

I don't know how to pass the right parameter, which is a boolean. As you can see, the parameter has to be a string but no one works.

Pass the string "1" for true, or "0" for false.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742