对Win10 RS2 GDI缩放技术的兼容性
事实上,要兼容Win10 RS2 GDI缩放技术,最好的方法就是使用纯GDI绘图。
从下边的截图可以看到,这种方法对Win10 RS2 GDI缩放技术的兼容性比较好。
这是150%缩放下的程序(透明度设为0xF0):
放大局部:
再放大:
使用GdiGradientFill和GdiAlphaBlend函数,可以绘制带有Alpha通道的透明图形,但是还没有实现除锯齿,因为GdiAlphaBlend函数不支持HALFTONE缩放模式。
实际上,我们可以使用StretchBlt先将背景2倍放大拷出来,然后GdiAlphaBlend混合,最后再StretchBlt将混合后的图形2倍缩小拷回去来实现除锯齿。
<code class="language-cpp">void GdiAlphaBlendFac(HDC hdc1, int x, int y, int width, int height, HDC hdc2, int x2, int y2, int fac, unsigned constalpha) { // 先将背景放大 HDC hdc3 = CreateCompatibleDC(hdc1); HBITMAP hbmp3 = CreateCompatibleBitmap(hdc1, width * fac, height * fac); SelectObject(hdc3, hbmp3); SetStretchBltMode(hdc3, HALFTONE); SetBrushOrgEx(hdc3, 0, 0, NULL); StretchBlt(hdc3, 0, 0, width * fac, height * fac, hdc1, x, y, width, height, SRCCOPY); // 然后将图形图层混合进去 BLENDFUNCTION bf = { AC_SRC_OVER, 0, (BYTE)constalpha, AC_SRC_ALPHA }; GdiAlphaBlend(hdc3, 0, 0, width * fac, height * fac, hdc2, x2, y2, width * fac, height * fac, bf); // 最后将背景连同图形图层缩小 SetStretchBltMode(hdc1, HALFTONE); SetBrushOrgEx(hdc1, 0, 0, NULL); StretchBlt(hdc1, x, y, width, height, hdc3, 0, 0, width * fac, height * fac, SRCCOPY); DeleteDC(hdc3); DeleteObject(hbmp3); } </code>
绘图代码:
<code class="language-cpp"> case WM_ERASEBKGND: // 去掉系统托管的背景擦除阶段,防止闪烁 return 0; case WM_PAINT: // 窗口客户区需要更新 { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: 在此处添加使用 hdc 的任何绘图代码... // 内存位图,用来加速绘制,防止闪烁 RECT rc; GetClientRect(hWnd, &rc); HDC hdc1 = CreateCompatibleDC(hdc); HBITMAP hbmp1 = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top); SelectObject(hdc1, hbmp1); FillRect(hdc1, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); // 首先进行一些普通GDI绘图函数,作为衬底图形 SelectObject(hdc1, GetStockObject(NULL_BRUSH)); MoveToEx(hdc1, 0, 0, NULL); LineTo(hdc1, 150, 100); Ellipse(hdc1, 10, 40, 120, 80); // 创建带有Alpha通道的32位位图,作为图形图层 HDC hdc2 = CreateCompatibleDC(hdc1); HBITMAP hbmp2 = CreateBitmap(200, 200, 1, 32, NULL); SelectObject(hdc2, hbmp2); // 注意: // 只能使用GdiGradientFill函数进行绘图! // RGB值必须预乘Alpha值! TRIVERTEX tvrc[] = { { 0, 0, 0x0000, 0x0000, 0x0000, 0x0000 }, { 200, 200, 0x0000, 0x0000, 0x0000, 0x0000 }, }; GRADIENT_TRIANGLE grc[] = { { 0, 1 } }; GdiGradientFill(hdc2, tvrc, 2, grc, 1, GRADIENT_FILL_RECT_V); TRIVERTEX tvtri[] = { { 100, 0, 0xff00, 0x0000, 0x0000, 0xff00 }, { 200, 200, 0x0000, 0xff00, 0x0000, 0xff00 }, { 0, 200, 0x0000, 0x0000, 0xff00, 0xff00 }, }; GRADIENT_TRIANGLE gtri[] = { { 0, 1, 2 } }; GdiGradientFill(hdc2, tvtri, 3, gtri, 1, GRADIENT_FILL_TRIANGLE); // 进行带有HALFTONE除锯齿的AlphaBlend // 注意,必须是整数倍,否则背景会失真 GdiAlphaBlendFac(hdc1, 10, 10, 100, 100, hdc2, 0, 0, 2, 0xff); // 删除图形图层 DeleteDC(hdc2); DeleteObject(hbmp2); // 内存位图上屏 BitBlt(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hdc1, 0, 0, SRCCOPY); DeleteDC(hdc1); DeleteObject(hbmp1); EndPaint(hWnd, &ps); return 0; } </code>
最终效果:
放大:
[修改于 7年9个月前 - 2017/03/30 17:33:22]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。