GetGadgetFont & FreeFont

Für allgemeine Fragen zur Programmierung mit PureBasic.
BSP
Beiträge: 203
Registriert: 01.02.2009 14:04

GetGadgetFont & FreeFont

Beitrag von BSP »

Hallo.

Ich möchte eine Prozedure schreiben,
in der die Gadgets möglichst autonom arbeiten.
Soll heissen, sämtliche ID's werden per #PB_Any bestimmt.
Die Gadgets bekommen auch eigene Fonts,
die beim beenden des Fensters auch wieder frei gegeben werden sollen.

font=GetGadgetFont(butt)
FreeFont(font)

So einfach gehts aber leider nicht.
Das Gadget wird ja beim beenden des Fensters freigegeben.
Da brauche ich mich also nicht drum kümmern.
Wie bekomme ich die passende Font ID,
um auch den Font wieder frei zu geben?
Oder gibts ein Api, um den Font frei zu geben?

Gruß: BSP

Code: Alles auswählen

Procedure MsG_Hinweis(wnd)
  font1=FontID(LoadFont(#PB_Any,"",30))
  font2=FontID(LoadFont(#PB_Any,"",10))
  
  win=OpenWindow(#PB_Any ,0,0,100,100,a2$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,WindowID(wnd))
  
  butt=ButtonGadget(#PB_Any,10,10,80,80,"Ok")
  SetGadgetFont(butt,font1)
  
  Repeat
    ev=WaitWindowEvent()
    If ev=#WM_CLOSE : ende=1 : EndIf
    If ev=#PB_Event_Gadget And EventGadget()=butt
      If GetGadgetFont(butt)=font1
        SetGadgetFont(butt,font2)
      Else
        SetGadgetFont(butt,font1)
      EndIf
    EndIf
  Until ende
  
  ; ------------------------------------
  ; -- Auf diese beiden kommts mir an:--
  font=GetGadgetFont(butt)
  ;FreeFont(FontID(font))
  ; ------------------------------------
  CloseWindow(win)
EndProcedure

win=OpenWindow(#PB_Any ,0,0,200,200,a2$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

Msg_Hinweis(win)

Repeat
Until WaitWindowEvent()=#WM_CLOSE
End
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: GetGadgetFont & FreeFont

Beitrag von Danilo »

Du übergibst an FreeFont eine FontID() statt einer FontNummer, deshalb Crash.
Geht wenn Du die Fontnummer zwischenspeicherst:

Code: Alles auswählen

Procedure MsG_Hinweis(wnd)
  f1=LoadFont(#PB_Any,"",30)
  f2=LoadFont(#PB_Any,"",10)
  font1=FontID(f1)
  font2=FontID(f2)
 
  win=OpenWindow(#PB_Any ,0,0,100,100,a2$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,WindowID(wnd))
 
  butt=ButtonGadget(#PB_Any,10,10,80,80,"Ok")
  SetGadgetFont(butt,font1)
 
  Repeat
    ev=WaitWindowEvent()
    If ev=#WM_CLOSE : ende=1 : EndIf
    If ev=#PB_Event_Gadget And EventGadget()=butt
      If GetGadgetFont(butt)=font1
        SetGadgetFont(butt,font2)
      Else
        SetGadgetFont(butt,font1)
      EndIf
    EndIf
  Until ende
 
  CloseWindow(win)
  ; ------------------------------------
  ; -- Auf diese beiden kommts mir an:--
  FreeFont(f1)
  FreeFont(f2)
  ; ------------------------------------
EndProcedure

win=OpenWindow(#PB_Any ,0,0,200,200,a2$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

Msg_Hinweis(win)

Repeat
Until WaitWindowEvent()=#WM_CLOSE
End
Du solltest auch die Fonts nicht freigeben wenn sie noch benutzt werden,
deshalb habe ich das CloseWindow() davor gemacht. Oder Du machst ein
FreeGadget() vor FreeFont().
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
BSP
Beiträge: 203
Registriert: 01.02.2009 14:04

Re: GetGadgetFont & FreeFont

Beitrag von BSP »

Hallo Danilo.
Danke für die schnelle Antwort.
Aber es hilft noch nicht weiter.
Letztenendes soll das ein eigenes Gadget werden. Quasi.
Ich will es als Baustein in ein Progarmm einsetzen,
ohne mich vorher um die "Global"isierung der Variablen kümmern zu müssen.
(Deshalb auch alles mit #PB_Any).
Auch will ich die Procedure (das Gadget) verlassen können
und später an anderer Stelle das Window löschen können,
ohne das vorher die ID's bekannt sind.

Ich habe mal ein Beispiel aus der WinAPI Library.exe von RSBasic
leicht verändert, damit Du eine bessere Vorstellung davon bekommst,
was mir vorschwebt.

Code: Alles auswählen

EnableExplicit

Define EventID
Define Font

Procedure ListWindows(hwnd,Param)
  Protected String$
  Protected String2$
  Protected font
  
  String$ = Space(250)
  String2$ = Space(1024)
  GetWindowText_(hwnd,String$,250)
  GetClassName_(hwnd,@String2$,Len(String2$))
  
  Debug "Handle-Nummer des Gadgets: "+Str(hwnd)
  Debug "PureBasic-Nummer des Gadgets: "+Str(GetProp_(hwnd, "PB_ID"))
  Debug "Typ des Gadgets: "+String2$
  Debug "Inhalt des Gadgets: "+String$
  font=GetGadgetFont(GetProp_(hwnd, "PB_ID"))
  Debug "FontID : "+Str(font)
  Debug "--------------------------------------------------------------------"
  
  ;FreeFont(FontID(font))
  
  ProcedureReturn #True
EndProcedure

If OpenWindow(0,0,0,500,400,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ButtonGadget(1,10,10,120,30,"Hallo Button",0)
  font=LoadFont(#PB_Any,"",16)
  SetGadgetFont(1,FontID(font))
  Debug "Font : "+Str(FontID(font))
  Debug "--------------------------------------------------------------------"
  StringGadget(2,140,10,100,20,"Hallo Edit",0)
  ListViewGadget(3,10,50,100,100,0)
  
  EnumChildWindows_(WindowID(0),@ListWindows(),0)
  
  Repeat
    EventID=WaitWindowEvent()
    If EventID = #PB_Event_CloseWindow
      End
    EndIf
  ForEver
EndIf
Gruß: BSP

PS. Klar, einen Font zu löschen, der noch gebraucht wir, ist nicht die feine Art.
Im späteren Programm wird das natürlich noch verbessert.
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
Bisonte
Beiträge: 2476
Registriert: 01.04.2007 20:18

Re: GetGadgetFont & FreeFont

Beitrag von Bisonte »

Mir ist nicht ganz klar, was Du meinst...

Wenn ich das richtig sehe, ist das eine "MessageBox" also sowas, was das MessageRequester() macht.
Und bei soetwas verstehe ich den Sinn eines Verlassens der Procedure und späteren schliessen des
dort geöffneten Window nicht so ganz...

Um das als "Baustein" ohne Gedanken an Globalisierung usw. machen zu müssen, solltest du allerdings
noch ein bisschen Tuning betreiben.
z.B. ein "Protected" der benutzten Variablen innerhalb der Prozedur ist dringend vonnöten, damit es nicht
aus Versehen mit einer Globalen Variablen kollidiert...
Ausserdem sollte so eine "Baustein" Prozedure nur mit den Variablen auskommen, die als Parameter übergeben
werden.
Das a2$ z.B. ist höchstwahrscheinlich eine Globale Variable, die vielleicht in einem späteren Projekt nicht vorkommt.

Also ich meine das in etwa so...

Code: Alles auswählen

Procedure.i Msg_Hinweis(Titel.s, Fontname.s, ParentWindow)
  
  Protected Font1 = LoadFont(#PB_Any, Fontname, 30)
  Protected Font2 = LoadFont(#PB_Any, Fontname, 10)
  Protected Win, Btn, Event, Quit = 0
  
  Win = OpenWindow(#PB_Any ,0,0,100,100,Titel,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,WindowID(ParentWindow))
  
  Btn = ButtonGadget(#PB_Any,10,10,80,80,"Ok")
  SetGadgetFont(Btn,FontID(Font1))
  
  Repeat
    Event = WaitWindowEvent(25)
    
    If Event = #WM_CLOSE And EventWindow() = Win
      Quit = 1
    EndIf
    
    If Event = #PB_Event_Gadget
      If EventGadget() = Btn
        If GetGadgetFont(Btn) = FontID(Font1)
          SetGadgetFont(Btn,FontID(Font2))
        Else
          SetGadgetFont(Btn,FontID(Font1))
        EndIf
      EndIf
    EndIf
    
  Until Quit > 0
  
  CloseWindow(Win)
  FreeFont(Font1)
  FreeFont(Font2)
  
EndProcedure

win=OpenWindow(#PB_Any ,0,0,200,200,a2$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

MsgHinweis(a2$, "", win)

Repeat
Until WaitWindowEvent()=#WM_CLOSE
End
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
BSP
Beiträge: 203
Registriert: 01.02.2009 14:04

Re: GetGadgetFont & FreeFont

Beitrag von BSP »

Hallo Bisonte.

Mir geht es in der Hauptsache um diese drei Zeilen:

font=GetGadgetFont(butt)
CloseWindow(win)
FreeFont(font)

Der Grundgedanke dabei war,
die Verwaltung der ID's dem System zu überlassen
und diese dann bei Bedarf abzurufen und zu verarbeiten.
Das scheint aber in diesem Fall nicht zu gehen.
Schade, hält das System doch alle Werte bereit.

Ok, dann also wieder auf die gute Art alles vorher festlegen.
Ursprünglich hatte ich mit #PB_Any versucht anstatt mit Konstanten.

Anbei noch mal den Code, an dem ich gerade bastel.
Bitte nicht zu streng sein, ich weis das der sch... ist,
weil ich am Experimentieren bin, was geht und was nicht.

Code: Alles auswählen

Global AnzFonts=1

Enumeration ;AnzFonts
  #HinweisFont1
  #HinweisFont2
  #HinweisFont3
EndEnumeration
AnzFonts=#PB_Compiler_EnumerationValue


Procedure ListWindows(hwnd,Param)
  Protected String$
  Protected String2$
  Protected font
  
  String$ = Space(250)
  String2$ = Space(1024)
  GetWindowText_(hwnd,String$,250)
  GetClassName_(hwnd,@String2$,Len(String2$))
  
  Debug "Handle-Nummer des Gadgets: "+Str(hwnd)
  Debug "PureBasic-Nummer des Gadgets: "+Str(GetProp_(hwnd, "PB_ID"))
  Debug "Typ des Gadgets: "+String2$
  Debug "Inhalt des Gadgets: "+String$
  font=GetGadgetFont(GetProp_(hwnd, "PB_ID"))
  Debug "FontID : "+Str(font)
  Debug "--------------------------------------------------------------------"
  
  ;FreeFont((font))
  
  ProcedureReturn #True
EndProcedure

Procedure MyCloseWindow(wnd)
  EnumChildWindows_(WindowID(wnd),@ListWindows(),0)
  CloseWindow(wnd)
EndProcedure

Procedure Hinweis(wnd,a1$,a2$,a3$, ok=0)
  Protected font1 , font2 , font3
  
  fl=#PB_Window_ScreenCentered
  fl|#PB_Window_Tool
  fl|#PB_Window_SystemMenu
  If a2$="":a2$="Hinweis":EndIf
  win=OpenWindow(#PB_Any ,0,0,0,0,a2$,fl,WindowID(wnd))
; ----- Fensterbreite ermitteln
  ; --- erst das Textfeld
  fonth3=16
  LoadFont(#HinweisFont3,"",fonth3)
  StartDrawing(WindowOutput(win))
  DrawingFont(FontID(#HinweisFont3))
  zeilen=CountString(a3$,#LF$)+1
  For i=1 To zeilen
    a$=StringField(a3$,i,#LF$)
    a=TextWidth(a$)
    If txtw<a:txtw=a:EndIf
    a=TextHeight(a$)
    If txth<a:txth=a:EndIf
  Next
  StopDrawing()
  feld3w=txtw+16
  feld3h=txth*zeilen+8
  
  ; --- Das Symbolfeld
  If Not a1$=""
    LoadFont(#HinweisFont1,"",fonth3*zeilen)
    StartDrawing(WindowOutput(win))
    DrawingFont(FontID(#HinweisFont1))
    feld1h=feld3h
    feld1w=TextWidth(a1$)+8
    StopDrawing()
  EndIf
  ; --- Die buttonmaße
  If ok:butth=2*txth:EndIf
  
; --- Fenster einstellen
  winw=feld1w + feld3w
  winh=feld3h + butth
  ExamineDesktops()
  x=DesktopWidth(0)/2  - winw/2
  y=DesktopHeight(0)/2 - winh/2
  ResizeWindow(win,x,y,winw,winh)
  If Not a1$=""
    i=TextGadget(#PB_Any,0,0,feld1w,feld1h,a1$,#SS_CENTER);|#PB_Text_Border
    SetGadgetFont(i,FontID(#HinweisFont1))
  EndIf
  i=TextGadget(#PB_Any,feld1w,0,feld3w,feld3h,a3$,#SS_CENTER);|#PB_Text_Border
  SetGadgetFont(i,FontID(#HinweisFont3))
  If ok
    StartDrawing(WindowOutput((win)))
    DrawingFont(FontID(#HinweisFont3))
    w=TextWidth(" Ok ")+4
    StopDrawing()
    x=winw/2 - w/2
    y=feld3h + txth/2
    h=txth+4
    butt=ButtonGadget(#PB_Any,x,y,w,h," Ok ")
    SetGadgetFont(i,FontID(#HinweisFont3))
  EndIf
  If ok
    Repeat
    Until WaitWindowEvent()=#PB_Event_Gadget And EventGadget()=butt
    a=GetGadgetFont(butt)
    CloseWindow(win)
    ;FreeFont(FontID(a))
    win=0
  EndIf
  ProcedureReturn win
EndProcedure

fl=#PB_Window_ScreenCentered
fl|#PB_Window_SystemMenu
wnd=OpenWindow(#PB_Any ,0,0,300,200,a2$,fl)

a$="Dies"+#LF$
a$+"ist ein"+#LF$
a$+"Beispieltext"+#LF$+#LF$
a$+"Daten werden Eingelesen"
butt=0
;butt=1
win=Hinweis(wnd,"!","",a$,butt)

If butt =0
  ; Aktion, z.B. Daten einlesen
  Delay(4000)
EndIf

If win
  MyCloseWindow(win)
EndIf

Repeat:Until WaitWindowEvent()=#WM_CLOSE

Gruß & Dank:
BSP
PB 5.31 (x86) & (x64) Win10
Antworten