Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.09.19;
Скачать: [xml.tar.bz2];

Вниз

Как культурно закрыть процесс ?   Найти похожие ветки 

 
Sasha73 ©   (2004-07-28 12:45) [0]

Добрый день, уважаемые мастера!
Вопрос глупый, но все же!
Есть програмка:
Program Mishen;
Uses
 Windows, SysUtils, Forms, QDialogs, QControls, ExtCtrls;

{$R *.RES}

  Var
     Quit     : Bool;

BEGIN
    Quit:=False;
    Application.Initialize;
    Repeat
          Application.ProcessMessages;
          Sleep(50);
    Until Quit;

    ShowMessage("Exit!");
END.

Вопросы:
1. Как узнать что Win-да выгружается (как, чем поймать сообщение WM_Quit) (очень туго у меня с сообщениями)?
2. Как из другого процесса послать сообщение WM_Quit этому ?


 
Digitman ©   (2004-07-28 12:51) [1]

а куда у тебя форма делась ?


 
Sasha73 ©   (2004-07-28 13:04) [2]

А ее и не было!
Это просто процесс!
С формой было бы проще!


 
Digitman ©   (2004-07-28 13:06) [3]


> А ее и не было!


видать, потерялась


> Это просто процесс!


это не "процесс", это текст программы, использующей VCL


> С формой было бы проще!


ну так а какого ж ляда ? добавь форму и не мучайся !
или сомнения гложут ?


 
Sasha73 ©   (2004-07-28 13:17) [4]

В том то и дело - НЕ НУЖНА мне форма!
Спасибо за информативные ответы!


 
Digitman ©   (2004-07-28 13:22) [5]


> Sasha73

угу ... а объект TApplication тогда зачем тебе ? ... ты выкинул из проекта форму, оставив при этом модуль Forms, и думаешь что сэкономил пару-тройку сотен килобайт ?


 
Sasha73 ©   (2004-07-28 13:28) [6]

Вообще прога для видео-захвата используя DirectShow!
Application.Initialize надо для инициализации подключенных библиотек!
Я думаю TApplication и можно использовать для поимки соосщения WM_Quit или я не прав? Но как ? Туго у меня с сообщениями!
Хотябы где посмотреть примерчики об этом?


 
Ertong ©   (2004-07-28 13:34) [7]


> В том то и дело - НЕ НУЖНА мне форма!

А зачем тебе
Application.Initialize;
Application.ProcessMessages;


 
Digitman ©   (2004-07-28 13:40) [8]


> Application.Initialize надо для инициализации подключенных
> библиотек!


цитирую :

Provides an opportunity to initialize sub-systems such as OLE automation.

procedure Initalize;

Description

Initialize is the first method called for every project. It calls the InitProc procedure pointer. By default, the call to Initialize for the application does nothing because the default InitProc pointer is nil .

To use Initialize, the InitProc pointer must be predefined. This can be accomplished in one of two ways:

Include a unit that defines InitProc, such as the OleAuto unit.
Create a custom initialization procedure that assigns a value to the InitProc pointer, and add a call to this procedure to the project source prior to the call to Initialize.

я не вижу, чтобы у тебя в проекте где-то явно или неявно выполнялись условия, обозначенные в цитате жирным и оправдывающие использование объекта Application и его метода Initialize

что для начала на это скажешь ?


 
Digitman ©   (2004-07-28 13:44) [9]


> 1. Как узнать что Win-да выгружается
> 2. Как из другого процесса послать сообщение WM_Quit этому
> ?


1. Лови сообщение WM_QUERYENDSESSION

The WM_QUERYENDSESSION message is sent when the user chooses to end the Windows session or when an application calls the ExitWindows function

2. При использовании TApplication следет посылать сообщение окну с хэндлом Application.Handle


 
Sasha73 ©   (2004-07-28 13:53) [10]

Спасибо за ответы!
Может я не прав на счет Application.Initialize, но без него видео захват у меня не работает - Это не важно (пока)!

> Digitman ©   (28.07.04 13:44) [9]

Вот я и пытался спросить: как и в каком месте поймать сообщение, например, WM_QUERYENDSESSION ??? (ТУГО у меня с этим, да и стем, наверное, тоже ;-) )


 
Digitman ©   (2004-07-28 14:13) [11]


> без него видео захват у меня не работает


ну очевидно потому что где-то в проекте явно или неявно используется модуль OleAuto .. а вообще говоря выражение "не работает" отдает детским садом, а не речью программиста ... что значит "не работает" ?


> как и в каком месте поймать сообщение, например, WM_QUERYENDSESSION


коль скоро TApplication ты вынужден использовать, то проще всего создать и подключить к проекту невидимую форму, у которой будет назначен обработчик как минимум одного события OnCloseQuery, реагирующего в т.ч. и на это сообщение

Program Mishen;
Uses
Windows, SysUtils, Forms, QDialogs, QControls, ExtCtrls;

{$R *.RES}

BEGIN
Application.Initialize;
Application.ShowMainForm := false;
Application.CreateForm(TMyInvisibleForm, MyInvisibleForm);
MyInvisibleForm.Run;
END.

и все !! и никаких выкрутасов !!

теперь, когда сессия ОС будет завершаться либо какой-то процесс пошлет сообщение окну с хэндлом равным Application.Handle, у твоей формы MyInvisibleForm возникнет событие OnCloseQuery


 
Sasha73 ©   (2004-07-28 14:40) [12]

Большое СПАСИБО!

И последнее:
Предположим мы убрали объект TApplication - получили:
Program Mishen;
Uses
 Windows, QDialogs;
{$R *.RES}
  Var
     Quit     : Bool;
BEGIN
    Quit:=False;
    Repeat
//           Application.ProcessMessages;
          Sleep(50);
    Until Quit;
    ShowMessage("Exit!");
END.

1. Я так понимаю вместо Application.ProcessMessages нужно сто-то вставить, чтобы обрабатывались сообщения?
2. Как в таком случае узнать, что пора сохраниться и закрыться?


 
Digitman ©   (2004-07-28 14:52) [13]


> Sasha73 ©   (28.07.04 14:40) [12]


я не понимаю, чем вызвано твое упрямство и возражения против ГОТОВОГО выше приведенного кода ? зачем тебе эти подробности ? их изложение потянет на целую лекцию !

факт возбуждения события формы OnCloseQuery и есть ожидаемое тобой событие


 
Sasha73 ©   (2004-07-28 15:06) [14]

С OnCloseQuery и так понятно!
А без формы (вообще) все на столько сложно?


 
Digitman ©   (2004-07-28 15:33) [15]


> на столько сложно?


да нет, не сложно

repeat
 Application.HandleMessage
until Terminated;


 
Kurtevich   (2004-07-28 19:25) [16]

без формы вобще все совсем не так сложно, и без ТАппликатион тоже... просто надо вызывать функцию виндовз: GetMessage или PeekMessage (как делает сама Дельфя), например... будет всего на пару строчек больше... кажись она может даже без окна работать...

вобщем делаешь так: берешь исходники vcl, находишь TApplication.ProcessMessage, и тупо дерешь оттудава все че те нада, с чуством спокойствия на душе оттого, что ты по сути ничего не меняешь по сравнению с вызовом сопственно ProcessFucksaggesss или whatever.... заодно посмотришь скока гавна эти подонки навешивают на невинные виндовские функции! :)

внимание, пример кода:

while not Quit do
 if PeekMessage(Msg, 0, 0, 0, PM_REMOVE)
   and Msg.Message <> WM_??? then QUIT := true;

 
всего делов-то... :)


 
Kurtevich   (2004-07-28 19:27) [17]

а Digitman-а этого ты не слушай - он любитель потрепаться и похвастаться своим превосходством над несчастными лузерами, а вот дельный совет дать его че-то ломит...


 
Kurtevich   (2004-07-28 19:30) [18]

да, вместо WM_??? конечно же надо вставить WM_CLOSEQUERY или как оно там называется anyway... я просто не знаю, это надо где-то посмотреть


 
Sasha73 ©   (2004-07-29 10:45) [19]

Огромное спасибо за ответы > Kurtevich   (28.07.04 19:25) [16] !
Пока меня Digitman пинал, я до этого уже сам дошел, но сообщений никаких не ловлю!
Сделал так:
    Log("Запуск удачный!");
    While True do begin
//       Application.ProcessMessages;
      if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then begin
        if Msg.Message <> WM_QUIT then begin
          TranslateMessage(Msg);
          DispatchMessage(Msg);
        end
        else begin
          Log("Сообщение "+IntToStr(Msg.message)+"!");
          Break;
        end
      end
      else Log("Нет сообщений !");
    end;

{    repeat
          Application.HandleMessage;
          If Application.Terminated then Log("Exit");
    until Application.Terminated;}

    Log("Exit");


 
Sasha73 ©   (2004-07-29 11:02) [20]

