Ändern der form, der Größe von einem WM_SIZE-Nachricht
Ich habe eine form mit einer Mindesthöhe gesetzt, weil ich nicht wollen, dass es in der Größe verändert werden, über einen bestimmten Punkt, wenn es in einem "minimalistischen display" - Modus.
Wenn ein Benutzer versucht, das Fenster zu maximieren, indem Aero, sodass er an der Oberseite des Bildschirms, wird das Fenster maximiert, aber die Höhe der Fenster ist nur 240 Pixeln (maximale Größe). Wenn ich Versuch zu handhaben, die WM_SIZE
Nachricht, wenn die wParam
ist SIZE_MAXIMIZED
jeder Versuch, die Höhe des Formulars umgangen wird.
Derzeit bin ich Umgang mit SC_MAXIMIZE
zu erkennen, wenn die maximieren-Schaltfläche gedrückt wird, und WM_NCLBUTTONDBLCLK
maximieren Sie das Fenster, wenn der Benutzer doppelt klickt der Titelleiste. In beiden Situationen, ich kann schalten Sie die erweiterten Fenster-Modus und stellen Sie die minimale Größe, so dass er in der Lage sein, in den Vollbildmodus zu gehen.
Natürlich weder von diesen Nachrichten werden gepostet, wenn das Fenster maximiert ist über ShowWindow(SW_MAXIMIZE)
oder wenn die aero-rasten an den oberen Rand des Bildschirms.
Gibt es eine andere Nachricht, die ich verarbeiten kann, die auftreten können, kurz bevor das system tatsächlich die Maximierung, so kann ich passen Sie die Größe des Fensters und Anzeige-Modus vor der hand?
Aktuelle Code:
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0112) { //WM_SYSCOMMAND
if (m.WParam == new IntPtr(0xF030)) { //Maximize event - SC_MAXIMIZE from Winuser.h
//The window is being maximized
this.MaximumSize = new Size(9999, 9999);
ToggleDeviceDisplay(true);
linkToggleDeviceList.Visible = false;
}
} else if (m.Msg == 0x00A3) { //WM_NCLBUTTONDBLCLK - Double clicking on window title bar, min or max
if (this.WindowState == FormWindowState.Normal) {
if (grpDeviceList.Visible == false) {
this.MaximumSize = new Size(9999, 9999);
ToggleDeviceDisplay(true);
}
this.WindowState = FormWindowState.Maximized;
linkToggleDeviceList.Visible = false;
} else {
this.WindowState = FormWindowState.Normal;
linkToggleDeviceList.Visible = true;
}
return;
} else if (m.Msg == 0x0005) { //WM_SIZE
if (m.WParam == new IntPtr(0x02)) { //SIZE_MAXIMIZED
//CANT GET WINDOW TO GO TO FULL-SCREEN FROM HERE
this.MaximumSize = new Size(9999, 9999);
//THE LINE BELOW DOESN'T WORK, probably because it is already being sized
this.Height = Screen.FromHandle(this.Handle).WorkingArea.Size.Height;
} else if (m.WParam == new IntPtr(0x00)) { //SIZE_RESTORED
linkToggleDeviceList.Visible = true;
}
}
base.WndProc(ref m);
}
Wenn das Fenster bereits im erweiterten Anzeigemodus, wenn WM_SIZE maximieren gesendet wird, ist es kein problem, weil das max-Fenster Größe auf Vollbild zulassen, jedoch, wenn Sie versuchen, zu maximieren, die aus der minimalen Modus, komme ich nicht an die app zu wechseln, um den gesamten Bildschirm, während Sie die Nachricht.
Ich weiß, ich könnte trigger einen timer oder so zu laufen, von der Nachricht so würde die Größe so schnell die Benutzer nicht bemerken würde, es war nicht voll-Bildschirm sofort, aber das ist nur eine schreckliche hack.
EDIT:
Zur Veranschaulichung der zwei-Fenster-Staaten, hochgeladen habe ich zwei screenshots hier. Das Obere Bild zeigt die erweiterte Anzeige, die hat keine Begrenzungen auf die Größe der Fenster, das untere Bild zeigt die minimal-display, das hat eine Höhenbeschränkung festgelegt, so dass Sie nicht erhöhen die Höhe des Fensters, so wie alle es tun würden, zeigen mehr leeren Raum.
Dank.
- Warum bist du nicht mit dem tatsächlichen Fenster Nachricht Konstante Werte, wie
WM_SIZE
statt die hex-Werte? - Kein guter Grund, am Anfang war ich nur mit 2 Nachrichten, also habe ich die Werte stattdessen definieren Sie in meiner app als Konstanten, wie ich sollte.
- Das Konzept der "Fenster-Höhe darf nicht mehr als Y-Pixel, außer wenn der Nutzer will, um es größer, dann kann es größer sein," dumm ist, aus Windows-Sicht. Entweder die Fenster der Höhe begrenzt ist, um Y Pixel, oder es ist es nicht. Sie können es nicht haben beide weisen.
- Seit Ihrem full-screen-Modus ist -- wieder, aus Windows-Sicht -- völlig anders aus als ein minimalistisches interface, könnte Sie nicht zwei unterschiedliche windows?
- Ich denke, das ist das problem, es ist nicht eine vollständig andere Oberfläche, es ist eigentlich das gleiche interface, außer in die minimal-Ansicht, die nur einen kleinen Teil von der Spitze das Fenster, das zeigt grundlegende Statistiken sichtbar ist, wenn Sie in der erweiterten Ansicht, die oben im Abschnitt sichtbar ist, außer die Höhe des Fensters wird erweitert und eine große DataGridView unter all den Statistiken sichtbar wird.
- Ich fügte hinzu, screenshots der beiden Fenster Mitgliedstaaten auf, hoffentlich fügen Sie Klarheit.
- Vielen Dank für die Klarstellung. Mein Vorschlag wird sein, leicht Neugestaltung Ihrer Oberfläche: Sie konnten zeigen/ausblenden der Geräteliste, indem Sie das Fenster vergrößern, wodurch das gesamte problem.
- Im Grunde ist die device-Liste ist immer sichtbar, außer es ist über die Grenzen der form, wenn im minimal-Modus, und der Benutzer könnte nur erhöhen die Höhe, setzen Sie das Gerät Liste? Ich ursprünglich vermeiden, dass die Methode nur, weil es seltsam aussieht, wenn das Fenster verkleinert, sodass nur der Titel der groupbox ist, zu zeigen, oder die device-Liste, die ist wirklich klein, aber wenn ich kann nicht finden eine praktikable Lösung finden, ich denke, ich werde gehen mit dieser Methode. Oder haben Sie irgendwelche Tipps, verwalten Sie die Größe ein wenig besser mit Ihrer Idee? Nochmals vielen Dank für die Hilfe.
- Nein, nicht ganz: Sie behandeln würde, window-resize-Ereignisse zu zeigen, oder verstecken Sie das Gerät in der Liste nach Bedarf. Um zu verhindern, dass eine Größe von nur ein paar Pixel mehr als das minimal-interface (das wäre nicht die Spitze der Gruppe Feld, wenn Sie verstecken, die Sie behandeln können
WM_WINDOWPOSCHANGING
beheben Sie das Fenster, um die minimale Höhe, bis das Fenster wird angepasst, um mindestens die minimale Höhe + Schwelle. - Sie können nicht diese Arbeit machen, es gibt keinen snap-Benachrichtigung. Sie haben in dieses problem zwingt den Benutzer, um Ihre Fenster hübsch Aussehen. Das ist einfach der falsche Ansatz, halten Sie die Benutzer verantwortlich.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es scheint mir, wie Sie versuchen zu tun, eine einfache Sache in eine allzu komplizierte Art und Weise. Ich würde Prozess der
WM_GETMINMAXINFO
- Meldung, die an Ihrem Fenster an, wenn seine Größe oder position zu ändern. Die Bearbeitung dieser Meldung gibt Ihnen die Möglichkeit zu geben Sie die maximale oder minimale Werte für jedes dieser Attribute, um wirksam zu verhindern, es wird kleiner oder größer als die Sie wünschen.Werde ich nicht erlaubt, eine Menge von Beispiel-code, da Ihre Frage zeigt Sie bereits wissen, wie zu überschreiben
WndProc
und behandeln Fenster-Nachrichten. Das einzige, was Sie tun müssen, definieren Sie dieMINMAXINFO
Struktur in verwaltetem code. So etwas wie dieses:Verwenden
Marshal.PtrToStructure
zu konvertieren, die Zeiger enthalten, die in derMessage.LParam
- Eigenschaft auf eine Instanz derMINMAXINFO
Struktur, die oben definiert werden. So, innerhalb IhrerWndProc
- Methode, Sie würde so etwas machen:Update:
Aus die screenshots, die du gepostet hast sieht es so aus das zwei verschiedene displays sind identisch, der einzige Unterschied ist der, ob das DataGridView an die unten gezeigt wird. Die GroupBox oben angezeigt, unabhängig von der form der Größe.
So, es scheint mir, dass die Lösung ist einfach zu handhaben, die
Form.Resize
Ereignis (das sollte erhöht werden unabhängig, wie Sie Ihr Formular in der Größe geändert wird, entweder durch manuelles ziehen an den Grenzen, auf die Titelleiste Schaltflächen, oder mit Aero-Snap).Innerhalb des event-handler-Methode, überprüfen Sie die aktuellen Abmessungen der form. Wenn es ausreichend groß ist, legen Sie die
DataGridView
controlVisible
Eigenschafttrue
. Wenn es nicht von ausreichender Größe, wechseln Sie zu den "minimal-Modus", indem SieDataGridView.Visible = false
.Es ist nicht eine technisch sehr aufwändige Lösung, aber es scheint, wie es sollte, erreichen Sie alle Ihre gewünschten Ziele. Die motivation, so wie ich es verstehe, ist nur eine einfachere Schnittstelle, wenn die form zu klein ist, um in der Lage sein, alles zu sehen, und erweitern Sie die Schnittstelle, wenn die form größer ist. Wenn Sie mit der
Resize
Ereignis und überprüfen Sie die tatsächliche Größe der form, nachdem das Ereignis ausgelöst hat, können Sie nicht falsch sein.Eine alternative Lösung ist, einfach zu aktivieren
AutoScroll
Eigenschaft und zeigen immer beide regler. Alle Benutzer tun müssen, ist, navigieren Sie nach oben oder unten, um zu sehen, was Sie wollen. WinForms kümmert sich um den rest.WM_GETMINMAXINFO
lange nicht gemeldet, weil ich denke, es kann der Weg zu gehen, wie gut. Nun, das einzige Problem, das ich habe, ist Windows sendet diese Nachricht, wenn die Fenster verschieben, oder versuchen, um Ihre Größe zu ändern. Wenn sich die app im minimal-Modus, möchte ich sagen, die max Größe die kleinere Größe, aber wenn Sie versuchen, aero-snap, muss ich trick Sie zu denken, die maximale Größe ist die Größe des Displays. Jetzt bin ich nur Probleme, herauszufinden, wie zu wissen, Wann die eingehende Nachricht durch ein verschieben/Größe ändern vs Aero Fragen, wie groß die max Größe ist.SC_MAXIMIZE
undWM_NCLBUTTONDBLCLK
große Arbeit, aber aero snap nur Beiträge die WM_SIZE-Nachricht, nachdem es maximiert meinem Fenster (mit der kleineren Höhe). In der WM_SIZE, ich kann nicht scheinen, um die Höhe zu ändern, es ignoriert die Größe ändern.Verstehe ich richtig: Sie wollen Ihre Fenster zu haben, die minimal erlaubte Größe und in der Lage sein, maximiert werden? Wenn das also dein code ist viel zu Komplex und eigentlich nicht notwendig. Verwenden Sie einfach den window-Eigenschaft MinimumSize.
Du willst also deine form zu haben eine minimale Größe, maximale Größe und noch in der Lage sein, um es zu maximieren mit Titelleiste doppelklicken, maximieren-Schaltfläche, und Aero snap? Tricky 🙂 Hier ist die Lösung.
Legen Sie die Eigenschaften MinimumSize und schreiben dann 2 Ereignisse:
und:
Wird den trick tun. Zumindest auf meiner Maschine 🙂