flat assembler
Message board for the users of flat assembler.

Index > Tutorials and Examples > Rebar control usage example.

Author
Thread Post new topic Reply to topic
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 06 Apr 2013, 23:10
I'd like to present here a simple program written with FASM presenting how to create a rebar control that has three bands: one with a simple toolbar and two bands with edit controls. The application user may test the rebar control rearrangement using drag&drop technique.

The application shows also how to manage the 'WM_GETMINMAXINFO' message in order to determine the application window minimal width and height.

Image

http://www.youtube.com/watch?v=6nDisCzikXE

Here you may take a look at the program code:
Code:
;
; A simple program written with FASM that shows how to create a rebar control
; that contains a toolbar and two edit controls inside its bands.
;
; The application is resizable, so every user may test the flexibility of the
; rebar control, rearrange the bands configuration and observe how the
; 'WM_GETMINMAXINFO' message is managed to determine the application window
; minimal width and height.
;
; (C) Mikolaj Hajduk, 06.04.2013.
;
format PE GUI 4.0

entry start


; Include a header file containing necessary macros.
;
include 'win32wx.inc'

; Use UTF-8 encoding if you want to have your strings displayed always the same
; way despite of local settings of the user system and if your application has to
; be multilingual.
;
include 'ENCODING\utf8.inc'

; A definition of the constant describing the program version (encoded date of
; the last changes).
;
PROG_VERSION equ '2013.04.06.0'

; Constants used to determine the application window minimal width and height.
;
WND_MIN_WIDTH   = 400
WND_MIN_HEIGHT  = 300

; An identifier of a bitmap used by the application toolbar as a container for
; icons displayed on the toolbar buttons.
;
IDTB_BITMAP     = 101

; Identifiers of controls placed inside the rebar control.
;
ID_ADDRESS1     = 201
ID_ADDRESS2     = 202
ID_TOOLBAR      = 203

; Identifiers of the toolbar buttons.
;
TB_OPEN         = 501
TB_SAVE         = 502
TB_EXIT         = 503

; The width and height (in pixels) of each icon displayed on the toolbar button.
;
BITMAP_SIZE     = 16

; Numbers used to determine which of the icons stored in the bitmap should be
; displayed on the given button.
;
OPEN_IMG        = 13
SAVE_IMG        = 9
CLOSE_IMG       = 2

; A definition of a structure containing information used to handle the
; 'TTN_GETDISPINFO' notification (needed to display a tooltip window associated
; with a given toolbar button).
;
struct  NMTTDISPINFOW
        hdr             NMHDR
        lpszText        dd ?
        szText          rw 80
        hInst           dd ?
        uFlags          dd ?
        lParam          dd ?
ends


