栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在WPF中,如何将AppBar停靠到屏幕边缘,例如WinAmp?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在WPF中,如何将AppBar停靠到屏幕边缘,例如WinAmp?

请注意: 这个问题收集了很多反馈,下面的一些人提出了要点或修正。因此,尽管我将代码保存在这里(并可能进行更新),但我还在
github上 创建了一个
WpfAppBar项目
。随时发送请求请求。

该项目还构建到WpfAppBar nuget包中


我从问题中提供的第一个链接(http://www.preproject.com/KB/dotnet/AppBar.aspx)中获取了代码,并对其进行了修改,以完成两件事:

  1. 使用WPF
  2. 是“独立的”-如果将此单个文件放在项目中,则可以调用AppBarFunctions.SetAppBar(…),而无需对窗口进行任何进一步的修改。

这种方法不会创建基类。

使用时,只需在普通的wpf窗口中的任何位置调用此代码即可(例如单击按钮或初始化)。请注意,只有在初始化窗口之后才能调用此函数,如果尚未创建HWND(如在构造函数中),则会发生错误。

将窗口设为应用栏:

AppBarFunctions.SetAppBar( this, ABEdge.Right );

将窗口还原为普通窗口:

AppBarFunctions.SetAppBar( this, ABEdge.None );

这是文件的完整代码- 请注意, 您需要将第7行的名称空间更改为适当的名称。

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;        }        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);        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 ABSetPos(ABEdge edge, Window appbarWindow)        { APPBARDATA barData = new APPBARDATA(); barData.cbSize = Marshal.SizeOf(barData); barData.hWnd = new WindowInteropHelper(appbarWindow).Handle; barData.uEdge = (int)edge; if (barData.uEdge == (int)ABEdge.Left || barData.uEdge == (int)ABEdge.Right) {     barData.rc.top = 0;     barData.rc.bottom = (int)SystemParameters.PrimaryScreenHeight;     if (barData.uEdge == (int)ABEdge.Left)     {         barData.rc.left = 0;         barData.rc.right = (int)Math.Round(appbarWindow.ActualWidth);     }     else     {         barData.rc.right = (int)SystemParameters.PrimaryScreenWidth;         barData.rc.left = barData.rc.right - (int)Math.Round(appbarWindow.ActualWidth);     } } else {     barData.rc.left = 0;     barData.rc.right = (int)SystemParameters.PrimaryScreenWidth;     if (barData.uEdge == (int)ABEdge.Top)     {         barData.rc.top = 0;         barData.rc.bottom = (int)Math.Round(appbarWindow.ActualHeight);     }     else     {         barData.rc.bottom = (int)SystemParameters.PrimaryScreenHeight;         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);        }    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/576269.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号