• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

question about creation of own winapi control

Started by Frank Brübach, January 07, 2012, 03:23:56 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frank Brübach

I've built an own CustomControl with buttons and Scintilla Editor for an exercise (used one of fred harris example as basis), see picture.

here is my question if there is a way to call an own "sdk winapi" control by an own function like...

  CALL myWINMAIN(0,szClassName,szCaption,100,100,640,480,0,%MySDKWindow,hInst, BYVAL%Null)

I show a fictive code example what I am thinking of..

#COMPILE EXE
#DIM ALL

%MySDKWindow = 1001

FUNCTION PBMAIN () AS LONG
  'fictive + hypothetical code example and setup for a win api with own Winmain function

  LOCAL szClassName AS ASCIIZ*80
  LOCAL szCaption   AS ASCIIZ * 255
  LOCAL hInst AS DWORD, hCtl AS DWORD, hFont AS DWORD, hwnd AS LONG
  LOCAL val1 AS LONG, val2 AS LONG, val3 AS LONG, val4 AS LONG

  szClassName        = "MyOwnWindow_ClassName"
  szCaption          = "SDK Window for nothing more like this one"

  '------------> that's possible to create such sdk window control ? --------------------->
  CALL myWINMAIN(0,szClassName,szCaption,100,100,640,480,0,%MySDKWindow,hInst, BYVAL%Null)
  '------------> that's possible to create such sdk window control ? --------------------->

  '------ Button ------------------\\
  hCtl = CreateWindowEx(0, "BUTTON", "&ComixHeroes", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          val1, val2, val3, val4, hWnd, %IDOK, hInstance, BYVAL %NULL)
  IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0
  '------ Button ------------------\\

      ' Display the window on the screen
    ShowWindow hWnd, iCmdShow
    UpdateWindow hWnd

    FUNCTION = msg.wParam
END FUNCTION


'Function myWinmain(1,1,1,1) works to call a second sdk window frame
'but not with parameter like above myWinmain(0,szClassName, szCaption, 100,100..)

FUNCTION WINMAIN (BYVAL hInstance     AS DWORD, _
                  BYVAL hPrevInstance AS DWORD, _
                  BYVAL lpCmdLine     AS ASCIIZ PTR, _
                  BYVAL iCmdShow      AS LONG) AS LONG
...

' Register the window class
   szClassName        = "MyAnotherClassName"
   wcex.cbSize        = SIZEOF(wcex)
   wcex.style         = %CS_HREDRAW OR %CS_VREDRAW
   wcex.lpfnWndProc   = CODEPTR(WndProcSDK)
   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

       ' Create a window using the registered class
   hWnd = CreateWindowEx(%WS_EX_CONTROLPARENT, _           ' extended style '%WS_EX_TOOLWINDOW, _ '
                             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

...


'==============================================================================
FUNCTION WndProcSdk (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, _
                  BYVAL wParam AS DWORD, BYVAL lParam AS LONG) EXPORT AS LONG
'------------------------------------------------------------------------------
    ' WndProc is the message handler for all windows creating using the HelloWin
    ' class name.  A single WndProc procedure can handle multiple windows by
    ' testing the hWnd variable passed to it.
    '--------------------------------------------------------------------------

    LOCAL hDC    AS DWORD
    LOCAL pPaint AS PAINTSTRUCT
    LOCAL tRect  AS RECT

    ' The SELECT CASE is used to catch only those messages which the message
    ' handler needs to process.  All other messages are passed through the
    ' tests to the default handler.
    SELECT CASE wMsg

    CASE %WM_CREATE

    CASE %WM_PAINT
        hDC = BeginPaint(hWnd, pPaint)
        GetClientRect hWnd, tRect
        SetBkMode hDC, %TRANSPARENT
        SetTextColor hDC, %RED
        DrawText hDC, "Hello to my another Windows!", -1, tRect, %DT_SINGLELINE OR %DT_CENTER OR %DT_VCENTER
        EndPaint hWnd, pPaint
        FUNCTION = 1
        EXIT FUNCTION

    CASE %WM_ERASEBKGND
        hDC = wParam
        DrawGradientx hDC              ' Pass the DC of the region to repaint
        FUNCTION = 1
        EXIT FUNCTION

    CASE %WM_DESTROY
        PostQuitMessage 0
        EXIT FUNCTION

    END SELECT

    ' Any message which is not handled in the above SELECT CASE reaches this
    ' point and is processed by the Windows default message handler.
    FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)

