在内存创建对话框资源

 

 


//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);
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值