; The data section.
;
section '.data' data readable writeable

        hRebar          dd 0    ; The handle of the rebar control.

        hToolbar        dd 0    ; The handle of the toolbar.

        hImageList      dd 0    ; The handle of an image list i.e. a collection
                                ; of images of the same size, each of which is
                                ; identified by its index. All images are hold in
                                ; one wide bitmap attached to the application as
                                ; a resource.

        hEdit1          dd 0    ; The handles of edit controls placed inside the
        hEdit2          dd 0    ; rebar control bands.

        hFont           dd 0    ; The handle of the font used to display strings
                                ; inside window controls.

        ; The name of the application window class.
        ;
        ClassName       du "RebarExample", 0

        ; A string displayed in the application window title bar.
        ;
        WindowCaption   du "Rebar example, v.", PROG_VERSION, 0

        ; An instance of the WNDCLASSEX structure containing information about
        ; the application window class.
        ;
        wc              WNDCLASSEX      sizeof.WNDCLASSEX, 0, WindowProc, 0, 0,\
                                        NULL, NULL, NULL,\
                                        \
                                        COLOR_BTNFACE + 1,\     ; The color value used for painting the
                                        \                       ; background (or a handle to the class
                                        \                       ; background brush). If it is a color value
                                        \                       ; then it must be one of the standard system
                                        \                       ; colors plus 1.
                                        \
                                        NULL, ClassName, NULL

        ; An instance of the MSG structure used to store information about
        ; messages from the thread message queue.
        ;
        msg             MSG

        ; The name of the used font. 'Tahoma' is the proper choice for applications
        ; that display strings denoted in the scripts other than Latin (supports
        ; most Unicode chars).
        ;
        FontName        du 'Tahoma', 0

        align 4

        ; An array of the 'TBUTTON' structure instances. Each of the instances contains information
        ; about a corresponding toolbar button.
        ;
        ;                       Zero-based              Command id      Button state            Button style.
        ;                       button image            associated      flags.
        ;                       index.                  with the
        ;                                               button.
        ;                       -------------------------------------------------------------------------------
        tb      TBBUTTON        OPEN_IMG,               TB_OPEN,        TBSTATE_ENABLED,        TBSTYLE_BUTTON
                TBBUTTON        SAVE_IMG,               TB_SAVE,        TBSTATE_ENABLED,        TBSTYLE_BUTTON
                TBBUTTON        0,                      0,              TBSTATE_ENABLED,        TBSTYLE_SEP
                TBBUTTON        CLOSE_IMG,              TB_EXIT,        TBSTATE_ENABLED,        TBSTYLE_BUTTON


        ; A calculated number of the buttons contained in the toolbar.
        ;
        TB_NROFBUTTONS  = ($ - tb) / sizeof.TBBUTTON

        ; Strings displayed in the tooltips associated with the toolbar buttons.
        ;
        TipOpen         du "Open File", 0
        TipSave         du "Save File", 0
        TipExit         du "Exit Application", 0

        ; A string containing the name of the edit control class.
        ;
        EDIT            du "EDIT", 0

        ; An instance of the structure carrying information used to load common
        ; control classes.
        ;
        icex            INITCOMMONCONTROLSEX    sizeof.INITCOMMONCONTROLSEX,\
                                                ICC_COOL_CLASSES + ICC_BAR_CLASSES

        ; An instance of the 'REBARBANDINFO' structure used to store information
        ; about particular bands in the rebar control. Some of the structure fields
        ; may be filled already at the compilation stage as invariant and common for
        ; all bands. Others have to be defined at the execution time.
        ;
        rbBand          REBARBANDINFO           sizeof.REBARBANDINFO,\
                                                \
                                                RBBIM_STYLE + RBBIM_CHILD +\            ; Flags indicating which
                                                RBBIM_CHILDSIZE + RBBIM_SIZE,\          ; structure members are
                                                \                                       ; valid and must be filled.
                                                \
                                                RBBS_CHILDEDGE + RBBS_GRIPPERALWAYS     ; Flags that specify the
                                                                                        ; band style.


; The code section.
;
section '.code' code readable executable

        start:
                ; Ensure that the common control DLL (Comctl32.dll) is loaded
                ; and register chosen common control classes.
                ;
                invoke  InitCommonControlsEx, icex

                stdcall ErrorRoutine, exit

                ; Retrieve a handle of the application file.
                ;
                invoke  GetModuleHandle, 0

                stdcall ErrorRoutine, exit

                mov     [wc.hInstance], eax

                ; As an application icon use one of the predefined icons.
                ;
                invoke  LoadIcon, 0, IDI_APPLICATION

                stdcall ErrorRoutine, exit

                mov     [wc.hIcon], eax

                ; A cursor associated with the application is a standard, arrow
                ; shaped one.
                ;
                invoke  LoadCursor, 0, IDC_ARROW

                stdcall ErrorRoutine, exit

                mov     [wc.hCursor], eax

                ; Registering the application window class in the system.
                ;
                invoke  RegisterClassEx, wc

                stdcall ErrorRoutine16, exit

                ; Create the main application window.
                ;
                invoke  CreateWindowEx, 0, ClassName, WindowCaption, WS_VISIBLE + WS_OVERLAPPEDWINDOW,\
                                CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, [wc.hInstance], NULL

                stdcall ErrorRoutine, exit

        ; A loop where all messages referring to the application window have been
        ; processed.
        ;
        msg_loop:
                ; Retrieve a message from the application message queue.
                ;
                invoke  GetMessage, msg, NULL, 0, 0

                ; Exit when the 'WM_QUIT' message has been retrieved.
                ;
                test    eax, eax
                jz      exit

                ; Display a proper error message when something has gone wrong
                ; (eax = -1).
                ;
                inc     eax

                stdcall ErrorRoutine, exit

                ; Translate virtual-key strokes into character messages.
                ;
                invoke  TranslateMessage, msg

                ; Dispatch the retrieved message to the window procedure.
                ;
                invoke  DispatchMessage, msg
                jmp     msg_loop

        ; Quit the application.
        ;
        exit:
                invoke  ExitProcess, [msg.wParam]

        ; The error handling routine that organizes the program flow when any of
        ; API functions returns zero value.
        ;
        ErrorRoutine16:
                ; Zeroize bits of the eax register from the 16th to the 31st one.
                ; Done to assure that the eax register won't contain any "garbage"
                ; after calling API functions returning 16-bit result.
                ;
                and     eax, 0xFFFF

        ErrorRoutine:
                ; Check value stored in the eax register. If it's nonzero then
                ; return to the address following the place the error procedure
                ; has been called.
                ;
                test    eax, eax
                jz      @f

                retn    4

                ; Check value of the last error that has occurred.
                ;
                @@:
                invoke  GetLastError
                test    eax, eax
                jnz     @f

                ; If there was no error, i.e. the 'GetLastError' function returned
                ; 'ERROR_SUCCESS', we return to the place when the 'ErrorRoutine'
                ; procedure was called and remove the 'ReturnTo' address stored on
                ; the stack before the procedure call.
                ;
                retn    4

                @@:
                ; If there was an error, we display a message box with a human readable
                ; description of the error, remove the address of the procedure caller
                ; and return to the 'ReturnTo' address.
                ;
                stdcall ShowLastError, NULL, eax

                add     esp, 4
                retn

        ; The main application window procedure. Here we specify how to react
        ; on the events occurring inside the window.
        ;
        proc WindowProc, hwnd, wmsg, wparam, lparam

                push    ebx

                ; Depending on the message type perform proper actions.
                ;
                cmp     [wmsg], WM_CREATE
                je      .wmcreate

                cmp     [wmsg], WM_COMMAND
                je      .wmcommand

                cmp     [wmsg], WM_NOTIFY
                je      .wmnotify

                cmp     [wmsg], WM_SIZE
                je      .wmsize

                cmp     [wmsg], WM_GETMINMAXINFO
                je      .wmgetminmaxinfo

                cmp     [wmsg], WM_DESTROY
                je      .wmdestroy

                ; Ensure that all messages not processed by the application
                ; window procedure will be processed by default window procedure.
                ;
                .defwndproc:
                        invoke  DefWindowProc, [hwnd], [wmsg], [wparam], [lparam]
                        jmp     .finish

                ; Operations performed when the application window is to be created.
                ;
                .wmcreate:

                        ; Create an instance of the 'Rebar' window class that
                        ; will be used as a container for the toolbar and two
                        ; edit controls.
                        ;
                        invoke  CreateWindowEx, WS_EX_TOOLWINDOW,\              ; The window will be used as
                                                \                               ; a floating toolbar.
                                                \
                                                REBAR_CLASS,\                   ; The rebar control class name.
                                                \
                                                NULL,\
                                                \
                                                WS_CHILD + WS_BORDER +\         ; Style of the created window:
                                                WS_VISIBLE +\                   ;
                                                \                               ;
                                                WS_CLIPSIBLINGS +\              ; clip all other overlapping rebar
                                                \                               ; child windows out of the region
                                                \                               ; of the updated child window,
                                                \                               ;
                                                WS_CLIPCHILDREN +\              ; exclude area of child windows
                                                \                               ; from the redraw when drawing occurs
                                                \                               ; within the parent window,
                                                \                               ;
                                                RBS_VARHEIGHT +\                ; display bands at the minimum required
                                                \                               ; height,
                                                \                               ;
                                                RBS_BANDBORDERS,\               ; display narrow lines to separate
                                                \                               ; adjacent bands.
                                                \
                                                0, 0, 0, 0,\
                                                [hwnd], NULL, [wc.hInstance], NULL

                        stdcall ErrorRoutine, .wmdestroy

                        mov     [hRebar], eax

                        ; Create the first edit control.
                        ;
                        invoke  CreateWindowEx, WS_EX_CLIENTEDGE, EDIT, NULL,\
                                WS_VISIBLE + WS_CHILD + ES_AUTOHSCROLL,\
                                0, 0, 0, 0, [hwnd], ID_ADDRESS1, [wc.hInstance], NULL

                        stdcall ErrorRoutine, .wmdestroy

                        mov     [hEdit1], eax

                        ; Create the second edit control.
                        ;
                        invoke  CreateWindowEx, WS_EX_CLIENTEDGE, EDIT, NULL,\
                                WS_VISIBLE + WS_CHILD + ES_AUTOHSCROLL,\
                                0, 0, 0, 0, [hwnd], ID_ADDRESS2, [wc.hInstance], NULL

                        stdcall ErrorRoutine, .wmdestroy

                        mov     [hEdit2], eax

                        ; Create the toolbar.
                        ;
                        invoke  CreateWindowEx, 0,\
                                                TOOLBAR_CLASS,\         ; The toolbar control class name.
                                                \
                                                NULL,\
                                                \
                                                WS_CHILD +\             ; Style of the created window:
                                                \                       ;
                                                TBSTYLE_FLAT +\         ; The toolbar and the buttons
                                                \                       ; have transparent background.
                                                \                       ;
                                                TBSTYLE_TOOLTIPS +\     ; Create a tooltip control used
                                                \                       ; to display descriptive text for
                                                \                       ; each of the toolbar buttons.
                                                \                       ;
                                                CCS_NORESIZE +\         ; Prevent the toolbar from using
                                                \                       ; the default width and height.
                                                \                       ; Use the width and height specified
                                                \                       ; in the request of creation or sizing.
                                                \                       ;
                                                CCS_NODIVIDER,\         ; Do not draw default two-pixel
                                                \                       ; highlight on the top of the control.
                                                \
                                                \
                                                0, 0, 0, 0,\
                                                [hwnd], NULL, [wc.hInstance], NULL

                        stdcall ErrorRoutine, .wmdestroy

                        mov     [hToolbar], eax

                        ; Send the message 'TB_BUTTONSTRUCTSIZE' to the toolbar in order to inform
                        ; about the size of the 'TBBUTTON' structure (that depends on the version
                        ; of the common control DLL library used in the program).
                        ;
                        invoke  SendMessage, [hToolbar], TB_BUTTONSTRUCTSIZE, sizeof.TBBUTTON, 0

                        ; Create an image list from the specified bitmap.
                        ;
                        invoke  ImageList_LoadImage, [wc.hInstance],\
                                                        IDTB_BITMAP,\           ; Identifier of the bitmap resource.
                                                        \
                                                        BITMAP_SIZE,\           ; The width of each image in the list.
                                                        \
                                                        16,\                    ; Number of images by which the list can
                                                        \                       ; grow when the system needs to make room
                                                        \                       ; for new images.
                                                        \
                                                        CLR_DEFAULT,\           ; The color used to generate mask (here
                                                        \                       ; the color of the upper-left pixel of
                                                        \                       ; the image becomes the mask color).
                                                        \
                                                        IMAGE_BITMAP,\          ; The type of image to load.
                                                        \
                                                        LR_CREATEDIBSECTION     ; Flags that specify the way the image
                                                                                ; is loaded.

                        stdcall ErrorRoutine, .wmdestroy

                        mov     [hImageList], eax

                        ; Set the image list used by the toolbar to display buttons.
                        ;
                        invoke  SendMessage, [hToolbar], TB_SETIMAGELIST, 0, [hImageList]

                        ; Set the distance from the left border (in pixels) for the first
                        ; image in the toolbar control.
                        ;
                        invoke  SendMessage, [hToolbar], TB_SETINDENT,\
                                                \
                                                8,\     ; Identation, in pixels.
                                                \
                                                0

                        stdcall ErrorRoutine, .wmdestroy


                        ; Add to the toolbar all buttons defined in the 'tb' array.
                        ;
                        invoke  SendMessage, [hToolbar], TB_ADDBUTTONS, TB_NROFBUTTONS, tb

                        stdcall ErrorRoutine, .wmdestroy

                        ;
                        ; Insert a band containing the toolbar into the rebar control.
                        ;

                        ; Fill appropriate fields of the 'rbBand' structure with data
                        ; characteristic for the toolbar control.
                        ;
                        push    [hToolbar]
                        pop     [rbBand.hwndChild]
                        mov     [rbBand.cxMinChild], 140
                        mov     [rbBand.cyMinChild], 26
                        mov     [rbBand.cx], 0

                        ; Insert the toolbar band at the last location.
                        ;
                        invoke  SendMessage, [hRebar], RB_INSERTBAND, -1, rbBand

                        stdcall ErrorRoutine, .wmdestroy

                        ;
                        ; Insert a band containing the first edit control into the rebar
                        ; control.
                        ;

                        ; Prepare 'rbBand' structure by filling its fields with data
                        ; characteristic for the first edit control.
                        ;
                        push    [hEdit1]
                        pop     [rbBand.hwndChild]
                        mov     [rbBand.cxMinChild], 170
                        mov     [rbBand.cyMinChild], 26
                        mov     [rbBand.cx], 170

                        ; Insert the first edit control at the last location.
                        ;
                        invoke  SendMessage, [hRebar], RB_INSERTBAND, -1, rbBand
                        stdcall ErrorRoutine, .wmdestroy

                        ;
                        ; Insert a band containing the second edit control into the rebar
                        ; control.
                        ;

                        ; Prepare 'rbBand' structure by filling its fields with data
                        ; characteristic for the second edit control.
                        ;
                        push    [hEdit2]
                        pop     [rbBand.hwndChild]
                        mov     [rbBand.cxMinChild], 160
                        mov     [rbBand.cyMinChild], 26
                        mov     [rbBand.cx], 160

                        ; Insert the second edit control at the last location.
                        ;
                        invoke  SendMessage, [hRebar], RB_INSERTBAND, -1, rbBand
                        stdcall ErrorRoutine, .wmdestroy

                        ; Create a font that will be used to display all strings inside
                        ; the application window controls.
                        ;
                        invoke  CreateFont, 16, 0, 0, 0, 0, FALSE, FALSE, FALSE,\
                                        DEFAULT_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,\
                                        DEFAULT_QUALITY, FIXED_PITCH + FF_DONTCARE, FontName

                        stdcall ErrorRoutine, .wmdestroy

                        mov     [hFont], eax

                        ; Set the created font to the edit controls.
                        ;
                        invoke  SendMessage, [hEdit1], WM_SETFONT, eax, TRUE

                        invoke  SendMessage, [hEdit2], WM_SETFONT, [hFont], TRUE

                        ; Window procedure should return 0 when processes the 'WM_CREATE'
                        ; message.
                        ;
                        jmp     .return0

                ; Operations performed when the application window has changed its sizes.
                ;
                .wmsize:
                        invoke  SendMessage, [hRebar], WM_SIZE, [wparam], [lparam]

                        ; Window procedure should return 0 when processes the 'WM_SIZE'
                        ; message.
                        ;
                        jmp     .return0

                ; Assure that the width and height of the application window never be smaller
                ; than the values hold in the constants 'WND_MIN_WIDTH' and 'WND_MIN_HEIGHT'.
                ;
                .wmgetminmaxinfo:

                        virtual at eax
                                .minmax MINMAXINFO
                        end virtual

                        mov     eax, [lparam]

                        mov     dword [.minmax.ptMinTrackSize.x], WND_MIN_WIDTH
                        mov     dword [.minmax.ptMinTrackSize.y], WND_MIN_HEIGHT

                        ; Window procedure should return 0 when processes the 'WM_GETMINMAXINFO'
                        ; message.
                        ;
                        jmp     .return0

                ; Process the message 'WM_COMMAND' sent when the application user presses any
                ; of the toolbar buttons.
                ;
                .wmcommand:
                        mov     eax, [wparam]

                        cmp     eax, TB_EXIT
                        je      .wmdestroy

                        cmp     eax, TB_OPEN
                        je      .open

                        cmp     eax, TB_SAVE
                        je      .save

                        ; Window procedure should return 0 when processes the 'WM_COMMAND'
                        ; message.
                        ;
                        jmp     .return0

                ; Operations performed when the toolbar sends the message 'WM_NOTIFY' to the
                ; main application window in case the mouse cursor hovers over any toolbar
                ; button. The notification code 'TTN_NEEDTEXTW' is sent in order to complete
                ; information needed to display a tooltip window.
                ;
                .wmnotify:

                        virtual at ebx
                                .tmp    NMTTDISPINFOW
                        end virtual

                        ; The 'lparam' parameter contains a pointer to the 'NMTTDISPINFOW'
                        ; structure instance that identifies the tool that needs text and
                        ; receives the requested information.
                        ;
                        mov     ebx, [lparam]

                        ; Check if the notification code is equal to the 'TTN_NEEDTEXTW'.
                        ; Otherwise forward the 'WM_NOTIFY' message to the default window
                        ; procedure.
                        ;
                        cmp     dword [.tmp.hdr.code], TTN_NEEDTEXTW
                        jne     .defwndproc

                        ; Get the id of the toolbar button that sent the notification
                        ; and copy it to the eax register.
                        ;
                        mov     eax, [.tmp.hdr.idFrom]

                        ; Accordingly to the button id contained in the eax register,
                        ; the 'lpszText' field of the 'NMTTDISPINFOW' structure instance
                        ; gets a pointer to the appropriate tooltip text associated with
                        ; the given button.
                        ;
                        .tbopen:
                                cmp     eax, TB_OPEN
                                jne     .tbsave

                                mov     dword [.tmp.lpszText], TipOpen
                                jmp     .finish

                        .tbsave:
                                cmp     eax, TB_SAVE
                                jne     .tbexit

                                mov     dword [.tmp.lpszText], TipSave
                                jmp     .finish

                        .tbexit:
                                cmp     eax, TB_EXIT
                                jne     .finish

                                mov     dword [.tmp.lpszText], TipExit
                                jmp     .finish

                ; Operations performed in case the 'Open' button has been pressed.
                ;
                .open:
                        invoke  MessageBox, 0, "'Open' button has been pressed.", "Open", MB_OK
                        jmp     .finish


                ; Operations performed in case the 'Save' button has been pressed.
                ;
                .save:
                        invoke  MessageBox, 0, "'Save' button has been pressed.", "Save", MB_OK
                        jmp     .finish

                ; Operations performed when the application window is to be destroyed.
                ; This is a regular cleanup after receiving the 'WM_DESTROY' message: here
                ; we delete objects and resources allocated during the application window
                ; creation. We don't need to destroy all controls (child windows) manually
                ; because it will be done automatically.
                ;
                .wmdestroy:
                        ; Delete the font used to display strings in the application
                        ; window controls.
                        ;
                        cmp     [hFont], 0
                        je      .ImageListDestroy

                        invoke  DeleteObject, [hFont]

                        .ImageListDestroy:
                                ; Destroy the image list used by the toolbar control.
                                ;
                                cmp     [hImageList], 0
                                je      .quit

                                invoke  ImageList_Destroy, [hImageList]

                        ; Post the 'WM_QUIT' message to the application message queue.
                        ;
                        .quit:
                                invoke  PostQuitMessage, 0

                .return0:
                        xor     eax, eax

                .finish:
                        pop     ebx
                        ret
        endp

        ; A simple procedure that displays a message box containing a human readable
        ; description of the last error.
        ;
        proc    ShowLastError, hwnd, LastErr

                locals
                        Buffer dd ?
                endl

                lea     eax, [Buffer]
                invoke  FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER + FORMAT_MESSAGE_FROM_SYSTEM, 0, [LastErr],\
                                LANG_NEUTRAL, eax, 0, 0

                invoke  MessageBox, [hwnd], [Buffer], NULL, MB_ICONERROR + MB_OK
                invoke  LocalFree, [Buffer]

                ret
        endp


