WPF에서 AppBar 도킹 (예 : 화면 가장자리 잠금)에 대한 완전한 지침이 있습니까? InterOp 호출이 필요하다는 것을 알고 있지만 간단한 WPF 양식을 기반으로하는 개념 증명 또는 소비 할 수있는 구성 요소 화 된 버전을 찾고 있습니다.
관련 자료 :
제 영어가 유감입니다 ... 여기에 필립 리크의 해결책이 있습니다. 작업 표시 줄 위치 및 크기 변경과 올바르게 작동합니다.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
namespace wpf_appbar
{
public enum ABEdge : int
{
Left,
Top,
Right,
Bottom,
None
}
internal static class AppBarFunctions
{
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(Rect r)
{
Left = (int)r.Left;
Right = (int)r.Right;
Top = (int)r.Top;
Bottom = (int)r.Bottom;
}
public static bool operator ==(RECT r1, RECT r2)
{
return r1.Bottom == r2.Bottom && r1.Left == r2.Left && r1.Right == r2.Right && r1.Top == r2.Top;
}
public static bool operator !=(RECT r1, RECT r2)
{
return !(r1 == r2);
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
[StructLayout(LayoutKind.Sequential)]
private struct APPBARDATA
{
public int cbSize;
public IntPtr hWnd;
public int uCallbackMessage;
public int uEdge;
public RECT rc;
public IntPtr lParam;
}
private enum ABMsg : int
{
ABM_NEW = 0,
ABM_REMOVE,
ABM_QUERYPOS,
ABM_SETPOS,
ABM_GETSTATE,
ABM_GETTASKBARPOS,
ABM_ACTIVATE,
ABM_GETAUTOHIDEBAR,
ABM_SETAUTOHIDEBAR,
ABM_WINDOWPOSCHANGED,
ABM_SETSTATE
}
private enum ABNotify : int
{
ABN_STATECHANGE = 0,
ABN_POSCHANGED,
ABN_FULLSCREENAPP,
ABN_WINDOWARRANGE
}
private enum TaskBarPosition : int
{
Left,
Top,
Right,
Bottom
}
[StructLayout(LayoutKind.Sequential)]
class TaskBar
{
public TaskBarPosition Position;
public TaskBarPosition PreviousPosition;
public RECT Rectangle;
public RECT PreviousRectangle;
public int Width;
public int PreviousWidth;
public int Height;
public int PreviousHeight;
public TaskBar()
{
Refresh();
}
public void Refresh()
{
APPBARDATA msgData = new APPBARDATA();
msgData.cbSize = Marshal.SizeOf(msgData);
SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref msgData);
PreviousPosition = Position;
PreviousRectangle = Rectangle;
PreviousHeight = Height;
PreviousWidth = Width;
Rectangle = msgData.rc;
Width = Rectangle.Right - Rectangle.Left;
Height = Rectangle.Bottom - Rectangle.Top;
int h = (int)SystemParameters.PrimaryScreenHeight;
int w = (int)SystemParameters.PrimaryScreenWidth;
if (Rectangle.Bottom == h && Rectangle.Top != 0) Position = TaskBarPosition.Bottom;
else if (Rectangle.Top == 0 && Rectangle.Bottom != h) Position = TaskBarPosition.Top;
else if (Rectangle.Right == w && Rectangle.Left != 0) Position = TaskBarPosition.Right;
else if (Rectangle.Left == 0 && Rectangle.Right != w) Position = TaskBarPosition.Left;
}
}
[DllImport("Shell32", CallingConvention = CallingConvention.StdCall)]
private static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int RegisterWindowMessage(string msg);
private class RegisterInfo
{
public int CallbackId { get; set; }
public bool IsRegistered { get; set; }
public Window Window { get; set; }
public ABEdge Edge { get; set; }
public ABEdge PreviousEdge { get; set; }
public WindowStyle OriginalStyle { get; set; }
public Point OriginalPosition { get; set; }
public Size OriginalSize { get; set; }
public ResizeMode OriginalResizeMode { get; set; }
public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam,
IntPtr lParam, ref bool handled)
{
if (msg == CallbackId)
{
if (wParam.ToInt32() == (int)ABNotify.ABN_POSCHANGED)
{
PreviousEdge = Edge;
ABSetPos(Edge, PreviousEdge, Window);
handled = true;
}
}
return IntPtr.Zero;
}
}
private static Dictionary<Window, RegisterInfo> s_RegisteredWindowInfo
= new Dictionary<Window, RegisterInfo>();
private static RegisterInfo GetRegisterInfo(Window appbarWindow)
{
RegisterInfo reg;
if (s_RegisteredWindowInfo.ContainsKey(appbarWindow))
{
reg = s_RegisteredWindowInfo[appbarWindow];
}
else
{
reg = new RegisterInfo()
{
CallbackId = 0,
Window = appbarWindow,
IsRegistered = false,
Edge = ABEdge.None,
PreviousEdge = ABEdge.None,
OriginalStyle = appbarWindow.WindowStyle,
OriginalPosition = new Point(appbarWindow.Left, appbarWindow.Top),
OriginalSize =
new Size(appbarWindow.ActualWidth, appbarWindow.ActualHeight),
OriginalResizeMode = appbarWindow.ResizeMode,
};
s_RegisteredWindowInfo.Add(appbarWindow, reg);
}
return reg;
}
private static void RestoreWindow(Window appbarWindow)
{
RegisterInfo info = GetRegisterInfo(appbarWindow);
appbarWindow.WindowStyle = info.OriginalStyle;
appbarWindow.ResizeMode = info.OriginalResizeMode;
appbarWindow.Topmost = false;
Rect rect = new Rect(info.OriginalPosition.X, info.OriginalPosition.Y,
info.OriginalSize.Width, info.OriginalSize.Height);
appbarWindow.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
new ResizeDelegate(DoResize), appbarWindow, rect);
}
public static void SetAppBar(Window appbarWindow, ABEdge Edge)
{
RegisterInfo info = GetRegisterInfo(appbarWindow);
info.Edge = Edge;
APPBARDATA abd = new APPBARDATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = new WindowInteropHelper(appbarWindow).Handle;
if (Edge == ABEdge.None)
{
if (info.IsRegistered)
{
SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref abd);
info.IsRegistered = false;
}
RestoreWindow(appbarWindow);
info.PreviousEdge = info.Edge;
return;
}
if (!info.IsRegistered)
{
info.IsRegistered = true;
info.CallbackId = RegisterWindowMessage("AppBarMessage");
abd.uCallbackMessage = info.CallbackId;
uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd);
HwndSource source = HwndSource.FromHwnd(abd.hWnd);
source.AddHook(new HwndSourceHook(info.WndProc));
}
appbarWindow.WindowStyle = WindowStyle.None;
appbarWindow.ResizeMode = ResizeMode.NoResize;
appbarWindow.Topmost = true;
ABSetPos(info.Edge, info.PreviousEdge, appbarWindow);
}
private delegate void ResizeDelegate(Window appbarWindow, Rect rect);
private static void DoResize(Window appbarWindow, Rect rect)
{
appbarWindow.Width = rect.Width;
appbarWindow.Height = rect.Height;
appbarWindow.Top = rect.Top;
appbarWindow.Left = rect.Left;
}
static TaskBar tb = new TaskBar();
private static void ABSetPos(ABEdge Edge, ABEdge prevEdge, Window appbarWindow)
{
APPBARDATA barData = new APPBARDATA();
barData.cbSize = Marshal.SizeOf(barData);
barData.hWnd = new WindowInteropHelper(appbarWindow).Handle;
barData.uEdge = (int)Edge;
RECT wa = new RECT(SystemParameters.WorkArea);
tb.Refresh();
switch (Edge)
{
case ABEdge.Top:
barData.rc.Left = wa.Left - (prevEdge == ABEdge.Left ? (int)Math.Round(appbarWindow.ActualWidth) : 0);
barData.rc.Right = wa.Right + (prevEdge == ABEdge.Right ? (int)Math.Round(appbarWindow.ActualWidth) : 0);
barData.rc.Top = wa.Top - (prevEdge == ABEdge.Top ? (int)Math.Round(appbarWindow.ActualHeight) : 0) - ((tb.Position != TaskBarPosition.Top && tb.PreviousPosition == TaskBarPosition.Top) ? tb.Height : 0) + ((tb.Position == TaskBarPosition.Top && tb.PreviousPosition != TaskBarPosition.Top) ? tb.Height : 0);
barData.rc.Bottom = barData.rc.Top + (int)Math.Round(appbarWindow.ActualHeight);
break;
case ABEdge.Bottom:
barData.rc.Left = wa.Left - (prevEdge == ABEdge.Left ? (int)Math.Round(appbarWindow.ActualWidth) : 0);
barData.rc.Right = wa.Right + (prevEdge == ABEdge.Right ? (int)Math.Round(appbarWindow.ActualWidth) : 0);
barData.rc.Bottom = wa.Bottom + (prevEdge == ABEdge.Bottom ? (int)Math.Round(appbarWindow.ActualHeight) : 0) - 1 + ((tb.Position != TaskBarPosition.Bottom && tb.PreviousPosition == TaskBarPosition.Bottom) ? tb.Height : 0) - ((tb.Position == TaskBarPosition.Bottom && tb.PreviousPosition != TaskBarPosition.Bottom) ? tb.Height : 0);
barData.rc.Top = barData.rc.Bottom - (int)Math.Round(appbarWindow.ActualHeight);
break;
}
SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref barData);
switch (barData.uEdge)
{
case (int)ABEdge.Bottom:
if (tb.Position == TaskBarPosition.Bottom && tb.PreviousPosition == tb.Position)
{
barData.rc.Top += (tb.PreviousHeight - tb.Height);
barData.rc.Bottom = barData.rc.Top + (int)appbarWindow.ActualHeight;
}
break;
case (int)ABEdge.Top:
if (tb.Position == TaskBarPosition.Top && tb.PreviousPosition == tb.Position)
{
if (tb.PreviousHeight - tb.Height > 0) barData.rc.Top -= (tb.PreviousHeight - tb.Height);
barData.rc.Bottom = barData.rc.Top + (int)appbarWindow.ActualHeight;
}
break;
}
SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref barData);
Rect rect = new Rect((double)barData.rc.Left, (double)barData.rc.Top, (double)(barData.rc.Right - barData.rc.Left), (double)(barData.rc.Bottom - barData.rc.Top));
appbarWindow.Dispatcher.BeginInvoke(new ResizeDelegate(DoResize), DispatcherPriority.ApplicationIdle, appbarWindow, rect);
}
}
}
왼쪽 및 오른쪽 가장자리에 작성할 수있는 것과 동일한 코드입니다. 잘 했어, 필립 리크, 고마워!
여러 디스플레이 설정에서 작동하도록 Philip Rieck (btw. Thanks)의 코드를 수정했습니다. 여기 내 해결책이 있습니다.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
namespace AppBarApplication
{
public enum ABEdge : int
{
Left = 0,
Top,
Right,
Bottom,
None
}
internal static class AppBarFunctions
{
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct APPBARDATA
{
public int cbSize;
public IntPtr hWnd;
public int uCallbackMessage;
public int uEdge;
public RECT rc;
public IntPtr lParam;
}
[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFO
{
public int cbSize;
public RECT rcMonitor;
public RECT rcWork;
public int dwFlags;
}
private enum ABMsg : int
{
ABM_NEW = 0,
ABM_REMOVE,
ABM_QUERYPOS,
ABM_SETPOS,
ABM_GETSTATE,
ABM_GETTASKBARPOS,
ABM_ACTIVATE,
ABM_GETAUTOHIDEBAR,
ABM_SETAUTOHIDEBAR,
ABM_WINDOWPOSCHANGED,
ABM_SETSTATE
}
private enum ABNotify : int
{
ABN_STATECHANGE = 0,
ABN_POSCHANGED,
ABN_FULLSCREENAPP,
ABN_WINDOWARRANGE
}
[DllImport("Shell32", CallingConvention = CallingConvention.StdCall)]
private static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int RegisterWindowMessage(string msg);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO mi);
private const int MONITOR_DEFAULTTONEAREST = 0x2;
private const int MONITORINFOF_PRIMARY = 0x1;
private class RegisterInfo
{
public int CallbackId { get; set; }
public bool IsRegistered { get; set; }
public Window Window { get; set; }
public ABEdge Edge { get; set; }
public WindowStyle OriginalStyle { get; set; }
public Point OriginalPosition { get; set; }
public Size OriginalSize { get; set; }
public ResizeMode OriginalResizeMode { get; set; }
public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam,
IntPtr lParam, ref bool handled)
{
if (msg == CallbackId)
{
if (wParam.ToInt32() == (int)ABNotify.ABN_POSCHANGED)
{
ABSetPos(Edge, Window);
handled = true;
}
}
return IntPtr.Zero;
}
}
private static Dictionary<Window, RegisterInfo> s_RegisteredWindowInfo
= new Dictionary<Window, RegisterInfo>();
private static RegisterInfo GetRegisterInfo(Window appbarWindow)
{
RegisterInfo reg;
if (s_RegisteredWindowInfo.ContainsKey(appbarWindow))
{
reg = s_RegisteredWindowInfo[appbarWindow];
}
else
{
reg = new RegisterInfo()
{
CallbackId = 0,
Window = appbarWindow,
IsRegistered = false,
Edge = ABEdge.Top,
OriginalStyle = appbarWindow.WindowStyle,
OriginalPosition = new Point(appbarWindow.Left, appbarWindow.Top),
OriginalSize =
new Size(appbarWindow.ActualWidth, appbarWindow.ActualHeight),
OriginalResizeMode = appbarWindow.ResizeMode,
};
s_RegisteredWindowInfo.Add(appbarWindow, reg);
}
return reg;
}
private static void RestoreWindow(Window appbarWindow)
{
RegisterInfo info = GetRegisterInfo(appbarWindow);
appbarWindow.WindowStyle = info.OriginalStyle;
appbarWindow.ResizeMode = info.OriginalResizeMode;
appbarWindow.Topmost = false;
Rect rect = new Rect(info.OriginalPosition.X, info.OriginalPosition.Y,
info.OriginalSize.Width, info.OriginalSize.Height);
appbarWindow.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
new ResizeDelegate(DoResize), appbarWindow, rect);
}
public static void SetAppBar(Window appbarWindow, ABEdge Edge)
{
RegisterInfo info = GetRegisterInfo(appbarWindow);
info.Edge = Edge;
APPBARDATA abd = new APPBARDATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = new WindowInteropHelper(appbarWindow).Handle;
if (Edge == ABEdge.None)
{
if (info.IsRegistered)
{
SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref abd);
info.IsRegistered = false;
}
RestoreWindow(appbarWindow);
return;
}
if (!info.IsRegistered)
{
info.IsRegistered = true;
info.CallbackId = RegisterWindowMessage("AppBarMessage");
abd.uCallbackMessage = info.CallbackId;
uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd);
HwndSource source = HwndSource.FromHwnd(abd.hWnd);
source.AddHook(new HwndSourceHook(info.WndProc));
}
appbarWindow.WindowStyle = WindowStyle.None;
appbarWindow.ResizeMode = ResizeMode.NoResize;
appbarWindow.Topmost = true;
ABSetPos(info.Edge, appbarWindow);
}
private delegate void ResizeDelegate(Window appbarWindow, Rect rect);
private static void DoResize(Window appbarWindow, Rect rect)
{
appbarWindow.Width = rect.Width;
appbarWindow.Height = rect.Height;
appbarWindow.Top = rect.Top;
appbarWindow.Left = rect.Left;
}
private static void GetActualScreenData(ABEdge Edge, Window appbarWindow, ref int leftOffset, ref int topOffset, ref int actualScreenWidth, ref int actualScreenHeight)
{
IntPtr handle = new WindowInteropHelper(appbarWindow).Handle;
IntPtr monitorHandle = MonitorFromWindow(handle, MONITOR_DEFAULTTONEAREST);
MONITORINFO mi = new MONITORINFO();
mi.cbSize = Marshal.SizeOf(mi);
if (GetMonitorInfo(monitorHandle, ref mi))
{
if (mi.dwFlags == MONITORINFOF_PRIMARY)
{
return;
}
leftOffset = mi.rcWork.left;
topOffset = mi.rcWork.top;
actualScreenWidth = mi.rcWork.right - leftOffset;
actualScreenHeight = mi.rcWork.bottom - mi.rcWork.top;
}
}
private static void ABSetPos(ABEdge Edge, Window appbarWindow)
{
APPBARDATA barData = new APPBARDATA();
barData.cbSize = Marshal.SizeOf(barData);
barData.hWnd = new WindowInteropHelper(appbarWindow).Handle;
barData.uEdge = (int)Edge;
int leftOffset = 0;
int topOffset = 0;
int actualScreenWidth = (int)SystemParameters.PrimaryScreenWidth;
int actualScreenHeight = (int)SystemParameters.PrimaryScreenHeight;
GetActualScreenData(Edge, appbarWindow, ref leftOffset, ref topOffset, ref actualScreenWidth, ref actualScreenHeight);
if (barData.uEdge == (int)ABEdge.Left || barData.uEdge == (int)ABEdge.Right)
{
barData.rc.top = topOffset;
barData.rc.bottom = actualScreenHeight;
if (barData.uEdge == (int)ABEdge.Left)
{
barData.rc.left = leftOffset;
barData.rc.right = (int)Math.Round(appbarWindow.ActualWidth) + leftOffset;
}
else
{
barData.rc.right = actualScreenWidth + leftOffset;
barData.rc.left = barData.rc.right - (int)Math.Round(appbarWindow.ActualWidth);
}
}
else
{
barData.rc.left = leftOffset;
barData.rc.right = actualScreenWidth + leftOffset;
if (barData.uEdge == (int)ABEdge.Top)
{
barData.rc.top = topOffset;
barData.rc.bottom = (int)Math.Round(appbarWindow.ActualHeight) + topOffset;
}
else
{
barData.rc.bottom = actualScreenHeight + topOffset;
barData.rc.top = barData.rc.bottom - (int)Math.Round(appbarWindow.ActualHeight);
}
}
SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref barData);
SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref barData);
Rect rect = new Rect((double)barData.rc.left, (double)barData.rc.top,
(double)(barData.rc.right - barData.rc.left), (double)(barData.rc.bottom - barData.rc.top));
//This is done async, because WPF will send a resize after a new appbar is added.
//if we size right away, WPFs resize comes last and overrides us.
appbarWindow.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
new ResizeDelegate(DoResize), appbarWindow, rect);
}
}
}
1996 년부터 훌륭한 MSDN 기사가 있습니다. 응용 프로그램 도구 모음으로 Windows 95 셸 확장 . 이 지침에 따라이 페이지의 다른 답변에서는 수행 할 수없는 많은 시나리오를 처리하는 WPF 기반 앱 바가 생성됩니다.
데모 응용 프로그램과 GitHub에서 AppBarWindow
구현 가 있습니다.
사용 예 :
<apb:AppBarWindow x:Class="WpfAppBarDemo.MainWindow" xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:apb="clr-namespace:WpfAppBar;Assembly=WpfAppBar"
DataContext="{Binding RelativeSource={RelativeSource Self}}" Title="MainWindow"
DockedWidthOrHeight="200" MinHeight="100" MinWidth="100">
<Grid>
<Button x:Name="btClose" Content="Close" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Height="23" Margin="10,10,0,0" Click="btClose_Click"/>
<ComboBox x:Name="cbMonitor" SelectedItem="{Binding Path=Monitor, Mode=TwoWay}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,38,0,0"/>
<ComboBox x:Name="cbEdge" SelectedItem="{Binding Path=DockMode, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,65,0,0" VerticalAlignment="Top" Width="120"/>
<Thumb Width="5" HorizontalAlignment="Right" Background="Gray" x:Name="rzThumb" Cursor="SizeWE" DragCompleted="rzThumb_DragCompleted" />
</Grid>
</apb:AppBarWindow>
코드 비하인드 :
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
this.cbEdge.ItemsSource = new[]
{
AppBarDockMode.Left,
AppBarDockMode.Right,
AppBarDockMode.Top,
AppBarDockMode.Bottom
};
this.cbMonitor.ItemsSource = MonitorInfo.GetAllMonitors();
}
private void btClose_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void rzThumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
this.DockedWidthOrHeight += (int)(e.HorizontalChange / VisualTreeHelper.GetDpi(this).PixelsPerDip);
}
}
도킹 된 위치 변경 :
엄지 손가락으로 크기 조정 :
다른 앱 바와의 협력 :
복제하려는 경우 from GitHub 라이브러리 자체는 3 개의 파일 일 뿐이므로 프로젝트에 쉽게 놓을 수 있습니다.
이 질문을 발견하게되어 매우 기쁩니다. 위의 클래스는 실제로 유용하지만 AppBar 구현의 모든 기초를 다루지는 않습니다.
AppBar의 모든 동작을 완전히 구현하려면 (전체 화면 응용 프로그램 등에 대처)이 MSDN 기사도 읽으십시오.
나는 몇 주 동안이 과제를 탐구하고 마침내이 기능을 매우 친숙한 방식으로 제공하는 매우 견고한 NuGet 패키지를 만들었습니다. 새 WPF 앱을 만든 다음 기본 창의 클래스를 Window에서 DockWindow (XAML의 경우)로 변경하면됩니다.
here 패키지를 가져 와서 데모 앱의 Git 저장소를 참조하십시오.
상용 대안으로, 작업 표시 줄이 왼쪽, 오른쪽, 위쪽, 아래쪽 가장자리에 도킹 된 모든 경우 및 보안을 지원하는 WPF의 즉시 사용 가능한 ShellAppBar 구성 요소, 다중 모니터 지원, 드래그- 도킹, 자동 숨기기 등을 사용하면 이러한 모든 경우를 직접 처리하는 데 드는 시간과 비용을 절약 할 수 있습니다.
[~ # ~] 면책 조항 [~ # ~] : ShellAppBar의 개발자 인 LogicNP Software에서 일합니다.
작업 표시 줄의 크기를 조정할 때 마지막으로 게시 한 코드가 작동하지 않았습니다. 다음 코드 변경이 더 잘 작동하는 것 같습니다.
SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref barData); if (barData.uEdge == (int)ABEdge.Top) barData.rc.bottom = barData.rc.top + (int)Math.Round(appbarWindow.ActualHeight); else if (barData.uEdge == (int)ABEdge.Bottom) barData.rc.top = barData.rc.bottom - (int)Math.Round(appbarWindow.ActualHeight); SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref barData);