回答
實現此目的的正確方法是將消息處理程序處理程序(例如,通過重寫Form.WndProc
)添加到窗體並處理消息WM_NCHITTEST
。 (您可以在PInvoke.net上找到該消息的C#定義)特別是,當您收到消息時,計算命中測試是否針對指定調整大小的區域中的點,如果是,則返回HTBOTTOMRIGHT。默認的窗口過程會爲你完成剩下的工作,因爲它假設用戶點擊了窗口邊界的右下角,即使你的窗口沒有邊框。
這個問題需要一點點的Win32 interop,但它會使你的調整大小看起來像其他任何窗口調整大小。
最簡單的方法是按@benPearce的說法,在面板的角落放置一個面板,並使用寬度/高度調整窗體大小。它會起作用,但調整大小不會一帆風順,特別是在Vista和Win7 Basic中,在標準移動和重新調整大小時完全重繪被禁用,而每一步都將嘗試重繪。
更新:在這兩種方法中,您將不得不弄清楚如何繪製抓手。例如,您可以放置標準抓手的位圖。儘管如此,由於您的表單沒有標題和邊框,因此您不一定會使用標準的Windows視覺效果,您可能會選擇更快捷的方式。
更新2:如果您有一個覆蓋整個窗口的控件,它將吃掉表單鼠標消息。你必須以某種方式剪輯你想用來調整大小的地方。您有幾種選擇來處理這個:
- 調整控制,使尺寸調整握一些空間。
- 調整控制區域(通過Region屬性)以排除調整大小的控制點。
- 覆蓋調整大小控制面板,聽取它的MouseEnter消息,並將Capture屬性設置爲true,這將導致所有更多的鼠標消息到達它。 注意:調整大小完成後,鼠標離開該區域後,您將不得不釋放捕獲。
我會推薦去選擇最簡單的選項1。選項3是最複雜的,需要關於鼠標輸入在Windows中的工作方式的詳細信息,所以我不會推薦它。選項2是選項1的一個很好的選擇,但您必須嘗試查看ListView控件如何對其區域進行調整。
非常感謝,這對於靜態表單非常有用。但是我的表單包含一個填充表單的列表視圖。沒有WM_NCHITTEST消息被激發。 – 2009-10-08 06:41:38
任何人都在尋找如何繪製抓手,'ControlPaint.DrawSizeGrip'是一個開始。 – AnotherUser 2014-07-02 11:23:38
下面是與Franci的解釋相對應的代碼,我正在寫它,但他同時回答了他的解釋,如果這段代碼適合您的需求,那麼這是很好的解決辦法。
protected override void WndProc(ref Message m) {
const int wmNcHitTest = 0x84;
const int htBottomLeft = 16;
const int htBottomRight = 17;
if (m.Msg == wmNcHitTest) {
int x = (int) (m.LParam.ToInt64() & 0xFFFF);
int y = (int) ((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
Point pt = PointToClient(new Point(x, y));
Size clientSize = ClientSize;
if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16) {
m.Result = (IntPtr) (IsMirrored ? htBottomLeft : htBottomRight);
return;
}
}
base.WndProc(ref m);
}
編輯:寫夾子,你可以初始化一個new VisualStyleRenderer(VisualStyleElement.Status.Gripper.Normal)
並使用其PaintBackground()
方法。
有關繪製抓手的更多說明,請參閱http://stackoverflow.com/a/4918111/161052 – JYelton 2012-11-28 20:54:55
非常感謝發佈這個偉大的樣本和解釋。我在下面添加了一些其他代碼可能會感興趣的附加內容。這裏的一些代碼來自其他stackoverflow帖子,但爲了能夠在一個代碼塊中看到它,可能會對其他人有所幫助。 我希望能夠調整窗體的大小,而不僅僅是右下角。我也想能夠拖動表格。最後,我想要一個陰影。
//***********************************************************
//This gives us the ability to resize the borderless from any borders instead of just the lower right corner
protected override void WndProc(ref Message m)
{
const int wmNcHitTest = 0x84;
const int htLeft = 10;
const int htRight = 11;
const int htTop = 12;
const int htTopLeft = 13;
const int htTopRight = 14;
const int htBottom = 15;
const int htBottomLeft = 16;
const int htBottomRight = 17;
if (m.Msg == wmNcHitTest)
{
int x = (int)(m.LParam.ToInt64() & 0xFFFF);
int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
Point pt = PointToClient(new Point(x, y));
Size clientSize = ClientSize;
///allow resize on the lower right corner
if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htBottomLeft : htBottomRight);
return;
}
///allow resize on the lower left corner
if (pt.X <= 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htBottomRight : htBottomLeft);
return;
}
///allow resize on the upper right corner
if (pt.X <= 16 && pt.Y <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htTopRight : htTopLeft);
return;
}
///allow resize on the upper left corner
if (pt.X >= clientSize.Width - 16 && pt.Y <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(IsMirrored ? htTopLeft : htTopRight);
return;
}
///allow resize on the top border
if (pt.Y <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htTop);
return;
}
///allow resize on the bottom border
if (pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htBottom);
return;
}
///allow resize on the left border
if (pt.X <= 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htLeft);
return;
}
///allow resize on the right border
if (pt.X >= clientSize.Width - 16 && clientSize.Height >= 16)
{
m.Result = (IntPtr)(htRight);
return;
}
}
base.WndProc(ref m);
}
//***********************************************************
//***********************************************************
//This gives us the ability to drag the borderless form to a new location
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
private void YOURCONTROL_MouseDown(object sender, MouseEventArgs e)
{
//ctrl-leftclick anywhere on the control to drag the form to a new location
if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Control)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
//***********************************************************
//***********************************************************
//This gives us the drop shadow behind the borderless form
private const int CS_DROPSHADOW = 0x20000;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
//***********************************************************
- 1. WPF無邊界窗口調整大小
- 2. 調整邊界不窗口在WPF
- 3. 右下角的Tkinter窗口
- 4. 如何從頂部調整無邊界窗口的大小?
- 5. 使用SDL2調整無邊界窗口時的問題
- 6. 無邊界窗口monogame
- 7. CEF 3無邊界窗口
- 8. Eclipse 4 - 無邊界窗口
- 9. 在德爾福的無邊界窗體/窗口中平滑調整大小
- 10. 右下角的分機窗口
- 11. 屏幕右下角的位置窗口
- 12. Silverlight窗口邊界
- 13. Linux上的無邊界窗口
- 14. WPF無邊界窗口的DropShadow
- 15. 可移動的WPF無邊界窗口
- 16. 如何繪製彎曲邊界的右下角三角形?
- 17. 當小窗口白色塊右下角
- 18. 任何下降WPF自定義窗口主題,沒有邊界透明,調整模擬邊界的大小?
- 19. 在Qt主窗口的右下角放置彈出窗口
- 20. pygame中的窗口邊界
- 21. 更改窗口的邊界
- 22. 當窗口大小調整時容器不響應 - 在右邊留下空白
- 23. 無邊界窗口全功能
- 24. 在wpf中移動無邊界窗口
- 25. 無邊界wpf窗口行爲.net 3.5
- 26. 無邊界窗口帶陰影和blurbehind
- 27. 如何使QML窗口無邊界?
- 28. 如何通過調整大小窗口將圖像修復到右下角?
- 29. Qt的:調整無邊界插件
- 30. 右對齊調整窗口大小
發表了一些代碼。您可以通過更改控件的寬度和高度來調整大小。 – 2009-10-08 05:50:52
由於Andrew Keith的評論,修改了問題並添加了截圖的鏈接:用戶應該能夠調整表單的大小。 – 2009-10-08 05:59:21
使用面板查看我的解決方案:http://stackoverflow.com/a/8848440/640781 – edid 2012-01-13 09:42:07