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 at 23:23










  • Thanks very much! Trying it now.
    – Jonathan Gilbert
    Nov 20 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 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 at 23:23










  • Thanks very much! Trying it now.
    – Jonathan Gilbert
    Nov 20 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 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 at 22:20









Jonathan Gilbert

2,5491320




2,5491320








  • 1




    A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.
    – Hans Passant
    Nov 20 at 23:23










  • Thanks very much! Trying it now.
    – Jonathan Gilbert
    Nov 20 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 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 at 23:23










  • Thanks very much! Trying it now.
    – Jonathan Gilbert
    Nov 20 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 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 at 23:23




A usable IOleWindow declaration is available here. Getting the methods is the wrong order is quite fatal.
– Hans Passant
Nov 20 at 23:23












Thanks very much! Trying it now.
– Jonathan Gilbert
Nov 20 at 23:25




Thanks very much! Trying it now.
– Jonathan Gilbert
Nov 20 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 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 at 0:06

















active

oldest

votes











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






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















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.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • 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

Wiesbaden

Marschland

Dieringhausen