Solved

DOS Application window in my form

Posted on 2002-05-10
18
1,110 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
  • 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
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
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

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
TVirtualStringTree  search using TEdit 7 121
indy Tmemory stream non latin charcter issue 2 111
Run video youtube webbrowse 10 62
enhance the following code 3 32
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

810 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