?
Solved

Activating a (covered) App to come to front

Posted on 2003-03-18
36
Medium Priority
?
480 Views
Last Modified: 2007-12-19
When my (VB 6 made) App gets activated by a telephone call, it always came to front automatically in Win NT 4.0

Now in 2000, it only comes to front if Outlook XP is covering it. When covered by Word XP or some other applications, my app stays in the background, and blinks in the task bar.

When the phone call comes in, the MDI frame creates a new MDI child window, and the MDI childs Form_Load does this:

     With MDIDaddy
        If .WindowState = vbMinimized Then
            .WindowState = vbNormal
            .Top = mlngTop
            .Left = mlngLeft
            .Height = mlngHeight
            .Width = mlngWidth
        End If
        Me.Top = (.ScaleHeight - Me.Height) / 2
        Me.Left = (.ScaleWidth - Me.Width) / 2
    End with

My questions are: What exactly was changed in Win2000 (compared with NT 4.0) ? Which of these code statements causes the OS to such actions like blinking in the taskbar or taking my app to the front ?

I need a way to have a behaviour that is really unique, no matter whether taking me to the front or leaving me back, but NOT DEPENDING ON WHICH OTHER application is currently at the front.

If I would use "AppActivate", would this always cause my app to come to the front, no matter which other apps are before it (OK, those not being system modal) ?
0
Comment
Question by:PC-Alex
[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
  • 15
  • 14
  • 4
  • +2
36 Comments
 
LVL 9

Expert Comment

by:MSGeek
ID: 8159613
I think you are looking for the WonTop function?
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8160084
WonTop ? Isn't this chinese food ?

Just kidding.

Seems to be a FoxPro command. It could tell if my window is on top of all others, this could be helpful indeed, but it is only for use inside FoxPro, and I have VB 6.
0
 
LVL 9

Expert Comment

by:MSGeek
ID: 8160338
No coment on first question, as I beleive China is supporting our countries current endeavor.

http://support.microsoft.com/default.aspx?scid=kb;en-us;274478

I couldn't tell you, I have only used it in FoxPro, sorry.
0
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.

 
LVL 44

Expert Comment

by:CrazyOne
ID: 8160496
Try this from Win32 help

The SetWindowPos function changes the size, position, and Z order of a child, pop-up, or top-level window. Child, pop-up, and top-level windows are ordered according to their appearance on the screen. The topmost window receives the highest rank and is the first window in the Z order.

BOOL SetWindowPos(

    HWND hWnd,      // handle of window
    HWND hWndInsertAfter,      // placement-order handle
    int X,      // horizontal position
    int Y,      // vertical position
    int cx,      // width
    int cy,      // height
    UINT uFlags       // window-positioning flags
   );      
 

Parameters

hWnd

Identifies the window.

hWndInsertAfter

Identifies the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values:

Value      Meaning
HWND_BOTTOM      Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.
HWND_NOTOPMOST      Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.
HWND_TOP      Places the window at the top of the Z order.
HWND_TOPMOST      Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated.
 

For more information about how this parameter is used, see the following Remarks section.

X

Specifies the new position of the left side of the window.

Y

Specifies the new position of the top of the window.

cx

Specifies the new width of the window, in pixels.

cy

Specifies the new height of the window, in pixels.

uFlags

Specifies the window sizing and positioning flags. This parameter can be a combination of the following values:

Value      Meaning
SWP_DRAWFRAME      Draws a frame (defined in the window's class description) around the window.
SWP_FRAMECHANGED      Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.
SWP_HIDEWINDOW      Hides the window.
SWP_NOACTIVATE      Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter).
SWP_NOCOPYBITS      Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.
SWP_NOMOVE      Retains the current position (ignores the X and Y parameters).
SWP_NOOWNERZORDER      Does not change the owner window's position in the Z order.
SWP_NOREDRAW      Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.
SWP_NOREPOSITION      Same as the SWP_NOOWNERZORDER flag.
SWP_NOSENDCHANGING      Prevents the window from receiving the WM_WINDOWPOSCHANGING message.
SWP_NOSIZE      Retains the current size (ignores the cx and cy parameters).
SWP_NOZORDER      Retains the current Z order (ignores the hWndInsertAfter parameter).
SWP_SHOWWINDOW      Displays the window.
 

Return Values

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the SWP_SHOWWINDOW or SWP_HIDEWINDOW flag is set, the window cannot be moved or sized.
All coordinates for child windows are client coordinates (relative to the upper-left corner of the parent window's client area).
A window can be made a topmost window either by setting the hWndInsertAfter parameter to HWND_TOPMOST and ensuring that the SWP_NOZORDER flag is not set, or by setting a window's position in the Z order so that it is above any existing topmost windows. When a non-topmost window is made topmost, its owned windows are also made topmost. Its owners, however, are not changed.

If neither the SWP_NOACTIVATE nor SWP_NOZORDER flag is specified (that is, when the application requests that a window be simultaneously activated and its position in the Z order changed), the value specified in hWndInsertAfter is used only in the following circumstances:

7      Neither the HWND_TOPMOST nor HWND_NOTOPMOST flag is specified in hWndInsertAfter.
7      The window identified by hWnd is not the active window.

 

An application cannot activate an inactive window without also bringing it to the top of the Z order. Applications can change an activated window's position in the Z order without restrictions, or it can activate a window and then move it to the top of the topmost or non-topmost windows.
If a topmost window is repositioned to the bottom (HWND_BOTTOM) of the Z order or after any non-topmost window, it is no longer topmost. When a topmost window is made non-topmost, its owners and its owned windows are also made non-topmost windows.

A non-topmost window can own a topmost window, but the reverse cannot occur. Any window (for example, a dialog box) owned by a topmost window is itself made a topmost window, to ensure that all owned windows stay above their owner.
If an application is not in the foreground, and should be in the foreground, it must call the SetForegroundWindow function.


The Crazy One
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8160617
SetWindowPos(f.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)

FLAG would be one or more of the

Specifies the window sizing and positioning flags. This parameter can be a combination of the following values:

Value     Meaning
SWP_DRAWFRAME     Draws a frame (defined in the window's class description) around the window.
SWP_FRAMECHANGED     Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.
SWP_HIDEWINDOW     Hides the window.
SWP_NOACTIVATE     Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter).
SWP_NOCOPYBITS     Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.
SWP_NOMOVE     Retains the current position (ignores the X and Y parameters).
SWP_NOOWNERZORDER     Does not change the owner window's position in the Z order.
SWP_NOREDRAW     Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.
SWP_NOREPOSITION     Same as the SWP_NOOWNERZORDER flag.
SWP_NOSENDCHANGING     Prevents the window from receiving the WM_WINDOWPOSCHANGING message.
SWP_NOSIZE     Retains the current size (ignores the cx and cy parameters).
SWP_NOZORDER     Retains the current Z order (ignores the hWndInsertAfter parameter).
SWP_SHOWWINDOW     Displays the window.
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8160624
Oops that should be
SetWindowPos(f.hWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8160648
Also

The SetForegroundWindow function puts the thread that created the specified window into the foreground and activates the window. Keyboard input is directed to the window, and various visual cues are changed for the user.

BOOL SetForegroundWindow(

    HWND hWnd      // handle of window to bring to foreground
   );    
 

Parameters

hWnd

Identifies the window that should be activated and brought to the foreground.

 

Return Values

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The foreground window is the window at the top of the Z order. It is the window that the user is working with. In a preemptive multitasking environment, you should generally let the user control which window is the foreground window. However, an application can call SetForegroundWindow if it wants to put itself into the foreground to display a critical error or information that requires the user's immediate attention. A good example is a debugger when it hits a breakpoint.

The system assigns a slightly higher priority to the thread that created the foreground window than it does to other threads.
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8160687
With MDIDaddy
       If .WindowState = vbMinimized Then
           .WindowState = vbNormal
           .Top = mlngTop
           .Left = mlngLeft
           .Height = mlngHeight
           .Width = mlngWidth
       End If
       Me.Top = (.ScaleHeight - Me.Height) / 2
       Me.Left = (.ScaleWidth - Me.Width) / 2

       SetForegroundWindow(.hWnd)

   End with
0
 
LVL 9

Expert Comment

by:MSGeek
ID: 8160738
Hey Spencer, I knew you would kno wthis one, thought since I beat ya to it I'd take a shot.  Oh well..  :)
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8160971
Hehehe I live in the Denver Colorado area and we are getting the biggest snow storm we probably have had in maybe 10 years. I had to go out and make a delivery in it. Phew not fun. Plus now my ISP email server is down for probably 24hrs but it took a 30 min phone call to find out. So I am kind of out of the loop for a while. Without email I won't be able to keep in touch with the questioners. Bummer :>(
0
 
LVL 9

Expert Comment

by:MSGeek
ID: 8161147
Whoo, not only will you get a ton of snow, but you'll be slammed with EE Mail!
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8164736
Finally got my email back. :>)
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8165799
Thanks for the Tips, CrazyOne, I will test this for the case that AppActivate doesn't work for me. I'll post the results later.

The very question that I hoped to get an answer was the "WHY", regarding the changes between NT 4 and Win 2000.
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8166677
OK, Tests are through.

AppActivate didn't help anything.

SetWindowPos pushes my app in front only if HWND_TOPMOST is used, and I didn't manage it with the normal HWND_TOP. But when using HWND_TOPMOST, after that no other application can be taken in front of my app, it seems now that I am SYSTEM MODAL, and this can't be a clean solution.

Next, I'll test SetForegroundWindow, but have not much hope ....
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8166712
SetForegroundWindows also just made the app blinking in the taskbar, nothing more.

Perhaps theres a unique key in Windows for taking the currently blinking app to the front, something like ALT-TAB ?
0
 
LVL 85

Expert Comment

by:oBdA
ID: 8168663
Well, I can tell you about the "why": In NT4, focus stealing was enabled by default. Any application that wnated to have the focus could just go ahead and grab it (and boy, was it annoying.)
This was changed with the release of W2k; now an application that wants to put itself in the foreground does not get the focus immediately anymore by default; instead, as you noticed, the taskbar button starts to blink.
This behaviour is controlled at HKEY_CURRENT_USER\Control Panel\Desktop, with "ForegroundFlashCount" and "ForegroundLockTimeout".
The easiest way to change this is using TweakUI.
You can look it up at http://www.microsoft.com/mspress/books/sampchap/6232.asp (or by googeling for "ForeGroundLockTimeOut")
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8168765
The SetForegroundWindow works for me on all platforms. It always brings the app to the top. Instead of useing the form handle use the Application handle and see what happens.

Or you could do this

SetWindowPos(f.hWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)

then follow that code to do this

SetWindowPos(f.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8172565
Thanks oBdA for the theoretical background as well as CrazyOne for the hint.

I fiddelled with the registry settings in order to simulate Win NT 4 behaviour. It didn't work, setting only ForegroundLockTimeout to 0, or setting both reg values to 0 did not bring my app to foreground.

Then I tested CrazyOne's idea, and it made it a little better, my app comes to the front and I can still take others in front after that.

One thing still makes this way no solution: when the call comes in, my app waits for an ENTER keystroke to take the call. But although it is in foreground, it doesn't have the input focus (title bar is grey). So I tested AppActivate or SetForegroundWindow AFTER calling SetWindowPos(HWND_TOPMOST), nothing helped. Even if I leave HWND_NOTOPMOST completely away, I get no input focus.

Is there any another possibility ?

0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8172707
I'm really wondering why SetForegroundWindow doesn't work as documented. Because of the statements about the current thread, I compared two ThreadIds with GetCurrentThreadId, at the point of frmMain.Form_Load and at the point where I call SetForegroundWindow (which is invoked by a COM DLL being connected with the telephony server), but both IDs are identical ...
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8174948
Did you use the Application handle instead of the form handle for the SetForegroundWindow?
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8175163
I used the .hwnd from my main windows (MDI Frame wnd). What is an Application handle, something like an HINSTANCE in C++ ? How to get it in VB ?
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8175196
I can't remember in VB what that handle is but in Delphi it is

Application.Handle
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8175224
I guess in VB it would be App.hInstance
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8180454
I tried it with App.hInstance, but nothing changed. Anayway, in MSDN it is documented with HWND.
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8180482
What about simulating a mouseclick on the title bar ? Isn't there a SendMessage(WM_MOUSE...) - combination that I could use to fool my app ?
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8181656
What happens if you use the SetFocus on the form after bringing it to the foreground.
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8194443
Thanks for the hint, CrazyOne, but it didn't help. It is not allowed to place SetFocus inside Form_Load, so I took it into Form_Activate, but with no visible change.
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8201464
Because time is running out, I have opened a support case at Microsoft.

I will document what came out at this place for all of you having the same problems.

Here is what came out: Microsoft doesn't want Applications to steal the focus. Period.

SetForegroundWindows does not work in Windows 2000, even if you set the registry key ForegroundLockTimeout = 0.

There is one exception that can be used if you have full control over all applications that run on the PC: If an application calls "AllowSetForegroundWindow(ASFW_ANY)", the application allows other applications to steal the focus. This explains why Outlook XP, which goes "under" my app without any additional calling of functions by me.

Finally some MSDN articles MS pointed me to:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui
/windowsuserinterface/windowing/windows/windowreference/windowfunctions/setf
oregroundwindow.asp

INFO: Change the Foreground Window in Windows 98 & Windows 2000
ID: Q227043
http://support.microsoft.com/support/kb/articles/Q227/0/43.asp

INFO: SetActiveWindow() and SetForegroundWindow() Clarification
ID: Q97925
http://support.microsoft.com/support/kb/articles/Q97/9/25.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/
flashwindowex.asp
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8201479
Now to the points.

CrazyOne had given valuable tips that I tested, although it didn't solve my problem in the end.

oBdA lead me to the theoretical background that I asked for, to understand what was really changed.

I think partitioning the points in 150 for CrazyOne and 100 for oBdA would be a fair deal.

Agreed ?
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8209843
It works ! To complete the discussion, here is a complete VB 6 sample app that demonstrates how:

Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
Private Const SPI_GETFOREGROUNDLOCKTIMEOUT = &H2000
Private Const SPI_SETFOREGROUNDLOCKTIMEOUT = &H2001
Private Const SPIF_SENDWININICHANGE = &H2
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Private mlTimeoutSpeicher As Long
Private lSuccess As Long

Private Sub Form_Load()
   
    lSuccess = SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0&, mlTimeoutSpeicher, SPIF_SENDWININICHANGE)
     
    lSuccess = SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0&, ByVal 0&, SPIF_SENDWININICHANGE)
End Sub

Private Sub Timer1_Timer()
       lSuccess = SetForegroundWindow(Me.hwnd)
End Sub

Private Sub cmdOK_Click()
    lSuccess = SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0&, mlTimeoutSpeicher, SPIF_SENDWININICHANGE)
    Unload Me
