计算机中窗口定义,MFC中自定义窗口类名

本文探讨了MFC中窗口类名的定制方法,详细解释了如何通过重载PreCreateWindow方法来更改窗口类名,并指出该方法不适用于对话框的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MFC中封装很多常用的控件,把类名也给封装了,没有提供明显的接口出来,用win api写窗口程序,第一步就是注册窗口类

此时类名和标题名是一起注册的,所以能把标题很好地让用户来设定,类名也应该是很简单的,可惜的是MFC没有这样做,原因也许是window name可以不停的改,而类名不能。窗口的类名是有Create来确定的,要在Create前,给窗口选择一个已经注册的窗口类名,作为参数窗口 Create就ok了,CWnd的Create最终还是到了CreateEx中来,看看CreateEx就会清楚许多

BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,

LPCTSTR lpszWindowName, DWORD dwStyle,

const RECT& rect, CWnd* pParentWnd, UINT nID,

LPVOID lpParam /* = NULL */)

{

return CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,

rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,

pParentWnd->GetSafeHwnd(), (HMENU)(UINT_PTR)nID, lpParam);

}

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)

{

ASSERT(lpszClassName == NULL || AfxIsValidString(lpszClassName) ||

AfxIsValidAtom(lpszClassName));

ENSURE_ARG(lpszWindowName == NULL || AfxIsValidString(lpszWindowName));

// allow modification of several common create parameters

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

{

PostNcDestroy();

return FALSE;

}

AfxHookWindowCreate(this);

HWND hWnd = ::AfxCtxCreateWindowEx(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)

{

TRACE(traceAppMsg, 0, "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;

}来源:-计算机二级考试

可以看到最后到了::AfxCtxCreateWindowEx,可以很容易地知道这里调用了CreateWindowEx来创建一个窗口

在前面有一个PreCreateWindow(cs),而cs经过PreCreateWindow处理后,交给::AfxCtxCreateWindowEx处理

::AfxCtxCreateWindowEx在中转给CreateWindowEx,cs.lpszClass就是类名,可以清楚了AfxCtxCreateWindowEx的用心良苦

我们可以重载的PreCreateWindow,来修改类名,如下的代码:

// TODO: 在此添加专用代码和/或调用基类

//VERIFY(AfxDeferRegisterClass(AFX_WND_REG));

//AfxEndDeferRegisterClass(AFX_WND_REG);

//cs.lpszClass = AfxRegisterWndClass(NULL);

WNDCLASS wndcls;

memset(&wndcls, 0, sizeof(WNDCLASS));   // start with NULL

// defaults

wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

//you can specify your own window procedure

wndcls.lpfnWndProc = ::DefWindowProc;

wndcls.hInstance = AfxGetInstanceHandle();

wndcls.hIcon =  NULL; // or load a different icon

wndcls.hCursor =NULL;

wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

wndcls.lpszMenuName = NULL;

// Specify your own class name for using FindWindow later

wndcls.lpszClassName = _T("MyNewClass");

// Register the new class and exit if it fails

if(!AfxRegisterClass(&wndcls))

{

TRACE("Class Registration Failed\n");

return FALSE;

}来源:-计算机二级考试

cs.lpszClass = wndcls.lpszClassName;

return TRUE;

//return CWnd::PreCreateWindow(cs);

其实就是为了把一个已经注册的类名字符串传给CreateWindowEx,从上面代码中的注释中来看,我还用了一种让系统来生成 className的方法AfxRegisterWndClass。CWnd::PreCreateWindow不符合我的心意,注释掉了,其实里面也没什么就是判断而已。而在MFC中CWnd其他派生类就不这么简单了,不过单纯的修改类名,就重载这个方法大多就ok了。

是的,只是大多数可以的,可惜的是这个方法,对于Dialog来说并不行,因为它不用CWnd::Create,也就绕不到

PreCreateWindow上来了,你可以重载对话框的这个方法,断点,是断不下来的。因为CDialog的创建可以直接用系统的api来搞,不用再劳驾CWnd来中转到CReateWindowEx了,所以就不能够用上述方法来改对话框的类名了。

看下它的创建代码了:

BOOL CDialog::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd)

{

ASSERT(IS_INTRESOURCE(lpszTemplateName) ||

AfxIsValidString(lpszTemplateName));

m_lpszTemplateName = lpszTemplateName;  // used for help

if (IS_INTRESOURCE(m_lpszTemplateName) && m_nIDHelp == 0)

m_nIDHelp = LOWORD((DWORD_PTR)m_lpszTemplateName);

#ifdef _DEBUG

if (!_AfxCheckDialogTemplate(lpszTemplateName, FALSE))

{

ASSERT(FALSE);          // invalid dialog template name

PostNcDestroy();        // cleanup if Create fails too soon

return FALSE;

}

#endif //_DEBUG

HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG);

HRSRC hResource = ::FindResource(hInst, lpszTemplateName, RT_DIALOG);

HGLOBAL hTemplate = LoadResource(hInst, hResource);

BOOL bResult = CreateIndirect(hTemplate, pParentWnd, hInst);

FreeResource(hTemplate);

return bResult;

}

可以看出来CDialog是靠资源来创建的,可以这样来来搞的,在资源脚本中定义Class “对话框类名”在对话框domodal或者Create前注册这个类名,然后等着modal和Create后就可以了。来源:-计算机二级考试

MFC自定义界面HUI,高效简单,含详细注释和示例。 HUI包括基本控件、按钮、标签、编辑框、表格、悬停提示等,可组合出更多功能。资源占用少,效率高,能在低端机上运行,流畅不闪烁,完全满足工控等各种专业软件实现个性化要求。 本资源是“http://download.youkuaiyun.com/detail/hhhh63/6961889”的正式发布版。包括3个项目,Hui、HuiDemo1和HuiDemo2。 一、Hui项目 本项目是DLL项目,包括完整的界面库,使用双缓存,局部重画等技术,性能优异。为保证在不同的MFC版本中使用,本次上传提供了这部分的源码,一般不要对其改动。 二、HuiDemo1 简单的应用示例,包括窗口分割,控制面板和主显示区等,展示控件各方向停靠、自动充满、全屏切换、记忆窗口位置和大小、选项设置和保存注册表等功能,用户可直接以此为基础开发新项目。如需扩展其它功能,可从HuiDemo2查找复制相应代码。 三、HuiDemo2 除HuiDemo1的所有功能外,还包括界面库的全部功能和其它实用扩展功能,左中右三栏式分布,左右固定宽度,中间栏大小可变。 1、左边是属性栏,固定宽度,上边是时钟,下边是鼠标信息,当鼠标移到中间的图像区时显示鼠标位置和图像值。 2、中间是图像区,演示如何动态生存索引图像,从下向上移动,自适应大小,长宽比不变,点右边的调色板按钮改变颜色,点保存按钮把当前图像保存到桌面。 3、右边上边是控制栏,在中间的图像区中画各种几何图形,并计算几何图形包围的图像数据的最大值,最小值和平均值。 4、右边下边是表格演示,显示Windows文件夹下的文件列表,自动充满窗口区,随窗口大小改变显示项数,保证界面美观,最下面是搜索和定位功能。 四、运行环境,VC2010或更高版本。 欢迎大家下载并提意见,本资源版权归作者所有,分享供大家研究学心,不得用于商业用途,如有特殊要求请与本人联系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值