乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      VC++ MFC 使用剪切板的方法

       成長(zhǎng)中輝煌 2013-06-24
      Windows剪貼板是一種比較簡(jiǎn)單同時(shí)也是開(kāi)銷比較小的IPC(InterProcess Communication,進(jìn)程間通訊)機(jī)制。Windows系統(tǒng)支持剪貼板IPC的基本機(jī)制是由系統(tǒng)預(yù)留的一塊全局共享內(nèi)存,用來(lái)暫存在各進(jìn)程間進(jìn)行交換的數(shù)據(jù):提供數(shù)據(jù)的進(jìn)程創(chuàng)建一個(gè)全局內(nèi)存塊,并將要傳送的數(shù)據(jù)移到或復(fù)制到該內(nèi)存塊;接受數(shù)據(jù)的進(jìn)程(也可以是提供數(shù)據(jù)的進(jìn)程本身)獲取此內(nèi)存塊的句柄,并完成對(duì)該內(nèi)存塊數(shù)據(jù)的讀取。

      為使剪貼板的這種IPC機(jī)制更加完善和便于使用,需要解決好如下三個(gè)問(wèn)題:提供數(shù)據(jù)的進(jìn)程在結(jié)束時(shí) Windows系統(tǒng)將刪除其創(chuàng)建的全局內(nèi)存塊,而接受數(shù)據(jù)的進(jìn)程則希望在其退出后剪貼板中的數(shù)據(jù)仍然存在,可以繼續(xù)為其他進(jìn)程所獲??;能方便地管理和傳送剪貼板數(shù)據(jù)句柄;能方便設(shè)置和確定剪貼板數(shù)據(jù)格式。為完善上述功能,Windows提供了存在于USER32.dll中的一組API函數(shù)、消息和預(yù)定義數(shù)據(jù)格式等,并通過(guò)對(duì)這些函數(shù)、消息的使用來(lái)管理在進(jìn)程間進(jìn)行的剪貼板數(shù)據(jù)交換。

      Windows系統(tǒng)為剪貼板提供了一組API函數(shù)和多種消息,基本可以滿足編程的需要。而且Windows還為剪貼板預(yù)定義了多種數(shù)據(jù)格式。通過(guò)這些預(yù)定義的格式,可以使接收方正確再現(xiàn)數(shù)據(jù)提供方放置于剪貼板中的數(shù)據(jù)內(nèi)容。

      文本剪貼板和位圖剪貼板的使用

      這兩種剪貼板是比較常用的。其中,文本剪貼板是包含具有格式CF_TEXT的字符串的剪貼板,是最經(jīng)常使用的剪貼板之一。在文本剪貼板中傳遞的數(shù)據(jù)是不帶任何格式信息的ASCII字符。若要將文本傳送到剪貼板,可以先分配一個(gè)可移動(dòng)全局內(nèi)存塊,然后將要復(fù)制的文本內(nèi)容寫(xiě)入到此內(nèi)存區(qū)域。最后調(diào)用剪貼板函數(shù)將數(shù)據(jù)放置到剪貼板:

      注意:
      下面代碼中:
      1、HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1);
      分配內(nèi)存長(zhǎng)度必須是dwLength + 1,否則在調(diào)用SetClipboardData時(shí)會(huì)出錯(cuò);可以通過(guò)調(diào)用 int i2 = ::GlobalSize(hGlobalMemory );來(lái)查看分配的長(zhǎng)度。

      2、hGlobalMemory不能釋放,即不能調(diào)用::GlobalFree(hGlobalMemory),因?yàn)槿绻谝粋€(gè)程序中還要粘貼的話就必須不能釋放,否則在同一程序中粘貼時(shí)獲得的指針為NULL,但如果只在別的程序中粘貼則可以釋放。

      以上兩條是在編制HsfBrowserCtl(HOOPS三維瀏覽控件)時(shí)總結(jié)出來(lái)的??蓞⒖丛a中的復(fù)制、粘貼部分。

      DWORD dwLength = 100; // 要復(fù)制的字串長(zhǎng)度
      HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1); // 分配內(nèi)存
      LPBYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory); // 鎖定內(nèi)存
      for (int i = 0; i 〈 dwLength; i++) // 將"*"復(fù)制到全局內(nèi)存塊
      *lpGlobalMemory++ = '*';
      GlobalUnlock(hGlobalMemory); // 鎖定內(nèi)存塊解鎖
      HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
      ::OpenClipboard(hWnd); // 打開(kāi)剪貼板
      ::EmptyClipboard(); // 清空剪貼板
      ::SetClipboardData(CF_TEXT, hGlobalMemory); // 將內(nèi)存中的數(shù)據(jù)放置到剪貼板
      ::CloseClipboard(); // 關(guān)閉剪貼板


      這里以O(shè)penClipboard()打開(kāi)剪貼板,并在調(diào)用了EmptyClipboard()后使hWnd指向的窗口成為剪貼板的擁有者,一直持續(xù)到 CloseClipboard()函數(shù)的調(diào)用。在此期間,剪貼板為擁有者所獨(dú)占,其他進(jìn)程將無(wú)法對(duì)剪貼板內(nèi)容進(jìn)行修改。

      從剪貼板獲取文本的過(guò)程與之類似,首先打開(kāi)剪貼板并獲取剪貼板的數(shù)據(jù)句柄,如果數(shù)據(jù)存在就拷貝其數(shù)據(jù)到程序變量。由于GetClipboardData()獲取的數(shù)據(jù)句柄是屬于剪貼板的,因此用戶程序必須在調(diào)用CloseClipboard()函數(shù)之前使用它:


      HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
      ::OpenClipboard(hWnd); // 打開(kāi)剪貼板
      HANDLE hClipMemory = ::GetClipboardData(CF_TEXT);// 獲取剪貼板數(shù)據(jù)句柄
      DWORD dwLength = GlobalSize(hClipMemory); // 返回指定內(nèi)存區(qū)域的當(dāng)前大小
      LPBYTE lpClipMemory = (LPBYTE)GlobalLock(hClipMemory); // 鎖定內(nèi)存
      m_sMessage = CString(lpClipMemory); // 保存得到的文本數(shù)據(jù)
      GlobalUnlock(hClipMemory); // 內(nèi)存解鎖
      ::CloseClipboard(); // 關(guān)閉剪貼板


      大多數(shù)應(yīng)用程序?qū)D形數(shù)據(jù)采取的是位圖的剪貼板數(shù)據(jù)格式。位圖剪貼板的使用與文本剪貼板的使用是類似的,只是數(shù)據(jù)格式要指明為CF_BITMAP,而且在使用SetClipboardData()或GetClipboardData()函數(shù)時(shí)交給剪貼板或從剪貼板返回的是設(shè)備相關(guān)位圖句柄。下面這段示例代碼將把存在于剪貼板中的位圖數(shù)據(jù)顯示到程序的客戶區(qū):


      HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
      ::OpenClipboard(hWnd); // 打開(kāi)剪貼板
      HANDLE hBitmap = ::GetClipboardData(CF_BITMAP); // 獲取剪貼板數(shù)據(jù)句柄
      HDC hDC = ::GetDC(hWnd); // 獲取設(shè)備環(huán)境句柄
      HDC hdcMem = CreateCompatibleDC(hDC); // 創(chuàng)建與設(shè)備相關(guān)的內(nèi)存環(huán)境
      SelectObject(hdcMem, hBitmap); // 選擇對(duì)象
      SetMapMode(hdcMem, GetMapMode(hDC)); // 設(shè)置映射模式
      BITMAP bm; // 得到位圖對(duì)象
      GetObject(hBitmap, sizeof(BITMAP), &bm);
      BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); //位圖復(fù)制
      ::ReleaseDC(hWnd, hDC); // 釋放設(shè)備環(huán)境句柄
      DeleteDC(hdcMem); // 刪除內(nèi)存環(huán)境
      ::CloseClipboard(); // 關(guān)閉剪貼板


      多數(shù)據(jù)項(xiàng)和延遲提交技術(shù)

      要把數(shù)據(jù)放入剪貼板,在打開(kāi)剪貼板后一定要調(diào)用EmptyClipboard()函數(shù)清除當(dāng)前剪貼板中的內(nèi)容,而不可以在原有數(shù)據(jù)項(xiàng)基礎(chǔ)上追加新的數(shù)據(jù)項(xiàng)。但是,可以在EmptyClipboard()和CloseClipboard()調(diào)用之間多次調(diào)用SetClipboardData()函數(shù)來(lái)放置多個(gè)不同格式的數(shù)據(jù)項(xiàng)。例如:


      OpenClipboard(hWnd);
      EmptyClipboardData();
      SetClipboardData(CF_TEXT, hGMemText);
      SetClipboardData(CF_BITMAP, hBitmap);
      CloseClipboard();


      這時(shí)如果用CF_TEXT或CF_BITMAP等格式標(biāo)記去調(diào)用IsClipboardFormatAvailable()都將返回TRUE,表明這幾種格式的數(shù)據(jù)同時(shí)存在于剪貼板中。以不同的格式標(biāo)記去調(diào)用GetClipboardData()函數(shù)可以得到相應(yīng)的數(shù)據(jù)句柄。

      對(duì)于多數(shù)據(jù)項(xiàng)的剪貼板數(shù)據(jù),還可以用CountClipboardFormats()和EnumClipboardFormats()函數(shù)得到當(dāng)前剪貼板中存在的數(shù)據(jù)格式數(shù)目和具體的數(shù)據(jù)格式。EnumClipboardFormats()的函數(shù)原型為:


      UINT EnumClipboardFormats(UINT format);


      參數(shù)format指定了剪貼板的數(shù)據(jù)格式。如果成功執(zhí)行將返回format指定的格式的下一個(gè)數(shù)據(jù)格式值,如果format為最后的數(shù)據(jù)格式值,那么將返回0。由此不難寫(xiě)出處理剪貼板中所有格式數(shù)據(jù)項(xiàng)的程序段代碼:


      UINT format = 0; // 從第一種格式值開(kāi)始枚舉
      OpenClipboard(hWnd);
      while(format = EnumClipboardFormats(format))
      {
      …… // 對(duì)相關(guān)格式數(shù)據(jù)的處理
      }
      CloseClipboard();


      在數(shù)據(jù)提供進(jìn)程創(chuàng)建了剪貼板數(shù)據(jù)后,一直到有其他進(jìn)程獲取剪貼板數(shù)據(jù)前,這些數(shù)據(jù)都要占據(jù)內(nèi)存空間。如在剪貼板放置的數(shù)據(jù)量過(guò)大,就會(huì)浪費(fèi)內(nèi)存空間,降低對(duì)資源的利用率。為避免這種浪費(fèi),可以采取延遲提交(Delayed rendering)技術(shù),即由數(shù)據(jù)提供進(jìn)程先創(chuàng)建一個(gè)指定數(shù)據(jù)格式的空(NULL)剪貼板數(shù)據(jù)塊,直到有其他進(jìn)程需要數(shù)據(jù)或自身進(jìn)程要終止運(yùn)行時(shí)才真正提交數(shù)據(jù)。

      延遲提交的實(shí)現(xiàn)并不復(fù)雜,只需剪貼板擁有者進(jìn)程在調(diào)用SetClipboardData()將數(shù)據(jù)句柄參數(shù)設(shè)置為NULL 即可。延遲提交的擁有者進(jìn)程需要做的主要工作是對(duì)WM_RENDERFORMAT、WM_DESTORYCLIPBOARD和 WM_RENDERALLFORMATS等剪貼板延遲提交消息的處理。

      當(dāng)另一個(gè)進(jìn)程調(diào)用GetClipboardData()函數(shù)時(shí),系統(tǒng)將會(huì)向延遲提交數(shù)據(jù)的剪貼板擁有者進(jìn)程發(fā)送WM_RENDERFORMAT消息。剪貼板擁有者進(jìn)程在此消息的響應(yīng)函數(shù)中應(yīng)使用相應(yīng)的格式和實(shí)際的數(shù)據(jù)句柄來(lái)調(diào)用SetClipboardData()函數(shù),但不必再調(diào)用OpenClipboard()和EmptyClipboard()去打開(kāi)和清空剪貼板了。在設(shè)置完數(shù)據(jù)有也無(wú)須調(diào)用CloseClipboard()關(guān)閉剪貼板。如果其他進(jìn)程打開(kāi)了剪貼板并且調(diào)用EmptyClipboard()函數(shù)去清空剪貼板的內(nèi)容,接管剪貼板的擁有權(quán)時(shí),系統(tǒng)將向延遲提交的剪貼板擁有者進(jìn)程發(fā)送WM_DESTROYCLIPBOARD消息,以通知該進(jìn)程對(duì)剪貼板擁有權(quán)的喪失。而失去剪貼板擁有權(quán)的進(jìn)程在收到該消息后則不會(huì)再向剪貼板提交數(shù)據(jù)。另外,在延遲提交進(jìn)程在提交完所有要提交的數(shù)據(jù)后也會(huì)收到此消息。如果延遲提交剪貼板擁有者進(jìn)程將要終止,系統(tǒng)將會(huì)為其發(fā)送一條WM_RENDERALLFORMATS消息,通知其打開(kāi)并清除剪貼板內(nèi)容。在調(diào)用 SetClipboardData()設(shè)置各數(shù)據(jù)句柄后關(guān)閉剪貼板。

      下面這段代碼將完成對(duì)數(shù)據(jù)的延遲提交,WM_RENDERFORMAT消息響應(yīng)函數(shù)OnRenderFormat()并不會(huì)立即執(zhí)行,當(dāng)有進(jìn)程調(diào)用GetClipboardData()函數(shù)從剪貼板讀取數(shù)據(jù)時(shí)才會(huì)發(fā)出該消息。在消息處理函數(shù)中完成對(duì)數(shù)據(jù)的提交:

      進(jìn)行延遲提交:


      HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
      ::OpenClipboard(hWnd); // 打開(kāi)剪貼板
      ::EmptyClipboard(); // 清空剪貼板
      ::SetClipboardData(CF_TEXT, NULL); // 進(jìn)行剪貼板數(shù)據(jù)的延遲提交
      ::CloseClipboard(); // 關(guān)閉剪貼板


      在WM_RENDERFORMAT消息的響應(yīng)函數(shù)中:


      DWORD dwLength = 100; // 要復(fù)制的字串長(zhǎng)度
      HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1); // 分配內(nèi)存塊
      LPBYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory); // 鎖定內(nèi)存塊
      for (int i = 0; i 〈 dwLength; i++) // 將"*"復(fù)制到全局內(nèi)存塊
      *lpGlobalMemory++ = '*';
      GlobalUnlock(hGlobalMemory); // 鎖定內(nèi)存塊解鎖
      ::SetClipboardData(CF_TEXT, hGlobalMemory); // 將內(nèi)存中的數(shù)據(jù)放置到剪貼板
      DSP和自定義數(shù)據(jù)格式的使用

      Windows系統(tǒng)預(yù)定義了三個(gè)帶“DSP”前綴的數(shù)據(jù)格式:CF_DSPTEXT、CF_DSPBITMAP和 CF_DSPMETAFILEPICT。這是一些偽標(biāo)準(zhǔn)格式,用于表示在程序中定義的私有剪貼板數(shù)據(jù)格式。對(duì)于不同的程序,這些格式的規(guī)定是不同的,因此這些格式只針對(duì)某一具體程序的不同實(shí)例才有意義。

      為使用DSP數(shù)據(jù)格式,必須確保進(jìn)程本身與剪貼板擁有者進(jìn)程同屬一個(gè)程序。可以調(diào)用GetClipboardOwner()函數(shù)來(lái)獲取剪貼板擁有者窗口句柄,并調(diào)用GetClassName()來(lái)獲取窗口類名:

      HWND hClipOwner = GetClipboardOwner();
      GetClassName(hClipOwner, &ClassName, 255);

      如果剪貼板擁有者窗口類名同本進(jìn)程的窗口類名一致,就可以使用帶有DSP前綴的剪貼板數(shù)據(jù)格式了。
      除了使用Windows預(yù)定義的剪貼板數(shù)據(jù)格式外,也可以在程序中使用自定義的數(shù)據(jù)格式。對(duì)于自定義的數(shù)據(jù)格式lpszFormat,可以調(diào)用RegisterClipboardFormat()函數(shù)來(lái)登記,并獲取其返回的格式標(biāo)識(shí)值:

      UINT format = RegisterClipboardFormat(lpszFormat);

      對(duì)此返回的格式標(biāo)識(shí)值的使用與系統(tǒng)預(yù)定義的格式標(biāo)識(shí)是一樣的??梢酝ㄟ^(guò)GetClipboardFormatName()函數(shù)來(lái)獲取自定義格式的ASCII名。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(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)論公約

        類似文章 更多