저는 Delphi로 작성한 수업을 Lazarus에 이식하려고합니다. 연결된 USB 장치를 감지하기 위해 WM_DEVICECHANGE
에 의존합니다. Delphi에서 완벽하게 작동하는 동안 Windows 메시지를 수신하도록 구성 요소를 가져올 수 없습니다.나사로에서 Windows 메시지 수신 및 처리
AllocateHwnd
이 Free Pascal의 자리 표시자인 것을 알고 난 후에, 나는 LCL이 그 목적을 위해 무엇을하는지 모방하기 시작했습니다.
TUSB = class(TComponent)
private
FHandle: HWND;
procedure WndProc(var Msg: TMessage);
procedure AllocHandle(Method: TWndMethod);
public
constructor Create(AOwner: TComponent);
end;
.
.
.
procedure CallbackAllocateHWnd(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam); stdcall;
var
Msg: TMessage;
PMethod: ^TWndMethod;
begin
FillChar(Msg{%H-}, SizeOf(Msg), #0);
Msg.msg := uMsg;
Msg.wParam := wParam;
Msg.lParam := lParam;
PMethod := {%H-}Pointer(GetWindowLong(ahwnd, GWL_USERDATA));
if Assigned(PMethod) then PMethod^(Msg);
Windows.DefWindowProc(ahwnd, uMsg, wParam, lParam);
end;
procedure TUSB.AllocHandle(Method: TWndMethod);
var
PMethod: ^TWndMethod;
begin
FHandle := Windows.CreateWindow(PChar('STATIC'), '', WS_OVERLAPPED, 0, 0, 0, 0, 0, 0, MainInstance, nil);
if Assigned(Method) then
begin
Getmem(PMethod, SizeOf(TMethod));
PMethod^ := Method;
SetWindowLong(FHandle, GWL_USERDATA, {%H-}PtrInt(PMethod));
end;
SetWindowLong(FHandle, GWL_WNDPROC, {%H-}PtrInt(@CallbackAllocateHWnd));
end;
constructor TUSB.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
AllocHandle(@WndProc);
end;
이 나에게 유효한 창 핸들을 제공하지만 CallbackAllocateHWnd
가 호출되지 않습니다. 이 항목은 Windows 전용이며 이식 가능하지 않다는 것을 알고 있지만, 지금은 걱정할 필요가 없습니다. 난 그냥 TComponent
클래스를 파생하고 Windows 메시지를 받고 처리 할 수 있습니다. 델파이에서도 똑같은 코드 라인이 작동합니다.
편집 : 또한 HWND_MESSAGE를 hWndParent
으로 시도했습니다.
편집 2 : SetWindowLong(FHandle, GWL_WNDPROC, {%H-}PtrInt(@CallbackAllocateHWnd));
다음에 오는 호출이 잘못된 색인을 의미하는 것을 발견했습니다. 심지어 거기에 GetWindowLong
시도하고 나에게 같은 오류를 준다!
allochandle이 실행됩니까? afaik setwindowlong은 이전 wndproc을 저장하고 wndproc에서 호출합니다. –
FHandle은 AllocHandle을 실행 한 후에 유효한 창 핸들을 가지고 있지만 메시지를 보낼 때 내 사용자 지정 WndProc가 트리거되지 않습니다. –