The wpa.hhf bundled with the latest version of hla is not up to date. I think the CD version may be up to date, but I do not have it to say for sure.

Those who do not have the CD version may wish to update manually. To update, open the wpa.hhf into a text editor.

1>There is a missing semicolon at the end of this line: (bug?)

w.DrawText( _hdcOut_, _lpString_, _nCount_, _lpRect_, _uFormat_ )

2> TabbedTextOut keyword is missing, to add, copy and paste the following keyword between #TextOut and #GetCurrentPositionEx.


#keyword TabbedTextOut(_x_, _y_, _string_, _len_, _tCount_, _tabs_, _offset_);

w.TabbedTextOut( _hdcOut_, _x_, _y_, _string_, _len_, _tCount_, _tabs_, _offset_);


Make sure the variable _hdcOut_ matches the variable in the BeginPaint macro.
Posted on 2003-11-01 12:48:03 by Kain
Originally posted by Kain
The wpa.hhf bundled with the latest version of hla is not up to date. I think the CD version may be up to date, but I do not have it to say for sure.

Those who do not have the CD version may wish to update manually. To update, open the wpa.hhf into a text editor.

1>There is a missing semicolon at the end of this line: (bug?)

w.DrawText( _hdcOut_, _lpString_, _nCount_, _lpRect_, _uFormat_ )



Well, technically it isn't really needed because the DrawText macro invocation usually has a semicolon
after it. But for consistency's sake it should be there.



2> TabbedTextOut keyword is missing, to add, copy and paste the following keyword between #TextOut and #GetCurrentPositionEx.


#keyword TabbedTextOut(_x_, _y_, _string_, _len_, _tCount_, _tabs_, _offset_);

w.TabbedTextOut( _hdcOut_, _x_, _y_, _string_, _len_, _tCount_, _tabs_, _offset_);


Make sure the variable _hdcOut_ matches the variable in the BeginPaint macro.


I've added that now, thanks.
Actually, there are a lot of GDI macros still missing. I'm adding them as I work on the book.
Cheers,
Randy Hyde
Posted on 2003-11-02 01:31:29 by rhyde
>>I've added that now, thanks.
Actually, there are a lot of GDI macros still missing. I'm adding them as I work on the book.


I understand it can be a daunting task, especially with your work-load.


Question: If we write in hla, can be boast that our programs are written in assembly?

From what I have read so far, hla has many features similar to JAVA combined with the power of assembly.

I can say that I've learned a lot more about machine architecture after starting to read your books. Thanks for making them available for those on a ... limited budget.
Posted on 2003-11-02 13:43:31 by Kain


Question: If we write in hla, can be boast that our programs are written in assembly?


I don't see why not. HLA is an assembler at its core with a lot of HLL extensions just like masm but HLA takes it further. I am going to post some HLA code orginally posted by someone from the alt.lang.asm newsgroup to demonstrate that HLA can be used to write real assembly code. :)

 


unit Example;

// switch off HLA's stack frame stuff...
//
// and, yes, using "unit" and these two
// lines below is all that's needed to
// switch it _ALL_ off for the entire length
// of the source file...and, yes, you've
// got to ask yourself why everyone makes
// such a fuss about HLA's generation when
// it's so easily switched off...
//
?@noframe := true;
?@nodisplay := true;

// like "public main" in other assemblers...making the
// entry point visible (but, also, using the HLA thing
// of being able to use an "alias" inside the file,
// different to its real "outside" name, as seen by the
// linker :)...
//
procedure Main; @external("_HLAMain");

// this is our "extern" section for defining links to
// the Windows API used...would be a bunch of "extern"
// or "proto" statements in some other assembler :)
//
static

GetModuleHandleA: procedure;
@external("__imp__GetModuleHandleA@4");
LoadCursorA: procedure;
@external("__imp__LoadCursorA@8");
RegisterClassExA: procedure;
@external("__imp__RegisterClassExA@4");
CreateWindowExA: procedure;
@external("__imp__CreateWindowExA@48");
DestroyWindow: procedure;
@external("__imp__DestroyWindow@4");
ShowWindow: procedure;
@external("__imp__ShowWindow@8");
UpdateWindow: procedure;
@external("__imp__UpdateWindow@4");
PeekMessageA: procedure;
@external("__imp__PeekMessageA@20");
GetMessageA: procedure;
@external("__imp__GetMessageA@16");
TranslateMessage: procedure;
@external("__imp__TranslateMessage@4");
DispatchMessageA: procedure;
@external("__imp__DispatchMessageA@4");
WaitMessage: procedure;
@external("__imp__WaitMessage@0");
ExitProcess: procedure;
@external("__imp__ExitProcess@4");
DefWindowProcA: procedure;
@external("__imp__DefWindowProcA@16");
PostQuitMessage: procedure;
@external("__imp__PostQuitMessage@4");
CreateRoundRectRgn: procedure;
@external("__imp__CreateRoundRectRgn@24");
SetWindowRgn: procedure;
@external("__imp__SetWindowRgn@12");
GetWindowDC: procedure;
@external("__imp__GetWindowDC@4");
ReleaseDC: procedure; @external("__imp__ReleaseDC@8");

endstatic;

// Constant section; basically, everything in this section
// is just an "EQU" for all Windows constants used...
//
const

FALSE := $00000000;
TRUE := $00000001;

IDC_ARROW := $00007F00;

COLOR_3DFACE := $0000000F;

WS_OVERLAPPED := $00000000;
WS_CAPTION := $00C00000;
WS_SYSMENU := $00080000;
WS_MINIMIZEBOX := $00020000;

WS_OVERLAPPEDWINDOW := WS_OVERLAPPED | WS_CAPTION |
WS_SYSMENU | WS_MINIMIZEBOX;

CW_USEDEFAULT := $80000000;
HWND_DESKTOP := $00000000;

SW_SHOWNORMAL := $00000001;

PM_NOREMOVE := $00000000;

WM_CREATE := $00000001;
WM_DESTROY := $00000002;
WM_PAINT := $0000000F;
WM_QUIT := $00000012;
WM_ERASEBKGND := $00000014;
WM_NCCREATE := $00000081;
WM_NCDESTROY := $00000082;
WM_NCCALCSIZE := $00000083;
WM_NCHITTEST := $00000084;
WM_NCPAINT := $00000085;
WM_NCACTIVATE := $00000086;
WM_NCMOUSEMOVE := $000000A0;

WVR_VALIDRECTS := $00000400;

HTCAPTION := 2;

WindowWidth := 480;
WindowHeight := 320;

endconst;

// Actual code; Don't be fooled by "procedure Main" as
// _nothing_ is generated for the procedure but what
// you specifically see in the code...in this context,
// the "procedure" is actually acting like a code section
// wrapper only (you know, "_text segment" / "_text ends" ;)...
//
// Note, there are no other sections because the program's
// initialised data is delibrately thrown into the code
// section and the stack alone provides us writeable data
// (although, there's NO use of EBP in the code so following
// the stack is no fun...in fact, I might indeed have messed
// up counting those bytes or something...anyway, if I have,
// it's not in any "fatal" way that stops it running ;)...
//
procedure Main;
begin Main;

sub (48, esp);

cld ();
mov (&MainWndClass, esi);
mov (esp, edi);
mov (12, ecx);
rep.movsd();

pushd (0);
call (GetModuleHandleA);
mov (eax, ebx);
mov (ebx, [ esp + 20 ]);

pushd (IDC_ARROW);
pushd (0);
call (LoadCursorA);
mov (eax, [ esp + 28 ]);

pushd (esp);
call (RegisterClassExA);
add (48, esp);
cmp (eax, 0);
je Terminate;

pushd (0);
pushd (ebx);
pushd (0);
pushd (HWND_DESKTOP);
pushd (WindowHeight);
pushd (WindowWidth);
pushd (CW_USEDEFAULT);
pushd (CW_USEDEFAULT);
pushd (WS_OVERLAPPEDWINDOW);
pushd (0);
pushd (&ClassName);
pushd (0);
call (CreateWindowExA);
cmp (eax, 0);
je Terminate;
mov (eax, ebx);

pushd (SW_SHOWNORMAL);
pushd (ebx);
call (ShowWindow);

pushd (ebx);
call (UpdateWindow);

sub (28, esp);
MsgLoop:
pushd (PM_NOREMOVE);
pushd (0);
pushd (0);
pushd (0);
lea (ebx, [ esp + 16 ]);
pushd (ebx);
call (PeekMessageA);
cmp (eax, 0);
je NoMessage;

pushd (0);
pushd (0);
pushd (0);
pushd (ebx);
call (GetMessageA);
cmp (eax, 0);
je ExitProgram;

pushd (ebx);
call (TranslateMessage);

pushd (ebx);
call (DispatchMessageA);

NoMessage:

call (WaitMessage);

jmp MsgLoop;

ExitProgram:
mov ([ esp + 8 ], eax);
add (28, esp);

Terminate:
pushd (eax);
call (ExitProcess);

align(4);

WndProc:
mov (&MsgTable, edx);
sub (8, edx);

NextMsg:
add (8, edx);
mov ([ edx ], eax);

cmp (eax, 0);
je DefProcessing;

cmp ([ esp + 8 ], eax);
jne NextMsg;

jmp ([ edx + 4 ]);

DefProcessing:
pushd ([ esp + 16 ]);
pushd ([ esp + 16 ]);
pushd ([ esp + 16 ]);
pushd ([ esp + 16 ]);
call (DefWindowProcA);

ret (16);

align (4);

CreateProc:
xor (eax, eax);
ret (16);

align (4);

DestroyProc:
pushd (0);
call (PostQuitMessage);

xor (eax, eax);
ret (16);

align (4);

PaintProc:
xor (eax, eax);
ret (16);

align (4);

NcCreateProc:

pushd (24);
pushd (24);
pushd (WindowHeight);
pushd (WindowWidth);
pushd (0);
pushd (0);
call (CreateRoundRectRgn);

pushd (FALSE);
pushd (eax);
pushd ([ esp + 12 ]);
call (SetWindowRgn);

mov (TRUE, eax);
ret (16);

align (4);

NcDestroyProc:
xor (eax, eax);
ret (16);

align (4);

NcCalcSizeProc:
cmp ((type dword [ esp + 12 ]), FALSE);
je NoValidRect;

mov ([ esp + 16 ], ebx);

mov ([ ebx ], eax);
mov (eax, [ ebx + 16 ]);
add (8, eax);
mov (eax, [ ebx + 32 ]);

mov ([ ebx + 4 ], eax);
mov (eax, [ ebx + 20 ]);
add (24, eax);
mov (eax, [ ebx + 36 ]);

mov ([ ebx + 8 ], eax);
mov (eax, [ ebx + 24 ]);
sub (16, eax);
mov (eax, [ ebx + 40 ]);

mov ([ ebx + 12 ], eax);
mov (eax, [ ebx + 28 ]);
sub (32, eax);
mov (eax, [ ebx + 44 ]);

mov (WVR_VALIDRECTS, eax);
jmp EndOfNcCalcSizeProc;

NoValidRect:
xor (eax, eax);

EndOfNcCalcSizeProc:
ret (16);

align (4);

NcHitTestProc:
mov (HTCAPTION, eax);
ret (16);

align (4);

NcPaintProc:
xor (eax, eax);
ret (16);

align (4);

NcActivateProc:
xor (eax, eax);
ret (16);

// *** Data ***
// (Read-only data, as we're still in the code section)

align (4);

MainWndClass:
dword 48;
dword NULL;
dword &WndProc;
dword NULL;
dword NULL;
dword NULL;
dword NULL;
dword NULL;
dword COLOR_3DFACE + 1;
dword NULL;
dword &ClassName;
dword NULL;

MsgTable:
dword WM_CREATE, &CreateProc;
dword WM_DESTROY, &DestroyProc;
dword WM_PAINT, &PaintProc;
dword WM_NCCREATE, &NcCreateProc;
dword WM_NCDESTROY, &NcDestroyProc;
dword WM_NCCALCSIZE, &NcCalcSizeProc;
dword WM_NCHITTEST, &NcHitTestProc;
dword WM_NCPAINT, &NcPaintProc;
EndOfMsgTable:
dword WM_NCACTIVATE, &NcActivateProc;

ClassName: byte "Example", 0;

end Main;

end Example;


Posted on 2003-11-02 15:33:49 by Odyssey
Wow. That blew away any doubts I had about hla.

I have been interested in assembly for just over a week now and I must have power-downloaded every free assembler available, visited forums and such. Doing so of course, I ran into some people who do not consider hla a 'true assembler.'

I should have known better... today while browsing the FASM forum, I read a post by someone who said FASM is not a true assembler. I guess you just cannot please some people.

Now I'll go play around with that code you provided.
Posted on 2003-11-02 21:01:14 by Kain



I don't see why not. HLA is an assembler at its core with a lot of HLL extensions just like masm but HLA takes it further. I am going to post some HLA code orginally posted by someone from the alt.lang.asm newsgroup to demonstrate that HLA can be used to write real assembly code. :)





That looks like something Beth would post :-)
I never saw the original post... Thanks for reposting it here.

Cheers,
Randy Hyde
Posted on 2003-11-03 14:23:06 by rhyde

That looks like something Beth would post :-)
I never saw the original post... Thanks for reposting it here.


Yes it was posted by Beth but I don't remember which thread it was though.
Posted on 2003-11-03 19:58:55 by Odyssey

Wow. That blew away any doubts I had about hla.

I should have known better... today while browsing the FASM forum, I read a post by someone who


Amusing. Even Rene (Betov) calls FASM a true assembler.
Guess they must have been upset because it automatically optimizes displacements for you.
Cheers,
Randy Hyde
Posted on 2003-11-18 14:45:08 by rhyde