In diesem kleinen Tutorial zum Windows API Code Pack werden wir uns näher mit den Shell-Interfaces zu Ordnern und Dateien in der Windows API auseinandersetzen.

Der grobe Aufbau der betreffenden Klassen im Windows API Code Pack schaut folgendermaßen aus:

Aufbau der Shell-Klassen

Wichtig für das Tutorial sind eigentlich nur ShellFileSystemFolder für die Ordner und ShellFile für die Dateien. ShellLibrary haben wir bereits im vorherigen Tutorial verwendet.

 

Eigenschaften

Zugriff auf die Eigenschaften einer Datei oder eines Ordners ermöglicht die Properties-Eigenschaft des ShellObjects. Unter System finden sich alle möglichen Eigenschaften, die eine Datei besitzen kann, der Zugriff kann über zwei Varianten erfolgen:

// Entweder so:
var p = file.Properties.System.Title;

// Oder über den Namen der Eigenschaft:
var p2 = file.Properties.GetProperty<string>("System.Title");

Beide Male wird ein ShellProperty-Objekt zurückgeliefert. Den eigentlichen Inhalt der Dateieigenschaft erhalten wir schließlich über Value:

string title = file.Properties.System.Title.Value;

Darüber hinaus können wir uns natürlich auch mit LINQ bestimmte Dateien zurückliefern lassen. Um zum Beispiel um alle Dateien eines Ordners zu erhalten, die das Schlüsselwort bzw. die Markierung “Visual Studio 2010” enthalten genügt die folgende LINQ-Abfrage:

var files =
    from f in ShellFileSystemFolder.FromFolderPath(@"C:\Folder\")
    let k = f.Properties.System.Keywords.Value ?? Enumerable.Empty<string>()
    where k.Contains("Visual Studio 2010")
    select f;

foreach (var file in files)
    Console.WriteLine(file.Name);

k enthält dabei entweder den String-Array von f.Properties.System.Keywords.Value, oder, falls die Eigenschaft bei der Datei nicht gesetzt wurde und null zurückgeliefert wird, eine leere String-Auflistung IEnumerable<string>.

Vorschaubilder

Das Windows API Code Pack bietet eine komfortable Möglichkeit auf die Vorschaubilder von Ordnern und Dateien, die man unter anderem vom Windows Explorer, zu zugreifen und das sowohl als System.Drawing.Bitmap, als auch als System.Windows.Media.Imaging.BitmapSource für WPF-Anwendungen. Die Einbindung in ein WPF-Image ist dementsprechend einfach.

Die Bilder stehen unter der Eigenschaft Thumbnail in den vier Größen Small, Medium, Large, ExtraLarge zur Verfügung.

<Image Source="{Binding Path=SelectedItem.Thumbnail.MediumBitmapSource}" />

Eine Verwendung in einer Anwendung könnte z. B. folgendermaßen ausschauen:

Beispielanwendung

, ,

Windows 7 LibrariesMit dem neuen Betriebssystem Windows 7 hat Microsoft die Libraries eingeführt, die Dateien aus unterschiedlichen Ordnern zusammenfassen können.

Die Beschreibungen dieser Libraries liegen im Verzeichnis …\AppData\Roaming\Microsoft\Windows\
Libraries als XML-Dateien mit der Endung .ms-library
vor.

Für den Umgang mit den Libraries hat Microsoft der Windows Shell einige neue Interfaces spendiert. Damit .Net-Entwickler nicht leer ausgehen hat man darüberhinaus das Windows API Code Pack ins Leben gerufen, einen .Net-Wrapper, der neben den Windows 7-Neuerungen (Libraries, Jump Lists, etc.) auch DirectX 10.0/10.1/11.0, Direct2D, DirectWrite und zahlreiche andere APIs umfasst.

Arbeiten mit Libraries

Für den Einsatz der Libraries muss lediglich Microsoft.WindowsAPICodePack.Shell als Referenz zum Projekt hinzugefügt werden.

Dreh- und Angelpunkt ist die Klasse ShellLibrary, die alles nötige zum Erstellen, Laden und Bearbeiten von Libraries bereitstellt.

Libraries laden

Zum Laden steht die Load-Methode zur Verfügung, die entweder den Namen oder ein IKnownFolder-Objekt erwartet. Mehr zu Known Folders: http://msdn.microsoft.com/en-us/library/bb776911(VS.85).aspx. KnownFolders enthält eine Auflistung dieser besonderen Ordner, zu denen auch die 4 Standard-Libraries gehören. Um also die Video-Bibliothek zu laden, reicht folgende Zeile. Mit dem 2. Parameter können wir dabei festlegen, ob wir die Library verändern, z. B. neue Ordner hinzufügen oder alte entfernen, wollen.

ShellLibrary lib = ShellLibrary.Load(KnownFolders.VideosLibrary, true);

Libraries auslesen

Wir haben nun vollen Zugriff auf die Library und können z. B. alle Ordner der Library auslesen:

foreach (ShellFolder dir in lib)
    Console.WriteLine(dir.ParsingName);

Libraries bearbeiten

Neben dem bloßen Auslesen können wir der Library auch neue Ordner spendieren, oder bisherige entfernen. Dabei ist zu beachten, dass die Library zuvor auch mit der entsprechenden Einstellung geladen werden musste. Der zweite Parameter der Load-Methode musste also den Wert false besitzen.

// Ordner hinzufügen
lib.Add("D:/test/");

// Ordner entfernen
lib.Remove("D:/test/");

Last but not least, lässt sich sogar der vom Explorer bekannte Dialog ins eigene Programm einbinden:

ShellLibrary.ShowManageLibraryUI(
    lib.Name,
    IntPtr.Zero,
    "Hi there",
    "Ok, let's add some stuff",
    true
    );

win7_libs_002 Mit dem ersten Parameter geben wir den Namen der Library an, mit der der Dialog hantieren soll, es folgt der Handler des Elternfensters, als drittes der Titel des Dialogs und schließlich der Beschreibungstext. Der Dialog liefert keinerlei Informationen über die vom Benutzer getätigten Änderungen zurück.

Libraries können für eine bestimmte Anzeige optimiert werden. Vier verschiedene stehen zur Auswahl: Dokumente, Musik, Bilder und Videos. Diese Anzeigeart lässt sich über die Eigenschaft LibraryType steuern:

lib.LibraryType = LibraryFolderType.Music;

Das Icon der Library lässt sich über IconResourceId ansprechen:

// Nutze das gleiche Icon wie die Musik-Library
lib.IconResourceId = new IconReference("imageres.dll", -1004);

Libraries erstellen

Für die Erstellung neuer Libraries kann man einfach auf den Konstruktor der ShellLibrary-Klasse zurückgreifen:

ShellLibrary test = new ShellLibrary("MyLib", false);

// Soll Musik enthalten
test.LibraryType = LibraryFolderType.Music;

Dateien auslesen

Um schließlich alle Dateien einer Library aufzulisten müssen wir uns eine eigene Methode schreiben, die alle Unterordner rekursiv durchläuft. In etwa so:

List<ShellFile> files = new List<ShellFile>();

foreach (ShellFolder dir in lib)
    GetAllFiles(dir, files);

// ...

void GetAllFiles(ShellFolder parent, List<ShellFile> files)
{
    foreach (ShellObject obj in parent)
    {
        // Check if it's a file
        ShellFile file = obj as ShellFile;
        if (file != null)
        {
            files.Add(file);
        }

        // Check if it is a folder
        ShellFolder folder = obj as ShellFolder;
        if (folder != null)
        {
            GetAllFiles(folder, files);
        }
    }
}

Ende

Fragen, Erweiterungsvorschläge, Kritik etc. können in den Kommentaren geäußert werden.

, ,

In diesem kleinen Artikel soll beschrieben werden, wie man LINQ im Zusammenhang mit dem Datenbanksystem MySQL einsetzt.

Read the rest of this entry

, , , ,

Der Artikel ist nun auf XNA.mag zu finden:
http://www.xnamag.de/article.php?aid=15

, , , ,

Der Artikel ist nun auf XNA.mag zu finden:
http://www.xnamag.de/article.php?aid=48

, , , ,

geckofxDa das Webbrowser-Control bekanntermaßen ein Wrapper für den Internet Explorer ist, man diesen unter Umständen aber nicht unbedingt nutzen möchte, würde sich als Alternative ein Webbrowser-Control anbieten, welches Mozillas Gecko-Engine unterstützt, die unter anderem auch vom Firefox verwendet wird. Ein solches Control, was die Nutzung der Gecko-Engine in WinForms-Anwendungen ermöglicht, ist GeckoFx.

GeckoFx

geckofx – Google Code Seite

Die Nutzung gestaltet sich relativ einfach. Ein wenig Umständlich ist lediglich, dass das Control unbedingt den XulRunner benötigt (den ich bei mir, auf Grund einiger Xul-Tests, allerdings schon auf der Platte hatte). Der folgende Code zeigt, wie man eine Webseite seiner Wahl mit dem Control anzeigt.

public partial class Form1 : Form
{
    private GeckoWebBrowser browser = null;

    public Form1()
    {
        InitializeComponent();

        Xpcom.Initialize(@"C:Programmexulrunner");
        browser = new GeckoWebBrowser();
        browser.Location = new Point(20, 20);
        browser.Width = 500;
        browser.Height = 500;
        Controls.Add(browser);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Show();
        browser.Navigate("http://www.xnamag.de");
    }
}
, , ,

Der Artikel ist nun auf XNA.mag zu finden:
http://www.xnamag.de/article.php?aid=47

, , ,

Der Artikel ist nun auf XNA.mag zu finden:
http://www.xnamag.de/article.php?aid=46

, , ,