?
Solved

C++ console app - window on top

Posted on 2011-03-23
18
Medium Priority
?
640 Views
Last Modified: 2012-05-11
I have a C++ console app in VS2005 and from within the app, I make a call to run a standalone executable, and I really want this app to run in the background or minimized and not take focus away from my console app.  I have tried a bunch of different methods (See code below) to accomplish what I needed, but it seems to be a no-go.  The standalone executable seems to take focus away from my console app, or not starting minimized.  

Any help would be greatly appreciated.

Method 1:

system("C:\\StartEasySuite.bat");
Batch file contains: start /min c:\test\EasySuite.exe

Method 2:
WinExec("C:\\test\\EasySuite.exe",SW_FORCEMINIMIZE);

Method 3:

STARTUPINFO         siStartupInfo;
PROCESS_INFORMATION piProcessInfo;

memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
		
BOOL bSuccess;


bSuccess = CreateProcess(TEXT("C:\\Test\\EasySuite.exe"),    
                     0,						 
                     0,
                     0,
                     FALSE,
                     NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW ,
                     0,
                     0,                              
                     &siStartupInfo,
                     &piProcessInfo) ; 

Open in new window

0
Comment
Question by:arunykand
  • 9
  • 8
18 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 35200498
You're on the right track - make that
siStartupInfo.cb           =   sizeof(STARTUPINFO);
	siStartupInfo.dwFlags      =   STARTF_USESHOWWINDOW;
	siStartupInfo.wShowWindow  =   SW_HIDE;

Open in new window


Or use this shrink-wrapped function that does that for you and waits until the called app finishes:
DWORD ExecuteAndWaitForCompletion   (   LPSTR   pszCmd, BOOL bShow)
{
	STARTUPINFO         si;
	PROCESS_INFORMATION pi;

	BOOL                bRes;

	DWORD               dwCode  =   0;

	MSG				   msg;

	ZeroMemory  (   &si,    sizeof  (   STARTUPINFO));

	si.cb           =   sizeof  (   STARTUPINFO);
	si.dwFlags      =   STARTF_USESHOWWINDOW;
	si.wShowWindow  =   bShow ? SW_SHOWNORMAL : SW_HIDE;

	bRes    =   CreateProcess   (   NULL,
								   pszCmd,
								   NULL,
								   NULL,
								   TRUE,
								   NORMAL_PRIORITY_CLASS,
								   NULL,
								   NULL,
								   &si,
								   &pi
							   );

	while   (   WAIT_OBJECT_0   !=  MsgWaitForMultipleObjects   (   1,
																   &pi.hProcess,
																   FALSE,
																   INFINITE,
																   QS_ALLINPUT
															   )
		   )
		   {
			   while   (   PeekMessage (   &msg,   NULL,   0,  0,  PM_REMOVE))
					   {
						   DispatchMessage     (   &msg);
					   }
		   }

	GetExitCodeProcess  (   pi.hProcess,    &dwCode);

	CloseHandle (   pi.hProcess);
	CloseHandle (   pi.hThread);

	return  (   dwCode);
}

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 35200516
As a side note, 'SW_HIDE' is the key here. Oh, BTW, other alternatives would be
WinExec("C:\\test\\EasySuite.exe",SW_HIDE);

ShellExecute(NULL,"open","C:\\test\\EasySuite.exe",NULL,NULL,SW_HIDE);

Open in new window

0
 

Author Comment

by:arunykand
ID: 35201082
JKR....I'm still playing around with your suggestions..I cannot get any of them to work as expected, my window loses focus and the other software is shown, even when SW_HIDE is implemented.

FYI...my app is a full-screen console app (not GUI) that was created in c++ using 'CreateWindow', I didn't write this code, but in-herited.

g_hWnd = CreateWindow(WINDOW_CLASS_NAME, 0,
                         WS_VISIBLE |WS_POPUP | CS_DBLCLKS ,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT,
                         0, 0, g_hInstance, 0);

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 86

Expert Comment

by:jkr
ID: 35201108
That is more than weird. Can you double-check that with e.g. 'notepad.exe'?
0
 

Author Comment

by:arunykand
ID: 35201743
Hmm, I tried notepad, and works as intended.....

This software i'm trying to invoke from my app is called "EasySuite" from Targus.  It comes pre-loaded on their USB File Share cable http://http://www.staples.com/Targus-Data-SYNC-Cable/product_857875?cmArea=SC3:CG58:DP1426:CL164417  and it is supposed to 'Autorun' when inserted, but since auto-run was disabled on the PC due to security reasons, I thought I would invoke it, and have it minimized.  

Any ideas?
0
 
LVL 86

Expert Comment

by:jkr
ID: 35202929
Well, if an application choses not to obey the 'int nCmdShow' parameter passed in to 'WinMain()', there's hardly anything you can do other to complain that the program does not behave the way the Windows style guides require it. Another option would be (albeit the last resort) to start it on an invisible desktop...
0
 
LVL 86

Expert Comment

by:jkr
ID: 35202944
Ooops, another idea - try to set 'dwX' and/or 'dwY' in STARTUPINFO to positions outside your visible screen area and use 'STARTF_USEPOSITION' in 'dwFlags' - that could also work.
0
 

Author Comment

by:arunykand
ID: 35202966
Hmm...Ok i'm not sure how to proceed...My issue is, when this pc boots, it does an auto-login and starts up my software (full-screen, command window program), I've replaced the explorer shell with my software, so even if the user tries to exit, there will be no desktop, they just have to do a log-off or shutdown via ctrl-alt-del.  So to get back to my point, when my software is running in full screen mode, one of the options is to have this "EasySuite" software invoked, and run in the background, but as you can see, I haven't had much luck today!

0
 

Author Comment

by:arunykand
ID: 35202986
I just saw your comments about screen position, but I think the issue will be, I will still lose focus away from my app, but now I just won't be able to see the "EasySuite" software, still back to the same issue as before....
0
 
LVL 86

Expert Comment

by:jkr
ID: 35202989
>>I haven't had much luck today!

Don't say that, the 'invisible desktop' way will certainly work, but I'd certainly try the other way outlined in my last comment first ;o)
0
 

Author Comment

by:arunykand
ID: 35203000
Is it somehow possible to run the EasySuite software as a service....I'm out of ideas, just throwing it out there...
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 35203026
Well, then...
HWINSTA hWinStat = CreateWindowStation(_T("WinStatABC"), 0, 
      WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE,
      NULL);

   HDESK hDesk = CreateDesktop(
         _T("WinStatABC\\DeskABC"), NULL, NULL, 0,
         DESKTOP_ENUMERATE | DESKTOP_CREATEWINDOW, NULL);

   siStartupInfo.cb           =   sizeof(STARTUPINFO);
   siStartupInfo.lpDesktop    =   _T("WinStatABC\\DeskABC");
   siStartupInfo.dwFlags      =   STARTF_USESHOWWINDOW;
   siStartupInfo.wShowWindow  =   SW_HIDE;

Open in new window

0
 

Author Comment

by:arunykand
ID: 35203198
So going back to the position comment you made, 0 0 is top left right?  What do I need to put in to take it out of my screen?  

Jkr, I appreciate the help
0
 
LVL 86

Expert Comment

by:jkr
ID: 35203225
Yes, that's right - yet I assume the 'focus' issue would remain. I'd try something ridiculpusly high for testing purposes, e.g. ix you have 1600x1200, try to set

siStartupInfo.dwX = 3200;
siStartupInfo.dwY = 0;
0
 

Author Comment

by:arunykand
ID: 35203249
I will give that a shot first thing in the morning.  Fyi....I went out and bought a different brand of usb databtransfer cable with built in software and unfortunately the software is the same used by targus
0
 
LVL 8

Expert Comment

by:lomo74
ID: 35207054
>> FYI...my app is a full-screen console app (not GUI) that was created in c++ using 'CreateWindow', I didn't write this code, but in-herited.
I'm a bit confused. CreateWindow is called for GUI apps, not for console apps.
Do you mean your app looks like a terminal? (just like putty or the like)

Besides this, what about this idea:

1) launch child process
2) wait the creation of the main window
3) once created, hide the main window
4) maybe get focus back calling SetForegroundWindow

have a look at example - I used notepad just to test.
be careful: after execution you'll have a wandering hidden notepad window... :-)

#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdio.h>

BOOL CALLBACK MyEnumProc(HWND hWnd, LPARAM param)
{
	TCHAR buf[256];

	//is this the window we're looking for?
	if (GetClassName(hWnd, buf, 256) &&
		_tcsicmp(buf, TEXT("Notepad")) == 0)
	{
		//yes: store handle and stop searching
		*((HWND*)param) = hWnd;
		return FALSE;
	}
	else
		return TRUE; //go on searching
}

HWND WaitNotepadWindow()
{
	HWND ret = NULL;

	for (int i = 0; i < 100; i++)
	{
		//enum windows
		EnumWindows(MyEnumProc, (LPARAM)&ret);

		//found our main window?
		if (ret != NULL)
			break;

		//have a small rest, the retry
		Sleep(50);
	}

	return ret;
}

int main(int argc, char** argv)
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory(&si, sizeof(si));
	ZeroMemory(&pi, sizeof(pi));

	si.cb = sizeof(si);
		
	BOOL bSuccess;

	if ((bSuccess = CreateProcess(TEXT("C:\\WINDOWS\\System32\\Notepad.exe"),
		0, 0, 0, FALSE, NORMAL_PRIORITY_CLASS, 0, 0, &si, &pi)) == TRUE)
	{
		//detach from process
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		
		HWND hWindow;

		//wait for main window to come up
		if ((hWindow = WaitNotepadWindow()) != NULL)
			ShowWindow(hWindow, SW_HIDE); //then hide it
		
		//if we were a GUI app, we could make this
		//call to get back focus
		//SetForegroundWindow(g_hWnd);
	}
}

Open in new window

0
 

Author Closing Comment

by:arunykand
ID: 35207636
JKR...got it working, you're the man!
0
 
LVL 86

Expert Comment

by:jkr
ID: 35208625
Thanks ;o)

BTW, don't forget to 'CloseWindowStation()' and 'CloseDesktop()' when you're done.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
Suggested Courses

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question