Microsoft KB Archive/830033

= How to apply Windows XP themes to Office COM add-ins =

Article ID: 830033

Article Last Modified on 5/16/2007

-

APPLIES TO


 * Microsoft Office Basic 2007
 * Microsoft Office Basic Edition 2003
 * Microsoft Office Professional 2007
 * Microsoft Office Professional Edition 2003
 * Microsoft Office Small Business 2007
 * Microsoft Office Small Business Edition 2003
 * Microsoft Office Standard 2007
 * Microsoft Office Standard Edition 2003
 * Microsoft Office Home and Student 2007
 * Microsoft Office Student and Teacher Edition 2003
 * Microsoft Office Access 2007
 * Microsoft Office Access 2003
 * Microsoft Office Excel 2007
 * Microsoft Office Excel 2003
 * Microsoft Office FrontPage 2003
 * Microsoft Office Outlook 2007
 * Microsoft Office Outlook 2003
 * Microsoft Office PowerPoint 2007
 * Microsoft Office PowerPoint 2003
 * Microsoft Office Project Professional 2007
 * Microsoft Office Project Professional 2003
 * Microsoft Office Project Standard 2007
 * Microsoft Office Project Standard 2003
 * Microsoft Office Publisher 2007
 * Microsoft Office Publisher 2003
 * Microsoft Office Visio Professional 2007
 * Microsoft Office Visio Professional 2003
 * Microsoft Office Visio Standard 2007
 * Microsoft Office Visio Standard 2003
 * Microsoft Office Word 2007
 * Microsoft Office Word 2003

-





SUMMARY
When you create a COM add-in for a Microsoft Office program (for example, Microsoft Visio), the appearance of that add-in will conform by default to the standard Office appearance. However, with Microsoft Windows XP, you can choose from a number of visual styles (or themes) to customize the appearance of a Microsoft Windows program.

Unless Windows themes are explicitly enabled for a COM add-in, the appearance of the add-in does not change with these color schemes, leading the add-in to appear dated or out-of-synch with the program where it is contained. With the Microsoft Visual C++ or the Microsoft Visual Studio .NET languages, you can enable your COM add-in to opt-in to Windows themes.

When you enable an add-in for Windows themes, the themes affect only the appearance of the add-in. The functionality of the add-in is not affected.

Disclaimer
Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure. However, they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.

Microsoft Visual Basic 6.0
Visual Basic 6.0 does not support themes. Add-ins cannot be themed by using Visual Basic 6.0.

Microsoft Visual C++ 6.0
To use Visual C++ 6.0 to enable a COM add-in to opt-in to Windows XP themes, follow these steps:   Create a manifest file that contains the following information. Customize the information for your specific add-in:     My Office Addin built with .Net      Do one of the following:   Include the following preprocessor instruction:  Compile with: /D ISOLATION_AWARE_ENABLED </li></ul> </li>  Add the manifest file to your resource file, as in the following example: ISOLATIONAWARE_MANIFEST_RESOURCE_ID RT_MANIFEST &quot;mydllname.dl.manifest&quot; </li></ol>
 * 1) define ISOLATION_AWARE_ENABLED </li>
 * 1) include &quot;windows.h&quot;

Microsoft Visual Studio .NET and Managed Languages
To use Visual Studio .NET and the .NET Framework to enable Windows XP themes for a COM add-in, follow these steps.

Note In this example, C# is used to enable a themed activation context on a Windows form. Also, for Windows themes to be enabled for buttons, check boxes, radio buttons, and group boxes, the FlatStyle property of those objects must be set to System. <ol>  Include the following information in a .cs file. Customize the information for your specific add-in: using System.Runtime.InteropServices; using System; using System.Security; using System.Security.Permissions; using System.Collections; using System.IO; using System.Text; using System.Windows.Forms;

namespace MyOfficeNetAddin {   ///     ///     This class is intended to use with the C# 'using' statement in    ///     to activate an activation context for turning on visual theming at    ///     the beginning of a scope, and have it automatically deactivated ///    when the scope is exited. ///

[ SuppressUnmanagedCodeSecurity ] internal class EnableThemingInScope : IDisposable {  // Private data private uint cookie; private static ACTCTX enableThemingActivationContext; private static IntPtr hActCtx; private static bool contextCreationSucceeded = false;

public EnableThemingInScope(bool enable) {  cookie = 0; if (enable && OSFeature.Feature.IsPresent(OSFeature.Themes)) {   if (EnsureActivateContextCreated) {    if (!ActivateActCtx(hActCtx, out cookie)) {        // Be sure cookie always zero if activation failed cookie = 0; }   }   }  }

~EnableThemingInScope {  Dispose(false); }

void IDisposable.Dispose {  Dispose(true); }

private void Dispose(bool disposing) {  if (cookie != 0) {   if (DeactivateActCtx(0, cookie)) {      // deactivation succeeded... cookie = 0; }  }  }

private bool EnsureActivateContextCreated {  lock (typeof(EnableThemingInScope)) {   if (!contextCreationSucceeded) {    // Pull manifest from the .NET Framework install // directory

string assemblyLoc = null; FileIOPermission fiop = new FileIOPermission(PermissionState.None); fiop.AllFiles = FileIOPermissionAccess.PathDiscovery; fiop.Assert; try {     assemblyLoc = typeof(Object).Assembly.Location; }    finally {      CodeAccessPermission.RevertAssert; }

string manifestLoc = null; string installDir = null; if (assemblyLoc != null) {     installDir = Path.GetDirectoryName(assemblyLoc); const string manifestName = &quot;XPThemes.manifest&quot;; manifestLoc = Path.Combine(installDir, manifestName); }

if (manifestLoc != null && installDir != null) {     enableThemingActivationContext = new ACTCTX; enableThemingActivationContext.cbSize = Marshal.SizeOf(typeof(ACTCTX)); enableThemingActivationContext.lpSource = manifestLoc;

// Set the lpAssemblyDirectory to the install // directory to prevent Win32 Side by Side from // looking for comctl32 in the application // directory, which could cause a bogus dll to be     // placed there and open a security hole. enableThemingActivationContext.lpAssemblyDirectory = installDir; enableThemingActivationContext.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID; // Note this will fail gracefully if file specified // by manifestLoc doesn't exist. hActCtx = CreateActCtx(ref enableThemingActivationContext); contextCreationSucceeded = (hActCtx != new IntPtr(-1)); }   }

// If we return false, we'll try again on the next call into // EnsureActivateContextCreated, which is fine. return contextCreationSucceeded; } }

// All the pinvoke goo... [DllImport(&quot;Kernel32.dll&quot;)] private extern static IntPtr CreateActCtx(ref ACTCTX actctx); [DllImport(&quot;Kernel32.dll&quot;)] private extern static bool ActivateActCtx(IntPtr hActCtx, out uint lpCookie); [DllImport(&quot;Kernel32.dll&quot;)] private extern static bool DeactivateActCtx(uint dwFlags, uint lpCookie);

private const int ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004; private struct ACTCTX {  public int       cbSize; public uint     dwFlags; public string   lpSource; public ushort   wProcessorArchitecture; public ushort   wLangId; public string   lpAssemblyDirectory; public string   lpResourceName; public string   lpApplicationName; } } } </li>  Create your form with the following wrapper. This procedure pushes a themed activation context before creating any controls: using( new EnableThemingInScope( true ) ) { Form1 form1 = new Form1; form1.CreateControl; } </li></ol>

<div class="references_section">