; The import section.
;
section ".idata" import data readable writeable

library kernel32,               "KERNEL32.DLL",\
        user32,                 "USER32.DLL",\
        gdi32,                  "GDI32.DLL",\
        comctl32,               "COMCTL32.DLL"

import  kernel32,\
        ExitProcess,            "ExitProcess",\
        FormatMessage,          "FormatMessageW",\
        GetLastError,           "GetLastError",\
        GetModuleHandle,        "GetModuleHandleW",\
        LocalFree,              "LocalFree",\
        SetLastError,           "SetLastError"

import  user32,\
        CreateWindowEx,         "CreateWindowExW",\
        DefWindowProc,          "DefWindowProcW",\
        DispatchMessage,        "DispatchMessageW",\
        GetMessage,             "GetMessageW",\
        GetWindowLong,          "GetWindowLongW",\
        LoadCursor,             "LoadCursorW",\
        LoadIcon,               "LoadIconW",\
        MessageBox,             "MessageBoxW",\
        MoveWindow,             "MoveWindow",\
        PostQuitMessage,        "PostQuitMessage",\
        RegisterClassEx,        "RegisterClassExW",\
        SendMessage,            "SendMessageW",\
        SetWindowLong,          "SetWindowLongW",\
        TranslateMessage,       "TranslateMessage"

