如何创建没有边框的窗口和像github app一样的阴影?

时间:2014-03-04 07:13:00

标签: winapi

如何创建没有边框的窗口,但它的行为与边框相似。像git-hub应用程序窗口,它也有阴影效果。如何创建这样的窗口。
谢谢。使用win 32 c ++。

我曾尝试过处理wm_Ncpaint调用,但没有用。

        #include "stdafx.h"
        #include "CustomWindow.h"

        LONG_PTR g_lpCustomWindowptr = NULL;
        BOOL g_bStateofWindow = TRUE;

        // creating window 
        CreateWindowEx(WS_EX_ACCEPTFILES,
                       szWindowClass,
                       szTitle,
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL,
                       NULL, hInstance, NULL);

        void CustomWindow::CreateCustomWindow(HWND hwnd)
        {
            // To set border and handling Doc with default cases
            LONG_PTR lpStyle = GetWindowLongPtr(hwnd, GWL_STYLE);

            lpStyle &= ~(WS_CAPTION | WS_ACTIVECAPTION );

            //lpStyle |= WS_THICKFRAME;

            SetWindowLongPtr(hwnd, GWL_STYLE, lpStyle);

            //set the customized proc.
            g_lpCustomWindowptr = SetWindowLongPtr(hwnd,
                GWLP_WNDPROC,
                (LONG_PTR)CustonWindow_WndProc);
        }

        LRESULT CALLBACK CustomWindow::CustonWindow_WndProc(IN HWND hwnd, 
                                                            IN UINT message, 
                                                            IN WPARAM wParam, 
                                                            IN LPARAM lParam)
        {
            switch (message)
            {
            case WM_SIZE:   
                {           
                    if (SIZE_MAXIMIZED == wParam)
                    {           
                        HMONITOR hmon= MonitorFromWindow(hwnd, 
                            MONITOR_DEFAULTTONEAREST);

                        MONITORINFO moninfo = {0};

                        moninfo.cbSize= sizeof(moninfo);

                        GetMonitorInfo(hmon, &moninfo);

                        SetWindowPos(hwnd,
                            HWND_TOP, 
                            moninfo.rcWork.left,            
                            moninfo.rcWork.top,
                            moninfo.rcWork.right,
                            moninfo.rcWork.bottom, 
                            SWP_FRAMECHANGED | 
                            SWP_NOREDRAW);
                    }
                }
                break;
            case WM_NCACTIVATE :
                {
                    if (TRUE == wParam)
                    {

                        SendMessage(hwnd,WM_NCPAINT,wParam,0);

                    }
                    else if(FALSE == wParam )
                    {
                        SendMessage(hwnd,WM_NCPAINT,wParam,0);

                    }
                    return true;
                }
            case WM_NCCALCSIZE:
                {   
                    return 0;
                }
                break;

            case  WM_NCPAINT:
                {
                    HDC hDC;

                    hDC = GetWindowDC(hwnd);

                    HPEN hPen = CreatePen(PS_SOLID, 5, RGB(0,0,255));; 

                    SelectObject(hDC, hPen);

                    RECT rcClientRect = {0};

                    GetClientRect(hwnd,&rcClientRect);

                    if(FALSE == wParam)
                    {
                        MoveToEx(hDC,rcClientRect.left,rcClientRect.top,NULL);

                        LineTo(hDC,rcClientRect.right - 1,rcClientRect.top );

                        LineTo(hDC,rcClientRect.right - 1,rcClientRect.bottom - 1 );

                        LineTo(hDC,rcClientRect.left,rcClientRect.bottom - 1);

                        LineTo(hDC,rcClientRect.left,rcClientRect.top);
                    }
                    else
                    {
                        HPEN hPen1 = CreatePen(PS_SOLID, 5, RGB(255,0,0));; 

                        SelectObject(hDC, hPen1);

                        MoveToEx(hDC,rcClientRect.left,rcClientRect.top,NULL);

                        LineTo(hDC,rcClientRect.right - 1,rcClientRect.top );

                        LineTo(hDC,rcClientRect.right - 1,rcClientRect.bottom - 1 );

                        LineTo(hDC,rcClientRect.left,rcClientRect.bottom - 1);

                        LineTo(hDC,rcClientRect.left,rcClientRect.top);
                    }
                    ReleaseDC(hwnd, hDC);
                }               


            }
            break;




        }
        return  CallWindowProc((WNDPROC)g_lpCustomWindowptr,
                               hwnd, 
                               message, 
                               wParam, 
                               lParam);
        }

1 个答案:

答案 0 :(得分:2)

要创建没有边框,系统菜单和标题栏的窗口,但使用Aero阴影,您需要执行以下操作:

  1. 使用WS_CAPTION样式
  2. 创建窗口
  3. 调用DwmExtendFrameIntoClientArea WDM API传递1像素上边距
  4. 处理WM_NCCALCSIZE消息,请勿在处理此消息时将呼叫转发至DefWindowProc,但只需返回0
  5. 这是一个使用Delphi编写的干净Windows API创建此类窗口的简单示例:

    program BorderlessWindow;
    
    uses
      DwmApi,
      Winapi.UxTheme,
      Windows, SysUtils, Messages;
    
    {$R *.res}
    
    var
      Msg        : TMSG;
      LWndClass  : TWndClass;
      hMainHandle: HWND;
      lMargins: TMargins;
    
    procedure ReleaseResources;
    begin
      PostQuitMessage(0);
    end;
    
    function WindowProc(hWnd,Msg:Longint; wParam : WPARAM; lParam: LPARAM):Longint; stdcall;
    begin
      case Msg of
          WM_DESTROY: ReleaseResources;
          WM_NCHITTEST: Exit(HTCAPTION);  // This is needed only to move window with mouse
          WM_NCCALCSIZE: Exit(0); // This line will hide default window border and caption
      end;
      Result:=DefWindowProc(hWnd,Msg,wParam,lParam);
    end;
    
    begin
      //create the window
      LWndClass.hInstance := hInstance;
      with LWndClass do
        begin
          lpszClassName := 'MyWinApiWnd';
          Style         := 0;//CS_PARENTDC or CS_BYTEALIGNCLIENT;
          hIcon         := LoadIcon(hInstance,'MAINICON');
          lpfnWndProc   := @WindowProc;
          hbrBackground := COLOR_BTNFACE+1;
          hCursor       := LoadCursor(0,IDC_ARROW);
        end;
    
      RegisterClass(LWndClass);
      hMainHandle := CreateWindow(LWndClass.lpszClassName,nil,
            WS_CAPTION or WS_VISIBLE,
            (GetSystemMetrics(SM_CXSCREEN) div 2)-190,
            (GetSystemMetrics(SM_CYSCREEN) div 2)-170, 386,200,0,0,hInstance,nil);
    
      if DwmCompositionEnabled then
      begin
        // This API call adds aero shadow
        lMargins.cyTopHeight := 1;
        DwmExtendFrameIntoClientArea(hMainHandle, lMargins);
      end;
    
      //message loop
      while GetMessage(Msg,0,0,0) do
      begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;
    end.