|

Win32/ FPC - Chapter 4 - by Delax
Welcome back! Last chapter we looked at a definition of a Window Class. This time we will take a look at what you can actually do with this Window
Class.
To use a Window Class you have to register it. This is actually quite easy and is done with one little line of code:
Result := RegisterClass(WindowClass) <> 0;
RegisterClass(WindowClass) registers a Window Class. As parameter we have to set a name of a valid Window Class. We store any messages in Result thus we are able to deal with any errors that may occur.
Right, so we got a registered Window Class. So what? Simple: now we can open a window with the new Window Class. As example we'll use
the FPC "Hello World" again.
{
$Id: winhello.pp,v 1.4 2002/09/07 15:06:35 peter Exp $
Copyright (c) 1996 by Charlie Calvert
Modifications by Florian Klaempfl
Standard Windows API application written in Object Pascal.
No VCL code included. This is all done on the Windows API
level.
}
{$APPTYPE GUI}
{$MODE DELPHI}
program WinHello;
uses
Strings, Windows;
const
AppName = 'WinHello';
function WindowProc(Window: HWnd; AMessage: UINT; WParam : WPARAM;
LParam: LPARAM): LRESULT; stdcall; export;
var
dc : hdc;
ps : paintstruct;
r : rect;
begin
WindowProc := 0;
case AMessage of
wm_paint:
begin
dc:=BeginPaint(Window,@ps);
GetClientRect(Window,@r);
DrawText(dc,'Hello world by Free Pascal',-1,@r,
DT_SINGLELINE or DT_CENTER or DT_VCENTER);
EndPaint(Window,ps);
Exit;
end;
wm_Destroy:
begin
PostQuitMessage(0);
Exit;
end;
end;
WindowProc := DefWindowProc(Window, AMessage, WParam, LParam);
end;
{ Register the Window Class }
function WinRegister: Boolean;
var
WindowClass: WndClass;
begin
WindowClass.Style := cs_hRedraw or cs_vRedraw;
WindowClass.lpfnWndProc := WndProc(@WindowProc);
WindowClass.cbClsExtra := 0;
WindowClass.cbWndExtra := 0;
WindowClass.hInstance := system.MainInstance;
WindowClass.hIcon := LoadIcon(0, idi_Application);
WindowClass.hCursor := LoadCursor(0, idc_Arrow);
WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
WindowClass.lpszMenuName := nil;
WindowClass.lpszClassName := AppName;
Result := RegisterClass(WindowClass) >< 0;
end;
{ Create the Window Class }
function WinCreate: HWnd;
var
hWindow: HWnd;
begin
hWindow := CreateWindow(AppName, 'Hello world program',
ws_OverlappedWindow, cw_UseDefault, cw_UseDefault,
cw_UseDefault, cw_UseDefault, 0, 0, system.MainInstance, nil);
if hWindow >< 0 then begin
ShowWindow(hWindow, CmdShow);
ShowWindow(hWindow, SW_SHOW);
UpdateWindow(hWindow);
end;
Result := hWindow;
end;
var
AMessage: Msg;
hWindow: HWnd;
begin
if not WinRegister then begin
MessageBox(0, 'Register failed', nil, mb_Ok);
Exit;
end;
hWindow := WinCreate;
if longint(hWindow) = 0 then begin
MessageBox(0, 'WinCreate failed', nil, mb_Ok);
Exit;
end;
while GetMessage(@AMessage, 0, 0, 0) do begin
TranslateMessage(AMessage);
DispatchMessage(AMessage);
end;
Halt(AMessage.wParam);
end.
{
$Log: winhello.pp,v $
Revision 1.4 2002/09/07 15:06:35 peter
* old logs removed and tabs fixed
Revision 1.3 2002/02/22 13:37:49 pierre
* fix problem if started through cygwin bash
}
Download the Source Code here
We are again only interested in a special part of the code. "Create the Window Class".
{ Create the Window Class }
function WinCreate: HWnd;
var
hWindow: HWnd;
begin
hWindow := CreateWindow(AppName, 'Hello world program',
ws_OverlappedWindow, cw_UseDefault, cw_UseDefault,
cw_UseDefault, cw_UseDefault, 0, 0, system.MainInstance, nil);
if hWindow >< 0 then begin
ShowWindow(hWindow, CmdShow);
ShowWindow(hWindow, SW_SHOW);
UpdateWindow(hWindow);
end;
Result := hWindow;
end;
Hmm, the title is quite confusing, but we are actually creating a Window here. Let's have a look what the SDK Reference has to say about creating windows.
CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam);
And, as usual, now the step-by-step explaination.
lpClassName: This is the name of the Window Class we want to use. As you (should!) remember, we gave our Window Class a name at the end.
lpWindowName: This is the title of your window.
dwStyle: Important. This defines the behavior of your window. You can define things like "Window is closed at startup", "Window is a Pop-Up", "Window has a scrollbar" and so on.
x/ y: These are the X/ Y coordinates of the top-left corner of your window. If it's not important where your window is located, take CW_USEDEFAULT and Windows will choose a place.
nWidth/ nHeight: This is the height and width of your window in pixel. CW_USEDEFAULT is the alternative. Important: The height and width of your window is including the scrollbars, window title and stuff like that. A window defined as 640x480 is NOT 640x480 inside, but the size of the complete window is 640x480!
hWndParent: This is a handle to the parent window (if there is one). Most of the applications will have the Windows Desktop as parent window. But think about error messages of your own application. These will have your application as parent.
hMenu: Here you can define a menu for your window. Nope, we won't do that for now.
hInstance: Again the handle of our application.
lpParam: These are advanced parameters for creating the window or starting your application.
So in theory this creates a window. But it's better to check than be sorry.
if hWindow >< 0 then begin
ShowWindow(hWindow, CmdShow);
ShowWindow(hWindow, SW_SHOW);
UpdateWindow(hWindow);
end;
Phew! And that's it. You know how to create a window. But don't get excited as you can't write Windows applications just yet. Only one little detail is missing: the event handling. Receiving and processing Windows messages, remember?
Delax/ Sundancer Inc.
[delax@sundancerinc.de]
Back to previous page
|