熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#中如何處理父窗口及其子窗口標題

2022-06-13   來源: .NET編程 

  如果你用 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/CMDIChildWndNET 框架平台裡則設置 FormIsMdiContainer 和 FormMdiParent不管用哪種方式其核心都是 user kernel尤其是 DefFrameProc當 MDI 子窗口最大化時它會聯接父子窗口的標題文本來產生主窗口標題串理解了這一點下面我來示范如何改寫MDI這個例子的原始版本來自 MSDN 庫中用C#寫的 Scribble MDI(用 scribble sample搜索一下即可找到)基本思路是首先在 Scribble 例子的 MainWindow 中改寫 WM_GETTEXT 消息處理例程必須添加兩個數據成員NormalText 和 MaximizedText用它們來保存常態和最大化狀態的標題

   

  // in Scribblecs MainWindow class

  private String NormalText = Scribble;

  private String MaximizedText = Window is now maximized;

   

  如果想讓其它類存取這兩個成員那麼可以通過屬性機制代替數據成員

   

  private String normaltext;

  public String NormalText

  {

  get { return normaltext; }

  set { normaltext = value; }

  }

   

  因為在例子程序中 MainWindow 是唯一一個存取該字符串的類所以沒有必要使用屬性機制有了這兩個新的數據成員你要做的只是 改寫 WM_GETTEXT 處理例程返回子窗口最大化狀態以及常態時的標題文本那麼如何改寫 WM_GETTEXT 處理例程呢?

   

  WindowsForms 提供了一些 處理 WM_XXX 消息的虛擬函數如 OnResize/WM_SIZE等但是恰恰缺少與 WM_GETTEXT 相關東東(OnGetText/WM_GETTEXT)不要擔心沒有虛函數我們總是可以改寫包羅萬象的 WndProc 處理例程為此必須知道所處理的消息ID也就是 WM_GETTEXT 的消息 ID = xD有人會問你是怎麼知道這個消息的 ID 是 xD 啊很簡單一種方法是運行 SPY 獲取另一種方法是直接查找Windows SDK 中的 winuserh 頭文件一旦你能深入到 WndProc 這一層次編寫代碼那麼你基本上能用 C 語言寫程序了因為 Win API 和其它語言之間所有東東通過 WPARAMs 和 LPARAMs 參數傳遞的包括字符串在內對於 WM_GETTEXT 來說MessageLParam 是指向 char* 的指針MessageWParam 是該指針長度也就是說你必須完成將文本串拷貝到調用者的緩沖裡好在這並不是太難下面是程序代碼

   

  public class MainWindow : SystemWindowsFormsForm

  {

  private String NormalText = Scribble;

  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 = xD;

  if (mMsg==WM_GETTEXT) {

  Form active = thisActiveMdiChild;

  String s = active!=null &&

  activeWindowState==FormWindowStateMaximized ? MaximizedText :

  NormalText;

  char[] c = sToCharArray();

  IntPtr buf = mLParam;

  int len = cLength;

  MarshalCopy(c buf MathMin((int)mWParam len));

  mResult = (IntPtr)len;

  return;

  }

  baseWndProc(ref m);

  }

   

   // rest of MainWindow unchanged from Scribble sample

   

  }

   

  經過上述的改動現在運行程序當MDI子窗口最大化時主窗口標題顯示的文本是Window is now maximized如圖一所示



圖一 子窗口最大化時的主窗口標題

  當兩個窗口處於常態時其畫面如圖二所示



圖二 子窗口在常態時兩個窗口的標題
From:http://tw.wingwit.com/Article/program/net/201311/13196.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.