• Welcome to Theos PowerBasic Museum 2017.

shortest sdk window frame :)

Started by Frank Brübach, June 30, 2010, 08:51:21 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frank Brübach

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

Frank Brübach

#1
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

José Roca

#2
 
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.

Frank Brübach

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