The edit is in a different program (DPI unaware). My program is trying to get the text width.
std::wstring text = L"1234";
HWND edit = 0x04AC1BF0;
// AttachThreadInput
// ...
auto ret1 = ::GetCaretPos(&pt1); // pt1 => {x=1 y=1}
// Set text to "1234" here
// ...
::Sleep(3000);
auto ret2 = ::GetCaretPos(&pt2); // pt2 => {x=25 y=1}
HDC hdc = GetDC(edit);
auto hFont = (HFONT)SendMessage(edit, WM_GETFONT, 0, 0);
auto oldObj = SelectObject(hdc, hFont);
CSize size1;
auto ret3 = GetTextExtentPoint32(hdc, text.c_str(), text.size(), &size1); // size1 => {cx=32 cy=16}
CRect rect1;
DrawText(hdc, text.c_str(), text.size(), &rect1, DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE); // {LT(0, 0) RB(32, 16) [32 x 16]}
SelectObject(hdc, oldObj);
ReleaseDC(edit, hdc);
So GetTextExtentPoint32
behaves the same as DrawText. They both returns width as 32
. Result of GetCaretPos
changes from {1, 1}
to {25, 1}
, means the width is 24
.
DPI is 150% on my computer. Those APIs return values don't change if I set DPI it to 100%. So I think it is not because of DPI impact.
What's the relationship of those 2 APIs?
With API monitor tool, I can see the program itself calls GetTextExtentPoint32A and returns [24, 12]
. That behaves similar to GetCaretPos.
How could I get the same result as the target process itself?
Things become more interesting now! If I create the font and select it again, then GetTextExtentPoint32
returns [24, 12]
!
LOGFONT font = { 0 };
::GetObject(hFont, sizeof(LOGFONT), &font);
hFont = ::CreateFontIndirect(&font);
auto oldObj = ::SelectObject(hdc, hFont);
If I DrawText to the edit before recreation, I can see the font is Bold
, but after font recreation and redrawn, it looks Normal
.
Could you explain this?
The documentation for
GetCaretPos
saysOn the other hand, the other two functions that you mention do participate in DPI virtualization.