【发布时间】:2016-07-15 18:55:44
【问题描述】:
我想让TextBox 带有底部边框,但为TextBox 绘制的图形在调整大小时会因为Color.Transparent 而变形/损坏。
使用我找到的代码,我能够创建一个带下划线的文本框(绘制的矩形,顶部、左侧、右侧透明)。问题是当我调整窗体/窗口的大小时:当我将其调整为更小,然后再次调整大小以扩展它时,绘制的图形会失真。 有什么解决办法吗?
代码如下:
[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 时如何防止“闪烁/撕裂”?
【问题讨论】:
-
TextBox 不喜欢被画在上面;图形将立即消失,所有这些技巧只能起到很大的作用。你看到的效果被称为“撕裂”。你最好用标签和纯文本框创建一个真实的表单..
-
Winforms 并不真正支持透明度。 TextBox 根本不支持。
标签: c# winforms user-interface graphics window-resize