我们在键盘上跳舞,演绎最美的人生

HtmlEditor常用模式

1、撤销重做模式

基础封装:

  #region 重做单元

        /// <summary>
        /// 表示开始进行重做单元
        /// </summary>
        /// <param name="title"></param>
        private void StartUndoUnit(string title = "coolform")
        {
            var ims = htmlDesignEditor.Document as IMarkupServices2;
            ims.BeginUndoUnit(title);
        }

        /// <summary>
        /// 表示结束进行重做单元
        /// </summary>
        private void EndUndoUnit()
        {
            var ims = htmlDesignEditor.Document as IMarkupServices2;
            ims.EndUndoUnit();
           
        }

        #endregion

封装好后,在通过代码来改变HtmlEditor内的内容时,需要把更改的操作包含在起来,如:

           StartUndoUnit();
                foreach (var tempSelectCell in cells)
                {
                    var element = tempSelectCell.Value;

                    IHTMLStyle style = element.style;

                    style.SetTextAlign("center");


                }
                EndUndoUnit();    

只有把操作代码给StartUndoUnit()跟EndUndoUnit()包含起来后,HtmlEditor才会把里面的多个操作当作是一个工作单元,当你使用Undo()撤销时,才会一次性进行撤销操作。

 

2、鼠标区域限制

当进行拖拉跳转单元格等操作时,我们需要鼠标拖拉的范围进行调整,即限制鼠标的可活动范围:

    #region "鼠标区域限制"

        /// <summary>
        /// 移除鼠标区域限制
        /// </summary>
        /// <remarks></remarks>
        private void RemoveMouseRect()
        {
            Cursor.Clip = Rectangle.Empty;
        }

        /// <summary>
        /// 设置鼠标区域限制,此区域大小由传入的控件参数决定
        /// </summary>
        /// <param name="el"></param>
        /// <remarks></remarks>
        private void SetMouseRect(IHTMLElement el)
        {
            Size s = new Size(el.offsetWidth, el.offsetHeight);
            Point p = _coolPf.GetAbsoluteLocation(el);

            SetMouseRect(p, s);
        }

        /// <summary>
        /// 设置鼠标区域限制
        /// </summary>
        /// <param name="p">The p.</param>
        /// <param name="s">The s.</param>
        private void SetMouseRect(Point p, Size s)
        {
            Rectangle r = this.htmlDesignEditor.RectangleToScreen(this.htmlDesignEditor.ClientRectangle);
            p.X += r.Left;
            p.Y += r.Top;
            IHTMLElement2 body = this.htmlDesignEditor.HtmlDocument2.GetBody() as IHTMLElement2;
            p.X -= body.GetScrollLeft();
            p.Y -= body.GetScrollTop();

            //检测最左边缘
            if (p.X < 0)
            {
                s.Width += p.X;
                p.X = 0;
            }

            //检测最上边缘
            if (p.Y < r.Top)
            {
                s.Height = s.Height + p.Y - r.Top;
                p.Y = r.Top;
            }

            //检测可见区域
            int height = r.Height;
            int width = r.Width;
            if (r.Left < 0)
            {
                width = r.Width + r.Left;
            }
            if (r.Top < 0)
            {
                height = r.Height + r.Top;
            }

            //设置可见区域
            if (width < s.Width)
            {
                s.Width = width;
            }
            if (height < s.Height)
            {
                s.Height = height - 20;
            }
            if (p.X + s.Width > r.Left + r.Width)
            {
                s.Width -= 6;
            }

            var newRect = new Rectangle(p, s);
            Cursor.Clip = newRect;
        }

        #endregion

eg:如选择单元格时,需要限制鼠标在当前表格范围内:

              //开始选择单元格
                //保存相关的信息
                //设置鼠标限制区域
                //改变鼠标形状
                if (_selectTableCellHelper.StartSelectCell(el))
                {
                    Cursor.Current = new Cursor("CellSelect.cur");
                    SetMouseRect(_selectTableCellHelper.MouseDownTable);
                    return;
                }

选择完成后,需要清空对鼠标的区域限制:

   if (_selectTableCellHelper.State == SelectCellState.Doing)
            {
                _selectTableCellHelper.State = SelectCellState.Finish;
                RemoveMouseRect();
                Cursor.Current = Cursors.Default;
            }

 

3、对控件加入自定义的行为展示

在进行控件设计时,我们分别定义了很多控件,如文本框,时间日期框等等,但文本框,时间日期框本质上都是input控件,为了在设计时能区别不同的控件,我们对某些控件加入特殊的行为展示,如对时间日期控件加入日期小标志,如下图。

 

如何加入自定义行为,请参见:IElementBehaviorFactory, IElementBehavior, IHTMLPainter三个接口。

eg:

 public class DateTimeBehavior : IElementBehaviorFactory, IElementBehavior, IHTMLPainter
    {
        protected IHTMLDocument2 Document
        {
            get
            {
                return (IHTMLDocument2)this.Element.document;
            }
        }
        protected IHTMLElement Element
        {
            get
            {
                return _behaviorSite.GetElement();
            }
        }
        protected IHTMLWindow2 Window
        {
            get
            {
                return this.Document.GetParentWindow();
            }
        }
        private IElementBehaviorSite _behaviorSite;

        public IElementBehaviorSite ElementSite
        {
            get
            {
                return _behaviorSite;
            }
        }
        public IHTMLPaintSite PaintSite
        {
            get
            {
                return (IHTMLPaintSite)_behaviorSite;
            }
        }



        public void Update()
        {
            PaintSite.InvalidateRect(IntPtr.Zero);
        }


        #region IElementBehaviorFactory 成员

        public IElementBehavior FindBehavior(string bstrBehavior, string bstrBehaviorUrl, IElementBehaviorSite pSite)
        {
            return this;
        }

        #endregion

        #region IElementBehavior 成员

        public void Init(IElementBehaviorSite pBehaviorSite)
        {
            _behaviorSite = pBehaviorSite;

        }

        public void Notify(int dwEvent, IntPtr pVar)
        {
            if (dwEvent == 1)
            {
                //IHTMLEventObj eventobj = this.Element as IHTMLEventObj;

                //mshtml.IHTMLElement el = ElementSite.GetElement() as mshtml.IHTMLElement;

                //mshtml.IHTMLImgElement imgel =( mshtml.IHTMLImgElement)el ;

                //mshtml.HTMLImgEvents2_Event imageEvent = imgel  as mshtml.HTMLImgEvents2_Event;
                //imageEvent.onmousemove += new mshtml.HTMLImgEvents2_onmousemoveEventHandler(imageEvent_onmousemove);

                //imageEvent.onmousedown += new mshtml.HTMLImgEvents2_onmousedownEventHandler(imageEvent_onmousedown);
                //imageEvent.onmouseup += new mshtml.HTMLImgEvents2_onmouseupEventHandler(imageEvent_onmouseup);
            }

        }

        void imageEvent_onmousemove(mshtml.IHTMLEventObj pEvtObj)
        {
            mshtml.IHTMLElement el = pEvtObj.srcElement;
            int ex = el.offsetWidth - 20;
            if (pEvtObj.offsetX >= ex && pEvtObj.offsetX <= el.offsetWidth && pEvtObj.offsetY <= 20)
            {
                _buttonPushed = true;
                Update();
            }
            else
            {
                _buttonPushed = false;
                Update();
            }
            // System .Diagnostics .Debug .WriteLine ("move:"+_buttonPushed .ToString ());
        }

        public void Detach()
        {
            //OnBehaviorDetach();
            _behaviorSite = null;
        }

        #endregion

        #region IHTMLPainter 成员


        public void Draw(int leftBounds, int topBounds, int rightBounds, int bottomBounds, int leftUpdate, int topUpdate, int rightUpdate, int bottomUpdate, int lDrawFlags, IntPtr hdc, IntPtr pvDrawObject)
        {
            //mshtml.IHTMLElement el = ElementSite.GetElement() as mshtml.IHTMLElement;
            //mshtml.IHTMLTable3 table = el as mshtml.IHTMLTable;
            try
            {
                Graphics g = Graphics.FromHdc(hdc);
                //Rectangle bounds = new Rectangle(leftBounds, topBounds, rightBounds - leftBounds, bottomBounds - topBounds);
                //Rectangle updateRect = new Rectangle(leftUpdate, topUpdate, rightUpdate - leftUpdate, bottomUpdate - topUpdate);

                //g.DrawRectangle(new Pen(SystemColors.Control), rightBounds - 20, topBounds, 20, 20);
                //g.FillRectangle(new SolidBrush(SystemColors.Control), rightBounds - 20, topBounds, 20, 20);

                //g.FillEllipse(new SolidBrush(Color.Black), rightBounds - 15, topBounds + 5, 10, 10);
                g.PageUnit = GraphicsUnit.Pixel;

                g.DrawImage(Image.FromFile("datePicker.gif"),  leftBounds  +20, topBounds);
                g.Dispose();

            }
            catch
            {

            }

        }

        public void OnResize(int cx, int cy)
        {
            Size size = new Size(cx, cy);

        }
        private bool _buttonPushed = false;
        public void GetPainterInfo(HTML_PAINTER_INFO htmlPainterInfo)
        {
            //htmlPainterInfo = new HTML_PAINTER_INFO();
            //OnGetPainterInfo(ref htmlPainterInfo);
            htmlPainterInfo.lFlags = 0x000002;
            htmlPainterInfo.lZOrder = 8;
            htmlPainterInfo.iidDrawObject = Guid.Empty;
            htmlPainterInfo.rcBounds = new RECT(20, 0, 0, 20);
            //htmlPainterInfo = new HTML_PAINTER_INFO();
        }


        private const int ButtonPart = 1009;
        #endregion

        private void imageEvent_onmousedown(mshtml.IHTMLEventObj pEvtObj)
        {
            mshtml.IHTMLElement el = pEvtObj.srcElement;
            int ex = el.offsetWidth - 20;
            if (pEvtObj.offsetX >= ex && pEvtObj.offsetX <= el.offsetWidth && pEvtObj.offsetY <= 20)
            //if (((mshtml.IHTMLEventObj3)pEvtObj).behaviorPart == ButtonPart)
            {


                _buttonPushed = true;
                Update();
            }
        }

        private void imageEvent_onmouseup(mshtml.IHTMLEventObj pEvtObj)
        {

            if (_buttonPushed)
            {
                _buttonPushed = false;
                Update();
                if (((mshtml.IHTMLEventObj3)pEvtObj).behaviorPart == ButtonPart)
                {
                    //System.Windows.Forms.MessageBox.Show("ASDdsdsddssdsdsddsFASFA");
                    OnClick();
                }
            }
        }

        private void OnClick()
        {
            //throw new Exception("The method or operation is not implemented.");
        }

        #region IHTMLPainter 成员


        public void HitTestPoint(int ptx, int pty, out int pbHit, out int plPartID)
        {
            Point pt = new Point(ptx, pty);
            plPartID = 0;
            pbHit = 0;
            if (pt.X <= 20 && pt.Y <= 20) plPartID = ButtonPart;
            if (plPartID > 0)
            {
                pbHit = 1;
            }

        }

        #endregion
    }

使用:

添加:

            var grid = new  DateTimeBehavior();
             object obj = grid;
             IHTMLElement2 ele2 = input as IHTMLElement2;
             dynamic cookieid = ele2.AddBehavior(null,ref obj);    

删除:

               IHTMLElement2 ele = element as IHTMLElement2;
                int behaviorid = _toolTipBehaviorCookiedIDList[uniqueId];
                ele.RemoveBehavior(behaviorid);

*请注意,删除Behavior需要根据添加Behavior到控件时返回的id才能删除,故添加时需要记录保存ID

posted @ 2014-10-30 13:44  嘉应子  阅读(502)  评论(0编辑  收藏  举报