-
Привет всем. Помогите с моим первым окном на WinApi. На TForm всё ок, а тут какая-то лажа... никак ни могу понять в чем дело. 1. Есть поток, на выходе битовая карта. 2. DirectDraw7 - вывод данных на окно. 3. Собственно само окно. Проблема: DD7 при повторной активации возобновляет воспроизведение на экран, работает без ошибок, но экран не меняется. Код:
unit UFlowVisionArea;
interface
Uses Windows, Messages;
Type
TFlowInformation = Record
ClassName: PWideChar;
BasicName: PWideChar;
hIconName: PWideChar;
dwExStyle: Cardinal;
dwStyle: Cardinal;
Style: Cardinal;
Color: Byte;
Atom: TAtom;
WMSG: MSG;
End;
TFlowConstructor = Packed Record
Active: LongBool;
Handle: HWND;
Top: Integer;
Left: Integer;
Right: Integer;
Bottom: Integer;
Width: Integer;
Height: Integer;
Diagonal: Integer;
StartTick: Cardinal;
WndClassEx: TWndClassEx;
End;
TFlowVisionArea = class
Protected
var
FlowInformation: TFlowInformation;
FlowConstructor: TFlowConstructor;
Protected
Procedure IncomeData;
Procedure ResultData; virtual;
Procedure InsideData(Key: PInteger); virtual;
Procedure ActiveData(Key: PInteger); virtual;
Procedure ChangeName(Name: PWideChar);
Public
Constructor Create; virtual;
Destructor Destroy; override;
end;
implementation
function WindowProc(wnd: HWND; MSG: Integer; wparam: wparam; lparam: lparam)
: LRESULT; STDCALL;
begin
case MSG of
WM_DESTROY:
begin
PostQuitMessage(0);
Result := 0;
Exit;
end;
else
Result := DefWindowProc(wnd, MSG, wparam, lparam);
end;
end;
procedure TFlowVisionArea.ActiveData(Key: PInteger);
begin
With FlowConstructor do
case Key^ of
WA_ACTIVE:
begin
SetActiveWindow(Handle);
ShowWindow(Handle, SW_RESTORE);
SetForegroundWindow(Handle);
Active := True;
end;
WA_CLICKACTIVE:
begin
Active := True;
end;
WA_INACTIVE:
begin
Active := False;
end;
end;
end;
procedure TFlowVisionArea.ChangeName(Name: PWideChar);
begin
if Name = #0 then
SetWindowText(FlowConstructor.Handle, FlowInformation.BasicName)
else
SetWindowText(FlowConstructor.Handle, Name);
end;
constructor TFlowVisionArea.Create;
var
NoCopy: HWND;
begin
With FlowConstructor, FlowInformation do
begin
StartTick := GetTickCount;
NoCopy := FindWindow(ClassName, nil);
if (IsIconic(NoCopy)) then
begin
ShowWindow(NoCopy, SW_RESTORE);
SetForegroundWindow(NoCopy);
StartTick := 0;
Exit;
end;
WndClassEx.cbSize := SizeOf(WndClassEx);
WndClassEx.Style := Style;
WndClassEx.lpfnWndProc := @WindowProc;
WndClassEx.cbClsExtra := 0;
WndClassEx.cbWndExtra := 0;
WndClassEx.hInstance := hInstance;
WndClassEx.hIcon := LoadIcon(hInstance, hIconName);
WndClassEx.hCursor := LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW));
WndClassEx.hbrBackground := Color_BtnFace + Color;
WndClassEx.lpszMenuName := nil;
WndClassEx.lpszClassName := ClassName;
WndClassEx.hIconSm := LoadIcon(hInstance, hIconName);
Atom := RegisterClassEx(WndClassEx);
if Left < 0 then
Left := GetSystemMetrics(SM_XVIRTUALSCREEN);
if Top < 0 then
Top := GetSystemMetrics(SM_YVIRTUALSCREEN);
if Right = 0 then
Right := GetSystemMetrics(SM_CXVIRTUALSCREEN);
if Bottom = 0 then
Bottom := GetSystemMetrics(SM_CYVIRTUALSCREEN);
Width := Right - Left;
Height := Bottom - Top;
Diagonal := Round(Sqrt(Sqr(Width) + Sqr(Height)));
Handle := CreateWindowEx(dwExStyle, ClassName, BasicName, dwStyle, Left,
Top, Right, Bottom, 0, 0, hInstance, nil);
end;
end;
destructor TFlowVisionArea.Destroy;
begin
if not FlowInformation.Atom = 0 then
GlobalDeleteAtom(FlowInformation.Atom);
PostMessage(FlowConstructor.Handle, WM_CLOSE, 0, 0);
inherited;
end;
procedure TFlowVisionArea.IncomeData;
begin
With FlowInformation do
while GetMessage(WMSG, 0, 0, 0) do
begin
TranslateMessage(WMSG);
DispatchMessage(WMSG);
Case WMSG.message OF
WM_KEYDOWN:
InsideData(@WMSG.wparam);
WM_ACTIVATE:
ActiveData(@WMSG.wparam);
END;
end;
end;
procedure TFlowVisionArea.InsideData(Key: PInteger);
begin
if Key = nil then
Destroy;
end;
procedure TFlowVisionArea.ResultData;
begin
ShowWindow(FlowConstructor.Handle, SW_SHOWMAXIMIZED);
end;
end.
Если найдете-какие-то вообще ошибки при работе с API, то тоже дайте знать. Это мое первое окошко.
-
а где собственно последовательность вызовов этих кусочков ?
-
Дело в том, что
WM_ACTIVATE:
ActiveData(@WMSG.wparam);
Не ловит сообщения об активации. Пробовал ставить LoWord(WMSG.wparam). Уже вот записывал в файл принимаемые сообщения. WM_ACTIVATE = 6. приходит, а в Case не попадает. Что может быть, никак не могу понять
-
Написал вот так:
With FlowInformation do
while GetMessage(WMSG, 0, 0, 0) do
begin
If TranslateMessage(WMSG) then
InsideData(@WMSG.wparam)
else
DispatchMessage(WMSG);
ActiveData(IsIconic(FlowConstructor.Handle));
end;
если меняется результат приостанавливаю или запускаю поток. Забавно, что Alt + F4 теперь обрабатывается внутри процедуры InsideData и приложение никак по другому не реагирует
-
> Monarch © (26.05.10 18:46) [2]
> Не ловит сообщения об активации.
Оно д.б. в оконной процедуре.
> If TranslateMessage(WMSG) then > InsideData(@WMSG.wparam) > else > DispatchMessage(WMSG);
За такое надо убивать из рогатки.
-- Regards, LVT.
-
:) Посмотрел на картинку ещё раз, почесал затылок и поменял процедуру. Но кроме как ехидничать и подкалывать, лучше помогли бы.
-
> Monarch © (27.05.10 09:41) [5]
> Но кроме как ехидничать и подкалывать, лучше помогли бы.
Во-первых, непонятно, зачем API, если с TForm всё ок. Во-вторых, Classes.MakeObjectInstance/FreeObjectInstance. В-третьих, RTFM: msdn: DispatchMessage.
-- Regards, LVT.
-
О! Спасибо. Положил процедуру обработки внутрь класса. А я всё думал как-же её туда положить. И так и эдак пробовал, пробовал не получалось. А теперь получилось. Обработку WM_ACTIVATE положил теперь в неё и всё прекрасно работает. API поставил для собственного прозрения и просветления :) Давно хотел так сделать.
-
> Monarch © (27.05.10 10:37) [7]
Еще нескладно: WideChar, а функции зовутся ansiшные.
-- Regards, LVT.
-
Поменял, хотя и так почему-то работали
-
> Monarch © (27.05.10 13:39) [9]
> Поменял, хотя и так почему-то работали
Неявные преобразования.
-- Regards, LVT.
-
Спасибо за помощь
|