C#仿QQ皮肤----基窗体FormBase与基用户控件FormBase1的实现

C# 实现简易QQ界面 做了一个简易的QQ界面 1 功能:点击 我的好友会出现好友列表      点击 QQ群会出现QQ群列表                 点击   最近联系人 会出现联系人列表                点击   右上方的叉叉 就能关闭了 实现步骤 把窗口的FormBorderStyle设置为none 再把背景图片设置为QQ界面 然后拖一个panel到窗口中 再拖3个 阅读详情

   C#仿QQ皮肤-实现原理系列文章导航
                                                              http://www.cnblogs.com/sufei/archive/2010/03/10/1682847.html                                                  

 

      哎,这两个项目有点紧把文章给荒废了,这周努力一把多出两篇吧!

上次说到 把总体层次的说完了 http://www.cnblogs.com/sufei/archive/2010/03/20/1690624.html  ,接下来就应该细细的说说是怎么实现的了,今天的主要是分析一下基窗体FormBase与基用户控件FormBase1的实现

       前面我说过了这个窗体是为了实现添加修改等弹出窗体而设计的最常用的窗体之一,他在继承过后有一个固定的大小,是为了方便排版,如果所有窗体的大小都 不动的话正好跟主窗体配合是合适的,这个我是设计在程序里的,给不会排版的朋友以方便,当然您也是可以自己修改的,也就是说不管你怎么处理,只要是用我的控件就算是不做任何处理,也不是很难看,呵呵。

       因为我的每个窗体和控件可能都 会多多少少的用到不少Windows的API,特别是Windows消息这一块的,我把常用的放到了一下类里共享给大家吧,不过没有过多的注释,因为这些在网上都 有大家只要Google一下就OK了,哎,听说Google走了,那就Bing吧,呵呵

   类文件

代码
using  System;
using  System.Collections.Generic;

using  System.Text;
using  System.Runtime.InteropServices;
using  System.Drawing;
using  System.Globalization;

namespace  CRD.Common
{
    
public   static   class  Win32
    {
        
public   const   int  MF_REMOVE  =   0x1000 ;

        
public   const   int  SC_RESTORE  =   0xF120 ;  // 还原
         public   const   int  SC_MOVE  =   0xF010 ;  // 移动
         public   const   int  SC_SIZE  =   0xF000 ;  // 大小
         public   const   int  SC_MINIMIZE  =   0xF020 ;  // 最小化
         public   const   int  SC_MAXIMIZE  =   0xF030 ;  // 最大化
         public   const   int  SC_CLOSE  =   0xF060 ;  // 关闭 

        
public   const   int  WM_SYSCOMMAND  =   0x0112 ;
        
public   const   int  WM_COMMAND  =   0x0111 ;

        
public   const   int  GW_HWNDFIRST  =   0 ;
        
public   const   int  GW_HWNDLAST  =   1 ;
        
public   const   int  GW_HWNDNEXT  =   2 ;
        
public   const   int  GW_HWNDPREV  =   3 ;
        
public   const   int  GW_OWNER  =   4 ;
        
public   const   int  GW_CHILD  =   5 ;

        
public   const   int  WM_NCCALCSIZE  =   0x83 ;
        
public   const   int  WM_WINDOWPOSCHANGING  =   0x46 ;
        
public   const   int  WM_PAINT  =   0xF ;
        
public   const   int  WM_CREATE  =   0x1 ;
        
public   const   int  WM_NCCREATE  =   0x81 ;
        
public   const   int  WM_NCPAINT  =   0x85 ;
        
public   const   int  WM_PRINT  =   0x317 ;
        
public   const   int  WM_DESTROY  =   0x2 ;
        
public   const   int  WM_SHOWWINDOW  =   0x18 ;
        
public   const   int  WM_SHARED_MENU  =   0x1E2 ;
        
public   const   int  HC_ACTION  =   0 ;
        
public   const   int  WH_CALLWNDPROC  =   4 ;
        
public   const   int  GWL_WNDPROC  =   - 4 ;

        
public   const   int  WS_SYSMENU  =   0x80000 ;
        
public   const   int  WS_SIZEBOX  =   0x40000 ;

        
public   const   int  WS_MAXIMIZEBOX  =   0x10000 ;

        
public   const   int  WS_MINIMIZEBOX  =   0x20000 ;

