Нельзя использовать нестатический метод класса в качестве обратного вызова API. Вам нужно либо:
объявляет MagImageScalingCallback()
со спецификаторами class
и static
:
class function MagImageScalingCallback(hwnd: HWND; srcdata: Pointer;
srcheader: MAGIMAGEHEADER; destdata: Pointer; destheader: MAGIMAGEHEADER;
unclipped: TRect; clipped: TRect; dirty: HRGN): BOOL; stdcall; static;
делает MagImageScalingCallback()
автономной не-членом функцию.
Если вы посмотрите на пример, на котором основан ваш код, он использует метод class static
для обратного вызова WindowProc
API.
В любом случае, обратный вызов не может иметь неявный параметр Self
, поэтому, если вам нужен доступ к данным вашего класса внутри обратного вызова, вы можете передать указатель Self
вашего класса в обратный вызов, используя HWND
через Win32 API (Get|Set)WindowLong/Ptr(GWL_USERDATA)
или (Get|Set)Prop()
функции. Например:
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
Classes,
SysUtils,
Magnification;
type
THostWNDThread = class(TThread)
private
class function WindowProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; static;
class function MagImageScalingCallback(hwnd: HWND; srcdata: Pointer;
srcheader: MAGIMAGEHEADER; destdata: Pointer; destheader: MAGIMAGEHEADER;
unclipped: TRect; clipped: TRect; dirty: HRGN): BOOL; stdcall; static;
protected
procedure Execute; override;
public
end;
procedure THostWNDThread.Execute;
var
Msg: TMsg;
WndClass: WNDCLASS;
hWndMag: HWND;
begin
with WndClass do
begin
Style := 0;
lpfnWndProc := @WindowProc;
cbClsExtra := 0;
cbWndExtra := 0;
hInstance := HInstance;
hIcon := 0;
hCursor := LoadCursor(0, IDC_ARROW);
hbrBackground := COLOR_WINDOW;
lpszMenuName := nil;
lpszClassName := 'THostWNDThread';
end;
if not Windows.RegisterClass(FWndClass) then
RaiseLastOSError;
try
hWndMag := CreateWindow(WndClass.lpszClassName, nil, DesiredStyles, DesiredXPos, DesiredYPos, DesiredWidth, DesiredHeight, 0, 0, HInstance, nil);
if hWndMag = 0 then
RaiseLastOSError;
try
SetWindowLongPtr(hWndMag, GWL_USERDATA, LONG_PTR(Self));
if not MagSetImageScalingCallback(hWndMag, MagImageScalingCallback) then
raise Exception.Create('Cant set Scaling callback');
while GetMessage(Msg, hWndMag, 0, 0) > 0 do
begin
TranslateMessage(msg);
DispatchMessage(msg)
end;
finally
DestroyWindow(hWndMag);
end;
finally
Windows.UnregisterClass(WndClass.lpszClassName, HInstance);
end;
end;
class function THostWNDThread.WindowProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
// handle uMsg as needed...
Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
end;
class function THostWNDThread.MagImageScalingCallback(hwnd: HWND; srcdata: Pointer;
srcheader: MAGIMAGEHEADER; destdata: Pointer; destheader: MAGIMAGEHEADER;
unclipped: TRect; clipped: TRect; dirty: HRGN): BOOL; stdcall;
var
pThread: THostWNDThread;
begin
pThread := THostWNDThread(GetWindowLongPtr(hwnd, GWL_USERDATA));
// use pThread and parameters as needed ...
Result := True;
end;
var
Thread: THostWNDThread;
begin
try
Thread := THostWNDThread.Create(False);
Thread.WaitFor;
Thread.Free;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.