End Sub
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8211731
Just curious but doesn't puttting this in a timer
lSuccess = SetForegroundWindow(Me.hwnd)

in essence does this?
SetWindowPos(f.hWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
0
 
LVL 85

Expert Comment

by:oBdA
ID: 8212417
I was just about to comment that MS's statement that they don't want applications to steal the focus is not what I'd call "precise". Applications are able to steal the focus as they please.
Focus stealing should be disabled by default - only that I have some ugly application that resets the registry values to allow focus stealing at every boot. It's getting on my nerves because when a new email comes in, Notes just grabs the focus, whatever is up front. I'm currently resetting it in Autostart, but the fact that some application has the guts to just reset this instead of accepting the given value is really annoying.
Oh well.
0
 
LVL 1

Author Comment

by:PC-Alex
ID: 8212877
CrazyOne, no, thats not the same, I can assure you that I tested it; SetWindowPos(f.hWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS) didn't change anything when we tested it in the beginning. It might just be that SystemParametersInfo is the door-opener to bring ALL these functions to effect, this I haven't tested.

What was wondering me the most is, that this difference: setting the Registry Value ForegroundLockTimeout to 0  didn't have any effect, but calling these strange SystemParametersInfo functions (which don't change the registry! check it out with Regmon!) makes it work.

