News:

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

File loading/saving, window resizing and other help

Started by dav7, September 13, 2007, 02:38:23 PM

Previous topic - Next topic

dav7

Hi everyone, I'm very new to ASM so need a bit of help.

I basically need help with saving and loading of a file and window sizing. And maybe a few other things.

"My first Project" :P will hopefully be an ASM implementation of a program that is a real classic to me, NotePad (my NotePad, and no, you've never heard of it before). I made like a dillion versions in VB 1.0, a dillion ^ 31337 versions in QB 4.5, now I'd like to attempt it in Win32 ASM. DOS and Linux GUI/console versions later. Much later.

Basically, the concept behind NotePad is that when opened it shows a very small cute window and opens notepad.txt from the current folder (or creates it if it doesn't exist), restores its x/y postion onscreen from notepad.ini (which is also created if it doesn't exist, and "initialized") and if window resizing is implemented (probably a good idea), the window size is also restored.
You then do whatever you want to the contents of the textbox, hit ESC and the app x/y, size and the contents of the textbox are committed back to file.

I have absolutely no idea as to where to start using MASM (I'm using MASM32 specifically) so... well, I'm asking for some assistance :wink
And no, I don't mean "I-want-to-be-lazy-can-you-plzplzplzplz-write-my-1st-app-for-me-XD" assistance, I mean "can you please provide me with information and resources that a 5 year old would understand as to how file saving/loading works, window resizing and etc" assistance. I can't stress though how little I understand of ASM. If you just say "use N function" I'll probably be like "huh? how? :/". Basically, I understand mov, jmp, jne, add, sub, and not much more, and I vaguely understand db and dw. I know "what they do" but not really "how they do". I to a medium extent understand registers, although I'm not entirely confident with my understanding of registers. I know they define bytes and words (words = ??), and they allocate memory for the program... and that's about it. I do understand .if/.elseif/.endif and very much appreciate the fact that they support ==, || and && :D

You might be thinking about now "lol, this guy has no hope, why is he posting on a forum asking about his first program? He should be reading manuals and stuff or something." Well, I have to admit that I learn by reading code. Er, code that I can understand, that is :wink. I learnt how PHP worked by reading a forum's sourcecode. I'd never really looked at PHP beforehand, and never really gotten into C-like languages before (yes, that's right, I don't know C, but I'm still trying ASM... you can't stop me XD), but for some reason picked up PHP and ran with it. No manuals... no forums... no nothing, I was just able to figure out the code. Well, if this "ability" to decode a language and then understand it could be thought of like a little gadget I aim at something then I understand it, I'm aiming the little box and pressing the button, but nothing happens when I aim it at the concepts behind assembler. I'm not sure if that's the fact that I see a few MOVs nestled amongst character soup, or the fact that it's not a very visual language, but...
I AM DETERMINED TO GIVE ASSEMBLY A TRY AND WILL NOT GIVE UP!
:toothy :bg :toothy :8) :P :U :lol :wink :green

So, I basically want someone (or a few people) to maybe give me well commented :P code snippets that sort-of-work-but-need-figuring-out-and-understanding-to-implement-successfully (keeping in mind the previous statement about how much ASM I understand), concepts, hints, and etc, so that I can write my 1st application while understanding what I'm doing at the same time. I've decided that's the only way I'll manage ASM, because in case you didn't read my ("Hi world" post - http://www.masm32.com/board/index.php?topic=7884.0), I still have leftover BASIC in my system that needs flushing. As you know, I took quite a liking to PHP when I saw it, and I'm not sure whether this is a good or bad thing.

Now, I do want you to know that I do have some code here, it just displays a window and a textbox, and exits when I hit ESC, but I, well, I can't get any of the file loading/saving examples I've found to work in my application  :'(


All of that said...

Some ideas for optimizations in the program:

  • If the window position, size, or text box contents weren't modified, why save them?
  • I'm currently using resources to draw my window (I'm a visual design junkie, dav7 = UI. (repeat x 1337) Anyone need a UI for their project? :8)) however I have a feeling... a feeling... that drawing my window from code and putting my edit control on my newly code-drawn window is going to take less KB than using resources for my window. I think I'm right. I want to include visual styles in my application though, which also dumps entries in the resource table, taking up KB - although it seems to look like disabling visual styles doesn't make the textbox look weird/non-styled, which is promising
  • I very much hope there's a Yes for this, it's not entirely MASM-related, but here goes: is there a property for textboxes that shows a vertical scrollbar when there's text to scroll, but hides the vertical scrollbar when there's no text to scroll? At the moment my app is behaving like IE, with its scrollbar visible but disabled when there is no text to scroll, but I want it to behave like Firefox, which hides the scrollbar when it's not needed. If this isn't manageable easily, I don't want some "is there N lines in the textbox" hack, my font sizes might be different from your font sizes...
  • Is there a feasible, simple way I might be able to save the x/y, size and textbox contents in the text file?

I think that's a comprehensive enough list, should keep someone (hopefully not too) busy  :bg

To wrap up, I've put the complete source to my current "edition" of NotePad online, for anyone who wants to download it. Everything required to compile - the resources, source files, make program, includes, libraries, even ml.exe, rc.exe, etc :P (although you can replace those if you want to for whatever reason) - is included in the archive. Extract the archive anywhere then run compile.bat and NotePad.exe should magically appear - If NotePad.exe doesn't appear, I will be VERY surprised. The app in its current state isn't very exciting, but it's 3.50KB (I wish it were 2.00KB or something :P) of promise :D
You can grab it at http://dav7.net/stuff/NotePad.zip. It's 850KB, which is kind of large, but then you remember all the stuff inside... that is pretty good compression IMHO :P


Oh, and for those of you too lazy to download the above file, here's the ASM source in all its indented (I'm also an indent junkie, and if it's possible to indent a language, I usually figure out a way) goodness:


.386
.model flat, stdcall
option casemap: none

include build\inc\windows.inc
include build\inc\user32.inc
include build\inc\kernel32.inc
include build\inc\comctl32.inc

includelib lib\user32.lib
includelib lib\kernel32.lib
includelib lib\comctl32.lib

szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text, 0
lbl:
ENDM

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

.data
dlgname db "NOTEPAD", 0
hInstance dd 0
hEdit db 0

.code

start:

invoke GetModuleHandle, NULL
mov hInstance, eax

invoke InitCommonControls

invoke DialogBoxParam, hInstance, ADDR dlgname, 0, ADDR WndProc, 0

invoke ExitProcess, eax

WndProc proc hWin:DWORD, uMsg:DWORD, wParam :DWORD, lParam :DWORD

.if uMsg == WM_CREATE



.elseif uMsg == WM_CLOSE || (uMsg == WM_COMMAND && wParam == IDCANCEL)
invoke EndDialog, hWin, 0


.endif

xor eax, eax
ret

WndProc endp

end start


Well, that's that. Now for the hard part, waiting for the responses :P

Vortex

dav7,

Your application runs fine on my XP. To reduce the size of the final executable, you can use Pelle's powefull linker Polink supplied with the latest release of the Masm32 package. This linker creates smaller executables, plus you can merge the sections to reduce the size of your application.

I was able to reduce the size of Notepad.exe to 1024 bytes. I removed manifest.xml and converted the resources to binary data.

; original code by dav7

.386
.model flat, stdcall
option casemap: none

include notepad.inc

.data

Rsrc    db 1,0,255,255,0,0,0,0,0,0,0,0,196,8,200,144
        db 1,0,10,0,10,0,113,0,58,0,0,0,0,0,78,0
        db 111,0,116,0,101,0,112,0,97,0,100,0,0,0,8,0
        db 188,2,0,1,77,0,83,0,32,0,83,0,72,0,69,0
        db 76,0,76,0,32,0,68,0,76,0,71,0,0,0,0,0
        db 0,0,0,0,0,0,0,0,68,16,161,80,0,0,0,0
        db 113,0,58,0,100,0,0,0,255,255,129,0,0,0,0,0

.code

    start:

        invoke  GetModuleHandle, NULL
        invoke  DialogBoxIndirectParam,eax,ADDR Rsrc,NULL,ADDR WndProc,NULL
        invoke  ExitProcess, eax
       
        WndProc PROC hWin:DWORD, uMsg:DWORD, wParam :DWORD, lParam :DWORD

            .if uMsg == WM_CREATE

            .elseif uMsg == WM_CLOSE

                invoke  EndDialog, hWin, 0

            .else

                mov eax, FALSE
                ret

            .endif

        mov eax, TRUE
        ret

        WndProc ENDP

END start


Building the executable :

\masm32\bin\ml /c /coff Notepad.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS /MERGE:.data=.text Notepad.obj

[attachment deleted by admin]

dav7

Cool, my app worked on 2 PCs other than my own :P

Oh yike... don't remove manifest.xml! :wink

Having manifest.xml in the app enables visual styles. "Visual styles?" Yeah, where your controls look really nice. Go and take your latest application with its buttons that look like it came out of Win98, put
~~
1 24
manifest.xml
~~
without the ~~ in your .rc script, take my manifest.xml (you don't need to change it, especially that publicKeyToken one, that's the same between all apps, and the descriptions don't need to be modified just for a test), add a call to InitCommonControls (it has no parameters) in a strategic location (at the top, before the dialog message loop seems a fine place to me), recompile and BOOM, XP style controls. :toothy

So no, manifest.xml stays in, even if just for a textbox. kthx. :bg

How did you convert the resources to binary? I want to convert manifest.xml to binary too :P

Vortex

Hi dav7,

To reduce the size of the exe as possible, I removed the manifest file. Naturally, using those files is a personal choice. To convert the .res file to binary, I have a tool named res2obj which has the additional capacity to convert bin files to MS COFF object modules :

http://www.masm32.com/board/index.php?topic=3510.0

Finally, I used Hutch's bintodb.exe tool to convert the bin file to a readable form displaying byte sequences.

res2obj cannot process compiled resource files ( .res ) including manifests. I am not sure if manifest.xml can be converted to binary resource data, I guess it's the operating system's duty to handle the xml data embedded in an executable so the OS would not detect it if the XML existed as binary data located in the .DATA section.

This time, instead of binary resource templates , I used your compiled resource script to build the application. The size is 2048 bytes with sections merged.

\masm32\bin\rc Resource.rc
\masm32\bin\ml /c /coff Notepad.asm
\masm32\bin\polink /SUBSYSTEM:WINDOWS /MERGE:.data=.text Notepad.obj Resource.res



[attachment deleted by admin]

dav7

Aha, now this is something I can like. Smaller file size AND the same features as before!

Time to modify my compile tool  :bg

Thanks very much for your help by the way, I really appreciate it :8)

Now I need to get into saving and loading of files. Where do I start with THAT? :eek

Vortex

Hi dav7,

Iczelion's Win32asm tutorial set is exactly what are you looking for :

http://win32assembly.online.fr/tutorials.html

Tutorial 12 : Memory Management and File I/O explains the basics of file management. The example code in this tutorial displays an edit control to load and save files :

http://win32assembly.online.fr/tut12.html