7 Replies - 1064 Views - Last Post: 03 November 2012 - 01:13 PM Rate Topic: -----

#1 darkmaster_101  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-November 12

Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 10:02 AM

I am having problems implementing the IDesktopWallpaper com interface which is part of the Windows 8 SDK

I managed to convert the Shobjidl.h file to a .tlb file, which when viewed in Microsoft's OLE viewer gives me this

[
  uuid(C2CF3110-460E-4FC1-B9D0-8A1C0C9CC4BD)
]
coclass DesktopWallpaper {
    [default] interface IDesktopWallpaper;
};



and

[
  odl,
  uuid(B92B56A9-8B55-4E14-9A89-0199BBB6F93B)
]
interface IDesktopWallpaper : IUnknown {
    HRESULT _stdcall SetWallpaper(
                    [in] LPWSTR monitorID, 
                    [in] LPWSTR wallpaper);
    HRESULT _stdcall GetWallpaper(
                    [in] LPWSTR monitorID, 
                    [out] LPWSTR* wallpaper);
    HRESULT _stdcall GetMonitorDevicePathAt(
                    [in] unsigned int monitorIndex, 
                    [out] LPWSTR* monitorID);
    HRESULT _stdcall GetMonitorDevicePathCount([out] unsigned int* count);
    HRESULT _stdcall GetMonitorRECT(
                    [in] LPWSTR monitorID, 
                    [out] tagRECT* displayRect);
    HRESULT _stdcall SetBackgroundColor([in] unsigned long color);
    HRESULT _stdcall GetBackgroundColor([out] unsigned long* color);
    HRESULT _stdcall SetPosition([in] DESKTOP_WALLPAPER_POSITION position);
    HRESULT _stdcall GetPosition([out] DESKTOP_WALLPAPER_POSITION* position);
    HRESULT _stdcall SetSlideshow([in] IShellItemArray* items);
    HRESULT _stdcall GetSlideshow([out] IShellItemArray** items);
    HRESULT _stdcall SetSlideshowOptions(
                    [in] DESKTOP_SLIDESHOW_OPTIONS options, 
                    [in] unsigned int slideshowTick);
    HRESULT _stdcall GetSlideshowOptions(
                    [out] DESKTOP_SLIDESHOW_OPTIONS* options, 
                    [out] unsigned int* slideshowTick);
    HRESULT _stdcall AdvanceSlideshow(
                    [in] LPWSTR monitorID, 
                    [in] DESKTOP_SLIDESHOW_DIRECTION direction);
    HRESULT _stdcall GetStatus([out] DESKTOP_SLIDESHOW_STATE* state);
    HRESULT _stdcall Enable([in] long Enable);
};



I have converted what I think the code should be and got this

