Jump to content
Michael Aivaliotis

How do you make your application window frontmost?

Recommended Posts

I need to programmatically force my LabVIEW application to become frontmost on a Windows system. Basically I want it to punch through any currently open application windows and become the main active app.

What I've tried:

  • I ran the SetForegroundWindow Windows API function. This causes the titlebar to flash and draw attention for a short while but does not make it frontmost.
  • I ran the BringWindowToTop Windows API function. This does not make it frontmost.
  • I made my application window floating. This does appear to work. However this causes other problems since the window which I need to be frontmost is also a dialog box. So I don't want the user to click behind the dialog box onto my main application window.
  • I tried using the floating window property (as mentioned above), then quickly made it modal again. This has the affect of flashing the window to the user and then disappearing behind any other app windows. Not good and also confusing.

So, is there any way to do this?

Share this post


Link to post
Share on other sites

Hey Mikael. That was another function I used but it wasn't working for me. I was setting the hWndInsertAfter parameter to 0 (Places the window at the top of the Z order). However by setting it to -1 and then back to -2. I managed to get the result I needed. :-)

Thanks!

Share this post


Link to post
Share on other sites

I had some problems with making a LabVIEW window the frontmost of all windows at one point. Using Windows DLLs I could make a LabVIEW window become the topmost of all other LabVIEW windows, but if there was say notepad open I couldn't get it to make the window on top of notepad.

So I wrote a quick AutoIt program to do it and it seems to work fine. Source is included. It is a command line program where you can specify the Processor ID, or the Title of the window (not sure why I didn't implement hWnd). If the Processor ID has more than one window it just picks the first one. If you don't know the Processor ID of an application you can open the Task Manager, go to the Processes tab, and then in XP you can add a column called PID using the View >> Select Columns. Not sure how it's done in Windows 7 but I know it is there too.

Usage: FocusWindow.exe /PID ####

Will focus the window with the PID #### and return the HWND.

Usage: FocusWindow.exe /TITLE "####"

Will focus the window with the title "####"

FocusWindow.zip

Share this post


Link to post
Share on other sites

Hey Mikael. That was another function I used but it wasn't working for me. I was setting the hWndInsertAfter parameter to 0 (Places the window at the top of the Z order). However by setting it to -1 and then back to -2. I managed to get the result I needed. :-)

Thanks!

Also replied here.

I'm trying to do the same thing, only I want to make a VI which is run via Call By Reference from a remote application instance always on top with key focus. I can get always on top to work like you did, where I call SetWindowPos twice (once with hWndInsertAfter = -2 and again with it = -1).

Then, I get two "active" windows and the wrong one (launching application) has key focus. SetFocus, SetActive, etc. seem to be no help whether I call them before or after SetWindowPos. SetForegroundWindow just makes it blink 3 times, like you had experienced...

Any Ideas?

post-9197-093862900 1279663353_thumb.png

Share this post


Link to post
Share on other sites

Yair-

Works! For our application, I just had to add a SetWindowPos (hWndInsertAfter = -1) afterward to keep the window in front (topmost)... Thanks for the help!

Wow that sure does work...it actually works a little too good. I wrote a VI that just waits 10 seconds then calls your VI to bring it forward. In the first 10 seconds I took notepad and put it frontmost manually. Then the VI brought it self to the front.

Problem is after the VI stopped executing it was still the front, meaning it was Always On Top, of all other windows...I then went to close the VI but nothing happened. I then realized it was because my VI was unsaved and the Save Dialog appeared but because my window was front most I couldn't see it. And because the save dialog was there I couldn't move my VI's window to see the Save Dialog window. I closed it by using the keyboard but how do I make the window not Always On Top after bringing it to the front?

Share this post


Link to post
Share on other sites

The hWndInsertAfter argument in SetWindowPos is what controls the window's Z order. -1 makes it always on top. I believe -2 cancels this, so you can probably just call it again with that value.

In fact, you may not even need the original call at all. You'll note that my code did not have it, because I was only bringing the window to the top, not making it topmost. I don't remember if my code gives the window focus or not, but I believe it should.

Share this post


Link to post
Share on other sites

Wow that sure does work...it actually works a little too good. I wrote a VI that just waits 10 seconds then calls your VI to bring it forward. In the first 10 seconds I took notepad and put it frontmost manually. Then the VI brought it self to the front.

Problem is after the VI stopped executing it was still the front, meaning it was Always On Top, of all other windows...

The hWndInsertAfter argument in SetWindowPos is what controls the window's Z order... you may not even need the original call at all... You'll note that my code did not have it, because I was only bringing the window to the top, not making it topmost. I don't remember if my code gives the window focus or not, but I believe it should.

Yair is correct that you don't need the SetWindowPos call unless you want Topmost. Removing the SetWindowPos call does not affect focus in this use case. I've attached a VI that will cancel Topmost and another that will set Top instead of Topmost. hWndInsertAfter = -2 sets "NoTopmost" (above all non-topmost windows).

Cancel Calling VI Wnd Topmost.vi

Set Calling VI Wnd Top & Active.vi

Edited by Bean

Share this post


Link to post
Share on other sites

Yair is correct that you don't need the SetWindowPos call unless you want Topmost. Removing the SetWindowPos call does not affect focus in this use case. I've attached a VI that will cancel Topmost and another that will set Top instead of Topmost. hWndInsertAfter = -2 sets "NoTopmost" (above all non-topmost windows).

You can also use "BringWindowToTop" which will not set it as a top level window but will bring it to the top of the Z-Order.

Share this post


Link to post
Share on other sites

Hi Folks -

Does someone have the code to make a non-VI window called from LabVIEW always on top? I have a .chm (help) file I call that gets lost behind a background window if it is not always on top. Also it is built with 64-bit LabVIEW 2010. That said, George Zou basically created a 64-bit version of one of his previous VI utilities to do just this, and I have it and it works great (Thank you George). Problem is I need to build a 64-bit executable for another guy in the lab and since the VI is password protected, the executable builds but when we go to run we get the following error.

LabVIEW: Resource not found.

An error occurred loading VI 'Make Window Always on Top64.vi'.

LabVIEW load error code 3: Could not load front panel.

So I think the password protection on the block diagram is really what is causing this issue. In the meantime, I can't find George. We had been emailing over the years but I must have deleted some emails because the last one I can find for him is back in 2002. (George - if you are out there somewhere and can address this, let me know.) In any case, it would be best for me to be able to do this myself. If anyone has a VI that they can post that has an string input for window name (non-LabVIEW window) that will do this, it would be quite helpful.

Thanks,

Don

post-115-0-61528400-1313424003.jpg

Share this post


Link to post
Share on other sites

You're looking for the SetWindowPos function from the user32.dll.

Share this post


Link to post
Share on other sites

Can we still use user32.dll for 64-bit LabVIEW? It appears the VIs shown above or equivalent snippets would be a good starting point rather than reinventing the wheel if user32.dll is still valid to use in 64-bit LabVIEW.

Share this post


Link to post
Share on other sites

It looks like user32.dll should work according to:

0 down vote

There is no user64.dll for the exact same reason you just describe, .net program can be agnostic to cpu architecture so the same code needs to work on x86 and x64.

If you take your program to x86 platform it will still run without any modifications.

I guess that when they named user32.dll they didn't have those scenarios in mind.

http://stackoverflow.com/questions/1540741/c-pinvoking-user32-dll-on-a-64-bit-system

So I am assuming maybe I can start to fool around with this stuff by just downloading some of the above VIs?......Don

Share this post


Link to post
Share on other sites

So I am assuming maybe I can start to fool around with this stuff by just downloading some of the above VIs?......Don

You won't know until you try. Trying 32-bit calls on 64-bit certainly won't set anything on fire, but it looks like there is indeed a 64-bit version of user32.dll that will be seamlessly called if you don't use an absolute path.

Share this post


Link to post
Share on other sites

You won't know until you try. Trying 32-bit calls on 64-bit certainly won't set anything on fire, but it looks like there is indeed a 64-bit version of user32.dll that will be seamlessly called if you don't use an absolute path.

Well the name of the Windows DLLs has not changed between 32bit and 64bit Windows just because they wanted to avoid to having to change all DLL names everywhere when referencing DLLs dynamically by name. The 32 in the name is a left over artefact since all these DLLs also had the same name without 32 in Windows 3.x. Back then when moving to 32 bit architecture the MS developers chose to use a distinctive name to avoid name collisions.

When moving to 64bit, MS decided to use different base directories instead and leave the DLL names alone.

So VIs accessing system DLLs can work both on 32bit and 64bit Windows but you need to be aware that some parameters can actually change in size. For instance any HANDLE datatype (almost every WinAPI datatype starting with a H) is a 32 bit entity in 32 bit Windows and a 64 bit entitiy in 64 bit Windows. So the right data type to use for such parameters is the (unsigned) pointer sized integer. If you use a normal 32 bit integer it may still work on resource constrained systems but will sooner or later fail badly when your system has more memory and the value of handles can go above 4GB address range. Same for any pointer that you decide to treat as integer type for whatever reasons and there are also a few other Windows datatypes that can change bitness.

  • Like 1

Share this post


Link to post
Share on other sites

FYI to anyone else who digs up this thread: Bean's VIs don't work if you have "Show revision number in titlebar" enabled in your LV Options and you execute the code in the dev environment. This is because it uses "FP.Title" as the window title.

  • Like 1

Share this post


Link to post
Share on other sites

For what it's worth, there is a private VI property that returns the OS window handle so you don't need to use FindWindow. It's somewhere on lava but I can't link to it via the mobile site. I think it's called OSNativeWindow or something. The thread has a VI containing the property node which can be dropped in any other VI (it's a private property). That should fix any issue with window titles not matching.

FindWindow has a lot of limitations, some of which include conflicts with other windows, or inability to find Windows without a title bar. I tend to use the property exclusively when I need an hWnd.

  • Like 1

Share this post


Link to post
Share on other sites
For what it's worth, there is a private VI property that returns the OS window handle so you don't need to use FindWindow. It's somewhere on lava but I can't link to it via the mobile site. I think it's called OSNativeWindow or something. The thread has a VI containing the property node which can be dropped in any other VI (it's a private property). That should fix any issue with window titles not matching.

 

Here: http://lavag.org/topic/13803-getting-the-window-handle-for-a-fp-with-no-title-bar/

Share this post


Link to post
Share on other sites

Hi,

 

I've been trying to use FindWindow and BringWindowToTop. It works well when run from the dev env. When I build an executable and run that, it crashes straight away with an access violation even though the BringToFront.vi hasn't been run yet. Any suggestions what that could be?

I'm building on 2013 32bit.

BringToFront.vi

Share this post


Link to post
Share on other sites

For me I use code similar to this.  It gets the HWND using a VI reference instead of window title.  This is more robust for things that maybe in subpanels, or hidden but in most cases the get HWND from window title you posted should work.  Where we differ more is on the make window top.  The VI I have for set Z order comes from code posted here.  I've used this technique in built EXEs without a problem.

 

EDIT: OpenG error, and Application Control is required.

Make Window Top.zip

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.