Author Topic: WM_CHAR in dialogbox procedure  (Read 531 times)

jimg

  • Member
  • **
  • Posts: 196
WM_CHAR in dialogbox procedure
« on: August 30, 2017, 11:09:52 AM »
I threw together a quickie dialog using DialogBoxIndirectParam.   I just wanted some specialized keyboard input for a program I am working on.
There are no controls on the dialog, I am just handling everything directly in the dialog code.

The dialogbox procedure does not receive the WM_CHAR message.
The only useful message to get keyboard input is the WM_KEYDOWN message.
I tried returning  DLGC_WANTCHARS or DLGC_WANTALLKEYS in response to the WM_GETDLGCODE message, but still no WM_CHAR message.
Normally the WM_CHAR message would be sent as the result of the TranslateMessage function, but that is not really for use within a dialog and didn't work.

I finally kludeged a workaround with the code:
Code: [Select]
    .elseif eax==WM_KEYDOWN
            .data?
            kbs db 256 dup (?)
            chout dd ?
            .code 
            mov edx,lParam
            shr edx,16
            and edx,0ffh
            mov chout,0
            invoke GetKeyboardState,addr kbs
            invoke ToAscii,wParam,edx,addr kbs,addr chout,0
            ; ascii character returned in chout
but I'm thinking there is probably a much cleaner way to get the ascii character from the keyboard.  I don't want to use an edit control which causes more trouble than it solves in my particular circumstance.

Any suggestions?

jj2007

  • Member
  • *****
  • Posts: 7756
  • Assembler is fun ;-)
    • MasmBasic
Re: WM_CHAR in dialogbox procedure
« Reply #1 on: August 30, 2017, 05:18:22 PM »
Hi Jim,
Can't help you without seeing complete code but you are not alone with your problem. Hope it helps...

sinsi

  • Member
  • *****
  • Posts: 1006
Re: WM_CHAR in dialogbox procedure
« Reply #2 on: August 30, 2017, 05:26:31 PM »
Does it have to be a dialog? Why not a simple RegisterClassEx/CreateWindowEx?
I can walk on water but stagger on beer.

jj2007

  • Member
  • *****
  • Posts: 7756
  • Assembler is fun ;-)
    • MasmBasic
Re: WM_CHAR in dialogbox procedure
« Reply #3 on: August 30, 2017, 06:13:33 PM »
There are no controls on the dialog, I am just handling everything directly in the dialog code.... I don't want to use an edit control which causes more trouble than it solves in my particular circumstance.

If there was an edit control, subclassing would work, see attachment: The edit field doesn't accept chars between "e" and "z".

aw27

  • Member
  • ****
  • Posts: 855
  • Let's Make ASM Great Again!
Re: WM_CHAR in dialogbox procedure
« Reply #4 on: August 30, 2017, 06:56:26 PM »
With the information you provided I can only suggest that you pick the WM_CHAR from the main loop and send it to the dialog with a:

invoke SendMessage, myDialogHwnd, msg.message, msg.wParam, msg.lParam

jimg

  • Member
  • **
  • Posts: 196
Re: WM_CHAR in dialogbox procedure
« Reply #5 on: August 31, 2017, 12:04:06 AM »
Thanks for the responses.  I thought this might have been simple enough that someone would have immediately known a solution.
When I can get the whole mess more presentable, I'll post the source.

Sinsi:  Yes, I could have just done a full windows with translate message.  I just tend to go the simple route when possible.  Quickie dialogs have served me well before this.

Aw27:  I'm not getting WM_CHAR messages any where else while the modal dialog is running.  The main is also a dialog so I don't have message loop.  Perhaps that may be the only other solution.

JJ:  Originally I started with subclassed edits but the code started getting out of hand and misbehaving.  I rewrote with the simple dialog and ended up with about one fourth the code and it's a lot simpler and faster.


I do have one additional question for now, which I'll embed here where no one will see it.
I am getting a periodic character 252 in the WM_KEYDOWN message.  Anyone know what this is?  Microsoft just says it's unknown and reserved.  I'm guessing some kind of keyboard heartbeat.



jimg

  • Member
  • **
  • Posts: 196
Re: WM_CHAR in dialogbox procedure
« Reply #6 on: August 31, 2017, 12:33:32 AM »
JJ-

Thanks for that link.  After working through it, it's amazing how it parallels my process over the last two days.   (And what a surprise to see a post by Hutch in the middle :) )
I guess my above solution wasn't so bad after all.


jj2007

  • Member
  • *****
  • Posts: 7756
  • Assembler is fun ;-)
    • MasmBasic
Re: WM_CHAR in dialogbox procedure
« Reply #7 on: August 31, 2017, 01:01:38 AM »
(And what a surprise to see a post by Hutch in the middle :) )

He was still young then ;)


Implementing a subclassed edit is IMHO remarkably simple, just create it in WM_INITDIALOG. Here is the subclass:
Code: [Select]
SubEdit proc hwnd, uMsg, wParam, lParam
  .if uMsg==WM_CHAR
.if wParam>="e" && wParam<="z"
return 0 ; to suppress the message
.endif
  .endif
  invoke CallWindowProc, opEdit, hwnd, uMsg, wParam, lParam
  ret
SubEdit endp

Look for opEdit in the source posted above.

jimg

  • Member
  • **
  • Posts: 196
Re: WM_CHAR in dialogbox procedure
« Reply #8 on: August 31, 2017, 02:46:23 AM »
Yes, done it many times (like in the ascii table prog I posted not too long ago).

In this case, because I was juggling a few things at once, it just got real messy real fast, so I backed off and tried a "simpler" approach.

aw27

  • Member
  • ****
  • Posts: 855
  • Let's Make ASM Great Again!
Re: WM_CHAR in dialogbox procedure
« Reply #9 on: August 31, 2017, 03:22:21 AM »
I don't have message loop.
Iczelion inspiration?   :biggrin:

Quote
I am getting a periodic character 252 in the WM_KEYDOWN message
Do you have a screensaver?

Vortex

  • Member
  • *****
  • Posts: 1733
Re: WM_CHAR in dialogbox procedure
« Reply #10 on: August 31, 2017, 03:26:12 AM »
Hi jimg,

I tried to simulate your design by creating an invisible edit control. The subclass procedure does the job.

Your method based on GetKeyboardState is better. Quick and practical.

Code: [Select]
include DlgBoxWmchar.inc

.data

DlgBox      db 'DLGBOX',0
capt        db 'Info',0
format1     db 'You pressed %c',0

.data?

pOldEditBox dd ?
hEdit       dd ?
buffer      db 16 dup(?)

.code

start:

    invoke  GetModuleHandle,0
    xor     ecx,ecx
   
    invoke  DialogBoxParam,eax,ADDR DlgBox,ecx,\
            ADDR DlgProc,ecx
           
    invoke  ExitProcess,eax

DlgProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    .IF uMsg==WM_INITDIALOG

        invoke  GetDlgItem,hWnd,IDC_EDIT
        mov     hEdit,eax
       
        invoke  SetWindowLong,eax,GWL_WNDPROC,\
                ADDR SubclassProc
               
        mov     pOldEditBox,eax

    .ELSEIF uMsg==WM_CLOSE

        invoke  EndDialog,hWnd,0

    .ELSE

        xor     eax,eax
        ret

    .ENDIF

    mov  eax,1

    ret

DlgProc ENDP


SubclassProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    .IF uMsg==WM_CHAR

        invoke  wsprintf,ADDR buffer,ADDR format1,wParam
        invoke  MessageBox,0,ADDR buffer,ADDR capt,MB_OK
       
        xor     eax,eax
        ret

    .ENDIF

    invoke      CallWindowProc,pOldEditBox,hWnd,uMsg,\
                wParam,lParam
               
    ret

SubclassProc ENDP

END start

jimg

  • Member
  • **
  • Posts: 196
Re: WM_CHAR in dialogbox procedure
« Reply #11 on: August 31, 2017, 04:06:36 AM »
Thanks Vortex :)

AW: I get the character exactly every 10 seconds.  I have a screensaver, but I don't think that is it.  Just something weird about my machine.  Doesn't happen on my other computers.

aw27

  • Member
  • ****
  • Posts: 855
  • Let's Make ASM Great Again!
Re: WM_CHAR in dialogbox procedure
« Reply #12 on: August 31, 2017, 05:03:34 AM »
@jimg
I meant some program issuing it to prevent the screensaver from triggering.  :icon_rolleyes:

jimg

  • Member
  • **
  • Posts: 196
Re: WM_CHAR in dialogbox procedure
« Reply #13 on: August 31, 2017, 07:10:29 AM »
Oh.  Nope, screen saver kicks in when expected.   Hopefully it's not a keylogger or something.

aw27

  • Member
  • ****
  • Posts: 855
  • Let's Make ASM Great Again!
Re: WM_CHAR in dialogbox procedure
« Reply #14 on: August 31, 2017, 11:16:48 AM »
So it is not a result of a simulated keystroke.   :(
And unfortunately is not easy to find the origin of windows messages.  :(