사용자 설정에 따라 Aero/Glass와 사용자 정의 렌더링 프레임 (WM_NCPAINT
처리)을 번갈아 가며 창을 만들려고합니다. (Windows Vista).WM_NCPAINT 처리 Vista/Aero에서 DWM 유리 렌더링 "깨뜨림"
DwmComposition
이 사용 가능합니다. 내 응용 프로그램은 유리 프레임으로 표시되지만 사용자 정의 WM_NCPAINT
코드 경로를 설정하도록 전환 한 다음 DefWindowProc
의 WM_NCPAINT
처리를 사용하도록 전환하면 이제 원시 프레임이 "Vista 기본"스타일로 영원히 멈추게됩니다. 더 이상 반투명이 아니며 캡션 버튼이 일반적인 Aero/Glass와 다르게 보입니다.
저는 창 스타일을 변경 한 다음 SWP_FRAMECHANGED
을 보내고 창을 바꿔 가며 숨기는 등 모든 방법을 시도했지만 모든 것을 사용할 수는 없습니다. DefWindowProc
으로 연기하는 대신 유리창에 대해 WM_NCPAINT
을 처리하자마자 내 창은 영원히 "깨졌습니다".
WM_NCPAINT의 처리를 중지하고 유리가 반환 될 필요가 있음을 나타내는 것처럼 보인 MSDN (코드 도트 MSDN 도트 마이크로 소프트 도트 슬래시 크롬)에서 C#/WPF 예제를 발견했지만 작동하지 않는 것 같습니다. 내 자신의 응용 프로그램.
이 상태를 깨끗하게 재설정 할 수있는 방법이 있습니까? 내 코드는 C++에 여기에 살고 :
http://bengoodger.dreamhosters.com/software/chrome/dwm/
#include <windows.h>
#include <dwmapi.h>
static const wchar_t* kWindowClass = L"BrokenGlassWindow";
static const wchar_t* kWindowTitle =
L"BrokenGlass - Right click client area to toggle frame type.";
static const int kGlassBorderSize = 50;
static const int kNonGlassBorderSize = 40;
static bool g_glass = true;
bool IsGlass() {
BOOL composition_enabled = FALSE;
return DwmIsCompositionEnabled(&composition_enabled) == S_OK &&
composition_enabled && g_glass;
}
void SetIsGlass(bool is_glass) {
g_glass = is_glass;
}
void ToggleGlass(HWND hwnd) {
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM w_param,
LPARAM l_param) {
PAINTSTRUCT ps;
HDC hdc;
RECT wr;
HBRUSH br;
RECT* nccr = NULL;
RECT dirty;
RECT dirty_box;
MARGINS dwmm = {0};
WINDOWPOS* wp = NULL;
switch (message) {
case WM_CREATE:
SetCursor(LoadCursor(NULL, IDC_ARROW));
break;
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &wr);
br = GetSysColorBrush(IsGlass() ? COLOR_APPWORKSPACE : COLOR_WINDOW);
FillRect(hdc, &wr, br);
EndPaint(hwnd, &ps);
break;
case WM_NCPAINT:
if (IsGlass())
return DefWindowProc(hwnd, message, w_param, l_param);
GetWindowRect(hwnd, &wr);
if (!w_param|| w_param == 1) {
dirty = wr;
dirty.left = dirty.top = 0;
} else {
GetRgnBox(reinterpret_cast<HRGN>(w_param), &dirty_box);
if (!IntersectRect(&dirty, &dirty_box, &wr))
return 0;
OffsetRect(&dirty, -wr.left, -wr.top);
}
hdc = GetWindowDC(hwnd);
br = CreateSolidBrush(RGB(255,0,0));
FillRect(hdc, &dirty, br);
DeleteObject(br);
ReleaseDC(hwnd, hdc);
break;
case WM_NCACTIVATE:
// Force paint our non-client area otherwise Windows will paint its own.
RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW);
break;
case WM_NCCALCSIZE:
nccr = w_param ? &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0]
: reinterpret_cast<RECT*>(l_param);
nccr->bottom -= IsGlass() ? kGlassBorderSize : kNonGlassBorderSize;
nccr->right -= IsGlass() ? kGlassBorderSize : kNonGlassBorderSize;
nccr->left += IsGlass() ? kGlassBorderSize : kNonGlassBorderSize;
nccr->top += IsGlass() ? kGlassBorderSize : kNonGlassBorderSize;
return WVR_REDRAW;
case WM_RBUTTONDOWN:
SetIsGlass(!g_glass);
ToggleGlass(hwnd);
break;
case 0x31E: // WM_DWMCOMPOSITIONCHANGED:
ToggleGlass(hwnd);
break;
case 0xAE: // WM_NCUAHDRAWCAPTION:
case 0xAF: // WM_NCUAHDRAWFRAME:
return IsGlass() ? DefWindowProc(hwnd, message, w_param, l_param) : 0;
case WM_WINDOWPOSCHANGED:
dwmm.cxLeftWidth = kGlassBorderSize;
dwmm.cxRightWidth = kGlassBorderSize;
dwmm.cyTopHeight = kGlassBorderSize;
dwmm.cyBottomHeight = kGlassBorderSize;
DwmExtendFrameIntoClientArea(hwnd, &dwmm);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, w_param, l_param);
}
return 0;
}
ATOM RegisterClazz(HINSTANCE instance) {
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = instance;
wcex.lpszClassName = kWindowClass;
return RegisterClassEx(&wcex);
}
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int show_command) {
RegisterClazz(instance);
HWND hwnd = CreateWindow(kWindowClass, kWindowTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
instance, NULL);
ShowWindow(hwnd, show_command);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return static_cast<int>(msg.wParam);
}
달콤합니다. 나는 이것을 일찍 시도했지만, 정책 감각이 뒤 바뀌었다. 감사! –