Hook soll text in edit-control bestimmen



  • Hi,
    ich wage mich gerade wieder mal an Hooks und möchte dazu ein Programm schreiben, welches in einem Textfenster alle Classnames von Fenstern auflistet die seit Programmstart neu erstellt wurden (von allen laufenden prozessen, nicht nur das eigene Programm). Dazu setze ich in einer DLL einen CBT-Hook und möchte dann daraus mit SendMessage und WM_SETTEXT den Classname eines neu erstellten Fensters in das Textfenster schreiben. Das schaut in der DLL bisher bei mir so aus:

    [...]
    
    HWND mainwnd;
    
    LRESULT CALLBACK CBTProc(int nCode,W PARAM wParam, LPARAM lParam)
    {
            if(nCode==HCBT_CREATEWND)
            {
                                        LPCTSTR WndClassName;
                                        WndClassName = ((CBT_CREATEWND*)lParam)->lpcs->lpszClass;
                                        SendMessage(mainwnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)WndClassName);
            }
            if(nCode<0)
            {
                       return CallNextHookEx(hook, nCode, wParam, lParam);
            }
            return 0;
    }
    DLLIMPORT BOOL SetHook(HWND hwnd)
    {
              mainwnd = hwnd;
              hook = SetWindowsHookEx(WH_CBT, CBTProc, hInstance, 0);
              if(hook != NULL)
              {
                      return TRUE;
              }
              return FALSE;
    }
    

    Der SetHook-Funktion wird übrigens natürlich das Handle des Textfensters übergeben. Die DLL funktioniert so jedenfalls und es wird auch registriert wenn neue Fenster erstellt werden (daher weil wenn ich ein Beep in der HookProc einfüge piept mein PC ziemlich wenn ich ein neues Fenster öffne 😉 ), aber in dem Textfenster in meinem Programm kommt nichts an...? Wenn ich allerdings in meinem Programm nach dem Laden der DLL und des Hooks ein neues Fenster erstell, funktioniert alles so wie es soll, dh. es steht der Classname im Textfenster drin. Deshalb die Frage: Warum wird das Textfenster nicht aktualisiert wenn andere Fenster außerhalb meines Programms geöffnet werden und was kann ich dagegen tun?? Bin für jede Hilfe dankbar!!



  • Ich bin selbst noch Win32-API-N00B, aber traue mich jetzt einfach mal die Frage zu beantworten ... werde langsam mutig! 😉

    Also wenn Prozesse die DLL in ihren Speicherbereich laden, existiert logischerweise für jeden Prozess eine eigene HWND mainwnd Variable. Das heißt, die DLL Deines eigenen Prozesses sendet die Message per SendMessage(mainwnd, ...) auch tatsächlich an Dein Fenster, bei allen anderen Instanzen wird mainwnd aber ein undefinierter Wert sein.

    Abhilfe:
    Du stellst HWND mainwnd in einen SharedMemory-Bereich. Wenn ich mich nicht ganz irre sollte folgendes Dein Problem lösen:

    #pragma data_seg( "SHARDATA")
    HWND mainwnd;
    #pragma data_seg()
    

    Bis denn,
    Timo



  • Vielen Dank für deinen Beitrag, aber deine Idee funktioniert leider nicht. Außerdem verstehe ich nicht wirklich, was du mit "allen anderen Instanzen" meinst, die DLL wird doch nur von meinem Prozess verwendet.



  • Hallo nochmal,

    naja, Dein Programm ruft vielleicht als einzigstes die SetHook-Funktion auf, aber Windows registriert sie dann für jeden Prozess, für den eine Message von Deinem Hook "gefangen" wird. Hab gerade keinen Link zur Hand, aber such mal bei Google danach falls es Dich interessiert (und das sollte es doch eigentlich, schließlich willst Du das ja programmieren!).

    Hab vergessen, die Variablen im shared memory müssen static sein und initialisiert werden. Also probier mal:

    #pragma data_seg("SHARDATA")
    static HWND mainwnd = 0;
    #pragma data_seg()
    

    Des weiteren fällt mir aber auch gerade auf:
    Woher bekommst Du denn eigentlich hInstance? Du musst bei systemweiten Hooks das instance handle der DLL angeben. Das steht aber auch alles in der MSDN (soweit ich weiß auch mit nem Beispiel), also einfach mal da rein schauen und schlau werden.
    Außerdem, wird Deine Callbackfunktion überhaupt exportiert?

    Gruß,
    Timo


Anmelden zum Antworten