Loading ...
Sorry, an error occurred while loading the content.
 

CreateToolWindow in 2003 without a shim - works for me

Expand Messages
  • matt_mastracci
    I managed to get CreateToolWindow working without using the shim classes and without having place it in a try{}catch{} block to do it twice. My ToolWindow s
    Message 1 of 8 , Nov 30, 2003
      I managed to get CreateToolWindow working without using the shim
      classes and without having place it in a try{}catch{} block to do it
      twice. My ToolWindow's position is remembered every time I start
      VS.NET. I don't know if this information has been posted here, but I
      thought I would mention it for people to try.

      I'll just quickly mention the first way I tried and why it didn't work
      for me. As many of you have probably tried (I found this by Googling
      for CreateToolWindow originally), you can get the tool windows to show
      up by using this method:

      try
      {
      CreateToolWindow(...)
      }
      catch ( Exception )
      {
      CreateToolWindow(...)
      }

      The first time through, of course, the CreateToolWindow will throw an
      exception, requiring it to be done a second time. The first
      toolwindow created with this method will not have its position
      remembered, either. In addition, I've discovered that this method
      will actually crash VS.NET on exit in some cases and I was motivated
      to find a better way of doing it.

      My method relies on the fact that the ActiveX hosting code has a
      certain code path that only gets executed the first time through in
      any AppDomain. This is the code that checks for the IE hosting
      environment and ends up throwing an exception.

      You can, fortunately, eliminate this behaviour by modifying a private
      variable to pretend that the first ActiveX control has already been
      created. From what I can tell in my experiments, this has no ill
      effects and VS.NET has no problems with these windows whatsoever:

      ---
      // Run this code before any CreateToolWindow calls
      Type tp = typeof( System.Windows.Forms.Control );
      tp = tp.GetNestedType( "ActiveXImpl", BindingFlags.NonPublic );
      FieldInfo fi = tp.GetField( "globalActiveXCount", BindingFlags.Static
      | BindingFlags.NonPublic );
      fi.SetValue( null, Convert.ToInt32( fi.GetValue( null ) ) + 1 );
      ---

      By executing this code, you will *not* have an exception thrown on the
      first time through the CreateToolWindow call.

      You could probably do this in a different way by hosting IE in a
      hidden window and pointing it at your control through an HTML file,
      but I haven't tried this.

      With any luck, this can save somebody some head-scratching.

      Matt.
    • matt_mastracci
      After further experimentation it turns out that while the tool window s dock position *is* remembered, the visibility state is often not remembered. This
      Message 2 of 8 , Dec 1, 2003
        After further experimentation it turns out that while the tool
        window's dock position *is* remembered, the visibility state is often
        not remembered. This could likely be a consequence of how I'm
        creating the toolwindow.
      • Matthew Raymer
        Matt, Definitely an interesting idea and worth investigating. Now, for me at least, the most important question is, what was your process of thinking to come
        Message 3 of 8 , Dec 1, 2003
          Matt,

          Definitely an interesting idea and worth investigating.

          Now, for me at least, the most important question is, what was your
          process of thinking to come to this conclusion? I mean, this is
          completely non-linear (which is GOOD - I like non-linear thinking).

          -----Original Message-----
          From: matt_mastracci [mailto:matt_mastracci@...]
          Sent: Monday, December 01, 2003 1:16 PM
          To: vsnetaddin@yahoogroups.com
          Subject: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim -
          works for me

          I managed to get CreateToolWindow working without using the shim
          classes and without having place it in a try{}catch{} block to do it
          twice. My ToolWindow's position is remembered every time I start
          VS.NET. I don't know if this information has been posted here, but I
          thought I would mention it for people to try.

          I'll just quickly mention the first way I tried and why it didn't work
          for me. As many of you have probably tried (I found this by Googling
          for CreateToolWindow originally), you can get the tool windows to show
          up by using this method:

          try
          {
          CreateToolWindow(...)
          }
          catch ( Exception )
          {
          CreateToolWindow(...)
          }

          The first time through, of course, the CreateToolWindow will throw an
          exception, requiring it to be done a second time. The first
          toolwindow created with this method will not have its position
          remembered, either. In addition, I've discovered that this method
          will actually crash VS.NET on exit in some cases and I was motivated
          to find a better way of doing it.

          My method relies on the fact that the ActiveX hosting code has a
          certain code path that only gets executed the first time through in
          any AppDomain. This is the code that checks for the IE hosting
          environment and ends up throwing an exception.

          You can, fortunately, eliminate this behaviour by modifying a private
          variable to pretend that the first ActiveX control has already been
          created. From what I can tell in my experiments, this has no ill
          effects and VS.NET has no problems with these windows whatsoever:

          ---
          // Run this code before any CreateToolWindow calls
          Type tp = typeof( System.Windows.Forms.Control );
          tp = tp.GetNestedType( "ActiveXImpl", BindingFlags.NonPublic );
          FieldInfo fi = tp.GetField( "globalActiveXCount", BindingFlags.Static
          | BindingFlags.NonPublic );
          fi.SetValue( null, Convert.ToInt32( fi.GetValue( null ) ) + 1 );
          ---

          By executing this code, you will *not* have an exception thrown on the
          first time through the CreateToolWindow call.

          You could probably do this in a different way by hosting IE in a
          hidden window and pointing it at your control through an HTML file,
          but I haven't tried this.

          With any luck, this can save somebody some head-scratching.

          Matt.







          Yahoo! Groups Sponsor


          ADVERTISEMENT

          <http://rd.yahoo.com/SIG=12c5a46c7/M=267637.4116732.5333197.1261774/D=eg
          roupweb/S=1705007207:HM/EXP=1070368983/A=1853619/R=0/*http:/www.netflix.
          com/Default?mqso=60178356&partid=4116732> click here


          <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
          pmail/S=:HM/A=1853619/rand=624893911>

          Replies go to the entire list. Visit
          http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search message
          archives, or change delivery options.



          Your use of Yahoo! Groups is subject to the Yahoo!
          <http://docs.yahoo.com/info/terms/> Terms of Service.


          [Non-text portions of this message have been removed]
        • matt_mastracci
          Well, my processes generally tend to be non-linear, but I can summarize here. :) Basically, I wanted to use CreateToolWindow, so I googled for it (as usual).
          Message 4 of 8 , Dec 2, 2003
            Well, my processes generally tend to be non-linear, but I can
            summarize here. :)

            Basically, I wanted to use CreateToolWindow, so I googled for it (as
            usual). The first non-Microsoft link (I always look for non-Microsoft
            resources first - they usually explain the gotchas :)) was:

            http://weblogs.asp.net/dstone/posts/8253.aspx

            In this blog, he describes how to use CreateToolWindow with a
            try{}catch{} block to guarantee creation. I simplified his code to:

            try
            {
            CreateToolWindow(...)
            }
            catch()
            {
            CreateToolWindow(...)
            }

            When I booted my addin up in VS.NET, I noticed that my tool window was
            always coming up undocked. What I also noticed is that it *was*
            docked before the exception in the debugger was thrown on the first
            CreateToolWindow call above.

            My theory was that the act of throwing the exception within
            CreateToolWindow was causing VS.NET to forget the dock state. Made
            sense to me. :)

            I was creating a hidden tool window to do some command dispatching on
            the UI thread. This was created earlier in my add-in development
            process because I wasn't sure what sort of COM threading model the
            VS.NET classes used. Probably just a habit from my non-Windows
            programming. I switched the order of my CreateToolWindow() calls so
            that my hidden window was first. My visible tool window now
            remembered its position and dockstate! I assumed that my invisible
            tool window was not remembering this state, but it wasn't important to
            me anyways.

            This was working for me, but it seemed to cause VS.NET to crash 90% of
            the time when a solution was open and the user clicked the top-left
            close button. Trial-and-error (commenting out functionality in the
            addin) led me to the CreateToolWindow calls.

            I theorized that since I wasn't doing anything too complicated with
            the tool windows, it must be the try{}catch{} hack. I also took the
            leap that something about throwing an error during the
            CreateToolWindow() call was corrupting something within VS.NET
            (perhaps updating a collection with null, or an invalid pointer).

            Using this, I checked out the ActiveX code in
            System.Windows.Forms.Control with reflector, in an attempt to stop the
            first CreateToolWindow from failing. My theory at this point was, to
            explain the fact that only the first CreateToolWindow call was
            failing, the problem must lie in some first-time-through
            initialization code. Reflector confirmed this.

            Since I had proof that something was being done the first time through
            (and I couldn't see any calls that were truly required the
            first-time-through), I pointed the reflection classes at the global
            static integer I discovered in Reflector and boom! It worked. :)

            I still believe that you might be able to do this another way by
            hosting IE invisibly and pointing it at one of your .NET controls. It
            might be the "safe way" to modify that global variable.

            Matt.

            --- In vsnetaddin@yahoogroups.com, "Matthew Raymer"
            <maraymer_1970@y...> wrote:
            > Matt,
            >
            > Definitely an interesting idea and worth investigating.
            >
            > Now, for me at least, the most important question is, what was your
            > process of thinking to come to this conclusion? I mean, this is
            > completely non-linear (which is GOOD - I like non-linear thinking).
            >
            > -----Original Message-----
            > From: matt_mastracci [mailto:matt_mastracci@y...]
            > Sent: Monday, December 01, 2003 1:16 PM
            > To: vsnetaddin@yahoogroups.com
            > Subject: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim -
            > works for me
            >
            > I managed to get CreateToolWindow working without using the shim
            > classes and without having place it in a try{}catch{} block to do it
            > twice. My ToolWindow's position is remembered every time I start
            > VS.NET. I don't know if this information has been posted here, but I
            > thought I would mention it for people to try.
            >
            > I'll just quickly mention the first way I tried and why it didn't work
            > for me. As many of you have probably tried (I found this by Googling
            > for CreateToolWindow originally), you can get the tool windows to show
            > up by using this method:
            >
            > try
            > {
            > CreateToolWindow(...)
            > }
            > catch ( Exception )
            > {
            > CreateToolWindow(...)
            > }
            >
            > The first time through, of course, the CreateToolWindow will throw an
            > exception, requiring it to be done a second time. The first
            > toolwindow created with this method will not have its position
            > remembered, either. In addition, I've discovered that this method
            > will actually crash VS.NET on exit in some cases and I was motivated
            > to find a better way of doing it.
            >
            > My method relies on the fact that the ActiveX hosting code has a
            > certain code path that only gets executed the first time through in
            > any AppDomain. This is the code that checks for the IE hosting
            > environment and ends up throwing an exception.
            >
            > You can, fortunately, eliminate this behaviour by modifying a private
            > variable to pretend that the first ActiveX control has already been
            > created. From what I can tell in my experiments, this has no ill
            > effects and VS.NET has no problems with these windows whatsoever:
            >
            > ---
            > // Run this code before any CreateToolWindow calls
            > Type tp = typeof( System.Windows.Forms.Control );
            > tp = tp.GetNestedType( "ActiveXImpl", BindingFlags.NonPublic );
            > FieldInfo fi = tp.GetField( "globalActiveXCount", BindingFlags.Static
            > | BindingFlags.NonPublic );
            > fi.SetValue( null, Convert.ToInt32( fi.GetValue( null ) ) + 1 );
            > ---
            >
            > By executing this code, you will *not* have an exception thrown on the
            > first time through the CreateToolWindow call.
            >
            > You could probably do this in a different way by hosting IE in a
            > hidden window and pointing it at your control through an HTML file,
            > but I haven't tried this.
            >
            > With any luck, this can save somebody some head-scratching.
            >
            > Matt.
            >
            >
            >
            >
            >
            >
            >
            > Yahoo! Groups Sponsor
            >
            >
            > ADVERTISEMENT
            >
            > <http://rd.yahoo.com/SIG=12c5a46c7/M=267637.4116732.5333197.1261774/D=eg
            > roupweb/S=1705007207:HM/EXP=1070368983/A=1853619/R=0/*http:/www.netflix.
            > com/Default?mqso=60178356&partid=4116732> click here
            >
            >
            > <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
            > pmail/S=:HM/A=1853619/rand=624893911>
            >
            > Replies go to the entire list. Visit
            > http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search message
            > archives, or change delivery options.
            >
            >
            >
            > Your use of Yahoo! Groups is subject to the Yahoo!
            > <http://docs.yahoo.com/info/terms/> Terms of Service.
            >
            >
            > [Non-text portions of this message have been removed]
          • Matthew Raymer
            Matt, Cool work! I m not that familiar with reflector. Could you give a sample of how you used it in the diagnosis of the problem? Matthew ... From:
            Message 5 of 8 , Dec 2, 2003
              Matt,

              Cool work! I'm not that familiar with reflector. Could you give a
              sample of how you used it in the diagnosis of the problem?

              Matthew

              -----Original Message-----
              From: matt_mastracci [mailto:matt_mastracci@...]
              Sent: Tuesday, December 02, 2003 10:31 PM
              To: vsnetaddin@yahoogroups.com
              Subject: Re: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim
              - works for me

              Well, my processes generally tend to be non-linear, but I can
              summarize here. :)

              Basically, I wanted to use CreateToolWindow, so I googled for it (as
              usual). The first non-Microsoft link (I always look for non-Microsoft
              resources first - they usually explain the gotchas :)) was:

              http://weblogs.asp.net/dstone/posts/8253.aspx

              In this blog, he describes how to use CreateToolWindow with a
              try{}catch{} block to guarantee creation. I simplified his code to:

              try
              {
              CreateToolWindow(...)
              }
              catch()
              {
              CreateToolWindow(...)
              }

              When I booted my addin up in VS.NET, I noticed that my tool window was
              always coming up undocked. What I also noticed is that it *was*
              docked before the exception in the debugger was thrown on the first
              CreateToolWindow call above.

              My theory was that the act of throwing the exception within
              CreateToolWindow was causing VS.NET to forget the dock state. Made
              sense to me. :)

              I was creating a hidden tool window to do some command dispatching on
              the UI thread. This was created earlier in my add-in development
              process because I wasn't sure what sort of COM threading model the
              VS.NET classes used. Probably just a habit from my non-Windows
              programming. I switched the order of my CreateToolWindow() calls so
              that my hidden window was first. My visible tool window now
              remembered its position and dockstate! I assumed that my invisible
              tool window was not remembering this state, but it wasn't important to
              me anyways.

              This was working for me, but it seemed to cause VS.NET to crash 90% of
              the time when a solution was open and the user clicked the top-left
              close button. Trial-and-error (commenting out functionality in the
              addin) led me to the CreateToolWindow calls.

              I theorized that since I wasn't doing anything too complicated with
              the tool windows, it must be the try{}catch{} hack. I also took the
              leap that something about throwing an error during the
              CreateToolWindow() call was corrupting something within VS.NET
              (perhaps updating a collection with null, or an invalid pointer).

              Using this, I checked out the ActiveX code in
              System.Windows.Forms.Control with reflector, in an attempt to stop the
              first CreateToolWindow from failing. My theory at this point was, to
              explain the fact that only the first CreateToolWindow call was
              failing, the problem must lie in some first-time-through
              initialization code. Reflector confirmed this.

              Since I had proof that something was being done the first time through
              (and I couldn't see any calls that were truly required the
              first-time-through), I pointed the reflection classes at the global
              static integer I discovered in Reflector and boom! It worked. :)

              I still believe that you might be able to do this another way by
              hosting IE invisibly and pointing it at one of your .NET controls. It
              might be the "safe way" to modify that global variable.

              Matt.

              --- In vsnetaddin@yahoogroups.com, "Matthew Raymer"
              <maraymer_1970@y...> wrote:
              > Matt,
              >
              > Definitely an interesting idea and worth investigating.
              >
              > Now, for me at least, the most important question is, what was your
              > process of thinking to come to this conclusion? I mean, this is
              > completely non-linear (which is GOOD - I like non-linear thinking).
              >
              > -----Original Message-----
              > From: matt_mastracci [mailto:matt_mastracci@y...]
              > Sent: Monday, December 01, 2003 1:16 PM
              > To: vsnetaddin@yahoogroups.com
              > Subject: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim -
              > works for me
              >
              > I managed to get CreateToolWindow working without using the shim
              > classes and without having place it in a try{}catch{} block to do it
              > twice. My ToolWindow's position is remembered every time I start
              > VS.NET. I don't know if this information has been posted here, but I
              > thought I would mention it for people to try.
              >
              > I'll just quickly mention the first way I tried and why it didn't work
              > for me. As many of you have probably tried (I found this by Googling
              > for CreateToolWindow originally), you can get the tool windows to show
              > up by using this method:
              >
              > try
              > {
              > CreateToolWindow(...)
              > }
              > catch ( Exception )
              > {
              > CreateToolWindow(...)
              > }
              >
              > The first time through, of course, the CreateToolWindow will throw an
              > exception, requiring it to be done a second time. The first
              > toolwindow created with this method will not have its position
              > remembered, either. In addition, I've discovered that this method
              > will actually crash VS.NET on exit in some cases and I was motivated
              > to find a better way of doing it.
              >
              > My method relies on the fact that the ActiveX hosting code has a
              > certain code path that only gets executed the first time through in
              > any AppDomain. This is the code that checks for the IE hosting
              > environment and ends up throwing an exception.
              >
              > You can, fortunately, eliminate this behaviour by modifying a private
              > variable to pretend that the first ActiveX control has already been
              > created. From what I can tell in my experiments, this has no ill
              > effects and VS.NET has no problems with these windows whatsoever:
              >
              > ---
              > // Run this code before any CreateToolWindow calls
              > Type tp = typeof( System.Windows.Forms.Control );
              > tp = tp.GetNestedType( "ActiveXImpl", BindingFlags.NonPublic );
              > FieldInfo fi = tp.GetField( "globalActiveXCount", BindingFlags.Static
              > | BindingFlags.NonPublic );
              > fi.SetValue( null, Convert.ToInt32( fi.GetValue( null ) ) + 1 );
              > ---
              >
              > By executing this code, you will *not* have an exception thrown on the
              > first time through the CreateToolWindow call.
              >
              > You could probably do this in a different way by hosting IE in a
              > hidden window and pointing it at your control through an HTML file,
              > but I haven't tried this.
              >
              > With any luck, this can save somebody some head-scratching.
              >
              > Matt.
              >
              >
              >
              >
              >
              >
              >
              > Yahoo! Groups Sponsor
              >
              >
              > ADVERTISEMENT
              >
              >
              <http://rd.yahoo.com/SIG=12c5a46c7/M=267637.4116732.5333197.1261774/D=eg
              >
              roupweb/S=1705007207:HM/EXP=1070368983/A=1853619/R=0/*http:/www.netflix.
              > com/Default?mqso=60178356&partid=4116732> click here
              >
              >
              >
              <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
              > pmail/S=:HM/A=1853619/rand=624893911>
              >
              > Replies go to the entire list. Visit
              > http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search
              message
              > archives, or change delivery options.
              >
              >
              >
              > Your use of Yahoo! Groups is subject to the Yahoo!
              > <http://docs.yahoo.com/info/terms/> Terms of Service.
              >
              >
              > [Non-text portions of this message have been removed]





              Yahoo! Groups Sponsor


              ADVERTISEMENT

              <http://rd.yahoo.com/SIG=12c6slrml/M=267637.4116732.5333197.1261774/D=eg
              roupweb/S=1705007207:HM/EXP=1070461957/A=1853619/R=0/*http:/www.netflix.
              com/Default?mqso=60178356&partid=4116732> click here


              <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
              pmail/S=:HM/A=1853619/rand=904092239>

              Replies go to the entire list. Visit
              http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search message
              archives, or change delivery options.



              Your use of Yahoo! Groups is subject to the Yahoo!
              <http://docs.yahoo.com/info/terms/> Terms of Service.


              [Non-text portions of this message have been removed]
            • matt_mastracci
              It s tough to describe my style. I ve been debugging, decompiling and disassembling in various forms for over 15 years. :) Basically, if you get an exception
              Message 6 of 8 , Dec 2, 2003
                It's tough to describe my style. I've been debugging, decompiling and
                disassembling in various forms for over 15 years. :)

                Basically, if you get an exception thrown from somewhere in the
                Framework, fire up Reflector and point it at the method where the
                exception was raised. Use logic to pinpoint the conditions that could
                allow you to find yourself throwing that exception, using the
                available source. Once you've got the conditions nailed, figure out
                what could cause those. Repeat until you've got an idea of what went
                wrong. :)

                Matt.

                --- In vsnetaddin@yahoogroups.com, "Matthew Raymer"
                <maraymer_1970@y...> wrote:
                > Matt,
                >
                > Cool work! I'm not that familiar with reflector. Could you give a
                > sample of how you used it in the diagnosis of the problem?
                >
                > Matthew
                >
                > -----Original Message-----
                > From: matt_mastracci [mailto:matt_mastracci@y...]
                > Sent: Tuesday, December 02, 2003 10:31 PM
                > To: vsnetaddin@yahoogroups.com
                > Subject: Re: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim
                > - works for me
                >
                > Well, my processes generally tend to be non-linear, but I can
                > summarize here. :)
                >
                > Basically, I wanted to use CreateToolWindow, so I googled for it (as
                > usual). The first non-Microsoft link (I always look for non-Microsoft
                > resources first - they usually explain the gotchas :)) was:
                >
                > http://weblogs.asp.net/dstone/posts/8253.aspx
                >
                > In this blog, he describes how to use CreateToolWindow with a
                > try{}catch{} block to guarantee creation. I simplified his code to:
                >
                > try
                > {
                > CreateToolWindow(...)
                > }
                > catch()
                > {
                > CreateToolWindow(...)
                > }
                >
                > When I booted my addin up in VS.NET, I noticed that my tool window was
                > always coming up undocked. What I also noticed is that it *was*
                > docked before the exception in the debugger was thrown on the first
                > CreateToolWindow call above.
                >
                > My theory was that the act of throwing the exception within
                > CreateToolWindow was causing VS.NET to forget the dock state. Made
                > sense to me. :)
                >
                > I was creating a hidden tool window to do some command dispatching on
                > the UI thread. This was created earlier in my add-in development
                > process because I wasn't sure what sort of COM threading model the
                > VS.NET classes used. Probably just a habit from my non-Windows
                > programming. I switched the order of my CreateToolWindow() calls so
                > that my hidden window was first. My visible tool window now
                > remembered its position and dockstate! I assumed that my invisible
                > tool window was not remembering this state, but it wasn't important to
                > me anyways.
                >
                > This was working for me, but it seemed to cause VS.NET to crash 90% of
                > the time when a solution was open and the user clicked the top-left
                > close button. Trial-and-error (commenting out functionality in the
                > addin) led me to the CreateToolWindow calls.
                >
                > I theorized that since I wasn't doing anything too complicated with
                > the tool windows, it must be the try{}catch{} hack. I also took the
                > leap that something about throwing an error during the
                > CreateToolWindow() call was corrupting something within VS.NET
                > (perhaps updating a collection with null, or an invalid pointer).
                >
                > Using this, I checked out the ActiveX code in
                > System.Windows.Forms.Control with reflector, in an attempt to stop the
                > first CreateToolWindow from failing. My theory at this point was, to
                > explain the fact that only the first CreateToolWindow call was
                > failing, the problem must lie in some first-time-through
                > initialization code. Reflector confirmed this.
                >
                > Since I had proof that something was being done the first time through
                > (and I couldn't see any calls that were truly required the
                > first-time-through), I pointed the reflection classes at the global
                > static integer I discovered in Reflector and boom! It worked. :)
                >
                > I still believe that you might be able to do this another way by
                > hosting IE invisibly and pointing it at one of your .NET controls. It
                > might be the "safe way" to modify that global variable.
                >
                > Matt.
                >
                > --- In vsnetaddin@yahoogroups.com, "Matthew Raymer"
                > <maraymer_1970@y...> wrote:
                > > Matt,
                > >
                > > Definitely an interesting idea and worth investigating.
                > >
                > > Now, for me at least, the most important question is, what was your
                > > process of thinking to come to this conclusion? I mean, this is
                > > completely non-linear (which is GOOD - I like non-linear thinking).
                > >
                > > -----Original Message-----
                > > From: matt_mastracci [mailto:matt_mastracci@y...]
                > > Sent: Monday, December 01, 2003 1:16 PM
                > > To: vsnetaddin@yahoogroups.com
                > > Subject: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim -
                > > works for me
                > >
                > > I managed to get CreateToolWindow working without using the shim
                > > classes and without having place it in a try{}catch{} block to do it
                > > twice. My ToolWindow's position is remembered every time I start
                > > VS.NET. I don't know if this information has been posted here, but I
                > > thought I would mention it for people to try.
                > >
                > > I'll just quickly mention the first way I tried and why it didn't work
                > > for me. As many of you have probably tried (I found this by Googling
                > > for CreateToolWindow originally), you can get the tool windows to show
                > > up by using this method:
                > >
                > > try
                > > {
                > > CreateToolWindow(...)
                > > }
                > > catch ( Exception )
                > > {
                > > CreateToolWindow(...)
                > > }
                > >
                > > The first time through, of course, the CreateToolWindow will throw an
                > > exception, requiring it to be done a second time. The first
                > > toolwindow created with this method will not have its position
                > > remembered, either. In addition, I've discovered that this method
                > > will actually crash VS.NET on exit in some cases and I was motivated
                > > to find a better way of doing it.
                > >
                > > My method relies on the fact that the ActiveX hosting code has a
                > > certain code path that only gets executed the first time through in
                > > any AppDomain. This is the code that checks for the IE hosting
                > > environment and ends up throwing an exception.
                > >
                > > You can, fortunately, eliminate this behaviour by modifying a private
                > > variable to pretend that the first ActiveX control has already been
                > > created. From what I can tell in my experiments, this has no ill
                > > effects and VS.NET has no problems with these windows whatsoever:
                > >
                > > ---
                > > // Run this code before any CreateToolWindow calls
                > > Type tp = typeof( System.Windows.Forms.Control );
                > > tp = tp.GetNestedType( "ActiveXImpl", BindingFlags.NonPublic );
                > > FieldInfo fi = tp.GetField( "globalActiveXCount", BindingFlags.Static
                > > | BindingFlags.NonPublic );
                > > fi.SetValue( null, Convert.ToInt32( fi.GetValue( null ) ) + 1 );
                > > ---
                > >
                > > By executing this code, you will *not* have an exception thrown on the
                > > first time through the CreateToolWindow call.
                > >
                > > You could probably do this in a different way by hosting IE in a
                > > hidden window and pointing it at your control through an HTML file,
                > > but I haven't tried this.
                > >
                > > With any luck, this can save somebody some head-scratching.
                > >
                > > Matt.
                > >
                > >
                > >
                > >
                > >
                > >
                > >
                > > Yahoo! Groups Sponsor
                > >
                > >
                > > ADVERTISEMENT
                > >
                > >
                > <http://rd.yahoo.com/SIG=12c5a46c7/M=267637.4116732.5333197.1261774/D=eg
                > >
                > roupweb/S=1705007207:HM/EXP=1070368983/A=1853619/R=0/*http:/www.netflix.
                > > com/Default?mqso=60178356&partid=4116732> click here
                > >
                > >
                > >
                > <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
                > > pmail/S=:HM/A=1853619/rand=624893911>
                > >
                > > Replies go to the entire list. Visit
                > > http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search
                > message
                > > archives, or change delivery options.
                > >
                > >
                > >
                > > Your use of Yahoo! Groups is subject to the Yahoo!
                > > <http://docs.yahoo.com/info/terms/> Terms of Service.
                > >
                > >
                > > [Non-text portions of this message have been removed]
                >
                >
                >
                >
                >
                > Yahoo! Groups Sponsor
                >
                >
                > ADVERTISEMENT
                >
                > <http://rd.yahoo.com/SIG=12c6slrml/M=267637.4116732.5333197.1261774/D=eg
                > roupweb/S=1705007207:HM/EXP=1070461957/A=1853619/R=0/*http:/www.netflix.
                > com/Default?mqso=60178356&partid=4116732> click here
                >
                >
                > <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
                > pmail/S=:HM/A=1853619/rand=904092239>
                >
                > Replies go to the entire list. Visit
                > http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search message
                > archives, or change delivery options.
                >
                >
                >
                > Your use of Yahoo! Groups is subject to the Yahoo!
                > <http://docs.yahoo.com/info/terms/> Terms of Service.
                >
                >
                > [Non-text portions of this message have been removed]
              • Matthew Raymer
                Sort of cool. I m familiar with using exception handling and I ve done some work with system.reflection. So, I guess I ll have to wait and see if I need to
                Message 7 of 8 , Dec 2, 2003
                  Sort of cool. I'm familiar with using exception handling and I've done
                  some work with system.reflection. So, I guess I'll have to wait and see
                  if I need to go back to the ToolWindow in the future. It would be cool
                  to be free of the shim.



                  -----Original Message-----
                  From: matt_mastracci [mailto:matt_mastracci@...]
                  Sent: Wednesday, December 03, 2003 11:07 AM
                  To: vsnetaddin@yahoogroups.com
                  Subject: Re: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim
                  - works for me

                  It's tough to describe my style. I've been debugging, decompiling and
                  disassembling in various forms for over 15 years. :)

                  Basically, if you get an exception thrown from somewhere in the
                  Framework, fire up Reflector and point it at the method where the
                  exception was raised. Use logic to pinpoint the conditions that could
                  allow you to find yourself throwing that exception, using the
                  available source. Once you've got the conditions nailed, figure out
                  what could cause those. Repeat until you've got an idea of what went
                  wrong. :)

                  Matt.

                  --- In vsnetaddin@yahoogroups.com, "Matthew Raymer"
                  <maraymer_1970@y...> wrote:
                  > Matt,
                  >
                  > Cool work! I'm not that familiar with reflector. Could you give a
                  > sample of how you used it in the diagnosis of the problem?
                  >
                  > Matthew
                  >
                  > -----Original Message-----
                  > From: matt_mastracci [mailto:matt_mastracci@y...]
                  > Sent: Tuesday, December 02, 2003 10:31 PM
                  > To: vsnetaddin@yahoogroups.com
                  > Subject: Re: [news] [vsnetaddin] CreateToolWindow in 2003 without a
                  shim
                  > - works for me
                  >
                  > Well, my processes generally tend to be non-linear, but I can
                  > summarize here. :)
                  >
                  > Basically, I wanted to use CreateToolWindow, so I googled for it (as
                  > usual). The first non-Microsoft link (I always look for non-Microsoft
                  > resources first - they usually explain the gotchas :)) was:
                  >
                  > http://weblogs.asp.net/dstone/posts/8253.aspx
                  >
                  > In this blog, he describes how to use CreateToolWindow with a
                  > try{}catch{} block to guarantee creation. I simplified his code to:
                  >
                  > try
                  > {
                  > CreateToolWindow(...)
                  > }
                  > catch()
                  > {
                  > CreateToolWindow(...)
                  > }
                  >
                  > When I booted my addin up in VS.NET, I noticed that my tool window was
                  > always coming up undocked. What I also noticed is that it *was*
                  > docked before the exception in the debugger was thrown on the first
                  > CreateToolWindow call above.
                  >
                  > My theory was that the act of throwing the exception within
                  > CreateToolWindow was causing VS.NET to forget the dock state. Made
                  > sense to me. :)
                  >
                  > I was creating a hidden tool window to do some command dispatching on
                  > the UI thread. This was created earlier in my add-in development
                  > process because I wasn't sure what sort of COM threading model the
                  > VS.NET classes used. Probably just a habit from my non-Windows
                  > programming. I switched the order of my CreateToolWindow() calls so
                  > that my hidden window was first. My visible tool window now
                  > remembered its position and dockstate! I assumed that my invisible
                  > tool window was not remembering this state, but it wasn't important to
                  > me anyways.
                  >
                  > This was working for me, but it seemed to cause VS.NET to crash 90% of
                  > the time when a solution was open and the user clicked the top-left
                  > close button. Trial-and-error (commenting out functionality in the
                  > addin) led me to the CreateToolWindow calls.
                  >
                  > I theorized that since I wasn't doing anything too complicated with
                  > the tool windows, it must be the try{}catch{} hack. I also took the
                  > leap that something about throwing an error during the
                  > CreateToolWindow() call was corrupting something within VS.NET
                  > (perhaps updating a collection with null, or an invalid pointer).
                  >
                  > Using this, I checked out the ActiveX code in
                  > System.Windows.Forms.Control with reflector, in an attempt to stop the
                  > first CreateToolWindow from failing. My theory at this point was, to
                  > explain the fact that only the first CreateToolWindow call was
                  > failing, the problem must lie in some first-time-through
                  > initialization code. Reflector confirmed this.
                  >
                  > Since I had proof that something was being done the first time through
                  > (and I couldn't see any calls that were truly required the
                  > first-time-through), I pointed the reflection classes at the global
                  > static integer I discovered in Reflector and boom! It worked. :)
                  >
                  > I still believe that you might be able to do this another way by
                  > hosting IE invisibly and pointing it at one of your .NET controls. It
                  > might be the "safe way" to modify that global variable.
                  >
                  > Matt.
                  >
                  > --- In vsnetaddin@yahoogroups.com, "Matthew Raymer"
                  > <maraymer_1970@y...> wrote:
                  > > Matt,
                  > >
                  > > Definitely an interesting idea and worth investigating.
                  > >
                  > > Now, for me at least, the most important question is, what was your
                  > > process of thinking to come to this conclusion? I mean, this is
                  > > completely non-linear (which is GOOD - I like non-linear thinking).
                  > >
                  > > -----Original Message-----
                  > > From: matt_mastracci [mailto:matt_mastracci@y...]
                  > > Sent: Monday, December 01, 2003 1:16 PM
                  > > To: vsnetaddin@yahoogroups.com
                  > > Subject: [news] [vsnetaddin] CreateToolWindow in 2003 without a shim
                  -
                  > > works for me
                  > >
                  > > I managed to get CreateToolWindow working without using the shim
                  > > classes and without having place it in a try{}catch{} block to do it
                  > > twice. My ToolWindow's position is remembered every time I start
                  > > VS.NET. I don't know if this information has been posted here, but
                  I
                  > > thought I would mention it for people to try.
                  > >
                  > > I'll just quickly mention the first way I tried and why it didn't
                  work
                  > > for me. As many of you have probably tried (I found this by
                  Googling
                  > > for CreateToolWindow originally), you can get the tool windows to
                  show
                  > > up by using this method:
                  > >
                  > > try
                  > > {
                  > > CreateToolWindow(...)
                  > > }
                  > > catch ( Exception )
                  > > {
                  > > CreateToolWindow(...)
                  > > }
                  > >
                  > > The first time through, of course, the CreateToolWindow will throw
                  an
                  > > exception, requiring it to be done a second time. The first
                  > > toolwindow created with this method will not have its position
                  > > remembered, either. In addition, I've discovered that this method
                  > > will actually crash VS.NET on exit in some cases and I was motivated
                  > > to find a better way of doing it.
                  > >
                  > > My method relies on the fact that the ActiveX hosting code has a
                  > > certain code path that only gets executed the first time through in
                  > > any AppDomain. This is the code that checks for the IE hosting
                  > > environment and ends up throwing an exception.
                  > >
                  > > You can, fortunately, eliminate this behaviour by modifying a
                  private
                  > > variable to pretend that the first ActiveX control has already been
                  > > created. From what I can tell in my experiments, this has no ill
                  > > effects and VS.NET has no problems with these windows whatsoever:
                  > >
                  > > ---
                  > > // Run this code before any CreateToolWindow calls
                  > > Type tp = typeof( System.Windows.Forms.Control );
                  > > tp = tp.GetNestedType( "ActiveXImpl", BindingFlags.NonPublic );
                  > > FieldInfo fi = tp.GetField( "globalActiveXCount",
                  BindingFlags.Static
                  > > | BindingFlags.NonPublic );
                  > > fi.SetValue( null, Convert.ToInt32( fi.GetValue( null ) ) + 1 );
                  > > ---
                  > >
                  > > By executing this code, you will *not* have an exception thrown on
                  the
                  > > first time through the CreateToolWindow call.
                  > >
                  > > You could probably do this in a different way by hosting IE in a
                  > > hidden window and pointing it at your control through an HTML file,
                  > > but I haven't tried this.
                  > >
                  > > With any luck, this can save somebody some head-scratching.
                  > >
                  > > Matt.
                  > >
                  > >
                  > >
                  > >
                  > >
                  > >
                  > >
                  > > Yahoo! Groups Sponsor
                  > >
                  > >
                  > > ADVERTISEMENT
                  > >
                  > >
                  >
                  <http://rd.yahoo.com/SIG=12c5a46c7/M=267637.4116732.5333197.1261774/D=eg
                  > >
                  >
                  roupweb/S=1705007207:HM/EXP=1070368983/A=1853619/R=0/*http:/www.netflix.
                  > > com/Default?mqso=60178356&partid=4116732> click here
                  > >
                  > >
                  > >
                  >
                  <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
                  > > pmail/S=:HM/A=1853619/rand=624893911>
                  > >
                  > > Replies go to the entire list. Visit
                  > > http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search
                  > message
                  > > archives, or change delivery options.
                  > >
                  > >
                  > >
                  > > Your use of Yahoo! Groups is subject to the Yahoo!
                  > > <http://docs.yahoo.com/info/terms/> Terms of Service.
                  > >
                  > >
                  > > [Non-text portions of this message have been removed]
                  >
                  >
                  >
                  >
                  >
                  > Yahoo! Groups Sponsor
                  >
                  >
                  > ADVERTISEMENT
                  >
                  >
                  <http://rd.yahoo.com/SIG=12c6slrml/M=267637.4116732.5333197.1261774/D=eg
                  >
                  roupweb/S=1705007207:HM/EXP=1070461957/A=1853619/R=0/*http:/www.netflix.
                  > com/Default?mqso=60178356&partid=4116732> click here
                  >
                  >
                  >
                  <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
                  > pmail/S=:HM/A=1853619/rand=904092239>
                  >
                  > Replies go to the entire list. Visit
                  > http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search
                  message
                  > archives, or change delivery options.
                  >
                  >
                  >
                  > Your use of Yahoo! Groups is subject to the Yahoo!
                  > <http://docs.yahoo.com/info/terms/> Terms of Service.
                  >
                  >
                  > [Non-text portions of this message have been removed]





                  Yahoo! Groups Sponsor


                  ADVERTISEMENT

                  <http://rd.yahoo.com/SIG=12cqq4db6/M=267637.4116732.5333197.1261774/D=eg
                  roupweb/S=1705007207:HM/EXP=1070507252/A=1853619/R=0/*http:/www.netflix.
                  com/Default?mqso=60178356&partid=4116732> click here


                  <http://us.adserver.yahoo.com/l?M=267637.4116732.5333197.1261774/D=egrou
                  pmail/S=:HM/A=1853619/rand=661651245>

                  Replies go to the entire list. Visit
                  http://groups.yahoo.com/group/vsnetaddin to unsubscribe, search message
                  archives, or change delivery options.



                  Your use of Yahoo! Groups is subject to the Yahoo!
                  <http://docs.yahoo.com/info/terms/> Terms of Service.


                  [Non-text portions of this message have been removed]
                • simon_capewell
                  Fantastic, this is exactly what I was looking for. I d already got the try catch block, but was getting a random crash on exit and my tool window wasn t
                  Message 8 of 8 , Feb 18, 2004
                    Fantastic, this is exactly what I was looking for. I'd already got
                    the try catch block, but was getting a random crash on exit and my
                    tool window wasn't remembering its position. Not anymore!

                    Many thanks
                    Simon
                  Your message has been successfully submitted and would be delivered to recipients shortly.