END FUNCTION



my idea was to create a complete new Winmain Api Control by a simple function from pbmain() or winmain() function. and then to subclass or call a button or other control (scintilla editor for example) with createWindowEx function.

I know how to setup a second sdk window by button click with a control (see pic2) but that's using same window controlclass like simple sdk window frame.

perhaps anybody has an idea or know more about this topic or give a tip if that's in general possible to open a new sdk window frame by a simple function (for example: myWinmain(0,"testSDK", "Hello my new WindowSDK", 100,100,640,480, %NEWSDK,hInstance, byval %NULL) )

the problem is here to include a button or edit control to an existing second sdk window frame. I wish to have something similar to call a dialog in ddt modus like this one for a sdk window using winmain () function

function pbmain() as long

FUNCTION PBMAIN () AS LONG
DIM hDlg AS DWORD, result as long

DIALOG NEW 0, "myTestDialog",-1,-1, 330, 203, _
                                   %WS_POPUP         OR _
                                   %WS_VISIBLE       OR _
                                   %WS_CLIPCHILDREN  OR _
                                   %WS_CAPTION       OR _
                                   %WS_SYSMENU       OR _
                                   %WS_MINIMIZEBOX,     _
                                   0 TO hDlg

CONTROL ADD BUTTON, hDlg, %ButtonClose, "Click to kill", 90, 50, 150, 100

DIALOG SHOW MODAL hDlg, CALL cbDialog TO result



END FUNCTION


thanks, frank

José Roca

It's not clear to me what you mean. However, an application can only have a WinMain (or PBMain) function.

Frederick J. Harris

When I wish to create applications which contain more than one main window, I typically register window classes for any additional top level overlapped windows in the WM_CREATE message handler for my main program start up window.  There seems to be some difference of opinion on this, as I believe Jose and possibly others too prefer to register window classes for additional top level windows in WinMain() / PBMain().  In any case, the additional window classes need to be registered before CreateWindowEx() calls can be made on them.

When this is performed as I just described you can create instances of these additional windows through button click processing or anything else.  Not sure if this is what you are getting at.  If it is I have a PowerBASIC demo of this handy I can post.

Eros Olmi

Quote from: Frank Brübach on January 07, 2012, 03:23:56 PM
I've built an own CustomControl with buttons and Scintilla Editor for an exercise (used one of fred harris example as basis), see picture.

Frank,

a custom control is not a dialog with some controls inside it but a complete (or partially complete) new control with its registered window class (see here for reference about what is a window class: http://msdn.microsoft.com/en-us/library/windows/desktop/ff468928(v=VS.85).aspx), its behave, its drawing, its controlling function, ...

So your example is not a custom control but instead a normal window with some standard and custom controls inside.

PowerBasic web site has some nice Custom Controls developed you can use as a driver.
Few examples (I just searched PB Source forum for "Custom" inside post title)
URL Control: http://www.powerbasic.com/support/pbforums/showthread.php?t=24545&highlight=custom
Custom Control Properties ListBox: http://www.powerbasic.com/support/pbforums/showthread.php?t=22892&highlight=custom
Data Entry Grid Custom Control: http://www.powerbasic.com/support/pbforums/showthread.php?t=25160&highlight=custom
custom control knob: http://www.powerbasic.com/support/pbforums/showthread.php?t=25129&highlight=custom

Ciao
Eros

thinBasic Script Interpreter - www.thinbasic.com | www.thinbasic.com/community
Win7Pro 64bit - 8GB Ram - Intel i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

Dominic Mitchell

It appears he is trying to write a custom control with embedded controls.
For example,   
 
 
+-----------------------------------------+
| +------------------------+              |
| |                        |              |
| |                        | +----------+ |
| |                        | | Button 1 | |
| |                        | +----------+ | 
| |    Edit Control        |              | <---- MyCustomConrol
| |                        | +----------+ | 
| |                        | | Button 2 | |
| |                        | +----------+ |
| |                        |              |
| |                        |              |
| +------------------------+              |
+-----------------------------------------+


In the diagram above, the custom control is made up of
1) A container with the class name "MyCustomControl".
2) Three predefined controls, one edit control and two buttons.

