News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

GUI

Started by Slugsnack, June 22, 2009, 04:45:21 PM

Previous topic - Next topic

Slugsnack

I was trying to get started with GUIs today and used ResEdit to create a simple dialog sort thing.. Then tried to convert the code it generated ( C ) to ASM with little success..



( http://img4.imageshack.us/img4/5463/guiy.jpg )

On the left screen is ResEdit with what I created with it. The code it generated is in the notepad++ on the right screen.

Generated C code :

// Generated by ResEdit 1.4.5
// Copyright (C) 2006-2009
// http://www.resedit.net

HINSTANCE hInst = GetModuleHandle(0);
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof wcex);
wcex.cbSize         = sizeof wcex;
wcex.hbrBackground  = (HBRUSH)(COLOR_3DFACE + 1);
wcex.lpszMenuName   = 0;


wcex.style          = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = DefWindowProc;
wcex.hInstance      = hInst;
wcex.hIcon          = LoadIcon(0, (LPCTSTR)IDI_APPLICATION);
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName  = WndClass00;
RegisterClassEx(&wcex);

HFONT hfont0 = CreateFont(-11, 0, 0, 0, 400, FALSE, FALSE, FALSE, 1, 400, 0, 0, 0, ("Ms Shell Dlg 2"));
HWND hwnd = CreateWindowEx(0, ("WndClass0"), ("Dialog"), WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU, 0, 0, 209, 89, 0, 0, hInst, 0);
HWND hCtrl0_0 = CreateWindowEx(0, WC_BUTTON, ("OK"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 119, 8, 75, 23, hwnd, (HMENU)IDOK, hInst, 0);
SendMessage(hCtrl0_0, WM_SETFONT, (WPARAM)hfont0, FALSE);
HWND hCtrl0_1 = CreateWindowEx(0, WC_BUTTON, ("Cancel"), WS_VISIBLE | WS_CHILD | WS_TABSTOP, 119, 34, 75, 23, hwnd, (HMENU)IDCANCEL, hInst, 0);
SendMessage(hCtrl0_1, WM_SETFONT, (WPARAM)hfont0, FALSE);
HWND hCtrl0_2 = CreateWindowEx(0, WC_EDIT, 0, WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL, 8, 15, 104, 36, hwnd, (HMENU)IDC_EDIT1, hInst, 0);
SendMessage(hCtrl0_2, WM_SETFONT, (WPARAM)hfont0, FALSE);


My failed translation to ASM code :

include \masm32\include\masm32rt.inc


DefWindowProc proto :DWORD, :DWORD, :DWORD, :DWORD

COLOR_3DFACE    equ 15
IDC_EDIT1       equ 102

.data

.data?

hInst                   DWORD       ?
wcex                    WNDCLASSEX  <>

hfont                   DWORD       ?
hdlg                    DWORD       ?
hbutton0                DWORD       ?
hbutton1                DWORD       ?
hbutton2                DWORD       ?

msg                     MSG         <>

.code
    Start:

xor ebx, ebx
    invoke GetModuleHandle, ebx
mov hInst, eax

    invoke memfill, addr wcex, sizeof wcex, ebx

mov wcex.cbSize, sizeof wcex

mov wcex.hbrBackground, COLOR_3DFACE + 1
mov wcex.lpszMenuName, ebx

mov wcex.style, CS_HREDRAW OR CS_VREDRAW
mov wcex.lpfnWndProc, offset WindowProc

push hInst
pop wcex.hInstance

    invoke LoadIcon, ebx, IDI_APPLICATION
mov wcex.hIcon, eax
    invoke LoadCursor, ebx, IDC_ARROW
mov wcex.hCursor, eax

mov wcex.lpszClassName, chr$("WindowClass", 0)
    invoke RegisterClassEx, addr wcex

    invoke CreateFont, -11, ebx, ebx, ebx, 400, FALSE, FALSE, FALSE, 1, 400, 0, 0, 0, chr$("Ms Shell Dlg 2", 0)
mov hfont, eax

    invoke CreateWindowEx, ebx, chr$("WindowClass", 0), chr$("Window Name", 0), WS_VISIBLE OR WS_BORDER OR WS_CAPTION OR WS_DLGFRAME OR WS_POPUP OR WS_SYSMENU, ebx, ebx, 209, 89, ebx, ebx, hInst, ebx
mov hdlg, eax

    invoke CreateWindowEx, ebx, chr$("Button", 0), chr$("OK", 0), WS_VISIBLE OR WS_CHILD OR WS_TABSTOP OR 1, 119, 8, 75, 23, hdlg, IDOK, hInst, ebx
mov hbutton0, eax

    invoke SendMessage, eax, WM_SETFONT, hfont, FALSE

    invoke CreateWindowEx, ebx, chr$("Button", 0), chr$("Cancel", 0), WS_VISIBLE OR WS_CHILD OR WS_TABSTOP, 119, 34, 75, 23, hdlg, IDCANCEL, hInst, ebx
mov hbutton1, eax

    invoke SendMessage, eax, WM_SETFONT, hfont, FALSE

    invoke CreateWindowEx, ebx, chr$("Edit", 0), ebx, WS_VISIBLE OR WS_CHILD OR WS_TABSTOP OR WS_BORDER OR ES_AUTOHSCROLL, 8, 15, 104, 36, hdlg, IDC_EDIT1, hInst, 0
mov hbutton2, eax

    invoke SendMessage, eax, WM_SETFONT, hfont, FALSE

    .WHILE TRUE

            invoke GetMessage, addr msg, ebx, ebx, ebx

            .BREAK .IF (!eax)

            .IF eax == FALSE

                    invoke TranslateMessage, addr msg
                    invoke DispatchMessage, addr msg

            .ENDIF

    .ENDW

    invoke ExitProcess, ebx

WindowProc proc hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

    .IF uMsg == WM_DESTROY

        invoke PostQuitMessage, NULL

    .ELSE

        invoke DefWindowProc, hwnd, uMsg, wParam, lParam

    .ENDIF

ret
WindowProc endp

    end Start

ramguru

 :bg You may wanna use ResEd instead of ResEdit  :lol

When using resource file you don't need to convert anything.
In case of dialog just call DialogBoxParam. Look at examples.

Slugsnack

Thanks for your tip on ResEd. I ended up getting that and RadASM and started out all over again..



( http://img198.imageshack.us/img198/6423/23601356.jpg )

DialogBoxParam is failing with ERROR_RESOURCE_TYPE_NOT_FOUND

Code for GUI.asm :

include \masm32\include\masm32rt.inc

DlgProc proto :DWORD, :DWORD, :DWORD, :DWORD

.data?

hInstance DWORD ?

.const

IDD_DLG1 EQU 1000
IDC_EDT1 EQU 1001
IDC_BTN1 EQU 1002
IDC_BTN2 EQU 1003

.code
Start:

xor ebx, ebx
invoke GetModuleHandle, ebx
mov hInstance, eax

invoke DialogBoxParam, eax, chr$("IDD_DLG1", 0), ebx, addr DlgProc, ebx
invoke ExitProcess, ebx

DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    .IF uMsg == WM_INITDIALOG

            invoke GetDlgItem, hWnd, IDC_EDT1
            invoke SetFocus, eax

    .ELSE

        mov eax, FALSE
        ret

    .ENDIF

mov eax, TRUE

ret
DlgProc endp

end Start


Code for resource file :

#define IDD_DLG1 1000
#define IDC_EDT1 1001
#define IDC_BTN1 1002
#define IDC_BTN2 1003

IDD_DLG1 DIALOGEX 10,10,166,61
CAPTION "IDD_DLG"
FONT 8,"MS Sans Serif",0,0,0
STYLE WS_VISIBLE|WS_OVERLAPPEDWINDOW
BEGIN
  CONTROL "",IDC_EDT1,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP,15,21,54,15,WS_EX_CLIENTEDGE
  CONTROL "IDC_BTN",IDC_BTN1,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,93,15,54,15
  CONTROL "IDC_BTN",IDC_BTN2,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,93,36,54,15
END


Any ideas ? ^_^

ramguru

in rc file: #define IDD_DLG1 1000

so IDD_DLG1 is actually a number not a string ...
it's not like associative array, compiler can't guess
what's behind that string..
so either use:

invoke DialogBoxParam, eax, IDD_DLG1, 0, addr DlgProc, 0

or

invoke DialogBoxParam, eax, 1000, 0, addr DlgProc, 0

Also using ebx is a bad habit .. w/o preserving it :}

Slugsnack

Nope no luck using IDD_DLG1 instead of chr$() but yeah I was definitely wrong the first time doing that.

As for using ebx, I don't see it as a big issue. STDCall expects it to be preserved in function calls but I don't think there is a need to preserve it in the 'main' of the program as long as each function I code preserves it.

edit : OMG I finally realised why none of it was working.. I was using an empty resource.h file.. All I had to do was copy the one out of MASM folder and voila everything works perfect

thanks for your help ramguru : )

Damos

register preservation needs to be observed in callback procs like the typical winproc function as windows expects that on return of this function ebx,esi & edi are as they were when it was called. :toothy You are right though there is no need in the 'main' part.
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction. - Albert Einstien

Slugsnack

Yeap in my DlgProc I only modify EAX/ECX/EDX as defined by STDCALL convention

Been doign that 'xor ebx, ebx' thing in my 'main' functions since agesssss. Forgotten who even told me to do that. But it's just because of small speed gains from using registers to immediate numbers and like one byte instruction differences, etc. Probably not worth doing even but HEY WE'RE ASM PROGRAMMERS !

jj2007

On a side note: You don't need chr$("text", 0):

Quote     chr$ MACRO any_text:VARARG
        LOCAL txtname
        .data
          txtname db any_text, 0
        .code
        EXITM <OFFSET txtname>
      ENDM

Normally no problem, except in cases where a double zero marks the end of an array (e.g. the filetype+extension array in FileOpen).

Slugsnack

ahhh thanks for catching that one ; )

dedndave

yah - and i didn't know about the 00 either - lol
in fact, i didn't know about FileOpen at all
i'm a n00b32 - thinkin of changing my nic

fearless

I normally just use one of the templates - New Project --> Win32 App --> DialogAsMain. Then adjust it from there. Have to adjust the .inc file slightly for a small error, when it generates the following code:

include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc
include comctl32.inc
include comdlg32.inc

includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib comctl32.lib
includelib comdlg32.lib

WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD

IDD_DIALOG equ 1000

IDM_MENU equ 10000
IDM_FILE_EXIT equ 10001
IDM_HELP_ABOUT equ 10101

.const

ClassName db 'DLGCLASS',0
AppName db 'Dialog as main',0
AboutMsg db 'MASM32 RadASM Dialog as main',13,10,'Copyright © MASM32 2001',0

.data?

hInstance dd ?
CommandLine dd ?
hWnd dd ?


The .const is in the wrong place (should be .data) so i rename it and place a .const just above the IDD_DIALOG constant. Build all - works. Then i can get on with the main coding and also jump into the editor when needed to update the GUI.
ƒearless