Seite 1 von 1

GUI in DLL aufrufen: IMA in EXE

Verfasst: 01.02.2008 17:58
von Kiffi
Hallo,

ich möchte aus einer EXE eine DLL-Funktion aufrufen, die ihr eigenes
OpenWindow() ausführen soll. Klappt auch erst einmal augenscheinlich
gut. Wenn ich aus der EXE die DLL-Funktion CallGui aufrufe, so erscheint
das Fenster der DLL. Wenn ich nun allerdings in das Fenster der EXE
klicke, so bekomme ich einen IMA in der Zeile CallFunctionFast(CallGui).

EXE:

Code: Alles auswählen

If OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "exe")
  If CreateGadgetList(WindowID(0))
    ButtonGadget(0, 0, 0, 100, 20, "CallGui")
    Repeat
      WWE=WaitWindowEvent()
      If WWE = #PB_Event_Gadget And EventGadget()=0
        hDLL = OpenLibrary(#PB_Any, "dll.dll")
        CallGui = GetFunction(hDLL, "CallGui")
        CallFunctionFast(CallGui)
        CloseLibrary(hDLL)
      EndIf
    Until WWE = #PB_Event_CloseWindow
  EndIf
EndIf
DLL:

Code: Alles auswählen

ProcedureDLL CallGui()
  OpenWindow(99, #PB_Ignore, #PB_Ignore, 100, 100, "dll")
  Repeat
  Until WaitWindowEvent()=#PB_Event_CloseWindow
EndProcedure
Was mache ich falsch?

Grüße ... Kiffi

P.S.: Ich bin mir sicher, darüber schon mal was gelesen zu haben. Aber
dank dieser $%§&-Suchfunktion finde ich nix.

Verfasst: 01.02.2008 19:15
von Andreas
Auszug aus der Hilfe :

Pro Ereignisschleife darf nur einmal WaitWindowEvent() aufgerufen werden, da andernfalls Ereignisse "verloren" gehen (jedes Ereignis kann nur einmal ausgewertet werden und steht damit nach der ersten Verarbeitung nicht noch ein zweites Mal zur Verfügung).

Ich habe die Sache so gelöst :

DLL:

Code: Alles auswählen

Procedure wcb(WindowID, Message, wParam, lParam)
Result = #PB_ProcessPureBasicEvents
Select Message
   Case #WM_CLOSE
   PostQuitMessage_(0)
EndSelect
ProcedureReturn Result
EndProcedure

ProcedureDLL CallGui() 
  OpenWindow(99, #PB_Ignore, #PB_Ignore, 100, 100, "dll") 
  SetWindowCallback(@wcb(),99)
  While GetMessage_(m.MSG, 0, 0, 0)
  If IsDialogMessage_(hwnd,m) = 0
  TranslateMessage_(m)
  DispatchMessage_(m)
  EndIf
  Wend
EndProcedure

Prog:

Code: Alles auswählen

If OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "exe") 
  If CreateGadgetList(WindowID(0)) 
    ButtonGadget(0, 0, 0, 100, 20, "CallGui") 
    Repeat 
      WWE=WaitWindowEvent() 
      If WWE = #PB_Event_Gadget And EventGadget()=0 
        hDLL = OpenLibrary(#PB_Any, "dll.dll") 
        CallGui = GetFunction(hDLL, "CallGui") 
        CallFunctionFast(CallGui) 
        CloseLibrary(hDLL) 
      EndIf 
    Until WWE = #PB_Event_CloseWindow 
  EndIf 
EndIf

Verfasst: 01.02.2008 19:42
von Kiffi
Hallo Andreas,

erstmal vielen Dank für Deine Hilfe!
Andreas hat geschrieben:[...] Pro Ereignisschleife darf nur einmal WaitWindowEvent() aufgerufen
werden, da andernfalls Ereignisse "verloren" gehen
soweit klar. Allerdings gehe ich eigentlich davon aus, dass ich mit der DLL
einen neuen Prozess starte, in dem ich dann eine weitere EventSchleife
laufen lassen kann. Die Lösung, die Du angeboten hast, kann ich nicht
verwenden, da ich ich hier die nativen PB-Befehle verwenden möchte und
so weit wie möglich erst einmal auf Callbacks verzichten will.

Und: Die Tatsache, dass bei mehrfachem Aufruf von WaitWindowEvent()
innerhalb einer Eventschleife einige Events verschluckt werden, sollte
eigentlich nicht dazu führen, dass ich einen IMA bekomme, sondern eher
dazu, dass meine Applikation nur stockend reagiert.

Aber Dein Posting hat mich auf eine Idee gebracht: Ich verfrachte den
Aufruf der DLL-Funktion einfach in einen Thread und schon funktioniert es.

:-)

Code: Alles auswählen

Procedure CallGui(lDummy.l)
  
  hDLL = OpenLibrary(#PB_Any, "dll.dll")
  CallGui = GetFunction(hDLL, "CallGui")
  CallFunctionFast(CallGui)
  CloseLibrary(hDLL)
  
EndProcedure

If OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "exe")
  If CreateGadgetList(WindowID(0))
    ButtonGadget(0, 0, 0, 100, 20, "CallGui")
    Repeat
      WWE=WaitWindowEvent()
      If WWE = #PB_Event_Gadget And EventGadget()=0
        CreateThread(@CallGui(), 42)
      EndIf
    Until WWE = #PB_Event_CloseWindow
  EndIf
EndIf
(Nun stellt sich die Frage, ich ich damit den Teufel nicht mit dem Beelzebub
ausgetrieben habe und ich durch die Verwendung von Threads noch
andere Probleme bekomme...)

Grüße ... Kiffi

Verfasst: 01.02.2008 19:52
von Andreas
Kiffi hat geschrieben:soweit klar. Allerdings gehe ich eigentlich davon aus, dass ich mit der DLL
einen neuen Prozess starte, in dem ich dann eine weitere EventSchleife
laufen lassen kann.
Nein, meines Wissens wird da wird kein neuer Process gestartet.
Da wird das Modul(dll) in den Adressraum des aufrufenden Prozesses gemappt.