C# plik zewnętrzny nie wchodzi do panelu

0

Witam
Posiadam pewien problem z kodem , a mianowicie chciałbym by zewnętrzna aplikacja exe wyświetlała się w panelu. Jak można to rozwiązać ?

 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;

namespace zewnetrzny_exe_proba_3
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        public Process proc;
       
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (proc == null || proc.HasExited)
            {
                proc = Process.Start(@"C:\Program Files\TenDollars2Surf\TenDollars2Surf.exe"); // or whatever
                //proc = Process.Start("C:\Program Files\TenDollars2Surf\TenDollars2Surf.exe");
                proc.WaitForInputIdle();
                SetParent(proc.MainWindowHandle, panel1.Handle);
                MoveWindow(proc.MainWindowHandle, 0, 0, panel1.Width, panel1.Height, false);
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }
        
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!proc.HasExited) proc.Kill();
        }
    }
}
0

Nie znam tego języka więc ci nie pomogę. Powiem tylko jak w delphi to zrobić ograniczając kod do minimum.
Krótko mówiąc musisz przykładowo pobrać uchwyt okna tego obcego programu (swoją drogą, program WinInfo pokazuje nazwy uchwytów itd jakbyś chciał się upewnić)

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633541%28v=vs.85%29.aspx
tu masz opis funki ustawiającej rodzica np. Kalkulatorowi

A sam kod przeniesienia odpalonego wcześniej kalkulatora wygląda tak:

procedure TForm1.Button1Click(Sender: TObject);
var
  h: HWND; //zmienna do uchytu
  rozmiar: TRect; //tu zmienna do trzymania rozmiaru kalkulatora
begin
  h:= FindWindow(nil, 'Kalkulator'); //najpierw musisz znaleźć okno do programu np. do kalkulatora
  GetWindowRect(h, rozmiar); //pobieranie wymiarów okna np. Kalkulatora

  Winapi.Windows.SetParent(h, Panel1.Handle); //tu ta funkcja, do której link dałem na MSDN tobie, czyli ustawia kalkulatorowi rodzica Panel1
  MoveWindow(h, 5, 5, rozmiar.Width, rozmiar.Height, True); //a tu przeniesienie okna kalkulatora w położenie XY: 5, 5
end;

w tym kodzie musiałbym dodać jakieś odmalowywanie, odświeżanie okna kalkulatora itd.

Poczekaj lepiej na jakichś PRO z tego forum, zbluzgają mnie za ten kod, że niedorobiony, lamerski i do delphi, ale może pomogą ci.

1

Wszystko jest ok tylko za szybko próbujesz zmienić parenta i przesunąć okno bo te jeszcze się nie zdąży tworzyć

Daj Thread.Sleep(1000) pomiędzy instrukcjami a zobaczysz że wszystko zacznie działać
Zamiast sleepa lepiej będzie czekać na gotowość okna w pętli z małym sleepem czekając aż uchwyt okna przestanie być nullem zerem

//edit:

proc.WaitForInputIdle();
while (proc.MainWindowHandle == IntPtr.Zero)
{
    Thread.Sleep(10);
    proc.Refresh();
}
0

Dzięki Wielkie ! To było dokładnie to :)

Jeszcze jedno pytanie. Posiadam tam panel , w którym właśnie się wyświetla ten plik exe. Jak zrobić by było automatyczne klikanie w niego np co 2 minuty za pomocą lewego przycisku myszy
Próbuję coś w ten sposób ale nie działa:

 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;

namespace zewnetrzny_exe_proba_3
{
    public partial class Form1 : Form
    {
        //do plików exe
        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        public Process proc;
        
        //do klikadełka

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

        public const int MOUSEEVENTF_LEFTDOWN = 0x02;
        public const int MOUSEEVENTF_LEFTUP = 0x04;
        public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        public const int MOUSEEVENTF_RIGHTUP = 0x10;
       
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //wersja jako button
            //if (proc == null || proc.HasExited)
            //{
                
               // proc = Process.Start(@"C:\Program Files\TenDollars2Surf\TenDollars2Surf.exe"); // or whatever 
              //  Thread.Sleep(1500);
              //  proc.Refresh();
              //  SetParent(proc.MainWindowHandle, panel1.Handle);
              //  MoveWindow(proc.MainWindowHandle, 0, 0, panel1.Width, panel1.Height, false);
            //}
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            proc = Process.Start(@"C:\Program Files\TenDollars2Surf\TenDollars2Surf.exe"); // or whatever
            Thread.Sleep(1500);
            proc.Refresh();
            SetParent(proc.MainWindowHandle, panel1.Handle);
            MoveWindow(proc.MainWindowHandle, 0, 0, panel1.Width, panel1.Height, false); 
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }
        
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!proc.HasExited) proc.Kill();
        }

        
        

         public void DoMouseClick()
         {
             //Call the imported function with the cursor's current position
             //int X = Cursor.Position.X;
             //int Y = Cursor.Position.Y;

             int X = 10;
             int Y = 10;
             mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
             
         }
   

    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1