First: PowerBASIC PB/DLL

PowerBASIC programs consist of a main program, a window procedure, and possibly your own additional functions. The main program, which must be called WinMain(), sets up the window class, creates and initially displays the window, and manages the message loop. The window procedure, which will be called WindowProc() in all our examples, processes the messages it receives from Windows.

'*****************************************************************************
'                                                                            *
'  First.bas                                                                 *
'                                                                            *
'  This is the first Fastgraph for Windows example program. It demonstrates  *
'  tasks common to most Fastgraph for Windows programs and serves as a       *
'  template for building the other examples.                                 *
'                                                                            *
'*****************************************************************************
#COMPILE EXE "First.exe"
#INCLUDE "FGWin.inc"
'------------------------------------------------------------------------------
FUNCTION WINMAIN (BYVAL hInstance     AS LONG, _
                  BYVAL hPrevInstance AS LONG, _
                  lpCmdLine           AS ASCIIZ PTR, _
                  BYVAL iCmdShow      AS LONG) AS LONG
  LOCAL Msg         AS tagMsg
  LOCAL wndclass    AS WndClassEx
  LOCAL szClassName AS ASCIIZ * 80
  LOCAL hWnd        AS LONG
  szClassName            = "FGfirst"
  wndclass.cbSize        = SIZEOF(WndClass)
  wndclass.style         = %CS_HREDRAW OR %CS_VREDRAW OR %CS_OWNDC
  wndclass.lpfnWndProc   = CODEPTR(WindowProc)
  wndclass.cbClsExtra    = 0
  wndclass.cbWndExtra    = 0
  wndclass.hInstance     = hInstance
  wndclass.hIcon         = LoadIcon(hInstance, BYVAL %IDI_APPLICATION)
  wndclass.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)
  wndclass.hbrBackground = %NULL
  wndclass.lpszMenuName  = %NULL
  wndclass.lpszClassName = VARPTR(szClassName)
  wndclass.hIconSm       = LoadIcon(hInstance, BYVAL %IDI_APPLICATION)
  RegisterClassEx wndclass
  hWnd = CreateWindow( _
    szClassName, _               ' window class name
    "First Fastgraph for Windows Program", _ ' window caption
    %WS_OVERLAPPEDWINDOW, _      ' window style
    %CW_USEDEFAULT, _            ' initial x position
    %CW_USEDEFAULT, _            ' initial y position
    %CW_USEDEFAULT, _            ' initial x size
    %CW_USEDEFAULT, _            ' initial y size
    %NULL, _                     ' parent window handle
    %NULL, _                     ' window menu handle
    hInstance, _                 ' program instance handle
    BYVAL %NULL)                 ' creation parameters
  ShowWindow hWnd, iCmdShow
  UpdateWindow hWnd
  WHILE GetMessage(Msg, %NULL, 0, 0)
    TranslateMessage Msg
    DispatchMessage Msg
  WEND
  FUNCTION = msg.wParam
END FUNCTION
'------------------------------------------------------------------------------
GLOBAL hDC AS LONG
GLOBAL hPal AS LONG
GLOBAL hVB AS LONG
GLOBAL cxClient AS LONG, cyClient AS LONG
FUNCTION WindowProc (BYVAL hWnd AS LONG, BYVAL iMsg AS LONG, _
                     BYVAL wParam AS LONG, BYVAL lParam AS LONG) EXPORT AS LONG
  LOCAL ps AS PAINTSTRUCT
  SELECT CASE iMsg
    CASE %WM_CREATE
      hDC = GetDC(hWnd)
      fg_setdc hDC
      hPal = fg_defpal()
      fg_realize hPal
      fg_vbinit
      hVB = fg_vballoc(640, 480)
      fg_vbopen hVB
      fg_vbcolors
      fg_setcolor 19
      fg_fillpage
      FUNCTION = 0
      EXIT FUNCTION
    CASE %WM_PAINT
      BeginPaint hWnd, ps
      fg_vbscale 0, fg_getmaxx(), 0, fg_getmaxy(), 0, cxClient-1, 0, cyClient-1
      EndPaint hWnd, ps
      FUNCTION = 0
      EXIT FUNCTION
    CASE %WM_SETFOCUS
      fg_realize hPal
      InvalidateRect hWnd, BYVAL %NULL, %TRUE
      FUNCTION = 0
      EXIT FUNCTION
    CASE %WM_SIZE
      cxClient = LOWRD(lParam)
      cyClient = HIWRD(lParam)
      FUNCTION = 0
      EXIT FUNCTION
    CASE %WM_DESTROY
      fg_vbclose
      fg_vbfree hVB
      fg_vbfin
      DeleteObject hPal
      ReleaseDC hWnd, hDC
      PostQuitMessage 0
      FUNCTION = 0
      EXIT FUNCTION
  END SELECT
  FUNCTION = DefWindowProc(hWnd, iMsg, wParam, lParam)
END FUNCTION

First, notice the directive at the beginning of the program:

#INCLUDE "FGWin.inc"

The FGWin.inc include file contains Fastgraph's function prototypes and symbolic constant definitions. It also force-includes the WIN32API.INC include file if necessary. This statement will appear in the PowerBASIC versions of all Fastgraph example programs.

Now let's look at WinMain(). WinMain() first sets up a window class that defines the window characteristics and associates a window procedure with the class. It then calls the CreateWindow() Windows API function to create a window based on that window class (this also generates the WM_CREATE message). CreateWindow() returns a window handle, which we store in the variable hWnd, for use elsewhere in the program. Next, the Windows API function ShowWindow() initially displays the window, and another Windows API function, UpdateWindow(), then generates the first WM_PAINT message to display the window contents. The remainder of WinMain() is a WHILE loop implementing the message loop. The message loop retrieves messages Windows sends to the program and sends these to the program's window procedure for processing. The message loop executes until the user exits the program. Note that we've exclusively used Windows API functions to handle the details of WinMain().

The window procedure WindowProc() is where most of the action takes place and provides our first look at some Fastgraph functions. Note that our program does not explicitly call WindowProc(). Instead, it is called by Windows in response to events such as creating or resizing the window. The message loop passes these events to WindowProc() as messages, which WindowProc() processes through its own distinct message handlers. WindowProc() implements the message handlers as a SELECT CASE construct. Our window procedure includes WM_CREATE, WM_PAINT, WM_SETFOCUS, WM_SIZE, and WM_DESTROY message handlers, which we'll now discuss in detail.

Windows generates a WM_CREATE message when it first creates the program's window. Only one WM_CREATE message typically occurs per program instance, so it is a good place for any application-specific initialization code. Our WM_CREATE message handler first calls the Windows API function GetDC() to obtain a device context to the window's client area and then calls fg_setdc() to make the device context available to other Fastgraph functions:

hDC = GetDC(hWnd)
fg_setdc hDC

Next, it creates and realizes the default logical palette:

hPal = fg_defpal()
fg_realize hPal

The WM_CREATE message handler then initializes Fastgraph's virtual buffer environment, creates a 640x480 virtual buffer and makes it the active virtual buffer, and assigns the logical palette colors to the virtual buffer:

fg_vbinit
hVB = fg_vballoc(640, 480)
fg_vbopen hVB
fg_vbcolors

Finally, we fill the virtual buffer with blue pixels (color 19 is blue when using Fastgraph's default 256-color virtual buffers with the default logical palette):

fg_setcolor 19
fg_fillpage

Windows generates a WM_PAINT message when the window's client area must be repainted. Our WM_PAINT handler begins with a call to the Windows API function BeginPaint(), then calls fg_vbscale() to display the contents of the 640x480 virtual buffer scaled to the size of the client area, and ends with a call to the Windows API function EndPaint(). This sequence is typical of WM_PAINT message handlers in Fastgraph programs.

Windows generates a WM_SETFOCUS message when the window gains the input focus. This most often happens when the window becomes the active or top-level window. Our WM_SETFOCUS handler first calls fg_realize() to activate the program's logical palette (in case another program has changed the logical palette colors), then calls the Windows API function InvalidateRect() to force a WM_PAINT message to redraw the client area. This sequence is typical of WM_SETFOCUS message handlers in Fastgraph programs.

Windows generates a WM_SIZE message whenever the size of the window changes, and also upon creation of a window. Our WM_SIZE handler simply saves the new width and height of the client area (in pixels) in the variables cxClient and cyClient. These quantities are passed to fg_vbscale() in the WM_PAINT message handler.

Windows generates a WM_DESTROY message after removing a window to signal a program exit. Our WM_DESTROY handler first closes the virtual buffer, releases its memory, and terminates virtual buffer processing:

fg_vbclose
fg_vbfree hVB
fg_vbfin

It then calls three Windows API functions to delete the logical palette created with fg_defpal(), release the device context created with GetDC(), and exit:

DeleteObject hPal
ReleaseDC hWnd, hDC
PostQuitMessage 0

Finally, our window procedure ends with a call to the Windows API function DefWindowProc(). This provides default message processing for the hundreds of other Windows message types not explicitly handled by the window procedure.

<< Prev

Next >>

Contents
Fastgraph Home Page

 

copyright 2001 Ted Gruber Software, Inc.