Laden...

Form immer vor Taskleiste

Erstellt von EL_Broto vor 15 Jahren Letzter Beitrag vor 15 Jahren 7.377 Views
E
EL_Broto Themenstarter:in
55 Beiträge seit 2008
vor 15 Jahren
Form immer vor Taskleiste

Hallo leute

Ich hätte gerne, dass meine Form immer vor der Taskleiste verharrt.
Mit TopMost klappt das noch nicht 100%, da die Form dann hinter der Taskleiste verschindet, sobald man auf diese klickt.
Wie mach ich das am besten?

mfg EL_Broto

5.742 Beiträge seit 2007
vor 15 Jahren

Hallo EL_Broto,

Ich hätte gerne, dass meine Form immer vor der Taskleiste verharrt.

Das ist sehr ungewöhnlich.

Was möchtest du erreichen?

E
EL_Broto Themenstarter:in
55 Beiträge seit 2008
vor 15 Jahren

Hallo winSharp93,

mir ist es prinzipiell egal, ob es eine Form ist oder ob es noch andere Möglichkeiten gibt.
Ich möchte mir einen kleinen Applauncher schreiben, der hätte Klasse platz unter meinem Start-Button, da ich meine Taskleiste 2-zeilig verwende.

mfg EL_Broto

5.742 Beiträge seit 2007
vor 15 Jahren

Ich möchte mir einen kleinen Applauncher schreiben, der hätte Klasse platz unter meinem Start-Button, da ich meine Taskleiste 2-zeilig verwende.

Dann würde ich folgenden Workaround vorschlagen:
Ein Timer bringt deine Form jede Sekunde (Interval beliebig) in den Vordergrund.

R
234 Beiträge seit 2007
vor 15 Jahren

Performanter wäre es sich an die entsprechende Window-Hook (wenn die Taskleiste den in den Vordergrund kommt) zu hängen und nur bei Bedarf die eigene Form wieder "nach Oben" zu holen. Hab schonmal etwas ähnliches gemacht, wenn ich den Code noch finde poste ich ihn hier.

E
EL_Broto Themenstarter:in
55 Beiträge seit 2008
vor 15 Jahren

Wär klasse, wenn du den findest bzw. mir wer erklärt, wie das sonst gehen würde.
Mein nächstes Problem ist, dass meine Form "jumpy" beim verschieben ist(eigens realisiert mit MouseDown, MouseMove und MouseUp, da BorderStyle=none;). Hab ich Fehler in meinem Code?


private void Form1_MouseDown(object sender, MouseEventArgs e)
{
     if (e.Button == MouseButtons.Left) {
          this.Cursor = Cursors.SizeAll;
          move = true;
          mousePosition = e.Location;
     }

}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
     if (move) {
          this.Location = new Point(this.Location.X-mousePosition.X+e.X,this.Location.Y-mousePosition.Y+e.Y);
          this.mousePosition = e.Location;
     }
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
     if (e.Button == MouseButtons.Left) {
          move = false;
          this.Cursor = Cursors.Default;
     }
}

Edit: Ferner wäre interessant, die Form transparent zu machen, jedoch soll sie trotzdem klickbar sein, was sie mit TrensparencyKey nicht ist.

1.346 Beiträge seit 2008
vor 15 Jahren

Mán kann die Form mit this.Opacity Transparent machen.

Gruß pdelvo

E
EL_Broto Themenstarter:in
55 Beiträge seit 2008
vor 15 Jahren

Das stimmt, jedoch sollten die Elemente in der Form dann auch transperent.

946 Beiträge seit 2008
vor 15 Jahren

eigens realisiert mit MouseDown, MouseMove und MouseUp, da BorderStyle=none;).

Dein Code funktioniert nicht besonders zuverlässig. Versuche mal diesen hier:

