Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Extracting a CBitmap from a CImageList (from a toolbar bitmap)

646 views
Skip to first unread message

John

unread,
Dec 26, 2000, 11:41:22 AM12/26/00
to
I am trying to extract a CBitmap from a CImageList to use
for menu item bitmaps. The images already exist in a
composite toolbar bitmap, so I would rather not have to
recreate individual bitmap files for these. Using separate
bitmap files does work, however.

I have tried the following code without success. Any help
would be greatly appreciated.

Thanks,

John

---

// THIS DOES NOT WORK

// create an image list from the toolbar bitmap resource
CImageList il;
BOOL bRetVal = il.Create(IDR_MAINFRAME, 16, 4,
ILC_COLOR8);
ASSERT(bRetVal);

// a simple sanity check
int x = il.GetImageCount();
ASSERT(x);

// extract a particular image
IMAGEINFO ii;
bRetVal = il.GetImageInfo( 1, &ii);
ASSERT(bRetVal);

// create a CBitmap with the extracted image
static CBitmap bmp;
bRetVal = bmp.Attach(ii.hbmImage);
ASSERT(bRetVal);

// get the "File" menu
CMenu* pMenu = AfxGetMainWnd()->
GetMenu()->
GetSubMenu(0);
ASSERT(pMenu);

// set the "File -> New" menu bitmap
bRetVal = pMenu->SetMenuItemBitmaps(
ID_FILE_NEW,
MF_BYCOMMAND,
&bmp,
&bmp);
ASSERT(bRetVal);

---

// THIS DOES WORK

// load a single bitmap
static bool bLoaded = false;
static CBitmap bmp2;

if (bLoaded == false)
{
BOOL bRetVal = bmp2.LoadBitmap(IDB_BITMAP1);
ASSERT(bRetVal == TRUE);
bLoaded = true;
}

bRetVal = pMenu->SetMenuItemBitmaps(
ID_FILE_OPEN,
MF_BYCOMMAND,
&bmp2,
&bmp2);
ASSERT(bRetVal);

Ali

unread,
Dec 26, 2000, 12:09:25 PM12/26/00
to
The answer to your question is pretty simple. IDR_MAINFRAME is not a id to
a bitmap...
The id must be an id to a bitmap, meaning that when you look under your
bitmaps in the resource panel that ID must show up under bitmaps.
Go to your resource panel right click, click import, got your res dir,
select ToolBar.bmp.
You get the idea..

Ali

"John" <John_F...@agilent.REMOVE.com> wrote in message
news:97784908...@goodnews.cos.agilent.com...

John

unread,
Dec 26, 2000, 12:53:50 PM12/26/00
to
I tried your suggestion , and I still have the same bad
result.

As far as IDR_ resource ID's go, they are shared by
multiple resources of different types (menus, accelerators,
toolbars, bitmaps, etc.). They should work fine. It
doesn't really matter in my case -- I was just using this as
an example. I can use a separate IDB_ resource id as you
suggested. This does not solve my problem, however.

Thanks for the suggestion,

John


"Ali" <ali...@yahoo.com> wrote in message
news:Bh426.2699$qCL5.26...@news.randori.com...

John

unread,
Dec 26, 2000, 5:48:48 PM12/26/00
to
I am trying to extract a CBitmap from a CImageList to use
for menu item bitmaps. The images already exist in a
composite toolbar bitmap, so I would rather not have to
recreate individual bitmap files for these. Using separate
bitmap files does work, however.

I have tried the following code without success. Any help
would be greatly appreciated.

Thanks,

John

---

// THIS DOES NOT WORK

// it compiles and executes, but no bitmap is put in the
menu item

// create an image list from the toolbar bitmap resource
CImageList il;
BOOL bRetVal =

il.Create(IDB_TOOLBAR, 16, 4, ILC_COLOR8);
ASSERT(bRetVal);

---

// THIS DOES WORK
// it compiles and executes, and a bitmap is put in the
menu item

arminzuercher

unread,
Dec 26, 2000, 6:45:03 PM12/26/00
to
Hi John,
did you tried to convert it into an icon and use this instead of the bitmab
like:


int pos = 1;
HICON hicon = m_iImageList.ExtractIcon(pos);
::DrawIconEx(...)

"John" <John_F...@agilent.REMOVE.com> schrieb im Newsbeitrag
news:97784908...@goodnews.cos.agilent.com...

John

unread,
Dec 26, 2000, 7:17:21 PM12/26/00
to
Thanks for you reply. The problem converting to an icon is
that I do not want to draw it -- I want to pass it to
SetMenuItemBitmaps(), which requires a CBitmap for a
parameter.

I 'll try your suggestion for debugging purposes.

John

"arminzuercher" <arminz...@compuserve.de> wrote in
message news:u4fOlX5bAHA.1208@tkmsftngp05...

Ajay Kalra

unread,
Dec 26, 2000, 10:52:02 PM12/26/00
to
John,

There is an example in MSDN/MSJ which shows how to use Toolbar icons in a
menu. Search for CCoolMenuManager in MSDN. Paul Dilascia wrote this article
in MSJ in Oct 1998(?). You can download the source from
www.microsoft.com/msj. You can integrate it in your code by adding only few
lines of code. You give same ids to toolbar buttons and menu items and you
are done.

--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com

Note: Please post all replies to newsgroup only.

John <John_F...@agilent.REMOVE.com> wrote in message

news:97787113...@goodnews.cos.agilent.com...

John

unread,
Dec 26, 2000, 11:12:31 PM12/26/00
to
Ajay -- Thanks for your response.

Unfortunately, I can't use Paul's menu manager. We're
already using a different third-party menu manager, etc.
The two will not work together.

At this point, I believe the simplest solution for me is to
solve the problem of getting a CBitmap from a CImageList.
It doesn't seem like that should be too hard to do, but I
haven't figured it out yet.

Any further advice along those lines would be greatly
appreciated!

Thanks again,

John

"Ajay Kalra" <ajay...@yahoo.com> wrote in message
news:OsZE7f7bAHA.452@tkmsftngp02...

Ajay Kalra

unread,
Dec 27, 2000, 12:22:45 AM12/27/00
to
If you are using a menu manager, what is it doing if it does not draw the
icons.

BTW, Paul Dilascia's will work with any existing code. It is completely non
obtrusive.

--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com

Note: Please post all replies to newsgroup only.

John <John_F...@agilent.REMOVE.com> wrote in message

news:97789055...@goodnews.cos.agilent.com...

Jeff Partch

unread,
Dec 27, 2000, 7:38:02 AM12/27/00
to
Hi, John!

The main problem here, I think, is that GetImageInfo doesn't seem to return an HBITMAP to the
indexed image, but the whole composite bitmap or something. I am also not convinced that it returns
a copy either.

Anyway, I wrote this function (and I ain't too proud of it)...

HBITMAP MenuBitmapFromImageList(HIMAGELIST hil, int nIndex)
{
HBITMAP hbmRet = NULL;

if ((hil) &&
(nIndex >= 0) &&
(nIndex < ImageList_GetImageCount(hil)))
{
HICON hIcon = ImageList_GetIcon(hil, nIndex, 0);
ICONINFO ii;

ZeroMemory(&ii, sizeof(ii));

if (hIcon && GetIconInfo(hIcon, &ii) && ii.hbmColor)
{
hbmRet = (HBITMAP)CopyImage(
ii.hbmColor,
IMAGE_BITMAP,
GetSystemMetrics(SM_CXMENUCHECK)-1,
GetSystemMetrics(SM_CYMENUCHECK)+2,
LR_MONOCHROME);

DeleteObject(ii.hbmColor);
}

if (ii.hbmMask)
DeleteObject(ii.hbmMask);

if (hIcon)
DestroyIcon(hIcon);
}
return hbmRet;
}

...But there are other problems. First, the size of the imagelist bitmaps is larger than the size of
a menuitem bitmap -- on my system anyway, and they do not look good at all without compression, and
they do not compress too well using the default GetSystemMetrics values. So as you can see above, I
punted with the size. These are just the trial and error values that seem to work best for me, but
they are still pretty ugly images (some better than others) when it's all said and done.

If you want to see for yourself, comment out this code in your post...

> // extract a particular image
> IMAGEINFO ii;
> bRetVal = il.GetImageInfo( 1, &ii);
> ASSERT(bRetVal);

And modify this line...

> bRetVal = bmp.Attach(ii.hbmImage);

to...

bRetVal = bmp.Attach(MenuBitmapFromImageList(il, 1));

Jeff...
--
Please post all follow-ups to the newsgroup only.

John

unread,
Dec 27, 2000, 1:47:44 PM12/27/00
to
The menu manager we're using does draw bitmaps in the menu
items. The issue I'm having is with menus I create
dynamically. The statically created ones (from the resource
editor) get the bitmaps just fine. For the dynamically
added ones, I need to call CMenu::SetMenuItemBitmaps().
This works fine if I load the bitmap from a file, as I
showed in my code example. What I am trying to avoid is
having two different files with the same bitmap -- one in
the "composite" toolbar bitmap, and another individual
bitmap file for each toolbar button.

So, what I am trying to accomplish is:

- load the toolbar composite bitmap into a CImageList
- extract a CBitmap from the CImageList
- set the CBitmap for a given menu item using
SetMenuItemBitmaps()

This doesn't seem like it should be that hard, but maybe I
off track here.

Thanks for all your replies -- any further advice is
welcome!

John


"Ajay Kalra" <ajay...@yahoo.com> wrote in message

news:u$VHnS8bAHA.1564@tkmsftngp03...

Ajay Kalra

unread,
Dec 27, 2000, 2:53:57 PM12/27/00
to
I still think you are approaching it wrong. The article I talked about will
work with existing code. It will require you to add no more than 5-10 lines
of code. I am surprised that you are using a menu manager which does not
work with dynamically created menus.

On other side, what you are trying to do should work. I have never worked
with SetMenuItemBitmaps() and I dont know any shortcomings this might have.

--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com

Note: Please post all replies to newsgroup only.

John <John_F...@agilent.REMOVE.com> wrote in message

news:9779430...@goodnews.cos.agilent.com...

John

unread,
Dec 27, 2000, 4:30:27 PM12/27/00
to
I now have a working solution! Thanks to Jeff, Ajay,
"arminzuercher" and Ali for your replies. Here is the code
I am using. I removed extraneous ASSERT()'a and error
checks for illustrative purposes.

John

---

// create an image list from the toolbar bitmap

CImageList il;
BOOL bRetVal = il.Create(

IDR_MAINFRAME, // toolbar/bitmap resource ID
16, // width of each bitmap (16x15)
4, // grow size
ILC_COLOR4 | ILC_MASK); // 16 color bitmaps and mask

// extract an image as an icon
HICON hIcon = il.ExtractIcon(1);

// get icon info for ultimate convertion to a bitmap
ICONINFO ii;
::ZeroMemory(&ii, sizeof(ii));
bRetVal = ::GetIconInfo(hIcon, &ii);

// convert to HBITMAP
HBITMAP hBmp = (HBITMAP) CopyImage(
ii.hbmColor, // handle to image
IMAGE_BITMAP, // type of image
0, // x: 0 -> use same size as orig
0, // y: 0 -> use same size as origi
LR_CREATEDIBSECTION); // create DIB style bitmap

DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
DestroyIcon(hIcon);

// convert to CBitmap
CBitmap bmp;
bRetVal = bmp.Attach(hBmp);

// add to menu
bRetVal = pMenu->SetMenuItemBitmaps(
nID,
MF_BYCOMMAND,
&bmp,
&bmp);

0 new messages