An edit control may not necessarily display integral lines of text. So its possible that the following code could return a visible line count that includes a partially displayed line.
Used in a Win32 dialog -
void CVisibleCountApp::OnCount()
{
RECT rc{};
int lastLine{};
BOOL bVisible{ TRUE };
Edit_GetRect(m_hEdit, &rc);
int firstLine = Edit_GetFirstVisibleLine(m_hEdit);
for (int i = firstLine; bVisible; i++)
{
int charIndex = Edit_LineIndex(m_hEdit, i);
auto coord = SendMessage(m_hEdit, EM_POSFROMCHAR, charIndex, 0);
POINT pt{ LOWORD(coord), HIWORD(coord) };
bVisible = PtInRect(&rc, pt);
if (bVisible)
lastLine = i;
}
TCHAR szMsg[128]{};
_stprintf_s(szMsg, _T("First line index: %d, Last line index: %d, No. Lines %d"), firstLine, lastLine, lastLine - firstLine + 1);
MessageBox(m_hWnd, szMsg, _T("Visible Line Count"), MB_ICONINFORMATION);
}
Example output -