Display XP Style CFileDialog in Windows 7 - c++

I want to display CFileDialog like the image below in Windows 7.
As per msdn
if OFN_ENABLETEMPLATE is set and OFN_EXPLORER flag is not set, the system uses the template to create an old-style dialog box that replaces the default dialog box.
But even after doing that what I get is something like this.
Please help!

Try this:
CFileDialog fd(1,0,0,0,0,0,0,FALSE);
fd.m_ofn.lStructSize = sizeof(OPENFILENAME_NT4);
fd.DoModal();
The last parameter to CTOR specifies Vista-style to be false, and structure size of sizeofed with to reflect NT4 file-dialog.

I don't think you can. That windows belong to OS and is not implemented anymore. The the closest thing you can use is the old-style dialog box.
You can try to customize this one by hooking the window but it's not easy and I don't thing it worth.

Related

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 display a modal message box in C++ on Mac?

CFUserNotificationDisplayAlert and CFUserNotificationDisplayNotice creates a non-modal window and this is bad because it could bring your application UI in a very undesired state if you select the original application window (the message box is hidden but the applicaton does not respond).
The old SystemAlert was modal but this one doesn't fully support Unicode strings.
How can i display a message box as a modal window under Mac? I'm looking for someting similar to MessageBox from Windows?
I've implemented it with CFUserNotificationDisplayAlert and it doesn't return until the user closes the MessageBox.
If you want to take a look of the code, I have it in MessageBox function in Mac
there you will find a MessageBox function implemented for mac, it's only implemented for MB_OKCANCEL, but with little more code could cover the entire MessageBox flags and return values, is a good starting point.
It looks that CreateStandardAlert is the right solution because this one is modal.
DialogRef theItem;
DialogItemIndex itemIndex;
CreateStandardAlert(kAlertNoteAlert, CFSTR("aaa"), CFSTR("bbb"), NULL, &theItem);
RunStandardAlert(theItem, NULL, &itemIndex);
Have a look at NSBeginAlertSheet function or at NSApp's:
- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow
modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo
may be its what you want. Here is also a nice article about working with sheets.

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()..

How do I write a console application in Windows that would minimize to the system tray?

I have a written a Visual C++ console application (i.e. subsystem:console) that prints useful diagnositic messages to the console.
However, I would like to keep the application minimized most of the time, and instead of minimizing to the taskbar, appear as a nice icon on the system tray. I would also like to restore the console when the system tray icon is clicked.
How should I change my program to do this?
This is going to be an ugly hack.
First, you have to retrieve the hWnd / hInstance of you console application. Right now, I can only come up with one way:
Create a Guid with CoCreateGuid()
Convert it to a string
Set the title of the console window to this guid with SetConsoleTitle()
Find the hWnd of the your window with the Guid as the tile with FindWindow()
And you can do it from the usual way from this point. See http://www.gidforums.com/t-9218.html for more info.
Don't forget the rename your console window to the original title once you're done.
As you can see, even though this is possible to do, it's a horrible and painful solution. Please don't do it. Please do not minimize console applications to the system tray. It is not something you are supposed to be able to do in the Windows API.
You might want to write a separate gui to function as a log reader. You will then find it much easier to make this minimize to the tray. It would also let you do some other stuff you might find useful, such as changing which level of logging messages are visible on the fly.
To learn the console's hWnd you have two choices:
On Windows 2000 or later you can use the GetConsoleWindow() function. Don't forget to define _WIN32_WINNT as 0x0500 or greater before including windows.h to have access to this function.
If you want to run your program on earlier Windows versions as well then you must use something like the GUID trick described above.
Probably your best bet is to create a "Message-only window" (a message queue without a visible window) to receive the Notification Area messages.
The answer with a GUID is completely ridiculous (no sense at all)
The Console hWnd is of course given by GetConsoleWindow() (!)

How to add custom item to system menu in C++?

I need to enumerate all running applications. In particular, all top windows. And for every window I need to add my custom item to the system menu of that window.
How can I accomplish that in C++?
Update.
I would be more than happy to have a solution for Windows, MacOS, and Ubuntu (though, I'm not sure if MacOS and Ubuntu have such thing as 'system menu').
For Windows, another way to get the top-level windows (besides EnumWindows, which uses a callback) is to get the first child of the desktop and then retrieve all its siblings:
HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD);
while (wnd) {
// handle 'wnd' here
// ...
wnd = GetNextWindow(wnd, GW_HWNDNEXT);
}
As for getting the system menu, use the GetSystemMenu function, with FALSE as the second argument. The GetMenu mentioned in the other answers returns the normal window menu.
Note, however, that while adding a custom menu item to a foreign process's window is easy, responding to the selection of that item is a bit tricky. You'll either have to inject some code to the process in order to be able to subclass the window, or install a global hook (probably a WH_GETMESSAGE or WH_CBT type) to monitor WM_SYSCOMMAND messages.
Once you have another window's top level handle, you may be able to call GetMenu() to retrieve the Window's system menu and then modify it, eg:
HMENU hMenu = GetMenu(hwndNext);
You can use EnumWindows() to enumerate top level Windows.
I don't have a specific answer for the second part of your question, but if you subclass the window, I imagine you can modify the system menu.
EDIT: or do what Chris said: call GetMenu()
Re: the update - please note that not even Microsoft Windows requires windows to have a sytem menu. GetMenu( ) may return 0. You'll need to intercept window creation as well, because each new top window presumably needs it too.
Also, what you propose is rather intrusive to other applications. How are you going to ensure they don't break when you modify their menus? And how are you going to ensure you suppress the messages? In particular, how will you ensure you intercept them before anyone else sees them? To quote Raymond Chen, imagine what happens if two programs would try that.