import  gdi32,\
        CreateFont,             "CreateFontW",\
        DeleteObject,           "DeleteObject"

import  comctl32,\
        ImageList_LoadImage,    "ImageList_LoadImageW",\
        ImageList_Destroy,      "ImageList_Destroy",\
        InitCommonControlsEx,   "InitCommonControlsEx"


; The section of the program resources. Here we specify information about the
; application (description, author, version) and the application manifest
; informing Windows which version of the common controls program should use
; giving it a modern visual style instead of the classical Win9x "boxy" style.
;
section '.rsrc' resource data readable

        RT_MANIFEST     = 24
        ID_MANIFEST     = 1

        directory       RT_BITMAP, toolbarbmp,\
                        RT_MANIFEST, manifest

        resource        toolbarbmp,\
                        IDTB_BITMAP, LANG_NEUTRAL, tbmp

        resource        manifest,\
                        ID_MANIFEST, LANG_NEUTRAL, man

        resource        versions,\
                        1, LANG_NEUTRAL, version

        bitmap          tbmp, 'Toolbar.bmp'

        versioninfo     version, VOS__WINDOWS32, VFT_APP, VFT2_UNKNOWN, LANG_ENGLISH + SUBLANG_DEFAULT, 0,\
                        'FileDescription', 'Rebar example',\
                        'LegalCopyright', '(C) Mikolaj Hajduk, 2013',\
                        'FileVersion', PROG_VERSION,\
                        'ProductVersion', PROG_VERSION,\
                        'OriginalFilename', 'RebarExample.exe'

        ; Content of the manifest included as an application resource.
        ;
        resdata man
                db '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
                db '<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">'
                db '<assemblyIdentity '
                        db 'version="', PROG_VERSION, '" '
                        db 'processorArchitecture="X86" '
                        db 'name="MikolajHajduk.RebarExample" '
                        db 'type="win32"'
                db '/>'
                db '<description>Rebar example.</description>'
                db '<dependency>'
                        db '<dependentAssembly>'
                                db '<assemblyIdentity '
                                        db 'type="win32" '
                                        db 'name="Microsoft.Windows.Common-Controls" '
                                        db 'version="6.0.0.0" '
                                        db 'processorArchitecture="X86" '
                                        db 'publicKeyToken="6595b64144ccf1df" '
                                        db 'language="*"'
                                db '/>'
                        db '</dependentAssembly>'
                db '</dependency>'
                db '</assembly>'
        endres
    
