VC窗口类注册与诞生
来源:互联网 发布:1 手机 知乎 编辑:程序博客网 时间:2024/05/17 09:13
1、窗口类的结构
typedef struct tagWNDCLASSA {
UINT style;//style = CS_VREDRAW|CS_HREDRAW表示窗口在运动或者调整大小时需要重画
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;
2、MFC类注册宏
AFXIMPL.H中,定义了五个默认窗口宏:
#define AFX_WND_REG 0x00001
#define AFX_WNDCONTROLBAR_REG 0x00002
#define AFX_WNDMDIFRAME_REG 0x00004
#define AFX_WNDFRAMEORVIEW_REG 0x00008
#define AFX_WNDOLECONTROL_REG 0x00020
#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister);
又定义了这样的一个宏:
#ifndef _UNICODE
#define _UNICODE_SUFFIX
#else
#define _UNICODE_SUFFIX _T("u")
#endif
#ifndef _DEBUG
#define _DEBUG_SUFFIX
#else
#define _DEBUG_SUFFIX _T("d")
#endif
#ifdef _AFXDLL
#define _STATIC_SUFFIX
#else
#define _STATIC_SUFFIX _T("s")
#endif
#define AFX_WNDCLASS(s) /
_T("Afx") _T(s) _T("42") _STATIC_SUFFIX _UNICODE_SUFFIX _DEBUG_SUFFIX
#define AFX_WND AFX_WNDCLASS("Wnd")
#define AFX_WNDCONTROLBAR AFX_WNDCLASS("ControlBar")
#define AFX_WNDMDIFRAME AFX_WNDCLASS("MDIFrame")
#define AFX_WNDFRAMEORVIEW AFX_WNDCLASS("FrameOrView")
#define AFX_WNDOLECONTROL AFX_WNDCLASS("OleControl")
WINCORE.cpp中,初始化了以上宏:
const TCHAR _afxWnd[] = AFX_WND;
const TCHAR _afxWndControlBar[] = AFX_WNDCONTROLBAR;
const TCHAR _afxWndMDIFrame[] = AFX_WNDMDIFRAME;
const TCHAR _afxWndFrameOrView[] = AFX_WNDFRAMEORVIEW;
const TCHAR _afxWndOleControl[] = AFX_WNDOLECONTROL;
3、MFC类注册函数
在定义AFX_WND_REG时,就有,
#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister);
其实现函数在WINCORE.CPP中,(其他的均在此中)
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
{
//已注册检测
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
fToRegister &= ~pModuleState->m_fRegisteredClasses;//当前模块求反再求与运算
if (fToRegister == 0)//为0则注册
return TRUE;
WNDCLASS wndcls;
memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults
wndcls.lpfnWndProc = DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hCursor = afxData.hcurArrow;
INITCOMMONCONTROLSEX init;
init.dwSize = sizeof(init);
//只有style 、lpszClassName值修改了
if (fToRegister & AFX_WND_REG)//The first digit is 1,第1位为1
{
// Child windows - no brush, no icon, safest default class styles
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;//局部变量
wndcls.lpszClassName = _afxWnd;
if (AfxRegisterClass(&wndcls))//
fRegisteredClasses |= AFX_WND_REG;//Long型局部变量,求或
……
}
来看看这个函数
BOOL AFXAPI AfxRegisterClass(WNDCLASS* lpWndClass)
{
WNDCLASS wndcls;
上面: wndcls.lpfnWndProc = DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hCursor = afxData.hcurArrow;
if (GetClassInfo(lpWndClass->hInstance, lpWndClass->lpszClassName,
&wndcls))//获取到了,说明hInstance,lpszClassName已注册
{
// class already registered
return TRUE;
}
if (!::RegisterClass(lpWndClass))//开始注册
{
TRACE1("Can't register window class named %s/n",
lpWndClass->lpszClassName);
return FALSE;
}
if (afxContextIsDLL)//如果是dll,做相应的处理
{
AfxLockGlobals(CRIT_REGCLASSLIST);
TRY
{
// class registered successfully, add to registered list
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
LPTSTR lpszUnregisterList = pModuleState->m_szUnregisterList;
// the buffer is of fixed size -- ensure that it does not overflow
ASSERT(lstrlen(lpszUnregisterList) + 1 +
lstrlen(lpWndClass->lpszClassName) + 1 <
_countof(pModuleState->m_szUnregisterList));
// append classname + newline to m_szUnregisterList
lstrcat(lpszUnregisterList, lpWndClass->lpszClassName);
TCHAR szTemp[2];
szTemp[0] = '/n';
szTemp[1] = '/0';
lstrcat(lpszUnregisterList, szTemp);
}
CATCH_ALL(e)
{
AfxUnlockGlobals(CRIT_REGCLASSLIST);
THROW_LAST();
// Note: DELETE_EXCEPTION not required.
}
END_CATCH_ALL
AfxUnlockGlobals(CRIT_REGCLASSLIST);
}
return TRUE;
}
4、MFC注册窗口实现
WINCORE.CPP中,
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)//11个参数,//hInstance参数没有,
{
CREATESTRUCT cs;
cs.dwExStyle = dwExStyle;
cs.lpszClass = lpszClassName;
cs.lpszName = lpszWindowName;
cs.style = dwStyle;
cs.x = x;
cs.y = y;
cs.cx = nWidth;
cs.cy = nHeight;
cs.hwndParent = hWndParent;
cs.hMenu = nIDorHMenu;
cs.hInstance = AfxGetInstanceHandle();//此处通过全局函数获取
cs.lpCreateParams = lpParam;
if (!PreCreateWindow(cs))//此处调用this指向的对象,一般都会返回TRUE
{
PostNcDestroy();
return FALSE;
}
}
来看看PreCreateWindow(cs)),
1>
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return TRUE;
}
2>
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
}
if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
cs.style |= FWS_PREFIXTITLE;
if (afxData.bWin4)
cs.dwExStyle |= WS_EX_CLIENTEDGE;
return TRUE;
}
3>
BOOL CSingleView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
4>
BOOL CView::PreCreateWindow(CREATESTRUCT & cs)
{
ASSERT(cs.style & WS_CHILD);
if (cs.lpszClass == NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
}
if (afxData.bWin4 && (cs.style & WS_BORDER))
{
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
}
return TRUE;
}
在来看看代码后面,
AfxHookWindowCreate(this);//安装钩子
HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);//创建
//创建的检验
#ifdef _DEBUG
if (hWnd == NULL)
{
TRACE1("Warning: Window creation failed: GetLastError returns 0x%8.8X/n",
GetLastError());
}
#endif
if (!AfxUnhookWindowCreate())
PostNcDestroy(); // cleanup if CreateWindowEx fails too soon
if (hWnd == NULL)
return FALSE;
ASSERT(hWnd == m_hWnd); // should have been set in send msg hook
return TRUE;
- VC窗口类注册与诞生
- 窗口类之注册与窗口之诞生
- 窗口类之注册与窗口之诞生
- 深入浅出MFC:窗口类的注册与窗口的诞生
- 学习笔记之深入浅出MFC 第2讲 窗口类注册与窗口的诞生
- VC初学者入门系列之一:窗口类的诞生
- 窗口类的诞生(注册自己的窗口类一)
- 窗口类的诞生(注册自己的窗口类二)
- VC++中为什么要注册窗口类
- 21.VC(custom)-注册窗口类
- MFC 窗口类的诞生
- 窗口的注册与创建
- 注册窗口类
- 注册窗口类
- MFC注册窗口类
- 注册窗口类 registerclass
- 注册窗口类
- 窗口类型注册类
- android 网络可用否,以及类型
- AT命令收集
- pb解决数据窗列比较少,而选中状态比较宽现象
- Undo Tablespace 切换注意事项
- ITPUB知识索引贴--RAC
- VC窗口类注册与诞生
- 为什么下载的视频都打不开呢
- 为什么下载的视频都打不开呢
- Oracle 11g Active Data Guard
- jquery easyui datagrid 添加超链接
- OPPO智能机Find华丽来袭
- Oracle 11g RMAN 异机duplicate数据库
- 感谢CSDN周老师
- 1274-二分图最大匹配