Was mich aber stört, ist, dass aufgrund von Dialog-Nummer, Window-Nummer usw. irgendwie ein Chaos entsteht, so habe ich mir ein Modul gemacht, das das alles vereinfacht.
Das Modul ist außerdem ein Objekt/eine Klasse, das heißt, man kann mehrere Instanzen eines Dialogs öffnen, und alle Nummern usw. sind sozusagen in einer Hand, gesammelt im Objekt.
Ein bisschen musste ich mit den öffentlichen Instanz-Variablen tricksen, da ist ein 2. Pointer notwendig, aber das ist für mich verschmerzbar.
Die Klasse habe ich nicht von Hand geschrieben, ich habe mir dazu einen kleinen (naiv implementierten) Objekt-Precompiler geschrieben, der das alles in ein Objekt gießt.
Ich denke, ich werde den Precompiler so erweitern, dass er auch die Erstellung reiner Module (also ohne die OOP-Komponente) automatisieren kann, die ganzen Declares sind schon lästig, wäre toll, ginge das automatisch. Egal, ich komme vom Thema ab
Zunächst einmal die Source-Klasse vor der Precompiler-Verwendung:
Code: Alles auswählen
Module Dialog
  
  Structure object
    window_no.i As Public
    dialog_no.i As Public
    xml_no.i As Public
  EndStructure
  
  Public Class xml_number ; Xml Number after NewCatch
  
  ; Helpers
  Class Procedure CheckXMLTree(xml_no)
    
    If xml_no=0 Or XMLStatus(xml_no)<>#PB_XML_Success
      MessageRequester("XML error",
                       "XML error: " + XMLError(xml_no) + " (Line: " + XMLErrorLine(xml_no) + ")")
      End
    EndIf
    
  EndProcedure
  Class Procedure OpenXMLDialog_(xml_no, window_name.s, x, y)
    
    Protected dialog_no = CreateDialog(#PB_Any)
    
    If OpenXMLDialog(dialog_no, xml_no, window_name, x, y)=0
      MessageRequester("Dialog error",
                       "Dialog error: " + DialogError(dialog_no))
      End
    EndIf
    
    ProcedureReturn dialog_no
    
  EndProcedure
  
  ; Constructors, Open the window
  Public Class Procedure NewCatchXML(window_name.s, adress, size, free_xml=#False, x=0, y=0)
    
    ; new instance
    Protected *this.object = _New_()
    
    ; create xml tree & check it
    *this\xml_no = CatchXML(#PB_Any, adress, size)
    xml_number   = *this\xml_no
    CheckXMLTree(*this\xml_no)
    
    ; create dialog window
    *this\dialog_no = OpenXMLDialog_(*this\xml_no, window_name, x, y)
    If free_xml
      FreeXML(*this\xml_no)
      *this\xml_no = 0
      xml_number = 0
    EndIf
    
    ; get window number (e.g. EventWindow() = window_no)
    *this\window_no = DialogWindow(*this\dialog_no)
    
    ; returns instance pointer
    ProcedureReturn *this
    
  EndProcedure
  Public Class Procedure NewParseXML(window_name.s, string_name.s, free_xml=#False, x=0, y=0)
    
    ; new instance
    Protected *this.object = _New_() 
    
    ; create xml tree & check it
    *this\xml_no = ParseXML(#PB_Any, string_name)
    xml_number   = *this\xml_no
    CheckXMLTree(*this\xml_no)
    
    ; create dialog dialog
    *this\dialog_no = OpenXMLDialog_(*this\xml_no, window_name, x, y)
    If free_xml
      FreeXML(*this\xml_no)
      *this\xml_no = 0
      xml_number = 0
    EndIf
    
    ; get window number (for e.g. EventWindow() = window_no)
    *this\window_no = DialogWindow(*this\dialog_no) 
    
    ; returns instance pointer
    ProcedureReturn *this                           
    
  EndProcedure
  Public Class Procedure New(window_name.s, xml_no, x=0, y=0, free_xml=#False)
    
    ; new instance
    Protected *this.object = _New_() 
    
    ; check xml tree
    *this\xml_no = xml_no 
    CheckXMLTree(xml_no)
    
    ; create dialog dialog
    *this\dialog_no = OpenXMLDialog_(*this\xml_no, window_name, x, y)
    
    ; get window number (for e.g. EventWindow() = window_no)
    *this\window_no = DialogWindow(*this\dialog_no) 
    
    ; returns instance pointer
    ProcedureReturn *this                           
    
  EndProcedure
  
  ; Destructor  
  Public Procedure Free(*this.object)
    FreeDialog(*this\dialog_no)
    _Free_(*this)
  EndProcedure
  
EndModule
; Create a dialog Object with:
;     Global Window.Dialog
;     Window = Dialog::NewCatch(..)
; Create pointer to private instance variables (if needed)
; dont use _method_table_:
;     Global *Window.Dialog::Variables
;     *Window = Window  <--- important
; Free:
;     Window = Dialog::Free()
;     -> Window will be 0, and can be tested
Code: Alles auswählen
; Instance Interface of Object with Public Instance Procedures (Methods)
Interface Dialog
  Free.i()
EndInterface
DeclareModule Dialog
  EnableExplicit
  ; Public Enumeration
  ; Public Structure
  ; Structure of Public Instance Variables (Attributes)
  Structure Variables
    *_method_table_
    window_no.i
    dialog_no.i
    xml_no.i
  EndStructure
  ; Declare Public Class Variables (Attributes)
  Global xml_number.i
  ; Declare Public Class Procedures (Methods)
  Declare.i New(window_name.s, xml_no, x=0, y=0, free_xml=#False)
  Declare.i NewCatchXML(window_name.s, adress, size, free_xml=#False, x=0, y=0)
  Declare.i NewParseXML(window_name.s, string_name.s, free_xml=#False, x=0, y=0)
EndDeclareModule
Module Dialog
  EnableExplicit
  ; Private Enumeration
  ; Private Structure
  ; Structure of Private Instance Variables (Attributes)
  Structure object Extends Variables
  EndStructure
  ; Declare Private Class Variables (Attributes)
  ; Declare all Instance & Private Class Procedures (Methods)
  Declare.i OpenXMLDialog_(xml_no, window_name.s, x, y)
  Declare.i CheckXMLTree(xml_no)
  Declare.i _Free_(*this.object)
  Declare.i _New_()
  Declare.i Free(*this.object)
  ; Procedures (Methods) Implementation
  Procedure.i OpenXMLDialog_(xml_no, window_name.s, x, y)
    Protected dialog_no = CreateDialog(#PB_Any)
    If OpenXMLDialog(dialog_no, xml_no, window_name, x, y)=0
    MessageRequester("Dialog error",
    "Dialog error: " + DialogError(dialog_no))
    End
    EndIf
    ProcedureReturn dialog_no
  EndProcedure
  Procedure.i CheckXMLTree(xml_no)
    If xml_no=0 Or XMLStatus(xml_no)<>#PB_XML_Success
    MessageRequester("XML error",
    "XML error: " + XMLError(xml_no) + " (Line: " + XMLErrorLine(xml_no) + ")")
    End
    EndIf
  EndProcedure
  Procedure.i New(window_name.s, xml_no, x=0, y=0, free_xml=#False)
    Protected *this.object = _New_()
    *this\xml_no = xml_no
    CheckXMLTree(xml_no)
    *this\dialog_no = OpenXMLDialog_(*this\xml_no, window_name, x, y)
    *this\window_no = DialogWindow(*this\dialog_no)
    ProcedureReturn *this
  EndProcedure
  Procedure.i _Free_(*this.object)
    FreeStructure(*this)
  EndProcedure
  Procedure.i Free(*this.object)
    FreeDialog(*this\dialog_no)
    _Free_(*this)
  EndProcedure
  Procedure.i _New_()
    Protected *new.object = AllocateStructure(object)
    If *new: *new\_method_table_ = ?method_table
    Else: MessageRequester("Runtime Class Allocation Error","Allocation of Object 'Dialog' failed."): End
    EndIf
    ProcedureReturn *new
  EndProcedure
  Procedure.i NewCatchXML(window_name.s, adress, size, free_xml=#False, x=0, y=0)
    Protected *this.object = _New_()
    *this\xml_no = CatchXML(#PB_Any, adress, size)
    xml_number   = *this\xml_no
    CheckXMLTree(*this\xml_no)
    *this\dialog_no = OpenXMLDialog_(*this\xml_no, window_name, x, y)
    If free_xml
    FreeXML(*this\xml_no)
    *this\xml_no = 0
    EndIf
    *this\window_no = DialogWindow(*this\dialog_no)
    ProcedureReturn *this
  EndProcedure
  Procedure.i NewParseXML(window_name.s, string_name.s, free_xml=#False, x=0, y=0)
    Protected *this.object = _New_()
    *this\xml_no = ParseXML(#PB_Any, string_name)
    xml_number   = *this\xml_no
    CheckXMLTree(*this\xml_no)
    *this\dialog_no = OpenXMLDialog_(*this\xml_no, window_name, x, y)
    If free_xml
    FreeXML(*this\xml_no)
    *this\xml_no = 0
    EndIf
    *this\window_no = DialogWindow(*this\dialog_no)
    ProcedureReturn *this
  EndProcedure
  ; DataSection of Public Instance Procedures (Methods)
  DataSection
    method_table:
    Data.i @Free()
  EndDataSection
EndModule
LG Tom und Danke
Testcode im nächsten Post
Ich habe das auch im englischen Forum gepostet: http://www.purebasic.fr/english/viewtop ... 13&t=68207