解决了!
我最初的问题是CreateFont函数是否可以与CreateWindow函数一起使用。我在文档中找到的所有东西都让我相信它只适用于text函数。
由于我无法执行我得到的建议,并且在我的问题上没有取得任何进展,我采取了新的方法。我创建了测试代码,以便可以在WM_CREATE:和WM_PAINT:中所做的更改之间轻松切换。现在,我更容易找到我在文档中找到的东西,搜索和我脑海中突然出现的东西。
下面是我的测试代码。添加和删除styleSelection的注释让我可以选择我正在处理的内容。
全局: HFONT hFont;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
HDC hdc;
string styleSelection = "WM_CREATE";
//styleSelection = "WM_PAINT";
switch(uMsg) {
case WM_CLOSE: {
DeleteObject(hFont);
DestroyWindow(hWnd);
break;
}
case WM_COMMAND: {
DeleteObject(hFont);
PostQuitMessage(0);
break;
}
case WM_CREATE: {
HINSTANCE hIns = ((LPCREATESTRUCT)lParam)->hInstance;
if((styleSelection == "WM_CREATE") && (hFont = CreateFontA(18, 0, 0, 0, FW_DONTCARE, 1, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, TEXT("DONTCARE")))) {
int textHStart = 20; int textLineSpace = 16;
vector < int > textVStart = { 20,60,100,120,160 };
vector < string > newStrings;
newStrings = getDynamicData(); // Get the strings for output
for(int i = 0; i < newStrings.size(); i++) {
CreateWindowEx(NULL, TEXT("Static"), newStrings[i].c_str(), WS_CHILD | WS_VISIBLE, textHStart, textVStart[i], newStrings[i].length() * 10, textLineSpace, hWnd, (HMENU)IDC_USER_LABEL, hIns, NULL);
}
}
HWND hButton = CreateWindowA(_T("button"), _T("Exit"), WS_CHILD | WS_VISIBLE, 385, 250, 60, 25, hWnd, (HMENU)IDC_BUTTON, hIns, 0);
return 0;
}
case WM_DESTROY: {
DeleteObject(hFont);
PostQuitMessage(0);
break;
}
case WM_CTLCOLORSTATIC: {
HDC hEdit = (HDC)wParam;
SetTextColor(hEdit, RGB(0, 0, 0));
//SetBkColor(hEdit, RGB(0xFF, 0x00, 0x00));
SetBkMode(hEdit, TRANSPARENT);
return (INT_PTR)GetStockObject(HOLLOW_BRUSH);
}
case WM_PAINT: {
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
if((styleSelection == "WM_PAINT") && (hFont = CreateFontA(18, 0, 0, 0, FW_DONTCARE, 1, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, TEXT("DONTCARE")))) {
HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
HDC hEdit = (HDC)wParam;
SetTextColor(hdc, RGB(0, 0, 0));
//SetBkColor(hdc, RGB(0xFF, 0x00, 0x00));
SetBkMode(hdc, TRANSPARENT);
int index = 7; // Vertical spaces and number of lines for the array
const char* cpaText[7] = { "Hello,","", "What I want to do", "is to format this text." };
for(int iLoopCounter = 0; cpaText[iLoopCounter] != 0; iLoopCounter++, index += 20) {
TextOutA(hdc, 5, index, cpaText[iLoopCounter], strlen(cpaText[iLoopCounter]));
}
SelectObject(hdc, hOldFont);
}
EndPaint(hWnd, &ps);
break;
}
default: {
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
break;
}
}
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}
////---- this is the data to be printed.
vector < string > getDynamicData() {
vector < string > retvec;
retvec.push_back("This is a test.");
retvec.push_back("I am trying to change the text");
return retvec;
}我最终想出的解决方案是在答案部分。
发布于 2021-08-11 17:01:41
我的工作解决方案:
我的一个问题是WM_PAINT中的TextOut没有使用动态文本。回顾早先使用Jonathan Potter在Add dynamic text to WM_CREATE in C++ using variables中的建议解决的问题,我最终意识到同样的方法也适用于TextOut。
在我让TextOut处理动态文本之后,下一个选项是将WM_CREATE保留为标准字体样式,或者将所有内容迁移到WM_PAINT。我决定迁移到WM_PAINT将是更干净的解决方案。以下是我最终得到的结论:
全局: HFONT hFont;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
HDC hdc;
string styleSelection = "standardFont";
styleSelection = "specialFont";
switch(uMsg) {
case WM_CREATE: {
if(-1 == DefWindowProc(hWnd, WM_CREATE, wParam, lParam))
return -1;
hFont = CreateFontA(18, 0, 0, 0, FW_DONTCARE, 1, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, TEXT("DONTCARE"));
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM)hFont);
}
break;case WM_CLOSE: {
DeleteObject(hFont);
DestroyWindow(hWnd);
break;
}
case WM_COMMAND: {
DeleteObject(hFont);
PostQuitMessage(0);
break;
}
case WM_DESTROY: {
//DestroyObject((HFONT)GetWindowLongPtr(hWnd, GWLP_USERDATA));
DeleteObject((HFONT)GetWindowLongPtr(hWnd, GWLP_USERDATA));
return DefWindowProc(hWnd, WM_DESTROY, wParam, lParam);
}
case WM_PAINT: {
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
HDC hEdit = (HDC)wParam;
SetBkMode(hdc, TRANSPARENT);
if(styleSelection == "standardFont") {
SetTextColor(hdc, RGB(0, 0, 0));
int textHStart = 20; int textLineSpace = 16;
vector < int > textVStart = { 20,60,100,120,160 };
vector < string > newStrings;
newStrings = getDynamicData(); // Get the strings for output
for(int i = 0; i < newStrings.size(); i++) {
TextOutA(hdc, textHStart, textVStart[i], newStrings[i].c_str(), newStrings[i].size());
}
}
else {
DefWindowProc(hWnd, WM_PAINT, wParam, lParam);
hFont = (HFONT)GetWindowLongPtr(hWnd, GWLP_USERDATA);
HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
SetTextColor(hdc, RGB(0xFF, 0x00, 0x00));
int textHStart = 20; int textLineSpace = 16;
vector < int > textVStart = { 20,60,100,120,160 };
vector < string > newStrings;
newStrings = getDynamicData(); // Get the strings for output
for(int i = 0; i < newStrings.size(); i++) {
TextOutA(hdc, textHStart, textVStart[i], newStrings[i].c_str(), newStrings[i].size());
}
SelectObject(hdc, hOldFont);
DeleteObject(hFont);
}
EndPaint(hWnd, &ps);
break;
}
default: {
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
break;
}上面的代码还实现了一些SoronelHaetir推荐的内容。我将根据SoronelHaetir的其余建议进行更多的研究,我仍然需要解决可能的内存泄漏问题和其他一些平滑项目,但这适用于我想要做的事情。它所需要的就是阅读,耐心和足够的毅力,直到我弄明白为止。
发布于 2021-08-07 17:05:16
您不应该在WM_PAINT处理程序期间调用CreateWindow。
相反,您需要做的是保存在WM_CREATE处理程序中创建的字体,然后在以后获取WM_PAINT时使用该字体。带有GWLP_USERDATA的GetWindowLongPtr/SetWindowLongPtr是执行这种数据保存所提供的规范方法。
例如:
LRESULT WINAPI MyWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
if(-1 == DefWindowProc(hWnd, WM_CREATE, wParam, lParam))
return -1;
HFONT hFont = CreateFont(...);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM)hFont);
}
break;
case WM_DESTROY:
DestroyObject((HFONT)GetWindowLongPtr(hWnd, GWLP_USERDATA));
return DefWindowProc(hWnd, WM_DESTROY, wParam, lParam);
case WM_PAINT:
{
DefWindowProc(hWnd, WM_PAINT, wParam, lParam);
HFONT hFont = (HFONT)GetWindowLongPtr(hWnd, GWLP_USERDATA);
...
}
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}还可以在实际创建窗口的任何代码中创建HFONT,并将该HFONT作为lParam参数传递给CreateWindow,然后在处理WM_CREATE时按说明保存它(而不是在处理WM_CREATE时实际创建HFONT )。
发布于 2021-08-07 17:35:36
对于文本框,它已经完成了
HFONT newFont = CreateFont(22, 0, 0, 0,0 , FALSE, FALSE, FALSE, DEFAULT_CHARSET,
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY,
DEFAULT_PITCH | FF_DECORATIVE, L"Lucida Console");
::PostMessage(hc,WM_SETFONT,(WPARAM)newFont,(LPARAM)0);您应该在其他地方创建所有这些内容
并使用WS_EX_COMPOSITED
将此::PostMessage(hc,WM_SETFONT,(WPARAM)newFont,(LPARAM)0);添加到您已有的for循环的末尾。但不是使用hc ofc
https://stackoverflow.com/questions/68694300
复制相似问题