The syntax for creating this control would be

SDK

hControl = CreateWindowEx(%WS_EX_CONTROLPARENT, _                    ' extended styles
                          "MyCustomControl", _                       ' class name
                          "", _                                      ' caption
                          %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, _ ' window styles
                          10, 170, _                                 ' left, top
                          336, 161, _                                ' width, height
                          hParent, %IDC_FORM1_MYCUSTOMCONTROL1, _    ' handle of parent, control ID
                          ghInstance, BYVAL %NULL)                   ' handle of instance, creation parameters


DDT

CONTROL ADD "MyCustomControl", _                        ' class name
            hDlg, %IDC_FORM1_MYCUSTOMCONTROL1, _        ' handle of parent, control ID
            "", _                                       ' caption
            10, 170, _                                  ' left, top
            336, 161, _                                 ' width, height
            %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, _  ' window styles
            %WS_EX_CONTROLPARENT _                      ' extended styles
            TO hControl

                         
This post demonstrates creating a compound control
http://www.powerbasic.com/support/pbforums/showpost.php?p=379340&postcount=27

It is part of this thread
http://www.powerbasic.com/support/pbforums/showthread.php?t=47631&highlight=custom+control

Other threads on this topic
http://www.powerbasic.com/support/pbforums/showthread.php?t=11685&highlight=aggregate+control   

http://www.powerbasic.com/support/pbforums/showthread.php?t=13538&highlight=custom+control
http://www.powerbasic.com/support/pbforums/showthread.php?t=20718&highlight=custom+control
http://www.powerbasic.com/support/pbforums/showpost.php?p=69266&postcount=8
http://www.powerbasic.com/support/pbforums/showpost.php?p=69281&postcount=23
http://www.powerbasic.com/support/pbforums/showpost.php?p=69288&postcount=30
Dominic Mitchell
Phoenix Visual Designer
http://www.phnxthunder.com

Frank Brübach

#5
1) thank you jose, eros, fred and dominic for your useful links, explanations and tips. To be truly I have undervalue this topic with custom controls and checked first of all fred harris example with DLL custom control service with dll and test example but didn't noticed all other examples with creation of own control classes in sdk style (or ddt modus, for example by borje hagsten).

@fred: I like your "dllcustomcontrollserver" example with color buttons and added a fourth button and a scintilla editor into it. I think I have understood this interesting setup. If you have another example to show or with different windows frame I am glad to see that :)

QuoteWhen I wish to create applications which contain more than one main window, I typically register window classes for any additional top level overlapped windows in the WM_CREATE message handler for my main program start up window.

@eros: thank you, that was the unsure moment I have had about dialog/control class differences, now it's more clear!

@dominic: I have chosed one of your example with infolist and checked it too. I add here a scintilla  edit control too. thanks for your diagram.

2) my motivation was to think about a sdk window frame creation, if that's also possible to create a new winmain() class control in similar modus like a button, edit control or something else. then it would be nice to see if there's a way to call this winmainClass with a usual function you does it with (for example)


hSdkControl = CreateWindowEx(%WS_EX_CONTROLPARENT, _                    ' extended styles
                          "MySDK_CustomControl", _                       ' class name
                          "", _                                      ' caption
                          %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, _ ' window styles
                          10, 170, _                                 ' left, top
                          336, 161, _                                ' width, height
                          hParent, %IDC_FORM1_MYSDK_CUSTOMCONTROL1, _    ' handle of parent, control ID
                          ghInstance, BYVAL %NULL)                   ' handle of instance, creation parameters


imagine you have the diagram from Dominic and there's a Winmain_ControlClass before button1, button2 and the followin Edit Control.

I know that's only possible to create one winmain() sdk window frame by function and my second idea was to start a new winmain(2) sdk window frame by an include file via button click for example. I am not sure if there's a way to call after that a simple new sdk window with this command line