        [DllImport(
" user32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern   int  SetWindowLong(IntPtr hWnd,  int  Index,  int  Value);

        [DllImport(
" user32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern   int  GetWindowLong(IntPtr hWnd,  int  Index);

        [DllImport(
" user32 " )]
        
public   static   extern  IntPtr GetSystemMenu(IntPtr hwnd,  int  flag);

        [DllImport(
" user32 " )]
        
public   static   extern   int  TrackPopupMenu( int  hMenu,  int  wFlags,  int  x,  int  y,  int  nReserved, IntPtr hwnd,  int  lprc);

        [DllImport(
" user32 " )]
        
public   static   extern   int  SendMessage(IntPtr hwnd,  int  msg,  int  wp,  int  lp);

        [DllImport(
" user32 " )]
        
public   static   extern   int  ReleaseCapture();

        [DllImport(
" gdi32.dll " )]
        
public   static   extern   int  CreateRoundRectRgn( int  x1,  int  y1,  int  x2,  int  y2,  int  x3,  int  y3);

        [DllImport(
" user32.dll " )]
        
public   static   extern   int  SetWindowRgn(IntPtr hwnd,  int  hRgn, Boolean bRedraw);

        
public   const   int  CS_DROPSHADOW  =   0x20000 ;

        [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);

        
public   struct  MENUINFO
        {
            
public   int  cbSize;
            
public   uint  fMask;
            
public   int  dwStyle;
            
public   int  cyMax;
            
public   int  hbrBack;
            
public   int  dwContextHelpID;
            
public   int  dwMenuData;
        }

        [DllImport(
" gdi32 " )]
        
public   static   extern   int  CreatePatternBrush( int  hBitmap);

        [DllImport(
" user32 " )]
        
public   static   extern   int  SetMenuInfo(IntPtr hMenu,  ref  MENUINFO mi);

        [DllImport(
" user32.dll " , EntryPoint  =   " ShowWindow " , CharSet  =  CharSet.Auto)]
        
public   static   extern   int  ShowWindow(IntPtr hwnd,  int  nCmdShow);

        [DllImport(
" kernel32.dll " )]
        
public   static   extern   bool  SetProcessWorkingSetSize(IntPtr process,  int  minSize,  int  maxSize);

        
public   const   int  GCW_ATOM  =   - 32 ;
        
public   const   int  GCL_CBCLSEXTRA  =   - 20 ;
        
public   const   int  GCL_CBWNDEXTRA  =   - 18 ;
        
public   const   int  GCL_HBRBACKGROUND  =   - 10 ;
        
public   const   int  GCL_HCURSOR  =   - 12 ;
        
public   const   int  GCL_HICON  =   - 14 ;
        
public   const   int  GCL_HMODULE  =   - 16 ;
        
public   const   int  GCL_MENUNAME  =   - 8 ;
        
public   const   int  GCL_STYLE  =   - 26 ;
        
public   const   int  GCL_WNDPROC  =   - 24 ;

        [DllImport(
" user32 " , EntryPoint  =   " GetClassLong " )]
        
public   static   extern   int  GetClassLong( int  hwnd,  int  nIndex);

        [DllImport(
" user32 " , EntryPoint  =   " SetClassLong " )]
        
public   static   extern   int  SetClassLong( int  hwnd,  int  nIndex,  int  dwNewLong);

        
public   const   int  WM_SETREDRAW  =   0x000B ;
        
public   const   int  WM_USER  =   0x400 ;
        
public   const   int  EM_GETEVENTMASK  =  (WM_USER  +   59 );
        
public   const   int  EM_SETEVENTMASK  =  (WM_USER  +   69 );

        [DllImport(
" user32.dll " )]
        
public   extern   static   bool  LockWindowUpdate(IntPtr hWndLock);

        [DllImport(
" User32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern  IntPtr GetWindowDC(IntPtr handle);

        [DllImport(
" User32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern  IntPtr ReleaseDC(IntPtr handle, IntPtr hDC);

        [DllImport(
" Gdi32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern  IntPtr CreateCompatibleDC(IntPtr hdc);

        [DllImport(
" User32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern   int  GetClassName(IntPtr hwnd,  char [] className,  int  maxCount);

        [DllImport(
" User32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern  IntPtr GetWindow(IntPtr hwnd,  int  uCmd);

        [DllImport(
" User32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern   bool  IsWindowVisible(IntPtr hwnd);

        [DllImport(
" user32 " , CharSet  =  CharSet.Auto)]
        
public   static   extern   int  GetClientRect(IntPtr hwnd,  ref  RECT lpRect);

        [DllImport(
" user32 " , CharSet  =  CharSet.Auto)]
        
public   static   extern   int  GetClientRect(IntPtr hwnd, [In, Out]  ref  Rectangle rect);

        [DllImport(
" user32 " , CharSet  =  CharSet.Auto)]
        
public   static   extern   bool  MoveWindow(IntPtr hwnd,  int  X,  int  Y,  int  nWidth,  int  nHeight,  bool  bRepaint);

        [DllImport(
" user32 " , CharSet  =  CharSet.Auto)]
        
public   static   extern   bool  UpdateWindow(IntPtr hwnd);

        [DllImport(
" user32 " , CharSet  =  CharSet.Auto)]
        
public   static   extern   bool  InvalidateRect(IntPtr hwnd,  ref  Rectangle rect,  bool  bErase);

        [DllImport(
" user32 " , CharSet  =  CharSet.Auto)]
        
public   static   extern   bool  ValidateRect(IntPtr hwnd,  ref  Rectangle rect);

        [DllImport(
" user32.dll " , CharSet  =  CharSet.Auto)]
        
public   static   extern   bool  GetWindowRect(IntPtr hWnd, [In, Out]  ref  Rectangle rect);

        [StructLayout(LayoutKind.Sequential)]
        
public   struct  RECT
        {
            
public   int  Left;
            
public   int  Top;
            
public   int  Right;
            
public   int  Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        
public   struct  WINDOWPOS
        {
            
public  IntPtr hwnd;
            
public  IntPtr hwndAfter;
            
public   int  x;
            
public   int  y;
            
public   int  cx;
            
public   int  cy;
            
public   uint  flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        
public   struct  NCCALCSIZE_PARAMS
        {
            
public  RECT rgc;
            
public  WINDOWPOS wndpos;
        }

        [StructLayout(LayoutKind.Sequential)]
        
public   struct  tagSCROLLINFO
        {
            
public   uint  cbSize;
            
public   uint  fMask;
            
public   int  nMin;
            
public   int  nMax;
            
public   uint  nPage;
            
public   int  nPos;
            
public   int  nTrackPos;
        }
        
public   enum  fnBar
        {
            SB_HORZ 
=   0 ,
            SB_VERT 
=   1 ,
            SB_CTL 
=   2
        }
        
public   enum  fMask
        {
            SIF_ALL,
            SIF_DISABLENOSCROLL 
=   0X0010 ,
            SIF_PAGE 
=   0X0002 ,
            SIF_POS 
=   0X0004 ,
            SIF_RANGE 
=   0X0001 ,
            SIF_TRACKPOS 
=   0X0008
        }

        
public   static   int  MakeLong( short  lowPart,  short  highPart)
        {
            
return  ( int )((( ushort )lowPart)  |  ( uint )(highPart  <<   16 ));
        }
        
public   const   int  SB_THUMBTRACK  =   5 ;
        
public   const   int  WM_HSCROLL  =   0x114 ;
        
public   const   int  WM_VSCROLL  =   0x115 ;
        [DllImport(
" user32.dll " , EntryPoint  =   " GetScrollInfo " )]
        
public   static   extern   bool  GetScrollInfo(IntPtr hwnd,  int  fnBar,  ref  SCROLLINFO lpsi);
        [DllImport(
" user32.dll " , EntryPoint  =   " SetScrollInfo " )]
        
public   static   extern   int  SetScrollInfo(IntPtr hwnd,  int  fnBar, [In]  ref  SCROLLINFO lpsi,  bool  fRedraw);

        [DllImport(
" User32.dll " , CharSet  =  CharSet.Auto, EntryPoint  =   " SendMessage " )]
        
static   extern  IntPtr SendMessage(IntPtr hWnd,  uint  Msg, IntPtr wParam, IntPtr lParam);
        [DllImport(
" user32.dll " , SetLastError  =   true )]
        
public   static   extern   bool  PostMessage(IntPtr hWnd,  uint  Msg,  long  wParam,  int  lParam);

        
public   struct  SCROLLINFO
        {
            
public   uint  cbSize;
            
public   uint  fMask;
            
public   int  nMin;
            
public   int  nMax;
            
public   uint  nPage;
            
public   int  nPos;
            
public   int  nTrackPos;
        }

        
public   enum  ScrollInfoMask
        {
            SIF_RANGE 
=   0x1 ,
            SIF_PAGE 
=   0x2 ,
            SIF_POS 
=   0x4 ,
            SIF_DISABLENOSCROLL 
=   0x8 ,
            SIF_TRACKPOS 
=   0x10 ,
            SIF_ALL 
=  SIF_RANGE  +  SIF_PAGE  +  SIF_POS  +  SIF_TRACKPOS
        }

        
public   enum  ScrollBarDirection
        {
            SB_HORZ 
=   0 ,
            SB_VERT 
=   1 ,
            SB_CTL 
=   2 ,
            SB_BOTH 
=   3
        }

        [DllImport(
" user32.dll " , CharSet  =  CharSet.Auto, ExactSpelling  =   true )]
        
public   static   extern   bool  GetClientRect(HandleRef hWnd, [In, Out]  ref  RECT rect);


        [StructLayout(LayoutKind.Sequential)]
        
public   class  SYSTEMTIME
        {
            
public   short  wYear;
            
public   short  wMonth;
            
public   short  wDayOfWeek;
            
public   short  wDay;
            
public   short  wHour;
            
public   short  wMinute;
            
public   short  wSecond;
            
public   short  wMilliseconds;
            
public   override   string  ToString()
            {
                
return  ( " [SYSTEMTIME:  "   +   this .wDay.ToString(CultureInfo.InvariantCulture)  +   " / "   +   this .wMonth.ToString(CultureInfo.InvariantCulture)  +   " / "   +   this .wYear.ToString(CultureInfo.InvariantCulture)  +   "   "   +   this .wHour.ToString(CultureInfo.InvariantCulture)  +   " : "   +   this .wMinute.ToString(CultureInfo.InvariantCulture)  +   " : "   +   this .wSecond.ToString(CultureInfo.InvariantCulture)  +   " ] " );
            }
        }

        [StructLayout(LayoutKind.Sequential, CharSet 
=  CharSet.Auto)]
        
public   class  SYSTEMTIMEARRAY
        {
            
public   short  wYear1;
            
public   short  wMonth1;
            
public   short  wDayOfWeek1;
            
public   short  wDay1;
            
public   short  wHour1;
            
public   short  wMinute1;
            
public   short  wSecond1;
            
public   short  wMilliseconds1;
            
public   short  wYear2;
            
public   short  wMonth2;
            
public   short  wDayOfWeek2;
            
public   short  wDay2;
            
public   short  wHour2;
            
public   short  wMinute2;
            
public   short  wSecond2;
            
public   short  wMilliseconds2;
        }
    }
}

 

  这个类的使用方法其实很简单,大家看下下面的代码就明白了

 

 Win32.SetWindowLong( this .Handle,  - 16 , Win32.WS_SYSMENU  +  Win32.WS_SIZEBOX  +  Win32.WS_MAXIMIZEBOX  +  Win32.WS_MINIMIZEBOX);

 

  其实说白了就是一个实体类,呵呵Win32.WS_SYSMENU 这样就行了。

       下面开始一步一步的来实现吧

 第一步.先建一个名称为FormBase的窗体,这个过程相信没有人不会吧,我就不写了;

 第二步.把窗体变为无边框并且设置其大小为580, 364,我把要修改的属性一一的罗列一下吧!!!

就只有这几个属性需要修改一下,别的都 是默认的就行了;

     第三步.我们来处理一下我们要定义这样几个变量,是处理加载窗体是默认皮肤的

 

代码
  // 默认的肤色 这是一个枚举
         private  SkinColor _currentSkinColor  =  SkinColor.Default;

        
// 设置窗体无边框
         private  FormBorderStyle _formBorderStyle  =  FormBorderStyle.None;

        
// 得到一个值表示 是否重绘
         private   bool  _isRedrawSuspended;

        
// 当前应用的皮肤
         public  SkinColor CurrentSkinColor
        {
            
get  {  return  _currentSkinColor; }
            
set  { _currentSkinColor  =  value; }
        }

 

 

    第一行是取得系统默认的皮肤;

    第二行是设置窗体无边框的这个咱们已经用属性设置过了, 我是不放心才写了一下,呵呵大家可以只写代码的;

    第三行是定义一个变量指示是否要重绘;

    第四行的是定义当前皮肤属性,方便取和设置;

第四步,FormBorderStyle和FormBorderStyle这个两属性我们需要定义一下

    因为我们的窗体是无边框的所以FormBorderStyle这个属性我们也不希望能被使用都随时改变,可能为影响美难,所以我在这里禁止使用,也 就是说不让它出现在

属性窗体中,这个是怎么设置的呢,其实Ms做的很文件,只要一行代码就可以了

   

代码
// 指定方法或是属性是否可以在编辑器中查看Never始终不能,Always始终是可以的,Advanced只有高级用户才能查看
        [EditorBrowsable(EditorBrowsableState.Never)]
        
public   new  FormBorderStyle FormBorderStyle
        {
            
get  {  return   base .FormBorderStyle; }
            
set  {  base .FormBorderStyle  =  value; }
        }

 

   有了这几行代码我们不管怎么样改变窗体他都会是无标题的了,那我们怎么设置样式呢,别急看下面的代码

 

代码

 

有个这个属性我们不就能设置了吗?

好现在窗体的样式 基本上实现了

还有两个地方也要改一下不过是常用的大家看下代码吧

,重写OnLoad事件和OnResize事件

代码
  // 得到一个值表示 是否重绘
         public   bool  IsRedrawSuspended
        {
            
get  {  return  _isRedrawSuspended; }
        }

        
// 构造函数
         public  FormBase()
        {
            
this .SetStyle(ControlStyles.DoubleBuffer  |  ControlStyles.AllPaintingInWmPaint,  true );
            InitializeComponent();
        }

 

第五步

   为什么要重写呢,OnResize事件重写的目的是留出边框的大小,而OnLoad的重写是为了应用皮肤我处理一下消息

我都 写在了代码里下面是这个事件的代码

代码
// 重写的OnLoad事件
         protected   override   void  OnLoad(EventArgs e)
        {

            Win32.SetWindowLong(
this .Handle,  - 16 , Win32.WS_SYSMENU  +  Win32.WS_SIZEBOX  +  Win32.WS_MAXIMIZEBOX  +  Win32.WS_MINIMIZEBOX);

            
int  Rgn  =  Win32.CreateRoundRectRgn( 3 ,  3 ,  this .Width  -   2 ,  this .Height  -   2 ,  7 ,  7 );
            Win32.SetWindowRgn(
this .Handle, Rgn,  true );

            
this .PerformReSetFormBitmap();
            
base .OnLoad(e);

            
if  ( this != Shared.MainForm  &&   this .CurrentSkinColor  !=  Shared.CurrentSkinColor)
            {
                Shared.ChangeSkinColor(Shared.CurrentSkinColor, 
this ,  true );
            }
        }

        
// 重写的OnResize事件
         protected   override   void  OnResize(EventArgs e)
        {
            
base .OnResize(e);

            
int  Rgn  =  Win32.CreateRoundRectRgn( 3 ,  3 ,  this .Width  -   2 ,  this .Height  -   2 ,  7 ,  7 );
            Win32.SetWindowRgn(
this .Handle, Rgn,  true );

        }

 

第六步,设置窗体的图片

方法很简单,直接 看代码应该理我容易理解

代码
  // 设置用户控件的图片
         public   void  PerformReSetFormBitmap()
        {
            
try
            {
                
this .SuspendRedraw();

                ReSetFormBitmap();
            }
            
catch
            {
                
throw ;
            }
            
finally
            {
                
this .ResumeRedraw();
            }
        }

        
public   virtual   void  ReSetFormBitmap()
        {

        }

 

第七步,设置窗体背景

跟上面的实现 方法是一样的

代码
  // 设置用户控件背景
         public   void  PerformChangeBackgroundStripe(BackgroundStripe backgroundStripe)
        {
            
try
            {
                ChangeBackgroundStripe(backgroundStripe);
            }
            
catch
            {
                
throw ;
            }
            
finally
            {
                
this .ResumeRedraw();
            }
        }

        
public   virtual   void  ChangeBackgroundStripe(BackgroundStripe backgroundStripe)
        {
            
this .CurrentSkinColor  =  Shared.CurrentSkinColor;
        }

 

第七八步,设置的默认皮肤

跟上面的实现 方法是一样的,这三个实现方法是一样的,在这里不在多解释了

代码
  #region   // 设置皮肤色ChangeSkinColor


        
public   void  PerformChangeSkinColor()
        {
            PerformChangeSkinColor(SkinColor.Undefault);
        }

        
// 设置皮肤色
         public   void  PerformChangeSkinColor(SkinColor skinColor)
        {
            
try
            {
                
this .SuspendRedraw();

                ChangeSkinColor(skinColor);
            }
            
catch
            {
                
throw ;
            }
            
finally
            {
                
this .ResumeRedraw();
            }
        }

 

 

最后一步,就是当修改皮肤是我们要做什么了

  其实也不是很难的,只要调用一些方法就可以,大家如果 想知道 每个方法的意思 的话,可以自己转到定义去看, 当然在说到皮肤控件是我会一一说明 的

实现 代码

代码

 

这个实体基本上就是这样实现 的,FormBase跟窗体的实现 是一样的,只是在新建的时候创建的是用户控件,实现 的方法没有二样,

      有了这个窗体就为了们实现FunctionFormBase这个窗体打下了基础,下一次的文章我会接着说FunctionFormBase这个窗体的实现 也就是常用的添加,删除的小窗体,先看看效果吧!!!

 

 

效果就是这样的,

下面是这个窗体实现的所有代码

 

代码
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;

using  System.Text;
using  System.Windows.Forms;
using  System.IO;
using  CRD.Common;

namespace  CRD.WinUI.Forms
{
    
///   <summary>
    
///  常用的窗体之一,用于添加修改等弹出窗体
    
///   </summary>
     public   partial   class  FormBase : Form
    {
        
// 默认的肤色 这是一个枚举
         private  SkinColor _currentSkinColor  =  SkinColor.Default;

        
// 设置窗体无边框
         private  FormBorderStyle _formBorderStyle  =  FormBorderStyle.None;

        
// 得到一个值表示 是否重绘
         private   bool  _isRedrawSuspended;

        
// 当前应用的皮肤
         public  SkinColor CurrentSkinColor
        {
            
get  {  return  _currentSkinColor; }
            
set  { _currentSkinColor  =  value; }
        }

        
// 指定方法或是属性是否可以在编辑器中查看Never始终不能,Always始终是可以的,Advanced只有高级用户才能查看
        [EditorBrowsable(EditorBrowsableState.Never)]
        
public   new  FormBorderStyle FormBorderStyle
        {
            
get  {  return   base .FormBorderStyle; }
            
set  {  base .FormBorderStyle  =  value; }
        }

        
// 指定事件或是属性是否显示在属性窗口中
        
// [Browsable(false)]
        
// 指定事件或是属性是否显示在属性窗口中
        [Browsable( true )]
        
public  FormBorderStyle FormStyle
        {
            
get  {  return  _formBorderStyle; }
            
set  { _formBorderStyle  =  value; }
        }

        
// 得到一个值表示 是否重绘
         public   bool  IsRedrawSuspended
        {
            
get  {  return  _isRedrawSuspended; }
        }

        
// 构造函数
         public  FormBase()
        {
            
this .SetStyle(ControlStyles.DoubleBuffer  |  ControlStyles.AllPaintingInWmPaint,  true );
            InitializeComponent();
        }

        
// 重写的OnLoad事件
         protected   override   void  OnLoad(EventArgs e)
        {

            Win32.SetWindowLong(
this .Handle,  - 16 , Win32.WS_SYSMENU  +  Win32.WS_SIZEBOX  +  Win32.WS_MAXIMIZEBOX  +  Win32.WS_MINIMIZEBOX);

            
int  Rgn  =  Win32.CreateRoundRectRgn( 3 ,  3 ,  this .Width  -   2 ,  this .Height  -   2 ,  7 ,  7 );
            Win32.SetWindowRgn(
this .Handle, Rgn,  true );

            
this .PerformReSetFormBitmap();
            
base .OnLoad(e);

            
if  ( this != Shared.MainForm  &&   this .CurrentSkinColor  !=  Shared.CurrentSkinColor)
            {
                Shared.ChangeSkinColor(Shared.CurrentSkinColor, 
this ,  true );
            }
        }

        
// 重写的OnResize事件
         protected   override   void  OnResize(EventArgs e)
        {
            
base .OnResize(e);

            
int  Rgn  =  Win32.CreateRoundRectRgn( 3 ,  3 ,  this .Width  -   2 ,  this .Height  -   2 ,  7 ,  7 );
            Win32.SetWindowRgn(
this .Handle, Rgn,  true );

        }

        
#region    // 设置用户控件的图片ReSetFormBitmap

        
// 设置用户控件的图片
         public   void  PerformReSetFormBitmap()
        {
            
try
            {
                
this .SuspendRedraw();

                ReSetFormBitmap();
            }
            
catch
            {
                
throw ;
            }
            
finally
            {
                
this .ResumeRedraw();
            }
        }

        
public   virtual   void  ReSetFormBitmap()
        {

        }

        
#endregion

        
#region    // 设置用户控件背景ChangeBackgroundStripe

        
// 设置用户控件背景
         public   void  PerformChangeBackgroundStripe(BackgroundStripe backgroundStripe)
        {
            
try
            {
                ChangeBackgroundStripe(backgroundStripe);
            }
            
catch
            {
                
throw ;
            }
            
finally
            {
                
this .ResumeRedraw();
            }
        }

        
public   virtual   void  ChangeBackgroundStripe(BackgroundStripe backgroundStripe)
        {
            
this .CurrentSkinColor  =  Shared.CurrentSkinColor;
        }

        
#endregion

        
#region   // 设置皮肤色ChangeSkinColor


        
public   void  PerformChangeSkinColor()
        {
            PerformChangeSkinColor(SkinColor.Undefault);
        }

        
// 设置皮肤色
         public   void  PerformChangeSkinColor(SkinColor skinColor)
        {
            
try
            {
                
this .SuspendRedraw();

                ChangeSkinColor(skinColor);
            }
            
catch
            {
                
throw ;
            }
            
finally
            {
                
this .ResumeRedraw();
            }
        }

        
// 修改皮肤色时
         public   virtual   void  ChangeSkinColor(SkinColor skinColor)
        {
            
if  ( this .CurrentSkinColor  !=  skinColor)
            {
                
this .ReSetFormBitmap();
                
if  (skinColor  !=  SkinColor.Undefault)
                {
                    Shared.ChangeSkinColor(skinColor, 
this );
                }
            }
            
else
            {
                
this .ReSetFormBitmap();
                Shared.ChangeControlsSkinColor(
this );
            }
            
this .CurrentSkinColor  =  Shared.CurrentSkinColor;
        }

        
#endregion

        
#region  Suspend / Resume Controls Painting
        
public   void  SuspendRedraw()
        {
            _isRedrawSuspended 
=   true ;
            SuspendRedraw(
this );
        }

        
public   void  SuspendRedraw(Control control)
        {
            
if  (DesignMode)  return ;
        }

        
public   void  ResumeRedraw()
        {
            _isRedrawSuspended 
=   false ;

            ResumeRedraw(
this );
        }

        
public   void  ResumeRedraw(Control control)
        {
            
if  (DesignMode)  return ;
        }

        
public   void  LockWindowUpdate( bool  lockUpdate)
        {
            Shared.LockWindowUpdate(
this , lockUpdate);
        }
        
#endregion

    }
}

 

 

                         

                              如有转载请注明出处谢谢合作!!!

签名:做一番一生引以为豪的事业;找一个一生荣辱与共的妻子;在有生之年报答帮过我的人;并有能力帮助需要帮助的人;

C#实现的窗体基本框架 立即下载

相关推荐

【零基础入门哈希签名架构,从Lamport到SPHINCS+】第二集 哈希签名树 Merkle Tree Authentication

在第一集中,我们一直忽略了一个问题。设想一下,假如有一个Hacker(黑客),在截获到Sender发送给Receiver的公钥之后,把这个公钥改成Hacker自己的公钥,然后再发给Receiver,那么Receiver就会误认为这是Sender的公钥。所以我们之前所说放方案,其安全性都需要建立在一个前提下:Receiver需要确认公钥确实是Sender发出的。

m0_50572808的博客 2452

C#仿QQ皮肤-皮肤控件窗体SkinForm的实现

    原文:http://www.sufeinet.com/thread-1950-1-1.html 可以下载源码 导读部分 ------------------------------------------------------------------------------------------------------------- C#仿QQ皮肤-实现原理系列文章导航 最新版源...

weixin_33919950的博客 208

STM32开发者必看:如何在正点原子探索者开发板上快速移植CANopenNode协议栈

本文为STM32开发者提供了在正点原子探索者开发板上快速移植CANopenNode协议栈的实战指南。文章详细介绍了从环境准备、硬件抽象层适配到协议栈初始化与测试的全过程,并分享了PDO配置与性能优化等关键技巧,帮助开发者高效实现CANopen标准化通信。

weixin_29173777的博客 462

C#仿QQ皮肤-基窗体FunctionFormBase的实现

                                                     阅读全文:http://www.cckan.net/forum.php?mod=viewthread&amp;tid=363        导读部分-----------------------------------------------------------------------...

weixin_33755557的博客 149

Halcon实战:5分钟搞定线序颜色检测(附完整代码解析)

本文详细介绍了如何使用Halcon在5分钟内实现工业级线序颜色检测的高效方案。通过机器视觉技术,结合实战项目经验,提供完整的代码解析和优化技巧,帮助开发者快速构建鲁棒性强、准确率高的检测系统,适用于电子制造和汽车线束等行业。

weixin_29098367的博客 441

SAP中错记虚拟利润中心的调整,冲销处理实例

我非CO专业顾问。工作中遇到的问题,也会找资料,分析,测试。有时这个过程会拿到结果,解决问题。遂将过程记录下来备查。读者请谨慎参考!EC-PCA: 利润中心记账流程_9ke0-优快云博客。

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 1795

C# QQ管理系统——窗体版

功能要求 实现增删查功能 制作步骤介绍 创建主页面 创建查询页面 实现搜索功能 搜索功能进阶(判断非空) 实现右键菜单删除功能 新增功能页面 制作过程 一.主页面 详细步骤 将各类控件放入窗口,并修改摆放 双击 “确定” 按钮 在 “确定” 按钮内获取当前选择的按钮,并弹出对应的窗口 代码展示 private void button1_Click(object sender, EventArgs e) { if (rb_delete.Checked

YuStart的博客 655

历史预测+LLM双杀!DriveGPT4-V2闭环驾驶配置避坑指南

本文深入探讨了DriveGPT4-V2在工程化部署中的核心挑战与解决方案。通过融合历史轨迹预测与大语言模型,该模型旨在实现更可靠的端到端自动驾驶。文章详细解析了从环境配置、多模态Token对齐、轻量控制头设计到训练优化与闭环仿真验证的全流程,为开发者提供了一份详实的避坑指南。

transformer2023的博客 383

C#仿QQ皮肤-常用用户控件EnterFrom1和窗体EntryForm的实现

  导读部分 ------------------------------------------------------------------------------------------------------------- C#仿QQ皮肤-实现原理系列文章导航 最新版源码下载 http://www.cckan.net/thread-2-1-1.html  ...

weixin_30445169的博客 101

物联网开发笔记(34)- 使用Micropython开发ESP32开发板之控制步进电机(28BYJ-48)

使用Micropython开发ESP32开发板之控制步进电机(28BYJ-48)

zhusongziye的博客 1万+

如何给K8S配置一个具有永久有效的kubeconfig

在 Amazon EKS 环境中,Kubernetes 的认证机制与 AWS IAM 深度集成,通过aws-iam-authenticator动态生成临时凭证。这种设计虽然增强了安全性,但给需要持久化凭证的工具链(如 CI/CD 系统中的 KubeVela)带来了挑战。具体表现为:临时凭证失效​​:默认 Token 有效期为 15 分钟至 1 小时;​​IAM 角色限制​​:直接使用aws eks get-token生成的凭证无法持久化

小杨同学的博客 660

C#仿QQ皮肤-总体层次说明(一)

                                                                           C#仿QQ皮肤-实现原理系列文章导航                                                               http://www.cnblogs.com/sufei/archive/2010/03

sufeinet 1188

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

C#仿QQ皮肤-总体层次说明(二)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34122810的博客 71

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C# 高仿腾讯QQ (窗口皮肤美化)(附测试源码)

  首写这篇文章之前先跟大家说声抱歉,我很少写这方面的文章,所以一直不敢动手,之前的文章确实不带源的,因为当时只是想做为自己初次开发的记录过程,打算程序开发完后再来贴源的。不过从现在开始,我觉定还是把自己每次写的控件实例写出来,和大家一起探讨研究,这样也可增加自己学习经验。   在这里先跟大家说一下,由于我也是菜鸟型人物,C#、Winform完全是因为兴趣爱好而自学的,所以很不专业,里面的一些说...

weixin_30367169的博客 641

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

FormBase设置

Bestway.Windows.Forms.FormBase 1、样式一              2、样式二

快乐人生 1263

Form_base单点登录方法

登录系统的地址为http://tivoli04/WebConnect5.5/portal/windows/index.asp)1、 写一个fsso的文件,在安装路径底下有一个template:fsso.conf.t...

cuiliqian8980的博客 538
上一篇: C#仿QQ皮肤----基窗体FormBase与基用户控件FormBase1的实现
下一篇: 浅析C# WinForm控件开发前期准备
csdsuper
博客等级 码龄22年 35粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值