Winform 自定義窗體皮膚組件

来源:https://www.cnblogs.com/czly/archive/2018/05/31/9117143.html
-Advertisement-
Play Games

分享一個很久之前寫的一個Winform換膚組件。 主要利用CBT鉤子,NativeWindow來實現。可實現動態換皮膚插件修改窗體顯示外觀。 我們先定義一個自定義組件 using Skin; using System; using System.Collections.Generic; using ...


分享一個很久之前寫的一個Winform換膚組件。

主要利用CBT鉤子,NativeWindow來實現。可實現動態換皮膚插件修改窗體顯示外觀。
我們先定義一個自定義組件

using Skin;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace SkinControl
{
public class LySkinEngine : Component
{
#region 欄位
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
    private static HookProc _cbtHook;

    private static IntPtr Hook;

    private static string m_SkinName = "";
    #endregion

    #region API
    /// <summary>
    /// SetWindowsHookEx
    /// </summary>
    /// <param name="idHook"></param>
    /// <param name="lpfn"></param>
    /// <param name="hMod"></param>
    /// <param name="dwThreadId"></param>
    /// <returns></returns>
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, int hMod, int dwThreadId);

    /// <summary>
    /// CallNextHookEx
    /// </summary>
    /// <param name="hhk"></param>
    /// <param name="nCode"></param>
    /// <param name="wParam"></param>
    /// <param name="lParam"></param>
    /// <returns></returns>
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    /// <summary>
    /// UnhookWindowsHookEx
    /// </summary>
    /// <param name="hhk"></param>
    /// <returns></returns>
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern bool UnhookWindowsHookEx(IntPtr hhk);
    #endregion

    #region FnHookProc
    /// <summary>
    /// FnHookProc
    /// </summary>
    /// <param name="nCode"></param>
    /// <param name="wParam"></param>
    /// <param name="lParam"></param>
    /// <returns></returns>
    private static IntPtr FnHookProc(int nCode, IntPtr wParam, IntPtr lParam)
    {

        switch (nCode)
        {
            case 5:
                Control control = Control.FromHandle(wParam);

                if (control != null)
                {

                    Skin.SkinResource tmpSkinClass = GetSkin();

                    FormBase frmBase = new FormBase(control as Form, tmpSkinClass);

                }
                break;
            default:
                break;
        }
        return CallNextHookEx(Hook, nCode, wParam, lParam);
    }
    #endregion

    #region 動態載入皮膚資源
    private static SkinResource GetSkin()
    {
        SkinResource tmpResource = new SkinResource();

        Assembly ass = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + @"\Skin\" + m_SkinName + @".dll");

        Type type = ass.GetType("SkinFile.Skin");

        //生成實例 Skin1
        Object obj = Activator.CreateInstance(type);

        //標題背景
        PropertyInfo pi = type.GetProperty("CaptionBackgroundColor");
        tmpResource.CaptionBackgroundColor = (Color)pi.GetValue(obj, null);
        //標題前景色
        PropertyInfo pi1 = type.GetProperty("CaptionColor");
        tmpResource.CaptionColor = (Color)pi1.GetValue(obj, null);


        return tmpResource;
    }
    #endregion

   
    public void SetSkin(string varSkinName)
    {
        m_SkinName = varSkinName;
        if (Hook == IntPtr.Zero)
        {
            _cbtHook = new HookProc(FnHookProc);
            Hook = SetWindowsHookEx(5, _cbtHook, 0, AppDomain.GetCurrentThreadId());
            Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
        }
    }

    /// <summary>
    /// Application_ApplicationExit
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Application_ApplicationExit(object sender, EventArgs e)
    {
        //Engine.Dispose(false);
        UnhookWindowsHookEx(Hook);
    }

}
}
View Code

 

新增一個皮膚資源類,主要用於存儲皮膚文件中的信息

namespace Skin
{
public class SkinResource
{
public Color CaptionColor {get;set;}
public Color CaptionBackgroundColor {get;set;}
}
}

 

新增一個類,主要實現對窗體的消息接管和繪製

