Solved

DOS Application window in my form

Posted on 2002-05-10
18
1,113 Views
Last Modified: 2007-11-27
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

0
Comment
Question by:graga
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
  • 3
  • +5
18 Comments
 
LVL 25

Expert Comment

by:Tomas Helgi Johannsson
ID: 7000749
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
 
LVL 9

Expert Comment

by:ginsonic
ID: 7000778
interested
0
 

Author Comment

by:graga
ID: 7000811
Tomas, which memo component is that?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 25

Expert Comment

by:Tomas Helgi Johannsson
ID: 7000873
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
 

Author Comment

by:graga
ID: 7000960
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
 
LVL 1

Expert Comment

by:MBo
ID: 7001030
0
 
LVL 1

Expert Comment

by:MBo
ID: 7001037
sorry above link isn't working
Try
http://master-brain.boom.ru
then press Download
and find
DosCommand.zip
0
 
LVL 17

Expert Comment

by:geobul
ID: 7001044
listening...
0
 

Author Comment

by:graga
ID: 7002149
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7002413
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7002418
forgot the :

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

Accepted Solution

by:
Lee_Nover earned 200 total points
ID: 7002454
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
 

Author Comment

by:graga
ID: 7002713
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
 
LVL 17

Expert Comment

by:geobul
ID: 7002873
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7003126
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
 

Expert Comment

by:L44
ID: 7477078
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
 

Expert Comment

by:RBritz
ID: 21982184
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
 
LVL 17

Expert Comment

by:geobul
ID: 21986049
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

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question