I've been chasing a GPF problem too. It may well be my error,
but I can't seem to isolate it. An "isolation version" is now
231 lines long and I'm trying to reduce that.
The error is curious because It never occurs if the mouse is
used to click a buttons; only if the ALT+Letter is used
instead of the mouse. (BTW I'm using PB DLL 6.0 under NT 4.0
with SP6).
To cause the error in the program below, sequence between the
dialogs using ALT+L, ALT+B, ALT+L, ALT+B, etc.
I've homed in on line 70 as the culprit where a local array is
dimensioned based on a value n in a user declared TYPE, in this
case 'This.n'. Values from an ASCIIZ array in the structure are
transferred from the structure to the local array, which is
then to be used a parameter to a CONTROL ADD COMBOBOX. Reading
from the ASCIIZ array is the problem, not writing into the local
DD() array. (and reading from This.DD(i), where i=1 to 3 is no
problem; only if the index is 4 or greater does the error occur).
Does anyone have any suggestions on tools to use to find this
type of problem. THE ABOVE ANALYSIS MAY BE FAR OFF THE MARK.
A previous random store may have caused this symptom. But
without DDT source code it is hard to track back - I'll
keep trying.
I'd appreciate any advice. More experienced Windows programs
may see my error quickly, without even having to run the program.
--------------------------------------------------------------
The failing code follows
--------------------------------------------------------------
#COMPILE EXE
#REGISTER NONE
#DEBUG ERROR ON
$INCLUDE "WIN32API.INC"
TYPE ButtonList
LeType AS LONG
event AS LONG
x1 AS LONG
y1 AS LONG
w1 AS LONG
h1 AS LONG
x2 AS LONG
y2 AS LONG
w2 AS LONG
h2 AS LONG
L AS LONG
columns AS LONG
Ti AS LONG
options AS LONG
ex_options AS LONG
n AS LONG
defaultselect AS LONG
message AS ASCIIZ *100
DD(100) AS ASCIIZ *100
END TYPE
GLOBAL LoopCount AS LONG
GLOBAL hDlg AS LONG ' Global Dialog handle
GLOBAL DlgCount AS LONG ' Nested Menu Count
GLOBAL FirstButtonID AS LONG ' Device ID of first button on screen
GLOBAL W AS LONG ' Width of Button to be gnerated
GLOBAL T AS LONG ' Horizontal Tab character count on page
GLOBAL L AS LONG ' Line count within page
GLOBAL Columns AS LONG ' Number of columns in menu
GLOBAL TabCount() AS LONG ' Tabs Array
GLOBAL NullList() AS STRING
GLOBAL Speeds() AS STRING
GLOBAL boxColor AS LONG
GLOBAL ButtonTable() AS ButtonList
GLOBAL Bi() AS LONG
FUNCTION MakeButton(index AS LONG) AS LONG
#REGISTER NONE
LOCAL This AS ButtonList
This=ButtonTable(index)
SELECT CASE This.LeType
CASE 1
TabCount(1)=MAX(0,(320-This.Columns*W)/(This.Columns+1))
FOR k&=2 TO This.Columns
TabCount(k&)=TabCount(k&-1)+TabCount(1)+W
NEXT k&
This.x1=TabCount(This.Ti)
This.x2=W+This.x1-This.w2
This.y1=17*This.L+5
This.y2=This.y1+1
This.w1=W-This.w2-1
IF FirstButtonID=0 THEN FirstButtonID=This.event
CONTROL ADD BUTTON,hDlg,This.event,This.message,This.x1,_
This.y1,This.w1,This.h1,%BS_LEFT OR %WS_TABSTOP OR %BS_OWNERDRAW
IF This.n THEN
This.h2=11*10
'***************************************************************************
'OPEN"Dump.txt"FOR APPEND AS #9
DIM DD(1:This.n) AS STRING
'PRINT #9,"** Allocate DD(1:This.n): "RIGHT$(" "+STR$(LoopCount),4)
'FOR i&=1 TO This.n
'************** Accessing This.DD(i&)in the PRINT statement causes GPF too
'PRINT #9,RIGHT$(" "+STR$(i&),4)"|"HEX$(VARPTR(DD(i&)))"="This.DD(i&)"|":
'NEXT i&
'CLOSE #9
FOR i&=1 to 4 ' No error if loop goes to 3
DD(i&)=This.DD(i&) '<><><> Accessing This.DD(i&) appears to cause a GPF
NEXT i&
'PRINT #9,"//// Exit Loop: "RIGHT$(" "+STR$(LoopCount),4)
INCR LoopCount
'****************************************************************************
' The array DD() is supposed to be used on the following line, but
' Speeds() has been substituted to make fault isolation easier
CONTROL ADD COMBOBOX,hDlg,This.event+1,Speeds(),This.x2,_
This.y2,This.w2,This.h2,%CBS_DROPDOWNLIST OR %WS_TABSTOP
COMBOBOX SELECT hDlg,This.event+1,This.defaultselect
END IF
END SELECT
END FUNCTION
CALLBACK FUNCTION MA_Main()
#REGISTER NONE
SELECT CASE CBMSG
CASE %WM_DRAWITEM
DIM t AS DRAWITEMSTRUCT PTR
t=CBLPARAM
'Color area and frame it with black
FillRect @t.hDc,@t.rcItem,boxColor
FrameRect @t.hDc,@t.rcItem,GetStockObject(%BLACK_BRUSH)
SetBkMode @t.hDC,%TRANSPARENT
CONTROL GET TEXT hDlg,@t.CtlID TO text$
DrawText @t.hDC,BYCOPY text$,-1,BYVAL VARPTR(@t.RcItem),_
%DT_SINGLELINE OR %DT_CENTER OR %DT_VCENTER
FUNCTION=%False
CASE %WM_COMMAND
SELECT CASE LOWRD(CBWPARAM)
CASE 111
SELECT CASE HIWRD(CBWPARAM)
CASE %BN_CLICKED
DECR DlgCount
FOR i&=700 TO 711:CONTROL KILL hDlg,i&:NEXT i&
CONTROL KILL hDlg,804:CONTROL KILL hDlg,805
CONTROL KILL hDlg,111:CONTROL KILL hDlg,207
FOR i&=Bi(DlgCount)+1 TO Bi(DlgCount+1)
CONTROL KILL hDlg,ButtonTable(i&).event
IF ButtonTable(i&).n>0 THEN CONTROL KILL hDlg,ButtonTable(i&).event+1
NEXT i&
FirstButtonID=0
FOR i&=Bi(DlgCount-1)+1 TO Bi(DlgCount):MakeButton i&:NEXT i&
CONTROL SET FOCUS hDlg,FirstButtonID
END SELECT
CASE 101
SELECT CASE HIWRD(CBWPARAM)
CASE %BN_CLICKED
CALL Lesson_Dialog
END SELECT
END SELECT
END SELECT
END FUNCTION
FUNCTION DeclareButton(BYVAL event AS LONG,_
BYVAL message AS STRING,DDList() AS STRING) AS LONG
#REGISTER NONE
LOCAL This AS ButtonList
INCR Bi(DlgCount)
This.LeType=1:This.L=L:This.event=event:This.message=message
IF LBOUND(DDList)=0 THEN This.n=0 ELSE This.n=UBOUND(DDList)-LBOUND(DDList)+1
w2&=0
FOR i&=1 TO This.n
This.DD(i&)=DDList(i&+LBOUND(DDList)-1)
w2&=MAX(6,w2&,LEN(This.DD(i&))+1)
NEXT i&
This.Columns=Columns
This.w2=4*w2&:This.h2=11*10
This.w1=4.5*LEN(This.message):This.h1=14
This.Ti=T:This.defaultselect=0
ButtonTable(Bi(DlgCount))=This
INCR L
END FUNCTION
FUNCTION ShowDialog() AS LONG
#REGISTER NONE
FirstButtonID=0
FOR i&=Bi(DlgCount-1)+1 TO Bi(DlgCount):MakeButton i&:NEXT i&
CONTROL SET FOCUS hDlg,FirstButtonID
END FUNCTION
FUNCTION PBMAIN() AS LONG
#REGISTER NONE
DIM Bi(0:10) AS LONG
DIM ButtonTable(0:1000) AS ButtonList
DIM TabCount(1:10) AS LONG
LOCAL Lb AS LOGBRUSH
Lb.lbStyle=%BS_SOLID:Lb.lbColor=&H80C0FF:boxColor=CreateBrushIndirect(Lb)
' Main Dialog
DIM NullList(0:0):NullList(0)=""
DIM Speeds(5:49) AS STRING
LOCAL i AS LONG:FOR i=5 TO 49:speeds(i)=" "+RIGHT$(STR$(100+i),2)+" ":NEXT
LoopCount=1
KILL"Dump.txt"
DlgCount=1
DIALOG NEW 0,"Test Program for GPF Error",,,320,240,_
%WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MAXIMIZEBOX OR _
%WS_MINIMIZEBOX,0 TO hDlg
IF hDlg=0 THEN EXIT FUNCTION ' Error occurred
FOR i&=Bi(DlgCount-1)+1 TO Bi(DlgCount)
CONTROL KILL hDlg,ButtonTable(i&).event
IF ButtonTable(i&).n>0 THEN CONTROL KILL hDlg,ButtonTable(i&).event+1
NEXT i&
W=0
INCR DlgCount
FirstButtonID=0
Bi(DlgCount)=Bi(DlgCount-1)
L=3:T=1:Columns=2
DeclareButton 101,"&L Button", NullList()
DeclareButton 102,"Button 102", NullList()
DeclareButton 103,"Button 103", NullList()
DeclareButton 104,"Button 104", NullList()
DeclareButton 105,"Button 105", NullList()
L=3:T=2
DeclareButton 106,"Button 106", NullList()
DeclareButton 107,"Button 107", NullList()
DeclareButton 108,"Button 108", NullList()
DeclareButton 109,"Button 109", NullList()
DeclareButton 110,"Button 110", NullList()
INCR L
T=1:Columns=1
DeclareButton %IDOK,"E&xit", NullList()
W=45
ShowDialog
DIALOG SHOW MODAL hDlg, CALL MA_Main
END FUNCTION
FUNCTION Lesson_Dialog AS LONG
#REGISTER NONE
FOR i&=101 TO 110:CONTROL KILL hDlg,i&:NEXT i&
CONTROL KILL hDlg,%IDOK
W=0
INCR DlgCount
FirstButtonID=0
Bi(DlgCount)=Bi(DlgCount-1)
FOR i&=0 TO 6
CONTROL ADD BUTTON,hDlg,705+i&,"",5+45*i&,39,40,14,_
%BS_LEFT OR %WS_TABSTOP
NEXT i&
FOR i&=0 TO 4
CONTROL ADD BUTTON,hDlg,700+i&,"",53+53*i&,175,0,14,_
%BS_LEFT OR %WS_TABSTOP
NEXT i&
CONTROL ADD BUTTON,hDlg,111,"&Button 111",125,192,68,14,_
%BS_LEFT OR %WS_TABSTOP OR %BS_OWNERDRAW
CONTROL ADD BUTTON,hDlg,207,"Button 207",222,192,68,14,_
%BS_LEFT OR %WS_TABSTOP OR %BS_OWNERDRAW
L=11:T=1:Columns=3
DeclareButton 804,"Button 804", Speeds()
W=69
ShowDialog
CONTROL SET FOCUS hDlg,804
END FUNCTION
---------------------------------------------------------------
but I can't seem to isolate it. An "isolation version" is now
231 lines long and I'm trying to reduce that.
The error is curious because It never occurs if the mouse is
used to click a buttons; only if the ALT+Letter is used
instead of the mouse. (BTW I'm using PB DLL 6.0 under NT 4.0
with SP6).
To cause the error in the program below, sequence between the
dialogs using ALT+L, ALT+B, ALT+L, ALT+B, etc.
I've homed in on line 70 as the culprit where a local array is
dimensioned based on a value n in a user declared TYPE, in this
case 'This.n'. Values from an ASCIIZ array in the structure are
transferred from the structure to the local array, which is
then to be used a parameter to a CONTROL ADD COMBOBOX. Reading
from the ASCIIZ array is the problem, not writing into the local
DD() array. (and reading from This.DD(i), where i=1 to 3 is no
problem; only if the index is 4 or greater does the error occur).
Does anyone have any suggestions on tools to use to find this
type of problem. THE ABOVE ANALYSIS MAY BE FAR OFF THE MARK.
A previous random store may have caused this symptom. But
without DDT source code it is hard to track back - I'll
keep trying.
I'd appreciate any advice. More experienced Windows programs
may see my error quickly, without even having to run the program.
--------------------------------------------------------------
The failing code follows
--------------------------------------------------------------
#COMPILE EXE
#REGISTER NONE
#DEBUG ERROR ON
$INCLUDE "WIN32API.INC"
TYPE ButtonList
LeType AS LONG
event AS LONG
x1 AS LONG
y1 AS LONG
w1 AS LONG
h1 AS LONG
x2 AS LONG
y2 AS LONG
w2 AS LONG
h2 AS LONG
L AS LONG
columns AS LONG
Ti AS LONG
options AS LONG
ex_options AS LONG
n AS LONG
defaultselect AS LONG
message AS ASCIIZ *100
DD(100) AS ASCIIZ *100
END TYPE
GLOBAL LoopCount AS LONG
GLOBAL hDlg AS LONG ' Global Dialog handle
GLOBAL DlgCount AS LONG ' Nested Menu Count
GLOBAL FirstButtonID AS LONG ' Device ID of first button on screen
GLOBAL W AS LONG ' Width of Button to be gnerated
GLOBAL T AS LONG ' Horizontal Tab character count on page
GLOBAL L AS LONG ' Line count within page
GLOBAL Columns AS LONG ' Number of columns in menu
GLOBAL TabCount() AS LONG ' Tabs Array
GLOBAL NullList() AS STRING
GLOBAL Speeds() AS STRING
GLOBAL boxColor AS LONG
GLOBAL ButtonTable() AS ButtonList
GLOBAL Bi() AS LONG
FUNCTION MakeButton(index AS LONG) AS LONG
#REGISTER NONE
LOCAL This AS ButtonList
This=ButtonTable(index)
SELECT CASE This.LeType
CASE 1
TabCount(1)=MAX(0,(320-This.Columns*W)/(This.Columns+1))
FOR k&=2 TO This.Columns
TabCount(k&)=TabCount(k&-1)+TabCount(1)+W
NEXT k&
This.x1=TabCount(This.Ti)
This.x2=W+This.x1-This.w2
This.y1=17*This.L+5
This.y2=This.y1+1
This.w1=W-This.w2-1
IF FirstButtonID=0 THEN FirstButtonID=This.event
CONTROL ADD BUTTON,hDlg,This.event,This.message,This.x1,_
This.y1,This.w1,This.h1,%BS_LEFT OR %WS_TABSTOP OR %BS_OWNERDRAW
IF This.n THEN
This.h2=11*10
'***************************************************************************
'OPEN"Dump.txt"FOR APPEND AS #9
DIM DD(1:This.n) AS STRING
'PRINT #9,"** Allocate DD(1:This.n): "RIGHT$(" "+STR$(LoopCount),4)
'FOR i&=1 TO This.n
'************** Accessing This.DD(i&)in the PRINT statement causes GPF too
'PRINT #9,RIGHT$(" "+STR$(i&),4)"|"HEX$(VARPTR(DD(i&)))"="This.DD(i&)"|":
'NEXT i&
'CLOSE #9
FOR i&=1 to 4 ' No error if loop goes to 3
DD(i&)=This.DD(i&) '<><><> Accessing This.DD(i&) appears to cause a GPF
NEXT i&
'PRINT #9,"//// Exit Loop: "RIGHT$(" "+STR$(LoopCount),4)
INCR LoopCount
'****************************************************************************
' The array DD() is supposed to be used on the following line, but
' Speeds() has been substituted to make fault isolation easier
CONTROL ADD COMBOBOX,hDlg,This.event+1,Speeds(),This.x2,_
This.y2,This.w2,This.h2,%CBS_DROPDOWNLIST OR %WS_TABSTOP
COMBOBOX SELECT hDlg,This.event+1,This.defaultselect
END IF
END SELECT
END FUNCTION
CALLBACK FUNCTION MA_Main()
#REGISTER NONE
SELECT CASE CBMSG
CASE %WM_DRAWITEM
DIM t AS DRAWITEMSTRUCT PTR
t=CBLPARAM
'Color area and frame it with black
FillRect @t.hDc,@t.rcItem,boxColor
FrameRect @t.hDc,@t.rcItem,GetStockObject(%BLACK_BRUSH)
SetBkMode @t.hDC,%TRANSPARENT
CONTROL GET TEXT hDlg,@t.CtlID TO text$
DrawText @t.hDC,BYCOPY text$,-1,BYVAL VARPTR(@t.RcItem),_
%DT_SINGLELINE OR %DT_CENTER OR %DT_VCENTER
FUNCTION=%False
CASE %WM_COMMAND
SELECT CASE LOWRD(CBWPARAM)
CASE 111
SELECT CASE HIWRD(CBWPARAM)
CASE %BN_CLICKED
DECR DlgCount
FOR i&=700 TO 711:CONTROL KILL hDlg,i&:NEXT i&
CONTROL KILL hDlg,804:CONTROL KILL hDlg,805
CONTROL KILL hDlg,111:CONTROL KILL hDlg,207
FOR i&=Bi(DlgCount)+1 TO Bi(DlgCount+1)
CONTROL KILL hDlg,ButtonTable(i&).event
IF ButtonTable(i&).n>0 THEN CONTROL KILL hDlg,ButtonTable(i&).event+1
NEXT i&
FirstButtonID=0
FOR i&=Bi(DlgCount-1)+1 TO Bi(DlgCount):MakeButton i&:NEXT i&
CONTROL SET FOCUS hDlg,FirstButtonID
END SELECT
CASE 101
SELECT CASE HIWRD(CBWPARAM)
CASE %BN_CLICKED
CALL Lesson_Dialog
END SELECT
END SELECT
END SELECT
END FUNCTION
FUNCTION DeclareButton(BYVAL event AS LONG,_
BYVAL message AS STRING,DDList() AS STRING) AS LONG
#REGISTER NONE
LOCAL This AS ButtonList
INCR Bi(DlgCount)
This.LeType=1:This.L=L:This.event=event:This.message=message
IF LBOUND(DDList)=0 THEN This.n=0 ELSE This.n=UBOUND(DDList)-LBOUND(DDList)+1
w2&=0
FOR i&=1 TO This.n
This.DD(i&)=DDList(i&+LBOUND(DDList)-1)
w2&=MAX(6,w2&,LEN(This.DD(i&))+1)
NEXT i&
This.Columns=Columns
This.w2=4*w2&:This.h2=11*10
This.w1=4.5*LEN(This.message):This.h1=14
This.Ti=T:This.defaultselect=0
ButtonTable(Bi(DlgCount))=This
INCR L
END FUNCTION
FUNCTION ShowDialog() AS LONG
#REGISTER NONE
FirstButtonID=0
FOR i&=Bi(DlgCount-1)+1 TO Bi(DlgCount):MakeButton i&:NEXT i&
CONTROL SET FOCUS hDlg,FirstButtonID
END FUNCTION
FUNCTION PBMAIN() AS LONG
#REGISTER NONE
DIM Bi(0:10) AS LONG
DIM ButtonTable(0:1000) AS ButtonList
DIM TabCount(1:10) AS LONG
LOCAL Lb AS LOGBRUSH
Lb.lbStyle=%BS_SOLID:Lb.lbColor=&H80C0FF:boxColor=CreateBrushIndirect(Lb)
' Main Dialog
DIM NullList(0:0):NullList(0)=""
DIM Speeds(5:49) AS STRING
LOCAL i AS LONG:FOR i=5 TO 49:speeds(i)=" "+RIGHT$(STR$(100+i),2)+" ":NEXT
LoopCount=1
KILL"Dump.txt"
DlgCount=1
DIALOG NEW 0,"Test Program for GPF Error",,,320,240,_
%WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MAXIMIZEBOX OR _
%WS_MINIMIZEBOX,0 TO hDlg
IF hDlg=0 THEN EXIT FUNCTION ' Error occurred
FOR i&=Bi(DlgCount-1)+1 TO Bi(DlgCount)
CONTROL KILL hDlg,ButtonTable(i&).event
IF ButtonTable(i&).n>0 THEN CONTROL KILL hDlg,ButtonTable(i&).event+1
NEXT i&
W=0
INCR DlgCount
FirstButtonID=0
Bi(DlgCount)=Bi(DlgCount-1)
L=3:T=1:Columns=2
DeclareButton 101,"&L Button", NullList()
DeclareButton 102,"Button 102", NullList()
DeclareButton 103,"Button 103", NullList()
DeclareButton 104,"Button 104", NullList()
DeclareButton 105,"Button 105", NullList()
L=3:T=2
DeclareButton 106,"Button 106", NullList()
DeclareButton 107,"Button 107", NullList()
DeclareButton 108,"Button 108", NullList()
DeclareButton 109,"Button 109", NullList()
DeclareButton 110,"Button 110", NullList()
INCR L
T=1:Columns=1
DeclareButton %IDOK,"E&xit", NullList()
W=45
ShowDialog
DIALOG SHOW MODAL hDlg, CALL MA_Main
END FUNCTION
FUNCTION Lesson_Dialog AS LONG
#REGISTER NONE
FOR i&=101 TO 110:CONTROL KILL hDlg,i&:NEXT i&
CONTROL KILL hDlg,%IDOK
W=0
INCR DlgCount
FirstButtonID=0
Bi(DlgCount)=Bi(DlgCount-1)
FOR i&=0 TO 6
CONTROL ADD BUTTON,hDlg,705+i&,"",5+45*i&,39,40,14,_
%BS_LEFT OR %WS_TABSTOP
NEXT i&
FOR i&=0 TO 4
CONTROL ADD BUTTON,hDlg,700+i&,"",53+53*i&,175,0,14,_
%BS_LEFT OR %WS_TABSTOP
NEXT i&
CONTROL ADD BUTTON,hDlg,111,"&Button 111",125,192,68,14,_
%BS_LEFT OR %WS_TABSTOP OR %BS_OWNERDRAW
CONTROL ADD BUTTON,hDlg,207,"Button 207",222,192,68,14,_
%BS_LEFT OR %WS_TABSTOP OR %BS_OWNERDRAW
L=11:T=1:Columns=3
DeclareButton 804,"Button 804", Speeds()
W=69
ShowDialog
CONTROL SET FOCUS hDlg,804
END FUNCTION
---------------------------------------------------------------
Comment