+ -
当前位置:首页 → 问答吧 → winform 无边框 窗体基本功能 拖动和系统右键菜单冲突

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

时间:2009-12-24

来源:互联网

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
  }

  }
}

作者: renyibin   发布时间: 2009-12-24

哎,粘了这么长的代码,不知道什么意思~!接分

作者: changling_wang   发布时间: 2009-12-24

代码有点长了!你加点描述就好了!

作者: zqd5920   发布时间: 2009-12-24

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

作者: renyibin   发布时间: 2009-12-24

C# code

[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); 

        }



这是无边框拖动

作者: hhc123   发布时间: 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: 的功能了

作者: 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

接分,接分,接分,接分,

作者: songgongpu   发布时间: 2009-12-25

参考

作者: starts_2000   发布时间: 2009-12-25

学习。。。

作者: qyq520wei   发布时间: 2010-06-06

有没有牛人可以解决这个问题啊?
急!!!
呵呵~

作者: madai   发布时间: 2011-12-09