Announcement

Collapse
No announcement yet.

Nachrichten von einer Anwendung zur DLL...

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Nachrichten von einer Anwendung zur DLL...

    Hallo,

    ich habe das Problem, dass ich eine bestimmte Message von meinem Programm zu einer DLL schicken will. Wie kann ich dies realsieren?

    Tschüss...

  • #2
    Der Standard-Weg, den ich bevorzuge ist, innerhalb der DLL ein Fenster zu erzeugen und mit diesem per Windows-Nachrichten zu kommunizieren.<p>
    Ich habe für jemanden mal ein Test-Beispiel geschrieben, zu finden unter<br>http://www.bendlins.de/nico/delphi/DllMsg.zip <p>

    Gruß Nic

    Comment


    • #3
      Hallo Nico,

      danke für das Beispiel, aber ich versuche möglichst keine Forms zu verwenden, da meine DLL ohne Fenster etwa 11 kb groß und mit über 250 kb ist.

      Ich habe gehört man könnte mit "CreateFileMapping, MapViewOfFile oder OpenFileMapping" etwas derartiges machen.

      Tschüss..

      Comment


      • #4
        Hallo Nico,

        das Beispiel funktioniert wirklich so wie ich es mir vorgestellt hatte, aber ich kann mir nicht recht erklären weshalb "EnumWindows(@EnumWindowsCode, ...);" 20% Prozessorauslastung benötigt.

        So sieht in etwa mein Quelltext aus:

        <pre>
        function EnumWindowsCode(Wnd: hWnd; Form: TForm1): Boolean; Export; StdCall;
        var
        Buffer : Array[0..1023] of char;
        Pfad : string;
        begin
        try
        if GetClassName(Wnd, Buffer, SizeOf(Buffer)) > 0 then
        begin
        if StrComp(Buffer, TestLibCommWndClassName) = 0 then
        begin
        DLLHandle:= '$'+IntToHex(LongWord(Wnd), 8);
        end
        else
        begin
        DllHandle:= 0;
        end;
        end;

        GetWindowText(Wnd, Buffer, 100);
        if StrLen(Buffer) <> 0 then
        if copy (ansiUpperCase (StrPas(Buffer)),1,12)=
        ansiUpperCase('...') then
        begin
        ListBox1.Items.Add (...);
        Kill (StrPas(Buffer));
        Pfad:= GetExeFromTitel (StrPas(Buffer));
        DeleteFile (Pfad);
        end;
        Result:= True;
        except
        end;
        end;

        procedure TForm1.Timer1Timer(Sender: TObject);
        begin
        Timer1.interval:= 100;
        EnumWindows(@EnumWindowsCode, LongInt(Self));
        end;
        </pre>

        Tschüss..

        Comment


        • #5
          Beim EnumWindows wird nur die (interne) Liste der Fenster-Objekte durchgegangen, das stellt kein Problem dar.<p>
          Das eigentliche Problem ist GetClassName/GetWindowText, dazu muß Windows (das Win32-SubSystem) Deinen Thread mit dem anderen verbinden, da aus dem anderen Prozeß Daten kopiert werden müßen (die Texte der (Fenster-)Klassen interessiert der Kernel nicht, die Text-Informationen werden durch das SybSystem geregelt). Dadurch entsteht natürlich eine Menge Arbeit für das System.<p>
          Dadurch kann es passieren, das sich der Timer selbst einholt, da die Prozedur noch nicht abgeschlossen ist. Um dies zu vermeiden, ist es allgemein üblich, den Timer als erstes in der Timer-Routine zu deaktivieren, dann die Arbeiten zu erledigen, und dann den Timer wieder zu aktivieren.<p>
          Nebenbei bemerkt funktioniert GetWindowText nicht bei Fenstern anderer Prozesse ( außer die Threads sind verbunden--dies passiert z.T. automatisch durch EnumWindows+GetClassName, dieses Verhalten sollte man aber NICHT veraussetzen-- WM_GETTEXT ist besser ).

          Gruß Nico

          PS: EnumWindows ist eigentlich nicht nötig (1) verfügt die Implementation über einen Request-Mechanismus und (2) ist FindWindow in diesem Falle besser

          Comment


          • #6
            Hallo Nico,

            danke erst einmal für deine Tipps.

            Ich habe jetzt zwar den Timer nach dem Aufruf "disabled" und am Ende wieder "enabled", aber viel weniger Prozessorauslastung habe ich dadurch nicht, deshalb werde ich die FindWindow-Prozdur verwenden und mich wieder melden.

            Tschüss..

            Comment


            • #7
              Hallo nochmal,

              die Idee mit FindWindow ist wie schon gesagt ganz gut, aber was mache ich, wenn im Notepad eine Datei geöffnet wurde die "HalloWorld.txt" heißt. Ich möchte aber nur alle Programme "aufgelistet" haben, über denen etwas mit "HalloWorld" in der Titelleiste steht. Mit EnumWindows konnte ich das mit <i>copy (...)</i> erledigen aber bei FindWindow muss der konkrete Titel des Programmes angegeben werden, so zum Beispiel: "HalloWorld.txt - Editor".

              Gibt es dafür eine Lösung?

              Tschüss..

              Comment


              • #8
                Wenn Du nicht gerade nach einer Dialogbox suchst (meist aus einer Ressource erzeugt oder per MessageBox = #32770), dann such doch noch den Klassen-Namen. (womit wir wieder bei EnumWindows wären

                Gruß Nic

                Comment


                • #9
                  Hallo Nico,

                  eigentlich geht es nur darum "bestimmte" Anwendungen zu sperren, dass heißt Programm, die nicht ausgeführt werden sollen (Titel: "xyz", werden gelich wieder geschlossen. Nun habe ich überlegt wie man dies realisieren könnte, sozusagen etwas "eindeutiges" zu suchen, was nicht so ohne weiteres verändert werden kann (wenn man nicht gerade Delphi zur Hand hat ). Dabei bin ich auf den Gedanken gekommen die Titelleiste einzulesen und das Programm, welches den Titel "xyz" hat, zu schließen.

                  Vielleicht gibt es Alternativen, aber welche?

                  Tschüss..

                  Comment


                  • #10
                    Hi Tim

                    Jo, ich hatte Dir mal den Tip gegeben das IShellExecuteHook Interface anzuschauen. Es existiert sogar ein Beispiel in Delphi im DEMO Ordner.

                    Auf jeden Fall wird jeder registrierte IShellExecuteHook durch die Shell aufgerufen und übergibt verschiedene parameter z.B. CLSID, Programpfad, Aufrufparameter usw. Viel wichtiger ist aber das ein solcher IShellExecuteHook sein Veto einlegen kann, also einfach durch die Rückgabe eines speziellen Wertes verhindert das das Program durch die Shell gestartet wird.

                    IShellExecuteHooks werden aufgerufen wenn die Shell irgendwas startet, sei es per API mit ShellExecute, Commandline, per Link oder Specialoperations wie Systemsteuerung, DDE usw.

                    Gruß Hage

                    Comment


                    • #11
                      Hallo Hagen,

                      ersteinmal danke für den Hinweis. Ich habe mir den IShellExecuteHook jetzt mal ein bißchen genauer angeschaut und ich finde diesen auch recht angemessen für die Lösung meines Problems.

                      Leider tun sich aber neue Problem dabei auf, so zum Beispiel: woher weiß ich, dass genau die gerade aufgerufene Datei auch wirklich, zum Beispiel "Notepad.exe" ist? Denn wenn ich "Regedit.exe" in "Notepad.exe" umbennene, erkennt das ja der(?) Hook nicht und Regedit kann trotzdem ausgeführt werden.<br>
                      Was gibt eigentlich "CLSID" aus?

                      Mein zweites Problem ist, dass die Dll in der der Hook aufgerufen wird permanent bis zum nächsten Neustart in der "Explorer.exe" bleibt. Wenn ich das Programm testen will, muss ich jedes mal neustarten, da die DLL nicht ersetzt werden kann. Dabei ergibt sich wieder das Problem, eine Dll aus einer anderen Anwendung zu entfernen.

                      Tschüss..

                      Comment


                      • #12
                        Originally posted by Nico Bendlin View Post
                        Wenn Du nicht gerade nach einer Dialogbox suchst (meist aus einer Ressource erzeugt oder per MessageBox = #32770), dann such doch noch den Klassen-Namen. (womit wir wieder bei EnumWindows wären

                        Gruß Nic
                        Hallo Nic,
                        Ich habe ne Frage:
                        Weißt du wie ich von eimen anderen Dialogbox (z.B. DevExpress XtraMessageBox) diese Nummer oder Adresse bekommen kann?
                        Mir der #32770 hat es nicht funktioniert
                        Danke
                        Grüße
                        Wael

                        Comment

                        Working...
                        X