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

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

最终效果图如下:

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

我们声明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

时间: 2024-08-08 17:51:22

利用C# Winform做Windows系统任务栏的相关文章

Windows平台下利用APM来做负载均衡方案 - 负载均衡(下)

概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效果,可以说还是非常的理想的.同时我们也收集到了不少的问题,比如说如何在这种分布式的架构下使用Session,NLB中有一台服务器挂掉了会导致对外暴露的地址无法访问,如果实现服务器之间的同步,如果更好的进行热修复等等,还有我们在上一篇中也提到了NLB所提供的功能是非常简单的,为了回答我们前面提到的问题

系统任务栏图标透明且无法打开解决办法 for Windows

电脑系统任务栏下的图标变成透明的而且无法打开,多次尝试找到了一个完美解决方法! 1.打开注册表 按下:win+R打开“运行”,输入"regedit"打开注册表. 2.打开目录找到值项 依次打开 HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify 3.清空项值 找到IconStreams和PastIconsStream将它俩的值全选清空

thinkphp 定时执行php文件--windows系统任务计划

实现思路如下: 通过win的"任务"功能来定时执行一个bat文件,bat文件会调用php.exe文件,php.exe可以传递参数指定执行哪个类和方法 方法如下: 一,thinkphp开启cli支持 1.tp正好支持cli命令模式,手册的路径为13.7.4 如果是用的其他框架不支持cli,那么只能直接写程序了,其实就是写面向过程的最基础的php代码. 2.在入口文件下开启命令,加入一句 define('MODE_NAME', 'cli'); 网站一般还有可以通过网页访问的模块,所以可以新

[delphi技术]隐藏/显示任务栏-程序不在任务显示-全面控制Windows任务栏

1.隐藏任务条 var  h:THandle; //变量h:=FindWindow('Shell_TrayWnd',nil);ShowWindow(h,SW_hide); 2.显示任务条h:=FindWindow('Shell_TrayWnd',nil);ShowWindow(h,SW_SHOW); 3.怎样在Delphi中调用API函数使任务不在任务栏中显示出来 SetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW); Sh

[转帖]第二个显示屏上禁用Windows任务栏

http://os.51cto.com/art/201812/589207.htm 这个过程非常简单,你可以在一分钟内摆脱第二个屏幕上的任务栏. 您需要做的就是按照以下步骤操作: --打开设置,然后转到 --单击左侧菜单中的任务栏. --向下滚动以查找多个显示 --现在关闭所有显示屏上显示"显示任务栏"的切换按钮. 就是这样,这样做会禁用所有辅助显示器上的任务栏. 请记住,只有在扩展模式下运行第二个屏幕时,这些设置才有效. 如果您处于"复制"模式,则此设置将不起作用

windows 任务栏图标宽度固定

这个需要修改注册表. win+r regedit ->enter 找到以下项 HKEY_CURRENT_USER-Control Panel-Desktop-WindowsMetrics 新建字符键值.. MinWidth 54 MaxWidth 55 注销重新登录.. 效果如图. windows 任务栏图标宽度固定,码迷,mamicode.com

利用Python脚本管理Windows服务

Windows服务常用的功能就是启动服务,关闭服务,重启服务和查询服务运行状态,其中查询服务运行状态是其他三种操作的基础. 本文中提到的使用Python脚本管理Windows服务实际上是调用win32serviceutil模块,此模块来自pywin32包,此模块本身有管理服务的功能,有兴趣的可以去阅读它的部分源码. 本脚本存在的目的是为了熟练Python的语法和基本操作,Windows下有更好的命令行工具来管理服务,如sc.Powershell等.通常命令行工具的执行速度要比services.m

Delphi 全面控制Windows任务栏

核心提示:使用Windows95/NT/98操作系统的用户知道:Windows正常启动后,在电脑屏幕下方出现一块 任务栏. 使用Windows95/NT/98操作系统的用户知道:Windows正常启动后,在电脑屏幕下方出现一块 任务栏.从系统功能角度而言,整个任务栏包括几个不同的子区域,从左至右依次是:开始 按钮.应用程序切换区(Application Switch Bar).任务栏通知区(Notification Area)以 及任务栏时钟.与其它Windows应用程序相同,任务栏程序(sys

RedHat 6.4企业版利用iso镜像做本地yum源

修改文章:http://linux.cn/article-1017-1.html 而RedHat的yum则需要注册付费才能使用,如果不这样则有两种解决方案 1. 利用iso镜像做本地yum源 2. 利用光盘做本地yum源 在这里用iso或者光盘做本地yum源的方法是差不多的,只是用光盘的话Linux系统会自动挂载,用iso镜像的或需要手动挂载,这里就说挂载iso的方法吧. [一]用本地文件创建本地yum源 1. 创建iso存放目录和挂载目录 mkdir /mnt/iso mkdir /mnt/c