日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

剪貼板查看器

 londonKu 2012-09-06

監(jiān)視剪貼板內(nèi)容變化的程序叫剪貼板查看器。在Windows中已經(jīng)擁有了剪貼板查看器,當(dāng)然也可以用API函數(shù)編寫自己的剪貼板查看器程序。

8.3.1  剪貼板查看器鏈接列表

   Windows下可以同時(shí)運(yùn)行很多剪貼板查看器,用于時(shí)刻監(jiān)視剪貼板內(nèi)容的變化情況。但Windows在剪貼板內(nèi)容發(fā)生變化時(shí),只對(duì)一個(gè)剪貼板查看器窗口發(fā)送消息,這就是所謂的“當(dāng)前剪貼板查看器”。

   應(yīng)用程序想要得到Windows發(fā)送給當(dāng)前剪貼板查看器的消息,就必須加入“剪貼板查看器鏈接列表”。當(dāng)一個(gè)程序?qū)⒆约鹤?cè)為一個(gè)剪貼板查看器時(shí),其窗口句柄被Windows留作當(dāng)前剪貼板查看器窗口句柄,它也就被Windows設(shè)置為當(dāng)前剪貼板查看器。當(dāng)此程序收到一個(gè)剪貼板查看器消息時(shí),就把這個(gè)消息發(fā)送給剪貼板鏈表中下一個(gè)程序的窗口過程。

8.3.2  有關(guān)剪貼板查看器的函數(shù)和消息

1. 剪貼板查看器函數(shù)消息介紹

   程序通過調(diào)用函數(shù)SetClipboardViewer成為剪貼板查看器鏈表中的一員。如果程序是作為剪貼板查看器使用的,那么在主窗口創(chuàng)建之初就應(yīng)該調(diào)用此函數(shù)。即在處理消息WM_CREATE期間,函數(shù)返回前一個(gè)當(dāng)前剪貼板查看器的窗口句柄,將其放在靜態(tài)變量中,如下所示:

static HWND hWndNextViewer;

case WM_CREATE :

   hWndNextViewer = SetClipboardViewer(hWnd);

   在以后介紹的實(shí)例中,大家將看到具體的應(yīng)用。

   一旦成為當(dāng)前剪貼板查看器,只要剪貼板有任何變化,Windows都會(huì)把WM_DRAWCLIPBOARD消息發(fā)送給其窗口過程。剪貼板查看器鏈表中的每一個(gè)程序,都應(yīng)該用SendMessage把這個(gè)消息發(fā)送給下一個(gè)剪貼板查看器。鏈表中的最后一個(gè)程序,就是當(dāng)前剪貼板查看器的窗口所保存的hWndNextViewerNULL。當(dāng)消息傳給它后,程序只是簡單地返回,消息不再從這里發(fā)出。具體的處理方法是除了當(dāng)前剪貼板查看器,一般都是簡單地將消息發(fā)送給下一個(gè)剪貼板查看器的窗口過程,并使本窗口的客戶區(qū)無效,如下所示:

case WM_DRAWCLIPBOARD :

if( hWndNextViewer )

   SendMessage ( hWndNextViewer, message, wParam, lParam);

InvalidateRect( hWnd, NULL, TRUE);

Break;

   在處理WM_PAINT期間,可以調(diào)用OpenClipboard,GetClipboardDataCloseClipboard讀取剪貼板的內(nèi)容。當(dāng)一個(gè)程序要從剪貼板查看器鏈表中刪除自己時(shí),應(yīng)當(dāng)調(diào)用ChangeClipboardChain函數(shù)。函數(shù)原型如下:

BOOL ChangeClipboardChain(HWND hWndRemove, HWND hWndNewNext )

   其中,第一個(gè)參數(shù)hWndRemove是從剪貼板查看器鏈中刪除的窗口句柄;第二個(gè)參數(shù)hWndNewNext是剪貼板查看器鏈中hWndRemove后面緊跟的窗口句柄。當(dāng)程序調(diào)用ChangeClipboardChain時(shí),Windows將消息   WM_CHANGECBCHAIN發(fā)送到當(dāng)前剪貼板查看器。在此消息中,參數(shù)wParam是函數(shù)ChangeClipboardChain的第一個(gè)參數(shù),參數(shù)lParam是函數(shù)ChangeClipboardChain的第二個(gè)參數(shù)。

   當(dāng)程序收到消息WM_CHANGECBCHAIN,必須檢查wParam與保留的hWndNextViewer靜態(tài)變量是否相同。如果相同,則將hWndNextViewer設(shè)置為lParam。此項(xiàng)工作保證了將來WM_DRAWCLIPBOARD消息不會(huì)被發(fā)送到一個(gè)已經(jīng)不存在的窗口。如果不同,并且hWndNextViewer不為NULL,表明非當(dāng)前剪貼板查看器,則將消息發(fā)送給下一個(gè)剪貼板查看器,如下所示:

case WM_CHANGECBCHAIN :

  if( (HWND) wParam ==hWndClipboardViewer )

hWndClipboardViewer = (HWND) lParam;

 else if (hWndClipboardViewer)

SendMessage ( hWndClipboardViewer, message, wParam, lParam);

  return 0;

   當(dāng)程序要結(jié)束時(shí),如果它仍然在剪貼板查看器鏈中,則必須將其刪除。為了保證這一點(diǎn),可以在處理消息WM_DESTORY時(shí)通過調(diào)用函數(shù)ChangeClipboardChain來實(shí)現(xiàn),如下所示:

case WM_DESTORY :

ChangeClipboardChain( hWnd, hWndNextViewer );

PostQuitMessage( 0);

break;

   Windows還提供獲得第一個(gè)剪貼板查看器窗口句柄的函數(shù):

HWND GetClipboardViewer(VOID);

   一般來說不會(huì)用到這個(gè)函數(shù)。如果沒有當(dāng)前剪貼板查看器,那么此函數(shù)的返回值為NULL。

2. 剪貼板查看器的實(shí)例分析

   下面來看一個(gè)剪貼板查看器的具體實(shí)例,這個(gè)實(shí)例提供了顯示CF_BITMAPCF_TEXT的剪貼板查看器。雖然它只提供了Windows剪貼板查看器的部分功能,但從中可以了解剪貼板查看器是如何工作的。

   首先,在創(chuàng)建窗口時(shí)就設(shè)置本窗口為剪貼板查看器鏈表中的一員,其中函數(shù)SetOwner是用在窗口標(biāo)題表明客戶區(qū)的內(nèi)容來自何處。其中,用到了函數(shù)GetClipboardOwner,如下所示:

case WM_CREATE:   

       hNextViewer = SetClipboardViewer( hWnd );

       SetOwner( hWnd );

       break;

   其次,看消息是如何在剪貼板查看器鏈表中傳遞的,如下所示:

     case WM_DRAWCLIPBOARD:

         if (hNextViewer)

           SendMessage( hNextViewer, WM_DRAWCLIPBOARD, wParam, lParam );

           InvalidateRect( hWnd, NULL, TRUE );  

           SetOwner( hWnd );

           break;

   再看應(yīng)用程序是如何將自己從剪貼板查看器鏈表中刪除的,如下所示:

case WM_CHANGECBCHAIN:

          if ( (HWND)wParam == hNextViewer )

                 hNextViewer = (HWND)lParam;

          else if ( hNextViewer )

          SendMessage( hNextViewer, WM_CHANGECBCHAIN, wParam, lParam );

          break;

   最后是介紹在消息WM_PAINT中實(shí)現(xiàn)了什么。真正的具體實(shí)現(xiàn)是在這里完成的,在前面已經(jīng)介紹了有關(guān)函數(shù)的具體操作,讀者看起來應(yīng)該輕松一些。

case WM_PAINT :

{

              static HANDLE hMem;         // 剪貼板文本的句柄         

              static HBITMAP hBitmap;      // 剪貼板位圖的句柄

              RECT rect;         // 客戶區(qū)            

              PAINTSTRUCT ps;           // 繪圖的結(jié)構(gòu)

              BeginPaint( hWnd, &ps );

              GetClientRect( hWnd, &rect );

              OpenClipboard( hWnd );

              if (hMem = GetClipboardData( CF_TEXT ))

                 // 如果剪貼板中的內(nèi)容為文本格式,則執(zhí)行

              {

                 LPSTR lpMem = GlobalLock( hMem );

                 DrawText( ps.hdc, lpMem, -1, &rect, DT_LEFT );

                 GlobalUnlock( hMem );

              }

              // 如果非文本格式,測(cè)試是否為位圖格式

              else if (hBitmap = GetClipboardData( CF_BITMAP ))

              {

                 BITMAP bm;

                 HDC hMemDC = CreateCompatibleDC( ps.hdc );

                 SelectObject( hMemDC, hBitmap );

                 GetObject( hBitmap, sizeof (BITMAP), (LPSTR) &bm );

                 BitBlt( ps.hdc, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0,

                            SRCCOPY );

                         DeleteDC( hMemDC );

                  }

                  CloseClipboard( );

                  EndPaint( hWnd, &ps );

              }

              break;

   通過本章的學(xué)習(xí),了解了如何運(yùn)用API提供的函數(shù)來編寫剪貼板的程序。在實(shí)際的編程中會(huì)經(jīng)常用到剪貼板的內(nèi)容,希望通過本章的學(xué)習(xí),讀者在編寫程序時(shí)能如虎添翼。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多