cyycoish 发表于 2015-9-13 02:08:04

【.net、dll】皮肤ModernWolfSkin

这是一个dll,基于dnet fx 4.5. 由vb.net编写
那么使用皮肤后的效果是这个样子:



先扯淡,说说ModernWolfSkin各项花边:
关于为啥叫做Modern Wolf Skin?
有一个德国户外品牌叫做jack wolf skin,生产冲锋衣。。。等等。
名字酷酷的有没有?
微软在win8中引入的Metro UI也叫做New Windows UI或者Modern UI
是该UI的设计思路
所以,+到一起,诞生了Modern Wolf Skin。
既然是“狼皮”了,那么其中有个重要的类叫做:NCCoyoteSkin
顾名思义:NC郊狼皮(大家可以查一下郊狼的习性,这种狼生活与北美,生存能力极强,在其栖息地随处可见)
所以郊狼皮是一个很基础的类。
以后呢,还会实现更加漂亮的ArcticWolfSkin(北极狼皮)和支持dwm对NC进行扩展的支持Ribbon界面的CanisRufusSkin(红狼皮)

还有一个类叫做“土狗皮”(啊?肿么狼皮里冒出土狗皮)嘻嘻,大家自己去调用。
好了,接下来我跟大家分别讲述一下这个dll在vbdnet和csharp中的用法

在vbdnet中使用该dll非常容易,母语嘛。。
首先添加该dll的引用,如图:

然后,浏览,找到该dll 添加!
然后呢,在要使用皮肤的窗体类里边定义私有成员变量:
Private WndSkn As New ModernWolfSkin.ModernWolfSkin.NCCoyoteSkin(Me)
可以看见,这里初始化变量使用了NCCoyoteSkin(郊狼皮)的构造函数,并且传入一个Form自己的实例
(此处和csharp大有不同,而且cs傻X就傻X在这个地方。。。。等会说。。)
再然后,重载掉窗体类的WndProc函数:
Protected Overrides Sub WndProc(ByRef m As Message)
    MyBase.WndProc(m) '首先先让基类的WndProc处理message
    WndSkn.HandleMsg(m) '然后让郊狼皮的实例处理message,使用郊狼皮类的实例的HandleMsg函数,传入m(我们不需要返回值,所以直接call它)
End Sub
那么代码至此,我们已经得到了这样一个窗体:

上源代码:
Public Class Form1
    Private WndSkn As New ModernWolfSkin.ModernWolfSkin.NCCoyoteSkin(Me)
    Protected Overrides Sub WndProc(ByRef m As Message)
      MyBase.WndProc(m)
      WndSkn.HandleMsg(m)
    End Sub
End Class
好了,最后是对皮肤的添油加醋。使用IDE的智能感知看看郊狼皮的成员函数和各项属性吧。
这里我放上公开函数,属性的“元数据”这是写dll时候留下的,大家可以利用其XML注释。
        ''' <summary>
      ''' The construct sub of the class.
      ''' You can define and init this class as a member variable in a form class.
      ''' </summary>
      ''' <param name="TargetForm">Input form class name</param>
      Public Sub New(ByRef TargetForm As Form)

      ''' <summary>
      ''' Render or redraw the non-client coyote skin now.
      ''' </summary>
      Public Sub RenderNow()

      ''' <summary>
      ''' Custom the titlebar of non-client coyote skin.
      ''' </summary>
      ''' <param name="BgColor">Titlebar's background color</param>
      ''' <param name="Increment">Titlebar's height incremental value as pixels. Default value is 0 (no increment).</param>
      ''' <param name="LightSytle">Controlboxe's Color. Value "True" for light color and "False" for dark color. This color will change with titlebar's backcolor.</param>
      Public Sub SetTitleBar(ByVal BgColor As Color, Optional ByVal Increment As Long = 0, Optional ByVal LightSytle As Boolean = False)

      ''' <summary>
      ''' Mseeage handler. Must use it in form class's overrided procedure which called "WndProc". And this function must use after "MyBase.WndProc(m)".
      ''' </summary>
      ''' <param name="m">Import the message which called "m".</param>
      ''' <returns></returns>
      Public Overridable Function HandleMsg(ByRef m As Message) As Message

      ''' <summary>
      ''' Unpublished function, being test.
      ''' We are sorry about that we cant provide arguments of this function.
      ''' </summary>
      ''' <param name="m">None</param>
      ''' <param name="objWndProcX">None</param>
      ''' <returns></returns>
      Public Overridable Function InternationalTest_HandleMsg(ByRef m As Message, ByRef objWndProcX As PtrWndProcX) As Message

      ''' <summary>
      ''' Add icons for controlboxes
      ''' </summary>
      Public Function SetControlBoxIcons(ByVal Close0 As Icon,
                                    ByVal Close1 As Icon,
                                    ByVal Maximize0 As Icon,
                                    ByVal Maximize1 As Icon,
                                    ByVal Minimum0 As Icon,
                                    ByVal Minimum1 As Icon,
                                    ByVal Normal0 As Icon,
                                    ByVal Normal1 As Icon) As Boolean
      ''' <summary>
      ''' Return The image of client area
      ''' </summary>
      ''' <returns>Image</returns>
      Public Function GetClientImage() As Image

      'Properties
      ''' <summary>
      ''' Get or set the controlbox's status.
      ''' </summary>
      ''' <returns>Integer</returns>
      Public Property ControlBox() As EnumControlBox

      ''' <summary>
      ''' A boolean value that indicate visible of the border.
      ''' </summary>
      ''' <returns>Boolean</returns>
      Public Property BorderVisible() As Boolean

      ''' <summary>
      ''' The color of the border.
      ''' </summary>
      ''' <returns>Color</returns>
      Public Property BorderColor As Color

      ''' <summary>
      ''' Set the non-client background image.
      ''' </summary>
      Public WriteOnly Property NCBackgroundImage As Image

      ''' <summary>
      ''' The image aligment of non client area.
      ''' </summary>
      ''' <returns>Integer</returns>
      Public Property BackgroundImageAlignment As EnumPictureAlignment

      ''' <summary>
      ''' Get or set a value of controlbox's image that from which way.
      ''' </summary>
      ''' <returns>Integer</returns>
      Public Property ControlBoxImageSource As EnumImageSource

      ''' <summary>
      ''' Get or set close control box lighting colors.
      ''' </summary>
      ''' <returns>Color</returns>
      Public Property ActiveCloseBoxColor As Color

      ''' <summary>
      '''Get or set minimum control box lighting colors.
      ''' </summary>
      ''' <returns>Color</returns>
      Public Property ActiveMinimumBoxColor As Color

      ''' <summary>
      '''Get or set maximize control box lighting colors.
      ''' </summary>
      ''' <returns>Color</returns>
      Public Property ActiveMaximizeBoxColor As Color

      ''' <summary>
      '''Get or set close control box lighting colors.
      ''' </summary>
      ''' <returns>Color</returns>
      Public Property UneabledControlBoxColor As Color

      ''' <summary>
      ''' To get the border width of a window.
      ''' </summary>
      ''' <returns>Long</returns>
      Public ReadOnly Property BorderWidthPty As Long

      ''' <summary>
      ''' To get the title bar's height.
      ''' </summary>
      ''' <returns>Long</returns>
      Public ReadOnly Property TitleBarHeightPty As Long

      ''' <summary>
      ''' Set non client border color.
      ''' </summary>
      ''' <returns>Color</returns>
      Public Property NCColor As Color
希望你拥有一张自己的“郊狼皮”!{:soso_e100:}