oBdA, you could try calling "SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0&, mlTimeoutSpeicher, SPIF_SENDWININICHANGE)" with a mlTimeoutSpeicher of 20000 (default) from outside into the Notes application, perhaps by hooking or by sending an appropriate windows message.

BTW, the complete demo project that I posted was developped out of the hints from MS, so they are really not so strictly behind this policy as I thought. But you must admit that for a call center application (which I develop), an incoming call is a reasonable reason to "steal" the focus.
0
 
LVL 44

Expert Comment

by:CrazyOne
ID: 8212924
I believe the SystemParametersInfo is logging the info in memory. If one manually chages it in the registry it may take a reboot for it to be apparent
0
 
LVL 44

Accepted Solution

by:
CrazyOne earned 600 total points
ID: 8212945
I don't know there is still sonmething weird here because when I use SetForegroundWindow the app becomes the one with the focus with or without using the SystemParametersInfo. Hmmmm
0
 

Expert Comment

by:SpideyMod
ID: 8227529
A request for a split has been made at: http://www.experts-exchange.com/Community_Support/Q_20566590.html

I have reduced the points down to 150 and accepted Crazyone's answer.  

oBdA, points for you at:
http://www.experts-exchange.com/Operating_Systems/Win2000/Q_20566840.html


SpideyMod
Community Support Moderator @Experts Exchange
0

Featured Post

Enterprise Mobility and BYOD For Dummies

Like “For Dummies” books, you can read this in whatever order you choose and learn about mobility and BYOD; and how to put a competitive mobile infrastructure in place. Developed for SMBs and large enterprises alike, you will find helpful use cases, planning, and implementation.

Question has a verified solution.

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

NTFS file system has been developed by Microsoft that is widely used by Windows NT operating system and its advanced versions. It is the mostly used over FAT file system as it provides superior features like reliability, security, storage, efficienc…
This article will show how Aten was able to supply easy management and control for Artear's video walls and wide range display configurations of their newsroom.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

762 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