MFC用代码创建控件,注册创建自定义窗口

手动创建控件流程

  1. 创建类成员控件类型变量
    图中除m_hicn之外均为控件
    在这里插入图片描述
  2. 每种类型的控件,创建代码如下:
	CFont* pFont = GetFont();
	m_list2.Create(WS_VISIBLE | WS_CHILD | WS_TABSTOP | LVS_REPORT, CRect(11, 64, 429, 290), this, 12340);
	m_list2.SetFont(pFont);
	
	m_edit2.Create(WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL | ES_AUTOHSCROLL | WS_BORDER, CRect(57, 11, 137, 31), this, 12350);
	m_edit2.SetFont(pFont);

	m_button2.Create(L"button2", WS_CHILD | WS_VISIBLE | WS_TABSTOP, CRect(98, 36, 173, 58), this, 12341);
	m_button2.SetFont(pFont);

	m_combobox2.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_DROPDOWNLIST, CRect(11, 36, 86, 58), this, 12345);
	m_combobox2.SetFont(pFont);

	m_static2.Create(L"static2", WS_CHILD | WS_VISIBLE, CRect(146, 11, 183, 23), this, 12346);
	m_static2.SetFont(pFont);

不难看出每种类型的控件Create函数既相互联系又相互区别。它们都有对自身ID,窗口大小和位置,风格,父窗口的定义,但有的控件创建有内容文本这一参数,有些没有,并且每一种控件它们都有自己专属的风格,CComboBox有CBS_DROPDOWNLIST,CEdit有ES_AUTOHSCROLL,CListCtrl有LVS_REPORT等等。细细挖掘就知道,这些Create都重写的父类CWnd的Create函数。

注册创建自定义窗口

MSDN中

CWnd::Create

virtual BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);

Return Value

Nonzero if successful; otherwise 0.

Parameters

lpszClassName

Points to a null-terminated character string that names the Windows class (a WNDCLASS structure). The class name can be any name registered with the global AfxRegisterWndClass function or any of the predefined control-class names. If NULL, uses the default CWnd attributes.

lpszWindowName

Points to a null-terminated character string that contains the window name.

dwStyle

Specifies the window style attributes. WS_POPUP cannot be used. If you wish to create a pop-up window, use CWnd::CreateEx instead.

rect

The size and position of the window, in client coordinates of pParentWnd.

pParentWnd

The parent window.

nID

The ID of the child window.

pContext

The create context of the window.

Remarks

Creates a Windows child window and attaches it to the CWnd object.

You construct a child window in two steps. First, call the constructor, which constructs the CWnd object. Then call Create, which creates the Windows child window and attaches it to CWnd. Create initializes the window’s class name and window name and registers values for its style, parent, and ID.

Example

// Dynamically create static control using CWnd::Create,
// instead of with CStatic::Create, which doesn’t
// need the “STATIC” class name.

void CMyDlg::OnCreateStatic()
{
CWnd* pWnd = new CWnd;
pWnd->Create(_T(“STATIC”), “Hi”, WS_CHILD | WS_VISIBLE,
CRect(0, 0, 20, 20), this, 1234);
}

CWnd::Create()函数只限于创建包括所有控件在内的子窗口,一般不用于创建主窗口。创建主窗口的任务交由CWnd::CreateEx()

CWnd::CreateEx

BOOL CreateEx( DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HMENU nIDorHMenu, LPVOID lpParam = NULL );

BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam = NULL);

Return Value

Nonzero if successful; otherwise 0.

Parameters

dwExStyle

Specifies the extended style of the CWnd being created. Apply any of the extended window styles to the window.

lpszClassName

Points to a null-terminated character string that names the Windows class (aWNDCLASS structure). The class name can be any name registered with the global AfxRegisterWndClass function or any of the predefined control-class names. It must not be NULL.

lpszWindowName

Points to a null-terminated character string that contains the window name.

dwStyle

Specifies the window style attributes. See Window Styles and CWnd::Create for a description of the possible values.

x

Specifies the initial x-position of the CWnd window.

y

Specifies the initial top position of the CWnd window.

nWidth

Specifies the width (in device units) of the CWnd window.

nHeight

Specifies the height (in device units) of the CWnd window.

hwndParent

Identifies the parent or owner window of the CWnd window being created. Use NULL for top-level windows.

nIDorHMenu

Identifies a menu or a child-window identifier. The meaning depends on the style of the window.

lpParam

Points to the data referenced by the lpCreateParams field of the CREATESTRUCT structure.

rect

The size and position of the window, in client coordinates of pParentWnd.

pParentWnd

The parent window.

nID

The ID of the child window.

Remarks

Creates an overlapped, pop-up, or child window with the extended style specified in dwExStyle.

The CreateEx parameters specify the WNDCLASS, window title, window style, and (optionally) initial position and size of the window. CreateEx also specifies the window’s parent (if any) and ID.

When CreateEx executes, Windows sends the WM_GETMINMAXINFO, WM_NCCREATE, WM_NCCALCSIZE, and WM_CREATE messages to the window.

To extend the default message handling, derive a class from CWnd, add a message map to the new class, and provide member functions for the above messages. Override OnCreate, for example, to perform needed initialization for a new class.

Override further OnMessage message handlers to add further functionality to your derived class.

If the WS_VISIBLE style is given, Windows sends the window all the messages required to activate and show the window. If the window style specifies a title bar, the window title pointed to by the lpszWindowName parameter is displayed in the title bar.

The dwStyle parameter can be any combination of window styles.

Example

void CMyDlg::OnCreateExtendedCtrl()
{
CWnd* pWnd = new CStatic;
pWnd->CreateEx(WS_EX_CLIENTEDGE, // Make a client edge label.
_T(“STATIC”), “Hi”,
WS_CHILD | WS_TABSTOP | WS_VISIBLE,
5, 5, 30, 30, m_hWnd, (HMENU)1234);
}

以上英文文档也取自MSDN,有一些值得注意的点,我想提醒一下:

  • CreateEx()主要用于创建主窗口,Create()则用于子窗口(包括控件)。
  • Create()中nID不可为NULL,凡是子窗口都应有一个用于标识身份的ID
  • Create()中父窗口不可为NULL,可以是桌面
  • CreateEx()中nID作主窗口时必须为NULL
  • Create()中风格不可为pop,Create()函数其实是内部调用了CreateEx()

用vs创建mfc基于对话框的应用程序,将下列函数改作下列所示:

BOOL CMFCApplication1App::InitInstance()
{
	
	CWnd* wnd = new CWnd;
	m_pMainWnd = wnd;#程序需要指定主窗口
	CString szClass;

	HBRUSH Hbr = (HBRUSH)::GetStockObject(BLACK_BRUSH);

	HCURSOR Hcr = (HCURSOR)LoadStandardCursor(IDC_CROSS);

	HICON hico = LoadIcon(IDR_MAINFRAME);
	szClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,Hcr,Hbr,hico);
	
	wnd->CreateEx(0, szClass, L"First CreateEx window", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CRect(0, 300, 600,900), NULL,0);
	
	
	/*wnd->Create(szClass, L"First Create window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CRect(0, 300, 600, 900), CWnd::FromHandle(GetDesktopWindow()), 12386);*/
	return TRUE;#此处必须为TRUE不然不启动消息泵

}

发布了15 篇原创文章 · 获赞 21 · 访问量 1672

猜你喜欢

转载自blog.csdn.net/qzonelaji/article/details/104088357