Visual Studio .NET Google
Release Date: 7/28/2004
| Update Date: 7/28/2004
John Robbins
Download this article: BugsLayer0311.exe (669KB)
In order to complete software development to the most efficiently, the key is to find the answer to the coding problem as much as possible. When we start to search for those answers on the Internet, there is no doubt that goes to use Google. Google is not only the most comprehensive search engine, but also the fastest search engine.
After I learned this, I can't help but feel surprised, there is only a very few developers who will spend time reading Google documents. Google can return a large number of links for any query you propose. In order to make the search truly efficient, the secret is to tell Google how to determine the scope of the search so you can get 100 most suitable answers, rather than a million meaningless results.
In order to better determine the scope of the search, Google establishes a special search group for a specific topic, including information on Microsoft, Apple Macintosh, BSD, Linux, and US Government. For example, your query will only run on a site that mainly includes Microsoft content from http://www.google.com/microsoft.html. To use these specific sites, use your browser to access http://www.google.com/options/specialsearchserches.html.
In addition, you can restrict your search to a single site. Enter "Site:" (without quotation marks) in the search editing control, follow the site you want to search, or you can use the Advanced Search page. For example, to search for MSDN Online, enter "Site: msdn.microsoft.com" before searching for strings.
I greatly want you to read the full Google search document, which is at http://www.google.com/about.html. You can find an answer on the Internet, but you will never find those answers if there is no smart search.
Don't say anything else, single one is the two Google search skills I offer you to read this column article carefully, let alone more prompt skills. Because I am basically a lazy person, I don't like to open the browser every time there is a problem, type "Site: MSDN. Microsoft.com" in the Google search box. I want to click the button to make the Google search just mentioned, and the USENET group, the Google directory also has the entire Web search from Visual Studio .NET. It can be said that it is an outstanding small external program. To take a look at the appearance of this external program, see Figure 1.
Figure 1 Google Add
My original idea is that this column article should be short and practical, providing you with a practical tool for searching Internet. However, I have encountered some very strange restrictions in this external program model, so I have to spend considerable effort to break through these restrictions. I hope that I will make you a lot of trouble when you start developing your own external procedure (and you don't have to swear in front of your computer).
For the rest of this column article, I assume that you are very familiar with how the add-in work and how to write an external knowledge in this area. If you want to catch up with my progress, please read the Bugslayer column articles or Visual Studio .NET documentation in January 2002.
This page
Commandbarsf1 monitoring from hell? True Google External Program Implementation Point Summary Tips
Commandbars from hell
My original design is to put the entire Google add-in in a toolbar. The first control is a combo box that simulates the existing Find Combination box by saving past search. The next control is all buttons from the combo box. The order of these buttons is: Search for MSDN Online, search for Microsoft Site, search the Google group, search the Google directory, search the web.
Toolbars and menus in Visual Studio are Commandbars. Commandbars' documentation indicates that they come from Microsoft Office DLL, ie mso.dll. The Visual Studio .NET documentation did not discuss Commandbars directly, just reference the Microsoft Office documentation. The problem brought about by this document suggests that the functionality of Visual Studio .NET Commandbars is the same as Office Commandbars, but as you will see later, they are not the same. This means you have to figure out your own Visual Basic for Applications in Office XP Developer documents.
Since I already have some experience using Visual Studio .NET Commandbars, I realized that my first task should be the prototype of this combo box so that it can be found. I doubt that this is just an external program model, and the Visual Studio Integration Program (vsip) model may solve this problem, but I haven't confirmed it yet, mainly because writing VSIP code needs more content, and cannot be written Managed code. Since most readers are intended to become a faithful support of this external program, we should eventually find what limitations do they find.
In the source code of this month, you can see the CommandBar test application called Toolbartest in Visual Basic .NET (see the link start section of this article). You may want to compile and install the add-on, so you can see these limitations. The installation can be completed by running the Toolbartest.REG file as part of the project.
The process of adding a combo box is very simple, just the add method of the Controls property in the toolbar. As you can see in the downloadable code, only when calling the IDTEXTENSIBILITY2.ONCONNECTION method and the ext_connectmode parameter is ext_cm_uisetup (this parameter), I will create and fill the toolbar. . Because the user interface installation is only executed, I will find this toolbar that has been created later, and then the toolbar is active.
When the second runtime, the code to find the toolbar is running normally, but the combo box I created in the first location in the toolbar is gone. I am very confused, I think it may be hidden, so I need to cancel it. I quickly prepared a macro to enumerate the control on the toolbar, and I found that the combination of I added was really invisible. I reset the CommandPreeload option to 1. After enforcing the external user interface, the combo box appears after initializing and re-running Visual Studio. But unfortunately, restart will still lose the combo box.
Readers who have some experience in CommandBars may doubt whether I am incorrectly incorrectly incorrectly in calling Commandbars.Controls.Add. True. As you can see, I really add the combo box as a non-dismutor control. At this time, I realized that the external program model has problems, it seems to only save the button. My solution is that when you load an external program in the IDTextensibility2.onConnection method, I found the COMMANDBAR of the add-in and manually insert the combo box into the first location on the toolbar. You can see the code in Connect.AddComboBox in Toolbartest. Although the toolbar cannot save the combo box is somewhat strange, at least you have a way to partially solve the problem. The real problem is this situation: The toolbar is visible, but the add-in is not loaded when starting. In this case, the toolbar will not display correctly. You can see this process in the Toolbartest Address. Although you can tell users to ensure that you can always load an add-in, you can actually differ. If you run Toolbartest, you will find that if the add-in is not loaded, as soon as you click a button, the combo box will appear like a magic because it is the first addition combination box. From the perspective of the user interface, this is not ideal.
Since I didn't think of any solution about the disappearance of the combo frame, I would like to pin on the CommandBarcomboBox.change event from the combo box, which is its uniquely supported event. I hung this event and add several items to the combo box and start testing. As you can see from the code, you will pop up a message box as long as the Change notification is triggered, inform you that the event will be displayed and the text in the combo box can be displayed. In addition, I also histed the IDTCommandTarget.exec method, which also pops up a message box, which has a different title, which includes text in the combo box. At first glance, I can use the mouse to select an item from the drop-down combination box, and I can also trigger the CommandBarComboBox.change event.
Now I have to see what happens when entering the contents in the combination box editing control. I find it correctly to enter a new value and press Enter to pop up the Change Notification - this is the correct response. Similarly, click any button to cause the message box to pop up the corresponding test. But since then, the situation has turned sharply.
Because I want to imitate the Find Combination box of the standard toolbar, I entered some new text, and then click one of the buttons immediately. Worse, the text entered is removed, and the first item in the combination box list is replaced! This looks definitely like a bug and describes the Visual Studio .NET Output Model does not want you to use the combo box in Commandbars. No matter what I use, you cannot stop changing the text. Worse, change the text in the combo box and click anywhere elsewhere elsewhere, causing the input text to be replaced, while the replacement text will issue a Change Notification.
After performing a Spy operation, I saw the standard toolbar Find Combination box and the combination of my toolbar Edit the Windows process of the control. My combo box comes from mso.dll, ie Office XP control DLL, and the Find Combination box edit control comes from vsbrowse.dll, why it is a web browsing package. Because the Find combination frame is normal, its Windows process comes from another DLL, it is clear that the default combo box is not very correct. Although the editable combination box cannot be used normally, it is not a problem with the combination box, so I started a test to see if I can save my idea about a single toolbar. Because Office XP Developer documents indicate, you can actually place a lot of different controls on Commandbar, so I tried to use different MSoControlType controls. I found that in addition to buttons or combo boxes, Commandbars.Controls.Add always triggers anomalies when you try to add controls. I originally thought it also allowed to add edit controls.
Finally, if you create a subclass, the add-in can only add buttons and select the combo box on the toolbar. I am very disappointed, because I think the editable combo box on the toolbar has many uses. Fortunately, at least I have experienced all of CommanDBar, so I understand which controls can be added to the above controls. What controls cannot be added.
Back to top
F1 monitoring?
I wanted to temporarily do some other work, so I think that if I can assign my Google Adds command to some keys, you can use Google search directly in your editor. The final situation is whether I can use some way to display the list of Dynamic Help windows when you edit. In this way, my add-on will search for Google, find the exact same text used by the usual F1 commands. In addition, I don't have to parse the current key from the editing window.
After browsing MSDN Help, I found that the information contained in the "Adding Custom Links to the Dynamic Help Window" is very useful. In the part of how to debug the help topic added to the Dynamic Help, you can know how Visual Studio .NET searches for topics. In the registry key_current_user / software / microsoft / Visualstudio / 7.0 / Dynamic Help, add a new string value "Display Debug Output in Detail" and then set it to YES. After restarting Visual Studio, you will see some of the other details in the Dynamic Help window, as shown in Figure 2.
Figure 2 More details
When you move the cursor to a different area, you will find that the value under Active Context changes according to the movement of the cursor. In fact, what is interesting when clicking around IDE is very interesting.
When browsing the Visual Studio .NET automation document, I uninform to see the ContextAttribute collection, which contains all the properties associated with the global context or window context associated with the Dynamic Help window. When I just use some macros to access each ContextAttribute value (as shown in Figure 3), I found that the DTE object contains a keyword list when the cursor is in the source window.
I plan to check the window of this activity by writing an external connection command. If the window is not a source window, I will use the normal help.f1help command. I found two modes when I run a macro shown in FIG. 3 for multiple projects in order to get information about the mode in the ContextAttribute collection. As I doubt, the first mode is that for different projects, F1 Keywords - Active Context listed in dynamic help - is not always located in the first location in the array. In fact, in the Visual Basic .NET project, it does not seem to follow any special model at all, and may appear anywhere in the array. After another reading the document, I found the highPriorityAttributes property of the DTE object, which seems to imply that it should contain the F1 keyword. After adding the code for checking the properties, HIGHPRIRITITRIBUTES (this process is done in the macro of Figure 3), I found that for the source code window, highpriorityAttributes.count is always zero. This discovery hinders my plan because I want to perform Google search for the same F1 keyword.
The second mode I found in the ContextAttribute collection is that most keywords start with "VB." For applications based on Visual Basic .NET. Since these keywords are actually a keyword specific to the helper engine, this is understandable. Although I can go to "VB.", I am estimated that I am not worth doing, because I can't get F1 keywords.
So far, I have failed on the two main ideas of Google Adds. Since I can't make Visual Studio .NET CommandBar correctly handle the combo box, it is impossible to make sure you can search the correct F1 keyword. I need to take a step to see if I can find another way to enter IDE.
Back to top
Real Google Add
If I can't let Google adds enters CommandBar, I am sure that it can make it a boarding tool window. If you are not familiar with how to host hosts in the tool window, I suggest you access "Automation Samples for Visual Studio .NET", you can download the basic ToolWindow add-in from the web page. The key part of this example is a fill program C COM DLL that assumes a boarding public language runtime (CLR) and all work that loads your user controls to the tool window. As you will see later, I adopted this fill program DLL code, adding an error handling, assertion (so you will know the specific crux when there is a problem), and some other useful features. Since your add-in should load this fillpage and tell the fill program to load what content, you can reuse the improved fill DLL without any change.
You should look back to see screenshots of running Google Adds (see Figure 1). I think the Google window should be placed between the Solution / Class Fixed window and the Properties / Dynamic Help fixed window, which is more convenient to access. You can drag the Google window into the tab next to the Dynamic Help window. If you hide the Google window, the View | Other Windows pop-up menu will use Google Search Window as the first. You can also assign a key combination such as Alt F1 (can be used on the default keyboard) to Googleaddin.ViewGoogle commands. Because I can control the combo box in the Google window, so I will make the health of the combo box are exactly the same as the FIND combo box in the standard toolbar. Anything you typed in the edit control will be added to the combo box and save the search between the IDE run. Just as I explained in this column article, the button distributed at the top of the control will execute a special search.
When you click on one of the search buttons, the add-in will boot the browser window according to your Help settings. If you have selected the MSDN Help system outside, a complete browser window will pop up outside the IDE. If you have selected internal help, open a browser window in the IDE. You can override the default settings in the options.
As all excellent add-on, Google Adds have a correctly integrated Options conversation property page, as shown in Figure 4. All options in the Settings section can see its meaning from the literal, but I just want to mention it, the Default Google Site drop-down list allows you to specify which international Google version you want to use. I found all international sites on http://www.google.com/language_tools.
Figure 4 Google Adder Options Page
Group Limits String Text allows you to specify which groups are listed in. By default, the search will be restricted to the "Comp. *" Group. If you wish to limit the search to the USENENENENEN group hosted by Microsoft, you can use "Microsoft.Public. *" Instead of this text.
Back to top
Implementation points
For Google Add, I want to use a little time to discuss several interesting implementation points. If you are not familiar with the add-in, and if you want to know how I put the options property page in the Options dialog, please read the Leo Notenboom's MSDN Magazine Article "Custom Add-insid You Maximize The Productivity of Visual Studio .NET ".
The first problem I want to solve is how to control the built-in browser window in Visual Studio .NET. After understanding each window type in the constant of vsWindowkind *, you can know that there is a vswindowkindwebbrowser, which is a Window containing a web browser. The average person can realize that the content in this window is an instance of ShDocvw.Webbrowser, and you will master its usage and find it is useful. Unfortunately, I can't determine how to get the actual web browser control to call the shdocvw.webbrowser.navigate method.
The Window class has an Object property, which says it returns an interface or object that can be accessed by name at runtime. Although this paragraph is particularly blurred, I think there is since I write Google add-in use with C #, I should try to convert the returned object to ShDocvw.WebBBBBBBBBBBBBROWSER, and then see what it will produce. After adding a reference to ShDocvw.dll to the project, I installed the code in Figure 5. Although there is no document description, it is very effective for converting Window.Object values to shdocvw.webbrowser. What is even more pleased, calling the NaviGate method to automatically display the web toolbar and put the URL in the browsing address combo box.
After verifying that I can control the internal web browser window in the IDE, I started to create a practical control, this process is nothing special. However, I want to completely debug and testing the control before using the control within IDE. Although the .NET user control resides in an external program can be developed and commissioned, I don't want to do this. GoogleControl.dll with the corresponding name contains the UI of the control.
Because I hope that the control is independent, all logic used to establish Google Search URL is in GoogleControl.btnbar_ButtonClick. Just perform several different categories of search and find a common element, you can draw each parameter. The only more interesting design decision I made is that I don't want to access the IDE control itself to open a window, so when pressing a special search button, the control triggers its GoogleSearch event, the event The parameter contains a complete URL. In this way, the application with control can generate the browser window according to the situation.
When boarding the Google control, I have little known to choose the usage event will lead to some serious tricky problems. As mentioned earlier, Microsoft provides a fillpoint control with an example of an external program. All of the reasons for this fill program is that Visual Studio .NET IDE is an ActiveX host, and the .NET framework does not create an ActiveX control. Your add-in will create a TOOLWINDOW to inform it to host the population. Once you create ToolWindow, you have to access the fill program in this ToolWindow to inform it to board the CLR and create a specific control. If you can exercise Figure 6 CVSNetToolwinshim :: HostuserControl2 and CVSNetToolwinshim :: FinalConstruct method, it will provide a large guidance. Complete VSNetToolHostShim.cpp is located in VSNetToolHostShim2Project.
Although the Microsoft Control requires some formal assertions, it works well. However, since GoogleControl triggers an event because the button is pressed, I realize that the Microsoft code will not help. Although creating code and everything goes well, you can't access the actual boarding CLR control within the VsNethostShim ActiveX control. If you cannot access the control, you cannot receive event notifications, or you cannot call the control itself.
After experiencing a moment, considering the reinforcement of Google Control, I remembered the System.Runtime.Remoting.ObjectHandle.Remoting.ObjectHandle.Remoting.ObjectHandle. Remoting.ObjectHandle class that allows the application domain to pass the application domain while the control instance. If I can get the IObjectToolHostshim2 that returns C # code in some way, the problem is completely solved. It is happy that call Appdomain.createInstance (it is a method you must call in CVSNetToolwinshim :: HostControl2 to create a .NET object) will return to the IObjectHandle interface. The result of this approach is that the Microsoft host fill program has included IOBJECTHANDLE interfaces in its implementation, but there is no way to disclose it. What I need to do is to add a new method to the ObjectHandle class member data just on the IID_IOBJECTHANDLE. Add a new method. You can see this line code in the CVSNetToolwinshim :: getObjectHandle method.
Once you have written in .NET, you have to include ObjectHandle, you have to call the unwrap method, and then force the return value to the appropriate type, so you get a reference to the host control. Although I really want the CVSNetToolwinshim :: getObjectHandle method to return to ObjectHandle directly (which can be done by importing Mscoree.IDL in VSNetToolHostShim2.idl), but the mscoree.idl file contains references to files that do not exist, so if imported or If Mscoree.h is included in the IDL file, the mscoree.idl file will not compile. So I returned to iUnknown, you need to convert the return value to ObjectHandle to call the unwrap method.
If the last few sectors don't understand, you need to refer to Figure 7, Figure 7 shows how to create ToolWindow in the Google Adds and make Google Control to properly place. For your own tool window, you can use code to ensure that the host control can be installed correctly.
For all of these operations made around the VSNetToolHostShim2 control, you can use the control in full accordance with any controls you want to host in Visual Studio .NET in an existing form. With VSNetToolHostShim2, you can now handle the control of the trigger event. You can better separate the functions like I have dealt with Google controls, which may enable dreams that can be inserted into a real reusable control in multiple applications.
The last task of the Google Add program is to seamlessly integrate it into the environment, I want to add a Google Search Window option to the View | Other Windows pop-up menu. According to my understanding of the document, I need to do "& view" commandbar, have been enumerating the Other Windows pop-up menu, and then insert my command at the end of the pop-up menu. I didn't think this will become a big problem, but I have done this with a wrong assumption.
My first step is to write the following macros, enumerate the various items on the "& View" menu, and then return to their type:
Sub cotmenu ()
DIM CW as new cmdwindowcw.clear ()
DIM CMDS AS _COMMAMANDBARS
Cmds = ctype (DTE.Commandbars, _Commandbars)
Dim filemenu as commandbar = cmds ("& view")
For Each Ctrl As CommandBarcontrol in FileMenu.Controls
CW.writeline (Ctrl.caption VBTAB Ctrl.Type.Tostring ())
NEXT
End Sub
By the way, CMDWindow is a simple class that encapsulates the contents to the Command window and Output pane. My idea about macro is to enumerate the control, then output it, so I can know which values do you need.
But I am surprised to see that the Other Windows menu is not listed in the output, and there is no other type in addition to MSoControlButton for each menu item. By clicking around, I found that you can easily enumerate the Other Windows menu so you can easily add my menu option to the correct location. My assumption is that I can get the MSoControlPopup type from CommandBar directly.
Back to top
to sum up
Although the entire process has a lot of errors, it is finally completed this daily access to an external program that resolves the emergence of development issues. Google is a great search engine, now I embed it in my IDE, I really don't know what it should be.
Back to top
prompt
In my last column article, only one of the two prompts due to the tension of the layout. In order to make up for the lack of this prompt, you can see three this month! If you have any experience to be published, please send them to me by email, my email address is john@wintellect.com.
Tip 56 The Microsoft Visual Studio group has set up some of the functions of Visual Studio to become a collection, and you may find that this collection is very useful. You can visit PowerToys for Visual Studio .NET 2003 to download these addresses. With Visual Basic Commenter, you can add XML annotations in Visual Basic .NET, using Custom Help Builder, you can easily add your own class document to your help system, both of which are more than IDEs.
Tip 57 In order to accelerate the startup of Visual Studio .NET IDE, you can cancel the start page. Because START Page needs to load all web browsing components, you can save a lot of startup times by skipping the start page. To turn off Start Page, select Options from the Tools menu to open the Options dialog. In the Environment / General Properties page, select "Show Empty Environment" in the "At Startup" combo box.
Tip 58 Another Performance Tip is to close the tracking activity options in the Solution Explorer window. This way you can avoid Solution Explorer when you operate different files in your project. Select Options from the Tools menu. In the Options dialog, select the Environment / Projects and Solutions Properties page to uncheck the track Active Item in Solution Explorer. If you have any questions and opinions on John, please send email to slayer@microsoft.com.
John Robbins is one of the founders of Wintellect, which is a company dedicated to .NET framework and Windows programming, company business involves software consultation, education and development. His recent book is "Debugging Applications for Microsoft .Net and Microsoft Windows" (Microsoft Press, 2003). You can visit http://www.wintellect.com to contact John.
Puck from MSDN Magazine in November 2003.
This magazine can be booked from local newsstands or by subscribing to purchase.