Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];

Вниз

Макет TAppAPI   Найти похожие ветки 

 
Sphinx   (2005-01-05 15:23) [0]


type
 TAppEngine = class
   private
     FAppName:       PChar;
     FAppTitle:      PChar;
     FAppHandle:     THandle;
     FScreenWidth:   Word;
     FScreenHeight:  Word;
     FAppActive:     Boolean;
     FAppRun:        Boolean;

     function FWinCreate: HResult;
     procedure WMButtonDown (var aMsg: TMessage); message WM_KEYDOWN;
   protected
   published
   public
     property Active: Boolean read FAppActive;
     property Run: Boolean read FAppRun;

     constructor Create(AppName, AppTitle: PChar; ScreenWidth, ScreenHeight: Word);
     destructor Destroy; override;
     function GetHandle: THandle;
 end;

function WindowProc(iHandle: THandle; aMSG: Cardinal;
 wParam: Cardinal; lParam: Integer): Integer; stdcall;
begin
 Result := DefWindowProc(iHandle, aMSG, wParam, lParam);
end;

constructor TAppEngine.Create(AppName, AppTitle: PChar; ScreenWidth, ScreenHeight: Word);
begin
 FAppRun:=False;
 FAppActive:=False;
 if (AppName="") or (AppTitle="") then Exit;
 FAppName:=AppName;
 FAppTitle:=AppTitle;
 FScreenWidth:=ScreenWidth;
 FScreenHeight:=ScreenHeight;
 if  FWinCreate<>S_OK then Exit;
 FAppRun:=True;
 inherited Create;
end;

function TAppEngine.FWinCreate: HRESULT;
var
 // &#241;&#242;&#240;&#243;&#234;&#242;&#243;&#240;&#224; &#238;&#239;&#232;&#241;&#251;&#226;&#224;&#254;&#249;&#224;&#255; &#239;&#224;&#240;&#224;&#236;&#229;&#242;&#240;&#251; &#241;&#238;&#231;&#228;&#224;&#226;&#224;&#229;&#236;&#238;&#227;&#238; &#236;&#229;&#237;&#254;
 WinClass:   TWndClass;

 Instance:   HWnd;
begin
// &#238;&#239;&#240;&#229;&#228;&#229;&#235;&#229;&#237;&#232;&#229; &#239;&#224;&#240;&#224;&#236;&#229;&#242;&#240;&#238;&#226; &#241;&#238;&#231;&#228;&#224;&#226;&#224;&#229;&#236;&#238;&#227;&#238; &#238;&#234;&#237;&#224;

 Instance:=HInstance;
 // &#238;&#239;&#240;&#229;&#228;&#229;&#235;&#229;&#237;&#232;&#229; &#234;&#235;&#224;&#241;&#241;&#224;
 WinClass.lpszClassName:=FAppName;
 // &#243;&#234;&#224;&#231;&#224;&#237;&#232;&#229; &#239;&#240;&#238;&#246;&#229;&#228;&#243;&#240;&#251; &#228;&#235;&#255; &#238;&#225;&#240;&#224;&#225;&#238;&#242;&#234;&#232; &#239;&#240;&#232;&#245;&#238;&#228;&#255;&#249;&#232;&#233; &#241;&#238;&#225;&#251;&#242;&#232;&#233;
 WinClass.lpfnWndProc:=@WindowProc;
 // &#241;&#242;&#232;&#235;&#252; &#238;&#234;&#237;&#224;
 WinClass.style:=CS_VREDRAW or CS_HREDRAW;
 // &#243;&#234;&#224;&#231;&#224;&#242;&#229;&#235;&#252; &#236;&#238;&#228;&#243;&#235;&#255;
 WinClass.hInstance:=Instance;
 // &#232;&#234;&#238;&#237;&#234;&#224; &#239;&#240;&#232;&#235;&#238;&#230;&#229;&#237;&#232;&#255;
 WinClass.hIcon:=LoadIcon(Instance, MakeIntResource("ICON"));
 // &#234;&#243;&#240;&#241;&#238;&#240; &#239;&#240;&#232;&#235;&#238;&#230;&#229;&#237;&#232;&#255;
 WinClass.hCursor:=LoadCursor(0, IDC_ARROW);
 // &#244;&#238;&#237;&#238;&#226;&#251;&#233; &#246;&#226;&#229;&#242; &#238;&#234;&#237;&#224;
 WinClass.hbrBackground:=($000000);
 // &#228;&#238;&#239;&#238;&#235;&#237;&#232;&#242;&#229;&#235;&#252;&#237;&#251;&#229; &#239;&#224;&#240;&#224;&#236;&#229;&#242;&#240;&#251; &#237;&#229; &#237;&#243;&#230;&#237;&#251;&#229; &#226; &#228;&#224;&#237;&#237;&#238;&#236; &#239;&#240;&#232;&#235;&#238;&#230;&#229;&#237;&#232;&#232;
 WinClass.lpszMenuName:=nil;
 WinClass.cbClsExtra:=0;
 WinClass.cbWndExtra:=0;
 // &#239;&#238;&#239;&#251;&#242;&#234;&#224; &#231;&#224;&#240;&#229;&#227;&#229;&#241;&#242;&#240;&#232;&#240;&#238;&#226;&#224;&#242;&#252; &#234;&#235;&#224;&#241;&#241; &#239;&#240;&#232;&#235;&#238;&#230;&#229;&#237;&#232;&#255;
 if (RegisterClass(WinClass)=0) then
 begin
   // &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#224;&#246;&#232;&#255; &#239;&#240;&#238;&#226;&#224;&#235;&#229;&#237;&#224;,
   Result:=E_FAIL;
   Exit;
 end;
 // &#241;&#238;&#231;&#228;&#224;&#237;&#232;&#229; &#238;&#234;&#237;&#224; &#239;&#240;&#238;&#227;&#240;&#224;&#236;&#236;&#251;
 FAppHandle := CreateWindowEx
  (WS_EX_APPWINDOW ,  // &#240;&#224;&#241;&#248;&#232;&#240;&#229;&#237;&#237;&#251;&#233; &#241;&#242;&#232;&#235;&#252; &#238;&#234;&#237;&#224;
   FAppName,                      // &#232;&#236;&#255; &#234;&#235;&#224;&#241;&#241;&#224;
   FAppTitle,                     // &#231;&#224;&#227;&#238;&#235;&#238;&#226;&#238;&#234; &#238;&#234;&#237;&#224;
   WS_POPUP,                      // &#241;&#242;&#232;&#235;&#252; &#238;&#234;&#237;&#224;
   0,                             // &#235;&#229;&#226;&#224;&#255; &#239;&#238;&#231;&#232;&#246;&#232;&#255; &#238;&#234;&#237;&#224;
   0,                             // &#239;&#240;&#224;&#226;&#224;&#255; &#239;&#238;&#231;&#232;&#246;&#232;&#255; &#238;&#234;&#237;&#224;
   FScreenWidth,                  // &#248;&#232;&#240;&#232;&#237;&#224; &#238;&#234;&#237;&#224;
   FScreenHeight,                 // &#226;&#251;&#241;&#238;&#242;&#224; &#238;&#234;&#237;&#224;
   0,                             // &#238;&#242;&#237;&#238;&#248;&#229;&#237;&#232;&#229; &#234; &#227;&#235;&#224;&#226;&#237;&#238;&#236;&#243; &#238;&#234;&#237;&#243;
                                  // 0-&#227;&#235;&#224;&#226;&#237;&#238;&#229; &#238;&#234;&#237;&#238;
   0,                             // &#236;&#229;&#237;&#254; &#239;&#240;&#232;&#235;&#238;&#230;&#229;&#237;&#232;&#255;
   Instance,                      // &#243;&#234;&#224;&#231;&#224;&#242;&#229;&#235;&#252; &#236;&#238;&#228;&#243;&#235;&#255;
   nil );                         // &#239;&#224;&#240;&#224;&#236;&#229;&#242;&#240;&#251; &#238;&#234;&#237;&#224;
 // &#229;&#241;&#235;&#232; &#237;&#229; &#243;&#228;&#224;&#235;&#238;&#241;&#252; &#241;&#238;&#231;&#228;&#224;&#242;&#252; &#238;&#234;&#237;&#238;
 if (FAppHandle = 0) then
 begin
   Result := E_FAIL;
   Exit;
 end;
 // &#239;&#238;&#234;&#224;&#231;&#224;&#242;&#252; &#238;&#234;&#237;&#238;
 ShowWindow(FAppHandle, SW_SHOW);

 // &#239;&#229;&#240;&#229;&#234;&#235;&#254;&#247;&#229;&#237;&#232;&#229; &#224;&#234;&#242;&#232;&#226;&#237;&#238;&#227;&#238; &#238;&#234;&#237;&#224;
 SetActiveWindow(FAppHandle);

 // &#239;&#240;&#238;&#240;&#232;&#241;&#238;&#226;&#224;&#242;&#252; &#241;&#238;&#228;&#229;&#240;&#230;&#232;&#236;&#238;&#229; &#238;&#234;&#237;&#224;
 UpdateWindow(FAppHandle);
 // &#239;&#240;&#238;&#246;&#229;&#228;&#243;&#240;&#224; &#231;&#224;&#226;&#229;&#240;&#248;&#229;&#237;&#224; &#243;&#241;&#239;&#229;&#248;&#237;&#238;
 Result := S_OK;
