Solved

DOS Application window in my form

Posted on 2002-05-10
18
1,112 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
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
control image tags in a string ? 12 142
Adoquery sql  left join does not work 25 99
Dev express lookupcombo 3 35
how to change, disabled button color FMX ? 1 40
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
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…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

837 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