News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Easy Code tutorials

Started by rsala, July 31, 2012, 06:10:22 AM

Previous topic - Next topic

rsala

In this section there will be Easy Code small and dedicated tutorials, specially oriented to visual projects and MASM32 SDK, for you to easily learn how to program applications with this IDE.

Enjoy Easy Code!

Ramon
EC coder

rsala

#1
Basic knowledge

The Easy Code visual project mode makes easy to build an application. However, in order to avoid problems, you have to know some basic principles:

Each Window, MDIWindow or DialogBox object created in a project is called an Owner window since it will contain (own) all child controls. The window procedure for any "owner window" must exist and it has to be named with its own name plus the word Procedure (all case sensitive). Also, it must have the four parameters for a window proceure. For example, for a window object named Window1, its procedure name will be Window1Proceure and will look like this:

Masm version:
    Window1Procedure Proc hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
        .If uMsg == WM_CREATE
            ;Initial code
        .ElseIf uMsg == WM_CLOSE
            ;Final code
            Invoke IsModal, hWnd
            .If Eax
                Invoke EndModal, hWnd, IDCANCEL
                Mov Eax, TRUE    ;Return TRUE
                Ret
            .EndIf
        .EndIf
        Xor Eax, Eax    ;Return FALSE
        Ret
    Window1Procedure EndP


GoAsm version:
    Window1Procedure Frame hWnd, uMsg, wParam, lParam
        Cmp D[uMsg], WM_CREATE
        Jne >
        ;Inital code
        Jmp > L2

:       Cmp D[uMsg], WM_CLOSE
        Jne > L2
        ;Final code
        Invoke IsModal, hWnd
        Or Eax, Eax
        Jz > L2
        Invoke EndModal, hWnd, IDCANCEL
        Mov Eax, TRUE    ;Return TRUE
        Ret

L2:     Xor Eax, Eax    ;Return FALSE
        Ret
    EndF


As you can see the window procedure always return TRUE or FALSE. When returning TRUE (any other value than 0), no further message processing will be performed and a cycle is complete. When returning FALSE, it will mean that the default window procedure will be called. This is the reason why the default return value, at the end of the procedure, is always FALSE. All messages you do not process, are processed by the default window procedure, which is part of the Windows API, in order to avoid undesirable results. So do not change the default return value FALSE. Also, when you process a message and you do not want further processing for it, return TRUE, but just for those messages you already processed. For example, after calling the EndModal method, you must return TRUE because the window is already destroyed (it does not exist) and returning FALSE would generate errors (the application would probably crash).

When a project has more than a window, one of them has to be the Main window, that is, the window being shown when the application starts (also called the StartUp window). The main window can be set in the Project properties. All other existing windows can be created at run time with the Create method. For example, to create a window named Settings, we will do the following:

Invoke Create, TextAddr("Settings"), hWndParent, lMode, lParam

The hWndParent parameter is a HWND (DWord) value with the handle to the window being the parent. This value can be NULL (except for MDI child windows) if the created window is going to have no parent. The lMode parameter is a LONG (DWord) value specifying how the window is to be shown, modal or modeless. Finally, the lParam parameter is the LPARAM (DWord) value passed to a dialog box in the lParam parameter of the WM_INITDIALOG message. This value is only for DialogBox objects, modal or not, and it may be NULL if not needed (it has no effect for Window objects).

Child controls may also have its own window procedure although it is not usually needed. The name for a child control window procedure must be "the owner window name plus the control name". For example, the window procedure name for a button named Button1 being inside a window named Window1, will be Window1Button1 and will look like this:

Masm version:
    Window1Button1 Proc hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM

        Xor Eax, Eax    ;Return FALSE
        Ret
    Window1Button1 EndP


GoAsm version:
    Window1Button1 Frame hWnd, uMsg, wParam, lParam

        Xor Eax, Eax    ;Return FALSE
        Ret
    EndF


As said for window objects procedures, the default return value must be FALSE and must not be changed. However, window procedures for child controls are often not used as it is enough to process the WM_COMMAND and WM_NOTIFY received by their owner window. So, unless you are going to process some message (i.e. WM_RBUTTONDOWN), you can delete the corresponding window procedure (that will save some bytes in the final executable file).

For more information, please see the "Visual Projects (Easy Code Power Mode)" topic in the Easy Code help file.

See you!


EC coder

rsala

#2
Getting child controls handle

