最近在跟孩子学习DEV C++,使用Win32 API生成桌面 Windows 应用,尝试自己动手制作一个简易计算器应用程序。使用CreateWindow函数生成的控件背景和字体都是系统默认的,感觉缺乏些个性化。经查阅了资料找到一些方法,可以改变控件默认字体及静态控件的背景、文本颜色等,相比FillRect、DrawText等函数简单、好用,特此记录分享。
一、修改控件的默认字体、大小
通过SendMessage函数发送WM_SETFONT消息,将wParam参数设置为新创建的字体,并将lParam参数设置为TRUE,则控件将重新绘制自身,即可在控件创建后使用我们设置的字体。此消息不返回值,且适用于所有控件,而不仅仅是对话框中的控件。示例如下:
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch (Message) {
case WM_CREATE: {
//创建窗口按扭
h0 = CreateWindow("button", "0", WS_CHILD | WS_VISIBLE, 84, 363, 80, 60, hwnd,
(HMENU)0, hInst, NULL);
h1 = CreateWindow("button", "1", WS_CHILD | WS_VISIBLE, 2, 300, 80, 60, hwnd,
(HMENU)1, hInst, NULL);
//...省略...
sc = CreateWindow("static", "0", SS_RIGHT | WS_CHILD | WS_VISIBLE, 2, 48, 323,
30, hwnd, (HMENU)20, hInst, NULL); //计算结果右对齐输出,静态控件
sc2 = CreateWindow("static", " ", SS_RIGHT | WS_CHILD | WS_VISIBLE, 2, 18,
323, 30, hwnd, (HMENU)21, hInst, NULL); //计算式右对齐输出,静态控件
//创建新字体
HFONT hFont = CreateFont(36, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,
CLEARTYPE_QUALITY, VARIABLE_PITCH, "Elephant");
//使用新字体修改控件默认字体
SendMessage(h0, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
SendMessage(h1, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
//...省略...
SendMessage(sc, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
SendMessage(sc2, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
break;
}
二、设置静态框控件的背景及字体颜色
我们可以通过处理WM_CTLCOLORSTATIC消息,来达到修改静态框控件默认的灰色背景及文本颜色。Windows开发网官方给的解释是:静态控件或只读或禁用的编辑控件将在控件即将绘制时,将 WM_CTLCOLORSTATIC 消息发送到其父窗口。 通过响应此消息,父窗口可以使用指定的设备上下文句柄来设置静态控件的文本前景色和背景色。
//处理静态框消息。重绘静态框背景、设置文本颜色
case WM_CTLCOLORSTATIC: {
COLORREF clrBackground = GetSysColor(COLOR_WINDOW); // 获取主窗口的背景色
HBRUSH hbrNew = CreateSolidBrush(clrBackground);// 创建一个新的画笔,颜色与主窗口背景色相同
SetBkColor((HDC)wParam, clrBackground); // 将新画笔设置为静态控件的背景色
SetTextColor((HDC)wParam, RGB(255, 0, 0));//设置字体颜色
SetBkMode((HDC)wParam, TRANSPARENT); //文本字体背景透明
return (LRESULT)hbrNew; // 返回新画笔的句柄,这样Windows就会使用它来重新绘制
}
三、自己写的一个函数用来修改字体及颜色
自己写的函数,方便随时调用。第一个参数是将要改变的控件句柄,第二个参数是显示的文本,第三个参数是系统字体名字,第四个参数是显示的样式。
void display(HWND hwnd, const string &text, string FontName, const unsigned &uInt ) {
HDC hdc;
RECT rc;
HFONT hf;//设置字体变量;
GetClientRect(hwnd, &rc);
hdc = GetDC(hwnd);
UpdateWindow(hwnd);
RedrawWindow(hwnd, &rc, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
FillRect(hdc, &rc, (HBRUSH) (COLOR_WINDOW + 1));
SetTextColor(hdc, RGB(255, 0, 0));//设置字体颜色
SetBkMode(hdc, TRANSPARENT); //文本字体背景透明:1为透明,2不透明
hf = CreateFont(36, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,
CLEARTYPE_QUALITY, VARIABLE_PITCH, FontName.c_str());
(HFONT)SelectObject(hdc, hf);//将创建的字体用于指定句柄
// unsigned i=DT_RIGHT | DT_VCENTER | DT_SINGLELINE; i=38为右对齐垂直居中
// i=37横居中、垂直居中(简写而已)
DrawTextA(hdc, text.c_str(), -1, &rc, uInt);
DeleteObject(hf);//删除字体
ReleaseDC(hwnd, hdc);
}
//用法示例
display(hWnd, "1", "Elephant", 37);
通过以上代码,可以按自己的想法来设置程序界面,感觉是不是很好?附截图