Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Блокировка завершения работы / 17 сообщений из 17, страница 1 из 1
25.08.2021, 17:28
    #40093161
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Есть приложение. В нем создается ActiveX форма. Теперь если при запущенном приложении попытаться завершить работу Windows, то я получаю уведомление о том, что система не может завершить работу из-за этого приложения.

Никаких MessageBox'ов не появляется. Если приложение просто закрыть, то оно отлично закрывается. В чем может быть причина блокировки и куда смотреть? При завершении работы OnDestroy у ActiveX не вызывается

С уважением, Vasilisk
...
Рейтинг: 0 / 0
25.08.2021, 17:36
    #40093164
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
лови WM_QUERYENDSESSION и обрабатывай его руками.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25.08.2021, 17:50
    #40093168
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Мимопроходящий
лови WM_QUERYENDSESSION и обрабатывай его руками.
Как обрабатывать? Дефолтный WM_QUERYENDSESSION у основного приложения возвращает 1. Что еще нужно?
...
Рейтинг: 0 / 0
25.08.2021, 18:02
    #40093172
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
А в ActiveX обработчик WM_QUERYENDSESSION не вызывается вообще
...
Рейтинг: 0 / 0
25.08.2021, 18:09
    #40093173
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
_Vasilisk_
Мимопроходящий
лови WM_QUERYENDSESSION и обрабатывай его руками.
Как обрабатывать? Дефолтный WM_QUERYENDSESSION у основного приложения возвращает 1. Что еще нужно?
отдавай 0, до тех пор, пока не закроешь свой ActiveX.
а как закрыл, отдай 1.
...
Рейтинг: 0 / 0
25.08.2021, 18:22
    #40093175
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Мимопроходящий
отдавай 0, до тех пор, пака не закроешь свой ActiveX.
Так он отлично сам закрывается. Причем быстро и без вопросов. Вопрос, что может мешать закрытию приложения?
...
Рейтинг: 0 / 0
25.08.2021, 18:24
    #40093176
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
ну, знач я тебя не так понял.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25.08.2021, 18:33
    #40093181
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
_Vasilisk_Если приложение просто закрыть, то оно отлично закрывается.

А если послать ему WM_CLOSE (или сразу WM_ENDSESSION)? Есть странные приложения,
на крестик реагирующие нормально, а по сообщению закрываться отказывающиеся.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25.08.2021, 18:49
    #40093184
Кроик Семён
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
_Vasilisk_,

OleVariant - переменной, которая держит ссылку на ActiveX-обьект формы, перед завершением приложения (в OnClose, видимо) надо присвоить Unassigned
...
Рейтинг: 0 / 0
25.08.2021, 19:17
    #40093185
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Кроик Семён> перед завершением приложения (в OnClose, видимо)

Там до OnClose не доходит, видимо.

До OnCloseQuery доходит хоть?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
27.08.2021, 17:31
    #40093529
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Dimitry Sibiryakov
Есть странные приложения, на крестик реагирующие нормально, а по сообщению закрываться отказывающиеся.
Это мое тестовое приложение с одной формой и ActiveX на ней
Кроик Семён
OleVariant - переменной, которая держит ссылку на ActiveX-обьект формы, перед завершением приложения (в OnClose, видимо) надо присвоить Unassigned
Нет. Проблема в конкретном COM-объекте, а не компоненте-враппере. Если положить другой ActiveX, то все корректно завершается
Гаджимурадов Рустам
Там до OnClose не доходит, видимо.
До OnCloseQuery доходит хоть?
Добавил логирование сообщений в основном приложении
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
procedure TForm1.WndProc(var AMsg: TMessage);
const
  CSkipMsgSet: set of Byte = [
    WM_PAINT,
    WM_NCPAINT,
    WM_GETTEXTLENGTH,
    WM_SETTEXT,
    WM_GETMINMAXINFO,
    WM_WINDOWPOSCHANGING,
    WM_NCCALCSIZE,
    WM_WINDOWPOSCHANGED,
    WM_MOVE,
    WM_SIZE,
    WM_ERASEBKGND,
    WM_NCHITTEST,
    WM_SETCURSOR,
    $00AE,
    WM_NCMOUSEMOVE
  ];
  CSkipMsg: array[0..4] of Cardinal = (
    WM_PRINTCLIENT,
    WM_IME_SETCONTEXT,
    WM_IME_NOTIFY,
    WM_DWMNCRENDERINGCHANGED,
    WM_NCMOUSELEAVE
  );
var
  LSkipMsg: Boolean;
  LMsgName: string;
  Li: Integer;
begin
  LSkipMsg :=
    not FLogMsg or
    ((AMsg.Msg >= WM_MOUSEFIRST) and (AMsg.Msg <= WM_MOUSELAST)) or
    (AMsg.Msg >= WM_USER) or
    (AMsg.Msg in CSkipMsgSet);
  if not LSkipMsg then begin
    for Li := 0 to Length(CSkipMsg) - 1 do begin
      if AMsg.Msg = CSkipMsg[Li] then begin
        LSkipMsg := True;
        Break;
      end;
    end;
  end;

  if LSkipMsg then
    inherited WndProc(AMsg)
  else begin
    case AMsg.Msg of
      WM_CLOSE: LMsgName := 'WM_CLOSE';
      WM_QUERYENDSESSION: LMsgName := 'WM_QUERYENDSESSION';
      WM_QUIT: LMsgName := 'WM_QUIT';
      WM_DESTROY: LMsgName := 'WM_DESTROY';
      WM_NCDESTROY: LMsgName := 'WM_NCDESTROY';
      WM_NCCREATE: LMsgName := 'WM_NCCREATE';
      WM_ACTIVATE: LMsgName := 'WM_ACTIVATE';
      WM_SETFOCUS: LMsgName := 'WM_SETFOCUS';
      WM_CAPTURECHANGED: LMsgName := 'WM_CAPTURECHANGED';
      WM_SYSCOMMAND: LMsgName := 'WM_SYSCOMMAND';
      WM_NCACTIVATE: LMsgName := 'WM_NCACTIVATE';
      WM_NCLBUTTONDOWN: LMsgName := 'WM_NCLBUTTONDOWN';
      WM_KILLFOCUS: LMsgName := 'WM_KILLFOCUS';
      WM_SETICON: LMsgName := 'WM_SETICON';
      WM_GETTEXT: LMsgName := 'WM_GETTEXT';
      WM_SHOWWINDOW: LMsgName := 'WM_SHOWWINDOW';
      WM_ACTIVATEAPP: LMsgName := 'WM_ACTIVATEAPP';
      WM_CHANGEUISTATE: LMsgName := 'WM_CHANGEUISTATE';
      WM_SYSKEYDOWN: LMsgName := 'WM_SYSKEYDOWN';
      WM_ENDSESSION: LMsgName := 'WM_ENDSESSION';
    else
      LMsgName := Format('%d ($%0:.4x)', [AMsg.Msg]);
    end;
    LogEnter(Format('Message: %s, WPARAM: %d, LPARAM: %d', [LMsgName, AMsg.WParam, AMsg.LParam]));
    inherited WndProc(AMsg);
    LogLeave(Format('Message: %s, Result: %d', [LMsgName, AMsg.Result]));
  end;
  if AMsg.Msg = WM_ACTIVATE then
    FLogMsg := True;
end;

Получил такие логи
Обычное закрытие приложения
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
[15:59:03.385] >>> Message: WM_NCLBUTTONDOWN, WPARAM: 20, LPARAM: 4784693
[15:59:03.557]   >>> Message: WM_CAPTURECHANGED, WPARAM: 0, LPARAM: 0
[15:59:03.557]   <<< Message: WM_CAPTURECHANGED, Result: 0
[15:59:03.557]   >>> Message: WM_SYSCOMMAND, WPARAM: 61536, LPARAM: 4784693
[15:59:03.557]     >>> Message: WM_CLOSE, WPARAM: 0, LPARAM: 0
[15:59:03.557]       OnCloseQuery
[15:59:03.557]       OnClose
[15:59:03.557]     <<< Message: WM_CLOSE, Result: 0
[15:59:03.557]   <<< Message: WM_SYSCOMMAND, Result: 0
[15:59:03.557] <<< Message: WM_NCLBUTTONDOWN, Result: 0
[15:59:03.557] >>> Message: WM_NCACTIVATE, WPARAM: 0, LPARAM: 6948918
[15:59:03.557] <<< Message: WM_NCACTIVATE, Result: 1
[15:59:03.557] >>> Message: WM_ACTIVATE, WPARAM: 0, LPARAM: 6948918
[15:59:03.557] <<< Message: WM_ACTIVATE, Result: 0
[15:59:03.557] >>> Message: WM_KILLFOCUS, WPARAM: 6948918, LPARAM: 0
[15:59:03.557] <<< Message: WM_KILLFOCUS, Result: 0
[15:59:03.557] OnDestroy
[15:59:03.557] >>> TForm1.Destroy
[15:59:03.557]   >>> Message: 144 ($0090), WPARAM: 0, LPARAM: 0
[15:59:03.557]   <<< Message: 144 ($0090), Result: 0
[15:59:03.557]   >>> Message: WM_DESTROY, WPARAM: 0, LPARAM: 0
[15:59:03.557]     >>> Message: WM_SETICON, WPARAM: 1, LPARAM: 0
[15:59:03.557]     <<< Message: WM_SETICON, Result: 24709287
[15:59:03.557]     >>> Message: WM_GETTEXT, WPARAM: 6, LPARAM: 2145650996
[15:59:03.557]     <<< Message: WM_GETTEXT, Result: 5
[15:59:03.557]   <<< Message: WM_DESTROY, Result: 0
[15:59:03.557]   >>> Message: WM_NCDESTROY, WPARAM: 0, LPARAM: 0
[15:59:03.557]   <<< Message: WM_NCDESTROY, Result: 0
[15:59:03.557] <<< TForm1.Destroy
Завершение работы с правильным ActiveX
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
[15:59:29.667] >>> Message: WM_NCACTIVATE, WPARAM: 0, LPARAM: 0
[15:59:29.667] <<< Message: WM_NCACTIVATE, Result: 1
[15:59:29.667] >>> Message: WM_ACTIVATE, WPARAM: 0, LPARAM: 0
[15:59:29.667] <<< Message: WM_ACTIVATE, Result: 0
[15:59:29.667] >>> Message: WM_ACTIVATEAPP, WPARAM: 0, LPARAM: 7936
[15:59:29.667] <<< Message: WM_ACTIVATEAPP, Result: 0
[15:59:29.667] >>> Message: WM_KILLFOCUS, WPARAM: 0, LPARAM: 0
[15:59:29.667] <<< Message: WM_KILLFOCUS, Result: 0
[15:59:35.198] >>> Message: 800 ($0320), WPARAM: -486510649, LPARAM: 1
[15:59:35.198] <<< Message: 800 ($0320), Result: 0
[15:59:35.230] >>> Message: WM_QUERYENDSESSION, WPARAM: 0, LPARAM: 0
[15:59:35.230]   OnCloseQuery
[15:59:35.230] <<< Message: WM_QUERYENDSESSION, Result: 1
[15:59:35.230] >>> Message: WM_ENDSESSION, WPARAM: 1, LPARAM: 0
[15:59:35.230] <<< Message: WM_ENDSESSION, Result: 0
[15:59:35.230] >>> Message: WM_SHOWWINDOW, WPARAM: 0, LPARAM: 0
[15:59:35.230] <<< Message: WM_SHOWWINDOW, Result: 0
[15:59:35.230] OnDestroy
[15:59:35.230] >>> TForm1.Destroy
[15:59:35.230]   >>> Message: 144 ($0090), WPARAM: 0, LPARAM: 0
[15:59:35.230]   <<< Message: 144 ($0090), Result: 0
[15:59:35.230]   >>> Message: WM_DESTROY, WPARAM: 0, LPARAM: 0
[15:59:35.230]     >>> Message: WM_SETICON, WPARAM: 1, LPARAM: 0
[15:59:35.230]     <<< Message: WM_SETICON, Result: 61539501
[15:59:35.230]     >>> Message: WM_GETTEXT, WPARAM: 6, LPARAM: 2145650996
[15:59:35.230]     <<< Message: WM_GETTEXT, Result: 5
[15:59:35.230]   <<< Message: WM_DESTROY, Result: 0
[15:59:35.230]   >>> Message: WM_NCDESTROY, WPARAM: 0, LPARAM: 0
[15:59:35.230]   <<< Message: WM_NCDESTROY, Result: 0
[15:59:35.277] <<< TForm1.Destroy
OnClose не вызывается вообще
Завершение работы с проблемным ActiveX
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
[16:37:49.812] >>> Message: WM_NCACTIVATE, WPARAM: 0, LPARAM: 0
[16:37:49.825] <<< Message: WM_NCACTIVATE, Result: 1
[16:37:49.825] >>> Message: WM_ACTIVATE, WPARAM: 0, LPARAM: 0
[16:37:49.825] <<< Message: WM_ACTIVATE, Result: 0
[16:37:49.825] >>> Message: WM_ACTIVATEAPP, WPARAM: 0, LPARAM: 10256
[16:37:49.825] <<< Message: WM_ACTIVATEAPP, Result: 0
[16:37:49.826] >>> Message: WM_KILLFOCUS, WPARAM: 0, LPARAM: 0
[16:37:49.826] <<< Message: WM_KILLFOCUS, Result: 0
[16:38:04.542] >>> Message: 800 ($0320), WPARAM: -486510649, LPARAM: 1
[16:38:04.542] <<< Message: 800 ($0320), Result: 0
[16:38:04.639] >>> Message: WM_QUERYENDSESSION, WPARAM: 0, LPARAM: 0
[16:38:04.639]   OnCloseQuery
[16:38:04.639] <<< Message: WM_QUERYENDSESSION, Result: 1
[16:38:16.233] >>> Message: WM_ENDSESSION, WPARAM: 0, LPARAM: 0
[16:38:16.233] <<< Message: WM_ENDSESSION, Result: 0
Здесь WM_ENDSESSION приходит тогда, когда Windows предлагает убить мешающее приложения, а я нажимаю "Отмена"
...
Рейтинг: 0 / 0
27.08.2021, 18:41
    #40093543
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Может этот ActiveX создаёт своё окно, которое обрабатывает WM_QUERYENDSESSION возвращая 0?
...
Рейтинг: 0 / 0
27.08.2021, 18:54
    #40093545
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
GunSmoker
Может этот ActiveX создаёт своё окно, которое обрабатывает WM_QUERYENDSESSION возвращая 0?
Нет. Там обычная форма, на которой лежит TStringGrid. Все.

Сейчас добавлю еще логгер сообщений для этого ActiveX
...
Рейтинг: 0 / 0
27.08.2021, 19:14
    #40093546
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Правда в нем создается еще один COM-объект (уже не визуальный), а этот COM-объект порождает пару потоков. Но рядом лежит почти такой-же ActiveX и он работает.

Есть в VCL место, куда можно воткнуть логгер всех, приходящих в главный поток, сообщений?
...
Рейтинг: 0 / 0
27.08.2021, 19:56
    #40093553
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
А не в фоновом потоке окно какое-нибудь?
...
Рейтинг: 0 / 0
27.08.2021, 20:22
    #40093555
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
GunSmoker
Может этот ActiveX создаёт своё окно, которое обрабатывает WM_QUERYENDSESSION возвращая 0?
Таки есть какая-то зараза
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
function EnumThreadWindowsProc(AHandle: HWND; AData: TForm1): BOOL; stdcall;
var
  LRes: LRESULT;
  LBuf: array[Byte] of Char;
  LClass: string;
  LLen: Integer;
begin
  LRes := SendMessage(AHandle, WM_QUERYENDSESSION, 0, 0);
  LLen := GetClassName(AHandle, LBuf, Length(LBuf));
  SetString(LClass, LBuf, LLen);
  AData.memLog.Lines.Add(Format('%s: %d', [LClass, LRes]));
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumThreadWindows(GetCurrentThreadId, @EnumThreadWindowsProc, LPARAM(Self));
end;


TForm1: 1
TApplication: 1
TPUtilWindow: 1
TPUtilWindow: 1
TPUtilWindow: 0
DAXParkingWindow: 1
TPUtilWindow: 1
TPUtilWindow: 1
MSCTFIME UI: 1
IME: 1Сейчас буду его искать
...
Рейтинг: 0 / 0
27.08.2021, 20:41
    #40093559
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка завершения работы
Нашел.

Было
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
constructor TMyObject.Create;
begin
  inherited Create;
  FHandle := AllocateHWnd(WndProc);
end;

procedure TMyObject.WndProc(var AMsg: TMessage);
begin
  if AMsg.Msg = WM_UPDATE then begin
    .........
  end;
end;

Стало
Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TMyObject.WndProc(var AMsg: TMessage);
begin
  if AMsg.Msg = WM_UPDATE then begin
    .........
  end else
    AMsg.Result := DefWindowProc(FHandle, AMsg.Msg, AMsg.WParam, AMsg.LParam);
end;


Теперь нужно остальные проекты причесать
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Блокировка завершения работы / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]