News:

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

Dialog box keyboard input

Started by RedXVII, February 15, 2006, 01:02:40 AM

Previous topic - Next topic

RedXVII

How to process keyboard input for a dialog box. Basically spent the last 3 hours searching msdn's disorganised and incomprehensible doocumentation to not find much.

Basically, I want a windows message to my DlgProc sent when someone presses enter, more specifically, when someone presses enter after entering something in an edit box. Shouldnt this be really really simple to do?

Does someone know how to do this?

Thanks  :U

zooba

It is :bg

Put a call to IsDialogMessage in your message loop, and enter should send a WM_COMMAND message for an accelerator key with ID of ID_OKAY (or whatever the equivalent is, I think it's zero or 1 :wink).

This call will also handle tabbing between controls. Don't worry. I didn't find it until I saw it here on the board. MSDN could do with some better organisation :U

Cheers,

Zooba

sinsi

Quote from: zooba on February 15, 2006, 01:49:49 AM
MSDN could do with some better organisation :U

better? some would be nice...
Light travels faster than sound, that's why some people seem bright until you hear them.

RedXVII

Errr.... what message loop?  :P Im using dialogboxparam for main window because its just easy to set up my nice interface with radasm. I dont know if you could do the same with createwindow (can you use dialog .dlg templates in createwindow?), but i wanted to use the radasm tools as it makes it so much easier to edit and see what youre gonna get when you hit run.

So right, heres what it looks like. I dont think i can use IsDialogeMessage because i have no msg loop. Maybe i should change dialoboxparam to something else to use my own message loop? Or is there a trick i could use?


start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
invoke ExitProcess,0

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

mov eax,uMsg
.if eax==WM_INITDIALOG
           .....



Cheers  :U

ramguru

If you want process input using DialogBox... you must process WM_KEYDOWN (after SetFocus etc.). In order to use message loop you need CreateDialogParam... Maybe you just need hot-key in your case...

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

mov eax,uMsg
.if eax==WM_INITDIALOG
invoke RegisterHotKey, hWin, 111, 0, VK_RETURN

.elseif eax==WM_HOTKEY
.if wParam == 111
invoke MessageBox, hWin, 0, 0, MB_OK
.endif
xor    eax, eax
ret

.elseif eax==WM_CLOSE
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

DlgProc endp



zooba

In that case, WM_KEYDOWN is your best option. WM_HOTKEY has special behaviours WRT stealing focus from other windows.

If the message loop is already taken care of, IsDialogMessage is probably in there (test by tabbing between controls - if you can it's probably there). Then you just need to handle the command message if it is send, as I said earlier. :U

RedXVII

Hmmmm ok, not sure whats going on here then. Im still using Dialogueboxparam and the tab key does indeed work. Which means that pressing enter is passed into my message loop, right? Maybe im going about this the wrong way?  :dazzled:  :eek Take a look. I read in the faithful msdn documentation that im meant to use IDOK for the enter key, but knowing MSDN this is probably rubbish, it wasnt very clear about it. Thing is, im picking nothing up in the debugger also :( . and before you think it, BN_CLICKED works fine.

.elseif eax==WM_COMMAND
mov eax,wParam
.IF lParam==0
.ELSE
mov edx,wParam
shr edx,16
.if dx==BN_CLICKED
                                        ......
.elseif dx==IDOK
.if ax==IDC_EDT2
                                        ......
.endif
.endif
.endif


Cheers  :U

zooba

The MSDN isn't quite as bad as you seem to think. :wink

Quote from: wParam
The high-order word specifies the notification code if the message is from a control. If the message is from an accelerator, this value is 1. If the message is from a menu, this value is zero.
The low-order word specifies the identifier of the menu item, control, or accelerator.

lParam
Handle to the control sending the message if the message is from a control. Otherwise, this parameter is NULL.

So you want to be checking the low word of wParam (in your code, AX) for IDOK. If this is right, you'll then have to use GetFocus to find out which control has been selected as I'm not sure it passes the control handle in this case.

Trial and error, mate :U

farrier

It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

RedXVII

Ive been fiddling with this all day. Im pretty sure IsDialogMessage is not sending an IDOK when i press enter in my edit box. I even observed it in the debugger, enter didnt do anything at all. Does anyone have a working version of that?


Thanks farrier, it looks like subclassing would do the trick, although i havent got it working fully yet.

Cheers  :U

RedXVII

Subclassing isnt working either.  :'( This is really really rubbish. Its doing as before, but it isnt sending messages when the enter key is pressed. I only wanted to do something so simple and ive spent the last 2 days on trying to get 1 key working. This is so depressing i dont think ill continue programming for about a month if this isnt complete soon.

Someone please tell me they have an example which uses a dialog box, uses isdialogmessage and does something special when enter is pressed in an edit box?

Please please help. Its driving me insane...  :'(

MichaelW

I think the IDOK message is actually triggered by the dialog box's default push button. For this to happen there must be a default push button and the edit control style must not include ES_WANTRETURN. Subclassing the edit control and trapping WM_KEYDOWN, VK_RETURN would allow you to bypass these requirements, and readily differentiate between Enter in the edit control and actuation of the default push button.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc

    DlgProc   PROTO :DWORD,:DWORD,:DWORD,:DWORD
    EditProc  PROTO :DWORD,:DWORD,:DWORD,:DWORD

    .data
        hInstance   dd 0
        oldEditProc dd 0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
    mov hInstance, rv(GetModuleHandle,NULL)
    call Main
    invoke ExitProcess, eax
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Main proc
    Dialog "TEST","MS Sans Serif",8,WS_OVERLAPPEDWINDOW,\
              2,5,5,80,60,1024
    DlgEdit WS_BORDER or WS_VSCROLL or ES_AUTOVSCROLL or ES_MULTILINE \
              or WS_TABSTOP,5,5,70,30,1000
    DlgButton "OK",WS_TABSTOP or BS_DEFPUSHBUTTON,25,42,30,10,IDOK
    CallModalDialog hInstance,0,DlgProc,NULL
    ret
Main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    .IF uMsg == WM_INITDIALOG
      invoke GetDlgItem,hWin,1000
      invoke SetWindowLong,eax,GWL_WNDPROC,EditProc
      mov oldEditProc, eax
    .ELSEIF uMsg == WM_COMMAND
      .IF wParam == IDOK
        MsgBox 0,"IDOK", "WM_COMMAND",0
      .ENDIF
    .ELSEIF uMsg == WM_CLOSE
       invoke EndDialog, hWin, 0
    .ENDIF
    return 0
DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
EditProc proc hCtl:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    .IF uMsg == WM_KEYDOWN
      .IF wParam == VK_RETURN
        MsgBox 0,"VK_RETURN","WM_KEYDOWN",0
      .ENDIF
    .ENDIF
    invoke CallWindowProc,oldEditProc,hCtl,uMsg,wParam,lParam
    ret
EditProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
eschew obfuscation

RedXVII

i dont have masm32rt.inc. So i cant compile this and am not sure of the syntax used....

know where i can get it? i googled it but got nothing

Mark Jones

"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

MichaelW

Same code with only the minimal components from masm32rt.inc:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .486
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\dialogs.inc
    include \masm32\macros\macros.asm
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

    DlgProc   PROTO :DWORD,:DWORD,:DWORD,:DWORD
    EditProc  PROTO :DWORD,:DWORD,:DWORD,:DWORD

    .data
        hInstance   dd 0
        oldEditProc dd 0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
    mov hInstance, rv(GetModuleHandle,NULL)
    call Main
    invoke ExitProcess, eax
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Main proc
    Dialog "TEST","MS Sans Serif",8,WS_OVERLAPPEDWINDOW,\
              2,5,5,80,60,1024
    DlgEdit WS_BORDER or WS_VSCROLL or ES_AUTOVSCROLL or ES_MULTILINE \
              or WS_TABSTOP,5,5,70,30,1000
    DlgButton "OK",WS_TABSTOP or BS_DEFPUSHBUTTON,25,42,30,10,IDOK
    CallModalDialog hInstance,0,DlgProc,NULL
    ret
Main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    .IF uMsg == WM_INITDIALOG
      invoke GetDlgItem,hWin,1000
      invoke SetWindowLong,eax,GWL_WNDPROC,EditProc
      mov oldEditProc, eax
    .ELSEIF uMsg == WM_COMMAND
      .IF wParam == IDOK
        MsgBox 0,"IDOK", "WM_COMMAND",0
      .ENDIF
    .ELSEIF uMsg == WM_CLOSE
       invoke EndDialog, hWin, 0
    .ENDIF
    return 0
DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
EditProc proc hCtl:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    .IF uMsg == WM_KEYDOWN
      .IF wParam == VK_RETURN
        MsgBox 0,"VK_RETURN","WM_KEYDOWN",0
      .ENDIF
    .ENDIF
    invoke CallWindowProc,oldEditProc,hCtl,uMsg,wParam,lParam
    ret
EditProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
eschew obfuscation