界面开发(四)--- 还窗体的新面貌

     前一篇给窗体设置了Region,将窗体的FormBorderStyle设置成了None,然后修改了窗体的显示区域Region。一个本来完好的窗体让我们设置成为了一个空白的没有任何色彩的窗体,这对我们的界面开发好像是背到而行,有点南辕北辙了。其实不然,只有将窗体上的所有原有的信息给去除掉,才能还原窗体的本来面貌,给窗体一个新面貌。

     这篇就对窗体的界面开发设计一个新面貌。

     我在界面开篇的开篇就已经说过,界面开发其实就是修改窗体的两个区域,Client Area和None Client Area,如下图:

    

     而我们现在已经将窗体修改成了没有任何信息的窗体,如下图:

    

     现在我们要做的,就是在这个什么都没有的图上添加上我们自己的界面,将窗体的Client Area和None Client Area从新绘制让其有新的面貌。而他的绘制确实需要很多的GDI+知识。

     Client Area的绘画很简单,主要就是对窗体的背景色进行修改,这个对于C#开发人员就是一句话的事情,设置窗体的背景色就可以了。代码如下:

this._parentForm.BackColor = this._engine.SkinColor.Back;

 

     但是,对于None Client Area的绘画就比较麻烦,他不仅仅画的是颜色,还有窗体的标题栏、最大化、最小化、关闭按钮、窗体图标和窗体的边框,接下来就是一一对窗体的进行绘画。

     窗体的标题栏分为两大部分:窗体的图标和窗体的标题,绘画这些的第一步都是对窗体的绘画区域的设置。找到绘画的区域,然后使用GDI+进行绘画,具体的过程就是这样,代码如下:

#region NcPaint
/// <summary>
/// NcPaint
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
private bool NcPaint(SkinningForm form, SkinEngine engine)
{
    
// Declared Filed
    bool result = true;
    IntPtr hdc 
= (IntPtr)0;
    Graphics g 
= null;
    Region region 
= null;
    IntPtr hrgn 
= (IntPtr)0;

    
try
    {
        
// Get Rect
        RECT rectScreen = new RECT();
        NativeMethod.GetWindowRect(_parentForm.Handle, 
ref rectScreen);
        Rectangle rectBounds 
= rectScreen.ToRectangle();
        rectBounds.Offset(
-rectBounds.X, -rectBounds.Y);

        
// prepare clipping
        Rectangle rectClip = rectBounds;
        region 
= new Region(rectClip);
        rectClip.Inflate(
-engine.SkinAppearance.BorderWidth, -engine.SkinAppearance.BorderWidth);
        rectClip.Y 
+= engine.SkinAppearance.CaptionHeight;
        rectClip.Height 
-= engine.SkinAppearance.CaptionHeight;

        
// create graphics handle
        hdc = NativeMethod.GetDCEx(_parentForm.Handle, (IntPtr)0,
            (DCXFlags.DCX_CACHE 
| DCXFlags.DCX_CLIPSIBLINGS | DCXFlags.DCX_WINDOW));
        g 
= Graphics.FromHdc(hdc);

        
// Apply clipping
        region.Exclude(rectClip);
        hrgn 
= region.GetHrgn(g);
        NativeMethod.SelectClipRgn(hdc, hrgn);

        
if (_bufferGraphics == null || _currentCacheSize != rectBounds.Size)
        {
            
if (_bufferGraphics != null)
                _bufferGraphics.Dispose();

            _bufferGraphics 
= _bufferContext.Allocate(g, new Rectangle(00,
                        rectBounds.Width, rectBounds.Height));
            _currentCacheSize 
= rectBounds.Size;
        }

        
// Get Caption Bounds
        Rectangle captionBounds = rectBounds;
        captionBounds.Height 
= this._engine.SkinAppearance.BorderWidth + this._engine.SkinAppearance.CaptionHeight;

        
// Draw Caption
        engine.SkinAppearance.DrawCaptionBackground(g, captionBounds, this._formIsActive, this._engine);
        
// Draw Caption Icon
        if (this._parentForm.ShowIcon && this._parentForm.Icon != null)
        {
            DrawIcon(g);
        }
        
// Draw Caption Text
        DrawCaptionText(g, this._parentForm.Text, this._parentForm.Font);

        
// Draw Caption Button
        DrawCaptionControlBox(g);

        
// Draw Border
        engine.SkinAppearance.DrawBorder(g, rectBounds, engine);
    }
    
catch
    {
        result 
= false;
    }

    
// cleanup data
    if (hdc != (IntPtr)0)
    {
        NativeMethod.SelectClipRgn(hdc, (IntPtr)
0);
        NativeMethod.ReleaseDC(_parentForm.Handle, hdc);
    }
    
if (region != null && hrgn != (IntPtr)0)
        region.ReleaseHrgn(hrgn);

    
if (region != null)
        region.Dispose();

    
if (g != null)
        g.Dispose();
    
return result;
}
#endregion

 

      这个就完全绘制了窗体的边框。界面效果如下:

     

      代码下载地址:/Files/zhjp11/皮肤/SkinEngines20100324.rar

 

posted @ 2010-03-24 13:48 萧萧空间 阅读(...) 评论(...) 编辑 收藏