DCSIMG
March 2010 - Posts - Arik Poznanski's Blog

Arik Poznanski's Blog

It CAN be done with .NET

News

MVP

MCC

CodeProject MVP

MCPD

MCTS

Subscribe to my blog by email

Arik Poznanski LinkedIn Profile

Email: arik.com at gmail dot com
or, use this form

Locations of visitors to this page


Sela Group

Sela Canada

DZone MVB

Links

Official Blogs

WPF / SL Blogs

Developers Blogs

March 2010 - Posts

Developer Academy 4: My Summary

Today I’ve attended Developer Academy 4.
Following is my impression on this event.

The opening keynotes where presented by several people, each one presented one topic: Guy Burstein (Visual Studio 2010), Brad Abrams (Silverlight 4) and Eliaz Tobias (Windows Azure).
As always, Guy’s presentation was very good and fun to watch.

I missed the morning sessions because I had a 3 hours session as a Windows 7 expert in “Meet the Experts”.
It was an interesting experience and the people who came really challenged me.

After lunch I’ve attended Maor David-Pur session, “Introduction to Cloud Computing & Windows Azure Platform”. Maor explained very simply what is Windows Azure and how us developers can use it when building systems. Although it was a rough time (right after lunch) Maor made it very interesting.

Afterwards I’ve attended Pavel Yosifovich session “.Net Framework 4: What’s new in the Base Class Library and the CLR ? “. Pavel had a great demonstration about: Hosting different CLRs side by side, a long waited feature for every .NET/COM developer out there (all three of us), type embedding, improvements to the GC, AppDomain monitoring and a very good introduction to MEF.

Last session was by David Sackstein, “Capture the Windows 7 User Experience with Windows Presentation Foundation 4”, a short introduction to windows 7 features available with WPF 4.

I cannot finish this post without mentioning Sela’s dominant attendance in the conference. 6 speakers in the sessions, 5 experts in “Meet the Experts” and dozens of participants. Well done guys.

All in all, the conference was very good and I look forward to the next Microsoft conferences.

That’s it for now,
Arik Poznanski.

Windows 7 Libraries C# Quick Reference

Following are some listings to be used as a quick reference to common Windows 7 Libraries features using Windows API Code Pack.

The code in this post is based on previous work by Alon and other Sela team members. Great work all.

Forward

Just to clarify the terminology used:
Every Windows 7 library is represented as an XML file with the .library-ms extension.
The common libraries files are commonly stored in: C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Libraries\

So if, for example, we work now with the Pictures library, than in the following sections:
libraryName = Pictures
locationPath = C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Libraries\

Note: you can create library files wherever you want, not necessarily in the mentioned folder.

Features

Creating a new library

ShellLibrary shellLibrary =
    new ShellLibrary(libraryName, locationPath, overwriteExisting);

Add folder to an existing library

using (ShellLibrary shellLibrary =
    ShellLibrary.Load(libraryName, folderPath, isReadOnly))
{
    shellLibrary.Add(folderToAdd);
}

Remove folder from a library

using (ShellLibrary shellLibrary =
    ShellLibrary.Load(libraryName, folderPath, isReadOnly))
{
    shellLibrary.Remove(folderToRemove);
}

Enumerate library folders

using (ShellLibrary shellLibrary =
    ShellLibrary.Load(libraryName, folderPath, isReadOnly))
{
    foreach (ShellFileSystemFolder folder in shellLibrary)
    {
        Debug.WriteLine(folder.Path);
    }
}

Change default save location

using (ShellLibrary shellLibrary =
    ShellLibrary.Load(libraryName, folderPath, isReadOnly))
{
    shellLibrary.DefaultSaveFolder = newSaveLocation;
}

Change library icon

using (ShellLibrary shellLibrary =
    ShellLibrary.Load(libraryName, folderPath, isReadOnly))
{
    shellLibrary.IconResourceId = new IconReference(moduleName, resourceId);
}

Pin library to explorer navigation pane

using (ShellLibrary shellLibrary =
    ShellLibrary.Load(libraryName, folderPath, isReadOnly))
{
    shellLibrary.IsPinnedToNavigationPane = true;
}

Setting library type

using (ShellLibrary shellLibrary =
    ShellLibrary.Load(libraryName, folderPath, isReadOnly))
{
    shellLibrary.LibraryType = libraryType;
    
    // libraryType can be:
    //  LibraryFolderType.Generic
    //  LibraryFolderType.Documents
    //  LibraryFolderType.Music
    //  LibraryFolderType.Pictures
    //  LibraryFolderType.Videos
}

Open library manage UI

ShellLibrary.ShowManageLibraryUI(
    libraryName, folderPath, hOwnerWnd, title, instruction, allowNonIndexableLocations);

Delete library

string FileExtension = ".library-ms";

File.Delete(Path.Combine(folderPath,libraryName + FileExtension));

Get library change notification

string FileExtension = ".library-ms";

FileSystemWatcher libraryWatcher = new FileSystemWatcher(folderPath);
libraryWatcher.NotifyFilter = NotifyFilters.LastWrite;
libraryWatcher.Filter = libraryName + FileExtension;
libraryWatcher.IncludeSubdirectories = false;

libraryWatcher.Changed += (s, e) =>
{
    //cross thread call
    this.Dispatcher.Invoke(new Action(() =>
        {
            using (ShellLibrary shellLibrary =
                ShellLibrary.Load(libraryName, folderPath, isReadOnly))
            {
                // get changed information
                ...
            }
        }));
};
libraryWatcher.EnableRaisingEvents = true;

