Solved

Keeping a program window always on on top

Posted on 2014-02-05
13
1,566 Views
Last Modified: 2014-03-03
Hi,

So we have a program at work which the team should always have a view on, but they don't.

We can install something like "always on top". However, this relies on them right clicking and hitting "Always on top".

Is there something I can enter in the Target of the short-cut/a switch i can enter.....or just do anything that will force the program to start "On top"
0
Comment
Question by:LFC1980
  • 7
  • 5
13 Comments
 
LVL 45

Expert Comment

by:Martin Liss
ID: 39839275
What kind of a program is it? In other words is it Excel, Visio, or...?
0
 

Author Comment

by:LFC1980
ID: 39839873
It's the Cisco agent s/w

http://www.cisco.com/en/US/products/sw/custcosw/ps427/

Need the team to have view of it at all times so they know who is available in the team
0
 
LVL 30

Accepted Solution

by:
Zoppo earned 150 total points
ID: 39841463
Hi MartinLiss,

I found a solution which maybe is suitable for your needs. To use it you'll have to install AutoIt scripting language i.e. from http://www.autoitscript.com/site/autoit/downloads/

Then create a new AutoIt script, paste the code shown below and set the path and filename of your program in the two variables $exepath and $exe. If you want you can remove one or both of the two calls to MsgBox if you don't like to see them.

Then you can save the script anywhere, i.e. on the Desktop. Starting the script (i.e. via doubleclick) first searches the application's window (if the application isn't yet running it'll be started) and set it to 'top-most'.
#include <Constants.au3>
#Include <WinAPIEx.au3>

Local $exepath = "D:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\"
Local $exe = "devenv.exe"

Func WinGetByPID($iPID)
	Local $aWList = WinList()
	For $iCC = 1 To $aWList[0][0]
	If WinGetProcess($aWList[$iCC][1]) = $iPID And BitAND(WinGetState($aWList[$iCC][1]), 2) = 2 Then
		Return $aWList[$iCC][1]
	EndIf
	Next
	Return 0
EndFunc

LOCAL $hwnd = 0
LOCAL $pid = ProcessExists( $exe )

While ( $hwnd = 0 )
	if ( $pid = 0 ) Then
		$pid = Run( $exepath & $exe )
		if ( $pid = 0 ) Then
;remove this if you don't want to be informed about failure
			MsgBox ( $MB_SYSTEMMODAL, $exe, "Failed to start executable" )
			exit( 1 )
		EndIf
	EndIf
	Sleep( 250 )
	$hwnd = WinGetByPID( $pid )
WEnd

if ( $hwnd <> 0 ) then
	WinSetOnTop( $hwnd, "", 1)
;remove this if you don't want to be informed about success
	MsgBox ( $MB_SYSTEMMODAL, $exe, "Window " & $hwnd & " set to top-most" )
EndIf

Open in new window

I hope this helps,

ZOPPO
0
 

Author Comment

by:LFC1980
ID: 39842371
Thanks - I'm off work for a while now, so will report back some point end of next week
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 39842481
No problem, I'm not in a hurry ;o)

Have a nice weekend ...
0
 

Author Comment

by:LFC1980
ID: 39866704
Okay, sorry for the delay...my few days off made me totally forget

It works a treat. However, one thing I didn't think of....pesky minimise button...doh!!
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 30

Expert Comment

by:Zoppo
ID: 39866769
No problem ...

I guess you mean you want to disallow minimizing the window using minimize button, right?

For this you can use a script like this one:
#include <Constants.au3>
#include <WindowsConstants.au3>
#Include <WinAPI.au3>
#Include <WinAPIEx.au3>


Local $exepath = "D:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\"
Local $exe = "devenv.exe"

Func WinGetByPID($iPID)
	Local $aWList = WinList()
	For $iCC = 1 To $aWList[0][0]
		If WinGetProcess($aWList[$iCC][1]) = $iPID And BitAND(WinGetState($aWList[$iCC][1]), 2) = 2 Then
			if ( BitAND( _WinAPI_GetWindowLong( $aWList[$iCC][1], $GWL_EXSTYLE ), $WS_EX_APPWINDOW ) ) Then
				Return $aWList[$iCC][1]
			endif
		EndIf
	Next
	Return 0
