Hi
Unfortunately with notepad most of your work is already done. You've redefined the Select All menu string to display an accelerator string, now you just need to define it under the Accelerators resource using your favorite resource editor. Just mimic the syntax for an already existing accelerator since they're all defined slightly differently if you use Reshack, Exescope, Borland Resource Editor, etc.
(Actually it's exactly as DakienDX said, heh)
This should be all you need to do and the code should now accept your Ctrl-A. The question is, *why* is this all you need to do in notepad? When you select a menu item the WM_COMMAND message is sent to the menu window. If you've added the accelerator as above and set a bmsg breakpoint on the hWnd of the menu bar and select Ctrl-A you'll get this info from Softice:
:bmsg 2ec wm_command
Break due to BMSG 02EC WM_COMMAND (ET=1.35 seconds)
hWnd=02EC wParam=0007 lParam=00010000 msg=0111 WM_COMMAND
The high-order word of wParam is the resource ID of Select All (007) and the low-order word indicates the message came from an accelerator (0001). This is clarified in the Win32 Programmers Reference:
------------------------------------------------------------
WM_COMMAND
wNotifyCode = HIWORD(wParam); // notification code
wID = LOWORD(wParam); // item, control, or accelerator identifier
hwndCtl = (HWND) lParam; // handle of control
wNotifyCode
Value of the high-order word of wParam. Specifies the notification code if the message is from a control. If the message is from an accelerator, this parameter is 1. If the message is from a menu, this parameter is 0.
wID
Value of the low-order word of wParam. Specifies the identifier of the menu item, control, or accelerator.
hwndCtl
Value of lParam. Identifies the control sending the message if the message is from a control. Otherwise, this parameter is NULL.
----------------------------------------------------------------
Now you need to find where in code the WM_COMMAND message is processed. If you look at the code line you broke at on the BMSG breakpoint you'll see:
141F:07DE 6668741C4000 PUSH 00401C74
141F:07E4 666800000300 PUSH 00030000
141F:07EA EA16764F01 JMP 014F:7616
That very first address (401C74) is actually the start of the programs main message processing loop. So if you set a bpx breakpoint on it, specifying your regular CS value, i.e.
bpx 167:401C74
you'll be able to continue the tracing with the Select All message parameters as they are being processed.
Find where the WM_COMMAND message (111) is compared and you'll continue on to where the Resource ID's begin to be compared. You can actually find this easily in Wdasm by searching for the other menu commands such as Save and Copy.
You should find this snippet of code:
:0040125A 0FB7750C movzx esi, word ptr [ebp+0C]
:0040125E 83FE20 cmp esi, 00000020
This first line passes the stack parameter [ebp+0C] to esi. This is your Resource ID (0007 for Select All, 0301 for Copy, etc.). It then goes through a series of compares to find the proper routine for the proper menu item selected.
Now, the point of this whole explanation isn't to confuse the issue, but to point out something you'd need to know if you want to add accelerator keys to *other* applications that may handle this a bit differently, or if you want to patch in a new menu item/accelerator to handle some of your own code.
Notice the stack parameter [ebp+0C] is handled as a WORD PTR. With this syntax this effectively masks out the low-order word of wParam, which would indicate if it was from an accelerator (0001) or not (0000). If you were to check [ebp+0C] as a DWORD you'd see it was actually 00010007 if the accelerator was used. OK, so what you say?
Well, for notepad you don't need to do anything else, the code is taking care of all situations whether an accelerator is used or not. Look at how this is handled in a different app, Regmon:
------------------------------------------------
:00405BBD 25FFFF0000 and eax, 0000FFFF
; this line masks out the LOWORD(wParam)=0001 Accelerator key modifier
.
.
* Possible Ref to Menu: LISTMENU, Item: "Save Ctrl+S"
|
:00405BE4 3D479C0000 cmp eax, 00009C47 ;MenuItemID of "Save"
:00405BE9 7F69 jg 00405C54
--------------------------------------------------
Now if you were to patch in a new menu item somewhere, it would *have* to be after the accelerator key is handled, by essentially masking it out and ignoring it for the rest of the code, or you'd have to handle it yourself.
All I'm really trying to get across here is showing how to identify what the messaging loop is doing and how it handles accelerator keys, and point out that the *placement* of an inline patch to handle a new routine from a menu item is critical. If you ignored the accelerator key (if you used one), then you might find your code didn't work when you used the key and might wonder why.
Enough ramblings, hope this helped or something
Cheers,
Kayaker