Add location bar in your MFC application

zhaozj2021-02-08  255

problem

I just installed Windows® 2000 Release Candidate 1 on several machines. I don't know how to get the open dialog box with new Outlook style column in my MFC application (see Figure 1).

Figure 1 The New Open Dialog

Can I only set a logo, or if I need a new header file and a new public dialog DDL? I noticed that some old applications such as NotePad seem to get a new Open dialog without recompilation, but they are not MFC applications. Ideally, I want to get an application using the Old Dialog in Windows 9X and Windows NT®, and use the new dialog box in Windows 2000.

Warren Stevens

Reply

This problem is probably not to give you a happy answer. Windows 2000 new Open dialog is implemented with a new version of Commdlg.dll, which contains the "Places" section on the edge. Displaying its function is GetopenFileName, which is used in Windows 9x and Windows NT®. However, getopenFileName now uses a new version of OpenFileName, which is a structure that passes information between your applications and dialogs. The new structure has some additional members:

Typedef struct tagofn {

DWORD lstructsize; // is very important!

•••••

// I'm thinking that you always know and like it.

#if (_WIN32_WINNT> = 0x0500)

Void * pvreserved;

DWORD DWRESERVED;

DWORD flagsex;

#ENDIF / / (_WIN32_WINNT> = 0x0500)

OpenFileName, * lpopenfilename;

Yes, this is the case. Windows 2000 is the 5th version of Windows, with a 16-en-blended representation is 0x500. If you use the _Win32_winnt = 0x0500 compiler, OpenFileName will get three new members. The first two are reserved, the third logo domain, Flagsex, has a new OFN_EX_NOPLACESBAR section, which blocks the Places column. Windows - or more accurately, Commmdlg.dll - Use OpenFileName first member lstructSize to decide to display that dialog, if lstructsize is 76 (old size), Windows runs the old dialog; if it is 76 3'4 = 88 (new size), it runs a new dialog - this is the friendly Redmondtonians initially told me. In my study, I found this is not a complete picture.

But before I detailed, let's take a look at MFC first, discuss another problem. In MFC applications, you don't often call GetopenFileName directly, but use cfiledialog - or, the framework uses CFiledialog. When the user calls File | Open, the control is controlled by CWINAPP: ONFILEOPEN and several other functions, and finally reaches CDOCManager :: DOPTFileName, this function creates a cfiledialog. CfileDialog has a data member with an OpenFileName structure:

Class CfileDialog: Public ccommondialog {

OpenFileName M_OFN;

•••••

}

The size of this structure is the size of OpenFileName when friendly Redmondtonians compiles MFC42.DLL; in other words, the old size. Moreover, if you are performing a static connection, the MFC code is frozen in the mfc42.dll or nafxcw.lib, you can't set only m_ofn.lstructSize as a new size, because CfileDialog has other data members in addition to M_OFN, they will Covered by a member of the new OpenFileName. No longer delay, I started using extreme methods to avoid this problem. I think what I can do, similar to the use of CPROPERTYPAGE in MFC. The size of PropSheetPage and PropSheetHead is increasing from Windows 95 to Windows 98, this is to support Wizard style pages. In order to support the newly expanded structure, the MFC provides CPROPERTYPAGEEX and CPROPERTYSHEETEX. The initial class (without EX) still uses the old structure; and the new class uses the new structure. This is a mixture, especially because AFXDLGS.H has its own old structure definition (AFX_ OldpropsheetPage and AFX_OLDPROPSHEETHEETHEETHEETHER, but thus doing. I have done the same thing for CfileDialog. First of all, I derive a new CFiledialoGex class, which has a new M_OFN that contains the new OpenFileNameEx structure, I imitate the 0x500 version to define. I join these three new members and use m_ofn. Rewrive the cfiledialog function. Unfortunately, because most of the MFC code is fixed, there is no virtual function, which means copying the original whole class. But I have been determined.

After I think I have found all the places in M_OFN, I rewrite it, I am very happy to compile my code (on Windows 98), then run - the result I got the old style dialogue frame. And there is a mystery. I forgot to consider: If Windows 2000 uses lstructSize to determine the Open dialog box, why get a new dialog box when running in Windows 2000? what! Notepad.exe appearing in Windows 98 is clearly in the size of the old OpenFileName on LSTRUCTSIZE, so Windows 2000 must use something other than LSTRUCTSIZE to decide to run the dialog.

Here, I decided to go back to the head to re-consider the problem. I put the MFC on one side and try to call GetopenFileName directly. I rewrive my app on the onfileopen:

Void cmyapp :: onfileopen ()

{

OpenFileName OFN; // Older Version

MEMSET (& OFN, 0, SIZEOF (OFN);

OFN.LSTRUCTSIZE = SizeOf (OFN);

INT NRESULT = :: GetopenFileName (& OFN);

}

Because running through this exercise, I use the old 0x400 version of the SDK file (because the application can run both in Windows 2000, or run on Windows 9x), OFN.LSTRUCTSIZE has the old size. When I compiled and run, I got the old dialog on Windows 98, and I got a new dialog on Windows 2000 - just like NOTEPAD! It can therefore be said, in fact, Windows 2000 is sufficiently savvy to use new dialogs for old applications - but not old MFC applications. It is meaningless. Where is the difference between an MFC application? It must be a sign. In order to find the truth, I have added different signs in the OpenFileName structure until my program generates an old style window without a Places column. You, when I join the flag OFN_ENABLEHOOK for the OFN.FLAGS, my dialog returns to the past. I report this strange behavior to Redmondtonians, confirmed that "this behavior is designed."

Then, Windows 2000 determines whether the size of the OpenFileName and whether the dialog uses the HOOK process. If OpenFileName has an old size, Windows 2000 uses OFN_ENABLEHOOK to determine which dialog runs. If OpenFileName uses the hook process (or sets orn_enableTemplate), Windows 2000 Displays dialog box in the old style; otherwise, the new dialog is displayed. This explains why the MFC app shows the old dialog - because CFiledialog, just like all MFC's public dialog box, use the hook process. This is how the MFC embeds the public dialog into its message mapping system, which uses AFXWndProc to embed other windows in the same way.

Now you have seen the results: you confused. The only way to get a new style dialog box in an MFC application is to completely bypass the CFiledialog, call GetopenFileName directly, and do not use the hook process. Even if you compile your app with the new SDK file and Winver = 0x500, you still can't use the MFC because it has an old size of the library and DLLs. You can compile the MFC using Winver = 0x500, but who knows how will it? And if you really build a new MFC, you will have to release a new DLL and your app, give it a different name, because your new MFC DLL will definitely not use CFiledialog with other hopes. Compatible with the old size of other structures. Or, you can regenerate the MFC, then static connection, which will greatly increase your executable size if you don't re-realize Windows.

To the time of the cut, I heard that in the upcoming new Visual C ®, there will be a new version of the MFC DLL of different names. The new version of MFC will support new UI and APIs that appear in Windows 2000.

At the same time, I will leave the picture 2 to you, it takes from the latest SDK documentation, "Header File Conventions", provides the key to the Windows version problem. It explains you that, in order to reach a version of Windows and Microsoft® Internet Explorer, you must use the SDK header file to define which macros. Don't fall on the expressway of life.

Paul Dilascia is Windows : Writing Reusable Windows Code In C (Addison-Wesley, 1992) author, or a free consultant and well-known bookmaker. His contact method: cppqa@microsoft.com or http://www.dilacia.com.

转载请注明原文地址:https://www.9cbs.com/read-1945.html

New Post(0)