Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Windows doesn't permit processes to snatch the foreground window unless the user starts them. This is to avoid things like persuading the user to type their bank details into the wrong window. However the current foreground process can pass permission to another process to do this. See <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms632668%28v=vs.85%29.aspx" rel="nofollow">AllowSetForegroundWindow</a> for the details. To do this you have to provide the process id for the process that will become foreground and ShellExecute doesn't provide that. However, if you switch to using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154%28v=vs.85%29.aspx" rel="nofollow">ShellExecuteEx</a> you can get this from the hProcess member on the SHELLEXECUTEINFO structure.</p> <p>You can then call <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539%28v=vs.85%29.aspx" rel="nofollow">SetForegroundWindow</a> in your new process and it will be permitted. Otherwise it just starts flashing on the taskbar.</p> <p><strong>EDIT</strong></p> <p>If your initial application is the foreground application and you start a subprocess from that then the subprocess should automatically become foreground as described in the documentation for these functions.</p> <p>Below is an example of how we can choose to enable and set another application to become the foreground window. In this case it just creates a text file and calls ShellExecuteEx with the <code>open</code> verb. We have to wait for the child process to get going and to have its window prepared and then we can locate the window from the process ID and give it permissions and set its window to be foreground. In this case the launched notepad (or whatever is your "open" verb for .txt files) will be foreground anyway. If you separately run a notepad process and substiture in the process ID for that process where we normally put in the child process ID then we can make <em>another</em> process become foreground -- one that is not part of our process tree. This can be compiled using Visual C++ with <code>cl -nologo -W3 -O2 -MD fg_test.cpp</code> to produce an fg_test.exe.</p> <pre><code>#define STRICT #define WIN32_LEAN_AND_MEAN #include &lt;windows.h&gt; #include &lt;stdio.h&gt; #include &lt;tchar.h&gt; #include &lt;shellapi.h&gt; #pragma comment(lib, "shell32") #pragma comment(lib, "user32") static void PrintError(LPCTSTR szPrefix, DWORD dwError); static BOOL CALLBACK OnGetWindowByProcess(HWND hwnd, LPARAM lParam); typedef struct { DWORD pid; HWND hwnd; } WINDOWPROCESSINFO; int _tmain(int argc, TCHAR *argv[]) { SHELLEXECUTEINFO sxi = {0}; sxi.cbSize = sizeof(sxi); sxi.nShow = SW_SHOWNORMAL; FILE *fp = NULL; _tfopen_s(&amp;fp, _T("junk.txt"), _T("wt")); _fputts(_T("Example text file\n"), fp); fclose(fp); sxi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_WAITFORINPUTIDLE; sxi.lpVerb = _T("open"); sxi.lpFile = _T("junk.txt"); if (!ShellExecuteEx(&amp;sxi)) PrintError(_T("ShellExecuteEx"), GetLastError()); else { WINDOWPROCESSINFO info; info.pid = GetProcessId(sxi.hProcess); // SPECIFY PID info.hwnd = 0; AllowSetForegroundWindow(info.pid); EnumWindows(OnGetWindowByProcess, (LPARAM)&amp;info); if (info.hwnd != 0) { SetForegroundWindow(info.hwnd); SetActiveWindow(info.hwnd); } CloseHandle(sxi.hProcess); } return 0; } static BOOL CALLBACK OnGetWindowByProcess(HWND hwnd, LPARAM lParam) { WINDOWPROCESSINFO *infoPtr = (WINDOWPROCESSINFO *)lParam; DWORD check = 0; BOOL br = TRUE; GetWindowThreadProcessId(hwnd, &amp;check); _tprintf(_T("%x %x %x\n"), hwnd, check, infoPtr-&gt;pid); if (check == infoPtr-&gt;pid) { _tprintf(_T("found window %x for process id %x\n"), hwnd, check); infoPtr-&gt;hwnd = hwnd; br = FALSE; } return br; } static void PrintError(LPCTSTR szPrefix, DWORD dwError) { LPTSTR lpsz = NULL; DWORD cch = 0; cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, LANG_NEUTRAL, (LPTSTR)&amp;lpsz, 0, NULL); if (cch &lt; 1) { cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, _T("Code 0x%1!08x!"), 0, LANG_NEUTRAL, (LPTSTR)&amp;lpsz, 0, (va_list*)&amp;dwError); } _ftprintf(stderr, _T("%s: %s"), szPrefix, lpsz); LocalFree((HLOCAL)lpsz); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload