Different views can be seperated into different dlls in an MDI application:
Advantages:
I will try to explain this using an example. In my example, I have an EXE which I
call Host. It is an MDI application. Then I have 2 views inside 2 DLLs.
The name of these dlls are inside an INI file called HOST.INI.
The only catch is all DLLs that the HOST application can load must export a function by called Init().
Some kind of a rudimentary COM, eh? 🙂
At runtime, the HOST application loads the DLL & collects information from the INI
file such as its CMultiDocTemplate pointer, the handle to the image to be displayed
on the menu and string to be displayed on the menu to invoke the view.
All of this information is stored in a simple CList of a struct I defined.
struct __VIEWINFO
{
int iImage;
CString strLabel;
CMultiDocTemplate *pDocTemp;
};
In the OnCreate() function of the CMainFrame, the DLL is loaded.
HICON hIcon;
CString strLabel;
CMultiDocTemplate *pDocTemplate;
HINSTANCE hDLL;
LPDLLFUNC lpfnDllFunc;
UINT uReturnVal;m_List.SubclassDlgItem(IDC_LIST, &m_wndMyDialogBar);
m_pImageList = new CImageList();
m_pImageList ->Create(32, 32, TRUE,1, 4);int n = GetPrivateProfileInt(“dll”,”Total”,0,”host.ini”);
for (int i = 0; i < n; i++) { CString strDllName; strDllName.Format("dll%d",i+1); GetPrivateProfileString("dll",strDllName,0,strDllName.GetBuffer(15),15,"host.ini"); strDllName.TrimRight(); if(strDllName.IsEmpty()) continue; hDLL = LoadLibrary(strDllName); lpfnDllFunc = (LPDLLFUNC)::GetProcAddress(hDLL,"Init"); if (!lpfnDllFunc) FreeLibrary(hDLL); else { uReturnVal = lpfnDllFunc(&hIcon,&strLabel,&pDocTemplate); m_pImageList ->Add(hIcon);
__VIEWINFO *viewInfo = new __VIEWINFO;
viewInfo->iImage = m_pImageList->GetImageCount()-1;
viewInfo->strLabel = strLabel;
viewInfo->pDocTemp = pDocTemplate;
m_ViewList.AddTail(viewInfo);
}
}
m_List.SetImageList(m_pImageList,LVSIL_NORMAL);POSITION pos = m_ViewList.GetHeadPosition();
i = 0;
while(pos != NULL)
{
__VIEWINFO *viewInfo = m_ViewList.GetNext(pos);
ASSERT(viewInfo);
int nIndex = m_List.InsertItem(i++,viewInfo->strLabel,viewInfo->iImage);
m_List.SetItemData(nIndex,(ULONG)viewInfo->pDocTemp);
}
When the user selects the menu item to invoke the view the view can be opened using the following code
{
int nSel = m_List.GetNextItem(-1, LVNI_SELECTED);
if(-1 == nSel)
return;
CMultiDocTemplate *pDocTemplate = (CMultiDocTemplate *)m_List.GetItemData(nSel);
pDocTemplate->OpenDocumentFile(NULL);
}
DLLS:
The DLLs are MFC extension DLLs. As I mentioned earlier, all of the DLLs that HOST will use need to
export a function called Init. It is inside this function that the DLL returns it’s identity to the HOST application.
extern “C” AFX_EXT_API
UINT Init(HICON *hIcon,CString *strLabel,CMultiDocTemplate **pDocTemplate)
{
new CDynLinkLibrary(View1DLL);CWinApp* pApp = AfxGetApp();
ASSERT(pApp != NULL);*pDocTemplate = new CMultiDocTemplate(IDR_VIEW1TYPE,
RUNTIME_CLASS(CView1Doc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CView1View));pApp->AddDocTemplate(*pDocTemplate);
*hIcon = pApp->LoadIcon(IDI_VIEW1ICON);
*strLabel = “View 1”;
return 0;
}
I have put togother a very simple demo, which clearly explains the whole mechanism:
NOTE : Copy the ini file to the System directory
Date Last Updated: April 3, 1999