09-06-2025, 12:44 PM
(This post was last modified: 09-06-2025, 01:04 PM by Jules Marchildon.)
continuing my journey;
I wanted to see if creating the bitmaps dynamically would work out. My first thought was to make a large bitmap and resize later, turns out I'm better off with a smaller bitmap and enlarge if needed. The original pac-man had 18x18 tile so I'll stick to that for now. Testing code follows, resized larger to see placement details...
In this trial, using tile size 18x18 and cutting a tile and display beside it. Optionally you can turn off the grid. Tested each bitmap individually. Click on tile, see result to right.
I wanted to see if creating the bitmaps dynamically would work out. My first thought was to make a large bitmap and resize later, turns out I'm better off with a smaller bitmap and enlarge if needed. The original pac-man had 18x18 tile so I'll stick to that for now. Testing code follows, resized larger to see placement details...
Code:
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC" '-PB include
GLOBAL gtile_size AS LONG
GLOBAL goffsetX, goffsetY AS LONG
GLOBAL gClientW, gClientH AS LONG
GLOBAL ghBmpLayout1 AS DWORD '-Exterior wall, double line.
GLOBAL ghBmpLayout2 AS DWORD '-Interior wall, single line.
GLOBAL ghBmpLayout3 AS DWORD '-Exterior wall, single line, connection point to Interior wall.
GLOBAL ghBMpLayout4 AS DWORD '-Center wall, double line.
'--------------------------------------------------------------------------------------------------
'
'--------------------------------------------------------------------------------------------------
FUNCTION WINMAIN(BYVAL hInstance AS LONG, BYVAL hPrevInstance AS LONG, BYVAL lpCmdLine AS ASCIIZ PTR, BYVAL iCmdShow AS LONG) AS LONG
'-starting tile size, adjust based on best results
gtile_size = 72
'-place all images on same line, start at...
goffsetX = 30
goffsetY = 30
'-window setup
LOCAL wce AS WNDCLASSEX
LOCAL szAppName AS ASCIIZ * 80
szAppName = "PACMANTILES"
wce.cbSize = SIZEOF(wce)
wce.style = %CS_HREDRAW OR %CS_VREDRAW
wce.lpfnWndProc = CODEPTR(WndProc)
wce.hInstance = hInstance
wce.hIcon = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
wce.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW)
wce.hbrBackground = GetStockObject(%WHITE_BRUSH) '-use white to see the result black & blue image map
wce.lpszClassName = VARPTR(szAppName)
wce.hIconSm = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
RegisterClassEx wce
LOCAL clientW, clientH, totalW, totalH AS LONG
clientW = 1100
clientH = 300
totalW = clientW + GetSystemMetrics(%SM_CXFRAME) * 2
totalH = clientH + GetSystemMetrics(%SM_CYCAPTION) + GetSystemMetrics(%SM_CYFRAME) * 2
LOCAL hWnd AS LONG
hWnd = CreateWindowEx(0, szAppName, "Pac-Man Outline Map tiles:", %WS_OVERLAPPEDWINDOW, _
300, 200, totalW, totalH, %NULL, %NULL, hInstance, BYVAL %NULL)
ShowWindow hWnd, iCmdShow
UpdateWindow hWnd
LOCAL uMsg AS tagMSG
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
FUNCTION = uMsg.wParam
END FUNCTION
'--------------------------------------------------------------------------------------------------
'
'--------------------------------------------------------------------------------------------------
FUNCTION WndProc(BYVAL hWnd AS DWORD, BYVAL uMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS DWORD
'----------------'
SELECT CASE uMsg
'----------------'
'~~~~~~~~~~~~~~~'
CASE %WM_CREATE
'~~~~~~~~~~~~~~~'
'-create the four layout bitmaps
ghBmpLayout1 = DrawRoundConcentricRect(hWnd, %TRUE, %TRUE, %TRUE, gtile_size) '-Exterior wall, double line
ghBmpLayout2 = DrawRoundConcentricRect(hWnd, %FALSE, %TRUE, %TRUE, gtile_size)'-Interior wall, single line
ghBmpLayout3 = DrawRoundConcentricRect(hWnd, %TRUE, %FALSE, %TRUE, gtile_size)'-Exterior wall, single line for connection
ghBmpLayout4 = DrawRoundConcentricRect(hWnd, %TRUE, %TRUE, %FALSE, gtile_size)'-Center wall, double line, square corners
FUNCTION = 0 : EXIT FUNCTION
'~~~~~~~~~~~~~~~'
CASE %WM_PAINT
'~~~~~~~~~~~~~~~'
'-for purpose of showing image results
LOCAL ps AS PAINTSTRUCT
LOCAL hDC AS DWORD
LOCAL hMemDC AS DWORD
hDC = BeginPaint(hWnd, ps)
'-draw first bitmap at goffsetX, goffsetY
hMemDC = CreateCompatibleDC(hDC)
SelectObject hMemDC, ghBmpLayout1
BitBlt hDC, goffsetX, goffsetY, 3*gtile_size, 3*gtile_size, hMemDC, 0, 0, %SRCCOPY
DeleteDC hMemDC
'-draw second bitmap with offset
hMemDC = CreateCompatibleDC(hDC)
SelectObject hMemDC, ghBmpLayout2
BitBlt hDC, goffsetX + 3*gtile_size + goffsetX, goffsetY, 3*gtile_size, 3*gtile_size, hMemDC, 0, 0, %SRCCOPY
DeleteDC hMemDC
'-draw third bitmap with offset
hMemDC = CreateCompatibleDC(hDC)
SelectObject hMemDC, ghBmpLayout3
BitBlt hDC, goffsetX + 6*gtile_size + 2*goffsetX, goffsetY, 3*gtile_size, 3*gtile_size, hMemDC, 0, 0, %SRCCOPY
DeleteDC hMemDC
'-draw forth bitmap with offset
hMemDC = CreateCompatibleDC(hDC)
SelectObject hMemDC, ghBmpLayout4
BitBlt hDC, goffsetX + 9*gtile_size + 3*goffsetX, goffsetY, 3*gtile_size, 3*gtile_size, hMemDC, 0, 0, %SRCCOPY
DeleteDC hMemDC
EndPaint hWnd, ps
FUNCTION = 0 : EXIT FUNCTION
'~~~~~~~~~~~~~~~~'
CASE %WM_DESTROY
'~~~~~~~~~~~~~~~~'
IF ghBmpLayout1 THEN DeleteObject ghBmpLayout1
IF ghBmpLayout2 THEN DeleteObject ghBmpLayout2
IF ghBmpLayout3 THEN DeleteObject ghBmpLayout3
IF ghBmpLayout4 THEN DeleteObject ghBmpLayout4
PostQuitMessage 0
EXIT FUNCTION
'----------'
END SELECT
'----------'
FUNCTION = DefWindowProc(hWnd, uMsg, wParam, lParam)
END FUNCTION
'--------------------------------------------------------------------------------------------------
' Create our outline map tiles as bitmaps, setup in a 3x3 tile grid format.
' The map layout code will manage the cut tiles and place them on the maze where needed.
'--------------------------------------------------------------------------------------------------
FUNCTION DrawRoundConcentricRect(BYVAL hWnd AS DWORD, BYVAL ExteriorW AS LONG, BYVAL InteriorW AS LONG, _
BYVAL roundFlag AS LONG, BYVAL tile AS LONG) AS DWORD
LOCAL hDC, hMemDC, hBmp AS DWORD
LOCAL hPen, hOldPen, hOldBrush AS LONG
LOCAL cornerRadius, x1, y1, x2, y2, penWidth AS LONG
'
' [Flags]
'
' ExteriorW InteriorW roundFlag bitmap type
'----------------------------------------------------------------------------------------
' %TRUE %TRUE %TRUE Exterior double line wall with round corners
' %FALSE %TRUE %TRUE Interior single line wall with round corners, centered
' %TRUE %FALSE %TRUE Exterior single line wall for Interior connection with round corners
' %TRUE %TRUE %FALSE Exterior double line wall with square corners, outer on inside edges
'
'-create bitmap to draw on
hDC = GetDC(hWnd)
hMemDC = CreateCompatibleDC(hDC)
hBmp = CreateCompatibleBitmap(hDC, tile*3, tile*3)
SelectObject hMemDC, hBmp
ReleaseDC hWnd, hDC
'-fill background black
PatBlt hMemDC, 0, 0, tile*3, tile*3, %BLACKNESS '<-expects a ROP code, not a color value
'-create a blue solid pen similar to original classic blue
penWidth = 6
hPen = CreatePen(%PS_SOLID, penWidth, RGB(33, 41, 192))
hOldPen = SelectObject(hMemDC, hPen)
hOldBrush = SelectObject(hMemDC, GetStockObject(%NULL_BRUSH))
'-%TRUE, tile/3 for round, %FALSE, 0 for square
cornerRadius = IIF(roundFlag, tile/3, 0)
'-draw exterior rectange wihtdouble lines
IF ExteriorW THEN
IF roundFlag THEN
'-exterior rounded rectangle for round corners, near outer edge
x1 = penWidth - 2
y1 = penWidth - 2
'-align to edge, confirm calc? 95 for tile=32, 191 for tile=64
x2 = tile*3 - 1
y2 = tile*3 - 1
ELSE
'-exterior edge rectangle with square corners, we wrap it around the
' center tile, this is used for the center piece, will can add
' the final doorway details later in the code.
x1 = tile - penWidth
y1 = tile - penWidth
x2 = tile*2 + penWidth
y2 = tile*2 + penWidth
END IF
RoundRect hMemDC, x1, y1, x2, y2, cornerRadius*3, cornerRadius*3
END IF
'-draw interior rectangle with rounded or square corners
IF InteriorW THEN
'-interior rectangle, inflated to intersect tile center
x1 = (tile / 2 + penWidth - 4) '-left
y1 = (tile / 2 + penWidth - 4) '-top
x2 = (tile*3 - tile / 2 - 3)+4 '-right, try tweak +4 iow +1
y2 = (tile*3 - tile / 2 - 3)+4 '-bottom,try tweak +4 iow +1
RoundRect hMemDC, x1, y1, x2, y2, cornerRadius*2, cornerRadius*2
END IF
'-###-
#IF 1 '-set to 0 for final code, or remove code block.
'-draw a visual aid, *skip outer edges
LOCAL lCol, lRow, cx, cy, i AS LONG
LOCAL dotSpacing AS LONG
dotSpacing = 3 '-space dots
FOR lRow = 0 TO 2
FOR lCol = 0 TO 2
cx = lCol * tile
cy = lRow * tile
'-top edge, *skip for first row
IF lRow > 0 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx + i, cy, RGB(255, 255, 255)
NEXT i
END IF
'-bottom edge, *skip for last row
IF lRow < 2 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx + i, cy + tile - 1, RGB(255, 255, 255)
NEXT i
END IF
'-left edge, *skip for first column
IF lCol > 0 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx, cy + i, RGB(255, 255, 255)
NEXT i
END IF
'-right edge, *skip for last column
IF lCol < 2 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx + tile - 1, cy + i, RGB(255, 255, 255)
NEXT i
END IF
NEXT lCol
NEXT lRow
#ENDIF
'-###-
'-clean up
SelectObject hMemDC, hOldBrush
SelectObject hMemDC, hOldPen
DeleteObject hPen
DeleteDC hMemDC
FUNCTION = hBmp '-return our bitmap handle
END FUNCTION
In this trial, using tile size 18x18 and cutting a tile and display beside it. Optionally you can turn off the grid. Tested each bitmap individually. Click on tile, see result to right.
Code:
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC" '-PB include
GLOBAL gtile_size AS LONG
GLOBAL gTargetTileSize AS LONG
GLOBAL goffsetX, goffsetY AS LONG
GLOBAL ghBmpLayout1 AS DWORD '-Exterior wall, double line.
GLOBAL ghBmpLayout2 AS DWORD '-Interior wall, single line.
GLOBAL ghBmpLayout3 AS DWORD '-Exterior wall, single line, connection point to Interior wall.
GLOBAL ghBMpLayout4 AS DWORD '-Center wall, double line.
GLOBAL ghSelected AS DWORD '-Selected tile bitmap.
'--------------------------------------------------------------------------------------------------
'
'--------------------------------------------------------------------------------------------------
FUNCTION WINMAIN(BYVAL hInstance AS LONG, BYVAL hPrevInstance AS LONG, BYVAL lpCmdLine AS ASCIIZ PTR, BYVAL iCmdShow AS LONG) AS LONG
gtile_size = 18 '-square tile size
gTargetTileSize = 18 '-target size for selected tile
'-place all images on same line, start at...
goffsetX = 30
goffsetY = 30
'-window setup
LOCAL wce AS WNDCLASSEX
LOCAL szAppName AS ASCIIZ * 80
szAppName = "PACMANTILES"
wce.cbSize = SIZEOF(wce)
wce.style = %CS_HREDRAW OR %CS_VREDRAW
wce.lpfnWndProc = CODEPTR(WndProc)
wce.hInstance = hInstance
wce.hIcon = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
wce.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW)
wce.hbrBackground = GetStockObject(%BLACK_BRUSH)
wce.lpszClassName = VARPTR(szAppName)
wce.hIconSm = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
RegisterClassEx wce
LOCAL clientW, clientH, totalW, totalH AS LONG
clientW = 920
clientH = 260
totalW = clientW + GetSystemMetrics(%SM_CXFRAME) * 2
totalH = clientH + GetSystemMetrics(%SM_CYCAPTION) + GetSystemMetrics(%SM_CYFRAME) * 2
LOCAL hWnd AS LONG
hWnd = CreateWindowEx(0, szAppName, "Pac-Man Cut Bitmap tiles:", %WS_OVERLAPPEDWINDOW, _
500, 250, totalW, totalH, %NULL, %NULL, hInstance, BYVAL %NULL)
ShowWindow hWnd, iCmdShow
UpdateWindow hWnd
LOCAL uMsg AS tagMSG
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
FUNCTION = uMsg.wParam
END FUNCTION
'--------------------------------------------------------------------------------------------------
'
'--------------------------------------------------------------------------------------------------
FUNCTION WndProc(BYVAL hWnd AS DWORD, BYVAL uMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS DWORD
'----------------'
SELECT CASE uMsg
'----------------'
'~~~~~~~~~~~~~~~'
CASE %WM_CREATE
'~~~~~~~~~~~~~~~'
'-create the four layout bitmaps
ghBmpLayout1 = DrawRoundConcentricRect(hWnd, %TRUE, %TRUE, %TRUE, gtile_size) '-Exterior wall, double line
ghBmpLayout2 = DrawRoundConcentricRect(hWnd, %FALSE,%TRUE, %TRUE, gtile_size) '-Interior wall, single line
ghBmpLayout3 = DrawRoundConcentricRect(hWnd, %TRUE, %FALSE,%TRUE, gtile_size) '-Exterior wall, single line for connection
ghBmpLayout4 = DrawRoundConcentricRect(hWnd, %TRUE, %TRUE, %FALSE,gtile_size) '-Center wall, double line, square corners
FUNCTION = 0 : EXIT FUNCTION
'~~~~~~~~~~~~~~~'
CASE %WM_PAINT
'~~~~~~~~~~~~~~~'
'-for purpose of showing image results
LOCAL ps AS PAINTSTRUCT
LOCAL hDC AS DWORD
LOCAL hMemDC AS DWORD
hDC = BeginPaint(hWnd, ps)
'-draw first bitmap at goffsetX, goffsetY
hMemDC = CreateCompatibleDC(hDC)
SelectObject hMemDC, ghBmpLayout1 '###### ######
'SelectObject hMemDC, ghBmpLayout2 '# try one at a time...
'SelectObject hMemDC, ghBmpLayout3 '#
'SelectObject hMemDC, ghBmpLayout4 '###### ######
BitBlt hDC, goffsetX, goffsetY, 3*gtile_size, 3*gtile_size, hMemDC, 0, 0, %SRCCOPY
DeleteDC hMemDC
'-draw selected tile if exists, resized to gTargetTileSize
IF ghSelected THEN
hMemDC = CreateCompatibleDC(hDC)
SelectObject hMemDC, ghSelected
StretchBlt hDC, goffsetX + 3*gtile_size + 30, goffsetY, gTargetTileSize, gTargetTileSize, _
hMemDC, 0, 0, gtile_size, gtile_size, %SRCCOPY
DeleteDC hMemDC
END IF
EndPaint hWnd, ps
FUNCTION = 0 : EXIT FUNCTION
'~~~~~~~~~~~~~~~~'
CASE %WM_LBUTTONDOWN
'~~~~~~~~~~~~~~~~'
LOCAL x, y AS LONG
x = LO(WORD, lParam)
y = HI(WORD, lParam)
IF x >= goffsetX AND x < goffsetX + 3*gtile_size AND y >= goffsetY AND y < goffsetY + 3*gtile_size THEN
LOCAL COL, ROW AS LONG
COL = (x - goffsetX) \ gtile_size
ROW = (y - goffsetY) \ gtile_size
'-delete previous selected bitmap if exists
IF ghSelected THEN DeleteObject ghSelected
'-create new selected bitmap by copying the tile
LOCAL hDCWin, hMemDC_src, hMemDC_dest AS DWORD
hDCWin = GetDC(hWnd)
hMemDC_src = CreateCompatibleDC(hDCWin)
SelectObject hMemDC_src, ghBmpLayout1 '###### #######
'SelectObject hMemDC_src, ghBmpLayout2 '# Select matching above
'SelectObject hMemDC_src, ghBmpLayout3 '#
'SelectObject hMemDC_src, ghBmpLayout4 '###### #######
ghSelected = CreateCompatibleBitmap(hDCWin, gtile_size, gtile_size)
hMemDC_dest = CreateCompatibleDC(hDCWin)
SelectObject hMemDC_dest, ghSelected
BitBlt hMemDC_dest, 0, 0, gtile_size, gtile_size, hMemDC_src, COL * gtile_size, ROW * gtile_size, %SRCCOPY
DeleteDC hMemDC_src
DeleteDC hMemDC_dest
ReleaseDC hWnd, hDCWin
'-repaint the window
InvalidateRect hWnd, BYVAL %NULL, %TRUE
END IF
FUNCTION = 0 : EXIT FUNCTION
'~~~~~~~~~~~~~~~~'
CASE %WM_DESTROY
'~~~~~~~~~~~~~~~~'
IF ghBmpLayout1 THEN DeleteObject ghBmpLayout1
IF ghBmpLayout2 THEN DeleteObject ghBmpLayout2
IF ghBmpLayout3 THEN DeleteObject ghBmpLayout3
IF ghBmpLayout4 THEN DeleteObject ghBmpLayout4
IF ghSelected THEN DeleteObject ghSelected
PostQuitMessage 0
EXIT FUNCTION
'----------'
END SELECT
'----------'
FUNCTION = DefWindowProc(hWnd, uMsg, wParam, lParam)
END FUNCTION
'--------------------------------------------------------------------------------------------------
' Create our outline map tiles as bitmaps, setup in a 3x3 tile grid format. Tile size 18x18
' The map layout code will manage the cut tiles and place them on the maze where needed.
'--------------------------------------------------------------------------------------------------
FUNCTION DrawRoundConcentricRect(BYVAL hWnd AS DWORD, BYVAL ExteriorW AS LONG, BYVAL InteriorW AS LONG, _
BYVAL roundFlag AS LONG, BYVAL tile AS LONG) AS DWORD
LOCAL hDC, hMemDC, hBmp AS DWORD
LOCAL hPen, hOldPen, hOldBrush AS LONG
LOCAL cornerRadius, x1, y1, x2, y2, penWidth AS LONG
'
' [Flags]
'
' ExteriorW InteriorW roundFlag bitmap type
'----------------------------------------------------------------------------------------------
' %TRUE %TRUE %TRUE Exterior double line wall with round corners
' %FALSE %TRUE %TRUE Interior single line wall with round corners, centered
' %TRUE %FALSE %TRUE Exterior single line wall for Interior connection with round corners
' %TRUE %TRUE %FALSE Exterior double line wall with square corners, outer on inside edges
'
'-create a canvas to draw on
hDC = GetDC(hWnd)
hMemDC = CreateCompatibleDC(hDC)
hBmp = CreateCompatibleBitmap(hDC, tile*3, tile*3)
SelectObject hMemDC, hBmp
ReleaseDC hWnd, hDC
'-fill background black
PatBlt hMemDC, 0, 0, tile*3, tile*3, %BLACKNESS '<-expects a ROP code, not a color value
'-use blue solid pen that is 4 pixel's wide, when using 64 pixel tile
penWidth = 3
hPen = CreatePen(%PS_SOLID, penWidth, RGB(33, 33, 255))
hOldPen = SelectObject(hMemDC, hPen)
hOldBrush = SelectObject(hMemDC, GetStockObject(%NULL_BRUSH))
'-%TRUE, tile/3 for round, %FALSE, 0 for square
cornerRadius = IIF(roundFlag, tile/3, 0)
'-draw exterior rectange wihtdouble lines
IF ExteriorW THEN
IF roundFlag THEN
'-exterior rounded rectangle for round corners, near outer edge
x1 = penWidth - 2
y1 = penWidth - 2
'-align to edge, confirm calc? 95 for tile=32, 191 for tile=64
x2 = tile*3 - 1
y2 = tile*3 - 1
ELSE
'-exterior edge rectangle with square corners, we wrap it around the
' center tile, this is used for the center piece, will can add
' the final doorway details later in the code.
x1 = tile - penWidth
y1 = tile - penWidth
x2 = tile*2 + penWidth
y2 = tile*2 + penWidth
END IF
RoundRect hMemDC, x1, y1, x2, y2, cornerRadius*4, cornerRadius*4
END IF
'-draw interior rectangle with rounded or square corners
IF InteriorW THEN
'-interior rectangle, inflated to intersect tile center
x1 = (tile / 2 + penWidth - 4) '-left
y1 = (tile / 2 + penWidth - 4) '-top
x2 = (tile*3 - tile / 2 - 3)+4 '-right
y2 = (tile*3 - tile / 2 - 3)+4 '-bottom
RoundRect hMemDC, x1, y1, x2, y2, cornerRadius*2, cornerRadius*2
END IF
'-###-
#IF 1 '-set to 0 for final code, or remove code block.
'-draw a visual aid, *skip outer edges
LOCAL lCol, lRow, cx, cy, i AS LONG
LOCAL dotSpacing AS LONG
dotSpacing = 3 '-space dots
FOR lRow = 0 TO 2
FOR lCol = 0 TO 2
cx = lCol * tile
cy = lRow * tile
'-top edge, *skip for first row
IF lRow > 0 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx + i, cy, RGB(255, 255, 255)
NEXT i
END IF
'-bottom edge, *skip for last row
IF lRow < 2 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx + i, cy + tile - 1, RGB(255, 255, 255)
NEXT i
END IF
'-left edge, *skip for first column
IF lCol > 0 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx, cy + i, RGB(255, 255, 255)
NEXT i
END IF
'-right edge, *skip for last column
IF lCol < 2 THEN
FOR i = 0 TO tile - 1 STEP dotSpacing
SetPixelV hMemDC, cx + tile - 1, cy + i, RGB(255, 255, 255)
NEXT i
END IF
NEXT lCol
NEXT lRow
#ENDIF
'-###-
'-clean up
SelectObject hMemDC, hOldBrush
SelectObject hMemDC, hOldPen
DeleteObject hPen
DeleteDC hMemDC
FUNCTION = hBmp '-return our bitmap handle
END FUNCTION