我有一个带有扩展框架的窗口,如下所示:
但是在扩展框架中绘制的任何东西都有非常奇怪的颜色(除了白色,唯一保持不变的颜色),就像这样(忽略中心的杂乱内容和右边凌乱的工具栏。
粉红色矩形(0xFFC9FF
)应该是0x8000FF
。如果我将DirectX11内容(中心内容)放在扩展帧中,我的FPS计数器的alpha混合就会搞砸了。如果我对右边的对话框做同样的事情,也会发生同样的情况。
那我怎么能正确地做到这一点?我已经尝试先画一个内存DC,然后使用BitBlt
。我正在使用GDI +(加CreateCompatibleDC
,CreateCompatibleBitmap
和其他函数来处理内存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);
}
}
答案 0 :(得分:3)
正如我所提到的,你几乎就在那里使用AlphaBlend。我忘记/意识到的是你需要使用一个32位DibSection来保存紫色矩形。您还需要确保使用32位感知绘图功能。这意味着您必须直接写入Dib的位,在通过调用GetDIBits检索它们之后(或者在从某些位创建DIB之前)或,您需要使用GDI +绘制紫色长方形。您可以在WM_INITDIALOG处理程序中看到我注释掉的代码。这给出了第二张图像中显示的结果。
在尝试了一些建议之后我给出了一个自删除以来的答案,我认识到了一个熟悉的问题。紫色矩形的颜色根据窗口遮挡的窗口颜色而改变。
这是另一个经过测试的代码示例,可以在Win7的DWM实现下运行。我不确定Glass是否会有所不同,或者Win 8的行为是否相似。
这里是图像:(绘制时颜色正确,使图像成为8位索引,稍微改变了一下)
请注意,编辑框中的文字有点时髦,从好的变为不好,因为窗口的背景会从黑色变为白色。当我使用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()