Textgadget autosize

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Dorian a écrit :48 c'est déjà plus que bien ^^
tu les connais pas , ils sont difficile ! :lol: :lol:

ps : je viens de corriger un petit truc , maintenant ça doit allé :D
(toujours avec la limitation 48 et text un peut trop long ...)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

j'ai isolé le problème. Comme j'avais fait mes tests dans une callback et le hDC que je recois par wParam n'est pas le même que celui retourné par GetDC_().

donc maintenant la question c'est comment obtenir ce hDC en dehors d'un message ? (exemple WM_CTLCOLORSTATIC)

Dri :-?
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

voila ce que j'ai réussi à coder... ca ne fonctionne correctement que pour les chaines de caractere sans retour a la ligne :-?

Code : Tout sélectionner

Procedure AutosizeCallback(WindowID.l, Message.l, wParam.l, lParam.l)
  Protected WndProc.l, Gadget.l, Size.Size
  Protected Text.s, Field.s, Count.l, i.l, w.l, h.l
  
  WndProc = GetProp_(WindowID, "AutosizeWndProc")
  
  If Message = #WM_CTLCOLORSTATIC And GetProp_(lParam, "AutosizeValue")
    Gadget = GetDlgCtrlID_(lParam)
    
    Text = GetGadgetText(Gadget)
    
    ;vire les retours charriot
    Text = ReplaceString(Text, #CRLF$, #LF$)
    Text = ReplaceString(Text, #CR$, #LF$)
    
    Count = CountString(Text, #LF$) + 1
    
    For i = 1 To Count
      Field = StringField(Text, i, #LF$)
      GetTextExtentPoint32_(wParam, Field, Len(Field), Size)
      
      If w < Size\cx
        w = Size\cx
        Size\cx = 0
      EndIf
    Next i
    
    h = Size\cy * Count
    ResizeGadget(Gadget, #PB_Default, #PB_Default, w, h)
  EndIf
  
  ProcedureReturn CallWindowProc_(WndProc, WindowID, Message, wParam, lParam)
EndProcedure

Procedure SetTextGadgetAutosize(TextGadget.l, Autosize.l)
  Protected GadgetID.l, WindowID.l, WndProc.l
  
  If IsGadget(TextGadget)
    GadgetID = GadgetID(TextGadget)
    SetProp_(GadgetID, "AutosizeValue",  Autosize)
    
    WindowID = GetParent_(GadgetID)
  
    If GetProp_(WindowID, "AutosizeWndProc") = #Null
      WndProc = SetWindowLong_( WindowID, #GWL_WNDPROC, @AutosizeCallback() )
      SetProp_(WindowID, "AutosizeWndProc", WndProc)
    EndIf
    
    InvalidateRect_(GadgetID, #Null, #True)
  EndIf
EndProcedure

If OpenWindow(0,0,0,270,160,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"TextGadget") And CreateGadgetList(WindowID(0))
  label.s = "Auto size"
  label + #CRLF$ + "ceci est un exemple"
  label + #CRLF$ + "c'est simple"
  
  TextGadget(0, 10, 10, 250, 20, label)
  TextGadget(1, 10, 50, 250, 20, label)
  
  ;change de police pour le fun
  LoadFont(0, "Verdana", 18)
  SetGadgetFont(0, UseFont(0))
  SetGadgetFont(1, UseFont(0))
  
  ;change la couleur de la fenetre pour avoir un visuel
  hBrush = CreateSolidBrush_($FFFFFF)
  SetClassLong_(WindowID(), #GCL_HBRBACKGROUND, hBrush)
  InvalidateRect_(WindowID(), #Null, #True)
  
  ;autosize le 2e gadget
  SetTextGadgetAutosize(1, #True)
  
  Repeat
  Until WaitWindowEvent()=#PB_Event_CloseWindow
  
  DeleteObject_(hBrush)
EndIf
[edit]
le bug semble venir de stringfield

[edit]
j'ai changé les #CRLF$ en #LF$ et ca fonctionne, je pense que c'est soit un bug de stringfield, soit un truc qui manque dans l'aide

[edit]
c'est ma faute, pas de bug dans stringfield ^^, je modifirai le code en conséquence

[edit]
j'avais oublié de virer les Debug

Dri
Dernière modification par Dr. Dri le lun. 26/déc./2005 22:58, modifié 3 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

je viens de remodifier mon listing .... :)

@ Dri , je test ton truc :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

j'ai changer la ligne

"LoadFont(0, "Verdana", 18)" par "LoadFont(0, "Verdana", 48)"

la fenetre ne se redimentionne pas !! :?
mon system ne marche pas si mal finalement !! :D
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Dobro a écrit :j'ai changer la ligne

"LoadFont(0, "Verdana", 18)" par "LoadFont(0, "Verdana", 48)"

la fenetre ne se redimentionne pas !! :?
mon system ne marche pas si mal finalement !! :D
Dans mon exemple c'est le textgadget qui s'auto dimensionne
(c'est pour ca que j'en ai mis deux en exemple ^^)

voila un code qui change la taille de la fenetre
(j'ai pas remis les fonctions "autosize")

Code : Tout sélectionner

If OpenWindow(0,0,0,270,160,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"TextGadget") And CreateGadgetList(WindowID(0))
  label.s = "Auto size"
  label + #CRLF$ + "ceci est un exemple"
  label + #CRLF$ + "c'est simple"
  
  TextGadget(0, 0, 00, 250, 20, label)
  
  ;change de police pour le fun
  LoadFont(0, "Verdana", 18)
  SetGadgetFont(0, UseFont(0))
  
  ;autosize le gadget
  SetTextGadgetAutosize(0, #True)
  
  Repeat
    If WindowWidth() <> GadgetWidth(0) Or WindowHeight() <> GadgetHeight(0)
      ResizeWindow( GadgetWidth(0), GadgetHeight(0) )
    EndIf
  Until WaitWindowEvent()=#PB_Event_CloseWindow
  
  DeleteObject_(hBrush)
EndIf
Dri ;)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

ouaip ! :D ça marche ...

et que pense tu de cette exemple qui utilise l'autre methode ?

(nouveau listing ..)


  ; PureBasic Visual Designer v3.92 build 1460

;- Window Constants
Declare Open_message(text$,taille)

Enumeration
     #message
     #Police
     #Button_0
     #Text_0
EndEnumeration

text$= "hello " + Chr (10)+ Chr (13)+ "comment vas tu ?" ; <----------------------------ICI ajoute du text
taille=8 ; <----------------------------ICI change la taille
Open_message(text$,taille)



; ******************* boucle principale ****************
Repeat ; Start of the event loop
    Event = WaitWindowEvent () ; This line waits until an event is received from Windows
     WindowID = EventWindowID () ; The Window where the event is generated, can be used in the gadget procedures
     GadgetID = EventGadgetID () ; Is it a gadget event?
     EventType = EventType () ; The event type
     If Event = #PB_EventGadget
         If GadgetID = #Button_0
             End
         EndIf
     EndIf
Until Event = #PB_Event_CloseWindow ; End of the event loop
End
;**********************************



Procedure Open_message(text$,taille)
     FontID = LoadFont ( #Police , "Comic Sans MS" , taille, #PB_Font_Bold )
    long=( Len (text$)*taille)
     If OpenWindow ( #message , 10, 10,long, 50+long/8, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar , "message" )
         If CreateGadgetList ( WindowID ())
             ButtonGadget ( #Button_0 , 0, WindowHeight ()-30, 60, 30, "ok" )
             TextGadget ( #Text_0 , 30, (taille/8 ), 140+long, taille*200, text$)
             SetGadgetFont ( #Text_0 , FontID )
         EndIf
     EndIf
EndProcedure
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Dobro a écrit :ouaip ! :D ça marche ...

et que pense tu de cette exemple qui utilise l'autre methode ?
C'est risqué de se baser sur le nombre de caractères, les 'i' ne sont pas aussi longs que les 'm'

Dri ;)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Dr. Dri a écrit :
Dobro a écrit :ouaip ! :D ça marche ...

et que pense tu de cette exemple qui utilise l'autre methode ?
C'est risqué de se baser sur le nombre de caractères, les 'i' ne sont pas aussi longs que les 'm'

Dri ;)

c'est pour ça que j'ai laissé de la marge de chaque coté !! :wink:

de toute façon ta methode comme la mienne se trouve bloqué par le system
en largeur de fenetre !! essaye d'entrer une phrase du genre

"comment vas tu ?comment vas tu ?comment vas tu ?comment vas tu ?comment vas tu ?comment vas tu ?"

tu vas voir qu'elle sera troncqué !!!! (dans les deux methode !! )

:lol:
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

J'ai découvert une autre faiblesse dans le code, faut que je trouve le moyen de faire un refresh auto genre intercepter les évennements de changement (texte, police etc)
Voila un exemple qui gère le refresh en manuel

Code : Tout sélectionner

Procedure AutosizeCallback(WindowID.l, Message.l, wParam.l, lParam.l)
  Protected WndProc.l, Gadget.l, Size.Size
  Protected Text.s, Field.s, Count.l, i.l, w.l, h.l
  
  WndProc = GetProp_(WindowID, "AutosizeWndProc")
  
  If Message = #WM_CTLCOLORSTATIC And GetProp_(lParam, "AutosizeValue")
    Gadget = GetDlgCtrlID_(lParam)
    
    Text = GetGadgetText(Gadget)
    
    ;vire les retours charriot
    Text = ReplaceString(Text, #CRLF$, #LF$)
    Text = ReplaceString(Text, #CR$, #LF$)
    
    Count = CountString(Text, #LF$) + 1
    
    For i = 1 To Count
      Field = StringField(Text, i, #LF$)
      GetTextExtentPoint32_(wParam, Field, Len(Field), Size)
      
      If w < Size\cx
        w = Size\cx
        Size\cx = 0
      EndIf
    Next i
    
    h = Size\cy * Count
    ResizeGadget(Gadget, #PB_Default, #PB_Default, w, h)
  EndIf
  
  ProcedureReturn CallWindowProc_(WndProc, WindowID, Message, wParam, lParam)
EndProcedure

Procedure SetTextGadgetAutosize(TextGadget.l, Autosize.l)
  Protected GadgetID.l, WindowID.l, WndProc.l
  
  If IsGadget(TextGadget)
    GadgetID = GadgetID(TextGadget)
    SetProp_(GadgetID, "AutosizeValue",  Autosize)
    
    WindowID = GetParent_(GadgetID)
    
    If GetProp_(WindowID, "AutosizeWndProc") = #Null
      WndProc = SetWindowLong_( WindowID, #GWL_WNDPROC, @AutosizeCallback() )
      SetProp_(WindowID, "AutosizeWndProc", WndProc)
    EndIf
    
    InvalidateRect_(GadgetID, #Null, #True)
  EndIf
EndProcedure

If OpenWindow(0,0,0,270,160,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"TextGadget") And CreateGadgetList(WindowID(0))
  
  StringGadget(0, 10, 10, 250, 20, "")
  TextGadget  (1, 10, 40, 250, 20, "")
  
  ;change la couleur de la fenetre pour avoir un visuel
  hBrush = CreateSolidBrush_($FFFFFF)
  SetClassLong_(WindowID(), #GCL_HBRBACKGROUND, hBrush)
  InvalidateRect_(WindowID(), #Null, #True)
  
  ;autosize le textgadget
  SetTextGadgetAutosize(1, #True)
  
  ;donne le focus au stringgadget
  ActivateGadget(0)
  
  ;synchronise les deux gadgets
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget And EventGadgetID() = 0
      If EventType() = #PB_EventType_Change
        SetGadgetText(1, GetGadgetText(0))
        ;l'autosize n'est pas encore au point, faut un refresh
        InvalidateRect_(WindowID(), #Null, #True)
      EndIf
    EndIf
    
  Until Event = #PB_Event_CloseWindow
 
  DeleteObject_(hBrush)
EndIf
Dri :(
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Oué c'est ca va marcher avec certaines polices, mais pas toutes...
Là tu nous fais ça à l abarbare DoBro !!! :lol:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

lionel_om a écrit :Oué c'est ca va marcher avec certaines polices, mais pas toutes...
Là tu nous fais ça à l abarbare DoBro !!! :lol:
ben donne moi une police ou ça marche pas ? .... 8O

fait pas d'affirmation gratuite , assure .. :lol:

il est de toute façon facile d'adapter le code , il restera toujours plus petit qu'en utilisant les aPIs !! :D
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Si tu prend une police classique ca va marcher, mais si tu prend une police pas ordinaire et très large, ca va pas bien marcher

Par contre utilise le param "Border" pour tes TextGadgets car regarde, il sont largement trop grands...
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

soit ! soit ! :)
CameleonTH
Messages : 333
Inscription : sam. 25/juin/2005 11:18
Localisation : Laon (02)
Contact :

Message par CameleonTH »

@Dr. Dri
Sa serait pas mal un exemple du méme type mais non pas dans une fenétre window mais dans un screen. :D
Répondre