Laden...

bestimmtes fenster auf die maximalgröße resizen?

Erstellt von jase vor 15 Jahren Letzter Beitrag vor 15 Jahren 6.510 Views
J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren
bestimmtes fenster auf die maximalgröße resizen?

morgen,

wie kann ich ein bestimmtes fenster auf seine maximal größe resizen lassen (fenster kann nicht auf fullscreengröße vergrößert werden, dennoch möchte ich mit einem programm sicherstellen können, dass das fenster in seiner maximalen größe ist.)

jase

M
205 Beiträge seit 2008
vor 15 Jahren

Hallo,

um welches Fenster handelt es sich denn? Eines deiner Anwendung oder ein externes? Wenns eines von deine ist ist einfach:

f.Bounds = Screen.PrimaryScreen.Bounds; // f ist dein Form

mfg Markus

J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

leider ein externes 😭

3.511 Beiträge seit 2005
vor 15 Jahren

Mittels FindWindow das Handle der fremden Form ermitteln und dann per SetWindowPos die Größe ändern.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

das hilft mir schonmal weiter.

via google hab ich nochwas intressantes gefunden:
http://www.mycsharpcorner.com/Post.aspx?postID=32
das wäre im grunde perfekt für mich, das problem ist nur dass ich nicht weiß wie ich auf child windows des gefundenen prozesses zugreifen kann. wenn ich nur den namen der exe angebe findet er nur das fenster des prozesses, welches zuletzt aktiv war.

schön wäre ne möglichkeit ein fenster zu finden, indem man nach teile des title suchen könnte..
also wenn das fenster zbsp als titel "das ist ein tolles window" hat wäre es toll, wenn ich nur nach "tolles" suchen kann und er mir dann den handle gibt.

3.511 Beiträge seit 2005
vor 15 Jahren

Da kann dir jetzt EnumChildWindows weiterhelfen. Entweder holst du dir so alle Fenster eines Prozesses, oder wenn du das Desktop-Handle angibts, alle geöffneten Fenster. Schau mal bei PInvoke.Net rein. Da gibt es ein Beipsiel zu EnumChildWindows.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

danke für den tipp, hab aber in der zwischenzeit was anderes gefunden. funktioniert jetzt:


        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
        int X, int Y, int cx, int cy, uint uFlags);

[...]

            Process[] processes = Process.GetProcessesByName("notepad");
            uint SWP_NOMOVE = 0x0002;


            foreach (Process p in processes)
            {

                string windowTitle = p.MainWindowTitle;
                if (windowTitle.Contains("tolles") == true)
                {
                    MessageBox.Show("gefunden: " + windowTitle);
                    SetWindowPos(p.MainWindowHandle, IntPtr.Zero, 10, 10, 900, 900, SWP_NOMOVE);
                }
            }

danke trotzdem!

edit:
das funktioniert leider auch nur für den zuletzt aktivierten child des prozesses.. für alle childs muss ich wohl nochmal suchen..

915 Beiträge seit 2006
vor 15 Jahren

Also, wenn deinen Ansatz mit eben Khalid's Vorschlag (EnumChild Windows) kombinierst erhällst dein gewünschtes Resultat.

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

ich hab jetz einiges probiert, versucht den pinvoke.net vorschlag umzuarbeiten, kriegs aber einfach ned hin X(

hier mal was ich hab:


        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool EnumChildWindows(int hWndParent, Delegate lpEnumFunc, int lParam);

        public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

[...]

        public bool EnumWindow(IntPtr handle, IntPtr pointer)
        {
            uint SWP_SHOWWINDOW = 0x0040;
            SetWindowPos(handle, IntPtr.Zero, xTop, yTop, xBottom, yBottom, SWP_SHOWWINDOW);
            SetForegroundWindow(handle);
            return true;
        }

[...]

Process[] processes = Process.GetProcessesByName("notepad");
foreach (Process p in processes)
                {
                    if (p.MainWindowTitle.Contains("tolles"))
                         EnumChildWindows(p.MainWindowHandle, EnumWindow, 0);
                }

die fehler sind dann:

Error 1 The best overloaded method match for 'WindowsApplication2.Form1.EnumChildWindows(int, System.Delegate, int)' has some invalid arguments
Error 2 Argument '1': cannot convert from 'System.IntPtr' to 'int'
Error 3 Argument '2': cannot convert from 'method group' to 'System.Delegate'

ansich ja alles verständliche fehlermeldungen, aber egal wie ich es biege; für jeden gelösten fehler kommen 2 neue 🙁

kann mir jemand vlt etwas auf die sprünge helfen?

jase

J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

vlt noch wichtig zu erwähnen:

bei dem programm ist die handhabung ähnlich wie zbsp firefox, welchen man auch mehrmals geöffnet haben kann.. es handelt sich also nicht um nur ein fenster, sondern um mehrere, die aber trotzdem alle zum gleichen prozess gehören..

3.511 Beiträge seit 2005
vor 15 Jahren

Du musst einen eigenen Delegaten definieren und den diesen der Methode übergeben. Das ist allerdings auf PInvoke.Net so beschrieben.


[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);

public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
//...
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
    {
    GCHandle gch = GCHandle.FromIntPtr(pointer);
    List<IntPtr> list = gch.Target as List<IntPtr>;
    if (list == null)
    {
        throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
    }
    list.Add(handle);
    //  You can modify this to check to see if you want to cancel the operation, then return a null here
    return true;
    }

public static List<IntPtr> GetChildWindows(IntPtr parent)
    {
    List<IntPtr> result = new List<IntPtr>();
    GCHandle listHandle = GCHandle.Alloc(result);
    try
    {
        EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
        EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
    }
    finally
    {
        if (listHandle.IsAllocated)
        listHandle.Free();
    }
    return result;
    }

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

das war der richtige tipp; ich hatte das


EnumWindowProc childProc = new EnumWindowProc(EnumWindow);

vergessen.
allerdings ist der effekt nicht ganz wie gewünscht: stattdessen, dass er für beide offene fenster die im namen "tolles" haben diese größer macht und in den vordergrund setzt maximiert er die textbox von einem der beiden fenster..
ich vermute dass das daran liegt dass enumchildwindows auf einen teil des fensters anspringt, in diesem fall wohl die textbox.
wie komme ich an den von mir gewünschten effekt (beide fenster in eine neue position bringen & in den vordergrund bringen)?

jase

3.511 Beiträge seit 2005
vor 15 Jahren

Hmm, EnumChildWindows ermittelt wirklich nur die Handles der Fenster und keine anderen zufälligen. Wundert mich jetzt ein bisschen, das EnumChildWindow aufeinmal ein Handle einer TextBox zurückliefert.

Du könntest mit dem folgenden Codeteil mal prüfen, welche Controls er da wirklich durch das Handle zurückliefert:


Control ctrl = Form.FromHandle(derHandle);
Console.WriteLine(ctrl.GetType().ToString());

Entweder es knallt, weil der Handle ungültig ist, oder du bekommst den entsprechenden Klassennamen des Handles.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

knallt:

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="WindowsApplication2"
StackTrace:
at WindowsApplication2.Form1.EnumWindow(IntPtr handle, IntPtr pointer) in X:\stick\code\csharp\WindowsApplication2\WindowsApplication2\Form1.cs:line 45
at WindowsApplication2.Form1.EnumChildWindows(Int32 hWndParent, Delegate lpEnumFunc, Int32 lParam)
at WindowsApplication2.Form1.init() in X:\stick\code\csharp\WindowsApplication2\WindowsApplication2\Form1.cs:line 79
at WindowsApplication2.Form1.button2_Click(Object sender, EventArgs e) in X:\stick\code\csharp\WindowsApplication2\WindowsApplication2\Form1.cs:line 150
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms. UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at WindowsApplication2.Program.Main() in X:\stick\code\csharp\WindowsApplication2\WindowsApplication2\Program.cs:line 17
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

so sieht momentan mein code aus:


       public bool EnumWindow(IntPtr handle, IntPtr pointer)
        {
            uint SWP_SHOWWINDOW = 0x0040;
            Control ctrl = Form.FromHandle(handle);
            MessageBox.Show(ctrl.GetType().ToString());
            SetWindowPos(handle, IntPtr.Zero, xTop, yTop, xBottom, yBottom, SWP_SHOWWINDOW);
            SetForegroundWindow(handle);
            return true;
        }

        void init()
        {

                foreach (Process p in processes)
                {
                    if (p.MainWindowTitle.Contains("tolles"))

                    {

                        EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                        EnumChildWindows(p.MainWindowHandle.ToInt32(), childProc, 0);
                    }
                }
            }
        }

edit:
und noch ne frage:
mit setpos kann ich zwar die größe des fenster ändern, aber ne option für maximieren hab ich nicht gefunden.. mir reicht zwar für diesen einen fall das angeben von werten, die außerhalb des zulässigen bereiches sind (da das fenster dann eh nicht größer sein kann), aber wie löst man das sonst? resizen ist ja nicht das gleiche wie maximieren...

49.485 Beiträge seit 2005
vor 15 Jahren
J
jase Themenstarter:in
39 Beiträge seit 2007
vor 15 Jahren

herbivore,
das hab ich schon durchgelesen, jedoch sind meine kentnisse nicht so perfekt dass ich meinen fehler sehe.. ich vermute momentan dass es daran liegt, dass ich den handle beim aufruf von enumchildwindows() in einen int32 konvertiere?

der handle wird beim aufruf ja mitgegeben aber nach dem control aufruf "genullt".

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo jase,

jedoch sind meine kentnisse nicht so perfekt dass ich meinen fehler sehe

dafür ist aber in der FAQ perfekt beschrieben, wie du vorgehen musst, um den Fehler zu finden. Es liegt also bei dir.

herbivore

3.511 Beiträge seit 2005
vor 15 Jahren

Der Fehler liegt höchstwahrscheinlich an dieser Stelle


MessageBox.Show(ctrl.GetType().ToString());

Wie ich bereits geschrieben habe, liefert Form.FromHandle null zurück, wenn der angegebene Handle nicht in ein Control aufgelöst werden kann. Deswegen wird es knallen. Es gibt auch noch Form.FromChildHandle. Aber ich weis jetzt den Unterschied nicht. Da müsstest du mal nachlesen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)