More Direct2D work.

This commit is contained in:
Pietro Gagliardi 2015-09-17 11:00:53 -04:00
parent 3ea8a2f7dd
commit 8dc72ddc5c
1 changed files with 41 additions and 15 deletions

View File

@ -13,14 +13,15 @@ struct uiArea {
int vwheelCarry; int vwheelCarry;
clickCounter cc; clickCounter cc;
BOOL capturing; BOOL capturing;
ID2D1HwndRenderTarget *rt;
}; };
static void doPaint(uiArea *a, HDC dc, RECT *client, RECT *clip) static HRESULT doPaint(uiArea *a, ID2DRenderTarget *rt, RECT *client, RECT *clip)
{ {
uiAreaHandler *ah = a->ah; uiAreaHandler *ah = a->ah;
uiAreaDrawParams dp; uiAreaDrawParams dp;
dp.Context = newContext(dc); dp.Context = newContext(rt);
dp.ClientWidth = client->right - client->left; dp.ClientWidth = client->right - client->left;
dp.ClientHeight = client->bottom - client->top; dp.ClientHeight = client->bottom - client->top;
@ -30,14 +31,12 @@ static void doPaint(uiArea *a, HDC dc, RECT *client, RECT *clip)
dp.ClipWidth = clip->right - clip->left; dp.ClipWidth = clip->right - clip->left;
dp.ClipHeight = clip->bottom - clip->top; dp.ClipHeight = clip->bottom - clip->top;
// TODO is this really the best for multimonitor setups?
dp.DPIX = GetDeviceCaps(dc, LOGPIXELSX);
dp.DPIY = GetDeviceCaps(dc, LOGPIXELSY);
dp.HScrollPos = a->hscrollpos; dp.HScrollPos = a->hscrollpos;
dp.VScrollPos = a->vscrollpos; dp.VScrollPos = a->vscrollpos;
ID2D1RenderTarget_BeginDraw(rt);
(*(ah->Draw))(ah, a, &dp); (*(ah->Draw))(ah, a, &dp);
return ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
} }
struct scrollParams { struct scrollParams {
@ -475,10 +474,10 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
{ {
uiArea *a; uiArea *a;
CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
HDC dc; RECT client, clip;
PAINTSTRUCT ps;
RECT client;
WINDOWPOS *wp = (WINDOWPOS *) lParam; WINDOWPOS *wp = (WINDOWPOS *) lParam;
D2D1_SIZE_U size;
HRESULT hr;
a = (uiArea *) GetWindowLongPtrW(hwnd, GWLP_USERDATA); a = (uiArea *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
if (a == NULL) { if (a == NULL) {
@ -490,22 +489,49 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
switch (uMsg) { switch (uMsg) {
case WM_PAINT: case WM_PAINT:
dc = BeginPaint(a->hwnd, &ps); if (a->rt == NULL)
if (dc == NULL) a->rt = makeHWNDRenderTarget(a->hwnd);
logLastError("error beginning paint in areaWndProc");
if (GetClientRect(a->hwnd, &client) == 0) if (GetClientRect(a->hwnd, &client) == 0)
logLastError("error getting client rect in WM_PAINT in areaWndProc()"); logLastError("error getting client rect in WM_PAINT in areaWndProc()");
doPaint(a, dc, &client, &(ps.rcPaint)); // TODO really FALSE?
EndPaint(a->hwnd, &ps); if (GetUpdateRect(a->hwnd, &clip, FALSE) == 0)
logLastError("error getting clip rect in WM_PAINT in areaWndProc()");
hr = doPaint(a, (ID2D1RenderTarget *) (a->rt), &client, &clip);
switch (hr) {
case S_OK:
if (ValidateRect(a->hwnd, NULL) == 0)
logLastError("error validating rect ater WM_PAINT in areaWndProc()");
break;
case D2DERR_RECREATE_TARGET:
// DON'T validate the rect
// instead, simply drop the render target
// we'll get another WM_PAINT and make the render target again
ID2D1HwndRenderTarget_Release(a->rt);
a->rt = NULL;
break;
default:
logHRESULT("error painting in WM_PAINT in areaWndProc()", hr);
}
return 0; return 0;
case WM_PRINTCLIENT: case WM_PRINTCLIENT:
if (GetClientRect(a->hwnd, &client) == 0) if (GetClientRect(a->hwnd, &client) == 0)
logLastError("error getting client rect in WM_PRINTCLIENT in areaWndProc()"); logLastError("error getting client rect in WM_PRINTCLIENT in areaWndProc()");
doPaint(a, (HDC) wParam, &client, &client); //TODO doPaint(a, (HDC) wParam, &client, &client);
return 0; return 0;
case WM_WINDOWPOSCHANGED: case WM_WINDOWPOSCHANGED:
if ((wp->flags & SWP_NOSIZE) != 0) if ((wp->flags & SWP_NOSIZE) != 0)
break; break;
if (a->rt == NULL)
a->rt = makeHWNDRenderTarget(a->hwnd);
else {
if (GetClientRect(a->hwnd, &client) == 0)
logLastError("error getting client rect for resizing Direct2D render target in areaWndProc()");
size.width = r.right - r.left;
size.height = r.bottom - r.top;
// don't track the error; we'll get that in EndDraw()
// see https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx
ID2D1HwndRenderTarget_Resize(a->rt, &size);
}
if ((*(a->ah->RedrawOnResize))(a->ah, a)) if ((*(a->ah->RedrawOnResize))(a->ah, a))
if (InvalidateRect(a->hwnd, NULL, TRUE) == 0) if (InvalidateRect(a->hwnd, NULL, TRUE) == 0)
logLastError("error redrawing area on resize in areaWndProc()"); logLastError("error redrawing area on resize in areaWndProc()");