[ComImport, Guid("C2CF3110-460E-4fc1-B9D0-8A1C0C9CC4BD")]
    class IDesktopWallpaper
    {
        
    }

    // Declare IMediaControl as a COM interface which 
    // derives from the IDispatch interface. 
           
    [Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B"), //B92B56A9-8B55-4E14-9A89-0199BBB6F93B
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] //try InterfaceIsDual if needed
    interface DesktopWallpaperInterface
    {
        // Note that the members of IUnknown and Interface are NOT
        // listed here 
        //

        void AdvanceSlideshow(
  [In]  string monitorID,
  [In]  DESKTOP_SLIDESHOW_DIRECTION direction);

        void Enable(out bool enable); /*use "out" or get AccessViolationException */

        void GetBackgroundColor([Out]  COLORREF color);

        void GetMonitorDevicePathAt([In] int monitorIndex, [Out]  string monitorID); //might be IntPtr?

        void GetMonitorDevicePathCount(out uint count);
    
        void GetMonitorRECT([In] string monitorID, [Out]  RECT displayRect);

        void GetPosition([Out] DESKTOP_WALLPAPER_POSITION position);

        void GetSlideshow([Out] object items);
        /*void GetSlideshow([Out]  IShellItemArray items); */

        void GetSlideshowOptions([Out]  DESKTOP_SLIDESHOW_OPTIONS options, [Out]  uint slideshowTick);

        void GetStatus([Out]  DESKTOP_SLIDESHOW_STATE state);

        void GetWallpaper([In] string monitorID, [Out]  string wallpaper);

        void SetBackgroundColor([In] COLORREF color);

        void SetPosition([In]  DESKTOP_WALLPAPER_POSITION position);

        void SetSlideshow([In]  object items);
        /* void  SetSlideshow([In]  IShellItemArray items); */

        void SetSlideshowOptions([In]  DESKTOP_SLIDESHOW_OPTIONS options, [In]  uint slideshowTick);

        void SetWallpaper([In] string monitorID, [In] string wallpaper);

    }

    [StructLayout(LayoutKind.Sequential)]
    struct RECT
    {
        public int left, top, right, bottom;
    }

    public enum SIGDN : uint
    {
        NORMALDISPLAY = 0,
        PARENTRELATIVEPARSING = 0x80018001,
        PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
        DESKTOPABSOLUTEPARSING = 0x80028000,
        PARENTRELATIVEEDITING = 0x80031001,
        DESKTOPABSOLUTEEDITING = 0x8004c000,
        FILESYSPATH = 0x80058000,
        URL = 0x80068000
    }


     [Flags]
    public enum DESKTOP_SLIDESHOW_DIRECTION : int
    {
        DSD_FORWARD = 0,
        DSD_BACKWARD = 1
    }

     [Flags]
    public enum DESKTOP_WALLPAPER_POSITION : int
    {
        DWPOS_CENTER = 0,
        DWPOS_TILE = 1,
        DWPOS_STRETCH = 2,
        DWPOS_FIT = 3,
        DWPOS_FILL = 4,
        DWPOS_SPAN = 5
    }

     [Flags]
    public enum DESKTOP_SLIDESHOW_OPTIONS : int
    {
        DSO_SHUFFLEIMAGES = 0x1
    }


     [Flags]
    public enum DESKTOP_SLIDESHOW_STATE : int
    {
        DSS_ENABLED = 0x1,
        DSS_SLIDESHOW = 0x2,
        DSS_DISABLED_BY_REMOTE_SESSION = 0x4
    }

    [StructLayout(LayoutKind.Sequential)]
    struct COLORREF
    {
        public byte R;
        public byte G;
        public byte B;
    }



Right now I'm interested in getting the following methods working:

Enable(..)
SetWallpaper(..)
GetMonitorDevicePathCount(..)

This is the code I am using to try and get this to work

 IDesktopWallpaper dw = new IDesktopWallpaper();
 DesktopWallpaperInterface wallpaper = (DesktopWallpaperInterface)dw;

 bool enable = true;
 wallpaper.Enable(out enable);

 string wallp = @"PATH_TO_IMAGE_FILE";

 string empty = String.Empty;

 wallpaper.SetWallpaper(null, wallp); /*sets the wallpaper to a random colour */

 uint monitorCount =0;
 wallpaper.GetMonitorDevicePathCount(out monitorCount); /*causes ArgumentException*/




GetMonitorDevicePathCount gives me an ArgumentException
But so does changing the interface to int, IntPtr, UintPointer and Uint32

If I change the line
wallpaper.SetWallpaper(null, wallp);
to
wallpaper.SetWallpaper(empty, wallp);

then the screen is not changed to a random colour, but the wallpaper is not changed

I am really struggling to get this to work, does anyone have any ideas on what could be going wrong?

Am am using Windows 8 x64 in Visual Studio 2010 compiling a .Net 3.5 target framework as a Windows Application
The current build settings are for Debug Any CPU
However I have tried using x86 and x64 both produce the same result.

It's got to the point where I'm going to take just about any advice you have for me now, I just want to get this to work.

If you want any more information please just ask

Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: Problems implementing IDesktopWallpaper com interface

#2 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5537
  • View blog
  • Posts: 11,866
  • Joined: 02-June 10

Re: Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 10:19 AM

Quote

I am having problems implementing the IDesktopWallpaper com interface which is part of the Windows 8 SDK
...

I am using Windows 8 x64 in Visual Studio 2010 compiling a .Net 3.5 target framework as a Windows Application


Just a thought... Try using a set of technology all designed to work together. You're trying to use an interface for Win8, in a version of VS and .NET that pre-dates Win8.

Just as a test, why do you try using VS 2012 and .NET 4.5, both of which are meant for Win8 and see if you continue to have the same problem.

Otherwise it sounds a lot like: I'm having trouble getting a color picture on my 1950's black and white TV, even though I'm feeding a color signal from my cable box.

This post has been edited by tlhIn`toq: 03 November 2012 - 10:20 AM

Was This Post Helpful? 0
  • +
  • -

#3 darkmaster_101  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-November 12

Re: Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 10:53 AM

Well I took your advice and installed Visual Studio 2012 Express for Desktop
Using VS 2012 and the .Net framework 4.5 and I am still getting the same results.

However I will follow your advice and continue use VS 2012 for this project because as you point out, it was designed to use Windows 8.

Thanks

This post has been edited by tlhIn`toq: 03 November 2012 - 11:28 AM
Reason for edit:: No need to quote the entire previous post: We all see it

Was This Post Helpful? 0
  • +
  • -

#4 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5537
  • View blog
  • Posts: 11,866
  • Joined: 02-June 10

Re: Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 11:33 AM

Sorry that didn't help. But it did eliminate an entire set of possibilities.

You have this
13 uint monitorCount =0;  
14 wallpaper.GetMonitorDevicePathCount(out monitorCount); /*causes ArgumentException*/ 


But the documentation show this (for C++):
HRESULT GetMonitorDevicePathCount(  [out]  UINT *count);



Notice how you are supplying a uint where the documentation is showing a pointer to a unit.
Was This Post Helpful? 0
  • +
  • -

#5 darkmaster_101  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-November 12

Re: Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 11:46 AM

View Postdarkmaster_101, on 03 November 2012 - 10:02 AM, said:

GetMonitorDevicePathCount gives me an ArgumentException
But so does changing the interface to int, IntPtr, UintPointer and Uint32



View PosttlhIn`toq, on 03 November 2012 - 11:33 AM, said:

Sorry that didn't help. But it did eliminate an entire set of possibilities.

You have this
13 uint monitorCount =0;  
14 wallpaper.GetMonitorDevicePathCount(out monitorCount); /*causes ArgumentException*/ 


But [url=" documentation%5B/url] show this (for C++):
HRESULT GetMonitorDevicePathCount(  [out]  UINT *count);



Notice how you are supplying a uint where the documentation is showing a pointer to a unit.


I did notice (see my above quote)

I have tried again on VS2012 with uint*, int* IntPtr and UIntPtr all give me an AccessViolationException
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5537
  • View blog
  • Posts: 11,866
  • Joined: 02-June 10

Re: Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 12:08 PM

Are you trying to change the type on line 13, or the use of it on 14? You should be changing the use of it on 14
Was This Post Helpful? 0
  • +
  • -

#7 darkmaster_101  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-November 12

Re: Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 12:19 PM

View PosttlhIn`toq, on 03 November 2012 - 12:08 PM, said:

Are you trying to change the type on line 13, or the use of it on 14? You should be changing the use of it on 14


I change the Interface signature to match the type that I want
So if I was testing it using a uint pointer

 //interface code
 unsafe void GetMonitorDevicePathCount(out uint* count);

 //implementation code

 unsafe{
    uint zero = 0;
    uint* monitorCount = &zero;

    wallpaper.GetMonitorDevicePathCount(out monitorCount);
}



and if I was testing a UIntPtr
I would do
 //interface code
 void GetMonitorDevicePathCount(out UIntPtr count);

//implementation code
 UIntPtr monitorCount = new UIntPtr(0);
 wallpaper.GetMonitorDevicePathCount(out monitorCount);




If this isn't what you mean, could you please provide an example?
Was This Post Helpful? 0
  • +
  • -

#8 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5537
  • View blog
  • Posts: 11,866
  • Joined: 02-June 10

Re: Problems implementing IDesktopWallpaper com interface

Posted 03 November 2012 - 01:13 PM

I was guessing taking this:

13 uint monitorCount =0;  
14 wallpaper.GetMonitorDevicePathCount(out monitorCount); /*causes  



And just using the address (a pointer) to monitorCount

13 uint monitorCount =0;  
14 wallpaper.GetMonitorDevicePathCount(out *monitorCount); //Note the * 


This post has been edited by tlhIn`toq: 03 November 2012 - 01:14 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1