protected override void WndProc(ref Message m)
{
    const int WM_NCHITTEST = 0x84,
              HTCLIENT     = 0x01,
              HTCAPTION    = 0x02;

    base.WndProc(ref m);

    if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCLIENT)
        m.Result = (IntPtr)HTCAPTION;
}

Den Coursor kannst du ja nachträglich irgendwie hinzufügen, da dieser eigentlich eher nebensächlich ist.

230 Beiträge seit 2007
vor 15 Jahren

Ich hätte gerne, dass meine Form immer vor der Taskleiste verharrt.

HI Man muß TopMost im richtigen Event plazieren. Grüsse sarabande


        private void Form1_Deactivate(object sender, EventArgs e)
        {
            this.TopMost = true;
        }

R
234 Beiträge seit 2007
vor 15 Jahren

Wär klasse, wenn du den findest

Ich habe meinen Code jetzt nicht gefunden und daraufhin ein wenig im Internet gesucht und habe festgestellt, dass die von mir beschriebene Möglichkeit einen globalen Hook benötigt (WH_CBT) - mein Code damals hatte doch ein wenig andere Anforderungen. Zitat aus How to set a Windows hook in Visual C# .NET: "Global hooks are not supported in the .NET Framework". Es gibt die möglichkeit, das irgendwie in eine C++ DLL auszulagern, aber ich weiß nicht ob das nicht vielleicht ein wenig zu aufwendig ist. Ansonsten kannst du dir den Artikel ja mal durchlesen.

Das Problem bei setzen von TopMost in einem Event oder per Timer ist, dass die Form dann über allen anderen Anwendungen liegen würde und nicht nur über der Taskleiste. Per Hook hätte man es so realisieren können, dass nur wenn die Taskleiste den Focus erhält, die Form wieder in den Vordergrund gebracht wird.

230 Beiträge seit 2007
vor 15 Jahren

Das Problem bei setzen von TopMost in einem Event oder per Timer ist, dass die Form dann über allen anderen Anwendungen liegen würde und nicht nur über der Taskleiste.

HI! Ne, ne - ein Applauncher sollte auch nicht von anderen Anwendungen verdeckt werden. 😃 Wenn ich erst eine Anwendung verschieben muß, um an den Applauncher zu kommen, kann ich gleich auf das Icon der Verknüfung in der Taskleiste klicken(OS-Einstellung der Taskleiste: "Immer im Vordergrund"). Das geht schneller. 😃 Grüsse - sarabande

E
EL_Broto Themenstarter:in
55 Beiträge seit 2008
vor 15 Jahren
  
        private void Form1_Deactivate(object sender, EventArgs e)  
        {  
            this.TopMost = true;  
        }  
  

Ist unzuverlässig bzw. funktioniert nicht, da, wenn ich in ein anderes Fenster klicke und dann auf die Taskleiste, ist der Laucher wiederum im Hintergrund.

Ne, ne - ein Applauncher sollte auch nicht von anderen Anwendungen verdeckt werden. 😃 Wenn ich erst eine Anwendung verschieben muß, um an den Applauncher zu kommen, kann ich gleich auf das Icon der Verknüfung in der Taskleiste klicken(OS-Einstellung der Taskleiste: "Immer im Vordergrund"). Das geht schneller. 😃

Ich verwende meine Taskleiste zweizeilig und "Immer im Vordergrund", daher ist es über keiner anderen Form, sondern nur über dem ungenutzen Teil der Taskleiste.

@See Sharp: Könntest du deinen Code etwas erklären, ich keinen Plan, was du da machst.

1.346 Beiträge seit 2008
vor 15 Jahren

See Sharp hat die WndProc Methode überschrieben. Sie ist ein sehr 'Systemnahe' Methodedie Nachrichten vom BS empfängt. In dieser Überprüft er ob das Fenster den Fokus verliert. Dort kannst du es in dem if wieder in den Fordergrund bringen.

Gruß pdelvo

230 Beiträge seit 2007
vor 15 Jahren

Ich verwende meine Taskleiste zweizeilig und "Immer im Vordergrund", daher ist es über keiner anderen Form, sondern nur über dem ungenutzen Teil der Taskleiste.

Hi! Wenn Taskleiste auf "immer im Vordergrund steht", kann es natürlich nicht funktionieren. Mein Code funktioniert nur, wenn Du diese Option unter Eigenschaften der Taskleiste entfernst. Jede Message, die den Fordergrund erzwingt, wird bei dieser Einstellung der Taskleiste vom OS verworfen. Das gilt auch für Lösungen mittels Hook, Timer oder MessageKeller überwachen.
Wie sieht eine zweizeilige Taskleiste aus? Ich kriege das hier mit XP nicht hin 😦 Grüsse - sarabande

R
234 Beiträge seit 2007
vor 15 Jahren

Ne, ne - ein Applauncher sollte auch nicht von anderen Anwendungen verdeckt werden. 🙂

Okay, dann habe ich das - wie schon befürchtet - falsch verstanden.

Wie sieht eine zweizeilige Taskleiste aus?

Rechtklick auf die Taskleiste -> Haken bei "Taskleiste fixieren" entfernen und dann denn Balken der überhalb der Taskleiste steht nach oben ziehen. 🙂

/EDIT:

eigens realisiert mit MouseDown, MouseMove und MouseUp, da BorderStyle=none😉.
Dein Code funktioniert nicht besonders zuverlässig. Versuche mal diesen hier:
[...]
Den Coursor kannst du ja nachträglich irgendwie hinzufügen, da dieser eigentlich eher nebensächlich ist.

Alternative Möglichkeit:


bool move = false;
Point movingStarted;

private void Form1_MouseDown(object sender, MouseEventArgs e) {
	if(!move) {
		movingStarted.X = e.X;
		movingStarted.Y = e.Y;
		move = true;
	}
}

private void Form1_MouseMove(object sender, MouseEventArgs e) {
	if(e.Button != MouseButtons.None) {
		Point newPos = new Point(FormMain.MousePosition.X - movingStarted.X,
								 FormMain.MousePosition.Y - movingStarted.Y);
		this.Location = newPos;
	}
}

private void Form1_MouseUp(object sender, MouseEventArgs e) {
	move = false;
}


T
177 Beiträge seit 2007
vor 15 Jahren

Hallo rastalt und El_Broto,

@El_Broto ich hätte dir dieselbe Technik wie rastalt empfohlen, jedoch:

@rastalt dir ist ein kleiner Fehler unterlaufen:


Point newPos = new Point(FormMain.MousePosition.X - movingStarted.X,
                                 FormMain.MousePosition.Y - movingStarted.Y);
this.Location = newPos;

wär korrekterweise:


Point newPos = new Point(FormMain.MousePosition.X - movingStarted.X,
                                 FormMain.MousePosition.Y - movingStarted.Y);
this.Location = new Point(this.Location.X + newPos.X, this.Location.Y + newPos.Y);

😉 😉 😉

€dith sagt: Mein Code ist falsch...

Mit freundlichen Grüssen,
Tobias

R
234 Beiträge seit 2007
vor 15 Jahren

@rastalt dir ist ein kleiner Fehler unterlaufen:

Hast du deinen Code mal ausprobiert?
Wenn ich meine entsprechende Zeile durch deine ersetze, "springt" das Fenster beim Bewegen nach außerhalb des sichtbaren Bereichs. Ich würde also vorschlagen doch meinen Code zu benutzten. 😉

T
177 Beiträge seit 2007
vor 15 Jahren

Gut ich muss zugeben ich habe mich verlesen und "FormMain.MousePosition.Y" überlesen.

Und ja ich habe meinen Code auch nicht getestet.

Also El_Broto, kannst du problemlos den Code von rastalt verwenden...

Mit freundlichen Grüssen,
Tobias