C#窗体皮肤制作(二):创建窗体库项目以及最小化、最大化、关闭按钮的实现

很高兴有朋友关注这篇博客,同时也十分抱歉让关注的朋友久等了,隔上一篇博客也有3个月没有更新,主要是由于3月份辞职,4月份初离职到期离开了北京高德,来到了上海张江。目前新工作也处于熟悉当中,希望大家能体谅。刚好这周末有点时间,我就接着写写,这篇博客主要是针对初学者,希望给为他们能提供一种较易理解的窗体皮肤制作思路,记得自己当初学习C#编程的时候也是摸着石头过河。

闲话少说,我还是接着上篇博客继续写,上次说明了下如何收集图片资源,这次就以360安全卫士来做示例进行模仿,本来也想过模仿下qq,但是qq的界面不太大众化也比较复杂,由于主要目的是希望让初学者弄明白做皮肤制作的思路,话说"授人以鱼不如授人以渔",因此这套博客的解讲的过程会比较简单易懂,让初学者也能学的明白,并且会将每篇对应的代码上传到我的csdn资源中,感兴趣的可以下载。我相信只要明白了思路,加上自己努力,qq之类的界面也是可以搞定的。

这一篇博客主要是讲自定义窗体的实现大体思路,以及最小化、最大化、关闭按钮的实现。总体思路是去掉窗体的默认边框,用其他的控件来替代最小化、最大化、关闭按钮的默认实现。第一讲不会考虑太多的细节,待功能开发的差不多时再进行一些代码的重构。由于是第一篇关于代码的,所以会从项目的创建、图片资源的引入开始,一步步讲解。

第一步:资源图片的选择

