IOleWindow not working properly for IFileDialog?












0















I'm working with some code that uses Microsoft.WindowsAPICodePack to provide a C# wrapper of the Vista-style common dialogs (IFileOpenDialog, IFileSaveDialog). I'm wanting to add validation of the selected item in the OnFileOk event callback, and this is mostly working, but one aspect of it is to extract the HWND of the dialog to use as a parent for the message box that is shown. Microsoft provides documentation on how to do this:




The calling process can use the window handle of the dialog itself as the parent of the UI. That handle can be obtained by first calling IOleWindow::QueryInterface and then calling IOleWindow::GetWindow with the handle as shown in this example.




(https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx)



I added a definition of the IOleWindow interface to the code:



[ComImport,
Guid(ShellIIDGuid.IOleWindow),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleWindow
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ContextSensitiveHelp(
[In] bool fEnterMode);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetWindow();
}

...

internal const string IOleWindow = "00000114-0000-0000-C000-000000000046";


When I cast the IFileDialog passed into OnFileOk to IOleWindow (I haven't done that much work with COM interop recently, but this wraps a call to QueryInterface in the underlying COM world, right?), no error occurs and the IOleWindow reference is not null. But, when I call GetWindow, it seems to always return IntPtr.Zero. I have tried declaring the method with an out parameter instead of a return value, and get the same result: no error, but always IntPtr.Zero.



Does anybody see what I'm doing wrong?? Am I doing nothing wrong, but just sometimes you can't get a window handle??










share|improve this question


















  • 1





    A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.

    – Hans Passant
    Nov 20 '18 at 23:23











  • Thanks very much! Trying it now.

    – Jonathan Gilbert
    Nov 20 '18 at 23:25











  • As I'm sure you already knew, that was the problem exactly. If you feel like submitting an answer, even as little as "The order of methods in a COM interface is important, and the order in your IOleWindow declaration is wrong", I'll be happy to mark it as the answer. :-)

    – Jonathan Gilbert
    Nov 21 '18 at 0:06
















0















I'm working with some code that uses Microsoft.WindowsAPICodePack to provide a C# wrapper of the Vista-style common dialogs (IFileOpenDialog, IFileSaveDialog). I'm wanting to add validation of the selected item in the OnFileOk event callback, and this is mostly working, but one aspect of it is to extract the HWND of the dialog to use as a parent for the message box that is shown. Microsoft provides documentation on how to do this:




The calling process can use the window handle of the dialog itself as the parent of the UI. That handle can be obtained by first calling IOleWindow::QueryInterface and then calling IOleWindow::GetWindow with the handle as shown in this example.




(https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx)



I added a definition of the IOleWindow interface to the code:



[ComImport,
Guid(ShellIIDGuid.IOleWindow),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleWindow
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ContextSensitiveHelp(
[In] bool fEnterMode);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetWindow();
}

...

internal const string IOleWindow = "00000114-0000-0000-C000-000000000046";


When I cast the IFileDialog passed into OnFileOk to IOleWindow (I haven't done that much work with COM interop recently, but this wraps a call to QueryInterface in the underlying COM world, right?), no error occurs and the IOleWindow reference is not null. But, when I call GetWindow, it seems to always return IntPtr.Zero. I have tried declaring the method with an out parameter instead of a return value, and get the same result: no error, but always IntPtr.Zero.



Does anybody see what I'm doing wrong?? Am I doing nothing wrong, but just sometimes you can't get a window handle??










share|improve this question


















  • 1





    A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.

    – Hans Passant
    Nov 20 '18 at 23:23











  • Thanks very much! Trying it now.

    – Jonathan Gilbert
    Nov 20 '18 at 23:25











  • As I'm sure you already knew, that was the problem exactly. If you feel like submitting an answer, even as little as "The order of methods in a COM interface is important, and the order in your IOleWindow declaration is wrong", I'll be happy to mark it as the answer. :-)

    – Jonathan Gilbert
    Nov 21 '18 at 0:06














0












0








0








