Laden...

Eigene Form-Klasse

Erstellt von vbtricks vor 16 Jahren Letzter Beitrag vor 16 Jahren 4.886 Views
vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 16 Jahren
Eigene Form-Klasse

Salut,

ich bin gerade dabei, eine eigene Form-Klasse mit individuellem Design zu erstellen. Diese wird von System.Windows.Forms.Form abgeleitet. Inzwischen bin ich auch schon soweit, dass sich die Form in der Größe ändern lässt.

Leider gibt es noch ein paar offene Fragen:*Überladen der FormBorderStyle-Eigenschaft
Da die Klasse intern auf einer Form mit FormBorderStyle=None aufsetzt, würde ich die FormBorderStyle-Eigenschaft gerne überladen, um die Änderung dieser Eigenschaft nicht auf die interne Form zu übertragen

*Systemmenü
Gibt es eine Möglichkeit, das Systemmenü anzuzeigen, obwohl die Form BorderStyle=None hat oder alternativ ein eigenes Menü beim Rechtsklick auf die Schaltfläche in der Taskleiste anzuzeigen?

*Kein Refresh beim Hover
Eigentlich sollen die Buttons in der Titelleiste beim Hover mit anderen Grafiken übermalt werden, dafür erstelle ich mit CreateGraphics für die Form ein Graphics Objekt, aber wenn ich in dieses male, wird der Inhalt der Form nicht aktualisiert.

*Code einigermaßen im .NET-Sinne?

Selbstverständlich bin ich für alle Verbesserungsvorschläge offen.

Da das ganze relativ umfangreich ist, stelle ich den Code als VS-Solution zum Download: gui.zip

Wenn jemand die Zeit finden würde, und mir bei der Klärung obiger Fragen behilflich sein könnte, wäre ich sehr dankbar,

Stefan

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo vbtricks,

Teilantwort:

FormBorderStyle: Leider nicht möglich, da FormBorderStyle nicht virtual ist. Du kannst höchstens den internen Style merken, auf StyleChanged reagieren (wenn das durch FormBorderStyle denn ausgelöst wird) und ihn dann wieder zurücksetzen.

Hover: Mal abgesehen davon, dass CreateGraphics tendenziell ein Hinweis ist, dass was mit dem Design der Anwendung nicht stimmt (normalerweise kommt man mit den im OnPaint übergebenen Graphics-Objekten hin), bezieht sich ein Graphics-Objekt für eine Form meines Wissens immer auf die ClientArea und wird entsprechend an den Grenzen der ClientArea geclipt.

herbivore

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 16 Jahren

Salut,

Original von herbivore
Hover: Mal abgesehen davon, dass CreateGraphics tendenziell ein Hinweis ist, dass was mit dem Design der Anwendung nicht stimmt (normalerweise kommt man mit den im OnPaint übergebenen Graphics-Objekten hin), bezieht sich ein Graphics-Objekt für eine Form meines Wissens immer auf die ClientArea und wird entsprechend an den Grenzen der ClientArea geclipt.

hm, ich male aber eigentlich im ClientArea der Form, ClipBounds und VisibleClipBound scheinen von den Werten in Ordnung zu sein.

Wenn ich kein CreateGraphics verwenden darf, wie male ich dann bei einem Hover auf die Form? Ein OnPaint wird da ja nicht ausgelöst und ein Me.Refresh() ist ja wohl nicht elegant.

Stefan

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo vbtricks,

wie male ich dann bei einem Hover auf die Form?

Löse mit Invalidate das Neuzeichnen aus.

herbivore

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 16 Jahren

Salut,

wieder was dazugelernt.

Stefan

871 Beiträge seit 2005
vor 16 Jahren

Hallo vbTricks,

bezüglich des Systemmenüs schau dir mal die beiden nativen WIn32 API Funktionen "GetSystemMenu" und "SetSystemMenu" an, vielleicht sind die was für dich.

Grüsse, Egon

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 16 Jahren

Salut,

