Avatar of ttobin333
ttobin333
 asked on

Window Handle Changes in Always-On-Top Window?

Dear Experts,

When locating and restoring a window minimized to system tray, I am having problems when this window is in "always-on-top" status prior to minimizing.

Using the FindWindow("ThunderRT6Main", MyTitle) and GetWindow(MyHndl, GW_HWNDPREV) functions, I am able to successfully locate and restore the desired application from minimized to visible status. However, when the target window is in always-on-top mode prior to minimizing, the Get Window function returns a different handle and the process does not work.

What am I doing wrong?

Thanks!
Visual Basic Classic

Avatar of undefined
Last Comment
ttobin333

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
nffvrxqgrcfqvvc

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
ttobin333

ASKER
Hi egl1044,

I thought that I had a working method, but the example you gave (mutex) didn't work. I pasted it into my app exactly as you instructed.

It seems to detect the application itself even when another instance is not running, and prevents itself from loading. Can you please assist?

Thanks!
nffvrxqgrcfqvvc

Hi ttobin,

My understanding from your last question was that you wanted to prevent multiple instances of your application from loading if you detected another instance you wanted to have your application show the first main instance even if it was in the system tray. The code I posted in your last post should work :). Just to be sure you need to test it in the compiled form rather executable form and not from the VB IDE.

It works by creating a block of memory in your application, I then write the first instance (hWnd) to this memory. Now if another instance was to be launched your application would read that block of memory and obtain the (hWnd). This (hWnd) is actually the first instance and not the (NEW) instance. This way you can use the (hWnd) with ShowWindow() API.

This what you were looking for? If I am completely wrong here just let me know what it is your doing and I can help you solve it :)
ttobin333

ASKER
Thanks for your quick response, egl1044!

The concept is very logical...I will give it another try.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ttobin333

ASKER
egl1044, it works great!

My mistake was, I was trying to run it from the VB IDE (duh).

Does the use of the memory block require any clean up when closing the app?

Thanks again!!!
ttobin333

ASKER
Also, ShowWindow shows the app when it is minimized to the system tray, but not when it is minimized to the task bar. How can I show it in that case also?
ttobin333

ASKER
In combination with your excellent mutex method, using the all of the following commands togethe, I can cover all possibilities.  I can now show the original instance window whether it is minimized to system tray or task bar, or if it is hiding behind other windows:

Public Const SW_NORMAL = 4
Public Const SW_SHOW = 5

 If AppPrevInstanceSecure("MyAppName") Then
    MainAppWindow = hWndFromMainApp
    ShowWindow(MainAppWindow, SW_SHOW)
    ShowWindow(MainAppWindow, SW_NORMAL)
    SetForegroundWindow (MainAppWindow)
    End
Else
    InitForMainApp Me.hwnd
End If

Is that OK or do you recommend a better way?
Please also comment on my clean up question.

Thanks!
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
nffvrxqgrcfqvvc

Hi,

Great to to see it's working :)
IsIconic
http://msdn.microsoft.com/en-us/library/ms633527(VS.85).aspx
ShowWindow
http://msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

It looks good to me (untested) but from the documents SW_RESTORE seems to be the flag to use to show the window from the minimized state. You can try it and see if it works.
Private Declare Function IsIconic Lib "user32" (ByVal hWnd As Long) As Long
 
 If IsIconic(Me.hWnd) Then'your hwnd
    ' SW_RESTORE
    Else
    ' SW_SHOW
  End If

Open in new window

nffvrxqgrcfqvvc

<< Does the use of the memory block require any clean up when closing the app? >>

Nope. You should be fine here. It only allocates 4 bytes of memory this is the size of a single Long variable so nothing to worry about. When your main instance closes the memory will be released automatically.

Also here is the difference between VB's internal AppPrevInstance and the Mutex(AppPrevInstanceSecure) when using the VB method if someone renamed your executable or moved its location  multiple instances would still be launced. However with the Mutex approach a user can rename your executable or move it on the system and it will still block a second instance. So it's the much better option to use for making sure a second instance never spawns.

The reason it doesn't work in the VB IDE is for one we never call ReleaseMutex() and you can't really test multiple instance from VB IDE :)
ttobin333

ASKER
Excellent!!! Thank you very much!
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy