News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Getting Focus

Started by Jimg, August 04, 2005, 03:52:31 PM

Previous topic - Next topic

Jimg

I have another Newbie type question :(

I have a dialog as main program.  While the program is running, the user can click on some other program or the desktop or whatever, and my program loses focus.  What is the best message in the dlgproc to trap to know when the focus is returned to my dialog or anything in it?  I need to update my information in case the user made changes to the desktop, specifically moving icons around, while he was gone.  By best message, I suppose I mean the last general one where all the painting and whatever is done, and things have settled down.  I'm really hazy on the order of events in a situation like this or what I should be looking for.

PBrennick

Jimq,
GetFocus will return the handle of the current open window, dialogbox or control.  Since you already know what your handles are, just call the API and do a compare.
Paul
The GeneSys Project is available from:
The Repository or My crappy website

Mark Jones

You could toggle on the WM_ACTIVATE message.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Jimg

Thanks Paul.

Mark-
  Yeah, WM_ACTIVATE would have been my guess.  The problem is it is only a guess and I would prefer some definitive statement from someone who knows the actual answer or at least what Microsoft recommends.  I also get a WM_USER message after the activate.  Anyone know if this is always the case or just some quirk of my program?  If it's reliable, it's a little cleaner to use than WM_ACTIVATE.

hutch--

Jim,

If you actually want an app to stay on top you can set the zorder property for its main window with SetWindowPos() and will not disappear when something else gets the focus.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Jimg

Thanks Hutch.  No, in this app I would encourge the user to move the desktop icons around, I just wanted to know when he was done and came back to the app.  I think I'll do a postmessage when I get the activate, and let all the other stuff run it's course before doing anything.

tenkey

Well, I went to MSDN and when I looked at the SetFocus API, they mentioned two messages WM_KILLFOCUS and WM_SETFOCUS.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

Tedd

When your app loses focus, it will receive a WM_KILLFOCUS message (with wParam set to the 'new' window's handle.)
When it gains focus, it receives a WM_SETFOCUS message (with wParam set to the 'old' window's handle.)

You will receive a WM_SETFOCUS message just after creation (when your window becomes the foreground), and then any other time you regain focus.

Repainting is actually done lazily. Whenever you receive a WM_PAINT message, it's actually because there are no other relevant messages in your queue (and there is a region that needs updating.)


Tracking access to the desktop through wm_killfocus probably isn't very reliable though - a user could easily move to another window, and then onto the desktop, yet you would have no indication of this.

Random thoughts:
- some kind of mouse hooking; or
- if you only need to know which icons have changed then you only need to know when your app regains focus, and then just compare the positions of the icons with their previously known positions.
No snowflake in an avalanche feels responsible.

Jimg

Quote- if you only need to know which icons have changed then you only need to know when your app regains focus, and then just compare the positions of the icons with their previously known positions.
Thanks Tedd, that's exactly what I intended to do :wink

Interesting.   After much testing, these are the messages I always get when my app gets focus  (using alt-tab to return the focus to the app)-

In this order:

WM_WINDOWPOSCHANGING = 00000046h
WM_WINDOWPOSCHANGED = 00000047h
WM_ACTIVATEAPP = 0000001Ch
WM_NCACTIVATE = 00000086h
WM_GETTEXT = 0000000Dh
WM_ACTIVATE = 00000006h
WM_USER = 00000400h

I get a whole lot of other messages (mouse movement, etc.)  but these are the only consistant messages

I never see the wm_setfocus message at all????  I don't know if any of these are the result of calling PrintHex from the debug library to print out the values.

I find that last WM_USER strangely attractive.  I'm not sending it, and it's supposed to be for my use.  Is this something used by the debug library?

PBrennick

Jimg,
wm_setfocus is a message you send, not receive.  The earlier mention of this was probably a typo.  Using GetFocus is all you need to do as all you are interested in is if your message queue has reawakened.  When it reawakens, you can check the icon positions.  Until they return to your window, it does not matter if they give focus to another window as you do not need to update until the user is active in your window.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

Jimg

Hi Paul-

I must be misunderstanding the GetFocus function.  As I read it, I have to execute the GetFocus function to find out which window currently has the (keyboard) focus.  So I would have to continually execute GetFocus to find out when I lose focus, and when it returns.  This would be like setting up a timer that ticks every few milliseconds and executes the GetFocus?  I really don't like that kind of situation, it's bad enough the windows wastes all that time polling, it should just tell me.  Again, maybe I'm just misunderstanding the function.

Mark Jones

I thought WM_ACTIVATE was simple enough solution. Whenever your window becomes active, BANG, you get a WM_ACTIVATE message. Unless I missed something? Try this in your main loop:


        .elseif uMsg==WM_ACTIVATE
            invoke Beep,500,500
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Jimg

Hi Mark-

Yes, I think so too (although it's a little more complicated than that, I seem to get activates at odd-ball times not just when the focus returns to me).  I was just trying to respond to Paul and not doing a very good job of it.

PBrennick

Jimg,
I don't mind whose method you use and Mark is a good coder.  But remember one thing, according to what you want to do you will be running some kind of loop no matter what method you use and it 'does' tell you.  You just are not understanding what I am saying.  You do not add another loop.  The message loop you are already using is good enough.  All I am saying is you can be doing anything you want and then if your message loop tells you there is a message, see if your window has focus.  The reason this is better than WM_ACTIVATE is because for 'this particular test' you do not carewhat uMsg contains.  All you care is if it contains something.  Then and only then, you issue a GetFocus and compare it to the handle of your message.  The normal loop processor will handle the contents of uMsg.  If you decide to use Marks method, there are problems with it.  If your window has focus and the screensaver fires, it will lose focus.  When the screensaver shuts down, your window will regain focus as it was the last window to have focus before the event.  When this happens WM_ACTIVATE will trigger a message and you will respond to an improper event.  Read every thing you can and then try the methods that make sense to you.  We just want to help.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

Mark Jones

Quote from: PBrennick on August 06, 2005, 12:50:09 AM
Jimg,
I don't mind whose method you use and Mark is a good coder.

Ha! Thanks Paul, but I think you should reserve "good" for someone with some actual skillz. :bg

Quote...When this happens WM_ACTIVATE will trigger a message and you will respond to an improper event.  Read every thing you can and then try the methods that make sense to you.  We just want to help.

Indeed. WM_ACTIVATE just seemed simple to use, but it's bound to have its share of issues. Still, in the land of endless oodles and oodles of code, simple is good. :)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08