WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Control Manager
plus
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

cGetFocus vs WinGetActive


Question:

I'm trying to check to see if the current window has the focus.

This works:

myName = cWndInfo(DllHwnd(""),0)
...

IF WinGetActive() == myName THEN Yes!!
But I thought it would be more efficient/elegant to do this:
myHnd = DllHwnd("")
...

IF cGetFocus() == myHnd THEN Yes!!
but it doesn't work. Why not?

Further testing shows that it may have something to do with the program running iconized on a system that is not running the standard Windows EXPLORER shell. This is the original context where this came up. Try this test program:

AddExtender("wwctl44i.dll")
myHnd = DllHwnd("")

IntControl(54,"",1,0,0)
WHILE WinState("") < @NORMAL
    TimeDelay(1)
    IF cGetFocus() == myHnd THEN Pause("","I have the focus now!")
ENDWHILE
Exit
When I run this, it starts out minimized (as all WB programs do), and when I click on it, it gets the focus, but doesn't announce *until* I de-iconize it. If you are running EXPLORER (such that it shows up in the "task bar"), then you can see the effect by *right* clicking on it, getting the popup menu and then hitting escape. At least on my system, this leaves it as the active window, but does not "de-iconize" it. And, when I do de-iconize it, it then pops up the announcement.

All of this may seem obscure/moot, but the fact is that it does work correctly (under my conditions) if I use the first method (cWndByName and WinActivate), but doesn't work (just sits there) if I try to do it with handles (instead of with window names). I'm curious as to why...

Answer:

cGetFocus is different from DllHwnd in that it returns the window handle of the window with 'keyboard focus'. A running WinBatch script by default has a minimized/iconized window. It looks as though the only way to give the window 'keyboard focus' is to first activate it. WinActivate and BoxOpen can be used to 'activate' this window: Here is another example that uses BoxOpen instead of WinActivate.
AddExtender("wwctl44i.dll")
BoxOpen("","")
myHnd = DllHwnd("")
hFocus = cGetFocus()
IF hFocus == myHnd THEN Message("","My window is active")

User Reply:

Yes, I think that is well understood. But the point is that the results of these two functions should compare equal if (and only if) the current windows has the focus.

But the point, which I have probably not made as clear as I should have, is that a minimized WinBatch script can have the focus (even though WinState("") == @ICON).

Two points regarding this last sentence:

  1. It can be difficult to acheive this state of affairs if you are running the standard shell. But it is not impossible; in my last post, I gave a procedure for achieving it.
  2. It is in this state that my problem arises. I.e., you won't see the discrepancy if the WB program is running in the @NORMAL state.
P.S. Keep in mind that it does work correctly if I use the functions that work at the "window title" level. I'm just curious as to why it doesn't work exactly the same way when I use the functions that deal at the "window handle" level.

Answer:

I think you will have to ask MSFT that question. MSFT apparently has a slight difference in definition between the foreground window and the window with the focus.

I encounter that difference in definition frequently. If you recall, in Win2K and again in WinXP, I think, Microsoft made some subtle changes to window activation which in turn affected how certain WinBatch functions behave in terms of sending keystrokes and in how the Control Manager extender works, too. Ostensibly, these changes were supposed to improve the end-user experience when an application is trying to alert the user that the application requires some sort of user intervention. The end result that I observe is that there are times when I have a window that is in the foreground in terms of Z-order, but the window that has keyboard focus is actually in the background. When a background application "steals" the keyboard focus, you typically see the taskbar unhide itself [if it was hidden], and the application's button on the taskbar highlights itself until the application is brought to the foreground.

User Reply:

Thanks - I think that was about where I was headed as well. It seems that "foreground window" does not mean exactly the same thing as "window with the focus" (as you say), but here's another question. With which (if any) of the above phrases is the term "active window" synonymous?

Answer:

MSFT defines the active window as "the top-level window of the application with which the user is currently working." WB defines the active window (WinGetActive, etc.) as the foreground window. Neither definition is synonymous with the window that has the focus.

User Reply:

Wouldn't the stipulation "with which the user is currently working." imply that the window also has keyboard focus? I'm not sure how the user would be working with the application if the app's foremost window didn't have focus.

Answer:

I've seen some paint programs where a floating toobar can sometimes have input focus, and it would seem the floating toolbar is the topmost window. I've even seen it when the floating toobar has keyboard focus, but the underlying window is the one responding to the mouse.

Another issue, glossed over earlier, as it did not appear in the specific test case being discussed, is the difference between a parent window - say a dialog box, and a specific control in the dialog box.

WinGetActive will return the parent window, while as cGetFocus will return the control window.

The key is "the top-level window". That has a specific meaning in Windows terminology. A button can have the input focus but it is never a top level window.

User Reply:

This has been an illuminating discussion. I think the core of my problem is probably simply the fact that cGetFocus() can return a handle to something that is not a toplevel window, something that WinActivate and friends would never do. I think that was my basic misunderstanding.
Article ID:   W16817
File Created: 2007:07:03:14:26:24
Last Updated: 2007:07:03:14:26:24