Конференция "WinAPI" » Проблема с активацией окна [D7, WinXP]
 
  • Monarch © (25.05.10 18:03) [0]
    Привет всем.
    Помогите с моим первым окном на 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

    // Процедура обработки сообщений Windows
    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;

    { TFlowVisualizer }

    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, то тоже дайте знать. Это мое первое окошко.
  • Игорь Шевченко © (25.05.10 21:57) [1]
    а где собственно последовательность вызовов этих кусочков ?
  • Monarch © (26.05.10 18:46) [2]
    Дело в том, что

          WM_ACTIVATE:
            ActiveData(@WMSG.wparam);


    Не ловит сообщения об активации.
    Пробовал ставить LoWord(WMSG.wparam).
    Уже вот записывал в файл принимаемые сообщения.
    WM_ACTIVATE = 6. приходит, а в Case не попадает.
    Что может быть, никак не могу понять
  • Monarch © (26.05.10 19:01) [3]
    Написал вот так:

     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 и приложение никак по другому не реагирует
  • Leonid Troyanovsky © (27.05.10 08:48) [4]

    > 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]
    :) Посмотрел на картинку ещё раз, почесал затылок и поменял процедуру.
    Но кроме как ехидничать и подкалывать, лучше помогли бы.
  • Leonid Troyanovsky © (27.05.10 09:57) [6]

    > Monarch ©   (27.05.10 09:41) [5]

    > Но кроме как ехидничать и подкалывать, лучше помогли бы.

    Во-первых, непонятно, зачем API, если с TForm всё ок.
    Во-вторых, Classes.MakeObjectInstance/FreeObjectInstance.
    В-третьих, RTFM: msdn: DispatchMessage.

    --
    Regards, LVT.
  • Monarch © (27.05.10 10:37) [7]
    О! Спасибо. Положил процедуру обработки внутрь класса. А я всё думал как-же её туда положить. И так и эдак пробовал, пробовал не получалось. А теперь получилось.
    Обработку WM_ACTIVATE положил теперь в неё и всё прекрасно работает.
    API поставил для собственного прозрения и просветления :)
    Давно хотел так сделать.
  • Leonid Troyanovsky © (27.05.10 11:23) [8]

    > Monarch ©   (27.05.10 10:37) [7]

    Еще нескладно: WideChar, а функции зовутся ansiшные.

    --
    Regards, LVT.
  • Monarch © (27.05.10 13:39) [9]
    Поменял, хотя и так почему-то работали
  • Leonid Troyanovsky © (27.05.10 16:13) [10]

    > Monarch ©   (27.05.10 13:39) [9]

    > Поменял, хотя и так почему-то работали

    Неявные преобразования.

    --
    Regards, LVT.
  • Monarch © (28.05.10 17:46) [11]
    Спасибо за помощь
 
Конференция "WinAPI" » Проблема с активацией окна [D7, WinXP]
Есть новые Нет новых   [134431   +14][b:0][p:0.004]