I add a background image to my window, and other images do not appear.
The background image overlap other images
Image:
http://i.stack.imgur.com/efb2z.png
how to fix ?
Code
/* ENTER */
CPngImage imagea;
imagea.Load(IDB_PNG1);
image.SetBitmap((HBITMAP)imagea.Detach());
/* PROGRESS BAR */
CPngImage imageaa;
imageaa.Load(IDB_PNG2);
image2.SetBitmap((HBITMAP)imageaa.Detach());
/* BACKGROUND */
CPngImage imageaaa;
imageaaa.Load(IDB_PNG3);
image3.SetBitmap((HBITMAP)imageaaa.Detach());
New poblem
http://i.stack.imgur.com/wIurg.png
are you using the SetWindowPos function properly ?
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545%28v=vs.85%29.aspx
You need to use OnEraseBackground().
There are two ways to make a background image:
- draw directly on the dialog in OnEraseBackground()
- put an image behind all other controls
There are some subtle pro and cons to each approach, but for most application both should work. It seems you're using the second method. What you need to do is make sure the background control is all the way at the bottom of the control stack (z-pos - use SetWindowPos() to send it to the background, or just create it before all others, but then you can't use the dialog editor) and also to make sure your background control has WS_CLIPSIBLINGS set.
CPngImage supports the MFC framework infrastructure and is not intended to be used directly from your code.
Related
Visual Studio's windows have a close button (as well as other frame controls) that blend into the caption color and appear like so:
I was wondering if there's an accepted way of drawing controls like that. Do controls like these use DrawFrameControl or DrawThemeBackground, or do they use another approach altogether?
Thank you for any information.
There are two approaches for creating custom buttons using Win32 API:
1. Draw the control yourself. This is very complicated and requires a lot of knowledge about Win32 controls. Here are some links to get you started:
https://learn.microsoft.com/en-us/windows/win32/controls/user-controls-intro
https://www.codeproject.com/Articles/646482/Custom-Controls-in-Win-API-Control-Customization
Owner-drawn button, WM_CTLCOLORBTN and WM_DRAWITEM (clearing an HDC)
2. Modify an existing control using SubclassWindow. This is much easier, but in most cases very limited.
For example you can use a static control and handle mouse activity for it. You can also use multiple controls and show and move them as needed.
There is no set way of doing this since it's custom logic. But here are some links:
https://learn.microsoft.com/en-us/windows/win32/controls/window-controls
https://learn.microsoft.com/en-us/windows/win32/inputdev/mouse-input
https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-mousemove
i've implemented a owner draw button into my win32 app (no MFC). The button is a normal 20x20 bitmap (round icon with transparency). The problem is that the button is positioned on a solid background and i can see the buttons gray background (since the bitmap is round). I've tried responding to WM_CTLCOLORBTN with NULL_BRUSH but no luck.. I've tried displaying the button using a bitmap and a ico file but wont budge.. Does anyone know how to solve this problem?
This is my problem, the settings icon should be transparent at the edges (not white/gray)
It sounds like you're trying to make a non-rectangular control.
You could call SetWindowRgn to tell Windows that your control is non-rectangular.
In addition to what #joel's answer, if you want to make some area transperant put a unique color in the area where you want to have transperancy using some image editors (RGB(0xFF,0x00,0xFF)) is mostly used Then use TransperantBlt
You say it's a solid background but your image shows some kind of orange-yellow gradient as a background. If it really was a standard windows button solid color you can load the bitmap with LoadImage using the LR_LOADMAP3DCOLORS or LR_LOADTRANSPARENT. Since you have a gradient you'll have to use a more complicated technique to mask out the bitmap.
http://www.winprog.org/tutorial/transparency.html
I've followed the steps from this question:
Higher color depth for MFC toolbar icons?
The code works. But I have another problem - any disabled buttons are just grey boxes.
Once they are enabled - they are exactly as they should be.
I suspect that the CToolBar doesn't know how to grey out the supplied images - can anyone help?
thanks in advance.
CToolBar actually accepts up to three imagelists each to handle the normal, disabled and highlighted states of the button.
To accomplish what I need - just normal and disabled button states. I need two images. One with normal coloured icons and the other with greyed out icons.
Add the images as Bitmap resources to your project - amend and make note of the IDs
Create two imagelists and set them accordingly: (m_wndToolBar is the toolbar in my project)
CImageList imgListActive;
CImageList imgListDisabled;
/* Load your CImageLists */
m_wndToolBar.GetToolBarCtrl().SetImageList(&imgListActive);
m_wndToolBar.GetToolBarCtrl().SetDisabledImageList(&imgListDisabled);
To set the highlighted versions of the toolbar:
CImageList imgListHighlighted;
/* Load your CImageList */
m_wndToolBar.GetToolBarCtrl().SetHotImageList(&imgListHighlighted);
et voila!
Usually two things are necessary to get the high color buttons and the correctly greyed out images:
Always edit the .bmp file for the toolbar outside of VisualStudio.
Add the images to MFC using a call to CMFCToolBar::AddToolBarForImageCollection(IDR_MAINFRAME); in your InitInstance() implementation.
Unfortunately this also means that you have to edit the Toolbar definition directly in the .rc resource file of the application.
I'm making a non-rectangular dialog, modelled over an image from Photoshop (the image is the background of the dialog, and the user will see trough the transparent part of the image). I'ts like a dashboard-style window for a media-app with a few custom-drawn controls. Most of the background-image is either opaque or 100% transparent - but in between there is a thin area of partially transparent pixels, ment to blend the image smootly into the background. This works great for web-graphics, but I have not found a way to make this work for Windows windows. I'm using the Windows Template Library (WTL), msvc 2008 - and the app must run on Windows XP as well as Vista and Windows 7.
Currently, I'm simply using the opaque part of the background-image to create a GDI clipping-region, but this gives pretty rough edges.
Does anyone know about any API functions to accomplish this (part of WTL, or reachable from WTL)?
Perhaps you could use layered windows? I haven't tested these with WTL but you should be able to get the effect you want. To the best of my knowledge I don't think you can add controls to a layered window so you'll need to attach it to another (non-layered) window to use controls.
Not sure how this interoperates with WTL, but have a look at the AlphaBlend function. You'll need to select your partially transparent bitmap into a DC and copy that to your dialog's DC in your paint function.
This article shows how to use layered windows with WTL and the Gdi+ API which is available on all your target platforms.
How Would I go about placing text on the windows desktop? I've been told that GetDesktopWindow() is what I need but I need an example.
I'm assuming your ultimate goal is displaying some sort of status information on the desktop.
You will have to do either:
Inject a DLL into Explorer's process and subclass the desktop window (the SysListView32 at the bottom of the Progman window's hierarchy) to paint your text directly onto it.
Create a nonactivatable window whose background is painted using PaintDesktop and paint your text on it.
First solution is the most intrusive, and quite hard to code, so I would not recommend it.
Second solution allows the most flexibility. No "undocumented" or reliance on a specific implementation of Explorer, or even of just having Explorer as a shell.
In order to prevent a window from being brought to the top when clicked, you can use the extended window style WS_EX_NOACTIVATE on Windows 2000 and up. On downlevel systems, you can handle the WM_MOUSEACTIVATE message and return MA_NOACTIVATE.
You can get away with the PaintDesktop call if you need true transparency by using layered windows, but the concept stays the same. I wrote another answer detailing how to properly do layered windows with alpha using GDI+.
Why not just draw the text in the desktop wallpaper image file?
This solution would be feasible if you don't have to update the information too often and if you have a wallpaper image.
One can easily use CImage class to load the wallpaper image, CImage::GetDC() to obtain a device context to draw into, then save the new image, and finally update the desktop wallpaper to the new image.
i haven't tried but i assume you could do the following:
use GetDesktopWindow to retrieve the handle of the desktop window
use SetWindowLong to point the windows message handler to your own procedure
in your proc, process the WM_PAINT message (or whatever) and draw what you need.
in your proc, call the original message handler (as returned by SetWindowLong).
not 100% sure it will work, but seems like it should as this is the normal way to subclass a window.
-don
If your intent is to produce something like the Sidebar, you probably just want to create one or more layered windows. That will also allow you to process mouse clicks and other normal sources of input, and if you supply the alpha channel information, Windows will make sure that your window is drawn properly at all times. If you don't want the window to be interactive, use appropriate styles (such as WS_EX_NOACTIVATE) like Koro suggests.