簡體   English   中英

如何將第二個(子)窗體與主(父)窗體一起放在 windows z-order 的前面

[英]How can I bring a second (child) form to the front of the windows z-order along with main (parent) form

正如標題所暗示的那樣,當我的主表單 (FormA) 被激活(具有焦點)時,我想將輔助表單(沒有任務欄圖標的 FormB)帶到前面(z 順序)。

例如,我的程序以兩種形式(FormA 和 FormB)運行。 然后我打開最大化記事本(只是為了覆蓋我的應用程序包含在屏幕上的兩個表單 [FormA 和 FormB])。 然后我單擊屏幕底部我的應用程序(即 FormA)的 Windows 任務欄項以打開我的應用程序備份。 發生這種情況時,FormB 不會顯示,而是留在 z 順序的背景中。 我希望這兩種形式都放在所有其他形式的前面。

最后像任何普通應用程序一樣恢復FormA時,FormB應該是相同的Z-ORDER減去ONE。

電流源示例

public partial class FormA : Form
{
  public FormA()
  {
    Log FormB = new FormB();
    FormB.Show();

    Log FormB = new FormB();
    FormB.ShowDialog();
  }

  private void FormA_Activated(object sender, EventArgs e)
  {
    if (FormB.Visible)
    {
      FormB.Show();
    }
  }
}

我最終通過一些試驗和錯誤找到了如何做到這一點。 希望這可以幫助其他人在未來我想在這里發布我的發現。

因為 .NET Form 類不直接支持它,所以您需要使用SetWindowPos API。 要做到這一點,需要做四件事。 以下所有來源都可以添加到您的 FORM 來源 (FormA) 中。

如下所示,用法 (#4) 顯示了我在主窗體 (FormA) 頂部使用工具條菜單項(文件、編輯等)的示例。 然后作為我的日志表單 (FormB) 的第二個表單被認為是次要表單。 這可以通過多種形式完成(如我的示例所示,超過 2 個)。

注意:我的所有工具條菜單項都將CheckOnClick設置為 TRUE。 這樣每次您選擇菜單項時,它們都會被打開和關閉。

  1. 聲明枚舉

    #region Enums public enum SpecialWindowHandles { /// <summary> /// Places the window at the top of the Z order. /// </summary> HWND_TOP = 0, /// <summary> /// Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows. /// </summary> HWND_BOTTOM = 1, /// <summary> /// Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated. /// </summary> HWND_TOPMOST = -1, /// <summary> /// Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window. /// </summary> HWND_NOTOPMOST = -2 } [Flags] public enum SetWindowPosFlags : uint { /// <summary> /// If the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request. /// </summary> SWP_ASYNCWINDOWPOS = 0x4000, /// <summary> /// Prevents generation of the WM_SYNCPAINT message. /// </summary> SWP_DEFERERASE = 0x2000, /// <summary> /// Draws a frame (defined in the window's class description) around the window. /// </summary> SWP_DRAWFRAME = 0x0020, /// <summary> /// Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed. /// </summary> SWP_FRAMECHANGED = 0x0020, /// <summary> /// Hides the window. /// </summary> SWP_HIDEWINDOW = 0x0080, /// <summary> /// Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter). /// </summary> SWP_NOACTIVATE = 0x0010, /// <summary> /// Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned. /// </summary> SWP_NOCOPYBITS = 0x0100, /// <summary> /// Retains the current position (ignores X and Y parameters). /// </summary> SWP_NOMOVE = 0x0002, /// <summary> /// Does not change the owner window's position in the Z order. /// </summary> SWP_NOOWNERZORDER = 0x0200, /// <summary> /// Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing. /// </summary> SWP_NOREDRAW = 0x0008, /// <summary> /// Same as the SWP_NOOWNERZORDER flag. /// </summary> SWP_NOREPOSITION = 0x0200, /// <summary> /// Prevents the window from receiving the WM_WINDOWPOSCHANGING message. /// </summary> SWP_NOSENDCHANGING = 0x0400, /// <summary> /// Retains the current size (ignores the cx and cy parameters). /// </summary> SWP_NOSIZE = 0x0001, /// <summary> /// Retains the current Z order (ignores the hWndInsertAfter parameter). /// </summary> SWP_NOZORDER = 0x0004, /// <summary> /// Displays the window. /// </summary> SWP_SHOWWINDOW = 0x0040, } #endregion
  2. 聲明 API

     #region APIs [DllImport("user32.dll", SetLastError = true)] private static extern bool SetWindowPos(IntPtr hWnd, SpecialWindowHandles hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags); #endregion
  3. 創建函數

    #region Functions private void BringVisibleWindowsToFront() { //Get parent form handle IntPtr hndParentWindow = this.Handle; //Bring all childern forms to the front foreach (Form frmChild in Application.OpenForms) { //If form is not this form if (frmChild.Handle != this.Handle) { //If form is visible and not minimized if (frmChild.WindowState != FormWindowState.Minimized && frmChild.Visible == true) SetWindowPos(frmChild.Handle, SpecialWindowHandles.HWND_TOP, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE); } } //Set the parent form to the top most z order SetWindowPos(hndParentWindow, SpecialWindowHandles.HWND_TOP, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE); } private void SetAllFormWindowsAlwaysOnTop(bool active) { SpecialWindowHandles OnTop = (active ? SpecialWindowHandles.HWND_TOPMOST : SpecialWindowHandles.HWND_NOTOPMOST); //Get parent form handle IntPtr hndParentWindow = this.Handle; //Bring all childern forms to the front foreach (Form frmChild in Application.OpenForms) { //If form is not this form if (frmChild.Handle != this.Handle) { //If form is visible and not minimized if (frmChild.WindowState != FormWindowState.Minimized && frmChild.Visible == true) SetWindowPos(frmChild.Handle, OnTop, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE); } } //Set the parent form to the top most z order SetWindowPos(hndParentWindow, OnTop, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE); } #endregion
  4. 用法(工具條菜單項示例)

     #region ToolStripMenuItems events //Shows or hides the log form (FormB) private void showLogToolStripMenuItem_Click(object sender, EventArgs e) { if (showLogToolStripMenuItem.Checked) { FormB.ShowLog(true); SetAllFormWindowsAlwaysOnTop(alwaysOnTopToolStripMenuItem.Checked); } else FormB.ShowLog(false); } //Sets all the forms (in this case FormA and FormB) to always be on top or not private void alwaysOnTopToolStripMenuItem_Click(object sender, EventArgs e) { SetAllFormWindowsAlwaysOnTop(alwaysOnTopToolStripMenuItem.Checked); } #endregion

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM