{"id":23383,"date":"2008-02-20T10:00:00","date_gmt":"2008-02-20T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/02\/20\/there-can-be-more-than-one-or-zero-converting-a-process-to-a-window\/"},"modified":"2008-02-20T10:00:00","modified_gmt":"2008-02-20T10:00:00","slug":"there-can-be-more-than-one-or-zero-converting-a-process-to-a-window","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080220-00\/?p=23383","title":{"rendered":"There can be more than one (or zero): Converting a process to a window"},"content":{"rendered":"<p>A common question I see is &#8220;How do I find the window that corresponds to an <code>HINSTANCE<\/code>?&#8221;\n This question comes pre-loaded with the assumption that there is only one window that corresponds to an <code>HINSTANCE<\/code>, which is true for only the most rudimentary of Win32 programs. Even a simple program like Notepad has more than one window with the same <code>HINSTANCE<\/code>, as Spy quickly reveals.\n But when I hear this question, I smell something suspicious. First, instance handles are meaningful only when you specify which process you&#8217;re referring to, since an instance handle in Win32 is the base address of a module, and different processes can have different DLLs loaded at the same base address (thanks to separate address spaces). Second, I can&#8217;t think of any normal scenarios where you&#8217;d even care about finding all the windows that have a particular instance handle, especially since <a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/04\/18\/409205.aspx\"> the instance handle is ignored if the window belongs to a global class<\/a>, and global classes are typically the only classes you are interested in anyway when you go snooping into another process. (After all, if it&#8217;s not your process, you don&#8217;t really know much of anything about its private classes.)\n But you probably already know that the person asking the question is asking the wrong question. They almost certainly launched a program with the <code>ShellExecute<\/code> function and now want to locate its window so they can do, um, <i>something<\/i> with it. But you already know that <a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/05\/05\/590749.aspx\"> you can&#8217;t do anything meaningful with the <code>HINSTANCE<\/code> returned by the <code>ShellExecute<\/code> function<\/a> <a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/11\/08\/1035971.aspx\"> aside from compare it against the number 32<\/a>, since it&#8217;s not really an instance handle on Win32. That the return value is of type <code>HINSTANCE<\/code> is just a carry-over from 16-bit Windows.\n But the person who asked the question never got that far in reading the documentation and just said, &#8220;Well, I&#8217;ve got an <code>HINSTANCE<\/code> and I need a window, so can somebody help me convert this <code>HINSTANCE<\/code> to a window?&#8221; without understanding what&#8217;s really going on. They need&nbsp;Y, but have&nbsp;X (a fake&nbsp;X, but still), so obviously the thing they need next is a way to convert your X to a Y.\n Even if it doesn&#8217;t make sense.\n It&#8217;s like asking for double-strength placebos.\n Okay, so you get past the initial disconnect of asking for the wrong thing. Say you have a process ID or a thread ID and you want to find the window for that process or thread.\n Again, there can be more than one, and there might be zero. If it&#8217;s a process you&#8217;re after, you can enumerate the windows on the desktop and use the <code>GetWindowThreadProcessId<\/code> function to determine what thread and process they belong to. If you are interested in the windows that belong to a thread, you can use the <code>EnumThreadWindows<\/code> function. Your next task is deciding which of those windows is the one you want.\n When you try to explain this to people, you sometimes get stuck in the <i>Why won&#8217;t you answer my question?<\/i> cycle.\n &#8220;I have a thread ID. How do I get the corresponding window?&#8221;\n <i>You can use the <code>EnumThreadWindows<\/code> function to get all the windows on the thread.<\/i>\n &#8220;Yes, I know about <code>EnumThreadWindows<\/code>, but how do I get the window that I want?&#8221;\n <i>Well, you haven&#8217;t said what you wanted yet.<\/i>\n &#8220;I want the window that corresponds to the thread.&#8221;\n <i>But which one? How will you decide among all the windows?<\/i>\n &#8220;That&#8217;s what I&#8217;m asking you!&#8221;\n <i>But you haven&#8217;t yet described what you want.<\/i>\n &#8220;I want the window corresponding to the thread. Why won&#8217;t you answer my question?&#8221;\n Note that saying, &#8220;I am looking for the top-level unowned window&#8221; is a step forward, but it still doesn&#8217;t uniquely identify a window. There can be multiple top-level unowned windows in a process. For example, Explorer typically has lots of top-level unowned windows. There&#8217;s the desktop, the taskbar, your open folder windows, and property sheets. If you ask for &#8220;the&#8221; top-level unowned window of Explorer, which one do you want?<\/p>\n<p> Perhaps people are getting the idea that there is a way to uniquely specify &#8220;the&#8221; window for a process because the <code>System.Diagnostics.Process<\/code> object has a property called <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/system.diagnostics.process.mainwindowhandle.aspx\"> <code>MainWindowHandle<\/code><\/a>. The documentation for that property doesn&#8217;t do anything to dispel the notion, either. I have no idea how that property decides among multiple top-level unowned windows. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>A common question I see is &#8220;How do I find the window that corresponds to an HINSTANCE?&#8221; This question comes pre-loaded with the assumption that there is only one window that corresponds to an HINSTANCE, which is true for only the most rudimentary of Win32 programs. Even a simple program like Notepad has more than [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-23383","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A common question I see is &#8220;How do I find the window that corresponds to an HINSTANCE?&#8221; This question comes pre-loaded with the assumption that there is only one window that corresponds to an HINSTANCE, which is true for only the most rudimentary of Win32 programs. Even a simple program like Notepad has more than [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/23383","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=23383"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/23383\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=23383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=23383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=23383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}