The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: hfheatherfox07 on September 02, 2011, 03:11:46 AM

Title: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 02, 2011, 03:11:46 AM
Hi;
I was wondering how to  Set/Kill Focus events when the window get or lose focus 

I am familiar with setting focus on an edit window or even the main window ...but how does the app know when it is out of focus?

I have found WM_KILLFOCUS .... I have even thought of setting WM_SETFOCUS state to true at the beginning but how does a window know wen you clicked out side of it?

What I am using this for is my windows 7 Aero glass theme... it seems that when a window loses focus the close button turns gray ... I want to make the Aero Glass skin as correct as possible!

Thank you
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 02, 2011, 03:16:47 AM
WM_KILLFOCUS and WM_SETFOCUS are messages that your DlgProc will receive to inform you that focus has changes
you use the SetFocus function to change the focus between windows
if you invoke that function, you will receive the appropriate message if it alters the state of your window
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 02, 2011, 03:21:04 AM
Quote from: dedndave on September 02, 2011, 03:16:47 AM
WM_KILLFOCUS and WM_SETFOCUS are messages that your DlgProc will receive to inform you that focus has changes
you use the SetFocus function to change the focus between windows
if you invoke that function, you will receive the appropriate message if it alters the state of your window

I use that  a lot with the edit boxes examples that I did ,  how does the window know when it lost focus ... I can not visualize what that command is ....
in a window you have  mouse clicks commands .... what do you have for out side the window?
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 02, 2011, 03:22:19 AM
Quotehow does the window know when it lost focus
it receives WM_KILLFOCUS   :P

for mouse clicks outside the window, like keypresses when you don't have focus, your window receives no message

what you are seeing may be related to the default button
or - it may become disabled

you can enable/disable buttons with SendDlgItemMessage
WM_ENABLE
WM_DISABLE

you can set the default button with SendMessage
DM_SETDEFID

sometimes, you may have to use BM_SETSTYLE to "turn off" the default state of a button
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 02, 2011, 03:27:37 AM
How does it receive the WM_KILLFOCUS is it automatic when you click off the window? that would be nice ... I can just use that to change the button bmp

I looked at a few skinned examples in other languages and they seem to have a resource for that color ;
so the there is 3 of each , button over, button down, button up... except the close button has an extra one for out of focus
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 02, 2011, 03:33:11 AM
http://msdn.microsoft.com/en-us/library/bb775945%28v=VS.85%29.aspx
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 02, 2011, 03:36:59 AM
Ah thanks !
it seems that BN_KILLFOCUS does that

BN_KILLFOCUS Notification Code

Sent when a button loses the keyboard focus. The button must have the BS_NOTIFY style to send this notification code.

The parent window of the button receives this notification code through the WM_COMMAND message.


I just have to make that happen  :bg
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 04, 2011, 10:52:28 PM
Quote from: dedndave on September 02, 2011, 03:22:19 AM
Quotehow does the window know when it lost focus
it receives WM_KILLFOCUS   :P

for mouse clicks outside the window, like keypresses when you don't have focus, your window receives no message

what you are seeing may be related to the default button
or - it may become disabled

you can enable/disable buttons with SendDlgItemMessage
WM_ENABLE
WM_DISABLE

you can set the default button with SendMessage
DM_SETDEFID

sometimes, you may have to use BM_SETSTYLE to "turn off" the default state of a button

Since you brought it up .... How to you send the command  WS_DISABLED and WM_ENABLE also how do you send the command WS_GRAYED    .....

I  would love to know ... i realize now we use invoke EnableWindow .... but I saw an example of that in MASMv7 although the command WS_GRAYED is used for a menu item ... I can not get it sent to a button....


Oh, and here is that example with changing the button color with BN_KILLFOCUS and BN_SETFOCUS if any body wants it.... :U
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: Gunner on September 04, 2011, 11:32:34 PM
Everything you are asking is documented.  All you have to do is search msdn OR download the psdk.  You don't "send" WS_DISABLED,  WS = Window Style.  The docs say to enable/disable a window use EnableWindow.  You could use GetWindowLong to get the style bits for the window, change the WS_DISABLED bit, then call SetWindowLong with the new value... then you have to call SetWindowPos to make the changes.  You CAN send the Message WM_ENABLE with SendMessage to enable/disable windows, I would use EnableWindow since I think it does some house keeping in the background on internal structures...
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 04, 2011, 11:45:59 PM
here's a little tip for you...

instead of
.ELSEIF  uMsg == WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
and eax,0ffffh


you can
.ELSEIF  uMsg == WM_COMMAND
movzx eax,word ptr wParam
movzx edx,word ptr wParam+2


be careful to use the right instruction
for some things, like WM_MOUSEWHEEL, the value is a signed distance - then you would want MOVSX instead of MOVZX

QuoteWS_DISABLED and WM_ENABLE  also how do you send the command WS_GRAYED

WS_ prefixes are for window styles
WM_ prefixes are for window messages

anyways - i am not sure those messages are what we really want - they apply more to windows than buttons
to disable a pushbutton, you simply ignore the WM_COMMAND messages it sends
you could store a global variable to store the enable/disable state of the buttons,
then check that variable before processing messages received from the button

grayed elements are usually menu items
although, the regular close box may be grayed because it is actually a custom drawn system menu item

not sure how to gray out pushbutton text - haven't tried that, yet
it is easy with a checkbox or radio button
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 04, 2011, 11:53:50 PM
Thank for the replies ..... I Googled it and I ran into a winasm thread entitled "How to send WS_DISABLED"   http://www.winasm.net/forum/index.php?showtopic=2749


I think that through me off.... well at least it was educational for me .... I am embarrassed :red to say that I use theses a lot but never realized that

WS_ prefixes are for window styles
WM_ prefixes are for window messages

:red :red
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 04, 2011, 11:56:29 PM
fix your link   :bg
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 04, 2011, 11:57:37 PM
Quote from: dedndave on September 04, 2011, 11:56:29 PM
fix your link   :bg


Thanks just did ...too many pages opened at once ...sorry  :red

boy my face is red a lot today
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 05, 2011, 12:00:16 AM
well - if you can do it with EnableWindow, then sending WM_ENABLE should work, too
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 05, 2011, 12:04:43 AM
Quote from: dedndave on September 05, 2011, 12:00:16 AM
well - if you can do it with EnableWindow, then sending WM_ENABLE or WM_DISABLE should work, too

What did you think of my example that I posted ? 

I think you may have been right after all .... I think what I am seeing is the effect of the button being disabled .when the window losses focus... I got it to work ....but with 3 states per each button,
like in the "aero glass" I don't see this being the solution.... :(
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 05, 2011, 12:07:30 AM
WM_ENABLE
wParam...
Indicates whether the window has been enabled or disabled. This parameter is TRUE
if the window has been enabled or FALSE if the window has been disabled.

so, you can send the message with 1 of 3 functions
PostMessage
SendMessage
SendDlgItemMessage

for the first 2 functions, hWnd is the button handle
for the last one, hDlg is the dialog box handle, and nIDDlgItem is the button ID

for all of them...
Msg is WM_ENABLE
wParam is TRUE/FALSE
lParam is NULL
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 05, 2011, 12:09:30 AM
now - as to making the self-made buttons look and act like the OS buttons   :P

if you really want something different for that, you can probably draw it like the OS does - as a custom-drawn menu
you are trying to make pushbuttons act like menu items, which they are not
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 05, 2011, 12:09:58 AM
Quote from: dedndave on September 05, 2011, 12:00:16 AM
well - if you can do it with EnableWindow, then sending WM_ENABLE should work, too

here is the code:

mov eax,uMsg
.if eax==WM_INITDIALOG
invoke GetDlgItem,hWin,1002
mov hBtn,eax

.elseif eax==WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
and eax,0FFFFh
.if edx==BN_CLICKED
.if eax==1001
invoke SetWindowText,hWin,offset NewCaption
.elseif eax==1002
invoke EnableWindow,hBtn,0
.elseif eax==1003
invoke EnableWindow,hBtn,1

Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 05, 2011, 12:11:24 AM
 :U
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 05, 2011, 12:13:55 AM
Quote from: dedndave on September 05, 2011, 12:07:30 AM
WM_ENABLE
wParam...
Indicates whether the window has been enabled or disabled. This parameter is TRUE
if the window has been enabled or FALSE if the window has been disabled.

so, you can send the message with 1 of 3 functions
PostMessage
SendMessage
SendDlgItemMessage

for the first 2 functions, hWnd is the button handle
for the last one, hDlg is the dialog box handle, and nIDDlgItem is the button ID

for all of them...
Msg is WM_ENABLE
wParam is TRUE/FALSE
lParam is NULL

Thank you !  :U
I was looking to learn more ways of doing things ...I will give this  a try when I get home tonight...

Since we are on this topic, just found the examples (not mine)
basics.zip has the buttons
basics2.zip has the the menu

but they use invoke EnableWindow

I was looking to learn what you just wrote  :U

Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 05, 2011, 12:59:39 AM
some additional info from EnableWindow documenation...

QuoteIf the window is being disabled, the system sends a WM_CANCELMODE message. If the enabled state of
a window is changing, the system sends a WM_ENABLE message after the WM_CANCELMODE message.
(These messages are sent before EnableWindow returns.) If a window is already disabled, its child
windows are implicitly disabled, although they are not sent a WM_ENABLE message.

in Community Content...

QuoteSome care is needed if using this to disable a dialog box control.  If the control had focus when it becomes disabled,
the focus might be stranded.  See http://blogs.msdn.com/b/oldnewthing/archive/2004/08/04/208005.aspx
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 05, 2011, 02:00:01 AM
i was just playing with the one you named "bmp Button Grayed when not in focus"

i noticed that a regular close button behaves the same way   :P
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 05, 2011, 02:09:54 AM
Quote from: dedndave on September 05, 2011, 02:00:01 AM
i was just playing with the one you named "bmp Button Grayed when not in focus"

i noticed that a regular close button behaves the same way   :P

can you upload it? not home right did not have the chance to mess around yet
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 05, 2011, 02:23:42 AM
(http://img148.imageshack.us/img148/2766/closebox.png)
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 05, 2011, 02:26:15 AM
Thanks ....

Well that answers that than .....

I think you were right .... I was seeing the effect of the button being disabled and not a gray button skin.....

I think I will go that route  :U
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: hfheatherfox07 on September 15, 2011, 09:48:05 PM
Quote from: dedndave on September 05, 2011, 12:07:30 AM
WM_ENABLE
wParam...
Indicates whether the window has been enabled or disabled. This parameter is TRUE
if the window has been enabled or FALSE if the window has been disabled.

so, you can send the message with 1 of 3 functions
PostMessage
SendMessage
SendDlgItemMessage

for the first 2 functions, hWnd is the button handle
for the last one, hDlg is the dialog box handle, and nIDDlgItem is the button ID

for all of them...
Msg is WM_ENABLE
wParam is TRUE/FALSE
lParam is NULL

I Finally got around to this.... ::)

This does not seem to work
Title: Re: Set/Kill Focus events when the window get or lose focus
Post by: dedndave on September 16, 2011, 12:12:39 AM
yah - it is more or less intended for windows - not buttons   :P

there are a few finer points to the code
for WM_COMMAND, wParam LOW WORD is the ID
also, use the IDC values as you have assigned them
it makes it easier to change values and to read the code
here are a few changes....
; Get the Button handle
        INVOKE  GetDlgItem,hWnd,IDC_BTN2
        mov     hBtn,eax
;
;
;

.ELSEIF uMsg == WM_COMMAND

        movzx   eax,word ptr wParam

.IF eax==IDC_BTN1 ; If BTN1 is pressed - Disable BTN2
invoke EnableWindow,hBtn,FALSE
.ENDIF

.IF eax==IDC_BTN3 ; If BTN3 is pressed - Enable BTN2
invoke EnableWindow,hBtn,TRUE
.ENDIF

.IF eax==IDC_CLOSE
INVOKE SendMessage,hWnd,WM_CLOSE,0,0
.ENDIF