在多文档编程框架中,要显示多个视图,如何将视图类封装到DLL中?运行时将其创建此视图,并嵌入到到主框架中,以此实现模块编程呢?步骤如下:
(1)创建一个MFC的扩展DLL工程,在资源中添加一个FormView窗口,并创建相应的类CDeviceManageView。添加导出函数如下:
在stdafx.h文件中定义全局变量
//全局变量
extern CWnd * g_pParentWnd ;
extern BOOL g_bIsCloseView ;
//在dllmain.cpp中声明
CWnd * g_pParentWnd = NULL;
BOOL g_bIsCloseView = FALSE;
extern "C" AFX_EXT_API UINT Create(CRuntimeClass * * view,CWnd * p)
{
new CDynLinkLibrary(Scale3DCDeviceManageDLL);
g_pParentWnd = p;
*view = RUNTIME_CLASS(CScale3DCDeviceManageView);
g_bIsCloseView = TRUE;
return(0);
}
extern "C" AFX_EXT_API BOOL GetVisual()
{//视图是否可见
return g_bIsCloseView;
}
(2)主框架中调用DLL函数创建视图
HINSTANCE hDllInst = AfxLoadLibrary(CScale3DCGlobal::GetApplicationPath()
+ _T("\\DeviceManage.DLL"));
if (hDllInst)
{
typedef UINT(*MYFUNC)(CRuntimeClass**,CWnd *parent);
MYFUNC CreateViewUI = NULL;
CreateViewUI = (MYFUNC)GetProcAddress(hDllInst, "Create");
if (CreateViewUI)
{
CRuntimeClass* pNewViewClass;
CreateViewUI(&pNewViewClass,AfxGetMainWnd());
ASSERT(pNewViewClass);
CCreateContext context;
context.m_pNewViewClass = pNewViewClass;
pChildFrame = new CScale3DCChildFrame;//测试工程中的子框架窗口
if (!pChildFrame->LoadFrame(32000,//与DLL中的资源ID一致
WS_OVERLAPPEDWINDOW | FWS_PREFIXTITLE, AfxGetMainWnd(), &context))
return;
pChildFrame->SetWindowText(_T("通信连接"));
pChildFrame->InitialUpdateFrame(NULL, TRUE);
}
//FreeLibrary(hDllInst);
}
}
编译器相关设置,如下:
(2)设置视图的标签页标题
#include <afxMDIChildWndEx.h>
void CScale3DCScaleWeightView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
CMDIChildWndEx * pFrame = (CMDIChildWndEx*)this->GetParentFrame();
//CScale3DCChildFrame * pMidFrame = (CScale3DCChildFrame*)pFrame;
pFrame->SetWindowText(_T("称重数据区"));
// TODO: 在此添加专用代码和/或调用基类
}
(3)设置视图窗口的背景颜色
BOOL CScale3DCScaleWeightView::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rt;
GetClientRect(&rt);
CBrush brush;
brush.CreateSolidBrush(RGB(224, 241, 251));
CBrush * pOldBrush = pDC->SelectObject(&brush);
pDC->FillRect(&rt, &brush);
pDC->SelectObject(pOldBrush);
return TRUE;
//return CFormView::OnEraseBkgnd(pDC);
}
(4)在FormView中添加消息处理如下:
void CScale3DCUserManageView::OnNcDestroy()
{
CFormView::OnNcDestroy();
g_bIsCloseView = FALSE;
// TODO: 在此处添加消息处理程序代码
}
(5)为DLL中的视图窗口,设置唯一的ID(即相对于所有的DLL包含的视图)。
(6)控件产生提示
.h文件中添加提示控件
CToolTipCtrl m_tip;
void CScale3DCWeightView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
m_tip.Create(this);
m_tip.AddTool(GetDlgItem(IDC_ADD_SCALE), _T("称重界面"));
}
BOOL CScale3DCDeviceManageView::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (pMsg->message == WM_MOUSEMOVE)
m_Mytip.RelayEvent(pMsg);
return CFormView::PreTranslateMessage(pMsg);
}
(7)窗口静态标签控件透明
HBRUSH CScale3DCWeightView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: 在此更改 DC 的任何特性
if (nCtlColor == CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT); //设备背景透明模式
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
// TODO: 如果默认的不是所需画笔,则返回另一个画笔
return hbr;
}
(8)显示滚动条
SetScrollSizes(MM_TEXT, CSize(800, 170*4));//设置滚动条范围
(9)在子框架中给主框架发消息
void CScale3DCWeightView::OnNcDestroy()
{//通知主视图,关闭相关面板
g_bIsCloseView = FALSE;
CMDIChildWndEx * pFrame = (CMDIChildWndEx*)this->GetParentFrame();
CWnd * pMainFrame = pFrame->GetParentFrame();
if(pMainFrame)
::SendMessage(pMainFrame->m_hWnd, WM_APP + 301, 0, 0);
CFormView::OnNcDestroy();//放到最后一句
}
(10)CImage类加载DLL中的资源
VOID CScale3DCYiBiaoData::SetImage(INT id)
{
m_nImgID = id;
HINSTANCE temp = AfxGetResourceHandle();//保存旧的句柄
//设置当前DLL资源环境句柄
AfxSetResourceHandle(GetModuleHandle(_T("Scale3DCDeviceManage")));//DLL名称
m_img.Destroy();//为了多次加载
m_img.LoadFromResource(AfxGetResourceHandle(), id);
AfxSetResourceHandle(temp);//恢复原先句柄
}
从资源中加载字符串,则不必,直接LoadString(id)即可
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。