然后说到csharp对这个dll的调用。
不得不说,没有me的cs实现起来实在是超麻烦的。
那么总会有个办法,毕竟cs和vbdnet是亲兄弟,哥哥vbdnet的分享弟弟cs总有办法用吧。
首先,请添加引用。
这样实现:
(假设窗体类名叫Form1)
在program.cs的main里边会有这么一句话:Application.Run(new Form1());
也就是说,程序启动咋创建Form1的实例呢?cs很直接,没有用到变量。在Application的run函数里边,直接new了一个Form1
我们要想办法将Form1的实例传到Form1类自身里边以供郊狼皮的构造函数初始化使用。
第一,我们要在Form1类里边搞一个公共变量存放这个类自身的实例
public Form frm;
后边将 Application.Run(new Form1()); 替换成:
            Form1 form1 = new Form1();
            form1.frm = form1;
            Application.Run(form1);
好了,这样frm就能代替me使用了
那么,program.cs是酱紫的:
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      
      static void Main()
      {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 form1 = new Form1();
            form1.frm = form1;
            Application.Run(form1);
      }
    }
}

怎样给窗体披上郊狼皮呢,这里直接上代码(放心,我会注释大法):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ModernWolfSkin.ModernWolfSkin;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
      
      public Form frm; //自身实例
      private NCCoyoteSkin CoyoteSkin; //和vbdnet一样,有木有?但是不能初始化,原因:
      //frm是在Form1被实例化以后通过“form1.frm = form1;”(mian里边)一句被初始化的
      //所以我们用的时候再去对其进行判断是否为null,而不能现在就放在郊狼皮的构造函数中对其init
      //否则会导致传入了null
      private bool bSkinReady = false; //搞个变量,判断皮肤是否已经准备好

      public Form1() //构造函数,我们不去管它
      {
            InitializeComponent();
      }

      private bool LoadSkin() //这个函数就是判断frm这个form1自身实例是否初始化
      {
            if (frm != null)
            {
                if (CoyoteSkin == null) //如果此时郊狼皮木有粗始化,那就粗屎画
                  CoyoteSkin = new NCCoyoteSkin(ref frm);
                return true;
            }
            else
                return false;
      }
      protected override void WndProc(ref Message m) //和vbdnet的demo一样要重载Wndproc
      {
            base.WndProc(ref m);
            if (bSkinReady) //一定要判断郊狼皮是否已经初始化
                CoyoteSkin.HandleMsg(ref m); //使用HandleMsg函数处理message,这里按饮引用传入
      }

      private void Form1_Load(object sender, EventArgs e)
      {
            //因为,如此这般 粗屎化完毕后,郊狼皮不能被披上!
            //所以使用了一个蛋疼的办法:
            //首先记录窗体原来的WindowState,再最小化窗体!然后等皮肤初始化完毕后恢复WindowState
            //好蛋疼(流汗)木有办法呀(无奈)
            FormWindowState OriginalWndStat = this.WindowState; //记录原来状态
            this.WindowState = FormWindowState.Minimized; //最小化

            bSkinReady = LoadSkin(); //加载皮肤
            if(!bSkinReady) //皮肤木有加载OK
                MessageBox.Show("Failed To Load Skin!");

            this.WindowState = OriginalWndStat; //恢复WindowState
      }
    }
}

好了基本上实现了,就是有点不舒服
那么对MWS皮肤的介绍到此为止,点个赞么,喵!{:soso_e154:}

1.0.0.1版本的dll下载地址:

ps:狼是很有趣的动物,请大家保护生态环境,不要剥夺它们的家
最后,请试用一下土狗皮!{:soso_e112:}

Lv.1 液态物体 发表于 2015-9-13 05:07:30

土狗...我要怎么吐槽?
不行.严肃点.

不能这样叫土狗:叫本地狗

cyycoish 发表于 2015-9-13 16:07:42

Lv.1 液态物体 发表于 2015-9-13 05:07
土狗...我要怎么吐槽?
不行.严肃点.




你需要这样来上一句:
Dim Qux As New ModernWolfSkin.NCMoleCricketSkin(1)

7KY6 发表于 2018-1-14 15:45:27

可以可以!!
页: [1]
查看完整版本: 【.net、dll】皮肤ModernWolfSkin