--------------------------------------------------------------------------- ----------------------------------------------------------------------- - 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 !)