欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

UpdateLayeredWindow實(shí)現(xiàn)任意異形窗口使用詳解

 更新時(shí)間:2022年09月01日 11:41:01   作者:DoubleLi  
這篇文章主要為大家介紹了UpdateLayeredWindow實(shí)現(xiàn)任意異形窗口使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

前面提到,我們可以用SetWindowRgn或SetLayeredWindowAttributes實(shí)現(xiàn)不規(guī)則以及半透明的效果

對(duì)于SetWindowRgn,它通過(guò)一個(gè)Rgn來(lái)設(shè)置區(qū)域,這個(gè)Rgn一般可以從圖片中讀取,在這張圖片中,將不需要顯示的區(qū)域標(biāo)記為一種特殊的顏色,這里有個(gè)問(wèn)題,必須保證這種顏色沒(méi)有被正常的區(qū)域使用,否則會(huì)被誤傷。

為了解決這個(gè)問(wèn)題,可以考慮用兩張圖片,增加一張單色的掩碼圖,這種方案帶來(lái)了額外的管理開銷。SetWindowRgn的好處是效率較高,對(duì)于大部分自繪的皮膚,一般只有四個(gè)角落有一些不規(guī)則,所以用SetWindowRgn是最好的選擇。

  • SetLayeredWindowAttributes可以將特定的窗口設(shè)置為某種透明度,也可以用它來(lái)過(guò)濾某種顏色,匹配的顏色會(huì)變成全透明。也就是類似于SetWindowRgn的效果。
  • SetLayeredWindowAttributes直接從DC中獲得顏色,所以你需要事先繪制DC。
  • SetLayeredWindowAttributes過(guò)濾顏色后,相關(guān)區(qū)域雖然不可見(jiàn),但是不可見(jiàn)的區(qū)域可以放置子窗口,這點(diǎn)和SetWindowRgn有所區(qū)別。此外若子窗口刷新不及時(shí)或其他原因,那么父窗口因?yàn)镾etLayeredWindowAttributes被隱藏的DC顏色將被浮出水面。
  • UpdateLayeredWindow直接根據(jù)DC中的Alpha通道來(lái)實(shí)現(xiàn)透明效果,它很好的處理了和背景的Alpha Blend的問(wèn)題,所以完美的解決了SetWindowRgn的鋸齒問(wèn)題。

