diff --git a/redo/area_windows.c b/redo/area_windows.c index ce538db..7e49bff 100644 --- a/redo/area_windows.c +++ b/redo/area_windows.c @@ -289,10 +289,10 @@ static void adjustAreaScrollbars(HWND hwnd, void *data) SetScrollInfo(hwnd, SB_VERT, &si, TRUE); } -void repaintArea(HWND hwnd) +void repaintArea(HWND hwnd, RECT *r) { // NULL - the whole area; TRUE - have windows erase if possible - if (InvalidateRect(hwnd, NULL, TRUE) == 0) + if (InvalidateRect(hwnd, r, TRUE) == 0) xpanic("error flagging Area as needing repainting after event", GetLastError()); if (UpdateWindow(hwnd) == 0) xpanic("error repainting Area after event", GetLastError()); @@ -386,10 +386,16 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM return (LRESULT) areaKeyEvent(data, TRUE, wParam, lParam); case msgAreaSizeChanged: adjustAreaScrollbars(hwnd, data); - repaintArea(hwnd); // this calls for an update + repaintArea(hwnd, NULL); // this calls for an update + return 0; + case msgAreaGetScroll: + getScrollPos(hwnd, (int *) wParam, (int *) lParam); + return 0; + case msgAreaRepaint: + repaintArea(hwnd, (RECT *) lParam); return 0; case msgAreaRepaintAll: - repaintArea(hwnd); + repaintArea(hwnd, NULL); return 0; default: return DefWindowProcW(hwnd, uMsg, wParam, lParam); diff --git a/redo/area_windows.go b/redo/area_windows.go index 877f8b6..1ab3156 100644 --- a/redo/area_windows.go +++ b/redo/area_windows.go @@ -46,6 +46,23 @@ func (a *area) SetSize(width, height int) { C.SendMessageW(a._hwnd, C.msgAreaSizeChanged, 0, 0) } +func (a *area) Repaint(r image.Rectangle) { + var hscroll, vscroll C.int + var rect C.RECT + + C.SendMessageW(a._hwnd, C.msgAreaGetScroll, C.WPARAM(uintptr(unsafe.Pointer(&hscroll))), C.LPARAM(uintptr(unsafe.Pointer(&vscroll)))) + r = r.Add(image.Pt(int(hscroll), int(vscroll))) // adjust by scroll position + r = image.Rect(0, 0, a.width, a.height).Intersect(r) + if r.Empty() { + return + } + rect.left = C.LONG(r.Min.X) + rect.top = C.LONG(r.Min.Y) + rect.right = C.LONG(r.Max.X) + rect.bottom = C.LONG(r.Max.Y) + C.SendMessageW(a._hwnd, C.msgAreaRepaint, 0, C.LPARAM(uintptr(unsafe.Pointer(&rect)))) +} + func (a *area) RepaintAll() { C.SendMessageW(a._hwnd, C.msgAreaRepaintAll, 0, 0) } diff --git a/redo/winapi_windows.h b/redo/winapi_windows.h index c11dc7c..7beb888 100644 --- a/redo/winapi_windows.h +++ b/redo/winapi_windows.h @@ -30,6 +30,8 @@ enum { msgCOMMAND, // WM_COMMAND proxy; see forwardCommand() in controls_windows.go msgNOTIFY, // WM_NOTIFY proxy msgAreaSizeChanged, + msgAreaGetScroll, + msgAreaRepaint, msgAreaRepaintAll, msgTabCurrentTabHasChildren, msgBeginModal, @@ -122,7 +124,7 @@ extern void calculateBaseUnits(HWND, int *, int *, LONG *); // area_window.c #define areaWindowClass L"gouiarea" -extern void repaintArea(HWND); +extern void repaintArea(HWND, RECT *); extern DWORD makeAreaWindowClass(char **); extern HWND newArea(void *);