winform 无边框 窗体基本功能 拖动和系统右键菜单冲突

renyibin 2009-12-24 09:18:47
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using RightMenuItem;

namespace ClientFrom
{
public partial class Form12 : Form
{

private const int WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息
private const int WM_NCHITTEST = 0x0084;
private const int WM_NCMBUTTONDOWN = 0x00A7;
private const int WS_SYSMENU = 0x00080000; // 系统菜单
private const int WS_MINIMIZEBOX = 0x20000; // 最大最小化按钮
private const int SC_MAXIMIZE = 0xF030;//最大化信息
private const int SC_MINIMIZE = 0xF020;//最小化信息
private const int GWL_WNDPROC = -4;
private static int LEFT = 2, RIGHT = 2, BOTTOM = 2, TOP = 2, TITLE_WIDTH = 16;//边框和标题栏的大小
private int m_BorderWidth = 4;
private int m_CaptionHeight = 22;

[DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
public static extern int GetWindowLong(HandleRef hWnd, int nIndex);

[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll")]
private static extern int GetSystemMenu(int hwnd, int bRevert);

[DllImport("user32.dll")]
private static extern int AppendMenu(int hMenu, int Flagsw, int IDNewItem, string lpNewItem);

public Form12()
{
InitializeComponent();

//SetWindowLong(new HandleRef(this, this.Handle), -16, GetWindowLong(new HandleRef(this, this.Handle), -16) | WS_SYSMENU); //这里加上这段后 下面的case WM_NCHITTEST:就没反应了 请问这儿怎么写

}

#region WndProc

protected override void WndProc(ref Message m)
{

base.WndProc(ref m);
HandleRef hr = new HandleRef(this, m.HWnd);
switch (m.Msg)
{
case WM_SYSCOMMAND:
if (m.WParam == (IntPtr)SC_MAXIMIZE)
{
m.WParam = (IntPtr)SC_MINIMIZE;
}


break;

case WM_NCHITTEST:

if (m.Result == (IntPtr)HitTest.HTCLIENT)
{
m.HWnd = this.Handle;
Rectangle rect = this.Bounds;
Point vPoint = new Point((int)m.LParam & 0xFFFF, (int)m.LParam >> 16 & 0xFFFF);
vPoint = PointToClient(vPoint);
if (vPoint.X <= LEFT)
{
if (vPoint.Y <= TOP)
{
m.Result = (IntPtr)HitTest.HTTOPLEFT;
}
else if (vPoint.Y >= ClientSize.Height - BOTTOM)
{
m.Result = (IntPtr)HitTest.HTBOTTOMLEFT;
}
else
{
m.Result = (IntPtr)HitTest.HTLEFT;
}
}
else if (vPoint.X >= ClientSize.Width - RIGHT)
{
if (vPoint.Y <= TOP)
{
m.Result = (IntPtr)HitTest.HTTOPRIGHT;
}
else if (vPoint.Y >= ClientSize.Height - BOTTOM)
{
m.Result = (IntPtr)HitTest.HTBOTTOMRIGHT;
}
else
{
m.Result = (IntPtr)HitTest.HTRIGHT;
}
}
else if (vPoint.Y <= TOP)
{
m.Result = (IntPtr)HitTest.HTTOP;
}
else if (vPoint.Y >= ClientSize.Height - BOTTOM)
{
m.Result = (IntPtr)HitTest.HTBOTTOM;
}
else if (vPoint.Y > TITLE_WIDTH)
{
m.Result = (IntPtr)HitTest.HTCAPTION;
}
}
break;


}


}



#endregion

/// <summary>
/// 枚举鼠标拖动
/// </summary>
public enum HitTest : int
{
HTERROR = -2,
HTTRANSPARENT = -1,
HTNOWHERE = 0,
HTCLIENT = 1,
HTCAPTION = 2,
HTSYSMENU = 3,
HTGROWBOX = 4,
HTSIZE = HTGROWBOX,
HTMENU = 5,
HTHSCROLL = 6,
HTVSCROLL = 7,
HTMINBUTTON = 8,
HTMAXBUTTON = 9,
HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17,
HTBORDER = 18,
HTREDUCE = HTMINBUTTON,
HTZOOM = HTMAXBUTTON,
HTSIZEFIRST = HTLEFT,
HTSIZELAST = HTBOTTOMRIGHT,
HTOBJECT = 19,
HTCLOSE = 20,
HTHELP = 21
}

}
}
...全文
354 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wtin008 2012-06-07
  • 打赏
  • 举报
回复
同求答案。。加上任务栏左右键功能后不能改变大小,可以改变大小的时候却不能使用任务栏左右键功能。。
madai 2011-12-09
  • 打赏
  • 举报
回复
有没有牛人可以解决这个问题啊?
急!!!
呵呵~
qyq520wei 2010-06-06
  • 打赏
  • 举报
回复
学习。。。
starts_2000 2009-12-25
  • 打赏
  • 举报
回复
songgongpu 2009-12-25
  • 打赏
  • 举报
回复
接分,接分,接分,接分,
renyibin 2009-12-24
  • 打赏
  • 举报
回复
hhc123 你的我试过了 不好用
private void Form12_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}
renyibin 2009-12-24
  • 打赏
  • 举报
回复
发的东西很好 很完整 放到VS2008里新建一个窗体就行了 就能看到是什么意思 就是
//SetWindowLong(new HandleRef(this, this.Handle), -16, GetWindowLong(new HandleRef(this, this.Handle), -16) | WS_SYSMENU); //这里加上这段后 下面的case WM_NCHITTEST:就没反应了 请问这儿怎么写
这段有问题
把注释去掉 就不能响应case WM_NCHITTEST: 的功能了
hhc123 2009-12-24
  • 打赏
  • 举报
回复

[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_MOVE = 0xF010;
public const int HTCAPTION = 0x0002;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);

}


这是无边框拖动
renyibin 2009-12-24
  • 打赏
  • 举报
回复
//SetWindowLong(new HandleRef(this, this.Handle), -16, GetWindowLong(new HandleRef(this, this.Handle), -16) | WS_SYSMENU); //这里加上这段后 下面的case WM_NCHITTEST:就没反应了 请问这儿怎么写
这段有问题
平生我自如 2009-12-24
  • 打赏
  • 举报
回复
代码有点长了!你加点描述就好了!
Return门徒 2009-12-24
  • 打赏
  • 举报
回复
哎,粘了这么长的代码,不知道什么意思~!接分

111,120

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