end;

procedure TAppEngine.WMButtonDown (var aMsg: TMessage);
begin
 if INT(aMsg.WParam)=VK_F12 then
   FAppRun:=False;
end;


и в проекте:


 App:=TAppEngine.Create("D3DEngine", "DirectX D3D Engine", 800, 600);
 mainHandle:=App.GetHandle;

 // &#225;&#229;&#241;&#234;&#238;&#237;&#229;&#247;&#237;&#251;&#233; &#246;&#232;&#234;&#235;
 while App.Run do
   begin
     PeekMessage(aMSG, mainHandle, 0, 0, PM_REMOVE);
     TranslateMessage(aMsg);
     DispatchMessage(aMsg);
   end;

 if Assigned(App) then App.Free;


Проблема в том что при нажатии F12 окно не закрывается, то есть TAppEngine.WMButtonDown судя по всему не выполняется...


 
Sphinx   (2005-01-05 15:24) [1]

Ой...звиняюсь...коментарии на русском были...

З.Ы. Заранее благодарен за помощ


 
GuAV ©   (2005-01-05 15:54) [2]

А какие меры вообще приняты для того чтоб сообщение передавалось классу TAppEngine ?

Выход из цикла должен бы быть по wm_quit.


>function WindowProc(iHandle: THandle; aMSG: Cardinal;
> wParam: Cardinal; lParam: Integer): Integer; stdcall;
>begin
>  Result := DefWindowProc(iHandle, aMSG, wParam,
>lParam);
> end;

Если это готовая оконная процедура, то смысл не ясен.


 
Sphinx   (2005-01-05 17:23) [3]

Я только разбираюсь в WinAPI, до этого все сообщения обрабатывал в WindowProc, и не создавал ни какого класса, но копировать код создания и обработки событий из одного проекта в другой надоело. Поэтому и пытаюсь создать класс для WinAPI. Самый простой.

> А какие меры вообще приняты для того чтоб сообщение передавалось
> классу TAppEngine ?


> procedure WMButtonDown (var aMsg: TMessage); message WM_KEYDOWN;

Это не передает сообщения??? Прочитал что вроде это как раз прием сообщений от Windows программой, или это только если создан объект Application из Forms?


 
GuAV ©   (2005-01-05 18:12) [4]

Sphinx   (05.01.05 17:23) [3]
Это не передает сообщения???


Это принимает сообщение. См controls.pas начиная отсюда:   FObjectInstance := Classes.MakeObjectInstance(MainWndProc);


 
Sphinx   (2005-01-06 23:13) [5]

Я видимо чего-то недопонимаю, если трудно объясните.

Просмотрел controls.pas там во-первых
WinClass.lpfnWndProc:=@WindowProc;
ссылается на DefWindowProc из user32 и вобщем то отличай не очень много (как мне показалось)...только реализовано все через дополнительные классы и структуры...
Далее, почти все события определены в classes.pas примерно так же как и пытаюсь сделать я:

> procedure TAppEngine.WMButtonDown (var aMsg: TMessage);

только вместо aMsg: TMessage там для событий клавиатуры Msg: TWMKeyDown.

По поводу WM_QUIT - так не до него еще...не могу принять ни одно сообщение.

Интересно что если сделать так:
function WindowProc(iHandle: THandle; aMSG: Cardinal;
wParam: Cardinal; lParam: Integer): Integer; stdcall;
begin
if (aMsg=WM_KEYDOWN) and (INT(wParam)=VK_F12) then Halt(0)
Result := DefWindowProc(iHandle, aMSG, wParam, lParam);
end;

WinClass.lpfnWndProc:=@WindowProc;


то приложение закрывается...

а если описать:


procedure WMButtonDown (var aMsg: TMessage); message WM_KEYDOWN;

procedure TAppEngine.WMButtonDown (var aMsg: TMessage);
begin
if INT(aMsg.WParam)=VK_F12 then
  Halt(0);
end;


не закрывается, вот этого я не пойму, ведь если написано message WM_KEYDOWN то процедура должна выполнятся при поступлении сообщения о нажатии клавиши, или нет?


 
GuAV ©   (2005-01-07 00:07) [6]


>Просмотрел controls.pas там во-первых
> WinClass.lpfnWndProc:=@WindowProc;

у меня там InitWndProc (D7)

Но она потом подменяется на FObjectInstance - результат MakeObjectInstance(MainWndProc);
из TWinControl.MainWndProc вызывается TControl.WindowProc, которая вызывает TWinControl.WndProc, она вызывает унаследованную TControl.WndProc. TControl.WndProc вызывает метод Dispatch, тем самым передавая сообщения обработчикам объекта.

Т.е. чтобы обработчик заработал нужно
0. написать оконный метод типа TWndMethod.
1. Сделать MakeObjectInstance для оконного метода.
2. Вызывать Dispatch из этого метода.

Возможно, можно совместить эти пункты, приведя Dispatch к TWndMethod.

Чтобы освободить память занятую под оконную процедуру MakeObjectInstance - вызвать FreeObjectInstance.


 
GuAV ©   (2005-01-07 00:14) [7]

Да, забыл ещё
3. Указать результат MakeObjectInstance как оконную процедуру окна.


 
Sphinx   (2005-01-08 23:13) [8]

Провозился с исходниками VCL и RTL, вроде разобрался в хитросплетении вызовов между TControl и TWinControl.

Получилось следующее (переписал почти полностью, от греха подальше, благо еще не многое сделано):
unit uTWinAPI;

interface

uses
 Classes,
 Messages,
 SysUtils,
 Windows;

type
 TWinAPI = class
   private
     FAppClass:        PChar;
     FAppName:         PChar;
     FAppHandle:       THandle;
     FAppActive:       Boolean;
     FAppRun:          Boolean;
     FWindowLeft:      Word;
     FWindowTop:       Word;
     FWindowWidth:     Word;
     FWindowHeight:    Word;
     FWinClass:        TWndClass;
     FWindowProc:      TWndMethod;
     FObjectInstance:  Pointer;

     procedure WMButtonDown (var aMsg: TMessage); message WM_KEYDOWN;

   protected
   published
   public
     constructor Create;
     destructor Destroy; override;

     property Handle: THandle read FAppHandle write FAppHandle;
     property Active: Boolean read FAppActive;
     property Run: Boolean read FAppRun;
     property WindowProc: TWndMethod read FWindowProc write FWindowProc;

     procedure WndProc(var aMessage: TMessage);

     function ShowDialog(Title, Text: PChar; uType: Cardinal): Integer;
     function WindowCreate(AppClass, AppName: PChar; Left, Top, Width, Height: Word): HResult;
     function WindowClose: HResult;

 end;

implementation

constructor TWinAPI.Create;
begin
 FAppClass:="TWinAPI";
 FAppName:="WinAPI1";
 FAppActive:=False;
 FAppRun:=False;
 FWindowLeft:=0;
 FWindowTop:=0;
 FWindowWidth:=250;
 FWindowHeight:=150;

 FWindowProc:=WndProc;
 FObjectInstance:=Classes.MakeObjectInstance(WindowProc);

 inherited Create;

end;

destructor TWinAPI.Destroy;
begin
 if FAppHandle<>0 then WindowClose;

 Classes.FreeObjectInstance(FObjectInstance);

 inherited Destroy;
end;

procedure TWinAPI.WndProc(var aMessage: TMessage);
begin
 Dispatch(aMessage);
//  DefWindowProc(FAppHandle, aMessage.Msg, aMessage.WParam, aMessage.LParam);
end;

function TWinAPI.ShowDialog(Title, Text: PChar; uType: Cardinal): Integer;
begin
 Result:=MessageBox(FAppHandle, Text, Title, uType);
end;

function TWinAPI.WindowCreate(AppClass, AppName: PChar; Left, Top, Width, Height: Word): HResult;
var
 wordError:      Word;
 cardinalError:  Cardinal;
