当前位置: 首页 > news >正文

WinForm_2一个简单实用的小应用——桌面时钟

对于WinForm编程呢,我准备采用编写不同的小应用或小游戏这种方式——因此,可能每一个程序会包揽相对较多的东西,毕竟WinForm编程还是挺简单的^_^

今天先来做一个挺实用的小应用——桌面时钟,也就是在桌面上显示一个时钟。

要不先来看看效果如何呢?

可以看见,在桌面上的右上角,显示了一个数字时钟

OK,下面来看看是如何实现的:(从三个方面介绍)

(1)Form这个类中的一些属性

(2)计时器(Timer类)

(3)时钟的绘制

一、先介绍今天在Form这个类中用到的一些属性

Text:窗口的标题

BackColor:窗口背景色

TransparencyKey:获取或设置将表示窗体透明区域的颜色——这个属性相对重要,来看看msdn中的描述:

当将 Color 分配给 TransparencyKey 属性时,具有相同 BackColor 的窗体区域将透明显示。在窗体的透明区域执行的任何鼠标操作(如鼠标单击)都将传输到该透明区域下的窗口。(因此你如果想透明窗口客户区,只需要将该属性设置为窗口背景色BackColor就行了)

FormBorderStyle:窗口边框风格——它由一个枚举FormBorderStyle提供所有的选项(具体可参阅msdn)

ShowInTaskbar:决定是否让窗口在任务栏中显示(bool类型,设置为false就不显示)

StartPosition:窗口的起始位置——它也是由一个枚举FormStartPosition提供所有的选项(具体可参阅msdn)

WindowState:窗口显示的状态(最大化、最小化还是常规大小)——它也是由一个枚举FormWindowState提供所有选项

以下是相关代码的实现:

//窗口标题
Text = "DesktopClock";
//ResizeRedraw = true;
BackColor = SystemColors.Window;
//设置窗口透明区域的颜色(和背景色一样)
TransparencyKey = BackColor;
//去掉边框
FormBorderStyle = FormBorderStyle.None;
//不在任务栏中显示窗体
ShowInTaskbar = false;
//窗口其实位置
StartPosition = FormStartPosition.CenterScreen;
//最大化显示
WindowState = FormWindowState.Maximized;


二、浅谈Timer这个类

因为是一个时钟程序,那么必定少不了计时器

在Win32 SDK中是由SetTimer()KillTimer()这两个API函数来启动和销毁一个计时器,在WM_TIMER消息或是指定的函数中来响应计时器消息到来时的操作。那么在WinForm中呢,这些功能都封装到Timer这个类中,具体就是类中的Start()Stop()方法来启动和销毁一个计时器,Tick属性来安装事件委托——如何响应计时器消息

以下是相关代码的实现:

//设置定时器
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(TimerOnTick);
timer.Start();
//计时器响应事件
public void TimerOnTick(object obj, EventArgs ea)
{
    Invalidate();
}


不过别忘了销毁计时器(虽然C#中有GC垃圾回收机制,不过最好是我们自行解决。呵呵,Win32 SDK的习惯)

//当窗口关闭时停止计时器
protected override void OnFormClosing(FormClosingEventArgs fcea)
{
    base.OnFormClosing(fcea);

    timer.Stop();
}


三、看看时钟的绘制细节

(1). 如果是在Win32 SDK中,你肯定第一时间会想到应该在WM_PAINT中实现。但如果你看了我上一篇文章,你就会知道,在C#中事件委托这一机制取代了Win32 SDK的原始消息响应机制,你可以重写在Form中由Control这个类继承下来的OnPaint方法,本质上,它也就是响应WM_PAINT这个消息。

(2). 获取本地时间——关于时间和日期的操作基本上都封装到了DateTime这个类了,那么获取本地时间就可以使用该类中的Now()方法.

以下是相关代码的实现:

//绘制数字时钟
protected override void OnPaint(PaintEventArgs pea)
{
    base.OnPaint(pea);

    Graphics grfx = pea.Graphics;
    String str = DateTime.Now.ToString("T"); //获取本地时间
    Font font = new Font(Font.FontFamily, 100);//设置新字体
    SizeF sizef = grfx.MeasureString(str, font);//获取时间字符串的大小(用于定位)

    //在桌面右上角绘制数字时钟
    grfx.DrawString(str, font, Brushes.Orange,
        (ClientSize.Width - sizef.Width), 0);
}


OK,实现的细节差不多就是这样,还是贴上完整源代码,供初学者参考:

//DesktopClock.cs
using System;
using System.Drawing;
using System.Windows.Forms;

class DesktopClock: Form
{
    private Timer timer;

    public DesktopClock()
    {
        //窗口标题
        Text = "DesktopClock";
        //ResizeRedraw = true;
        BackColor = SystemColors.Window;
        //设置窗口透明区域的颜色(和背景色一样)
        TransparencyKey = BackColor;
        //去掉边框
        FormBorderStyle = FormBorderStyle.None;
        //不在任务栏中显示窗体
        ShowInTaskbar = false;
        //窗口其实位置
        StartPosition = FormStartPosition.CenterScreen;
        //最大化显示
        WindowState = FormWindowState.Maximized;

        //设置定时器
        timer = new Timer();
        timer.Interval = 1000;
        timer.Tick += new EventHandler(TimerOnTick);
        timer.Start();
    }

    //计时器响应事件
    public void TimerOnTick(object obj, EventArgs ea)
    {
        Invalidate();
    }

    //按下Ctrl+Q就可以退出程序
    protected override void OnKeyDown(KeyEventArgs kea)
    {
        base.OnKeyDown(kea);

        if (kea.Modifiers == Keys.Control && kea.KeyCode == Keys.Q)
            Close();
    }

    //绘制数字时钟
    protected override void OnPaint(PaintEventArgs pea)
    {
        base.OnPaint(pea);

        Graphics grfx = pea.Graphics;
        String str = DateTime.Now.ToString("T"); 
        Font font = new Font(Font.FontFamily, 100);
        SizeF sizef = grfx.MeasureString(str, font);

        //在桌面右上角绘制数字时钟
        grfx.DrawString(str, font, Brushes.Orange,
            (ClientSize.Width - sizef.Width), 0);
    }

    //当窗口关闭时停止计时器
    protected override void OnFormClosing(FormClosingEventArgs fcea)
    {
        base.OnFormClosing(fcea);

        timer.Stop();
    }

    static void Main()
    {
        Application.Run(new DesktopClock());
    }
}


相关文章:

  • 数据分析工程师笔试题:计算平均数的指标及其优缺点
  • 新视野OJ 2005 [Noi2010]能量采集 (数论-gcd)
  • Python 入门教程 17 ---- Introduction to Classes
  • HDU 4288 Coder 【线段树+离线处理+离散化】
  • 近期刷题的c语言总结。
  • 程序员看婚姻
  • Python 入门教程 18 ---- File Input/Output
  • 【职业】致迷茫的大学生们
  • (poj1.3.2)1791(构造法模拟)
  • 微软云技术Windows Azure专题(五):如何将WCF服务部署在Windows Azure上
  • 『Asp.Net 组件』Asp.Net 服务器组件 内嵌JS:让自己的控件动起来
  • 『Asp.Net 组件』第一个 Asp.Net 服务器组件:自己的文本框控件
  • 『Asp.Net 组件』Asp.Net 服务器组件 内嵌图片:自己的图片控件
  • 『Asp.Net 组件』Asp.Net 服务器组件 内嵌CSS:将CSS封装到程序集中
  • 『Asp.Net 组件』Asp.Net 服务器组件 的开发优势和劣势
  • [数据结构]链表的实现在PHP中
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • avalon2.2的VM生成过程
  • EOS是什么
  • EventListener原理
  • HTML-表单
  • iOS编译提示和导航提示
  • maven工程打包jar以及java jar命令的classpath使用
  • mockjs让前端开发独立于后端
  • Vue实战(四)登录/注册页的实现
  • vue--为什么data属性必须是一个函数
  • 系统认识JavaScript正则表达式
  • MPAndroidChart 教程:Y轴 YAxis
  • ​Java并发新构件之Exchanger
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (八)Flask之app.route装饰器函数的参数
  • (第二周)效能测试
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (一)基于IDEA的JAVA基础1
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .net 4.0发布后不能正常显示图片问题
  • .net Application的目录
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Framework杂记
  • .net 获取url的方法
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .net中我喜欢的两种验证码
  • @Data注解的作用
  • @NestedConfigurationProperty 注解用法
  • [ 蓝桥杯Web真题 ]-布局切换
  • [16/N]论得趣
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [Android Studio 权威教程]断点调试和高级调试
  • [Android] Implementation vs API dependency
  • [BT]BUUCTF刷题第8天(3.26)
  • [BZOJ4010]菜肴制作
  • [c++] C++多态(虚函数和虚继承)
  • [CSS]文字旁边的竖线以及布局知识
  • [FxCop.设计规则]8. 也许参数类型应该是基类型