Laden...

Form auf Desktop in Hintergrund "festhalten"

Erstellt von De3pBlu3 vor 13 Jahren Letzter Beitrag vor 13 Jahren 5.275 Views
D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren
Form auf Desktop in Hintergrund "festhalten"

Ich habe folgendes Problem:

Mein Ausgangspunkt ist ein neues Projekt mit einem leeren Form, dessen Border Style ich auf none gesetzt habe.

Nun möchte ich dieses Form, wie im Titel bereits erwähnt, auf dem Desktop "festhalten".

Das heißt mein Form soll nach dem Programmstart sofort in den Hintergrund rutschen (bis auf den Desktop) und sich somit hinter allen anderen offenen Windows-Fenstern befinden.
Desweiteren soll es dort auch bleiben!!! - will meinen, selbst durch Win+D oder Win+M bzw. alle anderen Möglichkeiten, Fenster zu minimieren, soll das Form sichtbar bleiben.

Habe leider überhaupt keine Idee, wie man das umsetzen könnte - aber ich hoffe ihr 😉

A
118 Beiträge seit 2009
vor 13 Jahren

Also ich kann mir nicht vorstellen, dass es möglich ist, das minimieren durch Win+D zu verhindern. Die Reihenfolge der Fenster kannst du jedenfalls mit Hilfe der Win Api ändern. (siehe SetWindowPos Function)

Eine mögliche, aber sehr unschöne Lösung wäre es, das Fenster mit einem Timer immer wieder sichtbar zu machen, falls es minimiert wurde.

Mfg
Aratar

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

Vielen dank für die schnelle Antwort...
werde das im laufe des Abends auf jeden fall noch ausprobieren

Frage am Rand: es wird nicht zufällig ein Event ausgelöst wenn das Fenster minimiert wird?...dann könnte man das damit natürlich umsetzen

A
118 Beiträge seit 2009
vor 13 Jahren

Nicht direkt. Aber du kannst das Resize- Event der Form abonnieren und wenn es gefeuert wird den WindowState des Formulars überprüfen:


if (this.WindowState == FormWindowState.Minimized)
{
//....
}

Mfg
Aratar

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

also das mit der Reihenfolge habe ich leider noch nicht hinbekommen...weiß aber leider auch nicht was ich falsch mache...mein aufruf sieht so aus:


public partial class MainWindow : Form
{
    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

    private void MainWindow_Load(object sender, EventArgs e)
    {
        SetWindowPos(this.Handle, 1, 0, 0, this.Width, this.Height, 0x0040);
    }
}

stimmt das alles oder hat sich da nen fehler eingeschlichen?:)

Ich habe bemerkt, dass Win+M schon ohne zusätzliche Codezeilen das Fenster nicht minimiert...allerdings scheint Win+D die Größe des Fensters nicht zu ändern...somit klappt das leider auch noch nicht...aber ich werde dafür mal noch ein paar andere events testen...

H
18 Beiträge seit 2010
vor 13 Jahren

Hi,

AFAIK wird beim Ausführen der Funktion "Desktop anzeigen" mit [WIN]-~~ lediglich das Listview des Desktops in den Vordergrund geholt. Daher kommen auch keine Nachrichten über den Vorgang bei Deiner Anwendung an.

Gruß
Patrick

3.511 Beiträge seit 2005
vor 13 Jahren

Dein Vorhaben ist, so wie du es beschrieben hast, nicht möglich. Was willst du denn genau erreichen? Denn, wie holliesoft besreits geschrieben hat, werden unter bestimmten Umständen nicht alle Windows Nachrichten verarbeitet, bzw. an die entsprechenden Fenster übermittelt.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

U
1.578 Beiträge seit 2009
vor 13 Jahren

Entwickel doch die Applikation als Windows Widget, die haben deine gewünschte Eigenschaften bereits.

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

Also...erreichen möchte ich folgendes:

Ich will eine Kalender-Anwendung schreiben, die auf dem Desktop sozusagen eingebettet ist...also eine art "interaktiver Desktop".
Somit soll sich diese Anwendung auch wie der Desktop selber verhalten, sprich:*immer im Hintergrund *immer sichtbar (soll also nicht minimert werden können) *auch in der Taskbar nicht sichtbar (diese Eigenschaft habe ich aber schon gefunden:))

...hoffe ihr habt jetzt eine konkretere vorstellung davon, was ich erreichen möchte?!

Die Idee, die Anwendung als Windows Widget zu entwickeln, klingt erstmal brauchbar, auch wenn ich nicht glaube, dass man damit eine art "zweiten Desktop" simulieren kann.

Werde mich darüber mal informieren...

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo De3pBlu3,

siehe http://de.wikipedia.org/wiki/Active_Desktop (ok, allerdings nicht besonders zukunftsträchtig, aber Alternativen werden dort auch gleich genannt)

herbivore

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

Naja...da ich Windows 7 nutze hat sich das speziell mit "Active Desktop" erledigt...aber wie dort auch bereits nochmal steht, werden nun die "Desktop Gadgets" verwendet, über die ich gerade Infos sammel...

Danke 🙂

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

Also ich habe gemerkt, dass das mit den Windows Gadgets irgendwie nicht das Richtige ist.
Es ist zwar eine sehr einfach Methode um kleine Anwendungen auf den Desktop zu bringen...dennoch würde ich lieber bei C# bleiben, anstatt html css php usw. zu nutzen. Denn dies ist noch dazu mein erstes großes Projekt in C# und soll somit auch zu Lehrzwecken dienen 😃

Ich werde heute mal noch ein bisschen mit der SetWindowPos() Fuktion rumspielen...vielleicht erreiche ich ja doch noch was.
Wenn jemand noch ein paar super Ideen zu meinem Problem hatt, dann bitte immer her damit 😃

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

Dank eurer Hilfe kann ich nun den ersten Teilerfolg präsentieren. Ich habe es gerade endlich geschafft, dass das Form hinter allen anderen Windows-Fenster nach dem Programmstart platziert wird 🙂
Wen es interessiert - hier ein Beispielcode:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {

        private static int HWND_BOTTOM = 0x1;
        private static int SWP_NOSIZE = 0x1;
        private static int SWP_NOMOVE = 0x2;
        private static int SWP_SHOWWINDOW = 0x40;
        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            SetWindowPos(this.Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            SetWindowPos(this.Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
        }
    }
}

Wenn ich es jetzt noch hinbekomme, dass mein Fenster immer sichtbar bleibt, dann wäre ich total zu frieden 🙂

156 Beiträge seit 2010
vor 13 Jahren

Moin,

Desktop holen
GetDesktopWindow Function

eigenes Fenster als Kind des Desktops setzen
SetParent Function

hand, mogel

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

Interessante Funktionen 🙂...
nur weiß ich leider jetzt nicht auf Anhieb, was es mir bringt, dass mein Child den Desktop als Parent hat...was für Vorteile bringt mir das bzw. welches Problem könnte man damit lösen?

156 Beiträge seit 2010
vor 13 Jahren

Moin,

mit folgender Funktion


        private void Form1_Activated(object sender, EventArgs e)
        {
            SetWindowPos(this.Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
        }

schiebst Du Dein Fenster immer nach hinten ... es kann aber passieren das das Fenster kurz vorne ist ... Du manipulierst nur die Z-Order ... nicht das eigentliche Verhalten (also immer hinten bleiben)

hand, mogel

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

aso...
und das gesamte Verhalten von meinem Fenster veränder ich, indem ich es als Child vom Desktop setze?!
In welche Funktion muss ich das machen...im Standardkonstruktor, oder in der Load-Funktion - oder ist das egal?

156 Beiträge seit 2010
vor 13 Jahren

und das gesamte Verhalten von meinem Fenster veränder ich, indem ich es als Child vom Desktop setze?!

jain ... das Verhalten ist gleich - es fügt sich seiner Z-Order Sortierung ... wenn Du mehrere Fenster auf TopMost setzt, verhalten Die sich untereinander auch wie immer - bleiben aber immer vor allen anderen die nicht TopMost gesetzt sind ... Du hast quasi 3 Ebenen wo sich die Fenster mit der Z-Order anordnen ... TopMost / Normal oder "immer hinten" ... letzteres nur wenn Du das Fenster als Kind vom Desktop-Fenster festnagelst

In welche Funktion muss ich das machen...im Standardkonstruktor, oder in der Load-Funktion - oder ist das egal?

wenn das Handle des Fensters erstellt wurde

hand, mogel

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

@mogel: danke für den Tipp...hat auch so funktioniert wie ich mir das gedacht habe 🙂

Ich habe nun aber eine noch elegantere Lösung gefunden, bei dir in zwei Codezeilen sowohl die Sperre für das Minimieren, als auch das Ändern der Z-Order mit enthalten sind:


IntPtr hwndParent = FindWindow("progman", null);
SetParent(form.Handle, hwndParent);

Nur fehlt mir noch ein wenig das Verständnis dafür, was die Funktion FindWindow mit dem Parameter "progman" genau macht?!
Kann mir das jemand erklären?

P
660 Beiträge seit 2008
vor 13 Jahren

Hier hast du eine gute Erklärung inklusive einem Beispiel
FindWindow
Und die Doku liefert auch einiges (ClassName = ProzessName)

MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden! *"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht." *"Ignorance simplifies ANY problem." *"Stoppt die Piraterie der Musikindustrie"

R
100 Beiträge seit 2009
vor 13 Jahren

Nur fehlt mir noch ein wenig das Verständnis dafür, was die Funktion FindWindow mit dem Parameter "progman" genau macht?!

FindWindow mit dem Parameter "progman" sucht nach dem Handle vom Desktop. Desktop hat ClassName "progman" und WindowName "Program Manager".

D
De3pBlu3 Themenstarter:in
13 Beiträge seit 2011
vor 13 Jahren

aso...na das macht das doch schon klarer...was ich dann nur komisch finde ist folgendes:
wenn ich anstatt der findWindow methode mit dem parameter "progman" die funktion getDesktopWindow benutze, dann erreiche ich nur, dass mein form nicht minimiert wird...
allerdings ist dabei dann nicht enthalten, dass mein form immer im hintergrund bleibt - was findWindow gleich mit übernimmt...
könnt ihr mir das auch noch erklären?!