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

Вниз

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 вся ветка

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

Наверх




Память: 0.54 MB
Время: 0.036 c
14-1093289489
wnew
2004-08-23 23:31
2004.09.12
Странные, светлые пятна на фотографиях.


14-1093502826
Holy
2004-08-26 10:47
2004.09.12
Страховая пенсия


3-1092750216
Jey
2004-08-17 17:43
2004.09.12
Резервное копирование баз данных


1-1092556672
TeNY
2004-08-15 11:57
2004.09.12
Kylix Setup Error -10 :в чём проблема?


14-1093105357
Черный прапор
2004-08-21 20:22
2004.09.12
Сталкивались ли вы с переводом ресурсов (локализацией)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский