อัปเดต:
ตามที่ @donovan WPF ยุคปัจจุบันสนับสนุนสิ่งนี้โดยกำเนิดผ่านการตั้งค่า
ShowInTaskbar="False"
และVisibility="Hidden"
ใน XAML (ฉันยังไม่ได้ทดสอบ แต่อย่างไรก็ตามตัดสินใจที่จะชนการแสดงความคิดเห็น)
คำตอบเดิม:
มีสองวิธีในการซ่อนหน้าต่างจากตัวสลับงานใน Win32 API:
- เพื่อเพิ่ม
WS_EX_TOOLWINDOW
สไตล์หน้าต่างขยายนั่นคือแนวทางที่ถูกต้อง
- เพื่อทำให้เป็นหน้าต่างย่อยของหน้าต่างอื่น
น่าเสียดายที่ WPF ไม่รองรับการควบคุมรูปแบบหน้าต่างที่ยืดหยุ่นเท่ากับ Win32 ดังนั้นหน้าต่างที่มีWindowStyle=ToolWindow
ค่าเริ่มต้นWS_CAPTION
และWS_SYSMENU
สไตล์ซึ่งทำให้มีคำอธิบายภาพและปุ่มปิด ในทางกลับกันคุณสามารถลบสองสไตล์นี้ได้โดยการตั้งค่าWindowStyle=None
อย่างไรก็ตามจะไม่ตั้งค่าWS_EX_TOOLWINDOW
รูปแบบขยายและหน้าต่างจะไม่ถูกซ่อนจากตัวสลับงาน
หากต้องการมีหน้าต่าง WPF WindowStyle=None
ที่ซ่อนอยู่จากตัวสลับงานสามารถทำได้สองวิธี:
- ไปกับโค้ดตัวอย่างด้านบนและทำให้หน้าต่างเป็นหน้าต่างย่อยของหน้าต่างเครื่องมือขนาดเล็กที่ซ่อนอยู่
- ปรับเปลี่ยนสไตล์หน้าต่างเพื่อรวม
WS_EX_TOOLWINDOW
สไตล์เพิ่มเติมด้วย
โดยส่วนตัวแล้วฉันชอบแนวทางที่สองมากกว่า จากนั้นอีกครั้งฉันทำสิ่งขั้นสูงบางอย่างเช่นการขยายกระจกในพื้นที่ไคลเอนต์และเปิดใช้งานการวาด WPF ในคำบรรยายภาพดังนั้นการทำงานร่วมกันเล็กน้อยจึงไม่ใช่ปัญหาใหญ่
นี่คือโค้ดตัวอย่างสำหรับแนวทางการแก้ปัญหาการทำงานร่วมกันของ Win32 ขั้นแรกส่วน XAML:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300"
ShowInTaskbar="False" WindowStyle="None"
Loaded="Window_Loaded" >
ไม่มีอะไรเกินไปแฟนซีที่นี่เราก็ประกาศหน้าต่างด้วยและWindowStyle=None
ShowInTaskbar=False
นอกจากนี้เรายังเพิ่มตัวจัดการให้กับเหตุการณ์ Loaded ซึ่งเราจะปรับเปลี่ยนรูปแบบหน้าต่างขยาย เราไม่สามารถทำงานนั้นในตัวสร้างได้เนื่องจากยังไม่มีที่จับหน้าต่างในตอนนั้น ตัวจัดการเหตุการณ์นั้นง่ายมาก:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WindowInteropHelper wndHelper = new WindowInteropHelper(this);
int exStyle = (int)GetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE);
exStyle |= (int)ExtendedWindowStyles.WS_EX_TOOLWINDOW;
SetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE, (IntPtr)exStyle);
}
และการประกาศการทำงานร่วมกันของ Win32 ฉันได้ลบรูปแบบที่ไม่จำเป็นทั้งหมดออกจาก enums เพียงเพื่อให้โค้ดตัวอย่างมีขนาดเล็ก นอกจากนี้น่าเสียดายที่SetWindowLongPtr
ไม่พบจุดเข้าใช้งานใน user32.dll บน Windows XP ดังนั้นเคล็ดลับด้วยการกำหนดเส้นทางการโทรผ่านSetWindowLong
แทน
#region Window styles
[Flags]
public enum ExtendedWindowStyles
{
// ...
WS_EX_TOOLWINDOW = 0x00000080,
// ...
}
public enum GetWindowLongFields
{
// ...
GWL_EXSTYLE = (-20),
// ...
}
[DllImport("user32.dll")]
public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
{
int error = 0;
IntPtr result = IntPtr.Zero;
// Win32 SetWindowLong doesn't clear error on success
SetLastError(0);
if (IntPtr.Size == 4)
{
// use SetWindowLong
Int32 tempResult = IntSetWindowLong(hWnd, nIndex, IntPtrToInt32(dwNewLong));
error = Marshal.GetLastWin32Error();
result = new IntPtr(tempResult);
}
else
{
// use SetWindowLongPtr
result = IntSetWindowLongPtr(hWnd, nIndex, dwNewLong);
error = Marshal.GetLastWin32Error();
}
if ((result == IntPtr.Zero) && (error != 0))
{
throw new System.ComponentModel.Win32Exception(error);
}
return result;
}
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)]
private static extern IntPtr IntSetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)]
private static extern Int32 IntSetWindowLong(IntPtr hWnd, int nIndex, Int32 dwNewLong);
private static int IntPtrToInt32(IntPtr intPtr)
{
return unchecked((int)intPtr.ToInt64());
}
[DllImport("kernel32.dll", EntryPoint = "SetLastError")]
public static extern void SetLastError(int dwErrorCode);
#endregion