Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.12;
Скачать: CL | DM;

Вниз

CreateProcess, INFINITE и проблема с прорисовкой окон   Найти похожие ветки 

 
Skier ©   (2004-07-23 14:55) [0]

Если делать так
http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988621841&n=15
то появляется проблема с прорисовкой окон...

Не подскажите ли как сделать всё тоже самое что и в ссылке, но
чтобы можно было вызывать Application.ProcessMassages для обработки сообщений в очереди ?
И можно ли это сделать ?


 
wicked ©   (2004-07-23 15:03) [1]

это
> WaitForSingleObject( pi.hProcess, INFINITE );
заменить на
> wait_res := WaitForSingleObject( pi.hProcess, 100 );
> while wait_res = WAIT_TIMEOUT do begin
>     Application.ProcessMessages;
>     wait_res := WaitForSingleObject( pi.hProcess, 100 );
> end;


или я чего то недопонял?...


 
Skier ©   (2004-07-23 15:09) [2]

>wicked ©   (23.07.04 15:03) [1]
Нужно чтобы процесс запускался "модально"...


 
default ©   (2004-07-23 15:11) [3]

wicked ©   (23.07.04 15:03) [1]
только по твоему коду
лучше в одну строку
while WaitForSingleObject(pi.hProcess, 100 ) = WAIT_TIMEOUT  do Application.ProcessMessages


 
default ©   (2004-07-23 15:14) [4]

Skier ©   (23.07.04 15:09) [2]
поподробней(


 
wicked ©   (2004-07-23 15:17) [5]

тогда вместо:
> Application.ProcessMessages;
пишем
> while PeekMessage(Msg, Application.Handle, WM_PAINT, WM_PAINT, PM_REMOVE) do
>     DispatchMessage(Msg);

выбираем из очереди сообщений все WM_PAINT... имхо этого достаточно (не проверял)....


 
Sandman25 ©   (2004-07-23 15:17) [6]

Self.Enabled := False?


 
wicked ©   (2004-07-23 15:18) [7]

хотя не.... PeekMessage"у вместо Application.Handle надо передавать 0 для того, чтобы он все окна обрабатывал...


 
Суслик ©   (2004-07-23 16:19) [8]

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


 
wicked ©   (2004-07-23 16:23) [9]

хотя если не связываться с потоками, то оптимальным решением было бы [1] + [6]... имхо...


 
Бином Ньютоныч   (2004-07-24 16:08) [10]

MsgWaitForMultipleObjects(1, pi.hProcess, false, Timeout, QS_PAINT) ?


 
Skier ©   (2004-07-26 17:03) [11]

>Бином Ньютоныч   (24.07.04 16:08) [10]
Поподробней можно...особенно про параметр Timeout.
Во что он должен быть установлен для решения моей проблемы ?


 
Игорь Шевченко ©   (2004-07-26 17:12) [12]


> Если делать так
> http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988621841&n=15
> то появляется проблема с прорисовкой окон...


Какого рода проблема с прорисовкой окон появляется ?

Я использовал для решения подобной задачи функцию ShellExecuteEx + WaitForSingleObject


 
Skier ©   (2004-07-26 17:24) [13]

>Игорь Шевченко ©   (26.07.04 17:12) [12]

> Какого рода проблема с прорисовкой окон появляется ?

Например,... запускаю notepad в "модальном" режиме и если под
ним есть окна моего дельфийского приложения, то, если таскать
notepad мышью, окна не перерисовываются. Мне кажеться что нужно
правильно куда-то вставить ProcessMessages, но не знаю куда...:)


> Я использовал для решения подобной задачи функцию ShellExecuteEx
> + WaitForSingleObject

Поподробней не расскажешь ?


 
Игорь Шевченко ©   (2004-07-26 17:34) [14]

Skier ©   (26.07.04 17:24) [13]


> Например,... запускаю notepad в "модальном" режиме и если
> под
> ним есть окна моего дельфийского приложения, то, если таскать
> notepad мышью, окна не перерисовываются.


Разумеется. Ты же ждешь в своем приложении окончания работы другого процесса. Тогда тебе делать как в
Бином Ньютоныч   (24.07.04 16:08) [10]

Примерно так:

var
 WaitResult: DWORD;
begin
...... CreateProcess и прочая...
 WaitResult := MsgWaitForMultipleObjects(1, pi.hProcess, false,
      INFINITE, QS_PAINT);
   if WaitResult = WAIT_OBJECT_0 then begin
     { Процесс закончился }
     ......
   end else
     Application.ProcessMessages;
