In one of my superclass routines I want to do the normal thing with the + and - that are top of the keyboard but another thing with the %VK_ADD and %VK_SUBTRACT. I'd like the + and - to be accepted and displayed by the textbox when typed using the top row of the keyboard and I want the + and - from the keypad to be used to trigger the finishing of the field and moving to the next. In our programs a lot of number entry makes it useful to hit the + key to enter the number as is and the - key to take the number entered and turn it negative.
The top row + produces 16,187 keydown,43 char and 187,16 keyup.
The numberpad + produces 107 keydown,43 char and 107 up.
In the example below you can toggle insert and overwrite mode. Pressing the + key while in the middle of a word will truncate the rest of the field and go to the next field.
Up/Down arrows work as do the normal editing options.
+/- both work the same for text fields but in number fields the - will turn the value negative.
I also am trying some code that I converted from a subclassed decimal routine I found in Poffs to work as a superclass. (Still working on this).
Again I want the +- from the top row to work but the keypad +- to do their separate job.
Bob Mechler
The top row + produces 16,187 keydown,43 char and 187,16 keyup.
The numberpad + produces 107 keydown,43 char and 107 up.
In the example below you can toggle insert and overwrite mode. Pressing the + key while in the middle of a word will truncate the rest of the field and go to the next field.
Up/Down arrows work as do the normal editing options.
+/- both work the same for text fields but in number fields the - will turn the value negative.
I also am trying some code that I converted from a subclassed decimal routine I found in Poffs to work as a superclass. (Still working on this).
Again I want the +- from the top row to work but the keypad +- to do their separate job.
Code:
#COMPILE EXE #REGISTER NONE #DIM ALL #INCLUDE "WIN32API.INC" FUNCTION Validate(hdialog AS LONG,hctrlid AS LONG,sTxt AS STRING) AS LONG FUNCTION = 1 ' true allows navigation to next fields END FUNCTION GLOBAL FieldLen() AS LONG, FieldDec() AS LONG, VDSet() AS STRING,VR() AS STRING, VSET AS STRING,Keystrokes AS STRING GLOBAL V_INSOVR AS INTEGER 'INSERT/OVERWRITE FLAG FUNCTION CreateSuperClass(OldClassName AS STRING, NewClassName AS STRING, lpfnNewWndProc AS LONG, cbWndExtra AS LONG) AS LONG LOCAL wc AS WNDCLASSEX wc.cbSize = SIZEOF(wc) IF GetClassInfoEx(BYVAL 0&, BYVAL STRPTR(OldClassName), wc) THEN CallWindowProc lpfnNewWndProc, 0, 0, wc.lpfnWndProc, wc.cbWndExtra wc.hInstance = GetModuleHandle(BYVAL 0&) wc.lpszClassName = STRPTR(NewClassName) wc.lpfnWndProc = lpfnNewWndProc wc.cbWndExtra = wc.cbWndExtra + cbWndExtra FUNCTION = RegisterClassEx(wc) END IF END FUNCTION CALLBACK FUNCTION NEditProc STATIC OldProc AS LONG, OffsetWndExtra AS LONG LOCAL FieldLen AS LONG,V_NKEYPOS AS LONG,sTXT AS STRING,Txt AS ASCIIZ * %MAX_PATH IF CBHNDL = 0 THEN OldProc = CBWPARAM: OffsetWndExtra = CBLPARAM: EXIT FUNCTION SELECT CASE CBMSG ' control navigation macro CASE %WM_GETDLGCODE FUNCTION = %DLGC_WANTALLKEYS: EXIT FUNCTION CASE %WM_KEYDOWN SELECT CASE CBWPARAM CASE %VK_UP CONTROL GET TEXT GetParent(CBHNDL),getdlgctrlid(CBHNDL) to sTXT$ IF Validate(GetParent(CBHNDL),getdlgctrlid(CBHNDL),sTXT$) THEN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, -1) EXIT FUNCTION END IF CASE %VK_TAB IF GetAsyncKeyState(%VK_SHIFT) THEN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, -1) ELSE SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) END IF EXIT FUNCTION CASE %VK_DOWN,%VK_RETURN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) EXIT FUNCTION CASE %VK_F 'find routine IF GetAsyncKeyState(%VK_CONTROL) THEN CONTROL SET TEXT GetParent(CBHNDL),getdlgctrlid(CBHNDL),"Ctrl+F" EXIT FUNCTION END IF CASE %VK_INSERT IF NOT V_INSOVR THEN V_INSOVR = -1 SetWindowText GetParent(CBHNDL),"OVR" ELSEIF V_INSOVR THEN V_INSOVR = 0 SetWindowText GetParent(CBHNDL),"INS" END IF CASE %VK_ADD SendMessage CBHNDL, %EM_GETSEL, 0, 0 TO V_NKEYPOS& 'Used to detect when field is filled V_NKEYPOS& = LOWRD(V_NKEYPOS&) CONTROL GET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL) TO sTxt sTxt = LEFT$(sTxt,V_NKEYPOS&) CONTROL SET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL),sTxt SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) CASE %VK_SUBTRACT SendMessage CBHNDL, %EM_GETSEL, 0, 0 TO V_NKEYPOS& 'Used to detect when field is filled V_NKEYPOS& = LOWRD(V_NKEYPOS&) CONTROL GET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL) TO sTxt sTxt = LEFT$(sTxt,V_NKEYPOS&) IF VAL(sTxt) > 0 THEN sTXT = "-" + TRIM$(sTxt) END IF CONTROL SET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL),sTxt SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) END SELECT CASE %WM_KEYUP CONTROL SEND GetParent(CBHNDL),getdlgctrlid(CBHNDL), %EM_GETSEL, 0, 0 TO V_NKEYPOS& 'Used to detect when field is filled IF LOWRD(V_NKEYPOS&) = FieldLen(getdlgctrlid(CBHNDL)) THEN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) EXIT FUNCTION END IF CASE %WM_SETFOCUS SendMessage CBHNDL, %EM_SETSEL, 0, -1 CASE %WM_CHAR IF INSTR("+-",CHR$(CBWPARAM)) > 0 THEN EXIT FUNCTION IF V_INSOVR THEN SendMessage CBHNDL, %EM_GETSEL, 0, 0 TO V_NKEYPOS& 'Used to detect when field is filled V_NKEYPOS& = LOWRD(V_NKEYPOS&) SendMessage CBHNDL, %EM_SETSEL,V_NKEYPOS&,V_NKEYPOS& + 1 'Selects current character SendMessage CBHNDL, %WM_CLEAR,0,0 'If nothing to clear doesn't act END IF END SELECT FUNCTION = CallWindowProc(OldProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM) END FUNCTION CALLBACK FUNCTION NMoneyProc STATIC OldProc AS LONG, OffsetWndExtra AS LONG LOCAL FieldLen AS LONG,V_NKEYPOS AS LONG,sTXT AS STRING DIM Dpnt AS LOCAL LONG DIM hWnd AS LOCAL DWORD DIM Mlen AS LOCAL LONG DIM Tlen AS LOCAL LONG DIM Txt AS LOCAL ASCIIZ * %MAX_PATH DIM Value AS LOCAL DOUBLE IF CBHNDL = 0 THEN OldProc = CBWPARAM: OffsetWndExtra = CBLPARAM: EXIT FUNCTION SELECT CASE CBMSG ' control navigation macro CASE %WM_GETDLGCODE FUNCTION = %DLGC_WANTALLKEYS: EXIT FUNCTION CASE %WM_KEYDOWN SELECT CASE CBWPARAM CASE %VK_UP CONTROL GET TEXT GetParent(CBHNDL),getdlgctrlid(CBHNDL) to sTXT$ IF Validate(GetParent(CBHNDL),getdlgctrlid(CBHNDL),sTXT$) THEN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, -1) EXIT FUNCTION END IF CASE %VK_TAB IF GetAsyncKeyState(%VK_SHIFT) THEN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, -1) ELSE SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) END IF EXIT FUNCTION CASE %VK_DOWN,%VK_RETURN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) EXIT FUNCTION CASE %VK_F 'find routine IF GetAsyncKeyState(%VK_CONTROL) THEN CONTROL SET TEXT GetParent(CBHNDL),getdlgctrlid(CBHNDL),"Ctrl+F" EXIT FUNCTION END IF CASE %VK_INSERT IF NOT V_INSOVR THEN V_INSOVR = -1 SetWindowText GetParent(CBHNDL),"OVR" ELSEIF V_INSOVR THEN V_INSOVR = 0 SetWindowText GetParent(CBHNDL),"INS" END IF CASE %VK_ADD SendMessage CBHNDL, %EM_GETSEL, 0, 0 TO V_NKEYPOS& 'Used to detect when field is filled V_NKEYPOS& = LOWRD(V_NKEYPOS&) CONTROL GET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL) TO sTxt sTxt = LEFT$(sTxt,V_NKEYPOS&) CONTROL SET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL),sTxt SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) CASE %VK_SUBTRACT SendMessage CBHNDL, %EM_GETSEL, 0, 0 TO V_NKEYPOS& 'Used to detect when field is filled V_NKEYPOS& = LOWRD(V_NKEYPOS&) CONTROL GET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL) TO sTxt sTxt = LEFT$(sTxt,V_NKEYPOS&) IF VAL(sTxt) > 0 THEN sTXT = "-" + TRIM$(sTxt) END IF CONTROL SET TEXT GetParent(CBHNDL),GetDlgCtrlid(CBHNDL),sTxt SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) END SELECT CASE %WM_KEYUP CONTROL SEND GetParent(CBHNDL),getdlgctrlid(CBHNDL), %EM_GETSEL, 0, 0 TO V_NKEYPOS& 'Used to detect when field is filled IF LOWRD(V_NKEYPOS&) = FieldLen(getdlgctrlid(CBHNDL)) THEN SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) EXIT FUNCTION END IF CASE %WM_PASTE 'more handling for error EXIT FUNCTION CASE %WM_CHAR IF CBWPARAM < 32 THEN EXIT SELECT ' BkSpc, Tab, etc pass these on IF CBWPARAM > 57 THEN EXIT FUNCTION ' > "9" not legal IF CBWPARAM = 47 THEN EXIT FUNCTION ' "/" not legal IF CBWPARAM < 46 THEN EXIT FUNCTION ' < "." not legal Tlen = GetWindowTextLength(CBHNDL) ' current text length IF Tlen = 0 THEN EXIT SELECT ' anything goes here! GetWindowText CBHNDL, Txt, %MAX_PATH ' get current text Dpnt = INSTR(Txt,".") ' find "." IF CBWPARAM = 46 THEN ' "." was input IF Dpnt > 0 THEN EXIT FUNCTION ' can't have 2 ELSEIF Dpnt > 0 THEN ' already working on decimal value IF Dpnt + FieldDec(getdlgctrlid(CBHNDL)) = Tlen THEN EXIT FUNCTION ' can't have more than 2 places past decimal ELSE ' digits 0 -> 9 Mlen = FieldLen(getdlgctrlid(CBHNDL)) ' max length IF Tlen = Mlen - FieldDec(getdlgctrlid(CBHNDL)) - 1 THEN EXIT FUNCTION ' can't have more whole numbers than this END IF ' CASE %WM_SETFOCUS GetWindowText CBHNDL, Txt, %MAX_PATH Txt = REMOVE$(Txt,",") SetWindowText CBHNDL, Txt SendMessage CBHNDL, %EM_SETSEL, 0, -1 CASE %WM_KILLFOCUS GetWindowText CBHNDL, Txt, %MAX_PATH Value = Val(Txt) Txt = FORMAT$(Value, "0,." + STRING$(FieldDec(getdlgctrlid(CBHNDL)),"0")) SetWindowText CBHNDL, Txt END SELECT FUNCTION = CallWindowProc(OldProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM) END FUNCTION FUNCTION PBMAIN IF ISFALSE(CreateSuperClass("EDIT", "NEdit", CODEPTR(NEditProc), 4)) THEN EXIT FUNCTION IF ISFALSE(CreateSuperClass("EDIT", "NMoney", CODEPTR(NMoneyProc), 4)) THEN EXIT FUNCTION DIM FieldLen(1000:2000),FieldDec(1000:2000),VDSet(1000:2000) LOCAL hDlg AS LONG, i AS LONG DIALOG NEW 0, "Test", , , 200, 300, %WS_CAPTION OR %WS_SYSMENU OR %WS_MAXIMIZEBOX TO hDlg CONTROL ADD "Static",hDlg, 2003,"String",10,35,40,14,%SS_LEFT OR %WS_VISIBLE OR %WS_CHILD OR %SS_NOTIFY,%WS_EX_LEFT CONTROL ADD "NEdit", hDlg, 1003, "", 50, 35, 100, 14, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, %WS_EX_CLIENTEDGE CONTROL SEND hDlg,1003,%EM_LIMITTEXT,20,0: FieldLen(1003) = 20 CONTROL ADD "Static",hDlg, 2004,"String",10,50,40,14,%SS_LEFT OR %WS_VISIBLE OR %WS_CHILD OR %SS_NOTIFY,%WS_EX_LEFT CONTROL ADD "NEdit", hDlg, 1004, "", 50, 50, 100, 14, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, %WS_EX_CLIENTEDGE CONTROL SEND hDlg,1004,%EM_LIMITTEXT,20,0: FieldLen(1004) = 20 CONTROL ADD "Static",hDlg, 2005,"Money",10,65,40,14,%SS_LEFT OR %WS_VISIBLE OR %WS_CHILD,%WS_EX_LEFT CONTROL ADD "NMoney", hDlg,1005, "", 50, 65, 48, 14, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_RIGHT, %WS_EX_CLIENTEDGE CONTROL SEND hDlg,1005,%EM_LIMITTEXT,10,0: FieldLen(1005) = 10: FieldDec(1005) = 4 DIALOG SHOW MODAL hDlg END FUNCTION
Comment