how to show both icon and text on button on mfc? - c++

Code Used:
m_pButton->Create(L"ABC", WS_CHILD | WS_VISIBLE| BM_SETIMAGE,CRect(0,0,100,100),this,ID_BUTTON1);
m_pButton->SetIcon(::LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_ICON1)));
//above Code show neither showing image nor showing text.

You might use CMFCButton if you are using VS 2008 SP1 or higher.

BM_SETIMAGE is not a button style, but a message which is sent to the window in order to set a bitmap.
What you probably want is the BS_BITMAP style. Unfortunately as far as I know, it is not possible to have both text and a bitmap on a standard button. But you should find plenty of working implementations of a custom button class on sites like codeguru or codeproject.

BS_ICON and BS_BITMAP must be both unset to enable icon and text on the same button.
See https://msdn.microsoft.com/en-us/library/bb761822(VS.85).aspx

WPF might be able to do this. But, changing GUI topkits might not be an option anyway.

You could override the DrawItem method in CButton. For details check out the following links:
CButton::DrawItem
Owner drawn button - step by step

Related

How to mark multiple CButtons as clicked in MFC

I have a set of normal CButtons in MFC when a user clickes on one button its appearence should be changed to reflex the idea that it has been clicked sth like in the picture
i tried to change the style of the clicked button using the following code
button->SetButtonStyle(BS_DEFPUSHBUTTON);
Invalidate();
but the problem with this approach is that just one button at time is allowed to be marked so any ideas ? is the only way is to use a bitmap ?
Use CButton::SetState
This page has an example of what you want to do:
http://msdn.microsoft.com/en-us/library/ebw1hfe8(v=vs.90).aspx

MFC VSListBox change icons

Does anyone know if it is possible to change the icons on the MFC VSListBox Dialog Control?
Specifically I'm trying to change the folder icon to a '+' icon instead:
I haven't tried it myself, but CVSListBoxBase::AddButton() seems to be what you need.
CVSListBox derives from CVSListBoxBase, and when you call CVSListBoxBase::SetStandardButtons to set the buttons, it calls AddButton() for each button.
The documentation for CVSListBoxBase is unfinished, so you'll have to "play" with it, but you can read the code in afxvslistbox.cpp/.h

Windows XP Style: Why do we get dark grey background on static text widgets?

