Solved

C++ console app - window on top

Posted on 2011-03-23
18
623 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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 500 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

Three Reasons Why Backup is Strategic

Backup is strategic to your business because your data is strategic to your business. Without backup, your business will fail. This white paper explains why it is vital for you to design and immediately execute a backup strategy to protect 100 percent of your data.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Move windows 10 users 8 98
How do i run a c++ file? 15 57
boost::uuid crashes 17 60
parameter pack in c++11 2 19
If your system is showing symptoms of browser hijacks or 'google search redirects' check out my other article (http://rdsrc.us/u3GP7A) first and run the tool TDSSKiller (http://rdsrc.us/GDBBs4) to get rid of the infection. Once done, and if the …
Sometimes people don't understand why download speed shows differently for Windows than Linux.Specially, this article covers and shows the solution for throughput difference for Windows than a Linux machine. For this, I arranged a test scenario.I…
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…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

738 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