another problem with my mp3Player. i want to use shortcuts, like Ctrl+X. i thought i could receive them by the WM_KEYDOWN.
i have a simple window with some conrols on it. normally, if the window receives a key, the WM_KEYDOWN is sent, am i right?
but i only get a "ping"-sound!
in another proc of mine it works (huh?!). this one renders an image on a window without any controls and a tool-window-frame.
does this issue happen with the control elements? are some keys only sent to the control elements and no to the window? are there any possibilities to prevent/correct it?
Posted on 2002-11-14 16:09:03 by hartyl
As far as my knowledge goes every window recieves the 'WM_KEYDOWN'
message if they detect a keypress. Maybe one of the controls changes
this behaviour if they have keyboard/mouse input focus. But why not install
it as a 'real hotkey' instead?

You can use the api calls: RegisterHotKey, UnregisterHotKey, and then you'r
program will recieve the message 'WM_HOTKEY' whenever that key is pressed.
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

.if uMsg==WM_CREATE
;\\Register hotkey
invoke RegisterHotKey,hWnd, 49151, MOD_CONTROL, VK_X ;\\ Hotkey == CTRL+X
.elseif uMsg==WM_HOTKEY
;\\Here you put the code wich get's executed everytime the hotkey is pressed.
.elseif uMsg==WM_DESTROY
;\\Unregister hotkey
invoke UnregisterHotKey,hWnd, 49151
invoke PostQuitMessage, NULL
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
xor eax,eax
ret
WndProc endp
Posted on 2002-11-14 16:51:34 by natas
hartyl,
From the MS WM_KEYDOWN documentation:

"The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem key is pressed. A nonsystem key is a key that is pressed when the ALT key is not pressed. "

Use a debugger, and check that the windows's callback routine receives the WM_KEYDOWN message. If you cannot discover the problem that way, you may have to post to this NG, a small test version of your program that illustrates the problem. Ratch
Posted on 2002-11-14 19:01:33 by Ratch
Can someone tell me whats wrong here? I tried to work on the 'messages' a little bit.
Either my keyboard is really sticky, or something is fucked up in here...


;\\I got the number '24' from wParam when CTRL+X is pressed
.elseif uMsg==WM_CHAR
.if wParam==24;\\This works || CTRL+X
.endif
.elseif uMsg==WM_KEYDOWN
.if wParam==VK_CONTROL OR VK_X ;;\\This only works on: CTRL+Y
.endif
;\\This code executes on both 'CTRL+X' AND 'SHIFT+X'?
.if wParam==VK_SHIFT OR VK_X
.endif
Posted on 2002-11-14 19:04:41 by natas
natas,
I believe you are being done in by precedence levels. Your code of .if wParam==VK_CONTROL OR VK_X means
.if (wParam==VK_CONTROL) OR VK_X . I believe what you really want is .if (wParam==VK_CONTROL) OR (wParam==VK_X ) . Remember, == has a higher precedence level than OR, so unless you use parentheses, you won't get what you are looking for. Same goes for your other .IF statement. Ratch
Posted on 2002-11-14 19:50:28 by Ratch

natas,
I believe you are being done in by precedence levels. Your code of .if wParam==VK_CONTROL OR VK_X means
.if (wParam==VK_CONTROL) OR VK_X.

Excuse me If I am wrong, but 'OR' performs a bitwise inclusive OR on 'VK_CONTROL + VK_X).
Maybe your thinking in the same lane as in other programming languages when it comes to branching.


So you see, this:
.if wParam==VK_CONTROL OR VK_X
Can't be this:
.if (wParam==VK_CONTROL) OR (wParam==VK_X) ;\\ Is not allowed either..
[Then you need to do it like this:]
.if (wParam==VK_CONTROL) || (wParam==VK_X) ;\\ Wich performs a logical OR

VK_CONTROL == 17
VK_X == 88
17 OR 88 == 89
Posted on 2002-11-14 20:03:46 by natas
natas,
Sorry, I should have noticed it in your code earlier. Using OR in .IF will cause an error. When selecting .IF, one must use | for bitwise inclusive ORs, and || for logical ORs. Use the OR in statements like:

IF abc OR xyz ; logical in this case of conditional code assembly
do something
ENDIF

MOV EAX,hij OR klm ;bitwise for this case of making a constant

Now, you surely want to check wParam with VK_CONTROL and VK_X individually. You do NOT want to mix the bits from the two values with a bitwise OR before testing. The statement .if (wParam==VK_CONTROL) || (wParam==VK_X) will give you what you want. Ratch
Posted on 2002-11-14 20:46:22 by Ratch


.IF wParam == abc OR xyz ;bitwise OR
.ENDIF

.IF wParam == abc || wParam == xyz ;logical OR
.ENDIF
Anyway, I must have been real tired when I wrote my previously post. :rolleyes:
I didnt want to check for the keys 'VK_CONTROL/VK_X' logically. I wanted to check
if those two keys where combined, therefore I used a bitwise OR.

But that doesn't work, since WM_KEYDOWN always sends 'VK_X' even if another
key is pressed down(i.e It always sends 1 key). Why didn't I notice that before? :eek:

EDIT: Just found out that 'WM_CHAR' is case sensitive and 'WM_KEYDOWN' is not.
A.t.m this is the only thing that seems to work when you check for 'CTRL+X'


.elseif uMsg==WM_CHAR
.if wParam==24 ;\\ == CTRL+X ( NOT CASE SENSITIVE! )
.endif

Posted on 2002-11-15 00:55:14 by natas
i put a int 3 at the beginning of the DlgProc (for softice to break if i3here is on). i launched the program. softice broke several times for a WM_PAINT, WM_INITDIALOG and so on. then nothing came anymore - all messages were prcessed. i thought, if i type now some NORMAL chars or shortcuts, the DlgProc is called, to check if the WM_KEYDOWN-message is processed - NOTHING! softice didn't break, despite the int 3 at the beginning of the DlgProc! so, the message wasn't even sent!
but the idea with the "real" hotkeys is brilliant - i didn't know that something like this exists. thx natas
Posted on 2002-11-15 04:22:41 by hartyl
natas,
I looked in the MASM manual and I did not find any reference to | . So I guess that MASM does not use this symbol. I have documentation from a web site that says it does. Again I have learned that not everything on the web is correct.

To get back to your problem. I am enclosing a program called KEYVIEW1.TXT. Change the name to KEYVIEW1.EXE and run it. I translated this program from C to MASM from Charles Petzold's book Programming Windows. It shows that a Control-x or Control_X both generate an identical 5 message sequence. You are correct in using .IF == 24 to capture Control-X. Combining the bits with an inclusive OR does not make sense, because then nothing will compare correctly. Ratch
Posted on 2002-11-15 10:12:34 by Ratch
It shows that a Control-x or Control_X both generate an identical 5 message sequence. You are correct in using .IF == 24 to capture Control-X. Combining the bits with an inclusive OR does not make sense, because then nothing will compare correctly. Ratch

Ratch, I have already understood that ctrl+x/X makes an identical message.
Since the 'WM_KEYDOWN' only responds per key(but the WM_CHAR is case sensitiv).

What I cannot understand is why '24' == CTRL+X? I just know it does since I watched
the wParam when the key combnation got pressed.
Posted on 2002-11-15 13:30:57 by natas
natas,
That number is a keyboard code sent by the hardware of IBM compatible keyboards. Control-A is 01, Control-B is 2, etc. Since X is the 24th letter of the Roman alphabet, the keyboard sends 24 for Control-X. Ratch
Posted on 2002-11-15 16:29:50 by Ratch
A dialog proc???

Be aware that normal dialog box processing calls IsDialogMessage, which results in keyboard shortcuts being intercepted before the dialog box window proc calls the dialog proc.

WM_KEYUP and WM_KEYDOWN give keycodes that represent a key without regard to case. However, they do provide extra flag bits that indicate if modifier keys (e.g., shift and control) were down when the key events occurred. Because shift and control modes can exist simultaneously, you need to mask out (set to 0) the flags (and any other data) you don't want to compare.

mov eax,wParam ; get 32-bit value
and eax,(0FFH or VK_CONTROL) ; retain only character and modifier flag
.if eax == (VK_X or VK_CONTROL) ; check value
; ... rest of code

mov eax,wParam ; get 32-bit value
and eax,(0FFH or VK_CONTROL or VK_SHIFT) ; retain only character and modifier flags
.if eax == (VK_X or VK_SHIFT) ; check value, control must compare to 0
; ... rest of code

WM_CHAR is generated by TranslateMessage (from the WM_KEYUP and WM_KEYDOWN messages), and gives ANSI/Unicode codes. The codes depend on whether the shift or control keys are in effect. Lock keys also affect character codes. Control characters have values in the range 0-31 (decimal), and can be derived from printable characters. Take the character 'C' (hex 43) or character 'c' (hex 63), and zero out the three highest bits to get Control-C (hex 03).

Here are some control codes and their ASCII (ANSI) equivalents:

Control-G, BEL (bell)
Control-H, BS (backspace)
Control-I, HT (horizontal TAB)
Control-J, LF (line feed)
Control-L, FF (form feed)
Control-M, CR (carriage return)
Control-[, ESC
Posted on 2002-11-15 16:31:42 by tenkey
Ratch,
Thanks a bundle for clearing that up! I have a tendency to get
a little annoyed, when I cant find the answer for little things like that. :alright:
Posted on 2002-11-15 16:34:20 by natas
huh?! you guys make me a little bit weired...

i create my dialogbox using DialogBoxParam - is it wrong to do that? does the dialogbox catch my WM_KEYDOWN message and not send to me (my DlgProc)? if i create it with the WNDCLASSEX, will it work then?

i've tried RegisterHotKey - for some purposes it's good. but i want to make a "jump"-window, with the shortcut "j", so if i put the HotKey, i can't type any 'J's anymore. for the play-control it's quite good, so i jump to the next song even while playing a game!
Posted on 2002-11-16 06:58:10 by hartyl