We're writing Windows desktop apps using C++ and Win32. Our dialog boxes have an ugly appearance with "Windows XP style": the background to the static text is grey. Where the dialog box background is also grey, this is not a problem, but inside a tab control, where the background is white, the grey background to the text is very noticeable.
In the past we have done a lot of our own drawing of controls, but these days we are trying to use the standard look'n'feel as much as possible, and to avoid overriding standard behaviour as much as possible.
We are using the Win32 API, which is getting a bit dated, but I think the problem occurs even with ATL. We are creating a DIALOGTEMPLATE. The text is in a "static" control (0x0082). The only flag we set for the style is "SS_LEFT". The text control is inside a tab control: "SysTabControl32" with only one flag: WS_CLIPSIBLINGS set on it. I've experimented with SS_WHITERECT and WS_EX_TRANSPARENT and other settings, to no avail.
All of this gets drawn with the standard Windows dialog box message handler. My main question is "what are we doing wrong?" rather than "how can I work around it?", although I'll settle for the latter if no-one can help me with the first.
Any ideas?
The usual way of implementing pages in a tab control is required to access MS's solution to this problem :-
Instead of creating individual controls in the tab area, create a modeless child dialog for each page and have the controls on that. Create the page dialogs with the main dialog (not the tab) as their parent and as the user switches between tabs, simply show and hide the relevant page dialog.
In the WM_INITDIALOG handler for each page, call the uxtheme API EnableThemeDialogTexture
With the ETDT_ENABLETAB flag this automatically changes the background color of the dialog and all its child controls to paint appropriately on a tab.
If you have overridden WM_ERASEBKGND or WM_CTLCOLOR* in your pages DialogProc you will need to revert to default handling (return FALSE) as these methods are where the dialog code is going to do its heavy lifting. The style bits should simply be set as though the child page dialog page was going to be created on a normal windows 9X tabbed dialog.
The reason why the background is gray is because that is the default.
To override it, you can process the WM_CTLCOLORSTATIC message in the parent window and return a custom brush.
Your problem is not with ATL or WinAPI. In MFC there is the same problem.
Set Tab control as parent window for Static controls. But I think that overriding WM_DRAWITEM is more flexible solution.
I've got Win32/MFC applications with labels inside tabs on dialogs, and the background colour looks fine on them (that is, it reflects the XP-look theme, rather than being flat grey) without any obvious special handling.
Under the hood what's supposed to happen is that the label posts a WM_CTLCOLOR message to its parent, which sets the device context up appropriately: the default handling in Windows should set the appropriate background colour, at least for dialogs and tab controls.
One possibility is that you're doing something non-standard in your handling of WM_CTLCOLOR: is it over-ridden somewhere in your application? Possibly you have some old code that is setting the label background colour in this way.
(Also, as Rob asks, are you using a manifest to get comctl32 6.0 into your application?)
We're not overriding the WM_CTLCOLORSTATIC message. There's no occurrence of this string in our source code and nothing like it in our message handlers.
We've worked around this problem by overriding the WM_DRAWITEM message for tab controls to paint their contents with the grey background (standard for dialog boxes without tab controls) rather than the white background (standard for the contents of tab controls).
brush = CreateSolidBrush(GetSysColor(COLOR_MENU));
FillRect(lpdis->hDC, &lpdis->rcItem, brush);
SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU));
wtext = ToWideStrdup(c->u.tabcontrol.Tabs[lpdis->itemID].name);
rect = lpdis->rcItem;
rect.top += DlgMarginY - 1;
rect.bottom += DlgMarginY;
DrawTextW(lpdis->hDC, wtext, -1, &rect, DT_CENTER | DT_VCENTER);
free(wtext);
DeleteObject(brush);
This is obviously a workaround, not a proper answer to my question.
Incidentally, we initialise the "common controls", of which I believe the tab control is one, using code like this...I don't suppose this is related to the issue?
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='*' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
...
hCommCtrl = GetModuleHandle("comctl32.dll");`
if (hCommCtrl) {
ptrInit = (TfcInit_fn) GetProcAddress(hCommCtrl, "InitCommonControlsEx");
if (ptrInit) {
data.dwSize = sizeof(INITCOMMONCONTROLSEX);
data.dwICC = ctrlClass;
if (ptrInit(&data) )
gCommCtrlsInitialized |= ICC_TAB_CLASSES | ICC_BAR_CLASSES;
}
}
Have spent an amazing amount of time to try to fix a problem so seemingly simple, tried almost every constant for hbrBackground without success.
As an amateur found that the most simple & time efficient fix was to simply create a "Static" class child window that envelops the entire window. Just another hack level fix though

MFC CEdit placeholder text

How do I have a CEdit control display placeholder text when it's empty, similar to the behavior of NSTextFields in Cocoa?
Ages ago, I wrote a custom paint routine to do it, seemed to work fine.
Sometime after, they introduced SetCueBanner to CEdit, but I can remember it:
a) not working correctly
or -
b) not behaving the way I wanted
Perhaps it will work fine for you. If not, I can see if I can find my old code and post what I did in the custom paint routine.
EDIT
I just checked the Win32 docs, I think this is why I abandoned it:
You cannot set a cue banner on a multiline edit control
you could create a small window over the top of it that contains the placeholder text. Then when the user sets the keyboard focus to it hide the window and if the focus is removed and nothing is in the box then show it.
The SetCueBanner banner function is now working.

Dynamically resizing CMFCPropertySheet with PropSheetLook_OneNoteTabs style

I'm trying to resize dynamically a CMFCPropertySheet to add a custom control at the bottom of each page.
As all Property Pages are not of the same height, I have a mechanism to increase the size if necessary.
For this, I have overridden the OnActivatePage method and by using SetWindowPos, I can resize the sheet, first, then the tab control, then the page and finally I can move the OK/Cancel/Help buttons.
It works fine with PropSheetLook_OutlookBar and PropSheetLook_Tabs styles but not with PropSheetLook_OneNoteTabs style. The page (or the tab) is not correctly resized (the lighter grey color of the page does not fill the sheet.
OneNote style OneNote http://www.freeimagehosting.net/uploads/th.ec91600664.jpg
Outlook style Outlook http://www.freeimagehosting.net/uploads/th.319b6938ab.jpg
Any idea? A MFC Feature Pack bug?
I found the problem. One needs to get a reference to the different tab control the OneNote version uses via GetTab() and resize it accordingly.
Just follow the instructions as seen in here.
Although the instructions are for CPropertySheet they work for the CMFCPropertySheet as well.
Some parts of the code is deprecated so you will need to make the following amendments.
Skip the XmnPropSheetCallback and DoModal implementations completely
In OnInitDialog just make a call to CPropertySheet::OnInitDialog(); and then call OnSize instead of doing everything presented in that code.