2013-02-21 116 views
2

我需要繪製自定義標題欄,我自己繪製窗口標題。如何在繪製自定義標題(框架)時在alt +製表切換器中繪製標題?

HDC hdc = GetWindowDC(hwnd); 
    if (hdc && prepareTitleBarDC(getWidth(), 27)) { 
     SetWindowText(hwnd, _T("")); 
     DefWindowProc(hwnd, WM_NCPAINT, wParam, lParam); 
     m_titleBar->setSize(getWidth(), 27); 
     m_titleBar->setBkColor(SkColorSetARGB(0x00, 0x00, 0x00, 0x00)); 
     m_titleBar->paintEvent(m_pTitleBarDC); 
     FnSkBitmap::SaveSkBitmap(m_pTitleBarDC->canvas(), L"e:\\titlebar.bmp"); 

     HDC hdcPaint = CreateCompatibleDC(hdc); 
     HBITMAP hbm = CreateCompatibleBitmap(hdc, getWidth(), 27); 
     SelectObject(hdcPaint, hbm); 
     FnSkBitmap::DrawSkBitmap(m_pTitleBarDC->bitmap(), hdcPaint); 
     BLENDFUNCTION bfn = {0}; 
     bfn.BlendOp = AC_SRC_OVER; 
     bfn.BlendFlags = 0; 
     bfn.SourceConstantAlpha = 255; 
     bfn.AlphaFormat = AC_SRC_ALPHA; 
     AlphaBlend(hdc, 0, 0, getWidth(), 27, hdcPaint, 0, 0, getWidth(), 27, bfn); 
    } 
    ReleaseDC(hwnd, hdc); 
    return 0; 

而且使用的AlphaBlend與自己混的標準框架,但如果我用函數SetWindowText(_T( 「」)),然後在Alt + Tab鍵切換的稱號了。

我嘗試處理WM_GETTEXT消息並返回字幕字符串,但失敗。我怎樣才能自己繪製標題文字,但仍然在alt + tab切換器中創作標題?

+3

使用'SetWindowText' t Alt + Tab窗口看到的文本。但是,當你繪製自定義標題欄時,不要打擾繪製文本。 – 2013-04-10 18:00:44

回答

2

既然你已經繪製「自定義標題欄」沒有理由把它實際使用的實際窗口的文字畫

有兩種方法來實現這一目的,採用傳統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); 
} 

結果窗口的樣子:

screenshot of resulting window

您可以看到2個「自定義繪製」標題欄顯示自定義文本,而不是窗口上的文本。

快速瀏覽一下代碼會告訴你,使用自定義例程嘗試主題窗口標題比傳統要困難得多。當然,權衡是讓你有更多的控制權。您還會注意到,我將窗口文本切換爲使其顯示使用傳統方法時所需的內容。此外,您需要記住,如果您的窗口樣式沒有圖標,即使您指定它,也不會繪製一個圖標,但傳統方法會將隊列放在如何從與窗口相關聯的樣式中繪製自己的隊列上...

這些技術都可以實現您的目標。如果我換周圍沒有這個代碼,以繪製多個標題欄和擺脫由窗口樣式創建一個默認的結果會是什麼樣子的:

screenshot showing result 你可以在這裏看到任務切換仍然顯示實際的窗口文本和我的「定製」標題欄看起來像真正的交易...

好運,我希望在一個側面說明這有助於-ck

:我正在運行Windows8的,我不知道爲什麼標題圖紙例程忽略我的主題...也許我忘了一個指令