This is as short as I can produce it.
This sample is showing a standard created button using CreateWindow added with Visual Style, the button has an ugly white border (properly the standard background brush)
and then a subclassed static control also created with CreateWindows and then used SetWindowLong and added Visual style using a button template, this has not the ugly white border, its showing how it should be.
Is it really neccessary to subclass each and every control to remove the ugly white border?
And how about an app wide Font that will be added as default font for each and every control or text that will be output?
#include <Windows.h>
#include <CommCtrl.h>
#include <Uxtheme.h>
#include <vsstyle.h>
#include <Richedit.h>
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"uxtheme.lib")
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
LRESULT CALLBACK MyWndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK MyStaticProc(HWND,UINT,WPARAM,LPARAM);
static TCHAR szAppName[] = TEXT("Jubii");
static HINSTANCE g_hInst = NULL;
WNDPROC MyOriginalStaticProc;
int _stdcall WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpszCmdLine,int nCmdShow)
{
WNDCLASS wndclass;
MSG msg;
HWND hwnd;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance = hInst;
wndclass.lpfnWndProc = &MyWndProc;
wndclass.lpszClassName = szAppName;
wndclass.lpszMenuName = L"AllControlsInForm";
wndclass.style = CS_HREDRAW | CS_VREDRAW;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,L"Couldn't register window",szAppName,MB_OK|MB_ICONERROR);
return -1;
}
hwnd = CreateWindow(szAppName,
L"AllControlsInOneForm",
WS_OVERLAPPEDWINDOW | WS_SYSMENU,
50,
50,
640,
480,
NULL,
(HMENU) NULL,
hInst,
NULL
);
g_hInst = hInst;
InitCommonControls();
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MyStaticProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
static RECT windowRect;
static RECT borderRect;
static HTHEME hTheme;
switch(msg)
{
case WM_STYLECHANGED:
case WM_THEMECHANGED:
{
if(::IsThemeActive()&&GetWindowLong(hwnd,GWL_EXSTYLE)&WS_EX_CLIENTEDGE)
{
SetWindowLong(hwnd,GWL_EXSTYLE,GetWindowLong(hwnd,GWL_EXSTYLE)^WS_EX_CLIENTEDGE);
}
SetWindowPos(hwnd,NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);
RedrawWindow(hwnd,NULL,NULL,RDW_INVALIDATE|RDW_NOCHILDREN|RDW_UPDATENOW|RDW_FRAME);
}
return 0;
case WM_NCPAINT:
{
LRESULT lr = CallWindowProc(::MyOriginalStaticProc,hwnd,msg,wParam,lParam);
hTheme = OpenThemeData(hwnd,L"BUTTON");
if(hTheme)
{
RECT rcBorder;
RECT rcClient;
int nState;
HDC hdc = GetWindowDC(hwnd);
GetWindowRect(hwnd,&rcBorder);
rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top;
rcBorder.left = rcBorder.top = 0;
CopyRect(&rcClient,&rcBorder);
rcClient.left += rcBorder.left;
rcClient.top += rcBorder.top;
rcClient.right -= rcBorder.right;
rcClient.bottom -= rcBorder.bottom;
ExcludeClipRect(hdc,rcClient.left,rcClient.top,rcClient.right,rcClient.bottom);
if(::IsThemeBackgroundPartiallyTransparent(hTheme,EP_EDITTEXT,ETS_NORMAL))
{
DrawThemeParentBackground(hwnd,hdc,&rcBorder);
}
if(!IsWindowEnabled(hwnd))
nState = ETS_DISABLED;
else if(SendMessage(hwnd,EM_GETOPTIONS,0,0) & ECO_READONLY)
nState = ETS_READONLY;
else
nState = ETS_NORMAL;
DrawThemeBackground(hTheme,hdc,EP_EDITTEXT,nState,&rcBorder,NULL);
CloseThemeData(hTheme);
ReleaseDC(hwnd,hdc);
return 0;
}
return lr;
}
case WM_NCCALCSIZE:
{
LRESULT lr = CallWindowProc(::MyOriginalStaticProc,hwnd,msg,wParam,lParam);
NCCALCSIZE_PARAMS *nsParams = (NCCALCSIZE_PARAMS*)lParam;
hTheme = OpenThemeData(hwnd,L"EDIT");
if(hTheme)
{
RECT rcClient;
HDC hdc = GetDC(GetParent(hwnd));
ZeroMemory(&rcClient,sizeof(RECT));
if(GetThemeBackgroundContentRect(hTheme,hdc,EP_EDITTEXT,ETS_NORMAL,&nsParams->rgrc[0],&rcClient) == S_OK)
{
ReleaseDC(GetParent(hwnd),hdc);
return WVR_REDRAW;
}
ReleaseDC(GetParent(hwnd),hdc);
CloseThemeData(hTheme);
}
return lr;
}
default:
return CallWindowProc(::MyOriginalStaticProc,hwnd,msg,wParam,lParam);
}
}
LRESULT CALLBACK MyWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
static HWND hwndStaticSubClass;
HDC hdc;
PAINTSTRUCT ps;
switch(msg)
{
case WM_CREATE:
{
HDC hdc = GetWindowDC(hwnd);
HFONT hFont = CreateFont(
36,
20,
-300,
0,
FW_DONTCARE,
FALSE,
TRUE,
FALSE,
DEFAULT_CHARSET,
OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS,
CLEARTYPE_QUALITY,
VARIABLE_PITCH,
TEXT("Tahoma")
);
SendMessage(hwnd,WM_SETFONT,(WPARAM)hFont,(LPARAM)true);
hwndStaticSubClass = CreateWindow(L"STATIC",L"Hej",WS_CHILD | WS_VISIBLE, 120,120,200,200,hwnd,(HMENU) NULL,g_hInst,0);
::MyOriginalStaticProc = (WNDPROC)SetWindowLong(hwndStaticSubClass,GWL_WNDPROC,(LONG)&::MyStaticProc);
HWND hwndButton = CreateWindow(L"BUTTON",L"Hejsa",WS_CHILD | WS_VISIBLE,75,75,23,23,hwnd,(HMENU) NULL,g_hInst,0);
}
return 0;
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wparam;
SetTextColor(hdcStatic,RGB(46,46,46));
SetBkMode(hdcStatic,TRANSPARENT);
HBRUSH hollow = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
return (LONG) hollow;
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
SetBkMode(hdc,TRANSPARENT);
TextOut(hdc,10,10,L"Hello World!!!!",::strlen("Hello World!!!!"));
EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,msg,wparam,lparam);
}
}