powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Приложение после закрытия остается висеть в процессах
11 сообщений из 11, страница 1 из 1
Приложение после закрытия остается висеть в процессах
    #39738167
amadeus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть программа, создающая новое полноэкранное окно и выполняющая некоторые действия. Основной код программы:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
program prog;

uses
  windows,
  messages,
  window in 'window.pas';

{$APPTYPE GUI}

var
  window: TWindow;
  stop: Boolean = false;

begin
  window := TWindow.create("myProg");

  while (not stop) do begin
    sleep(10);
    stop := not window.update();
  end;

  window.free();
end.



Код модуля "window.pas":
Код: 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.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
unit window;

interface

uses
  windows, messages, sysUtils;

type
  TWindowError = class(Exception);

  TWindow = class(TObject)
  private
    FName: String;
    FHandle: HWnd;
  public
    constructor create(name: String); virtual;
    destructor destroy(); override;
    function update(): boolean;
  end;

implementation

function wndProc(window: HWnd; msgId, wParam, lParam: LongInt): LongInt; stdcall; export;
var
  msg: TMessage;
begin
  msg.msg := msgId;

  case msgId of
    WM_DESTROY: postQuitMessage(0);
  else
    wndProc := DefWindowProc(window, msgId, wParam, lParam);
    exit();
  end;

  result := msg.Result
end;

constructor TWindow.create(name: String);
var
  wndClass: TWndClass;
begin
  FName := name;

  wndClass.style := CS_HREDRAW or CS_VREDRAW;
  wndClass.cbClsExtra := 0;
  wndClass.cbWndExtra := 0;
  wndClass.hInstance := hInstance;
  wndClass.hIcon := loadIcon(0, IDI_INFORMATION);
  wndClass.hCursor := loadCursor(0, IDC_ARROW);
  wndClass.hbrBackground := hBrush(getStockObject(BLACK_BRUSH));
  wndClass.lPszMenuName := nil;
  wndClass.lPszClassName := PWideChar(name);
  wndClass.lpfnWndProc := @wndProc;

  if (registerClass(wndClass) <> 0) then begin
    FHandle := createWindow(
      PWideChar(name),
      PWideChar(name),
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      0,
      0,
      hInstance,
      nil
    );

    if (FHandle <> 0) then begin
      setWindowLong(FHandle, GWL_STYLE, WS_POPUP);
      showWindow(FHandle, SW_MAXIMIZE);
    end
    else TWindowError.create('Не удается создать окно.');
  end
  else
    raise TWindowError.create('Не удается зарегистрировать класс.');
end;

destructor TWindow.destroy();
begin
  destroyWindow(FHandle);

  inherited;
end;

function TWindow.update(): boolean;
var
  msg: TMsg;
begin
  result := true;

  while (peekMessage(msg, FHandle, 0, 0, 0)) do begin
    if (getMessage(msg, FHandle, 0, 0)) then begin
      translateMessage(msg);
      dispatchMessage(msg);

      if (msg.message = WM_DESTROY) then
      exit(false);
    end;
  end;
end;

end.



Проблема в том, что программа при закрытии окна остается висеть в диспетчере задач - видимо, цикл работает, не проходит до этой строки:

Код: pascal
1.
window.free();



А это значит, что метод "TWindow.update" не возвращает false, хотя должен при получении "WM_DESTROY"... В чем я ошибся?
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738177
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amadeusВ чем я ошибся?

Во-первых, в возвращаемых значениях оконной функции.
amadeusметод "TWindow.update" не возвращает false
Не вижу строчки в которой там упоминается false.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738190
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovНе вижу
Код: pascal
1.
exit(false);
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738204
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как это, работает у вас ?

Код: pascal
1.
  window := TWindow.create("myProg");
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738266
amadeus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторВо-первых, в возвращаемых значениях оконной функции.

В чем именно там ошибка?
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738271
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amadeusВ чем именно там ошибка?

Безмозглый копипаст вижу я. А вот инициализацию msg.Result - нет. А ведь
MSDNReturn Value

If an application processes this message, it should return zero.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738352
amadeus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
7.
  msg.msg := msgId;

  case msgId of
    WM_DESTROY: postQuitMessage(0);
  else
    result := defWindowProc(window, msgId, wParam, lParam);
  end;



Оставил такой код в этой функции, но ошибка все равно есть. Возможно, проблема не здесь, а в чем-то еще.
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738365
amadeus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Думаю, проблема в том, что коды сообщений, получаемых после вызова "getMessage" и в "wndProc", разные. Поэтому может не работать проверка на "WM_DESTROY" в "update".
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738427
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amadeus,

Проблема в том, что надо уметь читать документацию:

Microsoft DocsThe PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.GetMessage ParametershWnd

Type: HWND

A handle to the window whose messages are to be retrieved. The window must belong to the current thread.

If hWnd is NULL, GetMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed. PeekMessageW ParametershWnd

Type: HWND

A handle to the window whose messages are to be retrieved. The window must belong to the current thread.

If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed.

Я выделил жирным критичные моменты, в принципе этого должно хватить чтобы понять почему не работает. Если вдруг не хватит, то под катом - код, который у меня работает.
Ахтунг! Delphi 7
Код: 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.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
program apiform;

uses
  Windows,
  Messages,
  SysUtils;

type
  TWindowError = class(Exception);

  TWindow = class(TObject)
  private
    FName: String;
    FHandle: HWnd;
  public
    constructor create(name: string); virtual;
    function update(): boolean;
  end;

function wndProc(window: HWnd; msgId, wParam, lParam: LongInt): LongInt; stdcall;
begin
  if msgId = WM_DESTROY then
    postQuitMessage(0);
  Result := DefWindowProc(window, msgId, wParam, lParam); // call DestroyWindow() on WM_DESTROY
end;

constructor TWindow.create(Name: string);
var
  wndClass: TWndClass;
begin
  FName := Name;

  wndClass.style := CS_HREDRAW or CS_VREDRAW;
  wndClass.cbClsExtra := 0;
  wndClass.cbWndExtra := 0;
  wndClass.hInstance := hInstance;
  wndClass.hIcon := loadIcon(0, IDI_INFORMATION);
  wndClass.hCursor := loadCursor(0, IDC_ARROW);
  wndClass.hbrBackground := hBrush(getStockObject(BLACK_BRUSH));
  wndClass.lPszMenuName := nil;
  wndClass.lPszClassName := PChar(Name);
  wndClass.lpfnWndProc := @wndProc;

  if (registerClass(wndClass) <> 0) then begin
    FHandle := createWindow(
      PChar(name),
      PChar(name),
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      0,
      0,
      hInstance,
      nil
    );

    if (FHandle <> 0) then begin
      setWindowLong(FHandle, GWL_STYLE, WS_POPUP);
      showWindow(FHandle, SW_MAXIMIZE);
    end
    else TWindowError.create('CreateWindow error.');
  end
  else
    raise TWindowError.create('RegisterClass error.');
end;

function TWindow.update(): boolean;
var
  msg: TMsg;
begin
  Result := False;
  while (PeekMessage(msg, 0, 0, 0, 0)) do
  begin
    if GetMessage(msg, 0, 0, 0) then
    begin
      TranslateMessage(msg);
      DispatchMessage(msg);
    end else
      Exit;
  end;
  Result := True;
end;

begin
  with TWindow.create('myProg') do
  try
    while update() do
      sleep(10);
  finally
    Free;
  end;
end.


...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738503
amadeus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp , спасибо, буду разбираться.
...
Рейтинг: 0 / 0
Приложение после закрытия остается висеть в процессах
    #39738575
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amadeusОставил такой код в этой функции

Прелестно... Т.е. ты вообще забил на процитированное мною "функция должна возвращать..."
или просто не смог это прочитать?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Приложение после закрытия остается висеть в процессах
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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