Have you considered having the parent watch for the %EN_CHANGE notification and creating the textbox having the %ES_WANTRETURN style? Then you can detect the validity of the entry, and if correct, do stuff (stripping the CR from the data), otherwise, inform user of invalid data.
ES_WANTRETURN: Specifies that a carriage return be inserted when the user presses the ENTER key while entering text into a multiline edit control in a dialog box. If you do not specify this style, pressing the ENTER key has the same effect as pressing the dialog box's default push button. This style has no effect on a single-line edit control.
Announcement
Collapse
No announcement yet.
Problem with childwindows
Collapse
X
-
Thank you all for your suggestions. And excuse my delayed answer. After all I think, the best method is to test all inputs as far as possible before leaving the edit field, and check inputs which can only be tested after completion of input in a separate function ["CheckInputCtrls()"]. This function must be called
1. from childwindow after %EN_KILLFOCUS and
2. from parentwindow when "Ok", "submit" etc. is clicked or the childwindow is going to be changed by typing a tab of the tab control.
"Editbusy" prevents "CheckInputCtrls()" from being called twice.
Code:#PBFORMS CREATED V1.51 #COMPILE EXE #DIM ALL #PBFORMS BEGIN INCLUDES %USEMACROS = 1 #IF NOT %DEF(%WINAPI) #INCLUDE "WIN32API.INC" #ENDIF #IF NOT %DEF(%COMMCTRL_INC) #INCLUDE "COMMCTRL.INC" #ENDIF #INCLUDE "PBForms.INC" #PBFORMS END INCLUDES #PBFORMS BEGIN CONSTANTS %IDD_DIALOG1 = 101 %IDOK = 1 %IDC_SYSTABCONTROL32_1 = 2 %IDD_DIALOG2 = 102 %IDC_TEXTBOX1 = 3 %IDCANCEL = 2 #PBFORMS END CONSTANTS DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() DECLARE CALLBACK FUNCTION ShowDIALOG2Proc() DECLARE FUNCTION SampleTabCtrl(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _ lCount AS LONG) AS LONG DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG DECLARE FUNCTION ShowDIALOG2(BYVAL hParent AS DWORD) AS LONG #PBFORMS DECLARATIONS FUNCTION PBMAIN() PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR _ %ICC_INTERNET_CLASSES) GLOBAL gPage AS LONG GLOBAL ghPage() AS LONG GLOBAL gEditbusy AS LONG ShowDIALOG1 %HWND_DESKTOP ShowDIALOG2 %HWND_DESKTOP END FUNCTION FUNCTION CheckInputCtrls(BYVAL CtrlId AS LONG) AS LONG LOCAL hDlg,ret,flt AS LONG STATIC Editbusy AS LONG IF Editbusy THEN EXIT FUNCTION Editbusy = 1 hDlg = ghPage(gPage) SELECT CASE CtrlId CASE %IDC_TEXTBOX1 CONTROL SEND hDlg,CtrlId,%EM_GETMODIFY,0,0 TO ret IF ISTRUE ret THEN MessageBox hDlg,"test input after %EN_KILLFOCUS","",%MB_OK 'if input not valid then flt = 1 END IF CASE ELSE RESET CtrlId END SELECT IF flt THEN CONTROL SEND hDlg, %IDC_SYSTABCONTROL32_1, %TCM_SETCURFOCUS, gPage - 1, 0 Setfocus GetDlgItem(hDlg,CtrlId) FUNCTION = 1 END IF IF CtrlId THEN CONTROL SEND hDlg,CtrlId,%EM_SETMODIFY,%FALSE,0 END IF RESET Editbusy END FUNCTION CALLBACK FUNCTION ShowDIALOG1Proc() LOCAL pNMHDR AS NMHDR PTR SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG gPage = 1 DIALOG SEND CBHNDL, %DM_SETDEFID,%IDOK,0 CASE %WM_NCACTIVATE RedrawWindow CBHNDL, BYVAL 0&, BYVAL 0&, %RDW_ERASE OR %RDW_INVALIDATE OR %RDW_ALLCHILDREN OR %RDW_ERASENOW RedrawWindow ghPage(gPage), BYVAL 0&, BYVAL 0&, %RDW_ERASE OR %RDW_INVALIDATE OR %RDW_ALLCHILDREN OR %RDW_ERASENOW CASE %WM_NOTIFY pNMHDR = CBLPARAM IF @pNMHDR.hWndFrom = GetDlgItem(CBHNDL, %IDC_SYSTABCONTROL32_1) THEN CONTROL SEND CBHNDL, %IDC_SYSTABCONTROL32_1, %TCM_GETCURSEL, 0, 0 TO gPage INCR gPage SELECT CASE @pNMHDR.Code CASE %TCN_SELCHANGING IF CheckInputCtrls(GetDlgCtrlID(GetFocus())) THEN EXIT FUNCTION DIALOG SHOW STATE ghPage(gPage), %SW_HIDE FUNCTION = 0 CASE %TCN_SELCHANGE DIALOG SHOW STATE ghPage(gPage), %SW_SHOW FUNCTION = 0 END SELECT END IF CASE %WM_COMMAND SELECT CASE AS LONG CBCTL CASE %IDCANCEL DIALOG END CBHNDL,0 CASE %IDOK IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN IF CheckInputCtrls(GetDlgCtrlID(GetFocus())) THEN EXIT FUNCTION DIALOG END CBHNDL,0 END IF END SELECT END SELECT END FUNCTION CALLBACK FUNCTION ShowDIALOG2Proc() LOCAL ret AS LONG SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG LOCAL x,y AS LONG CONTROL GET LOC GetParent(CBHNDL),%IDC_SYSTABCONTROL32_1 TO x,y DIALOG SET LOC CBHNDL,x + 4,y + 16 CONTROL SET FOCUS CBHNDL,%IDC_TEXTBOX1 FUNCTION = 1 CASE %WM_COMMAND SELECT CASE AS LONG CBCTL CASE %IDC_TEXTBOX1 IF CBCTLMSG = %EN_KILLFOCUS THEN IF CheckInputCtrls(CBCTL) THEN EXIT FUNCTION END IF END SELECT END SELECT END FUNCTION FUNCTION SampleTabCtrl(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _ AS LONG) AS LONG LOCAL i AS LONG LOCAL hCtl AS DWORD LOCAL szBuf AS ASCIIZ * 32 LOCAL tTC_Item AS TC_ITEM CONTROL HANDLE hDlg, lID TO hCtl tTC_Item.Mask = %TCIF_TEXT tTC_Item.iImage = -1 tTC_Item.pszText = VARPTR(szBuf) DIM tAccel(lCount -1) AS ACCELAPI FOR i = 0 TO lCount - 1 szBuf = USING$("Tab #", i) TabCtrl_InsertItem(hCtl, i, tTC_Item) NEXT i END FUNCTION FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG1->-> LOCAL hDlg AS DWORD DIALOG NEW hParent, "MainWindow", 221, 161, 311, 169, %WS_POPUP OR _ %WS_BORDER OR %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR _ %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR _ %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_ABSALIGN OR %DS_MODALFRAME OR _ %DS_CENTER OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _ %WS_EX_WINDOWEDGE OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD BUTTON, hDlg, %IDOK, "&Ok", 174, 140, 60, 15 DIALOG SEND hDlg, %DM_SETDEFID, %IDOK, 0 CONTROL ADD "SysTabControl32", hDlg, %IDC_SYSTABCONTROL32_1, _ "SysTabControl32_1", 10, 25, 295, 105, %WS_CHILD OR %WS_VISIBLE OR _ %WS_TABSTOP OR %TCS_SINGLELINE OR %TCS_RIGHTJUSTIFY, _ %WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Cancel", 241, 140, 60, 15 #PBFORMS END DIALOG SampleTabCtrl hDlg, %IDC_SYSTABCONTROL32_1, 2 REDIM ghPage(1) ghPage(0) = hDlg ghPage(1) = ShowDIALOG2(hDlg) DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt #PBFORMS BEGIN CLEANUP %IDD_DIALOG1 #PBFORMS END CLEANUP FUNCTION = lRslt END FUNCTION FUNCTION ShowDIALOG2(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG2->-> LOCAL hDlg AS DWORD DIALOG NEW hParent, "Child1", 292, 179, 201, 75, %WS_CHILD OR %WS_BORDER _ OR %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _ %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE OR %DS_ABSALIGN OR _ %DS_MODALFRAME OR %DS_CONTROL OR %DS_CENTER OR %DS_3DLOOK OR _ %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_WINDOWEDGE OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "TextBox1", 5, 5, 100, 13 #PBFORMS END DIALOG DIALOG SHOW MODELESS hDlg, CALL ShowDIALOG2Proc TO lRslt #PBFORMS BEGIN CLEANUP %IDD_DIALOG2 #PBFORMS END CLEANUP FUNCTION = hDlg END FUNCTION
Leave a comment:
-
There are lots of examples of 'data entry' techniques on the forum.
Most accept the Enter key or the TAB key as a trigger to check the data that the user has entered. Sometimes a 'Submit' button is used.
In your example. If the user can navigate away from the TEXTBOX without causing a EN_KILLFOCUS notification, your code will need to allow for it.
When the enter key sends an %IDOK you need to check in the code that handles %IDOK if the keyboard focus is (still) on your TEXTBOX. If so you will have to deal with it.
This code shows one way to do that check. It also shows a bit of a hack which will allow you to force a EN_KILLFOCUS message be sent to the TEXTBOX - not that I am recommending it - just for fun
Code:CASE %IDOK IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 Then If GetDlgCtrlID(GetFocus()) = %IDC_TEXTBOX1 Then WinBeep 800, 50 : 'check the TextBox data SendMessage GetParent(GetFocus()), %WM_COMMAND, MAKLNG(%IDC_TEXTBOX1, %EN_KILLFOCUS), GetFocus() End If ? "%IDOK in ShowDIALOG1Proc, gtest: " + STR$(gtest) DIALOG END CBHNDL,0 END IF
Leave a comment:
-
Here is a small testprogram which demonstrates my problem:
Code:#PBFORMS CREATED V1.51 #COMPILE EXE #DIM ALL #PBFORMS BEGIN INCLUDES %USEMACROS = 1 #IF NOT %DEF(%WINAPI) #INCLUDE "WIN32API.INC" #ENDIF #IF NOT %DEF(%COMMCTRL_INC) #INCLUDE "COMMCTRL.INC" #ENDIF #INCLUDE "PBForms.INC" #PBFORMS END INCLUDES #PBFORMS BEGIN CONSTANTS %IDD_DIALOG1 = 101 %IDOK = 1 %IDC_SYSTABCONTROL32_1 = 2 %IDD_DIALOG2 = 102 %IDC_TEXTBOX1 = 3 %IDCANCEL = 2 #PBFORMS END CONSTANTS DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() DECLARE CALLBACK FUNCTION ShowDIALOG2Proc() DECLARE FUNCTION SampleTabCtrl(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _ lCount AS LONG) AS LONG DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG DECLARE FUNCTION ShowDIALOG2(BYVAL hParent AS DWORD) AS LONG #PBFORMS DECLARATIONS FUNCTION PBMAIN() PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR _ %ICC_INTERNET_CLASSES) GLOBAL ghPage() AS LONG GLOBAL gtest AS LONG ShowDIALOG1 %HWND_DESKTOP ShowDIALOG2 %HWND_DESKTOP END FUNCTION CALLBACK FUNCTION ShowDIALOG1Proc() SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG DIALOG SEND CBHNDL, %DM_SETDEFID,%IDOK,0 RedrawWindow CBHNDL, BYVAL 0&, BYVAL 0&, %RDW_ERASE OR %RDW_INVALIDATE OR %RDW_ALLCHILDREN OR %RDW_ERASENOW RedrawWindow ghPage(1), BYVAL 0&, BYVAL 0&, %RDW_ERASE OR %RDW_INVALIDATE OR %RDW_ALLCHILDREN OR %RDW_ERASENOW CASE %WM_COMMAND SELECT CASE AS LONG CBCTL CASE %IDCANCEL DIALOG END CBHNDL,0 CASE %IDOK IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN ? "%IDOK in ShowDIALOG1Proc, gtest: " + STR$(gtest) DIALOG END CBHNDL,0 END IF END SELECT END SELECT END FUNCTION CALLBACK FUNCTION ShowDIALOG2Proc() SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG LOCAL x,y AS LONG CONTROL GET LOC GetParent(CBHNDL),%IDC_SYSTABCONTROL32_1 TO x,y DIALOG SET LOC CBHNDL,x + 4,y + 16 CONTROL SET FOCUS CBHNDL,%IDC_TEXTBOX1 FUNCTION = 1 CASE %WM_COMMAND SELECT CASE AS LONG CBCTL CASE %IDC_TEXTBOX1 IF CBCTLMSG = %EN_KILLFOCUS THEN gtest = 1 END IF END SELECT END SELECT END FUNCTION FUNCTION SampleTabCtrl(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _ AS LONG) AS LONG LOCAL i AS LONG LOCAL hCtl AS DWORD LOCAL szBuf AS ASCIIZ * 32 LOCAL tTC_Item AS TC_ITEM CONTROL HANDLE hDlg, lID TO hCtl tTC_Item.Mask = %TCIF_TEXT tTC_Item.iImage = -1 tTC_Item.pszText = VARPTR(szBuf) FOR i = 0 TO lCount - 1 szBuf = USING$("Tab #", i) TabCtrl_InsertItem(hCtl, i, tTC_Item) NEXT i END FUNCTION FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG1->-> LOCAL hDlg AS DWORD DIALOG NEW hParent, "MainWindow", 221, 161, 311, 169, %WS_POPUP OR _ %WS_BORDER OR %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR _ %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR _ %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_ABSALIGN OR %DS_MODALFRAME OR _ %DS_CENTER OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _ %WS_EX_WINDOWEDGE OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD BUTTON, hDlg, %IDOK, "&Ok", 174, 140, 60, 15 DIALOG SEND hDlg, %DM_SETDEFID, %IDOK, 0 CONTROL ADD "SysTabControl32", hDlg, %IDC_SYSTABCONTROL32_1, _ "SysTabControl32_1", 10, 25, 295, 105, %WS_CHILD OR %WS_VISIBLE OR _ %WS_TABSTOP OR %TCS_SINGLELINE OR %TCS_RIGHTJUSTIFY, _ %WS_EX_TRANSPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Cancel", 241, 140, 60, 15 #PBFORMS END DIALOG SampleTabCtrl hDlg, %IDC_SYSTABCONTROL32_1, 5 REDIM ghPage(1) ghPage(0) = hDlg ghPage(1) = ShowDIALOG2(hDlg) DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt #PBFORMS BEGIN CLEANUP %IDD_DIALOG1 #PBFORMS END CLEANUP FUNCTION = lRslt END FUNCTION FUNCTION ShowDIALOG2(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG2->-> LOCAL hDlg AS DWORD DIALOG NEW hParent, "Child1", 292, 179, 201, 75, %WS_CHILD OR %WS_BORDER _ OR %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _ %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE OR %DS_ABSALIGN OR _ %DS_MODALFRAME OR %DS_CONTROL OR %DS_CENTER OR %DS_3DLOOK OR _ %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_WINDOWEDGE OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "TextBox1", 5, 5, 100, 13 #PBFORMS END DIALOG DIALOG SHOW MODELESS hDlg, CALL ShowDIALOG2Proc TO lRslt #PBFORMS BEGIN CLEANUP %IDD_DIALOG2 #PBFORMS END CLEANUP FUNCTION = hDlg END FUNCTION
Leave a comment:
-
I've never had any real success editing data "as the field is being left" but just this week I was testing some things for another purpose and made a discovery which might be of some use....
If the problem is, the user clicks the "OK" button before the field is edited...
The "OK" button gets a WM_COMMAND/BN_SETFOCUS BEFORE the button gets WM_COMMAND/BN_CLICKED. This requires the OK button be created with style BS_NOTIFY.
Maybe you can do something with the BN_SETFOCUS notification from the "OK" button?
The other path I started down was to subclass the edit controls, looking for the WM_SETFOCUS notification. On this notification, wParam is a handle to the control which is LOSING the focus... that is, "where did this come from?" That wasn't working out for me, so I never got to the next step, which would be picking off the WM_KILLFOCUS, in which wParam is a handle to the control which is GAINING the focus.
Knowing "where the focus WAS before it came here" or "where the focus WILL BE GOING when I leave this control" might be useful?
The other thing I've tried over the years... not using IDOK as the ID of the OK button. In these cases if I got WM_COMMAND/IDOK I 'eat' it and optionally post a click to the "real" OK button. If nothing else that allows me to know that the user hit the "Enter" key rather than clicking on the "real OK" button.
Some stuff to play with, anyway.
MCM
Leave a comment:
-
Example input of date: The user types "9.13.9" (german notation, month in the middle), the program should correct this to "09.12.09", e.g.. Or the user types "65" as year which makes no sense in the actual context. This should be corrected or complained not before leaving the field. Or: A date must be prior to another date. That can be tested only after leaving the field as well.
Leave a comment:
-
Frankly, I've only found a couple problems with doing field validation on
KillFocus. You have to allow for the user switching to another program or
minimizing your app. No big thing once you realize that it can happen.
And for me, the upside is that you can provide instant feed back ( such
as updating related fields and validating the field you just left ) without
having to wait for the user to click some other button. This is also good
if you have users that refuse to follow the normal flow of field entry
and go clicking whichever field they want. This way you know that they
have entered/changed the field as much as they want and that you can
do what checks you need to before going on to another field.
Just my opinion but it's worked well for over 30 years in various languages.
Leave a comment:
-
Instead of validating the user input when the control looses focus, you could try doing it as the user types.Last edited by Gerhard Praetorius; 29 Jan 2009, 05:05 AM.
Leave a comment:
-
Instead of validating the user input when the control looses focus, you could try doing it as the user types. Using EN_CHANGE for example -
Code:CASE %IDC_TEXTBOX1 IF CBCTLMSG = %EN_CHANGE THEN CONTROL GET TEXT CBHNDL, %TXT_TEXTBOX1 TO sTest ' check input e.g. x = VERIFY (sTest , "-+,.1234567890") IF x > 0 THEN sTest = REMOVE$(sTest, MID$(sTest, x, 1)) CONTROL SET TEXT CBHNDL, %TXT_TEXTBOX1, sTest CONTROL SEND CBHNDL, %TXT_TEXTBOX1, %EM_SETSEL, x-1, x-1 END IF END IF
Leave a comment:
-
>you have to test inputs in the parentdialog, and that means
You'll need so anyway.
And now you have to 'fix' any possible way that the user can leave your control.
>and which one has to be tested actually.
That may be a design flaw.
I am not saying it is impossible but i have experiance with this.
Lostfocus means the control does no longer has the focus.
That means you may have a empty-check in the control now having the focus.
By using setfocus you'll keep jumping.
If you must.. use WM_GETDLGCODE to detect and prevent.
Use a mousehook to prevent the click (i did that on one occasion).
You see, it is not that simple.
Controls are diverse and maybe the check is no longer behaving the same as you did on an older control.
The user will not like that.
Testing under a 'submit' is accepted behaviour, messageboxes during a lostfocus is super annoying.
You'll also get the lostfocus destroycaret syndrome, good luck..
Leave a comment:
-
No bad idea to illustrate the issue in a code snipped, Chris. Trying this I found out: In a small test environment the problem does not exist.
So it must be something special in my complex code which I have to find out. Is it really bad practice, Edwin, to test under "lostfocus"? With "OK",
"CANCEL" and "%WM_SYSCOMMAND" you have to test inputs in the parentdialog, and that means: It's not even easy to find out which of the controls in half a dozen or more childwindows has had the lost focus, and which one has to be tested actually.
Leave a comment:
-
Testing input under a 'lostfocus' is bad practise in most if not all cases.
Just test under the ok button.
You can also test when you click 'X' but that should be a cancel.
Leave a comment:
-
Problem with childwindows
Hi all,
I have a problem with tab controls and childwindows. In a childwindow there is a textbox with user input. After "CBCTLMSG = %EN_KILLFOCUS"
the program checks if the user input is OK. So far all right. The issue occurs when the focus changes by striking the Enter-key.
Then the program performs the "OK"-command in the parentwindow (the "OK"-button has the %DM_SETDEFID-style) BEFORE reaching %EN_KILLFOCUS in
the childwindow. So the dialog is closed before the user input is proved and eventually corrected. This does not happen when the "OK"-button
is activated by mouse-click. How can I make sure that the program "visits" %EN_KILLFOCUS first under all circumstances?Tags: None
Leave a comment: