六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

在應用程序中監視剪貼板的變化與內容

[摘要]剪貼板是Windows中系統級的堆空間,系統中任何一個應用程序對剪貼板都有訪問權,可以通過剪貼板消息和使用剪貼板API來讀寫剪貼板內容。因此使用剪貼板不僅可以在同一個應用程序內交互數據,也可以在不通...
剪貼板是Windows中系統級的堆空間,系統中任何一個應用程序對剪貼板都有訪問權,可以通過剪貼板消息和使用剪貼板API來讀寫剪貼板內容。因此使用剪貼板不僅可以在同一個應用程序內交互數據,也可以在不通應用程序之間交互數據。尤其是在不通應用程序之間交互時,應用程序往往需要對剪貼板內容的變化做到實時感知,即應用程序要能監視剪貼板內容的變化。



Windows應用是消息驅動的,同理當剪貼板內容發生變化時,Windows提供了剪貼板變化消息,因此要實時感知剪貼板內容的變化,關鍵是應用程序要能響應和處理Windows觸發的剪貼板變化消息。



第一步,要將窗口注冊為Clipboard Viewer

需要首先解釋兩個概念:Clipboard Viewer和Clipboard Viewer Chain。

Clipboard Viewer是一個需要取得并顯示剪貼板內容的窗口,通過Clipboard Viewer這個機制,應用程序可以在不影響剪貼板內容的情況下獲取剪貼板的變化消息。Clipboard Viewer可以顯示系統定義的標準格式的剪貼板內容,也可以顯示應用自定義的私有數據格式的內容。通過調用函數SetClipboardViewer將窗口注冊為Clipboard Viewer。

Clipboard Viewer Chain是保存Clipboard Viewer窗口以及他們之間的前后向關系的一個Windows系統鏈表,當一個窗口注冊為Clipboard Viewer后,他會被加入Clipboard Viewer Chain,并得到鏈表中下一個Viewer窗口的句柄,該句柄必須保存以在響應消息時使用,該句柄的作用在下文說明。Windows正是通過Clipboard Viewer Chain保證了所有Clipboard Viewer能接收和響應剪貼板變化消息。



第二步,響應剪貼板變化消息,判斷和取出剪貼板內容

在消息響應里必須正確處理兩個消息:WM_DRAWCLIPBOARD和WM_CHANGECBCHAIN。



當剪貼板內容發生變化時,Windows將觸發WM_DRAWCLIPBOARD消息,并將該消息送給Clipboard Viewer Chain的第一個窗口。每一個Clipboard Viewer窗口,包括第一個窗口在響應和處理該消息后,必須根據其保存的鏈表中的下一個窗口的句柄將該消息發送給下一個Clipboard Viewer窗口。窗口可以在該消息中取出剪貼板內容,并判斷是否是該窗口增在監視的內容,如果是就進行相應的處理。



當某個Clipboard Viewer窗口注銷時,系統將觸發WM_CHANGECBCHAIN,并將該消息送給Clipboard Viewer Chain的第一個窗口。每一個窗口必須處理該消息。



第三步,將窗口從Clipboard Viewer Chain中注銷

當窗口不再需要監視剪貼板變化消息,或窗口要關閉時,必須調用ChangeClipboardChain函數將窗口從Clipboard Viewer Chain中注銷。注銷后系統會觸發WM_CHANGECBCHAIN消息,同WM_DRAWCLIPBOARD消息一樣,該消息會給發送給Clipboard Viewer Chain的第一個窗口處理。下面代碼示例當窗口被關閉時進行注銷。



下面的代碼片斷給出了監視剪貼板中是否拷貝了URL地址的例子,如果剪貼板中的內容是URL地址,則將其顯示在窗口界面上。為使示例代碼具有一般性,下面給出了一般Windows程序代碼和基于MFC的代代碼。其他語言要實現該功能可以參考Windows程序代碼。兩個DEMO的完成代碼請見附件。



Windows程序示例代碼

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    int wmId, wmEvent;

    PAINTSTRUCT ps;

    HDC hdc;

    unsigned int anFormats[] = {CF_TEXT};

    unsigned int nFormat;



    switch (message)

    {

        //----------------------------------------------------------------   

        case WM_CREATE:  

            //將本窗口注冊到Clipboard Viewer Chain,

            //并保存Clipboard Viewer Chain中下一個窗口的句柄

            hwndNextViewer = SetClipboardViewer(hWnd);

            break;

        case WM_CHANGECBCHAIN:  //Clipboard Viewer注銷

            //如果注銷的Clipboard Viewer窗口是本窗口的下一個窗口,

            //則修改本窗口保存的下一個窗口句柄,

            //否則將該消息傳遞到Clipboard Viewer Chain的下一個窗口

            if ((HWND) wParam == hwndNextViewer)

                hwndNextViewer = (HWND) lParam;

            else if (hwndNextViewer != NULL)

                SendMessage(hwndNextViewer, message, wParam, lParam);  

            break;

        case WM_DRAWCLIPBOARD:  //剪貼板內容變化

            //觸發ON_PAINT顯示URL內容

            InvalidateRect(hWnd, NULL, TRUE);

            UpdateWindow(hWnd);

            //否則將該消息傳遞到Clipboard Viewer Chain的下一個窗口

            SendMessage(hwndNextViewer, message, wParam, lParam);

            break;

        case WM_DESTROY:

            //從Clipboard Viewer Chain注銷本窗口

            ChangeClipboardChain(hWnd, hwndNextViewer);

            PostQuitMessage(0);

            break;

        //----------------------------------------------------------------

        case WM_COMMAND:

            wmId    = LOWORD(wParam);

            wmEvent = HIWORD(wParam);

            // Parse the menu selections:

            switch (wmId)

            {

                case IDM_ABOUT:

                   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX,

hWnd, (DLGPROC)About);

                   break;

                case IDM_EXIT:

                   DestroyWindow(hWnd);

                   break;

                default:

                   return DefWindowProc(hWnd, message, wParam, lParam);

            }

            break;

        case WM_PAINT:

            hdc = BeginPaint(hWnd, &ps);

            //判斷剪貼板中的內容是否為URL地址,如是則顯示

            nFormat = GetPriorityClipboardFormat(anFormats,sizeof(anFormats));            

            if(nFormat == CF_TEXT)

            {

                OpenClipboard(hWnd);

                HGLOBAL hMem = GetClipboardData(nFormat);

                LPTSTR lpstr = (LPTSTR)GlobalLock(hMem);



                if(strstr(lpstr,"http://") != NULL

                   strstr(lpstr,"ftp://")  != NULL

                   strstr(lpstr,"file://") != NULL)

                {

                    RECT rt;

                    GetClientRect(hWnd, &rt);

                    DrawText(hdc, lpstr, -1, &rt, DT_LEFT);

                }

                GlobalUnlock(hMem);

                CloseClipboard();

            }

            EndPaint(hWnd, &ps);

            break;

        default:

            return DefWindowProc(hWnd, message, wParam, lParam);

   }

   return 0;

}