Sample

    template<typename T,bool DLG>
    class ImageFrameT{
    public:
        BEGIN_MSG_MAP(ImageFrameT)
            MESSAGE_HANDLER(WM_CREATE, OnCreate)
            MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
            MESSAGE_HANDLER(WM_PAINT, OnPaint)
            MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
            MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLBttonDown)
        END_MSG_MAP()
        ImageFrameT():m_res_(NULL),m_move_flag_(false){}
        virtual ~ImageFrameT(){}
        LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled){
            bHandled = FALSE;
            // 通過(guò)參數(shù)獲得資源句柄
            LPCREATESTRUCT lpCreateStruct = (LPCREATESTRUCT)lParam;
            if(lpCreateStruct && lpCreateStruct->lpCreateParams)
                m_res_ = (CImage*)(lpCreateStruct->lpCreateParams);
            ATLASSERT(m_res_);
            if(!DLG)
                this->InitSelf();
            return 0;
        }
        LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled){
            bHandled = FALSE;
            if(lParam){
                // 通過(guò)參數(shù)獲得資源句柄
                m_res_ = (CImage*)lParam;
            }
            if(DLG)
                this->InitSelf();
            return 0;
        }
        LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
            // OnPaint不作任何事,轉(zhuǎn)到UpdateLayeredWindow處理
            T* pT = static_cast<T*>(this);
            CPaintDC dc_(pT->m_hWnd);
            return TRUE;
        }
        LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
            // 屏蔽背景繪制
            return TRUE;
        }
        LRESULT OnLBttonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled){
            // 是否支持整窗口拖動(dòng)
            T* pT = static_cast<T*>(this);
            if(this->m_move_flag_)
                pT->PostMessage(WM_SYSCOMMAND,0xF012,0);
            else
                bHandled = FALSE;
            return 0;
        }
        void            SetRes(CImage* res){
            // 設(shè)置資源
            ATLASSERT(res);
            if(res)
                this->m_res_ = res;
        }
        void            SetMoveFlag(bool flag){
            // 設(shè)置是否可拖動(dòng)
            this->m_move_flag_ = flag;
        }
    private:
        void            InitSelf(){
            ATLASSERT(m_res_);
            if(m_res_){
                T* pT = static_cast<T*>(this);
                // 設(shè)置屬性WS_EX_LAYERED
                LONG lWindowLong = ::GetWindowLong(pT->m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED;
                ::SetWindowLong(pT->m_hWnd, GWL_EXSTYLE, lWindowLong);
                // 設(shè)置屬性WS_POPUP
                lWindowLong = ::GetWindowLong(pT->m_hWnd, GWL_STYLE) | WS_POPUP;
                // 去掉一堆其他屬性
                lWindowLong &= ~WS_CHILD;
                lWindowLong &= ~WS_BORDER;
                lWindowLong &= ~WS_CAPTION;
                lWindowLong &= ~WS_SYSMENU;
                ::SetWindowLong(pT->m_hWnd, GWL_STYLE, lWindowLong);
                pT->SetWindowPos(HWND_BOTTOM,0,0,
                        m_res_->GetWidth(),m_res_->GetHeight(),
                        SWP_NOMOVE | SWP_NOOWNERZORDER);
                CClientDC dc_(pT->m_hWnd);
                CDC mem_dc_;
                mem_dc_.CreateCompatibleDC(dc_);
                CBitmap mem_bitmap_;
                mem_bitmap_.CreateCompatibleBitmap(dc_,
                        m_res_->GetWidth(),
                        m_res_->GetHeight());
                mem_dc_.SelectBitmap(mem_bitmap_);
                m_res_->Draw(mem_dc_,0,0);
                BLENDFUNCTION pb_;
                pb_.AlphaFormat = 1;
                pb_.BlendOp = 0;
                pb_.BlendFlags =0;
                pb_.SourceConstantAlpha = 0xFF;
                CPoint  pt_(0,0);
                CSize   size_(m_res_->GetWidth(),m_res_->GetHeight());
                ::UpdateLayeredWindow(pT->m_hWnd,dc_,&pt_,&size_,mem_dc_,&pt_,0,&pb_,ULW_ALPHA );
                pT->CenterWindow(NULL);
            }
        }
    protected:
        CImage*         m_res_;
        bool            m_move_flag_;
    };
    class CAboutDlg :
        public CDialogImpl<CAboutDlg>,
        public ImageFrameT<CAboutDlg,true>
    {
        typedef ImageFrameT<CAboutDlg,true> BaseClass;
    public:
        enum { IDD = IDD_DIALOG1 };
        BEGIN_MSG_MAP(CAboutDlg)
            CHAIN_MSG_MAP(BaseClass)
            MESSAGE_HANDLER(WM_RBUTTONDOWN, OnClose)
        END_MSG_MAP()
        LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
        {
            EndDialog(0);
            return 0;
        }
    };
    CImage      bitmap_bg_;
    BOOL ret_ = File2CImageAndImplAlpha(&bitmap_bg_,_T("res/bk.png"));
    ATLASSERT(ret_);
    CAboutDlg dlg_;
    dlg_.SetMoveFlag(true);
    dlg_.DoModal(this->m_hSubWindow_,(LPARAM)(&bitmap_bg_));

放置子控件

若只需要最一個(gè)簡(jiǎn)單的窗口,那么上面的代碼可以完成要求。UpdateLayeredWindow有一個(gè)問(wèn)題,那就是它上面不能放置任何子窗口,放置上去的任何窗口都不可見(jiàn)。為了解決這個(gè)問(wèn)題,一種簡(jiǎn)單的辦法是自繪,在單個(gè)窗口中模擬各種消息。

若不想搞復(fù)雜,有一種變通的辦法,那就是在上面放置一個(gè)非子窗口,這種子窗口大小位置保持和它一致,同時(shí)這個(gè)子窗口用SetLayeredWindowAttributes搞成全透明,接下來(lái)我們將所有子控件放到這個(gè)全透明的子窗口即可。

Sample

    #define CHAIN_MSG_MAP_ALT_MEMBER_EX(theChainMember, msgMapID, msg) \
        { \
            if(uMsg == msg && \
                theChainMember &&\
                theChainMember->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, msgMapID)) \
                return TRUE; \
        }
    // 放置在ImageFrameT上的子窗口
    // 這個(gè)類主要處理消息的轉(zhuǎn)發(fā),通過(guò)WM_CREATE獲得最頂層窗口的指針
    // 并存儲(chǔ)在m_message_變量中,然后使用CHAIN_MSG_MAP_ALT_MEMBER_EX
    // 將它子窗口發(fā)給它的WM_COMMAND,WM_NOTIFY轉(zhuǎn)發(fā)過(guò)去
    template<typename T,typename Y>
    class SubWindowT{
    public:
        BEGIN_MSG_MAP(SubWindowT)
            MESSAGE_HANDLER(WM_CREATE, OnCreate)
            MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
            // 將這個(gè)不可見(jiàn)的窗口的WM_COMMAND和WM_NOTIFY消息
            // 轉(zhuǎn)發(fā)給最頂層的窗口
            CHAIN_MSG_MAP_ALT_MEMBER_EX(m_message_,1,WM_COMMAND)
            CHAIN_MSG_MAP_ALT_MEMBER_EX(m_message_,1,WM_NOTIFY)
        END_MSG_MAP()
        SubWindowT():m_message_(NULL){};
        LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled){
            bHandled = FALSE;
            T* pT = static_cast<T*>(this);
            LPCREATESTRUCT lpCreateStruct = (LPCREATESTRUCT)lParam;
            // 初始化m_message_
            if(lpCreateStruct && lpCreateStruct->lpCreateParams)
                m_message_ = (Y*)(lpCreateStruct->lpCreateParams);
            ATLASSERT(m_message_);
            // 設(shè)置屬性WS_POPUP
            LONG lWindowLong = ::GetWindowLong(pT->m_hWnd, GWL_STYLE) | WS_POPUP;
            // 去掉一堆其他屬性
            lWindowLong &= ~WS_CHILD;
            lWindowLong &= ~WS_BORDER;
            lWindowLong &= ~WS_CAPTION;
            lWindowLong &= ~WS_SYSMENU;
            ::SetWindowLong(pT->m_hWnd, GWL_STYLE, lWindowLong);
            return 0;
        }
        LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
            // 屏蔽背景消息
            return TRUE;
        }
        // 這個(gè)指針指向最頂層的窗口,用它來(lái)將緊貼這頂層窗口的不可見(jiàn)窗口的消息
        // 轉(zhuǎn)發(fā)給m_message_
        // 注意宏CHAIN_MSG_MAP_ALT_MEMBER_EX
        Y*      m_message_;
    };
    // 這個(gè)類在SubWindowT的基礎(chǔ)上實(shí)現(xiàn)了全透明的效果
    // 利用SetLayeredWindowAttributes可以對(duì)某種特定的顏色實(shí)現(xiàn)全透明過(guò)濾的特性
    template<typename Y>
    class SubWindow1 :
        public CWindowImpl<SubWindow1<Y>,CWindow>,
        public SubWindowT<SubWindow1<Y>,Y>{
        typedef SubWindowT<SubWindow1<Y>,Y> BaseClass;
    public:
        BEGIN_MSG_MAP(SubWindow1)
            CHAIN_MSG_MAP(BaseClass) //連接基類的消息處理邏輯,并優(yōu)先處理
            MESSAGE_HANDLER(WM_CREATE, OnCreate)
            MESSAGE_HANDLER(WM_PAINT, OnPaint)
            REFLECT_NOTIFICATIONS()
        END_MSG_MAP()
        LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled){
            bHandled = FALSE;
            // 設(shè)置屬性WS_EX_LAYERED
            LONG lWindowLong = ::GetWindowLong(this->m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED;
            lWindowLong &= ~WS_EX_TRANSPARENT;
            ::SetWindowLong(this->m_hWnd, GWL_EXSTYLE, lWindowLong);
            // 在OnPaint里面將整個(gè)窗口刷成RGB(255,0,255)
            // 在這里將此顏色過(guò)濾(編程全透明)
            ::SetLayeredWindowAttributes(this->m_hWnd,RGB(255,0,255),0,LWA_COLORKEY);
            return 0;
        }
        LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
            // 在OnPaint里面將整個(gè)窗口刷成RGB(255,0,255)
            // 以便讓SetLayeredWindowAttributes過(guò)濾
            CPaintDC dc_(this->m_hWnd);
            CRect client_rect_;
            this->GetClientRect(client_rect_);
            dc_.FillSolidRect(client_rect_,RGB(255,0,255));
            return TRUE;
        }
    };
    template<typename T,bool DLG,template<typename X> class SUB_WINDOW >
    class ImageFrameExT : public ImageFrameT<T,DLG>{
        typedef ImageFrameT<T,DLG> BaseClass;
    public:
        BEGIN_MSG_MAP(ImageFrameExT)
            CHAIN_MSG_MAP(BaseClass)
            MESSAGE_HANDLER(WM_CREATE, OnCreate)
            MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
            MESSAGE_HANDLER(WM_MOVE, OnMove)
        END_MSG_MAP()
        ImageFrameExT(){
            m_sub_rect_.SetRect(0,0,0,0);
        }
        LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled){
            bHandled = FALSE;
            T* pT = static_cast<T*>(this);
            if(!DLG){
                // 一并創(chuàng)建子窗口
                // 注意它將pT傳給了最后一個(gè)參數(shù),這個(gè)在
                // OnCreate傳給了SubWindowT
                m_hSubWindow_.Create(pT->m_hWnd,NULL,NULL,
                        WS_VISIBLE,0,0U,pT);
            }
            return 0;
        }
        LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled){
            bHandled = FALSE;
            T* pT = static_cast<T*>(this);
            if(DLG){
                // 一并創(chuàng)建子窗口
                // 注意這里沒(méi)有WS_CHILD
                m_hSubWindow_.Create(pT->m_hWnd,NULL,NULL,
                        WS_VISIBLE,0,0U,pT);
            }
            return 0;
        }
        LRESULT OnMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled){
            // 動(dòng)態(tài)更新子窗口
            bHandled = FALSE;
            T* pT = static_cast<T*>(this);
            if(m_hSubWindow_.IsWindow()){
                CRect win_rect_;
                pT->GetWindowRect(win_rect_);
                if(m_sub_rect_.IsRectNull()){
                    m_hSubWindow_.MoveWindow(win_rect_);
                }else{
                    CRect tmp_ = m_sub_rect_;
                    tmp_.OffsetRect(win_rect_.TopLeft());
                    m_hSubWindow_.MoveWindow(tmp_);
                }
            }
            return 0;
        }
        SUB_WINDOW<T>*      SubWindow(){
            // 獲得子窗口
            return &m_hSubWindow_;
        }
        void                SetSubRect(const CRect& rect){
            // 可以設(shè)置讓子窗口位于那塊區(qū)域,而不一定要占滿整屏
            m_sub_rect_ = rect;
        }
    protected:
        SUB_WINDOW<T>       m_hSubWindow_;
        CRect               m_sub_rect_;
    };
    class CMainFrame :
        public CFrameWindowImpl<CMainFrame>,
        public ImageFrameExT<CMainFrame,false,SubWindow1 >
    {
        typedef ImageFrameExT<CMainFrame,false,SubWindow1 > BaseClass;
    public:
        DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)
        BEGIN_MSG_MAP(CMainFrame)
            //REFLECT_NOTIFICATIONS()
            CHAIN_MSG_MAP(BaseClass)
            MESSAGE_HANDLER(WM_CREATE, OnCreate)
            MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
            CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
            ALT_MSG_MAP(1)
            COMMAND_CODE_HANDLER(BN_CLICKED,OnClick)
        END_MSG_MAP()
        LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
        {
            m_close_.Create(this->m_hSubWindow_,
                    CRect(200,200,50 + 200,26 + 200),
                    _T("Close"),
                    WS_CHILD | WS_VISIBLE);
            m_help_.Create(this->m_hSubWindow_,
                    CRect(260,200,50 + 260,26 + 200),
                    _T("Help"),
                    WS_CHILD | WS_VISIBLE);
            m_help2_.Create(this->m_hSubWindow_,
                    CRect(320,200,50 + 320,26 + 200),
                    _T("Help2"),
                    WS_CHILD | WS_VISIBLE);
            return 0;
        }
        LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
        {
            // 解決wtl不能關(guān)閉ws_popup的bug
            PostQuitMessage(0);
            bHandled = FALSE;
            return 1;
        }
        LRESULT OnClick(WORD wNotifyCode, WORD wID, HWND hWndCtl,
              BOOL& bHandled){
            if(m_close_ == hWndCtl){
                this->PostMessage(WM_CLOSE);
            }else if(m_help_ == hWndCtl){
            }else if(m_help2_ == hWndCtl){
            }
            return 0;
        }
        CButton     m_close_;
        CButton     m_help_;
        CButton     m_help2_;
    };

其他問(wèn)題

若上面放置普通的矩形控件,并且不支持透明,那么啥問(wèn)題都沒(méi)有,然后若要實(shí)現(xiàn)不規(guī)則或者透明控件,那么全透明窗口被過(guò)濾的顏色將被顯示出來(lái)

一個(gè)變通的辦法就是將需要填充子控件的區(qū)域摳出來(lái),并交給這個(gè)子窗口來(lái)畫(這就要求放置控件區(qū)域的地方?jīng)]有半透明,大部分需求都只是希望能夠處理簡(jiǎn)單的異形,并且消除鋸齒)。

    // 將父窗口中間摳出來(lái),交給子窗口來(lái)畫
    template<typename Y>
    class SubWindow2 :
        public CWindowImpl<SubWindow2<Y>,CWindow>,
        public SubWindowT<SubWindow2<Y>,Y>{
        typedef SubWindowT<SubWindow2<Y>,Y> BaseClass;
    public:
        BEGIN_MSG_MAP(SubWindow2)
            CHAIN_MSG_MAP(BaseClass)
            MESSAGE_HANDLER(WM_PAINT, OnPaint)
            REFLECT_NOTIFICATIONS()
        END_MSG_MAP()
        LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
            CPaintDC dc_(this->m_hWnd);
            ATLASSERT(m_res_);
            if(m_res_)
                m_res_->Draw(dc_,0,0);
            return TRUE;
        }
        inline void SetRes(CImage* res){
            ATLASSERT(res);
            if(res)
                this->m_res_ = res;
        }
    private:
        CImage*     m_res_;
    };
    class CAboutDlgEx :
        public CDialogImpl<CAboutDlgEx>,
        public ImageFrameExT<CAboutDlgEx,true,SubWindow2>
    {
        typedef ImageFrameExT<CAboutDlgEx,true,SubWindow2> BaseClass;
    public:
        enum { IDD = IDD_DIALOG1 };
        BEGIN_MSG_MAP(CAboutDlgEx)
            CHAIN_MSG_MAP(BaseClass)
            MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
            MESSAGE_HANDLER(WM_RBUTTONDOWN, OnClose)
            ALT_MSG_MAP(1)
        END_MSG_MAP()
        LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
            bool ret_ = m_res_.InitFromFile(
                    _T("res/imgbtn.png"),
                    _T("res/imgbtn_h.png"),
                    _T("res/imgbtn_p.png"),
                    _T("res/imgbtn_d.png"));
            ATLASSERT(ret_);
            m_btn_.Create(this->m_hSubWindow_,NULL,NULL,0,0,0U,&m_res_);
            m_btn_.MoveWindow(120,120,0,0,TRUE);
            return 0;
        }
        LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){
            EndDialog(0);
            return 0;
        }
        ImageButton<ButtonRes,true>     m_btn_;
        ButtonRes       m_res_;
    };

經(jīng)測(cè)試,這種方案在拖動(dòng)時(shí),兩個(gè)窗口交接處有明顯的刷新不一致存在。

Bug

在一些非32位圖像模式下,該函數(shù)會(huì)有些問(wèn)題,解決辦法就是強(qiáng)制創(chuàng)建32位的Bitmap

CBitmap bitmap;
BITMAPINFOHEADER bmih;
bmih.biSize                  = sizeof (BITMAPINFOHEADER) ;
bmih.biWidth                 = 384 ;
bmih.biHeight                = 256 ;
bmih.biPlanes                = 1 ;
bmih.biBitCount              = 32 ;  //注意32位
bmih.biCompression           = BI_RGB ;
bmih.biSizeImage             = 0 ;
bmih.biXPelsPerMeter         = 0 ;
bmih.biYPelsPerMeter         = 0 ;
bmih.biClrUsed               = 0 ;
bmih.biClrImportant          = 0 ;
bitmap.CreateDIBitmap(dc,&bmih);

為了避免繪圖匯到左上角,需要在調(diào)用UpdateLayeredWindow時(shí),明確指定左上角坐標(biāo)

CRect rect_;
GetWindowRect(rect_);
CPoint topleft(rect_.left,rect_.top);
CPoint  pt_(0,0);
CSize   size_(m_res_->GetWidth(),m_res_->GetHeight());
::UpdateLayeredWindow(pT->m_hWnd,dc_,&topleft,&size_,mem_dc_,&pt_,0,&pb_,ULW_ALPHA );

以上就是UpdateLayeredWindow實(shí)現(xiàn)任意異形窗口使用詳解的詳細(xì)內(nèi)容,更多關(guān)于UpdateLayeredWindow 異形窗口的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論