The complete archive that contains the application source code, a bitmap used by the toolbar control and an executable may be found here.
Smile
Post 06 Apr 2013, 23:10
View user's profile Send private message Visit poster's website Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 07 Apr 2013, 01:20
nice example and video too !, i have opened a "MHajduk folder" on harddisk to collect all your examples Very Happy what is that for video-capturer ?
Cheers,
Very Happy

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 07 Apr 2013, 01:20
View user's profile Send private message Visit poster's website Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 07 Apr 2013, 01:34
Awesome work!
Post 07 Apr 2013, 01:34
View user's profile Send private message Send e-mail Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777 07 Apr 2013, 05:25
MHajduk: You are a good programmer. However, it's very easy to draw custom toolbars in Mode 12/13h/tweaked without daddy Microsoft Wink

Most (>50%) ASM programmers today are just interested in learning how to use OS/Windows which has nothing to do with ASM/CPU/instructions. Think about it, they use ASM in their main source files as a calling convention to functions written in HL languages. That didn't make sense 20+ years ago! It should be the opposite: HL source files should call LL functions written in ASM library.

I say, if you want to learn ASM, use a REAL low-level OS like Menuet or Kolibri Wink


Last edited by uart777 on 07 Apr 2013, 05:54; edited 1 time in total
Post 07 Apr 2013, 05:25
View user's profile Send private message Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777 07 Apr 2013, 05:40
Real ASM is about writing your own. Here's a minimal example that does NOT use FASM's INCLUDE\MACRO:
Code:
format PE GUI 4.0
entry code

