//BaseDynDialog.h
#pragma once
class CBaseDynDialog : public CDialog
{
DECLARE_DYNAMIC(CBaseDynDialog)
public:
CBaseDynDialog();
virtual CBaseDynDialog::~CBaseDynDialog();
protected:
WORD *m_pDlgTemplate;
int m_iTemplateOffset;
WORD m_MaxSubItemNums;
LPWORD CopyWString (LPWORD lpWCStr, LPCWSTR lpStrIn);
public:
enum _tagClass_
{
BUTTON = 0x0080U,
EDIT = 0x0081U,
STATIC = 0x0082U,
LISTBOX = 0x0083U,
SCROLLBAR = 0x0084U,
COMBOBOX = 0x0085U,
};
public:
DWORD m_dwDlgExStyle, m_dwDlgStyle; //风格
WCHAR m_szDlgTitle[128]; //标题
RECT m_rcDlgRect; //位置&尺寸
WCHAR m_szFontFace[64]; //字体名称
WORD m_wFontPoint; //字体大小
WORD m_wFontWeight; //字体比重
BOOL m_wFontItalic; //斜体?
LPCWSTR m_szDlgMenuID; //菜单
LPCWSTR m_szDlgClass; //类
public:
BOOL InitTemplate();
BOOL AddControl(DWORD exStyle, DWORD lStyle, RECT rc, DWORD dwID,
LPCWSTR szTitle, WORD *wClass, int iClassLen,
BYTE *pbExData=NULL, WORD wExtLen=0);
void EndTemplateUpdate(CWnd *pParent);
public:
BOOL AddButton(DWORD lStyle, RECT rc, UINT uID, LPCWSTR sTitle);
BOOL AddEdit(DWORD lStyle, RECT rc, UINT uID, LPCWSTR sTitle);
public:
virtual INT_PTR DoDlgInMemory(CWnd *pParent);
virtual void OnOK();
};
//BaseDynDialog.cpp
#include "stdafx.h"
#include "BaseDnyDialog.h"
#include <afximpl.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*windowClass 0xFFFF +
0x0080 Button
0x0081 Edit
0x0082 Static
0x0083 List box
0x0084 Scroll bar
0x0085 Combo box
*/
IMPLEMENT_DYNAMIC(CBaseDynDialog, CDialog)
CBaseDynDialog::CBaseDynDialog()
{
m_iTemplateOffset = 0;
//后续的不检测内存边界 因此留意分配内存的大小
m_pDlgTemplate = (WORD*)GlobalAlloc(GPTR, 64*1024);
ASSERT(((ULONG_PTR)m_pDlgTemplate & 0x0003) == 0);
m_dwDlgExStyle = WS_EX_DLGMODALFRAME;
m_dwDlgStyle = DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION | DS_CENTER;
wcscpy_s(m_szDlgTitle, L"Dynamic Dlg" );
m_rcDlgRect.left = 0;
m_rcDlgRect.top = 0;
m_rcDlgRect.right = 200;
m_rcDlgRect.bottom = 100;
//字体
wcscpy_s(m_szFontFace, L"Times New Roman"); //字体名称
m_wFontPoint = 12; //字体大小
m_wFontWeight = FW_NORMAL; //字体比重
m_wFontItalic = FALSE; //斜体?
//菜单
m_szDlgMenuID = L"";
//类
m_szDlgClass = L"";
}
CBaseDynDialog::~CBaseDynDialog()
{
if(m_pDlgTemplate != NULL)
{
GlobalFree(m_pDlgTemplate);
m_pDlgTemplate = NULL;
}
}
//拷贝字符串到模板
LPWORD CBaseDynDialog::CopyWString (LPWORD lpWCStr, LPCWSTR lpStrIn)
{
while(1)
{
if(lpStrIn == NULL || lpStrIn[0] == 0)
{
*lpWCStr++ = 0;
break;
}
*lpWCStr++= (WORD) *lpStrIn;
lpStrIn++;
}
return lpWCStr;
}
//初始化模板
BOOL CBaseDynDialog::InitTemplate()
{
/*
typedef struct
{
WORD dlgVer;
WORD signature;
DWORD helpID;
DWORD exStyle;
DWORD style;
WORD cDlgItems;
short x;
short y;
short cx;
short cy;
sz_Or_Ord menu; // name or ordinal of a menu resource
sz_Or_Ord windowClass; // name or ordinal of a window class
WCHAR title[titleLen]; // title string of the dialog box
short pointsize; // only if DS_SETFONT flag is set
short weight; // only if DS_SETFONT flag is set
short bItalic; // only if DS_SETFONT flag is set
WCHAR font[fontLen]; // typeface name, if DS_SETFONT is set
} DLGTEMPLATEEX;
*/
m_iTemplateOffset = 0;
m_MaxSubItemNums = 0;
WORD *p = m_pDlgTemplate + m_iTemplateOffset;
/* start to fill in the dlgtemplate information, addressing by WORDs */
DWORD exStyle = m_dwDlgExStyle;
DWORD lStyle = DS_MODALFRAME | m_dwDlgStyle;
if(m_szFontFace[0]) { lStyle |= DS_SETFONT; }
*p++ = 1; // DlgVer
*p++ = 0xFFFF; // Signature
*p++ = 0; // LOWORD HelpID
*p++ = 0; // HIWORD HelpID
*p++ = LOWORD(exStyle); // LOWORD exStyle
*p++ = HIWORD(exStyle); // HIWORD exStyle
*p++ = LOWORD(lStyle); // LOWORD lStyle
*p++ = HIWORD(lStyle); // HIWORD lStyle
*p++ = 0; // NumberOfItems
*p++ = (WORD)m_rcDlgRect.left; // x
*p++ = (WORD)m_rcDlgRect.top; // y
*p++ = (WORD)(m_rcDlgRect.right - m_rcDlgRect.left); // cx
*p++ = (WORD)(m_rcDlgRect.bottom - m_rcDlgRect.top); // cy
p = CopyWString(p, m_szDlgMenuID); // Menu
p = CopyWString(p, m_szDlgClass); // Class
p = CopyWString(p, m_szDlgTitle); // title
/* Font information because of DS_SETFONT */
if(lStyle & DS_SETFONT)
{
*p++ = m_wFontPoint; // point size
*p++ = m_wFontWeight; // weight
*p++ = m_wFontItalic; // bItalic;
p = CopyWString(p, m_szFontFace); // Face name
}
m_iTemplateOffset = (LONG)(ULONG_PTR)(p - m_pDlgTemplate);
return TRUE;
}
//添加控件
BOOL CBaseDynDialog::AddControl(DWORD exStyle, DWORD lStyle, RECT rc, DWORD dwID,
LPCWSTR szTitle, WORD *wClass, int iClassLen, BYTE *pbExData, WORD wExtLen)
{
/*
typedef struct
{
DWORD helpID;
DWORD exStyle;
DWORD style;
short x;
short y;
short cx;
short cy;
DWORD id;
sz_Or_Ord windowClass; // name or ordinal of a window class
sz_Or_Ord title; // title string or ordinal of a resource
WORD extraCount; // bytes of following creation data
} DLGITEMTEMPLATEEX;
*/
__try
{
WORD *p = m_pDlgTemplate + m_iTemplateOffset;
/* make sure the item starts on a DWORD boundary */
p = (LPWORD) (((ULONG_PTR)(p) + 3) & (~(ULONG_PTR)3));
lStyle &= ~WS_POPUP; lStyle |= WS_CHILD;
*p++ = 0; // LOWORD (lHelpID)
*p++ = 0; // HIWORD (lHelpID)
*p++ = LOWORD(exStyle); // LOWORD (exStyle)
*p++ = HIWORD(exStyle); // HIWORD (exStyle)
*p++ = LOWORD (lStyle); // LOWORD (lStyle)
*p++ = HIWORD (lStyle); // HIWORD (lStyle)
*p++ = (WORD)rc.left; // x
*p++ = (WORD)rc.top; // y
*p++ = (WORD)(rc.right - rc.left); // cx
*p++ = (WORD)(rc.bottom - rc.top); // cy
*p++ = LOWORD(dwID); // LOWORD (Control ID)
*p++ = HIWORD(dwID); // HIWORD (Control ID)
while(iClassLen--) { *p++ = *wClass++; } //class
p = CopyWString(p, szTitle); //text
// advance pointer over nExtraStuff WORD
if(wExtLen > 0 && pbExData)
{
*p++ = wExtLen; //length
memcpy(p, pbExData, wExtLen); // extended data
p += (wExtLen+1)/2; //align WORD
}
else
{
*p++ = 0; //no extended data
}
m_iTemplateOffset = (LONG)(ULONG_PTR)(p - m_pDlgTemplate);
m_MaxSubItemNums++;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
{
ASSERT(0);
}
return TRUE;
}
//结束模板更新
void CBaseDynDialog::EndTemplateUpdate(CWnd *pParent)
{
//更新控件数量
((DLGTEMPLATEEX*) m_pDlgTemplate)->cDlgItems = m_MaxSubItemNums;
//关联对话框
InitModalIndirect((DLGTEMPLATE*)m_pDlgTemplate, pParent);
}
//添加按钮
BOOL CBaseDynDialog::AddButton(DWORD lStyle, RECT rc, UINT uID, LPCWSTR sTitle)
{
WORD wClass[] = {0xFFFFU, BUTTON};
return AddControl(0, lStyle | BS_PUSHBUTTON, rc, uID, sTitle, wClass, 2);
}
//添加编辑框
BOOL CBaseDynDialog::AddEdit(DWORD lStyle, RECT rc, UINT uID, LPCWSTR sTitle)
{
WORD wClass[] = {0xFFFFU, EDIT};
return AddControl(0, lStyle | WS_BORDER, rc, uID, sTitle, wClass, 2);
}
///
//应用
INT_PTR CBaseDynDialog::DoDlgInMemory(CWnd *pParent)
{
InitTemplate();
AddEdit(WS_VISIBLE, CRect(10, 10, 100, 30), 1000, L"1234");
AddButton(WS_VISIBLE, CRect(10, 50, 60, 70), IDOK, L"OK");
AddButton(WS_VISIBLE, CRect(70, 50, 120, 70), IDCANCEL, L"CANCEL");
EndTemplateUpdate(pParent);
return DoModal();
}
void CBaseDynDialog::OnOK()
{
CString szVal;
GetDlgItemText(1000, szVal);
AfxMessageBox(szVal);
CDialog::OnOK();
}
//测试
#include "BaseDnyDialog.h"
void CDlg3Dlg::OnButton1()
{
CBaseDynDialog dlg;
dlg.DoDlgInMemory(this);
}