![]()  | 
	
 
  | 
		
			
  | 	
	
	
		
		|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
![]()  | 
	
	
| 
		 | 
	Опции темы | Поиск в этой теме | Опции просмотра | 
| 
		 
			 
			#1  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Есть куча примеров о там, как создать окно на WinAPI. Захотелось все это запихнуть все в один объект и не париться каждый раз с кодом, вот только с callback'ом возникли проблемы.  
		
	
		
		
		
		
		
	
		
		
	
	
	За код просьба сильно не пинать... Код: 
	{$C +}
program Project1;
uses
  Windows, SysUtils, Messages;
const WndClassName = 'PROJECT1WCN';
type TWinCallback = function(aHandle : THandle; aMsg : Longint; awParam : WPARAM; alParam : LPARAM): Longint of object; stdcall;
type
  TxForm = class(TObject)
    private
    fHandle : THandle;
    fWndClassEx : WNDCLASSEX;
    fWinCallback : TWinCallback;
    function WinCallback(aHandle : THandle; aMsg : Longint; awParam : WPARAM; alParam : LPARAM): Longint; stdcall;
    public
    constructor Create;
    destructor Destroy; override;
    end;
{$R *.res}
{---------------------- TxForm ----------------------------}
constructor TxForm.Create;
begin
inherited Create;
fWinCallback := WinCallback;
ZeroMemory(@fWndClassEx, sizeof(fWndClassEx));
with fWndClassEx do
 begin
 cbSize := sizeof(fWndClassEx);
 lpszClassName := WndClassName;
 lpfnWndProc   := @fWinCallback;
 Style         := CS_VREDRAW or CS_HREDRAW;
 hInstance     := hInstance;
 hIcon         := LoadIcon(hInstance, IDI_APPLICATION);
 hCursor       := LoadCursor(hInstance, IDC_ARROW);
 hbrBackground := COLOR_BTNFACE + 1;
 lpszMenuName  := nil;
 cbClsExtra    := 0;
 cbWndExtra    := 0;
 end;
ASSERT(RegisterClassEx(fWndClassEx)<>0, 'RegisterClassEx');
fHandle := CreateWindowEx(WS_EX_TOPMOST,
                          WndClassName,
                          'Proj1',
                          WS_OVERLAPPED,
                          100,
                          100,
                          200,
                          200,
                          0,
                          0,
                          hInstance,
                          nil);
ASSERT(fHandle <> 0, 'CreateWindowEx');
ShowWindow(fHandle, SW_SHOW);
UpdateWindow(fHandle);
end;
destructor TxForm.Destroy;
begin
  inherited;
end;
function TxForm.WinCallback(aHandle : THandle; aMsg : Longint; awParam : WPARAM; alParam : LPARAM): Longint;
begin
Result := DefWindowProc(aHandle, aMsg, awParam, alParam);
end;
{---------------- End of TxForm ---------------------------}
//==============================================
var xForm : TxForm;
begin
xForm := TxForm.Create;
end.Как правильно реализовать?  | 
| 
		 
			 
			#2  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Не уверен, что можно туда подсовывать метод объекта. 
		
	
		
		
		
		
		
	
		
		
	
	
	Попробуй подслвывать обычную процедуру.  | 
| 
		 
			 
			#3  
			
			
			
			
		 
		
		
	 | 
|||
		
		
  | 
|||
| 
	
	
		
			
			 Нашел в сети библиотеку WinLight, реализующую необходимый функционал. Выпилил ненужные мне функции и классы, вроде все работает 
		
	
		
		
		
		
		
	
		
		
	
	
	Код: 
	program Project1;
uses
  Windows,
  Messages,
  SysUtils;
type
  TWindowParams = record
    Caption     : PChar;
    Style       : DWord;
    ExStyle     : DWord;
    X           : Integer;
    Y           : Integer;
    Width       : Integer;
    Height      : Integer;
    WndParent   : THandle;
    WndMenu     : THandle;
    Param       : Pointer;
    WindowClass : TWndClass;
  end;
type
  TxForm = class(TObject)
    private
  fWndCallback: Pointer;
  fWndHandle  : THandle;
  FWndParams  : TWindowParams;
  function WindowCallback(hWnd: HWnd; Msg, WParam, LParam:Longint):Longint; stdcall;
    protected
  procedure   CreateWindowParams(var WindowParams: TWindowParams); virtual;
    public
  constructor Create;
  destructor  Destroy; override;
  property    WndHandle: THandle read FWndHandle;
  property    WndCallback: Pointer read FWndCallback;
  end;
{ TxForm }
constructor TxForm.Create;
begin
inherited Create;
  FWndCallback := VirtualAlloc(nil,12,MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  asm
    mov  EAX, Self
    mov  ECX, [EAX].TxForm.FWndCallback
    mov  word  ptr [ECX+0], $6858
    mov  dword ptr [ECX+2], EAX
    mov  word  ptr [ECX+6], $E950
    mov  EAX, OFFSET(TxForm.WindowCallback)
    sub  EAX, ECX
    sub  EAX, 12
    mov  dword ptr [ECX+8], EAX
  end;
  CreateWindowParams(FWndParams);
  RegisterClass(FWndParams.WindowClass);
  with FWndParams do
    CreateWindowEx(ExStyle, WindowClass.lpszClassName, Caption,
      Style, X, Y, Width, Height,
      WndParent, WndMenu, hInstance, Param
    );
end;
procedure TxForm.CreateWindowParams(var WindowParams: TWindowParams);
var
  WndClassName : string;
begin
  Str(DWord(Self), WndClassName);
  WndClassName := ClassName+'_'+WndClassName;
  with FWndParams.WindowClass do
  begin
    style         := CS_DBLCLKS;
    lpfnWndProc   := WndCallback;
    cbClsExtra    := 0;
    cbWndExtra    := 0;
    lpszClassName := PChar(WndClassName);
    hInstance     := hInstance;
    hIcon         := LoadIcon(0, IDI_APPLICATION);
    hCursor       := LoadCursor(0, IDC_ARROW);
    hbrBackground := COLOR_BTNFACE + 1;
    lpszMenuName  := '';
  end;
  with FWndParams do
  begin
    WndParent := 0;
    Caption := 'xForm';
    Style   := WS_OVERLAPPEDWINDOW or WS_VISIBLE;
    ExStyle := 0;
    X       := Integer(CW_USEDEFAULT);
    Y       := Integer(CW_USEDEFAULT);
    Width   := Integer(CW_USEDEFAULT);
    Height  := Integer(CW_USEDEFAULT);
    WndMenu := 0;
    Param   := nil;
  end;
end;
destructor TxForm.Destroy;
begin
   UnregisterClass(FWndParams.WindowClass.lpszClassName, hInstance);
    if IsWindow(FWndHandle) then DestroyWindow(FWndHandle);
    VirtualFree(FWndCallback, 0, MEM_RELEASE);
  inherited;
end;
function TxForm.WindowCallback(hWnd: HWnd; Msg, WParam,
  LParam: Integer): Longint;
var
  WindowMsg : TMessage;
begin
  if FWndHandle = 0 then FWndHandle := hWnd;
  case Msg of
  WM_CLOSE: PostQuitMessage(0);
  end;
  Result := DefWindowProc(hWnd, Msg, WParam,LParam);
end;
{$R *.res}
var xw : TxForm;
    msg : TMsg;
begin
xw := TxForm.Create;
while (getmessage(msg, 0, 0, 0)) do
 begin
 TranslateMessage(msg);
 DispatchMessage(Msg);
 end;
end.Ссылка на оригинал  |