Modern Operating Systems all have the concept of file systems, so sometimes users need to specify files themselves. In the command line, you can pass the specified file as a parameter. In the graphic interface, you can select an interactive mode. In Windows, we call it the open file dialog box (open file dialog ), is a Common Dialog Box (the General dialog box also includes the color selection dialog box, page Setting dialog box, Print dialog box, and so on ). Today we are going to use winx to encapsulate the open file dialog box and save the file dialog box. We will refer to them as the file dialog box. Winx provides two file dialogs, including single file dialog box and multi-file dialog box. Let's take a look at the differences between winx operations, API methods, and MFC methods.
Our practical example program is step008-openfiles, which contains two projects:
API to open a file dialog box mainly through a structure (Openfilename) And an API (Getopenfilename). In addition, there are some auxiliary functions. Openfilename is defined as follows (modified for convenience ):
Typedef struct tagofn ...{
DWORD lstructsize; // The number of bytes in the structure.
Hwnd hwndowner; // The owner window handle of the dialog box, that is, the parent window.
Hinstance;. // contains the application handle of the dialog box.
Lptstr lpstrfilter; // filter string
Lptstr lpstrcustomfilter; // custom filter
DWORD nmaxcustfilter; // the maximum length of the custom filter string
DWORD nfilterindex; // default filter mode index
Lptstr lpstrfile; // full path file name
DWORD nmaxfile; // Maximum File Name Length
Lptstr lpstrfiletitle; // file name
DWORD nmaxfiletitle; // Maximum File Name Length
Lpctstr lpstrinitialdir; // initial directory
Lptstr lpstrtitle; // The title string of the dialog box.
DWORD flags; // flag. The action status of the dialog box is specified here.
Word nfileoffset; // the offset of the file name in the full path
Word nfileextension; // extension offset
Lpctstr lpstrdefext; // default Extension
Lparam lcustdata; // custom data passed to the hook function
Lpofnhookproc lpfnhook; // Hook Function
Lpctstr lptemplatename; // dialog box Template Name
} Openfilename, * lpopenfilename;
For more information, see msdn.
In API mode, if you want to display the open file dialog box, you need to call the API function getopenfilename. Its parameter is the pointer of the above structure. If you want to display the save file dialog box, you need to call the API function getsavefilename. The prototype is as follows:
Bool getopenfilename (lpopenfilename lpofn );
Bool getsavefilename (lpopenfilename lpofn );
The returned values that users care about are also returned through parameters. After all, what users need is to get a full path and file name through the display dialog box.
However, a bunch of members in the openfilename structure need to be specified by the user. It is really troublesome for a simple dialog box to open or save files.
MFC encapsulates the open and save file dialog boxes, which are included in the cfiledialog. To display the file dialog box in MFC mode, you must first construct the cfiledialog object and then call the domodal method to display the dialog box window. Let's take a look at the cfiledialog constructor and domodal function prototype:
Cfiledialog (bool bopenfiledialog, lpctstr lpszdefext = NULL, lpctstr lpszfilename = NULL, DWORD dwflags = empty | optional, lpctstr lpszfilter = NULL, cwnd * pparentwnd = NULL );
Virtual int domodal ();
It can be seen that MFC places all parameters specified to the openfilename structure in the cfiledialog constructor, and domodal has no parameters.
By viewing the source code of MFC, it is found that openfilename is implemented as a public member variable of cfiledialog. MFC also provides virtual functions that can change the behavior of cfiledialg by reloading virtual functions.
The encapsulation of MFC seems to simplify the operation. For example, the open file dialog box and the Save file dialog box are encapsulated in a class, which seems to have the same interface. However, the biggest drawback of the MFC method is that users are not completely isolated from the underlying layer. Users also need to understand the meaning and usage of members of the openfilename structure. Generally, a file dialog box, including a multi-file dialog box, is a type of GUI interaction that users want to obtain user input, user-selected or file name and path to be saved, and so on. Some of the less common ones should not be the obstacle for users to master basic usage.
The winx file dialog box is defined in the commondialogs. h file. Winx defines the single file dialog box and multi-file dialog box respectively. Let's take a look at its definition of a single file:
Enum filedialogtype
...{
Fdtsavefiledialog = 0,
Fdtopenfiledialog = 1,
};
Template <int nfiledlgtype>
Class filedialogt: Public openfilename
...{
//...
};
Typedef filedialogt <fdtopenfiledialog> filedialog;
Typedef filedialogt <fdtopenfiledialog> openfiledialog;
Typedef filedialogt <fdtsavefiledialog> savefiledialog;
Enumeration defines the file dialog box type (open or save), and ultimately shows different classes, openfiledialog and savefiledialog. The most interesting thing is that, unlike MFC, winx encapsulates the openfilename structure as a member variable and only derives from this system structure. In fact, there is no difference between the two objects in the binary structure, but the specific Writing Method in the class is simple in winx mode, unlike the MFC. in XXX format, winx can directly reference the openfilename member name.
Of course, the above has basically no effect on end users. Users are concerned about whether it is easy to use. Assume that you need a single file to open the file dialog box, just like in the actual analysis tutorial instance, you only need the following code:
Winx: openfiledialog DLG (_ T ("text files (*. TXT)/0 *. TXT/0all files (*. *)/0 *. */0 "));
If (idok! = DLG. domodal ())
Return-1;
Specify the file filter in the constructor of the winx: openfiledialog class (I think I usually have different filters). All other parameters follow the common default values, and finally the domodal is ready.
Let's take a look at the prototype of the winx: openfiledialog class constructor and domodal function:
Filedialogt (
In lpctstr szfilter = NULL,
In lpctstr szdefext = NULL,
In lpctstr szdlgtitle = NULL,
In lpctstr szinitfilename = NULL,
In uint ninitfilterindex = 1,
In lpctstr szinitialdir = NULL );
Int winx_call domodal (
Hwnd hwndparent = NULL, int dlgtype = nfiledlgtype, hinstance hinst = getthismodule ());
It seems that compared with MFC, there are only some changes in the Parameter order and function. In a deeper sense, winx clears the abstraction and concrete points. The parameters in the constructor are all abstract, and they do not depend on the type (open or save), parent window, and resource handle of the file dialog box, the parameters at these levels are moved to the domodal and specified the moment before the dialog box is displayed. That is to say, you can construct an openfiledialog object and display it in different forms, such as changing the parent window, changing the type, and changing the resource handle.
Finally, the single filedialog template definition is divided into three classes. What is the guiding ideology of this design? In my opinion, if you are clear about the dialog box you want to use (whether to open the file dialog box or save the file dialog box), you can directly select the desired class, other parameters can all use the default one, which is easy to use. The user wants to change the dialog box behavior in the intermediate process, and has the opportunity to modify it and use it flexibly. This is a small problem. winx still thinks a lot for users.
Besides encapsulation of Multi-file dialog boxes, the basic idea is the same. If you are interested, you can check the source code of commondialogs. h.
Unfortunately, winx only encapsulates the file dialog box in the general dialog box.