News:

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

WM_KEYDOWN

Started by hfheatherfox07, July 24, 2011, 02:02:34 AM

Previous topic - Next topic

hfheatherfox07

Hi I wanted to add a "keyboard sound .wav" so when you type you can here it ...

why is it that when you click on the .exe you can hear it , how to fix this?

I have used left mouse button click and that worked on other stuff

dedndave

you may not want to answer WM_KEYDOWN

here we go...
you want WM_NOTIFY, then look at the NMHDR structure (address in lParam) for NM_CHAR notification

hfheatherfox07

Quote from: dedndave on July 24, 2011, 03:10:01 AM
you may not want to answer WM_KEYDOWN

here we go...
you want WM_NOTIFY, then look at the NMHDR structure (address in lParam) for NM_CHAR notification


Thanks I will try that

MichaelW

WM_KEYDOWN is sent to the window with the keyboard focus, and as your dialog is defined that would be the edit control. If I were doing this I would switch to a modeless dialog and try intercepting WM_KEYDOWN, and WM_SYSKEYDOWN, in the message loop.
eschew obfuscation

hfheatherfox07

Quote from: MichaelW on July 24, 2011, 03:40:00 AM
WM_KEYDOWN is sent to the window with the keyboard focus, and as your dialog is defined that would be the edit control. If I were doing this I would switch to a modeless dialog and try intercepting WM_KEYDOWN, and WM_SYSKEYDOWN, in the message loop.


How would I accomplish that?

dedndave

ok, once again, edit controls are not as simple as i think they should be - lol
i tried this
.IF uMsg==WM_INITDIALOG
INVOKE SetWindowText, hWnd, addr szTitle
INVOKE SendMessage, hWnd, WM_SETICON,ICON_SMALL, hIcon

        .ELSEIF uMsg==WM_NOTIFY
        mov     edx,lParam
        .IF [edx].NMHDR.code==NM_CHAR
        INVOKE  PlaySound,2010,hInstance,SND_RESOURCE or SND_ASYNC
        .ENDIF

        .ELSEIF uMsg==WM_CHAR
        INVOKE  PlaySound,2010,hInstance,SND_RESOURCE or SND_ASYNC

.ELSEIF uMsg==WM_CLOSE
INVOKE EndDialog,hWnd,0


it seems the WM_NOTIFY and WM_CHAR messages are handled in the edit control, and are not sent to the DlgProc, as i thought
i guess you have to subclass or something, like Michael suggested
another way to go - hook the keyboard - surprised Michael didn't suggest that   :P

i did notice a couple other things, though

the ID number in the PlaySound call should match that in the resource file...
        INVOKE  PlaySound,2010,hInstance,SND_RESOURCE or SND_ASYNC

there is a problem in the batch file
the resource OBJ file winds up being named KeyBoardClicks.obj
that conflicts with the name that MASM wants to create
so, i used a REN command...
@echo off

REM change the set file name to whatever you want to name your Window.asm, .obj and .exe files.

set file=KeyBoardClicks
if exist %file%.exe del %file%.exe
SET MASMBINPATH=C:\masm32\bin
%MASMBINPATH%\rc.exe %file%.rc

%MASMBINPATH%\cvtres.exe /machine:ix86 %file%.res

ren %file%.obj rsrc.obj

%MASMBINPATH%\ml.exe /c /coff /Cp /nologo %file%.asm

%MASMBINPATH%\link.exe /SUBSYSTEM:WINDOWS %file%.obj rsrc.obj

if exist %file%.obj del %file%.obj
if exist %file%.res del %file%.res
if exist rsrc.obj del rsrc.obj

%file%.exe

notice the LINK command line

MichaelW

QuoteHow would I accomplish that?

Something like this, although WM_SYSKEYDOWN does not work as I expected, and there are problems with the Alt key that I did not try to solve.

include \masm32\include\masm32rt.inc
include \masm32\include\winmm.inc
includelib \masm32\lib\winmm.lib

DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM

.const

IDD_DIALOG1   equ 101
IDI_ICON      equ 100
IDC_EDT1      equ 102
WAV           equ 2010
.data
    szTitle       db "Key Board Clicks", 0
.data?
    hInstance dd ?
    hIcon   dd ?

    hDlg    dd ?
    msg MSG <>

.code

