summaryrefslogtreecommitdiff
path: root/redo/area_windows.c
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-08-23 20:39:47 -0400
committerPietro Gagliardi <[email protected]>2014-08-23 20:39:47 -0400
commitd679f5c5d9709ec18cc8410e8b8dba13d9622a7c (patch)
tree26b1b94e6b4df32e1ede91896e3d6bf1a4c5453b /redo/area_windows.c
parentf10c1f56b54ecd1b8fcd0d7486535a5d50e28957 (diff)
Implemented more/most of Area.OpenTextFieldAt() on Windows.
Diffstat (limited to 'redo/area_windows.c')
-rw-r--r--redo/area_windows.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/redo/area_windows.c b/redo/area_windows.c
index 58d8c56..9fc56ba 100644
--- a/redo/area_windows.c
+++ b/redo/area_windows.c
@@ -233,6 +233,26 @@ static void scrollArea(HWND hwnd, void *data, WPARAM wParam, int which)
dx = 0;
dy = delta;
}
+
+ // first move the edit control, if any, to avoid artifacting
+ if ((HWND) GetWindowLongPtrW(hwnd, 0) != NULL) {
+ HWND edit;
+ int x, y;
+
+ edit = (HWND) GetWindowLongPtrW(hwnd, 0);
+ x = (int) GetWindowLongPtrW(hwnd, sizeof (LONG_PTR));
+ y = (int) GetWindowLongPtrW(hwnd, 2 * sizeof (LONG_PTR));
+ x += dx;
+ y += dy;
+ if (SetWindowPos(edit, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER) == 0)
+ xpanic("error moving Area TextField in response to scroll", GetLastError());
+ SetWindowLongPtrW(hwnd, sizeof (LONG_PTR), (LONG_PTR) x);
+ SetWindowLongPtrW(hwnd, 2 * sizeof (LONG_PTR), (LONG_PTR) y);
+ // TODO doesn't work?
+ if (InvalidateRect(edit, NULL, TRUE) == 0)
+ xpanic("error marking Area TextField as needing redraw", GetLastError());
+ }
+
if (ScrollWindowEx(hwnd,
(int) dx, (int) dy,
// these four change what is scrolled and record info about the scroll; we're scrolling the whole client area and don't care about the returned information here
@@ -253,6 +273,9 @@ static void scrollArea(HWND hwnd, void *data, WPARAM wParam, int which)
// NOW redraw it
if (UpdateWindow(hwnd) == 0)
xpanic("error updating Area after scrolling", GetLastError());
+ if ((HWND) GetWindowLongPtrW(hwnd, 0) != NULL)
+ if (UpdateWindow((HWND) GetWindowLongPtrW(hwnd, 0)) == 0)
+ xpanic("error updating Area TextField after scrolling", GetLastError());
}
static void adjustAreaScrollbars(HWND hwnd, void *data)
@@ -411,7 +434,8 @@ DWORD makeAreaWindowClass(char **errmsg)
wc.hInstance = hInstance;
wc.hIcon = hDefaultIcon;
wc.hCursor = hArrowCursor,
- wc.hbrBackground = NULL; // no brush; we handle WM_ERASEBKGND
+ wc.hbrBackground = NULL; // no brush; we handle WM_ERASEBKGND
+ wc.cbWndExtra = 3 * sizeof (LONG_PTR); // text field handle, text field current x, text field current y
if (RegisterClassW(&wc) == 0) {
*errmsg = "error registering Area window class";
return GetLastError();
@@ -440,6 +464,7 @@ static LRESULT CALLBACK areaTextFieldSubProc(HWND hwnd, UINT uMsg, WPARAM wParam
switch (uMsg) {
case WM_KILLFOCUS:
ShowWindow(hwnd, SW_HIDE);
+ areaTextFieldDone((void *) data);
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
case WM_NCDESTROY:
if ((*fv_RemoveWindowSubclass)(hwnd, areaTextFieldSubProc, id) == FALSE)
@@ -452,7 +477,7 @@ static LRESULT CALLBACK areaTextFieldSubProc(HWND hwnd, UINT uMsg, WPARAM wParam
return 0; // unreached
}
-HWND newAreaTextField(HWND area)
+HWND newAreaTextField(HWND area, void *goarea)
{
HWND tf;
@@ -460,11 +485,34 @@ HWND newAreaTextField(HWND area)
L"edit", L"",
textfieldStyle | WS_CHILD,
0, 0, 0, 0,
- area, // owner window
- NULL, hInstance, NULL);
+ area, NULL, hInstance, NULL);
if (tf == NULL)
xpanic("error making Area TextField", GetLastError());
- if ((*fv_SetWindowSubclass)(tf, areaTextFieldSubProc, 0, (DWORD_PTR) NULL) == FALSE)
+ if ((*fv_SetWindowSubclass)(tf, areaTextFieldSubProc, 0, (DWORD_PTR) goarea) == FALSE)
xpanic("error subclassing Area TextField to give it its own WM_KILLFOCUS handler", GetLastError());
return tf;
}
+
+void areaOpenTextField(HWND area, HWND textfield, int x, int y, int width, int height)
+{
+ int sx, sy;
+ int baseX, baseY;
+ LONG unused;
+
+ getScrollPos(area, &sx, &sy);
+ x += sx;
+ y += sy;
+ calculateBaseUnits(textfield, &baseX, &baseY, &unused);
+ width = MulDiv(width, baseX, 4);
+ height = MulDiv(height, baseY, 8);
+ if (MoveWindow(textfield, x, y, width, height, TRUE) == 0)
+ xpanic("error moving Area TextField in Area.OpenTextFieldAt()", GetLastError());
+ ShowWindow(textfield, SW_SHOW);
+ if (SetFocus(textfield) == NULL)
+ xpanic("error giving Area TextField focus", GetLastError());
+}
+
+void areaMarkTextFieldDone(HWND area)
+{
+ SetWindowLongPtrW(area, 0, (LONG_PTR) NULL);
+}