Microsoft KB Archive/198522

= How To Place a Custom Bitmap on an Office Commandbar Button =

Article ID: 198522

Article Last Modified on 3/21/2005

-

APPLIES TO


 * Microsoft Project 2000 Standard Edition
 * Microsoft Excel 2000 Standard Edition
 * Microsoft Visual C++ 5.0 Enterprise Edition
 * Microsoft Visual C++ 6.0 Enterprise Edition
 * Microsoft Visual C++ 5.0 Professional Edition
 * Microsoft Visual C++ 6.0 Professional Edition
 * Microsoft Visual C++ 6.0 Standard Edition
 * The Microsoft Foundation Classes (MFC)
 * Microsoft Access 97 Standard Edition
 * Microsoft Excel 97 Standard Edition
 * Microsoft Outlook 97 Standard Edition
 * Microsoft PowerPoint 97 Standard Edition
 * Microsoft Word 97 Standard Edition
 * Microsoft Access 2000 Standard Edition
 * Microsoft Outlook 2000 Standard Edition
 * Microsoft PowerPoint 2000 Standard Edition
 * Microsoft Word 2000 Standard Edition
 * Microsoft Access 2002 Standard Edition
 * Microsoft Excel 2002 Standard Edition
 * Microsoft Outlook 2002 Standard Edition
 * Microsoft PowerPoint 2002 Standard Edition
 * Microsoft Word 2002 Standard Edition

-



This article was previously published under Q198522



SUMMARY
Using Automation, you can modify the Microsoft Office CommandBar to add one or more CommandBarButtons and customize the appearance of those additions with respect to the caption, the tooltip text, and the graphic image on the face.

The graphic can be one of the standard icons supplied by Microsoft Windows, one of the existing icons used by other CommandBarButttons, or a custom graphic such as a user-designed icon or bitmap. This article contains sample code to illustrate the last concept.



MORE INFORMATION
This article discusses an approach to using the Microsoft Foundation Class (MFC) Library installed with Microsoft Visual C++ versions 5.0 and 6.0 to add a CommandBar Control button to Microsoft Word's CommandBars, then to place a custom bitmap on that button. Two other articles in the Microsoft Knowledge Base show other aspects of managing the Microsoft Office menu and its controls. They are:

180625 How To Use Automation to Modify the Office Menu

194906 How To Add and Run a VBA Macro Using Automation from MFC

The second article shows how to use the graphic from an existing CommandBarButton as the graphic for the new button.

With adaptation, the Visual C++ code in this article can be used in your application, but the purpose of the article is to help you learn, both by walking through the code and by running the program.

Notes for Automating Microsoft Word 2000:

Some methods and properties have changed for Microsoft Word 2000. For additional information about using the sample code described in this article with the Microsoft Word 2000 type library, please see the following article in the Microsoft Knowledge Base:

224925 INFO: Type Libraries for Office May Change with New Release

Steps to Create the Project
 Follow steps 1 through 12 in the following Microsoft Knowledge Base article to create a sample project, but change the type library used in step 9 to MSWord8.olb:

178749 How To Create an Automation Project Using MFC and a Type Library

 Repeat steps 8, 9, and 10 of the above article to add the typelib for Microsoft Office to the project. The typelib for Microsoft Office 97 is in the file Mso97.dll (default location is as follows):

C:\Program Files\Microsoft Office\mso97.dll

For Office 2000 the typelib is MSO9.dll. For Office XP the default location of the typelib is C:\Program Files\Common Files\Microsoft Shared\Office10\MSO.dll. NOTE: Select all of the components of that typelib. You will generate and add to your project the files Mso97.h and Mso97.cpp (or names appropriate to the version).

As a result, you will get duplicates in the COleDispatchDriver wrapper classes. These result from the duplication of IDispatch names in Microsoft Word and Microsoft Office. To resolve those duplications, for this exercise, use the "namespace" facility provided by Visual C++. These steps will resolve the duplications:  At the very top of the Mswordx.h header file, insert the line:

namespace word { // that's an opening brace At the very bottom of that same file, add a line that contains only the closing brace and a semi-colon--specifically "};" (without the quotation marks)  At the beginning of the Mswordx.cpp file, on a new line just after the compiler directive "#endif", and before the line that reads LPDISPATCH _Application:GetApplication, add the following line:

using namespace word;</li>  Add the following #include statements to the #include statements at the top of AutoProjectDlg.cpp. Make sure these are added to the end (after stdafx.h): #include "msword8.h" // or the appropriate version's header #include "mso97.h"   // ot the appropriate version's header </li>  Add the following code to the CAutoProjectDlg::OnRun event handler in the AutoProjectDlg.cpp file: // Sample code word::_Application oWord; // using namespace for the // Word typelib's members

// Convenient values declared as ColeVariants. COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

// Get the Word IDispatch pointer and attach it to the Word object. if (!oWord.CreateDispatch("Word.Application")) {  AfxMessageBox("Couldn't get Word object."); return; }

oWord.SetVisible(TRUE); //This shows the application.

word::Documents oDocs(oWord.GetDocuments); word::_Document oDoc;

// Create a new document... /* Word 97 oDoc = oDocs.Add(covOptional, covOptional); End Word 97 */

/* Word 2002 */ oDoc = oDocs.Add(covOptional, // Template          covOptional,  // New Template      covOptional,  // Document Type      covTrue);     // Visible

/* Office 97 - no underscore in front of CommandBars CommandBars oBars = oWord.GetCommandBars; // New CommandBars // collection object end of Office 97 syntax */

/* Office XP - note the underscore in front of CommandBars */ _CommandBars oBars = oWord.GetCommandBars; // New CommandBars // collection object

CommandBar oBar; CommandBarControls oControls; /* Office 97 usage - no underscore in front of CommandBarButton CommandBarButton oButton; end of Office 97 usage */

/* Office XP usage - note the underscore in front of CommandBarButton */ _CommandBarButton oButton;

VARIANT vName; vName.vt = VT_BSTR; vName.bstrVal = SysAllocString(L"MyNewCommandBar");

VARIANT vPosition; vPosition.vt = VT_I2; vPosition.iVal = 4; // 4 = Floating; 0 = top;

// Add new bar to the command bars collection CommandBar oNewBar = oBars.Add(vName,    // const Variant Name                          vPosition, // const Variant Position                          covFalse,  // const Variant (replace)MenuBar                          covTrue    // const Variant Temporary                          );

oNewBar.SetVisible(TRUE);

// Get the collection (now empty) of controls on the new commandbar CommandBarControls oNewControls = oNewBar.GetControls;

VARIANT vType; vType.vt = VT_I4; vType.lVal = (long)1;

// Add a commandbarbutton to the collection of controls // on new commandbar // CommandBarButton oNewButton1 = // Office XP uses underscore

_CommandBarButton oNewButton1 = // Office XP - note leading underscore oNewControls.Add(vType, // Type = msoControlButton            covOptional,  // Id             covOptional,  // Parameter             covOptional,  // Before             covTrue       // Temporary             );

oNewButton1.SetStyle(3); // msoButtonIconAndCaption oNewButton1.SetCaption("New"); oNewButton1.SetTooltipText("This is a new button"); oNewButton1.SetVisible(TRUE); oNewButton1.SetState(0); // msoButtonUp

OpenClipboard; // Reserve clipboard for this program

// *************************************************************** // There are two alternative sources of bitmaps that this sample // can use. Choose either the 4 lines (next) that use "MyBitmap" // from the  resource file, or the line below that which loads a  //  bitmap from a bitmap file.

// Alternative 1: This code places a bitmap drawn by you in the // resource editor onto a button /* Remove the comment if you use this alternative CBitmap MyBitmap; MyBitmap.LoadBitmap(IDB_BITMAP1); // A Bitmap you drew in the // Resource Editor HBITMAP MyBitmapHandle = (HBITMAP)MyBitmap; // Cast it to a HBITMAP SetClipboardData(CF_BITMAP, MyBitmapHandle); */ //Remove the comment to use alternative 1. // End if alternative 1

// Alternative 2: This code places a bitmap from a file onto // the button. Comment it out if you use alternative 1 above. if(NULL==(SetClipboardData(CF_BITMAP, LoadImage(NULL, "C:\\Test.bmp", IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE) ))) {   AfxMessageBox("SetClipboardData returned a NULL"); }; // End of alternative 2

// End of alternatives // ***************************************************************

CloseClipboard; // Free clipboard so PasteFace can use it

oNewButton1.PasteFace; // This places the image from the // clipboard onto the command button

AfxMessageBox("Look at the button's face now");

oWord.Quit(covFalse, covOptional, covFalse); // End of Sample code

</li> Now, all you need is to copy a selected .bmp to c:\test.bmp, or change the above code's call to SetClipboardData to use a path and filename of your choosing.</li> Compile and run the example.</li></ol>

Keywords: kbautomation kbbutton kbhowto KB198522

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.