作者:沧桑不尽,请尊重原创,转载注明。
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封装机制淡忘了不少,跟踪下代码,算是温习一下了。

如何自定义MFC的窗口类名相关推荐

  1. c语言mfc窗口跳到下个窗口,MFC停靠窗口实现(CDockablePane)

    工作中编写MFC界面程序时用到了停靠窗口,为了避免之后用到时再去查询,这里记录下. 步骤 1.定义一个继承自CDockablePane的类 Class CDockableTest : public C ...

  2. VS2010中如何实现自定义MFC控件

    本文简要讲解在VS2010中怎样实现自定义MFC控件的知识,以下是分步骤说明. 一.自定义一个空白控件  1.先创建一个MFC工程 NEW Project-->MFC-->MFC Appl ...

  3. 使用mfc修改窗口背景,图表

    2019独角兽企业重金招聘Python工程师标准>>> 打开vc+界面. 一. 窗口创建之前修改,用自定义的窗口类WNDCLASS wc 由于窗口的图标,光标,背景是在窗口类设计是指 ...

  4. 如何给对话框设置窗口类名

    今天在研究ATL的时候发现修改类名是一件相当简单的事情. 一,Win32应用程序类名修改 1.新建Win32应用程序(HelloWorld) 2.打开以程序命名(HelloWorld)的资源文件Hel ...

  5. MFC底层窗口的实现

    MFC底层窗口的实现 代码: # include <windows.h> //底层实现窗口的文件 //6.处理窗口过程 此过程可先跳过 是最后一步 LRESULT CALLBACK Win ...

  6. MFC模态窗口与非模态窗口

    MFC模态窗口与非模态窗口 开发工具与关键技术:C++.VisualStudio 作者:何任贤 撰写时间:2019年07月25日 模态窗口的意思是指主窗口在打开模态窗口后,没法再操作主窗口,这就是模态 ...

  7. [测试项目]Windows 桌面自定义WorkerW分层窗口

    提示:本文所采用的方法属于本人猜想方案(目前没有在Win7及XP尝试过,但在NT的较高版本Win10在不发送052C消息,即不使用系统生成的WorkerW分层窗口实践成功.Win8开始DWM无法关闭, ...

  8. 【Visual Studio 2019】创建 MFC 桌面程序 ( 安装 MFC 开发组件 | 创建 MFC 应用 | MFC 应用窗口编辑 | 为按钮添加点击事件 | 修改按钮文字 | 打开应用 )

    文章目录 一.安装 MFC 开发组件 二.创建 MFC 应用 三.MFC 应用窗口编辑 四.为按钮添加点击事件 五.修改按钮文字 六.打开系统其它应用 七.博客源码 一.安装 MFC 开发组件 打开 ...

  9. 重新想象 Windows 8 Store Apps (27) - 选取器: 联系人选取窗口, 自定义联系人选取窗口...

    原文:重新想象 Windows 8 Store Apps (27) - 选取器: 联系人选取窗口, 自定义联系人选取窗口 [源码下载] 重新想象 Windows 8 Store Apps (27) - ...

最新文章

  1. SpringCloud学习(七)高可用的分布式配置中心(Spring Cloud Config)(Finchley版本)
  2. php数组全排列,元素所有组合
  3. 基于消息队列 RocketMQ 的大型分布式应用上云较佳实践
  4. css值变量吗,CSS变量初体验
  5. Boost:求容器的最小元素和最大元素
  6. 单词九连猜python编程_python实现猜单词游戏
  7. 口无遮拦的钉钉与坐立不安的腾讯
  8. 修改对象的某个属性的值_如何理解Python中的面向对象编程?
  9. AC控制器和无线路由器的区别
  10. HTML——HTML中的特殊符号
  11. office二级笔记
  12. 最新Java面试题整理!java字符大写转小写
  13. 三大跨境电商平台开店必备的材料
  14. 带目录计算机专业论文,计算机专业论文格式及目录系统
  15. 2020年中国无人船艇行业发展政策分析,竞争格局相对分散「图」
  16. RGB及颜色相关概念
  17. thinksns java_社交系统ThinkSNS+技术概要
  18. Macbook Pro Bootcamp 安装触控板驱动mac-precision-touchpad在Windows系统下实现更好的触控板操作
  19. Sina App Engine—新浪的开放云计算平台
  20. 卖给客户的软件oracle,Oracle销售云从设计上甩开同类软件十条街

热门文章

  1. HTML常用标签+CSS基础
  2. 互联网晚报 | 9月5日 星期日 | 美菜回应大规模裁员;网易云音乐Q2毛利率首次转正;美团展示数字人民币新应用...
  3. new php,PHP: 新特性 - Manual
  4. numpy 矩阵与向量相乘_有人把NumPy画成了花,生动又形象
  5. 证券期货行业监管大数据治理方案研究
  6. 【离散数学】二元关系的闭包
  7. 【Git】处理 Unable to access ‘https://github.com’: OpenSSL SSL_read: Connection was reset, errno 10054
  8. 南蛮图腾(洛谷P1498题题解,Java语言描述)
  9. 1月16日学习内容整理:存储库MongoDB之文档的增删改查操作补充
  10. 机器学习week8 ex7 review