Fragen Packet 1:Tastendruck, Radio, Dirbox



  • Ich vermute mal, dass es sich bei 'Play' und 'Pause' auf deiner Tastatur um Sondertasten handelt?
    Da wirst du wohl einen Keylogger (siehe z.B. unsere FAQ) bemühen müssen, um zu ermitteln, welcher Tastaturcode da gesendet wird.



  • gute idee



  • Guuuut, habs jetzt mit so gemacht:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39144.html

    aber wie unterscheide ich zwischen mehreren verschieden Tasten in der Prozedur ?

    EDIT: die Tasten die ich suchte waren:

    /*
    	VK_MEDIA_NEXT_TRACK (B0)
    	Windows 2000/XP: Next Track key
    
    	VK_MEDIA_PREV_TRACK (B1)
    	Windows 2000/XP: Previous Track key
    
    	VK_MEDIA_STOP (B2)
    	Windows 2000/XP: Stop Media key
    
    	VK_MEDIA_PLAY_PAUSE (B3)
    	Windows 2000/XP: Play/Pause Media key
    	*/
    

    EDIT 2:
    so jetzt:

    String Key = Msg.WParamLo;
    	ShowMessage(Key);
    	if (Key == "49217")
    		CLONE3->Click();
    	if (Key == "49286")
    	{
    		if (paused == 1 || (playing == 0 && paused == 0))
    			CLONE1->Click();
    		else
    			CLONE2->Click();
    	}
    


  • huch, geht nicht mehr ?
    Ich hab einfach neugestartet und weiter nichts, und er bekommt kein Ereigniss mehr, ich such mal.
    (selbst mit MSGBOX kommt nix, also kann ich fürs erste unbeständige Tastennummern ausschließen)

    EDIT: Ist aber unbeständig, habe es jetzt auf dies verbessert:

    String Key = Msg.WParamLo;
    	if (Key == IntToStr(Stop))
    		CLONE3->Click();
    	if (Key == IntToStr(Play_Pause))
    	{
    		if (paused == 1 || (playing == 0 && paused == 0))
    			CLONE1->Click();
    		else
    			CLONE2->Click();
    	}
    	if (Key == IntToStr(NXT))
    	{
    		CLONE4->Click();
    	}
    	if (Key == IntToStr(LST))
    	{
    		CLONE5->Click();
    	}
    

    Doch es wird noch immer das Event nicht ausgelöst

    EDIT 2: Moment O Mein Gott.
    Kein Programm kann reagiert mehr auf Tastendrücke ! liegt das nun am Prog oder am System ?



  • Ich weiß nicht.
    Sobald mein Programm läuft reagiert kein Programm mehr auf die gewünschten Tasten.
    Das ist in sofern gut, dass nur noch mein Prog darauf reagiert, und keine Konflikte entstehen.
    JA ABER WIE SOLLEN DIE ENTSTEHEN, WENN NICHT MAL MEIN PROGRAMM DRAUF REAGIERT ???



  • Hi,

    wenn du nach dem o.g. Link programmiert hast, ist es ein HotKey?



  • warte ich wollte etwas Code posten, aber dann ist mir das inet abgesoffen:

    ZITAT MEINER SELBST:

    Ich weiß nicht.
    Sobald mein Programm läuft reagiert kein Programm mehr auf die gewünschten Tasten.
    Das ist in sofern gut, dass nur noch mein Prog darauf reagiert, und keine Konflikte entstehen.
    JA ABER WIE SOLLEN DIE ENTSTEHEN, WENN NICHT MAL MEIN PROGRAMM DRAUF REAGIERT ???

    hmmm, was soll ich denn jetzt tun ?
    hier ist etwas Code:
    Header private

    private:
        void __fastcall MPSetVolume(TMediaPlayer* MP, int Volume);
    	int __fastcall  MPGetVolume(TMediaPlayer* MP);
    	/* Eine eindeutige ID für den Hotkey suchen. Der String ist egal.             *
    	 * Sinnvollerweise beschreibend zum Hotkey. Diese ID wird auch benötigt, wenn *
    	 * man den Hotkey zerstören will. Daher sollte der Wert irgendwo in der Klasse*
    	 * welche den HotKey verwaltet gespeichert werden.                            */
    	unsigned int Play_Pause;
    	unsigned int Stop;
    	unsigned int NXT;
    	unsigned int LST;
    
    	/* Die Modifier sind die Tasten welche zusätzlich auch noch gedrückt werden   *
    	 * müssen. Also z.B. Control oder so. Hier ist es keine (0). Um genauere      *
    	 * Info zu erhalten musst du einfach in der Hilfe unter "RegisterHotKey" nach *
    	 * lesen. (Windows SDK Hilfe)                                                 */
    	unsigned int HotKeyModifier_uint;
    
    	/* Funktionsdeklaration des Message-Handlers */
    	void __fastcall WMHotKey(TMessage &Msg);
    

    Header public:

    public:		// Benutzer Deklarationen
    	__fastcall TForm1(TComponent* Owner);
    	std::string playlistpath[16384];
    	int playlistlength;
    	void TForm1::Key_Version();
    	int recording;
    	void TForm1::REGISTERCHECK(String Version);
    	/* MessageMap, damit das Form auch weiss, wo die Message hin geschickt werden soll */
    BEGIN_MESSAGE_MAP
    /* MESSAGE_HANDLER(<Nachrichtenname>, <Nachrichtentyp>, <Handler-Funktionssname> */
       MESSAGE_HANDLER(WM_HOTKEY, TMessage, WMHotKey)
    END_MESSAGE_MAP(TForm)
    

    CPP

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
        UnregisterHotKey(Handle, Play_Pause); //HotKey löschen
    	UnregisterHotKey(Handle, Stop);
    	UnregisterHotKey(Handle, NXT);
    	UnregisterHotKey(Handle, LST);
    	GlobalDeleteAtom(Play_Pause);         //HotKey Identifier löschen
    	GlobalDeleteAtom(Stop);
    	GlobalDeleteAtom(NXT);
    	GlobalDeleteAtom(LST);
    
    	Stop = GlobalAddAtom("StopMe");
    	Play_Pause = GlobalAddAtom("PlayMe");
    	NXT = GlobalAddAtom("NextSong");
    	LST = GlobalAddAtom("LastSong");
    	HotKeyModifier_uint = 0;
    	RegisterHotKey(Handle, Play_Pause, HotKeyModifier_uint, VK_MEDIA_PLAY_PAUSE); //Hotkey registrieren.
    	RegisterHotKey(Handle, Stop, HotKeyModifier_uint, VK_MEDIA_STOP);
    	RegisterHotKey(Handle, NXT, HotKeyModifier_uint, VK_MEDIA_NEXT_TRACK);
    	RegisterHotKey(Handle, LST, HotKeyModifier_uint, VK_MEDIA_PREV_TRACK);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormDestroy(TObject *Sender)
    {
    	UnregisterHotKey(Handle, Play_Pause); //HotKey löschen
    	UnregisterHotKey(Handle, Stop);
    	UnregisterHotKey(Handle, NXT);
    	UnregisterHotKey(Handle, LST);
    	GlobalDeleteAtom(Play_Pause);         //HotKey Identifier löschen
    	GlobalDeleteAtom(Stop);
    	GlobalDeleteAtom(NXT);
    	GlobalDeleteAtom(LST);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::WMHotKey(TMessage &Msg)
    {
    	String Key = Msg.WParamLo;
    	if (Key == IntToStr(int(Stop)))
    		CLONE3->Click();
    	if (Key == IntToStr(int(Play_Pause)))
    	{
    		if (paused == 1 || (playing == 0 && paused == 0))
    			CLONE1->Click();
    		else
    			CLONE2->Click();
    	}
    	if (Key == IntToStr(int(NXT)))
    	{
    		CLONE4->Click();
    	}
    	if (Key == IntToStr(int(LST)))
    	{
    		CLONE5->Click();
    	}
    }
    

    Ich weiß nicht wo das Problem ist, es ging ja schon mal !

    so jetzt kann man etwas besser urteilen



  • Hmmm,

    naja, deaktiviere erstmal den Hotkey und probier(oder neues Projekt) folgendes:

    Im folgenden mal meine Variante zu abfangen der Mediatasten der Tastatur. Normal kannst du den Windows MediaPlayer damit
    steuern. Hier ist es ein TMediaPlayer auf dem Formular.

    Im ersten Schritt drücke ich direkt auf die Mediatasten.

    Zuerst erstellen wir die Message-Map zum Abfangen der Message CM_CHILDKEY, denn die wird ausgelöst und sendet
    den Code der Taste:

    *.h

    private:
        MESSAGE void __fastcall CMChildKey(TCMChildKey &Message);
        bool pause;
    
    public:
    
    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(CM_CHILDKEY, TCMChildKey, CMChildKey);
    END_MESSAGE_MAP(TForm);
    

    In der cpp:

    void __fastcall TFormMonitor::CMChildKey(TCMChildKey &Message)
    {
       int inx = ListBox->ItemIndex;   // Playliste
       int cnt = ListBox->Items->Count;
       unsigned int   Msg      = Message.Msg;
       unsigned short CharCode = Message.CharCode;
    
       TWinControl* sender;
       sender = static_cast<TWinControl*>(Message.Sender);
    
       switch (CharCode) {
    
          case VK_VOLUME_DOWN : {      
                //
          }
          break;
          case VK_VOLUME_UP : {         
                //
          }
          break;
          case VK_MEDIA_NEXT_TRACK : {   
             if (inx < cnt) {
                inx++;
                MediaPlayer->Close();
                ListBox->ItemIndex = inx;
                MediaPlayer->FileName = ListBox->Items->Strings[inx];
                MediaPlayer->Open();
                MediaPlayer->Play();
             }
          }
          break;
          case VK_MEDIA_PREV_TRACK : { 
             if (inx >0) {
                inx--;
                MediaPlayer->Close();
                ListBox->ItemIndex = inx;
                MediaPlayer->FileName = ListBox->Items->Strings[inx];
                MediaPlayer->Open();
                MediaPlayer->Play();
             }
          }
          break;
          case VK_MEDIA_STOP : {         
             MediaPlayer->Stop();
          }
          break;
          case VK_MEDIA_PLAY_PAUSE     : {    
             if (!pause) {
                pause = true;
                MediaPlayer->Pause();
             }
             else {
                pause = false;
                MediaPlayer->Play();
             }
          }
          break;
       }
       TForm::Dispatch(&Message);
    }
    

    Nun kannst du auch anders softwaremässig diese Tasten steuern (Timer, Code...).

    void __fastcall TFormMonitor::Button2Click(TObject *Sender)
    {
        keybd_event(VK_MEDIA_PLAY_PAUSE, 0, 0, 0);
        keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_KEYUP, 0);
    }
    

    Hoffe, der Schnipsel ist soweit komplett 🙂



  • Ok in einer weiteren Anwendung gehts, ich bau es jetzt um, um
    es in meinem SMP zu implementieren



  • Moment das doch nicht Global ?
    sobald ich minimiere gehen die Cuts nicht mehr, any advise ?



  • Tim06TR schrieb:

    Moment das doch nicht Global ?

    Systemweit ?

    Dafür ist die Hook-Dll in diesem Link, den du schon kennst. Etwas anpassen musst du aber noch.
    Hinweis: in der DLL den wParam mitschicken:

    keydll.cpp Funktion CheckKey anpassen:

    .
    .
       if(lParam & 0x40000000) 
          return CallNextHookEx(ghhookKB, nCode, wParam, lParam); 
    
       SendMessage(ghAppWnd, WM_KEYHOOK, wParam, lParam); //  <-- wParam mitschicken
    
       return CallNextHookEx(ghhookKB, nCode, wParam, lParam); 
    } 
    //---------------------------------------------------------------------------
    

    Die Messagemap im Hauptformular sieht dann genauso aus wie im o.g. Link.

    Die Funktion KeyHook:

    void __fastcall TForm1::KeyHook(TMessage &Message)
    {
       switch (Message.WParam) {
          case VK_VOLUME_DOWN : {        
             // 
          }
          break;
          case VK_VOLUME_UP : {      
             //
          }
          break;
          .
          .
    
        }
    }
    

    mfg
    kpeter



  • kpeter schrieb:

    keydll.cpp Funktion CheckKey anpassen:

    Jawohl!

    😉



  • ähm mit der dll hatte ich vorher schon etwas probleme, ich hab noch nie mit
    dlls gearbeitet.

    [ILINK32 Fehler] Error: Nicht auflösbares externes 'SetHook' referenziert von C:\DOKUMENTE UND EINSTELLUNGEN\TIM\EIGENE DATEIEN\RAD STUDIO\PROJEKTE\SMP\RELEASE\MUSICPLAYER.OBJ
    [ILINK32 Fehler] Error: Nicht auflösbares externes 'RemoveHook' referenziert von C:\DOKUMENTE UND EINSTELLUNGEN\TIM\EIGENE DATEIEN\RAD STUDIO\PROJEKTE\SMP\RELEASE\MUSICPLAYER.OBJ
    

    die dll ist auf release kompiliert heißt keydll.dll und ist im Release, Debug und im Programmordner.
    ich hab eig alles. (Kann ja nicht sein 😃 )

    extern "C" __declspec(dllexport) __stdcall void SetHook(void);
    extern "C" __declspec(dllexport) __stdcall void RemoveHook(void);
    extern "C" __declspec(dllexport) __stdcall DWORD CheckKey(int, WORD,LONG);
    
    private:
    	void __fastcall MPSetVolume(TMediaPlayer* MP, int Volume);
    	int __fastcall  MPGetVolume(TMediaPlayer* MP);
    	MESSAGE void __fastcall KeyHook(TMessage &Message);
    	BEGIN_MESSAGE_MAP
    	  MESSAGE_HANDLER(WM_KEYHOOK, TMessage, KeyHook);
    	END_MESSAGE_MAP(TForm);
    

    EDIT: Jansen kann es sein, dass du den Beitrag editiert hast, so das ich das nicht musste ?



  • Die keydll.lib hast du ins Formularprojekt eingebunden?



  • keydll.lib

    .lib ? oh ich hab nur ne dll und ne cpp zur Auswahl 😉
    Tut mir Leid, aber in dem Bereich hab ich 0,00 % Ahnung. (Wegguck)

    (btw: keydll.i = 50 MB 😮 was zur Hölle macht die denn ???)



  • Unter Projektoptionen des Projektes DLL :

    C++-Linker->Importbibliothek erzeugen = True (oder Häkchen nach BCB-Version)



  • Tim06TR schrieb:

    (btw: keydll.i = 50 MB 😮 was zur Hölle macht die denn ???)

    ***.ilc, *.ild, .ilf, .ils- Dateien

    Findest du unter Projektoptionen->Linker: Keine Status-Dateien generieren



  • Ah gut jetzt hab ich die lib. Er kompiliert [...].
    Jetzt muss ich mich leider wieder zu Wort melden, denn ich bekomme kein Event.
    Was kann ich denn jetzt noch falsch machen ? Egal was ich drück, nothing happens.
    nicht mal die Box erscheint bei einem Klick belibieger Taste.

    void __fastcall TForm1::KeyHook(TMessage &Message)
    {
    	/*
    	VK_MEDIA_NEXT_TRACK (B0)
    	Windows 2000/XP: Next Track key
    
    	VK_MEDIA_PREV_TRACK (B1)
    	Windows 2000/XP: Previous Track key
    
    	VK_MEDIA_STOP (B2)
    	Windows 2000/XP: Stop Media key
    
    	VK_MEDIA_PLAY_PAUSE (B3)
    	Windows 2000/XP: Play/Pause Media key
    	*/
    	ShowMessage("On Click Event");
    	switch (Message.WParam)
    	{
    		case VK_VOLUME_DOWN:
    		{
    			break;
    		}
    		case VK_VOLUME_UP:
    		{
    			break;
    		}
    		case VK_MEDIA_PLAY_PAUSE:
    		{
    			if (paused == 1 || (playing == 0 && paused == 0))
    				CLONE1->Click();
    			else
    				CLONE2->Click();
    			break;
    		}
    		default:
    		break;
    	}
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    	SetHook();
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormDestroy(TObject *Sender)
    {
    	RemoveHook();
    }
    //---------------------------------------------------------------------------
    

    Header:

    private:
    void __fastcall MPSetVolume(TMediaPlayer* MP, int Volume);
    int __fastcall  MPGetVolume(TMediaPlayer* MP);
    MESSAGE void __fastcall KeyHook(TMessage &Message);
    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_KEYHOOK, TMessage, KeyHook);
    END_MESSAGE_MAP(TForm);
    

    Ich weiß nicht.
    Dummerweise ist das ein wichtiger Bestandteil des Programms.
    Was kann ich denn noch falsch gemacht haben ?



  • Muss die Lib so ins Projekt wie eine bereits existierende Form ?
    Also mit "Hinzufügen" -> Dateityp = ".lib" -> Starten.
    So habs ich dann gemacht, scheint ja falsch zu sein ?



  • Moment...

    1. Projekt Formular und Projekt DLL einzeln erstellen.

    2. Projekt Formular öffnen. Dort Projektverwaltung anklicken, ganz oben der Prjektgruppe hinzufügen:
    das Projekt keydll hinzufügen. Projektgruppe namentlich speichern und dem Formular-Projekt die keydll.lib hinzufügen.

    In der Projektgruppe hast du jetzt zwei Projekte, die du einzeln aktivieren, bearbeiten und compilieren kannst.

    3. Alle Projekte erstellen.


Anmelden zum Antworten