I have just started experimenting with my resource editor and have quickly picked up how to create a simple form with a few controls on it, and have managed to compile it into my .exe

however i have a few questions...

first of all, is Developer studio the best resource editor?

when i compile it, it says it cant find various .h files. i have VC++ (i dont know any C++, it was cheap at a car boot sale :D ) and have them in my Microsoft Developer Studio directory.
and how can i get around copying all the .h files to the project directory to make it aseemble properly? if i set the dir to the .h files dir then it says it cant find the .rc (obviously).

is .rc the best type to save the resource as?

once i have got it into the .exe though, i am stuck. i cant work out how to actually make it appear. this is my code so far:

invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam, hInstance, FormName, NULL, ADDR DlgProcedure, 0
invoke ExitProcess,0

it says theres an error in the DialogBoxParam. second parameter is undefined, and its an argument type mismatch. that is the name of my form, and from various sources i have looked at, this is how the form is made to be shown on the screen. im pretty sure its an error in the source file, not the .rc. but i cant see what.

thanks in advance for your help.
skud.
Posted on 2001-08-08 07:38:38 by skud
In your resource script, you will have defined the dialog by either some name or an integer value.

e.g.


MainDlg DIALOG 77, 235, 207, 70
...
...


In this case the name of the dialog is MainDlg.
It could be "1 DIALOG ....".

In your .asm file you need:


.data
DlgName db "MainDlg",0

.code
invoke DialogBoxParam, hInstance, ADDR DlgName, NULL, ADDR DlgProc, NULL


Or if the dialog is defined using an integer rather than some name:


.code
invoke DialogBoxParam, hInstance, 1, NULL, ADDR DlgProc, NULL

It can be made more readable using equates though.

Mirno
Posted on 2001-08-08 08:37:23 by Mirno
thx.

it compiles now but it still doesnt show the window :(
i tried using showwindow with it but that doesnt do anything...

skud.
Posted on 2001-08-08 09:04:14 by skud
Could you post the code & rc file.

It'd make it a bit easier to help!

Mirno
Posted on 2001-08-08 09:16:51 by Mirno
here ya go!

thanks for the swift responses too.
the wonders of email notify!
Posted on 2001-08-08 09:50:17 by skud
Do you build using Quick Editor, or the batch files in \masm32\bin?
If you do, then the .rc file needs to be called rsrc.rc as this is hard coded into the building & linking process.

If you simply rename the .rc file and compile, you'll see a button on screen, and processor usage goes to 100%.
If you don't get that, then the assembler hasn't linked in the rsrc.obj file (which explains why it didn't work :D ).

After renaming the file. You'll also need to make some changes to the .asm file too!

1) The DLG proc returns true if it has processed its own message, otherwise it returns false.

So you need to add:


.if uMsg == WM_CLOSE
.....
.if uMsg == IDC_BUTTON1
.....
.else
mov eax, FALSE
ret
.endif

mov eax, TRUE
ret
DlgProc ENDP


2) When you click on a button, the dialog receives a WM_COMMAND message. When receving a WM_COMMAND, the ID of the command is in the lower 16bits of wParam, and the handle of the control is in lParam.

So change your code to:


.elseif uMsg == WM_COMMAND
.IF lParam != 0 ;Control if >0, menu if 0
mov eax, wParam
and eax, 0FFFFh
.IF eax == IDC_BUTTON1
....
.ENDIF
.ENDIF
.....


That should make it work properly.

3) Just for completeness, change from using "ExitProcess, 0" in your "WM_CLOSE" to using "EndDialog, hWnd, 0".
Its a little more "proper"!


I've included the "cut-down" version of the .rc file (hand edited to remove all the crap VC puts in). Its easier to read, and modify by hand, if you play around with it for a while you'll soon learn what everything does!

Mirno
Posted on 2001-08-08 10:31:29 by Mirno
Oops missed the zip!
Posted on 2001-08-08 10:33:26 by Mirno
its still not working
assembles, but when i run it it doesnt do anything.

is my Make.bat ok?

@echo off
C:\Masm32\BIN\rc rsrc.rc
C:\masm32\bin\ml /nologo /c /coff Button.asm
C:\masm32\bin\link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib Button.obj
echo.
echo.
echo.
if exist *.obj del *.obj
pause
cls
Posted on 2001-08-08 10:46:03 by skud
"\masm32\bin\rc button.rc" is fine if you are doing a make file yourself.
However, rc doesn't produce an .obj file. To do this you need to use "\masm32\bin\cvtres /machine:ix86 button.res"
This will produce an .obj file.

This brings us a whole new problem, as you have button.obj from button.asm, and button.obj from button.rc! I'm sure you can solve that one though!

When linking also link the resource's object file too.

That should solve the problem.

Mirno
Posted on 2001-08-08 10:55:53 by Mirno
Hi Skud,
there are several fundamental mistakes in your .asm code as mirno has pointed out. I won't bother going over them.

Here however is the zip file of your sources which I've edited to remove errors it's also got the binaries in it.

Mirno hasn't pointed this out but note That IDC_BUTTON must also be defined in the ASm source file

