我已經使用WPF Shell集成庫(http://archive.msdn.microsoft.com/WPFShell)實現了自定義窗口鑲邊。當ResizeMode設置爲NoResize時,系統關閉自定義窗口鑲邊中的按鈕表面
Chrome的工作原理是將ReSizeMode設置爲NoResize。然後,如果將鼠標懸停在關閉按鈕上,我注意到自定義鉻合金關閉按鈕下方顯示了基礎系統關閉按鈕。
預期的行爲是基本關閉按鈕應該永遠不會顯示。如果我移動窗口或在桌面上選擇另一個窗口並回到這個窗口,我注意到系統關閉按鈕再次隱藏。 所以可能基本上是當(1)應用程序第一次啓動時和(2)當ResizeMode = NoResize時。
我的第一個懷疑是我們如何處理Custom Chrome中的WM.NCHITTEST。如果我修改這個函數返回HTCLient,那麼這個問題就解決了。但是,我失去了拖放功能,並且右鍵單擊標題欄。
這是WindowsChromeWorker類的WM.NCHITTEST消息處理程序的代碼。
private IntPtr _HandleNCHitTest(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled) {
IntPtr lRet = IntPtr.Zero;
handled = false;
// Give DWM a chance at this first.
if (Utility.IsOSVistaOrNewer && _chromeInfo.GlassFrameThickness != default(Thickness) && _isGlassEnabled) {
// If we're on Vista, give the DWM a chance to handle the message first.
handled = NativeMethods.DwmDefWindowProc(_hwnd, uMsg, wParam, lParam, out lRet);
}
// Handle letting the system know if we consider the mouse to be in our effective non-client area.
// If DWM already handled this by way of DwmDefWindowProc, then respect their call.
if (IntPtr.Zero == lRet) {
var mousePosScreen = new Point(Utility.GET_X_LPARAM(lParam), Utility.GET_Y_LPARAM(lParam));
Rect windowPosition = _GetWindowRect();
HT ht = _HitTestNca(
DpiHelper.DeviceRectToLogical(windowPosition),
DpiHelper.DevicePixelsToLogical(mousePosScreen));
// Don't blindly respect HTCAPTION.
// We want UIElements in the caption area to be actionable so run through a hittest first.
if (ht != HT.CLIENT) {
Point mousePosWindow = mousePosScreen;
mousePosWindow.Offset(-windowPosition.X, -windowPosition.Y);
mousePosWindow = DpiHelper.DevicePixelsToLogical(mousePosWindow);
IInputElement inputElement = _window.InputHitTest(mousePosWindow);
if (inputElement != null && WindowChrome.GetIsHitTestVisibleInChrome(inputElement)) {
ht = HT.CLIENT;
}
}
//handled = false;
handled = true;
lRet = new IntPtr((int)ht);
}
return lRet;
}
private static readonly HT[,] _HitTestBorders = new[,]
{
{ HT.TOPLEFT, HT.TOP, HT.TOPRIGHT },
{ HT.LEFT, HT.CLIENT, HT.RIGHT },
{ HT.BOTTOMLEFT, HT.BOTTOM, HT.BOTTOMRIGHT },
};
private HT _HitTestNca(Rect windowPosition, Point mousePosition) {
// Determine if hit test is for resizing, default middle (1,1).
int uRow = 1;
int uCol = 1;
bool onResizeBorder = false;
//if (_window.ResizeMode == ResizeMode.NoResize)
// _chromeInfo.ResizeBorderThickness = new Thickness(0);
// Determine if the point is at the top or bottom of the window.
if (mousePosition.Y >= windowPosition.Top && mousePosition.Y < windowPosition.Top + _chromeInfo.ResizeBorderThickness.Top + _chromeInfo.CaptionHeight) {
onResizeBorder = (mousePosition.Y < (windowPosition.Top + _chromeInfo.ResizeBorderThickness.Top));
uRow = 0; // top (caption or resize border)
} else if (mousePosition.Y < windowPosition.Bottom && mousePosition.Y >= windowPosition.Bottom - (int)_chromeInfo.ResizeBorderThickness.Bottom) {
uRow = 2; // bottom
}
// Determine if the point is at the left or right of the window.
if (mousePosition.X >= windowPosition.Left && mousePosition.X < windowPosition.Left + (int)_chromeInfo.ResizeBorderThickness.Left) {
uCol = 0; // left side
} else if (mousePosition.X < windowPosition.Right && mousePosition.X >= windowPosition.Right - _chromeInfo.ResizeBorderThickness.Right) {
uCol = 2; // right side
}
// If the cursor is in one of the top edges by the caption bar, but below the top resize border,
// then resize left-right rather than diagonally.
if (uRow == 0 && uCol != 1 && !onResizeBorder) {
uRow = 1;
}
HT ht = _HitTestBorders[uRow, uCol];
if (ht == HT.TOP && !onResizeBorder) {
ht = HT.CAPTION;
}
return ht;
}
任何想法如何解決這個問題?
非常感謝, 阿瓊