EndFunc

LOCAL $hwnd = 0
LOCAL $pid = ProcessExists( $exe )

While ( $hwnd = 0 )
	if ( $pid = 0 ) Then
		$pid = Run( $exepath & $exe )
		if ( $pid = 0 ) Then

			;remove this if you don't want to be informed about failure
			MsgBox ( $MB_SYSTEMMODAL, $exe, "Failed to start executable" )
			exit( 1 )
		EndIf
	EndIf
	Sleep( 100 )
	$hwnd = WinGetByPID( $pid )
WEnd

if ( $hwnd <> 0 ) then
	WinSetOnTop( $hwnd, "", 1)

	$style = _WinAPI_GetWindowLong( $hwnd, $GWL_STYLE )

	if ( BitAND( $style, $WS_MINIMIZEBOX ) <> 0 ) then
		_WinAPI_SetWindowLong( $hwnd, $GWL_STYLE, BitAND( $style, BitNOT( $WS_MINIMIZEBOX ) ) )
	EndIf
	;remove this if you don't want to be informed about success
	MsgBox ( $MB_SYSTEMMODAL, $exe, "Window " & $hwnd & " set to top-most" )
EndIf

Open in new window

In my test this sets the VisualStudio window top-most and disables the minimize button.

Hope this help,s

ZOPPO
0
 

Author Comment

by:LFC1980
ID: 39867704
Yeah, that's what i DID mean...

Basically the monitoring software will sit on top, and I assume if i run your script above it will disable the minimise button. However, I've now been told the actual part that needs to stay on top is another window launched from within the main one e.g Let's say you have the Cisco s/w open, from within there you can launch a 'Reports' window which shows you who is available and what they have in their hold queue

I have tried looking in the program folder to see if I can apply the script to just the reporting bit, but hoped for too much to find a reporting.exe type file
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 39867890
Hm - unfortunateley it's hard for me to give you more detailed instruction without having that program for testing.

IMO the main problem is to find the window you want. To do this there basically are three methods:

1. Searching a window of a process
2. Search a window by its title
3. Search a window by its classname

My last script uses 1. whereas it always searches for the main window of the process.

If it's possible to use options 2. and 3. for your need depends on the uniqueness of the window's title and/or classname.

Maybe a combination would be a solution, i.e. searching for a window with title 'Reports' which is running within the process. But this can only work if that 'Reports' window already exists - if i.e. it isn't created at startup the script can only work if the user already started the app, opened the window and then starts the script. Further the script above can only search for top-level windows, this means i.e. a toolbar or similar can't be found this way.

You can i.e. try to replace the 'if' which uses _WinAPI_GetWindowLong with another statement like this:
     if WinGetTitle($aWList[$iCC][1]) = "Reports" then


Unfortunateley I'll stop for today - I can try more tomorrow ...

ZOPPO
0
 

Author Comment

by:LFC1980
ID: 39868897
Thanks for your help. I'll try and test when I have a free moment tomorrow - Been so busy that I'm actually testing this during lunch
0
 

Author Comment

by:LFC1980
ID: 39899751
The need for this has become less important, and with the annoying window that we did need hard to find from processes, I've decided to give up on it.

Your solution did exactly what I asked for before I complicated matter so will select that when closing
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 39899765
ok, thanks, and sorry I couldn't give you a solution which worked as you need - I think it could be solved but not without quite some effort. I'm not a expert with the here used script language, my next try would have been implementing a Win32 C++ application since using basic Win32 API functions often is easier there. But unfortunateley I don't have really much time to do it for fun ;o)

But if the issue will pop-up again with higher importance please let me know ...

Have a nice day,

best regards,

ZOPPO
0
 

Author Comment

by:LFC1980
ID: 39901077
Thank you
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

A short article about problems I had with the new location API and permissions in Marshmallow
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This video shows and describes the main difference between both orientations in Microsoft Word. Viewers will understand when to use each orientation and how to get the most out of them.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

708 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now