资源图片下载地址:[http://download.csdn.net/detail/bbirdsky/6923955]找到压缩包中的360safe.zip;

这一讲主要使用到的图片资源有:./MainFrame/Image/

background_mainwnd.jpg  // 这张做为窗体的背景,为了命名简单更名为img_bg

sys_button_***.jpg   //这4张分别对应最小化、最大化(还原)、关闭按钮的图片,更名为btn_***

第二步:创建解决方案(MySkins)

并添加一个Window窗体控件库项MySkins目用于做自定皮肤,另外添加一个Window窗体应用程序项目MySkinsTest用于做测试,并将MySkinsTest做为默认启动项目,并为MySkinsTest添加引用项目MySkins步骤如图:

第三步:创建目录结构

创建Contorl、Entity、Frame、Util用于存放对应的类文件,以及将图片资源添加进项目的图片资源中去,最终的项目结构如图:

第四步:测试代码

先在MySkins项目中添加一个BaseForm窗体,并在MySkinsTest测试项目中让默认的Form1窗体继承自BaseForm,测试项目只是用于测试MySkins项目的效果,注意一定要先添加MySkins依赖项目,不然会找不到BaseForm这个类!

namespace MySkinsTest
{
    public partial class Form1 : BaseForm
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}

第五步:皮肤代码(BaseForm)

1、此篇的核心就是BaseForm窗体基类,首先在Frame目录下创建一个普通的Form窗体,并做如下属性设置:

1>将FormBorderStyle设置为None,此时Form窗体就没有边框以及最大小、最小化、关闭按钮了;

将BackgroundImage设置为img_bg,并将DoubleBuffered双缓冲设置为true。

2>添加三个PictureBox分别用于替代最小化、最大化、关闭按钮,也可以尝试使用Button替代;

将PictureBox的BackColor设置为Transparent透明,默认是灰色;

将三个PictureBox的定位设置为Anchor:Top,Right,这样最大化后的按扭位置后按右上保持不变;

绑定鼠标点击、移入移出、按下抬起事件,建议是相同事件用同一个事件方法处理。

3>添加一个ToolTip控件,用于显示提示信息,设置完的效果如下图:

2、代码分析:本讲主要包含ControlState控件状态和ResUtils资源帮助类。

1>由于图片的背景图片是4个为一组的,因此定义状态枚举类:ControlState,代码如下:

     /// <summary>
     /// 控件状态
     /// </summary>
     public enum ControlState
     {
        Normal = 1,//控件默认时
        MouseOver = 2,//鼠标移上控件时
        MouseDown = 3,//鼠标按下控件时
        Disable = 4 //当控件不可用时
     }

2>由于需要从资源中获取图片以及需要对获取的图片按状态进行切分,因些需要帮助类:ResUtils,代码如下:

    /// <summary>
    /// 资源辅助类
    /// </summary>
    class ResUtils
    {
        /// <summary>
        /// 根据资源名称获取图像
        /// </summary>
        /// <param name="name">资源名称</param>
        /// <returns>图像</returns>
        public static Bitmap GetResAsImage(string name)
        {
            if (name == null || name == "")
            {
                return null;
            }
            return (Bitmap)Properties.Resources.ResourceManager.GetObject(name);
        }

        /// <summary>
        /// 图片按钮的背景图是4个,根据状态获取其中背景图
        /// </summary>
        /// <param name="name">图片名称</param>
        /// <param name="state">状态</param>
        /// <returns></returns>
        public static Bitmap GetResWithState(String name, ControlState state)
        {
            Bitmap bitmap = (Bitmap)GetResAsImage(name);
            if (bitmap == null)
            {
                return null;
            }
            int block = 0;
            switch (state)
            {
                case ControlState.Normal: block = 0; break;
                case ControlState.MouseOver: block = 1; break;
                case ControlState.MouseDown: block = 2; break;
                case ControlState.Disable: block = 3; break;
            }
            int width = bitmap.Width / 4;
            Rectangle rect = new Rectangle(block * width, 0, width, bitmap.Height);
            return bitmap.Clone(rect, bitmap.PixelFormat);
        }
    }

3>对于最小化、最大化、关闭的实现代码如下:

this.WindowState = FormWindowState.Maximized;  // 最大化

this.WindowState = FormWindowState.Minimized;  // 最小化

this.WindowState = FormWindowState.Normal;      // 一般状态

this.Close();  // 关闭

3、第一讲最终的效果实现了一个比较简单自定义窗体,具有最大化、最小化以及关闭功能。

不具备的功能:没有窗体小图标、标题,不能对窗体进行拖动、调整窗体大小,这是下一节要实现的功能。

小图标和标题比较简单好实现 ,窗体拖动、调整大小不使用win32Api也可以实现,但是效果不是太好,下节将使用win32Api进行实现!

对Win32不了解的可以看看这个文档:http://download.csdn.net/detail/bbirdsky/6910413

最后,我将继续保持更新。本篇对应代码下载:http://download.csdn.net/detail/bbirdsky/7366791。

C#窗体皮肤制作(二):创建窗体库项目以及最小化、最大化、关闭按钮的实现

时间: 2024-12-12 21:06:16

C#窗体皮肤制作(二):创建窗体库项目以及最小化、最大化、关闭按钮的实现的相关文章

iOS中静态库的制作——使用创建静态库项目的方式创建静态库

最近公司要求写SDK,我就想把它弄成静态库的方式 我的理解:所谓静态库,就是把所有的.m文件打包成一个.a文件,这样使分享代码的时候更加简洁,重要的是别人也不会看到你.m文件中的傻B代码了 环境是Xcode6.2 iOS8.2 首先,创建一个静态库项目 删掉Xcode自动创建的同名文件,然后导入你需要做成静态库的文件 在这里我导入一个简单的输出字符串的文件 然后选择运行的设备进行编译,这里我有不理解的地方:在Xcode6.2中,当我首先选择模拟器,然后编译文件的时候,.a文件依然是红色的,说明静

(转)WPF中让窗体不显示最大化,最小化,关闭按钮

1.在WPF中如果不想让窗体显示最大化,最小化,以及关闭按钮的话,可以再窗体的属性面板设置 将ResizeMode=NoResize时,将不会显示最大化最小化,只有关闭按钮:如下图: 将ResizeMode=CanMinimize时,最大化按钮被禁用,但是还是会显示,不能按,最小化,关闭按钮正常显示: 将WindowStyle=None时,将不会显示出最大化,最小化,以及关闭按钮,周围的边框也不存在. 还有一种方式: WPF:窗体不显示或禁用最大化.最小化.关闭按钮.图标以及对话框显示

窗体皮肤实现 - 重绘窗体非客户区(三)

窗体边框基本的绘制和控制完成,在第二篇中主要遗留的问题. 标题区域图标和按钮没绘制 缩放时客户区显示有问题 解决完下面的问题,皮肤处理基本完整.大致的效果GIF GIF中TShape的颜色表现有些问题,实际是正常的. 绘制标题区域内容 获取标题有效区域 绘制窗体图标 绘制按钮 绘制标题 标题区域主要考虑窗体是否在最大化状态,最大化后实际的标题绘制区域会有变化.可以通过 IsZoomed 或 GetWindowLong(Handle, GWL_STYLE) and WS_MAXIMIZE = WS

git使用(二)----创建版本库

创建版本库(操作都是在linux环境下) 什么是版本库呢?版本库又名仓库,英文名repository,其实就是一个目录,可以进行增删查改 创建一个目录,这里在根目录下创建一个git_home目录mkdir /git_homecd git_homegit init 这样就创建好了一个仓库,当然目前是一个空仓库 这个时候在当前目录通过ls -a可以看到多了一个.git的目录 把文件添加到版本库 版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词"Linux",在第8行删了一个单词&

窗体皮肤实现 - 重绘窗体非客户区(二)

第一个实现了基本处理.窗体边框的宽度有些肥大,需要进行瘦身. 实现:     1.改变外框线宽度 (WM_NCCALCSIZE)     2.改变外框样式 (WM_WINDOWPOSCHANGING) 通过 WM_NCCALCSIZE 消息可以实现目的. procedure WMNCCalcSize(var message: TWMNCCalcSize); message WM_NCCALCSIZE; procedure TTest.WMNCCalcSize(var message: TWMNC

窗体皮肤实现 - 重绘窗体非客户区(一)

现在皮肤控件也很多,但每次装一堆控件,使用又繁琐.稍微研究一下内部机制,还是比较简单的. 主要会使用到下面几个消息 1 const 2 WM_NCUAHDRAWCAPTION = $00AE; 3 WM_NCUAHDRAWFRAME = $00AF; 4 5 // 绘制非客户区消息 6 procedure WMNCPaint(var message: TWMNCPaint); message WM_NCPAINT; 7 // 在激活程序时需要相应的消息 8 procedure WMNCActiv

android studio学习----如何创建一个库项目

首先,打开Android studio的软件工具,进入到界面中点击菜单的“file”选项. 2 在弹出的下拉的菜单中,可以看到的是为"New Module“的选项点击进入. 3 进入到choose module type的模块的界面中,进行选择Android library的选项,然后点击”next“的选项. 4 进行配置library相关选项,输入application/ library name和Module name的昵称,点击”next“. 5 选择activity的模板,默认使用的是b

自定义窗体的最大化,最小化,关闭功能

namespace 自定义窗体的最大化_最小化和关闭按钮 { partial class Form1 { /// <summary> /// 必需的设计器变量. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源. /// </summary> /// <param name="disp

Android Studio创建库项目及引用

Android Studio创建库项目其实创建的是在主项目下创建Module模块,这个Module模块创建的时候选择库项目模式. 为什么要这样处理呢?因为在Android Studio中一个WorkSpace工作空间就是一个Android主项目.主项目其实也就是这个工作空间的一个Module模块,只不过这个模块是一个主模块.如果要想创建库项目,显而易见也应该是一个module模块项目,设置成Library就可以了. 然后自动生成的build.gradle文件里面会有一行标示 apply plug