I'm a newbie to PowerBasic and not very proficient at VB, but I've written some fairly complex stuff in VB long ago. I'm using PB because I want to create distributable code that doesn't require .net.
I am trying to create an application that students can use to estimate what their grade will be by entering scores they've got and possible scores on future assignments. Very simple in concept. Several text boxes where decimal numbers can be entered and a couple of buttons.
I'm having trouble controlling the focus. My intent is to validate data upon its display back to the user, and if the data is in error and display a message box indicating what's wrong. I want to prevent focus from changing so long as there is an error in the content of a textbox.
Below is an extract of my code which demonstrates my problem. When an error occurs in the content of the 2nd textbox, focus transfers to the 1st textbox, and won't change until I type something in the first textbox. I can't figure out what's happening and thus can't fix it. It must have something to do with the flow of control via the messages, but I'm so ignorant of message flow it's pathetic. I hope to fix that as time goes on, but for now if anyone can explain what's happening and/or how to get the focus in the right place (on the textbox containing the error), I would much appreciate it.
Thanks in advance,
Steve
I am trying to create an application that students can use to estimate what their grade will be by entering scores they've got and possible scores on future assignments. Very simple in concept. Several text boxes where decimal numbers can be entered and a couple of buttons.
I'm having trouble controlling the focus. My intent is to validate data upon its display back to the user, and if the data is in error and display a message box indicating what's wrong. I want to prevent focus from changing so long as there is an error in the content of a textbox.
Below is an extract of my code which demonstrates my problem. When an error occurs in the content of the 2nd textbox, focus transfers to the 1st textbox, and won't change until I type something in the first textbox. I can't figure out what's happening and thus can't fix it. It must have something to do with the flow of control via the messages, but I'm so ignorant of message flow it's pathetic. I hope to fix that as time goes on, but for now if anyone can explain what's happening and/or how to get the focus in the right place (on the textbox containing the error), I would much appreciate it.
Thanks in advance,
Steve
Code:
#PBFORMS CREATED V1.51 #COMPILE EXE #DIM ALL '------------------------------------------------------------------------------ ' ** Includes ** '------------------------------------------------------------------------------ #PBFORMS BEGIN INCLUDES #IF NOT %DEF(%WINAPI) #INCLUDE "WIN32API.INC" #ENDIF #INCLUDE "PBForms.INC" #PBFORMS END INCLUDES '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Constants ** '------------------------------------------------------------------------------ #PBFORMS BEGIN CONSTANTS %IDD_DIALOG1 = 101 %IDC_LBL_HomeworkScore = 1001 %IDC_LBL_ExamScores = 1002 %IDC_TB_HomeworkScore = 1005 %IDC_TB_Exam1Score = 1006 %IDC_TB_FinalExamScore = 1012 %IDC_BN_Estimate = 1014 %IDC_BN_Exit = 1015 #PBFORMS END CONSTANTS '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Declarations ** '------------------------------------------------------------------------------ DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG #PBFORMS DECLARATIONS '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Main Application Entry Point ** '------------------------------------------------------------------------------ FUNCTION PBMAIN() GLOBAL SizeError, ThisScore AS LONG ShowDIALOG1 %HWND_DESKTOP END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** CallBacks ** '------------------------------------------------------------------------------ CALLBACK FUNCTION ShowDIALOG1Proc() LOCAL EditString, GoodDataString AS STRING LOCAL Category, Assignment AS LONG SELECT CASE AS LONG CB.MSG CASE %WM_INITDIALOG ' Initialization handler CASE %WM_NCACTIVATE STATIC hWndSaveFocus AS DWORD IF ISFALSE CB.WPARAM THEN ' Save control focus hWndSaveFocus = GetFocus() ELSEIF hWndSaveFocus THEN ' Restore control focus SetFocus(hWndSaveFocus) hWndSaveFocus = 0 END IF CASE %WM_COMMAND ' Process control notifications SELECT CASE AS LONG CB.CTL CASE %IDC_TB_HomeworkScore ThisScore=%IDC_TB_HomeworkScore IF CB.CTLMSG = %EN_KILLFOCUS THEN IF SizeError THEN CONTROL SET FOCUS CB.HNDL, ThisScore END IF END IF IF CB.CTLMSG = %EN_CHANGE THEN ' after typed data is displayed back to user SizeError=0 CONTROL GET TEXT CB.HNDL, ThisScore TO EditString IF VAL(EditString)>100 THEN SizeError=-1 MSGBOX "Must be 100 or less", %MB_TASKMODAL CONTROL SET FOCUS CB.HNDL, ThisScore END IF END IF CASE %IDC_TB_Exam1Score ThisScore=%IDC_TB_Exam1Score IF CB.CTLMSG = %EN_KILLFOCUS THEN IF SizeError THEN CONTROL SET FOCUS CB.HNDL, ThisScore END IF END IF IF CB.CTLMSG = %EN_CHANGE THEN ' after typed data is displayed back to user SizeError=0 CONTROL GET TEXT CB.HNDL, ThisScore TO EditString IF VAL(EditString)>100 THEN SizeError=-1 MSGBOX "Must be 100 or less", %MB_TASKMODAL CONTROL SET FOCUS CB.HNDL, ThisScore END IF END IF CASE %IDC_BN_Estimate IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN MSGBOX "%IDC_BN_Estimate=" + _ FORMAT$(%IDC_BN_Estimate), %MB_TASKMODAL END IF CASE %IDC_BN_Exit IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN DIALOG END CBHNDL, %IDD_Dialog1 END IF END SELECT END SELECT END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Dialogs ** '------------------------------------------------------------------------------ FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG1->-> LOCAL hDlg AS DWORD LOCAL hFont1 AS DWORD LOCAL hFont2 AS DWORD DIALOG NEW hParent, "Grade Estimator", 105, 91, 320, 385, TO hDlg CONTROL ADD LABEL, hDlg, %IDC_LBL_HomeworkScore, "Homework Score", 10, _ 20, 100, 20 CONTROL ADD LABEL, hDlg, %IDC_LBL_ExamScores, "Exam Scores", 30, 60, _ 80, 20 20 CONTROL ADD TEXTBOX, hDlg, %IDC_TB_HomeworkScore, "", 115, 30, 45, 20, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_RIGHT OR _ %ES_AUTOHSCROLL, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR CONTROL ADD TEXTBOX, hDlg, %IDC_TB_Exam1Score, "", 115, 70, 45, 20, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_RIGHT OR _ %ES_AUTOHSCROLL, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR CONTROL ADD BUTTON, hDlg, %IDC_BN_Estimate, "Estimate", 10, 350, 55, 20 CONTROL ADD BUTTON, hDlg, %IDC_BN_Exit, "Exit", 255, 350, 45, 20 hFont1 = PBFormsMakeFont("MS Sans Serif", 16, 400, %FALSE, %FALSE, _ %FALSE, %ANSI_CHARSET) hFont2 = PBFormsMakeFont("MS Sans Serif", 12, 400, %FALSE, %FALSE, _ %FALSE, %ANSI_CHARSET) DIALOG SEND hDlg, %WM_SETFONT, hFont1, 0 CONTROL SEND hDlg, %IDC_LBL_HomeworkScore, %WM_SETFONT, hFont2, 0 CONTROL SEND hDlg, %IDC_LBL_ExamScores, %WM_SETFONT, hFont2, 0 CONTROL SEND hDlg, %IDC_TB_HomeworkScore, %WM_SETFONT, hFont2, 0 CONTROL SEND hDlg, %IDC_TB_Exam1Score, %WM_SETFONT, hFont2, 0 CONTROL SEND hDlg, %IDC_BN_Estimate, %WM_SETFONT, hFont2, 0 CONTROL SEND hDlg, %IDC_BN_Exit, %WM_SETFONT, hFont2, 0 #PBFORMS END DIALOG DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt #PBFORMS BEGIN CLEANUP %IDD_DIALOG1 DeleteObject hFont1 DeleteObject hFont2 #PBFORMS END CLEANUP FUNCTION = lRslt END FUNCTION
Comment