mfc vs2013 项目怎么更改类名_如何改变MFC应用程序主窗口的类名 | 学步园

0_1306364554fe9j.gif

说明

MFC自动创建的应用程序中,主窗口的类名是固定的。但在许多情况下,你可能希望自己拟定MFC的主窗口的类名。

如果你想进行进程间通信(IPC),这种技术就更显得简洁有效。最早的实现不同进程间通信的方法是发送消息,但是发送消息需要知道发送的目标对象,即确定目标窗口,识别出它的ID。

一种方法是迭代所有具有最上面显示属性的窗口,然后选出目标窗口的类名或者窗口名称,或者你也可以向所有窗口广播一个注册的窗口消息。这两种方法显得过于繁琐,因为我们通过一种方法可以直接一个特定的窗口。

Windows提供了一个函数FindWindow,它可以根据一个特定的名称或者类名找到特定的窗口。

windows中的窗口的标题常常由于打开文件的不同而发生改变,甚至用户改变了本地语言(当然前提是程序支持多种语言),窗口标题也会发生改变。但是如果你能给一个类预定义一个类名,那么你就可以根据这个唯一的类名找到这个窗口。

唯一的问题是,MFC创建的程序的类名在MFC程序创建时已经被预定义了。对于一个给予dialog的程序来说,这个预定义的类名是#32770。

背景知识

根据上面的分析,程序员现在面临的唯一的问题就是如何改变MFC程序的预定义的名称。

对于MFC SDI/MDI程序来说,我们可以通过函数 CMainFrame::PreCreateWindow 来改变类名。

对于基于dialog的程序来说,我们可以定义一个资源模板,在这个资源里指定类名,然后在VS编译程序时强制它加载这个资源。

SDI/MDI程序的代码示例

如果你用MFC创建一个SDI/MDI程序,你会发现一个函数CMainFrame::PreCReateWindow,在窗口创建过程中,这个函数会被调用很多次,应为它里面提供了窗口的类信息、窗口的风格等相关的窗口信息。

你可以重写这个函数,把一个窗口类名为你定义的名称的窗口类对象注册后,然后把窗口类名赋给返回值的类名属性,以供后续步骤继续使用。

函数CMainFrame::PreCreateWindow至少会被调用两次。MFC创建窗口过程中会检查由窗口结构体(window class struct)定义的icon值与CWinApp::LoadFrame定义和使用的icon值是否一致。如果MFC产生窗口过程中(一般是函数CFrameWnd::GetIconWndClass)发现窗口结构体对象定义了一个不同的icon,则MFC会自己使用它认为是正确的icon值来产生一个窗口类。一般的,icon的ID是IDR_MAINFRAME。

下面给出了一个程序员自己重写的函数CMainFrame::PreCreateWindow的示例。

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

if( !CFrameWnd::PreCreateWindow(cs) )

return FALSE;

// Just clear the styles we don't want.

cs.dwExStyle &= ~WS_EX_CLIENTEDGE;

// Check if our class is already defined

LPCTSTR pszClassName = _T("OwnClassName");

WNDCLASS wndcls;

if (!::GetClassInfo(AfxGetInstanceHandle(), pszClassName, &wndcls))

{

// Get the current requested window class

VERIFY(GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wndcls));

// We want to register this info with our name

wndcls.lpszClassName = pszClassName;

// Need to preset the icon otherwise the function GetIconWndClass

// calling us will overwrite our class.

LPCTSTR pszIcon = MAKEINTRESOURCE(IDR_MAINFRAME);

HINSTANCE hInst = AfxFindResourceHandle(pszIcon, ATL_RT_GROUP_ICON);

_ASSERTE(hInst!=NULL);

wndcls.hIcon =     ::LoadIcon(hInst, pszIcon);

// Register our class now and check the outcome

if (!::RegisterClass(&wndcls))

{

_ASSERTE(!__FUNCTION__ "RegisterClass failed");

return FALSE;

}

}

// Now use our class

cs.lpszClass = pszClassName;

return TRUE;

}

基于dialog程序的代码示例

在一个基于dialog的程序中,你需要做两件事。

一般的,基于对话框的程序中,其对话框的类名是"#32770"。当你想用一个不同的类来创建一个对话框时,那就需要告知程序对话框模板的类名,因为我们不能不能像处理SDI/MDI程序一样干预对话框的创建。在以往的VS程序中,我们可以打开资源编辑器,改变对话框的类名,但是VS-2008和VS-2010里面有一个bug,所以它们俩不允许我们指定类名。在资源编辑器中这个属性值的属性框是灰色的,所以不能改变类名。即使你通过其他手段改变了类名,这个地方也显示不出改变后的正确值。

所谓的其他手段,就是你可以在你的程序打开前,用其他编辑器,如记事本程序代开你的资源文件,找到你的对话框模板后,在其中添加一行CLASSNAME属性。添加完毕后,VS编译程序时会根据这行属性确定的类名来定义一个窗口,它不会删除这行值。

示例代码:

IDD_OWNCLASSNAMEDLG_DIALOG DIALOGEX 0, 0, 199, 28

STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE |

WS_CAPTION | WS_SYSMENU | WS_THICKFRAME

EXSTYLE WS_EX_APPWINDOW

CAPTION "OwnClassNameDlg"

CLASS "OwnClassNameDlg"

FONT 8, "MS Shell Dlg", 0, 0, 0x1

BEGIN

...

剩下的事情,就是在待用函数dlg.DoModal()之前,注册一个新的基于系统类#32770的窗口类,这个类的名称就是你刚才指定的类名。

代码并不是很复杂,示例如下:...

// Just get default class for the dialogs

WNDCLASS wndcls;

::GetClassInfo(NULL,MAKEINTRESOURCE(32770),&wndcls);

// Set our own class name

wndcls.lpszClassName = _T("OwnClassNameDlg");

// Just register the class

if (!::RegisterClass(&wndcls))

{

_ASSERTE(! __FUNCTION__ " Failed to register window class");

return FALSE;

}

COwnClassNameDlgDlg dlg;

m_pMainWnd = &dlg;

INT_PTR nResponse = dlg.DoModal();

...

补充说明:实际上,"#32770"并不能被称为一个窗口类名。它只是一个注册的对话框类的ID值,代码MAKEINTRESOURCE(32770)会把它变成类的名称。你也可以使用字符串"32770"来代表这个类。

啰嗦了一大堆,希望你喜欢我上面给你的这个小技巧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值