begin
 Result:=E_Fail;
 if FAppHandle<>0 then
   begin
     Result:=S_False;
     Exit;
   end;
 if AppClass<>FAppClass then FAppClass:=AppClass;
 if AppName<>FAppName then FAppName:=AppName;
 if Left<>FWindowLeft then FWindowLeft:=Left;
 if Top<>FWindowTop then FWindowTop:=Top;
 if Width<>FWindowWidth then FWindowWidth:=Width;
 if Height<>FWindowHeight then FWindowHeight:=Height;

 FWinClass.lpszClassName:=FAppClass;
 FWinClass.lpfnWndProc:=FObjectInstance;
 FWinClass.style:=CS_VREDRAW or CS_HREDRAW;
 FWinClass.hInstance:=hInstance;
 FWinClass.hIcon:=LoadIcon(hInstance, MakeIntResource("ICON"));
 FWinClass.hCursor:=LoadCursor(0, IDC_ARROW);
 FWinClass.hbrBackground:=($000000);
 FWinClass.lpszMenuName:=nil;
 FWinClass.cbClsExtra:=0;
 FWinClass.cbWndExtra:=0;

 wordError:=Windows.RegisterClass(FWinClass);
 if wordError=0 then
   begin
     cardinalError:=GetLastError;
     ShowDialog(FAppName, PChar("RegisterClass"+#13#10+"Error № "+IntToStr(cardinalError)), mb_OK or mb_IconError);
     Exit;
   end;

 FAppHandle := CreateWindowEx
  (WS_EX_APPWINDOW,
   FAppClass,
   FAppName,
   WS_POPUP,
   FWindowLeft,
   FWindowTop,
   FWindowWidth,
   FWindowHeight,
   0,
   0,
   hInstance,
   nil );
 if FAppHandle=0 then
   begin
     cardinalError:=GetLastError;
     ShowDialog(FAppName, PChar("CreateWindowEx"+#13#10+"Error № "+IntToStr(cardinalError)), mb_OK or

mb_IconError);
     Exit;
   end;

 ShowWindow(FAppHandle, SW_SHOW);
 SetActiveWindow(FAppHandle);
 UpdateWindow(FAppHandle);

 FAppRun:=True;

 Result:=S_Ok;
end;

function TWinAPI.WindowClose;
var
 longboolResult: LongBool;
 cardinalError:  Cardinal;
begin
 Result:=E_Fail;
 longboolResult:=DestroyWindow(FAppHandle);
 if longboolResult=False then
   begin
     cardinalError:=GetLastError;
     ShowDialog(FAppName, PChar("DestroyWindow"+#13#10+"Error № "+IntToStr(cardinalError)), mb_OK or mb_IconError);
     Exit;
   end;
 longboolResult:=Windows.UnregisterClass(FAppName, HInstance);
 if longboolResult=False then
   begin
     cardinalError:=GetLastError;
     ShowDialog(FAppName, PChar("UnregisterClass"+#13#10+"Error № "+IntToStr(cardinalError)), mb_OK or

mb_IconError);
     Exit;
   end;
 FAppHandle:=0;
 FAppActive:=False;
 FAppRun:=False;
end;

procedure TWinAPI.WMButtonDown(var aMsg: TMessage);
begin
 if INT(aMsg.WParam)=VK_F12 then
   begin
     WindowClose;
   end;  
end;

end.


проект теперь выглядит следующим образом:

program Tester;

{$R *.res}

uses
 Windows,
 uTWinAPI in "uTWinAPI.pas";

var
 App:          TWinAPI;
 mainHandle:   THandle;
 aMsg:         MSG;

begin
 App:=TWinAPI.Create;
 App.WindowCreate("TWinAPI", "WinAPI1", 0, 0, 250, 150);
 mainHandle:=App.Handle;

 while App.Run do
   begin
     PeekMessage(aMSG, mainHandle, 0, 0, PM_REMOVE);
     TranslateMessage(aMsg);
     DispatchMessage(aMsg);
   end;

 App.WindowClose;
 App.Free;
end.


При выполнении программа поставила меня в тупик, выпадает диалоговое окно:
CreateWindowEx
Error № 0 (NO_ERROR = без ошибок ?!)

а потом

DestroyWindow
Error № 1400 (ERROR_INVALID_WINDOW_HANDLE = оно и понятно, возвращается FAppHandle=0 ?!)

Заметил что ошибка пропадает если в качестве оконной процедуры указать к примеру @DefWindowProc или любую другую

процедуру вида:
procedure WProc(...)
даже указание такой процедуры procedure TWinAPI.WProc(...) приводит к такому же результату

и еще, если снять коментарий со строки DefWindowProc(FAppHandle, aMessage.Msg, aMessage.WParam,

aMessage.LParam);
то при запуске получаю:
CreateWindowEx
Error № 1400

Это я как понял происходит потому что при создании окна ему отсылаются сообщения, а FAppHandle еще не получен.


 
Sphinx   (2005-01-11 01:51) [9]

up



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.172 c
1-1108545499
Начинающий 2
2005-02-16 12:18
2005.02.27
Импорт формы в форму из DLL.


4-1105818592
Sphinx
2005-01-15 22:49
2005.02.27
Счетчик запусков программы


1-1108296764
Layner
2005-02-13 15:12
2005.02.27
Здравствуйте! научите передавать особый параметр в процедуру


1-1108466313
Checist [root]
2005-02-15 14:18
2005.02.27
Создание новой формы


3-1106911040
DSKalugin
2005-01-28 14:17
2005.02.27
Использование доменов FireBird 1.5.1





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский