Auf Fenster von einer DLL aus zugreifen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Auf Fenster von einer DLL aus zugreifen

Beitrag 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 :? .
Smash
Beiträge: 23
Registriert: 10.10.2004 00:09

Beitrag 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
Smash
Beiträge: 23
Registriert: 10.10.2004 00:09

Beitrag von Smash »

gerne wider! :allright:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Beitrag 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
Antworten