MFC注册窗口类以及FindWindow按窗口类名查询

转载 2013年12月04日 12:23:31

呵呵,最近在研究SendMessage函数,其中需要用到m_hWnd,之后延伸着又尝试获得窗口的句柄,于是遇到了FindWindow函数,原型如下:

HWND FindWindow

(

 LPCSTR lpClassName,    //输入窗口的类名,其实需要是注册过的类名才行,否则是要报错或者查找失败的。

 LPCSTR lpWindowName, //输入窗口的名称,就是窗口上面蓝色的那行玩意儿写的字。

);

对于这个函数,如果按照窗口的名称查找,相信大家都非常简单,因为名称在rc文件里,是已经注册过的了(具体的待会给大家贴代码就能看明白了)。但如果大家使用我们自己定义的窗口名称查询,则往往会失败,甚至是报错!尤其是在使用SendMessage告知另一个窗口退出时,会导致内存泄露!

对于这样的情况,编译器不一定能告诉各位,所以,如果没有亲自注册窗口类的经验的话,建议大家如果要使用FindWindow函数获得窗口句柄的话,尽量通过 窗口的名称查询

言归正传,出现之前的那种严重情况的原因,是在于MFC并没有一个一个帮大家将我们派生的窗口类进行注册,而是使用的默认窗口类的方式,具体渊源似乎俺也说不大清楚(嘿嘿,见笑了。。。),咱只能引用这一段话:

“   在早期的MFC中 (MFC 4.0之前的版本)提供了大量的预定以的窗口类,但这些窗口类在默认下已经不再被提供了,因为涉及到多版本的技术问题(多个版本的MFC加载在同一个地址空间),如涉及到的一个实际的问题就是MFC应用程序和OLE控件都会用到MFC的DLLs。 ”

而默认的窗口类,一般类名都是“#32770(Dialog)”,这个大家通过Spy++检测窗口的时候就可以看到。

 

拿我这边的一个小程序为例:
默认的类名是 #32770(Dialog)

而红线之前的,就是“注册”过的窗口的名称,这个是MFC自动做了的。那么,我们能使用这个默认类名进行操作么?嘿嘿~大家试试嘛···所有的未注册窗口似乎都是这个类名哦。。。。

OK,返回话题,既然默认是这样的,那么如何修改呢?这个咱参阅了这位大大的文章:http://hi.baidu.com/iwangkun/blog/item/97fc18d5ef59dfc251da4b21.html

由于是英文的,可能有的朋友会望而生畏,所以,咱把自己的心得以及经验总结一下,翻译出来吧:

首先,请用记事本或写字本的模式,打开需要注册窗口的工程目录下的rc资源文件(各个朋友,建议大家先将工程备份一份,因为错误的修改,很容易导致整个工程出错哦!)。这个时候,请找到我们要注册的窗口的数据位置,这个很好找的:

因为每一个窗口的数据开始位置,都是以窗口的句柄开头的,

比如我要注册的窗口类的对应句柄是IDD_CARHIRESYSTEM_DIALOG,

那么打开文件后,稍微需找一下就会发现这个数据段:

IDD_CARHIRESYSTEM_DIALOG     DIALOGEX               0, 0, 400, 280
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
    WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "车辆出租系统 CarHireSystem"
FONT 9, "宋体", 0, 0, 0x1
BEGIN
    COMBOBOX        IDC_COMBO_CHANCE,23,35,83,95,CBS_DROPDOWNLIST | CBS_SORT | 
                    WS_VSCROLL | WS_TABSTOP
    EDITTEXT        IDC_EDIT_SEARCH,125,33,83,15,ES_AUTOHSCROLL
    DEFPUSHBUTTON   "查询",IDC_BUTTON_SEARCH,219,29,50,25
    ........等等
END

如上所示,那么,我们接下来所要做事情,便是添加我们对窗口类的注册信息,

即:

IDD_CARHIRESYSTEM_DIALOG DIALOGEX 0, 0, 400, 280
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
    WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "车辆出租系统 CarHireSystem"
CLASS "CCarHireSystemDlg"   //""双引号内的类名,可以随意,但注意一定要写对哦,后面还要用到的。
FONT 9, "宋体", 0, 0, 0x1
BEGIN
    COMBOBOX        IDC_COMBO_CHANCE,23,35,83,95,CBS_DROPDOWNLIST | CBS_SORT | 
                    WS_VSCROLL | WS_TABSTOP
    EDITTEXT        IDC_EDIT_SEARCH,125,33,83,15,ES_AUTOHSCROLL
    DEFPUSHBUTTON   "查询",IDC_BUTTON_SEARCH,219,29,50,25
    ........等等
END

然后保存文件,如此,基本上任务已经完成了,就差进行注册了。MFC中的注册函数是 :AfxRegisterClass,格式如下:

BOOL AFXAPI AfxRegisterClass(WNDCLASS *lpWndClass);

那么,我们要做的事情是什么呢?   ----- 在窗口完成初始化之前,对窗口类进行注册。于是,我们找到工程的App类,加入如下代码:

/////////////////////////////////////////////////////////
WNDCLASS wc;

// Get the info for this class.
// #32770 is the default class name for dialogs boxes.
::GetClassInfo(AfxGetInstanceHandle(), "#32770", &wc);

// Change the name of the class.
wc.lpszClassName = "CCarHireSystemDlg"; //这里请再次注意,一定要保证和rc资源文件里保存的类名相同!

// Register this class so that MFC can use it.
AfxRegisterClass(&wc); 

/////////////////////////////////////////////////////////

 

如上,只要AfxRegisterClass(&wc); 不返回FALSE,那么我们的类名注册就成功了!

演示截图:

这个时候,大家再使用FindWindow("CCarHireSystemDlg",NULL)函数,就可以正常使用了!

最后再次重申两点:

1.修改rc资源文件前,建议大家备份工程。当修改了rc文件后,如果没有加入上面的注册代码,或者加入位置出错,都会导致程序编译无问题,但执行报错!这一点,如果在rc资源文件里保存的类名称,与注册代码里的类名称不相同,也会导致执行报错。

2.使用FindWindow函数时,如果窗口类还并未注册,那么,建议直接将第一个参数设为NULL,同时在第二个参数上传入窗口的名称,进行查询。注意,是窗口的名称,窗口类生成的对象的窗口标题!如此,也不会导致错误。

相关文章推荐

深入浅出MFC:窗口类的注册与窗口的诞生

对于一个Windows程序的开始,需要做一些准备工作,目的是为了进行一些基础的初始化和产生应用程序的工作舞台——窗口,当然这个过程已经没有什么难度,API函数CreateWindow 已经封装好了这一...

[MFC]MFC中OnDraw与OnPaint的区别

问题 问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同?  OnDraw()和OnPaint()好象兄弟俩,因为它们的工...

MFC注册窗口类以及FindWindow按窗口类名查询

呵呵,最近在研究SendMessage函数,其中需要用到m_hWnd,之后延伸着又尝试获得窗口的句柄,于是遇到了FindWindow函数,原型如下:HWND FindWindow( LPCSTR lp...

[转载]MFC注册窗口类以及FindWindow按窗口类名查询

最近在研究SendMessage函数,其中需要用到m_hWnd,之后延伸着又尝试获得窗口的句柄,于是遇到了FindWindow函数,原型如下: HWND FindWindow (  LPCSTR lp...

MFC中自定义窗口类名技巧

  • 2013年03月31日 11:49
  • 31KB
  • 下载

如何提供对 MFC 对话框为您自己窗口类名

注意 Microsoft Visual c + +.net 2002年和 Microsoft Visual c + +.net 2003年支持托管的代码模型所提供的 Microsoft.net 框...

如何改变MFC应用程序主窗口的类名

说明     MFC自动创建的应用程序中,主窗口的类名是固定的。但在许多情况下,你可能希望自己拟定MFC的主窗口的类名。     如果你想进行进程间通信(IPC),这种技术就更显得简洁有效。最早的...
  • xuhaofu
  • xuhaofu
  • 2014年02月20日 21:26
  • 1000

更改MFC对话框默认的窗口类名

原文地址::http://blog.csdn.net/flyoxs/article/details/2812625   相关网帖 1.关于VC中设置窗口类名----http://blog.csd...

修改基于对话框的MFC程序的主窗口类名

在单文档对象模型中修改主窗口的类名只需 重载 PreCreateWindow 函数,并在其中填写如下代码即可 //BOOL CReporterDlg::PreCreateWindow(CREATES...

窗口类名察看器(mini spy++)

  • 2008年02月01日 10:34
  • 9KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC注册窗口类以及FindWindow按窗口类名查询
举报原因:
原因补充:

(最多只允许输入30个字)