设为首页 友情链接
在线留言 发表文章
加入收藏 广告联系

刺猬首页

| 专案技术 | 网络技术 | 图形图象 | 网络编程 | 网页设计 | 操作系统 | 服务器 | 技术白皮书 | 在线实验室 | 刺猬论坛 |
  | 数据库 | 设计赏析 | 存储频道 | 网络安全 | 私服架设 |  Solaris | 网站评估 | PC维护技巧 | 下载中心 | 博 客 |
专题: | Linux | java | cisco | 防病毒 | 刀片 | SOA | iscsi | ASP.NET | SQL | Oracle |
您现在的位置: IT公社 IT community >> 网络编程 >> C# >> 教程正文 用户登录 新用户注册
专 题 栏 目
最 新 热 门
最 新 推 荐
相 关 文 章
使用C#开发SmartPhone程…
用C#实现智能设备上的No…
PHP中如何使用header发送…
VS2005中使用C#的新特性…
C#获取WAVE文件文件头信…
C#中势将窗体拖拽进行到…
关于C#中枚举打印机
C#位图处理指针问题
选择 VB.NET 还是 C# ?
数据结构与算法(C#实现)…
  C#中如何处理父窗口及其子窗口标题         ★★★★★
C#中如何处理父窗口及其子窗口标题
 

【导读】本文将示范如何在C#程序中定制和修改MDI应用的窗口标题。

如果你用 MFC 编写过多文档界面(MDI)Windows 程序,那么肯定知道:如果父窗口标题为“PCaption”,子窗口标题为“CCaption”,那么每当子窗口最大化并处于激活状态时,子窗口标题一般都会与父窗口标题合二为一,变成“PCaption-[CCaption]”。 这是一种 MDI 的默认行为。用 C# 编写多文档界面程序也不例外。很多用户都不喜欢这种缺省特性,往往想用定制的窗口标题取而代之。本文将示范如何在C#程序中定制和修改MDI应用的窗口标题。

如果用MFC来编程,只要改写框架窗口类的虚函数 CFrameWnd::OnUpdateFrameTitle 即可。那么在微软的 .NET 框架中如何用C#实现相同的功能呢?首先,我们必须理解 MDI 本身是如何通过 Windows 核心 API 来实现自己的行为特性的,其实这与MFC或者.NET的公共语言运行时(CLR)没有什么关系。在创建MDI应用时,框架及其子窗口有各自专门的窗口过程,DefFrameProc 和 DefMDIChildProc,一个处理各种 WM_MDIXXX 消息以及其它类似 WM_SIZE, WM_SYSCOMMAND 的消息,另一个实现 MDI 行为。

如果用纯 C 代码编写,那么必须自己负责用 DefFrameProc 和 DefMDIChildProc 创建窗口;在 MFC 中则使用 CMDIFrameWnd/CMDIChildWnd;.NET 框架平台里则设置 Form.IsMdiContainer 和 Form.MdiParent,不管用哪种方式,其核心都是 user kernel,尤其是 DefFrameProc,当 MDI 子窗口最大化时,它会联接父子窗口的标题文本来产生主窗口标题串。理解了这一点,下面我来示范如何改写MDI。这个例子的原始版本来自 MSDN 库中用C#写的 Scribble MDI(用 “scribble sample”搜索一下即可找到)。基本思路是首先在 Scribble 例子的 MainWindow 中改写 WM_GETTEXT 消息处理例程,必须添加两个数据成员:NormalText 和 MaximizedText,用它们来保存常态和最大化状态的标题 :

// in Scribble.cs, MainWindow class

private String NormalText = "Scribble2";

private String MaximizedText = "Window is now maximized";

如果想让其它类存取这两个成员,那么可以通过属性机制代替数据成员,如:

private String normaltext;

public String NormalText

{

get { return normaltext; }

set { normaltext = value; }

}

因为在例子程序中 MainWindow 是唯一一个存取该字符串的类,所以没有必要使用属性机制。有了这两个新的数据成员,你要做的只是 改写 WM_GETTEXT 处理例程,返回子窗口最大化状态以及常态时的标题文本。那么如何改写 WM_GETTEXT 处理例程呢?

Windows.Forms 提供了一些 处理 WM_XXX 消息的虚拟函数,如 OnResize/WM_SIZE等,但是恰恰缺少与 WM_GETTEXT 相关东东(OnGetText/WM_GETTEXT)。不要担心,没有虚函数,我们总是可以改写包罗万象的 WndProc 处理例程。为此必须知道所处理的消息ID,也就是 WM_GETTEXT 的消息 ID = 0x000D,有人会问,你是怎么知道这个消息的 ID 是 0x000D 啊,很简单,一种方法是运行 SPY 获取,另一种方法是直接查找Windows SDK 中的 winuser.h 头文件。一旦你能深入到 WndProc 这一层次编写代码,那么你基本上能用 C 语言写程序了,因为 Win32 API 和其它语言之间所有东东通过 WPARAMs 和 LPARAMs 参数传递的,包括字符串在内。对于 WM_GETTEXT 来说,Message.LParam 是指向 char* 的指针,Message.WParam 是该指针长度。也就是说你必须完成将文本串拷贝到调用者的缓冲里。好在这并不是太难,下面是程序代码:

public class MainWindow : System.Windows.Forms.Form

{

  private String NormalText = "Scribble2";

  private String MaximizedText = "Window is now maximized";

  // Handle WM_GETTEXT: Return maximized or

  // normal text, depending on

  // state of active MDI child window.

  protected override void WndProc(ref Message m)

  {

const int WM_GETTEXT = 0x000D;

if (m.Msg==WM_GETTEXT) {

  Form active = this.ActiveMdiChild;

  String s = active!=null &&

  active.WindowState==FormWindowState.Maximized ? MaximizedText :

NormalText;

  char[] c = s.ToCharArray();

  IntPtr buf = m.LParam;

  int len = c.Length;

  Marshal.Copy(c, 0, buf, Math.Min((int)m.WParam, len));

  m.Result = (IntPtr)len;

  return;

}

base.WndProc(ref m);

  }

  ...... // rest of MainWindow unchanged from Scribble sample

}

经过上述的改动,现在运行程序,当MDI子窗口最大化时,主窗口标题显示的文本是“Window is now maximized”,如图一所示,



图一 子窗口最大化时的主窗口标题



当两个窗口处于常态时,其画面如图二所示:



图二 子窗口在常态时两个窗口的标题

频道声明:本频道的文章除部分特别声明禁止转载的专稿外,可以自由转载.但请务必注明出出处和原始作者 文章版权归本频道与文章作者所有.对于被频道转载文章的个人和网站,我们表示深深的谢意。

原始作者:佚名 录入时间:2006-10-10
信息来源:不详 投稿信箱:itqoo@126.com
教程录入:admin    责任编辑:admin 
  • 上一个教程:

  • 下一个教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    - 关于我们 - 合作伙伴 - 友情链接 - 广告刊登 - 投稿热线 - 在线留言版权声明联系方式 -
    IT公社版权所有 粤ICP备05127012号
    Copyrigh@2005-2006 itqoo.com.Inc All Rights Reserved  推荐分辨率 1024*768
    联系站长:E-Mail:itqoo@126.com     MSN:urchincc@hotmail.com    QQ:点击这里给我发消息
    特别感谢:亿太网络提供空间支持