Cập nhật:
Theo @donovan, ngày nay WPF hỗ trợ điều này nguyên bản, thông qua cài đặt
ShowInTaskbar="False"
và Visibility="Hidden"
trong XAML. (Tôi chưa thử nghiệm điều này, nhưng tuy nhiên, tôi quyết định tăng khả năng hiển thị nhận xét)
Câu trả lời ban đầu:
Có hai cách để ẩn một cửa sổ khỏi trình chuyển đổi tác vụ trong Win32 API:
- để thêm
WS_EX_TOOLWINDOW
kiểu cửa sổ mở rộng - đó là cách tiếp cận phù hợp.
- để biến nó thành một cửa sổ con của một cửa sổ khác.
Thật không may, WPF không hỗ trợ kiểm soát linh hoạt kiểu cửa sổ như Win32, do đó, một cửa sổ WindowStyle=ToolWindow
kết thúc với kiểu WS_CAPTION
và WS_SYSMENU
kiểu mặc định , khiến nó có chú thích và nút đóng. Mặt khác, bạn có thể loại bỏ hai kiểu này bằng cách cài đặt WindowStyle=None
, tuy nhiên điều đó sẽ không đặt WS_EX_TOOLWINDOW
kiểu mở rộng và cửa sổ sẽ không bị ẩn khỏi trình chuyển đổi tác vụ.
Để có một cửa sổ WPF WindowStyle=None
cũng bị ẩn khỏi trình chuyển đổi tác vụ, bạn có thể thực hiện một trong hai cách:
- đi với mã mẫu ở trên và đặt cửa sổ thành cửa sổ con của một cửa sổ công cụ ẩn nhỏ
- sửa đổi kiểu cửa sổ để bao gồm cả
WS_EX_TOOLWINDOW
kiểu mở rộng.
Cá nhân tôi thích cách tiếp cận thứ hai hơn. Sau đó, một lần nữa, tôi thực hiện một số công việc nâng cao như mở rộng kính trong khu vực khách hàng và bật bản vẽ WPF trong chú thích, vì vậy một chút tương tác không phải là vấn đề lớn.
Đây là mã mẫu cho cách tiếp cận giải pháp tương tác Win32. Đầu tiên, phần 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" >
Không có gì quá lạ mắt ở đây, chúng tôi chỉ khai báo một cửa sổ với WindowStyle=None
và ShowInTaskbar=False
. Chúng tôi cũng thêm một trình xử lý vào sự kiện Đã tải, nơi chúng tôi sẽ sửa đổi kiểu cửa sổ mở rộng. Chúng tôi không thể thực hiện công việc đó trong hàm tạo, vì chưa có cửa sổ xử lý tại thời điểm đó. Bản thân trình xử lý sự kiện rất đơn giản:
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);
}
Và các khai báo Interop Win32. Tôi đã xóa tất cả các kiểu không cần thiết khỏi enum, chỉ để giữ cho mã mẫu ở đây nhỏ. Ngoài ra, không may là SetWindowLongPtr
điểm nhập không được tìm thấy trong user32.dll trên Windows XP, do đó, mẹo định tuyến cuộc gọi thông qua SetWindowLong
thay thế.
#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