In einer Anwendung, die ich entwickle, muss ich in der Lage sein, ein Windows-Formular kleiner als die vom Betriebssystem vorgegebene minimale Höhe zu machen (36 px in Vista). Ich habe versucht, WM_GETMINMAXINFO abzufangen und meine eigenen Informationen zur Verfügung zu stellen, um die OS-Grenzen zu überschreiben, aber das funktioniert nur für den Benutzer. Aus Code kann ich die Höhe auf einen Wert unterhalb der Grenze festlegen, aber meine Änderung funktioniert nur, bis WM_WINDOWPOSCHANGED in die Nachrichtenwarteschlange gebucht wird (was passiert, nachdem ich die Höhe geändert habe).
Nach vielen Experimenten und Versuchen habe ich eine Lösung gefunden. Ich habe OnResize überschrieben und die Größe des Formulars an die ListBox angepasst (siehe meinen Kommentar zu John Saunders). Wie ich in meiner Frage erwähnt habe, habe ich festgestellt, dass die Größe des Formulars nach dem Senden von WM_WINDOWPOSCHANGED zurückgeht. Weitere Untersuchungen ergaben, dass die Größenregression tatsächlich beginnt, wenn WM_WINDOWPOSCHANGING gesendet wird. WM_WINDOWPOSCHANGING ist die Schwesternachricht von WM_WINDOWPOSCHANGED, die auftritt, bevor sich die Fenstergröße tatsächlich ändert. Ich weiß nicht warum, aber aus irgendeinem Grund passt WM_WINDOWPOSCHANGING blind die Größe des Formulars an die vom Betriebssystem angegebenen Grenzen an (anscheinend fragt es das Fenster nicht mit WM_GETMINMAXINFO ab). Daher musste ich WM_WINDOWPOSCHANGING abfangen und es mit der Größe überschreiben, die ich wirklich wollte. Das bedeutet, dass ich die Größe des Formulars nicht mehr mit OnResize anpasse, sondern stattdessen die Formulargröße anpasse, wenn ich WM_WINDOWPOSCHANGING erhalte. Dies ist sogar besser als OnResize, da kein zugeordnetes Flimmern auftritt, wenn die Größe geändert und dann erneut geändert wird, wenn die Größe während OnResize angepasst wird.
Außerdem ist es notwendig, WM_GETMINMAXINFO abzufangen und zu überschreiben, andernfalls hilft sogar das Abfangen von WM_WINDOWPOSCHANGING nichts.
%Vor%Alexey war so nah!
%Vor%Hat den Trick für mich gemacht. Ich setze die Mindestgröße des Formulars auf die tatsächliche Größe des Formulars.
In meinem Projekt ist das alles, was ich tun muss, um das Formular winzig zu machen, vielleicht weil die Einstellung der Mindestgröße SetBoundsCore auslöst oder ich etwas anderes mache, das es auslöst; In diesem Fall müssen Sie irgendwie SetBoundsCore selbst auslösen.
Ich wünschte, ich könnte Zach mehr als +1 dafür geben, es ist großartig und hat meinen Speck gerettet. Für zukünftige Leser, hier ist die VB-Übersetzung von Zachs Code:
%Vor%Beim Abspielen mit minimaler Formulargröße ist mir aufgefallen, dass die minimale Formulargröße in Form.SetBoundsCore (...) auf die minimale Formulargröße des Systems beschränkt ist. Wenn ich IL disassembly inspiziere, fand ich, dass diese .Net-Methode immer korrigiert, was Sie geben (Breite und Höhe) zu SystemInformation.MinimumWindowSize, wenn sie kleiner sind und das Formular kein Elternteil und sein FormBorderStyle ist FixedSingle, Fixed3D , FixedDialog oder Sizable.
Die einfachste Lösung für dieses Problem besteht nicht darin, WM_WINDOWPOSCHANGING zu verarbeiten, sondern einfach FormBorderStyle = System.Windows.Forms.FormBorderStyle.None im Formularkonstruktor festzulegen.
Sie meinen, abgesehen von einem anderen Betriebssystem?
Wie wäre es mit "Verwenden Sie kein Formular"? Wie groß ist dieses Ding, das Sie anzeigen müssen? Ein Pixel? Benötigt es vollständige Windows Forms-Funktionalität?
Nun, ich weiß nicht genau, wie ich das oben genannte machen soll, aber es könnte ein Anfang für Sie sein - denken Sie außerhalb der (Begrenzungs) Box.
Ich folgte Zachs Antwort und es löste fast mein Problem. In einem Setup mit zwei Monitoren verschwand das Formular jedoch, wenn es auf dem zweiten Bildschirm maximiert wurde. Aus irgendeinem Grund hat Windows das Formular außerhalb des sichtbaren Bereichs positioniert. Das Hinzufügen eines Tests für den primären Bildschirm hat dieses Problem für mich gelöst:
%Vor%Tags und Links .net winforms minimum-size