Page 3 of 3

Re: StringGadget Vertical?

Posted: Tue Jan 26, 2016 8:58 pm
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.

Re: StringGadget Vertical?

Posted: Wed Jan 27, 2016 9:30 am
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

Re: StringGadget Vertical?

Posted: Wed Jan 27, 2016 5:17 pm
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

Re: StringGadget Vertical?

Posted: Thu Jan 28, 2016 8:19 am
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.

Re: StringGadget Vertical?

Posted: Thu Jan 28, 2016 10:55 am
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

Re: StringGadget Vertical?

Posted: Thu Jan 28, 2016 5:29 pm
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

Re: StringGadget Vertical?

Posted: Fri Jan 29, 2016 2:03 pm
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

Re: StringGadget Vertical?

Posted: Sat Jan 30, 2016 3:50 pm
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...)

Re: StringGadget Vertical?

Posted: Sat Jan 30, 2016 5:57 pm
by RASHAD
Previous post updated
Bug fixed

Re: StringGadget Vertical?

Posted: Sat Jan 30, 2016 11:40 pm
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
:

Re: StringGadget Vertical?

Posted: Sun Jan 31, 2016 5:09 am
by RASHAD
The caret in the right aligned gadget are shifted 2 pix
It looks like a 2 pix right margin

Re: StringGadget Vertical?

Posted: Sun Oct 17, 2021 5:17 am
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

Re: StringGadget Vertical?

Posted: Sun Oct 17, 2021 10:59 am
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

Re: StringGadget Vertical?

Posted: Mon Oct 18, 2021 4:46 am
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.