CMFCMenuBar kind of Transparency for a CMFCToolBar - c++

I want to let a Toolbar in MFC (CMFCToolBar) appear transparent just like the default appearence of a CMFCMenuBar.
I'm using the control styles TBSTYLE_FLAT | TBSTYLE_TRANSPARENT when creating the toolbar and do get a transparent background. However, I still have a top and bottom border and the gripper stays the same as well.
SetBorders(0,0,0,0) or removing the styles CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM won't do the trick.
And using CCS_NODIVIDER (for apparently removing the 2px top border) doesn't have an effect either.
I could imagine that a custom CMFCVisualManager class might be the way to go (e.g. playing with CMFCVisualManager::OnFillBarBackground), but couldn't figure anything out yet regarding that.
To be clear, this is the code I currently have:
m_wndToolBar.CreateEx(this /*MainFrame*/, TBSTYLE_FLAT | TBSTYLE_TRANSPARENT,
WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP)
LoadToolBar(IDR_MY_TOOLBAR, 0, 0, TRUE);
m_wndToolBar.SetPaneStyle(GetPaneStyle() & ~(CBRS_BORDER_TOP |
CBRS_BORDER_BOTTOM |
CBRS_BORDER_LEFT |
CBRS_BORDER_RIGHT));
m_wndToolBar.SetBorders(0,0,0,0);
Here's where I am right now:
And this is my goal:
Any help is highly appreciated!

Have you tried calling SetExclusiveRowMode(true)? Menu bars have exclusive row mode set, toolbars don't by default.

Related

Z- Ordering in PURE WIN32 Application

I have a Dialog Box created using CreateDialog(). I have two static picture controls, one with SS_BLACKFRAME, and the other is a Bitmap type picture control which is set using SendDlgItemMessage().
The ordering in the .rc file is:
CONTROL "",IDC_PROMPT_RIBBON,"Static",SS_BLACKRECT,0,0,260,30
CONTROL "",IDC_REBOOT_ICON,"Static",SS_BITMAP,10,11,10,9
The IDC_REBOOT_ICON uses an HBITMAP.
Everything works as expected when IDC_PROMPT_RIBBON is disabled.
When it is enabled, the icon is always drawn below the first control, even though it has to be drawn above it. I have tried to manually set the z-order via SetWindowPos() but it does not seem to do anything.
What am I missing?
What it looks like in the designer (What I am supposed to get):
What I get instead:
On stepping through the program, I can indeed confirm that the Image is being drawn first. Why is this happening?
PS. No MFC.
My Dialog Styles are
DS_ABSALIGN | DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION

PrintWindow on inactive desktop in Windows 10

So, I've run into a problem while trying to take a picture of a window located in an inactive desktop using the PrintWindow API and it is starting to get on my nerves.
The problem is that with a specific window, even though PrintWindow succeeds and I get the image of the window I want, that image is always an outdated copy of the last time the desktop was active. At first I thought the window was not receiving any input, but after some checking I noticed that it still receives and processes input, but does not render any changes until its desktop gets activated again. I tested in Windows 7 and 10, and that only happens in Windows 10.
After some more checking, I found out that the main window in fact updates itself just as expected and it is its child, which covers all the client area of the main window, who is to blame. The 2 windows were created with the following styles:
Class Styles: 0x00000003 = CS_VREDRAW | CS_HREDRAW
Parent Extended Styles: 0x00000000
Parent Standard Styles: 0x96000000 = WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
Child Extended Styles: 0x00000020 = WS_EX_TRANSPARENT
Child Standard Styles: 0x56300000 = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_HSCROLL | WS_VSCROLL
I have already tried an absolutely uncountable amount of things trying to get this problem solved, and I've searched the web extensively, all to no avail. I am so frustrated that I am well ready to give up if noone can at least come up with an explanation for this.
Windows does not render windows that are not visible. You are getting the current image, which is the same image you would get when getting the little preview window when hovering over the task bar icon.
Without the program itself explicitly calling the render function the window will not update. It's not going to be possible to get a screenshot of how the window would currently look if it updated.

Groupbox resizing issue with radio buttons on top

I'm not sure what I'm doing wrong here. I'm trying to implement a resizing dialog window using MFC. The code is pretty straightforward. I override the following sizing notification:
void CMyDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
//...
//First move the groupbox, pGroupbox is of type CWnd
pGroupbox->MoveWindow(rcGroupbox);
//And then move all radio buttons in it
//Each is moved the exact same way
//pEachRadioButton is of type CWnd
pEachRadioButton->MoveWindow(rcEachRadioButton);
}
But what I get as a result is this.
First here's the initial groupbox:
It happens only when I start dragging the bottom of the main window frame down. I get this artifact:
Note that the radio button positions themselves are correct. If I move the mouse over either of them, it redraws itself correctly (like this "shut-down" button):
Here's the layout of the dialog itself:
IDD_MY_DIALOG DIALOGEX 0, 0, 437, 190
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "My dialog"
MENU IDR_MENU_MAIN
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
PUSHBUTTON "&Cancel",IDCANCEL,381,169,50,14
GROUPBOX "When Tasks Are Completed",IDC_STATIC_WHEN_COMPLETED,7,113,423,36
CONTROL "Close the pro&gram",IDC_RADIO_CLOSE_PROGRAM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,26,129,73,8
CONTROL "Put computer to sleep",IDC_RADIO_SLEEP,"Button",BS_AUTORADIOBUTTON,122,129,84,10
CONTROL "Hibernate computer",IDC_RADIO_HIBERNATE,"Button",BS_AUTORADIOBUTTON,229,129,78,10
CONTROL "Shut down computer",IDC_RADIO_SHUT_DOWN,"Button",BS_AUTORADIOBUTTON,330,129,81,10
DEFPUSHBUTTON "&OK",IDC_BUTTON_SET,311,161,67,22
END
I did some search and found this article, but unfortunately setting those styles did not fix the bug.
Any idea how to fix this?
PS. I'm testing it on Windows Vista, 7, or 8 with visual themes enabled.
When you move a window, the window manager will move the current image of the window as it exists. Unfortunately because you moved the frame first, all those windows got clipped. Flipping them around wouldn't help, because then the tops would get clipped.
The easy way to fix it would be to call InvalidateRect on each control after moving it.
The better way would be to call BeginDeferWindowPos before you start moving anything, then EndDeferWindowPos when you're done so that all the windows move together.
P.S. Windows prefers for the group box to come after the radio buttons in the tab order, that might make a difference too.

How to implement a re-sizable border + making it invisible using MFC?

I was wondering, how do I create a re-sizable border in MFC without showing the border itself?
IDD_GADGETTRANSLUCENTDIALOG DIALOGEX 0, 0, 320, 201
STYLE DS_SETFONT | DS_FIXEDSYS | WS_SYSMENU | WS_THICKFRAME
The "WS_THICKFRAME" style provides the functionality of resizing, but I don't want the border to be visible. How would I go about doing this?
Or handle WM_NCPAINT and draw the borders (and caption) yourself...
I created a MCF application that has the borders (and frame) as optional. When in the mode of no border, I still wanted it resizable and movable, so essentially in OnMouseMove if I was within a few pixels of the edge of the window, I set the appropriate cursor (e.g. IDC_SIZENESW for the top right corner) then if nFlags & MK_LBUTTON did a SendMessage using WM_SYSCOMMAND and the appropriate size command (e.g. SC_SIZE + WMSZ_TOPRIGHT) and let the CWnd::OnSysCommand default handler process it. Also, same trick works with SC_MOVE...

WinAPI: Create resizable window without title bar, but with minimize/maximize/close buttons (as Firefox/Chrome/Opera)

If you look at the windows of the browsers Firefox, Chrome or Opera, you'll notice that their windows
have minimize/maximize/close buttons
are resizable
but have no title bar
I'm interested: how can I create such a window?
What I have already tried:
I looked around on StackOverflow (and googled, too), and found this: opening a window that has no title bar with win32
Unluckily, this didn't help completely:
The first step was to extend the solution proposed on opening a window that has no title bar with win32
hWnd = CreateWindow(szWindowClass, szTitle, WS_BORDER,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
SetWindowLong(hWnd, GWL_STYLE, WS_SIZEBOX);
// See remarks on http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545.aspx
SetWindowPos(hWnd, 0,
0, 0, 0, 0, // Position + Size
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
Of course, this delivers no minimize/maximize buttons, but on the other hand, if I want minimize/maximize buttons, I have to do:
SetWindowLong(hWnd, GWL_STYLE, WS_SIZEBOX | WS_MAXIMIZEBOX |
WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION);
Why does this combination seem to be necessary? First I probably want WS_MAXIMIZEBOX | WS_MINIMIZEBOX since I want these buttons.
But http://msdn.microsoft.com/en-us/library/ms632600.aspx says that if I set one of WS_MAXIMIZEBOX and WS_MINIMIZEBOX, I also have to set WS_SYSMENU. And when I set WS_SYSMENU, I also have to set WS_CAPTION but this is not what I want, because I wanted to avoid the title bar (indeed: if WS_CAPTION is not set, no minimize/maximize buttons are shown).
So what is to do?
The programs remove the non-client area (the title bar) and have a bunch of custom handling for reproducing the window buttons, icons, system menu etc. The benefit of this is that they can draw to the new "title bar", which is actually part of the standard client area, adding tabs or other custom controls.
The following two articles will show you how to do this on Vista and above (using the DWM):
Setting up a custom title bar on Windows Vista / 7
Setting up a custom title bar - reprise This one has a demo app showing the result of a number of variations / options.
This is very complex to do and get right, so the above two articles are invaluable. The author must have put a lot of work into them! Both links have example code written in Delphi, but it should be easy enough to translate it to C++ - the concepts are identical, it's just syntax.
You might also be interested in general resources on Glass and DWM, since it's all closely related. You'll spot the above two links included in that list :)
You can create a window with or without caption - whatever is more appropriate from the point of view of desired customization (that is "without" is you want to do it "without title bar" as you say), and the important wart is that you take over painting non-client area - this is the key thing.
At this point, there is no one to paint your mimimize/maximize buttons already. It does not however mean that you have to do the painting right from scratch and mimic standard UI. There is DrawFrameControl and friends API where you can use DFCS_CAPTIONMIN argument and have minimize button painted for you. You will also want to respond to other non-client area messages, e.g. handle WM_NCHITTEST to tell Windows where your new window buttons are.
You might also want to check Visual Styles Reference to leverage theme-enabled drawing API such as DrawThemeBackground.
A simple example of this activity is putting an additional button onto caption, such as described in detail here: CCaptionButton (buttons for the titlebar).
I believe they create a normal window and then paint over the title bar with their custom widgets/tabs. This is evident in Firefox, as when it hangs you can see the normal Windows title bar appear over the tabs.