HRESULT-chained the drawing functions together and fixed bugs in the focus drawing code.

This commit is contained in:
Pietro Gagliardi 2018-06-22 21:50:04 -04:00
parent d0f7cf81c5
commit 7d17df7121
1 changed files with 31 additions and 35 deletions

View File

@ -27,8 +27,10 @@ struct drawState {
BOOL freeTextBrush; BOOL freeTextBrush;
}; };
static HRESULT drawBackgrounds(struct drawState *s) static HRESULT drawBackgrounds(HRESULT hr, struct drawState *s)
{ {
if (hr != S_OK)
return hr;
if (s->m->hasImage) if (s->m->hasImage)
if (FillRect(s->dc, &(s->m->subitemIcon), GetSysColorBrush(COLOR_WINDOW)) == 0) { if (FillRect(s->dc, &(s->m->subitemIcon), GetSysColorBrush(COLOR_WINDOW)) == 0) {
logLastError(L"FillRect() icon"); logLastError(L"FillRect() icon");
@ -62,15 +64,16 @@ static void centerImageRect(RECT *image, RECT *space)
image->bottom += yoff; image->bottom += yoff;
} }
static HRESULT drawImagePart(struct drawState *s) static HRESULT drawImagePart(HRESULT hr, struct drawState *s)
{ {
uiTableData *data; uiTableData *data;
IWICBitmap *wb; IWICBitmap *wb;
HBITMAP b; HBITMAP b;
RECT r; RECT r;
UINT fStyle; UINT fStyle;
HRESULT hr;
if (hr != S_OK)
return hr;
if (s->p->imageModelColumn == -1) if (s->p->imageModelColumn == -1)
return S_OK; return S_OK;
@ -182,13 +185,14 @@ static HRESULT drawThemedCheckbox(struct drawState *s, HTHEME theme, int checked
return S_OK; return S_OK;
} }
static HRESULT drawCheckboxPart(struct drawState *s) static HRESULT drawCheckboxPart(HRESULT hr, struct drawState *s)
{ {
uiTableData *data; uiTableData *data;
int checked, enabled; int checked, enabled;
HTHEME theme; HTHEME theme;
HRESULT hr;
if (hr != S_OK)
return hr;
if (s->p->checkboxModelColumn == -1) if (s->p->checkboxModelColumn == -1)
return S_OK; return S_OK;
@ -226,7 +230,7 @@ static HRESULT drawCheckboxPart(struct drawState *s)
return S_OK; return S_OK;
} }
static HRESULT drawTextPart(struct drawState *s) static HRESULT drawTextPart(HRESULT hr, struct drawState *s)
{ {
COLORREF prevText; COLORREF prevText;
int prevMode; int prevMode;
@ -234,6 +238,8 @@ static HRESULT drawTextPart(struct drawState *s)
uiTableData *data; uiTableData *data;
WCHAR *wstr; WCHAR *wstr;
if (hr != S_OK)
return hr;
if (!s->m->hasText) if (!s->m->hasText)
return S_OK; return S_OK;
// don't draw the text underneath an edit control // don't draw the text underneath an edit control
@ -280,7 +286,7 @@ static HRESULT drawTextPart(struct drawState *s)
// much of this is to imitate what shell32.dll's CDrawProgressBar does // much of this is to imitate what shell32.dll's CDrawProgressBar does
#define indeterminateSegments 8 #define indeterminateSegments 8
static HRESULT drawProgressBarPart(struct drawState *s) static HRESULT drawProgressBarPart(HRESULT hr, struct drawState *s)
{ {
int progress; int progress;
LONG indeterminatePos; LONG indeterminatePos;
@ -290,8 +296,9 @@ static HRESULT drawProgressBarPart(struct drawState *s)
int i, nFill; int i, nFill;
TEXTMETRICW tm; TEXTMETRICW tm;
int sysColor; int sysColor;
HRESULT hr;
if (hr != S_OK)
return hr;
if (s->p->progressBarModelColumn == -1) if (s->p->progressBarModelColumn == -1)
return S_OK; return S_OK;
@ -392,7 +399,7 @@ fail:
return hr; return hr;
} }
static HRESULT drawButtonPart(struct drawState *s) static HRESULT drawButtonPart(HRESULT hr, struct drawState *s)
{ {
uiTableData *data; uiTableData *data;
WCHAR *wstr; WCHAR *wstr;
@ -400,8 +407,9 @@ static HRESULT drawButtonPart(struct drawState *s)
HTHEME theme; HTHEME theme;
RECT r; RECT r;
TEXTMETRICW tm; TEXTMETRICW tm;
HRESULT hr;
if (hr != S_OK)
return hr;
if (s->p->buttonModelColumn == -1) if (s->p->buttonModelColumn == -1)
return S_OK; return S_OK;
@ -611,10 +619,12 @@ fail:
return hr; return hr;
} }
static HRESULT updateAndDrawFocusRects(uiTable *t, HDC dc, int iItem, RECT *realTextBackground, RECT *focus, bool *first) static HRESULT updateAndDrawFocusRects(HRESULT hr, uiTable *t, HDC dc, int iItem, RECT *realTextBackground, RECT *focus, bool *first)
{ {
LRESULT state; LRESULT state;
if (hr != S_OK)
return hr;
if (GetFocus() != t->hwnd) if (GetFocus() != t->hwnd)
return S_OK; return S_OK;
// uItemState CDIS_FOCUS doesn't quite work right because of bugs in the Windows list view that causes spurious redraws without the flag while we hover over the focused item // uItemState CDIS_FOCUS doesn't quite work right because of bugs in the Windows list view that causes spurious redraws without the flag while we hover over the focused item
@ -626,7 +636,7 @@ static HRESULT updateAndDrawFocusRects(uiTable *t, HDC dc, int iItem, RECT *real
if (realTextBackground != NULL) if (realTextBackground != NULL)
if (*first) { if (*first) {
*focus = *realTextBackground; *focus = *realTextBackground;
first = false; *first = false;
return S_OK; return S_OK;
} else if (focus->right == realTextBackground->left) { } else if (focus->right == realTextBackground->left) {
focus->right = realTextBackground->right; focus->right = realTextBackground->right;
@ -646,8 +656,6 @@ static HRESULT updateAndDrawFocusRects(uiTable *t, HDC dc, int iItem, RECT *real
// so now we do everything in the item prepaint stage // so now we do everything in the item prepaint stage
// TODO consider switching to full-on owner draw // TODO consider switching to full-on owner draw
// TODO only compute the background brushes once? // TODO only compute the background brushes once?
// TODO integrate the focus rect stuff above
// TODO do hr chaining like in tablemetrics.cpp
HRESULT uiprivTableHandleNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *lResult) HRESULT uiprivTableHandleNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *lResult)
{ {
struct drawState s; struct drawState s;
@ -671,32 +679,20 @@ HRESULT uiprivTableHandleNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *
n = t->columns->size(); n = t->columns->size();
b = *nm; b = *nm;
focusFirst = false; focusFirst = true;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
b.iSubItem = i; b.iSubItem = i;
p = (*(t->columns))[i]; p = (*(t->columns))[i];
hr = fillDrawState(&s, t, &b, p); hr = fillDrawState(&s, t, &b, p);
if (hr != S_OK) if (hr != S_OK)
return hr; return hr;
hr = drawBackgrounds(&s); hr = drawBackgrounds(S_OK, &s);
if (hr != S_OK) hr = drawImagePart(hr, &s);
goto fail; hr = drawCheckboxPart(hr, &s);
hr = drawImagePart(&s); hr = drawTextPart(hr, &s);
if (hr != S_OK) hr = drawProgressBarPart(hr, &s);
goto fail; hr = drawButtonPart(hr, &s);
hr = drawCheckboxPart(&s); hr = updateAndDrawFocusRects(hr, s.t, s.dc, nm->nmcd.dwItemSpec, &(s.m->realTextBackground), &focus, &focusFirst);
if (hr != S_OK)
goto fail;
hr = drawTextPart(&s);
if (hr != S_OK)
goto fail;
hr = drawProgressBarPart(&s);
if (hr != S_OK)
goto fail;
hr = drawButtonPart(&s);
if (hr != S_OK)
goto fail;
hr = updateAndDrawFocusRects(s.t, s.dc, nm->nmcd.dwItemSpec, &(s.m->realTextBackground), &focus, &focusFirst);
if (hr != S_OK) if (hr != S_OK)
goto fail; goto fail;
hr = freeDrawState(&s); hr = freeDrawState(&s);
@ -704,7 +700,7 @@ HRESULT uiprivTableHandleNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *
return hr; return hr;
} }
// and draw the last focus rect // and draw the last focus rect
hr = updateAndDrawFocusRects(t, nm->nmcd.hdc, nm->nmcd.dwItemSpec, NULL, &focus, &focusFirst); hr = updateAndDrawFocusRects(hr, t, nm->nmcd.hdc, nm->nmcd.dwItemSpec, NULL, &focus, &focusFirst);
if (hr != S_OK) if (hr != S_OK)
return hr; return hr;
*lResult = CDRF_SKIPDEFAULT; *lResult = CDRF_SKIPDEFAULT;