vom Namen her klingen die schon mal nicht schlecht, allerdings finde ich zu SetSystemMenu bei Google kaum was und die MSDN scheint die Funktion nicht zu kennen (wobei das nichts heißen muss, wenn ich was in der MSDN nicht finde, die gehört zu einer der unübersichtlichsten Seiten im Web).

Hast du vielleicht ein Beispiel zur Hand?

Stefan

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo vbtricks,

GetSystemMenu Function

Ich suche in der MSDN immer über google nach dem Muster: <funktionsname> msdn

Meistens ist dann die Doku der Funktion unter den ersten fünf Treffern.

herbivore

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 16 Jahren

Salut,

soweit bin ich jetzt:


[DllImport("user32.dll")]
private static extern int GetSystemMenu(int hwnd, bool bRevert);
[DllImport("user32.dll")]
private static extern int AppendMenu(int hMenu, int Flagsw, int IDNewItem,
    string lpNewItem);
[DllImport("user32.dll")]
private static extern int SetSystemMenu(int hwnd, int Menu);
[DllImport("user32.dll")]
static extern IntPtr CreatePopupMenu();


public Form1()
{
    InitializeComponent();
    this.Show();
    int Menu1 = GetSystemMenu(this.Handle.ToInt32(), false);  // get handle to system menu
    //int Menu1 = CreatePopupMenu().ToInt32();
    AppendMenu(Menu1, 0xA00, 0, null);   // makes a separator
    AppendMenu(Menu1, 0, 666, "C# Rules!");
    this.FormBorderStyle = FormBorderStyle.None;
    //SetSystemMenu(this.Handle.ToInt32(), Menu1);
}

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    if (m.Msg == 0x112)
    {    // WM_SYSCOMMAND is 0x112
        if (m.WParam.ToInt32() == 666)
        {   // the Menu's ID is 666
            //everything in here will run when menu is clicked
            MessageBox.Show("Yo!");
        }
    }
}

Wenn ich die Zeile


this.FormBorderStyle = FormBorderStyle.None;

auskommentiere, wird ein neuer Eintrag zum Systemmenü hinzugefügt, mit der Zeile klappts nicht. Lass ich die Zeile


SetSystemMenu(this.Handle.ToInt32(), Menu1);

wieder zu, tut es nicht. Da scheint die Deklaration nicht zu stimmen...

Stefan

4.221 Beiträge seit 2005
vor 16 Jahren

Ein Handle kannst Du erst verwenden wenn es erstellt ist.

Ev. mit CreateHandle forcieren.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 16 Jahren

Salut,

die Handle des Fensters existiert doch nachdem ich die Show-Methode aufgerufen habe, ein manuelles CreateHandle danach liefert auch prompt einen Fehler...

Stefan

4.221 Beiträge seit 2005
vor 16 Jahren

OK das Show im Constructor habe ich übersehen (wer macht schon so was) 🙂

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

795 Beiträge seit 2006
vor 16 Jahren

Ich habe den Fehler mit den Formbuttens und dem Nicht-Refreshen gefunden!

In der Klasse ButtonInfo steht ja:


public Image ImageHover
{
    get { return imageNormal; }
}

Sollte das nicht so heissen?


public Image ImageHover
{
    get { return imageHover; }
}

GRuß, Christian.

`There are 10 types of people in the world: Those, who think they understand the binary system Those who don't even have heard about it And those who understand "Every base is base 10"`
B
53 Beiträge seit 2007
vor 16 Jahren

Hallo vbTricks,

schau mal hier in den Artikeln da gibt es einen für eigene WindowsBorder mit eigenen Einträgen im SystemMenü: [Artikel] Custom Window Border für Form's

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 16 Jahren

Salut,

@Schamese
Die Version hier im Thread ist nicht mehr besonders aktuell. Den Fehler hatte ich in meiner lokalen Version bereits behoben. Ich habe mal eine aktualisierte Version reingestellt.

@BennyP
Die im verlinkten Thread vorgestellte Version arbeitet bei mir nicht ganz sauber, was Darstellungsfehler nach sich zieht.

Stefan