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);

 

posted @ 2021-01-07 16:43  strive-sun  阅读(2253)  评论(2)    收藏  举报