对EDIT控件进行子类化对我来说效果很好 - 编辑对象属性时需要向用户显示一些格式信息(有些属性可能是多行)。重要的是,像Adrian在他的回答中所说的那样,在你自己的图纸上,在之前调用编辑控件的程序。之后调用它或发布自己的BeginPaint/EndPaint(返回0或DefWindowProc)会导致文本中出现的问题根本不显示,只在调整大小时显示,而不是在编辑后显示,留下剩余的脱字符的屏幕垃圾。因此,无论EDIT控件的其他重绘时间如何,我都没有任何问题。
一些设置:
SetWindowSubclass(attributeValuesEdit, &AttributeValueEditProcedure, 0, reinterpret_cast<DWORD_PTR>(this));
// Not only do multiline edit controls fail to display the cue banner text,
// but they also ignore the Edit_SetCueBannerText call, meaning we can't
// just call GetCueBannerText in the subclassed function. So store it as
// a window property instead.
SetProp(attributeValuesEdit, L"CueBannerText", L"<attribute value>");
回调:
LRESULT CALLBACK AttributeValueEditProcedure(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam,
UINT_PTR subclassId,
DWORD_PTR data
)
{
...
case WM_PRINTCLIENT:
case WM_PAINT:
{
auto textLength = GetWindowTextLength(hwnd);
if (textLength == 0 && GetFocus() != hwnd)
{
// Get the needed DC with DCX_INTERSECTUPDATE before the EDIT
// control's WM_PAINT handler calls BeginPaint/EndPaint, which
// validates the update rect and would otherwise lead to drawing
// nothing later because the region is empty. Also, grab it from
// the cache so we don't mess with the EDIT's DC.
HDC hdc = (message == WM_PRINTCLIENT)
? reinterpret_cast<HDC>(wParam)
: GetDCEx(hwnd, nullptr, DCX_INTERSECTUPDATE|DCX_CACHE|DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
// Call the EDIT control so that the caret is properly handled,
// no caret litter left on the screen after tabbing away.
auto result = DefSubclassProc(hwnd, message, wParam, lParam);
// Get the font and margin so the cue banner text has a
// consistent appearance and placement with existing text.
HFONT font = GetWindowFont(hwnd);
RECT editRect;
Edit_GetRect(hwnd, OUT &editRect);
// Ideally we would call Edit_GetCueBannerText, but since that message
// returns nothing when ES_MULTILINE, use a window property instead.
auto* cueBannerText = reinterpret_cast<wchar_t*>(GetProp(hwnd, L"CueBannerText"));
HFONT previousFont = SelectFont(hdc, font);
SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
SetBkMode(hdc, TRANSPARENT);
DrawText(hdc, cueBannerText, int(wcslen(cueBannerText)), &editRect, DT_TOP|DT_LEFT|DT_NOPREFIX|DT_NOCLIP);
SelectFont(hdc, previousFont);
ReleaseDC(hwnd, hdc);
// Return the EDIT's result (could probably safely just return zero here,
// but seems safer to relay whatever value came from the edit).
return result;
}
}
break;
编写自己的编辑控制(我实际上已经超过一次,相比于内置偏度完整性如果你做最低限度的工作(也许只有英文基本的插入符支持),但是如果你想在可变大小的集群上进行复杂脚本的光标导航,范围选择,输入法支持,上下文菜单复制和粘贴,高对比度模式以及文字到语音等辅助功能。所以不像其他许多其他答案,我推荐而不是实现您自己的EDIT控件仅用于提示横幅文本。
你可以像我在Aero.Controls中的即时搜索框那样伪造它。http://bitbucket.org/factormystic/aero.controls – 2009-12-24 06:01:24
我曾尝试过你的方法。我很好奇你是如何解决绘制“SearchBox”主题的问题的。但我看到你没有解决问题。 – 2009-12-24 15:10:10
6年过去了,我只是说默认使用一些文本的CreateWindow。当用户单击控件时,将删除文本。您也可以将字体设置为斜体,并在点击时更改它。 – kundrata 2016-11-25 11:59:27