That’s it for now,
Arik Poznanski.

kick it on DotNetKicks.com Shout it

Windows 7 Taskbar C# Quick Reference

Following are some listings to be used as a quick reference to common Windows 7 Taskbar features using Windows API Code Pack.

The code in this post is based on previous work by Yochay and Sasha.

Features

Setting the process Application ID

TaskbarManager.Instance.ApplicationId = "TaskbarManaged";

Note: This should be done before the window is shown, a good place is on form load.

Setting the Application ID of a window

TaskbarManager.Instance.SetApplicationIdForSpecificWindow(form.Handle, "SomethingElse");

or in WPF:

TaskbarManager.Instance.SetApplicationIdForSpecificWindow(wpfWindow, "SomethingElse");

Adding a file into the Recent category on the JumpList

 _jumpList = JumpList.CreateJumpList();

 ...

 _jumpList.AddToRecent(filePath);

Note: You must register (associate) the file type with your application for this to work.
Note 2: If you use the common dialogs to open a file it will get added automatically to the recent list.

Adding tasks to the JumpList

IJumpListTask task1 = new JumpListLink(filePath, taskTitle)
{
    Arguments = arguments,
    WorkingDirectory = workingDirectory
};

IJumpListTask separator = new JumpListSeparator();
IJumpListTask task2 = ...

_jumpList.AddUserTasks(task1, separator, task2);
_jumpList.Refresh();

Adding custom categories

JumpListCustomCategory category = new JumpListCustomCategory("My Category");
_jumpList.AddCustomCategories(category);

IJumpListItem item1 = new JumpListLink(path1, title1);
IJumpListItem item2 = new JumpListLink(path2, title2);

category.AddJumpListItems(item1, item2);

Creating Thumbnail Toolbars

 

ThumbnailToolbarButton button1 = new ThumbnailToolbarButton(icon, tooltip);
button1.Click += delegate
{
    MessageBox.Show("button1 clicked");
};

TaskbarManager.Instance.ThumbnailToolbars.AddButtons(form.Handle, button1);

 

Setting Overlay Icon

TaskbarManager.Instance.SetOverlayIcon(icon, accessibilityText);

Setting Progress State and Value

TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal, form.Handle);
TaskbarManager.Instance.SetProgressValue(currentValue, maximumValue, form.Handle);

Customizing Live Thumbnail

TabbedThumbnail preview = new TabbedThumbnail(parentForm.Handle, childForm.Handle);
TaskbarManager.Instance.TabbedThumbnail.AddThumbnailPreview(preview);
preview.TabbedThumbnailBitmapRequested += (o, e) =>
    {
        Bitmap bmp = new Bitmap(width, height);
        
        // draw custom bitmap...
        
        e.SetImage(bmp);
        e.Handled = true;
    };

Extra Notes

A drawback in Windows API Code Pack v1.0.1

When using the Windows API Code Pack library to add Taskbar features to your WinForms application you must add a references to the following WPF DLLs: PresentationCore.dll, PresentationFramework and WindowsBase.dll

The reason is that every Taskbar function in the library that has an handle in its arguments comes in pair, the first expects a native IntPtr (used with myWinForm.Handle property) and the second expects a WPF Window object. Since we use a class that expects WPF types in its arguments (Taskbar) we must add the WPF DLLs to our WinForms project.

A Bug in Windows API Code Pack v1.0.1

ThumbnailToolbarButton Click event isn’t fired when process is running elevated (i.e. as Administrator)

The problem is that some of the taskbar messages doesn’t pass thru the Windows UIPI mechanism.
A quick fix is to add the following line to the load event:

 

private void Form_Load(object sender, EventArgs eventargs)
{
    AllowTaskbarWindowMessagesThroughUIPI();
}

 

The definition of this method is brought here:

#region Fix bug in Windows API Code Pack

[DllImport("user32.dll", EntryPoint = "RegisterWindowMessage", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern uint RegisterWindowMessage([MarshalAs(UnmanagedType.LPWStr)] string lpString);

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr ChangeWindowMessageFilter(uint message, uint dwFlag);

private const uint MSGFLT_ADD = 1;
private const uint WM_COMMAND = 0x0111;
private const uint WM_SYSCOMMAND = 0x112;
private const uint WM_ACTIVATE = 0x0006;

/// <summary>
/// Specifies that the taskbar-related windows messages should
/// pass through the Windows UIPI mechanism even if the process is
/// running elevated. Calling this method is not required unless the
/// process is running elevated.
/// </summary>
private static void AllowTaskbarWindowMessagesThroughUIPI()
{
    uint WM_TaskbarButtonCreated = RegisterWindowMessage("TaskbarButtonCreated");

    ChangeWindowMessageFilter(WM_TaskbarButtonCreated, MSGFLT_ADD);
    ChangeWindowMessageFilter(WM_COMMAND, MSGFLT_ADD);
    ChangeWindowMessageFilter(WM_SYSCOMMAND, MSGFLT_ADD);
    ChangeWindowMessageFilter(WM_ACTIVATE, MSGFLT_ADD);
}

#endregion Fix bug in Windows API Code Pack

That’s it for now,
Arik Poznanski.

kick it on DotNetKicks.com Shout it