前一篇給窗體設置了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(0, 0,
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
這個就完全繪制了窗體的邊框。界面效果如下: