myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » Hotkey-Klasse
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Hotkey-Klasse

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Floste
myCSharp.de-Mitglied

avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.130
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland


Floste ist offline

Hotkey-Klasse

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschreibung:

Mit der Klasse kann man einfach Systemweite Hotkeys installieren.

So benutzt man die Klasse:

C#-Code:
Hotkey h=Hotkey.Register(Keys.A|Keys.Control|Keys.Alt);
h.HotkeyPressed+=...
....
h.Dispose();

Der Hotkey wird unregistriert, sobald der Garbagecollector das Hotkeyobjekt einsammelt. Deshalb muss man eine Referenz halten.

C#-Code:
public class Hotkey:IDisposable
    {
        protected Hotkey()
        { }

        /// <summary>
        /// Registers the hotkey. You have to keep a reference to the returned object.
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        public static Hotkey Register(Keys keys)
        {
            Hotkey ret = new Hotkey();
            ret.keys = keys;
            wnd.Register(ret);
            return ret;
        }

        /// <summary>
        /// Calls Dispose: Unregisters the hotkey
        /// </summary>
        /// <param name="h">The Hotkey</param>
        public static void UnRegister(Hotkey h)
        { h.Dispose(); }

        /// <summary>
        /// Rises when the hotkey is pressed
        /// </summary>
        public event EventHandler HotkeyPressed;

        public object Tag;
        private Keys keys;
        private int id;

        /// <summary>
        /// The keycombination
        /// </summary>
        public Keys Keys
        {
            get { return keys; }
        }

        #region IDisposable Member

        ~Hotkey()
        {
            Dispose();
        }

        bool disposed=false;

        /// <summary>
        /// Unregisters the Hotkey
        /// </summary>
        public void Dispose()
        {
            if (disposed) return;
            disposed=true;
            wnd.UnRegister(this);
        }


        #endregion

        private class wnd : Control
        {
            public wnd()
            {
                Visible=false;
            }

            public static wnd Default
            {
                get
                {
                    if (def == null)
                    {
                        def = new wnd();
                        def.CreateHandle();
                    }
                    return def;
                }
            }

            List<IntPtr> hotkeys=new List<IntPtr>();
            int getNewId(IntPtr item)
            {
                int i = 0;
                foreach(IntPtr r in hotkeys)
                {
                    if ((long)r == 0)
                    {
                        hotkeys[i] = item;
                        return i;
                    }
                    i++;
                }
                hotkeys.Add(item);
                return i;
            }

            IntPtr getObject(int id)
            {
                return hotkeys[id];
            }

            void removeId(int id)
            {
                hotkeys[id] = (IntPtr)0;
            }

            static wnd def;
            public short LOWORD(int l)
            { return ((short)(l & 0xffff));}

            public short HIWORD(int l)
            { return ((short)(l >> 16)); }

            public const int MOD_ALT = 0x1;
            public const int MOD_CONTROL = 0x2;
            public const int MOD_SHIFT = 0x4;
            public const int MOD_WIN = 0x8;
            public const int WM_HOTKEY = 0x312;

            [DllImport("user32.dll")]
            private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

            [DllImport("user32.dll")]
            private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_HOTKEY)
                {
                    Hotkey h = (Hotkey)GCHandle.FromIntPtr(getObject((int)m.WParam)).Target;
                    if (h.HotkeyPressed != null)
                    { h.HotkeyPressed(h, null); }
                }
                else
                    base.WndProc(ref m);
            }

            internal static void Register(Hotkey h)
            {
                h.id=Default.getNewId (GCHandle.ToIntPtr (GCHandle.Alloc (h,GCHandleType.WeakTrackResurrection)));
                int modifiers = 0;
                if ((h.keys & Keys.Alt) == Keys.Alt)
                    modifiers = modifiers | MOD_ALT;
                if ((h.keys & Keys.Control) == Keys.Control)
                    modifiers = modifiers | MOD_CONTROL;
                if ((h.keys & Keys.Shift) == Keys.Shift)
                    modifiers = modifiers | MOD_SHIFT;
                Keys k = h.keys & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;
                RegisterHotKey((IntPtr)Default.Handle, h.id, modifiers, (int)k);
            }

            internal static void UnRegister(Hotkey h)
            {
                try
                {
                    UnregisterHotKey(Default.Handle, h.id);
                }
                catch { }
                GCHandle.FromIntPtr(Default.getObject(h.id)).Free();
                Default.removeId(h.id);
            }
        }
    }

(Die interne Liste führe ich, da ein IntPtr größer als ein int sein kann.)

Schlagwörter: Hotkey systemweit registrieren System global Tastenkombination
05.01.2009 13:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
cH40zLOrd cH40zLOrd ist männlich
myCSharp.de-Mitglied

Dabei seit: 04.07.2008
Beiträge: 14


cH40zLOrd ist offline Füge cH40zLOrd Deiner Kontaktliste hinzu MSN-Passport-Profil von cH40zLOrd anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wenn ich deinen Code verwende und standardmässig STRG+ALT+A drücke, dann kriege ich eine InvalidOperationException mit dem Hinweis "Das Handle wurde nicht initialisiert." auf folgende, fettmarkierte Zeile:

Zitat:
C#-Code:
protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_HOTKEY)
                {
                    Hotkey h = (Hotkey)GCHandle.FromIntPtr(getObject((int)m.WParam)).Target; // hier
                    if (h.HotkeyPressed != null)
                    { h.HotkeyPressed(h, null); }
                }
                else
                    base.WndProc(ref m);
            }
01.03.2009 10:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.130
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland

Themenstarter Thema begonnen von Floste

Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Kann es sein, dass dein Code keine Referenz auf das Objekt hält?
01.03.2009 18:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
kleines_eichhoernchen kleines_eichhoernchen ist männlich
myCSharp.de-Mitglied

avatar-2079.jpg


Dabei seit: 07.11.2006
Beiträge: 3.971
Entwicklungsumgebung: Visual Studio 2005 (C#)
Herkunft: Ursprünglich Vogtland, jetzt Much


kleines_eichhoernchen ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo floste,

C#-Code:
public void Dispose()
        {
            if (disposed) return;
            disposed=true;
            wnd.UnRegister(this);
        }

da ich das erst jetzt sehe, schau dir mal  Dispose implementieren und verwenden an und ergänze dein Dispose noch um

C#-Code:
GC.SuppressFinalize (this);

02.03.2009 08:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Blogscreen Blogscreen ist männlich
myCSharp.de-Mitglied

avatar-2764.gif


Dabei seit: 26.09.2007
Beiträge: 344
Entwicklungsumgebung: VS 2003
Herkunft: Stuttgart


Blogscreen ist offline Füge Blogscreen Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo, existiert ein Testprojekt?

Grüße und danke
02.03.2009 11:01 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Jelly Jelly ist männlich
myCSharp.de-Mitglied

Dabei seit: 09.09.2007
Beiträge: 1.114
Entwicklungsumgebung: Visual Studio 2008/2010/2013
Herkunft: Burden (Luxemburg)


Jelly ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hey, die Klasse kommt mir wie gerufen... Werd in den nächsten Tagen genau so etwas brauchen... Ganz herzlichen Dank.

abs übrigens in einem Testprojekt ausprobiert, und es klappt einwandfrei!
02.03.2009 11:33 Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.130
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland

Themenstarter Thema begonnen von Floste

Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo, existiert ein Testprojekt?

Die klasse ist (fast) exakt so in  cmdFloste enthaqlten.
02.03.2009 11:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Jahr.
Richman007 Richman007 ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.01.2011
Beiträge: 17


Richman007 ist offline Füge Richman007 Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Gibt es zu diesem Quelltext eventuell auch eine Kommentar version?

Weil ich genau diesen Text in einem Projekt habe.

Falls nicht, ist auch nicht so wild. :)
17.01.2011 14:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 3 Monate.
user8744
myCSharp.de-Mitglied

Dabei seit: 22.06.2007
Beiträge: 1.150


user8744 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich hab einfach mal versucht F12 zu registrieren das klappte aber nicht.
A hingegen ging super. Gibts ne Chance die F Tasten auch zu unterstützen?
25.04.2011 04:14 Beiträge des Benutzers | zu Buddylist hinzufügen
Cat
myCSharp.de-Mitglied

avatar-3070.jpg


Dabei seit: 25.10.2009
Beiträge: 771


Cat ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Sebastian,

die "F12"-Taste ist für den System-Debugger reserviert.
Auf die Schnelle habe ich folgende Links dazu gefunden:
 Programm reagiert nach einer Zeit nicht mehr auf Tastatureingaben (wird hier erwähnt)
 Das C# 2010 Codebook (S. 594)
 http://stackoverflow.com/questions/40874...64-with-vs-2008
25.04.2011 10:01 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 3 Monate.
felix
myCSharp.de-Mitglied

Dabei seit: 30.07.2007
Beiträge: 174
Entwicklungsumgebung: Visual Studio 2015


felix ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Floste,

ich habe versucht, wie in deinem Beispiel Strg + Alt + A zu registrieren. [Ich habe eine Konsolenanwendung.] Leider tut sich da bei mir gar nichts. Muss ich noch irgendetwas beachten?
Hier mein Code:

C#-Code:
static void Main(string[] args)
{
    Hotkey h = Hotkey.Register(Keys.A | Keys.Control | Keys.Alt);
    h.HotkeyPressed += new EventHandler(hotkeyPressed);
    Console.ReadLine();

    h.Dispose();
}

static void hotkeyPressed(object sender, EventArgs e)
{
    System.Windows.Forms.MessageBox.Show("hotkey pressed");
}

Betriebssystem: Windows 7 64 Bit (falls das irgendeine Rolle spielt)
04.08.2011 17:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.130
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland

Themenstarter Thema begonnen von Floste

Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

großes Grinsen Du brauchst zwingend eine nachrichtenschleife. Die klasse darf nur innerhalb eines gui-threads verwendet werden, nicht in der console: Ersetz mal Console.ReadLine(); Durch System.Windows.Forms.Application.Run(); dann hast du quasi nen guithread^^

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am 04.08.2011 20:55.

04.08.2011 20:48 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
felix
myCSharp.de-Mitglied

Dabei seit: 30.07.2007
Beiträge: 174
Entwicklungsumgebung: Visual Studio 2015


felix ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Floste,

juhu ... das hat funktioniert. Vielen Dank. ;)
04.08.2011 21:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 11 Jahre.
Der letzte Beitrag ist älter als 8 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 27.05.2020 08:06