DOS Application window in my form

This is a strange one. I want to be able to run a DOS application so it displays INSIDE my form. Like when you start command prompt it appears in its own window. I want this window to be in my form.

1. The application will be initiated from Delphi.
2. DOS Application should be terminated from itself or from my Delphi application

gragaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Tomas Helgi JohannssonCommented:
Hi!

Take a look at the TDosMemo v.1.00 on Torry's Delphi Pages
http://www.torry.net/memos.htm
This is a great way to display a running DOS application "inside" a Delphi form.

Regards,
Tomas Helgi
0
ginsonicCommented:
interested
0
gragaAuthor Commented:
Tomas, which memo component is that?
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

Tomas Helgi JohannssonCommented:
I gave you the name of the component (TDosMemo).
Go to the link I posted and scroll half way down and
you should see it.

Regards,
Tomas Helgi
0
gragaAuthor Commented:
Tomas, sorry it's been a long day...

I'm just reading the description of the component. It looks like the component lets you re-direct output from a DOS application to a memo, not to run the program. That's not what I need.

Graga
0
MBoCommented:
0
MBoCommented:
sorry above link isn't working
Try
http://master-brain.boom.ru
then press Download
and find
DosCommand.zip
0
geobulCommented:
listening...
0
gragaAuthor Commented:
MBo,

I think we are on the wrong track. Both components allow to capture DOS command output to a memo field. This is not what I want. I want to display an interactive DOS application.

graga
0
Lee_NoverCommented:
well you can launch the dos app with CreateProcess then use dwProcessID from  the returned PROCESSINFO structure
to get the window from the processid use the folowing code

function EnumWindowsProc(Wnd: hWnd; ProcWndInfo: PProcessWindow): BOOL;
stdcall;
var
    WndProcessID: Cardinal;
begin
    GetWindowThreadProc(Wnd, WndProcessID);
    if WndProcessID = ProcWndInfo^.TargetProcessID then begin
        ProcWndInfo^.FoundWindow := Wnd;
        Result := False; // This tells EnumWindows to stop enumerating since
we've already found a window.
    end else Result := True; // Keep searching
end;

function GetProcessWindow(TargetProcessID: Cardinal): hWnd;
var
    ProcWndInfo: TProcessWindow;
begin
    ProcWndInfo.TargetProcessID := TargetProcessID;
    ProcWndInfo.FoundWindow := 0;
    EnumWindows(@EnumWindowsProc, @ProcWndInfo);
    Result := ProcWndInfo.FoundWindow;
end;


then simply set the windows parent to your form or panel or whatever control you wish  
the usage would be smth like :

ok:=CreateProcess(nil, 'DosApp.exe, nil, nil, true,
      NORMAL_PRIORITY_CLASS, nil, nil, si, pi);
if ok then
  Windows.SetParent(GetProcessWindow(pi.dwProcessId), somePanel.Handle);

I haven't tested it but that's the basic idea :)
0
Lee_NoverCommented:
forgot the :

type
  PProcessWindow = ^TProcessWindow;
  TProcessWindow = record
    TargetProcessID: Cardinal;
    FoundWindow: hWnd;
  end;
0
Lee_NoverCommented:
ehh :) just made a test app ,, the code bellow works just fine :



unit Unit1;

interface

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

type
  PProcessWindow = ^TProcessWindow;
  TProcessWindow = record
    TargetProcessID: Cardinal;
    FoundWindow: hWnd;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    OpenD: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  hDosWin: HWND = 0;

implementation

{$R *.dfm}

function EnumWindowsProc(Wnd: hWnd; ProcWndInfo: PProcessWindow): BOOL;stdcall;
var
   WndProcessID: Cardinal;
begin
   GetWindowThreadProcessId(Wnd, WndProcessID);
   if WndProcessID = ProcWndInfo^.TargetProcessID then begin
       ProcWndInfo^.FoundWindow := Wnd;
       Result := False; // This tells EnumWindows to stop enumerating since we've already found a window.
   end else Result := True; // Keep searching
end;

function GetProcessWindow(TargetProcessID: Cardinal): hWnd;
var
   ProcWndInfo: TProcessWindow;
begin
   ProcWndInfo.TargetProcessID := TargetProcessID;
   ProcWndInfo.FoundWindow := 0;
   EnumWindows(@EnumWindowsProc, Integer(@ProcWndInfo));
   Result := ProcWndInfo.FoundWindow;
end;

procedure TForm1.Button1Click(Sender: TObject);
var si: STARTUPINFO;
    pi: TProcessInformation;
    ok: Boolean;
begin
     if not OpenD.Execute then exit;
     FillChar(si, SizeOf(si), 0);
     si.cb:=SizeOf(si);
     si.wShowWindow:=SW_SHOW;
     ok:=CreateProcess(nil, PChar(OpenD.FileName), nil,
       nil, true, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, si, pi);

     if not ok then exit;

     hDosWin:=GetProcessWindow(pi.dwProcessID);
     if hDosWin > 0 then
     begin
       Windows.SetParent(hDosWin, Panel1.Handle);
       SetWindowPos(hDosWin, 0, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOZORDER);
     end;

     // we don't need the handles so we close them
     CloseHandle(pi.hProcess);
     CloseHandle(pi.hThread);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     if hDosWin > 0 then
        PostMessage(hDosWin, WM_CLOSE, 0, 0);
end;

end.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gragaAuthor Commented:
Lee, this looks good!
I can't however compile your code. It's complaining about "Variants" in uses clause.
When removed, GetWindowThreadProcessId complains about incompatible types.
I'm running D5
0
geobulCommented:
Hi,

I also like it. Nice code Lee_Nover ;-)

1. My uses clause (D5):
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

2.
GetWindowThreadProcessId(Wnd, @WndProcessID);

3.Add
Sleep(100);
or more after CreateProcess to let the new process to create its main window.

Regards, Geo
0
Lee_NoverCommented:
ahh yes sorry about the incompatibility :)
as you can see from the first code it is made for D5, I had to change it coz I'm using D6 :)
glad it helps :)
0
L44Commented:
I would also like to know how to run command prompt in my application ? Lee Nover, I've compiled your code,but still don't know how does it work?! what should I open, when open dialog appear ? cmd.exe ?

Thanks
0
RBritzCommented:
Hi all, I know this is an old thread, but, I was wondering...

The above code compiles/runs without any errors, but doesn't move/assign the dos window to the Panel as a parent (maybe it does, but the dos window is still not running in the panel), BUT as soon as I debug and step through it.... the dos window is assigned to the panel. I'm using D6... Any Ideas!?
0
geobulCommented:
Hi,

Add
Sleep(100);
or more after CreateProcess to let the new process to create its main window. Otherwise GetProcessWindow will return nothing and you won't have a window handle to set parent to.

Regards, Geo
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.