Problem with creating an API GUI Windows program with message loop
lazarus / 34-Windows
----------------------------------------------------------------------
Conrad · 2011-09-04 15:19
Hi all,
I'm new member of this forum. Previously I used TMT Pascal but now I
decided to try Lazarus environment.
As I usually wrote my Windows GUI programs using "clean" WINAPI
functions and message loop, I would like to know if it is possible in
Lazarus, too.
I have written the following code:
program Window1; uses Windows, Strings, Messages;
var Msg : TMsg;
Wnd : HWnd;
wc : TWndClass;
function WinProc(Window: HWND; Mess: UInt; WParam: WParam; LParam:
LParam ): UInt; stdcall;
begin
Result := 0;
case Mess of
WM_CLOSE: Result :=WinProc(Window, Mess, WParam, LParam);
WM_DESTROY: PostQuitMessage(0);
else
Result:=WinProc(Window, Mess, WParam, LParam);
end;
end;
begin
FillChar( wc, SizeOf( wc ), 0 );
with wc do
begin
style:=CS_HREDRAW + CS_VREDRAW;
lpfnWndProc:=@WinProc;
cbClsExtra:=0;
cbWndExtra:=0;
hInstance:=System.hInstance;
hCursor:=LoadCursor( THandle( NIL ), IDC_ARROW );
hbrBackGround := COLOR_WINDOW + 1;
lpszMenuName:=nil;
lpszClassName:='First GUI App';
end;
if RegisterClass( wc ) = 0 then Exit;
Wnd:=CreateWindow( wc.lpszClassName, 'ListView',
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 400, 0, 0,
HInstance, nil );
repeat
while GetMessage( Msg, 0, 0, 0 ) do
begin
TranslateMessage( Msg );
DispatchMessage( Msg );
end;
until Msg.Message = WM_QUIT;
end.
For the line: lpfnWndProc:=@WinProc;, the compiler reports the
following error:
window1.lpr(29,18) Error: Incompatible types: got "
" expected
""
Can anybody help me with this problem?
Thanks in advance
Conrad
----------------------------------------------------------------------
Leledumbo · 2011-09-04 15:31
Window procedure return value is HRESULT, not UINT. and:
QuoteWParam: WParam; LParam: LParamdoes it still work? it's supposed
to be an error due to duplicated identifier.
----------------------------------------------------------------------
Conrad · 2011-09-04 18:56
Unfortunately, problem still exists.
I forgot to mention that above code works fine under TMT (Framework)
Pascal.
Conrad
----------------------------------------------------------------------
felipemdc · 2011-09-04 19:17
Quote from: Conrad on September 04, 2011, 05:19:47 pmfunction
WinProc(Window: HWND; Mess: UInt; WParam: WParam; LParam: LParam ):
UInt; stdcall;
...
window1.lpr(29,18) Error: Incompatible types: got "" expected
""
The error is cristal clear in the compiler message ... the result
should be pointer sized and you are passing 4 bytes. Try:
function WinProc(Window: HWND; Mess: UInt; WParam: WParam; LParam:
LParam ): PtrUInt; stdcall;
----------------------------------------------------------------------
Leledumbo · 2011-09-04 22:22
Sorry, it should be LRESULT instead of HRESULT. Here's my old pure
Windows API code that compiles and works:
Code: Text [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i program
WinTemplate; {$apptype gui} uses Windows; var hMain: HWnd; ms:
MSG; active: Boolean; Width, Height: Word; procedure Error(s:
String); begin MessageBox(hMain, @s[1], nil, MB_OK); Halt(1);
end; procedure Fail(s: String); begin MessageBox(hMain, @s[1],
'Failure', MB_OK); end; function WinProc(h: HWnd; ms: DWORD; wp:
WPARAM; lp: LPARAM): LRESULT; stdcall; export; begin case ms of
WM_CREATE: active := True; WM_DESTROY: active := False;
end; WinProc := DefWindowProc(h, ms, wp, lp); end; procedure
WinReg; var wc: WNDCLASS; begin with wc do begin Style :=
cs_hRedraw or cs_vRedraw; lpfnWndProc := WndProc(@WinProc);
cbClsExtra := 0; cbWndExtra := 0; hInstance :=
System.MainInstance; hIcon := LoadIcon(hInstance,
idi_Application); hCursor := LoadCursor(0, idc_Arrow);
hbrBackground := COLOR_BTNSHADOW; lpszMenuName := nil;
lpszClassName := 'Main'; end; if RegisterClass(wc) = 0 then
Error('Window Registration Failed!'); end; procedure WinCreate;
begin hMain := CreateWindowEx(WS_EX_APPWINDOW, 'Main', 'WinApp',
WS_OVERLAPPEDWINDOW, (1024 - Width) div 2, (768 - Height) div
2, Width, Height, 0, 0, System.MainInstance, nil); if hMain = 0
then Error('Window Creation Failed!'); ShowWindow(hMain,
SW_SHOW); UpdateWindow(hMain); end; procedure WinDestroy;
begin DestroyWindow(hMain); end; begin WinReg; Width := 640;
Height := 480; WinCreate; repeat if PeekMessage(@ms, 0, 0, 0, 0)
then begin GetMessage(@ms, 0, 0, 0); TranslateMessage(ms);
DispatchMessage(ms); end; until not active; WinDestroy;end.
----------------------------------------------------------------------
avra · 2011-09-05 08:32
If you really have some reason to avoid Lazarus LCL for Windows GUI
development, then you could take a look at KOL. It could save you a
lot of time.
QuoteKOL - Key Objects Library is a set of objects to develop power
(but small) 32 bit Windows GUI applications using Delphi but without
VCL (or Free Pascal). It is distributed free of charge, with source
code.
http://kolmck.net
http://kolmck.net/e_kolmck.htm
----------------------------------------------------------------------
Conrad · 2011-09-05 18:45
Thanks for your all replies.
The following syntax: lpfnWndProc := WndProc(@WinProc) instead of
previous "lpfnWndProc:=@WinProc" solved my problem.
It is a difference between TMT Pascal and Lazarus which I didn't know
before (time to start reading manual
Conrad
----------------------------------------------------------------------
marcov · 2011-09-06 07:15
Quote from: Conrad on September 05, 2011, 08:45:41 pmThanks for your
all replies.
The following syntax: lpfnWndProc := WndProc(@WinProc) instead of
previous "lpfnWndProc:=@WinProc" solved my problem.
That is a hack. The return types don't match and you force it anyway.
QuoteIt is a difference between TMT Pascal and Lazarus which I didn't
know before (time to start reading manual
Most probably it is a 32-bit vs 64-bit problem. Your TMT code wasn't
entirely 64-bit clean, and my guess is that now you are using a 64-bit
compiler
----------------------------------------------------------------------
Conrad · 2011-09-06 12:11
You are absolutely right. I used 32-bit TMT pascal which is "a bit"
obsolete nowadays.
In fact, I don't have much experience in 64-bit programming, but in
future I would
like to convert one of my big TMT pascal projects (around 30.000 lines
of code) to 64-bit platform.
That is why I'm interested in Lazarus.
Anyway, thanks for help.
Conrad
----------------------------------------------------------------------
marcov · 2011-09-06 16:01
Study Leledumbo's 2nd post. The returnvalue should probably be
LRESULT.
----------------------------------------------------------------------
Conrad · 2011-09-07 18:42
One more question:
Now, I try to create simple dialog box with icon (both defined in
external resource file and compiled with Microsoft rc.exe compiler).
Everything works fine under my old TMT Pascal but I can't get the
dialog visible under Lazarus, however I can see the program running in
memory.
Does Lazarus accept resource files compiled by Microsoft rc.exe
compiler?
My code is below:
Code: [Select]
program Dlgbox;
{$apptype gui}
uses Windows, Messages;
{$R dlgbox.res}
var
DialogProc : HWnd;
Mess : TMsg;
const
MAIN_DIALOG = 200;
function DialogPr( Dialog : HWnd; ms: DWORD; wp: Wparam; lp: Lparam ):
LResult; stdcall; export;
begin
Result:=0;
case ms of
WM_COMMAND : begin
case LoWord( wp ) of
IDOK : SendMessage( Dialog,
WM_CLOSE, 0, 0 );
end
end;
WM_CLOSE : DestroyWindow( Dialog );
WM_DESTROY : begin
PostQuitMessage( 0 );
Result:=0;
end;
end
end;
begin
DialogProc:=CreateDialog( hInstance, MakeIntResource( MAIN_DIALOG ),
0, @DialogPr );
SendMessage( DialogProc, WM_SETICON, ICON_SMALL OR ICON_BIG,
LoadIcon( hInstance, MAKEINTRESOURCE( 100 )) );
ShowWindow( DialogProc, SW_RESTORE );
repeat
while GetMessage( @Mess, 0, 0, 0 ) do
begin
TranslateMessage( Mess );
DispatchMessage( Mess );
end;
until Mess.Message = WM_QUIT;
end.
==============
and resource file:
#include "afxres.h"
100 ICON "favourite.ico"
200 DIALOG MOVEABLE LOADONCALL DISCARDABLE 335, 123, 408, 102
STYLE DS_FIXEDSYS |DS_SETFONT |WS_POPUP |WS_VISIBLE |WS_SYSMENU
|WS_THICKFRAME |WS_MAXIMIZEBOX |WS_MINIMIZEBOX |WS_CAPTION
CAPTION "My Dialog Box"
FONT 8, "Ms Shell Dlg"
LANGUAGE LANG_NEUTRAL, 0
BEGIN
CONTROL "Close",IDOK,"BUTTON",BS_DEFPUSHBUTTON |BS_VCENTER
|BS_CENTER |WS_CHILD |WS_TABSTOP |WS_VISIBLE ,175,70,73,23
END
Conrad
----------------------------------------------------------------------
felipemdc · 2011-09-09 06:17
Quote from: Conrad on September 07, 2011, 08:42:00 pmDoes Lazarus
accept resource files compiled by Microsoft rc.exe compiler?
No. Pass the rc file for Free Pascal and it will use windres to
compile it:
{$R dlgbox.rc}