MFC程序示例代碼

首先要映射以下消息和繼承以下函數

afx_msg void OnChangeCbChain(HWND hWndRemove, HWND hWndAfter);

afx_msg void OnDrawClipboard();

afx_msg void OnDestroy();

virtual void OnInitialUpdate();





void CMonitorUrlView::OnInitialUpdate()

{

    CListView::OnInitialUpdate();



    m_pListCtrl = &GetListCtrl();;

    m_pListCtrl->SetExtendedStyle(LVS_EX_FULLROWSELECT

                                  LVS_EX_GRIDLINES

                                  LVS_EX_TRACKSELECT

                                  LVS_EX_TWOCLICKACTIVATE

                                  LVS_EX_UNDERLINECOLD);

    m_pListCtrl->ModifyStyle(LVS_TYPEMASK, LVS_REPORT);

    m_pListCtrl->InsertColumn(0, "URL",LVCFMT_LEFT,600,1);    



    //將本窗口注冊到Clipboard Viewer Chain,

    //并保存Clipboard Viewer Chain中下一個窗口的句柄

    m_hwndNextViewer = SetClipboardViewer();

}



void CMonitorUrlView::OnDestroy()

{

    CListView::OnDestroy();

    

    //從Clipboard Viewer Chain注銷本窗口

    ChangeClipboardChain(m_hwndNextViewer);

}



//Clipboard Viewer注銷

void CMonitorUrlView::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)

{

    //如果注銷的Clipboard Viewer窗口是本窗口的下一個窗口,

    //則修改本窗口保存的下一個窗口句柄,

    CView::OnChangeCbChain(hWndRemove,hWndAfter);



    if(hWndRemove == m_hwndNextViewer)

        m_hwndNextViewer = hWndAfter;

}



//剪貼板內容變化,判斷剪貼板中的內容是否為URL地址,如是則顯示

void CMonitorUrlView::OnDrawClipboard()

{

    CView::OnDrawClipboard();

        

    unsigned int anFormats[] = {CF_TEXT};

    unsigned int nFormat =

GetPriorityClipboardFormat(anFormats,sizeof(anFormats));  

    if(nFormat == CF_TEXT)

    {

        HGLOBAL hMem;

        OpenClipboard();

        

        if(hMem = ::GetClipboardData(CF_TEXT))

        {

            LPTSTR lpszText = (LPTSTR) GlobalLock(hMem);

            CString strURL = lpszText;

            strURL = strURL.SpanExcluding("\r\n");

            

            if(strURL.Left(7).CompareNoCase("http://") == 0

               strURL.Left(6).CompareNoCase("ftp://")  == 0

               strURL.Left(7).CompareNoCase("file://") == 0)

            {                

                m_pListCtrl->InsertItem(0,lpszText);

            }

            GlobalUnlock(hMem);

        }

        CloseClipboard();

    }   

}


主站蜘蛛池模板: 天天插伊人 | 一二三四影视在线观看免费视频 | 婷婷亚洲综合一区二区 | 欧美视频亚洲视频 | 人人草人人看 | 色综合图区 | 天天操天天摸天天碰 | 欧美一区视频 | 亚洲欧美手机在线观看 | 青青青国产免费 | 三级小说在线 | 日韩无砖2021特黄 | 夜间视频在线观看 | 天天欧美 | 婷婷综合七月激情啪啪 | 人人爱人人做 | 四虎影院免费看 | 日本xx高清视频免费观看 | 日韩不卡一级毛片免费 | 婷婷色天使在线视频观看 | 亚洲 欧美 中文字幕 | 四虎免费影院在线播放 | 在线观看视频一区二区三区 | 色迷迷网免费站视频在线观看 | 亚洲日本欧美在线 | 伊人操| 亚洲一级片在线播放 | 亚洲视频综合 | 香蕉国产成版人视频在线观看 | 特一级黄色大片 | 亚洲第成色999久久网站 | 日本大学生免费一级一片 | 欧美性xxxx偷拍 | 日本免费高清一区 | 午夜视频导航 | 亚洲国产成人久久一区www妖精 | 天天躁天天碰天天看 | 最近日本免费观看视频 | 青青草原免费在线视频 | 亚洲自偷| 亚洲欧美精品 |