I am using the Native file dialog, so there is no layout() but want to add an additional control to the dialog. The builtin Notepad application has a perfect example when they allow the user to select the desired encoding (see below, to the left of the "Save" button). Is it possible to add an additional control in Qt5 while still using the native dialog?
TL;DR: Completely custom components are not available with native dialogs, filters can be controlled using QFileDialog::setNameFilters.
Qt's implementation of the native windows file dialog uses ABI::Windows::Storage::Pickers. You can check the implementation out here. Depending on the type of action you perform, the implementation uses IFileOpenPicker, IFolderPicker or IFileSavePicker.
If you want to manipulate the native dialog, this class would have to provide you with the option to do so. We can find the documentation for the FileSavePicker class here.
Going through the available options, you see that there is no interface to provide any specific custom UI element. If you would only need the filter, the QFileDialog provides you with the ability to set a filter using QFileDialog::setNameFilters. If you need a completely custom control/functionality, you unfortunately have to provide your own QDialog.
Related
My English is not perfect, sorry.
I am using Visual C++ 2019 Community, with MFC.
At CFileDialog class, I wish choose the file encoding: UTF-16 (little/big endian), UTF-8, ANSI, etc, at saving, with or without signature (2 or bytes what signs the encoding, at the begin of the file). This should be contacted to open/save button. In documentation of CFileDialog, I can add only separate buttons, not extending the open/save button like in Visual Studio, LibreOffice, etc. How can I do this? I am beginner with MFC, and desktop programs, but not beginner with C++. Thank you.
In the comments to your question you state:
Yes, I know. But there is no place to write this. Handler of Open menu is built-in part of MFC. At the source code, CFileDialog is not happen. I added handler OnFileOpen(). This has not paramters, empty at now, and the open menu item manages well. So, I do not know to where I type OFN_ALLOWMULTISELCT.
If you look at Technical Note 22 it mentions:
ID_FILE_OPEN Opens an existing document.
Note
You must connect this to your CWinApp-derived class's message map to
enable this functionality.
CWinApp::OnFileOpen has a very simple implementation of calling
CWinApp::DoPromptFileName followed by CWinApp::OpenDocumentFile with
the file or path name of the file to open. The CWinApp implementation
routine DoPromptFileName brings up the standard FileOpen dialog and
fills it with the file extensions obtained from the current document
templates.
One common customization of ID_FILE_OPEN is to customize the FileOpen
dialog or add additional file filters. The recommended way to
customize this is to replace the default implementation with your own
FileOpen dialog, and call CWinApp::OpenDocumentFile with the
document's file or path name. There is no need to call the base class.
As you can see, it states:
The CWinApp implementation
routine DoPromptFileName brings up the standard FileOpen dialog and
fills it with the file extensions obtained from the current document
templates.
But DoPromptFileName seems to be an undocumented function. You can either:
Debug into to MFC source code to see what it does and override it in your own app class,
Continue to roll out your own CWinApp::OnFileOpen override which uses your own CFileDialog.
I suggest you also read up on CFileDialog constructor documentation because it will assist you for basic customization. However, it sounds to me you need to do what #sergiol said in the comments and display your own CFileDialog (using either approach previously described) and add your own combo with your encoding options. Then handle accordingly.
Please note that I have no experience with that level of customization but it should get you going.
I'm currently using a GetSaveFileName dialog in my C++ application. (As I know this was superseded by the IFileDialog interface I choose not to limit this question to the deprecated API but to accept solutions for both implementations).
The challenge is to react to user input (i.e. the user typing manually into the filename input) and modify the file dialog accordingly.
As a specific example consider automatically changing the file type in the file type dropdown when the user manually enters a supported file extension.
I had hoped that the lpfnHook member of the OPENFILENAME structure could do that for me, unfortunately it seems there is no event triggered for typed characters in the filename input.
The correct solution is to create the saved file using whatever filename the user types in, and format the file's content based on the selected filter. The user should be free to change the filter as desired before closing the dialog.
There is no need to react to individual key presses. But, if you must, then when using the legacy GetSaveFileName() API, the only option is to subclass the filename Edit field directly, such as with SetWindowSubclass(). You can get the Edit field's HWND using GetDlgItem() with the edt1 or cmb13 control ID. The subclass can intercept key press messages, then send the dialog a CDM_GETFILEPATH message to get the currently typed filename, parse the extension from it, and manually update the filter combo box accordingly. You can get the combo box's HWND using GetDlgItem() with the cmb1 control ID.
However, on Vista and later, GetSaveFileName() is just a wrapper for the newer IFileSaveDialog API when ComCtl32 v6 is used, so the above is not guaranteed to work anymore. But you can try it.
If you use the newer IFileDialog API directly, it does allow you to customize the dialog with new controls via IFileDialogCustomize, but it does not allow you to subclass existing controls (it provides no access to the HWNDs of the dialog or its controls. You would have to resort to lower level hooks to access them). If you did manage to subclass the filename Edit field, you could use IFileDialog::GetFileName() to retrieve the currently typed filename, but you can't update the filter combo box directly, as IFileDialog::SetFilterTypeIndex() can't be called once the dialog is displayed (unless you can figure out a way to get its HWND). On Vista only, you could try not specifying a filter at all (or, at least, a filter of *.*), and then use a combination of IFileDialogCustomize::AddComboBox() and IFileDialogControlEvents::OnItemSelected to simulate a manual filter list, and IFileDialog::SetFilter() to specify which items appear in the dialog based on the selected filter. But, SetFilter() is deprecated and no longer works in Windows 7 and later.
My question is :
what is the main difference between Common File Dialog and Common Item Dialog ?
The MSDN just said that :
Starting with Windows Vista, the Common Item Dialog supersedes the
older Common File Dialog when used to open or save a file.We recommend
that you use the Common Item Dialog API instead of the Common File
Dialog API.
but it has not explained that what is the change log or main difference between them ?
thank for any help.
Common File Dialog was just a custom DialogBog. On the other end, Common Item Dialog is a full COM server.
Microsoft's documentation says :
The Common Item Dialog implementation found in Windows Vista provides several advantages over the implementation provided in earlier versions:
Supports direct use of the Shell namespace through IShellItem instead of using file system paths.
Enables simple customization of the dialog, such as setting the label on the OK button, without requiring a hook procedure.
Supports more extensive customization of the dialog by the addition of a set of data-driven controls that operate without a Win32 dialog template. This customization scheme frees the calling process from UI layout. Since any changes to the dialog design continue to use this data model, the dialog implementation is not tied to the specific current version of the dialog.
Supports caller notification of events within the dialog, such as selection change or file type change. Also enables the calling process to hook certain events in the dialog, such as the parsing.
Introduces new dialog features such as adding caller-specified places to the Places bar.
In the Save dialog, developers can take advantage of new metadata features of the Windows Vista Shell.
Simply it is harder to use from a simple low-level Win32 program.
I am developing an MFC application, can i use SHAutoComplete with a CEdit control? Also is there any ready made auto complete controls are available? or i need to use write all the code for creating the list box below the edit control as user types in edit control?
Just pass CEdit's m_hwnd member to SHAutoComplete. I don't think that extension warrant another class. The listbox is created by the AutoComplete object created by SHAutoComplete.
SHAutoComplete helps to autocomplete paths (system or URL).
If this is a combo box and you want to use autocomplete for suggesting string contained in the combo, you have to write a code to handle it.
There are samples you can find. One I found (working):
http://www.ucancode.net/Visual_C_MFC_COM_faq/Visual-C-Auto-completion-ComboBox-CComboBox.htm
I have seen some programs use custom open/save file dialogs in that manner they add some extra buttons there.
How can I do this?
Note that I want to use the basic open/save dialogs, so I dont have to re-create them, thus remain the buttons in the OS language. I only want to add some extra buttons there.
Update: As David Heffernan points out below, this answer applies to Windows platforms before Vista. From Vista onwards, you should use the
IFileDialogCustomize COM interface instead.
Basically, you have to set the OFN_ENABLETEMPLATE flag in the OPENFILENAME structure you're passing to GetOpenFileName()/GetSaveFileName(). This allows you to specify a custom dialog template in the lpTemplateName member of the same structure. This template will be used to build the dialog box. See Explorer-Style Custom Templates for all the details.
Note that if you add your own controls to the dialog box (buttons in your case), you should
also set the OFN_ENABLEHOOK flag and specify a callback function in the lpfnHook member of the OPENFILENAME structure, so you can handle the messages sent by these controls. See Explorer-Style Hook Procedures for more information.
This should help you
Customizing common dialog controls