---------------------------------------------------------------------------
    -----------------------------------------------------------------------
            - A L W A Y S   U N D E R    C O N S T R U C T I O N -

           $$$$$$$$   $$$$$$$$  $$$$$$$$$$$$$   $$$$$$$$   $$$$$$$$
          $$$$$ $$$$ $$$$$ $$$$ $$$$$ $$$$ $$$ $$$$$ $$$$ $$$$$ $$$$
          $$$$$ $$$$ $$$$$      $$$$$ $$$$ $$$       $$$$       $$$$
          $$$$$$$$$$  $$$$$$$$  $$$$$ $$$$ $$$  $$$$$$$$   $$$$$$$$
          $$$$$ $$$$       $$$$ $$$$$ $$$$ $$$       $$$$ $$$$$
          $$$$$ $$$$ $$$$$ $$$$ $$$$$ $$$$ $$$ $$$$$ $$$$ $$$$$ $$$$
          $$$$$ $$$$  $$$$$$$$  $$$$$ $$$$ $$$  $$$$$$$$  $$$$$$$$$$

                    How to program for windows 95 in asm32
                        Lesson 2 : Your First Window !
                      by _HaK_ and corrected by I_Magnus

    -----------------------------------------------------------------------
  ---------------------------------------------------------------------------


  1.Introduction :
  ----------------

      OK this time  I'll try to teach you how to do your first window.
      It won't be complicated (just a bit). The only thing we have to
      know is that a window is composed of multiple elements :

       * A title bar with, most of the time, :

           - Three buttons : quit, minimize and maximize.
           - A title.
           - An  icon  before the  title which  become a  System Menu by
             clicking on it.

       * A Menu Bar

       * Borders

       * And a client area (the main component of the windows sometimes
         called working area)



  2.Stop talking and let's begin :
  --------------------------------

    2.1.The window creation :
    -------------------------

      Each window belongs to a class type.  And so, before creating a window,
      we have to register a new class  defining some options of the window.
      To register a new class type we'll use :  RegisterClassA
      And to create the window we'll use : CreateWindowExA

      2.1.1.First The RegisterClassA :
      --------------------------------

        This  function  is used  to  register a new  class  for a window.
        A class is a sort of  advanced  definition options for a windows.
        It defines the  procedure to call each time the user  touches the
        window, the menu of the window,  the icon and the cursor  of the
        application,...  Multiple  windows can use  the same  class, and
        then the same window procedure.

        With this API we have to push only a  parameter : a long pointer
        to the "WndClass" structure.

        To define a structure put it before the data segment in the first
        part  of the .ASM  (in the  definition part). Once  defined, the
        structure has to be declared in the data segment  assigned to a
        name. Each  time a name is  assigned to a  structure, it gets the
        same defined composition, but its own data area.

        The WndClass structure is defined as follows :

          WNDCLASS struc
              clsStyle          dd   ?   ; class style
              clsLpfnWndProc    dd   ?   ; pointer to the window procedure
              clsCbClsExtra     dd   ?   ; sort of size of buffer (0)
              clsCbWndExtra     dd   ?   ; sort of size of buffer too (0)
              clsHInstance      dd   ?   ; application instance handle
              clsHIcon          dd   ?   ; icon handle
              clsHCursor        dd   ?   ; cursor handle
              clsHbrBackground  dd   ?   ; background brush handle
              clsLpszMenuName   dd   ?   ; menu handle
              clsLpszClassName  dd   ?   ; far ptr to class name string,
                                         ; "null terminated"
          WNDCLASS ends

        To declare this structure you have to add to your data :

          NameYouWant  WNDCLASS 

        After, if  you want to access  a special  offset of the structure,
        do the following (it's an example) :

          mov  [NameYouWant.clsHIcon],eax

        If a first structure contains another structure, for example
        a RECT or a POINT structure, you can access them by typing :

          mov  [FirstStructureName.SecondStructureName.DataName],eax

        But be  careful : don't begin  a data name in the structure with
        numbers : it will result in a fatal error while compiling !

        OK, now to the WNDCLASS structure :

          * The first data is the class style. The value is a combination
            of the following value :

              CS_VREDRAW          EQU       0001h ;
              CS_HREDRAW          EQU       0002h ;
              CS_DBLCLKS          EQU       0008h ;
              CS_OWNDC            EQU       0020h ;
              CS_CLASSDC          EQU       0040h ;
              CS_PARENTDC         EQU       0080h ;
              CS_NOCLOSE          EQU       0200h ; Disable the close
                                                  ; command of the window.
              CS_SAVEBITS         EQU       0800h ;
              CS_BYTEALIGNCLIENT  EQU       1000h ;
              CS_BYTEALIGNWINDOW  EQU       2000h ;
              CS_GLOBALCLASS      EQU       4000h ;
              CS_IME              EQU   00010000h ; ? no info about this.

          [It seems to have something to do with Java.  I found a webpage
           dealing with it, and a MS Knowlege Base article describing it.
           Something to do with Client Side Image Map Editor? -- Ed.     ]

          * The second data  is a long  pointer  to a window  procedure :
            each time  something  appends  to the  window, this procedure
            is called. (for more info see below)

          * The next two data are integers, but i  have no info about them
            and if you put in zeros, it works perfectly !

          * The  clsHInstance need  to have the application handle getted
            by the API : GetModuleHandleA (see lesson 1)

        Now we access to an interesting part of the WNDCLASS structure :

          * The clsHIcon parameter : Here we have to put the handle of an
            Icon.  This Icon will  become  the Default  Icon  of the next
            created window (the  icon is shown in the taskbar and in the
            title bar (can be chosen if you want...or not)).

          * The clsHCursor  parameter : Here we have to put the handle of
            a Cursor. The selected cursor is shown when the user has  the
            mouse cursor within the window.

            The icon and  the  cursor can be  defined in the .RC file. But
            the icon and the cursor have to be loaded with the LoadCursorA
            and  LoadIconA  APIs, to get the Icon and Cursor handle that
            has to be moved to the  structure. If  no Cursor (or Icon)
            are selected, the default Cursor (or Icon) will be the current
            mouse cursor (or win logo for Icon).
            There is some "predefined"  cursor and icon that can be loaded
            from the application with handle 0 (HWND=0, so push 0 for hwnd
            before calling the LoadCursorA and LoadIconA).

              Predefined Cursor :

                IDC_ARROW        EQU   32512 ; normal cursor
                IDC_IBEAM        EQU   32513
                IDC_WAIT         EQU   32514
                IDC_CROSS        EQU   32515
                IDC_UPARROW      EQU   32516
                IDC_SIZE         EQU   32640 ; OBSOLETE: use IDC_SIZEALL
                IDC_ICON         EQU   32641 ; OBSOLETE: use IDC_ARROW
                IDC_SIZENWSE     EQU   32642
                IDC_SIZENESW     EQU   32643
                IDC_SIZEWE       EQU   32644
                IDC_SIZENS       EQU   32645
                IDC_SIZEALL      EQU   32646
                IDC_NO           EQU   32648
                IDC_HAND         EQU   32649 ; only Win98 ?
                                             ; (for win version >=500)
                IDC_APPSTARTING  EQU   32650
                IDC_HELP         EQU   32651

              Predefined Icons :

                IDI_APPLICATION  EQU   32512
                IDI_HAND         EQU   32513
                IDI_QUESTION     EQU   32514
                IDI_EXCLAMATION  EQU   32515
                IDI_ASTERISK     EQU   32516
                IDI_WINLOGO      EQU   32517

          * The clsHbrBackground to define the brush with which the window
            client area will be filled.  This can be a standard value such as :

              COLOR_SCROLLBAR           EQU 0
              COLOR_BACKGROUND          EQU 1
              COLOR_ACTIVECAPTION       EQU 2
              COLOR_INACTIVECAPTION     EQU 3
              COLOR_MENU                EQU 4
              COLOR_WINDOW              EQU 5
              COLOR_WINDOWFRAME         EQU 6
              COLOR_MENUTEXT            EQU 7
              COLOR_WINDOWTEXT          EQU 8
              COLOR_CAPTIONTEXT         EQU 9
              COLOR_ACTIVEBORDER        EQU 10
              COLOR_INACTIVEBORDER      EQU 11
              COLOR_APPWORKSPACE        EQU 12
              COLOR_HIGHLIGHT           EQU 13
              COLOR_HIGHLIGHTTEXT       EQU 14
              COLOR_BTNFACE             EQU 15
              COLOR_BTNSHADOW           EQU 16
              COLOR_GRAYTEXT            EQU 17
              COLOR_BTNTEXT             EQU 18
              COLOR_INACTIVECAPTIONTEXT EQU 19
              COLOR_BTNHIGHLIGHT        EQU 20
              COLOR_3DDKSHADOW          EQU 21
              COLOR_3DLIGHT             EQU 22
              COLOR_INFOTEXT            EQU 23
              COLOR_INFOBK              EQU 24
              COLOR_HOTLIGHT                EQU  26 ; Only Win98 ?
                                                    ; (for win version >=500)
              COLOR_GRADIENTACTIVECAPTION   EQU  27 ; Only Win98 ?
                                                    ; (for win version >=500)
              COLOR_GRADIENTINACTIVECAPTION EQU  28 ; Only Win98 ?
                                                    ; (for win version >=500)

            If you  want your own  brush, move to this data the handle of
            the brush you get  after the Brush  Creation  APIs (Just like
            CreateSolidBrush,...)

          * The  clsLpszMenuName  has to get the  Handle of a menu.  This
            Handle  can be obtained  by the  LoadMenu  API if the menu is
            stored in the  resource file. To load it You have to push the
            application  handle and the Menu resource ID (or a pointer to
            a null terminated  string defining the name of the menu given
            in the .RC file). The pushed application handle defines, just
            like the LoadIconA  and LoadCursorA, the module from where it
            must be loaded.

          * The  clsLpszClassName  gets the  offset  of  a  string,  null
            terminated, which defines the new class name to which will be
            assigned all the given parameters.

        Once you have  filled all  data, push the  offset of  the filled
        structure and call the RegisterClassA API to register it.

        Now the class is registered, we use the CreateWindowExA to create
        the window using the new registered class.

      2.1.2.CreateWindowExA :
      ---------------------

        This  is the  real function  to create  a window  or  one of its
        components (see Lesson 3). All its  parameters have to be pushed
        on the Stack and always in the inverted order.

        OK Now the parameters :

          HWND CreateWindowExA(
            DWORD dwExStyle,
            LPCSTR lpClassName,
            LPCSTR lpWindowName,
            DWORD dwStyle,
            int X,
            int Y,
            int nWidth,
            int nHeight,
            HWND hWndParent ,
            HMENU hMenu,
            HINSTANCE hInstance,
            LPVOID lpParam);

          * The first parameters define the  extended style of the window
            This  is a  complement to the  dwStyle parameter and can be a
            combination of :

              WS_EX_DLGMODALFRAME  EQU   00000001h
              WS_EX_NOPARENTNOTIFY EQU   00000004h
              WS_EX_TOPMOST        EQU   00000008h ; Window is always on top
              WS_EX_ACCEPTFILES    EQU   00000010h
              WS_EX_TRANSPARENT    EQU   00000020h ; Window is transparent
                                                   ;  (can see through it)
              WS_EX_MDICHILD       EQU   00000040h
              WS_EX_TOOLWINDOW     EQU   00000080h ; create a small window :
                                                   ; smaller caption,...
              WS_EX_WINDOWEDGE     EQU   00000100h
              WS_EX_CLIENTEDGE     EQU   00000200h
              WS_EX_CONTEXTHELP    EQU   00000400h
              WS_EX_RIGHT          EQU   00001000h
              WS_EX_LEFT           EQU   00000000h
              WS_EX_RTLREADING     EQU   00002000h ; write text mode :
                                                   ; right to left (Arabic)
              WS_EX_LTRREADING     EQU   00000000h ; left to right
              WS_EX_LEFTSCROLLBAR  EQU   00004000h ; scroll bar if one
                                                   ; on left
              WS_EX_RIGHTSCROLLBAR EQU   00000000h ; on right
              WS_EX_CONTROLPARENT  EQU   00010000h
              WS_EX_STATICEDGE     EQU   00020000h
              WS_EX_APPWINDOW      EQU   00040000h

          * The lpClassName gets the offset of the null terminated string
            defining  the  Class  to  which the window belongs. There are
            special Classes which define Window Control such as Edit Box,
            Buttons, etc...

          * The  lpWindowName gets the offset of a null terminated string
            defining the title of the window.

          * The  dwStyle  defines  the windows  main style. It can get a
            combination of these Values:

              WS_OVERLAPPED    EQU   00000000h ; flat window (win3.1 style)
              WS_POPUP         EQU   80000000h ; new popup window (no parent)
              WS_CHILD         EQU   40000000h ; window has a parent and
                                               ; belong to him
              WS_MINIMIZE      EQU   20000000h ; window is showed minimized
              WS_VISIBLE       EQU   10000000h ; window is showed normal
              WS_DISABLED      EQU   08000000h ; window is disabled
                                               ; (for child)
              WS_CLIPSIBLINGS  EQU   04000000h ; window clip his siblings
              WS_CLIPCHILDREN  EQU   02000000h ; window clip his children
              WS_MAXIMIZE      EQU   01000000h ; window is showed maximized
              WS_BORDER        EQU   00800000h ; window has black drawn
                                               ; border (ugly , win3.1 style)
              WS_DLGFRAME      EQU   00400000h ; window is similar to a
                                               ; dialog : 3d style
              WS_VSCROLL       EQU   00200000h ; window have vertical
                                               ; scroll bar
              WS_HSCROLL       EQU   00100000h ; window have horizontal
                                               ; scroll bar
              WS_SYSMENU       EQU   00080000h ; title bar have his menu
                                               ; (the icon on the left)
              WS_THICKFRAME    EQU   00040000h ; window can be resized
                                               ; (cursor on border)
              WS_GROUP         EQU   00020000h ; window create a new group
                                               ; (for child)
              WS_TABSTOP       EQU   00010000h ; window can be selected with
                                               ; the tab key (for child)
              WS_MINIMIZEBOX   EQU   00020000h ; window have the mini button
                                               ; in title bar
              WS_MAXIMIZEBOX   EQU   00010000h ; window have the maxi button
                                               ; in title bar
              If you choose only one of the WS_MINIMIZEDBOX or WS_MAXIMIZED,
              the other button will be displayed also (but grayed).

          * The 4 next parameters defines :

            - X : the abscissa  of the left side of window when displayed
                  (from left border)

            - Y : the  ordinate  of the top side of window when displayed
                  (from top border)

            - nWidth : the width of the window

            - nHeight : the height of the window

            You can assign any value to these  parameters. But there is a
            default value for Windows :

              CW_USEDEFAULT    EQU   80000000h

            And then with this value give the default abscissa, ordinate,
            width and/or Height to the window.

          * The hWndParent can get two values :

            - 0 if it's a new window

            - or the handle of the parent  window which will  include the
              child window (for window control).

          * The hMenu can get the Handle of a menu loaded by the LoadMenu
            API. If you want none : simply push 0.

            This  can be  used better  than the  HMenu in  the  WndClass,
            because the Menu will be specific to the window and if a Menu
            is defined in the WndClass all  window having the same  Class
            would have the same Menu.

            If you are creating a child window this parameters will define
            the value in wparam of the WM_COMMAND  (see  below) message if
            the user  selects the  child window. This is also a sort of
            identifier for the child window.

          * The  hInstance  parameter  just  gets the  value given by the
            GetModuleHandleA API, the Application handle.

          * You can assign a value to  lpParam  that will be given to the
            window  procedure  at  the  WM_CREATE  as  the  lparam ( this
            correspond to  the address of a special structure). It can be
            used for MDI  windows but i don't know how and what it is  so
            I put zero in for the moment (I will try it in the future)

      Once  you  have  pushed  all  the  values you wanted in the correct
      order, simply call the CreateWindowExA API.

      Before displaying  the new window,  Windows will send three message
      to the Window procedure : WM_CREATE, WM_NCCALCSIZE, WM_NCCREATE.

      Once The creation finished,  Windows gives you the handle  and puts
      in eax.  This is the  created  window  handle that  can be used  as
      parent handle if  creating child  windows.  This window  handle can
      be used for interaction on the created window or child window.

    2.2.The Window procedure :
    --------------------------

      This procedure is called every time something happens to the window.
      When  entering the procedure, Windows has put some parameter on the
      stack. To Access them simply define your procedure as follows :

        YourProcName PROC uses ebx edi esi, HWnd:DWORD, WMsg:DWORD,
                                            WParam:DWORD, LParam:DWORD

      We have to save on the stack ebx,edi and esi because  windows  does
      not save them.

      Windows give us four parameters which are all dword :

        - hwnd : the handle of the window calling the procedure.

        - wmsg : the window message

        - wparam : a dependent the case parameter

        - lparam : a dependent  the case  parameter too (often pointing a
                   structure)

      TASM  provide you an easy access  by adjusting  the correct address
      with the BP register  (load at beginning the  SP register to BP and
      then do the famous [BP],[BP+4],... addressing for  us). If  we want
      to access them we simply type :

        mov  eax,[hwnd]    or    push  [wparam]  , ...

      This has a consequence : if modifying the BP register, then do it
      with some precautions (or u will get fatal error while running) !

      When  we want to give  back the hand to  Windows, simply put a ret.

      Once we finished the whole procedure it has to be terminated with :

        YourProcName ENDP

      Now I'll try to explain to you a bit about the parameters :

        * First the HWnd. It's a window handle, and the handle belongs to
          the  calling window.  For example  if two  window are using the
          same class, they use the same Window  procedure. So this handle
          describe the calling window. It can be used as a replacement of
          the application  handle, because  you often  want to modify the
          calling  window, and  not all of the  application. This  handle
          corresponds to the  handle given back after the CreateWindowExA
          (has to be verified, it's a supposition).

        * Then the  WParam and  LParam.  As said before  these parameters 
          depend on the current window message  in the WMsg. So there  is  
          nothing  to  say  but  that the WParam is often  a simple value 
          and that  the  LParam most  of the  time points  to  a  special
          structure.

        * And to finish the WMsg. This parameter contains the main value.
          This says to  the procedure  what happens. For easier access to
          the value, windows programmers give them names.

          All the message name begin with WM_...

          OK now the full list (some of them are explained below the list) :

            WM_NULL                         EQU  0000h
            WM_CREATE                       EQU  0001h
            WM_DESTROY                      EQU  0002h
            WM_MOVE                         EQU  0003h
            WM_SIZE                         EQU  0005h
            WM_ACTIVATE                     EQU  0006h
            WM_SETFOCUS                     EQU  0007h
            WM_KILLFOCUS                    EQU  0008h
            WM_ENABLE                       EQU  000Ah
            WM_SETREDRAW                    EQU  000Bh
            WM_SETTEXT                      EQU  000Ch
            WM_GETTEXT                      EQU  000Dh
            WM_GETTEXTLENGTH                EQU  000Eh
            WM_PAINT                        EQU  000Fh
            WM_CLOSE                        EQU  0010h
            WM_QUERYENDSESSION              EQU  0011h
            WM_QUIT                         EQU  0012h
            WM_QUERYOPEN                    EQU  0013h
            WM_ERASEBKGND                   EQU  0014h
            WM_SYSCOLORCHANGE               EQU  0015h
            WM_ENDSESSION                   EQU  0016h
            WM_SHOWWINDOW                   EQU  0018h
            WM_WININICHANGE                 EQU  001Ah
            WM_SETTINGCHANGE                EQU  001Ah
            WM_DEVMODECHANGE                EQU  001Bh
            WM_ACTIVATEAPP                  EQU  001Ch
            WM_FONTCHANGE                   EQU  001Dh
            WM_TIMECHANGE                   EQU  001Eh
            WM_CANCELMODE                   EQU  001Fh
            WM_SETCURSOR                    EQU  0020h
            WM_MOUSEACTIVATE                EQU  0021h
            WM_CHILDACTIVATE                EQU  0022h
            WM_QUEUESYNC                    EQU  0023h
            WM_GETMINMAXINFO                EQU  0024h
            WM_PAINTICON                    EQU  0026h
            WM_ICONERASEBKGND               EQU  0027h
            WM_NEXTDLGCTL                   EQU  0028h
            WM_SPOOLERSTATUS                EQU  002Ah
            WM_DRAWITEM                     EQU  002Bh
            WM_MEASUREITEM                  EQU  002Ch
            WM_DELETEITEM                   EQU  002Dh
            WM_VKEYTOITEM                   EQU  002Eh
            WM_CHARTOITEM                   EQU  002Fh
            WM_SETFONT                      EQU  0030h
            WM_GETFONT                      EQU  0031h
            WM_SETHOTKEY                    EQU  0032h
            WM_GETHOTKEY                    EQU  0033h
            WM_QUERYDRAGICON                EQU  0037h
            WM_COMPAREITEM                  EQU  0039h
            WM_GETOBJECT                    EQU  003Dh ; Only Win98 ?
                                                       ; Win version >= 500
            WM_COMPACTING                   EQU  0041h
            WM_COMMNOTIFY                   EQU  0044h ; no longer supported
            WM_WINDOWPOSCHANGING            EQU  0046h
            WM_WINDOWPOSCHANGED             EQU  0047h
            WM_POWER                        EQU  0048h
            WM_COPYDATA                     EQU  004Ah
            WM_CANCELJOURNAL                EQU  004Bh
            WM_NOTIFY                       EQU  004Eh
            WM_INPUTLANGCHANGEREQUEST       EQU  0050h
            WM_INPUTLANGCHANGE              EQU  0051h
            WM_TCARD                        EQU  0052h
            WM_HELP                         EQU  0053h
            WM_USERCHANGED                  EQU  0054h
            WM_NOTIFYFORMAT                 EQU  0055h
            WM_CONTEXTMENU                  EQU  007Bh
            WM_STYLECHANGING                EQU  007Ch
            WM_STYLECHANGED                 EQU  007Dh
            WM_DISPLAYCHANGE                EQU  007Eh
            WM_GETICON                      EQU  007Fh
            WM_SETICON                      EQU  0080h
            WM_NCCREATE                     EQU  0081h
            WM_NCDESTROY                    EQU  0082h
            WM_NCCALCSIZE                   EQU  0083h
            WM_NCHITTEST                    EQU  0084h
            WM_NCPAINT                      EQU  0085h
            WM_NCACTIVATE                   EQU  0086h
            WM_GETDLGCODE                   EQU  0087h
            WM_SYNCPAINT                    EQU  0088h
            WM_NCMOUSEMOVE                  EQU  00A0h
            WM_NCLBUTTONDOWN                EQU  00A1h
            WM_NCLBUTTONUP                  EQU  00A2h
            WM_NCLBUTTONDBLCLK              EQU  00A3h
            WM_NCRBUTTONDOWN                EQU  00A4h
            WM_NCRBUTTONUP                  EQU  00A5h
            WM_NCRBUTTONDBLCLK              EQU  00A6h
            WM_NCMBUTTONDOWN                EQU  00A7h
            WM_NCMBUTTONUP                  EQU  00A8h
            WM_NCMBUTTONDBLCLK              EQU  00A9h
            WM_KEYFIRST                     EQU  0100h
            WM_KEYDOWN                      EQU  0100h
            WM_KEYUP                        EQU  0101h
            WM_CHAR                         EQU  0102h
            WM_DEADCHAR                     EQU  0103h
            WM_SYSKEYDOWN                   EQU  0104h
            WM_SYSKEYUP                     EQU  0105h
            WM_SYSCHAR                      EQU  0106h
            WM_SYSDEADCHAR                  EQU  0107h
            WM_KEYLAST                      EQU  0108h
            WM_IME_STARTCOMPOSITION         EQU  010Dh
            WM_IME_ENDCOMPOSITION           EQU  010Eh
            WM_IME_COMPOSITION              EQU  010Fh
            WM_IME_KEYLAST                  EQU  010Fh
            WM_INITDIALOG                   EQU  0110h
            WM_COMMAND                      EQU  0111h
            WM_SYSCOMMAND                   EQU  0112h
            WM_TIMER                        EQU  0113h
            WM_HSCROLL                      EQU  0114h
            WM_VSCROLL                      EQU  0115h
            WM_INITMENU                     EQU  0116h
            WM_INITMENUPOPUP                EQU  0117h
            WM_MENUSELECT                   EQU  011Fh
            WM_MENUCHAR                     EQU  0120h
            WM_ENTERIDLE                    EQU  0121h
            WM_MENURBUTTONUP                EQU  0122h ; Only Win98 ?
                                                       ; Win version >= 500
            WM_MENUDRAG                     EQU  0123h ; Only Win98 ?
                                                       ; Win version >= 500
            WM_MENUGETOBJECT                EQU  0124h ; Only Win98 ?
                                                       ; Win version >= 500
            WM_UNINITMENUPOPUP              EQU  0125h ; Only Win98 ?
                                                       ; Win version >= 500
            WM_MENUCOMMAND                  EQU  0126h ; Only Win98 ?
                                                       ; Win version >= 500
            WM_CTLCOLORMSGBOX               EQU  0132h
            WM_CTLCOLOREDIT                 EQU  0133h
            WM_CTLCOLORLISTBOX              EQU  0134h
            WM_CTLCOLORBTN                  EQU  0135h
            WM_CTLCOLORDLG                  EQU  0136h
            WM_CTLCOLORSCROLLBAR            EQU  0137h
            WM_CTLCOLORSTATIC               EQU  0138h
            WM_MOUSEFIRST                   EQU  0200h
            WM_MOUSEMOVE                    EQU  0200h
            WM_LBUTTONDOWN                  EQU  0201h
            WM_LBUTTONUP                    EQU  0202h
            WM_LBUTTONDBLCLK                EQU  0203h
            WM_RBUTTONDOWN                  EQU  0204h
            WM_RBUTTONUP                    EQU  0205h
            WM_RBUTTONDBLCLK                EQU  0206h
            WM_MBUTTONDOWN                  EQU  0207h
            WM_MBUTTONUP                    EQU  0208h
            WM_MBUTTONDBLCLK                EQU  0209h
            WM_PARENTNOTIFY                 EQU  0210h
            WM_ENTERMENULOOP                EQU  0211h
            WM_EXITMENULOOP                 EQU  0212h
            WM_NEXTMENU                     EQU  0213h
            WM_SIZING                       EQU  0214h
            WM_CAPTURECHANGED               EQU  0215h
            WM_MOVING                       EQU  0216h
            WM_POWERBROADCAST  >

Transfer interrupted!

M_DEVICECHANGE EQU 0219h WM_MDICREATE EQU 0220h WM_MDIDESTROY EQU 0221h WM_MDIACTIVATE EQU 0222h WM_MDIRESTORE EQU 0223h WM_MDINEXT EQU 0224h WM_MDIMAXIMIZE EQU 0225h WM_MDITILE EQU 0226h WM_MDICASCADE EQU 0227h WM_MDIICONARRANGE EQU 0228h WM_MDIGETACTIVE EQU 0229h WM_MDISETMENU EQU 0230h WM_ENTERSIZEMOVE EQU 0231h WM_EXITSIZEMOVE EQU 0232h WM_DROPFILES EQU 0233h WM_MDIREFRESHMENU EQU 0234h WM_IME_SETCONTEXT EQU 0281h WM_IME_NOTIFY EQU 0282h WM_IME_CONTROL EQU 0283h WM_IME_COMPOSITIONFULL EQU 0284h WM_IME_SELECT EQU 0285h WM_IME_CHAR EQU 0286h WM_IME_REQUEST EQU 0288h ; Only Win98 ? ; Win version >= 500 WM_IME_KEYDOWN EQU 0290h WM_IME_KEYUP EQU 0291h WM_CUT EQU 0300h WM_COPY EQU 0301h WM_PASTE EQU 0302h WM_CLEAR EQU 0303h WM_UNDO EQU 0304h WM_RENDERFORMAT EQU 0305h WM_RENDERALLFORMATS EQU 0306h WM_DESTROYCLIPBOARD EQU 0307h WM_DRAWCLIPBOARD EQU 0308h WM_PAINTCLIPBOARD EQU 0309h WM_VSCROLLCLIPBOARD EQU 030Ah WM_SIZECLIPBOARD EQU 030Bh WM_ASKCBFORMATNAME EQU 030Ch WM_CHANGECBCHAIN EQU 030Dh WM_HSCROLLCLIPBOARD EQU 030Eh WM_QUERYNEWPALETTE EQU 030Fh WM_PALETTEISCHANGING EQU 0310h WM_PALETTECHANGED EQU 0311h WM_HOTKEY EQU 0312h WM_PRINT EQU 0317h WM_PRINTCLIENT EQU 0318h WM_HANDHELDFIRST EQU 0358h WM_HANDHELDLAST EQU 035Fh WM_AFXFIRST EQU 0360h WM_AFXLAST EQU 037Fh WM_PENWINFIRST EQU 0380h WM_PENWINLAST EQU 038Fh WM_APP EQU 8000h All window message after 0400h are reserved so i have no docs on them. Ok, here are all the message values. But you don't need to fully support all these windows messages. You will only have to support those you want to use. If you don't support all window message (did you ? :)) you can call the default message processing of window : DefWindowProcA and this with all your parameters and it will support the ones that are unsupported by your code. I gave all the name, but I won't have time to explain them all and so refer to the famous Win32 programmer's reference Help file ! Some explanations on some of them : * WM_CREATE : this message is the first message this procedure will get. It is sent by windows just before the window is created. It can be used to initialize some value, define multiple things... LParam points to a structure containing the information on the created window. * WM_DESTROY : this message is sent when the user close the window : keyboard shortcut ( ALT-F4 ), the close button in the titlebar or the close option in the system menu. * WM_MOVE : The user has moved the window and finishes the move. LParam contains the new window position : in the low word the abscissa, and in the high word the ordinate. * WM_MOVING : The user is moving the window (window position is changing). LParam points to a rectangle (Left, Top, Right, Bottom) structure containing the window coordinates. * WM_SIZE : The user has finished resizing the window. * WM_SIZING : The user is resizing the window. * WM_PAINT : called when a window has to be repainted. If you want to draw something this must contain the BeginPaint and EndPaint APIs for initializing all the data contained in the PAINT structure. (Wait for a next lesson...) * WM_COMMAND : The user chose an element : a menu, a button, a window control,... The chosen element identification code is in WParam. This not include the title bar elements ! * WM_SYSCOMMAND : The user chose an element of the system menu. The element identification code is in WParam 2.3.Communication between the application and the window procedure : -------------------------------------------------------------------- Once you have finished creating a window, there is a way to communicate between the Window procedure and the main application. For example : The user clicked the close button in the title bar. The window procedure will get the WM_DESTROY message. But on the other hand nothing prevents the app that the user closed the application. The " official" way to do this is by calling in the window procedure the PostQuitMessageA. On the other side, the main application continues calling with no end the GetMessageA API and if the quit message was posted the value in eax is null and then you can jump to your ending code. But if the value in eax was not legal to zero, you have to call the TranslateMessage and then the DispatchMessage. An other way to send a message is using the PostThreadMessageA. This section is really poor because i didn't test too much the communication between the window procedure and the main application. But if you have some info on it, contact me (see at the end how to) ! 3.Others indications : ---------------------- If creating a window, don't forget one of the following styles: WS_NORMAL, WS_MINIMIZED or WS_MAXIMIZED. Because your window won't be displayed. An other way to select the way you display your window is using the API ShowWindow with one of the following parameters in the show state : SW_HIDE EQU 0 HIDE_WINDOW EQU 0 SW_SHOWNORMAL EQU 1 SW_NORMAL EQU 1 SHOW_OPENWINDOW EQU 1 SW_SHOWMINIMIZED EQU 2 SHOW_ICONWINDOW EQU 2 SW_SHOWMAXIMIZED EQU 3 SW_MAXIMIZE EQU 3 SHOW_FULLSCREEN EQU 3 SW_SHOWNOACTIVATE EQU 4 SHOW_OPENNOACTIVATE EQU 4 SW_SHOW EQU 5 SW_MINIMIZE EQU 6 SW_SHOWMINNOACTIVE EQU 7 SW_SHOWNA EQU 8 SW_RESTORE EQU 9 SW_SHOWDEFAULT EQU 10 SW_FORCEMINIMIZE EQU 11 SW_MAX EQU 11 4.The .ASM file : ----------------- ;--- Start of TUT_02.ASM -->8 .386 locals jumps .model flat,STDCALL ; All called APIs defined as being an external procedure extrn CreateWindowExA:Proc extrn DefWindowProcA:Proc extrn DispatchMessageA:Proc extrn ExitProcess:Proc extrn GetMessageA:Proc extrn GetModuleHandleA:Proc extrn LoadCursorA:Proc extrn LoadIconA:Proc extrn MessageBoxA:Proc extrn PostQuitMessage:Proc extrn RegisterClassA:Proc extrn TranslateMessage:Proc ; All Special value used ; The Class Style CS_VREDRAW EQU 0001h CS_HREDRAW EQU 0002h CS_GLOBALCLASS EQU 4000h ; The Background Brush Color COLOR_WINDOW EQU 5 ; The default size for the window CW_USEDEFAULT EQU 8000h ; The Used Window Style WS_OVERLAPPED EQU 000000000h WS_MAXIMIZEBOX EQU 000010000h WS_MINIMIZEBOX EQU 000020000h WS_THICKFRAME EQU 000040000h WS_SYSMENU EQU 000080000h WS_DLGFRAME EQU 000400000h WS_BORDER EQU 000800000h WS_CAPTION EQU 000C00000h ; WS_BORDER | WS_DLGFRAME WS_VISIBLE EQU 010000000h WS_OVERLAPPEDWINDOW EQU WS_OVERLAPPED OR WS_CAPTION OR WS_SYSMENU OR WS_THICKFRAME OR WS_MINIMIZEBOX OR WS_MAXIMIZEBOX OR WS_VISIBLE ; The support Window Message in the window procedure WM_LBUTTONDOWN EQU 0201h ; Left Mouse Boutton down in the Client ; Area of window WM_DESTROY EQU 0002h ; the minimum needed i think (most important) ; We define all the used structures : ; the class structure WNDCLASS struc clsStyle dd ? ; class style clsLpfnWndProc dd ? clsCbClsExtra dd ? clsCbWndExtra dd ? clsHInstance dd ? ; instance handle clsHIcon dd ? ; class icon handle clsHCursor dd ? ; class cursor handle clsHbrBackground dd ? ; class background brush clsLpszMenuName dd ? ; menu name clsLpszClassName dd ? ; far ptr to class name WNDCLASS ends ; the point structure used in the message structure POINT struc ptX dd ? ptY dd ? POINT ends ; the message structure (badly defined in the windows.inc of tasm) MSGSTRUCT struc msHWND dd ? msMESSAGE dd ? msWPARAM dd ? msLPARAM dd ? msTIME dd ? msPT POINT MSGSTRUCT ends ; now the data .data ; declare a class structure wc WNDCLASS ; declare a message structure msg MSGSTRUCT ; The main application handle. AppHWnd dd 0 ; The created window handle. NewHWnd dd 0 ; the created class name WndClassName db "ASMClass",0 ; the created window title WindowCaption db "Lesson 2",0 ; the msg box title (got when clicking in the client area) MsgBoxCaption db "Lesson 2",0 ; the msg box content. MsgBoxContent db "You clicked in the Client area of the window",0 ; now the code .code Start: ; Get the application handle push 0h call GetModuleHandleA ; get the application handle mov [AppHWnd],eax ; and store it ; we fill the class structure mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS ; class style mov [wc.clsLpfnWndProc], offset WndProc ; the window procedure mov [wc.clsCbClsExtra], 0 ; ? mov [wc.clsCbWndExtra], 0 ; ? mov eax, [AppHWnd] mov [wc.clsHInstance], eax ; the application handle push 32516 ; icon resource identifier push 0 ; where from to load (system) call LoadIconA ; load icon mov [wc.clsHIcon], eax ; store the geted handle push 32512 ; cursor resource identifier push 0 ; where from to load (system) call LoadCursorA ; Load cursor mov [wc.clsHCursor], eax ; store the geted handle mov [wc.clsHbrBackground], COLOR_WINDOW + 1 ; background color mov dword ptr [wc.clsLpszMenuName], 0 ; no menu mov dword ptr [wc.clsLpszClassName], offset WndClassName ; new created class name ; register the filled class push offset wc ; offset of filled class call RegisterClassA ; register it ! ; create the window push 0 ; lpParam push [AppHWnd] ; hInstance push 0 ; menu push 0 ; parent hwnd push CW_USEDEFAULT ; height push CW_USEDEFAULT ; width push CW_USEDEFAULT ; y push CW_USEDEFAULT ; x push WS_OVERLAPPEDWINDOW ; Style push offset WindowCaption ; Title string push offset WndClassName ; Class name push 0 ; extra style call CreateWindowExA ; create the window ! mov [NewHWnd], eax ; save the window handle ; (for future) ; now the message loop : does nothing, only wait on the quit message ; of the window procedure msg_loop: ; get the message push 0 push 0 push 0 push offset msg call GetMessageA ; if zero then quit message posted cmp ax, 0 je end_loop ; else continue the loop push offset msg call TranslateMessage push offset msg call DispatchMessageA jmp msg_loop ; OK now the message was posted end_loop: ; exit and close the application. push 0h call ExitProcess ; here the window procedure. WndProc PROC uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD cmp [wmsg], WM_DESTROY ; user want to quit ? je wmdestroy cmp [wmsg], WM_LBUTTONDOWN ; user clicked within the ; client area ? je wmlbuttondown push [lparam] push [wparam] push [wmsg] push [hwnd] call DefWindowProcA ; no, then call the default processing xor eax,eax ret ; and give the hand back wmdestroy: ; user want to quit ! push 0 ; wanted exit code (stored in the msg ; structure) call PostQuitMessage ; post quit message to main application xor eax,eax ret ; give the hand back wmlbuttondown: ; user clicked in the client area push 20h push offset MsgBoxCaption push offset MsgBoxContent push [NewHWnd] call MessageBoxA ; display the dialog box (see tut 1) xor eax,eax ret ; give hand back WndProc endp End Start ;8<- EOF TUT_01.ASM --- 5.The .DEF file : ----------------- ;--- Start of TUT_02.DEF -->8 NAME TUT_02 DESCRIPTION 'ASM program' EXETYPE WINDOWS CODE PRELOAD MOVEABLE DATA PRELOAD MOVEABLE MULTIPLE ;8<- EOF TUT_02.DEF --- 6.The makefile file : --------------------- ;--- Start of MakeFile -->8 # make -B Will build .EXE # make -B -DDEBUG Will build the debug version. NAME = TUT_02 OBJS = $(NAME).obj DEF = $(NAME).def !if $d(DEBUG) TASMDEBUG=/zi LINKDEBUG=/v !else TASMDEBUG= LINKDEBUG= !endif !if $d(MAKEDIR) IMPORT=$(MAKEDIR)\..\lib\import32 !else IMPORT=import32 !endif $(NAME).EXE: $(OBJS) $(DEF) tlink32 /Tpe /aa /c $(LINKDEBUG) $(OBJS),$(NAME),, $(IMPORT), $(DEF) .asm.obj: tasm32 $(TASMDEBUG) /ml /m2 $&.asm ;8<- EOF MakeFile --- 7.The Greetz And Some Info : ----------------------------- _Masta_ : Continues your tut they are useful ! To all Win32asm men : See you soon ! :) Message to Nemrod : (Scoobidoo) where are you ? To contact myself : - try the Sunday afternoon on #Win32asm on EFNET. (around 16 hours (GMT+1)) - or try my E-mail : kinher@infonie.fr Next lessons : 3. The Window components ! 4. Dialog Boxes ! All my lessons are released at first at : http://perso.infonie.fr/kinher As you can notice, my english is really bad, so i'm searching somebody to correct the tuts ! :) (and you get the tuts before anybody !)