FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Dobbs M-Dev
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
November 01, 2003

Create Binary Behaviors for IE with .NET

(Page 3 of 4)
Create Binary Behaviors for IE with .NET

Listing 1 Implementing IElementBehavior


namespace BinBehaviors
{
  [
  ComVisible(true),
  
    IElementBehaviorSiteOM bsiteOM;
    IHTMLPaintSite paintsite;

    IHTMLDocument2 document;
    IHTMLWindow2 parwindow;

    IHTMLElement element;
    HTMLElementEvents_Event events;

    Point point1, point2;
    float penwidth;
    Color pencolor;

    int xoffset, yoffset;
    Bitmap bitmap;

    /// <summary>
    /// A default constructor (no parameters) is necessary for COM instantiation
    /// </summary>
    public Line()
    {
      point1 = new Point(0, 0);
      point2= new Point(0, 0);
      penwidth = 1;
      pencolor = Color.Black;

      xoffset = yoffset = (int) this.penwidth + 1;
    }

    ~Line()
    {
    }

    /// <summary>
    /// Gets or sets the end points of the line as a single string.
    /// </summary>
    public string coords
    {
      get
      {
        return String.Format("{0} {1} {2} {3}", 
                             point1.X, point1.Y, point2.X, point2.Y);
      }
      set
      {
        UpdateCoords(value);
        DoLineDraw();
      }
    }

    // IElementBehavior method.
    void mshtml2.IElementBehavior.Init(IElementBehaviorSite behavsite)
    {
      try
      {
        this.bsite = behavsite;
        if (behavsite is IElementBehaviorSiteOM)
          this.bsiteOM = (IElementBehaviorSiteOM) behavsite;

        if (behavsite is mshtml.IHTMLPaintSite)
          this.paintsite = (mshtml.IHTMLPaintSite) behavsite;
      }
      catch (System.ExecutionEngineException e)
      {
        MessageBox.Show(e.Message);
      }
    }

    // IElementBehavior method.
    void mshtml2.IElementBehavior.Notify(int lEvent, System.IntPtr pVar)
    {
      try
      {
        switch ((_BEHAVIOR_EVENT)lEvent)
        {
          case _BEHAVIOR_EVENT.BEHAVIOREVENT_DOCUMENTREADY:
            if (this.bsite == null)
              return;

            this.element = this.bsite.GetElement(); // Cache the HTML element.
            this.document = (IHTMLDocument2) this.element.document;
            this.parwindow = (IHTMLWindow2) document.parentWindow;

            // Drawing to absolute point locations 
            // requires absolute position style.
            element.style.setAttribute("position", "absolute", 0);

            // Hook up event handlers.
            if (element is mshtml.HTMLElementEvents_Event)
            {
              this.events = (HTMLElementEvents_Event) this.element;
              events.onpropertychange += 
                new mshtml.HTMLElementEvents_onpropertychangeEventHandler(
                  HTMLElement_OnPropertyChange);
            }

            // Initial attribute values.

            // All HTML attributes come in as strings (or null, if not present).
            // "coords" property is ONLY a property, not an attribute.
            string x1 = element.getAttribute("x1", 0) as string;
            string y1 = element.getAttribute("y1", 0) as string;
            string x2 = element.getAttribute("x2", 0) as string;
            string y2 = element.getAttribute("y2", 0) as string;

            if (x1 != null)
              point1.X = Convert.ToInt32(x1);
            if (y1 != null)
              point1.Y = Convert.ToInt32(y1);
            if (x2 != null)
              point2.X = Convert.ToInt32(x2);
            if (y2 != null)
              point2.Y = Convert.ToInt32(y2);

            // ARGB must come in hexadecimal form.
            string argbstring = element.getAttribute("argb", 0) as string;
            if (argbstring != null)
              this.pencolor = Color.FromArgb(
                                (int) Convert.ToUInt32(argbstring, 16));
            
            // Width must be base 10.
            string widthstring = 
              (string) element.getAttribute("width", 0) as string;
            if (widthstring != null)
            {
              this.penwidth = Convert.ToSingle(widthstring);
              xoffset = yoffset = (int) this.penwidth + 1;
            }

            DoLineDraw();

            break;

          case _BEHAVIOR_EVENT.BEHAVIOREVENT_FIRST:
            //MessageBox.Show("event: first");
            break;
          case _BEHAVIOR_EVENT.BEHAVIOREVENT_LAST:
            MessageBox.Show("event: last");
            break;
          case _BEHAVIOR_EVENT.BEHAVIOREVENT_APPLYSTYLE:
            MessageBox.Show("event: apply style");
            break;

          default:
            MessageBox.Show("event: (default)");
            break;
        }
      }
      catch (System.ExecutionEngineException e)
      {
        MessageBox.Show(e.Message);
      }
    }

    // IElementBehavior method.
    void mshtml2.IElementBehavior.Detach()
    {
    }

    
    /// <summary>
    /// Handle the element's OnPropertyChange event. 
    /// Update the drawing to reflect the new property values.
    /// </summary>
    public void HTMLElement_OnPropertyChange()
    {
      IHTMLEventObj2 evo = (IHTMLEventObj2) parwindow.@event;

      string name = evo.propertyName.ToLower();
      object o = element.getAttribute(evo.propertyName, 0);

      switch (name)
      {
        case "x1":
          if (o is System.Int32)
            point1.X = (int) o;
          break;
        case "y1":
          if (o is System.Int32)
            point1.Y = (int) o;
          break;
        case "x2":
          if (o is System.Int32)
            point2.X = (int) o;
          break;
        case "y2":
          if (o is System.Int32)
            point2.Y = (int) o;
          break;
        case "coords":  // NOT CALLED, because of our coords property (above)
          UpdateCoords((string) o); // Object is a string (BSTR).
          break;
        case "width":
          if (o is System.Int32)
            penwidth = (int) o;
          break;
        case "argb":
          // ARGB will come as double if too big to fit as Int32.
          if (o is System.Double)
            pencolor = Color.FromArgb((int) Convert.ToUInt32((double) o));
          else if (o is System.Int32)
            pencolor = Color.FromArgb((int) o);
          break;
        default:
          break;
      }

      DoLineDraw();
    }

    /// <summary>
    /// Update the coordinates members (x1, y1, x2, y2) 
    /// given a string representation.
    /// </summary>
    /// <param name="coords">String representation of x1, y1, x2, y2.</param>
    private void UpdateCoords(string coords)
    {
      // May have: coords="  x1 ;y1 , x2 y2  ", etc.
      string s = coords.Trim();
      Regex re = new Regex("\\s*[,;]\\s*|\\s+"); // Separate at: space | punct. 
                                              // Order of alts is important.
      string[] segs = re.Split(s, 5);
      if (segs.Length >= 4)
      {
        point1.X = Convert.ToInt32(segs[0]);
        point1.Y = Convert.ToInt32(segs[1]);
        point2.X = Convert.ToInt32(segs[2]);
        point2.Y = Convert.ToInt32(segs[3]);
        UpdateAttributes();
      }
    }

    /// <summary>
    /// Update the HTML attributes to reflect actual property values.
    /// </summary>
    private void UpdateAttributes()
    {
      this.element.setAttribute("x1", point1.X.ToString(), 0);
      this.element.setAttribute("y1", point1.Y.ToString(), 0);
      this.element.setAttribute("x2", point2.X.ToString(), 0);
      this.element.setAttribute("y2", point2.Y.ToString(), 0);
    }

    //   .
  }
}


Previous Page | 1 | 2 | 3 | 4 Next Page
TOP 5 ARTICLES
No Top Articles.



MICROSITES
FEATURED TOPIC

ADDITIONAL TOPICS

INFO-LINK