![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Оконная процедура как метод класса... [D5, Win95/98]
SunSay © (2003-02-18 21:54:00)Вообщем у меня такая проблема...
Программирование через API Виндуз
Мне нужно сделать класс TForm, который умеет создавать окно,
и перехватывать сообщения:
uses
windows,
messages;
type
TWndMethod = function (hWindow: HWND; Msg: UINT; wParam: wParam; lParam: lParam):LRESULT; stdcall;
TForm = class (TObject)
private
FLeft,
FTop,
FWidth,
FHeight : Word;
...
FHandle : HWND;
...
function WndProc(hWindow: HWND; Msg: UINT; wParam: wParam; lParam: lParam):LRESULT; stdcall;
public
constructor Create(...);
...
WindowProc: TWndMethod;
...
procedure OnCreate; Virtual;
end;
function TForm.WndProc;
begin
case Msg of
...
WM_CREATE: OnCreate;
...
end;
end;
Вся проблема заключается в том, что я не могу назначить процедуру WndProc класса TForm
как оконную процедуру для создаваемого объекта (окна).
constructor TForm.Create(...);
begin
...
WindowProc := @WndProc; //ругается что нельзя назначить метод класса как оконную процедуру
...
WndClassInfo.lpfnWndProc := @WindowProc;
...
end;
Я пытался сделать что-то типа
type
TWndMethod = function (hWindow: HWND; Msg: UINT; wParam: wParam; lParam: lParam):LRESULT of object;
Но тогда программа вообще не может получить хендл создаваемого окна
(всмысле ничче не создается).
Уже три дня над этой {EQYTQ мучаюсь (если бы на исходниках VCL
дельфи стоял счетчик посещений, он наверняка бы у меня зашкалил).
Подскажите, пожалуйста, как можно решить эту проблему (если вы поняли о чем речь).
Буду очень благодарен!!!
_________________________
Да прибудет с тобой святой Kernel32
SunSay (2003-02-20 17:37:00) [1]Thanx
P.S. Большое
Digitman (2003-02-19 10:06:00) [2]uses Forms, ...
...
TMyForm = class (TObject)
private
hWnd: THandle;
procedure MyWndMethod(var message: TMessage);
public
constructor Create;
destructor Destroy; override;
...
end;
...
constructor TMyForm.Create;
begin
inherited Create;
hWnd := AllocateHWnd(MyWndMethod);
end;
destructor TMyForm.Destroy;
begin
DeallocateHWnd(hWnd);
inherited Destroy;
end;
procedure TMyForm.MyWndMethod(var message: TMessage);
begin
Dispatch(Message.Msg);
end;
p.s.
если нужно избежать подключение модуля Forms к проекту, просто перенеси декларацию/реализацию ф-ций Allocate/DeallocateHWnd (и всего, что с ними связано) в свой модуль
Юрий Зотов (2003-02-19 08:43:00) [3]> ругается что нельзя назначить метод класса как оконную
> процедуру
Правильно ругается, у них разные списки параметров. И не надо делать ее методом класса - сделайте ее обычной функцией и назначайте без проблем. Как в примере от PVOzerski.
PVOzerski (2003-02-19 06:08:00) [4]Я когда-то примерялся сделать мини-VCL для FreePascal, пошел "своим путем", не как Borland. Вот кусочки, может, пригодятся. Правда, пока не thread-safe, надо бы LastWinObject улучшить.
...
var
LastWinObject:pointer;
function APIwndproc(hwnd:tHandle;msg,wp,lp:cardinal):longint;stdcall;
var
M:tMessage;
W:tWindow;
begin
M.msg:=msg;
M.WParam:=wp;
M.LParam:=lp;
W:=tWindow(GetWindowLong(hwnd,GWL_USERDATA));
if W=nil then
begin
SetWindowLong(hWnd,GWL_USERDATA,longint(LastWinObject));
W:=tWindow(LastWinObject);
W.fHandle:=hwnd;
end;
W.WndProc(M);
Result:=M.Result;
end;
constructor tWindow.Create;
var
wc:WndClass;
i,l:longint;
found:boolean;
begin
...
_classname:=ClassName;//поле класса tWindow
...
LastWinObject:=pointer(self);
CreateWindow{Ex}({0,}@_classname[1],"",WndStyle,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
hInstance,
nil);
end;
...
procedure tWindow.WndProc(var msg:tMessage);
begin
Dispatch(msg);
end;
....
ION T (2003-02-18 23:39:00) [5]Методы всегда расчитывают на неявный параметр указывающий на экземпляр класса - self....винда на него не расчитывает.....
_________________________
Да пребудет с тобой святой bzImage
Ihor Osov'yak (2003-02-18 22:08:00) [6]forms.AllocateHWnd как источник идеи подойдет?