Get window icon, put it on canvas, overlay image, save as ico (WinXP and Win7) - c++

Right now I change the icon of a window with this code.
What I want to do though is get the current icon in use by a window. Then put it on a canvas. Then put another image on that (a badge) then save it as ico.

Never tried that, however the follow should work in general (with a lot of fiddling)
WM_GETICON to get the big and small icon.
Convert the icon to something the loader can understand (aka. either a BITMAP or ICO). E.g. How can I save HICON to an .ico file?
Load the image. E.g. Javascript: Render PNG stored as Uint8Array onto Canvas element without Data URI
canvas.drawImage
canvas.mozGetAsFile (Blob) or canvas.mozFetchAsStream (nsIInputStream) using the image/vnd.microsoft.icon mime.
Take the resulting data and reconstruct an icon.
LookupIconIdFromDirectoryEx and CreateIconFromResourceEx
WM_SETICON

Related

Can't use a transparent BMP with MFC Button control

I am really confused here ...
I am trying to add a MFC Button control onto my dialog in the IDE.
I want it to just show a BMP file. I have another already on the dialog that shows with a transparent background.
This is the image for the good button:
This is the other button image I downloaded. But it is PNG:
I have tried to convert it so that it is 32 bit BMP so that it is transparent:
But it is failing. It shows with a black background:
You can see on that screenshot that the lower image shows OK. But not the new one. How do I fix this image file?
Update:
I used a different image in the end for the question mark. But for others I ended up using PNG and manually using the load method as outlined below:

MFC Image Button with transparency

I'm updating an MFC dialog with a number of buttons on it.
At present, the dialog has a Picture control covering the whole dialog providing a patterned background. On top of that, each button is a CBitmapButton using (opaque) images carefully generated to match the area of background they cover.
It would obviously be much easier if the images could be created as mostly transparent, so the background shows through automatically. However, I can't work out how to get MFC to render transparent images correctly in this case.
I understand that I might want a different class to CBitmapButton, or need to write a custom subclass; that's fine, but I don't know where to start. It would be nice to support 32-bit BMP or PNG with alpha channel, but I'd settle for the "specified colour should be transparent" type.
It may not be the best way to do it, but what I'd do is create a custom CButton derived class (assuming that you're actually using the rest of the CButton functionality), then override the DrawItem function to put your custom draw code in.
For the image itself I'd use a Bitmap GDI+ object (which will allow you to load either BMPs or PNGs with alpha channels) then use the regular DrawImage function to draw the bitmap.
If you're going to put PNGs into your resource file then you need to put them in as a "PNG" type. Make sure when you look in the resource file code that the entry looks like
IDB_PNG1 PNG "C:\temp\test.png"
and doesn't try to treat it as a BITMAP resource otherwise you'll have problems loading them.
Edit
Putting my response here so I can post code. Yes, I meant to derive a custom class from CButton, then add a Gdiplus::Bitmap member variable. Here is roughly what you'll need to do to get it to work, though I haven't checked that the code actually compiles and works, but hopefully you'll get the idea. It's not the most efficient way to do it, but if you've not done much custom drawing before then it does have the advantage of being simple!
void CMyButton::LoadImage(const int resourceID)
{
m_pBitmap = Gdiplus::Bitmap::FromResource(NULL, MAKEINTRESOURCE(resourceID));
ASSERT(m_pBitmap);
}
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);
CRect rcClient;
GetClientRect(&rcClient);
if (lpDrawItemStruct->itemState & ODS_SELECTED)
{
// If you want to do anything special when the button is pressed, do it here
// Maybe offset the rect to give the impression of the button being pressed?
rcClient.OffsetRect(1,1);
}
Graphics gr(lpDrawItemStruct->hDC);
gr.DrawImage(m_pBitmap, rcClient.left, rcClient.top);
}

Need a way to display image and draw on the image in Visual C++

The current way that I found was to make a bitmap and paint it into a picturebox,
but there it is very slow when trying to scroll the panel (the picturebox is inside a scrollable panel).
Is there a better way to achieve this functionality?
Load the bitmap only when your picture box is created, then leave it in memory until the picture box is destroyed. Loading the bitmap every time OnPaint is called will destroy performance.
Also make sure you aren't re-painting your bitmap if you receive a WM_PAINT message and nothing has changed.
That image size, 1500x2000 will be slow. How about resizing it to 25% to show a preview and if a user wishes to see the whole image give them an alert it may take some time.

how to add an image along with text in a button in MFC?

Am having a hard time in adding image along with a text in a Button..I know that it can be done by enabling the owner draw function with bitmapbutton class..But I dont want to that..so is ther anyother way that i can add an image along with text without drawing the text?
Since you are using MFC Feature Pack, just cast your button into a CMFCButton class. Then you can call CMFCButton::SetImage to add the image.

Transparent window containing opaque text and buttons

I'm creating a non-intrusive popup window to notify the user when processing a time-consuming operation. At the moment I'm setting its transparency by calling SetLayeredWindowAttributes which gives me a reasonable result:
alt text http://img6.imageshack.us/img6/3144/transparentn.jpg
However I'd like the text and close button to appear opaque (it doesn't quite look right with white text) while keeping the background transparent - is there a way of doing this?
In order to do "proper" alpha in a layered window you need to supply the window manager with a PARGB bitmap by a call to UpdateLayeredWindow.
The cleanest way to achieve this that I know of is the following:
Create a GDI+ Bitmap object with the PixelFormat32bppPARGB pixel format.
Create a Graphics object to draw in this Bitmap object.
Do all your drawing into this object using GDI+.
Destroy the Graphics object created in step 2.
Call the GetHBITMAP method on the Bitmap object to get a Windows HBITMAP.
Destroy the Bitmap object.
Create a memory DC using CreateCompatibleDC and select the HBITMAP from step 5 into it.
Call UpdateLayeredWindow using the memory DC as a source.
Select previous bitmap and delete the memory DC.
Destroy the HBITMAP created in step 5.
This method should allow you to control the alpha channel of everything that is drawn: transparent for the background, opaque for the text and button.
Also, since you are going to be outputting text, I recommend that you call SystemParametersInfo to get the default antialiasing setting (SPI_GETFONTSMOOTHING), and then the SetTextRenderingHint on the Graphics object to set the antialiasing type to the same type that is configured by the user, for a nicer look.
I suspect you'll need two top level windows rather than one - one that has the alpha blend and a second that is display above the first with the opaque text and button but with a transparent background. To accomplish this with a single window you'll need to use the UpdateLayeredWindow API call, but using this will cause your buttons to not redraw when they are interacted with (hover highlights, focus etc.)
It is possible that if this application is for Vista only there is a new API call that you can use, but I do not believe it is available in XP or earlier.
I can't say for sure, you'll need to try it, but since everything is a window, you could try setting the layered attributes for your button to make it opaque.
As for the text, you may be able to put that in its own frame with a set background and foreground color, and modify its layered attributes to make the background color transparent...
But since these are child windows and not the top-level window, I really don't know that it'll work.