Hi! I bring good news!
I succeed in keeping FSE when making a child window with WS_OVERLAPPEDWINDOW
.
Using GetDeviceCaps
in SetWindowPos
to set full screen mode but cannot set background color of child window.
#include <Windows.h>
#include <windowsx.h>
#include <dwmapi.h>
#include"Resource.h"
#pragma comment(lib, "dwmapi.lib")
LRESULT CALLBACK WndProc2(HWND, UINT, WPARAM, LPARAM);
LRESULT hitTest(HWND hwnd, POINT cursor) {
const POINT border{
::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER),
::GetSystemMetrics(SM_CYFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)
};
RECT winRect;
if (!::GetWindowRect(hwnd, &winRect)) return HTNOWHERE;
enum region_mask {
client = 0b0000,
left = 0b0001,
right = 0b0010,
top = 0b0100,
bottom = 0b1000,
};
const auto result = left * (cursor.x < (winRect.left + border.x)) |
right * (cursor.x >= (winRect.right - border.x)) |
top * (cursor.y < (winRect.top + border.y)) |
bottom * (cursor.y >= (winRect.bottom - border.y));
switch (result) {
case left: return HTLEFT;
case right: return HTRIGHT;
case top: return HTTOP;
case bottom: return HTBOTTOM;
case top | left: return HTTOPLEFT;
case top | right: return HTTOPRIGHT;
case bottom | left: return HTBOTTOMLEFT;
case bottom | right: return HTBOTTOMRIGHT;
case client: return HTCAPTION;
default: return HTNOWHERE;
}
}
LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
switch (msg) {
case WM_NCHITTEST: {
return hitTest(hwnd, POINT{ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) });
}
case WM_CLOSE: {
::DestroyWindow(hwnd);
return 0;
}
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
}
return ::DefWindowProcW(hwnd, msg, wparam, lparam);
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
WNDCLASSEXW wcx{};
wcx.cbSize = sizeof(wcx);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.hInstance = nullptr;
wcx.lpfnWndProc = &wndProc;
wcx.lpszClassName = L"BorderlessWindowClass";
wcx.hbrBackground = CreateSolidBrush(RGB(240, 160, 160));
wcx.hCursor = ::LoadCursorW(nullptr, IDC_ARROW);
::RegisterClassExW(&wcx);
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc2;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = nullptr;
wcex.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_FULLSCREEN));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hbrBackground = CreateSolidBrush(RGB(20, 20, 160));
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FULLSCREEN);
wcex.lpszClassName = L"BorderlessWindowClass";;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
auto borderlessStyle = WS_VISIBLE;
HWND hwnd = CreateWindowExW(0, wcx.lpszClassName, L"window", borderlessStyle, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, nullptr, nullptr, nullptr, nullptr);
HWND hwnd2 = CreateWindowExW(0, wcex.lpszClassName, L"windows2", WS_CHILD| WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, hwnd, nullptr, nullptr, nullptr);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
ShowWindow(hwnd2, SW_SHOW);
UpdateWindow(hwnd2);
::SetWindowLongPtrW(hwnd, GWL_STYLE, borderlessStyle);
//static const MARGINS shadow_state{ 1,1,1,1 };
// ::DwmExtendFrameIntoClientArea(hwnd, &shadow_state);
//::SetWindowPos(hwnd, nullptr, 110, 110, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE);
SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
SetWindowLongPtr(hwnd, GWL_STYLE, WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_VISIBLE | WS_OVERLAPPED);
// I tried this too, and same problem
//SetWindowPos(hwnd, NULL, (GetDeviceCaps(GetDC(NULL), HORZRES) - W) / 2, (GetDeviceCaps(GetDC(NULL), VERTRES) - H) / 2, W, H, SWP_FRAMECHANGED | SWP_NOZORDER);
//SetWindowPos(hwnd, NULL, (GetDeviceCaps(GetDC(NULL), HORZRES) - 100) / 2, (GetDeviceCaps(GetDC(NULL), VERTRES) - 100) / 2, 400, 400, NULL);
SetWindowPos(hwnd, NULL, 0, 0, GetDeviceCaps(GetDC(NULL), HORZRES), GetDeviceCaps(GetDC(NULL), VERTRES), NULL);
MSG msg;
while (::GetMessageW(&msg, nullptr, 0, 0) == TRUE) {
::TranslateMessage(&msg);
::DispatchMessageW(&msg);
}
}
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Here is the effect: