News:

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

KeyPress Control While Program is running?

Started by silentenigma, October 13, 2009, 01:32:56 PM

Previous topic - Next topic

silentenigma

Hello everyone;
I am trying to write a small program(for improve my asm) that controls CAPS, NUM and SCROLL. I achieved to control those are pressed or not while program initalize. But I cant Control them while program is running.

I mean:
WM_INITDIALOG = before dialog appears process the commands
WM_COMMAND   = when a button is pressed process the commands
????????             = while program is running make these command. I am searching for that

According to the info above i think my problem is that.

Best Regards;
Thanks who 'd like to help
My heart is ripped out,
Chained on my boots
Look deep inside mey soul with pain,
Witness the fall of a hero

jj2007

Normally, this is for use in a loop. Welcome to the forum :thumbu

include \masm32\include\masm32rt.inc

KeyPressed MACRO VK_whatever
  invoke GetKeyState, VK_whatever ; GetKeyState returns a WORD
  .if sword ptr ax>=0
xor eax, eax
  .endif
  EXITM <eax>
ENDM

.code
AppName db "Masm32:", 0

start: MsgBox 0, "Hello World", addr AppName, MB_OK
.if KeyPressed(VK_SHIFT)
MsgBox 0, "You pressed Shift", addr AppName, MB_OK
.else
MsgBox 0, "You did not press Shift", addr AppName, MB_OK
.endif
exit

end start

silentenigma

Thanks for your post. But i already control that if CAPS,NUM or SCROLL button is pressed or not. Look:

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

mov eax,uMsg
.if eax==WM_INITDIALOG


invoke GetDlgItem,hWin,1001 ;CAPS handle
mov hBtn,eax
invoke GetKeyState,VK_CAPITAL; is caps pressed
.if ax==0
invoke EnableWindow,hBtn,FALSE;if no than label is Disabled
.else
invoke EnableWindow,hBtn,TRUE;if yes CAPS label is enabled
.endif

;same process for NUM&SCROLL
invoke GetDlgItem,hWin,1002
mov hBtn,eax
invoke GetKeyState,VK_NUMLOCK
.if ax==0
invoke EnableWindow,hBtn,FALSE
.else
invoke EnableWindow,hBtn,TRUE
.endif

invoke GetDlgItem,hWin,1003
mov hBtn,eax
invoke GetKeyState,VK_SCROLL
.if ax==0
invoke EnableWindow,hBtn,FALSE
.else
invoke EnableWindow,hBtn,TRUE
.endif


If you see i can get info of these three buttons pressed status at the first beginning of the program.

But my question is to get these info while progrm is running!!!
My heart is ripped out,
Chained on my boots
Look deep inside mey soul with pain,
Witness the fall of a hero

MichaelW

I'm not sure how good of an example this is, but it was easy to code and it does demonstrate one method of polling the toggle key state (build as a Console app).

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\winmm.inc
    includelib \masm32\lib\winmm.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      timerId   dd 0
      hEvent    dd 0
      CL_state  dw -1
      NL_state  dw -1
      SL_state  dw -1
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

TimeProc proc uID:DWORD, uMsg:DWORD, dwUser:DWORD, dw1:DWORD, dw2:DWORD

    invoke GetKeyState, VK_CAPITAL
    ;------------------------------------------------------
    ; Update the display only if the toggle state changes.
    ;------------------------------------------------------
    .IF ax != CL_state
        mov CL_state, ax
         loc 0,0
        .IF CL_state & 1
            print "C"
        .ELSE
            print "c"
        .ENDIF
        loc 3,0
    .ENDIF

    invoke GetKeyState, VK_NUMLOCK
    .IF ax != NL_state
         mov NL_state, ax
         loc 1, 0
        .IF NL_state & 1
            print "N"
        .ELSE
            print "n"
        .ENDIF
        loc 3,0
    .ENDIF

    invoke GetKeyState, VK_SCROLL
    .IF ax != SL_state
         mov SL_state, ax
         loc 2, 0
        .IF SL_state & 1
            print "S"
        .ELSE
            print "s"
        .ENDIF
        loc 3,0
    .ENDIF

    invoke GetKeyState, VK_ESCAPE
    .IF ax & 8000h
        invoke SetEvent, hEvent
    .ENDIf

    ret

TimeProc endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    ;---------------------------------------------
    ; Start a multimedia timer that will call the
    ; TimeProc callback once every 10ms.
    ;---------------------------------------------

    invoke timeSetEvent, 10, 1, TimeProc, 0, TIME_PERIODIC
    mov timerId, eax

    ;------------------------------------------------------
    ; Create a manual-reset event object that the TimeProc
    ; callback will set to the signaled state when the user
    ; presses the Escape key.
    ;------------------------------------------------------

    invoke CreateEvent, 0, TRUE, FALSE, NULL
    mov hEvent, eax

    ;----------------------------------------------
    ; The multimedia timer runs in its own thread.
    ; Block execution of the primary thread until
    ; the TimeProc callback sets the event object
    ; to the signaled state.
    ;----------------------------------------------

    invoke WaitForSingleObject, hEvent, INFINITE

    ;-------------------------
    ; Cancel the timer event.
    ;-------------------------

    invoke timeKillEvent, timerId

    print chr$(13,10,13,10)

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


In a gui app you could use the SetTimer function to set up the timer, and then poll the toggle key state in your WM_TIMER handler or in a TimerProc function.
eschew obfuscation

silentenigma

@MichaelW : Thanks for your reply. But after building your small program it didnt worked!. Anyway The thing that i want is actually simple!
Just kontrol the keypress event while program is running. I mean, i can control it before the dialog box appers (i wrote the code above), but i want to control if the CAPS pressed or not, after dialogbox appears!!

I wish i am clear. :'(
My heart is ripped out,
Chained on my boots
Look deep inside mey soul with pain,
Witness the fall of a hero

MichaelW

The attachment is a dialog app that runs the code from your WM_INITDIALOG handler in a WM_TIMER handler. The timer is set so a WM_TIMER message is sent every 10ms.
eschew obfuscation

silentenigma

@MichaelW : Great Thanks dude. This was what i want. I compiled my own source. Now according to your source i want to asked some related questions.

1.We used SetTimer for control the keypress WHILE program is RUNNING. Why cant we use WM_KEYUP/WM_KEYDOWN to get those keys state while program is running?
2.Using SetTimer is the only way to make some process while program is running?

Best Regards
thanks again.
My heart is ripped out,
Chained on my boots
Look deep inside mey soul with pain,
Witness the fall of a hero

MichaelW

QuoteWhy cant we use WM_KEYUP/WM_KEYDOWN to get those keys state while program is running?

WM_KEYUP/WM_KEYDOWN, and similar messages, are sent to the window with the keyboard focus. If some other application had the keyboard focus when one of the toggle keys was pressed, the state of the toggle would change, but your dialog would not be notified.
eschew obfuscation

BlackVortex

I admit I haven't followed this thread, but if we're tlaking about keyboard hooks, SetWindowsHookEx is tha bomb !

silentenigma

Quote from: MichaelW on October 17, 2009, 10:14:08 AM
WM_KEYUP/WM_KEYDOWN, and similar messages, are sent to the window with the keyboard focus. If some other application had the keyboard focus when one of the toggle keys was pressed, the state of the toggle would change, but your dialog would not be notified.

1. Michael what do you mean by keyboard focus?
2.You said your dialog would not ne notified, do mean that my application would not response to any key press?

Quote from: BlackVortex on October 17, 2009, 11:40:33 AM
I admit I haven't followed this thread, but if we're talking about keyboard hooks, SetWindowsHookEx is tha bomb !

Dear BlackVortex, i am talking and asking about key pressing! Can you open up keyboard hook a bit? So i can understand what do you want to say. Thanks


Thanks both of you for your answers:)
My heart is ripped out,
Chained on my boots
Look deep inside mey soul with pain,
Witness the fall of a hero

BlackVortex

Well, with the SetWindowsHookEx you can use it with the WH_KEYBOARD parameter and it lets you create a callback procedure of this type :
http://msdn.microsoft.com/en-us/library/ms644984%28VS.85%29.aspx

So you get notified about key presses and you can act on them. It's useful for programs to set up global keyboard hooks/shortcuts, trainers etc.

But reading your original post I'm kinda confused on the purpose of your program. Do you want to change the state of the keys or monitor them for change ?

silentenigma

Quote from: BlackVortex on October 17, 2009, 03:47:59 PM
But reading your original post I'm kinda confused on the purpose of your program. Do you want to change the state of the keys or monitor them for change ?

No BlackVortex, my aim is same as the sample that MichaelW sent above. It is just simple. Think about a small dialogbox, 3 buttons or labels (CAPS/NUM/SCROLL). When capslock is on CAPS label turns enabled(so the others), when it is off label turns disabled. I made it thanks MichaelW. I made it by SetTimer func.

But i want to learn something more(cuz i am still learning asm). I want to manage controlling if a key is pressed or not while program is running. And i want to made it by not using a Timer!.

So i asked again that what is a keyboard hook. And can i control these keys by using KeyboardProc Function?
My heart is ripped out,
Chained on my boots
Look deep inside mey soul with pain,
Witness the fall of a hero

BlackVortex

Well, your callback function will be called each time a keyboard event happens. Then you can do whatever you want and either pass the key event to the next program in the hook chain, or not, effectively "swallowing" the key event as if it never happened.

You should make a test for yourself, set up a global hook and make it beep when a specific key is pressed. For example "F2"

Start here :
http://msdn.microsoft.com/en-us/library/ms644990%28VS.85%29.aspx