Laden...

Transparente Desktoperweiterung

Erstellt von DivinitY vor 18 Jahren Letzter Beitrag vor 14 Jahren 18.358 Views
D
DivinitY Themenstarter:in
58 Beiträge seit 2005
vor 18 Jahren
Transparente Desktoperweiterung

Weiß zufällig jemand, wie ich folgende Situation am besten nachbauen kann.

Habe schon ein bisschen herumprobiert, allerdings hatte ich dabei einige Schwierigkeiten, wobei das Hauptproblem nach wie vor ist, wie ich es schaffe, dass

  1. diese Applikation ständig im Hintergrund ist bzw.
  2. das Drücken von WIN-D bzw. "Desktop anzeigen" in der Schnellstartleiste diese Applikation nicht minimiert.

Wäre für jeden Tipp dankbar.

1.457 Beiträge seit 2004
vor 18 Jahren

Die Anwendung sieht garnicht schlecht aus. Um welche Anwendung handelt es sich denn?

Meines erachtens wird das Active Desktop benutzt. Ich bin gerade selber auf der Suche nach Informationen zwischen C# und Active Desktop.

D
DivinitY Themenstarter:in
58 Beiträge seit 2005
vor 18 Jahren

Die Anwendung heißt DeskTask.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo DivinitY,

zu 2. könntest du es über den Resize-Event probieren. Wenn du es nicht schaffst, dass Minimieren zu verhinden, kannst du dort zumindest das Fenster sofort wiederherstellen.

Eine grundsätzlich andere Möglichkeit wäre wohl mit DirectDraw o.ä. direkt auf den Desktop zu zeichen.

herbivore

D
DivinitY Themenstarter:in
58 Beiträge seit 2005
vor 18 Jahren

Original von herbivore
zu 2. könntest du es über den Resize-Event probieren. Wenn du es nicht schaffst, dass Minimieren zu verhinden, kannst du dort zumindest das Fenster sofort wiederherstellen.

Bei mir wird das Resize-Event nur gefeuert wenn ich den Minimize-Button der Form direkt drücke, wenn ich alle Fenster per o.g. Varianten minimiere, wird der Event nicht ausgelöst. 🙄

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo DivinitY,

schau mal hier in minimieren verhindern . Das müsste dein Minimieren-Problem lösen.

herbivore

D
DivinitY Themenstarter:in
58 Beiträge seit 2005
vor 18 Jahren

Recht herzlichen Dank, dann werde ich mal 'weiterbasteln'.

MfG

DivinitY

2.921 Beiträge seit 2005
vor 18 Jahren

Halli hallo DivinitY, so etwas in der Art habe ich schon gemacht.

Auf den Desktop zeichnest du in dem Du Dir ein Handle von 0 (nicht null) nimmst und mit den entsprechenden Api-Funktionen zeichnest.

Zum abfangen des minimierens, so dass die Anwendung gar nicht erst sich minimiert es erkennt und wieder maximiert, kannst du einen Keyboard hook installieren.

Microsoft hat ein beispiel dazu in C#:

http://msdn.microsoft.com/msdnmag/issues/02/10/CuttingEdge/

Damit kannst du das Verhalten ganz abfangen.

und (getestet) hiermit auf den Desktop zeichnen:


[DllImport("user32.dll")]
		static extern IntPtr GetDesktopWindow();

		[DllImport("user32.dll")]
		static extern IntPtr GetDCEx(IntPtr hwnd, IntPtr hrgn, uint flags);

		private void button3_Click(object sender, System.EventArgs e)
		{
			IntPtr hdc = GetDCEx(GetDesktopWindow(), IntPtr.Zero, 1027);
			using(Graphics g = Graphics.FromHdc(hdc))
			{
				g.FillEllipse(Brushes.Red, 0, 0, 432, 432);
			} 		
		}

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

S
238 Beiträge seit 2004
vor 18 Jahren

Hmm, das funktioniert schonmal ziemlich gut (wenn man es in eine Klasse packt).
Ich habe mich etwas daran versucht und musste leider feststellen, dass diese Variante immer TopMost zeichnet. Will sagen: Sie zeichnet nur dann auf dem Desktop, wenn dieser auch gerade sichtbar ist. Sonst zeichnet sie auf dem gerade aktuellen Fenster. Oder hab ich irgendwas falsch gemacht? Ich meine, es wäre sehr schön, wenn sie auf dem wirklichen Desktop zeichnen würde, denn dann wäre der Text im Zweifelsfall auch hinter den Icons verborgen, was noch mal besser wäre, finde ich.

Jemand eine Idee, wie man das soweit anpassen kann?

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

563 Beiträge seit 2004
vor 18 Jahren

Leider kann ich dir nicht direkt weiterhelfen. Ich hätte aber ne andere Idee: Warum öffnest du nicht das Wallpaper, zeichnest auf das Bild und setztst es wieder als wallpaper? Denke dass meine Idee zuviel performance schluckt 🙁

Vieleicht ist es ja nen Versuch wert 🙂

Gruss,
.unreal

1.271 Beiträge seit 2005
vor 18 Jahren

Hallo DivinitY,

Ich kann dir zwar leider nicht helfen, wollte aber sagen, dass ich auf die Lösung gespannt bin. Lass es uns also auf jeden Fall wissen, wenn du das Problem gelöst hast 😉
Viel, viel Erfolg!

Gruß,
progger

A wise man can learn more from a foolish question than a fool can learn from a wise answer!
Bruce Lee

Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.

2.921 Beiträge seit 2005
vor 18 Jahren

dazu musst du den grafischen Canvas der ersten(!) geöffneten Explorer-Instanz ermitteln. Also den HDC dieses Explorers. Dann solltest du das erreichen.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

S
238 Beiträge seit 2004
vor 18 Jahren

Ok, klingt einleuchtend...wenn du mir jetzt noch sagen könntest, wie ich das schaffe, bin ich glücklich...

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

C
159 Beiträge seit 2005
vor 18 Jahren

Warum nicht eine Form nehmen, die Transparent und nicht verschiebbar machen....Rahmen weglassen und das wärs...
Als einziges musst Du dafür sorgen, wie diese das gegenteilige Verhalten von AlwaysOnTop besitzt.

Christof

S
238 Beiträge seit 2004
vor 18 Jahren

Hmm, auch ne Idee...weißt du auch, wie ich das Gegenteil von TopMost erreiche? AFAIK gibt es so was wie BottomMost nicht...oder doch? Wenn das jemand weiß - lasst es mich wissen, ich freu mich 😁

So, ich geh pennen...

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

L
50 Beiträge seit 2005
vor 18 Jahren

Hallo!

Die einzige lösung die mir dazu einfallen würde wäre beim Activated-Ereignis das Formular auf Deactivated zu stellen

Ich bin mir nicht sicher ob dieses ereignis dem GotFocus ereigniss in visual basic enspricht... hab das ereignis in c# bis jetzt nochnicht gebraucht

mfg luke

D
462 Beiträge seit 2005
vor 18 Jahren

Hallo!

Also: du könntest die Methode 'SendToBack()' aufrufen, und zwar immer dann, wenn das Fenster den Fokus bekommt oder sonst irgendwie in den Vordergrund kommen könnte und wenn das Fenster minimiert wird (klick auf 'Desktop anzeigen') das Fenster wiederherstellen.

Und ich würds ebenfalls mit einem transpartenten Fenster machen (also ohne Titelleiste).

mfg

S
238 Beiträge seit 2004
vor 18 Jahren

Das mit der SendToBack()-Methode könnte sogar funktionieren...werde ich bei Gelegenheit mal ausprobieren! Danke erstmal! 😁

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

R
1 Beiträge seit 2006
vor 17 Jahren

Hallo!

Hatte das selbe Problem beim Entwickeln meiner Anwendung. Die Anwendung sollte immer auf dem Desktop "kleben" und auch bei "Desktop anzeigen" nicht verschwinden. Die Lösung ist dass man das Handle vom "Desktopfenster" mit der Funktion FindWindow ermittelt und dann mittels SetParent das eigene Programm als Child vom "Desktopfenster" macht. Damit ist dann das eigene Windows Form automatisch im Hintergrund und beim Drücken von "Desktop anzeigen" verschwindet das Fenster nicht mehr.

Und hier nun der Link zu diesem genialen Code von Alexander 😄:
Desktop als Control missbrauchen

Ich hoffe das hat dir jetzt geholfen.

Romeo

S
238 Beiträge seit 2004
vor 17 Jahren

An sich eine sehr schöne Sache, die ja auch ganz gut funktioniert. Nur dummerweise hat sie zwei Schwachstellen:

  1. Die Buttons sind immer noch nicht "hinter" den Desktop-Icons
  2. Die gezeichnete Message wird immer noch "on Top" gezeichnet

Wenn mir jemand sagen kann, wie man diese beiden Schwachstellen beseitigt, wäre mein Problem gelöst...

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

M
1.439 Beiträge seit 2005
vor 17 Jahren

Schaut euch mal http://widgets.yahoo.com/ an. Früher hieß das noch Konfabulator.
Schaut auch sehr elegant aus.
Die dürften das ungefähr so gemacht haben:
Pro Widget eine Form, FormBorderStyle auf None, und die Transparenz entsprechend gesetzt.

S
238 Beiträge seit 2004
vor 17 Jahren

Ja, ist recht nahe dran...aber wirklich hinter den Icons ist das immer noch nicht. Aber schick ist es definitiv, muss man Yahoo! lassen!
Habs sogar mal installiert...hätt nicht gedacht, dass mir das mit nem Desktop-Widget mal passieren würde...

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

183 Beiträge seit 2006
vor 17 Jahren

Da möcht ich gern nochmal nachhaken, da ich selber gerade wirklich etliche Varianten ausgetestet habe bzw austeste wie man nun am besten auf ein Desktop zeichnet. Hat mittlerweile jemand eine Lösung wie man Text, Steuerlemente oder eben alles was das Form noch so beinhaltet(Bilder etc) >hinter< die Icons bekommt?

.unreal hatte mal zwischendurch geschrieben warum nicht das Wallpaper zeichnen und ändern. Ähnlich habe ich es auch mal gemacht in dem ich einfach immer mit meinen Daten eine HTML Seite erstellt habe in der sich JavaScript befindet welche die Aktualisierung übernimmt. ActiveDesktop musste demnach aktiveirt sein.

Würde mich über ein paar positive Meinungen/Vorschläge freuen.

Gut Schuß
VuuRWerK 😉

S
238 Beiträge seit 2004
vor 17 Jahren

Hmm, ich habe bisher nichts neues finden können, leider.

Ich für meinen Teil wollte aber auch ohne den Active Desktop aukommen (was geht).

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

M
13 Beiträge seit 2005
vor 16 Jahren

Eventuell hilft dir das weiter

Form auf Desktop kleben

S
238 Beiträge seit 2004
vor 16 Jahren

Nein, leider nicht wirklich, da die Form noch immer vor den Desktop-Icons liegt...und nicht dahinter, so wie ich es gerne hätte...leider...

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

40 Beiträge seit 2007
vor 16 Jahren

Habe auch schon ein ähnliches Programm gesehen - laut Beschreibung ändert es das Hintergrundbild (ohne die Vorlage zu ändern). Ich denke das wird auch so ziemlich die einzige Möglichkeit sein wenn du hinter allen Desktop-Objekten sein willst.

EDIT: Hier wird beschrieben wie man ein neues Wallpaper setzt. Vielleicht kann man das aktuelle auslesen, und geändert wieder setzen.
http://www.codeproject.com/csharp/WallChange.asp

S
238 Beiträge seit 2004
vor 16 Jahren

Na ja, es geht offensichtlich, da ich ein Beispiel in C++ gefunden habe, welches genau das tut, was ich haben möchte. Leider hab ich es bisher nicht geschafft, es anzupassen an C#...

Hier der Link: http://www.angelcode.com/dev/desktopdraw/

Offensichtlich geht das sogar mit DirectX: http://www.angelcode.com/dev/overlay

Kann das jemand nach C# portieren (also das erste, so dass man ein Objekt hat, auf dem man zeichnen kann, welches sich so verhält wie im ersten Beispiel)?

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

2.921 Beiträge seit 2005
vor 16 Jahren

das problem wurde schon hier gelöst:

Direkt auf Desktop zeichnen mit GDI+

Warum soll die Form hinter den Icons erscheinen?

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

S
238 Beiträge seit 2004
vor 16 Jahren

Also in meinem Fall, damit der gesamte Desktop weiterhin nutzbar bleibt (Icons, etc.), man jedoch bestimmte Infos (z.B. den Kalender, eine Uhr, irgendwie sowas) dahinter einblenden kann.
Man könnte auch irgendwas entwickeln, was dem Desktop zusätzliche Funktionen gibt (welche auch immer), wobei da eine Shell-"Replacement" vielleicht eleganter wäre...

Na ja, ich werd mir deinen Link mal ansehen, Rumpel, vielleicht löst der mein Problem?!? Danke auf jeden Fall schon mal...

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

165 Beiträge seit 2007
vor 16 Jahren

Ich hätte ma ne ganz dumme Idee. Das wäre dann das verhalten von ICQ, wenn man es an eine Seite dockt. Es verschiebt einfach alle Icons, die im Weg sind. Aber wie das geht weiß ich nicht...

Visit my Blog: http://michael.barz.de

S
238 Beiträge seit 2004
vor 16 Jahren

Nee, das is ja noch mal ne ganz andere Sache (irgendwo bei CodeProject gibt's das, mal nach dem Begriff 'Shell' suchen).
Eben solche Sachen will ich ja vermeiden. Eben wirklich nur diesen ungenutzten Layer zwischen Background-Picture und Icons nutzbar machen, das will ich...am besten mal das Sample ausprobieren, welches ich weiter oben gepostet habe (das von Angelcode), dann weiß man, was ich meine (den rotierenden Stern auf ein Icon bewegen, der ist dann dahinter).

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

S
238 Beiträge seit 2004
vor 16 Jahren

Ich hab mal noch eine Frage, die zwar was mit dem Thema zu tun hat, aber sich von meinem letzten Posting abgrenzt, deshalb das doppelte Posting.

Ich habe versucht, das Handle auf den Desktop zu bekommen mittels:


[DllImport("user32.dll", EntryPoint="FindWindowExA",  SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", EntryPoint = "FindWindowExA", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);
        
[DllImport("user32.dll", EntryPoint="FindWindowA", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

Jedoch kriege ich mit dem Aufruf


IntPtr hProgman = FindWindow("ProgMan", string.Empty);
IntPtr hShellDef = FindWindowEx(hProgman, IntPtr.Zero, "SHELLDLL_DefView", IntPtr.Zero);
IntPtr hDesktop = FindWindowEx(hShellDef, IntPtr.Zero, "SysLitView32", IntPtr.Zero);

Dreimal eine Null heraus.

In der C++-Variante werden die Handles exakt so geholt, bzw:


HWND hProgMan  = FindWindow("ProgMan", NULL);	
HWND hShellDef = FindWindowEx(hProgMan, NULL, "SHELLDLL_DefView", NULL);
hDesktopWnd    = FindWindowEx(hShellDef, NULL, "SysListView32", NULL);

Und da fragt man sich doch, warum das nicht klappt...

Kann mir da jemand helfen?

Greets - SK

Sagte ich schon Danke? Nein? ...kommt noch...

16 Beiträge seit 2007
vor 16 Jahren

hi Schattenkanzler

So bekommst du das Desktop-Handle.


[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();

nike122

T
1 Beiträge seit 2010
vor 14 Jahren

Hi,

Man kann die Form transparent machen, indem man den TransparentKey und den Hintergrund des Formulars auf die gleiche Farbe setzt(z.B. Magenta). Und um das Formular auf den Desktop zu setzen, kann man den Parent des Fensters setzen:


[DllImport( "user32.dll" )]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName );

[DllImport( "user32.dll" )]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent );

[DllImport( "user32.dll" )]
public static extern IntPtr GetDC(long hwnd);

public Form1()
{
InitializeComponent();
IntPtr desktopHandle = FindWindow("ProgMan", null);
SetParent(this.Handle, desktopHandle);
}