From dafdaa4de43fd6af29ef4df4ff85b289c81a672b Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Thu, 21 Apr 2016 23:29:44 -0400 Subject: [PATCH] Migrated text.c. --- windows/text.c | 62 ------------------------ windows/text.cpp | 87 ++++++++++++++++++++++++++++++++++ windows/ui_windows_new.h | 3 ++ windows/uipriv_windows_new.hpp | 7 +++ windows/utf16.cpp | 2 - 5 files changed, 97 insertions(+), 64 deletions(-) delete mode 100644 windows/text.c create mode 100644 windows/text.cpp diff --git a/windows/text.c b/windows/text.c deleted file mode 100644 index a43da03a..00000000 --- a/windows/text.c +++ /dev/null @@ -1,62 +0,0 @@ -// 9 april 2015 -#include "uipriv_windows.h" - - -WCHAR *windowText(HWND hwnd) -{ - LRESULT n; - WCHAR *text; - - n = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0); - // WM_GETTEXTLENGTH does not include the null terminator - text = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]"); - // note the comparison: the size includes the null terminator, but the return does not - if (GetWindowTextW(hwnd, text, n + 1) != n) - logLastError("error getting window text in windowText()"); - return text; -} - -void uiFreeText(char *text) -{ - uiFree(text); -} - -intmax_t uiWindowsWindowTextWidth(HWND hwnd) -{ - LRESULT len; - WCHAR *text; - HDC dc; - HFONT prevfont; - SIZE size; - - size.cx = 0; - size.cy = 0; - - // first we need the window text - // this copies what windowText() does because we need the len - // we could replace this with a call to windowText() but then we'd also need a call to wcslen() (or some other function that both this and windowText() would call to do the real work) - len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0); - if (len == 0) // no text; nothing to do - return 0; - text = (WCHAR *) uiAlloc((len + 1) * sizeof (WCHAR), "WCHAR[]"); - // note the comparison: the size includes the null terminator, but the return does not - if (GetWindowText(hwnd, text, len + 1) != len) - logLastError("error getting window text in uiWindowsWindowTextWidth()"); - - // now we can do the calculations - dc = GetDC(hwnd); - if (dc == NULL) - logLastError("error getting DC in uiWindowsWindowTextWidth()"); - prevfont = (HFONT) SelectObject(dc, hMessageFont); - if (prevfont == NULL) - logLastError("error loading control font into device context in uiWindowsWindowTextWidth()"); - if (GetTextExtentPoint32W(dc, text, len, &size) == 0) - logLastError("error getting text extent point in uiWindowsWindowTextWidth()"); - if (SelectObject(dc, prevfont) != hMessageFont) - logLastError("error restoring previous font into device context in uiWindowsWindowTextWidth()"); - if (ReleaseDC(hwnd, dc) == 0) - logLastError("error releasing DC in uiWindowsWindowTextWidth()"); - uiFree(text); - - return size.cx; -} diff --git a/windows/text.cpp b/windows/text.cpp new file mode 100644 index 00000000..d354a45f --- /dev/null +++ b/windows/text.cpp @@ -0,0 +1,87 @@ +// 9 april 2015 +#include "uipriv_windows.h" + +WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len) +{ + LRESULT n; + WCHAR *text; + + n = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0); + if (len != NULL) + *len = n; + // WM_GETTEXTLENGTH does not include the null terminator + text = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]"); + // note the comparison: the size includes the null terminator, but the return does not + if (GetWindowTextW(hwnd, text, n + 1) != n) { + logLastError(L"error getting window text"); + // on error, return an empty string to be safe + *text = L'\0'; + if (len != NULL) + *len = 0; + } + return text; +} + +WCHAR *windowText(HWND hwnd) +{ + return windowTextAndLen(hwnd, NULL); +} + +void setWindowText(HWND hwnd, WCHAR *wtext) +{ + if (SetWindowTextW(hwnd, wtext) == 0) + logLastError(L"error setting window text"); +} + +void uiFreeText(char *text) +{ + uiFree(text); +} + +intmax_t uiWindowsWindowTextWidth(HWND hwnd) +{ + LRESULT len; + WCHAR *text; + HDC dc; + HFONT prevfont; + SIZE size; + + size.cx = 0; + size.cy = 0; + + text = windowTextAndLen(hwnd, &len); + if (len == 0) // no text; nothing to do + goto noTextOrError; + + // now we can do the calculations + dc = GetDC(hwnd); + if (dc == NULL) { + logLastError(L"error getting DC"); + // on any error, assume no text + goto noTextOrError; + } + prevfont = (HFONT) SelectObject(dc, hMessageFont); + if (prevfont == NULL) { + logLastError(L"error loading control font into device context"); + ReleaseDC(hwnd, dc); + goto noTextOrError; + } + if (GetTextExtentPoint32W(dc, text, len, &size) == 0) { + logLastError("error getting text extent point"); + // continue anyway, assuming size is 0 + size.cx = 0; + size.cy = 0; + } + // continue on errors; we got what we want + if (SelectObject(dc, prevfont) != hMessageFont) + logLastError(L"error restoring previous font into device context"); + if (ReleaseDC(hwnd, dc) == 0) + logLastError(L"error releasing DC"); + + uiFree(text); + return size.cx; + +noTextOrError: + uiFree(text); + return 0; +} diff --git a/windows/ui_windows_new.h b/windows/ui_windows_new.h index e02e64e0..1645e45e 100644 --- a/windows/ui_windows_new.h +++ b/windows/ui_windows_new.h @@ -9,6 +9,9 @@ _UI_EXTERN void uiWindowsEnsureSetParent(HWND hwnd, HWND parent); // TODO document _UI_EXTERN void uiWindowsEnsureAssignControlIDZOrder(HWND hwnd, LONG_PTR controlID, HWND insertAfter); +// TODO document +_UI_EXTERN intmax_t uiWindowsWindowTextWidth(HWND hwnd); + // TODO document _UI_EXTERN void uiWindowsRegisterWM_COMMANDHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *), uiControl *c); _UI_EXTERN void uiWindowsUnregisterWM_COMMANDHandler(HWND hwnd); diff --git a/windows/uipriv_windows_new.hpp b/windows/uipriv_windows_new.hpp index f698f4e2..57c99d27 100644 --- a/windows/uipriv_windows_new.hpp +++ b/windows/uipriv_windows_new.hpp @@ -7,6 +7,8 @@ extern BOOL runWM_HSCROLL(WPARAM wParam, LPARAM lParam, LRESULT *lResult); extern void issueWM_WININICHANGE(WPARAM wParam, LPARAM lParam); // utf16.cpp +#define emptyUTF16() ((WCHAR *) uiAlloc(1 * sizeof (WCHAR), "WCHAR[]")) +#define emptyUTF8() ((char *) uiAlloc(1 * sizeof (char), "char[]")) extern WCHAR *toUTF16(const char *str); extern char *toUTF8(const WCHAR *wstr); extern WCHAR *strf(const WCHAR *format, ...); @@ -35,3 +37,8 @@ extern void setExStyle(HWND hwnd, DWORD exstyle); extern void clientSizeToWindowSize(HWND hwnd, intmax_t *width, intmax_t *height, BOOL hasMenubar); extern HWND parentOf(HWND child); extern HWND parentToplevel(HWND child); + +// text.cpp +extern WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len); +extern WCHAR *windowText(HWND hwnd); +extern void setWindowText(HWND hwnd, WCHAR *wtext); diff --git a/windows/utf16.cpp b/windows/utf16.cpp index 664cdbbe..ae38336c 100644 --- a/windows/utf16.cpp +++ b/windows/utf16.cpp @@ -4,7 +4,6 @@ // see http://stackoverflow.com/a/29556509/3408572 #define MBTWC(str, wstr, bufsiz) MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, bufsiz) -#define emptyUTF16() ((WCHAR *) uiAlloc(1 * sizeof (WCHAR), "WCHAR[]")) WCHAR *toUTF16(const char *str) { @@ -28,7 +27,6 @@ WCHAR *toUTF16(const char *str) } #define WCTMB(wstr, str, bufsiz) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, bufsiz, NULL, NULL) -#define emptyUTF8() ((char *) uiAlloc(1 * sizeof (char), "char[]")) char *toUTF8(const WCHAR *wstr) {