win32 - 创建带有标准阴影的无边框窗口
这个框框好像删不掉,就先放这边吧。。。
#define WIN32_LEAN_AND_MEAN #include <unknwn.h> #include <windows.h> #include <dwmapi.h> #include <gdiplus.h> #include <objidl.h> using namespace Gdiplus; #pragma comment(lib, "dwmapi.lib") #pragma comment(lib, "gdiplus.lib") 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+ Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdipToken = 0; Gdiplus::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); Gdiplus::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. Gdiplus::Graphics gfx{hdc}; Gdiplus::SolidBrush brush{Gdiplus::Color{255, 255, 255}}; int x = ps.rcPaint.left; int y = ps.rcPaint.top; int width = ps.rcPaint.right - ps.rcPaint.left; int height = ps.rcPaint.bottom - ps.rcPaint.top; gfx.FillRectangle(&brush, x, y, width, height); 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 }
结果:
相关文章: Borderless Window with Drop Shadow
github上另外一篇教程: https://github.com/melak47/BorderlessWindow#borderlesswindow
拓展:
如果想要启用drop shadow效果,可以使用CS_DROPSHADOW样式,子窗口不可用。
ULONG_PTR cNewStyle = GetClassLongPtr(hWnd, GCL_STYLE) | CS_DROPSHADOW; SetClassLongPtr(hWnd, GCL_STYLE, cNewStyle);