The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: xanatose on May 11, 2010, 10:13:59 PM

Title: keyboard sound?
Post by: xanatose on May 11, 2010, 10:13:59 PM
What will be the best way to hook up to the computer keyboard so that it plays a typewriter sound every time a key is pressed.

I basically want to make a personal toy :)
Title: Re: keyboard sound?
Post by: qWord on May 11, 2010, 11:44:18 PM
this should give you a idea how it could be done  :bg:
include masm32rt.inc
WndProc     proto :DWORD,:DWORD,:DWORD,:DWORD
.data
.data?
    keys1       db 256 dup (?)
    keys2       db 256 dup (?)
   
    hInstance   dd ?
    wcex        WNDCLASSEX <>
    msg         MSG <>
.code

start:
    xor edi,edi
    .while edi < 256
        invoke GetAsyncKeyState,edi
        mov keys1[edi],ah
        inc edi
    .endw

    mov hInstance,rv(GetModuleHandle,0)
    mov wcex.hInstance,eax
    mov wcex.cbSize,SIZEOF WNDCLASSEX
    mov wcex.style, CS_HREDRAW or CS_VREDRAW
    mov wcex.lpfnWndProc, OFFSET WndProc
    mov wcex.cbClsExtra,NULL
    mov wcex.cbWndExtra,NULL
    mov wcex.hbrBackground,rv(CreateSolidBrush,0ffffffh)
    mov wcex.lpszMenuName,NULL
    mov wcex.lpszClassName,chr$("SomeClass32")
    mov wcex.hIcon,rv(LoadIcon,NULL,IDI_APPLICATION)
    mov wcex.hIconSm,eax
    mov wcex.hCursor,rv(LoadCursor,NULL,IDC_ARROW)
    invoke RegisterClassEx, OFFSET wcex
    fn CreateWindowEx,NULL\
                     ,wcex.lpszClassName\
                     ,"keys"\
                     ,WS_OVERLAPPEDWINDOW\
                     ,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT\
                     ,NULL\
                     ,NULL\
                     ,hInstance\
                     ,NULL
    mov   edi,eax

    invoke ShowWindow,edi,SW_SHOWNORMAL
    invoke UpdateWindow,edi

    .while 1
        .break .if !rv(GetMessage,OFFSET msg,0,0,0)
        invoke TranslateMessage, OFFSET msg
        invoke DispatchMessage, OFFSET msg
    .endw
    invoke ExitProcess,msg.wParam


WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .if uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
    .elseif uMsg == WM_CREATE
        invoke SetTimer,hWnd,0,1000/30,0    ; 30 times per second
    .elseif uMsg == WM_TIMER
        push ebx
        xor ebx,ebx
        .while ebx < 256                    ; get all key states
            invoke GetAsyncKeyState,ebx
            mov keys2[ebx],ah
            inc ebx
        .endw
        xor ebx,ebx
        .while ebx < 256
            movzx eax,keys1[ebx]
            movzx ecx,keys2[ebx]
            mov keys1[ebx],cl
            and eax,80h
            and ecx,80h
            .if !eax && ecx && ebx >= VK_A && ebx <=VK_Z
                invoke MessageBeep,MB_OK
            .endif
            inc ebx
        .endw
        pop ebx
    .else
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif

    xor eax,eax
    ret
WndProc endp
end start
Title: Re: keyboard sound?
Post by: BlackVortex on May 12, 2010, 12:41:46 AM
I would set a global keyboard hook with SetWindowsHookEx and then every time a key is pressed your callback function is called.

That timer + GetAsyncKeyState looks like a very bad idea to me.
Title: Re: keyboard sound?
Post by: qWord on May 12, 2010, 12:53:01 AM
Quote from: BlackVortex on May 12, 2010, 12:41:46 AMThat timer + GetAsyncKeyState looks like a very bad idea to me.
well, it doesn't required a dll injection (which is done by SetWindowsHookEx)
Title: Re: keyboard sound?
Post by: BlackVortex on May 12, 2010, 03:29:52 AM
So ? There is no performance loss, it's actually much much better. That's exactly what that function is for.
Title: Re: keyboard sound?
Post by: oex on May 12, 2010, 11:02:07 AM
While they consider the complexities of the first half of the question I'll answer the second half :lol

invoke PlaySound, chr$("C:\masm32\typewriter.wav"), NULL, SND_FILENAME or SND_ASYNC