end;


> Поподробней не расскажешь ?


Нет, там тот же самый эффект будет, ты бы раньше написал то, что в [13]


 
Игорь Шевченко ©   (2004-07-26 17:37) [15]

Вдогонку - разумеется, процесс ожидания нужно поместить в цикл, из которого выходить по окончанию работы приложения.


 
Skier ©   (2004-07-26 17:41) [16]

> Игорь Шевченко ©   (26.07.04 17:34) [14]
Спасибо. Попробую.


> ты бы раньше написал то, что в [13]

Да, наверное...


 
Skier ©   (2004-07-26 17:44) [17]

>Игорь Шевченко ©   (26.07.04 17:37) [15]

> Вдогонку - разумеется, процесс ожидания нужно поместить
> в цикл,

while True do begin

//..............
if WaitResult = WAIT_OBJECT_0 then begin
 //...........
 Break;
end; //if
//..............

end; //while

Так ?


 
Игорь Шевченко ©   (2004-07-26 17:57) [18]

Skier ©   (26.07.04 17:44)


> Так ?


Практика - критерий истины :)
Некрасиво, но примерно так.


 
Skier ©   (2004-07-26 18:00) [19]

>Игорь Шевченко ©   (26.07.04 17:57) [18]

> Практика - критерий истины :)

:)

Спасибо ещё раз.


 
Бином Ньютоныч   (2004-07-26 19:42) [20]

Что-то типа такого, а?
 case MsgWaitForMultipleObjects(1, pi.hProcess, false, INFINITE, QS_PAINT) of
...
 WAIT_OBJECT_0 + 1 :
   while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
     DispatchMessage(Msg);
 ....


Сорри за задержку, не было менея тутоти:)


 
Бином Ньютоныч   (2004-07-26 19:48) [21]

Только вот с INFINITE я бы эта, того, поаккуратней был. Ктоего знает, этот другой процесс, вдруг повиснет.


 
Serge_ ©   (2004-07-27 03:54) [22]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
 procedure ExecDone;
   { Public declarations }
 end;
type TExecThread = class(TThread)
protected
procedure execute;override;
public
OnDone:TThreadMethod;
end;

var
 Form1: TForm1;

implementation

{$R *.dfm}
procedure TExecThread.Execute;
var si:STARTUPINFO;
pi:PROCESS_INFORMATION;
cmdline:string;
begin
ZeroMemory(@si,sizeof(si));
si.cb:=SizeOf(si);
cmdline:="sol.exe";
CreateProcess( nil, PChar(cmdline),  nil,nil,False,0,nil,nil,si,pi );
WaitForSingleObject( pi.hProcess, INFINITE );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
Synchronize(OnDone)
end;

procedure TForm1.ExecDone;
begin
Showmessage("Выполнение завершено...");
//
end;

procedure TForm1.Button1Click(Sender: TObject);
var t:TExecThread;
begin
t:=TExecThread.Create(True);
t.FreeOnTerminate:=true;
t.OnDone:=ExecDone;
t.Resume;
end;

end.


 
Skier ©   (2004-07-27 10:20) [23]

>Игорь Шевченко ©   (26.07.04 17:34) [14]
Не получается, к сожалению.
Перерисовка работает но notepad запускается "немодально", т.е.
можно переключиться на другое окно (окно моего приложения) пока
notepad работает...

вот код :


if not CreateProcess( nil,             // No module name (use command line).
                                 PChar(cmdline),  // Command line.
                                 nil,             // Process handle not inheritable.
                                 nil,             // Thread handle not inheritable.
                                 False,           // Set handle inheritance to FALSE.
                                 0,               // No creation flags.
                                 nil,             // Use parent"s environment block.
                                 nil,             // Use parent"s starting directory.
                                 si,              // Pointer to STARTUPINFO structure.
                                 pi )             // Pointer to PROCESS_INFORMATION structure.
           then begin
             //.............
             Exit;
           end;

           while True do begin
            WaitResult := MsgWaitForMultipleObjects(1, pi.hProcess, False, INFINITE, QS_PAINT);
            if WaitResult = WAIT_OBJECT_0 then Break
            else Application.ProcessMessages;
           end; //while


Может я что не так понял ?


 
panov ©   (2004-07-27 10:43) [24]

>Skier ©   (23.07.04 14:55)

Для перерисовки формы необязательно обрабатывать очередь сообщений.

Достаточно будет вызвать метод Update:


//Функция для создания нового процесса
//Параметры:
// aCommand:  Строка для выполнения исполняемого файла(полный путь)
// aShow:     Показывать/не показывать окно нового процесса
// aWaitExit: Ожидать/не ожидать завершения процесса

function ExecCmd(const aCommand: String;const aShow, aWaitExit: Boolean): Boolean;
var
 pi:PROCESS_INFORMATION;
 si:STARTUPINFO;
 cmdLine,Path: String;
 rc: Integer;
begin
 ZeroMemory(@si,sizeof(si));
 si.cb:=SizeOf(si);
 si.dwFlags := STARTF_FORCEONFEEDBACK+STARTF_USESHOWWINDOW;
 if aShow then si.wShowWindow := SW_SHOWNORMAL else si.wShowWindow := SW_HIDE;
 Path := ExtractFilePath(aCommand);
 cmdLine := aCommand;

 Result :=
        CreateProcess( nil,             // No module name (use command line).
                       PChar(cmdLine),  // Command line.
                       nil,             // Process handle not inheritable.
                       nil,             // Thread handle not inheritable.
                       False,           // Set handle inheritance to FALSE.
                       0,               // No creation flags.
                       nil,             // Use parent"s environment block.
                       PChar(Path),     // Use parent"s starting directory.
                       si,              // Pointer to STARTUPINFO structure.
                       pi );             // Pointer to PROCESS_INFORMATION structure.
 if Result then
 begin
   if aWaitExit then
   begin
     while WaitForSingleObject( pi.hProcess, 10)<>WAIT_OBJECT_0 do Form1.Update;
   end;
   CloseHandle(pi.hThread);
   CloseHandle(pi.hProcess);
 end;
end;


вызов:

procedure TForm1.Button1Click(Sender: TObject);
begin
 ExecCmd("c:\winnt\notepad.exe",True,True);
end;



 
Skier ©   (2004-07-27 10:47) [25]

>panov ©   (27.07.04 10:43) [24]
1) Будет ли (в твоём варианте) процесс "модальным" ?
2) Update очень подходит...если у меня на момент запуска
  notepad"a открыто несколько форм, то перечислять их все не  
  очень-то красиво...


 
Skier ©   (2004-07-27 10:48) [26]

в смысле 2) Update не очень подходит...:)


 
panov ©   (2004-07-27 10:54) [27]

>Skier ©   (27.07.04 10:47) [25]
1) Будет ли (в твоём варианте) процесс "модальным" ?

Да, будет-)

2) Update очень подходит...если у меня на момент запуска
 notepad"a открыто несколько форм, то перечислять их все не  
 очень-то красиво...



   if aWaitExit then
   begin
     while WaitForSingleObject( pi.hProcess, 10)<>WAIT_OBJECT_0 do
     begin
       for i := 0 to Screen.FormCount-1 do Screen.Forms[i].Update;
     end;
   end;


 
Skier ©   (2004-07-27 10:58) [28]

>panov ©   (27.07.04 10:54) [27]
Работает. Большое спасибо.


 
Бином Ньютоныч   (2004-07-27 11:49) [29]

>panov ©
Дергать каждые 10 мс поток без всякой на то необходимости мягко говоря неразумно.

>Skier ©
Что не получилось в таком варианте?

while true do
begin
 case MsgWaitForMultipleObjects(1, pi.hProcess, false, INFINITE, QS_PAINT) of
  WAIT_OBJECT_0: Break;
  WAIT_OBJECT_0 + 1 :
  {В очереди появились WM_PAINT, выбираем только их и переправляем окнам}
    while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do
      DispatchMessage(Msg);
 end;

end;


Вроде все модально, все перерисовывается при необходимости...непонятно.


 
panov ©   (2004-07-27 12:10) [30]

>Бином Ньютоныч   (27.07.04 11:49) [29]

Да, в примере с PeekMessage все нормально отрисовывается...



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

Текущий архив: 2004.09.12;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.041 c
14-1093342992
IGray
2004-08-24 14:23
2004.09.12
Где можно скачать Update Delphi 7.0 --> Delphi 7.1 ???


1-1093422967
Кирилл
2004-08-25 12:36
2004.09.12
Непрямоугольная форма


14-1093111146
Черный прапор
2004-08-21 21:59
2004.09.12
Какую (подерженную) иномарку выбрать


14-1092989958
ИМХО
2004-08-20 12:19
2004.09.12
AVI -> DVD


1-1093370651
Schummi
2004-08-24 22:04
2004.09.12
Вопрос про package