StringGadget Vertical?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: StringGadget Vertical?

Post by Michael Vogel »

Sorry to say that, but here (Windows 8.1) it's still displaying a second line under some circumstances. To see the issue, just add ResizeWindow(0,#PB_Ignore,#PB_Ignore,100,#PB_Ignore) before the Repeat line and add "1 2 3" (including spaces) at the beginning of the text.
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: StringGadget Vertical?

Post by Michael Vogel »

Still fighting, just did a slightly modified approach (for right alignment only) which fails as soon characters are deleted and some others added again...

Code: Select all

Procedure StringGadgetVCenter(gadget)

	Protected hwndEdit
	Protected hdc
	Protected fsz.SIZE
	Protected erect.RECT
	Protected height
	Protected s.s

	height=GadgetHeight(gadget)
	width=GadgetWidth(gadget)

	s=GetGadgetText(gadget)
	hwndEdit=GadgetID(gadget)
	hdc=GetDC_(hwndEdit)
	SelectObject_(hdc,GetGadgetFont(Gadget))
	If s
		GetTextExtentPoint32_(hdc,s,Len(s),fsz)
	Else
		GetTextExtentPoint32_(hdc,"!",1,fsz)
		fsz\cx=0
	EndIf
	ReleaseDC_(hwndEdit,hdc)

	Debug "Limit: "+Str(fsz\cx)+" / "+Str(fsz\cy)

	GetClientRect_(hwndEdit,eRect)
	eRect\left=width-fsz\cx-2
	eRect\top=height>>1-fsz\cy<<4/20
	eRect\bottom=height+fsz\cy>>1
	SendMessage_(hwndEdit,#EM_SETRECT,0,eRect)

EndProcedure

Text$ = "Test for vertical centered text - horizontal (above) or right aligned (below)..."

OpenWindow(0,0,0,300,200,"Edit Control VCenter",#PB_Window_SizeGadget|#PB_Window_ScreenCentered)

;StringGadget(0,10,10,280,40,Text$,#ES_MULTILINE)
;StringGadgetVCenter(0)

;StringGadget(1,10,60,280,40,StringField(Text$,1,"-"),#ES_MULTILINE|#ES_RIGHT)
StringGadget(1,10,60,280,40,StringField(Text$,1,"-"),#ES_MULTILINE)
StringGadgetVCenter(1)
SetActiveGadget(1)

ResizeWindow(0,#PB_Ignore,#PB_Ignore,100,#PB_Ignore)
Repeat

	Select WaitWindowEvent()
	Case #PB_Event_CloseWindow
		End
	Case #PB_Event_SizeWindow
		;ResizeGadget(0,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
		;StringGadgetVCenter(0)
		ResizeGadget(1,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
		StringGadgetVCenter(1)
	Case #PB_Event_Gadget
		gadget=EventGadget()
		Select gadget
		Case 0,1
			Select EventType()
			Case #PB_EventType_Change
				; Debug "Do "+Str(gadget)
				StringGadgetVCenter(gadget)
			EndSelect
		EndSelect

	EndSelect

ForEver
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: StringGadget Vertical?

Post by RASHAD »

Hi MV
Sorry ,I was very very busy today but remember I do not gave up either

Code: Select all

Procedure StringGadgetVCenter(gadget)
  SetWindowLongPtr_(GadgetID(gadget),#GWL_STYLE, GetWindowLongPtr_(GadgetID(gadget),#GWL_STYLE)|#ES_LEFT)
  lineCount = SendMessage_(GadgetID(gadget), #EM_GETLINECOUNT, 0, 0)
  myText$ = GetGadgetText(gadget)
  hDC = GetDC_(GadgetID(gadget))
  obj = SelectObject_(hDC, GetGadgetFont(gadget))
  GetTextExtentPoint32_(hDC, myText$, Len(myText$), @textXY.SIZE)
  DeleteObject_(obj)
  ReleaseDC_(GadgetID(gadget), hDC)
  eRect.RECT
  eRect\left = 2
  eRect\top = (GadgetHeight(gadget) - textXY\cy*lineCount) / 2 - 4
  eRect\right = GadgetWidth(gadget) - (eRect\left * 2)
  eRect\bottom = eRect\top + textXY\cy*lineCount
  SendMessage_(GadgetID(gadget), #EM_SETRECT, 0, eRect)
  If gadget = 1
     SetWindowLongPtr_(GadgetID(1),#GWL_STYLE, GetWindowLongPtr_(GadgetID(1),#GWL_STYLE)|#ES_CENTER)
  ElseIf gadget = 2
     SetWindowLongPtr_(GadgetID(2),#GWL_STYLE, GetWindowLongPtr_(GadgetID(2),#GWL_STYLE)|#ES_RIGHT)
  EndIf  
EndProcedure

LoadFont(0,"Georgia",10)

Text$ = "Test for vertical centered text - horizontal (above) or right aligned (below)..."

OpenWindow(0,0,0,300,200,"Edit Control VCenter",#PB_Window_SystemMenu| #PB_Window_MinimizeGadget| #PB_Window_MaximizeGadget| #PB_Window_SizeGadget| #PB_Window_ScreenCentered)

StringGadget(0,10,10,280,40,Text$,#ES_MULTILINE)
SetGadgetFont(0,FontID(0))
SetGadgetColor(0,#PB_Gadget_FrontColor,$0000FF)
SetGadgetColor(0,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(0)

StringGadget(1,10,60,280,40,StringField(Text$,1,"-"),#ES_MULTILINE)
SetGadgetFont(1,FontID(0))
SetGadgetColor(1,#PB_Gadget_FrontColor,$00FF00)
SetGadgetColor(1,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(1)

StringGadget(2,10,110,280,40,StringField(Text$,1,"-"),#ES_MULTILINE)
SetGadgetFont(2,FontID(0))
SetGadgetColor(2,#PB_Gadget_FrontColor,$FF0000)
SetGadgetColor(2,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(2)

Repeat

   Select WaitWindowEvent()
   Case #PB_Event_CloseWindow
      End
   Case #PB_Event_SizeWindow
      ResizeGadget(0,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20, #PB_Ignore)
      StringGadgetVCenter(0)
      ResizeGadget(1,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20, #PB_Ignore)
      StringGadgetVCenter(1)
      ResizeGadget(2,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20, #PB_Ignore)
      StringGadgetVCenter(2)
   Case #PB_Event_Gadget
      gadget=EventGadget()
      Select gadget
        Case 0,1,2
          Select EventType()
            Case #PB_EventType_Change
                StringGadgetVCenter(gadget)
          EndSelect
      EndSelect
   EndSelect
ForEver
Egypt my love
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: StringGadget Vertical?

Post by Michael Vogel »

You do not need to say sorry, I am happy that you spent so much time helping to solve this puzzle...
...which seems to be a tricky one, your latest version works in some cases, but other things don't look that perfect. When the cursor is at the end of the string it won't be seen under some circumstances, but I didn't find out for now, when this happens. But other things can be reproduced easily:
- move the cursor to the middle of the text field and enter some text, the complete string will be moved to the right out of the gadget
- when the text is longer than the gadget, deleting charcaters in the middle leaves empty space on the right side
- after that, a cursor jump using shift left and shift right also shows the text on an unwanted place.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: StringGadget Vertical?

Post by RASHAD »

@Michael
What you mentioned is the normal behavior of EditorGadget() or StringGadget() with #ES_MULTILINE
Tested with PB StringGadget() with #ES_MULTILINE and with Windows API RTF control
Test it yourself
Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: StringGadget Vertical?

Post by RASHAD »

While it is a normal behavior of Windows
We can always find a way to overcome that behavior

Code: Select all

Procedure StringGadgetVCenter(gadget)
  SetWindowLongPtr_(GadgetID(gadget),#GWL_STYLE, GetWindowLongPtr_(GadgetID(gadget),#GWL_STYLE)|#ES_LEFT)
  lineCount = SendMessage_(GadgetID(gadget), #EM_GETLINECOUNT, 0, 0)
  myText$ = GetGadgetText(gadget)
  hDC = GetDC_(GadgetID(gadget))
  obj = SelectObject_(hDC, GetGadgetFont(gadget))
  GetTextExtentPoint32_(hDC, myText$, Len(myText$), @textXY.SIZE)
  DeleteObject_(obj)
  ReleaseDC_(GadgetID(gadget), hDC)
  eRect.RECT
  eRect\left = 2
  eRect\top = (GadgetHeight(gadget) - textXY\cy*lineCount) / 2 - 4
  eRect\right = GadgetWidth(gadget) - (eRect\left * 2)
  eRect\bottom = eRect\top + textXY\cy*lineCount
  SendMessage_(GadgetID(gadget), #EM_SETRECT, 0, eRect)
  If gadget = 1
     SetWindowLongPtr_(GadgetID(1),#GWL_STYLE, GetWindowLongPtr_(GadgetID(1),#GWL_STYLE)|#ES_CENTER)
  ElseIf gadget = 2
     SetWindowLongPtr_(GadgetID(2),#GWL_STYLE, GetWindowLongPtr_(GadgetID(2),#GWL_STYLE)|#ES_RIGHT)     
  EndIf
  GetCaretPos_(p.POINT)
  Pos = SendMessage_(GadgetID(gadget),#EM_CHARFROMPOS,0,p\y<<16+p\x)
  SetGadgetText(gadget,myText$)
  SendMessage_(GadgetID(gadget), #EM_SETSEL,Pos,Pos)    
EndProcedure

LoadFont(0,"Georgia",12)

Text$ = "Test for vertical centered text - horizontal (above) or right aligned (below)..."

OpenWindow(0,0,0,300,200,"Edit Control VCenter",#PB_Window_SystemMenu| #PB_Window_MinimizeGadget| #PB_Window_MaximizeGadget| #PB_Window_SizeGadget| #PB_Window_ScreenCentered)

StringGadget(0,10,10,280,40,Text$,#ES_MULTILINE)
SetGadgetFont(0,FontID(0))
SetGadgetColor(0,#PB_Gadget_FrontColor,$0000FF)
SetGadgetColor(0,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(0)

StringGadget(1,10,60,280,40,Text$,#ES_MULTILINE)
SetGadgetFont(1,FontID(0))
SetGadgetColor(1,#PB_Gadget_FrontColor,$00FF00)
SetGadgetColor(1,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(1)

StringGadget(2,10,110,280,40,Text$,#ES_MULTILINE)
SetGadgetFont(2,FontID(0))
SetGadgetColor(2,#PB_Gadget_FrontColor,$FF0000)
SetGadgetColor(2,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(2)

Repeat

   Select WaitWindowEvent()
   Case #PB_Event_CloseWindow
      End
   Case #PB_Event_SizeWindow
      ResizeGadget(0,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
      StringGadgetVCenter(0)
      ResizeGadget(1,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
      StringGadgetVCenter(1)
      ResizeGadget(2,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
      StringGadgetVCenter(2)
   Case #PB_Event_Gadget
      gadget=EventGadget()
      Select gadget
        Case 0,1,2
          Select EventType()
            Case #PB_EventType_Change
                StringGadgetVCenter(gadget)
          EndSelect
      EndSelect

   EndSelect
ForEver
Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: StringGadget Vertical?

Post by RASHAD »

Now with arrow keys support

Code: Select all

Global Pos,myText$

Procedure StringGadgetVCenter(gadget)
  SetWindowLongPtr_(GadgetID(gadget),#GWL_STYLE, GetWindowLongPtr_(GadgetID(gadget),#GWL_STYLE)|#ES_LEFT)
  lineCount = SendMessage_(GadgetID(gadget), #EM_GETLINECOUNT, 0, 0)
  myText$ = GetGadgetText(gadget)
  If myText$ = ""
     myText$ = " "
  EndIf
  hDC = GetDC_(GadgetID(gadget))
  obj = SelectObject_(hDC, GetGadgetFont(gadget))
  GetTextExtentPoint32_(hDC, myText$, Len(myText$), @textXY.SIZE)
  DeleteObject_(obj)
  ReleaseDC_(GadgetID(gadget), hDC)
  eRect.RECT
  eRect\left = 2
  eRect\top = (GadgetHeight(gadget) - textXY\cy*lineCount) / 2 - 4
  eRect\right = GadgetWidth(gadget) - (eRect\left * 2)
  eRect\bottom = eRect\top + textXY\cy*lineCount
  SendMessage_(GadgetID(gadget), #EM_SETRECT, 0, eRect)
  If gadget = 1
     SetWindowLongPtr_(GadgetID(1),#GWL_STYLE, GetWindowLongPtr_(GadgetID(1),#GWL_STYLE)|#ES_CENTER)
  ElseIf gadget = 2
     SetWindowLongPtr_(GadgetID(2),#GWL_STYLE, GetWindowLongPtr_(GadgetID(2),#GWL_STYLE)|#ES_RIGHT)     
  EndIf
  GetCaretPos_(p.POINT)
  Pos = SendMessage_(GadgetID(gadget),#EM_CHARFROMPOS,0,p\y<<16+p\x)
  SetGadgetText(gadget,myText$)
  SendMessage_(GadgetID(gadget), #EM_SETSEL,Pos,Pos)
  SendMessage_(GadgetID(gadget), #EM_SCROLLCARET,Pos,Pos)   
EndProcedure

LoadFont(0,"Georgia",12)

Text$ = "Test for vertical centered text - horizontal (above) or right aligned (below)..."

OpenWindow(0,0,0,300,200,"Edit Control VCenter",#PB_Window_SystemMenu| #PB_Window_MinimizeGadget| #PB_Window_MaximizeGadget| #PB_Window_SizeGadget| #PB_Window_ScreenCentered)

StringGadget(0,10,10,280,40,Text$,#ES_MULTILINE)
SetGadgetFont(0,FontID(0))
SetGadgetColor(0,#PB_Gadget_FrontColor,$0000FF)
SetGadgetColor(0,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(0)

StringGadget(1,10,60,280,40,Text$,#ES_MULTILINE)
SetGadgetFont(1,FontID(0))
SetGadgetColor(1,#PB_Gadget_FrontColor,$00FF00)
SetGadgetColor(1,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(1)

StringGadget(2,10,110,280,40,Text$,#ES_MULTILINE)
SetGadgetFont(2,FontID(0))
SetGadgetColor(2,#PB_Gadget_FrontColor,$FF0000)
SetGadgetColor(2,#PB_Gadget_BackColor,$D3FEFC)
StringGadgetVCenter(2)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
        End
            
    Case #PB_Event_SizeWindow
      ResizeGadget(0,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
      StringGadgetVCenter(0)
      ResizeGadget(1,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
      StringGadgetVCenter(1)
      ResizeGadget(2,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20,#PB_Ignore)
      StringGadgetVCenter(2)

    Case #WM_KEYDOWN
        GetCaretPos_(p.POINT)
        If (GetActiveGadget() = 0 Or GetActiveGadget() = 1 Or GetActiveGadget() = 2 ) And (EventwParam() = 37 Or EventwParam() = 39)
          Pos = SendMessage_(GadgetID(GetActiveGadget()),#EM_CHARFROMPOS,0,p\y<<16+p\x)
          SetGadgetText(GetActiveGadget(),myText$)
          SendMessage_(GadgetID(GetActiveGadget()), #EM_SETSEL,Pos,Pos)
          SendMessage_(GadgetID(GetActiveGadget()), #EM_SCROLLCARET,Pos,Pos)
        EndIf
     
    Case #PB_Event_Gadget
      gadget=EventGadget()
      Select gadget
        Case 0,1,2
          Select EventType()
            Case #PB_EventType_Change
                StringGadgetVCenter(gadget)
          EndSelect
      EndSelect
    
    EndSelect

ForEver
Edit :Modified for Left Mouse
Edit 2:Bug fixed
Last edited by RASHAD on Sat Jan 30, 2016 5:56 pm, edited 2 times in total.
Egypt my love
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: StringGadget Vertical?

Post by Michael Vogel »

Rashad, you are brilliant, but anyway it seems to me, that Windows doesn't like to be pimped :?
If the text in the bottom field is deleted and you add the three characters "a", "b" and "c" you see "bc|a" in the gadget...

The last days I tried to play around a little bit, but now I think, it's better to give up. I am doing a weird "workaround" now, which can be seen here... (lousy, I know...)
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: StringGadget Vertical?

Post by RASHAD »

Previous post updated
Bug fixed
Egypt my love
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: StringGadget Vertical?

Post by Michael Vogel »

RASHAD wrote:Previous post updated
Bug fixed
Not sure, but I believe the cursor is shifted one or two pixels when a text field gets empty :wink: - what about this change...

Code: Select all

:
	myText$ = GetGadgetText(gadget)
	hDC = GetDC_(GadgetID(gadget))
	obj = SelectObject_(hDC, GetGadgetFont(gadget))
	If myText$
		GetTextExtentPoint32_(hDC, myText$, Len(myText$), @textXY.SIZE)
	Else
		GetTextExtentPoint32_(hDC," ",1,@textXY.SIZE)
		textXY\cx=0
	EndIf
:
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: StringGadget Vertical?

Post by RASHAD »

The caret in the right aligned gadget are shifted 2 pix
It looks like a 2 pix right margin
Egypt my love
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: StringGadget Vertical?

Post by BarryG »

I'm trying to use Sparkie's code to center a disabled StringGadget vertically with a gadget height of 32 pixels (to match an icon next to it), using the default system font (I don't want a custom font to make this "work"). The code below doesn't center it, even if I use #ES_MULTILINE with it. Neither do any other examples in this topic. Is there a sure-fire way to vertically center this in a pixel-perfect way? Thanks.

Image

Code: Select all

Procedure StringGadgetVCenter(gadNum)
  ;--> Get line count of StringGadget
  lineCount = SendMessage_(GadgetID(gadNum), #EM_GETLINECOUNT, 0, 0)
  myText$ = GetGadgetText(gadNum)
  ;--> Get width and height of text on one line
  hdc = GetDC_(GadgetID(gadNum))
  GetTextExtentPoint32_(hdc, myText$, Len(myText$), @textXY.SIZE)
  ReleaseDC_(GadgetID(gadNum), hdc)
  ;--> Set rect coordinates for StringGadget
  eRect.RECT
  eRect\left = 0
  eRect\top = (GadgetHeight(gadNum) - textXY\cy*lineCount) / 2
  eRect\right = GadgetWidth(gadNum) - (eRect\left * 2)
  eRect\bottom = eRect\top + textXY\cy*lineCount
  SendMessage_(GadgetID(gadNum), #EM_SETRECT, 0, eRect)
EndProcedure

If OpenWindow(0, 0, 0, 300, 50, "StringGadget Centered Text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  StringGadget(0, 20, 10, 260, 32, "I want this centered vertically please", #ES_CENTER | #WS_DISABLED)
  StringGadgetVCenter(0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: StringGadget Vertical?

Post by mk-soft »

Alternatively with a FrameGadget ...

Update

Code: Select all


Procedure GetTextHight(FontID = #PB_Default)
  Static img
  Protected r1
    
  If Not img
    img = CreateImage(#PB_Any, 16, 16)
  EndIf
  
  If StartDrawing(ImageOutput(img))
    If FontID : DrawingFont(FontID) : EndIf
    r1 = TextHeight("X")
    StopDrawing()
  EndIf
  ProcedureReturn r1
EndProcedure

Procedure GetTextWidth(Text.s, FontID = #PB_Default)
  Static img
  Protected r1
    
  If Not img
    img = CreateImage(#PB_Any, 16, 16)
  EndIf
  
  If StartDrawing(ImageOutput(img))
    If FontID : DrawingFont(FontID) : EndIf
    r1 = TextWidth(Text + "X")
    StopDrawing()
  EndIf
  ProcedureReturn r1
EndProcedure

Procedure StringGadgetEx(Gadget, x, y, Width, Height, Content.s, Flags = 0)
  Protected r1, h, f
  f = GetGadgetFont(#PB_Default)
  h = GetTextHight(f)
  r1 = StringGadget(Gadget, x, y + Height / 2 - h/2, Width, h, Content.s, Flags)
  ProcedureReturn r1
EndProcedure

If OpenWindow(0, 0, 0, 300, 50, "StringGadget Centered Text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  FrameGadget(0, 20, 10, 260, 32, "", #PB_Frame_Single)
  StringGadgetEx(1, 20+2, 10, 260-4, 32, "I want this centered vertically please", #PB_String_ReadOnly | #PB_String_BorderLess | #PB_Text_Center )
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: StringGadget Vertical?

Post by BarryG »

mk-soft wrote: Sun Oct 17, 2021 10:59 amAlternatively with a FrameGadget
Yeah, I'm currently doing it with a FrameGadget and a TextGadget over it. It works, except that I can't make the border look "disabled" like in my screenshot.
Post Reply