minimal code experiments:
this could be the shortest way for creating a sdk window frame. I have deleted simple all things I didn't need.
frank's sdk windowFrame example:
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC"
'-------------------------------------------------------------------------------
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, _
BYVAL lpCmdLine AS ASCIIZ PTR, BYVAL iCmdShow AS LONG) AS LONG
'-------------------------------------------------------------------------------
'
LOCAL hWnd AS DWORD
LOCAL wce AS Wndclass
LOCAL szAppName AS ASCIIZ * 96
LOCAL Msg AS tagMsg
szAppName = "franks_SDK_Windowframe"
wce.lpfnWndProc = CODEPTR(WndProc)
wce.lpszClassName = VARPTR(szAppName)
wce.hbrBackground = GetStockObject(%LtGray_BRUSH)
RegisterClass wce
hWnd = CreateWindow(szAppName, "Frank's SDK windowFrame (SDK) " + DATE$, _
%WS_OVERLAPPEDWINDOW OR %WS_CAPTION OR %WS_SYSMENU, 120, 120, 640, 480, _
%NULL, %NULL, hInstance, BYVAL %NULL)
ShowWindow hWnd, iCmdShow
DO WHILE GetMessage(Msg, %NULL, 0, 0)
TranslateMessage Msg
DispatchMessage Msg
LOOP
END FUNCTION
'-------------------------------------------------------------------------------
FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, _
BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
'-------------------------------------------------------------------------------
SELECT CASE wMsg
CASE %WM_DESTROY
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
any comments to this example or feedback are welcome.
best regards, frank
Hello all.
I have a question about the "GetMessage()" declare statement.
I wanted to create a "popup dialog" with sdk windowframe without "win32api.inc" file.
I cannot compile the example because here's the problem:
=>
problem solved!Quote' Message handler loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0) '-------------------> stop compiling
IF ISFALSE IsDialogMessage(hWndMain, uMsg) THEN
TranslateMessage uMsg
DispatchMessage uMsg
END IF
WEND
update: here's the fully working fine "popup dialog" code example without "win32api.inc".
'-------------> testcode for some experiments with sdk window frame without "win32api.inc" file,
'-------------> started begin octobre 2010, frank brübach
#COMPILE EXE
#DIM ALL
'#INCLUDE "win32api.inc"
'--------------------------------------> equates...
%NULL = 0
%LTGRAY_BRUSH = 1
%CS_BYTEALIGNCLIENT = &H00001000
%CS_BYTEALIGNWINDOW = &H00002000
%IDC_ARROW = 32512&
%COLOR_BTNFACE = 15
%IDI_APPLICATION = 32512
%WM_SETFONT = 1002
%SPI_GETWORKAREA = 48
%ANSI_VAR_FONT = 12
%CS_HREDRAW = &H2
%CS_VREDRAW = &H1
%COLOR_3DFACE = %COLOR_BTNFACE
%SIZE_MINIMIZED = 1
%SIZE_MAXIMIZED = 2
%TRUE = 1
%WM_SYSCOMMAND = &H112
%GW_OWNER = 4
%FALSE = 0
'--------------------------------------> types...
TYPE WNDCLASSEX
cbSize AS DWORD
STYLE AS DWORD
lpfnWndProc AS LONG
cbClsExtra AS LONG
cbWndExtra AS LONG
hInstance AS DWORD
hIcon AS DWORD
hCursor AS DWORD
hbrBackground AS DWORD
lpszMenuName AS ASCIIZ PTR
lpszClassName AS ASCIIZ PTR
hIconSm AS DWORD
END TYPE
TYPE RECT
nLeft AS LONG
nTop AS LONG
nRight AS LONG
nBottom AS LONG
END TYPE
TYPE POINTAPI
x AS LONG
y AS LONG
END TYPE
TYPE tagMSG
hwnd AS DWORD
message AS DWORD
wParam AS LONG
lParam AS LONG
time AS DWORD
pt AS POINTAPI
END TYPE
DECLARE FUNCTION SystemParametersInfo LIB "USER32.DLL" ALIAS "SystemParametersInfoA" (BYVAL uAction AS DWORD, BYVAL uParam AS DWORD, lpvParam AS ANY, BYVAL fuWinIni AS DWORD) AS LONG
DECLARE FUNCTION GetModuleHandle LIB "KERNEL32.DLL" ALIAS "GetModuleHandleA" (lpModuleName AS ASCIIZ) AS DWORD
DECLARE FUNCTION RegisterClassEx LIB "USER32.DLL" ALIAS "RegisterClassExA" (pcWndClassEx AS WNDCLASSEX) AS WORD
DECLARE FUNCTION TranslateMessage LIB "USER32.DLL" ALIAS "TranslateMessage" (lpMsg AS DWORD) AS LONG
DECLARE FUNCTION DispatchMessage LIB "USER32.DLL" ALIAS "DispatchMessageA" (lpMsg AS DWORD) AS LONG
DECLARE FUNCTION GetStockObject LIB "GDI32.DLL" ALIAS "GetStockObject" (BYVAL nIndex AS LONG) AS DWORD
DECLARE FUNCTION ShowWindow LIB "USER32.DLL" ALIAS "ShowWindow" (BYVAL hWnd AS DWORD, BYVAL nCmdShow AS LONG) AS LONG
DECLARE SUB PostQuitMessage LIB "USER32.DLL" ALIAS "PostQuitMessage" (BYVAL nExitCode AS LONG)
DECLARE FUNCTION DefWindowProc LIB "USER32.DLL" ALIAS "DefWindowProcA" (BYVAL hWnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION LoadCursor LIB "USER32.DLL" ALIAS "LoadCursorA" (BYVAL hInstance AS DWORD, lpCursorName AS ASCIIZ) AS DWORD
DECLARE FUNCTION LoadIcon LIB "USER32.DLL" ALIAS "LoadIconA" (BYVAL hInstance AS DWORD, lpIconName AS ASCIIZ) AS DWORD
DECLARE FUNCTION SendMessage LIB "USER32.DLL" ALIAS "SendMessageA" (BYVAL hWnd AS DWORD, BYVAL dwMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION UpdateWindow LIB "USER32.DLL" ALIAS "UpdateWindow" (BYVAL hWnd AS DWORD) AS LONG
DECLARE FUNCTION IsDialogMessage LIB "USER32.DLL" ALIAS "IsDialogMessageA" (BYVAL hDlg AS DWORD, lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION GetClientRect LIB "USER32.DLL" ALIAS "GetClientRect" (BYVAL hwnd AS DWORD, lpRect AS RECT) AS LONG
DECLARE FUNCTION MoveWindow LIB "USER32.DLL" ALIAS "MoveWindow" (BYVAL hWnd AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL bRepaint AS LONG) AS LONG
DECLARE FUNCTION GetDlgItem LIB "USER32.DLL" ALIAS "GetDlgItem" (BYVAL hDlg AS DWORD, BYVAL nIDDlgItem AS LONG) AS DWORD
DECLARE FUNCTION GetWindowRect LIB "USER32.DLL" ALIAS "GetWindowRect" (BYVAL hWnd AS DWORD, lpRect AS RECT) AS LONG
DECLARE FUNCTION EnableWindow LIB "USER32.DLL" ALIAS "EnableWindow" (BYVAL hWnd AS DWORD, BYVAL fEnable AS LONG) AS LONG
DECLARE FUNCTION GetWindow LIB "USER32.DLL" ALIAS "GetWindow" (BYVAL hWnd AS DWORD, BYVAL wCmd AS DWORD) AS LONG
DECLARE FUNCTION GetMessage LIB "USER32.DLL" ALIAS "GetMessageA" (lpMsg AS tagMSG, BYVAL hWnd AS DWORD, BYVAL uMsgFilterMin AS DWORD, BYVAL uMsgFilterMax AS DWORD) AS LONG
DECLARE FUNCTION CreateWindowEx LIB "USER32.DLL" ALIAS "CreateWindowExA" (BYVAL dwExStyle AS DWORD, _
lpClassName AS ASCIIZ, lpWindowName AS ASCIIZ, BYVAL dwStyle AS DWORD, BYVAL x AS LONG, _
BYVAL y AS LONG, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL hWndParent AS DWORD, _
BYVAL hMenu AS DWORD, BYVAL hInstance AS DWORD, lpParam AS ANY) AS DWORD
GLOBAL hInstance AS DWORD
GLOBAL hWnd AS DWORD
GLOBAL hIcon AS DWORD
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
LOCAL hWndMain AS DWORD
LOCAL hCtl AS DWORD
LOCAL hFont AS DWORD
LOCAL wcex AS WNDCLASSEX
LOCAL szClassName AS ASCIIZ * 80
LOCAL rc AS RECT
LOCAL szCaption AS ASCIIZ * 255
LOCAL nLeft AS LONG
LOCAL nTop AS LONG
LOCAL nWidth AS LONG
LOCAL nHeight AS LONG
hFont = GetStockObject(%ANSI_VAR_FONT)
' Register the window class
szClassName = "MyClassName"
wcex.cbSize = SIZEOF(wcex)
wcex.style = %CS_HREDRAW OR %CS_VREDRAW
wcex.lpfnWndProc = CODEPTR(WndProc)
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hCursor = LoadCursor (%NULL, BYVAL %IDC_ARROW)
wcex.hbrBackground = %COLOR_3DFACE + 1
wcex.lpszMenuName = %NULL
wcex.lpszClassName = VARPTR(szClassName)
wcex.hIcon = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Sample, if resource icon: LoadIcon(hInst, "APPICON")
wcex.hIconSm = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Remember to set small icon too..
RegisterClassEx wcex
' Window caption
szCaption = "SDK Main Window"
' Retrieve the size of the working area
SystemParametersInfo %SPI_GETWORKAREA, 0, BYVAL VARPTR(rc), 0
' Calculate the position and size of the window
nWidth = (((rc.nRight - rc.nLeft)) + 2) * 0.75 ' 75% of the client screen width
nHeight = (((rc.nBottom - rc.nTop)) + 2) * 0.70 ' 70% of the client screen height
nLeft = ((rc.nRight - rc.nLeft) \ 2) - nWidth \ 2
nTop = ((rc.nBottom - rc.nTop) \ 2) - (nHeight \ 2)
' Create a window using the registered class
hWndMain = CreateWindowEx(%WS_EX_CONTROLPARENT, _ ' extended style
szClassName, _ ' window class name
szCaption, _ ' window caption
%WS_OVERLAPPEDWINDOW OR _
%WS_CLIPCHILDREN, _ ' window styles
nLeft, _ ' initial x position
nTop, _ ' initial y position
nWidth, _ ' initial x size
nHeight, _ ' initial y size
%NULL, _ ' parent window handle
0, _ ' window menu handle
hInstance, _ ' program instance handle
BYVAL %NULL) ' creation parameters
hCtl = CreateWindowEx(0, "BUTTON", "&Popup", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
0, 0, 0, 0, hWndMain, %IDOK, hInstance, BYVAL %NULL)
IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0
hCtl = CreateWindowEx(0, "BUTTON", "&Close", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
0, 0, 0, 0, hWndMain, %IDCANCEL, hInstance, BYVAL %NULL)
IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0
' Show the window
ShowWindow hWndMain, nCmdShow
UpdateWindow hWndMain
' Message handler loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
IF ISFALSE IsDialogMessage(hWndMain, uMsg) THEN
'TranslateMessage uMsg
'DispatchMessage uMsg
END IF
WEND
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main Window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL rc AS RECT
SELECT CASE wMsg
CASE %WM_CREATE
' -------------------------------------------------------
' A good place to initiate things, declare variables,
' create controls and read/set settings from a file, etc.
' -------------------------------------------------------
CASE %WM_SIZE
' ----------------------------------------------------------------------
' If you have a Toolbar and/or a Statusbar, send the following messages:
' SendMessage hStatusbar, wMsg, wParam, lParam
' SendMessage hToolbar, wMsg, wParam, lParam
' ----------------------------------------------------------------------
' Resize the two sample buttons of the dialog
IF wParam <> %SIZE_MINIMIZED THEN
GetClientRect hWnd, rc
MoveWindow GetDlgItem(hWnd, %IDOK), (rc.nRight - rc.nLeft) - 185, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
MoveWindow GetDlgItem(hWnd, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
END IF
CASE %WM_COMMAND
' -------------------------------------------------------
' Messages from controls and menu items are handled here.
' -------------------------------------------------------
SELECT CASE LO(WORD, wParam)
CASE %IDOK
IF HI(WORD, wParam) = %BN_CLICKED THEN
ShowPopupDialog hwnd
END IF
CASE %IDCANCEL
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
'CASE %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT, %WM_CTLCOLORLISTBOX, %WM_CTLCOLORSTATIC
' --------------------------------------------------------
' wParam is the handle of the control's display context (hDC)
' lParam is the handle of the control
' Example of how to set the colors of an specific control:
' --------------------------------------------------------
' IF lParam = GetDlgItem(hWnd, CtlId) THEN
' SetBkColor wParam, GetSysColor(%COLOR_INFOBK)
' SetTextColor wParam, GetSysColor(%COLOR_INFOTEXT)
' FUNCTION = GetSysColorBrush(%COLOR_INFOBK)
' EXIT FUNCTION
' END IF
' --------------------------------------------------------
CASE %WM_SYSCOMMAND
' Capture this message and send a WM_CLOSE message
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_CLOSE
' --------------------------------------------------------
' The WM_CLOSE message is processed BEFORE the WM_DESTROY
' message and it can be used to confirm program exit or
' tasks like deallocating memory or similar tasks.
' --------------------------------------------------------
CASE %WM_DESTROY
' ---------------------------------------------------------------------------
' Is sent when program ends - a good place to delete any created objects and
' store settings in file for next run, etc. Must send PostQuitMessage to end
' properly in SDK-style dialogs. The PostQuitMessage function sends a WM_QUIT
' message to the program's (thread's) message queue, and then WM_QUIT causes
' the GetMessage function to return zero in WINMAIN's message loop.
' ---------------------------------------------------------------------------
PostQuitMessage 0 ' This function closes the main window
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Popup dialog - Calling example: ShowPopupDialog hWnd
' ========================================================================================
FUNCTION ShowPopupDialog (BYVAL hParent AS LONG) AS LONG
LOCAL hWndPopup AS LONG
LOCAL hCtl AS LONG
LOCAL hFont AS LONG
LOCAL rc AS RECT
LOCAL wcex AS WNDCLASSEX
LOCAL szClassName AS ASCIIZ * 80
LOCAL szCaption AS ASCIIZ * 255
hFont = GetStockObject(%ANSI_VAR_FONT)
szClassName = "MyPopupClassName"
wcex.cbSize = SIZEOF(wcex)
wcex.style = %CS_HREDRAW OR %CS_VREDRAW
wcex.lpfnWndProc = CODEPTR(PopupDlgProc)
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = GetModuleHandle("")
wcex.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW)
wcex.hbrBackground = %COLOR_3DFACE + 1
wcex.lpszMenuName = %NULL
wcex.lpszClassName = VARPTR(szClassName)
wcex.hIcon = 0
wcex.hIconSm = 0
RegisterClassEx wcex
GetWindowRect hParent, rc ' For centering child in parent
rc.nRight = rc.nRight - rc.nLeft ' Parent's width
rc.nBottom = rc.nBottom - rc.nTop ' Parent's height
szCaption = "Popup dialog"
hWndPopup = CreateWindowEx(%WS_EX_DLGMODALFRAME OR %WS_EX_CONTROLPARENT, _
szClassName, szCaption, %WS_CAPTION OR %WS_POPUPWINDOW OR %WS_VISIBLE, _
rc.nLeft + (rc.nRight - 390) / 2, _
rc.nTop + (rc.nBottom - 280) / 2, _
390, 280, hParent, 0, GetModuleHandle(""), BYVAL %NULL)
hCtl = CreateWindowEx(0, "BUTTON", "&Close", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
300, 218, 75, 23, hWndPopup, %IDCANCEL, GetModuleHandle(""), BYVAL %NULL)
IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0
ShowWindow hWndPopup, %SW_SHOW
UpdateWindow hWndPopup
' Message handler loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
IF ISFALSE IsDialogMessage(hWndPopup, uMsg) THEN
'TranslateMessage uMsg
'DispatchMessage uMsg
END IF
WEND
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Popup dialog procedure
' ========================================================================================
FUNCTION PopupDlgProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
SELECT CASE wMsg
CASE %WM_CREATE
EnableWindow GetWindow(hWnd, %GW_OWNER), %FALSE ' To make the popup dialog modal
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_CLOSE
EnableWindow GetWindow(hWnd, %GW_OWNER), %TRUE ' Maintains parent's zorder
CASE %WM_DESTROY
PostQuitMessage 0 ' This function closes the main window
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ===============================================================================
(In order to find a solution and more info's about "getmessage()" handling would be nice to get feedback.)
thanks, frank
The problem is that your declare is wrong:
DECLARE FUNCTION GetMessage LIB "USER32.DLL" ALIAS "GetMessageA" (lpMsg AS DWORD, BYVAL hWnd AS DWORD, BYVAL uMsgFilterMin AS DWORD, BYVAL uMsgFilterMax AS DWORD) AS LONG
Must be:
DECLARE FUNCTION GetMessage LIB "USER32.DLL" ALIAS "GetMessageA" (lpMsg AS tagMSG, BYVAL hWnd AS DWORD, BYVAL uMsgFilterMin AS DWORD, BYVAL uMsgFilterMax AS DWORD) AS LONG
The first parameter is a pointer to a tagMSG structure, not to a DWORD.
thanks for this hint josé.
Perhaps my mistake was to use an old getmessage() declare statement for updating the code example. Don't know where this one came from. perhaps I have mixed some "win32api.inc" files from pbwin site and your headers. For this case I have used an old getmessage() declare statement and have got headache ;)
filesize of popup dialog example withouth "win32api.inc": 10 kb
filesize of same popup dialog example with "win32api.inc": 17 kb
I have updated the code example in my post before.
frank