kernel_name: db 'KERNEL32.DLL', 0
_ExitProcess: db 0, 0, 'ExitProcess', 0
kernel_table:
ExitProcess dd RVA _ExitProcess
dd 0

user_name:   db 'USER32.DLL', 0
_MessageBox: db 0, 0, 'MessageBoxA', 0
_wsprintfA:  db 0, 0, 'wsprintfA', 0
user_table:
MessageBoxA dd RVA _MessageBox
wsprintfA   dd RVA _wsprintfA
dd 0

data import
dd 0,0,0, RVA kernel_name, RVA kernel_table
dd 0,0,0, RVA user_name, RVA user_table
dd 0,0,0,0,0
end data

title db 'FASM', 0
message db 'Minimal example', 0

code:
push 0 title message 0
call dword [MessageBoxA]
push 0
call dword [ExitProcess]    
Post 07 Apr 2013, 05:40
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 07 Apr 2013, 12:43
uart777
You just showing how to use Win API without invoke.
Yet invoke makes the code READABLE, and that fact is most important.
There is no harm in using invoke or struc/ends - these things make code easier to read.
Using IF/ELSE/ENDIF and loop macros, however, hide the flow of code, and
disable the use of static branch prediction to make code faster.
Post 07 Apr 2013, 12:43
View user's profile Send private message Send e-mail Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 07 Apr 2013, 13:58
hopcode, AsmGuru62 and uart777
Thank you all for your kind words referring to my programming style and creations. Smile

hopcode wrote:
what is that for video-capturer ?
I have used Debut Video Capture Software (here is the application homepage). This tool (along with other programs from the package) can be used not only for recording but also you may perform a kind of "post-production" with it (extract some sequences, merge them, remove original audio track and add another etc.). I've not fully learned all the subtleties of this application yet. I could probably make videos of better quality and more readable. However, I have some problems with the choice of the proper resolution that would give me the best visual effect when displayed in YouTube. Anyway, I think it's a good, fully professional set of video editing tools that, if used properly, can give a really eye-catching visual impression. Wink

