More work on table edit controls, including: subclassing the edit control to actually handle escape and enter, setting focus on the eidt control, selecting all text in the edit control, and splitting the sizing stuff into a separate function. We'll have to split the rect-gathering code into a separate file before we can add live resize to the edit control... which will probably be useful because then I could just write a function to enumerate focus rects later.
This commit is contained in:
parent
25a443f4f2
commit
bff9d0e311
|
@ -17,6 +17,47 @@ static HRESULT itemRect(HRESULT hr, uiTable *t, UINT uMsg, WPARAM wParam, LONG l
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is not how the real list view positions and sizes the edit control, but this is a) close enough b) a lot easier to follow c) something I can actually get working d) something I'm slightly more comfortable including in libui
|
||||||
|
// r should be the subitem label rect
|
||||||
|
static HRESULT resizeEdit(uiTable *t, WCHAR *wstr, RECT *r)
|
||||||
|
{
|
||||||
|
HDC dc;
|
||||||
|
HFONT prevFont;
|
||||||
|
TEXTMETRICW tm;
|
||||||
|
SIZE textSize;
|
||||||
|
RECT editRect;
|
||||||
|
|
||||||
|
// TODO check errors for all these
|
||||||
|
dc = GetDC(t->hwnd); // use the list view DC since we're using its coordinate space
|
||||||
|
prevFont = (HFONT) SelectObject(dc, hMessageFont);
|
||||||
|
GetTextMetricsW(dc, &tm);
|
||||||
|
GetTextExtentPoint32W(dc, wstr, wcslen(wstr), &textSize);
|
||||||
|
SelectObject(dc, prevFont);
|
||||||
|
ReleaseDC(t->hwnd, dc);
|
||||||
|
|
||||||
|
SendMessageW(t->edit, EM_GETRECT, 0, (LPARAM) (&editRect));
|
||||||
|
r->left -= editRect.left;
|
||||||
|
// find the top of the text
|
||||||
|
r->top += ((r->bottom - r->top) - tm.tmHeight) / 2;
|
||||||
|
// and move THAT by the right offset
|
||||||
|
r->top -= editRect.top;
|
||||||
|
r->right = r->left + textSize.cx;
|
||||||
|
// the real listview does this to add some extra space at the end
|
||||||
|
// TODO this still isn't enough space
|
||||||
|
r->right += 4 * GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CYEDGE);
|
||||||
|
// and make the bottom equally positioned to the top
|
||||||
|
r->bottom = r->top + editRect.top + tm.tmHeight + editRect.top;
|
||||||
|
|
||||||
|
// TODO intersect r with the list view's client rect to prevent clipping
|
||||||
|
|
||||||
|
// TODO check error or use the right function
|
||||||
|
SetWindowPos(t->edit, NULL,
|
||||||
|
r->left, r->top,
|
||||||
|
r->right - r->left, r->bottom - r->top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// the real list view intercepts these keys to control editing
|
// the real list view intercepts these keys to control editing
|
||||||
static LRESULT CALLBACK editSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIDSubclass, DWORD_PTR dwRefData)
|
static LRESULT CALLBACK editSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIDSubclass, DWORD_PTR dwRefData)
|
||||||
{
|
{
|
||||||
|
@ -131,45 +172,17 @@ static HRESULT openEditControl(uiTable *t, int iItem, int iSubItem, uiprivTableC
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
SendMessageW(t->edit, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE);
|
SendMessageW(t->edit, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE);
|
||||||
|
// TODO check errors
|
||||||
|
SetWindowSubclass(t->edit, editSubProc, 0, (DWORD_PTR) t);
|
||||||
|
|
||||||
// this is not how the real list view positions and sizes the edit control, but this is a) close enough b) a lot easier to follow c) something I can actually get working d) something I'm slightly more comfortable including in libui
|
hr = resizeEdit(t, wstr, &subitemLabel);
|
||||||
{
|
if (hr != S_OK)
|
||||||
HDC dc;
|
// TODO proper cleanup
|
||||||
HFONT prevFont;
|
return hr;
|
||||||
TEXTMETRICW tm;
|
// TODO check errors on these two, if any
|
||||||
SIZE textSize;
|
SetFocus(t->edit);
|
||||||
RECT editRect;
|
ShowWindow(t->edit, SW_SHOW);
|
||||||
|
SendMessageW(t->edit, EM_SETSEL, 0, (LPARAM) (-1));
|
||||||
// TODO deduplicate this with tabledraw.cpp
|
|
||||||
// TODO check errors for all these
|
|
||||||
dc = GetDC(t->hwnd); // yes, real list view uses itself here
|
|
||||||
prevFont = (HFONT) SelectObject(dc, hMessageFont);
|
|
||||||
GetTextMetricsW(dc, &tm);
|
|
||||||
GetTextExtentPoint32W(dc, wstr, wcslen(wstr), &textSize);
|
|
||||||
SelectObject(dc, prevFont);
|
|
||||||
ReleaseDC(t->hwnd, dc);
|
|
||||||
|
|
||||||
SendMessageW(t->edit, EM_GETRECT, 0, (LPARAM) (&editRect));
|
|
||||||
r.left = subitemLabel.left - editRect.left;
|
|
||||||
// find the top of the text
|
|
||||||
r.top = subitemLabel.top + ((subitemLabel.bottom - subitemLabel.top) - tm.tmHeight) / 2;
|
|
||||||
// and move THAT by the right offset
|
|
||||||
r.top = r.top - editRect.top;
|
|
||||||
r.right = subitemLabel.left + textSize.cx;
|
|
||||||
// the real listview does this to add some extra space at the end
|
|
||||||
// TODO this still isn't enough space
|
|
||||||
r.right += 4 * GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CYEDGE);
|
|
||||||
// and make the bottom equally positioned to the top
|
|
||||||
r.bottom = r.top + editRect.top + tm.tmHeight + editRect.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO check error or use the right function
|
|
||||||
SetWindowPos(t->edit, NULL,
|
|
||||||
r.left, r.top,
|
|
||||||
r.right - r.left, r.bottom - r.top,
|
|
||||||
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
|
|
||||||
// TODO get the correct constant from the real list view
|
|
||||||
ShowWindow(t->edit, SW_SHOWDEFAULT);
|
|
||||||
|
|
||||||
uiprivFree(wstr);
|
uiprivFree(wstr);
|
||||||
t->editedItem = iItem;
|
t->editedItem = iItem;
|
||||||
|
|
Loading…
Reference in New Issue