Hello, I am writing a Win32 application that has more than one active window.? Well, I've already coded everything, but it's all in one .asm file; which makes it seem very unorganized, and uneasy to follow.

What I want to do is have a seperate .asm file for each window.? For instance:

-My first window's .asm file.
? ? ? -Contains this Window's WndProc
? ? ? -Contains Processes only used by this window
? ? ? -Contains data only used by this window

-My second window's .asm file
? ? ? -Contains this Window's WndProc
? ? ? -Contains Processes only used by this window
? ? ? -Contains data only used by this window

-Another .asm file
? ? ? -Contains processes used by all Windows
? ? ? -Contains data used by all windows

I have tried to do this by including the asm file's to the first .asm file, but, long story short, I never got it to work.?

So if anyone could explain to me how to achieve a relative layout to what I want to do with my code, that would be much appreciated.? Thank you.

BBS-
Posted on 2005-07-21 10:40:12 by BBS
You have a main.asm and several .inc files.

In main.asm declare all your variables etc (or you can have another .inc files to declare all your variables) and include the appropriate stuff like includelib and required .inc.

Add the following lines

include <file1>.inc
include <file2>.inc
...

Where <file1>.inc and <file2>.inc are files that contains the stuff that you want to include.
Posted on 2005-07-21 10:51:29 by roticv
So if I wanted to have my second window's procedures seperate from the main.asm file, all I'd have to do is put the processes into, lets say window2.inc, and include it to where I would normally have the code?? ... like.

main.asm
.code
start:

WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
? ?...
? ?...
WndProc endp

include window2.inc

end start


window2.inc
WndProc2 proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
? ?...
? ?...
WndProc2 endp


And if so, do I need to define the code section in the include file?
Posted on 2005-07-21 11:07:55 by BBS
You don't need unless you are mixing .data with .code but of course you can add it at the beginning just for in case.  ;)
Posted on 2005-07-21 11:13:41 by roticv
Okay, thanks for the help!  :D
Posted on 2005-07-21 11:16:00 by BBS
There's a couple of ways to do this.

Cutting up the main .asm file and including the results are one way - if you do this, it's important that you do NOT add the .model and include+includelibs to the new .asm files (and you should call them .inc to make it clear that these are not separate modules, but files to be included).

The better way, in my humble opinion, is to do proper module separation.

For each task (or set of related tasks) that can be separated, write a .inc and a .asm file. The .inc file includes everything that other parts of the code needs to know to be able to use the stuff from the module. This includes STRUCTs, EQUs, PROTOs and such.

Your main program includes the various .inc files, and each .asm file is assembled separately. Finally, link.exe handles merging all the modules. This is a bit more work than a "monolithic" approach, so I would suggest you get yourself a decent IDE - RadASM seems to be popular.

Oh yes, "option proc:private" is important - it keeps the PROCs private to the .asm they're defined in, unless you explicitly declare them public.

PS: my code is written without hardcoded paths. You will have to set up INCLUDE and LIB environment variables before assembling.

set include=c:\masm32\include
set lib=c:\masm32\lib

Attachments:
Posted on 2005-07-21 11:17:15 by f0dder
Thanks f0dder.  :)

This is what I was hoping to find, though it's a tad bit more complicated than just including the code.  But I'm sure I'll figure it out if I tinker with it for a bit.  Thanks!

BBS-
Posted on 2005-07-21 11:30:15 by BBS
It certainly is a tad more complicated, but it's better suited for larger designs - by encapsulating things this way, it's harder for bugs to creep up. And you can (if you wish) use the name "windowproc" for all your windowproc callbacks, because of the "option proc:private" line.

And certainly do get yourself an IDE, so you don't have to mess around with multiple open editors, batch files, et cetera
Posted on 2005-07-21 11:39:07 by f0dder
Yeah, I have been using RadAsm.  So, whenever I want to link the modules together, I just include them all into a project and hit build?
Posted on 2005-07-21 11:46:22 by BBS
I don't personally use RadASM, so you will have to ask someone else - but that's the typical way IDEs handle multiple modules, so it's worth a try :)
Posted on 2005-07-21 11:50:00 by f0dder
:) Thanks for taking you rtime to explain this.  I think I finally understand it. 
Posted on 2005-07-21 11:56:10 by BBS
No problem - if you need any additional help, feel free to shout :)
Posted on 2005-07-21 14:04:11 by f0dder
BBS,

There is a technique that has not been mentioned here that is very common with MASM projects and tha is to build seperate modules into a library. If you project is reasonably small there is no problem in simply including a number of source files in your main file. The IDE you are using may be able to handle seperate modules that are not buit into a library but there is some advantage in placing code that you hae finished into a library, one is that the code does not get rebuilt over and over again so your build time is a lot faster, particularly on large projects.
Posted on 2005-07-21 23:59:55 by hutch--

there is some advantage in placing code that you hae finished into a library, one is that the code does not get rebuilt over and over again so your build time is a lot faster, particularly on large projects.

Neither will it if with separate .obj files, as long as you're using a decent IDE (every IDE I know of check if the source module has been modified since the .obj was created - if it hasn't, the module won't be rebuilt).

Libraries are mainly useful for collections of infrequently changed modules that are useful across projects.
Posted on 2005-07-22 00:11:50 by f0dder
Everybody has a theory, building libraries works very well in practice and they link very quickly. They are also IDE independent and part of a system supported by both MASM and VC. Feel free to continue the discussion elsewhere. :)
Posted on 2005-07-22 08:45:02 by hutch--
It wouldn't make sense to put often-changing object files in a library, since you'd end up building the .lib every time a single object changes - that's why they're best for "mostly static" content.

It's true that they link very quickly, though - it should be a bit faster linking to a .lib than a lot of .objs, since .lib files have a smart symbol table member.

In practice, IDEs (or makefiles, if you still prefer to do stuff manually) make your life a lot easier, once you start building large projects. Automatic dependency handling, automatic rebuilding of what's needed, etc. Not much of an issue if your projects are mainly 1-2 source modules, but once you're at 5+, it's a godsend.
Posted on 2005-07-22 10:34:42 by f0dder
Its usually the case where files that are in the rapid modification stage remain in a large project as source file format but when they are complete and need no further modification, it is good practice to shift them out into a library. Using the "include" format in MASM easily handles some dozens of files but when you build a large project that may use between hundreds to thousands of seperate modules, the library format is far more efficient and a linker is a lot faster that selectively checking the build state with one of the old MAKE utilities.

A reasonable IDE can handle building and checking code modules on the fly but it is a poor technique in comparison to a library where the user only needs to include the library with the INCLUDELIB syntax available with MASM. The only real problem I see with using this capacity with an IDE is that the code become IDE dependent and it is far less portable within the same hardware and OS because of it.
Posted on 2005-07-22 19:49:52 by hutch--

Its usually the case where files that are in the rapid modification stage remain in a large project as source file format

Indeed - wouldn't make sense to do otherwise.


but when they are complete and need no further modification, it is good practice to shift them out into a library.

humm, it's doable for any kind of program, I guess. I've only really seen it used for reusable code libraries, though (libc, zlib, aplib, et cetera). Depends on how you're using the code, I guess :)


A reasonable IDE can handle building and checking code modules on the fly but it is a poor technique in comparison to a library where the user only needs to include the library with the INCLUDELIB syntax available with MASM.

That kind of usage sounds like redistruatable and reusable code - in that case, a library is a perfect way of bundling the objects, and it doesn't really make sense to NOT use a library :)


The only real problem I see with using this capacity with an IDE is that the code become IDE dependent and it is far less portable within the same hardware and OS because of it.

Well, for a portable/reusable/redistributable project, using your IDE to build a library is the perfect solution :)
Posted on 2005-07-22 21:44:03 by f0dder
Hey guys, back for more.? :P

I don't understand why this isn't working.? Whenever I try to build the project, I get this error

C:\Masm32\Bin\LINK.EXE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"C:\Masm32\Lib" /OUT:"test.exe" "test.obj" "test.res"
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

test.obj : error LNK2001: unresolved external symbol _testing@0
test.exe : fatal error LNK1120: 1 unresolved externals


It may be just me, but by reading that, it doesn't seem like it's even messing with other.asm.? An explanation would be lovely, please.? :)

test.asm
.586
.model flat,stdcall
option casemap:none
option proc:private

? ?include windows.inc
? ?include kernel32.inc
? ?
? ?includelib kernel32.lib
? ?
? ?include test.inc

.code
entry:
invoke testing
invoke ExitProcess,0
END entry


other.asm
.586
.model flat,stdcall
option casemap:none
option proc:private

? ?include windows.inc
? ?include user32.inc
? ?
? ?includelib user32.lib

.data
Caption db "WooHoo",0
Message db "It worked, yay!",0

.code
PUBLIC testing
testing PROC
invoke MessageBox,0,addr Message,addr Caption,MB_OK
ret
testing ENDP
END


test.inc
testing PROTO
Posted on 2005-07-26 16:40:27 by BBS
Justv a couple of things, you have made a variable PUBLIC in one module but you probably need to use the EXTERNDEF syntax in te caller so it can be seen from there. I am having trouble reading the post because the print is too small but you may have a problem with,


option proc:private


In the module so if you don't need it, remove it.
Posted on 2005-07-26 17:38:18 by hutch--