namespace Skin
{
public partial class FormBase : NativeWindow
{
Form m_f = null;
    public FormBase(Form varForm,  Skin.SkinResource varSkin)
    {
        try
        {
            m_f = varForm;
            AssignHandle(m_f.Handle);
            m_f.HandleDestroyed += new EventHandler(this.OnHandleDestroyed);

            CloseButtonImage = Resource1.close_normal;
            CloseButtonHoverImage = Resource1.close_highlight;
            CloseButtonPressDownImage = Resource1.close_press;

            MaximumButtonImage = Resource1.max_normal;
            MaximumButtonHoverImage = Resource1.max_highlight;
            MaximumButtonPressDownImage = Resource1.max_press;

            MaximumNormalButtonImage = Resource1.restore_normal;
            MaximumNormalButtonHoverImage = Resource1.restore_highlight;
            MaximumNormalButtonPressDownImage = Resource1.restore_press;

            MinimumButtonImage = Resource1.min_normal;
            MinimumButtonHoverImage = Resource1.min_highlight;
            MinimumButtonPressDownImage = Resource1.min_press;

            HelpButtonImage = Resource1.skin_normal;
            HelpButtonHoverImage = Resource1.skin_highlight;
            HelpButtonPressDownImage = Resource1.skin_press;

            CaptionColor = varSkin.CaptionColor;
            CaptionBackgroundColor = varSkin.CaptionBackgroundColor;

        }
        catch(Exception ex)
        {
        }
     
    }


    #region 欄位

    struct _NonClientSizeInfo
    {
        public Size CaptionButtonSize;
        public Size BorderSize;
        public int CaptionHeight;
        public Rectangle CaptionRect;
        public Rectangle Rect;
        public Rectangle ClientRect;
        public int Width;
        public int Height;
    };

    #region 常量

    const int WM_NCACTIVATE = 0x86;
    const int WM_NCPAINT = 0x85;
    const int WM_NCLBUTTONDOWN = 0xA1;
    const int WM_NCRBUTTONDOWN = 0x00A4;
    const int WM_NCRBUTTONUP = 0x00A5;
    const int WM_NCMOUSEMOVE = 0x00A0;
    const int WM_NCLBUTTONUP = 0x00A2;
    const int WM_NCCALCSIZE = 0x0083;
    const int WM_NCMOUSEHOVER = 0x02A0;
    const int WM_NCMOUSELEAVE = 0x02A2;
    const int WM_NCHITTEST = 0x0084;
    const int WM_NCCREATE = 0x0081;
    //const int WM_RBUTTONUP = 0x0205;

    const int WM_LBUTTONDOWN = 0x0201;
    const int WM_CAPTURECHANGED = 0x0215;
    const int WM_LBUTTONUP = 0x0202;
    const int WM_SETCURSOR = 0x0020;
    const int WM_CLOSE = 0x0010;
    const int WM_SYSCOMMAND = 0x0112;
    const int WM_MOUSEMOVE = 0x0200;
    const int WM_SIZE = 0x0005;
    const int WM_SIZING = 0x0214;
    const int WM_GETMINMAXINFO = 0x0024;
    const int WM_ENTERSIZEMOVE = 0x0231;
    const int WM_WINDOWPOSCHANGING = 0x0046;


    // FOR WM_SIZING MSG WPARAM
    const int WMSZ_BOTTOM = 6;
    const int WMSZ_BOTTOMLEFT = 7;
    const int WMSZ_BOTTOMRIGHT = 8;
    const int WMSZ_LEFT = 1;
    const int WMSZ_RIGHT = 2;
    const int WMSZ_TOP = 3;
    const int WMSZ_TOPLEFT = 4;
    const int WMSZ_TOPRIGHT = 5;

    // left mouse button is down.
    const int MK_LBUTTON = 0x0001;

    const int SC_CLOSE = 0xF060;
    const int SC_MAXIMIZE = 0xF030;
    const int SC_MINIMIZE = 0xF020;
    const int SC_RESTORE = 0xF120;
    const int SC_CONTEXTHELP = 0xF180;

    const int HTCAPTION = 2;
    const int HTCLOSE = 20;
    const int HTHELP = 21;
    const int HTMAXBUTTON = 9;
    const int HTMINBUTTON = 8;
    const int HTTOP = 12;

    const int SM_CYBORDER = 6;
    const int SM_CXBORDER = 5;
    const int SM_CYCAPTION = 4;

    const int CS_DropSHADOW = 0x20000;
    const int GCL_STYLE = (-26);

    #endregion
    #endregion

    #region windows api

