Edwin,
Form1.bas has no globals or statics, Form2.bas has some statics that can't easily be removed, and Form3.bas has no globals or statics (I did remove a couple you might have seen though).
In terms of the ones in Form2, don't forget this is a post for beginners just wanting to learn Api coding with PowerBASIC. And Form2 is only the second lesson in a series where Form1.bas didn't even draw a 'Hello, World!" because I wanted to defer discussion of DrawText(), TextOut(), etc, so as not to load on too much too soon.
I of course could have gotten rid of the statics in Form2 in a number of ways (Get/SetWindowLong() with pointers, Property Lists, etc.) but for the same reasons as discussed above, I'd didn't think that would serve beginners. When you hit biginners with too much too soon, before long they won't be PowerBASIC beginners anymore, but rather VB.NET point and click beginners.
Be that as it may, here is Form2.bas revisited with no globals and no statics. I'll let the explaning it to beginners to someone else...
'Program Name altForm2.bas
#Compile Exe
#Include "Win32api.inc" 'Equates, declares, types translated from Windows.h
Type WndEventArgs
hWnd As Dword
wParam As Long
lParam As Long
End Type
Type tagInstanceData
wWidth As Word
wHeight As Word
wX As Word
wY As Word
xPos As Word
yPos As Word
wCharHt As Word
szText As Asciiz*128
End Type
Function fnWndProc_OnCreate(wea As WndEventArgs) As Long
Local ptrInstanceData As tagInstanceData Ptr
Local InstanceData As tagInstanceData
Local tm As TEXTMETRIC
Local hHeap As Dword
Local hDC As DWord
hHeap=GetProcessHeap()
ptrInstanceData=HeapAlloc(hHeap,%HEAP_ZERO_MEMORY,SizeOf(InstanceData))
If ptrInstanceData Then
hDC=GetDC(wea.hWnd)
Call GetTextMetrics(hDC,tm)
Call ReleaseDC(wea.hWnd,hDC)
@ptrInstanceData.wCharHt=tm.tmHeight
Call SetWindowLong(wea.hWnd,0,ptrInstanceData)
MsgBox("@ptrInstanceData.wCharHt=" & Trim$(Str$(@ptrInstanceData.wCharHt)))
Else
fnWndProc_OnCreate=-1
End If
fnWndProc_OnCreate=0
End Function
Function fnWndProc_OnMouseMove(wea As WndEventArgs) As Long
Local ptrInstanceData As tagInstanceData Ptr
ptrInstanceData=GetWindowLong(wea.hWnd,0)
@ptrInstanceData.wX=LoWrd(wea.lParam) : @ptrInstanceData.wY=HiWrd(wea.lParam)
Call InvalidateRect(wea.hWnd,ByVal %NULL,%TRUE)
fnWndProc_OnMouseMove=0
End Function
Function fnWndProc_OnSize(wea As WndEventArgs) As Long
Local ptrInstanceData As tagInstanceData Ptr
ptrInstanceData=GetWindowLong(wea.hWnd,0)
@ptrInstanceData.wWidth=LoWrd(wea.lParam) : @ptrInstanceData.wHeight=HiWrd(wea.lParam)
Call InvalidateRect(wea.hWnd,ByVal %NULL,%TRUE)
fnWndProc_OnSize=0
End Function
Function fnWndProc_OnChar(wea As WndEventArgs) As Long
Local ptrInstanceData As tagInstanceData Ptr
ptrInstanceData=GetWindowLong(wea.hWnd,0)
@ptrInstanceData.szText=@ptrInstanceData.szText+Chr$(wea.wParam)
Call InvalidateRect(wea.hWnd,ByVal %NULL,%TRUE)
fnWndProc_OnChar=0
End Function
Function fnWndProc_OnLButtonDown(wea As WndEventArgs) As Long
Local ptrInstanceData As tagInstanceData Ptr
ptrInstanceData=GetWindowLong(wea.hWnd,0)
If wea.wParam=%MK_LBUTTON Then
@ptrInstanceData.xPos=LoWrd(wea.lParam) : @ptrInstanceData.yPos=HiWrd(wea.lParam)
Call InvalidateRect(wea.hWnd,ByVal 0,%TRUE)
End If
fnWndProc_OnLButtonDown=0
End Function
Function fnWndProc_OnPaint(wea As WndEventArgs) As Long
Local ptrInstanceData As tagInstanceData Ptr
Local szLine As Asciiz*64
Local ps As PAINTSTRUCT
Local hDC As Long
hDC=BeginPaint(wea.hWnd,ps)
ptrInstanceData=GetWindowLong(wea.hWnd,0)
szLine="MouseX="+Trim$(Str$(@ptrInstanceData.wX)) & " MouseY="+Trim$(Str$(@ptrInstanceData.wY))
TextOut(hDC,0,0,szLine,Len(szLine))
szLine="@ptrInstanceData.wWidth="+Trim$(Str$(@ptrInstanceData.wWidth)) & " @ptrInstanceData.wHeight=" + Trim$(Str$(@ptrInstanceData.wHeight))
TextOut(hDC,0,16,szLine,Len(szLine))
TextOut(hDC,0,32,@ptrInstanceData.szText,Len(@ptrInstanceData.szText))
If @ptrInstanceData.xPos<>0 And @ptrInstanceData.yPos<>0 Then
szLine="WM_LBUTTONDOWN At (" & Trim$(Str$(@ptrInstanceData.xPos)) & "," & Trim$(Str$(@ptrInstanceData.yPos)) & ")"
TextOut(hDC,@ptrInstanceData.xPos,@ptrInstanceData.yPos,szLine,Len(szLine))
@ptrInstanceData.xPos=0 : @ptrInstanceData.yPos=0
End If
Call EndPaint(wea.hWnd,ps)
fnWndProc_OnPaint=0
End Function
Function fnWndProc_OnDestroy(wea As WndEventArgs) As Long
Local ptrInstanceData As tagInstanceData Ptr
Local hHeap As Dword,blnFree As Dword
hHeap=GetProcessHeap()
ptrInstanceData=GetWindowLong(wea.hWnd,0)
blnFree=HeapFree(hHeap,0,ptrInstanceData)
MsgBox("blnFree=" & Trim$(Str$(IsTrue(blnFree))))
MsgBox("Always Make Sure Memory Deallocates! Memory Leaks Are Bad!")
Call PostQuitMessage(0)
fnWndProc_OnDestroy=0
End Function
Function WndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
Local wea As WndEventArgs
Select Case As Long wMsg
Case %WM_CREATE
wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
WndProc=fnWndProc_OnCreate(wea)
Exit Function
Case %WM_MOUSEMOVE
wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
WndProc=fnWndProc_OnMouseMove(wea)
Exit Function
Case %WM_SIZE
wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
WndProc=fnWndProc_OnSize(wea)
Exit Function
Case %WM_CHAR
wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
WndProc=fnWndProc_OnChar(wea)
Exit Function
Case %WM_LBUTTONDOWN
wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
WndProc=fnWndProc_OnLButtonDown(wea)
Exit Function
Case %WM_PAINT
wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
WndProc=fnWndProc_OnPaint(wea)
Exit Function
Case %WM_DESTROY
wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
WndProc=fnWndProc_OnDestroy(wea)
Exit Function
End Select
WndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
End Function
Function WinMain(ByVal hIns As Long,ByVal hPrevIns As Long,ByVal lpCmdLine As Asciiz Ptr,ByVal iShow As Long) As Long
Local szClassName As Asciiz*16
Local wc As WndClassEx
Local hMainWnd As Dword
Local Msg As tagMsg
szClassName="altForm1"
wc.cbSize=SizeOf(wc) : wc.style=0
wc.lpfnWndProc=CodePtr(WndProc) : wc.cbClsExtra=0
wc.cbWndExtra=4 : wc.hInstance=hIns
wc.hIcon=LoadIcon(%NULL,ByVal %IDI_APPLICATION) : wc.hCursor=LoadCursor(%NULL,ByVal %IDC_ARROW)
wc.hbrBackground=GetStockObject(%WHITE_BRUSH) : wc.lpszMenuName=%NULL
wc.lpszClassName=VarPtr(szClassName) : wc.hIconSm=LoadIcon(%NULL,ByVal %IDI_APPLICATION)
Call RegisterClassEx(wc)
hMainWnd=CreateWindowEx(0,szClassName,"altForm1",%WS_OVERLAPPEDWINDOW,200,100,425,360,%HWND_DESKTOP,0,hIns,ByVal 0)
Call ShowWindow(hMainWnd,iShow)
While GetMessage(Msg,%NULL,0,0)
Call TranslateMessage(Msg)
Call DispatchMessage(Msg)
Wend
WinMain=msg.wParam
End Function
Fred