protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            e.Graphics.SmoothingMode      = SmoothingMode.AntiAlias;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;

            e.Graphics.DrawLine(new Pen(this.TabBottomLineColor), new Point(0, this.Height - 1), new Point(this.Width, this.Height - 1));

            // 判断重绘区域大小,解决由最小化还原后,无法绘制Tab的问题
            if (currPaintTh == null || e.ClipRectangle.Size.Width > TabHeader.Left_Offset)
            {
                // 被选中的Tab 需要处于顶层,因此最后绘制
                TabHeader thSelected = null;
                foreach (TabHeader th in lstTabHeader)
                {
                    if (th.Selected)
                    {
                        thSelected = th;
                    }
                    else
                    {
                        th.DrawAll(e.Graphics, th.Rect);
                    }
                }
                // 最后绘制
                if (thSelected != null)
                {
                    thSelected.DrawAll(e.Graphics, thSelected.Rect);
                }
            }
            else
            {
                // 绘制完整的TabHeader,如果仅绘制指定区域,可能会出现白色背景
                currPaintTh.DrawAll(e.Graphics, currPaintTh.Rect);
                currPaintTh = null;
            }
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (e.Button == System.Windows.Forms.MouseButtons.Left && thMouseDown != null)
            {
                //Win32API.OutputDebugStringA(string.Format("e.Button == System.Windows.Forms.MouseButtons.Left && thMouseDown != null"));
                if (!slided)
                {
                    if (Math.Abs(e.X - pMouseDown.X) > 15)
                    {
                        slided = true;
                    }
                }
                else
                {
                    btnAddNew.Visible = false;

                    Point newPos = thMouseDown.Rect.Location;
                    newPos.X += e.Location.X - pMouseDown.X;

                    // 是否在父窗体范围内移动
                    if (newPos.X < 0)
                    {
                        newPos.X = 0;
                    }

                    //防止将标签拖动到窗口右上角控制按钮区域
                    if (newPos.X > (this.Width - this.ControlBoxWidth - thMouseDown.Rect.Width))
                    {
                        newPos.X = this.Width - this.ControlBoxWidth - thMouseDown.Rect.Width;
                    }


                    // 判断移动方向,向左或向右
                    if (e.Location.X - pMouseDown.X > 0)
                    {
                        // 判断是否已经是最后一个Tab
                        if (thMouseDown.TabIndex != lstTabHeader.Count - 1)
                        {
                            TabHeader thRight = lstTabHeader[thMouseDown.TabIndex + 1];

                            // 向右移动时,判断是否与后一Tab 交换位置:当前Tab的 Right ,超过后一Tab 位置的一半
                            if (newPos.X + tabWidth > thRight.Rect.X + tabWidth / 2)
                            {
                                thRight.TabIndex--;
                                thMouseDown.TabIndex++;
                                lstTabHeader.Sort();
                            }
                        }
                    }
                    else
                    {
                        // 判断是否已经是第0个Tab
                        if (thMouseDown.TabIndex != 0)
                        {
                            TabHeader thLeft = lstTabHeader[thMouseDown.TabIndex - 1];

                            // 向右移动时,判断是否与后一Tab 交换位置:当前Tab的 Right ,超过后一Tab 位置的一半
                            if (newPos.X < thLeft.Rect.X + tabWidth / 2)
                            {
                                thLeft.TabIndex++;
                                thMouseDown.TabIndex--;
                                lstTabHeader.Sort();
                            }
                        }
                    }

                    thMouseDown.Rect.X = newPos.X;
                    pMouseDown         = e.Location;
                    this.Invalidate();
                }
            }
            if (e.Button == System.Windows.Forms.MouseButtons.Left && bolMouseDownNothing)
            {
                //Win32API.OutputDebugStringA(string.Format("e.Button == System.Windows.Forms.MouseButtons.Left && bolMouseDownNothing"));
                //这里会导致窗口位置移动,BUG
                //Win32API.OutputDebugStringA(string.Format("没有选中标签,当前坐标为:X:{0},Y:{1}", pMouseDown.X, pMouseDown.Y));
                if (this.Parent != null)
                {
                    //Win32API.OutputDebugStringA(string.Format("当前控件的父控件为:{0},Handle为:{1}", this.Parent, this.Parent.Handle));
                    Form tmpForm = this.Parent as Form;
                    if (tmpForm != null)
                    {
                        tmpForm.Location = new Point(tmpForm.Location.X + e.X - pMouseDown.X, tmpForm.Location.Y + e.Y - pMouseDown.Y);;
                    }
                }
            }
            else
            {
                //判断当前标签是否是鼠标悬停
                pMouseMove = e.Location;
                //thMouseMove = null;
                //Win32API.OutputDebugStringA( string.Format("当前鼠标坐标为X:{0}, y{1}", pMouseMove.X,pMouseMove.Y) );
                try
                {
                    foreach (TabHeader th in lstTabHeader)
                    {
                        //如果当前标签有鼠标悬停
                        if (th.HitTest(pMouseMove))
                        {
                            //如果当前标签是已经选择的标签,跳过
                            if (!th.Selected)
                            {
                                th.Hovered = true;
                                //thMouseMove = th;
                            }
                            else
                            {
                                th.Hovered = false;
                            }
                            //将当前标签的标题作为ToolTip显示
                            if (th.TitleHitTest(pMouseMove))
                            {
                                //判断当前标签的有鼠标悬停
                                if (toolTip1 != null)
                                {
                                    if (!toolTip1.GetToolTip(this).Equals(th.Title))
                                    {
                                        toolTip1.SetToolTip(this, th.Title);
                                    }
                                }
                            }
                            else
                            {
                                if (toolTip1 != null)
                                {
                                    toolTip1.Hide(this);
                                }
                            }
                        }
                        else
                        {
                            th.Hovered = false;
                        }
                        //Win32API.OutputDebugStringA(string.Format("标签是否选择:{0} , 是否鼠标悬停:{1}!", th.Selected, th.Hovered));
                    }
                }
                catch (Exception ex)
                {
                }
                this.Invalidate();
            }
        }
        /// <summary>
        /// 销毁一个标签释放标签中的对象
        /// </summary>
        /// <param name="tab"></param>
        private void DeleteOneTab(TabHeader tab)
        {
            try
            {
                int intTabIndex = -1;
                intTabIndex = tab.TabIndex;
                //如果当前关闭的标签的客户端主窗口句柄不等于IntPtr.Zero,则关闭
                if (tab.ClientHandle != IntPtr.Zero)
                {
                    //发送消息,让子进程退出
                    //Win32API.CloseWindow(tab.ClientHandle);
                    int ret = Win32API.PostMessageA(tab.ClientHandle, Win32API.WM_CLOSE, 0, 0);
                    //int ret = Win32API.DestroyWindow(tab.ClientHandle);
                    //Win32API.OutputDebugStringA( string.Format("发送API命令Win32API.PostMessageA给{0},返回值:{1},LastErrorCode:{2}", tab.ClientHandle, ret, Win32API.GetLastError() ));
                }
                //
                //从标签列表中移除当前选择的标签(标签上的关闭按钮被点击)
                lstTabHeader.Remove(tab);
                tab.Dispose();

                //重新计算剩余标签的宽度
                widthCalculate(false);
                //重置所有标签为未选中状态,并重新设置标签编号
                for (int i = 0; i < lstTabHeader.Count; i++)
                {
                    lstTabHeader[i].TabIndex = i;
                    lstTabHeader[i].Selected = false;
                }
                //如果关闭了标签,则激活该标签右侧的标签,如果为0或<0,不激活
                try
                {
                    //OutputDebugStringA(string.Format("当前删除的标签索引{0}", intTabIndex));
                    //至少有3个标签0,1,2,删除1号,2号成了1号
                    if (lstTabHeader.Count > 1)
                    {
                        //如果当前删除的标签号是最后一个标签,则激活左侧的标签
                        if (lstTabHeader.Count == intTabIndex)
                        {
                            intTabIndex = intTabIndex - 1;
                        }
                        lstTabHeader[intTabIndex].Selected = true;
                        thMouseDownPublic = lstTabHeader[intTabIndex];
                        if (thMouseDownPublic.ClientHandle != IntPtr.Zero)
                        {
                            //显示到最前面
                            Win32API.MoveWindow(thMouseDownPublic.ClientHandle, 0, 0, pnlWebBrowser.Width, pnlWebBrowser.Height, 1);
                            Win32API.ShowWindow(thMouseDownPublic.ClientHandle, 1);
                        }
                    }
                    //至少有2个标签0,1,删除1号,直接激活0号
                    else if (lstTabHeader.Count == 1)
                    {
                        //OutputDebugStringA(string.Format("当前删除的标签索引条件:intTabIndex == 0"));
                        lstTabHeader[0].Selected = true;
                        thMouseDownPublic        = lstTabHeader[0];
                        if (thMouseDownPublic.ClientHandle != IntPtr.Zero)
                        {
                            //显示到最前面
                            Win32API.MoveWindow(thMouseDownPublic.ClientHandle, 0, 0, pnlWebBrowser.Width, pnlWebBrowser.Height, 1);
                            Win32API.ShowWindow(thMouseDownPublic.ClientHandle, 1);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //OutputDebugStringA(string.Format("切换标签时发生了错误:{0}", ex.Message ));
                }

                lstTabHeader.Sort();
                this.Invalidate();
            }
            catch (Exception ex)
            {
                //
            }
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            thMouseDown = null;
            //Win32API.OutputDebugStringA(string.Format("OnMouseDown 按键为:{0} ,{1}次点击!", e.Button, e.Clicks ));

            if (e.Button == System.Windows.Forms.MouseButtons.Left && e.Clicks == 1)
            {
                pMouseDown = e.Location;

                bolDbClickedFlag = false;

                PublicModule.IsHeadDbClicked = false;

                foreach (TabHeader th in lstTabHeader)
                {
                    if (th.HitTest(pMouseDown))
                    {
                        thMouseDown          = th;
                        thMouseDown.Selected = true;
                        thMouseDownPublic    = th;
                        break;
                    }
                }


                //切换当前标签页的浏览器控件到前台显示
                try
                {
                    if (thMouseDown != null)
                    {
                        //利用子进程的Handle,让其显示
                        if (thMouseDown.ClientHandle != IntPtr.Zero)
                        {
                            //发送消息,让它显示到前台
                            Win32API.MoveWindow(thMouseDown.ClientHandle, 0, 0, pnlWebBrowser.Width, pnlWebBrowser.Height, 1);
                            Win32API.ShowWindow(thMouseDown.ClientHandle, 1);
                        }
                        //重新设置消息
                        try
                        {
                            //FormMain tmpForm = pnlWebBrowser.Parent as FormMain;
                            if (tempFormMain != null && thPreviousMouseDown != thMouseDown)
                            {
                                string strcommand = string.Format("/cmd:getstatus,{0}", thMouseDown.ClientName);
                                tempFormMain.SendToClient(strcommand, thMouseDown.ClientName);
                                Win32API.OutputDebugStringA(string.Format("发消息 /cmd:getstatus 给{0}", thMouseDown.ClientName));
                            }
                        }
                        catch (Exception ex)
                        {
                            string errmessage = string.Format("发送命令/cmd:getstatus到客户端{0},发生错误{1}", thMouseDown.ClientName, ex.Message);
                            Win32API.OutputDebugStringA(errmessage);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //do something
                }

                if (thMouseDown != null)
                {
                    //选中了标签
                    bolMouseDownNothing = false;
                    foreach (TabHeader th in lstTabHeader)
                    {
                        if (th != thMouseDown)
                        {
                            th.Selected = false;
                            if (th.ClientHandle != IntPtr.Zero)
                            {
                                Win32API.ShowWindow(th.ClientHandle, 0);
                            }
                        }
                    }
                    this.Invalidate();
                }
                else
                {
                    //移动窗口
                    bolMouseDownNothing = true;
                }
                //记录当前标签有无变更,如果没变更,不做下一步操作
                thPreviousMouseDown = thMouseDown;
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Left && e.Clicks == 2)
            {
                //双击
                bolDbClickedFlag = true;
                //双击标签,并不是按下非标签区域,置为False,壁纸还原时位置在鼠标点击位置
                bolMouseDownNothing          = false;
                PublicModule.IsHeadDbClicked = true;

                //判断当前点击位置是否有标签
                pMouseDown = e.Location;

                //遍历所有标签,进行点击测试
                foreach (TabHeader th in lstTabHeader)
                {
                    if (th.HitTest(pMouseDown))
                    {
                        thMouseDown          = th;
                        thMouseDown.Selected = th.Selected;
                        break;
                    }
                }
                //

                if (thMouseDown != null)
                {
                    if (DbClickCloseTab)
                    {
                        //如果当前选择了标签,并且标签数量大于1个(编号从0开始)
                        //OutputDebugStringA(string.Format("当前标签总数:{0}", lstTabHeader.Count));
                        if (thMouseDown != null && lstTabHeader.Count > 1)
                        {
                            //
                            DeleteOneTab(thMouseDown);
                        }
                    }
                    return;
                }
                //Win32API.OutputDebugStringA(string.Format("没有选中标签,当前坐标为:X:{0},Y:{1}", pMouseDown.X, pMouseDown.Y));
                //Win32API.OutputDebugStringA("双击标签栏的空白区域!");
                if (tempFormMain != null)
                {
                    if (tempFormMain.WindowState == FormWindowState.Normal)
                    {
                        //Win32API.OutputDebugStringA( string.Format("主窗口的left:{0},top:{1}", oldLocation.X, oldLocation.Y) );
                        tempFormMain.WindowState = FormWindowState.Maximized;
                        tempFormMain.HideBorder  = true;
                        cbtnMaximized.StateImage = Resources.res_mask4;
                    }
                    else if (tempFormMain.WindowState == FormWindowState.Maximized)
                    {
                        tempFormMain.WindowState = FormWindowState.Normal;
                        tempFormMain.HideBorder  = false;
                        cbtnMaximized.StateImage = Resources.max_mask4;
                        //Win32API.OutputDebugStringA(string.Format("主窗口的left:{0},top:{1}", tmpForm.Location.X, tmpForm.Location.Y ));
                    }
                    else
                    {
                        tempFormMain.WindowState = FormWindowState.Normal;
                        tempFormMain.HideBorder  = false;
                    }
                }
                if (this.Parent != null)
                {
                    //Win32API.OutputDebugStringA(string.Format("当前控件的父控件为:{0},Handle为:{1}", this.Parent, this.Parent.Handle));
                    //Form tmpForm = this.Parent as Form;
                    //if (tmpForm != null)
                    //{
                    //    if (tmpForm.WindowState == FormWindowState.Normal)
                    //    {
                    //        //Win32API.OutputDebugStringA( string.Format("主窗口的left:{0},top:{1}", oldLocation.X, oldLocation.Y) );
                    //        tmpForm.WindowState = FormWindowState.Maximized;
                    //        cbtnMaximized.StateImage = Resources.res_mask4;

                    //    }
                    //    else if (tmpForm.WindowState == FormWindowState.Maximized)
                    //    {
                    //        tmpForm.WindowState = FormWindowState.Normal;
                    //        cbtnMaximized.StateImage = Resources.max_mask4;
                    //        //Win32API.OutputDebugStringA(string.Format("主窗口的left:{0},top:{1}", tmpForm.Location.X, tmpForm.Location.Y ));
                    //    }
                    //    else
                    //    {
                    //        tmpForm.WindowState = FormWindowState.Normal;
                    //    }
                    //}
                }
            }
        }
Exemple #5
0
        public int CompareTo(object o)
        {
            TabHeader th = o as TabHeader;

            return(this.tabIndex.CompareTo(th.TabIndex));
        }