Не обращайте внимание на сообщение > Sasha73 ©   (29.07.04 10:45) [19] это я поспешил!
Розбираюсь!


 
Digitman ©   (2004-07-29 11:42) [21]


> Sasha73 ©   (29.07.04 10:45) [19]
> Пока меня Digitman пинал


и кто ж тебя, сироту, "пинал", а ?) что ж ты как ххххх в проруби-то ?)

нравится тебе Application - ну так и пользуй готовый подходящий цикл С ОЖИДАНИЕМ СООБЩЕНИЙ, реализованый Борландом в публичном метода Handlemessage ! Run() еще проще для организации цикла, но не подойдет тебе из-за того что ты отказываешься от формы в проекте ..Чего еще велосипед-то изобретать ? А потом жаловаться будешь, что некто Kurtevich, "приласкавший" тебя, горемычного, впарил тебе цикл, приведший к 100%-му CPU Usage твоим процессом ..


 
Kurtevich   (2004-07-29 12:58) [22]

ладно, ладно... GetMessage конечно же лучше... если б я не полез в исходники tapplication, то про Peek Message я б даже и не узнал никогда... а мораль - нефиг лазить по всяким...

Log("Запуск удачный!");
   While GetMessage(Msg, 0, 0, 0) do
     if Msg.Message <> WM_CLOSEQUERY then DoSomething()
     else break;
   end;

   Log("Exit");


так будёт лушше... горемычный ты мой... :)


 
Digitman ©   (2004-07-29 13:38) [23]


> Kurtevich   (29.07.04 12:58) [22]


а что это тебя так задело ? ...
ты предлагаешь заведомо "кривой" вариант, да еще и не используя ГОТОВЫХ возможностей Application (коль автор на нем таки настаивает) - и после этого еще у тебя хватает совести делать заявления а-ля "дельный совет дать его че-то ломит" ? Дельный совет автор получил уже в [15], НО после анализа требований по действительной необходимости исп-я TApplication !


 
Sasha73 ©   (2004-07-29 13:50) [24]

Извините, кого задолбал полностью!
Но пишем:

    Log("Запуск удачный!");
    While GetMessage(Msg, 0, 0, 0) do begin
        If Msg.Message=WM_TIMER then Log("Сообщение: WM_TIMER");
        If Msg.Message<>WM_TIMER then Log("Сообщение "+IntToStr(Msg.message)+"!");
    end;
    Log("Exit");

Получаем лог:
29.07.2004 12:20:59  Запуск удачный!
29.07.2004 12:20:59  Сообщение: WM_TIMER
29.07.2004 12:21:00  Сообщение: WM_TIMER
29.07.2004 12:21:00  Сообщение: WM_TIMER
29.07.2004 12:21:00  Сообщение: WM_TIMER
29.07.2004 12:21:00  Сообщение: WM_TIMER
29.07.2004 12:21:00  Сообщение: WM_TIMER
29.07.2004 12:21:01  Сообщение: WM_TIMER
29.07.2004 12:21:01  Сообщение: WM_TIMER
29.07.2004 12:21:01  Сообщение: WM_TIMER
29.07.2004 12:21:01  Сообщение: WM_TIMER
29.07.2004 12:21:01  Сообщение: WM_TIMER
29.07.2004 12:21:02  Сообщение: WM_TIMER
29.07.2004 12:21:02  Сообщение: WM_TIMER
29.07.2004 12:21:02  Сообщение: WM_TIMER
29.07.2004 12:21:02  Сообщение: WM_TIMER
29.07.2004 12:21:02  Сообщение: WM_TIMER
29.07.2004 12:21:03  Сообщение: WM_TIMER


Это с момента работы и до перезагрузки Винды (не резетом ;-))!
Где в логе "Exit", неужели Винда не посылает ничего перед выгрузкой, неужели она делает  TerminateProcess(...)? Где я не прав?
Мне просто нужно сохранение сделать вместо Log("Exit");

Кстати код (> Digitman ©   (28.07.04 15:33) [15]) :
repeat
Application.HandleMessage
until Terminated;
Log("Exit");

Тоже ничего не оставляет в логе при перезагрузке!

P.S.:
И отдельно хотелось бы ответить на фразу:

>Digitman ©   (28.07.04 14:13) [11]
> а вообще говоря выражение "не работает" отдает детским садом,
> а не речью программиста ... что значит "не работает" ?


