日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

如何设置Winform控件的ClientRectangle

發布時間:2025/4/16 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何设置Winform控件的ClientRectangle 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近學習制作WinForm控件,自己動手寫控件的時候才發現System.Windows.Forms.Control 竟然沒有提供默認的border繪制。記得以前用API做控件的時候,只需要設置空間窗口的WS_BORDER?風格就可以。遍尋無方,只有自己繪制了,這里有出現一個,如果border在客戶區,那么在OnPaint方法里不得不每次都要考慮Border所占用的區域,而且,如果從這個類派生的話,將無法獲得準確的客戶區。
????? 現在要解決的問題就是如何重新設置客戶區的矩形區域的尺寸,查看了一下Control類的ClientRectangle屬性:
public?Rectangle?ClientRectangle?{?get;?}是個只讀屬性,看來是不能通過這個屬性達到目的了。再查找Control類的文檔,也沒有這方面的說明,沒有辦法,只能用API搞定了。可以通過計算非客戶區尺寸來設置客戶區尺寸,Border在非客戶繪制。下面就是主要的代碼,就是通過重載WndProc方法,捕捉WM_NCCALCSIZE消息,實現自己的邏輯。
????? protected?override?void?WndProc(ref?Message?m)
{
switch?(m.Msg)
{
case?(int)WinAPI_WM.WM_NCCALCSIZE:
if?(m.WParam.ToInt32()?==?0)
{
WinAPI_RECT?rc?
=?(WinAPI_RECT)m.GetLParam(typeof(WinAPI_RECT));
rc.Left?
+=?1;
rc.Top?
+=?1;?
rc.Right?
-=?1;?
rc.Bottom?
-=?1;
Marshal.StructureToPtr(rc,?m.LParam,?
true);
m.Result?
=?IntPtr.Zero;
}

else
{
WinAPI_NCCALCSIZE_PARAMS?csp;
csp?
=?(WinAPI_NCCALCSIZE_PARAMS)m.GetLParam(typeof(WinAPI_NCCALCSIZE_PARAMS));
csp.rgrc0.Top?
+=?1;?
csp.rgrc0.Bottom?
-=?1;
csp.rgrc0.Left?
+=?1;?
csp.rgrc0.Right?
-=?1;

Marshal.StructureToPtr(csp,?m.LParam,?
true);
//Return?zero?to?preserve?client?rectangle
m.Result?=?IntPtr.Zero;
}

break;
case?(int)WinAPI_WM.WM_NCPAINT:
{
m.WParam?
=?NCPaint(m.WParam);
break;
}

}


base.WndProc(ref?m);
}


public?IntPtr?NCPaint(IntPtr?region)
{
IntPtr?hDC?
=?GetWindowDC(this.Handle);
if?(hDC?!=?IntPtr.Zero)
{
Graphics?grTemp?
=?Graphics.FromHdc(hDC);

int?ScrollBarWidth?=?SystemInformation.VerticalScrollBarWidth;
int?ScrollBarHeight?=?SystemInformation.HorizontalScrollBarHeight;

WINDOWINFO?wi?
=?new?WINDOWINFO();
wi.cbSize?
=?(uint)Marshal.SizeOf(wi);

//得到當前控件的窗口信息
GetWindowInfo(Handle,?ref?wi);

wi.rcClient.Right
--;
wi.rcClient.Bottom
--;


//獲得當前控件的區域
Region?UpdateRegion?=?new?Region(new?Rectangle(wi.rcWindow.Top,wi.rcWindow.Left,wi.rcWindow.Right-wi.rcWindow.Left,wi.rcWindow.Bottom-wi.rcWindow.Top));

//獲得客戶區以外的區域
UpdateRegion.Exclude(new?Rectangle(wi.rcClient.Top,?wi.rcClient.Left,?wi.rcClient.Right?-?wi.rcClient.Left,?wi.rcClient.Bottom?-?wi.rcClient.Top));

if?(IsHScrollVisible?&&?IsVScrollVisible)
{
UpdateRegion.Exclude(Rectangle.FromLTRB
(wi.rcClient.Right?
+?1,?wi.rcClient.Bottom?+?1,
wi.rcWindow.Right,?wi.rcWindow.Bottom));
}


//得到當前區域的句柄
IntPtr?hRgn?=?UpdateRegion.GetHrgn(grTemp);

//For?Painting?we?need?to?zero?offset?the?Rectangles.
Rectangle?WindowRect?=?new?Rectangle(wi.rcWindow.Top,?wi.rcWindow.Left,?wi.rcWindow.Right?-?wi.rcWindow.Left,?wi.rcWindow.Bottom?-?wi.rcWindow.Top);

Point?offset?
=?Point.Empty?-?(Size)WindowRect.Location;

WindowRect.Offset(offset);

Rectangle?ClientRect?
=?WindowRect;

ClientRect.Inflate(
-1,?-1);

//Fill?the?BorderArea
Region?PaintRegion?=?new?Region(WindowRect);
PaintRegion.Exclude(ClientRect);
grTemp.FillRegion(SystemBrushes.Control,?PaintRegion);

//Fill?the?Area?between?the?scrollbars
if?(IsHScrollVisible?&&?IsVScrollVisible)
{
Rectangle?ScrollRect?
=?new?Rectangle(ClientRect.Right?-?ScrollBarWidth,
ClientRect.Bottom?
-?ScrollBarHeight,?ScrollBarWidth?+?2,?ScrollBarHeight?+?2);
ScrollRect.Offset(
-1,?-1);
grTemp.FillRectangle(SystemBrushes.Control,?ScrollRect);
}


//Adjust?ClientRect?for?Drawing?Border.
ClientRect.Inflate(2,?2);
ClientRect.Width
--;
ClientRect.Height
--;

//Draw?Outer?Raised?Border
ControlPaint.DrawBorder3D(grTemp,?WindowRect,?Border3DStyle.Raised,
Border3DSide.Bottom?
|?Border3DSide.Left?|?Border3DSide.Right?|?Border3DSide.Top);

//Draw?Inner?Sunken?Border
ControlPaint.DrawBorder3D(grTemp,?ClientRect,?Border3DStyle.Sunken,
Border3DSide.Bottom?
|?Border3DSide.Left?|?Border3DSide.Right?|?Border3DSide.Top);

ReleaseDC(Handle,?hDC);

grTemp.Dispose();

return?hRgn;

}


RefreshScrollBar();
return?region;
}


轉載于:https://www.cnblogs.com/guanjinke/archive/2006/11/29/576961.html

總結

以上是生活随笔為你收集整理的如何设置Winform控件的ClientRectangle的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。