don't hesitate to contact me if you don't understand something
I've got some improved batch files if you want them also

the Martial
Posted on 2001-08-08 11:17:32 by MArtial_Code
thanks a lot for taking the time to correct my code!...
but i can't compile it. theres something wrong with my .bat.
i really dont get how the linking process works, or what .obj files do.

could you please correct my .bat

i just need a working example to get me on the right track.

skud.

PS. my Make.bat is posted above this post somewhere.
Posted on 2001-08-08 11:25:29 by skud
This:


-------------------------------- make.bat --------------------------------
@echo off
\masm32\bin\rc rsrc.rc
\masm32\bin\cvtres /machine:ix86 rsrc.res
\masm32\bin\ml /nologo /c /coff button.asm
\masm32\bin\link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib button.obj rsrc.obj
echo.
echo.
echo.
if exist *.obj del *.obj
if exist *.res del *.res
pause
------------------------------------------------------------------------------


It works for me!

Mirno
Posted on 2001-08-08 11:41:55 by Mirno
thanks.
compiles and runs now, after a thousand posts!

however, when i press the button nothing happens.
i understand that anything being triggered sends a WM_COMMAND right?

and then, as you said, the lower 16bits of wParam contains the name of the control thats been triggered. i have done this kind of thing before under winsock in non-blocking mode, but the same code here doesnt seem to be working...
Posted on 2001-08-08 11:56:53 by skud
hmmmm

mirno's code is working
martial something wrong with yours mate :D

i have a look at it.
shud have checked before posting.
Posted on 2001-08-08 11:59:39 by skud
skud, follow these steps and you should compile and run buttons.asm

1) extract the zip file and place button.rc and button.asm into as directory say \masm32\button

2)place build.bat in \masm32\bin

3) open a dos window and navigate to where you placed button.rc and button.asm

4)type the following then press return
set masm32path=c:\masm32

5)type the following to compile and run button.asm

%masm32path%\bin\build.bat button .\

if you follow the above you should have no problems.

p.s my code works perfectly...check the paths because my masm32 instalation is in d:\programs\ while yours is probably in c:\
p.p.s the button.exe is the button.asm compiled on my machine
the martial
Posted on 2001-08-08 12:30:19 by MArtial_Code
ok i have it working.

but why does the button have a .cont value?
the resource file knows it as its name and so does the .asm so whats the point in it? and how do you decide what value it has?

thanks.
skud.
Posted on 2001-08-08 13:39:35 by skud
good,

resources such as menuitems and buttons need an integer ID This ID gets passed to the window procedure as the low word of wParam when the item is clicked.

In the window procedure we compare the loword of wPram to the resource ID to find out which button/menuitem was selected so we can act accordingly

the value in the .CONST section defines a constant which will be the ID for the button. This value must be the same as what's defined in the resource file or at best you'll get nothing happening.

You can pretty much choose whatever value you wish for the ID bearing in mind that it must fit into 16 bits so the ID can be between 0 and 65535 decimal or 0 to FFFF hex

so for eg my resource file:

#include "c:\programs\masm32\include\resource.h"
#define IDM_MENU 1
#define IDM_OPEN 2
#define IDM_SAVE 3
#define IDM_EXIT 4
#define IDM_HELP 5
#define IDM_ABOUT 6
#define IDE_EDIT1 100
#define IDB_START 200
#define IDB_RESET 201
#define IDC_UP 300

Timer DIALOGEX 10,10,62,110
CAPTION "Timer"
Style DS_MODALFRAME|WS_VISIBLE|WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU|WS_OVERLAPPED|DS_3DLOOK
MENU IDM_MENU /*declares a menu for the above dialog box*/
{
EDITTEXT IDE_EDIT1,5,1,52,9,ES_CENTER
PUSHBUTTON "Start!",IDB_START,5,20,25,9
PUSHBUTTON "Reset!",IDB_RESET,32,20,25,9
AUTOCHECKBOX "UP",IDC_UP,30,12,20,5
}
IDM_MENU MENU
{
POPUP "&File"
{
MENUITEM "&Open...",IDM_OPEN
MENUITEM "&Save...",IDM_SAVE
MENUITEM SEPARATOR
MENUITEM "E&xit",IDM_EXIT
}
POPUP "&Help"
{
MENUITEM "&About",IDM_ABOUT
}
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

all of the #define above will have an equivalent equ in my asm source.

eg:

.CONST
IDM_MENU equ 1
IDM_OPEN equ 2
IDM_SAVE equ 3
IDM_EXIT equ 4
IDM_HELP equ 5
IDM_ABOUT equ 6
IDE_EDIT1 equ 100
IDB_START equ 200
IDB_RESET equ 201
IDC_UP equ 300

I hope that helps a bit

P.S. have a look at RadASM which is posted on this board. It's got a dialog editor which doesn't add any extraneous info to the .rc file. It'll automatically assign a value for the IDs which you can export for inclusion in your asm source file.

The Martial
Posted on 2001-08-08 15:12:55 by MArtial_Code