带底边框的文本框
TextBox with bottom border
我想让 TextBox
有底边框,但是为 TextBox
绘制的图形在调整大小时是 distorted/broken 因为 Color.Transparent
。
使用我找到的代码,我能够创建带下划线的文本框(顶部、左侧、右侧透明的绘制矩形)。问题是当我调整 form/window 的大小时:当我将它的大小调整到更小,然后再次调整大小以扩大它时,绘制的图形是扭曲的。 有什么解决办法吗?
照片如下:第二张照片已经缩小,然后又变大。
代码如下:
[DllImport("user32")]
private static extern IntPtr GetWindowDC(IntPtr hwnd);
struct RECT {
public int left, top, right, bottom;
}
struct NCCALSIZE_PARAMS {
public RECT newWindow;
public RECT oldWindow;
public RECT clientWindow;
IntPtr windowPos;
}
float clientPadding = 0;
int actualBorderWidth = 2;
Color borderColor = Color.Black;
protected override void WndProc(ref Message m) {
//We have to change the clientsize to make room for borders
//if not, the border is limited in how thick it is.
if (m.Msg == 0x83) { //WM_NCCALCSIZE
if (m.WParam == IntPtr.Zero) {
RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
rect.left += 2;
rect.right -= 2;
rect.top += 0;
rect.bottom -= 0;// (int)clientPadding;
Marshal.StructureToPtr(rect, m.LParam, false);
} else {
NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS));
rects.newWindow.left += (int)clientPadding;
rects.newWindow.right -= (int)clientPadding;
rects.newWindow.top += (int)clientPadding;
rects.newWindow.bottom -= 2;
Marshal.StructureToPtr(rects, m.LParam, false);
}
}
if (m.Msg == 0x85) {//WM_NCPAINT
IntPtr wDC = GetWindowDC(Handle);
using (Graphics g = Graphics.FromHdc(wDC)) {
ControlPaint.DrawBorder(g, new Rectangle(0, 0, Size.Width, Size.Height),
Color.Transparent, 1, ButtonBorderStyle.Solid,
Color.Transparent, 1, ButtonBorderStyle.Solid,
Color.Transparent, 1, ButtonBorderStyle.Solid,
borderColor, actualBorderWidth, ButtonBorderStyle.Solid);
}
return;
}
base.WndProc(ref m);
}
编辑:
我已经找到了问题,这是因为 Color.Transparent
我通过将其更改为 Color.White 来修复它,因为我有白色背景。但是,情况并非总是如此,我如何在使用 Color.Transparent 时防止 "Flickering/Tearing"?
要使 TextBox
具有底部边框,我可以提供的最简单的解决方法是将 1 像素高度的标签(或其他控件)停靠到 TextBox
的底部:
using System.Drawing;
using System.Windows.Forms;
public class MyTextBox : TextBox
{
public MyTextBox()
{
BorderStyle = System.Windows.Forms.BorderStyle.None;
AutoSize = false; //Allows you to change height to have bottom padding
Controls.Add(new Label()
{ Height = 1, Dock = DockStyle.Bottom, BackColor = Color.Black });
}
}
我想让 TextBox
有底边框,但是为 TextBox
绘制的图形在调整大小时是 distorted/broken 因为 Color.Transparent
。
使用我找到的代码,我能够创建带下划线的文本框(顶部、左侧、右侧透明的绘制矩形)。问题是当我调整 form/window 的大小时:当我将它的大小调整到更小,然后再次调整大小以扩大它时,绘制的图形是扭曲的。 有什么解决办法吗?
照片如下:第二张照片已经缩小,然后又变大。
代码如下:
[DllImport("user32")]
private static extern IntPtr GetWindowDC(IntPtr hwnd);
struct RECT {
public int left, top, right, bottom;
}
struct NCCALSIZE_PARAMS {
public RECT newWindow;
public RECT oldWindow;
public RECT clientWindow;
IntPtr windowPos;
}
float clientPadding = 0;
int actualBorderWidth = 2;
Color borderColor = Color.Black;
protected override void WndProc(ref Message m) {
//We have to change the clientsize to make room for borders
//if not, the border is limited in how thick it is.
if (m.Msg == 0x83) { //WM_NCCALCSIZE
if (m.WParam == IntPtr.Zero) {
RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
rect.left += 2;
rect.right -= 2;
rect.top += 0;
rect.bottom -= 0;// (int)clientPadding;
Marshal.StructureToPtr(rect, m.LParam, false);
} else {
NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS));
rects.newWindow.left += (int)clientPadding;
rects.newWindow.right -= (int)clientPadding;
rects.newWindow.top += (int)clientPadding;
rects.newWindow.bottom -= 2;
Marshal.StructureToPtr(rects, m.LParam, false);
}
}
if (m.Msg == 0x85) {//WM_NCPAINT
IntPtr wDC = GetWindowDC(Handle);
using (Graphics g = Graphics.FromHdc(wDC)) {
ControlPaint.DrawBorder(g, new Rectangle(0, 0, Size.Width, Size.Height),
Color.Transparent, 1, ButtonBorderStyle.Solid,
Color.Transparent, 1, ButtonBorderStyle.Solid,
Color.Transparent, 1, ButtonBorderStyle.Solid,
borderColor, actualBorderWidth, ButtonBorderStyle.Solid);
}
return;
}
base.WndProc(ref m);
}
编辑:
我已经找到了问题,这是因为Color.Transparent
我通过将其更改为 Color.White 来修复它,因为我有白色背景。但是,情况并非总是如此,我如何在使用 Color.Transparent 时防止 "Flickering/Tearing"?
要使 TextBox
具有底部边框,我可以提供的最简单的解决方法是将 1 像素高度的标签(或其他控件)停靠到 TextBox
的底部:
using System.Drawing;
using System.Windows.Forms;
public class MyTextBox : TextBox
{
public MyTextBox()
{
BorderStyle = System.Windows.Forms.BorderStyle.None;
AutoSize = false; //Allows you to change height to have bottom padding
Controls.Add(new Label()
{ Height = 1, Dock = DockStyle.Bottom, BackColor = Color.Black });
}
}