Quantcast
Channel: Visual Studio Integrate forum
Viewing all articles
Browse latest Browse all 4410

VS 2010: infinite loop when implementing IvsFind

$
0
0

My application based on a VS 2010 isolated shell hangs when I implement the VS Find and Replace dialog (aka IVsFindTarget) within our custom editor pane (It’s an usual document window related a node of the hierarchy tree).

The bug occurs when more than one document is opened, we choose the "Look in: All Open documents" option and we perform a Replace All on a specific string (for example Find "1" and Replace All "11").

VS keeps looping infinitely between the Find and Replace for both opened documents so my "1" becomes "11" and when it returns to the initial documents the "11" becomes "1111" and so on and so on.

In our EditorPane, we implemented 3 members ofIVsFindTarget interface that notifies us that a search was requested by the VS Find&Replace dialog. This EditorPane is not text based (It’s a graphical editor) so it does only implement following interface:IVsPersistDocData, IPersistFileFormat, IVsToolboxUser, IVsToolboxActiveUserHook, IOleCommandTarget, IVsFindTarget, IVsWindowFrameNotify3.

Here is the implementation so far (please note the exception handling has been removed for better readability):

intIVsFindTarget.Find(string pszSearch,

                       uint grfOptions,

                       int fResetStartPoint,

                       IVsFindHelper pHelper,

                       outuint pResult )

       {

           pResult = (int)__VSFINDRESULT.VSFR_NotFound;

           try

           {

               var farView = _editorViewasIWbFindAndReplace;

               if (farView != null)

               {

                   if (_findContext ==null)

                       _findContext = newWbFindAndReplaceContext(pHelper, pszSearch, grfOptions);

                   else

                   {

                       _findContext.VsHelper = pHelper;

                       _findContext.PatternSearch = pszSearch;

                       _findContext.SearchOptions = grfOptions;

                   }

                   var findResult = farView.FindAndReplace(_findContext, fResetStartPoint >= 1);

                   switch (findResult)

                   {

                       caseWbFindResult.Cancel:

                           pResult = (int)(__VSFINDRESULT.VSFR_NotFound |__VSFINDRESULT.VSFR_AndInterrupt);

                           break;

                       caseWbFindResult.Error:

                           pResult = (int)__VSFINDRESULT.VSFR_Error;

                           break;

                       caseWbFindResult.Found:

                           pResult = (int)__VSFINDRESULT.VSFR_Found;

                           break;

                       caseWbFindResult.EndOfDocument:

                           pResult = (int)__VSFINDRESULT.VSFR_EndOfDoc;

                           break;

                       caseWbFindResult.NotFound:

                           pResult = (int)__VSFINDRESULT.VSFR_EndOfSearch;

                           break;

                       default:

                           break;

                   }

               }

               returnVSConstants.S_OK;

}

       

intIVsFindTarget.Replace(string pszSearch,

                                       string pszReplace,

                                       uint grfOptions,

                                       int fResetStartPoint,

                                       IVsFindHelper pHelper,

                                   outint pfReplaced)

       {

           pfReplaced = 0;

               var farView = _editorViewasIWbFindAndReplace;

               if (farView != null)

               {

                   if (_replaceContext ==null)

                       _replaceContext = newWbFindAndReplaceContext(pHelper, pszSearch, pszReplace, grfOptions);

                   else

                   {

                       _replaceContext.VsHelper = pHelper;

                       _replaceContext.PatternSearch = pszSearch;

                       _replaceContext.SearchOptions = grfOptions;

                       _replaceContext.ReplacePattern = pszReplace;

                   }

                   var findResult = farView.FindAndReplace(_replaceContext, fResetStartPoint >= 1);

                   switch (findResult)

                   {

                       caseWbFindResult.Found:

                           pfReplaced = 1;

                           break;

                       caseWbFindResult.Error:           // Passtghoug

                       caseWbFindResult.Cancel:          // Passtghoug

                       caseWbFindResult.NotFound:        // Passtghoug

                       caseWbFindResult.EndOfDocument:   // Passtghoug

                       default:

                           break;

                   }

               }

               returnVSConstants.S_OK;

       }

intIVsFindTarget.GetCapabilities(bool[] pfImage,uint[] pgrfOptions)

       {

           // We do NOT support IVsTextImage

           if (pfImage != null&& pfImage.Length> 0)

               pfImage[0] = false;

               if (pgrfOptions != null&& pgrfOptions.Length> 0)

               {

                   pgrfOptions[0] = (uint)__VSFINDOPTIONS.FR_None;

                   var farView = _editorViewasIWbFindAndReplace;

                   if (farView !=null&& farView.IsSupported())

                   {

                       // Scope supported

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_Document;

                       // Options supported

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_MatchCase;

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_WholeWord;

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_Plain;

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_Wildcard;

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_RegExpr;

                       // Action supported

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_Find;

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_FindAll;

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_Replace;

                       pgrfOptions[0] |= (uint)__VSFINDOPTIONS.FR_ReplaceAll;

                   }

               }

               returnVSConstants.S_OK;

       }

intIVsFindTarget.GetProperty(uint propid,outobject pvar)

       {

           pvar = null;

               var ret = VSConstants.S_OK;

               switch ((__VSFTPROPID)propid)

               {

                   case__VSFTPROPID.VSFTPROPID_IsFindInFilesForegroundOnly:

                       pvar = true;

                       break;

                   case__VSFTPROPID.VSFTPROPID_IsDiskFile:

                       pvar = false; // No file

                       break;

                   case__VSFTPROPID.VSFTPROPID_WindowFrame:

                       // Return the Window frame

                       pvar = GetService(typeof(SVsWindowFrame));

                       break;

                   case__VSFTPROPID.VSFTPROPID_InitialPattern:

                   case__VSFTPROPID.VSFTPROPID_InitialPatternAggressive:

                       // Return the selected text

                       var farView = _editorViewasIWbFindAndReplace;

                       if (farView != null)

                           pvar = farView.GetInitialPattern();

                       break;

                   case__VSFTPROPID.VSFTPROPID_BlockName:

                   case__VSFTPROPID.VSFTPROPID_DocName:

                       pvar = _documentMoniker;

                       break;

                   default:

                       ret = VSConstants.E_NOTIMPL;

                       break;

               }

               return ret;

        }

My object "WbFindAndReplaceContext.FindText" will eventually invoke the following using the IVsFindHelper object:

VsHelper.FindInText(  PatternSearch,

                                           null,

                                           SearchOptions,

                                           (int)(__VSFINDBUFFERFLAGS.VSFB_StartOfLine | __VSFINDBUFFERFLAGS.VSFB_EndOfLine),

                                           (uint)bufferArray.Length,

                                           bufferArray,

                                           out indexPatternFound,

                                           out lengthPatternfound,

                                           out computedTextForReplace,

                                           out found );

It seems that the bug occurs because VS is not capable of tagging the documents which have already been searched and thus loops infinitely.

Is it our responsibility to tell VS to stop the search after all documents have been parsed or is there a flag we're not listening to in order to tell it to stop ?



Viewing all articles
Browse latest Browse all 4410

Trending Articles