In the MSDN, there is a C++ example of how to Resize an edit control, taking into account the font height and standard edit control's 3D border. Basically it just resizes the height. The original C++ code looks like this:
void ResizeEdit(HWND hwndEdit, HFONT hNewFont)

{
HFONT hSysFont,
hOldFont;
HDC hdc;
TEXTMETRIC tmNew,
tmSys;
RECT rc;
int nTemp; // Get the DC for the edit control.
hdc = GetDC(hwndEdit); // Get the metrics for the system font.
hSysFont = GetStockObject(SYSTEM_FONT);
hOldFont = SelectObject(hdc, hSysFont);
GetTextMetrics(hdc, &tmSys); // Get the metrics for the new font.
SelectObject(hdc, hNewFont);
GetTextMetrics(hdc, &tmNew); // Select the original font back into the DC and release the DC.
SelectObject(hdc, hOldFont);
DeleteObject(hSysFont);
ReleaseDC(hwndEdit, hdc); // Calculate the new height for the edit control.
nTemp = tmNew.tmHeight + (min(tmNew.tmHeight, tmSys.tmHeight)/2) +
(GetSystemMetrics(SM_CYEDGE) * 2); // Re-size the edit control.
GetWindowRect(hwndEdit, &rc);
MapWindowPoints(HWND_DESKTOP, GetParent(hwndEdit), (LPPOINT)&rc, 2);
MoveWindow( hwndEdit,
rc.left,
rc.top,
rc.right - rc.left,
nTemp,
TRUE);
}

I converted and tested this code to MASM syntax, not for speed purposes, simply for implementation purposes, trying to stick as closely to the original algorithm as possible (without disassembling the C code). My code, for the benefit of others trying to do the same thing:
ResizeEdit PROC hwndEdit :DWORD, hNewFont :DWORD

;; MSDN conversion by SubEvil
LOCAL hSysFont :DWORD
LOCAL hOldFont :DWORD
LOCAL hdc :DWORD
LOCAL tmNew :TEXTMETRIC
LOCAL tmSys :TEXTMETRIC
LOCAL rc :RECT
LOCAL nTemp :DWORD

INVOKE GetDC, hwndEdit
mov hdc, eax
INVOKE GetStockObject, SYSTEM_FONT
mov hSysFont, eax
INVOKE SelectObject, hdc, hSysFont
mov hOldFont, eax
INVOKE GetTextMetrics, hdc, addr tmSys
INVOKE SelectObject, hdc, hNewFont
INVOKE GetTextMetrics, hdc, addr tmNew
INVOKE SelectObject, hdc, hOldFont
INVOKE DeleteObject, hSysFont
INVOKE ReleaseDC, hwndEdit, hdc

INVOKE GetSystemMetrics, SM_CYEDGE
add eax, eax ;; Multiply system metrics by 2
mov ecx, tmNew.tmHeight
mov edx, tmSys.tmHeight
add eax, ecx
.IF ecx > edx ;; edx == min
shr edx, 1
add eax, edx
.ELSE ;; ecx (tmNew.tmHeight) == min
shr ecx, 1
add eax, ecx
.ENDIF
mov nTemp, eax

INVOKE GetWindowRect, hwndEdit, addr rc
INVOKE GetParent, hwndEdit
mov ecx, eax ;; Backup incase MASM uses eax for addr rc?
INVOKE MapWindowPoints, HWND_DESKTOP, ecx, addr rc, 2
mov ecx, rc.right
sub ecx, rc.left
INVOKE MoveWindow, hwndEdit, rc.left, rc.top, ecx, nTemp, TRUE
ret
ResizeEdit ENDP

Well, looking at the above code, I felt that:
1) The edit control may already have a font in it, why not just resize the control to that (already inside) font. Whether it be the System default font, or another?
2) Since we create a new font, 'extract' the original font, then put it back in, seems a little stupid!
3) What if the control doesn't have a 3D border? What if it only has a standard border (WS_BORDER) style, like some static controls do.
So I enhanced the above algorithm to ResizeHeight, it only needs the hWnd of the control and will resize according to the currently selected font for that control, then check for a 3D or 2D border and add the relevent, per system defined sizes to the height. My new algorithm is both faster, and more accurate and can be used on any (single line) Edit/Static control:
ResizeHeight PROC hWnd :DWORD

;; Written by SubEvil
LOCAL hdc :DWORD
LOCAL tm :TEXTMETRIC
LOCAL rc :RECT

INVOKE GetDC, hWnd
mov hdc, eax
INVOKE GetTextMetrics, hdc, addr tm
INVOKE ReleaseDC, hWnd, hdc

INVOKE GetWindowLong, hWnd, GWL_EXSTYLE
and eax, WS_EX_OVERLAPPEDWINDOW
.IF !Zero? ;; IF !Zero then hWnd = 3D
INVOKE GetSystemMetrics, SM_CYEDGE ;; Get 3D border size!
shl eax, 1 ;; Multiply by 2, for top+bottom / right+left
add tm.tmHeight, eax
.ENDIF

INVOKE GetWindowLong, hWnd, GWL_STYLE
and eax, WS_BORDER
.IF !Zero? ;; IF !Zero then hWnd = 3D
INVOKE GetSystemMetrics, SM_CYBORDER ;; Get 2D border size!
shl eax, 1 ;; Multiply by 2, for top+bottom / right+left
add tm.tmHeight, eax
.ENDIF

INVOKE GetWindowRect, hWnd, addr rc
INVOKE GetParent, hWnd
mov ecx, eax
INVOKE MapWindowPoints, HWND_DESKTOP, ecx, addr rc, 2
mov ecx, rc.right
sub ecx, rc.left
INVOKE MoveWindow, hWnd, rc.left, rc.top, ecx, tm.tmHeight, TRUE
ret
ResizeHeight ENDP

Also, I decided to enhance the algorithm, to provide a method to "Autosize" a control, based on currently selected Font, with minX, minY, maxX, maxY values. If minX or minY are -1, the function will do a true 'autosize', this function uses many personal macros, if there is interest in it, I can convert it, but too much effort if there isn't interest!
Posted on 2004-05-20 08:01:56 by SubEvil