搜尋
首頁Javajava教程如何理解C++ MFC進程間通訊之剪貼簿

這篇文章帶給大家的內容是關於如何理解C MFC進程間通信之剪貼板,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

Windows剪貼簿是比較簡單的進程間通訊機制,同時它的開銷相對較小。它的實作原理很簡單,其實就是由作業系統維護的一塊記憶體區域,
這塊記憶體區域不屬於任何單獨的進程,但是每一個進程又都可以存取這塊記憶體區域,當一個行程將資料放到該記憶體區域中,而另一個進程,則可以從該區塊記憶體區域中取出數據,從而實現通信,其實現過程由兩大部分組成,一個是共享記憶體操作,一個是剪貼簿的操作。
1、剪貼簿操作
(1)HWND GetClipboardOwner();
功能:取得指向剪貼簿的目前擁有者的句柄
如果這個函數執行成功,則傳回擁有剪貼簿的窗口句柄。否則,返回NULL。

(2)BOOL  OpenClipboard(HWND  hWndNewOwner );
第一個參數hWndNewOwner 指向一個與之關聯的視窗句柄,即代表是這個視窗開啟剪貼簿,如果這個參數設定為NULL 的話,則以當前的任務或說是進程來開啟剪貼簿。如果開啟剪貼簿成功,則函數傳回非 0 值,如果其他程式已經開啟了剪貼簿,那麼目前這個程式就無法再開啟剪貼簿了,所以會致使開啟剪貼簿失敗,從而該函數傳回 0 值。其實這也好理解,你想啊,剪貼簿總共才那麼一塊內存區域,你進程A 要往裡面寫數據,你進程B 又要往裡面寫數據,那不亂套去,解決這個亂套的辦法就是,如果我進程A 正在往剪貼簿裡面寫資料(可以理解為進程A 打開剪貼簿了),那麼進程B 就不能往剪貼簿裡頭寫資料了,既然要讓進程B 不能往剪貼簿中寫資料了,那我就讓進程B 打開剪貼簿失敗不就得了。所以如果某個程式已經打開了剪貼板,那麼其他應用程式將不能修改剪貼簿,直到打開了剪貼簿的這個程式呼叫了CloseClipboard 函數,並且只有在呼叫了EmptyClipboard 函數之後,打開剪貼簿的目前視窗才能擁有剪貼簿

(3)BOOL CloseClipboard(void);
如果某個進程開啟了剪貼簿,則在這個進程沒有呼叫CloseClipboard 函式關閉剪貼簿句柄之前,其他進程都是無法開啟剪貼簿的,所以我們每次使用完剪貼簿之後都應該關閉剪貼簿。注意,這裡的關閉剪貼簿並不代表當前打開剪貼簿的這個程式失去了對剪貼簿的所有權,只有在別的程式調用了EmptyClipboard 函數之後,當前的這個程式才會失去對剪貼簿的所有權,而那個呼叫EmptyClipboard 函數的程式才能擁有剪貼簿。

(4)HANDLE  SetClipboardData(UINT uFormat,  HANDLE hMem );  
SetClipboardData 函數來實現在剪貼簿中放置數據,這個函數以指定的剪貼簿格式將資料放在剪貼簿中放置資料。第一個參數 uFormat 用來指定要放到剪貼簿上的資料的格式,例如常見的有 CF_BITMAP ,CF_TEXT ,CF_DIB 等等(其他格式可以參考 MSDN)。第二個參數hMem 用來指定具有指定格式的資料的句柄,該參數可以是NULL ,如果該參數為NULL 則表示直到有程式對剪貼簿中的資料進行請求時,該程式(也就是擁有剪貼簿所有權的進程)才會將數據複製到剪貼簿中,也就是提供指定剪貼簿格式的數據,上面提及的就是延遲提交技術,這個延遲提交技術將會在後面做詳細的介紹。

(5)BOOL  IsClipboardFormatAvailable( UINT format );  
此函數用來判斷剪貼簿上的資料格式是否為 format 指定的格式。

(6)HANDLE  GetClipboardData( UINT uFormat );  
此函數依據 uFormat 指定的格式,傳回以指定格式存在於剪貼簿中的剪貼簿物件的句柄。

2、共享記憶體分配
(1)HGLOBAL  WINAPI  GlobalAlloc( UINT  uFlags,   SIZE_T  dwBytes );
第一個參數 uFlags 用來指定分配記憶體的方式。其值如下列表所示但是在剪貼簿的使用中,由於要實現動態資料交換,所以必須得使用 GHND 或 GMEM_MOVEABLE):
GHND   GMEM_MOVEABLE 和 GMEM_ZEROINIT 的組合。
GMEM_FIXED  分配一塊固定內存,回傳值是一個指標。
GMEM_MOVEABLE    分配一塊可移動記憶體。
GMEM_ZEROINIT        初始化記憶體的內容為 0
GPTR          即 GMEM_FIXED 與 GMEM_ZEROINIT 的組合。
第二個參數 dwBytes 用來指定指派的位元組數。

(2)HGLOBAL  WINAPI  GlobalReAlloc(HGLOBAL hMem,  SIZE_T dwBytes,  UINT uFlags);
此函數為再分配函數,即在原有的資料物件 hMem 上,為其擴大記憶體空間。
第一個參數 hMem 代表由 GlobalAlloc 函數傳回的資料物件句柄。
第二個參數 dwBytes 指定需要重新分配的記憶體的大小。
第三個參數 uFlags 指定分配的方式(可以參考 GlobalAlloc 函數)。

(3)SIZE_T  WINAPI  GlobalSize( HGLOBAL  hMem );
此函數用來傳回記憶體區塊的大小。
第一個參數 hMem 代表由 GlobalAlloc 函數傳回的資料物件句柄。

(4)LPVOID  WINAPI  GlobalLock( HGLOBAL  hMem );
此函數的作用是將全域記憶體物件加鎖,然後傳回該物件記憶體區塊第一位元組的指標。
第一個參數 hMem 代表由 GlobalAlloc 函數傳回的資料物件句柄。

(5)BOOL  WINAPI  GlobalUnlock( HGLOBAL  hMem );
你透過上面的GlobalLock 函數可以獲得這塊全域記憶體的存取權,
加鎖的意思就是你已經在使用這塊全域內存了,別的程式就不能再使用這塊全域內存了,而如果你一直不解鎖,那也不是個事啊,別的程式將會一直都使用不了這塊全局內存,那還叫全局內存幹嗎啊?所以這個函數就是用來對全域記憶體物件解鎖。
第一個參數 hMem 代表由 GlobalAlloc 函數傳回的資料物件句柄。

(6)HGLOBAL  WINAPI  GlobalFree( HGLOBAL  hMem );
此函數釋放全域記憶體區塊。
第一個參數 hMem 代表由 GlobalAlloc 函數傳回的資料物件句柄。

以下為範例程式碼,讀者也可以透過自己自電腦上進行Ctrl C(拷貝資料到剪貼簿) Ctrl V(從剪貼簿上拷貝資料) 進行某一項測試:

// Ctrl+C.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>  #include <process.h>  #include <windows.h>  using namespace std;int main()
{
    HWND hWnd = GetClipboardOwner();//获取当前剪贴板所属的窗口句柄
    DWORD Len = 32;
    HGLOBAL pClipData;
    pClipData = GlobalAlloc(GHND,Len+1);//分配共享内存

    char* pData;
    pData = (char*)GlobalLock(pClipData);//内存控制句柄加锁,其他进程不能再访问

    for(int i = 0;i < Len;i++)
    {
        pData[i] = &#39;a&#39;+i;                //在全局内存中赋值
    }

   GlobalUnlock(pClipData);//内存控制句柄解锁,其他进程可以访问

   if(!OpenClipboard(hWnd))//打开剪贴板
   {       cout<<"OPen fail!"<<endl;       return 0; 
   }

   EmptyClipboard();//清空剪贴板,这一步才真正拥有剪贴板
   SetClipboardData(CF_TEXT,pClipData);//将共享内存里的数据放入剪贴板
   CloseClipboard();//关闭剪贴板

   cout<<"剪贴完成"<<endl;   return 0;
}
//Ctrl+V.cpp#include "stdafx.h"#include <iostream>  #include <process.h>  #include <windows.h>  using namespace std;int main()
{
    HWND hWnd = GetClipboardOwner();//获取当前剪贴板所属的窗口句柄

    if(!OpenClipboard(hWnd))//打开剪贴板
    {        cout<<"OPen fail!"<<endl;        return 0; 
    }    if(IsClipboardFormatAvailable(CF_TEXT))
    {
         HANDLE hCilpData = GetClipboardData(CF_TEXT);
         DWORD Len = GlobalSize(hCilpData);          char* pData;
          pData = (char*)GlobalLock(hCilpData);//内存控制句柄加锁,其他进程不能再访问
          cout<<"剪贴板内容是:"<<pData<<endl;
          GlobalUnlock(hCilpData);//内存控制句柄解锁,其他进程可以访问
    }

   EmptyClipboard();//清空剪贴板,这一步才真正拥有剪贴板

   CloseClipboard();//关闭剪贴板

   cin.get();   return 0;
}

以上是如何理解C++ MFC進程間通訊之剪貼簿的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JVM中的類加載程序子系統如何促進平台獨立性?JVM中的類加載程序子系統如何促進平台獨立性?Apr 23, 2025 am 12:14 AM

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器會產生特定於平台的代碼嗎?解釋。Java編譯器會產生特定於平台的代碼嗎?解釋。Apr 23, 2025 am 12:09 AM

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

JVM如何處理不同操作系統的多線程?JVM如何處理不同操作系統的多線程?Apr 23, 2025 am 12:07 AM

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

在Java的背景下,'平台獨立性”意味著什麼?在Java的背景下,'平台獨立性”意味著什麼?Apr 23, 2025 am 12:05 AM

Java的平台獨立性是指編寫的代碼可以在任何安裝了JVM的平台上運行,無需修改。 1)Java源代碼編譯成字節碼,2)字節碼由JVM解釋執行,3)JVM提供內存管理和垃圾回收功能,確保程序在不同操作系統上運行。

Java應用程序仍然可以遇到平台特定的錯誤或問題嗎?Java應用程序仍然可以遇到平台特定的錯誤或問題嗎?Apr 23, 2025 am 12:03 AM

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

雲計算如何影響Java平台獨立性的重要性?雲計算如何影響Java平台獨立性的重要性?Apr 22, 2025 pm 07:05 PM

云计算显著提升了Java的平台独立性。1)Java代码编译为字节码,由JVM在不同操作系统上执行,确保跨平台运行。2)使用Docker和Kubernetes部署Java应用,提高可移植性和可扩展性。

Java的平台獨立性在廣泛採用中扮演著什麼角色?Java的平台獨立性在廣泛採用中扮演著什麼角色?Apr 22, 2025 pm 06:53 PM

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

容器化技術(例如Docker)如何影響Java平台獨立性的重要性?容器化技術(例如Docker)如何影響Java平台獨立性的重要性?Apr 22, 2025 pm 06:49 PM

容器化技術如Docker增強而非替代Java的平台獨立性。 1)確保跨環境的一致性,2)管理依賴性,包括特定JVM版本,3)簡化部署過程,使Java應用更具適應性和易管理性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版