MFC Wizard Appearance - mfc

I have a MFC wizard based application (CPropertySheet, CPropertyPage) created with vS2008. I am trying to give my app which is nearly completed a more modern look. I looked into CDHTMLDIalog but it looks like a lot of work and not too well documented. Next I thought I could use some of the features of the Feature Pack. I found a thread about this link text but have added the code mentioned in the thread to various places in my app but the appearance never changes.
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver);
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
CDockingManager::SetDockingMode(DT_SMART);
RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME | RDW_ERASE);
Have also replaced CPropertySheet with CMFCPropertySheet & CPropertyPage with CMFCPropertyPage
Thanks...

Define 'give my app more modern look'. I'm assuming you're not talking XP-style common controls here, but a different wizard layout. Do you want a header/banner graphic at the top or left side of your wizard? Look at the configuration parameters for the property sheet in m_psh.dwFlags : PSH_WIZARD97, PSH_WATERMARK, PSH_HEADER, ...
If you're talking about using the modern Office-style 'skins' for your wizard (Feature Pack style), you're out of luck. Can't do that for dialogs with the Feature Pack. Look into BCG Controls - it'll cost money but it's more up to date and you get extra features.
If it's something completely different what you want, please post mockups of what it should look like, and/or a screenshot of what it looks like now and what you don't like about it.

You should have:
CWinApp replaced with CWinAppEx in your main program file;
The Windows Common Controls 6.0 manifest implemented (either a RT_MANIFEST resource or a #pragma entry in your stdafx.h)
The code below at the beginning of the InitInstance() method (this code should have been added in the New Project wizard):
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);

Related

MFC dialog-based app with tab control - Visual Studio bugs/restrictions make recommended path impossible?

Create a dialog-based application in Visual Studio 2019. Insert a new dialog in the resources. Place a control (or two) on that dialog that you will later (try to) hook up to a variable (e.g. an edit box to enter your name).
Prepare to add that control variable by creating a class for this second dialog. If you inherit from CDialogEx (or perhaps other classes too - not tested), you can go on to add a variable for the control you added - easy, normal.
But if you had the "tab control" context from the title above in your mind, and chose to inherit from CMFCPropertyPage instead, can you add a variable subsequently? No you cannot - the class added makes no reference to the ID of the dialog resource, and so the Add Variable process has no basis to find a class to add the variable to.
I think this is a bug in Visual Studio... but I'm not 100% sure because I have always found the documentation around property sheets and property pages somewhat confusing. Specifically:
Do the classes implementing the tabs contents on a tab control "contain" the controls "on" the tab... or is the tab control really just a way to provide visual cues to show/hide sets of controls, and all of those controls and associated variables reside in one class?
I believe it's intended to be the former, but I can imagine that one uses a tab control because there are strong similarities between tab contents, and therefore potential benefits in implementing all the control variables in one place so as to avoid duplication. I just wish it was stated explicitly somewhere what the intention was.
Wider context: I'm trying to implement a dialog-based app with a tab control dominating that dialog. MS documentation says to implement a tab control using CPropertySheet and CPropertyPage to implement the tabbed dialog and tab contents. However, there is no (direct) way to create a dialog-based application whose main dialog inherits from CPropertySheet. When you look for examples of tab controls at the application level, you readily find things that deviate from the documented path considerably - using neither CPropertySheet nor CPropertyPage and using the WM_LBUTTONDOWN event instead of TCN_SELCHANGE, both without obvious reasons.
Any tips on (a) how to repair the apparent Visual Studio bug and/or (b) how to inherit from CPropertySheet for my application dialog and/or (c) where to find a clearer and more conventional example of tab control use at the top level would be greatly appreciated.
Given that there appears to be no clear and consistent way of approaching this, if (like me) you think "how hard can it be?", you might naively set out to see if you can create a new dialog-based application based on CDialog and manually convert it to CPropertyPage. You might fare better; I quickly hit a weird problem with the app compiling but not running - it could not load the window caption from the resource ID, despite the caption literally being there in black and white. Due to the weirdness, this was a red flag, and so to my mind problem (b) seems to be not worth the effort.
Without a CPropertySheet at the top level, there is no point having any kind of CPropertyPage or CMFCPropertyPage involved, making problem (a) pointless. That said, if you manually convert from (default) CDialogEx to CPropertyPage for your tab classes, it seems to have no problem compiling and running - the tabs just don't have any functionality that integrates with the main dialog.
Instead, I can now recommend working through the details of the video example even though it does strange things at first glance. You can achieve the desired result in more or less the same way as follows:
Use plain CDialogEx throughout, and so provide all the tab switching/showing/hiding/control work yourself (which the example demonstrates).
Create your main dialog and all tabs in the resource editor, adding the CDialog-based classes from there.
If you create your tab dialog resources via Insert Dialog (generic) instead of Add Resource (uses specific templates) then you will have to manually set certain dialog properties for each tab:
Border: Thin (or I preferred None)
Style: Child
System Menu: false
Title Bar: false
You can simplify the repositioning of the tabs (see below; it barely justifies the separate SetRectangle() function)
You should (probably) drive the tab changing from the TCN_SELCHANGE event instead of WM_LBUTTONDOWN
As noted, repositioning the tabs can be simplified to something like:
CRect tabRect;
m_tabControl.GetWindowRect( &tabRect );
for ( int i = 0; i < m_totalTabs; i++ )
{
m_pTabPage[ i ]->SetWindowPos( &wndTop, tabRect.left, tabRect.top, 0, 0,
i == m_currentTab? SWP_NOSIZE|SWP_SHOWWINDOW : SWP_NOSIZE|SWP_HIDEWINDOW );
}
Additional calls to ShowWindow() for each tab shown in the example are redundant.
One time, I had made on application as such. I don't remember if I used the Visual Studio new project wizard. Most probably, I did. But I will assist you on how to do it if you can not reach how to do it via the assistant.
The essential things:
Define the main dialog in the resources and the respective class in its H and CPP files.
In the YourAppClass::InitInstance you will need to have something like:
YourMainDlgClass dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");
TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n");
}
Insert a CMFCTabCtrl element in your dialog for tabs, instead of using a CPropertySheet.

Backgroung color toolbar and menubar in windows 7

I want to change the backgroung color of the toolbar and the menu bar of my application in Windows 7.
I have this look:
but I want this look:
So I'd like to know - this problem is connected with Visual Styles, and can be solved with some functions / changes of color scheme of application or I should write my own classes and set the particular color in RGBenter image description here.
If you have any example code, I would glad to see it.
As Cody indicated, you need to use visual styles. When you create a new project in Visual Studio, you’re given the opportunity to specify a visual style.
The new application uses the CMFCVisualManager class to render the individual UI components.
CMFCVisualManager...
Provides support for changing the appearance of your application at a
global level. The CMFCVisualManager class works together with a class
that provides instructions to draw the GUI controls of your
application using a consistent style.
If you’re dealing with an existing application, you would need to add the VisualManager class to your code. I would suggest you create a sample application and look at the code that gets generated. Once you understand how the code works, you can port what you need to your application.

Set Default view for CFileDialog to Large Icon

I am using CFileDialog to let the user select png images to display, But for png file I feel list view is inappropriate because user have to everytime change the view to Large icon, So what is needed is to by default set the view to "Large Icon" instead of list view.
Here's is what i have done, please let me know what should i add in-order to get Large Icon view. I am using Windows 7 VS 2010 MFC C++.
CFileDialog dlg(TRUE, _T("png"), 0, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, _T("Portable Network Graphics (.png)|*.png||"));
static char szTitle[] = _T("Select Icon");
dlg.m_ofn.lpstrTitle = szTitle;
static char szInitPath[] = _T("D:\\pngImagelist");
dlg.m_ofn.lpstrInitialDir = szInitPath;
Need help of all experts out their. Thanks in advance :)
You need to obtain IShellBrowser and use QueryActiveShellView to get the shell view, then QI for IFolderView on the shell view and call IFolderView::SetCurrentViewMode.
On the vista style file dialog (that is, if you don't disable the automatic upgrade in the constructor of CFileDialog, and you are running on Vista+), you can get IShellBrowser from the IFileDialog object via its IServiceProvider interface (QueryService with SID_STopLevelBrowser). On the Windows 2000 style file dialog, you can send an undocumented message WM_GETISHELLBROWSER to the file dialog to get its IShellBrowser interface. An example can be found at https://jiangsheng.net/2021/06/16/better-late-than-never/.
This is not an easy task as it requires the use of Spy++ and an understanding of the underlying Windows Shell environment. The list view control nested within the CFileDialog is actually a representation of what the Windows Shell sees. Spy++ will reveal that it's actually "ShellDLL_DefView". You can access this control using the methodology in Paul DiLascia article. It's dated, but, the idea should still be valid.

How to replace/update an ActiveX control in a MFC dialog

I have an older MFC project build in VS 2003 that I want to port to VS 2010. The project uses an ActiveX control for grids, namely, VSFlexGrid7 from Component One. The problem is, that this version of the ActiveX control does not work in Windows 7 (which is what I have). There is a newer version of the grid, namely, VSFlexGrid8 which should be compatible with Windows 7.
The solution would be to replace all the older controls with the newer ones.
My question is, what would be the steps in replacing the controls, without touching other parts of the project. What is the simplest method to accomplish this? Do I have to modify classes, resource IDs, etc.?
[Solution: Replace CLSIDs in the .RC file]
The ActiveX control is bound to the resource file via the guid that represents the control. If you were to look inside the .rc file you will see the control with the associated guid. In your case, it's probably best to completely remove the control from the dialog (using the resource editor) assuming that you can drag the newer version onto the same dialog. Once you've done that, you'll need to generate a new class wrapper for the control. The class wizard should be able to handle that for you. Once you've got a new class wrapper that represents the control, you'll need to replace the prior wrapper class in your source code.
Usually the control is created somewhere in your dialog code with CreateInstance.
If the interface is compatible (I assume it is) , you just have to change the name or GUID that is used in the CreateInstance Code.

What are the possible classes for the OpenThemeData function?

I'm trying to call the OpenThemeData (see msdn OpenThemeData) function but I couldn't determine what are the acceptable Class names to be passed in by the pszClassList parameter.
HTHEME OpenThemeData(
HWND hwnd,
LPCWSTR pszClassList
);
Could anybody tell me what are the acceptable class names that I can pass into that parameter?
Thanks!
The article Parts and States on MSDN contains a table which shows the control classes, parts, and states. The values in the table are defined in Vsstyle.h and Vssym32.h.
Here is a quick reference:
BUTTON, CLOCK, COMBOBOX, COMMUNICATIONS, CONTROLPANEL, DATEPICKER, DRAGDROP,
EDIT, EXPLORERBAR, FLYOUT, GLOBALS, HEADER, LISTBOX, LISTVIEW, MENU, MENUBAND,
NAVIGATION, PAGE, PROGRESS, REBAR, SCROLLBAR, SEARCHEDITBOX, SPIN, STARTPANEL,
STATUS, TAB, TASKBAND, TASKBAR, TASKDIALOG, TEXTSTYLE, TOOLBAR, TOOLTIP,
TRACKBAR, TRAYNOTIFY, TREEVIEW, WINDOW
The answer to the question Windows Visual Themes: Gallery of Parts and States? provides a "Parts and States Explorer" application where you can browse and test most of the styles.
I know this is an old question, but I want to give an updated answer (2018) for those who come here from Google.
The accepted answer of DavidK says to look into the file "AeroStyle.xml" where the themes are defined. This file was part of the Windows 7 SDK, but has been removed from the Windows 10 SDK, so the accepted answer is not useful anymore.
The answer of splash links to the MSDN where the list of theme names, parts and states is highly incompetlete and not updated.
The themes are drawn by UxTheme.dll which reads the images and colors, etc. from the file aero.msstyles in the folder C:\Windows\Resources\Themes\Aero on Windows 10.
To see the classes inside the XYZ.msstyles file use msstyles.Editor:
https://github.com/nptr/msstyleEditor
Several themes can only be obtained if you pass the correct window handle. There seems to be an automatic mechanism which detects the type of control from a window handle. If you pass the handle of the wrong window you may get another theme handle than expected or even NULL.
Microsoft internally has changed all their code to use OpenThemeDataForDpi() instead of OpenThemeData() because each monitor on Windows 10 may have a different resolution.
The problem that we have here is a severe lack of documentation in the MSDN and a lack of an API function to enumerate all availabe themes. Shame on Microsoft (once more).
You can look in "AeroStyle.xml" as a previous poster noted, which gives an exact list for Vista/Aero. However, if you want to play safe (and you probably do) the class names should, in general, be Windows class names of Windows common controls. For example, push buttons and check boxes use the class name "Button", the edit control "Edit", etc. I generally pick the class name of the control that's closest to whatever custom element I'm working on is, and use the theme data for that. That way you'll get code that works with XP, Vista and (hopefully) Windows 7, regardless of what the user's selected theme actually is.
However, unless you use raw Win32 a lot, you probably don't do much control creation directly using the class name. The class names are rather liberally sprinkled throughout MSDN. A good place to start is usually the "CommCtrl.h" file from the Platform SDK, which has a lot of them, and they're always described in the MSDN help on the individual common controls. You can also often learn them by looking at how dialogs are defined in .rc files by opening them in a text editor: these contain the class name for the controls.
Class names depend on the theme. For example, as the documentation for OpenThemeData states:
Class names for the Aero theme are
defined in AeroStyle.xml, which is
found in the Include folder of the
Microsoft Windows Software Development
Kit (SDK).
It has nothing to do with Aero, which even doesn't exits on XP !
See the source code of OpenThemeData()..