uart777 wrote:
MHajduk: You are a good programmer. However, it's very easy to draw custom toolbars in Mode 12/13h/tweaked without daddy Microsoft Wink

Most (>50%) ASM programmers today are just interested in learning how to use OS/Windows which has nothing to do with ASM/CPU/instructions. Think about it, they use ASM in their main source files as a calling convention to functions written in HL languages. That didn't make sense 20+ years ago! It should be the opposite: HL source files should call LL functions written in ASM library.

I say, if you want to learn ASM, use a REAL low-level OS like Menuet or Kolibri Wink
I mostly agree with that you have said above but the programs presented by me in this section are mainly intended for those FASM programmers who had started their programming carreer from the HLL languages under Windows. I'd like to show to all of them that assembler is an equally good tool for creation of fully functional and esthetic applications. Moreover, I'd like to prove that programming in assembler not always have to be associated with horrible effort and not effective work. Quite the contrary, I deeply believe that programming in FASM can be fun. Wink
Post 07 Apr 2013, 13:58
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 07 Apr 2013, 14:33
MHajduk,

Macro programming in fasm is an example of art (or perversion) itself. Wink
Post 07 Apr 2013, 14:33
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 07 Apr 2013, 15:51
baldr wrote:
MHajduk,

Macro programming in fasm is an example of art (or perversion) itself. Wink
Yes, indeed, programming macros in FASM isn't easy but, from the other hand, is a perfect mind exercise for those who can find a specific pleasure in it. Wink
Post 07 Apr 2013, 15:51
View user's profile Send private message Visit poster's website Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777 07 Apr 2013, 19:37
Guru: Thanks for sharing your opinion Wink In the eyes of a language/compiler writer - who has a real reason to use ASM - ".if" is no different than "invoke".
Quote:
Yet invoke makes the code READABLE
Code:
macro invoke {} ; LOL!    
It does absolutely NOTHING but cause unnecessary source bloat. No reason for it. We need to stop judging the entire Universe from our own little perspective. Please try to see the bigger picture and how it effects everyone else: 100,000s of pointless call prefixes.

Why walk to the grocery store when you can drive? (Unless you need practice/exercise). Why spend $ if you don't have to?
Post 07 Apr 2013, 19:37
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4020
Location: vpcmpistri
bitRAKE 07 Apr 2013, 20:16
MHajduk, what are your thoughts/experiences with UI font selection? I see in your examples a static choice of "Tahoma" - which probably works for a broad audience. Yet, it's not the default nor user preference.

Looking to solve this problem myself, I've found the UI font can be retrieved though SPI_GETNONCLIENTMETRICS, lfMessageFont of the NONCLIENTMETRICS structure -- which is apparently correct in a very universal sense. It still seems a little hacky in being outside the documentation (which doesn't wish to support such a range of Windows versions - XP and earlier being deprecated).

On the matter of macro-ized assembly: it has existed since almost the start of assembly. This is because of the depth of ideas one wishes to express in a programmer friendly manner. Much software is cut-n-paste and API use -- at any level of programming. We enjoy the ground floor in this great pyramid, though. Very Happy

(Nice example, how about a ribbon?)

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 07 Apr 2013, 20:16
View user's profile Send private message Visit poster's website Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 07 Apr 2013, 21:25
bitRAKE wrote:
MHajduk, what are your thoughts/experiences with UI font selection? I see in your examples a static choice of "Tahoma" - which probably works for a broad audience. Yet, it's not the default nor user preference.

Looking to solve this problem myself, I've found the UI font can be retrieved though SPI_GETNONCLIENTMETRICS, lfMessageFont of the NONCLIENTMETRICS structure -- which is apparently correct in a very universal sense. It still seems a little hacky in being outside the documentation (which doesn't wish to support such a range of Windows versions - XP and earlier being deprecated).
I've chosen the font 'Tahoma' because it works good with the wide range of Unicode characters belonging to various alphabets / writing systems (works with letters characteristic for Polish, with Cyrillic alphabets and such "exotic" writing system as Chinese for example).

From what I understood, you have suggested that an application should rather use fonts chosen by the user but there is a problem when our intention as a program authors is to display the strings completely independently from the user custom environment settings. I mean the situation when I want to display the "Cyrillic" version of the program in the "Latin" environment for example.
Post 07 Apr 2013, 21:25
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.