Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

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

Useful Links









Link to us