1.如何写一个与CWnd用同样方式创建的窗口?
class CMyWnd : public CWnd
{
}
----
2.如何写一个与CDialog用同样方式创建的窗口?
最佳方式:资源添加个窗口,然后利用类向导自动生成类,然后根据需要在上面改就好了(不用追求纯代码动态创建的,太麻烦了,容易出问题)
【
例子1: --有资源文件,自动生成的类
[
头文件:
class cdlg1111 : public CDialog
{
DECLARE_DYNAMIC(cdlg1111)
public:
cdlg1111(CWnd* pParent = nullptr); // 标准构造函数
virtual ~cdlg1111();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual BOOL OnInitDialog();
};
实现文件:
#include "pch.h"
#include "MFC888888888.h"
#include "cdlg1111.h"
#include "afxdialogex.h"
// cdlg1111 对话框
IMPLEMENT_DYNAMIC(cdlg1111, CDialog)
cdlg1111::cdlg1111(CWnd* pParent /*=nullptr*/)
: CDialog(IDD_DIALOG1, pParent)
{
int a = 0;
a++;
}
cdlg1111::~cdlg1111()
{
}
void cdlg1111::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
int cdlg1111::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
BOOL cdlg1111::OnInitDialog()
{
return 0;
}
BEGIN_MESSAGE_MAP(cdlg1111, CDialog)
ON_WM_CREATE()
END_MESSAGE_MAP()
// cdlg1111 消息处理程序
下面使用正确吗?
[
局部变量:
[
void OnBtnClick() --正确,
{
cdlg1111 dlg;
dlg.DoModal();
}
---
void OnBtnClick() --正确
{
cdlg1111 *pdlg = new cdlg1111();
pdlg->DoModal();
delete pdlg;
pdlg = NULL;
}
---
void OnBtnClick() --错误
{
cdlg1111 dlg;
dlg.ShowWindow(SW_SHOW);
}
改成:
void OnBtnClick() --还是错误,因为是非阻塞的,执行完,局部变量销毁了,窗口闪一下就消销毁了
{
cdlg1111 dlg;
pdlg.Create(cdlg1111::IDD, NULL);
dlg.ShowWindow(SW_SHOW);
}
正确方式:改成成员变量方式:
cdlg1111 m_dlg11;
初始化:
m_dlg11.Create(cdlg1111::IDD, NULL);
void OnBtnClick() --正确
{
m_dlg11.ShowWindow(SW_SHOW);
}
---
void OnBtnClick() --错误
{
cdlg1111 *pdlg = new cdlg1111();
pdlg->ShowWindow(SW_SHOW);
}
改成:
void OnBtnClick() --可以显示,但是申请的内存没有手动释放
{
cdlg1111 *pdlg = new cdlg1111();
pdlg->Create(cdlg1111::IDD, NULL);
dlg.ShowWindow(SW_SHOW);
}
正确方式:改成成员变量方式:
cdlg1111 *m_pdlg;
初始化:
m_pdlg = new cdlg1111();
m_pdlg->Create(cdlg1111::IDD, NULL);
void OnBtnClick() --可以显示,但是申请的内存没有手动释放
{
dlg.ShowWindow(SW_SHOW);
}
]
----------------------
成员变量:
cdlg1111 m_dlg;
cdlg1111 *m_pdlg;
初始化:
m_pdlg = new cdlg1111(this);
void OnBtnClick() --正确
{
m_dlg.DoModal();
}
---
void OnBtnClick() --正确
{
m_pdlg->DoModal();
}
---
void OnBtnClick() --错误,需要创建
{
m_dlg.ShowWindow(SW_SHOW);
}
---
void OnBtnClick() --错误,需要创建
{
m_pdlg->ShowWindow(SW_SHOW);
}
]
说明:
1.自动生成的类,构造函数把IDD和父窗口传进去了
2.Domodal() --里面包含了创建和显示,流程是没有就创建,有就不创建
3.ShowWindow前必须保证创建了
]
-----------------------------------------------------------------------------------------------
例子2:不用资源文件,动态创建dialog
不用资源文件,动态创建dialog问题?
问题1:class myDlg : public CDialog,然后Create函数需要传IDD或者模板名,发现没法用
问题2:使用CreateWindowEx,但是运行就崩了
那么不用资源文件,如何动态创建dialog呢?
[
新建模板类的方法
代码:
[
cmydlg.h头文件:
#pragma once
#include "afx.h"
#define DLG_TEMPLATE_BUFFER_MAX_LENGT 1024
class CDlgTemplate
{
public:
CDlgTemplate(int nBufferLength = DLG_TEMPLATE_BUFFER_MAX_LENGT);
~CDlgTemplate();
private:
WORD* m_pBuffer;
public:
DLGTEMPLATE* CreateTemplate(DWORD dwStyle, CRect& rect, CString strCaption, DWORD dwStyleEx = 0);
};
class myDlg : public CDialog
{
public:
myDlg();
virtual ~myDlg();
BOOL CreateModeDlg(CRect rect, BOOL bMode = TRUE, CWnd* pParent = NULL);
protected:
virtual BOOL OnInitDialog();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
private:
CDlgTemplate m_dlgTemp;
};
---
cmydlg.cpp文件:
#include "pch.h"
#include "cmydlg.h"
CDlgTemplate::CDlgTemplate(int nBufferLength)
{
m_pBuffer = new WORD[nBufferLength];
if ((!m_pBuffer) || (DLG_TEMPLATE_BUFFER_MAX_LENGT > nBufferLength))
{
exit(0);
}
}
CDlgTemplate::~CDlgTemplate()
{
if (m_pBuffer)
{
delete m_pBuffer;
m_pBuffer = NULL;
}
}
DLGTEMPLATE* CDlgTemplate::CreateTemplate(DWORD dwStyle, CRect& rect,
CString strCaption, DWORD dwStyleEx)
{
WORD* pTemp = m_pBuffer;
DLGTEMPLATE* pDlgTemp = (DLGTEMPLATE*)pTemp;
// 对话框模版
pDlgTemp->style = dwStyle;
pDlgTemp->dwExtendedStyle = dwStyleEx;
pDlgTemp->cdit = 0;
pDlgTemp->cx = rect.Width();
pDlgTemp->cy = rect.Height();
pDlgTemp->x = (short)rect.left;
pDlgTemp->y = (short)rect.top;
pTemp = (WORD*)(pDlgTemp + 1);
// 菜单
*pTemp++ = 0;
// class
*pTemp++ = 0;
// caption
wcscpy((WCHAR*)pTemp, strCaption);
pTemp += strCaption.GetLength() + 1;
// font
return pDlgTemp;
}
//
BEGIN_MESSAGE_MAP(myDlg, CDialog)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
END_MESSAGE_MAP()
myDlg::myDlg()
{
}
myDlg::~myDlg()
{
}
BOOL myDlg::CreateModeDlg(CRect rect, BOOL bMode /*= TRUE*/, CWnd* pParent/* = NULL*/)
{
BOOL bResult = FALSE;
DLGTEMPLATE* pTemp = NULL;
pTemp = m_dlgTemp.CreateTemplate(WS_POPUP, rect, _T(""), WS_EX_LEFT);
if (bMode)
{
bResult = InitModalIndirect(pTemp, pParent);
}
else
{
bResult = CreateIndirect(pTemp, pParent);
}
return bResult;
}
int myDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (__super::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
void myDlg::OnPaint()
{
CPaintDC dc(this);
CMemDC memDC(dc, this);
CDC *pMemDC = &memDC.GetDC();
pMemDC->SetBkMode(TRANSPARENT);
CRect rClient;
GetClientRect(&rClient);
pMemDC->FrameRect(rClient, &CBrush(RGB(219, 223, 230)));
CRect rcBk = rClient;
rcBk.left += 1;
rcBk.right -= 1;
rcBk.top += 1;
rcBk.bottom -= 1;
pMemDC->FillSolidRect(rcBk, RGB(255, 255, 255));
}
BOOL myDlg::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void myDlg::OnSize(UINT nType, int cx, int cy)
{
return __super::OnSize(nType, cx, cy);
}
BOOL myDlg::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE;
}
使用:
模态:
myDlg dlg;
dlg.CreateModeDlg(CRect(0, 0, 500, 400), TRUE, this);
dlg.DoModal();
非模态:
myDlg dlg;
dlg.CreateModeDlg(CRect(0, 0, 500, 400), FALSE, this);
dlg.ShowWindow(SW_SHOW);
]
问题:
显示的窗口比填入的窗口的宽高都大了,不知道咋回事
]
=>
总结:第二种太麻烦了,所以直接用第一种就好了
资源添加个窗口,然后利用类向导自动生成类,然后根据需要在上面改就好了
】