2011-08-25 7 views
7

मेरे पास नई वीएस एक्स्टेंसिबिलिटी एपीआई का उपयोग करके एक प्रबंधित वाक्यविन्यास हाइलाइटर है और यह मुझे ITextBuffer देता है, जो कि बढ़िया है।मैं एक EnvDTE से ITextBuffer कैसे प्राप्त कर सकता हूं। विन्डो?

मेरे विस्तार के दूसरे हिस्से में मुझे एक डीटीई ऑब्जेक्ट मिल रहा है और सक्रिय विंडो से जुड़ा हुआ ईवेंट बदल गया है, जो मुझे EnvDTE.Window ऑब्जेक्ट देता है।

var dte = (EnvDTE.DTE)this.GetService(typeof(EnvDTE.DTE)); 
dte.Events.WindowEvents.WindowActivated += WindowEvents_WindowActivated; 
// ... 

private void WindowEvents_WindowActivated(EnvDTE.Window GotFocus, EnvDTE.Window LostFocus) 
{ 
    // ??? 
    // Profit 
} 

मैं इस विधि में आईटीक्स्टबफर को विंडो से बाहर करना चाहता हूं। क्या कोई मुझे ऐसा करने का सीधा आगे बढ़ सकता है?

उत्तर

9

मैं जिस समाधान का उपयोग करता था वह विंडोज पथ प्राप्त करने के लिए IVsEditorAdaptersFactoryService और VsShellUtilities के साथ संयोजन में इसका उपयोग करता था।

var openWindowPath = Path.Combine(window.Document.Path, window.Document.Name); 
var buffer = GetBufferAt(openWindowPath); 

और

internal ITextBuffer GetBufferAt(string filePath) 
{ 
    var componentModel = (IComponentModel)GetService(typeof(SComponentModel)); 
    var editorAdapterFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>(); 
    var serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider(MetaSharpPackage.OleServiceProvider); 

    IVsUIHierarchy uiHierarchy; 
    uint itemID; 
    IVsWindowFrame windowFrame; 
    if (VsShellUtilities.IsDocumentOpen(
    serviceProvider, 
    filePath, 
    Guid.Empty, 
    out uiHierarchy, 
    out itemID, 
    out windowFrame)) 
    { 
    IVsTextView view = VsShellUtilities.GetTextView(windowFrame); 
    IVsTextLines lines; 
    if (view.GetBuffer(out lines) == 0) 
    { 
     var buffer = lines as IVsTextBuffer; 
     if (buffer != null) 
     return editorAdapterFactoryService.GetDataBuffer(buffer); 
    } 
    } 

    return null; 
} 
+0

+1, लेकिन ध्यान दें कि 'IsDocumentOpen()' कभी कभी झूठी लौटाता है जब दस्तावेज़ खोला किए जाने की प्रक्रिया में अब भी है (वी.एस. उपयोगकर्ता कोड करने के लिए, उदाहरण के लिए के लिए बाहर कॉल , खुली खिड़कियों की अपनी आंतरिक सूची अद्यतन करने से पहले फ़ाइल पार्सिंग)। इसके लिए मैंने पाया है कि एकमात्र कामकाज सभी खिड़की के फ्रेम को गिनना है, प्रत्येक के लिए VSFPROPID_ExtWindowObject प्राप्त करें, और इसे EnvDTE.Window (जिसका दस्तावेज़ का पूर्ण नाम वांछित पथ से मेल खाता है) से तुलना करें। – Cameron

+1

इसके अलावा, एम्बेडेड पीक दस्तावेज़ विंडो में 'IVsWindowFrame' नहीं है, जहां तक ​​मैं कह सकता हूं, इसलिए' IsDocumentOpen' विफल हो जाएगा, भले ही दस्तावेज़ चल रहा दस्तावेज़ तालिका में "खुला" है। आप अभी भी 'IVsRunningDocumentTable' की 'FindAndLockDocument' विधि' का उपयोग करके बफर प्राप्त कर सकते हैं (जो 'IsDocumentOpen' आंतरिक रूप से कॉल कर रहा है)। जाहिर है, अगर आपके पास पहले स्थान पर 'EnvDTE.Window' ऑब्जेक्ट है, तो यह लागू नहीं होता है, लेकिन यदि आपके पास पथ है तो इस कोने के मामले के बारे में जानना महत्वपूर्ण है। – Cameron

संबंधित मुद्दे