Office Add-In custom bitmap button

  • Thread starter Thread starter BC
  • Start date Start date
B

BC

Hello,

We are creating an Office add-in. We are able to
display the add-in successfully. However, we followed
a sample program, and it displays a FaceID = 1044 (which
is not the bitmap of the button we want to display). We
want to display our own custom bitmap.

How do we display our own custom bitmap instead
of the bitmap associated with FaceID = 1044?

TIA,
BC
 
One of the many stupid things about Excel is the way you have to create your
own bitmap buttons:

1. Load your bitmap.
2. Replace all of the pixels that you want to be transparent with the
standard Windows control background colour (as configured in the current
theme).
3. Backup the clipboard (as long as it isn't too big).
4. Copy the bitmap to the clipboard.
5. Paste the bitmap to the button.
6. Restore the clipboard.

Backing up and restoring the clipboard is optional, but it's really annoying
to users when they copy some text, start Excel, and paste only to find that
some dumb plug-in has trashed the clipboard.

If you're using Excel XP it's slightly easier in that you can set properties
of the button to the image and image mask.

Regards,
Aaron Queenan.
 
Hello Aaron,

Thank you for responding to my posting.

Do you have any sample C# code that implements
the process you described for creating a custom
button?

Thanks again,
BC
 
Hi BC,
here is my code (without backing up the clipboard, I haven't tought
about that :) ). Now I have to make it :)

oButton = (Office.CommandBarButton)oBar.Controls.Add
(MsoControlType.msoControlButton,
Missing.Value, Missing.Value, 1, false);

Clipboard.SetDataObject(oButtonIcon);
// oButtonIcon is Drawing.Icon

mButton.PasteFace();
mButton.Style = MsoButtonStyle.msoButtonIconAndCaption;

Hmmm, yes Aaron is right, I have to implement Clipboard backup.

Hope that helps
Sunny
 
For saving and restoring the clipboard:

System.Windows.Forms.IDataObject clipboardCurrent =
System.Windows.Forms.Clipboard.GetDataObject();
System.Windows.Forms.DataObject clipboardPreserve = new
System.Windows.Forms.DataObject();
foreach (string format in clipboardCurrent.GetFormats(false))
clipboardPreserve.SetData(format, clipboardCurrent.GetData(format));
...
System.Windows.Forms.Clipboard.SetDataObject(clipboardPreserve, true);

Note that saving the clipboard may use a lot of memory, because although the
clipboard contains a link to the data, we must copy all of the data for all
of the formats to ensure a "consistent user experience", so where the link
only took a few bytes of memory, the data could take many megabytes (or
gigabytes for image data).

For setting the transparent pixels, copying to the clipboard and pasting to
the button (assuming the top-left pixel contains the transparent colour:

System.Drawing.Color colorTransparent = bitmap.GetPixel(0, 0);
for (int x = bitmap.Width - 1; x >= 0; x--)
for (int y = bitmap.Height - 1; y >= 0; y--)
if (bitmap.GetPixel(x, y) == colorTransparent)
bitmap.SetPixel(x, y,
System.Drawing.Color.FromKnownColor(System.Drawing.KnownColor.Control));
System.Windows.Forms.Clipboard.SetDataObject(bitmap);
this.buttonToolbar.PasteFace();

In Excel XP you can set the .Picture property of the button, but you need to
use the VB6 picture object to do this. Perhaps Excel 2003 has added .NET
image support to the .Picture property.

Regards,
Aaron Queenan.
 
Hi Sunny,

Thank you for responding to my posting.

Unfortunately, I am new to both C# and .NET.
Could you please provide a little more detail
of your code snippet.

1. Should mButton be oButton?

2. How do I create an oButtonIcon?
I did not see an "Icon" item in the
Toolbox list.

3. Should I insert your code snippet after my
"MakeANewButton" method?

4. I am creating 2 buttons, how do I associate
which icon goes with which button? Do I insert
your code snippet after each call to my
"MakeANewButton" method?

// Create a button.
Microsoft.Office.Core.CommandBarButton insertText;

insertText = MakeANewButton(toolBar, "Insert text", 1043,
new Microsoft.Office.
Core._CommandBarButtonEvents_ClickEventHandler
insertText_Click));

//Your code snippet
oButton = (Office.CommandBarButton)oBar.Controls.Add
(MsoControlType.msoControlButton, Missing.Value,
Missing.Value, 1, false);
Clipboard.SetDataObject(oButtonIcon);
// oButtonIcon is Drawing.Icon
mButton.PasteFace();
mButton.Style = MsoButtonStyle.msoButtonIconAndCaption;


Thanks again,
BC
 
Hi BC,
To be honest, this code is from my Outlook 2000 addin. As far as it uses
the Office 2000 interfaces for buttons and commanbars, it have to work
in excel also.
I'll try to answer inline:


Hi Sunny,

Thank you for responding to my posting.

Unfortunately, I am new to both C# and .NET.
Could you please provide a little more detail
of your code snippet.

1. Should mButton be oButton?
yes :), stupid typo, I have changed the names to be easy ... and sorry
:)
2. How do I create an oButtonIcon?
I did not see an "Icon" item in the
Toolbox list.

System.Drawing.Bitmap oButtonIcon = new .....

or

System.Drawing.Icon .....

Read about that classes, their constructors can make an Bitmap/Icon
object from different sources - files, streams, etc.
In my case I have added the .ico file as resource, and after that read
it as stream in the constructor of the Icon object.
3. Should I insert your code snippet after my
"MakeANewButton" method?

Yes, the button have to be existing alread, you are just changing it
with new clothes :)
4. I am creating 2 buttons, how do I associate
which icon goes with which button? Do I insert
your code snippet after each call to my
"MakeANewButton" method?
If you are using only one picture for both buttons, you may load the
icon only once in the clipboard, and invoke .PasteFace of every button
after that. If the icons are different, you have to load the clipboard
for every image.
 
Hi Sunny,

Thanks once again for replying to my posting.
I hope I'm get closer to getting this to work.

Here's my problem:
I added a new icon to the project. The icon filename is
"icon1.ico". However, when I try to create the new icon
the add-in no longer works.

// Causes the add-in not to work.
Icon oButtonIcon = new Icon(GetType(), "icon1.ico");


oButton = (Microsoft.Office.Core.CommandBarButton)
toolBar.Controls.Add
(MsoControlType.msoControlButton,
Missing.Value, Missing.Value, 1, false);

Clipboard.SetDataObject(oButtonIcon);
// oButtonIcon is Drawing.Icon

oButton.PasteFace();
oButton.Style = MsoButtonStyle.msoButtonIconAndCaption;

Some more assistance would be greatly appreciated.

BC
 
Hi BC,

my advise is ALWAYS to use try/catch blocks when you touch anyhow any
Office object. When the addin throws unhandled exception, office just
forgets about the addin.

So, if you tell me what exactly is not working, and what is the
exception thrown, maybe I'll be able to help

Sunny
 
Hi Sunny,

Thanks again for responding to my posting.

//causes exception error
Icon oButtonIcon = new Icon(GetType(), "Icon1.ico");

The exception message:
Resource "Icon1.ico" could not be found in class
myAddin.Connect.

I added the icon to the project. The icon filename is
"icon1.ico"

I tried specifying the full path to the icon file and
that did hot help.

Thanks,
BC
 
Hi BC,

Hi Sunny,

Thanks again for responding to my posting.

//causes exception error
Icon oButtonIcon = new Icon(GetType(), "Icon1.ico");

The exception message:
Resource "Icon1.ico" could not be found in class
myAddin.Connect.

I added the icon to the project. The icon filename is
"icon1.ico"

I tried specifying the full path to the icon file and
that did hot help.

Thanks,
BC
Unfortunately when you deal with resources in C#, filenames are case
sensitive, so be careful.

Here is how I'm reading the resource file:

System.Reflection.Assembly myAssembly =
System.Reflection.Assembly.GetExecutingAssembly();
Stream s = myAssembly.GetManifestResourceStream
("MyNamespace.MyIcon.ico");
oIceButton = new System.Drawing.Bitmap(s);


Sunny
 
Hi Sunny,

Thanks for all of your help.
I finally got it to work!!

The problem I was having was that
I did not set the icon1.icon property
to "embedded resource". I did not change
it from the default setting of "control".

Thanks again,
BC
 
No problem at all,

wellcome in the world of pain :)

When you target office addin, it's real pain, and nothing goes easy :)

Sunny
 
Back
Top