Creating an MDI Application (C++ 5.0 and later)
Take the following steps to start an MDI (Multiple Document Interface) project and to add some code that positions, scales, and displays an image in a dialog box.
1. |
Start the Microsoft Developer Studio for Visual C++, version 5.0. |
|
2. |
Select the File >New menu option, select Project Workspace, and click the OK button. |
|
3. |
In the New Project Workspace dialog box, do the following: |
|
|
a. |
In the Type list box, select MFC AppWizard (exe). |
|
b. |
In the Name text box, specify mditutor. |
|
c. |
In the Location text box, specify the path of the project. |
|
d. |
In the Platforms list box, check Win32 Platforms. |
|
e. |
Click the Create button. |
4. |
In the Step 1 dialog box, do the following: |
|
|
a. |
Select Multiple Documents. |
|
b. |
Click the Next button. |
5. |
In the Step 2 of 6 dialog box, do the following: |
|
|
a. |
Select None for Database support. |
|
b. |
Click the Next button. |
6. |
In the Step 3 of 6 dialog box, do the following: |
|
|
a. |
Select None for OLE compound document support. |
|
b. |
Select ActiveX Controls for the type of OLE support. |
|
c. |
Click the Next button. |
7. |
In the Step 4 of 6 dialog box, do the following: |
|
|
a. |
Ensure that that 3D Controls and Printing and Print Preview are selected as features to include. |
|
b. |
Click the Next button. |
8. |
In the Step 5 of 6 dialog box, do the following: |
|
|
a. |
For comments, ensure that Yes, Please is selected. |
|
b. |
For how to use the MFC library, select As a shared DLL. |
|
c. |
Click the Next button. |
9. |
In the Step 6 of 6 dialog box, do the following: |
|
|
a. |
Select CMditutorView from the class list that AppWizard will create so that it appears in the Class name entry field. |
|
b. |
Change the Base class from CView to CFormView. |
|
c. |
Click the Finish button. |
10. |
Read New Project Information, and click OK. (The AppWizard creates the project files and opens the project.) |
|
11. |
Add #import and #include statements to your program so you can access the LEAD COM constants and classes: |
|
|
a. |
In the Project Workspace, click the FileView tab. |
|
b. |
Double-click the mditutor files folder to open it. |
|
c. |
Double-click the Header Files folder to open it. |
|
d. |
Double-click the StdAfx.h file to edit it. |
|
e. |
Add the following lines to the end of the file (keep in mind, you may have to change the path to where the dll's reside): |
#import "c:\\winnt\\system32\\ltrvr14n.dll" no_namespace, named_guids
#import "c:\\winnt\\system32\\ltr14n.dll" no_namespace, named_guids
#import "c:\\winnt\\system32\\ltrvw14n.ocx" no_namespace, named_guids
#import "c:\\winnt\\system32\\ltrio14n.dll" no_namespace, named_guids
#import "c:\\winnt\\system32\\ltrpr14n.dll" no_namespace, named_guids
#include "leadraster.h"
12. |
Change the resource file to add a LEAD RasterView control to the mditutor dialog template form as follows: |
|
|
a. |
In the Project Workspace, click the ResourceView tab. |
|
b. |
Double-click the mditutor resources folder to open it. |
|
c. |
Double-click the Dialog folder to open it. |
|
d. |
Double-click IDD_MDITUTOR_FORM to design the form. |
|
e. |
Select the TODO... text control; then press the Delete key to delete it. |
|
f. |
From the main menu, select Project > Add to project > Components and Controls. (The Component Gallery appears.) |
|
g. |
Click the Registered ActiveX Contols. |
|
h. |
Double-click the LEAD RasterView Control icon. (The Confirm Classes dialog box appears.) |
|
i. |
Ensure that both CLEADRasterView, CLEADRaster, and CPicture are checked. |
|
j. |
Click OK to complete the selection; then click Close to close the Component Gallery. (The LEAD RasterView control appears in the Controls toolbar.) |
|
k. |
|
|
l. |
Double-click the new LEAD RasterView control to edit its properties. |
|
m. |
Change the ID to IDC_LEADRASTERVIEW1. |
|
n. |
Press Ctrl-F4 to close all windows back to the Project Workspace. |
13. |
Do the following to add m_LEADRasterView1 to the CMditutorView class and link the variable to the LEAD RasterView control using dynamic data exchange: |
|
|
a. |
From the main menu, select View > ClassWizard. (The MFC ClassWizard dialog box appears.) |
|
b. |
Click the Member Variables tab. |
|
c. |
In the Class Name box, select CMditutorView. |
|
d. |
In the Control IDs list, select IDC_LEADRASTERVIEW1. |
|
e. |
Click the Add Variable... button. |
|
f. |
Specify m_LEADRasterView1 as the variable name, and Control as the category. |
|
g. |
Click OK to close the dialog box. |
14. |
Do the following to add code to the OnInitialUpdate function: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CMditutorView. |
|
c. |
In the Object IDs list box, select CMditutorView. |
|
d. |
In the Messages list box, select OnInitialUpdate. |
|
e. |
Click the Add function button. |
|
f. |
Click the Edit Code button to start entering the code. |
15. |
Edit the OnInitialUpdate() function to add the following code after the line that says //TODO: Add your specialized code here: |
ILEADRasterIO *pRasterIO=NULL;
CoCreateInstance(CLSID_LEADRasterIO, NULL, CLSCTX_ALL, IID_ILEADRasterIO, (void**)&pRasterIO);
CDocument *pDoc = GetDocument();
int nRet = pRasterIO->Load(m_LEADRasterView1.GetRaster(),
LPCTSTR(pDoc->GetPathName()), 0, 1, 1);
pRasterIO->Release();
if(nRet)
{
TCHAR szBuffer[30];
wsprintf(szBuffer, TEXT("Load Error: Error code %d"), nRet);
AfxMessageBox(szBuffer);
m_LEADRasterView1.GetRaster().SetBitmap(0);
// Parent of view is MDI Child frame window
CFrameWnd *pMDIFrame = GetParentFrame();
pMDIFrame->PostMessage(WM_CLOSE);
}
else
{
m_LEADRasterView1.SetPaintPalette(PAINTPALETTE_AUTO);
CRect rcRect;
GetClientRect(rcRect);
m_LEADRasterView1.MoveWindow(rcRect);
}
16. |
In the file Mditutor.CPP, find the function CMditutorApp::InitInstance() and comment out some lines as follows: |
// 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;
17. |
Press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CMditutorView. |
|
c. |
In the Object IDs list box, select CMditutorView. |
|
d. |
In the Messages list box, select WM_SIZE. |
|
e. |
Click the Add function button. |
|
f. |
Click the Edit Code button to start entering the code. |
18. |
Edit the OnSize() function to add the following code after the line that says //TODO: Add your message handler code here: |
if (IsWindow(m_LEADRasterView1.m_hWnd))
m_LEADRasterView1.MoveWindow(0, 0, cx, cy);
19. |
Press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CMainFrame. |
|
c. |
In the Object IDs list box, select CMainFrame. |
|
d. |
In the Messages list box, select WM_PALETTECHANGED. |
|
e. |
Click the Add function button. |
|
f. |
Click the Edit Code button to start entering the code. |
20. |
Edit the OnPaletteChanged() function to add the following code after the line that says //TODO: Add your message handler code here: |
CMDIChildWnd* pMDIChildWnd = MDIGetActive();
if (pMDIChildWnd == NULL)
return; // no active MDI child frame
SendMessageToDescendants(WM_DOREALIZE,
(WPARAM)pFocusWnd->m_hWnd, (LPARAM) TRUE);
21. |
Press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CMainFrame. |
|
c. |
In the Object IDs list box, select CMainFrame. |
|
d. |
In the Messages list box, select WM_QUERYNEWPALETTE. |
|
e. |
Click the Add function button. |
|
f. |
Click the Edit Code button to start entering the code. |
22. |
Edit the OnQueryNewPalette() function so that it appears as follows: |
BOOL CMainFrame::OnQueryNewPalette()
{
// always realize the palette for the active view
CMDIChildWnd* pMDIChildWnd = MDIGetActive();
if (pMDIChildWnd == NULL)
return FALSE; // no active MDI child frame (no new palette)
CView* pView = pMDIChildWnd->GetActiveView();
ASSERT(pView != NULL);
// just notify the target view
return((BOOL) pView->SendMessage(WM_DOREALIZE,
(WPARAM)m_hWnd, (LPARAM) FALSE));
}
23. |
Edit the MDITUTOR.H file and add the following line after the preprocessing: |
#define WM_DOREALIZE (WM_USER + 512)
24. |
Edit the MDITUTORVIEW.H file and insert the following line just before DECLARE_MESSAGE_MAP(): |
afx_msg LRESULT OnDoRealize(WPARAM wParam, LPARAM lParam);
25. |
Edit the MditutorView.CPP file and add the following function: |
LRESULT CMditutorView::OnDoRealize(WPARAM wParam, LPARAM lParam)
{
if (!m_LEADRasterView1.m_hWnd || !m_LEADRasterView1.GetRaster().GetBitmap())
return FALSE;
if(lParam)
{
return m_LEADRasterView1.SendMessage(WM_PALETTECHANGED, wParam);
}
else
{
UINT nColorsChanged = 0;
CDC* pdc;
pdc = theApp.m_pMainWnd->GetDC();
HPALETTE hpal =
(HPALETTE)m_LEADRasterView1.GetPalette((OLE_HANDLE) pdc->m_hDC);
if(hpal)
{
CPalette pal;
pal.Attach(hpal);
CPalette* oldPalette = pdc->SelectPalette(&pal, (BOOL) lParam);
nColorsChanged = pdc->RealizePalette();
if (nColorsChanged > 0)
m_LEADRasterView1.InvalidateRect(NULL, FALSE);
pdc->SelectPalette(oldPalette, TRUE);
}
theApp.m_pMainWnd->ReleaseDC(pdc);
return ((LRESULT) (BOOL) (nColorsChanged > 0));
}
}
26. |
In the MditutorView.CPP file, look for the following lines: |
BEGIN_MESSAGE_MAP(CMditutorView, CFormView)
//{{AFX_MSG_MAP(CMditutorView)
After these lines, add the following line:
ON_MESSAGE(WM_DOREALIZE, OnDoRealize)
Also, near the top of the file, add the following line:
extern CMditutorApp theApp;
27. |
Press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CMditutorView. |
|
c. |
In the Object IDs list box, select CMditutorView. |
|
d. |
In the Messages list box, select OnActivateView. |
|
e. |
Click the Add function button. |
|
f. |
Click the Edit Code button to start entering the code. |
28. |
Edit the OnActivateView() function so that it appears as follows: |
void CMditutorView::OnActivateView(BOOL bActivate, CView* pActivateView,
CView* pDeactiveView)
{
// TODO: Add your specialized code here and/or call the base class
CFormView::OnActivateView(bActivate, pActivateView, pDeactiveView);
if (bActivate)
{
ASSERT(pActivateView == this);
OnDoRealize((WPARAM)theApp.m_pMainWnd->m_hWnd,
(LPARAM) FALSE); // same as SendMessage(WM_DOREALIZE);
}
}
29. |
To remove the default printing functions, press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CMditutorView. |
|
c. |
In the Object IDs list box, select CMditutorView. |
|
d. |
In the Messages list box, select OnPrint. |
|
e. |
Click Delete function and answer YES to the dialog box. |
|
f. |
In the Messages list box, select OnBeginPrinting. |
|
g. |
Click Delete function and answer YES to the dialog box. |
|
h. |
Click OK to exit ClassWizard. |
|
i. |
Go to MditutorView.CPP and manually delete the functions CMditutorView::OnPrint() and CMditutorView::OnBeginPrinting(). |
30. |
To add new printing functions, press Ctrl-W to go to the MFC Class Wizard; then do the following: |
|
|
a. |
Click the Message Maps tab. |
|
b. |
In the Class Name combo box, select CMditutorView. |
|
c. |
In the Object IDs list box, select CMditutorView. |
|
d. |
In the Messages list box, select OnDraw. |
|
e. |
Click the Add function button. |
|
f. |
Click the Edit Code button to start entering the code. |
31. |
Edit the OnDraw() function so that it appears as follows: |
void CMditutorView::OnDraw(CDC* pDC)
{
CRect rcClip;
CSize winext;
CSize viewext;
CSize paintext;
CMditutorDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(pDC->IsPrinting())
{
pDC->SaveDC();
::GetWindowExtEx(pDC->m_hDC, &winext);
::GetViewportExtEx(pDC->m_hDC, &viewext);
paintext.cx = MulDiv((int) m_LEADRasterView1.GetRaster().GetBitmapWidth(), viewext.cx, winext.cx);
paintext.cy = MulDiv((int) m_LEADRasterView1.GetRaster().GetBitmapHeight(), viewext.cy, winext.cy);
::SetMapMode(pDC->m_hDC, MM_TEXT);
m_LEADRasterView1.Render((OLE_HANDLE) pDC->m_hDC, (float) 0, (float) 0, (float)
paintext.cx, (float) paintext.cy);
pDC->RestoreDC(-1);
}
}
32. |
To remove unused menu items, click the ResourceView tab of the Project Workspace, and do the following: |
|
|
a. |
Open the mditutor resources folder. |
|
b. |
Open the Menu folder. |
|
c. |
Double-click on IDR_MAINFRAME |
|
d. |
Click the File menu; then select the New menu item and press the Delete key. |
|
e. |
Double-click on IDR_MDITUTORTYPE. |
|
f. |
Click the File menu option; then select and delete the following items: New, Save, and Save As.... |
|
g. |
Press Ctrl-F4 twice to return to the Project Workspace. |
33. |
On the main menu, select Build > Build mditutor.exe to build the project. |
|
34. |
On the main menu, select Build > Execute mditutor.exe to run the project. |