Loading another application in a panel

  • (2 Pages)
  • +
  • 1
  • 2

17 Replies - 5915 Views - Last Post: 24 April 2011 - 06:01 AM Rate Topic: -----

#1 LightPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 08-June 10

Loading another application in a panel

Posted 22 April 2011 - 10:55 AM

Hello,

I have a question and I think it is a tough one :P

I want to build an application which allows you to add a program to a list.
When you select launch it will launch the selected program in that specific panel.

For Example:
I add notepad to a list.
When I click launch it needs to launch notepad.
But not on the normal way, it needs to be launched in the panel on my form.

But how do a make a thing like this?
Anyone knows how to do this?

Thx,

Jasper(The Netherlands)

Is This A Good Question/Topic? 1
  • +

Replies To: Loading another application in a panel

#2 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5476
  • View blog
  • Posts: 11,762
  • Joined: 02-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 11:01 AM

I've never seen anything that would allow this.
Anyone else?
Was This Post Helpful? 0
  • +
  • -

#3 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 9080
  • View blog
  • Posts: 34,127
  • Joined: 12-June 08

Re: Loading another application in a panel

Posted 22 April 2011 - 11:05 AM

Nope... opening up an app spins it up in it's own thread and then that app's creation goes off on it's own. There's not much to do about conforming it to as screen unless that functionality was already built in. Aka if you made your own notepad app... on that would open normally when executed, but then if executed with a special command line code would fill in a custom control.
Was This Post Helpful? 0
  • +
  • -

#4 LightPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 11:07 AM

View PosttlhIn`toq, on 22 April 2011 - 11:01 AM, said:

I've never seen anything that would allow this.
Anyone else?


Yeah it is quite difficult.
But I thought it would be fun to reopen my very first programming project.

A few years ago I started programming in Delphi and I wanted to create a program called Gamewindow.
This would allow you to run your games in a window if the game doesn't have this function in it.

But I never finished it because it was quite difficult.

But now I love to program in C# so I thought maybe I can make it in C#.


Thx for your reply btw, hopefully someone else know how to do it :)

View Postmodi123_1, on 22 April 2011 - 11:05 AM, said:

Nope... opening up an app spins it up in it's own thread and then that app's creation goes off on it's own. There's not much to do about conforming it to as screen unless that functionality was already built in. Aka if you made your own notepad app... on that would open normally when executed, but then if executed with a special command line code would fill in a custom control.


If you say it like this it sounds possible to me.
It is possible to build a multi threaded application, so this basically allows you to create an extra thread for the application.

This post has been edited by LightPhoenix: 22 April 2011 - 11:18 AM

Was This Post Helpful? 0
  • +
  • -

#5 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 991
  • View blog
  • Posts: 971
  • Joined: 30-September 10

Re: Loading another application in a panel

Posted 22 April 2011 - 11:58 AM

Hi,

This sort of thing requires Win32 interop. I have actually tested this out before (although I didn't actually end up using it in a real application)...

This embedding of one application in another reminds me of a little known language I know called Progress 4GL ;).

Anyway, try this in your form class (assuming your panel is if reasonable size and is called 'panel1'):

        [DllImport("USER32.DLL")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("USER32.dll")]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
 
        public Form1()
        {
            InitializeComponent();

            Process process = Process.Start("notepad.exe");
            process.WaitForInputIdle()
            SetParent(process.MainWindowHandle, this.panel1.Handle);
            
            MoveWindow(process.MainWindowHandle, 0, 0, this.Width - 90, this.Height, true);
        }




It's a bit rough around the edges. It will give you a start though :)

EDIT: Have a look at this link that i've found for a more complete version:

http://www.codeproje...&select=1248877

It actually seems quite well documented. Try typing in "Hosting a .exe in a WinForms" in google.

EDIT 2: Use WaitForInputIdle() instead of Thread.Sleep(). It's a much better alternative.

This post has been edited by CodingSup3rnatur@l-360: 22 April 2011 - 01:04 PM

Was This Post Helpful? 3
  • +
  • -

#6 LightPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 01:15 PM

View PostCodingSup3rnatur@l-360, on 22 April 2011 - 11:58 AM, said:

Hi,

This sort of thing requires Win32 interop. I have actually tested this out before (although I didn't actually end up using it in a real application)...

This embedding of one application in another reminds me of a little known language I know called Progress 4GL ;).

Anyway, try this in your form class (assuming your panel is if reasonable size and is called 'panel1'):

        [DllImport("USER32.DLL")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("USER32.dll")]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
 
        public Form1()
        {
            InitializeComponent();

            Process process = Process.Start("notepad.exe");
            process.WaitForInputIdle()
            SetParent(process.MainWindowHandle, this.panel1.Handle);
            
            MoveWindow(process.MainWindowHandle, 0, 0, this.Width - 90, this.Height, true);
        }




It's a bit rough around the edges. It will give you a start though :)

EDIT: Have a look at this link that i've found for a more complete version:

http://www.codeproje...&select=1248877

It actually seems quite well documented. Try typing in "Hosting a .exe in a WinForms" in google.

EDIT 2: Use WaitForInputIdle() instead of Thread.Sleep(). It's a much better alternative.


Awesome, I will try this and update you guys about it.
Was This Post Helpful? 0
  • +
  • -

#7 LightPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 01:26 PM

@CodingSup3rnatur@l-360

Thx for the code, it works with Notepad but for chrome and vlc it didn't work.
Do you know how do solve this?
Was This Post Helpful? 0
  • +
  • -

#8 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4463
  • View blog
  • Posts: 7,777
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 02:02 PM

I tested it out too, and certain applications simply won't work with it. I'm not well-versed enough with the Win32 API to determine what the cause might be. I'm not surprised Chrome didn't work, considering all the custom non-win-forms UI work they did.
Was This Post Helpful? 0
  • +
  • -

#9 LightPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 02:16 PM

View PostCurtis Rutland, on 22 April 2011 - 02:02 PM, said:

I tested it out too, and certain applications simply won't work with it. I'm not well-versed enough with the Win32 API to determine what the cause might be. I'm not surprised Chrome didn't work, considering all the custom non-win-forms UI work they did.


Hmm yeah, I have 12GB of DDR3 ram so I'm running 64bit programs.
So maybe my chrome and vlc programs are 64bit versions.

Byt how to let it work for 64bit if this is true?
Was This Post Helpful? 0
  • +
  • -

#10 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 991
  • View blog
  • Posts: 971
  • Joined: 30-September 10

Re: Loading another application in a panel

Posted 22 April 2011 - 02:21 PM

My best guess would be that the MainWindowHandle isn't being grabbed properly, and that is why it is not working...

Put this line after the SetParent() function call:

MessageBox.Show(process.MainWindowHandle.ToString());


and post back with what number pops up, if you could please :)
Was This Post Helpful? 0
  • +
  • -

#11 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4463
  • View blog
  • Posts: 7,777
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 02:24 PM

Quote

I have 12GB of DDR3 ram so I'm running 64bit programs.
So maybe my chrome and vlc programs are 64bit versions.


I know it has nothing to do with 32bit vs 64bit. The "Win32" api is still the Win32 API on Windows x64 (and besides, I tested this out on a x32 install).
Was This Post Helpful? 0
  • +
  • -

#12 LightPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 36
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 02:32 PM

View PostCodingSup3rnatur@l-360, on 22 April 2011 - 02:21 PM, said:

My best guess would be that the MainWindowHandle isn't being grabbed properly, and that is why it is not working...

Put this line after the SetParent() function call:

MessageBox.Show(process.MainWindowHandle.ToString());


and post back with what number pops up, if you could please :)


Notepad: 1247858
VLC: 0
Chrome: 0
Was This Post Helpful? 0
  • +
  • -

#13 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 991
  • View blog
  • Posts: 971
  • Joined: 30-September 10

Re: Loading another application in a panel

Posted 22 April 2011 - 02:55 PM

And there is the problem. You are not getting a valid handle to the main window's of those two applications. That could be due to any number of reasons, including; something with the application(s) specifically is preventing it from working, WaitForInputIdle() isn't allowing a valid handle to be grabbed, there are other processes running alongside the process you launch (I know IE spawns about a thousand processes when you open it up :)) etc etc.

Change the code to this:

Process process = Process.Start("<.EXE Goes Here>");

IntPtr ptr = IntPtr.Zero;

while ((ptr = process.MainWindowHandle) == IntPtr.Zero) ;

SetParent(process.MainWindowHandle, this.panel1.Handle);

MessageBox.Show(process.MainWindowHandle.ToString());

MoveWindow(process.MainWindowHandle, 0, 0, this.Width - 90, this.Height, true);



And make sure all the processes associated with whatever application your trying to run are dead before you try it :)


EDIT: You may also want to put a maximum number of tries on your while loop just in case a 'non zero' pointer can never be obtained (as the current loop would loop indefinately in that situation), like this:

 
int attempts = 0;

while((mainPtr = process.MainWindowHandle) == IntPtr.Zero && ++attempts < 100000) ;


You should also make sure you clean up after yourself before your program exits. You should at least include this API function:

[DllImport("kernel32", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);



and do something like this perhaps:

CloseHandle(<pointer to main window here>);
CloseHandle(<pointer to panel here>);

if(process != null)
{
   if (!process.HasExited) process.Kill();

    process.Dispose();
}




Just to be sure...

This post has been edited by CodingSup3rnatur@l-360: 24 April 2011 - 06:19 AM

Was This Post Helpful? 0
  • +
  • -

#14 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4463
  • View blog
  • Posts: 7,777
  • Joined: 08-June 10

Re: Loading another application in a panel

Posted 22 April 2011 - 03:35 PM

Smart edit, that's pretty much what I was going to suggest.

Hmm, when I copied and pasted your code, and paused it during execution, attempts never increased.

Also, Chrome isn't going to return a valid handle. I've allowed it to run for a long time, and it just doesn't.
Was This Post Helpful? 0
  • +
  • -

#15 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 991
  • View blog
  • Posts: 971
  • Joined: 30-September 10

Re: Loading another application in a panel

Posted 22 April 2011 - 04:13 PM

View PostCurtis Rutland, on 22 April 2011 - 10:35 PM, said:

Hmm, when I copied and pasted your code, and paused it during execution, attempts never increased.


 while ((mainPtr = process.MainWindowHandle) == IntPtr.Zero || ++attempts < 100000);


That's me being an idiot.

If a valid handle isn't obtained, the first part of the condition:

...((ptr = process.MainWindowHandle) == IntPtr.Zero ...


will evaluate to true, therefore, it will short circuit the second conditional, thus if a valid handle is never obtained, ... ++attempts < 100000) ; never gets executed/evaluated. Sort of defeats the purpose of having the count there really, wouldn't you say? :stupid:

This is better all round I think:

while((mainPtr = process.MainWindowHandle) == IntPtr.Zero) if(++attempts > 10000) break;



Or, looking at it at 1:30 in the morning...I think you could do this:

  while ((mainPtr = process.MainWindowHandle) == IntPtr.Zero && ++attempts < 100000);


Quote

Also, Chrome isn't going to return a valid handle. I've allowed it to run for a long time, and it just doesn't.


That's strange. I just downloaded Chrome, and i'm getting a valid handle pretty much straight away (after 1 attempt) with the while loop above, and it is displaying in the form...

This post has been edited by CodingSup3rnatur@l-360: 22 April 2011 - 05:05 PM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2