To change the static's control color and width, I did process the WM_NCPAINT
message, but it's not working properly:
the text isn't properly displayed. Should I draw it in this message? When I call SetWindowText()
, the new text is properly set, but I still have the issue #2.
after a call to SetWindowText()
, the text is set, but the border differs, it's smaller than the one I've draw in the WM_NCPAINT
message.
Here's how I'm handling WM_NCPAINT
:
case WM_NCPAINT:
{
PAINTSTRUCT ps;
HDC dc = BeginPaint(hwnd, &ps);
RECT rt = {0};
GetClientRect(hwnd, &rt);
HPEN pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
HPEN holdPen = SelectObject(dc, pen);
DrawBorder(dc, &rt);
SelectObject(dc, holdPen);
EndPaint(hwnd, &ps);
DeleteObject(pen);
pen = NULL;
return 0;
}
When the application starts, the static control border looks like the one I've draw at WM_NCPAINT
:
But once I call SetWindowText()
, for example, from a button click, it looks like this:
What am I missing?
Here's full code:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <Commctrl.h>
#include <crtdbg.h>
#include <strsafe.h>
#include <string.h>
#include <assert.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void EnableVisualStyles2(void);
LRESULT CALLBACK ButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void SetDefaultFont(HWND hwnd);
void DrawLine(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2);
void DrawBorder(HDC hdc, RECT *rect);
HFONT getSystemDefaultFont(void);
WNDPROC oldButtonProc;
HINSTANCE ghInstance;
HFONT hDefaultFont;
HWND btn, btn2;
enum
{
BTN_ID = 10,
BTN2_ID,
};
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow)
{
MSG msg = {0};
HWND hwnd;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
EnableVisualStyles2();
if(!RegisterClass(&wc)) {
return -1;
}
int width = 540;
int height = 460;
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
int cx = (screenWidth - width) / 2;
int cy = (screenHeight - height) / 2;
hwnd = CreateWindowW(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
cx, cy, width, height, NULL, NULL,
hInstance, NULL);
ghInstance = hInstance;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DeleteObject(hDefaultFont);
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
btn =
CreateWindow(L"static", L"+",
WS_VISIBLE | WS_CHILD | WS_TABSTOP |
SS_NOTIFY | SS_CENTER | SS_CENTERIMAGE,
15, 25, 50, 50,
hwnd, (HMENU) BTN_ID, NULL, NULL);
SetDefaultFont(btn);
oldButtonProc = (WNDPROC) SetWindowLongPtr(btn,
GWLP_WNDPROC,
(LONG_PTR) ButtonProc);
btn2 =
CreateWindow(L"Button", L"Click me!",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
15, 100, 70, 25,
hwnd, (HMENU) BTN2_ID,
NULL, NULL);
SetDefaultFont(btn2);
}
break;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case BTN_ID:
{
//InvalidateRect(btn, NULL, TRUE);
if(IsWindowVisible(btn2))
{
SetWindowText(btn, L"+");
ShowWindow(btn2, SW_HIDE);
}
else
{
SetWindowText(btn, L"-");
ShowWindow(btn2, SW_SHOW);
}
}
break;
case BTN2_ID:
{
InvalidateRect(btn, NULL, TRUE);
//SetWindowText(btn, L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0");
}
break;
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK ButtonProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_NCPAINT:
{
PAINTSTRUCT ps;
HDC dc = BeginPaint(hwnd, &ps);
RECT rt = {0};
GetClientRect(hwnd, &rt);
HPEN pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
HPEN holdPen = SelectObject(dc, pen);
DrawBorder(dc, &rt);
SelectObject(dc, holdPen);
EndPaint(hwnd, &ps);
DeleteObject(pen);
pen = NULL;
return 0;
}
}
return CallWindowProc(oldButtonProc, hwnd, msg, wParam, lParam);
}
void EnableVisualStyles2(void)
{
TCHAR dir[MAX_PATH] = {0};
GetSystemDirectory(dir, sizeof(dir) / sizeof(*dir));
ACTCTX actCtx = {0};
actCtx.cbSize = sizeof(ACTCTX);
actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID |
ACTCTX_FLAG_SET_PROCESS_DEFAULT |
ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
actCtx.lpSource = L"shell32.dll";
actCtx.lpAssemblyDirectory = dir;
actCtx.lpResourceName = (LPCTSTR) 124;
ULONG_PTR cookie = FALSE;
HANDLE h = CreateActCtx(&actCtx);
assert(h != INVALID_HANDLE_VALUE);
assert(ActivateActCtx(h, &cookie));
}
HFONT getSystemDefaultFont(void)
{
if(!hDefaultFont)
{
// get system default font
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
hDefaultFont = CreateFontIndirect(&ncm.lfMessageFont);
}
return hDefaultFont;
}
void SetDefaultFont(HWND hwnd)
{
SendMessage(hwnd, WM_SETFONT, (WPARAM)getSystemDefaultFont(), FALSE);
}
void DrawLine(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2)
{
MoveToEx(hdc, x1, y1, NULL);
LineTo(hdc, x2, y2);
}
void DrawBorder(HDC hdc, RECT *rect)
{
DrawLine(hdc, rect->left, rect->top, rect->left, rect->bottom);
DrawLine(hdc, rect->left, rect->top, rect->right, rect->top);
DrawLine(hdc, rect->right, rect->top, rect->right, rect->bottom);
DrawLine(hdc, rect->left, rect->bottom, rect->right, rect->bottom);
}
question from:
https://stackoverflow.com/questions/66053453/how-do-i-make-a-static-control-with-custom-width-and-color