- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to trap the page up/down keys when in an Edit box (in a Fortran Windows Dialog app) and perform the page up/down operation on another List box instead. Normally these keys do not invoke the callback. I would like to solve this without affecting the normal page up/down operation when the List box is selected.
Is there a special SendMessage command, or are there any special Properties settings? (W2K, CVF 6.6)
Greg
Is there a special SendMessage command, or are there any special Properties settings? (W2K, CVF 6.6)
Greg
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You'll have to subclass edit boxes themselves, (call SetWindowLong(GWL_WNDPROC) from dialog-init callback) and catch WM_CHAR/(wParam=VK_PRIOR/VK_NEXT). Need I elaborate?
Jugoslav
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could you please elaborate. I'm not sure what the new address for the window procedure argument should be. I tried using the old address (using GetWindowLong), and it still doesn't catch any direction keys. Also, isn't the handle that of the edit box?
I tried this using a standard Win32 procedure, however my final goal is to use a Win32 Modeless DIALOG procedure that normally traps inputs via SetDlgSub.
Greg
I tried this using a standard Win32 procedure, however my final goal is to use a Win32 Modeless DIALOG procedure that normally traps inputs via SetDlgSub.
Greg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The new address will be your subclassing procedure:
I don't think there's a way to trap the input normally via SetDlgSub. If you want to reach Dlg from within MyEditProc, you'll have to make it global.
HTH
Jugoslav
!This goes to dialog-initialization callback: INTERFACE INTEGER FUNCTION MyEditProc(... END INTERFACE ... !lpfnOldEditProc must be global lpfnOldEditProc = SetWindowLong(GetDlgItem(Dlg%hWnd, IDC_EDIT1), GWL_WNDPROC, LOC(MyEditProc)) ... !Your window procedure: INTEGER FUNCTION MyEditProc(hWnd, Msg, wParam, lParam) !DEC$ATTRIBUTES STDCALL:: MyEditProc USE DFWIN USE GLOBALS, ONLY: lpfnOldEditProc INTEGER, INTENT(IN):: hWnd, Msg, wParam, lParam ! IF (Msg == WM_CHAR) THEN IF (wParam == VK_PRIOR) THEN !Page up ELSE IF (wParam == VK_NEXT) THEN !Page down ELSE MyEditProc = CallWindowProc(lpfnOldEditProc, hWnd, Msg, wParam, lParam) END IF ELSE MyEditProc = CallWindowProc(lpfnOldEditProc, hWnd, Msg, wParam, lParam) END IF END FUNCTION MyEditProc
I don't think there's a way to trap the input normally via SetDlgSub. If you want to reach Dlg from within MyEditProc, you'll have to make it global.
HTH
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm fuzzy in these areas, but was able to properly trap using WM_GETDLGCODE rather than WM_CHAR.
Also, my understanding is that CallWindowProc sends all commands other than scroll to be processed in the normal manner.
This includes sending the normal character keys to the DlgSetSub callback.
The callback used is shown below.
Thanks again for your invaluable help.
Greg
Also, my understanding is that CallWindowProc sends all commands other than scroll to be processed in the normal manner.
This includes sending the normal character keys to the DlgSetSub callback.
The callback used is shown below.
Thanks again for your invaluable help.
Greg
!Callback for Input edit box to trap all keys INTEGER FUNCTION MyEditProc(hWnd, Msg, wParam, lParam) !DEC$ATTRIBUTES STDCALL:: MyEditProc USE DFWIN USE GLOBALData, ONLY: lpfnOldEditProc, hDlg_IDC_Output INTEGER, INTENT(IN):: hWnd, Msg, wParam, lParam ! INTEGER iSt SELECT CASE(Msg) CASE (WM_GETDLGCODE) IF (wParam == VK_PRIOR) THEN !Page up iSt=SendMessage(hDlg_IDC_Output, EM_SCROLL, SB_PAGEUP, 0) ELSE IF (wParam == VK_NEXT) THEN !Page down iSt=SendMessage(hDlg_IDC_Output, EM_SCROLL, SB_PAGEDOWN, 0) ELSE MyEditProc = CallWindowProc(lpfnOldEditProc, hWnd, Msg, wParam, lParam) END IF CASE DEFAULT MyEditProc = CallWindowProc(lpfnOldEditProc, hWnd, Msg, wParam, lParam) END SELECT END FUNCTION MyEditProc
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Um, WM_GETDLGCODE? I agree it has something to do with that (and I did forget about it first time), but docs say that WM_GETDLGCODE/wParam is not used; at best, you discovered an undocumented feature. Your code may work but I wouldn't bet it would work everywhere.
This works the following way: some keys (Enter, Tab, Arrows) in the dialog have special handling. IsDialogMessage in the dialog modal loop receives these keys and sends WM_GETDLGCODE to the control which has focus to "hear its opinion". If it returns zero, the message is converted to appropriate action (e.g. Tab key will be converted to WM_NEXTDLGCTL); otherwise, if it returns some (combination of) DLGC_ constant, the keypress is converted to normal keyboard input -- WM_CHAR (as if it is a normal window, not a dialog).
Now, I don't know what group PageUp/Down keys belong to. Try using my code (WM_CHAR) but add WM_GETDLGCODE handling and just return... uh, try DLGC_WANTARROWS or DLGC_WANTCHARS -- the docs are rather vague. DLGC_WANTALLKEYS will certainly work, but that will disable tab key as well.
Jugoslav
This works the following way: some keys (Enter, Tab, Arrows) in the dialog have special handling. IsDialogMessage in the dialog modal loop receives these keys and sends WM_GETDLGCODE to the control which has focus to "hear its opinion". If it returns zero, the message is converted to appropriate action (e.g. Tab key will be converted to WM_NEXTDLGCTL); otherwise, if it returns some (combination of) DLGC_ constant, the keypress is converted to normal keyboard input -- WM_CHAR (as if it is a normal window, not a dialog).
Now, I don't know what group PageUp/Down keys belong to. Try using my code (WM_CHAR) but add WM_GETDLGCODE handling and just return... uh, try DLGC_WANTARROWS or DLGC_WANTCHARS -- the docs are rather vague. DLGC_WANTALLKEYS will certainly work, but that will disable tab key as well.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following WM_CHAR block traps all characters, but not the direction keys.
Using DLGC_WANTALLKEYS traps characters and tab key in that block but still not direction keys.
All keys are trapped in the WM_GETDLGCODE block.
Greg
Using DLGC_WANTALLKEYS traps characters and tab key in that block but still not direction keys.
All keys are trapped in the WM_GETDLGCODE block.
Greg
SELECT CASE(Msg) CASE (WM_GETDLGCODE) TrapScrollProc = DLGC_WANTARROWS .OR. DLGC_WANTCHARS CASE (WM_CHAR) SELECT CASE(wParam) CASE (VK_PRIOR) iSt=SendMessage(hDlg_IDC_Output, EM_SCROLL, SB_PAGEUP, 0) !Page up CASE (VK_NEXT) iSt=SendMessage(hDlg_IDC_Output, EM_SCROLL, SB_PAGEDOWN, 0) !Page down CASE DEFAULT TrapScrollProc = CallWindowProc(lpfn_ScrollProc, hWnd, Msg, wParam, lParam) END SELECT CASE DEFAULT TrapScrollProc = CallWindowProc(lpfn_ScrollProc, hWnd, Msg, wParam, lParam) END SELECT
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I finally tested it myself (actually, I did test it the first time, but not on an edit box in a dialog). I couldn't get WM_CHAR to pass through as well, but what does work is to trap WM_KEYDOWN instead (and delete CASE(WM_GETDLGCODE)). You'll probably want to add EM_SCROLLCARET after EM_SCROLL.
Regards
Jugoslav
Regards
Jugoslav

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page