用SDK API 封装 一个窗口类(无边框、透明)

 效果如图。

#ifndef __Fagex_CEGui_W32_H__
#define __Fagex_CEGui_W32_H__

#ifndef WIN32_LEAN_AND_MEAN
#    define  WIN32_LEAN_AND_MEAN
#    include <windows.h>
#endif   // WIN32_LEAN_AND_MEAN

#include  <string>
#include  <map>
#include  <vector>

namespace  Fagex
{
    // from "size_t" to DWORD
    #   pragma warning(disable: 4267)

    //warning C4312: “类型转换”: 从“DWORD”转换到更大的“HBRUSH”
    #   pragma warning(disable: 4311)

    //warning C4311: “类型转换”: 从“HBRUSH”到“LONG”的指针截断
    #   pragma warning(disable: 4312)

    typedef std::string String;
} //namespace  Fagex

#endif   //__Fagex_CEGui_W32_H__

#ifndef __Fagex_CEGui_Window_H__
#define __Fagex_CEGui_Window_H__

#include  " FagexStdHreaders.h "

 namespace  Fagex
 {
    class Point
    {
    public:
        Point(int a, int b) : x(a), y(b) {};
        int x, y;
    };

    class Line
    {
    public:
        Line(const Point &p1, const Point &p2) : from(p1.x, p1.y), to(p2.x, p2.y) {};
        Point from, to;
    };

    class CEGuiWindow
    {
    public:
        //SetWindowLong  SetLayeredWindowAttributes
        #define   WS_EX_LAYERED                       0x00080000   
        #define   LWA_COLORKEY                        0x00000001   
        #define   LWA_ALPHA                           0x00000002 

        typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
        lpfnSetLayeredWindowAttributes SetLayeredWindowAttributes;
    
        typedef LRESULT (CEGuiWindow::*pCEGuiWindowFunction)(WPARAM, LPARAM) ;
        
        typedef struct tagMSGMAP_ENTRY
        {
            //UINT nMessage;                        // windows message
            pCEGuiWindowFunction pfn;            // routine to call (or special value)
        }MSGMAP_ENTRY;

        typedef std::map<UINT,MSGMAP_ENTRY> MessageEntries;
        typedef std::vector<Line> LineVector;

    public:
        CEGuiWindow(HINSTANCE hInstance);
        virtual ~CEGuiWindow();

        int createWindow(const String& windowName = "window", HWND hWndParent = 0, int x = 100,int y = 100, int nWidth = 300, int nHeight = 300);
        void setText(const String& title, const String& content, bool isUpdate = true);
        virtual bool showWindow(int nCmdShow = 1);
        bool showWindowAlapa(int nFrom, int to);
        void setBkColour(COLORREF color);
        void zoomWindow(const RECT &rect);
        RECT            mRect;

    protected:
        HWND                mhWnd;
        String                mWindowName;
        HINSTANCE            mhInstance;
        MessageEntries        mMessageEntries;
        String                mTitle;
        String                mContent;
        COLORREF            mBKColor;
        
    protected:
        LRESULT OnWmKeyUp(WPARAM wParam,LPARAM lParam);    //WM_PARINT
        LRESULT OnWmNchittest(WPARAM wParam,LPARAM lParam); //WM_NCHITTEST
        LRESULT OnWmDestroy(WPARAM wParam,LPARAM lParam);    //WM_DESTROY
        LRESULT OnWmPaint(WPARAM wParam,LPARAM lParam);    //WM_PAINT

    protected:
        virtual bool initializeWindow();
        virtual bool drawWindow();
        virtual bool drawTitleContent();

        static LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
        LRESULT DefWndProc(UINT msg,WPARAM wParam,LPARAM lParam);
    };
}
 #endif   // __Fagex_CEGui_Window_H__

 

// //FagexCEGuiWindow.cpp-----------------------------------------------

#include  " FagexCEGuiWindow.h "

namespace  Fagex
{
    CEGuiWindow::CEGuiWindow(HINSTANCE hInstance) : mhInstance(hInstance), mhWnd( 0 ), mBKColor(RGB( 255 , 255 , 255 ))
    {
        HMODULE hUser32  =  GetModuleHandle(TEXT( " USER32.DLL " ));   
        SetLayeredWindowAttributes  =  (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,  " SetLayeredWindowAttributes " );
    }

     // ----------------------------------------------------------------------------------------------------------------------
    CEGuiWindow:: ~ CEGuiWindow()
    {
        OnWmDestroy( 0 , 0 );

        HBRUSH hb  =  (HBRUSH)GetClassLong(mhWnd,GCL_HBRBACKGROUND);
        UnregisterClass(mWindowName.c_str(),mhInstance);
        DeleteObject(hb);
    }

     // ----------------------------------------------------------------------------------------------------------------------
     int  CEGuiWindow::createWindow( const  String &  winName, HWND hWndParent,  int  x,  int  y,  int  nWidth,  int  nHeight)
    {
        WNDCLASSEX wndclass;
        wndclass.cbSize  =   sizeof (wndclass);
        wndclass.style  =  CS_HREDRAW  |  CS_VREDRAW  |  CS_OWNDC;
        wndclass.lpfnWndProc  =  CEGuiWindow::WndProc;
        wndclass.cbClsExtra  =   0 ;
        wndclass.cbWndExtra  =   0 ;
        wndclass.hIcon  =  LoadIcon(NULL,IDI_APPLICATION);
        wndclass.hCursor  =  LoadCursor(NULL,IDC_ARROW);
        wndclass.hbrBackground  =  (HBRUSH)CreateSolidBrush(mBKColor);
        wndclass.hInstance  =  mhInstance;
        wndclass.lpszClassName  =  winName.c_str();
        wndclass.lpszMenuName  =  NULL;
        wndclass.hIconSm  =  NULL;

        RegisterClassEx( & wndclass);
        mhWnd  =  CreateWindowEx( 0 ,
            winName.c_str(),
            winName.c_str(),
            WS_POPUP  |  WS_EX_CLIENTEDGE,
            x,
            y,
            nWidth,
            nHeight,
            hWndParent,
             0 ,
            mhInstance,
             this );

        mWindowName  =  winName;

         if (mhWnd  ==  NULL) 
        { 
             return   - 1 ;
        }

        SetWindowLong(mhWnd,GWL_EXSTYLE, GetWindowLong(mhWnd,GWL_EXSTYLE) | WS_EX_LAYERED);
        SetLayeredWindowAttributes(mhWnd,NULL, 255 ,LWA_ALPHA);

         return   1 ;
    }

     // ----------------------------------------------------------------------------------------------------------------------
    LRESULT CALLBACK CEGuiWindow::WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
         if  (msg  ==  WM_CREATE)
        {     //  Store pointer to Win32Window in user data area
            SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(((LPCREATESTRUCT)lParam) -> lpCreateParams));
             return   0 ;
        }

        CEGuiWindow *  win  =  (CEGuiWindow * )GetWindowLongPtr(hWnd, GWLP_USERDATA);
         if  ( ! win)
             return  DefWindowProc(hWnd, msg, wParam, lParam);

         return  win -> DefWndProc(msg,wParam,lParam);
    }

     // ----------------------------------------------------------------------------------------------------------------------
    LRESULT CEGuiWindow::DefWndProc(UINT msg, WPARAM wParam,LPARAM lParam)
    {
        CEGuiWindow::MessageEntries::iterator it  =  mMessageEntries.find(msg);
         if (it  !=  mMessageEntries.end())
        {
            LRESULT ret  =  ( this ->* it -> second.pfn)(wParam,lParam);
             if (ret)  return  ret;
        }
         return  DefWindowProc(mhWnd, msg, wParam, lParam);
    }

     // ----------------------------------------------------------------------------------------------------------------------
     bool  CEGuiWindow::initializeWindow()
    {
        MSGMAP_ENTRY m;
        m.pfn  =   & CEGuiWindow::OnWmNchittest;
        mMessageEntries[WM_NCHITTEST]     =  m;

        m.pfn  =   & CEGuiWindow::OnWmDestroy;
        mMessageEntries[WM_DESTROY]       =  m;

        m.pfn  =   & CEGuiWindow::OnWmKeyUp;
        mMessageEntries[WM_KEYUP]         =  m;

        m.pfn  =   & CEGuiWindow::OnWmPaint;
        mMessageEntries[WM_PAINT]         =  m;

         return   true ;
    }

     // ----------------------------------------------------------------------------------------------------------------------
     bool  CEGuiWindow::showWindow( int  nCmdShow)
    {
        initializeWindow();

        ShowWindow(mhWnd,nCmdShow);
        UpdateWindow(mhWnd);

        RECT rect;
        GetWindowRect(mhWnd, & rect);
        mRect  =  rect;

         return   true ;
    }

     // ----------------------------------------------------------------------------------------------------------------------
    LRESULT CEGuiWindow::OnWmNchittest(WPARAM wParam,LPARAM lParam)
    {
        LRESULT nHitTest  =  DefWindowProc(mhWnd, WM_NCHITTEST, wParam, lParam);
         // 如果鼠标左键按下, GetAsyncKeyState 的返回值小于0
         if (nHitTest  ==  HTCLIENT  &&  GetAsyncKeyState(MK_LBUTTON)  <   0 )
        {
            nHitTest  =  HTCAPTION;
        }
         return  nHitTest;
    }

     // ----------------------------------------------------------------------------------------------------------------------
    LRESULT CEGuiWindow::OnWmDestroy(WPARAM wParam,LPARAM lParam)
    {
        DestroyWindow(mhWnd);
        PostQuitMessage( 0 );
         return   0 ;
    }

     // ----------------------------------------------------------------------------------------------------------------------
    LRESULT CEGuiWindow::OnWmPaint(WPARAM wParam,LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc  =  BeginPaint(mhWnd, & ps);
        EndPaint(mhWnd, & ps);

        drawTitleContent();
        drawWindow();

         // static int i = 0;
         // i++;
         // char sz[50];
         // ZeroMemory(sz,50);
         // sprintf(sz,"The tick is : %d",i);
         // setText(sz,mContent,false);
         return   1 ;
         // return DefDlgProc(mhWnd,WM_PAINT,wParam,lParam);
    }

     // ----------------------------------------------------------------------------------------------------------------------
    LRESULT CEGuiWindow::OnWmKeyUp(WPARAM wParam,LPARAM lParam)
    {
         switch (wParam)
        {
         case  VK_ESCAPE:
            PostQuitMessage( 0 );
             return   true ;

         case   ' Q ' :
            showWindowAlapa( 255 , 0 );
            PostMessage(mhWnd,WM_DESTROY, 0 , 0 );
             return   true ;;
        }
         return   false ;
    }

     // ----------------------------------------------------------------------------------------------------------------------
     bool  CEGuiWindow::showWindowAlapa( int  nFrom,  int  to)
    {
         for ( int  i  =   0 ; i  <   20 ;  ++ i)
        {
            SetLayeredWindowAttributes(mhWnd, NULL, nFrom  +  (to  -  nFrom)  /   20   *  i, LWA_ALPHA);
        }
        SetLayeredWindowAttributes(mhWnd, NULL, to, LWA_ALPHA);
         return   true ;
    }

     // -----------------------------------------------------------------------------------------------------------------------
     void  CEGuiWindow::setBkColour(COLORREF color)
    {
        mBKColor  =  color;
        HBRUSH hb  =  (HBRUSH)SetClassLong(mhWnd, GCL_HBRBACKGROUND, (LONG)(HBRUSH)CreateSolidBrush(mBKColor));
        DeleteObject(hb);
        InvalidateRect(mhWnd, NULL, TRUE);
    }

     // ----------------------------------------------------------------------------------------------------------------------
     void  CEGuiWindow::setText( const  String  & title,  const  String &  content,  bool  isUpdate)
    {
        mTitle  =  title;
        mContent  =  content;

         if (isUpdate)
            InvalidateRect(mhWnd,NULL,TRUE);
    }

     // ----------------------------------------------------------------------------------------------------------------------
     bool  CEGuiWindow::drawWindow()
    {
        RECT rect, rectTmp;
        GetClientRect(mhWnd, & rect);

        rectTmp  =  rect;
         int  x  =  rectTmp.left  +   20 ;
         int  y  =  rectTmp.top  +    20   +   20  ;

         int  cx  =  rectTmp.right  -   20 ;
         int  cy  =  y;

        HDC hdc  =  GetDC(mhWnd);

        LOGBRUSH lb;
        lb.lbStyle  =  BS_SOLID; 
        lb.lbColor  =  RGB( 255 , 0 , 0 ); 
        lb.lbHatch  =   0 ; 

        HPEN hPen  =  ExtCreatePen(PS_COSMETIC  |  PS_SOLID,  1 ,  & lb,  0 , NULL); 
        HPEN hOldPen  =  (HPEN)SelectObject(hdc, hPen); 

        LineVector lines;
        lines.push_back(Line(Point(x,y),Point(cx,cy)));
        lines.push_back(Line(Point(rect.left,rect.top),Point(rect.right,rect.top)));
        lines.push_back(Line(Point(rect.right  -   1 , rect.top),Point(rect.right  -   1 , rect.bottom)));
        lines.push_back(Line(Point(rect.right, rect.bottom  -   1 ),Point(rect.left, rect.bottom  -   1 )));
        lines.push_back(Line(Point(rect.left, rect.bottom),Point(rect.left, rect.top)));

         for (LineVector::iterator it  =  lines.begin(); it  !=  lines.end();  ++ it)
        {
            MoveToEx(hdc, it -> from.x , it -> from.y, NULL); 
            LineTo(hdc, it -> to.x , it -> to.y);
        }

        SelectObject(hdc, hOldPen); 
        DeleteObject(hPen); 

        ReleaseDC(mhWnd,hdc);
         return   true ;
    }

     // ----------------------------------------------------------------------------------------------------------------------
     bool  CEGuiWindow::drawTitleContent()
    {
        RECT rect, rectTmp;
        GetClientRect(mhWnd, & rect);

        rectTmp  =  rect;
        HDC hdc  =  GetDC(mhWnd);

        SetTextColor(hdc,RGB( 255 , 255 , 0 ));
        SetBkMode(hdc,TRANSPARENT);

         if ( ! mTitle.empty())
        {
            rectTmp.left  =  rect.left  +   20 ;
            rectTmp.top  =   rect.top  +    20 ;
            rectTmp.right  =  rect.right  -   20 ;                                                                                                                                                                                                                                                                                                                                                                                                                              
            rectTmp.bottom  =  rectTmp.top  +   20 ;
            DrawText(hdc,mTitle.c_str(),( int )mTitle.length(), & rectTmp, DT_LEFT  |  DT_END_ELLIPSIS);  // 标题
        }

        LOGFONT lf;
        ZeroMemory( & lf,  sizeof (LOGFONT));
        lf.lfHeight  =   14 ;
        lstrcpy(lf.lfFaceName, TEXT( " Arial " ));

        HFONT hfont  =  CreateFontIndirect( & lf);
        HFONT hOldFont  =  (HFONT)SelectObject(hdc, hfont);
         // 内容
         if ( ! mContent.empty())
        {
            rectTmp.left  =  rect.left  +   20 ;
            rectTmp.top  =   rect.top  +   20   +   30 ;
            rectTmp.right  =  rect.right  -   20 ;                                                                                                                                                                                                                                                                                                                                                                                                                              
            rectTmp.bottom  =  rect.bottom  -   20 ;
             int  height  =  DrawText(hdc,mContent.c_str(),( int )mContent.length(), & rectTmp, DT_LEFT  |  DT_WORDBREAK  |  DT_END_ELLIPSIS); 

            rect.bottom  =  rectTmp.top  +  height  +   20 ;
            zoomWindow(rect);
        }

        SelectObject(hdc,hOldFont);
        DeleteObject(hfont);

        ReleaseDC(mhWnd,hdc);
         return   true ;
    }

     // ----------------------------------------------------------------------------------------------------------------------
     void  CEGuiWindow::zoomWindow( const  RECT  & rect)
    {
        RECT rc;
        GetWindowRect(mhWnd, & rc);

         if (rect.right  -  rect.left  !=  rc.right  -  rc.left  ||  rect.bottom  -  rect.top  !=  rc.bottom  -  rc.top)
            MoveWindow(mhWnd, rc.left, rc.top, rect.right  -  rect.left, rect.bottom  -  rect.top, TRUE);
    }
}
 

//使用方式(对于指针,当然别忘了析构):

     pWindow  =   new  Fagex::CEGuiWindow(AfxGetInstanceHandle());
    pWindow -> createWindow( " 1 " , this -> m_hWnd);
    pWindow -> showWindow();

    pWindow -> setBkColour(RGB( 0 , 40 , 0 ));
    pWindow -> showWindowAlapa( 0 , 200 );
    pWindow -> setText( " 你好这是标题 " , " hello world, 这里是演示内容! " );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值