start:

  INVOKE GetModuleHandle,NULL
  mov hInstance,eax
  INVOKE LoadIcon, eax, IDI_ICON
  mov hIcon, eax
  INVOKE InitCommonControls
  ; ---------------------------------------------
  ;   Call the dialog box stored in resource file
  ; ---------------------------------------------
  ;INVOKE DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL

  invoke CreateDialogParam,hInstance,IDD_DIALOG1,0,ADDR DlgProc,0
  mov hDlg, eax

  msgLoop:
    invoke GetMessage, ADDR msg, 0, 0, 0
    .IF eax != 0
      SWITCH msg.message
        CASE WM_KEYDOWN
          INVOKE PlaySound,WAV,hInstance,SND_RESOURCE or NULL or SND_ASYNC
      ENDSW
      invoke IsDialogMessage, hDlg, ADDR msg
      jmp msgLoop
    .ENDIF

  INVOKE ExitProcess,0

; Dialog procedure
; ------------------------------------------------------------------------------

DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
  .IF uMsg==WM_INITDIALOG
    INVOKE SetWindowText, hWnd, addr szTitle
    INVOKE SendMessage, hWnd, WM_SETICON,ICON_SMALL, hIcon
  .ELSEIF uMsg==WM_COMMAND
      .IF wParam == WM_KEYDOWN
      .ELSEIF eax!=0
        ;mov eax, wParam
        ;shr eax, 16
        ;print hex$(eax),13,10
        ;INVOKE PlaySound,WAV,hInstance,SND_RESOURCE or NULL or SND_ASYNC
      .ENDIF
  .ELSEIF uMsg==WM_CLOSE
    INVOKE EndDialog,hWnd,0
  .ENDIF
xor eax,eax
ret
DlgProc endp

end start


eschew obfuscation

hfheatherfox07

Quote from: dedndave on July 24, 2011, 04:08:31 AM


i did notice a couple other things, though


there is a problem in the batch file
the resource OBJ file winds up being named KeyBoardClicks.obj
that conflicts with the name that MASM wants to create
so, i used a REN command...
@echo off

REM change the set file name to whatever you want to name your Window.asm, .obj and .exe files.

set file=KeyBoardClicks
if exist %file%.exe del %file%.exe
SET MASMBINPATH=C:\masm32\bin
%MASMBINPATH%\rc.exe %file%.rc

%MASMBINPATH%\cvtres.exe /machine:ix86 %file%.res

ren %file%.obj rsrc.obj

%MASMBINPATH%\ml.exe /c /coff /Cp /nologo %file%.asm

%MASMBINPATH%\link.exe /SUBSYSTEM:WINDOWS %file%.obj rsrc.obj

if exist %file%.obj del %file%.obj
if exist %file%.res del %file%.res
if exist rsrc.obj del rsrc.obj

%file%.exe

notice the LINK command line

Funny you should mention the bat file... I changed it last night to this:

@echo off
REM Add this comment to the assembley:
REM comment * ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤
REM                         Build this windows app with
REM                      "MAKEIT.BAT" on the PROJECT menu.
REM         ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤ *

set file=appname

set MASMBINPATH=C:\masm32\bin

if exist %file%.obj del %file%.obj
if exist rsrc.RES del rsrc.RES

%MASMBINPATH%\RC rsrc.rc

if errorlevel 1 goto errrsrc

%MASMBINPATH%\ml /c /coff /Cp %file%.asm

if errorlevel 1 goto errasm

%MASMBINPATH%\link /SUBSYSTEM:WINDOWS  %file%.obj rsrc.RES

if errorlevel 1 goto errlink

echo.
echo An application (%file%.exe) was created!
echo.
pause

if exist %file%.obj del %file%.obj
if exist rsrc.RES del rsrc.RES

cls
goto RunApp

:RunApp
%file%.exe
goto TheEndRun
:errlink
echo _
echo Link error
goto TheEnd

:errasm
echo _
echo Assembly Error
goto TheEnd

:errrsrc
echo _
echo Resource Link Error
goto TheEnd

:TheEnd

pause
:TheEndRun



Yes I got creative .... :bg

buy I had no idea that it effects the assembly..... why?

hfheatherfox07

Quote from: MichaelW on July 24, 2011, 04:44:28 AM
QuoteHow would I accomplish that?

Something like this, although WM_SYSKEYDOWN does not work as I expected, and there are problems with the Alt key that I did not try to solve.

include \masm32\include\masm32rt.inc
include \masm32\include\winmm.inc
includelib \masm32\lib\winmm.lib

DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM

.const

IDD_DIALOG1   equ 101
IDI_ICON      equ 100
IDC_EDT1      equ 102
WAV           equ 2010
.data
    szTitle       db "Key Board Clicks", 0
.data?
    hInstance dd ?
    hIcon   dd ?

    hDlg    dd ?
    msg MSG <>

.code

start:

  INVOKE GetModuleHandle,NULL
  mov hInstance,eax
  INVOKE LoadIcon, eax, IDI_ICON
  mov hIcon, eax
  INVOKE InitCommonControls
  ; ---------------------------------------------
  ;   Call the dialog box stored in resource file
  ; ---------------------------------------------
  ;INVOKE DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL

  invoke CreateDialogParam,hInstance,IDD_DIALOG1,0,ADDR DlgProc,0
  mov hDlg, eax

  msgLoop:
    invoke GetMessage, ADDR msg, 0, 0, 0
    .IF eax != 0
      SWITCH msg.message
        CASE WM_KEYDOWN
          INVOKE PlaySound,WAV,hInstance,SND_RESOURCE or NULL or SND_ASYNC
      ENDSW
      invoke IsDialogMessage, hDlg, ADDR msg
      jmp msgLoop
    .ENDIF

  INVOKE ExitProcess,0

; Dialog procedure
; ------------------------------------------------------------------------------

DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
  .IF uMsg==WM_INITDIALOG
    INVOKE SetWindowText, hWnd, addr szTitle
    INVOKE SendMessage, hWnd, WM_SETICON,ICON_SMALL, hIcon
  .ELSEIF uMsg==WM_COMMAND
      .IF wParam == WM_KEYDOWN
      .ELSEIF eax!=0
        ;mov eax, wParam
        ;shr eax, 16
        ;print hex$(eax),13,10
        ;INVOKE PlaySound,WAV,hInstance,SND_RESOURCE or NULL or SND_ASYNC
      .ENDIF
  .ELSEIF uMsg==WM_CLOSE
    INVOKE EndDialog,hWnd,0
  .ENDIF
xor eax,eax
ret
DlgProc endp

end start




Thanks MichaelW,
I will try it.......

hfheatherfox07

Quote from: MichaelW on July 24, 2011, 04:44:28 AM
QuoteHow would I accomplish that?

Something like this, although WM_SYSKEYDOWN does not work as I expected, and there are problems with the Alt key that I did not try to solve.


Thanks I like this idea , but the app still runs after it is closed ....

Press CTRL ALT Delete and you will see the app still running  , even though it is off on the screen...

hfheatherfox07

Strangely enough I got my example to work....

All I had to chance was to add WS_EX_CONTROLPARENT in the rsrc.rc for the Edit Control under eXeStyle ( I use ResED )

dedndave

that's great   :U
put the PlaySound call in WM_CHAR instead of WM_KEYDOWN
that way, it will click for repeated keys   :P

MichaelW

Quote from: hfheatherfox07 on July 29, 2011, 01:12:19 PM
Thanks I like this idea , but the app still runs after it is closed ....

Press CTRL ALT Delete and you will see the app still running  , even though it is off on the screen...

Sorry, I forgot to modify the dialog procedure. You destroy a modal dialog with EndDialog, but you destroy a modeless dialog the same way you would destroy a normal application window.

DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
  .IF uMsg==WM_INITDIALOG
    INVOKE SetWindowText, hWnd, addr szTitle
    INVOKE SendMessage, hWnd, WM_SETICON,ICON_SMALL, hIcon
  .ELSEIF uMsg==WM_COMMAND
      .IF wParam == WM_KEYDOWN
      .ELSEIF eax!=0
        ;mov eax, wParam
        ;shr eax, 16
        ;print hex$(eax),13,10
        ;INVOKE PlaySound,WAV,hInstance,SND_RESOURCE or NULL or SND_ASYNC
      .ENDIF
  .ELSEIF uMsg==WM_CLOSE
      invoke DestroyWindow, hWnd
  .ELSEIF uMsg==WM_DESTROY
      invoke PostQuitMessage, NULL
  .ENDIF
xor eax,eax
ret
DlgProc endp


eschew obfuscation