KeyPress in vs plugin

28 בדצמבר 2012

תגיות: , , , ,
אין תגובות

אחד הדברים שלפעמים נרצה לעשות זה להרשם לאירוע של keypress בתוך ה – text editor של visual studio.

יש כמה דרכים לממש זאת, הדרך הפשוטה היא בעזרת הקוד הבא:

 

Events2 events = (Events2)_applicationObject.Events;

events.TextDocumentKeyPressEvents.AfterKeyPress += AfterKeyPress;

 

כדי לקבל את applicationObject (שהוא ה – DTE) בפרויקט מסוג Package, ניתן לכתוב את הקוד הבא:

DTE2 app = (DTE2)ServiceProvider.GlobalProvider.GetService(typeof(DTE));

בשיטה הזאת צריכים לזכור להחזיק משתנה מסוג ה – event כמשתנה גלובלי, אחרת ה – GC עלול לנקות את הרישום לאירוע.

 

דרך נוספת היא בעזרת MEF, עם ה – API החדש (יחסית) של Visual Studio.

כאן יש דוגמא שמשתמשת ב – MEF כדי לזהות לחיצה על ctrl+1 ולבצע collapse על כל מה שיש ב – text editor מלבד המקטע שבו נמצאים כרגע.

ראשית נגדיר מחלקה שתממש את הממשק IKeyProcessorProvider והיא תראה כך:

[Export(typeof(IKeyProcessorProvider))]

[ContentType("any")]

[Name("MyKeyProc")]

[TextViewRole(PredefinedTextViewRoles.Editable)]

[Order(Before = "DefaultKeyProcessor")]

public class MyKeyProvider : IKeyProcessorProvider

{

    public KeyProcessor GetAssociatedProcessor(IWpfTextView wpfTextView)

    {

        return new MyKeyKeyProc();

    }

}

מטרת פוסט זה הינה לא להסביר וללמוד MEF, ולכן נסתפק בזה שבעזרת MEF וה – attributes שנמצאים על המחלקה, נגיע תמיד למתודה בזמן יצירת TextView חדש.

במתודה זו אנחנו יוצרים מופע של מחלקה שנראית כך:

internal sealed class MyKeyKeyProc : KeyProcessor

{

    public override void KeyDown(KeyEventArgs args)

    {

 

    }

}

באחד הפוסטים הבאים אספר קצת יותר איך עובדים עם MEF בפיתוח של VS PludIns.

הבעייה עם השיטות המתוארות היא שיש חלק מה – KeyDowns שלא מגיעים (למשל לחיצה על לחצן ימני במקלדת) מכיוון שמתי שהוא בקוד של VS האירוע נתפס ומטופל ולא נשלח הלאה, במידה ורוצים בכל זאת לקבל את האירועים, חייבים להשתמש עם מנגנון ה – CommandFilter.

בהינתן שיש לכם אובייקטי מסוג IVsTextView (ניתן לקבל אותו בעזרת MEF על ידי מימוש של IVsTextViewCreationListener), ניתן להשתמש בפונקציית AddCommandFilter.

ראשית נגדיר מחלקה שתראה כך:

internal class KeyPressChain : IOleCommandTarget

{

    internal IOleCommandTarget NextCommandTarget { get; set; }

 

    public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)

    {

        if (pguidCmdGroup == typeof(VSConstants.VSStd2KCmdID).GUID)

        {

            VSConstants.VSStd2KCmdID command = (VSConstants.VSStd2KCmdID)nCmdID;

            if (command == VSConstants.VSStd2KCmdID.PAGEDN)

            {

// do some code

                return VSConstants.S_OK;

            }

        }

 

        return NextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);

    }

 

    public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)

    {

        return NextCommandTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);

    }

}

כעת נרשום את הקוד הבא על ה – IVsTextView

IOleCommandTarget next;

commandFilter = new KeyPressChain();

VsTextView.AddCommandFilter(commandFilter, out next);

commandFilter.NextCommandTarget = next;

 

 

כעת נוכל לקבל את כל האירועים של המקלדת.

בפוסטים הבאים, אספר קצת יותר פרטים על MEF, ועל ה – API הנרחב של פיתוח ל – VS, וכיצד מתחילים לייצר PlugIn.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *