• Welcome to Theos PowerBasic Museum 2017.

Fred's Tutorial #2A: Windows API Tutorial: Form2 With No Globals/Statics

Started by Frederick J. Harris, August 20, 2007, 10:56:08 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frederick J. Harris

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