TECHNOLOGIES
FORUMS
JOBS
BOOKS
EVENTS
INTERVIEWS
Live
MORE
LEARN
Training
CAREER
MEMBERS
VIDEOS
NEWS
BLOGS
Sign Up
Login
No unread comment.
View All Comments
No unread message.
View All Messages
No unread notification.
View All Notifications
Answers
Post
An Article
A Blog
A News
A Video
An EBook
An Interview Question
Ask Question
Forums
Monthly Leaders
Forum guidelines
Boblysan
NA
66
0
APPBAR - Base class - Please help!
Jan 21 2005 1:38 AM
Ok, I ran across this AppBar class that works extremely well. Unfortunately, I am having a difficult time trying to figure out how to make things happen the way I'd like. My goal is to place a toolbar control on the AppBar form and have the orientation of the toolbar changed based on the horizontal / vertical screen alignment of the AppBar. It doesn't seem like this should be that difficult but I have been unable to figure it out as of yet. I have spent many hours on MSDN reading through the APPBAR docs and still have had no luck. How can I note which edge of the screen the appbar successfully docs to and then perform some action? The action I perform I can take care. My issue up to this point has been with following exactly where the code goes and determining how to trigger based on this event. (event = which edge did the appbar just doc to?) The code I found is listed below.. (long) ------------------------------------------------------------------------------------------------------------ // Contributed by Dean Cleaver - [
[email protected]
] // a base class for implementing a dockable Windows App-Bar // Much of the code ported from a C/C++ implementation by Jeffrey Richter #region Copyright © 2002-2004 The Genghis Group /* * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not claim * that you wrote the original software. If you use this software in a product, * an acknowledgment in the product documentation is IsRequired, as shown here: * * Portions Copyright © 2002-2004 The Genghis Group (http://www.genghisgroup.com/). * * 2. No substantial portion of the source code of this library may be redistributed * without the express written permission of the copyright holders, where * "substantial" is defined as enough code to be recognizably from this library. */ #endregion #region History // 4/15/2003 - Initial Version #endregion using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Design; using System.Globalization; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Windows.Forms; using System.Windows.Forms.Design; namespace Genghis.Windows.Forms { ///
/// Summary description for AppBar. ///
public class AppBarForm : System.Windows.Forms.Form { // The header from the original cpp file this was generated from. // Most of the credit belongs to Jeffrey Richter /****************************************************************************** Module name: AppBar.cpp Written by: Jeffrey Richter Purpose: AppBar base class implementation file. ******************************************************************************/ #region Private Structures [StructLayout(LayoutKind.Sequential)] private struct POINT { public int X; public int Y; public POINT(int X, int Y) { this.X = X; this.Y = Y; } public POINT(int pos) { this.X = pos & 0xFFFF; this.Y = (pos >> 16) & 0xFFFF; } } [StructLayout(LayoutKind.Sequential)] private struct RECT { public int left; public int top; public int right; public int bottom; public RECT(int left, int top, int right, int bottom) { this.left = left; this.right = right; this.top = top; this.bottom = bottom; } public int Width { get {return right - left;} } public int Height { get {return bottom - top;} } public static bool operator != (RECT o1, RECT o2) { if (o1.left != o2.left) return true; if (o1.right != o2.right) return true; if (o1.top != o2.top) return true; if (o1.bottom != o2.bottom) return true; return false; } public static bool operator == (RECT o1, RECT o2) { if (o1.left != o2.left) return false; if (o1.right != o2.right) return false; if (o1.top != o2.top) return false; if (o1.bottom != o2.bottom) return false; return false; } public override bool Equals(object o) { try { RECT o2 = (RECT) o; return this == o2; } catch { return false; } } public override int GetHashCode() { return base.GetHashCode(); } } [StructLayout(LayoutKind.Sequential)] private struct APPBARSTATE { public int size; // Size of this structure public int state; // ABE_UNKNOWN, ABE_FLOAT, or ABE_edge public bool autoHide; // Should AppBar be auto-hidden when docked? public bool alwaysOnTop; // Should AppBar always be on top? public int dockSizeHorizontal; public int dockSizeVertical; public RECT floatRect; // Floating rectangle (in screen coordinates) public int taskBarState; public int dockFlags; // See the ABF_* flags above public SIZE sizeInc; // Descrete width/height size increments public int proposedState; public bool fullScreenAppOpen; public bool autoHideIsVisible; } [StructLayout(LayoutKind.Sequential)] private struct APPBARDATA { public int size; public int hWnd; public int callbackMessage; public int edge; public RECT position; public int lParam; // message specific } [StructLayout(LayoutKind.Sequential)] private struct SIZE { public int cx; public int cy; public SIZE(int cx, int cy) { this.cx = cx; this.cy = cy; } } #endregion #region Private Constants private const int ABE_LEFT = 0; private const int ABE_TOP = 1; private const int ABE_RIGHT = 2; private const int ABE_BOTTOM = 3; private const int ABE_UNKNOWN = 4; private const int ABE_FLOAT = 5; private const int ABF_ALLOWLEFT = 0x00000001; private const int ABF_ALLOWRIGHT = 0x00000004; private const int ABF_ALLOWTOP = 0x00000002; private const int ABF_ALLOWBOTTOM = 0x00000008; private const int ABF_ALLOWFLOAT = 0x00000010; private const int ABF_ALLOWLEFTRIGHT = (ABF_ALLOWLEFT | ABF_ALLOWRIGHT); private const int ABF_ALLOWTOPBOTTOM = (ABF_ALLOWTOP | ABF_ALLOWBOTTOM); private const int ABF_ALLOWANYEDGE = (ABF_ALLOWLEFTRIGHT | ABF_ALLOWTOPBOTTOM); private const int ABF_ALLOWANYWHERE = (ABF_ALLOWANYEDGE | ABF_ALLOWFLOAT); private const int ABF_MIMICTASKBARAUTOHIDE = 0x00000020; private const int ABF_MIMICTASKBARALWAYSONTOP = 0x00000040; private const int ABM_NEW = 0x00000000; private const int ABM_REMOVE = 0x00000001; private const int ABM_QUERYPOS = 0x00000002; private const int ABM_SETPOS = 0x00000003; private const int ABM_GETSTATE = 0x00000004; private const int ABM_GETTASKBARPOS = 0x00000005; private const int ABM_ACTIVATE = 0x00000006; private const int ABM_GETAUTOHIDEBAR = 0x00000007; private const int ABM_SETAUTOHIDEBAR = 0x00000008; private const int ABM_WINDOWPOSCHANGED = 0x00000009; private const int ABN_FULLSCREENAPP = 0x2; private const int ABN_POSCHANGED = 0x1; private const int ABN_STATECHANGE = 0x0; private const int ABN_WINDOWARRANGE = 0x3; // lParam == TRUE means hide private const int ABS_AUTOHIDE = 0x0000001; private const int ABS_ALWAYSONTOP = 0x0000002; private const int AUTOHIDETIMERINTERVAL = 400; private const int AUTOHIDETIMERID = 1; private const short GWL_STYLE = (-16); private const short GWL_EXSTYLE = (-20); private const int HTBORDER = 18; private const int HTBOTTOM = 15; private const int HTBOTTOMLEFT = 16; private const int HTBOTTOMRIGHT = 17; private const int HTCAPTION = 2; private const int HTCLIENT = 1; private const int HTERROR = (-2); private const int HTGROWBOX = 4; private const int HTHSCROLL = 6; private const int HTLEFT = 10; private const int HTMAXBUTTON = 9; private const int HTMENU = 5; private const int HTMINBUTTON = 8; private const int HTNOWHERE = 0; private const int HTREDUCE = HTMINBUTTON; private const int HTRIGHT = 11; private const int HTSIZE = HTGROWBOX; private const int HTSIZEFIRST = HTLEFT; private const int HTSIZELAST = HTBOTTOMRIGHT; private const int HTSYSMENU = 3; private const int HTTOP = 12; private const int HTTOPLEFT = 13; private const int HTTOPRIGHT = 14; private const int HTTRANSPARENT = (-1); private const int HTVSCROLL = 7; private const int HTZOOM = HTMAXBUTTON; private const int HWND_TOP = 0; private const int HWND_BOTTOM = 1; private const int HWND_TOPMOST = -1; private const int HWND_NOTOPMOST = -2; private const int SM_SWAPBUTTON = 23; private const int SM_CXDOUBLECLK = 36; private const int SM_CYDOUBLECLK = 37; private const int SM_CXVSCROLL = 2; private const int SM_CXHSCROLL = 21; private const int SM_CYHSCROLL = 3; private const int SM_CXSCREEN = 0; private const int SM_CYSCREEN = 1; private const int SM_CXBORDER = 5; private const int SM_CYBORDER = 6; private const int SPI_GETDRAGFULLWINDOWS = 38; private const int SPI_GETWORKAREA = 48; private const int SWP_NOSIZE = 0x0001; private const int SWP_NOMOVE = 0x0002; private const int SWP_NOZORDER = 0x0004; private const int SWP_NOREDRAW = 0x0008; private const int SWP_NOACTIVATE = 0x0010; private const int SWP_FRAMECHANGED =0x0020; private const int SWP_DRAWFRAME = SWP_FRAMECHANGED; private const int VK_CONTROL = 0x11; private const int VK_RBUTTON = 0x2; private const int VK_LBUTTON = 0x1; private const int WA_INACTIVE = 0; private const int WMSZ_LEFT = 1; private const int WMSZ_RIGHT = 2; private const int WMSZ_TOP = 3; private const int WMSZ_TOPLEFT = 4; private const int WMSZ_TOPRIGHT = 5; private const int WMSZ_BOTTOM = 6; private const int WMSZ_BOTTOMLEFT = 7; private const int WMSZ_BOTTOMRIGHT = 8; private const int WM_NULL = 0x0000; private const int WM_CREATE = 0x0001; private const int WM_DESTROY = 0x0002; private const int WM_MOVE = 0x0003; private const int WM_SIZE = 0x0005; private const int WM_ACTIVATE = 0x0006; private const int WM_SETFOCUS = 0x0007; private const int WM_KILLFOCUS = 0x0008; private const int WM_ENABLE = 0x000A; private const int WM_SETREDRAW = 0x000B; private const int WM_SETTEXT = 0x000C; private const int WM_GETTEXT = 0x000D; private const int WM_GETTEXTLENGTH = 0x000E; private const int WM_PAINT = 0x000F; private const int WM_CLOSE = 0x0010; private const int WM_QUERYENDSESSION = 0x0011; private const int WM_QUIT = 0x0012; private const int WM_QUERYOPEN = 0x0013; private const int WM_ERASEBKGND = 0x0014; private const int WM_SYSCOLORCHANGE = 0x0015; private const int WM_ENDSESSION = 0x0016; private const int WM_SHOWWINDOW = 0x0018; private const int WM_CTLCOLOR = 0x0019; private const int WM_WININICHANGE = 0x001A; private const int WM_SETTINGCHANGE = 0x001A; private const int WM_DEVMODECHANGE = 0x001B; private const int WM_ACTIVATEAPP = 0x001C; private const int WM_FONTCHANGE = 0x001D; private const int WM_TIMECHANGE = 0x001E; private const int WM_CANCELMODE = 0x001F; private const int WM_SETCURSOR = 0x0020; private const int WM_MOUSEACTIVATE = 0x0021; private const int WM_CHILDACTIVATE = 0x0022; private const int WM_QUEUESYNC = 0x0023; private const int WM_GETMINMAXINFO = 0x0024; private const int WM_PAINTICON = 0x0026; private const int WM_ICONERASEBKGND = 0x0027; private const int WM_NEXTDLGCTL = 0x0028; private const int WM_SPOOLERSTATUS = 0x002A; private const int WM_DRAWITEM = 0x002B; private const int WM_MEASUREITEM = 0x002C; private const int WM_DELETEITEM = 0x002D; private const int WM_VKEYTOITEM = 0x002E; private const int WM_CHARTOITEM = 0x002F; private const int WM_SETFONT = 0x0030; private const int WM_GETFONT = 0x0031; private const int WM_SETHOTKEY = 0x0032; private const int WM_GETHOTKEY = 0x0033; private const int WM_QUERYDRAGICON = 0x0037; private const int WM_COMPAREITEM = 0x0039; private const int WM_GETOBJECT = 0x003D; private const int WM_COMPACTING = 0x0041; private const int WM_COMMNOTIFY = 0x0044 ; private const int WM_WINDOWPOSCHANGING = 0x0046; private const int WM_WINDOWPOSCHANGED = 0x0047; private const int WM_POWER = 0x0048; private const int WM_COPYDATA = 0x004A; private const int WM_CANCELJOURNAL = 0x004B; private const int WM_NOTIFY = 0x004E; private const int WM_INPUTLANGCHANGEREQUEST = 0x0050; private const int WM_INPUTLANGCHANGE = 0x0051; private const int WM_TCARD = 0x0052; private const int WM_HELP = 0x0053; private const int WM_USERCHANGED = 0x0054; private const int WM_NOTIFYFORMAT = 0x0055; private const int WM_CONTEXTMENU = 0x007B; private const int WM_STYLECHANGING = 0x007C; private const int WM_STYLECHANGED = 0x007D; private const int WM_DISPLAYCHANGE = 0x007E; private const int WM_GETICON = 0x007F; private const int WM_SETICON = 0x0080; private const int WM_NCCREATE = 0x0081; private const int WM_NCDESTROY = 0x0082; private const int WM_NCCALCSIZE = 0x0083; private const int WM_NCHITTEST = 0x0084; private const int WM_NCPAINT = 0x0085; private const int WM_NCACTIVATE = 0x0086; private const int WM_GETDLGCODE = 0x0087; private const int WM_SYNCPAINT = 0x0088; private const int WM_NCMOUSEMOVE = 0x00A0; private const int WM_NCLBUTTONDOWN = 0x00A1; private const int WM_NCLBUTTONUP = 0x00A2; private const int WM_NCLBUTTONDBLCLK = 0x00A3; private const int WM_NCRBUTTONDOWN = 0x00A4; private const int WM_NCRBUTTONUP = 0x00A5; private const int WM_NCRBUTTONDBLCLK = 0x00A6; private const int WM_NCMBUTTONDOWN = 0x00A7; private const int WM_NCMBUTTONUP = 0x00A8; private const int WM_NCMBUTTONDBLCLK = 0x00A9; private const int WM_KEYDOWN = 0x0100; private const int WM_KEYUP = 0x0101; private const int WM_CHAR = 0x0102; private const int WM_DEADCHAR = 0x0103; private const int WM_SYSKEYDOWN = 0x0104; private const int WM_SYSKEYUP = 0x0105; private const int WM_SYSCHAR = 0x0106; private const int WM_SYSDEADCHAR = 0x0107; private const int WM_KEYLAST = 0x0108; private const int WM_IME_STARTCOMPOSITION = 0x010D; private const int WM_IME_ENDCOMPOSITION = 0x010E; private const int WM_IME_COMPOSITION = 0x010F; private const int WM_IME_KEYLAST = 0x010F; private const int WM_INITDIALOG = 0x0110; private const int WM_COMMAND = 0x0111; private const int WM_SYSCOMMAND = 0x0112; private const int WM_TIMER = 0x0113; private const int WM_HSCROLL = 0x0114; private const int WM_VSCROLL = 0x0115; private const int WM_INITMENU = 0x0116; private const int WM_INITMENUPOPUP = 0x0117; private const int WM_MENUSELECT = 0x011F; private const int WM_MENUCHAR = 0x0120; private const int WM_ENTERIDLE = 0x0121; private const int WM_MENURBUTTONUP = 0x0122; private const int WM_MENUDRAG = 0x0123; private const int WM_MENUGETOBJECT = 0x0124; private const int WM_UNINITMENUPOPUP = 0x0125; private const int WM_MENUCOMMAND = 0x0126; private const int WM_CTLCOLORMSGBOX = 0x0132; private const int WM_CTLCOLOREDIT = 0x0133; private const int WM_CTLCOLORLISTBOX = 0x0134; private const int WM_CTLCOLORBTN = 0x0135; private const int WM_CTLCOLORDLG = 0x0136; private const int WM_CTLCOLORSCROLLBAR = 0x0137; private const int WM_CTLCOLORSTATIC = 0x0138; private const int WM_MOUSEMOVE = 0x0200; private const int WM_LBUTTONDOWN = 0x0201; private const int WM_LBUTTONUP = 0x0202; private const int WM_LBUTTONDBLCLK = 0x0203; private const int WM_RBUTTONDOWN = 0x0204; private const int WM_RBUTTONUP = 0x0205; private const int WM_RBUTTONDBLCLK = 0x0206; private const int WM_MBUTTONDOWN = 0x0207; private const int WM_MBUTTONUP = 0x0208; private const int WM_MBUTTONDBLCLK = 0x0209; private const int WM_MOUSEWHEEL = 0x020A; private const int WM_PARENTNOTIFY = 0x0210; private const int WM_ENTERMENULOOP = 0x0211; private const int WM_EXITMENULOOP = 0x0212; private const int WM_NEXTMENU = 0x0213; private const int WM_SIZING = 0x0214; private const int WM_CAPTURECHANGED = 0x0215; private const int WM_MOVING = 0x0216; private const int WM_DEVICECHANGE = 0x0219; private const int WM_MDICREATE = 0x0220; private const int WM_MDIDESTROY = 0x0221; private const int WM_MDIACTIVATE = 0x0222; private const int WM_MDIRESTORE = 0x0223; private const int WM_MDINEXT = 0x0224; private const int WM_MDIMAXIMIZE = 0x0225; private const int WM_MDITILE = 0x0226; private const int WM_MDICASCADE = 0x0227; private const int WM_MDIICONARRANGE = 0x0228; private const int WM_MDIGETACTIVE = 0x0229; private const int WM_MDISETMENU = 0x0230; private const int WM_ENTERSIZEMOVE = 0x0231; private const int WM_EXITSIZEMOVE = 0x0232; private const int WM_DROPFILES = 0x0233; private const int WM_MDIREFRESHMENU = 0x0234; private const int WM_IME_SETCONTEXT = 0x0281; private const int WM_IME_NOTIFY = 0x0282; private const int WM_IME_CONTROL = 0x0283; private const int WM_IME_COMPOSITIONFULL = 0x0284; private const int WM_IME_SELECT = 0x0285; private const int WM_IME_CHAR = 0x0286; private const int WM_IME_REQUEST = 0x0288; private const int WM_IME_KEYDOWN = 0x0290; private const int WM_IME_KEYUP = 0x0291; private const int WM_MOUSEHOVER = 0x02A1; private const int WM_MOUSELEAVE = 0x02A3; private const int WM_CUT = 0x0300; private const int WM_COPY = 0x0301; private const int WM_PASTE = 0x0302; private const int WM_CLEAR = 0x0303; private const int WM_UNDO = 0x0304; private const int WM_RENDERFORMAT = 0x0305; private const int WM_RENDERALLFORMATS = 0x0306; private const int WM_DESTROYCLIPBOARD = 0x0307; private const int WM_DRAWCLIPBOARD = 0x0308; private const int WM_PAINTCLIPBOARD = 0x0309; private const int WM_VSCROLLCLIPBOARD = 0x030A; private const int WM_SIZECLIPBOARD = 0x030B; private const int WM_ASKCBFORMATNAME = 0x030C; private const int WM_CHANGECBCHAIN = 0x030D; private const int WM_HSCROLLCLIPBOARD = 0x030E; private const int WM_QUERYNEWPALETTE = 0x030F; private const int WM_PALETTEISCHANGING = 0x0310; private const int WM_PALETTECHANGED = 0x0311; private const int WM_HOTKEY = 0x0312; private const int WM_PRINT = 0x0317; private const int WM_PRINTCLIENT = 0x0318; private const int WM_HANDHELDFIRST = 0x0358; private const int WM_HANDHELDLAST = 0x035F; private const int WM_AFXFIRST = 0x0360; private const int WM_AFXLAST = 0x037F; private const int WM_PENWINFIRST = 0x0380; private const int WM_PENWINLAST = 0x038F; private const int WM_APP = 0x8000; private const int WM_USER = 0x0400; private const int WM_REFLECT = WM_USER + 0x1c00; private const int WM_APPBARNOTIFY = WM_USER + 100; private const int WS_CAPTION = 0x00C00000; private const int WS_SYSMENU = 0x00080000; #endregion #region Private API Functions [DllImport("user32.dll", SetLastError=true)] private static extern int AdjustWindowRectEx(ref RECT lpRect, int dsStyle, int bMenu, int dwEsStyle); [DllImport("user32.dll", SetLastError=true)] private static extern int ClientToScreen(IntPtr hwnd, ref POINT lpPoint); [DllImport("user32.dll", SetLastError=true)] private static extern Int16 GetAsyncKeyState(int vKey); [DllImport("user32.dll", SetLastError=true)] private static extern int GetClientRect(IntPtr hwnd, ref RECT rect); [DllImport("user32.dll", SetLastError=true)] private static extern int GetKeyState(Int16 nVirtKey); [DllImport("user32.dll", SetLastError=true)] private static extern int GetMessagePos(); [DllImport("user32.dll", SetLastError=true)] private static extern int GetSystemMetrics(int nIndex); [DllImport("kernel32.dll", SetLastError=true)] private static extern int GetTickCount(); [DllImport("user32.dll", SetLastError=true)] private static extern int GetWindowLong(IntPtr hwnd, Int16 nIndex); [DllImport("user32.dll", SetLastError=true)] private static extern int GetWindowRect(IntPtr hwnd, ref RECT rect); [DllImport("user32.dll", SetLastError=true)] private static extern int InflateRect(ref RECT rect, int x, int y); [DllImport("User32.dll", SetLastError=true)] private static extern int KillTimer(IntPtr hwnd, int nIDEvent); [DllImport("User32.dll", CharSet=CharSet.Auto)] private static extern bool ReleaseCapture(); [DllImport("Kernel32.dll", SetLastError=true)] private static extern void RtlMoveMemory(ref RECT Destination, IntPtr Source, int Length); [DllImport("Kernel32.dll", SetLastError=true)] private static extern void RtlMoveMemory(IntPtr Destination, ref RECT Source, int Length); [DllImport("user32.dll", CharSet=CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); [DllImport("user32.dll", SetLastError=true)] private static extern int SetTimer(IntPtr hWnd, int nIDEvent, int uElapse, int lpTimerFunc); [DllImport("User32.dll", CharSet=CharSet.Auto)] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", SetLastError=true)] private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int Width, int Height, int flags); [DllImport("shell32.dll", SetLastError=true)] private static extern int SHAppBarMessage(int message, ref APPBARDATA pData); [DllImport("user32.dll", SetLastError=true)] private static extern int SystemParametersInfoA(int uAction, int uParam, ref bool lpvParam, int fuWinIni); [DllImport("user32.dll", SetLastError=true)] private static extern int SystemParametersInfoA(int uAction, int uParam, ref RECT lpvParam, int fuWinIni); [DllImport("user32.dll", SetLastError=true)] private static extern int UpdateWindow(IntPtr hwnd); #endregion #region Public Enumerations ///
/// Enumeration for the edge that the AppBar attaches to ///
public enum AppBarEdge { Left = ABE_LEFT, Top = ABE_TOP, Right = ABE_RIGHT, Bottom = ABE_BOTTOM, Unknown = ABE_UNKNOWN, Float = ABE_FLOAT } ///
/// Enumerations for the docking options ///
[FlagsAttribute()] public enum DockFlags { AllowLeft = ABF_ALLOWLEFT, AllowTop = ABF_ALLOWTOP, AllowRight = ABF_ALLOWRIGHT, AllowBottom = ABF_ALLOWBOTTOM, AllowFloat = ABF_ALLOWFLOAT } #endregion #region Public Properties ///
/// The edges the app bar can attach to ///
[TypeConverterAttribute(typeof(DockFlagConverter)), Editor(typeof(DockFlagEditor), typeof(UITypeEditor)), Category("AppBar"), DefaultValue(DockFlags.AllowFloat), Description("The edges the app bar can attach to")] public DockFlags DockOptions { get {return (DockFlags) this.appBarState.dockFlags;} set {this.appBarState.dockFlags = (int) value;} } ///
/// The increments by which the AppBar can be resized horizontally ///
[Category("AppBar"), DefaultValue(0), Description("The increments by which the AppBar can be resized horizontally")] public int HorzSizeInc { get {return this.appBarState.sizeInc.cx;} set {this.appBarState.sizeInc.cx = value;} } ///
/// The increments by which the AppBar can be resized vertically ///
[Category("AppBar"), DefaultValue(0), Description("The increments by which the AppBar can be resized vertically")] public int VertSizeInc { get {return this.appBarState.sizeInc.cy;} set {this.appBarState.sizeInc.cy = value;} } ///
/// The default starting position of the AppBar ///
[Category("AppBar"), DefaultValue(AppBarEdge.Float), Description("The default starting position of the AppBar")] public AppBarEdge Edge { get {return (AppBarEdge) this.appBarState.state;} set {this.appBarState.state = (int) value;} } ///
/// Whether or not the AppBar hides and then slides out from the edge ///
[Category("AppBar"), DefaultValue(false), Description("Whether or not the AppBar hides and then slides out from the edge")] public bool AutoHide { get {return this.appBarState.autoHide;} set {this.appBarState.autoHide = value;} } ///
/// Whether the AppBar is always on top ///
[Category("AppBar"), DefaultValue(false), Description("Whether the AppBar is always on top")] public bool AlwaysOnTop { get {return this.appBarState.alwaysOnTop;} set {this.appBarState.alwaysOnTop = value;} } ///
/// The width of the AppBar when docked on the side ///
[Category("AppBar"), DefaultValue(0), Description("The width of the AppBar when docked on the side")] public int HorzDockSize { get {return this.appBarState.dockSizeHorizontal;} set {this.appBarState.dockSizeHorizontal = value;} } ///
/// The height of the AppBar when docked on the top or bottom ///
[Category("AppBar"), DefaultValue(0), Description("The height of the AppBar when docked on the top or bottom")] public int VertDockSize { get {return this.appBarState.dockSizeVertical;} set {this.appBarState.dockSizeVertical = value;} } #endregion #region Private Variables private APPBARSTATE appBarState; private bool initializing = false; private bool moving = false; private System.ComponentModel.IContainer components; #endregion #region Constructors public AppBarForm() { this.initializing = true; components = null; // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // // Force the shell to update its list of AppBars and the workarea. // This is a precaution and is very useful when debugging. If you create // an AppBar and then just terminate the application, the shell still // thinks that the AppBar exists and the user's workarea is smaller than // it should be. When a new AppBar is created, calling this function // fixes the user's workarea. // Set default state of AppBar to docked on bottom with no width & height this.appBarState = new APPBARSTATE(); this.appBarState.size = Marshal.SizeOf(this.appBarState); //if (this.DesignMode) this.appBarState.state = ABE_FLOAT; this.appBarState.autoHide = false; this.appBarState.alwaysOnTop = false; this.appBarState.dockSizeHorizontal = 30; this.appBarState.dockSizeVertical = 30; this.appBarState.taskBarState = AppBarMessage(ABM_GETSTATE); this.appBarState.dockFlags = ABF_ALLOWANYWHERE; this.appBarState.sizeInc = new SIZE(0, 0); // Don't allow re-sizing this.appBarState.proposedState = ABE_UNKNOWN; this.appBarState.fullScreenAppOpen = false; this.appBarState.autoHideIsVisible = false; this.appBarState.floatRect = new RECT(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height); this.initializing = false; } ///
/// Clean up any resources being used. ///
protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #endregion #region Windows Form Designer generated code ///
/// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///
private void InitializeComponent() { // // AppBarForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(400, 270); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.Location = new System.Drawing.Point(500, 500); this.Name = "AppBarForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.AppBar_MouseDown); this.Load += new System.EventHandler(this.AppBarForm_Load); this.LocationChanged += new System.EventHandler(this.AppBarForm_LocationChanged); } #endregion #region Private Functions private int GetAutohideEdge() { for (int edge = ABE_LEFT; edge <= ABE_BOTTOM; edge++) { if (this.Handle.ToInt32() == AppBarMessage(ABM_GETAUTOHIDEBAR, edge)) { // We are an auto-hide AppBar and we found our edge. return edge; } } // NOTE: If AppBar is docked but not auto-hidden, we return ABE_UNKNOWN return ABE_UNKNOWN; } private bool ModifyStyle(Int16 styleOffset, int remove, int add, int flags) { int style = GetWindowLong(this.Handle, styleOffset); int newStyle = (style & (~ remove)) | add; if (style == newStyle) return false; SetWindowLong(this.Handle, styleOffset, newStyle); if (flags != 0) SetWindowPos(this.Handle, new IntPtr(0), 0, 0, 0, 0, ((SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE) | flags)); return true; } private void MimicState (int stateChangedMask, int state) { bool anyChange = false; // Assume that nothing changes // If the autohide state changed AND our style allows // us to mimic the Autohide state if (((stateChangedMask & ABS_AUTOHIDE) != 0) && ((this.appBarState.dockFlags & ABF_MIMICTASKBARAUTOHIDE) != 0)) { bool autoHide = (ABS_AUTOHIDE & state) != 0; // If our state doesn't match, change our state if (this.appBarState.autoHide != autoHide) { this.appBarState.autoHide = autoHide; anyChange = true; } } // If the AlwaysOnTop state changed AND our style allows // us to mimic the AlwaysOnTop state/ if (((stateChangedMask & ABS_ALWAYSONTOP) != 0) && ((this.appBarState.dockFlags & ABF_MIMICTASKBARALWAYSONTOP) != 0)) { // If our state doesn't match, change our state this.appBarState.alwaysOnTop = (ABS_ALWAYSONTOP & state) != 0; anyChange = true; } if (anyChange) { SetState(); ShowHiddenAppBar(false); } } private void SetState(int state) { if (this.DesignMode) return; // If the AppBar is registered as auto-hide, unregister it. int edge = GetAutohideEdge(); RECT currentRect; RECT position = new RECT(); if (edge != ABE_UNKNOWN) { // Our AppBar is auto-hidden, unregister it. AppBarMessage(ABM_SETAUTOHIDEBAR, edge, 0); } // Save the new requested state this.appBarState.state = state; switch (state) { case ABE_UNKNOWN: // We are being completely unregisterred. // Probably, the AppBar window is being destroyed. // If the AppBar is registered as NOT auto-hide, unregister it. AppBarMessage(ABM_REMOVE); break; case ABE_FLOAT: // We are floating and therefore are just a regular window. // Tell the shell that the docked AppBar should be of 0x0 dimensions // so that the workspace is not affected by the AppBar. currentRect = new RECT(0, 0, 0, 0); AppBarMessage(ABM_SETPOS, state, 0, ref currentRect); SetWindowPos(this.Handle, IntPtr.Zero, this.appBarState.floatRect.left, this.appBarState.floatRect.top, this.appBarState.floatRect.Width, this.appBarState.floatRect.Height, SWP_NOZORDER | SWP_NOACTIVATE); break; default: if (this.appBarState.autoHide & !(Convert.ToBoolean(AppBarMessage(ABM_SETAUTOHIDEBAR, GetState(), 1), CultureInfo.InvariantCulture))) { // We couldn't set the AppBar on a new edge, let's dock it instead. this.appBarState.autoHide = false; // Call a virtual function to let derived classes know that the AppBar // changed from auto-hide to docked. OnAppBarForcedToDocked(); } GetRect(GetState(), ref position); if (this.appBarState.autoHide) { currentRect = new RECT(0,0,0,0); AppBarMessage(ABM_SETPOS, ABE_LEFT, 0, ref currentRect); } else { // Tell the shell where the AppBar is. AppBarMessage(ABM_SETPOS, state, 0, ref position); } AdjustLocationForAutohide(this.appBarState.autoHideIsVisible, ref position); // Slide window in from or out to the edge SlideWindow(position); break; } // Set the AppBar's z-order appropriately IntPtr pwnd = new IntPtr(HWND_NOTOPMOST); // Assume normal Z-Order if (this.appBarState.alwaysOnTop) { // If we are supposed to be always-on-top, put us there. pwnd = new IntPtr(HWND_TOPMOST); if (this.appBarState.fullScreenAppOpen) { // But, if a full-screen window is opened, put ourself at the bottom // of the z-order so that we don't cover the full-screen window pwnd = new IntPtr(HWND_BOTTOM); } } SetWindowPos(this.Handle, pwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); // Make sure that any auto-hide appabrs stay on top of us after we move // even though our activation state has not changed. AppBarMessage(ABM_ACTIVATE); // Tell our derived class that there is a state change AppBarStateChange(false, state); } private void SetState() { SetState(GetState()); } private int AppBarMessage (int message, int edge /*= ABE_FLOAT*/, int lParam /*= 0*/, ref RECT position /*= null*/) { // Initialize an APPBARDATA structure. APPBARDATA abd = new APPBARDATA(); abd.size = Marshal.SizeOf(abd); abd.hWnd = this.Handle.ToInt32(); abd.callbackMessage = WM_APPBARNOTIFY; abd.edge = edge; abd.position = position; abd.lParam = lParam; int result = SHAppBarMessage(message, ref abd); // If the caller passed a rectangle, return the updated rectangle. position = abd.position; return result; } private int AppBarMessage (int message, int edge /*= ABE_FLOAT*/, int lParam /*= 0*/) { // Initialize an APPBARDATA structure. APPBARDATA abd = new APPBARDATA(); abd.size = Marshal.SizeOf(abd); abd.hWnd = this.Handle.ToInt32(); abd.callbackMessage = WM_APPBARNOTIFY; abd.edge = edge; abd.position = new RECT(0, 0, 0, 0); abd.lParam = lParam; int result = SHAppBarMessage(message, ref abd); // If the caller passed a rectangle, return the updated rectangle. return result; } private int AppBarMessage(int message) { return AppBarMessage(message, ABE_FLOAT, 0); } private int AppBarMessage(int message, int edge) { return AppBarMessage(message, edge, 0); } private int CalcProposedState (POINT point) { // Force the AppBar to float if the user is holding down the Ctrl key // and the AppBar's style allows floating. bool fForceFloat = ((GetKeyState(VK_CONTROL) & 0x8000) != 0) && ((this.appBarState.dockFlags & ABF_ALLOWFLOAT) != 0); return (fForceFloat ? ABE_FLOAT : GetEdgeFromPoint(this.appBarState.dockFlags, point)); } private void GetRect (int stateProposed, ref RECT rectProposed) { // This function finds the x, y, cx, cy of the AppBar window if (ABE_FLOAT == stateProposed) { // The AppBar is floating, the proposed rectangle is correct } else { // The AppBar is docked or auto-hide // Set dimensions to full screen. rectProposed = new RECT(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); // Subtract off what we want from the full screen dimensions if (!this.appBarState.autoHide) { // Ask the shell where we can dock. AppBarMessage(ABM_QUERYPOS, stateProposed, 0, ref rectProposed); } switch (stateProposed) { case ABE_LEFT: rectProposed.right = rectProposed.left + this.appBarState.dockSizeHorizontal; break; case ABE_TOP: rectProposed.bottom = rectProposed.top + this.appBarState.dockSizeVertical; break; case ABE_RIGHT: rectProposed.left = rectProposed.right - this.appBarState.dockSizeHorizontal; break; case ABE_BOTTOM: rectProposed.top = rectProposed.bottom - this.appBarState.dockSizeVertical; break; } } } private bool AdjustLocationForAutohide (bool show, ref RECT rect) { if ((GetState() == ABE_UNKNOWN) || (GetState() == ABE_FLOAT) || !this.appBarState.autoHide) { // If we are not docked on an edge OR we are not auto-hidden, there is // nothing for us to do; just return. return false; } // Showing/hiding doesn't change our size; only our position. int x = 0; int y = 0; // Assume a position of (0, 0) if (show) { // If we are on the right or bottom, calculate our visible position switch (GetState()) { case ABE_RIGHT: x = GetSystemMetrics(SM_CXSCREEN) - rect.Width; break; case ABE_BOTTOM: y = GetSystemMetrics(SM_CYSCREEN) - rect.Height; break; } } else { // Keep a part of the AppBar visible at all times int cxVisibleBorder = 2 * GetSystemMetrics(SM_CXBORDER); int cyVisibleBorder = 2 * GetSystemMetrics(SM_CYBORDER); // Calculate our x or y coordinate so that only the border is visible switch (GetState()) { case ABE_LEFT: x = -(rect.Width - cxVisibleBorder); break; case ABE_RIGHT: x = GetSystemMetrics(SM_CXSCREEN) - cxVisibleBorder; break; case ABE_TOP: y = -(rect.Height - cyVisibleBorder); break; case ABE_BOTTOM: y = GetSystemMetrics(SM_CYSCREEN) - cyVisibleBorder; break; } } rect = new RECT(x, y, x + rect.Width, y + rect.Height); return true; } private void ShowHiddenAppBar (bool show /*= true*/) { // Get our window location in screen coordinates. RECT position = new RECT(); GetWindowRect(this.Handle, ref position); this.appBarState.autoHideIsVisible = true; // Assume that we are visible if (AdjustLocationForAutohide(show, ref position)) { // the rectangle was adjusted, we are an autohide bar // Rememebr whether we are visible or not. this.appBarState.autoHideIsVisible = show; // Slide window in from or out to the edge SlideWindow(position); } if (show) // Associate a timer with the AppBar. The timer is used to determine // when a visible, inactive, auto-hide AppBar should be re-hidden. SetTimer(this.Handle, AUTOHIDETIMERID, AUTOHIDETIMERINTERVAL, 0); else { // Must have just hidden it, so don't bother with the timer for a while KillTimer(this.Handle, AUTOHIDETIMERID); } } private void SlideWindow(RECT rectEnd) { bool fullDragOn = false; // Only slide the window if the user has FullDrag turned on SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, ref fullDragOn, 0); // Get the current window position RECT rectStart = new RECT(); GetWindowRect(this.Handle, ref rectStart); if (fullDragOn && (rectStart != rectEnd)) { // Get our starting and ending time. int timeStart = GetTickCount(); int timeEnd = timeStart + AUTOHIDETIMERINTERVAL; int time; while ((time = GetTickCount()) < timeEnd) { // While we are still sliding, calculate our new position int x = rectStart.left - (rectStart.left - rectEnd.left) * (time - timeStart) / AUTOHIDETIMERINTERVAL; int y = rectStart.top - (rectStart.top - rectEnd.top) * (time - timeStart) / AUTOHIDETIMERINTERVAL; int nWidth = rectStart.Width - (rectStart.Width - rectEnd.Width) * (time - timeStart) / AUTOHIDETIMERINTERVAL; int nHeight = rectStart.Height - (rectStart.Height - rectEnd.Height) * (time - timeStart) / AUTOHIDETIMERINTERVAL; // Show the window at its changed position SetWindowPos(this.Handle, IntPtr.Zero, x, y, nWidth, nHeight, SWP_NOZORDER | SWP_NOACTIVATE | SWP_DRAWFRAME); UpdateWindow(this.Handle); } } // Make sure that the window is at its final position SetWindowPos(this.Handle, IntPtr.Zero, rectEnd.left, rectEnd.top, rectEnd.Width, rectEnd.Height, SWP_NOZORDER | SWP_NOACTIVATE | SWP_DRAWFRAME); UpdateWindow(this.Handle); } private static int GetEdgeFromPoint (int flags, POINT point) { int state = ABE_FLOAT; // Assume that the AppBar is floating // Let's get floating out of the way first if ((flags & ABF_ALLOWFLOAT) != 0) { // Get the rectangle that bounds the size of the screen // minus any docked (but not-autohidden) AppBars. RECT position = new RECT(); SystemParametersInfoA(SPI_GETWORKAREA, 0, ref position, 0); // Leave a 1/2 width/height-of-a-scrollbar gutter around the workarea InflateRect(ref position, -GetSystemMetrics(SM_CXVSCROLL), -GetSystemMetrics(SM_CYHSCROLL)); if (PtInRect(position, point) || ((flags & ABF_ALLOWANYEDGE) == 0)) { // If the point is in the adjusted workarea // OR no edges are allowed. return state; // The AppBar should float } } // If we get here, the AppBar should be docked; determine the proper edge // Get the dimensions of the screen int cxScreen = GetSystemMetrics(SM_CXSCREEN); int cyScreen = GetSystemMetrics(SM_CYSCREEN); // Find the center of the screen POINT pointCenter = new POINT(cxScreen / 2, cyScreen / 2); // Find the distance from the point to the center POINT pointOffset = new POINT(point.X - pointCenter.X, point.Y - pointCenter.Y); // Determine if the point is farther from the left/right or top/bottom bool isLeftOrRight = (Math.Abs(pointOffset.Y) * cxScreen) <= (Math.Abs(pointOffset.X) * cyScreen); // If (it should be left/right, AND we allow left/right) // OR we don't allow top/bottom if ((isLeftOrRight && ((flags & ABF_ALLOWLEFTRIGHT) != 0)) || ((flags & ABF_ALLOWTOPBOTTOM) == 0)) { state = (0 <= pointOffset.X) ? ABE_RIGHT : ABE_LEFT; } else { state = (0 <= pointOffset.Y) ? ABE_BOTTOM : ABE_TOP; } return state; // Return calculated edge } private int GetState () { return ((this.appBarState.proposedState != ABE_UNKNOWN) ? this.appBarState.proposedState : this.appBarState.state); } private bool IsEdgeLeftOrRight (int edge) { return ((edge == ABE_LEFT) || (edge == ABE_RIGHT)); } private void ClientToScreen(IntPtr hwnd, ref RECT rect) { POINT point = new POINT(); point.X = rect.left; point.Y = rect.top; ClientToScreen(hwnd, ref point); rect.left = point.X; rect.top = point.Y; point.X = rect.right; point.Y = rect.bottom; ClientToScreen(hwnd, ref point); rect.right = point.X; rect.bottom = point.Y; } private int GetStyle() { return GetWindowLong(this.Handle, GWL_STYLE); } private int GetExStyle() { return GetWindowLong(this.Handle, GWL_EXSTYLE); } private static bool PtInRect (RECT rect, POINT point) { if (point.X < rect.left | point.X > rect.right) return false; if (point.Y < rect.top | point.Y > rect.bottom) return false; return true; } private void AppBarStateChange (bool proposed, int stateProposed) { bool fullDragOn = false; // Find out if (the user has FullDrag turned on SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, ref fullDragOn, 0); // If FullDrag is turned on OR the appbar has changed position if ((fullDragOn | ! proposed) & !(stateProposed == ABE_UNKNOWN)) { if (stateProposed == ABE_FLOAT) // Show the window adornments ModifyStyle((short) GWL_STYLE, 0, (WS_CAPTION | WS_SYSMENU), (SWP_DRAWFRAME)); else // Hide the window adornments ModifyStyle((short) GWL_STYLE, (WS_CAPTION | WS_SYSMENU), 0, (SWP_DRAWFRAME)); } OnAppBarStateChange(proposed, stateProposed); } private void ABNFullScreenApp (bool open) { // This function is called when a FullScreen window is openning or // closing. A FullScreen window is a top-level window that has its caption // above the top of the screen allowing the entire screen to be occupied // by the window's client area. // If the AppBar is a topmost window when a FullScreen windiw is activated, // we need to change our window to a non-topmost window so that the AppBar // doesn't cover the FullScreen window's client area. // If the FullScreen window is closing, we need to set the AppBar's // Z-Order back to when the user wants it to be. if (this.appBarState.fullScreenAppOpen != open) { this.appBarState.fullScreenAppOpen = open; SetState(); } OnAbnFullScreenApp(open); } private void ABNPosChanged () { // The TaskBar or another AppBar has changed its size or position. if ((GetState() != ABE_FLOAT) && !this.appBarState.autoHide) { // If we're not floating and we're not auto-hidden, we have to // reposition our window. SetState(); } OnAbnPosChanged(); } private void ABNWindowArrange(bool beginning) { OnAbnWindowArrange(beginning); } private void ABNStateChange (int stateChangedMask, int state) { // Make our state mimic the taskbar's state. MimicState(stateChangedMask, state); OnAbnStateChange(stateChangedMask, state); } #endregion #region Protected Functions protected void OnMouseDown() { ReleaseCapture(); SendMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0); } protected virtual void OnAppBarStateChange(bool proposed, int proposedState) { // This function intentionally left blank. } protected virtual void OnAppBarForcedToDocked() { // Display the ppBar's caption text as the message box caption text. string sz = "AppBar"; //GetWindowText(this.Handle, sz); MessageBox.Show(null, "There is already an auto hidden window on this edge.\r\nOnly one auto hidden window is allowed on each edge.", sz,MessageBoxButtons.OK, MessageBoxIcon.Stop); } protected virtual void OnAbnWindowArrange (bool beginning) { // This function intentionally left blank. } protected virtual void OnAbnStateChange (int stateChangedMask, int state) { // This function intentionally left blank. } protected virtual void OnAbnFullScreenApp (bool open) { // This function intentionally left blank. } private void OnAbnPosChanged () { // This function intentionally left blank. } #endregion #region Message Processors [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] protected override void WndProc(ref System.Windows.Forms.Message m) { switch (m.Msg) { case WM_APPBARNOTIFY: OnAppBarCallbackMsg(ref m); break; case WM_CREATE: OnCreate(ref m); return; case WM_DESTROY: OnDestroy(ref m); return; case WM_TIMER: OnTimer(ref m); return; case WM_NCHITTEST: OnNcHitTest(ref m); return; case WM_ENTERSIZEMOVE: this.moving = true; OnEnterSizeMove(ref m); Debug.WriteLine("OnEnterSizeMove"); break; case WM_EXITSIZEMOVE: OnExitSizeMove(ref m); this.moving = false; Debug.WriteLine("OnExitSizeMove"); break; case WM_NCMOUSEMOVE: OnNcMouseMove(ref m); return; case WM_WINDOWPOSCHANGED: OnWindowPosChanged(ref m); Debug.WriteLine("OnWindowPosChanged"); return; case WM_MOVING: OnMoving(ref m); Debug.WriteLine("OnMoving"); break; case WM_ACTIVATE: OnActivate(ref m); return; case WM_SIZING: OnSizing(ref m); Debug.WriteLine("OnSizing"); break; } base.WndProc(ref m); } // Called when the AppBar recieves a WM_APPBARNOTIFY window message private void OnAppBarCallbackMsg (ref Message message) { switch (message.WParam.ToInt32()) { case ABN_FULLSCREENAPP: ABNFullScreenApp(Convert.ToBoolean(message.WParam.ToInt32(), CultureInfo.InvariantCulture)); break; case ABN_POSCHANGED: ABNPosChanged(); break; case ABN_WINDOWARRANGE: ABNWindowArrange(Convert.ToBoolean(message.WParam.ToInt32(), CultureInfo.InvariantCulture)); break; case ABN_STATECHANGE: // The shell sends ABN_STATECHANGE notifications at inappropriate // times. So, we remember the TaskBar's current state and set // a mask indicating which states have actually changed. This mask // and the state information is passed to the derived class. // Get the state of the Taskbar int taskBarState = AppBarMessage(ABM_GETSTATE); // Prepare a mask indicating which states have changed. The code in // the derived class should only act on the states that have changed. int stateChangedMask = 0; if ((taskBarState & ABS_ALWAYSONTOP) != (this.appBarState.taskBarState & ABS_ALWAYSONTOP)) { stateChangedMask |= ABS_ALWAYSONTOP; } if ((taskBarState & ABS_AUTOHIDE) != (this.appBarState.taskBarState & ABS_AUTOHIDE)) { stateChangedMask |= ABS_AUTOHIDE; } // Call the derived class ABNStateChange(stateChangedMask, taskBarState); // Save the TaskBar's state so that we can see exactly which states // change the next time be get an ABN_STATECHANGE notification. this.appBarState.taskBarState = taskBarState; break; } message.Result = new IntPtr(0); } private void OnCreate(ref Message message) { //if (CDialog::OnCreate(lpCreateStruct) == -1) // return(-1); base.WndProc(ref message); // Register our AppBar window with the Shell AppBarMessage(ABM_NEW); // Force the AppBar to mimic the state of the TaskBar // Assume that all states have changed MimicState(ABS_ALWAYSONTOP | ABS_AUTOHIDE, this.appBarState.taskBarState); message.Result = new IntPtr(0); } private void OnDestroy(ref Message message) { //// CDialog::OnDestroy(); base.WndProc(ref message); // Kill the Autohide timer KillTimer(this.Handle, AUTOHIDETIMERID); // Unregister our AppBar window with the Shell SetState(ABE_UNKNOWN); } private void OnWindowPosChanged(ref Message message) { // CDialog::OnWindowPosChanged(lpwndpos); base.WndProc(ref message); // When our window changes position, tell the Shell so that any // auto-hidden AppBar on our edge stays on top of our window making it // always accessible to the user. AppBarMessage(ABM_WINDOWPOSCHANGED); } private void OnActivate(ref Message message) { //// CDialog::OnActivate(nState, pWndOther, bMinimized); base.WndProc(ref message); if ((message.WParam.ToInt32() & 0xFFFF) == WA_INACTIVE) { // Hide the AppBar if we are docked and auto-hidden ShowHiddenAppBar(false); } // When our window changes position, tell the Shell so that any // auto-hidden AppBar on our edge stays on top of our window making it // always accessible to the user. AppBarMessage(ABM_ACTIVATE); } private void OnTimer(ref Message message) { // Get the position of the mouse and the AppBar's position // Everything must be in screen coordinates. POINT point = new POINT(GetMessagePos()); RECT position = new RECT(); GetWindowRect(this.Handle, ref position); // Add a little margin around the AppBar InflateRect(ref position, 2 * GetSystemMetrics(SM_CXDOUBLECLK), 2 * GetSystemMetrics(SM_CYDOUBLECLK)); if (!PtInRect(position, point)) { // If the mouse is NOT over the AppBar, hide the AppBar ShowHiddenAppBar(false); } } private void OnNcMouseMove(ref Message message) { // If we are a docked, auto-hidden AppBar, shown us // when the user moves over our non-client area ShowHiddenAppBar(true); //// CDialog::OnNcMouseMove(nHitTest, point); base.WndProc(ref message); } private void OnNcHitTest(ref Message message) { // Find out what the system thinks is the hit test code //// int hitResult = CDialog::OnNcHitTest(point); base.WndProc(ref message); int hitResult = message.Result.ToInt32(); // NOTE: If the user presses the secondary mouse button, pretend that the // user clicked on the client area so that we get WM_CONTEXTMENU messages bool primaryMouseBtnDown = Convert.ToBoolean((GetAsyncKeyState(GetSystemMetrics(SM_SWAPBUTTON) != 0 ? VK_RBUTTON : VK_LBUTTON) & 0x8000) != 0, CultureInfo.InvariantCulture); if ((hitResult == HTCLIENT) && primaryMouseBtnDown) { // User clicked in client area, allow AppBar to move. We get this // behavior by pretending that the user clicked on the caption area. hitResult = HTCAPTION; } // When the AppBar is docked, the user can resize only one edge. // This next section determines which edge the user can resize. // To allow resizing, the AppBar window must have the WS_THICKFRAME style. // If the AppBar is docked and the hittest code is a resize code... if ((GetState() != ABE_FLOAT) && (GetState() != ABE_UNKNOWN) && (HTSIZEFIRST <= hitResult) && (hitResult <= HTSIZELAST)) { if (0 == (IsEdgeLeftOrRight(GetState()) ? this.appBarState.sizeInc.cx : this.appBarState.sizeInc.cy)) { // If the width/height size increment is zero, then resizing is NOT // allowed for the edge that the AppBar is docked on. hitResult = HTBORDER; // Pretend that the mouse is not on a resize border } else { // Resizing IS allowed for the edge that the AppBar is docked on. // Get the location of the appbar's client area in screen coordinates. RECT rect = new RECT(); GetClientRect(this.Handle, ref rect); ClientToScreen(this.Handle, ref rect); hitResult = HTBORDER; // Assume that we can't resize POINT point = new POINT(message.LParam.ToInt32()); switch (GetState()) { case ABE_LEFT: if (point.X > rect.right) hitResult = HTRIGHT; break; case ABE_TOP: if (point.Y > rect.bottom) hitResult = HTBOTTOM; break; case ABE_RIGHT: if (point.X < rect.left) hitResult = HTLEFT; break; case ABE_BOTTOM: if (point.Y < rect.top) hitResult = HTTOP; break; } } } message.Result = new IntPtr(hitResult); // Return the hittest code } private void OnEnterSizeMove(ref Message message) { // The user started moving/resizing the AppBar, save its current state. this.appBarState.proposedState = GetState(); message.Result = new IntPtr(0); } private void OnExitSizeMove(ref Message message) { // The user stopped moving/resizing the AppBar, set the new state. // Save the new proposed state of the AppBar. int proposedState = this.appBarState.proposedState; // Set the proposed state back to unknown. This causes GetState // to return the current state rather than the proposed state. this.appBarState.proposedState = ABE_UNKNOWN; // Get the location of the window in screen coordinates RECT position = new RECT(); GetWindowRect(this.Handle, ref position); // If the AppBar's state has changed... if (GetState() == proposedState) { switch (GetState()) { case ABE_UNKNOWN: break; case ABE_LEFT: case ABE_RIGHT: // Save the new width of the docked AppBar this.appBarState.dockSizeHorizontal = position.Width; break; case ABE_TOP: case ABE_BOTTOM: this.appBarState.dockSizeVertical = position.Height; break; } } // Always save the new position of the floating AppBar if (proposedState == ABE_FLOAT) { position.right = position.left + this.appBarState.floatRect.Width; position.bottom = position.top + this.appBarState.floatRect.Height; this.appBarState.floatRect = position; } // After setting the dimensions, set the AppBar to the proposed state SetState(proposedState); if (this.moving) this.Visible = true; message.Result = new IntPtr(0); } private void OnMoving(ref Message message) { // We control the moving of the AppBar. For example, if the mouse moves // close to an edge, we want to dock the AppBar. // The lParam contains the window's position proposed by the system RECT rect = new RECT(); RtlMoveMemory(ref rect, message.LParam, Marshal.SizeOf(rect)); // Get the location of the mouse cursor POINT point = new POINT(GetMessagePos()); // Where should the AppBar be based on the mouse position? int stateProposed = CalcProposedState(point); if ((this.appBarState.proposedState != ABE_FLOAT) && (stateProposed == ABE_FLOAT)) { // While moving, the user took us from a docked/autohidden state to // the float state. We have to calculate a rectangle location so that // the mouse cursor stays inside the window. rect = this.appBarState.floatRect; rect = new RECT(point.X - rect.Width / 2, point.Y, (point.X - rect.Width / 2) + rect.Width, point.Y + rect.Height); } // Remember the most-recently proposed state this.appBarState.proposedState = stateProposed; // Tell the system where to move the window based on the proposed state GetRect(stateProposed, ref rect); // Tell our derived class that there is a proposed state change AppBarStateChange(true, stateProposed); RtlMoveMemory(message.LParam, ref rect, Marshal.SizeOf(rect)); message.Result = new IntPtr(0); } private void OnSizing(ref Message message) { // We control the sizing of the AppBar. For example, if the user re-sizes // an edge, we want to change the size in descrete increments. // The lParam contains the window's position proposed by the system RECT rect = new RECT(); RtlMoveMemory(ref rect, message.LParam, Marshal.SizeOf(rect)); // Get the minimum size of the window assuming it has no client area. // This is the width/height of the window that must always be present RECT rectBorder = new RECT(0, 0, 0, 0); AdjustWindowRectEx(ref rectBorder, GetStyle(), 0, GetExStyle()); // We force the window to resize in discrete units set by the this.appBarState.sizeInc // member. From the new, proposed window dimensions passed to us, round // the width/height to the nearest discrete unit. int newWidth; int newHeight; if (this.appBarState.sizeInc.cx != 0) newWidth = ((rect.Width - rectBorder.Width) + this.appBarState.sizeInc.cx / 2) / this.appBarState.sizeInc.cx * this.appBarState.sizeInc.cx + rectBorder.Width; else newWidth = rect.right - rect.left; if (this.appBarState.sizeInc.cy != 0) newHeight = ((rect.Height - rectBorder.Height) + this.appBarState.sizeInc.cy / 2) / this.appBarState.sizeInc.cy * this.appBarState.sizeInc.cy + rectBorder.Height; else newHeight = rect.bottom - rect.top; // Adjust the rectangle's dimensions switch (message.WParam.ToInt32()) { case WMSZ_LEFT: rect.left = rect.right - newWidth; break; case WMSZ_TOP: rect.top = rect.bottom - newHeight; break; case WMSZ_RIGHT: rect.right = rect.left + newWidth; break; case WMSZ_BOTTOM: rect.bottom = rect.top + newHeight; break; case WMSZ_BOTTOMLEFT: rect.bottom = rect.top + newHeight; rect.left = rect.right - newWidth; break; case WMSZ_BOTTOMRIGHT: rect.bottom = rect.top + newHeight; rect.right = rect.left + newWidth; break; case WMSZ_TOPLEFT: rect.left = rect.right - newWidth; rect.top = rect.bottom - newHeight; break; case WMSZ_TOPRIGHT: rect.top = rect.bottom - newHeight; rect.right = rect.left + newWidth; break; } RtlMoveMemory(message.LParam, ref rect, Marshal.SizeOf(rect)); message.Result = new IntPtr(0); } #endregion #region Event Handlers private void AppBar_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { // Trap the mousedown to allow moving the form by clicking on the client area. OnMouseDown(); } private void AppBarForm_LocationChanged(object sender, System.EventArgs e) { // Trap when the forms location is set from the inheriting forms properties. // Basically, this event fires once for the AppBar class, but initializing will be true // It fires again when the inheriting form sets it's location. At this time, we record // the location and size of the form, and then disable this event from firing again if (!this.initializing) { this.appBarState.floatRect.left = this.Left; this.appBarState.floatRect.top = this.Top; this.appBarState.floatRect.right = this.Right; this.appBarState.floatRect.bottom = this.Bottom; this.LocationChanged -= new System.EventHandler(this.AppBarForm_LocationChanged); } } private void AppBarForm_Load(object sender, System.EventArgs e) { if (!this.DesignMode) SetState(this.appBarState.state); } #endregion #region Custom Editor ///
/// This code is courtesy of Jose Castanedo of Janus Systems /// www.janusys.com /// Provides a custom editor for the Docking Flags which displays as a drop down list with check /// boxes allowing the user to select one or more options ///
[Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] public class DockFlagConverter : TypeConverter { ///
/// Constructor takes no arguments ///
public DockFlagConverter() { } public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context,Type type) { if (type == typeof(string)) { return true; } else { return base.CanConvertTo(type); } } public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context,System.Globalization.CultureInfo culture,object value,Type destinationType) { if (value == null) { return string.Empty; } else { Type type = value.GetType(); string strValue = string.Empty; Array values = Enum.GetValues(type); if (type == typeof(DockFlags)) { for(int i = 0; i
0) strValue += ", "; strValue += values.GetValue(i).ToString(); } } } } } return strValue; } } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] public class DockFlagEditor : System.Drawing.Design.UITypeEditor { private IWindowsFormsEditorService edSvc = null; public DockFlagEditor() { } protected virtual void SetEditorProps(object value,System.Windows.Forms.CheckedListBox editor) { Type type = value.GetType(); Array values = Enum.GetValues(type); for (int i = 0; i < values.Length; i++) { editor.Items.Add(values.GetValue(i)); if ((int) values.GetValue(i) != 0) { if (((int) value & (int) values.GetValue(i)) == (int) values.GetValue(i)) { editor.SetItemChecked(i, true); } } else { if ((int) value == 0) { editor.SetItemChecked(i, true); } } } editor.BorderStyle = System.Windows.Forms.BorderStyle.None; } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { if (context != null && context.Instance != null && provider != null) { edSvc = (IWindowsFormsEditorService) provider.GetService(typeof(IWindowsFormsEditorService)); if (edSvc != null) { System.Windows.Forms.CheckedListBox listBox = new System.Windows.Forms.CheckedListBox(); listBox.CheckOnClick = true; this.SetEditorProps(value, listBox); edSvc.DropDownControl(listBox); if (value.GetType() == typeof(DockFlags)) { DockFlags proposedValue = DockFlags.AllowFloat; for(int i=0; i
Reply
Answers (
1
)
what is the internet ports ?
function in C#