Click here to Skip to main content
6,821,293 members and growing! (19,473 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » .NET Framework » General     Advanced License: The Code Project Open License (CPOL)

AppBar using C#

By Mad__

How to make AppBar for .NET
C#, Windows, .NET1.0, Visual-Studio, Dev
Posted:18 Apr 2004
Views:77,661
Bookmarked:29 times
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
29 votes for this article.
Popularity: 4.20 Rating: 2.87 out of 5
10 votes, 35.7%
1
2 votes, 7.1%
2

3
6 votes, 21.4%
4
10 votes, 35.7%
5

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
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class MainForm : System.Windows.Forms.Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

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

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

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

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        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

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [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)

About the Author

Mad__


Member
Developing software for Civilian aviation and Meteorogical offices.
Occupation: Web Developer
Location: Ukraine Ukraine

Other popular .NET Framework articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 19 of 19 (Total in Forum: 19) (Refresh)FirstPrevNext
GeneralThanks, Exactly what I was looking for! Pinmemberjg00710:49 14 Jun '09  
Questionshould not be able to minimise AppBar when docked! PinmemberWebermania4:01 8 Sep '08  
GeneralExceptions encountered with .Net 2.0! Pinmemberirrdev1:55 23 Oct '07  
GeneralRe: Exceptions encountered with .Net 2.0! PinmemberYaroslav Trofimov4:03 22 Apr '08  
GeneralThanks for the article Pinmemberrayazax1:31 25 Apr '07  
GeneralNot working with .NET Frame 2.0 ? PinmemberHaggy1:56 21 Mar '06  
AnswerRe: Not working with .NET Frame 2.0 ? PinmemberNeno123423:27 13 Jan '07  
GeneralWindows bug? Pinmembergrowse5:32 31 Oct '05  
Generalgrumpf Pinmembermofin4:27 16 Sep '05  
GeneralGreat Pinsusschristos st.0:25 20 Oct '04  
GeneralRe: Great PinmemberMarcio Castilho19:52 25 Jan '05  
GeneralRe: Great PinmemberKeith Farmer11:47 27 Nov '05  
GeneralHmm.... Pinmembermirano5:37 19 Apr '04  
GeneralRe: Hmm.... PinsussAnonymous8:32 19 Apr '04  
GeneralRe: Hmm.... PinmemberEllery18:58 19 Apr '04  
GeneralRe: Hmm.... PinmemberMad__22:12 19 Apr '04  
GeneralRe: Hmm.... PinmemberSirLestat11:39 20 Apr '04  
GeneralRe: Hmm.... PinmemberRusskie17:06 22 Apr '04  
GeneralRe: Hmm.... PinmemberSylfaen20:02 31 Jul '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

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

PermaLink | Privacy | Terms of Use
Last Updated: 18 Apr 2004
Editor: Deeksha Shenoy
Copyright 2004 by Mad__
Everything else Copyright © CodeProject, 1999-2010
Web21 | Advertise on the Code Project