Schlüsselwörter : Dialogfeld, Dialog, setzbarer
1. Problem aufgeworfen
Das Problem kommt von stanley_xu, in der Hoffnung, nur die Schließknopf zu erhalten (es kann auch helfen), es gibt kein Symbol für das Programm oben links und das Dialogfeld kann die Fenstergröße ändern.
Die Eigenschaften von BorderSyle und Bordericons sind für TForm in VCL eingestellt, um die Einstellung von Fensterstilen zu vereinfachen (ansonsten müssen API -Funktionen wie SetWindowlong und Getwindowlong aufgerufen werden). Die Definition und Beschreibung von TFormborderSyle und TBORDERICON sind wie folgt:
Wertbedeutung
BSDIALOG NICHT VERSCHISSIGKEIT;
BSSINGLE NICHT SEHRIERUNG;
Bsnonenotresizable;
BSSIZIABLE STANDEL -BESTELLUNGEN
Bstoolwindow wie BSsingle, aber mit einer kleineren Beschriftung
BSSIZETOOLWIN wie BSSIZEAB mit einer kleineren Beschriftung
Typ TBORDICON = (BissystemMenu, Biminimize, Bimaximize, BiHelp);
TBordericons = set von TBORDERICON;
Wertbedeutung
BissystemMenu Das Formular verfügt über ein Steuerel (auch als Systemmenü bezeichnet).
Biminimieren, dass das Formular eine minimierte Taste hat
Bimaximieren Das Formular hat eine maximale Taste
BiHelp Wenn BorderSyle BSDIALOG oder Biminimize ist und Bimaximize ausgeschlossen ist, erscheint ein Fragezeichen in der Titelleiste des Formulars, und beim Klicken ändert sich der Cursor an CRHELP.
Offensichtlich können BorderSyle und Bordericons den allgemeinen Anforderungen nur erfüllen, und es ist unmöglich, Dialogfelder zu implementieren, die die Größen ändern können.
Wenn ich ein Fenster erhalten möchte, das nicht maximiert werden kann, aber die Größe ändern kann, setze ich BorderSyle auf BSSizable, entfernen Sie die Biminimierung und Bimaximierung von Bordericons, und das Ergebnis lautet wie folgt: Das Fenster kann geändert werden, aber es gibt es jedoch, aber es gibt es ein Symbol in der oberen linken Ecke ,:
Abbildung 1 Dialogfeld mit Symbol
Beachten Sie, dass sich in der oberen linken Ecke ein Symbol befindet.
Unser Ziel sind die beiden folgenden Effekte.
Abbildung 2 Dialogfeld Datei Öffnen
Abbildung 3 Dialogfeld des Ordners durchsuchen
2. Die Hälfte des Problems ist gelöst
Ich habe nach MSDN gesucht und einen Artikel gefunden, in dem Sie beigebracht werden, wie Sie Eigenschaftenseiten entwerfen, die die Größe ändern können Blatt, die im Artikel eingeführte Methode soll den Fensterstil vor der Erstellung der Eigenschaftsseite ändern und dann die Meldung von Wm_Size manuell verarbeiten.
Int Callback cmyPropertySheet :: xmnpropsheetcallback (hwnd hwnd, uint meldung, lparam lparam)
{
EXTERN INT CALLBACK AFXPROPSheetCallback (hwnd, uint meldung, lparam lparam);
// XMN: Rufen Sie den Rückruf von MFC an
int nres = afxPropsheetCallback (hwnd, message, lparam);
Schalter (Meldung)
{
Fall PSCB_Precreate:
// Setzen Sie unsere eigenen Fensterstile
((Lpdlgtemplate) lparam)-> style | = (ds_3dlook | ds_setfont
|.
brechen;
}
NRES zurückgeben;
}
Ich habe versucht, dieselbe Methode in eine Form von VCL zu verwenden. Stellen Sie BorderSyle beim Entwerfen auf BSDIALOG ein und überlasten Sie dann die CreateParams -Methode. Das Ergebnis ist jedoch, dass das Dialogfeld zu einem dicken Rand wird (weil es einen WS_THICKFRAME -Stil hat), die Maus kann sich automatisch ändern, nachdem sie sich an jeden Rand bewegt (Der hinzugefügte WM_SIZE -Nachrichtenverarbeitungsprozess wird nicht ausgelöst). Was ist das Problem?
Abbildung 4 Dialogfeld, das noch nicht vollständig zufriedenstellend ist
3. Lösen Sie das Problem
Ich habe den Quellcode von Forms.pas überprüft und das Problem gefunden. Im WM_NCCreate -Nachrichtenverarbeitungsprozess von TCustomForm befindet sich ein ModifysystemMenu -Einbettungsprozess, mit dem das Systemmenü des Formulars geändert wird. Beachten Sie, dass der rote Text unten lautet "Lassen Sie das Systemmenü wie ein Dialogfeld aussehen". Die nächsten paar Sätze von Code löschten die Menüelemente des Systems bis zu dem Punkt, an dem sich nur "verschieben" und "schließen".
procedure tcustomForm.wmnccreate (var message: twmnccreate);
VerfahrensmodifysystemMenu;
var
SYSMENU: Hmenu;
Beginnen
...
{Ändern Sie das Systemmenü, um eher so auszusehen, wie es S'pose ist, zu}
Sysmenu: = getSystemMenu (Handle, Falsch);
Wenn fborderSyle = bsdialog dann dann
Beginnen
{Machen Sie das Systemmenü wie ein Dialog aus, der nur hat
Bewege und schließen}
Deletemenu (sysmenu, sc_tasklist, mf_bycommand);
Deletemenu (sysmenu, 7, mf_byposition);
Deletemenu (sysmenu, 5, mf_byposition);
Deletemenu (sysmenu, sc_maximize, mf_bycommand);
Deletemenu (sysmenu, sc_minimize, mf_bycommand);
Deletemenu (sysmenu, sc_size, mf_bycommand);
Deletemenu (sysmenu, sc_restore, mf_bycommand);
Ende sonst
...
Ende;
Beginnen
geerbt;
SetMenu (fmenu);
Wenn nicht (csDesigning in componentState), dann modifysystemmenu;
Ende;
Daher ist das Problem, dass der Fensterstil eine Deformität hat: Es gibt WS_THICKFRAME (die Fenstergröße kann geändert werden), aber es reagiert nicht auf die WM_SIZE -Nachricht (SC_SIZE wird gelöscht).
Die Lösung ist sehr einfach: Implementieren Sie Ihren eigenen WM_NCCreate -Nachrichtenverarbeitungsprozess und ändern Sie das Systemmenü manuell.
procedure tzocdlgresis
// Die folgenden Codes werden von Form.pas Zeile 4047, Delphi 7 SP1 kopiert.
VerfahrensmodifysystemMenu;
var
SYSMENU: Hmenu;
Beginnen
Sysmenu: = getSystemMenu (Handle, Falsch);
{Machen Sie das Systemmenü wie ein Dialog aus, der nur hat
Befehle verschieben, Größe und Schließen}}
Deletemenu (sysmenu, sc_tasklist, mf_bycommand);
Deletemenu (sysmenu, 7, mf_byposition);
// Entfernen Sie den Separater nicht vor Schließen.
// deletemenu (sysmenu, 5, mf_byposition);
Deletemenu (sysmenu, sc_maximize, mf_bycommand);
Deletemenu (sysmenu, sc_minimize, mf_bycommand);
{Entfernen Sie den Befehl der Größe nicht, sonst verlieren wir die
Fähigkeit der Größe des Dialogs.
// deletemenu (sysmenu, sc_size, mf_bycommand);
Deletemenu (sysmenu, sc_restore, mf_bycommand);
Ende;
Beginnen
{Überspringen
Der Befehl der Größe aus dem Systemmenü.}
erbte DefaultHandler (Nachricht);
// Umgang mit dem Systemmenü auf unsere eigene Weise.
ModifysystemMenu;
Ende;
4. Tzocdlgressizable Klasse
Die endgültige Lösung, die ich als Klasse aus TFORM eingedämmt hat. Tzocdlgressizable.
Übrigens: Ich habe auch Tzocdlgressisable ein sizegrip -Attribut hinzugefügt.
Abbildung 5 Dialogfeld mit sizegrip ohne Symbol
Download (EXE- und Quellcode)
http://www.zocsoft.com/temp/Resizable_dialog.rar
5. Referenzmaterial:
MSDN: So entwirft man ein setzwerschbares MFC -Eigenschaftsblatt
Zitatadresse: "Implementieren eines Dialogfelds, mit dem die Größe in Delphi geändert werden kann"