Seite 1 von 1

Auf Fenster von einer DLL aus zugreifen

Verfasst: 09.07.2006 00:55
von Ligatur
Ich möchte ein Programm schreiben, welches mit Plugins in Form von DLLs funktioniert.
Ist es irgendwie möglich, dazu von der DLL aus auf das Programmfenster, Menüs o.ä. des Hauptprogramms zuzugreifen? Alle Versuche meinerseits waren nicht erfolgreich :cry: .
Oder ist es alternativ möglich, aus der DLL heraus auf Prozeduren des Hauptprogramms zuzugreifen? Ich habe versuchsweise schon eine ProcedureDLL im Hauptprogramm geschrieben und diese von einer DLL aus aufgerufen (Adresse an DLL übergeben und Prozedur mit CallDLLFast aufgerufen). Das klappte auch, beim Rücksprung aus der Prozedur kam es allerdings zu einem Speicherzugriffsfehler :? .

Verfasst: 09.07.2006 04:23
von Smash
Das hab ich mir mit Hilfe dieses Forums mal zusammengebaut.

Code: Alles auswählen

;Hauptprogramm.EXE
;PureBasic v3.94 

Enumeration
  #aWindow_0
  #Button_0
  #Listview_0
  #Library
EndEnumeration

Procedure Open_Window_0()
  If OpenWindow(#aWindow_0, 30, 150, 359, 230,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Hauptprogramm")
    If CreateGadgetList(WindowID())
      ButtonGadget(#Button_0, 165, 180, 130, 35, "RUN catch.dll")
      ListViewGadget(#Listview_0, 25, 15, 300, 155)
      AddGadgetItem (#Listview_0,-1," catch my if you can") 
      AddGadgetItem (#Listview_0,-1,"") 
      AddGadgetItem (#Listview_0,-1,"Die catch.DLL Holt den Text aus Zeile 1") 
      AddGadgetItem (#Listview_0,-1,"Und gibt ihn an die Hauptprogramm.exe weiter.") 
    EndIf
  EndIf
EndProcedure

Open_Window_0()
Repeat
    If GetGadgetItemText(#Listview_0, 0, 1) = ""
        AddGadgetItem (#Listview_0,-1,"Uhrzeit  ->   "+ FormatDate("%hh:%ii:%ss", Date())) 
    EndIf
    Select WindowEvent()
      Case #PB_EventCloseWindow
            End
      Case #PB_EventGadget
        Select EventGadgetID()
           Case #Button_0
              If OpenLibrary(#Library, "catch.dll")
                  Ergebnis3.s = PeekS(CallFunction(#Library, "catch_My" ,0,0,0,0))
                  CloseLibrary(#Library)
                  MessageRequester("Hauptprogramm ", "Ich bin das Hauptprogramm" + Chr(13) + "Und bekam von der DLL den Text" + Chr(13) + Chr(13) + Ergebnis3 , 0)
              Else
                  MessageRequester("error","catch.DLL   nicht gefunden",0)

              EndIf   
        EndSelect
    EndSelect
Delay (3)
ForEver

Code: Alles auswählen

;catch.dll
;PureBasic v3.94

Handle.l = 0
ReturnString$ = ""
Global ReturnString$
Buffer.s = ""
Global Buffer.s
MyID1 = 0
Global MyID1
Ja = 0 
Global Ja
KillProg.l = 0
Global KillProg.l
Anzeigefenster$ = "Hauptprogramm"
AnzeigeElement$ = "ListBox"
SucheName1.s = Anzeigefenster$
SucheName2.s = AnzeigeElement$
Global SucheName1.s
Global SucheName2.s


Declare EnumAllWindows() 
Declare EnumAllSubChilds(Handle.l) 
Declare EnumProc(Handle.l, lParam.l) 
Declare.s GetTitle(Handle) 
Declare.s GetClassName(Handle.l) 
Declare AddWindow(Handle.l, ProcessID.l, Name.s, ClassName.s) 
Global Window 
Structure Window 
  Handle.l 
  Process.l 
  Name.s 
  Class.s 
EndStructure 


Procedure.s GetClassName(Handle.l) 
  Class.s = Space(1024) 
  GetClassName_(Handle, @Class , Len(Class)) 
  ProcedureReturn Left(Class, Len(Class)) 
EndProcedure

Procedure.s GetTitle(Handle) 
  Name.s = Space(1024) 
  GetWindowText_(Handle, @Name, Len(Name)) 
  ProcedureReturn Left(Name, Len(Name)) 
EndProcedure

Procedure AddWindow(Handle.l, ProcessID.l, Name.s, ClassName.s) 
  If Name = SucheName1.s And Ja = 0
     Ja = 10
     KillProg.l = Handle
  EndIf
    If ClassName = SucheName2.s And Ja = 10
     MyID1 = Handle
     Ja = 0 
  EndIf 
EndProcedure

Procedure EnumAllSubChilds(Handle.l) 
  If Handle 
    EnumChildWindows_(Handle, @EnumProc(), 0) 
  EndIf 
EndProcedure

Procedure EnumProc(Handle.l, lParam.l) 
  Protected Window.Window 
  Window\Process = 0 
  GetWindowThreadProcessId_(Handle, @Window\Process) 
  Window\Name = GetTitle(Handle) 
  Window\Class = GetClassName(Handle) 
  AddWindow(Handle, Window\Process, Window\Name, Window\Class)
  EnumAllSubChilds(Handle)
  ProcedureReturn #True 
EndProcedure

Procedure EnumAllWindows() 
  Protected TmpL.l 
  TmpL = EnumWindows_(@EnumProc(), 0) 
EndProcedure  

ProcedureDLL catch_My(hwnd.l,hinst.l,lpCmdLine.s,nCmdShow.l) 
  EnumAllWindows()
  If MyID1 = 0 ; Or MyID3 = 0
    MessageRequester("error","Abzufangende Anzeige ID" + Chr(13) + "nicht gefunden." + Chr(13) + "Starte zuerst die Haupt Datei",0)
  Else
    SendMessage_(MyID1,#LB_GETTEXT,0,Buffer.s)
    PostMessage_(MyID1,388,0,0)
    MessageRequester("DLL", "Ich bin die DLL" + Chr(13) + "Und holte mir selbständig den Text" + Chr(13) + Chr(13) + Buffer.s , 0)
    ReturnString$ = Buffer.s
    Buffer.s = ""    
    ProcedureReturn ReturnString$ 
  EndIf
EndProcedure

Verfasst: 04.08.2006 20:50
von Smash
gerne wider! :allright:

Verfasst: 04.08.2006 21:03
von ts-soft
Meist Funktionieren Plugins genau umgekehrt. Das Programm durchsucht
einen Ordner um vorhandene Plugins zu finden. Plugins haben immer
bestimmte Funktionen, über die Informationen zwischen Hauptprogamm und
Plugin ausgetauscht werden. Standardwerte, wie hWnd des Hauptprogramms
stellt man einfach über Environmentvariablen zur Verfügung.
Integration dann über z.B. PluginGetMenueText() usw., wobei bei klicken des
eintrag, wieder das entsprechende Plugin mit der zugehörigen Funktion
aufgerufen wird.

Verfasst: 08.08.2006 00:04
von Ligatur
Smash hat geschrieben:gerne wider! :allright:
Tschuldigung, bin nicht so oft hier und habe dabei versäumt, hier zu antworten.:oops:

Also etwas verspätet: Danke für die Hilfe, der Code hat mir sehr weitergeholfen.

@ts-soft:
ts-soft hat geschrieben:Meist Funktionieren Plugins genau umgekehrt. Das Programm durchsucht
einen Ordner um vorhandene Plugins zu finden.
So soll es ja auch sein. Ich wollte mir aber durch Zugriffe auf das Hauptprogramm die Arbeit etwas erleichtern. Aber das wird dann ja wohl nichts :( . Aber diesmal etwas früher: Danke für die Antwort