Мне кажется форумы созданы не только для крутых программистов!
Я например занимаюсь Администрированием!
А писать приходится только для себя, чтобы облегчить себе работу!
Учился всему только сам (с книжками), да и то под ДОС! Знаю паскаль, ассемблер (не на высшем уровне, но все таки)!
Под ДОС-ом, как по мне, все гораздо проще было - разобрался с прерываниями и функциями ДОС, БИОС и можно писать!
А в Винде тут всякие сообщения, исключения, методы, классы,....-черт ногу сломает! Нету у меня времени этим заниматься!
Я бы то и не лез в это, но, говорю ж, пытаюсь облегчить себе жизнь (а Вам, наверное, отяжелить) - почтового робота, например, написать, да и еще для Офиса кое-что!
Поэтому, не судите строго!


 
Digitman ©   (2004-07-29 14:04) [25]

repeat
Application.HandleMessage
until Terminated;
MessageBox(0, "Завершение процесса", "", mb_ok + mb_setforeground);

если увидишь это сообщение, то разбирайся , почему твой лог не работает - значит, что-то в нем некорректно


 
Sasha73 ©   (2004-07-29 15:38) [26]

Я не полностью код привел. Было так:

    Application.Initialize;
    Log("Запуск удачный!");
    repeat
          Application.HandleMessage
    until Application.Terminated;
    ShowMessage("Exit!");
    Log("Exit");


Да и процедура Log незамысловатая:

Procedure Log( St : String );
   Const
        FileMailLog = "__exit.log";
     Var
        FOut              : TextFile;
   Begin
        AssignFile(FOut,FileMailLog);
        {$I-}
        If FileExists(FileMailLog) then Append(FOut) else ReWrite(FOut);
        {$I+}
        If IOResult=0 then
           Begin
                WriteLn(FOut,FormatDateTime("dd/mm/yyyy hh:nn:ss  ",Now)+St);
                CloseFile(FOut)
           End
   End;


Но все же формы нет - может поэтому!


 
Kurtevich   (2004-07-29 19:09) [27]

придется наверно создавать невидимое окно и ловить для него сообщения.... праа лишних строчек, зато намного цивильнее :))


 
Digitman ©   (2004-07-30 08:15) [28]


> Sasha73 ©   (29.07.04 15:38) [26]


> формы нет - может поэтому


да ни причем здесь форма, она лишь ощутимо упростит реализацию алгоритма в целом

ну messageBox() поймал ?


> Kurtevich   (29.07.04 19:09) [27]
> придется наверно создавать невидимое окно и ловить для него
> сообщения


объект Application  и так уже создает невидимое окно, на кой ляд еще одно создавать ?


 
Sasha73 ©   (2004-07-30 10:59) [29]


> ну messageBox() поймал ?

Нету никакого MessageBox() (на экране), ни лога "Exit" в файле!
А если прочитать внимательно > Sasha73 ©   (29.07.04 13:50) [24], то вообще видно, что кроме WM_TIMER, ни хрена больше не ловится!
МОЖЕТ ПЛЮНУТЬ НА ВСЕ ЭТО?


 
Digitman ©   (2004-07-30 11:25) [30]

function MyTerminateFunc: Boolean;
begin
 Log("MyTerminateFunc");
 Result := True;
end;
...
   Application.Initialize;
   AddTerminateProc(@MyTerminateFunc);
   repeat
         Application.HandleMessage
   until Application.Terminated;


 
Игорь Шевченко ©   (2004-08-03 18:10) [31]

Kurtevich

Ты б матчасть выучил, что ли...Прежде чем всякий бред постить


 
Sasha73 ©   (2004-08-05 12:13) [32]

СПАСИБО ВСЕМ!
Извините, что долго не отвечал - несколько дней Инет не работал (хотя Вы, наверное, только рады были  ;-) )!

> Digitman ©   (30.07.04 11:25) [30]
- этот код тоже не помог (ничего не происходит)!

Думаю тему можно закрывать - я все таки создал окно через CreateWindowEx() - там все ловится без вопросов, ну и черт с ним!!!



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.09.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.034 c
1-1094477837
Lord de Mon
2004-09-06 17:37
2004.09.19
Ошыбки


14-1094089809
Думкин
2004-09-02 05:50
2004.09.19
С днем рождения! 2 сентября


1-1094187250
Fynjy
2004-09-03 08:54
2004.09.19
OpenGL


14-1093593865
gn
2004-08-27 12:04
2004.09.19
CaribeНа


1-1093936918
O?O
2004-08-31 11:21
2004.09.19
Неактивность приложения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский