Click here to Skip to main content
11,478,642 members (69,224 online)
Click here to Skip to main content

AppBar using C#

, 18 Apr 2004 CPOL 138.6K 54
Rate this:
Please Sign up or sign in to vote.
How to make AppBar for .NET

Using the Code

First we must declare the needed structures and constants.
(I combine constants in enums).

We declare the RECT WINAPI structure as follows:

[StructLayout(LayoutKind.Sequential)]
struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

We declare the APPBARDATA SHELLAPI structure as follows:

[StructLayout(LayoutKind.Sequential)]
struct APPBARDATA
{
    public int cbSize;
    public IntPtr hWnd;
    public int uCallbackMessage;
    public int uEdge;
    public RECT rc;
    public IntPtr lParam;
}

Then, we declare the AppBar related constants enums as follows:

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
}
enum ABNotify : int
{
    ABN_STATECHANGE=0,
    ABN_POSCHANGED,
    ABN_FULLSCREENAPP,
    ABN_WINDOWARRANGE
}
enum ABEdge : int
{
    ABE_LEFT=0,
    ABE_TOP,
    ABE_RIGHT,
    ABE_BOTTOM
}

Next we declare the needed WIN32 and SHELL API functions import:

[DllImport("SHELL32", CallingConvention=CallingConvention.StdCall)]
static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
[DllImport("USER32")]
static extern int GetSystemMetrics(int Index);
[DllImport("User32.dll", ExactSpelling=true, 
    CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool MoveWindow
    (IntPtr hWnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("User32.dll", CharSet=CharSet.Auto)]
private static extern int RegisterWindowMessage(string msg);

The next step is creating a function to register AppBar:

private void RegisterBar()
{
    APPBARDATA abd = new APPBARDATA();
    abd.cbSize = Marshal.SizeOf(abd);
    abd.hWnd = this.Handle;
    if (!fBarRegistered)
    {
        uCallBack = RegisterWindowMessage("AppBarMessage");
        abd.uCallbackMessage = uCallBack;

        uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd);
    fBarRegistered = true;

    ABSetPos();
    }
    else
    {
    SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref abd);
    fBarRegistered = false;
    }
}

The last step is to create a function to position AppBar:

private void ABSetPos()
{
    APPBARDATA abd = new APPBARDATA();
    abd.cbSize = Marshal.SizeOf(abd);
    abd.hWnd = this.Handle;
    abd.uEdge = (int)ABEdge.ABE_TOP;

    if (abd.uEdge == (int)ABEdge.ABE_LEFT || abd.uEdge == (int)ABEdge.ABE_RIGHT) 
    {
    abd.rc.top = 0;
    abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height;
    if (abd.uEdge == (int)ABEdge.ABE_LEFT) 
    {
        abd.rc.left = 0;
        abd.rc.right = Size.Width;
    }
    else 
    {
        abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
        abd.rc.left = abd.rc.right - Size.Width;
    }

    }
    else 
    {
    abd.rc.left = 0;
    abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
    if (abd.uEdge == (int)ABEdge.ABE_TOP) 
    {
        abd.rc.top = 0;
        abd.rc.bottom = Size.Height;
    }
    else 
    {
        abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height;
        abd.rc.top = abd.rc.bottom - Size.Height;
    }
    }

    SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref abd); 

    switch (abd.uEdge) 
    { 
    case (int)ABEdge.ABE_LEFT: 
        abd.rc.right = abd.rc.left + Size.Width;
        break; 
    case (int)ABEdge.ABE_RIGHT: 
        abd.rc.left= abd.rc.right - Size.Width;
        break; 
    case (int)ABEdge.ABE_TOP: 
        abd.rc.bottom = abd.rc.top + Size.Height;
        break; 
    case (int)ABEdge.ABE_BOTTOM: 
        abd.rc.top = abd.rc.bottom - Size.Height;
        break; 
    }

    SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref abd); 
    MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, 
            abd.rc.right - abd.rc.left, abd.rc.bottom - abd.rc.top, true); 
}

This is a full listing of a sample AppBar form class:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;

namespace Sample.AppBar
{
    /// <span class="code-SummaryComment"><summary></span>
    /// Summary description for Form1.
    /// <span class="code-SummaryComment"></summary></span>
    public class MainForm : System.Windows.Forms.Form
    {
        /// <span class="code-SummaryComment"><summary></span>
        /// Required designer variable.
        /// <span class="code-SummaryComment"></summary></span>
        private System.ComponentModel.Container components = null;

        public MainForm()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <span class="code-SummaryComment"><summary></span>
        /// Clean up any resources being used.
        /// <span class="code-SummaryComment"></summary></span>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <span class="code-SummaryComment"><summary></span>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// <span class="code-SummaryComment"></summary></span>
        private void InitializeComponent()
        {
            // 
            // MainForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(960, 50);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
            this.Name = "MainForm";
            this.Text = "AppBar";
            this.Closing += new System.ComponentModel.CancelEventHandler(this.OnClosing);
            this.Load += new System.EventHandler(this.OnLoad);
        }
        #endregion

        #region APPBAR

        [StructLayout(LayoutKind.Sequential)]
        struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        struct APPBARDATA
        {
            public int cbSize;
            public IntPtr hWnd;
            public int uCallbackMessage;
            public int uEdge;
            public RECT rc;
            public IntPtr lParam;
        }

        enum ABMsg : int
        {
            ABM_NEW=0,
            ABM_REMOVE=1,
            ABM_QUERYPOS=2,
            ABM_SETPOS=3,
            ABM_GETSTATE=4,
            ABM_GETTASKBARPOS=5,
            ABM_ACTIVATE=6,
            ABM_GETAUTOHIDEBAR=7,
            ABM_SETAUTOHIDEBAR=8,
            ABM_WINDOWPOSCHANGED=9,
            ABM_SETSTATE=10
        }

        enum ABNotify : int
        {
            ABN_STATECHANGE=0,
            ABN_POSCHANGED,
            ABN_FULLSCREENAPP,
            ABN_WINDOWARRANGE
        }

        enum ABEdge : int
        {
            ABE_LEFT=0,
            ABE_TOP,
            ABE_RIGHT,
            ABE_BOTTOM
        }

        private bool fBarRegistered = false;

        [DllImport("SHELL32", CallingConvention=CallingConvention.StdCall)]
        static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
        [DllImport("USER32")]
        static extern int GetSystemMetrics(int Index);
        [DllImport("User32.dll", ExactSpelling=true, 
            CharSet=System.Runtime.InteropServices.CharSet.Auto)]
        private static extern bool MoveWindow
            (IntPtr hWnd, int x, int y, int cx, int cy, bool repaint);
        [DllImport("User32.dll", CharSet=CharSet.Auto)]
        private static extern int RegisterWindowMessage(string msg);
        private int uCallBack;

        private void RegisterBar()
        {
            APPBARDATA abd = new APPBARDATA();
            abd.cbSize = Marshal.SizeOf(abd);
            abd.hWnd = this.Handle;
            if (!fBarRegistered)
            {
                uCallBack = RegisterWindowMessage("AppBarMessage");
                abd.uCallbackMessage = uCallBack;

                uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd);
                fBarRegistered = true;

                ABSetPos();
            }
            else
            {
                SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref abd);
                fBarRegistered = false;
            }
        }

        private void ABSetPos()
        {
            APPBARDATA abd = new APPBARDATA();
            abd.cbSize = Marshal.SizeOf(abd);
            abd.hWnd = this.Handle;
            abd.uEdge = (int)ABEdge.ABE_TOP;

            if (abd.uEdge == (int)ABEdge.ABE_LEFT || abd.uEdge == (int)ABEdge.ABE_RIGHT) 
            {
                abd.rc.top = 0;
                abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height;
                if (abd.uEdge == (int)ABEdge.ABE_LEFT) 
                {
                    abd.rc.left = 0;
                    abd.rc.right = Size.Width;
                }
                else 
                {
                    abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
                    abd.rc.left = abd.rc.right - Size.Width;
                }

            }
            else 
            {
                abd.rc.left = 0;
                abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
                if (abd.uEdge == (int)ABEdge.ABE_TOP) 
                {
                    abd.rc.top = 0;
                    abd.rc.bottom = Size.Height;
                }
                else 
                {
                    abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height;
                    abd.rc.top = abd.rc.bottom - Size.Height;
                }
            }

            // Query the system for an approved size and position. 
            SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref abd); 

            // Adjust the rectangle, depending on the edge to which the 
            // appbar is anchored. 
            switch (abd.uEdge) 
            { 
                case (int)ABEdge.ABE_LEFT: 
                    abd.rc.right = abd.rc.left + Size.Width;
                    break; 
                case (int)ABEdge.ABE_RIGHT: 
                    abd.rc.left= abd.rc.right - Size.Width;
                    break; 
                case (int)ABEdge.ABE_TOP: 
                    abd.rc.bottom = abd.rc.top + Size.Height;
                    break; 
                case (int)ABEdge.ABE_BOTTOM: 
                    abd.rc.top = abd.rc.bottom - Size.Height;
                    break; 
            }

            // Pass the final bounding rectangle to the system. 
            SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref abd); 

            // Move and size the appbar so that it conforms to the 
            // bounding rectangle passed to the system. 
            MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, 
                abd.rc.right - abd.rc.left, abd.rc.bottom - abd.rc.top, true); 
        }

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == uCallBack)
            {
                switch(m.WParam.ToInt32())
                {
                    case (int)ABNotify.ABN_POSCHANGED:
                        ABSetPos();
                        break;
                }
            }

            base.WndProc(ref m);
        }

        protected override System.Windows.Forms.CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.Style &= (~0x00C00000); // WS_CAPTION
                cp.Style &= (~0x00800000); // WS_BORDER
                cp.ExStyle = 0x00000080 | 0x00000008; // WS_EX_TOOLWINDOW | WS_EX_TOPMOST
                return cp;
            }
        }

        #endregion

        /// <span class="code-SummaryComment"><summary></span>
        /// The main entry point for the application.
        /// <span class="code-SummaryComment"></summary></span>
        [STAThread]
        static void Main() 
        {
            Application.Run(new MainForm());
        }

        private void OnLoad(object sender, System.EventArgs e)
        {
            RegisterBar();
        }

        private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            RegisterBar();
        }
    }
}

For more information about creating AppBars, refer to the MSDN.

P.S.

Post in comments and questions about code parts. I plan to update the article descriptions based on your questions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mad__
Web Developer
Ukraine Ukraine
Developing software for Civilian aviation and Meteorogical offices.

Comments and Discussions

 
QuestionNice code but I have a problem Pin
Member 1100107622-Sep-14 12:55
memberMember 1100107622-Sep-14 12:55 
AnswerRe: Nice code but I have a problem Pin
Member 1100107622-Sep-14 13:03
memberMember 1100107622-Sep-14 13:03 
QuestionProblem width on left/right Pin
Member 876327324-May-14 3:52
memberMember 876327324-May-14 3:52 
QuestionDPI Setting Pin
S. Ryan24-Jan-14 6:38
memberS. Ryan24-Jan-14 6:38 
QuestionRe: DPI Setting Pin
Tailslide3-Jun-14 7:29
memberTailslide3-Jun-14 7:29 
AnswerRe: DPI Setting Pin
Nino Stella19-Jun-14 4:24
memberNino Stella19-Jun-14 4:24 
GeneralRe: DPI Setting Pin
Member 108047428-Jul-14 9:29
memberMember 108047428-Jul-14 9:29 
QuestionRe: DPI Setting Pin
James MacGilp20-Jan-15 6:05
memberJames MacGilp20-Jan-15 6:05 
AnswerRe: DPI Setting Pin
James MacGilp20-Jan-15 23:25
memberJames MacGilp20-Jan-15 23:25 
QuestionSize variable Pin
Member 1031492413-Oct-13 7:35
memberMember 1031492413-Oct-13 7:35 
QuestionWhat is tha Best way to store data in mobile application.In Windows phone,android and nokia Mobiles Pin
aamitsengar25-Apr-13 23:00
groupaamitsengar25-Apr-13 23:00 
QuestionHow to make it Autohide? Pin
kilkenny9920-Dec-12 5:22
memberkilkenny9920-Dec-12 5:22 
GeneralWill this work without having explorer shelled? Pin
q2418130103p2-May-11 9:21
memberq2418130103p2-May-11 9:21 
GeneralRe: Will this work without having explorer shelled? Pin
Veldrik2-May-12 19:04
memberVeldrik2-May-12 19:04 
GeneralThanks... Pin
puneetdhawan200020-Nov-10 0:28
memberpuneetdhawan200020-Nov-10 0:28 
GeneralThanks, Exactly what I was looking for! Pin
jg00714-Jun-09 10:49
memberjg00714-Jun-09 10:49 
Questionshould not be able to minimise AppBar when docked! Pin
Webermania8-Sep-08 4:01
memberWebermania8-Sep-08 4:01 
AnswerRe: should not be able to minimise AppBar when docked! Pin
Relair17-Feb-10 0:52
memberRelair17-Feb-10 0:52 
GeneralExceptions encountered with .Net 2.0! Pin
irrdev23-Oct-07 1:55
memberirrdev23-Oct-07 1:55 
GeneralRe: Exceptions encountered with .Net 2.0! Pin
Yaroslav Trofimov22-Apr-08 4:03
memberYaroslav Trofimov22-Apr-08 4:03 
GeneralThanks for the article Pin
rayazax25-Apr-07 1:31
memberrayazax25-Apr-07 1:31 
It helped.
I have one problem.
I have a from that sometimes need to be a task bar and sometimes floating bar, according to what user chooses.
We need to define ExStyle as WS_EX_TOOLWINDOW in order this stuff make working, but then when my form is floating I can not do minimize to it and I don't see it at task bar.
What can I do in order to fix it?
Thanks
QuestionNot working with .NET Frame 2.0 ? Pin
Haggy21-Mar-06 1:56
memberHaggy21-Mar-06 1:56 
AnswerRe: Not working with .NET Frame 2.0 ? Pin
Neno123413-Jan-07 23:27
memberNeno123413-Jan-07 23:27 
QuestionWindows bug? Pin
growse31-Oct-05 5:32
membergrowse31-Oct-05 5:32 
Generalgrumpf Pin
mofin16-Sep-05 4:27
membermofin16-Sep-05 4:27 
GeneralGreat Pin
christos st.20-Oct-04 0:25
susschristos st.20-Oct-04 0:25 
GeneralRe: Great Pin
Marcio Castilho25-Jan-05 19:52
memberMarcio Castilho25-Jan-05 19:52 
GeneralRe: Great Pin
Keith Farmer27-Nov-05 11:47
memberKeith Farmer27-Nov-05 11:47 
GeneralHmm.... Pin
mirano19-Apr-04 5:37
membermirano19-Apr-04 5:37 
GeneralRe: Hmm.... Pin
Anonymous19-Apr-04 8:32
sussAnonymous19-Apr-04 8:32 
GeneralRe: Hmm.... Pin
Ellery19-Apr-04 18:58
memberEllery19-Apr-04 18:58 
GeneralRe: Hmm.... Pin
Mad__19-Apr-04 22:12
memberMad__19-Apr-04 22:12 
GeneralRe: Hmm.... Pin
SirLestat20-Apr-04 11:39
memberSirLestat20-Apr-04 11:39 
GeneralRe: Hmm.... Pin
Russkie22-Apr-04 17:06
memberRusskie22-Apr-04 17:06 
GeneralRe: Hmm.... Pin
Sylfaen31-Jul-06 20:02
memberSylfaen31-Jul-06 20:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150520.1 | Last Updated 19 Apr 2004
Article Copyright 2004 by Mad__
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid