I have a window with extended frame made like this:
But anything drawn in the extended frame has very strange colors (except for white, the only color that stays the same), like this (ignore the messy content in the center and the messy toolbar at the right.
The pink rectangle (0xFFC9FF
) was supposed to be 0x8000FF
. If I put the DirectX11 content (the center thing) in the extended frame, alpha blending for my FPS counter gets messed up. If I do the same to the right dialog, the same happens.
So how can I do this correctly? I've already tried to draw first to a memory DC and then use BitBlt
. I'm using GDI+ (plus CreateCompatibleDC
, CreateCompatibleBitmap
and other functions to handle the memory DC).
PS: Because you asked, here is WndProc
:
LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT ReturnValue;
if (DwmDefWindowProc(hWnd, uMsg, wParam, lParam, &ReturnValue)) return ReturnValue;
switch (uMsg)
{
case WM_CREATE:
{
// ...
RECT rcClient;
GetWindowRect(hWnd, &rcClient);
SetWindowPos(hWnd,
NULL,
rcClient.left, rcClient.top,
rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
SWP_FRAMECHANGED);
return 0;
}
case WM_ACTIVATE:
{
MARGINS Margins;
Margins.cxLeftWidth = LEFT_BORDER;
Margins.cxRightWidth = RIGHT_BORDER;
Margins.cyTopHeight = TOP_BORDER;
Margins.cyBottomHeight = BOTTOM_BORDER;
if (DwmExtendFrameIntoClientArea(hWnd, &Margins) != S_OK)
{
MessageBox(hWnd, L"Erro ao configurar janela.", NULL, MB_ICONERROR);
PostQuitMessage(WM_QUIT);
}
if (LOWORD(wParam))
{
fActive = true;
}
else
{
fActive = false;
}
InvalidateRect(hWnd, NULL, false);
return 0;
}
case WM_SIZE:
/* ... */
case WM_NCCALCSIZE:
return 0;
case WM_NCHITTEST:
/* ... */
case WM_GETMINMAXINFO:
((LPMINMAXINFO)lParam)->ptMinTrackSize = { 640, 400 };
return 0;
case WM_PAINT:
{
using namespace Gdiplus;
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
RECT rcWindow;
GetWindowRect(hWnd, &rcWindow);
POINT ptSize = { rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top };
HDC hBuffer = CreateCompatibleDC(hDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, ptSize.x, ptSize.y);
SelectObject(hBuffer, hBitmap);
Graphics graphics(hBuffer);
Pen Outline(Color(128, 128, 128));
SolidBrush Selected(Color(128, 0, 255));
Rect Tab1(10, 10, 200, 50);
graphics.FillRectangle(&Selected, Tab1);
graphics.DrawRectangle(&Outline, Tab1);
/* ... */
BitBlt(hDC, 0, 0, ptSize.x, ptSize.y, hBuffer, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);
return 0;
}
/* ... */
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
As I mentioned, you were almost there with AlphaBlend. What I'd failed to remember/realize though was that you need to use a 32 bit DibSection that holds the purple rectangle. You also need to make sure you use 32bit aware drawing functions. That means you either have to write directly to the bits of the Dib, after retrieving them with a call to GetDIBits (or before creating a DIB from some bits) or you need to use GDI+ to draw the purple rectangle. You can see my commented-out code in the WM_INITDIALOG handler. This gives the result shown in the second image.
After trying some advice I gave in an answer I've since deleted, I recognized a familiar problem. The colour of the purple rectangle changed depending on on the colour of the window that my window was obscurring.
Here's another code sample that has been tested and works under Win7s implementation of the DWM. I'm not sure if Glass makes a difference here, or if Win 8 will behave similarly.
Here's the image: (The colour was correct when drawn, making the image an 8bit indexed one has changed it slightly)
Notice that the text in the edit-box is a bit funky, changing from okay to not okay as the background beneat the window changes from black to white. This is the same effect that the purple rectangle was exhibiting when I used GDI to draw it. When I used GDI+ instead, the problem went away. Dragging the window around rapidly can make the edges of the purple box appear a little strange. I think this is another one of the many failings of the DWM implementation in Windows7.
And here's the complete code for this window: