Detecting key combinations in superclassed edit controls

Started by Tight_Coder_Ex, January 14, 2011, 06:32:34 PM

Previous topic - Next topic

Tight_Coder_Ex

An example of how to dectect combinations such as ALT-SHIFT-"A" or CTL-F10 or specifically SHIFT-TAB as keyboard navigation is my responsibility as I'm not using Dialog templates.

Tight_Coder_Ex

Solved:  GetKeyState gives me all the information I need.  :dazzled:

Tight_Coder_Ex

#2
As there is no way to get HWND of a control using its ID unless it's in a dialog box, I devised my own.
This gives me the characteristic I wanted in so much as wrapping through the 7 primary text boxes.

In WM_CREATE is where I write the 7 handles of the child controls &
IN WM_COMMAND of the parent window is where CurrentID is set in response to VM_KEYFIRST


00 8B46 08               mov     eax, [esi + 8 wParam = chCharCode
03 3C 09                 cmp     al, VK_TAB
05 75 49                 jnz     50

07 6A 10                 push    VK_SHIFT
09 E8 C0000000           call    GetKeyState
0E 0FBAE0 07             bt      eax, 7 Test bit
12 8B0D B0304000         mov     ecx, [CurrentID]
18 73 12                 jnb     2C CY = 1 if shift was being pressed

Entry point when shift being similtaneously pressed with TAB

1A 66:81F9 0002          cmp     cx, FIRST_CTL At first control
1F 75 06                 jnz     27
21 66:B9 1802            mov     cx, LAST_CTL Wrap to last control
25 EB 16                 jmp     3D

27 83E9 04               sub     ecx, CTL_SKEW Bumpt to previous control
2A EB 11                 jmp     3D

Entry point when only TAB being pressed

2C 66:81F9 1802          cmp     cx, LAST_CTL Are we at last one
31 75 06                 jnz     39
33 66:B9 0002            mov     cx, FIRST_CTL Wrap to first control
37 EB 04                 jmp     3D
39 66:83C1 04            add     cx, CTL_SKEW Bump to next control

Strip MSB so ecx is correct offset within Ctl_Handles

3D 66:81E1 FF00          and     cx, 0FF
42 FFB1 80304000         push    [ecx+Ctl_Handles]
48 E8 27000000           call    SetFocus
4D F9                    stc Inhibit default proecessing
4E EB 01                 jmp     51

50 F8                    clc Do default processing
51 C3                    ret


Project is under development. Currently this wrapping operation is all that can be tested.

Test App

donkey

Quote from: Tight_Coder_Ex on January 17, 2011, 01:40:53 AM
As there is no way to get HWND of a control using its ID unless it's in a dialog box, I devised my own.

GetDlgItem should work equally well with windows as dialog boxes, at least I have never had a problem with it.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Tight_Coder_Ex

Quote from: donkey on January 17, 2011, 02:30:24 AM
GetDlgItem should work equally well with windows as dialog boxes, at least I have never had a problem with it.

What do you pass to API for hDlg

The GetDlgItem function retrieves the handle of a control in the specified dialog box.

HWND GetDlgItem(
  HWND hDlg,      // handle of dialog box
  int nIDDlgItem   // identifier of control
);

donkey

The handle to the main window. You can use any of the dialog functions such as SendDlgItemMessage etc... A dialog is just a normal window with a bit of extra window class memory and a different default processing but all functions that work on a dialog (functions not necessarily messages) will work equally well on a normal window.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Tight_Coder_Ex

Interesting.  I'll have to rework this sometime to see if it can be more efficient.  If the need arises, I would imagine it would work for other dialog functions as well.

disintx

Quote from: Tight_Coder_Ex on January 17, 2011, 04:26:52 AM
Interesting.  I'll have to rework this sometime to see if it can be more efficient.  If the need arises, I would imagine it would work for other dialog functions as well.
Think of it this way:
You thought you had a problem, and you worked around it by creating your own algorithm. Awesome! =)

donkey

I really hate to burst your bubble because you obviously put a bit of thought into navigation but you have created quite a lot of work for yourself to do something that Windows already does for you. Keyboard navigation can be added to all windows whether a dialog or not, you have only to enable it by setting the WS_TABSTOP style on each control. If you add that to your window styles when creating your controls it will cause them to react to a TAB key. In order to have a normal window process the TAB key in the way a dialog does you need only to execute the IsDialogMessage function in your message pump:

.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke IsDialogMessage, hwnd, ADDR msg
.IF eax ==FALSE
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDIF
.ENDW


There is no other code necessary, all dialog keys should work.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Tight_Coder_Ex

Quote from: disintx on January 17, 2011, 06:40:59 AMThink of it this way:
You thought you had a problem, and you worked around it by creating your own algorithm. Awesome! =)

It is the challenge that makes assm programming or probably any language for that matter rewarding.

Quote from: donkey on January 17, 2011, 07:25:32 AM
I really hate to burst your bubble because you obviously put a bit of thought into navigation

There is no other code necessary, all dialog keys should work.

Pretty hard to burst my bubble as that is the purpose to being here, as to hone my skills, not to become intrenched in a self proclaimed superiority.  This thread is shinning example as I hadn't realized I can use some of the advantages of navigation without dialog templates or definitions.  If however the occasion arises to port my app to Gnome, KDE or something else, this snippet may be of some use.

Another problem with MS is that through EN_SETFOCUS & EN_KILLFOCUS, I have yet to understand why the focus is set to the next control before the previous is killed.  Makes it really hard to design code trapping these events.

donkey

Quote from: Tight_Coder_Ex on January 17, 2011, 02:31:04 PM
If however the occasion arises to port my app to Gnome, KDE or something else, this snippet may be of some use.

Big job, the io subsystem in Linux is a bit more difficult to use and there are security level issues involved in trapping io events. Not to mention license issues with MASM, it violates the EULA to build code for any non-Microsoft OS.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Tight_Coder_Ex

Justifiably so, as I wouldn't be to happy if I supplied something for free and then someone used it to build a product for another platform.  To that end though, I use little to nothing of MASM and hand bomb the stuff I need for each module as to make it more portable to NASM.  From my perspective ML has but one claim to fame and that is emitting appropriate info for Olly or Windbg in the way of symbols, which does make debugging and testing more convenient.

jj2007

Quote from: Tight_Coder_Ex on January 17, 2011, 05:35:14 PMML has but one claim to fame and that is emitting appropriate info for Olly or Windbg in the way of symbols, which does make debugging and testing more convenient.

JWasm has no license restrictions, and produces symbols, too. Plus you have full Masm compatibility including macros...

Tight_Coder_Ex

Quote from: jj2007 on January 17, 2011, 05:40:50 PM
JWasm has no license restrictions, and produces symbols, too. Plus you have full Masm compatibility including macros...

:dance:  If and when I begin porting to linux, this will definately make it easier

donkey

Quote from: Tight_Coder_Ex on January 17, 2011, 05:35:14 PM
Justifiably so, as I wouldn't be to happy if I supplied something for free and then someone used it to build a product for another platform.  To that end though, I use little to nothing of MASM and hand bomb the stuff I need for each module as to make it more portable to NASM.  From my perspective ML has but one claim to fame and that is emitting appropriate info for Olly or Windbg in the way of symbols, which does make debugging and testing more convenient.

I would think all assemblers that can output COFF would also be able to export symbols, Goasm can output to either a DBG (codeview) file or embed symbols in the COFF debug directory. The DBG files can be read by OllyDbg, I've never tried WinDbg so can't comment on that.

OllyDbg output from a project built with GoAsm:
00401000 >/$ 6A 00          PUSH 0                                   ; /pModule = NULL
00401002  |. E8 F93F0000    CALL <JMP.&KERNEL32.GetModuleHandleA>    ; \GetModuleHandleA
00401007  |. A3 30204000    MOV DWORD PTR DS:[hInstance],EAX
0040100C  |. 68 FF3F0000    PUSH 3FFF
00401011  |. 6A 08          PUSH 8
00401013  |. 54             PUSH ESP                                 ; /pInitEx
00401014  |. E8 11400000    CALL <JMP.&COMCTL32.InitCommonControlsEx>; \InitCommonControlsEx
00401019  |. 6A 00          PUSH 0                                   ; /lParam = NULL
0040101B  |. 68 39104000    PUSH DialogTe.DlgProc                    ; |DlgProc = DialogTe.DlgProc
00401020  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
00401022  |. 68 E8030000    PUSH 3E8                                 ; |pTemplate = 3E8
00401027  |. FF35 30204000  PUSH DWORD PTR DS:[hInstance]            ; |hInst = NULL
0040102D  |. E8 DA3F0000    CALL <JMP.&USER32.DialogBoxParamA>       ; \DialogBoxParamA
00401032  |. 6A 00          PUSH 0                                   ; /ExitCode = 0
00401034  \. E8 CD3F0000    CALL <JMP.&KERNEL32.ExitProcess>         ; \ExitProcess
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable