AHK GUI Edit Control vertical centering?

Get help with using AutoHotkey and its commands and hotkeys
User avatar
PuzzledGreatly
Posts: 912
Joined: 29 Sep 2013, 22:18

AHK GUI Edit Control vertical centering?

16 Feb 2019, 18:21

I'd like to have a single line edit control with extra space top and bottom so that the text is centered vertically. I tried using 0x0200 which works for text controls but it seemed to have no effect. Suppose I have font set to size 16 and a edit control with a height of 50 how can i vertically center the text and keep it as an edit control allowing the user to input changes? Thanks.
teadrinker
Posts: 1865
Joined: 29 Mar 2015, 09:41
Contact:

Re: AHK GUI Edit Control vertical centering?

17 Feb 2019, 04:48

It seems that this impossible for a single line edit control. But a workaround is possible:

Code: Select all

editX := 10
editY := 10
editWidth := 300
editHeight := 50
marginHoriz := 5
fontFamily := Calibri
fontSize := 16

Gui, Parent: New
hEdit := AddEditWithMargin("Parent", editX, editY, editWidth, editHeight, marginHoriz, fontFamily, fontSize)
Gui, Parent: Show, % "w" editX*2 + editWidth " h" editY*2 + editHeight
Sleep, 500

GuiControl,, %hEdit%, % text := "Hello, AutoHotkey!"
PostMessage, EM_SETSEL := 0xB1, p := StrLen(text), p,, ahk_id %hEdit%
Return

ParentGuiClose:
   ExitApp

AddEditWithMargin(parentGui, editX, editY, editWidth, editHeight, marginHoriz, fontFamily, fontSize) {
   Gui, New, -Caption +ToolWindow +Parent%parentGui% +hwndhBack
   Gui, Color, White

   Gui, New, -Caption +ToolWindow +Parent%hBack% +hwndhFrame
   Gui, Font, s%fontSize% q5, % fontFamily
   Gui, Add, Edit,  % "hwndhEdit r1 w" editWidth - marginHoriz*2
   GuiControlGet, Pos, Pos, %hEdit%

   VarSetCapacity(WINDOWINFO, 60, 0)
   DllCall("GetWindowInfo", Ptr, hEdit, Ptr, &WINDOWINFO)
   editClientX := NumGet(WINDOWINFO, 20, "Int")
   editWindowX := NumGet(WINDOWINFO, 4, "Int")
   editBorderWidth := editClientX - editWindowX
   GuiControl, Move, %hEdit%, % "x" -editBorderWidth " y" -editBorderWidth
                             . " w" PosW + editBorderWidth*2 " h" PosH + editBorderWidth*2
   dpi := A_ScreenDPI/96
   marginVert := (editHeight - PosH)/2
   Gui, Show, % "NA x" marginHoriz*dpi " y" (marginVert + editBorderWidth*2)*dpi " w" PosW " h" PosH
   Gui, %hBack%: Show, % "NA x" editX*dpi " y" editY*dpi " w" editWidth " h" editHeight
   Return hEdit
}
just me
Posts: 7298
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK GUI Edit Control vertical centering?

17 Feb 2019, 06:01

Another kind of workaround:

Code: Select all

#NoEnv
Gui, Font, s16
; Required options: +hwnd... +Multi -VScroll -WantReturn -0x40 (ES_AUTOVSCROLL)
Gui, Add, Edit, x10 y10 w200 h50 Center +hwndHEDIT +Multi -VScroll -WantReturn -0x40, Data ;  +Limit5
Edit_VCENTER(HEDIT)
Gui, Show, w220 h80, Gui Test
Return
GuiClose:
ExitApp

Edit_VCENTER(HEDIT) {
   ; EM_GETRECT := 0x00B2 <- msdn.microsoft.com/en-us/library/bb761596(v=vs.85).aspx
   ; EM_SETRECT := 0x00B3 <- msdn.microsoft.com/en-us/library/bb761657(v=vs.85).aspx
   HFONT := DllCall("SendMessage", "Ptr", HEDIT, "UInt", 0x0031, "Ptr", 0, "Ptr", 0, "UPtr")
   HDC := DllCall("GetDC", "Ptr", HEDIT, "UPtr")
   OFONT := DllCall("SelectObject", "Ptr", HDC, "Ptr", HFONT, "UPtr")
   VarSetCapacity(RC, 16, 0)
   ; DT_EXTERNALLEADING (0x0200) | DT_CALCRECT (0x0400) | DT_EDITCONTROL (0x2000)
   DllCall("DrawText", "Ptr", HDC, "Str", "A", "Int", 1, "Ptr", &RC, "UInt", 0x2600)
   TXH := NumGet(RC, 12, "Int") - NumGet(RC, 4, "Int")
   DllCall("GetClientRect", "Ptr", HEDIT, "Ptr", &RC)
   CLH := NumGet(RC, 12, "Int")
   DllCall("SendMessage", "Ptr", HEDIT, "UInt", 0x00B2, "Ptr", 0, "Ptr", &RC)
   RCT := (CLH - TXH) // 2
   NumPut(RCT, RC, 4, "Int")
   NumPut(RCT + TXH, RC, 12, "Int")
   DllCall("SendMessage", "Ptr", HEDIT, "UInt", 0x00B3, "Ptr", 0, "Ptr", &RC)
   DllCall("SelectObject", "Ptr", HDC, "Ptr", OFONT)
   DllCall("ReleaseDC", "Ptr", HEDIT, "Ptr", HDC)
}
-0x40 will limit the text input to the width of the control.
burque505
Posts: 1374
Joined: 22 Jan 2017, 19:37

Re: AHK GUI Edit Control vertical centering?

17 Feb 2019, 12:37

@just me, that is very nice indeed. By coincidence I ran into that function in @Frosti's new post of rare gems.
User avatar
PuzzledGreatly
Posts: 912
Joined: 29 Sep 2013, 22:18

Re: AHK GUI Edit Control vertical centering?

17 Feb 2019, 19:15

Thanks very much for all the replies. I got it working I didn't realise vertically centering an edit control was so complex.
teadrinker
Posts: 1865
Joined: 29 Mar 2015, 09:41
Contact:

Re: AHK GUI Edit Control vertical centering?

18 Feb 2019, 02:03

just me wrote: Another kind of workaround:
It seems that the same could be made easier:

Code: Select all

Gui, Font, s16
Gui, Add, Edit, x10 y10 w200 h50 +hwndHEDIT +Multi -VScroll -WantReturn -0x40, % text := "Simple Example"
Edit_VCENTER(HEDIT)
Gui, Show, w220
PostMessage, EM_SETSEL := 0xB1, p := StrLen(text), p,, ahk_id %HEDIT%
Return

GuiClose:
   ExitApp
   
Edit_VCENTER(hEdit) {
   static EM_GETRECT := 0xB2, EM_SETRECT := 0xB3
   VarSetCapacity(RC, 16, 0)
   DllCall("GetClientRect", Ptr, hEdit, Ptr, &RC)
   ClientH := NumGet(RC, 12, "Int")
   DllCall("SendMessage", Ptr, hEdit, UInt, EM_GETRECT, Ptr, 0, Ptr, &RC)
   ClipY := NumGet(RC, 4, "Int")
   ClipH := (b := NumGet(RC, 12, "Int")) - ClipY
   margin := (ClientH - ClipY*2 - ClipH)//2
   NumPut(ClipY + margin, RC, 4, "Int")
   NumPut(b + margin, RC, 12, "Int")
   DllCall("SendMessage", Ptr, hEdit, UInt, EM_SETRECT, Ptr, 0, Ptr, &RC)
}
just me
Posts: 7298
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: AHK GUI Edit Control vertical centering?

18 Feb 2019, 02:46

teadrinker wrote:
18 Feb 2019, 02:03
It seems that the same could be made easier:
It does not work if the edit control can show more than one complete line for the given font size. For example, change the font size to s12 or less.
I noticed that this time while testing.
User avatar
rommmcek
Posts: 1101
Joined: 15 Aug 2014, 15:18

Re: AHK GUI Edit Control vertical centering?

20 Sep 2020, 15:51

Not perfect, but could be acceptable:

Code: Select all

Gui, Font, % fnt:= "s28"
Gui, Add, Edit, x10 y10 w300 h50 +hwndHEDIT +Multi -VScroll -WantReturn -0x40, % text := "Simple Example"

Edit_VCENTER(HEDIT, SubStr(fnt, 2))
Gui, Show
PostMessage, EM_SETSEL := 0xB1, p := StrLen(text), p,, ahk_id %HEDIT%
Return

GuiClose:
GuiEscape:
   ExitApp
   
Edit_VCENTER(hEdit, fn) {
   static EM_GETRECT := 0xB2, EM_SETRECT := 0xB3
   VarSetCapacity(RC, 16, 0)
   DllCall("GetClientRect", Ptr, hEdit, Ptr, &RC)
   ClientH := NumGet(RC, 12, "Int")
   DllCall("SendMessage", Ptr, hEdit, UInt, EM_GETRECT, Ptr, 0, Ptr, &RC)
   ClipY := NumGet(RC, 4, "Int")
   ClipH := (b := NumGet(RC, 12, "Int")) - ClipY
   margin := Round(ClientH/2 - ClipH/ClientH - fn) ; (ClientH - ClipY*2 - ClipH)//2
   NumPut(ClipY + margin, RC, 4, "Int")
   NumPut(b + margin, RC, 12, "Int")
   DllCall("SendMessage", Ptr, hEdit, UInt, EM_SETRECT, Ptr, 0, Ptr, &RC)
}

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], boiler, Google [Bot], mikeyww, yumuffin and 44 guests