Center Text in a new painted rect Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
pv007
Posts: 93
Joined: 20 Jul 2020, 23:50

Center Text in a new painted rect

19 Jun 2021, 15:11

Code: Select all

Font := "Consolas"
FontSize := "12"
BtnWidth := 200
BtnHeight := 30
BtnText := "Hello World"
BtnColor := "0000ff"


MakeGUI()
Return

MakeNewGui:
   GuiControlGet,Font
   GuiControlGet,FontSize
   GuiControlGet,BtnWidth
   GuiControlGet,BtnHeight
   GuiControlGet,BtnText
   GuiControlGet,BtnColor
   Gui, Destroy
   MakeGUI()
Return

MakeGUI() {

   global

   Gui, Font, s%FontSize%, %FontName%

   xPos := 250, w := 100
   Gui, Add, Text,, Font Name
   Gui, Add, Edit, x%xPos% yp w%w% vFont, %FontName%

   Gui, Add, Text, xm y+10, Font Size
   Gui, Add, Edit, x%xPos% yp w%w% vFontSize, %FontSize%

   Gui, Add, Text, xm y+10, Button Width
   Gui, Add, Edit, x%xPos% yp w%w% vBtnWidth, %BtnWidth%

   Gui, Add, Text, xm y+10, Button Height
   Gui, Add, Edit, x%xPos% yp w%w% vBtnHeight, %BtnHeight%

   Gui, Add, Text, xm y+10, Button Text
   Gui, Add, Edit, x%xPos% yp w%w% vBtnText, %BtnText%

   Gui, Add, Text, xm y+10, Button Bkg Color
   Gui, Add, Edit, x%xPos% yp w%w% vBtnColor, %BtnColor%
   
   Gui, Add, Button, xm y+10 w%w% gMakeNewGui, Build GUI

   Gui, Add, Text, w%BtnWidth% h%BtnHeight% hwndhText vhText +BackgroundTrans, %BtnText%
   Gui, Add, Text, y+20 w%BtnWidth% h%BtnHeight% +BackgroundTrans, %BtnText%
   Gui, Show

   GuiControlGet, Pos, Pos, hText
   pBitmap := BITMAPMaker(PosW, PosH, 0, BtnColor)
   hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap, 0xff000000)

   T := New paintDC(hText, HBITMAP, 255)
   T.SetRedraw(True)

}


BITMAPMaker(Width, Height, Radious, Color) {

   if (InStr(Color, "0x"))
      Color := StrReplace(Color, "0x")

   BkColor := 0xFFF
   BkColor .= Color

   ;FileAppend, BkColor: %BkColor% `n,*
	pBitmap := Gdip_CreateBitmap( Width, Height ) 
  	G := Gdip_GraphicsFromImage( pBitmap ) 
	Gdip_SetSmoothingMode( G , 4 )
	Brush := Gdip_BrushCreateSolid( BkColor )
   

   Gdip_FillRoundedRectangle(G, Brush, 0, 0, Width, Height, Radious)
   Gdip_DeleteBrush( Brush )
	Gdip_DeleteGraphics( G )
	return pBitmap
}


Class paintDC {

   __New(hWnd, hBitmap, Transparency)  {
      This.HLB := hWnd
      This.hBitmap := hBitmap
      This.Transparency := Transparency
      This.HasBackground := False
      This.Drawing := True
      SCCB := RegisterCallback("paintDC.SubClassCallback")
      DllCall("Comctl32.dll\SetWindowSubclass", "Ptr", hWnd, "Ptr", SCCB, "Ptr", hWnd, "Ptr", &This)
   }

   SubClassCallback(uMsg, wParam, lParam, IdSubclass, RefData) {
      Critical 100
      hWnd := This ; first parameter 'hWnd' is passed as 'This'
      Return Object(RefData).SubClassProc(hWnd, uMsg, wParam, lParam)
   }
      
   SubClassProc(hWnd, uMsg, wParam, lParam) {
   
      Static WM := { ERASEBKGND: 0x0014, PAINT: 0x000F }

      If (uMsg = WM.ERASEBKGND) {         
         If (!This.HasBackground) {            
            SELDC := DllCall("Gdi32.dll\CreateCompatibleDC", "Ptr", , "UPtr")
            DllCall("Gdi32.dll\SelectObject", "Ptr", SELDC, "Ptr", This.hBitmap)
            This.SELDC := SELDC
            This.HasBackground := True
         }
      }

      If (uMsg = WM.PAINT) {

         VarSetCapacity(PAINTSTRUCT, A_PtrSize + (4 * 7) + 32 + (A_PtrSize - 4), 0)

         LBDC := DllCall("USer32.dll\BeginPaint", "Ptr", hWnd, "Ptr", &PAINTSTRUCT, "UPtr")

         WM_GETFONT := 0x0031
         SendMessage, %WM_GETFONT%, 0, 0, , ahk_id %hWnd%
         Font := ErrorLevel

         HFONT := DllCall("Gdi32.dll\SelectObject", "Ptr", LBDC, "Ptr", Font, "UPtr")

         DllCall("Gdi32.dll\SetBkMode", "Ptr", LBDC, "Int", 1) ; TRANSPARENT

         VarSetCapacity(RECT, 16, 0)
         DllCall("GetClientRect", "Ptr", hWnd, "Ptr", &RECT)
     
         L := NumGet(RECT, 0, "Int")
         T := NumGet(RECT, 4, "Int")
         W := NumGet(RECT, 8, "Int") - L 
         H := NumGet(RECT, 12, "Int") - T

         DllCall("Gdi32.dll\GdiAlphaBlend", "Ptr", LBDC, "Int", 0, "Int", 0, "Int", W, "Int", H , "Ptr", This.SELDC, "Int", 0, "Int", 0, "Int", W, "Int", H , "UInt", This.Transparency << 16)

         DllCall("Gdi32.dll\SetTextColor", "Ptr", LBDC, "UInt", 0xFFFFFF)

         ; ======================================================================

         ; Centers the text in the background
         ControlGetText, Txt,, ahk_id %hWnd%
         Len := StrLen(Txt)

         ; => X Position, where the text will be drawn in the control
         NumPut(10, RECT, 0, "Int") 

         ; => Y Position, where the text will be drawn in the control
         NumPut(10, RECT, 4, "Int")

         NumPut(W, RECT, 8, "Int")
         NumPut(H, RECT, 12, "Int")

         DllCall("User32.dll\DrawText", "Ptr", LBDC, "Ptr", &Txt, "Int", Len, "Ptr", &RECT, "UInt", 0x0840)

         ; ======================================================================

      }

      Return DllCall("Comctl32.dll\DefSubclassProc", "Ptr", hWnd, "UInt", uMsg, "Ptr", wParam, "Ptr", lParam)

   }

   SetRedraw(Mode) {

      ;FileAppend, Redraw! `n,*
      Static WM_SETREDRAW := 0x000B
      Mode := !!Mode
      This.Drawing := Mode
      SendMessage, %WM_SETREDRAW%, %Mode%, 0, , % "ahk_id " . This.HLB
      If (Mode)
         WinSet, Redraw, , % "ahk_id " . This.HLB
      Return True
   }

}

image.png
image.png (22.11 KiB) Viewed 179 times
=> The class is a sketch , I'm missing to finish a lot of things, I would like to ask for ideas in how I could center the text in the background rect.

Im trying to align the text like when you use the option center:

Code: Select all

   Gui, Add, Text, y+20 w%BtnWidth% h%BtnHeight% center +BackgroundTrans 0x800000, Hello World
image.png
image.png (1.02 KiB) Viewed 180 times
^ Above the text is aligned to the center in X but not in Y (My goal is align in x and y)

The button always will have a height > of the text height, but it can be smaller in width than the text, in this case, will need to wrap the text:

Code: Select all

   Gui, Add, Text, y+20 w%BtnWidth% h%BtnHeight% center +BackgroundTrans 0x800000, They told him, "Don't you ever come around here"
image.png
image.png (2.07 KiB) Viewed 180 times

This is the part of the code responsible for the position where the text will be drawn, all other things in the code can be ignored by now:

Code: Select all

         ; ======================================================================

         ; Centers the text in the background
         ControlGetText, Txt,, ahk_id %hWnd%
         Len := StrLen(Txt)

         ; => X Position, where the text will be drawn in the control
         NumPut(10, RECT, 0, "Int") 

         ; => Y Position, where the text will be drawn in the control
         NumPut(10, RECT, 4, "Int")

         NumPut(W, RECT, 8, "Int")
         NumPut(H, RECT, 12, "Int")

         DllCall("User32.dll\DrawText", "Ptr", LBDC, "Ptr", &Txt, "Int", Len, "Ptr", &RECT, "UInt", 0x0840)

         ; ======================================================================
Appreciate any help!
User avatar
boiler
Posts: 16925
Joined: 21 Dec 2014, 02:44

Re: Center Text in a new painted rect

19 Jun 2021, 16:08

I didn't really look at your script it detail, but you can use option 0x200 to center text vertically in its defined height:

Code: Select all

Gui, Add, Progress, x10 y10 w150 h40 BackgroundWhite
Gui, Add, Text, xp yp wp hp Center BackgroundTrans 0x200 0x800000, Hello World
Gui, Show
return

GuiClose:
ExitApp
pv007
Posts: 93
Joined: 20 Jul 2020, 23:50

Re: Center Text in a new painted rect  Topic is solved

19 Jun 2021, 16:36

Thanks didnt know about this flag 0x200.

Problem solved:
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-drawtext

The last param of the dllcall of drawtext is a flag to align the text when its being painted.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 409 guests