小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

剪貼板查看器

 londonKu 2012-09-06

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

8.3.1  剪貼板查看器鏈接列表

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

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

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

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

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

static HWND hWndNextViewer;

case WM_CREATE :

   hWndNextViewer = SetClipboardViewer(hWnd);

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

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

case WM_DRAWCLIPBOARD :

if( hWndNextViewer )

   SendMessage ( hWndNextViewer, message, wParam, lParam);

InvalidateRect( hWnd, NULL, TRUE);

Break;

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

BOOL ChangeClipboardChain(HWND hWndRemove, HWND hWndNewNext );

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

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

case WM_CHANGECBCHAIN :

  if( (HWND) wParam ==hWndClipboardViewer )

hWndClipboardViewer = (HWND) lParam;

 else if (hWndClipboardViewer)

SendMessage ( hWndClipboardViewer, message, wParam, lParam);

  return 0;

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

case WM_DESTORY :

ChangeClipboardChain( hWnd, hWndNextViewer );

PostQuitMessage( 0);

break;

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

HWND GetClipboardViewer(VOID);

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

2. 剪貼板查看器的實例分析

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

   首先,在創(chuàng)建窗口時就設(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中實現(xiàn)了什么。真正的具體實現(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 );

              }

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

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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多