Re: Disabled CommandBarButton image in Office 2000 is always empty

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



Hello Jialiang,

From your post, my understanding on this issue is: you want to know how
to resolve the failure of 'PasteFace' when the Office is not an English
version, in addition

No, this one i figured out. I do just the enumeration you suggest below.

you wonder why the button face of the Office add-in
works abnormally when it is disabled. If I'm off base, please feel free
to let me know.

Yes, that is my problem. When I create the DIBs (either 256 color or true color DIB plus a 2 color mask DIB) I face the problem that Office 2000 apps show empty command bar buttons. When I enable them the DIBs are correctly used to draw the transparent image.

For your first question, please refer to the section '2. Transparent
button icon' of the codeproject article:
http://www.codeproject.com/com/wordhighlight.asp. It enumerates the data
formats currently available on the clipboard and tries to determine the
localized format name in m_szFaceFormatName and m_szMaskFormatName.

Yes, I followed that approach.

For your second question, it depends on how you copied the bitmap as
button face. There are several articles describing how to do it properly:

The KB: http://support.microsoft.com/kb/288771 (How To Create a
Transparent Picture For Office CommandBar Buttons) illustrates the
standard way to copy bitmaps as button face. (see the function
'CopyBitmapAsButtonFace'). Another article

Yes, that is the article I followd for DIB creation.

Would you have a look at the articles above and check the codes again? If
it still cannot help to resolve the problem, would you paste your
"CopyBitmapAsButtonFace" here? And I will help to see where the problem
is.

Here it is:

// spPic is an IPicture object created from a bmp resource
hr = spPic->get_Handle(&olePic);
hr = spPic->get_hPal(&olePal);
HBITMAP hb = (HBITMAP)olePic;
HPALETTE hp = (HPALETTE)olePal;

HPALETTE hPalOld = SelectPalette(hdc, hp, FALSE);
RealizePalette(hdc);

BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
GetDIBits(hdc, hb, 0, 0, 0, &bmi, DIB_RGB_COLORS);

int nColors = (bmi.bmiHeader.biBitCount > 8) ? 0 : (1 << bmi.bmiHeader.biBitCount);
DWORD headerLen = sizeof(bmi.bmiHeader) + nColors*sizeof(RGBQUAD);
HGLOBAL hBits = GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, headerLen + bmi.bmiHeader.biSizeImage);
if(hBits)
{
LPVOID pBits = GlobalLock(hBits);
CopyMemory(pBits, &bmi.bmiHeader, sizeof(bmi.bmiHeader));

GetDIBits(hdc, hb, 0, bmi.bmiHeader.biHeight, ((LPBYTE)pBits+headerLen), (LPBITMAPINFO)pBits, DIB_RGB_COLORS);

// S_OFF2000_CLIP_IMAGE was filled earlier with the localized name of the clipboard format "Toolbar Button Face"
UINT clipImage = RegisterClipboardFormat(S_OFF2000_CLIP_IMAGE);

// I copy the DIB to put CF_DIB as well as the Toolbar format into the clipboard
// I tried adding only the Toolbar format or both - neither way the disabled button image was displayed
SIZE_T cbDIB = GlobalSize(hBits);
HANDLE hgDIB = GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, cbDIB);
LPVOID pDIB = GlobalLock(hgDIB);
CopyMemory(pDIB, pBits, cbDIB);
GlobalUnlock(hgDIB);

GlobalUnlock(hBits);

BOOL f = OpenClipboard(NULL);
_sntprintf_s(sz, _countof(sz)-1, _TRUNCATE, _T("OpenClipboard = %ld\n"), (int)f);
OutputDebugString(sz);

EmptyClipboard();

// CF_DIB might be optional so I tried with and without this clipboard data
if(SetClipboardData(CF_DIB, hgDIB) == NULL)
GlobalFree(hgDIB);

if(SetClipboardData(clipImage, hBits) == NULL)
{
GlobalFree(hBits);
}
else
{
// Mask again is an IPicture
spPic = NULL;
hr = Mask->QueryInterface(&spPic);
if(spPic != NULL)
{
hr = spPic->get_Handle(&olePic);
hr = spPic->get_hPal(&olePal);
hb = (HBITMAP)olePic;
hp = (HPALETTE)olePal;

ZeroMemory(&bmi, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);

GetDIBits(hdc, hb, 0, 0, 0, &bmi, DIB_RGB_COLORS);

nColors = (bmi.bmiHeader.biBitCount > 8) ? 0 : (1 << bmi.bmiHeader.biBitCount);
headerLen = sizeof(bmi.bmiHeader) + nColors*sizeof(RGBQUAD);
hBits = GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, headerLen+bmi.bmiHeader.biSizeImage);
if(hBits)
{
pBits = GlobalLock(hBits);
CopyMemory(pBits, &bmi.bmiHeader, sizeof(bmi.bmiHeader));

GetDIBits(hdc, hb, 0, bmi.bmiHeader.biHeight, ((LPBYTE)pBits+headerLen), (LPBITMAPINFO)pBits, DIB_RGB_COLORS);

// S_OFF2000_CLIP_MASK contains the localized name of the "Toolbar Button Mask"
UINT clipMask = RegisterClipboardFormat(S_OFF2000_CLIP_MASK);
GlobalUnlock(hBits);

if(clipMask == 0 || SetClipboardData(clipMask, hBits) == NULL)
GlobalFree(hBits);
}
}
}

f = CloseClipboard();

_sntprintf_s(sz, _countof(sz)-1, _TRUNCATE, _T("CloseClipboard = %ld\n"), (int)f);
OutputDebugString(sz);
}

}

// apply the clipboard data and ensure the button is visible
hr = Button->raw_PasteFace();
hr = Button->put_Visible(VARIANT_TRUE);

// later on I have Button->put_Enabled(VARIANT_FALSE) which causes the image to disappear.


Thanks for any help on this. So far I just dropped the transparent image support and use the standard WinXP background color where my images should be transparent. As I need Office 2000 support only for a minority of customers this could be a workaround.

--
SvenC

.


Quantcast