Текущий архив: 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.54 MB
Время: 0.03 c