C# WinForm:
   需要实现的是:
   像QQ的主界面,永远不在任务栏显示,所以初始化窗体时就将form的ShowInTaskBar=false;
   点击"最小化"按钮时将form最小化到系统托盘notifyIcon;
   当双击notifyIcon时显示form。   你可能认为这很简单,网上也有很多类似问题的解答,我为什么还要问。因为我发现那些解答都不符合我的需求。下面是网上搜罗的几种解法:  (1)在SizeChanged中判断WindowState:
     
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.Show();
            this.Activate();
        }        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
            }
        }
       总结:这样做确实做了最小化处理,但你会发现每当最小化时,窗体会缩至屏幕左下角处,即使你在SizeChanged中试图Hide这个窗体,但这是在最小化后做的事情,你依然会看到上述现象。如果电脑开了窗体淡入淡出设置,那现象更明显。    (2)在Wndproc中截获最小化消息处理:
     
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.Show();
            this.Activate();
        }        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SYSCOMMAND)
            {
                if (m.WParam.ToInt32() == SC_MINIMIZE)
                {
                    this.Hide();
                } 
            }            base.WndProc(ref m);
        }
         总结:这个方法确实是在进行最小化之前做了隐藏处理,但是接着将处理base.WndProc(ref m);这样的话它还是会出现上述现象。而如果在this.Hide();之后来个return;这样就不处理base.WndProc(ref m);了,但这样做实际上并未对form做最小化处理。-------------------------------------------------------------------------------------------------------'
    细心的朋友应该会发现:当窗体最小化时,对应进程占用的内存会大幅减小。你可以在运行程序时打开进程管理器看下就知道了。
    所以我想实现:
    在真正意义上的最小化的前提下,不要让缩至屏幕左下角的现象发生。

解决方案 »

  1.   

    前提:
    窗体ShowInTaskbar始终false;
    真正做了最小化处理
      

  2.   

     private void button1_Click(object sender, EventArgs e)
            {
                this.Visible = false;
            }private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
            {
                if (!this.Visible)
                    this.Visible = true;
            }你用淡入淡出看看,没有你说的左下角什么的
      

  3.   

    使用 AnimateWindow 来定义窗体样式看看.
      

  4.   

    DrawAnimatedRects
    说错了,是这个。
      

  5.   

    用Animate去处理 实际上没做最小化的操作  不信你开任务管理器看  跟最小化还是不一样
    我原来form在load是内存一般在7-8M,正常最小画后只有1-2M,我要这样的效果
      

  6.   


            //最小化
            private void MinSize()
            {
                this.WindowState = FormWindowState.Minimized;
                this.notifyIcon1.ShowBalloonTip(2000, "", "服务器端仍在运行", ToolTipIcon.Info);
                this.notifyIcon1.Visible = true;
                this.ShowInTaskbar = false;
            }
            //窗子的Resize事件
            private void FServer_Resize(object sender, EventArgs e)
            {
                if (this.WindowState == FormWindowState.Minimized)
                {
                    MinSize();
                }
            }
    我原来写的窗体隐藏到托盘的代码片段,试试行不
      

  7.   

    五楼和七楼说的是API函数吧,貌似可以的
    看来。net framework无法直接完成这个效果
      

  8.   

    12楼说的对,而且我证实了即使采用API做Animate效果,最小化时,它仍然是先往屏幕左下角跑一下的。外观里开了淡入淡出的则现象更明显
      

  9.   

    写一个线程处理动画。你可以观察腾讯的QQ在最小化时大概有多少帧。不过要知道你的托盘的位置才可以。动画效果说明:每当最小化时,先记下窗体的大小,和位置,窗体会一直往托盘位置方向窗体越来越小。最后就Visable=false;相反,还原的时候:窗体会先Visable=true;窗体会从托盘位置方向向原来的窗体(先前记下的窗体大小,和位置)大小,位置,再做处理。全局变量:
    Size formNormalSize;Point formNormalLocation;
    最小化:
    new Thread(new ThreadStart(
     delegate
     {
      formNormalSize=窗体对象.Size;
      formNormalLocation=窗体对象.Location;
      for(int i=0;i<动画帧数;i++)
      {
       窗体对象.Size的Width Height都要减去指定的步长操作;
       if(
       (Math.Abs(窗体对象.Location.X-托盘位置.Location.X)<=指定范围的数值)
       ||
       (Math.Abs(窗体对象.Location.Y-托盘位置.Location.Y)<=指定范围的数值)
       )
       {
        窗体对象.Visable=false;
       }
      }
     }
    )).Start();//还原
    new Thread(new ThreadStart(
     delegate
     {
      窗体对象.Visable=true;
      for(int i=0;i<动画帧数;i++)
      {
       窗体对象.Size的Width Height都要加上指定的步长操作;
       if(
       (Math.Abs(窗体对象.Location.X-formNormalLocation.X)<=指定范围的数值)
       ||
       (Math.Abs(窗体对象.Location.Y-formNormalLocation.Y)<=指定范围的数值)
       )
       {
        窗体对象.Size=formNormalSize;
        窗体对象.Location=formNormalLocation;
       }
      }
     }
    )).Start();以上只是思路型的代码,没有实际应用。但愿对你有帮助。
      

  10.   

    更新红色部分。最小化: 
    new Thread(new ThreadStart( 
    delegate 

      Application.DoEvent();  formNormalSize=窗体对象.Size; 
      formNormalLocation=窗体对象.Location; 
      for(int i=0;i <动画帧数;i++) 
      { 
      窗体对象.Size的Width Height都要减去指定的步长操作; 
      if( 
      (Math.Abs(窗体对象.Location.X-托盘位置.Location.X) <=指定范围的数值) 
      || 
      (Math.Abs(窗体对象.Location.Y-托盘位置.Location.Y) <=指定范围的数值) 
      ) 
      { 
        窗体对象.Visable=false; 
        break;
      } 
      } 

    )).Start(); //还原 
    new Thread(new ThreadStart( 
    delegate 

        Application.DoEvent();
     
      窗体对象.Visable=true; 
      for(int i=0;i <动画帧数;i++) 
      { 
      窗体对象.Size的Width Height都要加上指定的步长操作; 
      if( 
      (Math.Abs(窗体对象.Location.X-formNormalLocation.X) <=指定范围的数值) 
      || 
      (Math.Abs(窗体对象.Location.Y-formNormalLocation.Y) <=指定范围的数值) 
      ) 
      { 
        窗体对象.Size=formNormalSize; 
        窗体对象.Location=formNormalLocation; 
            break;
      } 
      } 

    )).Start();
      

  11.   

    最好再在for循环的每一次执行,都加上一个Thread.Sleep(毫秒);来合理的操作。不然会很卡。
      

  12.   

    感谢linjf520的回答,不过你做的是实现缩放过程中的动画效果,这个我已经实现了。
    我需要的是:在真正最小化(不是Hide)的前提下,去掉向屏幕左下角的动画效果。
    12楼理解了我的意思
      

  13.   

    很难理解么? 这样说吧:
    你新建个Form,然后在属性中将它的ShowInTaskBar设置成false。
    我们这里不说托盘吧,因为其实跟托盘没啥关系。
    好了,然后你点击窗体最小化按钮,看看~ 在屏幕左下角是否有个标题栏样的缩在那?
    ----------------------------
    这就是问题所在,而我的要求是:
    前提条件:ShowInTaskBar始终为false不变,整个过程不用什么Hide()、visibel、Opacity之类的,就让其正常的最小化。你可以采用消息处理、P/Invoke等任何方式,只要能实现。如果不能实现,请告诉我:Windows下真的不能实现这样的。
      

  14.   

    给你一段c++的最小化托盘,我没写过C#的,参考:
    if(IsFirstMin==false)
    {
    NOTIFYICONDATA nc;
    nc.cbSize=sizeof(NOTIFYICONDATA);
    nc.hIcon=m_icon;
    nc.hWnd=m_hWnd;
    lstrcpy(nc.szTip,"UUBC");
    nc.uCallbackMessage=WM_NOTIFYICON;
    nc.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
    nc.uID=IDC_NOTIFYICON;
    Shell_NotifyIcon(NIM_ADD,&nc);
    IsFirstMin=true;
    }
    ShowWindow(false);
    IsMin=true;
      

  15.   

    谢谢27楼的方法,这个方法对于一般窗体很奏效,但是我的窗体的WindowState是FormWindowState.none
      我试了下为None的情况下,那个方法还是会留下向屏幕左下教去的痕迹
      

  16.   

    上面写错了 是FormBorderStyle.None;
    我的是一个无边框的窗体,窗体中Button,当点击它时执行:
    this.WindowState = FormWindowState.Minimized;