    [DllImport("User32.dll")]
    private static extern IntPtr GetWindowDC(IntPtr hwnd);
    [DllImport("User32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetWindowRect(IntPtr hwnd, ref Rectangle rect);
    [DllImport("User32.dll")]
    private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int SetClassLong(IntPtr hwnd, int nIndex, int dwNewLong);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetClassLong(IntPtr hwnd, int nIndex);

    #endregion

    #region 構造函數
    internal void OnHandleCreated(object sender, EventArgs e)
    {
        AssignHandle(((Form)sender).Handle);
    }

    internal void OnHandleDestroyed(object sender, EventArgs e)
    {
        ReleaseHandle();
    }
    #endregion

    #region 屬性

    [Category("ControlBox")]
    [Description("Close button image in control box.")]
    [DisplayName("CloseButtonImage")]
    [DesignOnly(true)]
    public Image CloseButtonImage { get; set; }

    [Category("ControlBox")]
    [Description("Close button image pressed down in control box.")]
    [DisplayName("CloseButtonPressDownImage")]
    [DesignOnly(true)]
    public Image CloseButtonPressDownImage { get; set; }

    [Category("ControlBox")]
    [Description("Close button image hover in control box.")]
    [DisplayName("CloseButtonHoverImage")]
    [DesignOnly(true)]
    public Image CloseButtonHoverImage { get; set; }

    [Category("ControlBox")]
    [Description("Maximum button image in control box.")]
    [DisplayName("MaximumButtonImage")]
    [DesignOnly(true)]
    public Image MaximumButtonImage { get; set; }

    [Category("ControlBox")]
    [Description("Maximum button hover image in control box.")]
    [DisplayName("MaximumButtonHoverImage")]
    [DesignOnly(true)]
    public Image MaximumButtonHoverImage { get; set; }

    [Category("ControlBox")]
    [Description("Maximum button pressed down image in control box.")]
    [DisplayName("MaximumButtonPressDownImage")]
    [DesignOnly(true)]
    public Image MaximumButtonPressDownImage { get; set; }

    [Category("ControlBox")]
    [Description("Maximum Normal button image in control box.")]
    [DisplayName("MaximumNormalButtonImage")]
    [DesignOnly(true)]
    public Image MaximumNormalButtonImage { get; set; }

    [Category("ControlBox")]
    [Description("Maximum Normal button hover image in control box.")]
    [DisplayName("MaximumNormalButtonHoverImage")]
    [DesignOnly(true)]
    public Image MaximumNormalButtonHoverImage { get; set; }

    [Category("ControlBox")]
    [Description("Maximum Normal button pressed down image in control box.")]
    [DisplayName("MaximumNormalButtonPressDownImage")]
    [DesignOnly(true)]
    public Image MaximumNormalButtonPressDownImage { get; set; }

    [Category("ControlBox")]
    [Description("Minimum button image in control box.")]
    [DisplayName("MinimumButtonImage")]
    [DesignOnly(true)]
    public Image MinimumButtonImage { get; set; }

    [Category("ControlBox")]
    [Description("Minimum button hover image in control box.")]
    [DisplayName("MinimumButtonHoverImage")]
    [DesignOnly(true)]
    public Image MinimumButtonHoverImage { get; set; }

    [Category("ControlBox")]
    [Description("Minimum button pressed down image in control box.")]
    [DisplayName("MinimumButtonPressDownImage")]
    [DesignOnly(true)]
    public Image MinimumButtonPressDownImage { get; set; }

    [Category("ControlBox")]
    [Description("Help button image in control box.")]
    [DisplayName("HelpButtonImage")]
    [DesignOnly(true)]
    public Image HelpButtonImage { get; set; }

    [Category("ControlBox")]
    [Description("Help button hover image in control box.")]
    [DisplayName("HelpButtonHoverImage")]
    [DesignOnly(true)]
    public Image HelpButtonHoverImage { get; set; }

    [Category("ControlBox")]
    [Description("Help button pressed down image in control box.")]
    [DisplayName("HelpButtonPressDownImage")]
    [DesignOnly(true)]
    public Image HelpButtonPressDownImage { get; set; }

    [Category("CaptionColor")]
    [Description("The color of caption.")]
    [DisplayName("CaptionColor")]
    [DefaultValue(typeof(Color), "Black")]
    [Browsable(true)]
    public Color CaptionColor { get; set; }

    [Category("CaptionColor")]
    [Description("The color of caption.")]
    [DisplayName("CaptionBackgroundColor")]
    [DefaultValue(typeof(Color), "Black")]
    [Browsable(true)]
    public Color CaptionBackgroundColor { get; set; }

    [DefaultValue("")]
    [Browsable(true)]
    [Category("ControlBox")]
    public virtual ContextMenuStrip CaptionContextMenu { get; set; }
    #endregion

    #region 方法

    private _NonClientSizeInfo GetNonClientInfo(IntPtr hwnd)
    {
        _NonClientSizeInfo info = new _NonClientSizeInfo();
        info.CaptionButtonSize = SystemInformation.CaptionButtonSize;
        info.CaptionHeight = SystemInformation.CaptionHeight;

        switch (m_f.FormBorderStyle)
        {
            case System.Windows.Forms.FormBorderStyle.Fixed3D:
                info.BorderSize = SystemInformation.FixedFrameBorderSize;
                break;
            case System.Windows.Forms.FormBorderStyle.FixedDialog:
                info.BorderSize = SystemInformation.FixedFrameBorderSize;
                break;
            case System.Windows.Forms.FormBorderStyle.FixedSingle:
                info.BorderSize = SystemInformation.FixedFrameBorderSize;
                break;
            case System.Windows.Forms.FormBorderStyle.FixedToolWindow:
                info.BorderSize = SystemInformation.FixedFrameBorderSize;
                info.CaptionButtonSize = SystemInformation.ToolWindowCaptionButtonSize;
                info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight;
                break;
            case System.Windows.Forms.FormBorderStyle.Sizable:
                info.BorderSize = SystemInformation.FrameBorderSize;
                break;
            case System.Windows.Forms.FormBorderStyle.SizableToolWindow:
                info.CaptionButtonSize = SystemInformation.ToolWindowCaptionButtonSize;
                info.BorderSize = SystemInformation.FrameBorderSize;
                info.CaptionHeight = SystemInformation.ToolWindowCaptionHeight;
                break;
            default:
                info.BorderSize = SystemInformation.BorderSize;
                break;
        }

        Rectangle areatRect = new Rectangle();
        GetWindowRect(hwnd, ref areatRect);

        int width = areatRect.Right - areatRect.Left;
        int height = areatRect.Bottom - areatRect.Top;

        info.Width = width;
        info.Height = height;

        Point xy = new Point(areatRect.Left, areatRect.Top);
        xy.Offset(-areatRect.Left, -areatRect.Top);

        info.CaptionRect = new Rectangle(xy.X, xy.Y + info.BorderSize.Height, width, info.CaptionHeight);
        info.Rect = new Rectangle(xy.X, xy.Y, width, height);
        info.ClientRect = new Rectangle(xy.X + info.BorderSize.Width,
            xy.Y + info.CaptionHeight + info.BorderSize.Height,
            width - info.BorderSize.Width * 2,
            height - info.CaptionHeight - info.BorderSize.Height * 2);
        
        return info;
    }

    private void DrawTitle(Graphics g, _NonClientSizeInfo ncInfo, bool active)
    {
        try
        {
        
        int titleX;

        if (m_f.ShowIcon &&
             m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
             m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)
        {
            Size iconSize = SystemInformation.SmallIconSize;
            g.DrawIcon(m_f.Icon, new Rectangle(new Point(ncInfo.BorderSize.Width+5, ncInfo.BorderSize.Height + (ncInfo.CaptionHeight - iconSize.Height) / 2+5), iconSize));
            titleX = ncInfo.BorderSize.Width + iconSize.Width + ncInfo.BorderSize.Width+5;
        }
        else
        {
            titleX = ncInfo.BorderSize.Width;
        }

        SizeF captionTitleSize = g.MeasureString(m_f.Text, SystemFonts.CaptionFont);
        g.DrawString(m_f.Text, SystemFonts.CaptionFont, new SolidBrush(CaptionColor),
                new RectangleF(titleX,
                    (ncInfo.BorderSize.Height + ncInfo.CaptionHeight - captionTitleSize.Height) / 2+5,
                    ncInfo.CaptionRect.Width - ncInfo.BorderSize.Width * 2 - SystemInformation.MinimumWindowSize.Width,
                    ncInfo.CaptionRect.Height), StringFormat.GenericTypographic);
            }
        catch(Exception ex)
        {

        }
    }

    private void DrawBorder(Graphics g, _NonClientSizeInfo ncInfo, Brush background, bool active,ref List<Rectangle> varBorders)
    {
        
        int tmpHeight = m_f.Height;
        int tmpWidth = m_f.Width;
        if (ncInfo.Rect.Height != tmpHeight)
        {
            ncInfo.Rect.Height = tmpHeight + ncInfo.BorderSize.Height;
        }
        if (ncInfo.Rect.Width != tmpWidth)
        {
            ncInfo.Rect.Width = tmpWidth + ncInfo.BorderSize.Width;
        }
        

        Rectangle borderTop = new Rectangle(ncInfo.Rect.Left,
                ncInfo.Rect.Top,
                ncInfo.Rect.Left + ncInfo.Rect.Width,
                ncInfo.Rect.Top + ncInfo.BorderSize.Height);
        Rectangle borderLeft = new Rectangle(
                new Point(ncInfo.Rect.Location.X, ncInfo.Rect.Location.Y + ncInfo.BorderSize.Height),
                new Size((int)(ncInfo.BorderSize.Width*2), ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height));
        Rectangle borderRight = new Rectangle(ncInfo.Rect.Width- 3*ncInfo.BorderSize.Width,
                ncInfo.Rect.Top + ncInfo.BorderSize.Height,
                (int)(ncInfo.BorderSize.Width * 2),
                ncInfo.ClientRect.Height + ncInfo.CaptionHeight + ncInfo.BorderSize.Height);
        Rectangle borderBottom = new Rectangle(ncInfo.Rect.Left + ncInfo.BorderSize.Width,
                ncInfo.Rect.Height - 3*ncInfo.BorderSize.Height,
                ncInfo.Rect.Width - ncInfo.BorderSize.Width ,
                (int)(ncInfo.BorderSize.Height * 2));
        varBorders.Add(borderTop);
        varBorders.Add(borderLeft);
        varBorders.Add(borderRight);
        varBorders.Add(borderBottom);
       
        g.FillRectangle(background, borderTop);
        // left border
        g.FillRectangle(background, borderLeft);
        // right border
        g.FillRectangle(background, borderRight);
        // bottom border
        g.FillRectangle(background, borderBottom);
    }
    private List<Rectangle> m_Borders = null;
    private void DrawCaption(IntPtr hwnd, bool active)
    {
        m_Borders = new List<Rectangle>();
        IntPtr dc;
        Graphics g;
        Size iconSize;
        _NonClientSizeInfo ncInfo;
        Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);
        Brush foregroundColor = new SolidBrush(CaptionColor);

        iconSize = SystemInformation.SmallIconSize;

        dc = GetWindowDC(hwnd);
        ncInfo = GetNonClientInfo(hwnd);
        g = Graphics.FromHdc(dc);

        Rectangle rc = ncInfo.CaptionRect;
        rc.Height = (int)(rc.Height + ncInfo.BorderSize.Height);
        g.FillRectangle(backgroundColor, rc);

        DrawBorder(g, ncInfo, backgroundColor, active, ref m_Borders);
        DrawTitle(g, ncInfo, active);
        DrawControlBox(g, ncInfo, backgroundColor, m_f.ControlBox, m_f.MaximizeBox, m_f.MinimizeBox, m_f.HelpButton);
        g.Dispose();
        ReleaseDC(hwnd, dc);
    }

    private void DrawControlBox(Graphics g, _NonClientSizeInfo info, Brush background, bool closeBtn, bool maxBtn, bool minBtn, bool helpBtn)
    {
        
        int tmpHeight = m_f.Height;
        int tmpWidth = m_f.Width;
        if (info.CaptionRect.Height > tmpHeight)
        {
            info.CaptionRect.Height = tmpHeight;
        }
        if (info.CaptionRect.Width > tmpWidth)
        {
            info.CaptionRect.Width = tmpWidth;
        }
        info.CaptionRect.Height = info.CaptionRect.Height * 2;
     
        
        if (m_f.ControlBox)
        {
            int closeBtnPosX =  info.CaptionRect.Width - info.BorderSize.Width - info.CaptionButtonSize.Width;
            int maxBtnPosX = closeBtnPosX - info.CaptionButtonSize.Width;
            int minBtnPosX = maxBtnPosX - info.CaptionButtonSize.Width;
            int btnPosY = info.BorderSize.Height + (info.CaptionHeight - info.CaptionButtonSize.Height) / 2;

            Rectangle btnRect = new Rectangle(new Point(closeBtnPosX, btnPosY), info.CaptionButtonSize);
            Rectangle maxRect = new Rectangle(new Point(maxBtnPosX, btnPosY), info.CaptionButtonSize);
            Rectangle minRect = new Rectangle(new Point(minBtnPosX, btnPosY), info.CaptionButtonSize);

            Brush backgroundColor = new SolidBrush(CaptionBackgroundColor);

            g.FillRectangle(backgroundColor, btnRect);
            g.FillRectangle(backgroundColor, maxRect);
            g.FillRectangle(backgroundColor, minRect);

            g.DrawImage(CloseButtonImage, btnRect);

            if (m_f.MaximizeBox || m_f.MinimizeBox)
            {
                if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                    m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)
                {
                    if (m_f.WindowState == FormWindowState.Maximized)
                    {
                        g.DrawImage(MaximumNormalButtonImage, maxRect);
                    }
                    else
                    {
                        g.DrawImage(MaximumButtonImage, maxRect);
                    }
                    g.DrawImage(MinimumButtonImage, minRect);
                }
            }
            else if (m_f.HelpButton)
            {
                if (m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.FixedToolWindow &&
                    m_f.FormBorderStyle != System.Windows.Forms.FormBorderStyle.SizableToolWindow)
                {
                    g.DrawImage(HelpButtonImage, maxRect);
                }
            }
        }

    }

    protected virtual void OnCaptionContextMenu(int x, int y)
    {
        if (this.CaptionContextMenu != null)
            this.CaptionContextMenu.Show(x, y);
    }

    #endregion

    #region 消息
    private int m_IsDrawButton = 0	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HTML:超文本標記語言(頁面中可以包含圖片、音樂、鏈接、程式等非文字元素,通過一組標簽的形式描述事物的一門語言) HTML的結構標簽:根標簽:<html>、頭標簽:<head>、體標簽:<body> HTML的字體標簽:<font> 屬性:color {字體顏色分為兩種(1)英文單詞設置:blac ...
  • 很多小步快跑的公司,開發人員多則3-4個,面對巨大業務壓力,日連夜的趕著上線,快速試錯,自然就沒時間搭建一些基礎設施,比如說logCenter,但初期 項目不穩定,bug又多,每次都跑到生產去找日誌,確實也不大方便,用elk或者用hadoop做日誌中心,雖然都是沒問題的,但基於成本和人手還是怎麼簡化 ...
  • 分享一篇文章,關於asp.net core中httpcontext的拓展。 現在,試圖圍繞HttpContext.Current構建你的代碼真的不是一個好主意,但是我想如果你正在遷移一個企業類型的應用程式,那麼很多HttpContext.Current會圍繞這個業務邏輯,它可能會提供一些暫時的緩解移 ...
  • 介紹一種取下拉框值以及綁定下拉框數據的方法 這裡用到的jquery-ui-multiselect插件 1、前臺html代碼 2、獲取值js代碼 3、後臺取值賦值代碼 //品類 if (hid_Cartype.Value == "") //將文本值放入lable控制項顯示 x_lb_Cartype.Vi ...
  • 只作為個人學習筆記。 ...
  • 索引 NET Core應用框架之BitAdminCore框架應用篇系列 框架演示:http://bit.bitdao.cn 框架源碼:https://github.com/chenyinxin/cookiecutter-bitadmin-core 20180531更新內容 本次更新內容如下: 一、將 ...
  • 閑來沒事,想做一個仿QQ登陸註冊的winform,於是利用工作之餘,根據自己的掌握和查閱的資料,歷時4天修改完成,新手水平,希望和大家共同學習進步,有不同見解希望提出! 廢話不多說,進入正題: 先來看看我繪製的界面: 運用的CSkin控制項完成的繪製,cskin和vs自帶的控制項其實差別不大,只是csk ...
  • BarcodeView控制項 一、 樣式一 我們要實現上圖中的效果,需要如下的操作: 設置控制項類型,將BarcodeFormat屬性設置為“QRCode”,讓控制項顯示為二維碼,如圖1; 圖 1設置界面 若將BarcodeFormat屬性設置為“Code128”,控制項則會顯示為一維碼,如圖2、圖3。 圖 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...