March 2010 - Posts
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.
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.
CodeProject
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.
CodeProject