Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > А как сделать MDI форму из чужого окна?


Автор: Гость_ГОСТЬ 19.4.2004, 05:11
Допустим у меня из программы выполняеться
ShellExecute(h, 'open', 'ping.exe', ....
запускаеться стандартное cmd окно винды, как его бы сделать типа MDI окошко, чтобы можно было им на главной форме управлять....
Возможно вообще такое?

Автор: x77 19.4.2004, 09:36
возможно, только геморройно. нижеприведённый код запускает досовскую прогу в мемо-контроле (т.е. весь выход, всё, что она генерит, выводится не в смд, а в мемо). а уже само это мемо размещай где хочешь, в т.ч. и в mdi-форме.

Код

procedure RunInMemo;
const
 bufsize = 2000;
var
 sa: TSecurityAttributes;
 si: TStartupInfo;
 pi: TProcessInformation;
 rp, wp: THandle;
 buf: pchar;
 ec: dword;
 bread: dword;
begin
 with sa do begin
   nLength := SizeOf (TSecurityAttributes);
   bInheritHandle := TRUE;
   lpSecurityDescriptor := nil;
 end;
 if CreatePipe (rp, wp, @sa, 0) then begin
   FillChar (si, SizeOf (TStartupInfo), #0);
   with si do begin
     cb := SizeOf (si);
     hStdInput := rp;
     hStdOutput := wp;
     dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
     wShowWindow := SW_HIDE;
   end;
   buf := AllocMem (bufsize + 1);
   try
     if CreateProcess (nil, pchar (Cmd), @sa, @sa, TRUE, NORMAL_PRIORITY_CLASS, nil, nil, si, pi) then begin
       repeat
         ec := WaitForSingleObject (pi.hProcess, 500);
       until ec <> WAIT_TIMEOUT;
       bread := 0;
       repeat
         ReadFile (rp, buf [0], bufsize, bread, nil);
         buf [bread] := #0;
         OemToAnsi (buf, buf);
         Memo.Text := Memo.Text + string (buf);
         Application.ProcessMessages;
       until bread < bufsize;
     end;
   finally
     FreeMem (buf);
     CloseHandle(pi.hProcess);
     CloseHandle(pi.hThread);
     CloseHandle(rp);
     CloseHandle(wp);
   end;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 RunInMemo ('C:\WINNT\system32\netstat', Memo1);
end;


если это дело слегка изменить:
Код

       ...
       repeat
         ec := WaitForSingleObject (pi.hProcess, 500);
         ReadFile (rp, buf [0], bufsize, bread, nil);
         buf [bread] := #0;
         OemToAnsi (buf, buf);
         Memo.Text := Memo.Text + string (buf);
         Application.ProcessMessages;
       until ec <> WAIT_TIMEOUT;
       ...


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

но здесь перехватывается только вывод. по идее, можно заморочиться, чтобы перехватывался и ввод, по тому же принципу.
Добавлено @ 09:39
изначально этот код мне попался с комментариями на то ли испанском, то ли итальянском, и глючил он безбожно. я тебе привёл отрывок уже из своего проекта, многократно правленный. но там тоже есть заморочки, например, у меня стабильно всё валится в эксепшн, если WaitForSingleObject передавать интервал меньше 100. почему - я до сих пор не понимаю.

Автор: Гость_ГОСТЬ 20.4.2004, 01:06
x77
спасибо конечно, так я делал , но геморойно ......., особенно если ping в окошке запускать, а если тарссировку то вообще кердык smile.gif
вот если бы можно было запихнуть в MDI окошко, может кто знает ????
HELP ME!!!!!
baaa.gif

Автор: x77 20.4.2004, 13:16
единственное, что приходит в голову - это отлавливать консоль и позиционировать её на своей форме, не давай перекрываться. изврат, конечно, но мне кажется, иллюзии работы "внутри" окна можно добиться.

Автор: z-END 20.4.2004, 21:47
еще можно такой вариант попробывать:
Windows.SetParent (ханд окна "ping.exe", хандл того контрола в который ее надо засунуть)

Автор: Гость_Гость 26.4.2004, 02:29
nJIaKca.spb благодарю тебя !!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)