I'm puzzled by the behavior of the IF..THEN..END IF block in my error checking in the following program (starting at line 116 in the code).
I can only assume it has to do with the value of the variable iErrCode (or possibly the ERRCLEAR statement) but I'm not getting it. I've read the help file carefully, even the part about short-circuit evaluation but I don't think that applies here. In this block:
The "ITERATE LOOP" instruction is reached but not executed. If, however, I move the variable iErrCode = 0 out of the IF block and place it at the beginning of the loop, it works as expected. Is this correct behavior? It would seem to me that if the compiler was going to stop evaluating statements inside the IF block (because iErrorCode has been set to 0 or ERRCLEAR was executed) that it wouldn't reach the ITERATE LOOP statement (but while running in debug mode you can see that it clearly reaches that statement and ignores it..thereby falling out of the loop).
I had suspected that because the value of iErrCode was set to 0, that the program was jumping to the end of the loop and executing the LOOP WHILE iErrCode <> 0 statement, but no, it jumps passed that all together. And anyway, it should return to the beginning of the outermost DO (line 41).
I'm posting the whole little program because it's not very long. Just type anything in the input box and hit enter. The program will display an error message and then appear to succeed (displaying a message that it did) but actually does nothing. You don't need any actual data file to see the effect.
The whole reason I came across this was to try out using the mouse functions with a text-mode interface. Works pretty well, except for the flickering (see note in the code, line 102). My second question was, can anyone think of way to restructure to flow of the program so as not to constantly re-draw the buttons once they've been triggered by the mouse (but still keeping the mouse-over effect)?
PBCC 5.00, by the way.
Thanks.
I can only assume it has to do with the value of the variable iErrCode (or possibly the ERRCLEAR statement) but I'm not getting it. I've read the help file carefully, even the part about short-circuit evaluation but I don't think that applies here. In this block:
Code:
hInFile = FREEFILE OPEN sInFileName FOR INPUT AS #hInFile IF ERR THEN iErrCode = ERR CALL ErrTrap(iErrCode) 'subroutine to display an error message ERRCLEAR iErrCode = 0 ITERATE LOOP 'ITERATE LOOP is never executed. Falls through. END IF
I had suspected that because the value of iErrCode was set to 0, that the program was jumping to the end of the loop and executing the LOOP WHILE iErrCode <> 0 statement, but no, it jumps passed that all together. And anyway, it should return to the beginning of the outermost DO (line 41).
I'm posting the whole little program because it's not very long. Just type anything in the input box and hit enter. The program will display an error message and then appear to succeed (displaying a message that it did) but actually does nothing. You don't need any actual data file to see the effect.
The whole reason I came across this was to try out using the mouse functions with a text-mode interface. Works pretty well, except for the flickering (see note in the code, line 102). My second question was, can anyone think of way to restructure to flow of the program so as not to constantly re-draw the buttons once they've been triggered by the mouse (but still keeping the mouse-over effect)?
PBCC 5.00, by the way.
Thanks.
Code:
#COMPILE EXE #DIM ALL %TRUE = -1 %FALSE = 0 DECLARE SUB DrawScreen () DECLARE SUB ErrTrap (iErrCode AS LONG) DECLARE SUB DrawFrame (row1 AS LONG, row2 AS LONG, col1 AS LONG, col2 AS LONG, _ FgColor AS LONG, BgColor AS LONG, HiLite AS LONG, iShadow AS LONG) FUNCTION PBMAIN () AS LONG DIM sLineIn AS STRING DIM hInFile AS LONG DIM hOutFile AS LONG DIM sInFileName AS STRING DIM sOutFileName AS STRING DIM sField() AS STRING DIM iErrCode AS LONG DIM sKey AS STRING DIM iClick AS LONG DIM iMX AS LONG DIM iMY AS LONG DIM iCount AS LONG DIM iColPos AS LONG DIM i AS LONG '///////////////////////////////////////// CONSOLE SCREEN 25, 80 DrawScreen () CURSOR OFF MOUSE ON MOUSE 3, MOVE, DOWN, UP sOutFileName = "ChapterDuesLookupTable.txt" DO sInFileName = "" sKey = "" iColPos = 22 'iErrCode = 0 'this variable placed here gives expected results. 'i.e, you'll get an error and the loop will repeat. COLOR 15, 0 LOCATE 14, iColPos : PRINT STRING$(30, " ") LOCATE 14, iColPos : PRINT "_" DO iMX = MOUSEX iMY = MOUSEY sKey = WAITKEY$ ' Wait for a key or mouse event SELECT CASE LEN(sKey) CASE 1 'trap single keypress (normal keys) IF sKey = $CR THEN EXIT DO END IF COLOR 15, 0 LOCATE 14, iColPos: PRINT sKey; "_" : INCR iColPos sInFileName = sInFileName & sKey 'build the input string (very limited) CASE 2 'trap extended keys (ALT) CASE 4 'trap mouse IF ((iMX >= 50 AND iMX <= 57) AND (iMY >= 16 AND iMY <= 18)) THEN 'Mouse is over "Help" DrawFrame (16, 18, 50, 57, 0, 8, 15, 0) CURSOR OFF LOCATE 17, 52 : PRINT "Help" DrawFrame (16, 18, 37, 44, 0, 8, 0, 0) CURSOR OFF LOCATE 17, 39 : PRINT "Exit" SELECT CASE ASC(sKey, 3) 'Parameter 3 = event. CASE 4 'Mouse click DrawFrame (16, 18, 50, 57, 15, 8, 0, 0) CURSOR OFF COLOR 0, 8 LOCATE 17, 52 : PRINT "Help" 'call a help screen here END SELECT ELSEIF ((iMX >= 37 AND iMX <= 44) AND (iMY >= 16 AND iMY <= 18)) THEN 'Mouse is over "Exit" DrawFrame (16, 18, 37, 44, 0, 8, 15, 0) CURSOR OFF LOCATE 17, 39 : PRINT "Exit" DrawFrame (16, 18, 50, 57, 0, 8, 0, 0) CURSOR OFF LOCATE 17, 52 : PRINT "Help" SELECT CASE ASC(sKey, 3) CASE 4 DrawFrame (16, 18, 37, 44, 15, 8, 0, 0) CURSOR OFF COLOR 0, 8 LOCATE 17, 39 : PRINT "Exit" SLEEP 500 'just to see the effect EXIT FUNCTION END SELECT ELSE 'this section is constantly being called/redrawn when the mouse 'moves, causing flicker. Is there a way to avoid this? DrawFrame (16, 18, 37, 44, 0, 8, 0, 0) 'Draw the Exit button DrawFrame (16, 18, 50, 57, 0, 8, 0, 0) 'Draw the help button LOCATE 17, 39 : PRINT "Exit" LOCATE 17, 52 : PRINT "Help" END IF END SELECT LOOP hInFile = FREEFILE OPEN sInFileName FOR INPUT AS #hInFile IF ERR THEN 'Here's the problem block.. iErrCode = ERR CALL ErrTrap(iErrCode) ERRCLEAR iErrCode = 0 ITERATE LOOP 'Iterate loop is never executed. Falls through. END IF hOutFile = FREEFILE OPEN sOutFileName FOR OUTPUT AS #hOutFile IF ERR THEN iErrCode = ERR CALL ErrTrap(iErrCode) ERRCLEAR iErrCode = 0 CLOSE #hOutFile KILL sOutFileName ITERATE LOOP END IF LOOP WHILE iErrCode <> 0 'we shouldn't get here if the IF ERR block is executed. '///////////////////////////////////////// PRINT# hOutFile, "// You can manually edit this file if needed. PRINT# hOutFile, "// However, be sure to use Notepad or DOS Edit to do so." PRINT# hOutFile, "// Saving this file in MS Word format will cause the PRINT# hOutFile, "// ""ChapterDuesLookup"" program to fail. PRINT# hOutfile, "// PRINT# hOutFile, "// The only rule that must be followed is the number and order of the fields. PRINT# hOutFile, "// They should be as follows: PRINT# hOutFile, "// PRINT# hOutFile, "// Chapter_Number | Chapter_Name | New_IND | Renew_IND | New_FAM | Renew_FAM | Life_IND | Life_FAM | Comments" PRINT# hOutFile, "// PRINT# hOutFile, "// PRINT# hOutFile, "// If Chapter_Name is unkown or not listed, it can be blank. If that's the case, PRINT# hOutFile, "// Leave at least once space between pipe characters '|'. PRINT# hOutFile, "// If there are no chapter dues for a certain field they can also be blank PRINT# hOutFile, "// or contain ""$0.00"". If blank, Leave at least once space between colons. PRINT# hOutFile, PRINT# hOutFile, "// this file can be programatially generated by saving the ""Chapter_Dues.xls"" PRINT# hOutFile, "// spreadsheet as a comma separated .txt file and then running the program PRINT# hOutFile, "// ""ConvertLookup.exe"" and entering the saved .txt file as the Input File name when prompted. PRINT# hOutfile, LINE INPUT #hInFile, sLineIn 'read the first line and ignore it. It's the header in the .txt file. WHILE NOT EOF (#hInFile) LINE INPUT #hInFile, sLineIn sLineIn = RTRIM$(sLineIn, ANY ", ") iCount = PARSECOUNT(sLineIn) 'store the number of fields in iCount IF iCount <> 9 THEN 'some fields in the spreadsheet are blank sLineIn = sLineIn & STRING$(9 - iCount, ",") 'but there should be nine. iCount = PARSECOUNT(sLineIn) 'recalculate iCount. Blanks will be handled END IF 'by the Lookup Program REDIM sField(iCount) 'redimension the array to iCount FOR i = 1 TO iCount sField(i) = PARSE$(sLineIn, i) 'If it's the last field, no trailing "|" IF i = iCount THEN PRINT# hOutFile, sField(i) ELSE PRINT# hOutFile, sField(i) & " | "; 'If not the last field, insert a "|" between fields. END IF NEXT WEND CLOSE #hOutFile CLOSE #hInfile DrawFrame (16, 20, 14, 67, 0, 8, 15, -1) 'draw a "window" COLOR 0, 8 CURSOR OFF LOCATE 17, 16 : PRINT $DQ & sOutFileName & $DQ & " created successfully." LOCATE 19, 20 : PRINT " Press any key to Exit" WAITKEY$ END FUNCTION '////////////////////////////////////////////////////////////////////////////////// '================================================================================= '////////////////////////////////////////////////////////////////////////////////// SUB ErrTrap(iErrCode AS LONG) SELECT CASE iErrCode 'What error number was encountered? CASE 53 'File not found PCOPY 1, 2 CURSOR OFF CALL DrawFrame (2, 11, 3, 50, 0, 8, 15, -1) COLOR 0, 8 LOCATE 2, 5 : PRINT "[ ERROR: File Not Found ]" LOCATE 2, 6 : COLOR 15, 5, 7 COLOR 0, 8 LOCATE 4, 5 : PRINT " The file name you entered was not found. " LOCATE 5, 5 : PRINT " Make sure you spelled it correctly and make " LOCATE 6, 5 : PRINT " sure it is in the same folder from which " LOCATE 7, 5 : PRINT " *THIS* program is being run. " LOCATE 9, 5 : PRINT " <press any key to try again> " LOCATE 12, 20 : COLOR 8, 0, 18 WAITKEY$ 'wait for a keypress. PCOPY 2, 1 CASE 64 'Bad File Name PCOPY 1, 2 CURSOR OFF CALL DrawFrame (2, 11, 3, 50, 0, 8, 15, -1) COLOR 0, 8 LOCATE 2, 5 : PRINT "[ ERROR: Bad File Name ]" LOCATE 2, 6 : COLOR 15, 5, 7 COLOR 0, 8 LOCATE 4, 5 : PRINT " The file name you entered was not found. " LOCATE 5, 5 : PRINT " Make sure you spelled it correctly and make " LOCATE 6, 5 : PRINT " sure it is in the same folder from which " LOCATE 7, 5 : PRINT " *THIS* program is being run. " LOCATE 9, 5 : PRINT " <press any key to try again> " LOCATE 12, 20 : COLOR 8, 0, 18 WAITKEY$ PCOPY 2, 1 CASE 70 'File in use, or permission denied PCOPY 1, 2 CURSOR OFF CALL DrawFrame (2, 11, 3, 50, 0, 8, 15, -1) COLOR 0, 8 LOCATE 2, 5 : PRINT "[ ERROR: Permission Denied. ]" LOCATE 2, 6 : COLOR 15, 5, 7 COLOR 0, 8 LOCATE 5, 5 : PRINT " The file name you entered is either write " LOCATE 6, 5 : PRINT " protected or is in use by another application. " LOCATE 7, 5 : PRINT " Close the file and try again. " LOCATE 9, 5 : PRINT " <Press any key to try again> " LOCATE 12, 20 : COLOR 8, 0, 18 WAITKEY$ PCOPY 2, 1 CASE 76 'path not found PCOPY 1, 2 CURSOR OFF CALL DrawFrame (2, 11, 3, 52, 0, 8, 15, -1) COLOR 0, 8 LOCATE 2, 5 : PRINT "[ ERROR: Path not found ]" LOCATE 2, 6 : COLOR 15, 5, 7 COLOR 0, 8 LOCATE 4, 5 : PRINT "The path name you entered does not exist. If " LOCATE 5, 5 : PRINT "there are spaces in the path, try inclosing the" LOCATE 6, 5 : PRINT " entire pathname in quotes, i.e. " LOCATE 7, 5 : PRINT " ""C:\Folder Name\File Name.txt"" " LOCATE 9, 5 : PRINT " <Press any key to try again> " LOCATE 12, 20 : COLOR 8, 0, 18 WAITKEY$ PCOPY 2, 1 CASE ELSE 'we don't know what happened. PCOPY 1, 2 CURSOR OFF CALL DrawFrame (2, 11, 3, 28, 0, 8, 15, -1) COLOR 0, 8 LOCATE 2, 5 : PRINT "[ ERROR: Unkown Error ]" LOCATE 2, 6 : COLOR 15, 5, 7 COLOR 0, 8 LOCATE 4, 5 : PRINT " [Unknown Error] " LOCATE 5, 5 : PRINT " Error: #" & STR$(ERR) LOCATE 6, 5 : PRINT " " LOCATE 7, 5 : PRINT " " LOCATE 9, 5 : PRINT " Press Any Key " LOCATE 12, 20 : COLOR 8, 0, 11 WAITKEY$ PCOPY 2, 1 END SELECT 'FUNCTION = iErrCode 'made this a SUB instead of FUNCTION. 'there's no reason to return a result here. END SUB '////////////////////////////////////////////////////////////////////////////// '============================================================================== '////////////////////////////////////////////////////////////////////////////// SUB DrawFrame (row1 AS LONG, row2 AS LONG, col1 AS LONG, col2 AS LONG, _ FgColor AS LONG, BgColor AS LONG, HiLite AS LONG, iShadow AS LONG) LOCAL iShadowCol AS LONG LOCAL iShadowRow1, iShadowRow2 AS LONG LOCAL i AS LONG COLOR HiLite, BgColor LOCATE row1, col1 PRINT CHR$(201); STRING$(col2 - col1, CHR$(205)); CHR$(187) INCR row1 FOR i = row1 TO row2 - 1 LOCATE i, col1 COLOR HiLite, BgColor PRINT CHR$(186); STRING$(col2 - col1, " "); COLOR FgColor, Bgcolor PRINT CHR$(186) NEXT LOCATE row2, col1 PRINT CHR$(200); STRING$(col2 - col1, CHR$(205)); CHR$(188) 'draw a shadow effect if the iShadow parameter is true (non zero) IF ISTRUE iShadow THEN iShadowCol = Col2 + 2 iShadowRow1 = row1 iShadowRow2 = row2 + 1 FOR i = iShadowRow1 TO iShadowRow2 LOCATE iShadowRow1, iShadowCol COLOR 0, 0, 1 INCR iShadowRow1 NEXT LOCATE iShadowRow2, Col1 + 1 COLOR 0, 0, iShadowCol - (Col1 + 1) END IF END SUB '//////////////////////////////////////////////////////////////////////////////////// '=================================================================================== '/////////////////////////////////////////////////////////////////////////////////// SUB DrawScreen () CLS LOCAL i AS LONG 'This draws the "desktop" background COLOR 0, 3 'Black, Cyan FOR i = 1 TO 25 IF (i = 24 OR i = 25) THEN LOCATE i, 1 PRINT STRING$(80, CHR$(177)); ELSE LOCATE i, 1 PRINT STRING$(80, CHR$(177)) END IF NEXT DrawFrame (11, 20, 20, 60, 0, 8, 15, -1) 'draw a "window" COLOR 0, 8 LOCATE 12, 22 : PRINT "File to convert:" COLOR 0, 0 LOCATE 14, 22 : PRINT STRING$(30, " ") 'Draw an input box COLOR 7, 8 : LOCATE 16, 22 'PRINT "Type ""exit"" to quit" DrawFrame (16, 18, 37, 44, 0, 8, 0, 0) 'Draw the Exit button DrawFrame (16, 18, 50, 57, 0, 8, 0, 0) 'Draw the help button LOCATE 17, 39 : PRINT "Exit" LOCATE 17, 52 : PRINT "Help" END SUB
Comment