在扩展框架中绘图会产生奇怪的颜色

时间:2015-06-27 21:04:01

标签: c++ winapi dwm

我有一个带有扩展框架的窗口,如下所示:

Custom Window Frame Using DWM

但是在扩展框架中绘制的任何东西都有非常奇怪的颜色(除了白色,唯一保持不变的颜色),就像这样(忽略中心的杂乱内容和右边凌乱的工具栏。

Screenshot

粉红色矩形(0xFFC9FF)应该是0x8000FF。如果我将DirectX11内容(中心内容)放在扩展帧中,我的FPS计数器的alpha混合就会搞砸了。如果我对右边的对话框做同样的事情,也会发生同样的情况。

那我怎么能正确地做到这一点?我已经尝试先画一个内存DC,然后使用BitBlt。我正在使用GDI +(加CreateCompatibleDCCreateCompatibleBitmap和其他函数来处理内存DC。)

PS:因为你问过,这里是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);
    }
}

1 个答案:

答案 0 :(得分:3)

正如我所提到的,你几乎就在那里使用AlphaBlend。我忘记/意识到的是你需要使用一个32位DibSection来保存紫色矩形。您还需要确保使用32位感知绘图功能。这意味着您必须直接写入Dib的位,在通过调用GetDIBits检索它们之后(或者在从某些位创建DIB之前),您需要使用GDI +绘制紫色长方形。您可以在WM_INITDIALOG处理程序中看到我注释掉的代码。这给出了第二张图像中显示的结果。

在尝试了一些建议之后我给出了一个自删除以来的答案,我认识到了一个熟悉的问题。紫色矩形的颜色根据窗口遮挡的窗口颜色而改变。

这是另一个经过测试的代码示例,可以在Win7的DWM实现下运行。我不确定Glass是否会有所不同,或者Win 8的行为是否相似。

这里是图像:(绘制时颜色正确,使图像成为8位索引,稍微改变了一下)

enter image description here enter image description here

请注意,编辑框中的文字有点时髦,从好的变为不好,因为窗口的背景会从黑色变为白色。当我使用GDI绘制它时,这与紫色矩形表现出的效果相同。当我使用GDI +时,问题就消失了。快速拖动窗口会使紫色框的边缘看起来有点奇怪。我认为这是Windows7中DWM实现的许多失败中的另一个。

以下是此窗口的完整代码:

def extract_names(filename):
  names = []
  f = open(filename, 'rU')
  text = f.read()

  yearmatch = re.search(r'Popularity\sin\s(\d\d\d\d)', text)
  if not yearmatch:
    sys.stderr.write('unavailable year\n')
    sys.exit(1)
  year = yearmatch.group(1)
  names.append(year)

  yeartuples = re.findall(r'<td>(\d+)</td><td>(\w+)</td>\<td>(\w+)</td>', text)#finds all patterns of date, boyname, and girlname, creates tuple)

  rankednames = {}
  for rank_tuple in yeartuples:
    (rank, boyname, girlname) = rank_tuple
    if boyname not in rankednames:
      rankednames[boyname] = rank
    if girlname not in rankednames:
      rankednames[girlname] = rank
  sorted_names = sorted(rankednames.keys())
  for name in sorted_names:
    names.append(name + " " + rankednames[name])

  return names


def main():

  args = sys.argv[1:]

  if not args:
    print 'usage: [--summaryfile] file [file ...]'
    sys.exit(1)

  summary = False
  if args[0] == '--summaryfile':
    summary = True
    del args[0]

  for filename in args:
    names = extract_names(filename)
    text = '\n'.join(names)

    if summary:
      outf = open(filename + '.summary', 'w')
      outf.write(text + '\n')
      outf.close()
    else:
      print text

if __name__ == '__main__':
    main()