2017-04-08 18 views
0

저는 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 시도하고 나에게 같은 오류를 준다!

+0

allochandle이 실행됩니까? afaik setwindowlong은 이전 wndproc을 저장하고 wndproc에서 호출합니다. –

+0

FHandle은 AllocHandle을 실행 한 후에 유효한 창 핸들을 가지고 있지만 메시지를 보낼 때 내 사용자 지정 WndProc가 트리거되지 않습니다. –

답변

1

그냥이 페이지에 끝나는 다른 사람의 참조 : 나사로 포럼에서 아이디어를 얻는 후

, 나는 uses 절에 LCLIntf 장치를 포함하는 문제를 해결할 수 있음을 발견했다. 나는 런타임에 코드를 따라 갔고 결국 Windows.SetWindowLongPtrW을 호출했다. 두 번째 호출을 SetWindowLong으로 바꾸는 것만으로도 이제는 Windows.SetWindowLongPtrW으로 바뀝니다.