既然你已經繪製「自定義標題欄」沒有理由把它實際使用的實際窗口的文字畫
有兩種方法來實現這一目的,採用傳統DrawCaption
從Win9x的WIN32API,另一種是使用更新鮮「的主題API」
這裏是同時使用了一個例子:
#include <Windows.h>
#include <Uxtheme.h>
#include <vssym32.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
const LPCWSTR WINDOW_CLASS = L"Test Window Class";
const LPCWSTR WINDOW_CAPTION = L"This is my test window";
const LPCWSTR CUSTOM_CAPTION = L"Custom Caption Text";
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
WNDCLASSEX wndClassEx = {};
wndClassEx.lpszClassName = WINDOW_CLASS;
wndClassEx.hInstance = hInstance;
wndClassEx.lpfnWndProc = WindowProc;
wndClassEx.cbSize = sizeof(wndClassEx);
wndClassEx.hCursor = (HCURSOR) LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
wndClassEx.style = CS_DBLCLKS | CS_DROPSHADOW;
ATOM registeredClass = RegisterClassEx(&wndClassEx);
HWND hwnd = CreateWindowEx(
0,
WINDOW_CLASS,
WINDOW_CAPTION,
WS_SYSMENU,
200, 200, 500, 300,
NULL, // parent
NULL, // menu
hInstance,
NULL // extra
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_LBUTTONDBLCLK:
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// fill the window with a color
HBRUSH hbrush = CreateSolidBrush(RGB(33, 33, 33));
FillRect(hdc, &ps.rcPaint, hbrush);
DeleteObject(hbrush);
// get a drawing area
RECT rect = {};
GetClientRect(hwnd, &rect);
rect.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYEDGE) * 2;
// draw a simple win9x style caption (switch out the window text while drawing)
SetWindowText(hwnd, CUSTOM_CAPTION);
DrawCaption(hwnd, hdc, &rect, DC_GRADIENT | DC_TEXT | DC_ACTIVE | DC_ICON);
SetWindowText(hwnd, WINDOW_CAPTION);
// use theme framework
HTHEME htheme = OpenThemeData(hwnd, L"Window");
// move downwards and then use new APIs for size
rect.top += rect.bottom + 20;
rect.bottom = rect.top + GetThemeSysSize(htheme, SM_CYSIZE) + GetThemeSysSize(htheme, SM_CXPADDEDBORDER) * 2;
// draw the background
DrawThemeBackground(htheme, hdc, WP_CAPTION, CS_ACTIVE, &rect, &ps.rcPaint);
// load the caption font and save the old one
LOGFONTW captionfont = {};
GetThemeSysFont(htheme, TMT_CAPTIONFONT, &captionfont);
HFONT newfont = CreateFontIndirect(&captionfont);
HGDIOBJ oldfont = SelectObject(hdc, newfont);
// center the font and draw
rect.top += GetThemeSysSize(htheme, SM_CXPADDEDBORDER);
DrawThemeTextEx(htheme, hdc, WP_CAPTION, CS_ACTIVE, CUSTOM_CAPTION, -1, DT_CENTER, &rect, NULL);
// cleanup fonts
SelectObject(hdc, oldfont);
DeleteObject(newfont);
// adjust draw location, load icon and draw
rect.left += GetThemeSysSize(htheme, SM_CXPADDEDBORDER) * 2;
rect.top += GetThemeSysSize(htheme, SM_CXPADDEDBORDER);
HICON icon = (HICON) LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
DrawIconEx(hdc, rect.left, rect.top, icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL);
// close theme
CloseThemeData(htheme);
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
結果窗口的樣子:
您可以看到2個「自定義繪製」標題欄顯示自定義文本,而不是窗口上的文本。
快速瀏覽一下代碼會告訴你,使用自定義例程嘗試主題窗口標題比傳統要困難得多。當然,權衡是讓你有更多的控制權。您還會注意到,我將窗口文本切換爲使其顯示使用傳統方法時所需的內容。此外,您需要記住,如果您的窗口樣式沒有圖標,即使您指定它,也不會繪製一個圖標,但傳統方法會將隊列放在如何從與窗口相關聯的樣式中繪製自己的隊列上...
這些技術都可以實現您的目標。如果我換周圍沒有這個代碼,以繪製多個標題欄和擺脫由窗口樣式創建一個默認的結果會是什麼樣子的:
你可以在這裏看到任務切換仍然顯示實際的窗口文本和我的「定製」標題欄看起來像真正的交易...
好運,我希望在一個側面說明這有助於-ck
:我正在運行Windows8的,我不知道爲什麼標題圖紙例程忽略我的主題...也許我忘了一個指令
使用'SetWindowText' t Alt + Tab窗口看到的文本。但是,當你繪製自定義標題欄時,不要打擾繪製文本。 – 2013-04-10 18:00:44