Hi All,

Just a couple of quick questions - I am doing some tutorials to get upto speed on HLA, currently Iczelion's "Simple Window" tutorial. Firstly I'm I correct in assuming that win32.hhf is now named w.hhf. Secondly - in this tutorial the procedure WndProc is defined and called, however in the w.hhf header file the procedure WndProc differs in syntax and variable declaration. I am correct in assuming that the syntax error during "build" is caused by the WndProc in the tutorial not being indentical to WndProc in the w.hhf.

The "build" error specifically is -

Error in file "CV.hla" at line 28 :
syntax error, unexpected UndefID.
Near: << nodisplay >>


Posted on 2003-12-21 15:49:24 by Krug

Yes you're right win32.hhf is now w.hhf. I think you may be using an old win32 HLA example program. The 'nodisplay' option should be '@nodisplay'. Some of iczelion's tutorials have been converted to HLA syntax. They are probably in the examples package at webster.

Here's the code for the tut03:


// Iczelion's tutorial #3: A Simple Window

program aSimpleWindow;
#include( "w.hhf" ) // Standard windows stuff.
#include( "strings.hhf" ) // Defines HLA string routines.
#include( "memory.hhf" ) // Defines "NULL" among other things.
#include( "args.hhf" ) // Command line parameter stuff.
#include( "conv.hhf" )

hInstance: dword;
CommandLine: string;


ClassName: string := "SimpleWinClass";
AppName: string := "Our First Window";

static GetLastError:procedure; @external( "__imp__GetLastError@0" );

// The window procedure. Since this gets called directly from
// windows we need to explicitly reverse the parameters (compared
// to the standard STDCALL declaration) in order to make HLA's
// Pascal calling convention compatible with Windows.
// This is actually a function that returns a return result in
// EAX. If this function returns zero in EAX, then the event
// loop terminates program execution.

procedure WndProc( hWnd:dword; uMsg:uns32; wParam:dword; lParam:dword );

begin WndProc;

// If the WM_DESTROY message comes along, then we've
// got to post a message telling the event loop that
// it's time to quit the program. The return value in
// EAX must be false (zero). The GetMessage function
// will return this value to the event loop which is
// the indication that it's time to quit.

if( uMsg = w.WM_DESTROY ) then

w.PostQuitMessage( 0 );
sub( eax, eax );


// If a WM_DESTROY message doesn't come along,
// let the default window handler process the
// message. Whatever (non-zero) value this function
// returns is the return result passed on to the
// event loop.

w.DefWindowProc( hWnd, uMsg, wParam, lParam );


end WndProc;

// WinMain-
// This is the "main" windows program. It sets up the
// window and then enters an "event loop" processing
// whatever messages are passed along to that window.
// Since our code is the only code that calls this function,
// we'll use the Pascal calling conventions for the parameters.

procedure WinMain
hInst: dword;
hPrevInst: dword;
CmdLine: string;
CmdShow: dword

msg: w.MSG;
hwnd: dword;

begin WinMain;

// Set up the window class (wc) object:

mov( @size( w.WNDCLASSEX ), wc.cbSize );
mov( w.CS_HREDRAW | w.CS_VREDRAW, wc.style );
mov( &WndProc, wc.lpfnWndProc );
mov( 0, wc.cbClsExtra );
mov( 0, wc.cbWndExtra );

mov( hInstance, wc.hInstance );
mov( w.COLOR_WINDOW+1, wc.hbrBackground );
mov( NULL, wc.lpszMenuName );
mov( ClassName, wc.lpszClassName );

// Get the icons and cursor for this application:

w.LoadIcon( NULL, val w.IDI_APPLICATION );
mov( eax, wc.hIcon );
mov( eax, wc.hIconSm );

w.LoadCursor( NULL, val w.IDC_ARROW );
mov( eax, wc.hCursor );

// Okay, register this window with Windows so it
// will start passing messages our way. Once this
// is accomplished, create the window and display it.

w.RegisterClassEx( wc );
mov( eax, hwnd );

w.ShowWindow( hwnd, w.SW_SHOWNORMAL );
w.UpdateWindow( hwnd );

// Here's the event loop that processes messages
// sent to our window. On return from GetMessage,
// break if EAX contains false and quit the
// program.


w.GetMessage( msg, NULL, 0, 0 );
breakif( !eax );
w.TranslateMessage( msg );
w.DispatchMessage( msg );

mov( msg.wParam, eax );

end WinMain;

begin aSimpleWindow;

// Get this process' handle:

w.GetModuleHandle( NULL );
mov( eax, hInstance );

// Get a copy of the command line string passed to this code:

mov( arg.cmdLn(), CommandLine );

WinMain( hInstance, NULL, CommandLine, w.SW_SHOWDEFAULT );

// WinMain returns a return code in EAX, exit the program
// and pass along that return code.

w.ExitProcess( eax );

end aSimpleWindow;

Posted on 2003-12-21 16:03:19 by Odyssey

Thanks for the reply , program now assembling and when run windows gives a dialog box with message "Unhandled Exception Error" - Am I missing something obvious?

NB This happens with tutorial 4 as well


Posted on 2003-12-22 05:52:34 by Krug


Thanks for the reply , program now assembling and when run windows gives a dialog box with message "Unhandled Exception Error" - Am I missing something obvious?

NB This happens with tutorial 4 as well



What OS are you using?
I cut and pasted the sample program given earlier and it compiled and ran just fine under XP.
Randy Hyde
Posted on 2003-12-23 10:42:20 by rhyde
Works under win98 and winME as well, copied and pasted exactly as shown.
Posted on 2003-12-23 13:13:21 by Kain

Currently running XP Professional. Using RadASM as IDE, when using run instruction (from Make menu) in RadASM the "Unhandled Exception Error" dialog box appears and the simple window does not, however went to command prompt and ran tutorial3.exe and the simple window appeared with no error message. Seems strange - any thoughts on why error message is generated when using RadASM?


Posted on 2003-12-23 13:23:49 by Krug