Конференция "WinAPI" » WM_ENDSESSION и Win7 [D7]
 
  • istok (21.10.09 15:21) [0]
    WM_EndSession не ловится в win7, а в xp ловится. Код представлен ниже:


    type
     TMyForm = class(TForm)
    ...
    private
    ...
       procedure WMEndSession(var Msg: TWMEndSession); message WM_ENDSESSION;
    ...
    procedure TMyForm.WMEndSession(var Msg: TWMEndSession);
    begin
     AddLog('WMEndSession');
     if Msg.EndSession = True then
     begin
       //call my app destructors
       halt;
     end;
     inherited;
    end;



    как же обрабатывать logoff\sutdown в win7 чтобы вызывать свои деструкторы?
  • clickmaker © (21.10.09 15:43) [1]
    > чтобы вызывать свои деструкторы?

    а мужики-то пишут-пишут и не знают, что обработчик WM_ENDSESSION - это, оказывается, единственное место для вызова деструкторов...
  • istok (21.10.09 15:52) [2]
    а я и не утверждал, что это единственное место, но других не знаю. queryendsession насколько я понимаю не подходит, что вы посоветуете?
  • clickmaker © (21.10.09 15:57) [3]
    TForm.OnDestroy
  • TIF © (21.10.09 15:58) [4]
    По-моему правильнее сначала ловить WM_QUERYENDSESSION, вернуть на это сообщение системе ответ TRUE, а уже только потом дождаться WM_ENDSESSION и сворачивать свою деятельность
  • istok (21.10.09 16:04) [5]

    > TIF ©   (21.10.09 15:58) [4]
    >
    > По-моему правильнее сначала ловить WM_QUERYENDSESSION, вернуть
    > на это сообщение системе ответ TRUE, а уже только потом
    > дождаться WM_ENDSESSION и сворачивать свою деятельность


    а мне нет смысла ловить WM_QUERYENDSESSION

    мне надо обработать закрытие приложения, при логофе\шатдауне. есть известный косяк с невызовом деструкторов, описанный например здесь: http://www.delphifaq.com/faq/delphi/vcl/f285.shtml
  • istok (21.10.09 16:10) [6]

    > clickmaker ©   (21.10.09 15:57) [3]
    >
    > TForm.OnDestroy


    дык не катит, по крайней мере в D7.  в предыдущем посте это описано..
  • clickmaker © (21.10.09 16:11) [7]
    > известный косяк с невызовом деструкторов

    какой смысл перед смертью чистить зубы, а?
  • istok (21.10.09 16:48) [8]

    > какой смысл перед смертью чистить зубы, а?


    такой, что программа перед своим закрытием должна кое-чего сделать согласно своей бизнес логике. но деструкторы не вызываются, события в вин7 не ловятся. и как это сделать в вин7 - пока непонятно..   в xp проблем нет.
  • clickmaker © (21.10.09 17:03) [9]
    и OnDestroy и OnClose даже не вызывается?
  • istok (21.10.09 21:43) [10]
    угу, оба не вызываются, по крайней мере не пишет соответствующий лог в файл.
    а при закрытии руками - пишет..
  • robot © (24.11.09 22:08) [11]
    Если еще нужно:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FWndHandle := Classes.AllocateHWnd(WndProc);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      Classes.DeallocateHWnd(FWndHandle);
    end;

    procedure TForm1.WndProc(var Msg: TMessage);
    begin
      if Msg.Msg = WM_ENDSESSION then
         Halt
      else
        Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
    end;

    Как-то так.
  • Игорь Шевченко © (24.11.09 22:14) [12]
    А тебе ж там написали, болезному:

    "the only reliable way
    of handling the WM_ENDSESSION is to use the HookWindow method of
    Application."

    даже пример привели.
  • robot © (02.12.09 19:26) [13]

    > Игорь Шевченко ©


    Сам-то проверял?

    Интересуюсь, т.к. для меня вопрос важен.

    Приведенный мной способ работает на win7 x64, 2008 r2 x64, d2007.

    Вдруг упустил чего.
  • Leonid Troyanovsky © (02.12.09 23:51) [14]

    > robot ©   (02.12.09 19:26) [13]

    > Вдруг упустил чего.

    У MS спросить надо.

    Regards, LVT.
 
Конференция "WinAPI" » WM_ENDSESSION и Win7 [D7]
Есть новые Нет новых   [134431   +15][b:0][p:0.001]