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

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

  1. 利用Delphi全面控制Windows任务栏

    使用Windows95/NT/98操作系统的用户知道:Windows正常启动后,在电脑屏幕下方出现一块 任务栏.从系统功能角度而言,整个任务栏包括几个不同的子区域,从左至右依次是:开始 按钮.应用程序 ...

  2. 转:ASP.NET MVC利用TryUpdateModel来做资料更新 (一)

    前言有使用 ASP.NET MVC 的朋友们一定多多少少有听过 TryUpdateModel,之前就看了很多有关它的文章,但在专案实务上都未曾实际使用过,而 TryUpdateModel 不仅能利用 ...

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

    http://os.51cto.com/art/201812/589207.htm 这个过程非常简单,你可以在一分钟内摆脱第二个屏幕上的任务栏. 您需要做的就是按照以下步骤操作: --打开设置,然后转 ...

  4. 利用SSH协议在Windows下使用PuTTY连接Ubuntu

    利用SSH协议在Windows下使用PuTTY连接Ubuntu Ubuntu部分 首先我们要为Ubuntu配置一下环境,让它支持ssh服务,我们要做的其实也很简单,就一下两步: 安装OpenSSH软件 ...

  5. 使用 advanced installer 为 winform 做自动更新

    原文:使用 advanced installer 为 winform 做自动更新 advanced installer 是一款打包程序,基于 windows installer 并扩展了一些功能,比如 ...

  6. ipad做windows副屏

    利用iPad做windows的触摸显示屏 由于ios与windows不兼容,所以利用软件进行 主要的软件有三款:duet display:spacedesk:Splashtop Wired XDisp ...

  7. nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录

    geo指令使用ngx_http_geo_module模块提供的.默认情况下,nginx有加载这个模块,除非人为的 --without-http_geo_module.ngx_http_geo_modu ...

  8. windows任务栏消失

    windows任务栏消失,快捷键打开任务管理器,新建任务explorer.exe

  9. Delphi 全面控制Windows任务栏

    核心提示:使用Windows95/NT/98操作系统的用户知道:Windows正常启动后,在电脑屏幕下方出现一块 任务栏. 使用Windows95/NT/98操作系统的用户知道:Windows正常启动 ...

随机推荐

  1. Struts2--属性设置方式

    Struts2自动获取/设置数据的方式一共分为两种 属性驱动(FieldDriven) 模型驱动(ModelDriven) 属性驱动 属性又分为两种: |- 基本数据类型 |- JavaBean属性类 ...

  2. JDBC入门学习

    Introduction What's JDBC JDBC stands for Java Database Connectivity, which is a standard Java API fo ...

  3. flickrf 分布式主键生成方案【mysql】

    [相关链接:http://blog.csdn.net/bluishglc/article/details/7710738] 具体做法: 1:找两台服务器,分别配置: TicketServer1: au ...

  4. OPP Services Log

    SELECT FCPP.CONCURRENT_REQUEST_ID REQ_ID, FCP.NODE_NAME, FCP.LOGFILE_NAME  FROM FND_CONC_PP_ACTIONS ...

  5. JavaScript对象详解

    JavaScript中的数据类型作为javascript的核心,我们经常要用到,也是最基础的.  javascript中有非常复杂的数据类型:包括对象(Object)数据类型,还有五个基本数据类型(N ...

  6. c#生成二维码

            String link ="www.baidu.com";//这里一般是一个链接 封装后的方法,直接调用就可以了  public void CreateQRCode ...

  7. vue DatePicker vue2.0的日期插件

    一个用vue2.0写的日期控件,可以支持简单的年月日选择.地址:https://github.com/Stevenzwzhai/vue-datepicker. 首先是关于日期对象的使用,基本就是日期的 ...

  8. IOS中div contenteditable=true无法输入

    在IOS中<div contenteditable="true"></div>中点击时可以弹出键盘但是无法输入.加一个样式-webkit-user-sele ...

  9. 解决 release-stripped.ap_' specified for property 'resourceFile' does not exist.

    设置buildTypes里的release的shrinkResources为false即可,如果是 release-stripped.ap_' specified for property 'reso ...

  10. [原创]JavaEE在CentOS服务器上的部署

    1.安装rz.sz命令 yum install lrzsz 2.配置环境变量 vi .bash_profile 默认的path:PATH=$PATH:$HOME/.local/bin:$HOME/bi ...