Make launched process on top

BlitzMax Forums/BlitzMax Programming/Make launched process on top

JoshK(Posted 2012) [#1]
I am using freeprocess to launch and communicate with an external EXE, but the launched window won't activate/become foreground, on top of main program window.

My launched process has window activation code like below, but it doesn't work when the process is launched from my main application:
	void Window::Activate()
	{
		BringWindowToTop(hwnd);
		SetWindowPos(hwnd,NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
		SetForegroundWindow(hwnd);
		SetActiveWindow(hwnd);
		SetFocus(hwnd);
		current = this;
	}


My main application also calls AllowSetForegroundWindow(), to try to give the launched process permission to take the foreground, but it doesn't seem to do anything:
		process=CreateProcess("~q"+procpath+"~q "+parameters)
?win32
		AllowSetForegroundWindow(process.handle)
?


How can I allow the window of my launched process to become the topmost window?


col(Posted 2012) [#2]
Out of curiousity have you tried

SetWindowPos(hwnd,-1,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

?

The -1 sets the window to HWND_TOPMOST.


JoshK(Posted 2012) [#3]
Yes, but that is not the behavior I want. Even when I do, the window still gets deactivated after a few seconds, and is non-active and forced on top. I want the window to be activated and appear on top, as if I click on it.


col(Posted 2012) [#4]
I understand.
I don't know why it would get deactivated after a few seconds though :/
I'd look into what's causing that, suspecting something in the initial process is activating the initial window again.

Other things come to mind to try -
Is it a completely fresh new window you're creating, ie no parent? Have you tried making it a child of the initial 'parent' window? If it can be a modeless window then how about using CreateDialog instead of CreateWindow(Ex)?


JoshK(Posted 2012) [#5]
I added this to the start of my main program:
?win32
Extern "win32"
	Function AllowSetForegroundWindow:Int(process:Int)
EndExtern
AllowSetForegroundWindow(-1)
?


And it makes no difference. I also tried calling it after CreateProcess().

Last edited 2012


JoshK(Posted 2012) [#6]
I solved this by calling AllowSetForegroundWindow(-1) directly AFTER the process is created.

I want to add this code in the pub.freeprocess module so that it creates a suspended process, calls AllowSetForegroundWindow(-1), and then resumes the process thread. I have it working except that the linker fails because it can't find the AllowSetForegroundWindow function. I included <windows.h> at the top of the freeprocess.c file, but it still doesn't work:


C:/BlitzMax/mod/pub.mod/freeprocess.mod/freeprocess.debug.win32.x86.a(freeprocess.c.debug.win32.x86.o):freeprocess.c:(.text+0x665): undefined reference to `AllowSetForegroundWindow'


Last edited 2012


col(Posted 2012) [#7]
Swapping out that extra

#ifdef _WIN32
include <window.h>
#endif

for

extern BOOL WINAPI AllowSetForegroundWindow(DWORD dwProcessId);

should fix the linker error.

Last edited 2012


JoshK(Posted 2012) [#8]
Thanks, here's the complete fix:
http://www.blitzmax.com/Community/posts.php?topic=99022


col(Posted 2012) [#9]
Nice one, thanks, this will come in handy for sure.

Oh god - I just remembered! The process.handle inside BMax TProcess isn't the real cpu process id handle. It's a handle to a PROCESS_INFORMATION structure that has the real handle instance inside it. So the command may have worked from BMax, it's just it had the wrong variable given to it.

Last edited 2012