Charles Steinhardt
MFC seems set up to open or create only standard files, not database records, so it puts up the standard File Open/Save Common Dialog and expects a file name to be entered. I would like to define my own Tree Control that displays information based on my recordset.
Dan, if Microsoft had wanted a mechanism to open new recordsets as opposed to files, don’t you think they would’ve implemented this behavior? Well, James “Mr.-Rebel-Without-a-Cause” Dean, maybe we’ll have to devise a method just for you!
Actually, you got me on a sore point! This is the first part of MFC that really tripped me up when I first started learning it. Following these non-intuitive initialization functions can be quite painful when all you want to do is the obvious. What you’re trying to do is very common, and I understand your frustration. On one hand, you need OnFileNew so that the MDI frame will appear; on the other hand, you don’t really want to open a “file” that is of your document type. You want to override the default behavior of OnFileNew. The simplest way is to edit the InitInstance that AppWizard created for you, following these four steps:
BOOL COnFileNewApp::InitInstance() { :
First, comment this local declaration out, create a new variable of this type called m_pDocTemplate, and place it as a member of your class (in the *.H file):
//CMultiDocTemplate* pDocTemplate;
Second, leave the remaining lines, but change any reference to pDocTemplate to m_pDocTemplate:
m_pDocTemplate = new CMultiDocTemplate( IDR_ONFILETYPE, RUNTIME_CLASS(COnFileNewDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(COnFileNewView)); AddDocTemplate(m_pDocTemplate); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame;
Third, comment out the following lines:
// Parse command line for standard shell commands, // DDE, file open //CCommandLineInfo cmdInfo; //ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line // if (!ProcessShellCommand(cmdInfo)) // return FALSE;
Fourth, add a function call something like this and leave the remaining lines:
GoAheadMakeMyView(); // The main window has been initialized, // so show and update it. pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); return TRUE; }
The GoAheadMakeMyView() function should do two things. It should create the default document/mdi/view of the type you created with new in m_pDocTemplate = new CmultiDocTemplate(..), and it should then perform the database processing you requested:
BOOL COnFileNewApp::GoAheadMakeMyView() {
This is the magic line that creates the doc/mdi/view:
m_pDocTemplate->OpenDocumentFile(NULL);
Perform your database initialization here if you’d like, or create a thread:
: : return TRUE; }
Stephen Beck, via MSN
O ye, Chico! Your best bet is to use resource-only DLLs and have your application load them dynamically and use the same IDs in both DLLs. Browse through your hard drive and I’m sure you’ll come across a few similar DLLs for other programs; they’re usually unimaginatively called RESDLL.DLL. These and other important issues relating to the development of multi-language applications are covered in detail in Nadine Kano’s Microsoft Press book, Developing International Software for Windows 95 and NT. I’m not trying to steer you away, it’s just that I know this book will be really beneficial.
Here’s how to make a resource-only DLL:
Create a DLL project. Just use AppWizard to create a DLL project for you.
Add a resource to the DLL project. Assume you’re adding a string table resource. Be sure to highlight the table name, right-click, select Properties in the pop-up menu, and change the resource to the language you’ll be placing in this resource file.
Compile the DLL just as if it were an EXE with resources.
CMyApp::InitInstance() { // one of the first things in the init code HINSTANCE hInst = LoadLibrary(“myres.dll”); if (hInst != NULL) AfxSetResourceHandle(hInst); // other initialization code would follow . . . }
Two other important points: Read the MFC Tech Note “TN057: Localization of MFC Components.” This Tech Note contains important information regarding circumstances such as yours, for example, saying that you must set the linker options to include /NOENTRY. This tells the linker that the DLL has no entry point-a logical conclusion since it has no code.
I’d use a single RESOURCE.H file for my EXE as well as for all the DLLs. One way would be to finish your EXE application first, and place all resources inside the EXE using one of the languages. Then, when everything is working, really screw things up and create the resource-only DLL by moving all the resources from the EXE to this new DLL project, along with a copy of the RESOURCE.H file. Then test the EXE to make sure that it’s loading the DLL properly and that the EXE utilizes all resources properly. Be sure to test every resource, because the compiler and linker won’t detect missing resources and your app will only fail at runtime! If you’re convinced the first DLL is complete, use the first DLL as a model for the remaining language DLLs. If I’ve failed to answer your question, well . . . what can I say other than, Je ne comprends pas, Monsieur!
Have a VC++ programming problem? Send it to “Dear Charles,” Visual C++ Developer, PO Box 72255, Marietta, GA 30007-2255; or visualcdev@pinpub.com. Be sure to include an e-mail address so Charles can contact you if he has additional questions.
An MFC/C++ consultant in New York City, the headquarters for the United Nations, Charles Steinhardt provides advanced Windows system consulting, including troubleshooting, for local and international clients. 70353.2604@compuserve.com.
To find out more about Visual C++ Developer and Pinnacle Publishing, visit their website at: http://www.pinppub.com/vcd/
Note: This is not
a Microsoft Corporation website.
Microsoft is not responsible for its content.
This article is reproduced from the April 1997 issue of Visual C++ Developer. Copyright 1997, by Pinnacle Publishing, Inc., unless otherwise noted. All rights are reserved. Visual C++ Developer is an independently produced publication of Pinnacle Publishing, Inc. No part of this article may be used or reproduced in any fashion (except in brief quotations used in critical articles and reviews) without prior consent of Pinnacle Publishing, Inc. To contact Pinnacle Publishing, Inc., please call (800) 788-1900 or (206) 251-1900.