CALL myWINMAIN(0,szClassName,szCaption,100,100,640,480,0,%MySDKWindow,hInst, BYVAL%Null)


there's a lot of things more to study, I will do for next weeks. two pictures of my control class experiments I add here. thanks for help!

best regards, frank

Frederick J. Harris

In a certain sense, any time one registers a window class with RegisterClass() or RegisterClassEx(), one has created a custom Window Class the instantiation of which through a CreateWindow() or CreateWindowEx() call results in a custom window object in the case of a top level window, or a custom windows control in the case of an object with the WS_CHILD property/style.

That custom control example of mine you are speaking of is an adaptation of one I learned from Chris Boss who is also very knowledgable in this area.  In that example the custom control consisted of only a simple colored window.  The buttons to change the color were located in the parent window.  When I created that tutorial/example I had thought of putting the three buttons within the control itself, but decided against that at the last moment, because that would have robbed me of the opportunity of showing function calls being made 'into' the control, as the button clicks would then have been picked up within the Window Procedure of the custom control in the dll rather than in the host or parent as is now the case.  However, by doing that I lost the opportunity of showing how to make a 'composite' control, which is apparently what you want and seemingly have achieved on your own anyway. 

In many cases when building custom window controls they are 'Composite Controls' and contain other simple Windows Controls such as buttons, edit controls, etc (or in your case, a Rich Edit Control).  The way I create these is inside the WM_CREATE handler of the custom control.   A few words about this may be in order.

I view the WM_CREATE message very much like an object constructor in OOP terminology.  When Windows sends a WM_CREATE message to a Window Procedure, it has already set up everything or nearly everything it needs to maintain that window such as the allocation of memory, creation of handles, etc.  So when you receive that WM_CREATE message, Windows is saying to you, "I've done everyting I need to create, service, and manage your window hWnd = xxxxxxxxx, so now its your turn to do what you need to do to customize its final creation.  Do what you will!"  So in the case of a composite custom control one would be making additional CreateWindow() calls inside the CreateWindow call the WM_CREATE message of which you are now coding!  So you can end up with whole series of cascading and almost recursive CreateWindow calls inside other CreateWindow calls inside yet other CreateWindow calls as an object pulls itself together – pulling itself up by the bootstraps, so to speak.  Because, don't forget, when a WM_CREATE call occurs, and while inside a WM_CREATE handler, the CreateWindow() call that caused the WM_CREATE message has not as of yet returned.

As an exercise, it might be worthwhile to modify that custom control example of mine to locate the buttons within the custom control and think that whole process through.

When you first posted Frank, I wasn't sure what you wanted.  That's why I mentioned another program I had that showed how to create a main form which then created multiple 'sub-forms'.  I use that architecture frequently in the work I do.  Here is that example...


#Compile                  Exe
#Dim                      All
%UNICODE                  = 1
#If %Def(%UNICODE)
    Macro ZStr            = WStringz
    Macro BStr            = WString
    %SIZEOF_CHAR          = 2
#Else
    Macro ZStr            = Asciiz
    Macro BStr            = String
    %SIZEOF_CHAR          = 1
#EndIf
#Include                  "Win32api.inc"
%IDC_BUTTON_1             = 1501
%IDC_BUTTON_2             = 1502
%IDC_BUTTON_3             = 1503

Type WndEventArgs
  hIns                    As Dword
  hWnd                    As Dword
  wParam                  As Dword
  lParam                  As Dword
End Type


Function fnForm1(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Local hParent As Dword

  Select Case As Long wMsg
    Case %WM_CREATE
      Local pCreateStruct As CREATESTRUCT Ptr
      pCreateStruct = lParam
      hParent=@pCreateStruct.lpCreateParams
      Call SetWindowLong(hWnd,0,hParent)
      Call EnableWindow(hParent,%FALSE)
      Function=0 : Exit Function
    Case %WM_PAINT
      Local ps As PAINTSTRUCT
      Local hDC As Dword
      hDC=BeginPaint(hWnd,ps)
      TextOut(hDC,0,0,"This Form Disables The Main Program Window.",43)
      TextOut(hDC,0,18,"Therefore It Can Be Considered As A Modal",41)
      TextOut(hDC,0,36,"Window.",7)
      Call EndPaint(hWnd,ps)
      fnForm1 = 0 : Exit Function
    Case %WM_DESTROY
      hParent=GetWindowLong(hWnd,0)
      Call EnableWindow(hParent,%TRUE)
      Function=0 : Exit Function
  End Select

  fnForm1=DefWindowProc(hWnd, wMsg, wParam, lParam)
End Function


Function fnForm2(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Local hParent As Dword

  Select Case As Long wMsg
    Case %WM_CREATE
      Local pCreateStruct As CREATESTRUCT Ptr
      pCreateStruct = lParam
      hParent=@pCreateStruct.lpCreateParams
      Call SetWindowLong(hWnd,0,hParent)
      Call ShowWindow(hParent,%SW_HIDE)
      Function=0 : Exit Function
    Case %WM_PAINT
      Local ps As PAINTSTRUCT
      Local hDC As Dword
      hDC=BeginPaint(hWnd,ps)
      TextOut(hDC,0,0,"This Form Hides The Main Program Window.  It",44)
      TextOut(hDC,0,18,"Will Be Shown Again When You Dismiss This",41)
      TextOut(hDC,0,36,"Window.",7)
      Call EndPaint(hWnd,ps)
      Function = 0 : Exit Function
    Case %WM_DESTROY
      hParent=GetWindowLong(hWnd,0)
      Call ShowWindow(hParent,%SW_RESTORE)
      Function=0 : Exit Function
  End Select

  fnForm2=DefWindowProc(hWnd, wMsg, wParam, lParam)
End Function


Function fnForm3(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Select Case wMsg
    Case %WM_PAINT
      Local ps As PAINTSTRUCT
      Local hDC As Dword
      hDC=BeginPaint(hWnd,ps)
      TextOut(hDC,0,0,"You can create as many Form3s As You Like.",42)
      Call EndPaint(hWnd,ps)
      fnForm3 = 0 : Exit Function
  End Select

  fnForm3=DefWindowProc(hWnd, wMsg, wParam, lParam)
End Function


Function fnMainWndProc_OnCreate(Wea As WndEventArgs) As Long
  Local pCreateStruct As CREATESTRUCT Ptr
  Local szClassName As ZStr*16
  Local wc As WndClassEx
  Local hCtl As Dword

  pCreateStruct=wea.lParam
  wea.hIns=@pCreateStruct.hInstance
  hCtl=CreateWindow("button","Button 1",%WS_CHILD Or %WS_VISIBLE,50,25,125,25,wea.hWnd,%IDC_BUTTON_1,wea.hIns,ByVal 0)
  hCtl=CreateWindow("button","Button 2",%WS_CHILD Or %WS_VISIBLE,50,60,125,25,wea.hWnd,%IDC_BUTTON_2,wea.hIns,ByVal 0)
  hCtl=CreateWindow("button","Button 3",%WS_CHILD Or %WS_VISIBLE,50,95,125,25,wea.hWnd,%IDC_BUTTON_3,wea.hIns,ByVal 0)
  'Form1 Window
  szClassName="Form1"                            :  wc.lpszClassName=VarPtr(szClassName) 'Form1
  wc.lpfnWndProc=CodePtr(fnForm1)                :  wc.hbrBackground=GetStockObject(%WHITE_BRUSH)
  wc.cbSize=SizeOf(wc)                           :  wc.style=%CS_HREDRAW Or %CS_VREDRAW
  wc.cbClsExtra=0                                :  wc.cbWndExtra=4
  wc.hInstance=wea.hIns                          :  wc.hIcon=LoadIcon(%NULL, ByVal %IDI_APPLICATION)
  wc.hCursor=LoadCursor(%NULL, ByVal %IDC_ARROW) :  wc.lpszMenuName=%NULL
  Call RegisterClassEx(wc)
  'Form2 Window
  szClassName="Form2"                            :  wc.lpszClassName=VarPtr(szClassName) 'Form2
  wc.lpfnWndProc=CodePtr(fnForm2)                :  wc.hbrBackground=GetStockObject(%WHITE_BRUSH)
  Call RegisterClassEx(wc)
  'Form3 Window
  szClassName="Form3"                            :  wc.lpszClassName=VarPtr(szClassName) 'Form3
  wc.lpfnWndProc=CodePtr(fnForm3)                :  wc.hbrBackground=GetStockObject(%WHITE_BRUSH)
  Call RegisterClassEx(wc)

  fnMainWndProc_OnCreate=0
End Function


Function fnMainWndProc_OnCommand(Wea As WndEventArgs) As Long
  Local hForm As Dword

  Select Case LoWrd(wea.wParam)
    Case %IDC_BUTTON_1
      hForm=CreateWindowEx(0,"Form1","Form1",%WS_OVERLAPPEDWINDOW,325,75,350,225,wea.hWnd,0,wea.hIns,Byval Wea.hWnd)
      Call ShowWindow(hForm,%SW_SHOWNORMAL)
      Call UpdateWindow(hForm)
    Case %IDC_BUTTON_2
      hForm=CreateWindowEx(0,"Form2","Form2",%WS_OVERLAPPEDWINDOW,350,250,350,125,wea.hWnd,0,wea.hIns,Byval Wea.hWnd)
      Call ShowWindow(hForm,%SW_SHOWNORMAL)
      Call UpdateWindow(hForm)
    Case %IDC_BUTTON_3
      hForm=CreateWindowEx(0,"Form3","Form3",%WS_OVERLAPPEDWINDOW,%CW_USEDEFAULT,%CW_USEDEFAULT,350,125,wea.hWnd,0,wea.hIns,Byval 0)
      Call ShowWindow(hForm,%SW_SHOWNORMAL)
      Call UpdateWindow(hForm)
  End Select

  fnMainWndProc_OnCommand=0
End Function


Function fnMainWndProc_OnClose(wea As WndEventArgs) As Long
  PostQuitMessage 0
  fnMainWndProc_OnClose=0
End Function


Function fnMainWndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) Export As Long
  Local wea As WndEventArgs

  Select Case wMsg
    Case %WM_CREATE
      wea.hWnd=hWnd : wea.wParam=wParam : wea.lParam=lParam
      fnMainWndProc=fnMainWndProc_OnCreate(wea)
      Exit Function
    Case %WM_COMMAND
      wea.hWnd=hWnd : wea.wParam=wParam : wea.lParam=lParam
      fnMainWndProc=fnMainWndProc_OnCommand(wea)
      Exit Function
    Case %WM_CLOSE
      wea.hWnd=hWnd : wea.wParam=wParam : wea.lParam=lParam
      fnMainWndProc=fnMainWndProc_OnClose(wea)
      Exit Function
  End Select

  fnMainWndProc=DefWindowProc(hWnd, wMsg, wParam, lParam)
End Function


Function WinMain(ByVal hIns As Long, ByVal hPrev As Long, ByVal lpCL As Asciiz Ptr, ByVal Is As Long) As Long
  Local szAppName As ZStr * 32
  Local hMainWnd As Dword
  Local wc As WndClassEx
  Local Msg As tagMsg

  szAppName="Multiple Windows"                     :  wc.lpszClassName=VarPtr(szAppName)
  wc.lpfnWndProc=CodePtr(fnMainWndProc)            :  wc.cbSize=SizeOf(wc)
  wc.style=%CS_HREDRAW Or %CS_VREDRAW              :  wc.cbClsExtra=0
  wc.cbWndExtra=0                                  :  wc.hInstance=hIns
  wc.hIcon=LoadIcon(%NULL, ByVal %IDI_APPLICATION) :  wc.hCursor=LoadCursor(%NULL, ByVal %IDC_ARROW)
  wc.hbrBackground=%COLOR_BTNSHADOW                :  wc.hIconSm=0
  wc.lpszMenuName=%NULL
  Call RegisterClassEx(wc)
  hMainWnd=CreateWindowEx(0,szAppName,"Multiple Forms",%WS_OVERLAPPEDWINDOW,575,75,240,190,0,0,hIns,ByVal 0)
  Call ShowWindow(hMainWnd,Is)
  While GetMessage(Msg,%NULL,0,0)
    TranslateMessage Msg
    DispatchMessage Msg
  Wend

  Function=msg.wParam
End Function