VB.NET: Eigene oder Fremde Prozesse vor dem Benutzer verstecken
In diesem Beitrag gehts es darum wie man Programme bzw Prozesse vor dem Benutzer verstecken kann. Ich hatte schon oft den fall, dass ein bestimmtes Programm unbedingt laufen musste, und keine Funktion bat, die es ausblenden ließ. Diese Anwendung nahm dann auchnoch Platz inder Taskleiste weg und man lief Gefahr, diese ausversehen zu beenden.
Dieses Problem kann man natürlich sehr einfach lösen, indem man diese Anwendung ausblendet! Was bei Mac OS mit einem einfachen Rechtsklick geht muss man bei Windows leider selbst machen. Aber gut, erstellen wir ein neues Windows Forms Projekt und plazieren auf dem Formular zwei Buttons und zwei Listbox - Objekte! (Siehe Bild)
Die Obere Liste soll uns später alle sichtbaren Fenster anzeigen und die untere alle von uns Versteckten.
Freundlicherweise stellt und Microsoft in der Win32 API eine Funktion zur Verfügung, die uns viel Arbeit erspart und das Verstecken der Fenster für uns übernimmt! Die Funktion die wir brauchen befindet sich in der User32.dll und nennt sich ShowWindow. Diese müssen wir ersteinmal importieren:
Imports System.Runtime.InteropServices
Public Class frmMain
_
Public Shared Function ShowWindow(ByVal hWnd As IntPtr,_
ByVal nCmdShow As Integer) As Long
End Function
End Class
Diese Funktion benötigt zwei Parameter, erstens ist hWnd, welches das Handle des Fensters enthällt welches wir ansprechen wollen und der zweite Parameter nCmdShow den Befehl den wir an das Fenster übergeben wollen!
Eigentlich sid wir schon fertig, denn wir können nun diese Funktion aufrufen und als Parameter z.B. Me und vbHide angeben und somit unser eigenes Formular verstecken! OK - das ist ja auch leicht! Denn das Handle von unserem eigenen Fenster kennen wir ja durch z.B. Me.Handle - aber wie kommen wir an das Handle eines anderen Fensters?
Zu unserem Glück bietet das .NET Framework hier sehr mächtige APIs die es und schnell ermöglichen auf die Prozess Strukturen von Windows zu zugreifen! Erstellen wir also noch einen Button auf dem Formular und nennen ihn "Aktualisieren". In dessen Klick-Event kommt nun folgender Code rein:
Private Sub Button3_Click(ByVal sender As System.Object,_
ByVal e As System.EventArgs) Handles Button3.Click
Dim pl As Process() = Process.GetProcesses
Me.ListBox1.Items.Clear()
For Each p As Process In pl
If p.MainWindowTitle <> "" Then
Me.ListBox1.Items.Add(p.MainWindowTitle)
End If
Next
End Sub
Wenn wir das Programm nun starten erhalten wir in Listbox1 alle Aktiven Prozesse, die dem Benutzer ein Fenster. also eine GUI bereitstellen. Aber nun im Detail: zuerst deklarieren wir pl - die als Typ einen Prozess-Array bekommt. In dieses Array können nun Prozess Objekte eingegeben werden, was wir auch sogleich tun durch die Anweisung Process.GetProcesses. Dadurch werden alle zur Zeit laufenden Prozesse in diesem Array gespeichert! Übrigens soll pl ProzessList heißen.
In der anschließenden For Each Schleife prüfen wir jeden Prozess persönlich ob sein Fenster (p.MainWindowTitle) einen Wert hat. Denn nur die Prozesse die hier einen Wert haben sind auch sichtbar! - Ausnahmen bilden hier die Formulare ohne Titel und der Windows Explorer von Windows Vista - Bill Gates selbst weis warum die Explorer Fenster keinen Titel haben!
Gut, Schritt eins haben wir geschafft, wir sehen alle offenen Fenster. Jetzt wollen wir diese auch verstecken können! Hier muss man aber aufpassen, denn wenn man ein Fenster verstecken will muss man dessen Handle angeben, sobalt das Fenster versteckt ist, hats dementsprechend auch kein Fenster-Handle mehr, da das Fenster ja weg ist! Deswegen ist es super wichtig, das Handle von JEDEM Fenster, dass man versteckt zu speichern da sonst nurnoch ein Beenden durch den Taskmanager bleibt!
Nun erstellen wir mit einem Doppelklick auf Button1 (Verstecken) das entsprechende Klick-Ereignis und geben folgenden Code ein:
Dim Windows As List(Of IntPtr) = New List(Of IntPtr)
Dim Titles As List(Of String) = New List(Of String)
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim pl As Process() = Process.GetProcesses
'Nur wenn ein Fenster gewählt wurde
If ListBox1.Text <> "" Then
For Each p As Process In pl
'Den Prozess suchen der gewählt wurde
If p.MainWindowTitle = ListBox1.Text Then
'Den Handle sichern
Windows.Add(p.MainWindowHandle)
'Den Namen des Fenster sichern
Titles.Add(p.MainWindowTitle)
'Das gewählte Fenster verstecken
ShowWindow(p.MainWindowHandle, vbHide)
'Den Titel des Versteckten Fensters in die Liste schreiben
ListBox2.Items.Add(p.MainWindowTitle)
End If
Next
End If
'Unsere Liste aktualisieren
Button3_Click(Me, e)
End Sub
Hier machen wir eigentlich nichts anderes als in der Aktualisieren Funktion, nur prüfen wir hier ob der Fenstertitel (MainWindowTitle) dem in der ListBox1 gewähltem Fenster entspricht. Danach wird das Handle des Fensters gespeichert in der dafür erstellten Liste Windows, gleich danach wird auchnoch der Name des Prozesses gesichert in der Liste Titles. Und anschließen rufen wir unsere importierte Funktion ShowWindow auf und übergeben das Handle des gewählten Fensters und den Befehl zum Verstecken!
So, nun können wir alle uns sichtbaren Fenster verstecken! Es fehlt also nur noch die Funktion um diese wieder sichtbar zu machen! Diese sieht den anderen beiden ziemlich ähnich:
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
Dim pl As Process() = _
Process.GetProcessesByName(ListBox2.Text)
For Each p As Process In pl
'Den gewählten Prozess anzeigen
ShowWindow(CLng(Windows(Titles.IndexOf(ListBox2.Text))), vbNormalFocus)
'Den gespeicherten Handle entfernen
Windows.RemoveAt(Titles.IndexOf(ListBox2.Text))
'Den gespeicherten Titel entfernen
Titles.RemoveAt(Titles.IndexOf(ListBox2.Text))
'Eintrag aus der Liste entfernen
ListBox2.Items.RemoveAt(ListBox2.SelectedIndex)
Next
'Liste aktualisieren
Button3_Click(Me, e)
End Sub
Hier suchen wir uns nicht erst alle Prozesse heraus sondern nehmen direkt den richtigen, da wir dessen Prozessnamen ja schon kennen (ListBox2). Und dann läuft das gleich Spielchen ab nur rückwärts. Erst machen wir das Fenster wieder sichtbar mit dem Handle aus der Liste Windows und dem Befehl vbNormalFocus. Dann läschen wir dieses Fenster aus allen Listen und auch aus unserer Liste mit den versteckten Fenstern!
Eine Anmerkung noch: Dieses Vorgehen versteckt ein Fenster vor dem benutzer! Dieser Prozess läuft weiterhin im Hintergrund und ist auch im TaskManager sichtbar! Wenn ihr auch diesen Austricksen wollt müsst ihr schon tiefer in die Trick-Kiste greifen, denn das geht nicht mehr so einfach, oder sogar garnicht, zumindest nicht mit einer Managed-Code Sprache wie VB.NET es eine ist!
Dieses DemoProjekt Herunterladen: hideprocessdemo
VB.NET: Lokale IP Adresse mit WMI bestimmen
Heute möchte ich euch zeigen, wie ihr mithilfe der WMI eure lokale IP Adresse bestimmen könnt. Diese Funktion fehlt leider noch in dem Aktuellem Framework. (Zum Thema WMI werde ich noch detailiertere Artikel schreiben!)
Fangen wir an. Das das nur ein kleines Demoprojekt ist, erstellen wir ein gewöhnliches Windows Forms Projekt. Die leere Form die es und gleich liefert ist auch schon alles was wir brauchen! Doppelklicken wir auf die Form um zum Code zu gelangen!
Ich möchte erstmal etwas über die WMI (Windows Management Instrumentation) sagen. Die WMI ist soetwas wie ein große Datenbank von allen Geräten, die in einem Computer verbaut sind, inklusive aller Infos wie Hersteller, Ports etc. Aber nicht nur das, man kann über die WMI soziemlich alle Einstellungen des Computers ändern! Also vorsicht dort kann man ziemlich viel Mist bauen!
Aber zurück zur Lokalen IP. Wie sovieles ist die Lokale IP auch in der WMI gespeichert, diese kann man auslesen, oder auch neu einstellen (was uns jetzt aber nicht interessiert!). Aber wo ist sie?
Imports System.Management
Public Class Form1
Function ShowIP() As String
Dim query As _
ManagementObjectSearcher = New ManagementObjectSearcher_
("SELECT * FROM Win32_NetworkAdapterConfiguration_
WHERE IPEnabled = True")
Dim queryCollection As ManagementObjectCollection = query.Get()
Dim IPAdress(1) As String
For Each mo As ManagementObject In queryCollection
IPAdress = mo.GetPropertyValue("IPAddress")
MessageBox.Show(IPAdress(0))
Next
End Function
End Class
So sieht unsere Funktion aus! Diese Funktion muss nurnoch im Form1_Load Ereignis aufgerufen werden. Überschaubar oder? Und auch überhaupt nicht kompliziert
Wie man sieht kann man die WMI ähnlich wie eine SQL Datenbank ansteuern. Man erstellt einen query vom Typ ManagementObjectSearcher dem man über seinen Konstruktor den SQL-Query zuweist! In diesem Fall möchten wir die Win32_NetworkAdapterConfiguration durchsuchen, macht ja auch Sinn wenn man die IP haben möchte oder? Undzwar picken wir uns nur die Netzwerkkarten raus, die auch aktiv sind und somit auch eine IP zugewiesen bekommen haben. Das sind nämlich die, die die Eigenschaft "IPEnabled" aktiviert haben!
Da wir als Antwort auf diesen Query mehr als nur einen Eintrag bekommen könnten müssen wir für das Ergebnis eine Collection anlegen. In diesem Fall eine ManagementObjectCollection. Diese Collection kann alle Management Objekte Speichern! Dieser weisen wir unseren Such-Query zu.
Die IP Adresse ist in jedem Netzwerkadapter in einem Ein-Dimensionalen Array gespeichert, weswegen wir eine entsprechende Variable anlegen, hier "IPAdress"!
Nun sprechen wir jede Netzwerkkarte an, die wir in unserer queryCollection haben und fragen deren IP Adresse ab. Diese Eigenschaft heißt, Übberraschug, "IPAdress". Das ManagementObject bietet und glücklicherweise die Funktion "GetPropertyValue" mit der wir jede Eigenschaft auslesen können, mit deren Hilfe können wir den IPAdress Array aus der WMI in unsere IPAdress Variable kopieren.
In diesem Array befindet sich die IPAdresse in dem ersten Feld. Dieses geben wir über die MessageBox aus!
Das wars auch schon nun kennen wir die lokalen IP Adressen von allen aktiven Netzwerkkarten! Zu dem Thema WMI werde ich noch öfter schreiben, unter anderem wie man in die WMI gelangt und sich mal umschauen kann und wie man die gespeicherten Informationen manipulieren kann!
Sicherheitsrisiko PHP Session ID
In letzter Zeit treffe ich wieder vermehrt auf Internetseiten, die die Session ID in der URL übergeben. Eigentlich dachte ich dieses Konzept ist langsam ausgestorben, aber anscheinend noch nicht. In diesem Beitrag möchte ich nochmal zeigen, was passierren kann wenn man die Session ID in der URL übergibt.
Neben den Cookies ist die PHP Session ID eins der wenigen Werkzeuge, die es dem Programmierer ermöglichen festzustellen, ob ein Benutzer eingeloggt ist oder nicht. Da Cookies oftmals in den Browsern deaktiviert sind bleibt nurnoch der Griff zur Session ID. Aber warum ist das gefährlich die ID in der URL anzugeben?
Eigentlich nichts! Zumindest solange man die Internetseite nicht verlässt. Wenn man zB. in einem Forum unterwegs ist, welches die ID in der URL übergibt und dieses Forum über einen Link der in irgendeinem post verlässt sendet man an automatisch die Referrer-Seite mit. Somit weis die Seite die ihr betretet automatisch wo ihr herkommt und da die Session ID auch in der URL steckt weis die Seite auch eure Session ID. Diese wird normalerweise auch in den Seitenstatistiken gespeichert!
Das gefährliche ist daran, dass wenn jemand an diesen Referrerlink von euch kommt und diesen aufruft ist er automatisch mit eurem Benutzer in diesem Forum eingeloggt! Und die Internetseite kann auch nicht unterscheiden, wer mit der Session ID unterwegs ist, denn es können auch ubegrenzt Benutzer mit einer Session ID auf der Internetseite unterwegs sein ohne dass der "original" Benutzer was davon mitkrigt.
Wenn ihr wisesn wollt welche Informationen von euch übertragen werden könnt ihr auf diesen link klicken und mal nachschauen.
LEider wenden immernoch sehr viele Seiten dieses Modell an. Ihr könnt es selbst ausprobieren in dem ihr bei Google einfach mal nach "inurl:phpsessionid" oder "inurl:phpsid" sucht. Hier ein paar traurige Beispiele:
Wie kann man sich schützen? Ganz einfach, als Programmierer sollte man die Session ID entweder per Mod Rewrite verstecken oder ein anderes Verfahren zur Benutzeranmeldung wählen. (Zu diesem Thema werde ich demnächst auch noch schreiben)
Als Benutzer sollte man sich immer vor dem Verlassen der Seite ausloggen, denn die Session ID bleibt solange gültig bis man sie Überschreibt oder löscht. Dies kann nur durch ein Logout oder durch einen erneuten Login erfolgen. Wenn man sich ausloggt, ist es auch egal, ob man vorher auf einen Link geklickt hat, denn die ID ist dann ungültig und wenn jemand dann sogar an eure ID kommt kann er damit nichts anfangen!
Wenn ihr also ne neue Internetseite erstellt auchtet darauf was ihr der öffentlichekit präsentiert, am besten so wenig wie möglich.
Java: Farbübergänge selbst erstellen
In diesem kleinen Beispiel möchte ich zeigen, wie man mit Java Farbübergänge der marke Eigenbau ertstellen kann. Klar, es gibt natürlich schon vorgefertigte Funktionen wie etwa GradientPaint() die einem genau das lefern was man braucht, aber ich wollte mal probieren selbst eine ähnliche Funktion zu basteln.
Alles wa wir brauchen ist ein Klasse die ein JFrame, also ein Fenster bereitstellt, auf dem wir zeichnen können. Wenn das Ereldigt ist plazieren wir noch einen Knopf (JButton) auf dem Formular in dessen Klick-Ereignis wir die Funktion aufrufen, die den Farbverlauf generiert.
Erstmal zum Verständnis: Wie funktioniert ein Farbverlauf? Eine Farbe setzt sich aus 3 Grundwerten zusammen: Rot, Grün und Blau. Die so genannten RGB-Werte aus diesen drei Farben kann man alle uns bekannten Farben zusammenmischen. Hier könnt ihr damit ein bisschen experementieren und mal verschiedene Farbwerte eingeben und gucken was rauskommt.
In HTM zum Beispiel werden Farben in der Hexadezimalen Schreibweise angegeben (zB. #2F13C4). In unserem Java Beispiel werden die zahlen in Dezimaler Schreibweise angegeben, diese können Werte von 0 - 255 enthalten. Diese Werte geben jeweils die Intensität der Farbe an. So ist zum Beispiel die Farbe Rot so deklariert: 255, 0, 0 - Der Rotanteil ist voll und die Grün und Blau Anteile leer. Somit erhalten wir ein leuchtendes Rot! Wenn man die nullen durch andere Zahlen ersetzt erhällt man weitere Farben. Die Farben Weiss und Schwarz sind die einfachsten: Weiss ist wenn alle drei Werte voll sind (255, 255, 255) und Schwarz das Gegenteil! (0, 0, 0)
Und so funktioniert auch ein Farbverlauf. Wenn man zB. einen Farbverlauf von Rot in Weiss haben möchte muss man ledeglich eine Schleife erstellen die für uns einen zB. waagerechten Streifen von Rot auf Weis Streicht. Sagen wir der Streifen soll 255 pixel breit und 100 Pixel hoch sein. Somuss man um einen Verlauf zu bekommen jeden Pixel der Rechts von dem Aktuellen liegt nur minimal anders färben.
Pixel 1: (255, 0, 0) Pixel 2: (255, 1, 1) Pixel 3: (255, 2, 2) usw.
Um etwas zeichnen zu können muss man ein Graphics-Objekt anlegen, welches uns die nötigen Funktionen bereitstellt. So würde unsere Funktion aussehen:
public void paintComponent(Graphics gr){
//Schleife sorgt dafür, dass der Übergang nach rechts erfolgt
for (int i = 0; i< 255; i++){
//Eine neue Farbe generieren
gr.setColor(new Color(255,i,i));
//Einen horizontalen Balken malen
gr.fillRect(i, 0, 1, 100);
}
}
Oben sehen Sie die Funktion, diese erwartet einen Parameter vom Typ Graphics, mit dem wir dann zeichnen können. Die Schleife fängt an und läuft 255 mal durch und macht unseren Übergang also 255 Pixel Breit.
In Zeile 8 wird dann eine Farbe generiert. Mit dem Operator new wird eine neue Instanz der Klasse Color erzeugt, die als Konstruktor 3 RGB-Werte erwartet. Der Erste Wert ist bei uns konstatnt 255 damit wir die Farbe rot bekommen. Die anderen beiden Werte (Grün und Blau) steigen dann zusammen mit i bis sie 255 erreichen.
In Zeile 10 wird dann schließlich Balken gemalt, der 100 Pixel hoch ist. die erten beiden Werte geben die Koordinaten (x,y) des anfangspunkts an. Die beiden anderen geben die Koordinaten (x,y) des Endpunkts an oder andres gesagt die Breite und Höhe.
Wenn wir die Balken zbB. breiter machen können die die Übergänge deutlicher sehen, und auch die einzelnen Balken sind nun besser erkänntlich.
Dieses vorgehen kann man nun veschieden Variieren um alle möglichen Übergänge zu erhalten!
Hier ist der Vollständige Code der Klasse:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
*
* @author Sebastian Gross // blog.bigbasti.com
*/
//Die Klasse erbt von JFrame also ist keine extra Instanz
//eines Fenster nötig.
public class Verlauf extends JFrame implements ActionListener {
private JButton knopp;
public Verlauf(String bName){
//Einen Knopf erstellen, mit dem wir das Zeichen
//Ereignis auslösen
knopp = new JButton(bName);
knopp.setBounds(50, 100, 150, 20);
//Unserem Fenster Namen und ein Layout zuweisen
this.setLayout(null);
this.setTitle(bName);
//Ruft die Funktion auf, die für das Anzeigen des
//Fensters sorgt
go();
}
public void actionPerformed(ActionEvent e) {
//Hier wird das Zeichnen Event ausgelößt
//und die PaintComponent Methode aufgerufen
paintComponent(this.getGraphics());
}
public void paintComponent(Graphics gr){
for (int i = 0; i< 255; i++){
gr.setColor(new Color(255,i,i));
gr.fillRect(i, 0, 3, 100);
}
}
public void go(){
//Dem Knopf einen ActionListener zuweisen
//in diesem Fall die Eigene Klasse da
//diese ja das Interface ActionListener
//implementiert
knopp.addActionListener(this);
//Den Konpf auf das Fenster setzen
this.getContentPane().add(knopp);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 600);
//Nachdem Größe und Schließverfahren
//eingestellt wurden das Fenster anzeigen:
this.setVisible(true);
}
public static void main(String[]args){
//Die Startmethode die lediglich eine Instanz
//von sich selbst erzeugt
Verlauf gui = new Verlauf("Hallo Welt!");
//Das Programm ist dann beendet, wenn der
//Benutzer auf das X im Fenster klickt
//Siehe Zeile 61
}
}
Auf die anderen Sachen werde ich hier nicht eingehen, da diese für dieses Beispiel uninteressant sind und auch anders gelößt werden können! Diese klasse könnt ihr direkt abspeichern und ausführen!
YouTube Ländersperre umgehen
Seit einiger Zeit hat YouTube auch Filme und Serien in sein Sortiment aufgenonnen, die kostenlos angeschaut werden können. Diese werden mit kurzen Werbeeinblendungen finanziert.
Dieser Dienst ist auch für Deutsche Besucher freigeschaltet allerdings können nicht alle Inhalte wiedergegeben werden. Versucht man zum Beispiel die Serie "Alf" zu öffnen, wird eine Fehlermeldung eingeblendet "This video is not available in your country."
Wie ich eben durch herumexperementieren herausgefunden habe, ist diese Sperre aber sehr leicht zu umgehen. Dazu benötigt man lediglich ein Kleines Tool, dass euch zu einem VPN in den USA verbindet. Zu empfehlen ist das Tool Hotspot Shield. Dieses Programm gibts es sowohl für Windows als auch für Mac, dazu ist es auch noch sehr leicht zu bedienen!
Ist es einmal gestartet genückt ein klick um sich mit dem Amerikanischen Netzwerk zu verbinden. Nun müssen wir nurnoch die gewünschte Episode aufrufen.
STOPP: Wie ihr sicher feststellen werdet arbeitet das System sehr langsam, weswegen sich dieser Dienst nicht zur Wiedergabe von solchen Inhalten anbietet.
Aber die YouTube Programmierer haben uns eine tolle Hilfe eingebaut, wennauch unfreiwillig, es wird nämlich das Land geprüft aus dem die Verbindung aufgebaut wird, aber nur einmal, und nur beim öffnen der Seite mit dem Stream!
Da heißt, ist die Seite einmal offen und man sieht den Flashplayer auf dem das video laufen soll muss man die VPN Verbindung beenden. Nun puffert Youtube das Video ganz normal über eure eigene schnelle Leitung und man kann das Video Ruckelfrei genießen!
Übrigens: das System funktioniert auch bei dem beliebten Dienst hulu.com, welches ebenfalls nur für Bürger der USA freigeschaltet ist!
Viel Spaß beim ausprobieren!
Tutorial: Windows Aero Glass in eigenen Projekten nutzen Teil 1
In dieser Demo möchte ich euch zeigen wie man die Aero Effekte von Windows Vista in eigenen Projekten nutzen kann. Dieses Vorgehen habe ich vor einiger Zeit in einem anderem Blog gelesen, weis leider nicht mehr in welchem. Dort wurde eine Möglichkeit beschrieben wie man es unter WPF macht. Ich möchte dies hier anhand eines Visual Basic.NET Projekts demonstrieren mit Verwendung des .NET Frameworks 3.5
Als erstes erstellt ihr ein neues Projekt für eine Windows Anwendung und fügt diesem Projekt eine neue Klasse hinzu. Diese Klasse habe ich hier "AeroForm" getauft.
Man könnte sich diese Klasse natürlich auch sparen und alles direkt in die Form integrieren, dann würde man aber die
Möglichkeit verlieren diese Funktionen auch in anderen Projekten zu benutzen. Also möchten wir diese Klasse möglichst Allgemein halten um den Wiederverwendungszweck zu steigern. Stichwort Polymorphie!
Aber nun zurück zu unserer neuen Klasse. Um die Übersichtlichkeit und die Lesbarkeit des Codes (für später) zu steigern erstellen wir erstmal einen Namespace "GlassCreator" mit unserer Klasse AeroForm.
Namespace GlassCreator Public Class AeroForm End Class End Namespace
Hier möchte ich kurz unser Vorgehen erläudern, wie wir das Fenster dazu bringen die Aero Transparenz zu "erlernen". Wir werden nichts anderes amchen, als die Ränder des Formulars in die Client-Oberfläche zu vergrößern (Siehe Bild)
Dazu benötigen wir die Funktion "DWMExtendFrameIntoClientArea" aus der Windows API, welche in der DLL "dwmapi.dll" zu finden ist. Diese müssen wir nun also importieren:
Namespace GlassCreator
Public Class AeroForm
<DllImport("dwmapi.dll", PreserveSig:=False)> _
Private Shared Sub DwmExtendFrameIntoClientArea_
(ByVal hwnd As IntPtr, _
ByRef margins As Integer)
End Sub
End Class
End Namespace
Wenn ihr euren Code nun erweitert habt werdet ihr feststellen, dass Visual Studio euch "DllImport" unterstreicht. Dies tut es weil wir die System.Runtime.InteropServices nicht importiert haben. Holen wir das also schnell nach:
Imports System.Runtime.InteropServices
Namespace GlassCreator
Public Class AeroForm
<DllImport("dwmapi.dll", PreserveSig:=False)> _
Private Shared Sub DwmExtendFrameIntoClientArea_
(ByVal hwnd As IntPtr, _
ByRef margins As Integer)
End Sub
End Class
End Namespace
Die frisch importierte Funktion benötigt zwei Parameter zum laufen, nämlich hwnd As IntPtr und ByRef margins As Integer. Wobei hwnd für das Handle des Fensters steht, auf welches die Aero Effekte angewendet werden sollen und margins für die neue Breite der Ränder des Fenstes!
Machen wir weiter. Erstellen wir die Funktion, die für uns später die Arbeit übernehmen wird. Diese ist sehr einfach aufgebaut:
Public Shared Function ExtendGlassFrame _
(ByVal hwnd As IntPtr, _
ByVal margin As Integer, _
ByVal clr As Color) As Boolean
System.Windows.Forms.Form.FromHandle(hwnd).BackColor = clr
AeroForm.DwmExtendFrameIntoClientArea(hwnd, margin)
Return True
End Function
Schauen wir uns diese Funktion mal etwas genauer an. Die Funktion, die ich "ExtendGlassFrame" getauft habe erwartet drei Parameter zum laufen. Die ersten zwei Parameter sind uns dabei schon aus dem Import von "DwmExtendFrameIntoClientArea" bekannt und haben sich nicht geändert! Der dritte Parameter "clr as Color" ist einfach nur die Farbe, die das Zielfenster später haben soll. Schließlich sehen wir, dass diese Funktion als "as Boolean" deklariert ist und einen Boolischen Wert zurückgeben wird. (Dies ist natürlich optional!)
Die Zeile 06 setzt die Farbe des Fensters, dessen Handle wir in der Variable hwnd bekommen auf die in clr übergebene Farbe.
Danach nutzen wir unsere importierte Funktion um die Ränder des Formulars zu vergrößern und übergeben die beiden benötigten Variablen!
Und am Ende geben wir noch den Wert "True" zurück um dem Aufrufer zu Zeigen, dass alles glatt gelaufen ist!
Damit wäre unsere Klasse auch schon fertig:
Imports System.Runtime.InteropServices
Namespace GlassCreator
Public Class AeroForm
_
Private Shared Sub DwmExtendFrameIntoClientArea _
(ByVal hwnd As IntPtr, _
ByRef margins As Integer)
End Sub
Public Shared Function ExtendGlassFrame(ByVal hwnd As IntPtr, _
ByVal margin As Integer, _
ByVal clr As Color) As Boolean
System.Windows.Forms.Form.FromHandle(hwnd).BackColor = clr
AeroForm.DwmExtendFrameIntoClientArea(hwnd, margin)
Return True
End Function
End Class
End Namespace
Kommen wir also zu dem Formular. Öffnen Sie die "Form1.vb" (Oder wie ihr es auch genannt habt) und erstellt einen neuen Button. Doppelklickt auf den Button damit Visual Studio für euch das Button1_Click Event erzeugt:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
End Sub
End Class
Hier müssen wir nurnoch die Funktion aus unserer frisch gebackenen Klasse aufrufen:
GlassCreator.AeroForm.ExtendGlassFrame(Me.Handle, _ 1, _ System.Drawing.SystemColors.ActiveCaptionText)
Der zweite Parameter "1" ist in diesem Fall völlig egal! Ihr könnt hier jede beliebige Integer Zahl wählen! Warum das so ist werde ich in dem 2ten Teil dieses Tutorials erklären!
Der Dritte Parameter (System.Drawing.SystemColors.ActiveCaptionText) ist ¸brigens die Farbe, die unser Fenster haben soll. ActiveCaptionText heiflt nur, dass das Fenster die aktuelle Standardfarbe der Fenster bekommen soll. Hier hätten wir auch jede beliebige andere Farbe nehmen können! (Siehe Unten)
Und das Wars auch schon:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
GlassCreator.AeroForm.ExtendGlassFrame(Me.Handle, _
1, _
System.Drawing.SystemColors.ActiveCaptionText)
End Sub
End Class
Starten wir nun das Programm und klicken auf den Button erhalten wir ein Glasklares Fenster in Aero Optik!
![]()
Übrigens, wenn wir als Farbe System.Drawing.Color.DeepPink ¸bergeben färbt sich die Clientoberfläche in Pink.
Ihr Könnt auch jede andere Farbe aus dem System.Drawing.Color.* Sortiment aussuchen.
Soviel zu dem ersten Teil dieses Tutorials. In dem Zweiten werde ich euch zeigen, wie Ihr Detailierter an die Sache
geht und weitere Möglichkeiten zeigen um jeden Rand persönlich anzusprechen. Und man kann auch fremde Fenster mit der Aero-Optik schmücken!
Bitte gebt mir Feedback damit ich die nächsten Tutorials besser und/oder verständlicher gestalten kann!
Ihr könnt euch dieses Demo-Projekt auch schon fertig runterladen: Dieses Demo Projekt herunterladen
Umstieg von Sony Vaio auf Apple Macbook
Seid nun mehr als einem Jahr hatte ich ein Notebook von Sony aus der FZ Serie mit integriertem Blu-Ray Player und co. Ein wirklich super Gerät sowohl vom Design als auch von der Leistung.
Doch irgendwie habe ich mich doch in die neuen Aluminium Macbooks von Apple verguckt, die von der Hardware sogar noch besser waren/sind als die aktuellen Sony Modelle in der Gleich Preisklasse. Als dann ein Bekannter von mir sich das 13" Modell zugelegt hat konnte ich mich auch nicht mehr bremsen.
Die KO-Argumente waren aber die geringe Größe, das geringe Gewicht und die enorm lange Akkulaufzeit von durchschnittlich mehr als 3 Stunden. Mein Vaio wiegt ca 1 KG mehr, viel Klumpiger und schafft wenn er gute Laune hat grade mal 2 Stunden.
Als Softwareentwickler war es mir auch wichtig, dass Windows vernünftig läuft, und auch dieser Umstand war dank Bootcamp gegeben, sodass ich alle meine Windows Programme wie Visual Studio weiterhin ohne Einschränkungen nutzen konnte!
Das einzige was mich bis Dato nervt ist, dass das Macbook nur 2 USB-Ports hat (die leider auch noch sehr nah an einander angebracht sind) und nur ein Mini Display Port für den man dann noch Adapter kaufen muss die jeweils 30 Euro kosten, eine Frechheit! Aber das Argument, dass man das auf Grund der geringen Größe nicht anders machen konnte lass ich nochmal durchgehen! Was mich auch noch fehlt ist der HDMI-Stecker den ich an meinem Vaio sehr sehr Lib gewonnen habe! Aber vieleicht kommt das ja noch.
Ansonsten ist es wie jedes andere Notebook auch, nur gewöhnt man sich einfach viel zu schnell an die Beleuchtete Tastatur und an den angenehmen Druckpunkt und auch an das Glossy Display, dass wirklich sehr stark Spiegelt!
Soweit erstmal dazu. Ein Beitrag über die vielen kleinen Dinge die einen an Mac OS stören werde ich nachher noch zusammenfassen.
Vorsicht: Billiganbieter
Vor kurzer Zeit habe ich mir zu Testzwecken einen vServer gemietet, welcher mit Windows lief. Natürlich habe ich mich vorher erkundigt welche Anbieter wohl empfehlenswert sind und die die Preis/Leistung bei denen ist.
Zu meinem Erstaunen musste ich feststellen, dass es eine enorme Preisspanne zwischen den Ganzen Anbietern gibt, sogar mit Windows Server als Betriebssystem. Es gibt Anbieter die fangen schon bei 8 Eur an und welche die erst ab 20 Euro bereit sind einen vServer mit Windows ab zudrücken. (Bei ähnlicher Hardware versteht sich!)
Da ich in den Bereich erst einstieg entschied ich mich für einen günstigen Anbieter. Dieser Anbieter lockte vorallem damit, dass man monatlich kündigen konnte.
Nach der Bestellung dauerte es nur knapp 2 Tage bis ich meine Zugangsdaten und die Server IP hatte. Alles verlief zu meiner Überraschung problemlos und sauber. - Auch die Administrations Oberfläche von Parallels machte einen sehr guten Eindruck und der vServer war auch problemlos über die Windows Remote Verbindung erreichbar und bedienbar.
Die Anbindung war auch mehr als gut mit einem Downstream von knapp 12 MB/s und einem Upstream von 4 MB/s.
Nach mehreren Wochen habe ich die Konfiguration größtenteils fertig gestellt, sodass alle Dienste, FTP-Zugänge und Benutzerkonten stabil liefen - als dann plötzlich eine Überraschung kam.
Von einer Minute auf die Andere war der Server aus und ich konnte weder über die Parallels Administration als auch über die Windows Remote Desktop Verbindung einen Kontakt zum Server Herstellen.
Sofort schrieb ich eine Mail an den Support, der mir dann auch innerhalb von 2 Stunden!? antwortete, dass meine Rechnung nicht bezahlt sei. Ich dachte mir platzt der Kragen, denn ich war mir zu 100% sicher, dass ich bei der Registrierung die Bezahlung per Lastschriftverfahren eingestellt habe, was mir ein Blick in meine Unterlagen auch bestätigte.
Nach einer erneuten Mail in der ich die Lage Beschrieben hatte und den Zugriff auf den Server wieder einforderte habe ich umsonst 2 Tage gewartet, denn nichts kam. - Kurz darauf habe ich mein Abo wieder gekündigt und noch eine Beschwerde Mail vonmir gegeben - welche natürlich (welche Überraschung) auch unbeantwortet blieb!
Das Geld für diesen und auch für den nächsten Monat!! wurde dann 1 Monat später von meinem Konto gebucht, obwohl ich nur einen Monat lang drauf Zugriff hatte. Eine weitere Beschwerdemail blieb wieder unbeantwortet.
Nach diesem Langen Hin und Her habe ich mir versprochen beim nächsten Mal lieber 5 Euro mehr zu investieren, dafür dann aber vernünftigen Support zu erhalten. Aber dennoch hat sich das ganze gelohnt, denn nur aus Fehlern kann man ja bekanntlich lernen!
Hallo Welt!
Hallo und willkommen zu meinem Neuen Blog.
Hier möchte ich euch einfach nur an meiner Arbeit, Problemen und/oder Fragen teilhaben lassen und einfach über (aus meiner Sicht) interessantes schreiben!
Danke und Viel Spaß!