I'm working with some code that uses Microsoft.WindowsAPICodePack to provide a C# wrapper of the Vista-style common dialogs (IFileOpenDialog, IFileSaveDialog). I'm wanting to add validation of the selected item in the OnFileOk event callback, and this is mostly working, but one aspect of it is to extract the HWND of the dialog to use as a parent for the message box that is shown. Microsoft provides documentation on how to do this:




The calling process can use the window handle of the dialog itself as the parent of the UI. That handle can be obtained by first calling IOleWindow::QueryInterface and then calling IOleWindow::GetWindow with the handle as shown in this example.




(https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx)



I added a definition of the IOleWindow interface to the code:



[ComImport,
Guid(ShellIIDGuid.IOleWindow),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleWindow
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ContextSensitiveHelp(
[In] bool fEnterMode);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetWindow();
}

...

internal const string IOleWindow = "00000114-0000-0000-C000-000000000046";


When I cast the IFileDialog passed into OnFileOk to IOleWindow (I haven't done that much work with COM interop recently, but this wraps a call to QueryInterface in the underlying COM world, right?), no error occurs and the IOleWindow reference is not null. But, when I call GetWindow, it seems to always return IntPtr.Zero. I have tried declaring the method with an out parameter instead of a return value, and get the same result: no error, but always IntPtr.Zero.



Does anybody see what I'm doing wrong?? Am I doing nothing wrong, but just sometimes you can't get a window handle??










share|improve this question














I'm working with some code that uses Microsoft.WindowsAPICodePack to provide a C# wrapper of the Vista-style common dialogs (IFileOpenDialog, IFileSaveDialog). I'm wanting to add validation of the selected item in the OnFileOk event callback, and this is mostly working, but one aspect of it is to extract the HWND of the dialog to use as a parent for the message box that is shown. Microsoft provides documentation on how to do this:




The calling process can use the window handle of the dialog itself as the parent of the UI. That handle can be obtained by first calling IOleWindow::QueryInterface and then calling IOleWindow::GetWindow with the handle as shown in this example.




(https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx)



I added a definition of the IOleWindow interface to the code:



[ComImport,
Guid(ShellIIDGuid.IOleWindow),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleWindow
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ContextSensitiveHelp(
[In] bool fEnterMode);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetWindow();
}

...

internal const string IOleWindow = "00000114-0000-0000-C000-000000000046";


When I cast the IFileDialog passed into OnFileOk to IOleWindow (I haven't done that much work with COM interop recently, but this wraps a call to QueryInterface in the underlying COM world, right?), no error occurs and the IOleWindow reference is not null. But, when I call GetWindow, it seems to always return IntPtr.Zero. I have tried declaring the method with an out parameter instead of a return value, and get the same result: no error, but always IntPtr.Zero.



Does anybody see what I'm doing wrong?? Am I doing nothing wrong, but just sometimes you can't get a window handle??







c# com common-dialog






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 22:20









Jonathan GilbertJonathan Gilbert

2,5571320




2,5571320








  • 1





    A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.

    – Hans Passant
    Nov 20 '18 at 23:23











  • Thanks very much! Trying it now.

    – Jonathan Gilbert
    Nov 20 '18 at 23:25











  • As I'm sure you already knew, that was the problem exactly. If you feel like submitting an answer, even as little as "The order of methods in a COM interface is important, and the order in your IOleWindow declaration is wrong", I'll be happy to mark it as the answer. :-)

    – Jonathan Gilbert
    Nov 21 '18 at 0:06














  • 1





    A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.

    – Hans Passant
    Nov 20 '18 at 23:23











  • Thanks very much! Trying it now.

    – Jonathan Gilbert
    Nov 20 '18 at 23:25











  • As I'm sure you already knew, that was the problem exactly. If you feel like submitting an answer, even as little as "The order of methods in a COM interface is important, and the order in your IOleWindow declaration is wrong", I'll be happy to mark it as the answer. :-)

    – Jonathan Gilbert
    Nov 21 '18 at 0:06








1




1





A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.

– Hans Passant
Nov 20 '18 at 23:23





A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.

– Hans Passant
Nov 20 '18 at 23:23













Thanks very much! Trying it now.

– Jonathan Gilbert
Nov 20 '18 at 23:25





Thanks very much! Trying it now.

– Jonathan Gilbert
Nov 20 '18 at 23:25













As I'm sure you already knew, that was the problem exactly. If you feel like submitting an answer, even as little as "The order of methods in a COM interface is important, and the order in your IOleWindow declaration is wrong", I'll be happy to mark it as the answer. :-)

– Jonathan Gilbert
Nov 21 '18 at 0:06





As I'm sure you already knew, that was the problem exactly. If you feel like submitting an answer, even as little as "The order of methods in a COM interface is important, and the order in your IOleWindow declaration is wrong", I'll be happy to mark it as the answer. :-)

– Jonathan Gilbert
Nov 21 '18 at 0:06












1 Answer
1






active

oldest

votes


















0














@Hans Passant's reply was on the nose. The order of methods in a COM interface is important, and I had the order wrong, simple as that. I got the order from documentation that was sorted alphabetically, and not from the actual IDL. :-P



Wrong order, for human eyes only:




  • https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nn-oleidl-iolewindow


Right order, the actual IDL:




  • https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/OleIdl.Idl#L577-L592


(I don't know who @tpn on GitHub is, this link may break but if it does then just look up IOleWindow in the file OleIdl.idl from the Windows SDK. :-) )






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53402466%2fiolewindow-not-working-properly-for-ifiledialog%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    @Hans Passant's reply was on the nose. The order of methods in a COM interface is important, and I had the order wrong, simple as that. I got the order from documentation that was sorted alphabetically, and not from the actual IDL. :-P



    Wrong order, for human eyes only:




    • https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nn-oleidl-iolewindow


    Right order, the actual IDL:




    • https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/OleIdl.Idl#L577-L592


    (I don't know who @tpn on GitHub is, this link may break but if it does then just look up IOleWindow in the file OleIdl.idl from the Windows SDK. :-) )






    share|improve this answer




























      0














      @Hans Passant's reply was on the nose. The order of methods in a COM interface is important, and I had the order wrong, simple as that. I got the order from documentation that was sorted alphabetically, and not from the actual IDL. :-P



      Wrong order, for human eyes only:




      • https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nn-oleidl-iolewindow


      Right order, the actual IDL:




      • https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/OleIdl.Idl#L577-L592


      (I don't know who @tpn on GitHub is, this link may break but if it does then just look up IOleWindow in the file OleIdl.idl from the Windows SDK. :-) )






      share|improve this answer


























        0












        0








        0







        @Hans Passant's reply was on the nose. The order of methods in a COM interface is important, and I had the order wrong, simple as that. I got the order from documentation that was sorted alphabetically, and not from the actual IDL. :-P



        Wrong order, for human eyes only:




        • https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nn-oleidl-iolewindow


        Right order, the actual IDL:




        • https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/OleIdl.Idl#L577-L592


        (I don't know who @tpn on GitHub is, this link may break but if it does then just look up IOleWindow in the file OleIdl.idl from the Windows SDK. :-) )






        share|improve this answer













        @Hans Passant's reply was on the nose. The order of methods in a COM interface is important, and I had the order wrong, simple as that. I got the order from documentation that was sorted alphabetically, and not from the actual IDL. :-P



        Wrong order, for human eyes only:




        • https://docs.microsoft.com/en-us/windows/desktop/api/oleidl/nn-oleidl-iolewindow


        Right order, the actual IDL:




        • https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/OleIdl.Idl#L577-L592


        (I don't know who @tpn on GitHub is, this link may break but if it does then just look up IOleWindow in the file OleIdl.idl from the Windows SDK. :-) )







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 7 at 19:56









        Jonathan GilbertJonathan Gilbert

        2,5571320




        2,5571320






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53402466%2fiolewindow-not-working-properly-for-ifiledialog%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith