问题描述
我使用扩展框架来渲染自定义标题和窗口边框。
<!DOCTYPE html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script>
L_NO_TOUCH = false;
L_DISABLE_3D = false;
</script>
<script src="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css"/>
<link rel="stylesheet" href="https://rawcdn.githack.com/python-visualization/folium/master/folium/templates/leaflet.awesome.rotate.css"/>
<style>html,body {width: 100%;height: 100%;margin: 0;padding: 0;}</style>
<style>#map {position:absolute;top:0;bottom:0;right:0;left:0;}</style>
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<style>
#map_c3b171654ca34f70ae3e417bb5685916 {
position: relative;
width: 100.0%;
height: 100.0%;
left: 0.0%;
top: 0.0%;
}
</style>
<style>
.leaflet-image-layer {
/* old android/safari*/
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges; /* safari */
image-rendering: pixelated; /* chrome */
image-rendering: -moz-crisp-edges; /* firefox */
image-rendering: -o-crisp-edges; /* opera */
-ms-interpolation-mode: nearest-neighbor; /* ie */
}
</style>
</head>
<body>
<div class="folium-map" id="map_c3b171654ca34f70ae3e417bb5685916" ></div>
</body>
<script>
var map_c3b171654ca34f70ae3e417bb5685916 = L.map(
"map_c3b171654ca34f70ae3e417bb5685916",{
center: [37.510284,15.092042],crs: L.CRS.EPSG3857,zoom: 8,zoomControl: true,preferCanvas: false,}
);
var tile_layer_422d20328f5a49e8891a1a5863d4c7f4 = L.tileLayer(
"https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png",{"attribution": "\u0026copy; \u003ca href=\"http://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors \u0026copy; \u003ca href=\"http://cartodb.com/attributions\"\u003eCartoDB\u003c/a\u003e,CartoDB \u003ca href =\"http://cartodb.com/attributions\"\u003eattributions\u003c/a\u003e","detectRetina": false,"maxNativeZoom": 18,"maxZoom": 18,"minZoom": 0,"noWrap": false,"opacity": 1,"subdomains": "abc","tms": false}
).addTo(map_c3b171654ca34f70ae3e417bb5685916);
var image_overlay_38ae38a401d9460fad332f027ec64fd4 = L.imageOverlay(
"data:image/png;base64,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",[[35.493948101997375,11.891264481977984],[38.849444372313364,15.684762434525926]],{}
).addTo(map_c3b171654ca34f70ae3e417bb5685916);
</script>
<!-- begin snippet: js hide: false console: false babel: false -->
我还使用分层窗口使背景透明。我的 COLORKEY 是 RGB(0,0)
hr = DwmExtendFrameIntoClientArea(hWnd,&margins);
我使用分层窗口的原因是,我想使窗口的底部边框的角变圆。
问题是我想做些漂亮的事情,我试图用GDI在客户区域中绘制一个“抗锯齿”窗口边框。但是,它可以在带有已绘背景(纯色)的情况下用作“抗锯齿”,而不能在“透明”背景下使用。
该如何解决?
如果尝试,请使用VS调试器,因为我没有放置功能窗口按钮。
SetLayeredWindowAttributes(hWnd,RGB(0,0),255,LWA_COLORKEY);
解决方法
好吧,在寻找解决方案之后,我想我终于找到了答案。
解决方案: 解决锯齿问题的一种解决方案是捕获整个窗口的背景,方法是从捕获中排除。此时,由于使用位图绘制背景,因此不需要分层窗口。 HDC将能够将其与背景混合。希望Windows 10 2004版本中有一个名为:
WDA_EXCLUDEFROMCAPTURE
用法:
SetWindowDisplayAffinity(hWnd,WDA_EXCLUDEFROMCAPTURE); //在创建时
来源: https://blogs.windows.com/windowsdeveloper/2019/09/16/new-ways-to-do-screen-capture/
之后,您可以使用位图绘制背景,然后在其上绘制所有内容。但是,这导致性能低下,我没有受益。尽管如此,在绘制时它仍然可以工作并产生反别名外观。对于性能问题,Direct2D可用于从返回的位图进行绘制。
示例:
int DsktpBkSS(HWND hWnd) {
HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
RECT windowPos;
SetWindowDisplayAffinity(hWnd,WDA_EXCLUDEFROMCAPTURE);
GetWindowRect(hWnd,&windowPos);
// Retrieve the handle to a display device context for the client
// area of the window.
hdcScreen = GetDC(NULL);
hdcWindow = GetDC(hWnd);
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
if (!hdcMemDC)
{
MessageBox(hWnd,L"CreateCompatibleDC has failed",L"Failed",MB_OK);
}
// Get the client area for size calculation
RECT rcClient;
GetClientRect(hWnd,&rcClient);
//This is the best stretch mode
SetStretchBltMode(hdcWindow,HALFTONE);
//The source DC is the entire screen and the destination DC is the current window (HWND)
if (!StretchBlt(hdcWindow,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),hdcScreen,windowPos.left+1,windowPos.top,SRCCOPY))
{
MessageBox(hWnd,L"StretchBlt has failed",MB_OK);
}
// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcWindow,rcClient.right - rcClient.left,rcClient.bottom - rcClient.top);
if (!hbmScreen)
{
MessageBox(hWnd,L"CreateCompatibleBitmap Failed",MB_OK);
}
// Select the compatible bitmap into the compatible memory DC.
if(hdcMemDC && hbmScreen){
SelectObject(hdcMemDC,hbmScreen);
}
// Bit block transfer into our compatible memory DC.
if(hdcMemDC)
if (!BitBlt(hdcMemDC,rcClient.bottom - rcClient.top,hdcWindow,L"BitBlt has failed",MB_OK);
}
// Get the BITMAP from the HBITMAP
if(hbmScreen)
GetObjectW(hbmScreen,sizeof(BITMAP),&bmpScreen);
if (hbmScreen)DeleteObject(hbmScreen);
if (hdcMemDC)DeleteObject(hdcMemDC);
ReleaseDC(NULL,hdcScreen);
ReleaseDC(hWnd,hdcWindow);
return 0;
}
稍后
(...){
if(message==WM_PAINT)
{
PAINTSTRUCT ps;
BeginPaint(hWnd,&ps);
Graphics graphics(ps.hdc);
/*SET SMOOTHING (AA)*/
graphics.SetSmoothingMode(SmoothingMode::SmoothingModeHighQuality);
if(DsktpBkSS(hWnd))
{
/*DRAW ROUNDED RECTANGLE*/
}
}
//...
};
对于使用“ 桌面窗口管理器”绘制的窗口,从左到右连续调整大小时,另一重要事项是一段时间后会产生“ 闪烁”。在Microsoft文档上,建议使用 StretchBlt(...)进行绘图,因为GDI +会导致这种情况。
为DWM提到的闪烁:https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-stretchblt
”使用BitBlt或StretchBlt函数代替Windows GDI +进行演示 您的绘图进行渲染。 GDI +一次渲染一条扫描线 软件渲染。这可能会导致应用程序闪烁。”