CWnd或CDialog-如何写一个与可以使用同样方式创建的窗口


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);
]

问题:
显示的窗口比填入的窗口的宽高都大了,不知道咋回事

]


=>
总结:第二种太麻烦了,所以直接用第一种就好了
资源添加个窗口,然后利用类向导自动生成类,然后根据需要在上面改就好了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值