2013-02-21 14 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的,我不知道为什么标题图纸例程忽略我的主题...也许我忘了一个指令