#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <dwmapi.h> #include <unknwn.h> #include <gdiplus.h> #pragma comment( lib, "dwmapi" ) #pragma comment( lib, "gdiplus" ) namespace gdip = Gdiplus; INT_PTR CALLBACK MyDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { // Initialize GDI+ gdip::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdipToken = 0; gdip::GdiplusStartup(&gdipToken, &gdiplusStartupInput, nullptr); struct MyDialog : DLGTEMPLATE { WORD dummy[3] = { 0 }; // unused menu, class and title } dlg; dlg.style = WS_POPUP | WS_CAPTION | DS_CENTER; dlg.dwExtendedStyle = 0; dlg.cdit = 0; // no controls in template dlg.x = 0; dlg.y = 0; dlg.cx = 300; // width in dialog units dlg.cy = 200; // height in dialog units DialogBoxIndirectW(hInstance, &dlg, nullptr, MyDialogProc); gdip::GdiplusShutdown(gdipToken); return 0; } INT_PTR CALLBACK MyDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { SetWindowTextW(hDlg, L"Borderless Window with Shadow"); // This plays together with WM_NCALCSIZE. MARGINS m{ 0, 0, 0, 1 }; DwmExtendFrameIntoClientArea(hDlg, &m); // Force the system to recalculate NC area (making it send WM_NCCALCSIZE). SetWindowPos(hDlg, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); return TRUE; } case WM_NCCALCSIZE: { // Returning 0 from the message when wParam is TRUE removes the standard // frame, but keeps the window shadow. if (wParam == TRUE) { SetWindowLong(hDlg, DWL_MSGRESULT, 0); return TRUE; } return FALSE; } case WM_PAINT: { PAINTSTRUCT ps{ 0 }; HDC hdc = BeginPaint(hDlg, &ps); // Draw with GDI+ to make sure the alpha channel is opaque. gdip::Graphics gfx{ hdc }; gdip::SolidBrush brush{ gdip::Color{ 255, 255, 255 } }; gfx.FillRectangle(&brush, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); EndPaint(hDlg, &ps); return TRUE; } case WM_NCHITTEST: { // Returning HTCAPTION allows the user to move the window around by clicking // anywhere. // Depending on the mouse coordinates passed in LPARAM, you may // return other values to enable resizing. SetWindowLong(hDlg, DWL_MSGRESULT, HTCAPTION); return TRUE; } case WM_COMMAND: { WORD id = LOWORD(wParam); if (id == IDOK || id == IDCANCEL) { EndDialog(hDlg, id); return TRUE; } return FALSE; } } return FALSE; // return FALSE to let DefDialogProc handle the message }
相關文章: https://stackoverflow.com/questions/43818022/borderless-window-with-drop-shadow
github上另外一篇教程: https://github.com/melak47/BorderlessWindow
拓展:
如果想要啟用drop shadow效果,可以使用CS_DROPSHADOW樣式,子窗口不可用。
ULONG_PTR cNewStyle = GetClassLongPtr(hWnd, GCL_STYLE) | CS_DROPSHADOW; SetClassLongPtr(hWnd, GCL_STYLE, cNewStyle);