Dynamic create/destroy CComboBox - mfc

I need to switch between the CBS_DROPDOWN and CBS_DROPDOWNLIST styles at runtime. It looks like the only way to do this is to re-create the control.
So I have the following code:
CRect rect;
m_Combo.GetWindowRect(&rect);
m_Combo.DestroyWindow();
m_Combo.Create(CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | WS_VISIBLE, rect, this, IDC_MYCOMBO);
But all that happens is the combo disappears. What am I missing?
EDIT:
Using ModifyStyle is not an option because this style cannot be changed at runtime. The control must be recreated.
EDIT 2:
Okay, so I was in screen coordinates instead of dialog coordinates.
CRect rect;
m_Combo.GetWindowRect(&rect);
ScreenToClient(&rect); // SUPER IMPORTANT :)
m_Combo.DestroyWindow();
m_Combo.Create(CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | WS_VISIBLE, rect, this, IDC_MYCOMBO);
But now, the position is right but the font does not match the dialog font.

Won't it just be enough to set the control's font to the dialog font? That is, after immediately after recreating the control
m_Combo.SetFont(GetFont());

Related

SetWindowPos not moving or resizing window

When I call SWP to try and move a resize a specific window. It does not move or resize.
SetWindowPos(hWndWindow, NULL, 0, 0, 500, 500, SWP_NOZORDER);
The window handle is valid. I tried both getting the handle with FindWindow and by manually setting the handle value to the window I wanted to resize.
When I use GetWindowPlacement, it says the window is SW_NORMAL and not SW_MAXIMIZE.
The window style is
0x160b0000 (WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINMIZEBOX | WS_MAXIMIZEBOX)
and the extend style is 0x0.
I have also tried setting the window to SW_NORMAL with ShowWindow before calling SetWindowPos.
SetWindowPos and MoveWindow both return non false values saying that they didn't fail.
Why is SetWindowPos and MoveWindow unable to move or resize this window?

MFC Add thin border to WS_CHILD window

How can I add border to an embedded child window with (WS_CHILD | DS_CONTROL) style hosed by a CFormView?
I have tried to add border in Dialog Editor by selecting Thin border type but it doesn't work.
I also tried SetWindowLong and ModifyStyle. But the result is, WS_BORDER style is added but still no border.
Is it possible to add border to embedded child window by choosing styles? or should I draw it myself?
Thanks,
Guan
As #IInspectable points out, passing SWP_DRAWFRAME to SetWindowPos is required after changing the window styles.
I finally choose ModifyStyle to add WS_BORDER to my WS_CHILD window and pass SWP_DRAWFRAME flag to the third parameter: m_wndMainPage.ModifyStyle(0, WS_BORDER, SWP_DRAWFRAME). It internally calls SetWindowPos and update the child window. Window border is drawn as expected.

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.

WINAPI Button background

In WINAPI, I create a button like:
case WM_CREATE:
{
Start = CreateWindowEx(WS_EX_TRANSPARENT, "Button", "Start", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20, 50, 75, 25, window, (HMENU)ID_START, hInstance, NULL);
break;
}
The button looks like:
But I need it to look like this one (which I did in .Net):
How can I get rid of that black border/background?
Start = CreateWindowEx(WS_EX_TRANSPARENT, ...);
You got the black outline because you used the WS_EX_TRANSPARENT style flag. It isn't clear why you used it, there's not much you can do with it when you use the Button control. It is otherwise probably the least understood style flag. Pass 0 instead to get a normal looking button.
It is otherwise a lost cause to get the exact look of a .NET button, Winforms doesn't use the built-in Button control. It creates its own, using a custom renderer to get the gradient look. Reproducing that native code is a lot of work.
I think the border you are seeing is because the button has the "Default Button" property. If you turn that off, then it will have a normal border. The Default property just tells Win32 which button to activate if the users hits ENTER on the dialog/form. If you only have one button, then it will always have the default property. If you add a second, it will not.
The property is the BS_DEFPUSHBUTTON property, so in your CreateWindowEx call, you should be able to do something like:
Start = CreateWindowEx(WS_EX_TRANSPARENT, "Button", "Start", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | ~BS_DEFPUSHBUTTON, 20, 50, 75, 25, window, (HMENU)ID_START, hInstance, NULL);
If not, you'll have to set it with ModifyStyle or ModifyStyleEx, and pass it in the "Remove" parameter. I forget which one the specific styles have to be passed in, but if I recall correctly, it's the normal style params, NOT the EX params.
I haven't tested this, but try creating the button like this:
Start = CreateWindowEx(0, WC_BUTTON, "Start", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_TEXT, 20, 50, 75, 25, window, (HMENU)ID_START, hInstance, NULL);
break;
It also might depend on how you've created your main window. Can you post the code for your main window creation?
EDIT: I mis-identified the border as the default-button border. As David Hefferman pointed out, it's not. That is, I have now reproduced that border effect; when the program starts there is no border, but just a little mousing over the left button creates the border – at least in Windows 7.
Original answer follows:
The black border is because it's default. You shouldn't interfere with the system's visualization of default buttons etc. Users rely on those cues.
To change the font, maybe, like, WM_SETFONT?
Disclaimer: I haven't tried that. It might be you need to handle WM_CTRLCOLOR or something like that. Just try it out, and in the end, if the default buttons don't cut it for you, simply implement your own button.

CMFCMenuBar kind of Transparency for a CMFCToolBar

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.