问题描述:form最小化到系统托盘后希望能够点击鼠标左键弹出ContextMenu所以新建了Control用来显示,但是在非菜单选项的地方点击的话菜单无法消失,只有在点击或者点击过菜单以后在其他地方单击鼠标ContextMenu才会消失。很急的说,大家帮帮忙哈!!左键弹出菜单的代码: private void Main_notifyIcon_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(e.Button==MouseButtons.Left) 

Control control = new Control(null,Control.MousePosition.X,Control.MousePosition.Y,1,1); 
control.Visible = true; 
control.CreateControl(); 
Point pos = new Point(0,0);
this.Main_PopUpMenu.Show(control,pos); 
}  }

解决方案 »

  1.   

    为什么这样做?直接做一个上下文菜单,关联到你的NotifyIcon组件。
    (1).如何在程序运行后隐藏窗体:   我们知道托盘程序运行后是无法看见主窗体的,他只会显示在工具栏上。在用Visual C#设计此类程序的时候,可以用二种方法使得程序运行后不显示主窗体。其中一种方法是重载主窗体中的OnActivated( )事件,OnActivated( )事件是在窗体激活的时候才触发的。通过重载此事件可以达到隐藏主窗体的目的。具体程序代码如下: protected override void OnActivated ( EventArgs e ) 

    this.Hide ( ) ; 
    }   另外一种方法是在初始化主窗体的时候完成的,通过设定主窗体的属性来达到不显示的目的。具体的程序代码如下: this.MaximizeBox = false ; 
    this.MinimizeBox = false ; 
    this.WindowState = System.Windows.Forms.FormWindowState.Minimized ;   在本文介绍的程序中,使用了第二种方法。 
    (2).如何为托盘程序设定显示图标:   在NotifyIcon组件中有一个属性icon就是来设定托盘图标的,由于Visual C#是一个完全的OOP (面向对象)语言,在Visual C#中任何东西都可以作为对象来处理。当然对应一个icon来说,也可以用对象的方法来处理他。我们通过下列语句来得到一个icon对象: private Icon mNetTrayIcon = new Icon ( "Tray.ico" ) ;   请注意:在编译好的程序中,必须要在同一个目录中有一个Tray.ico图标文件,否则程序运行时候会出错的。   通过下列语句把此icon对象付给NotifyIcon组件中的icon属性,此时如果程序正确编译,则此icon就会显示在工具栏中了。 TrayIcon.Icon = mNetTrayIcon ;   (3).设定当鼠标停留在托盘程序上显示的文本内容:   NotifyIcon组件中有一个属性Text。设定这个属性的内容,就是鼠标停留在托盘图标上显示的内容了。具体语句如下: TrayIcon.Text = "用Visual C#做托盘程序" + "\n" + "作者:马金虎于2001.12.08" ;   (4).如何在托盘程序加入菜单:   在NotifyIcon组件中有一个对象叫ContextMenu,在托盘程序中显示出的菜单就是通过设定此对象来实现的。以下的程序代码是为托盘程序加入菜单项: notifyiconMnu = new ContextMenu ( mnuItms ) ; 
    TrayIcon.ContextMenu = notifyiconMnu ; 
    //为托盘程序设定菜单   (5).如何设定ContextMenu对象的内容:   ContextMenu对象是托盘程序的菜单的结构,所以如何设定此对象,在本程序中是比较关键的。在程序中,是通过定义一个菜单项数组,并对这个数组设定不同的值(这当中包括菜单的一些属性和事件),然后把这个数组同时赋值给ContextMenu对象,来实现对ContextMenu对象的设置过程的。以下是程序中具体代码: //定义一个MenuItem数组,并把此数组同时赋值给ContextMenu对象 
    MenuItem [ ] mnuItms = new MenuItem [ 3 ] ; 
    mnuItms [ 0 ] = new MenuItem ( ) ; 
    mnuItms [ 0 ] .Text = "用Visual C#做托盘程序!" ; 
    mnuItms [ 0 ] .Click += new System.EventHandler ( this.showmessage ) ; mnuItms [ 1 ] = new MenuItem ( "-" ) ; 
    mnuItms [ 2 ] = new MenuItem ( ) ; 
    mnuItms [ 2 ] .Text = "退出系统" ; 
    mnuItms [ 2 ] .Click += new System.EventHandler ( this.ExitSelect ) ; 
    mnuItms [ 2 ] .DefaultItem = true ; notifyiconMnu = new ContextMenu ( mnuItms ) ; 
    TrayIcon.ContextMenu = notifyiconMnu ; 
    //为托盘程序加入设定好的ContextMenu对象   当成功加入了ContextMenu对象后,在程序编译完成运行时,当鼠标右键点击托盘图标,程序会自动弹出ContextMenu对象封装好的菜单。 
      

  2.   

    楼...楼...楼...上的大哥!!!那个俺想问的是左键菜单啊!左键菜单要新建一个Control是因为ContextMenu.show(ct,pt)中的ct部分必须是Control类型,NotifyIcon是不行的!
      

  3.   

    嗯,放到MouseDown里边效果也是一样啊!一开始也是放在MouseDown里边后来做实验就放到Click里边了
      

  4.   

    楼上,不好意思!!理解错误,不过放在Click 里边和放在Down里边也是一样啊
      

  5.   

    你在MouseDown里发一个右键消息给系统就行了。
      

  6.   

    to: JasonHeung(拥有一切也不过就这样笑着哭) 麻烦给看下,我的写法正确??怎么还是不行呢??谢谢啦private void Main_notifyIcon_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        const int WM_RbuttonD = 0x0204;
        Message msgD = Message.Create(this.Handle,WM_RbuttonD,new IntPtr(0),new IntPtr(0));
        PostMessage(msgD.HWnd ,msgD.Msg ,msgD.WParam ,msgD.LParam); 
    }
      

  7.   

    或者这样:
    不过也是出不来:(
    IntPtr hwnd_win ;
    IntPtr hwnd_nt; hwnd_win = FindWindow("WindowsForms10.Window.8.app3","MainForm"); 
    hwnd_nt = FindWindowEx(hwnd_win ,new IntPtr(0) ,"WindowsForms10.EDIT.app3","Main_notifyIcon"); 

    const int WM_RbuttonD = 0x0204;
    Message msgD = Message.Create(hwnd_nt,WM_RbuttonD,new IntPtr(0),new IntPtr(0));
    PostMessage(msgD.HWnd ,msgD.Msg ,msgD.WParam ,msgD.LParam); 
      

  8.   

    PostMessage(msgD.HWnd ,msgD.Msg ,msgD.WParam ,msgD.LParam); 
    msgD.HWnd  = this.Handle 还是不等于NotifyIcon所关联的window的句柄,但NotifyIcon所关联的window的句柄是保护成员,而NotifyIcon类又不能派生。
    看来要想其它办法。你现在的做法也可将就用了。要不将control变成主窗口类成员,你在ContextMenu的Popup事件里开个计时器,过一点时间,就将contextMenu1关闭,将control隐藏。