Desktop als Control missbrauchen?


Sunray

Erfahrenes Mitglied
Hi,
ich versuche gerade meinen Windows Desktop mit .NET zu erweitern. So als kleines Experiment. So weit bin ich im Moment:
Code:
Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As IntPtr

Public ReadOnly DesktopDeviceContext As IntPtr = GetDC(0)

Public Sub Main()
	Using g As Graphics = Graphics.FromHdc(DesktopDeviceContext)
		Dim elapsed As Long = 0
			While elapsed < 5000
			g.FillEllipse(Brushes.WhiteSmoke, New Rectangle(Form.MousePosition.X - 5, Form.MousePosition.Y - 5, 10, 10))
			Threading.Thread.Sleep(1)
			elapsed += 1
		End While
	End Using
End Sub
Für 5 Sekunden nach Programmstart kann ich lustige, weisse Kreise auf den Desktop malen, aber ich möchte mehr. Wäre es nicht auch möglich, Controls auf dem Desktop zu platzieren? Ich bekomme auch das Window Handle des Desktops mit
Code:
Declare Function GetDesktopWindow Lib "user32" () As IntPtr
heraus, aber das nützt mir nicht viel, da
Code:
System.Windows.Forms.Form.FromHandle(hwnd as IntPtr)
Null zurück gibt, wenn der aufrufende Prozess nicht Besitzer des Fensters ist, was ja so rein Sicherheitstechnisch auch Sinn macht.

Gibt es jetzt irgend eine Möglichkeit, trotzdem an eine Referenz auf "Desktop Control" zu bekommen oder zum Beispiel einen Butten auf dem Desktop zu platzieren, ohne transparente Fenster zu benutzen?
 

Alexander Schuc

crazy-weasel
Hi.

Mittels FindWindow kannst dir das Handle vom "Fenster" das für den Desktop verantwortlich ist holen. Also, ich meine dieses wo die Icons dargestellt werden. (Denke jetzt mal das es dieses ist, welches sollte es aber auch sonst sein.)

SetParent verwendest dann, um dein Fenster zum Child davon zu machen.

Und nun.. das wars auch schon.

Code:
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr FindWindow(
	[MarshalAs(UnmanagedType.LPTStr)]
	string lpClassName,
	[MarshalAs(UnmanagedType.LPTStr)]
	string lpWindowName );

[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent );
...
IntPtr hwndf = this.Handle;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf,hwndParent);
Wenn du willst, kannst nun auch noch Einstellen, das man mit der Maus durch dein Fenster durchklicken kann.

Code:
[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError=true)]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

private const int  GWL_EXSTYLE = -20;
private const int  WS_EX_TRANSPARENT = 0x20;
...
int exstyle = GetWindowLong(this.Handle, GWL_EXSTYLE);
exstyle |= WS_EX_TRANSPARENT;
SetWindowLong(this.Handle, GWL_EXSTYLE, exstyle);

Das ganze hab ich mal wo, glaube bei CodeProject, aufgeschnappt.

MfG,
Alex

p.s.:
Hab noch ein kleines Programm zum Verdeutlichen angehängt.
Es wird ein Fenster erstellt, via TransparentKey / BackgroundColor und der richtigen FormBorderStyle Einstellung sieht man das ganze Fensterzeugs nicht. 2 Buttons gibt es. Der eine zeichnet etwas am Desktop, hab dafür das Import und so aus deinem Code, der andere Beendet das Program.
Man kann wunderschön sehen, dass die Buttons direkt am Desktop sind. Die Icons sind allerdings noch dahinter.
Ach.. ich weiss das ich mich beim Projekt-Namen verschrieben hab. ;) Zu dieser Stunde sollte das erlaubt sein.
 

Anhänge

Sunray

Erfahrenes Mitglied
Danke für die Hilfe...
nur leider gibt
Code:
Dim fo As New Form1()
SetParent(GetDesktopWindow(), s.Handle)
0 zurück. Daraus lässt sich schliessen, dass es so nicht funktioniert. Schade... die WinForm Lösung ist zwar nicht ganz so cool wie den Desktop zu übernehmen aber funktioniert wenigstens ;) ...
 

Danielku15

Erfahrenes Mitglied
Um das alte Thema wieder mal aufzugreifen:

Ich pinne gerade mein Form auf meinen Desktop. Funktioniert auch wunderbar: Das Form liegt auf dem Desktop und auch bei "Desktop anzeigen" wird das Form angezeigt.

Jedoch hab ich zwei Fragen:

1) Wenn ich das Form auf den Desktop pinne. Sind weder ToolStrip noch MenuStrip anklickbar. Der Hover Funktioniert aber die Buttons werden nicht gedrückt. Woran könnte das Liegen?

2) Wie kann ich das Fenster vom Desktop wieder abdocken? Einfach als Parent IntPtr.Zero setzen?

Gruß Daniel
 

Fridulin

Erfahrenes Mitglied
Hallo,

ich möchte so etwas ähnliches machen, meine Form soll nun allerdings noch hinter den Symbolen auf den Desk sein. Sprich direkt vor dem Hintergundbild, aber hinter den Symbolen.
Das Beispiel mit den Deskbutton funktioniert bei mir leider nicht im neuen BS.

Hier ist mein Thread, ich habe schon den Beitrag gemeldet und hoffe das der bald verschoben wird in WinForms, da er ja eigentlich dort hinein gehört, finde ich.

http://www.tutorials.de/forum/net-grafik-und-sound/324567-anwedung-auf-den-desk-einbetten.html

Viele Grüße und für jede Hilfe wäre ich sehr Dankbar.
Fridulin