oop

Anfängerfragen zum Programmieren mit PureBasic.
delikanli_19_82
Beiträge: 173
Registriert: 30.11.2010 02:34

oop

Beitrag von delikanli_19_82 »

hallo leute,

ich bin am verzweifeln. ich habe mir diese Interface sache angeschaut und versuche mir damit eine Klasse für ein eigenes Button zu basteln. Basiert auf den ImageGadget. An sich läuft alles.

also das ganze sieht ja in etwa so aus:

Code: Alles auswählen

; Globale Style Parameter die später alle Instanzen einfärben soll
Global guiBkgColor.l = RGB( 200, 200, 200 )
Global guiTxtColor.l = RGB(   0,   0,   0 )
Global guiRdl1Color.l = RGB( 240, 240, 240 )
Global guiRdl2Color.l = RGB( 230, 230, 230 )
Global guiRdb1Color.l = RGB( 120, 120, 120 )
Global guiRdb2Color.l = RGB( 140, 140, 140 )
Global guiFontSize.l = 10
Global guiFontName.s = "ARIAL"
Global guiStyle.l = 0

; Zählt die gesamte aller verfügbaren Gadgets und identifiziert jedes einzelne über eine
; eindeutige Gadget-Nr
Global GID.l = 0

; Interface
; WARUM KANN MAN HIER EIGENTLICH KEINE VARIABLEN ANGEBEN?
; SOZUSAGEN ALS EIGENSCHAFTEN DES OBJEKTS?
Interface guiButton
    Type.s()
    Show.b()
    Name.l()
    Resize.b(w.l,h.l)
EndInterface

; INTERNE KRAM
Structure guiButton_Object
  VTable.l
  ID.l ; > SOLL EIGENTLICH DIE GID-NR des Gadgets enthalten und über Name() abrufbar sein
  Functions.l[SizeOf(guiButton)/4]
EndStructure

  ; GIBT AN, DAS ES SICH BEI DIESER KLASSE UM EIN BUTTON handelt
  Procedure.s guiButton__Type(*this.guiButton)
        ProcedureReturn "guiButton"
  EndProcedure

  ; ZEICHNET DEN GADGET AUF DEM SCHIRM
  ; WIESO KLAPPT ES MIT DEM FONTNAME und FONTSIZE NICHT?
  Procedure.b guiButton__Show(*this.guiButton)
      *object.guiButton_Object = AllocateMemory(SizeOf(guiButton_Object))
      Define t.s = "guiButton"
      Define p.l = GID : GID = GID + 1
      *object\ID = p
      Define w.l = 70 : Define h.l = 25
      Define ff.l = LoadFont(#PB_Any,guiFontName,guiFontSize)
      If CreateImage(p, w, h) And StartDrawing(ImageOutput(p))

        Box(0,0, w, h, guiBkgColor )
        Line( 0, 0, w-1, 1, guiRdl1Color )
        Line( 0, 0, 1, h-1, guiRdl1Color )
        Line( 0, h-1, w-1, 1, guiRdb1Color )
        Line( w-1, 0, 1, h, guiRdb1Color )

        If guiStyle = 0
          Line( 1, 1, w-2, 1, guiRdl2Color )
          Line( 1, 1, 1, h-2, guiRdl2Color )
          Line( 1, h-2, w-2, 1, guiRdb2Color )
          Line( w-2, 1, 1, h, guiRdb2Color )
        EndIf

        tx.l = (w - TextWidth(t)) / 2
        ty.l = (h - TextHeight(t)) / 2

        SetGadgetFont(p,ff)
        DrawText( tx, ty, t, guiTxtColor, guiBkgColor )

        StopDrawing()   
        ImageGadget(p, 0, 0, w, h, ImageID(p))
        ProcedureReturn #True 
      Else
        ProcedureReturn #False
      EndIf
  EndProcedure

  ; SOLL DIE GADGET NUMMER ZURÜCKGEBEN
  ; AN DIESER STELLE HABE ICH KEINE AHNUNG, WIE WEITER. ICH MUSS
  ; IRGENDWIE AN DIE "ID" in guiButton_Object, das beim Konstruktur
  ; ANGELEGT WIRD    
  Procedure.l guiButton__Name(*this.guiButton)
        ProcedureReturn 0 ; ?
  EndProcedure
  
  ; SOLL DEN GADGET AN HAND DES Gadget-Nr's resizen
  Procedure.b guiButton__Resize(*this.guiButton,*me.guiButton_Object,w.l,h.l)
        ;If IsGadget(*me\ID)
        ;    ResizeGadget(*me\ID,#PB_Ignore,#PB_Ignore,w,h)
        ;EndIf
        ProcedureReturn 0
  EndProcedure

  ; Konstructor
  Procedure guiButton()
    ; Function table
    *object.guiButton_Object = AllocateMemory(SizeOf(guiButton_Object))
    If *object=0: ProcedureReturn 0: EndIf
    
    *object\VTable  = *object+OffsetOf(guiButton_Object\Functions)
    *object\Functions[0] = @guiButton__Type()
    *object\Functions[1] = @guiButton__Show()
    *object\Functions[2] = @guiButton__Name()
    *object\Functions[3] = @guiButton__Resize()
    ProcedureReturn *object
  EndProcedure

; Testen
*obj1.guiButton = guiButton()
*obj2.guiButton = guiButton()

OpenWindow(0,60,60,200,200,"",#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget)

If *obj1 : *obj1\Show() : EndIf
If *obj2 : *obj2\Show() : EndIf

ResizeGadget(*obj1\Name(),#PB_Ignore,90,#PB_Ignore,#PB_Ignore)
ResizeGadget(*obj2\Name(),#PB_Ignore,50,#PB_Ignore,#PB_Ignore)

SetWindowTitle( 0, Str(*obj2\Name()) )

Repeat
  Event.l = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
ich möchte nun eine Methode "Name()" anlegen, das die ID des Objekts zurück gibt. Dazu habe ich eine globale Variable GID für GadgetID definiert.

Sie wird von einer Methode Show() der Klasse beim Aufruf inkrementiert und damit wird der ImageGadget generiert.

die ID soll aber eben in die Struktur klasse_intern abgelegt werden, so das ich später sowas machen:

Code: Alles auswählen

*button1.klasse = klasse()
*button1.Show()

*button2.klasse = klasse()
*button2.Show()

resizegadget(button1.Name(),0,0,100,30)
resizegadget(button2.Name(),50,50,120,40)
ich grübelle schon seit mehr als 3 stunden daran und habe bei google eine menge gelesen und auch hier im forum bin ich nicht fündig geworden.

kann mir jemand helfen?

mfg
kurt
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: oop

Beitrag von CSHW89 »

Ja das mit OOP und PureBasic ist ein wenig tricky. Du kannst die Strukturen und das Interface mit der selben Speicheradresse verwenden.
Also folgendes:

Code: Alles auswählen

*gui.guiButton = guiButton()
Debug *gui\Name()   ; Hier wird *gui als Klassenobjekt verwendet

*guiObj.guiButton_Object = *gui   ; Die Speicheradresse kann aber auch mit der Object-Structure verwendet werden
Debug *guiObj\ID
Bei deinem konkreten Fall kannst du entweder in der Name-Procedure die Structure zu 'guiButton_Object' ändern. oder in die Procedure folgendes schreiben:

Code: Alles auswählen

*guiObj.guiButton_Object = *gui
ProcedureReturn *guiObj\ID
lg kevin

PS: Deine guiButton-Procedure ist übrigens ein wenig merkwürding. Müsste so funktonieren, aber du allokierst erstmal Speicher mit größe 'SizeOf(guiButton)' in der ja schon die Funktionen drin sind, und dann nochmal einen Speicher für die funktionen.

Wenn jedes guiButton-Objekt die gleichen Funktionen benutzt, könntest du auch sowas machen:

Code: Alles auswählen

  ; Konstructor
  Procedure guiButton()
    ; Function table
    *object.guiButton_Object = AllocateMemory(SizeOf(guiButton_Object))
    If *object=0: ProcedureReturn 0: EndIf
   
    *object\VTable  = ?guiButton_Functions
    
    ProcedureReturn *object
    
    DataSection
      guiButton_Functions:
      Data.i @guiButton__Type(), @guiButton__Show(), @guiButton__Name(), @guiButton__Resize()
    EndDataSection
  EndProcedure
In der Structure dann den Eintrag mit den Funktionen löschen
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
delikanli_19_82
Beiträge: 173
Registriert: 30.11.2010 02:34

Re: oop

Beitrag von delikanli_19_82 »

hi CSHW89,

danke für dein feedback. sorry das es so lange gedauert hat.

ich bin bei http://www.purearea.net/pb/german/index.htm etwas fündig geworden.

vielen dank trotz allem für dein ansatz.

mfg

kurt
Antworten