我正在尝试制作从工具栏中弹出的无边框表单.我希望用户能够抓住右下角("调整大小句柄")并能够调整表单大小,但无法以任何其他方式调整表单大小或重新定位.
我听说我可以拦截WM_NCHITTEST发送到表单的消息,并设置其结果HTBOTTOMRIGHT,让操作系统处理重新调整表单的大小,就像它有一个相当大的框架一样.我的想法是检测鼠标指针是否已进入我在角落中定义的框,如果它已经,则返回HTBOTTOMRIGHT结果.

这并不像我预期的那样有效.我能够拦截消息,但似乎只有当用户将鼠标光标放在窗体的1px粗边框上时才会发送消息.这意味着它可以按照我想要的方式工作,如果你将光标精确地放在右下角的边缘上.
这是我的WndProc覆盖:
protected override void WndProc(ref Message m)
{
const UInt32 WM_NCHITTEST = 0x0084;
const UInt32 HTBOTTOMRIGHT = 17;
const int RESIZE_HANDLE_SIZE = 40;
bool handled = false;
if (m.Msg == WM_NCHITTEST)
{
Size formSize = this.Size;
Point screenPoint = new Point(m.LParam.ToInt32());
Point clientPoint = this.PointToClient(screenPoint);
Rectangle hitBox = new Rectangle(formSize.Width - RESIZE_HANDLE_SIZE, formSize.Height - RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE);
if (hitBox.Contains(clientPoint))
{
m.Result = (IntPtr)HTBOTTOMRIGHT;
handled = true;
}
}
if …Run Code Online (Sandbox Code Playgroud) 这是一个奇怪的.我有一个DataGridView.我正在设置我自己的自定义类DataSource的List包含对象.列表中大约有50,000个项目.我定义了我希望在Designer中可见的所有列,并设置AutoGenerateColumns为false.
一旦我设置DataSource到我的列表,它会立即正确填充.我可以上下滚动,选择不同的行.一切都是好的.但是当我一直向下滚动然后让包含DataGridView失去焦点的窗口时,一切都冻结了,过了一会儿,堆栈就会溢出:
System.Drawing.dll!System.Drawing.SafeNativeMethods.Gdip.GdipDeleteGraphics(System.Runtime.InteropServices.HandleRef graphics) + 0x2a bytes
System.Drawing.dll!System.Drawing.Graphics.Dispose(bool disposing) + 0x56 bytes
System.Drawing.dll!System.Drawing.Graphics.Dispose() + 0x12 bytes
System.Drawing.dll!System.Drawing.Font.GetHeight() + 0xc8 bytes
System.Drawing.dll!System.Drawing.Font.Height.get() + 0xb bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRow() + 0x44 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.Clone() + 0x44 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRowCollection.this[int].get(int index) + 0xa8 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridView.DataGridViewAccessibleObject.GetChild(int index) + 0xbd bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x76 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes
System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + …Run Code Online (Sandbox Code Playgroud) 我可能会犯这个错误,但我被困住了.我有一个GUI应用程序,它产生一个单独的线程,从服务器下载一堆数据.当这个下载线程完成时,我希望它向主线程发送一个信号,以便它知道它现在可以显示下载的数据.
我已经尝试调用Invoke(从我的主窗体)调用委托来进行显示工作,但这会阻止我的下载程序线程直到完成.我有点想在没有EndInvoke的情况下做一个BeginInvoke,但我知道它不适合这样做.