• 利用C# Winform做Windows系统任务栏


    最近公司做一个考试系统,需要一个答题栏,要求:占用屏幕上方一部分区域,而且始终置顶,当其他窗口最大化时“答题栏”始终置前并且不遮挡最大化窗口的任何部分!就像windows任务栏一样。

    最终效果图如下:

    image

    首先,我们必须声明所需的结构和常量。

    我们声明RECT WINAPI结构如下:

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

    我们声明APPBARDATA SHELLAPI结构如下:

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

    然后,我们声明AppBar用到的常量如下:

    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
    }

    接下来,我们声明需要用到的WIN32和SHELL API接口:

    [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)]
    static extern bool MoveWindow(IntPtr hWnd, int x, int y, int cx, int cy, bool repaint);
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    static extern int RegisterWindowMessage(string msg);

    下一步,我们创建一个注册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;
        }
    }

    最后,我们创建一个设置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;
            }
        }
    
        // 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);
    }

    参考地址:http://www.codeproject.com/Articles/6741/AppBar-using-C

    下载地址:http://pan.baidu.com/s/1qY4HX2c  b7nv

    作者:灬花儿灬
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    SQL的case when then else end语句的用法
    PR轨道工具
    Power Bi追加查询
    如何在电商平台查看历史价格
    MYSQL执行SQL出现错误:Error Code:1054.Unknown column "字段名" in 'order clause'如何解决
    Python 的基础数据类型
    整数回文转换
    N-城堡问题
    Find The Multiple
    Ecust DIV3 k进制 【暴力不断优化】
  • 原文地址:https://www.cnblogs.com/flower1990/p/6004972.html
Copyright © 2020-2023  润新知