win32

#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);
原文地址:https://www.cnblogs.com/strive-sun/p/14247220.html