At run time, all child controls you added in each window object are already created and ready to use when receiving the WM_CREATE message of the window they belong to, that is, the owner window (no children yet in the WM_NCCREATE message). Each child control has an identifier or ID, with its corresponding constant name (upper case). To refer to any control using this constant, you should take into account a simple rule. The constant name is all upper case and is formed by IDC_ plus the name of the owner window, plus _ plus the control object name. For example, the ID constant name for a Button control named Button1, being inside a window named ChildID, will be:

IDC_CHILDID_BUTTON1

With this ID you can easily get the corresponding handle by using the Easy Code GetWindowItem method, which returns the handle in register Eax:

Invoke GetWindowItem, hWnd, IDC_CHILDID_BUTTON1

This method requires two parameters, a handle and the control ID. The handle (hWnd) can be  the one to the "owner window" (mostly used) or the handle to any other control inside the window.

To demonstrate all said above, I attached a file with a simple project showing how to get the handle for a child control using its control ID. The handle for a control is useful (and necessary) in many operations.

Enjoy it!
EC coder

rsala

Raw data and files

The Easy Code resource editor has been made to allow the user to create all kind of resources and, at the same time, make it as easy as possible, but being limited for the syntax of the resource compiler (RC.EXE). As a result, you can add accelerators, menus, images (icon, cursor or bitmap), strings, a version resource and Raw Data.

A raw data resource permits the inclusion of binary data directly in the executable file and it specifies one or more integers or strings of characters. Integers can be specified in decimal, octal or hexadecimal format. RC compiler does not automatically append a terminating null character to a string. The string is a sequence of the specified ANSI (byte) characters unless explicitly qualified as a wide-character string with the L prefix (Unicode).

The block of data begins on a DWord boundary and RC performs no padding or alignment of data within the raw-data block. It is the programmer's responsibility to ensure the proper alignment of data within the block.

The following are some examples of raw data:

10,20,30,40                     Four integer (16-bit) values.
"A","B","C","D"               Four byte (8-bit) values.
"Readme.txt\0"              Double-quoted text to specify it is a string (null-terminated).

L"Readme.txt\0"            Unicode null-terminated string (L means Unicode, otherwise it is ANSI)
"\r"                                   A control character (8-bit) correspondig to ASCII 13 (<Carriage Return>).
0x40                                 A Hex integer (16-bit) value corresponding to 64 decimal.


This raw data has to be typed exactly the same in the Easy Code Raw Data resources window so that RC does not generate any error at compile time. In fact, raw data resources are usually used for binary data or, eventually, for ANSI strings, as strings defined in a String table are always Unicode.

In some cases, it would be interesting to add a whole file as a resource. As the RC compiler has no way to do that, Easy Code has a user-defined resource to accomplish this task. User-defined resources must have a value greater than 255, so Easy Code has the RT_FILEDATA reserved word (value 256). In the resource editor, adding a file is done in the Raw Data resources window. So, how does Easy Code know if it is raw data or a file name? It just looks in the Res folder for a file having the typed name. If it exists, an RT_FILEDATA resource will be created. To find it at run time, you will have to specify RT_FILEDATA in the 'ResourceType' parameter of the FindResource function. On the other hand, if there is no file in Res folder having the typed name, a normal RCDATA resource will be created and it will be found as RCDATA type.

Note that a file name could be treated as normal raw data if the file it specifies is not found in Res folder, but if it was entered without double quotes, the RC compiler will generate an error. On the other hand, if the file name is double-quoted, it will be treated as a Raw data string (RCDATA type).

Ramon
EC coder

rsala

Custom control

The Easy Code visual mode always subclasses all child controls in the project, so it is easy to develop a custom control by processing messages in the control procedure. The default return value in the control procedure must be always FALSE, so that all messages you do not process are being sent to the Windows default control procedure. On the other hand, for those messages you process and you do not want to be overwritten by the Windows default control procedure the return value must be TRUE. However, if you do not want a child control to be subclassed, just delete all its control procedure.

Attached are two liitle examples of a custom control (both, 32-bit and 64-bit). The attached examples has been compiled with UASM32 (32-bit version) and UASM64 (64-bit version), so you should have the latest version of EC v2 (released on June 26, 2017) and your UAsm.cfg and UAsm64.cfg files wll configured. Anyway, they will also compile fine with JWASM and/or ASMC.

BE CAREFUL: Your application may crash if the control procedure returns always TRUE.

Enjoy it!

Ramon
EC coder