程序間通信-剪貼闆
位于同一個程序中的多個線程共享同一個位址空間,是以線程之間的通信很簡單。
程序間通信的四種方式
剪貼闆
匿名管道
命名管道
郵槽
1、剪貼闆
Win32平台下,記憶體塊在實體記憶體中從來不會被移動,但可以在預設的堆中被移動。
BOOL OpenClipboard( );
打開了剪貼闆之後,還必須調用EmptyClipboard ,才能使目前視窗擁有剪貼闆。
BOOL EmptyClipboard(VOID)
SetClipboardData
The SetClipboardData function places data on the clipboard in a specified clipboard format.
The window must be the current clipboard owner, and the application must have called the
OpenClipboard function. (When responding to the WM_RENDERFORMAT and WM_RENDERALLFORMATS
messages, the clipboard owner must not call OpenClipboard before calling SetClipboardData.)
HANDLE SetClipboardData(
UINT uFormat, // clipboard format
HANDLE hMem // data handle
);
步驟:
a.打開剪貼闆:OpenClipboard,注意:一旦打開了剪貼版,其它運用程式将無法修改剪貼闆,直到調用了CloseClipboard。
b. 清空剪貼闆:EmptyClipboard,清空剪切闆,并将所有權傳遞給打開剪貼闆的運用程式
c. 為即将拷貝的内容配置設定記憶體空間:GlobalAlloc,第一個參數訓示配置設定記憶體的類型,重要的有兩類,GMEM_FIXED:Allocates fixed memory. The return value is a pointer;GMEM_MOVEABLE:Allocates movable
memory. In Win32, memory blocks are never moved in physical memory, but they can be moved within the default heap. The
return value is a handle to the memory object. To translate the handle into a pointer, use the GlobalLock function. This flag
cannot be combined with the GMEM_FIXED flag.
本例中采用GMEM_MOVEABLE,其傳回值是一個指向記憶體對象的句柄。
d. 将句柄轉換為指針:GlobalLock,将指定記憶體塊鎖定。
The internal data structures for each memory object include a lock count that is initially zero.
For movable memory objects, GlobalLock increments the count by one, and the GlobalUnlock
function decrements the count by one. For each call that a process makes to GlobalLock for an
object, it must eventually call GlobalUnlock. Locked memory will not be moved or discarded,
unless the memory object is reallocated by using the GlobalReAlloc function. The memory block
of a locked memory object remains locked until its lock count is decremented to zero, at which
time it can be moved or discarded.
e.将字元串的内容拷貝到可移動堆中:strcpy
f.釋放記憶體塊鎖定:GlobalUnlock
g.放置資料:SetClipboardData, The SetClipboardData function places data on the clipboard in a specified clipboard format. The
window must be the current clipboard owner, and the application must have called the OpenClipboard function.
SetClipboardData的第一個參數可以是指定的格式或NULL,如果是NULL,則采用的是延遲送出的技術,所謂延遲送出表示的是為了避免下面這種情況:當一個拷貝資料到剪貼闆的動作發生時,直到下一個從剪貼闆上取出資料的過程中,資料一直占用着記憶體空間,造成了資源浪費。為了改善這種情況,延遲送出技術采用SetClipboardData調用一個空的記憶體區塊,當下一個從剪貼闆取出資料的動作發生時,自動發送一個WM_RENERFORMAT消息,剪貼闆的所有者程式再次調用具有實際記憶體區塊參數的SetClipboardData方法,發生實際剪貼動作。第二次調用前不用再調用OpenClipboard方法。
h. 關閉剪貼闆:CloseClipboard
實作代碼如下:
if(OpenClipboard()) //打開剪貼闆
{
CString str;
HANDLE hClip; //剪貼闆句柄
char* pBuf;
EmptyClipboard();
GetDlgItemText(IDC_EDIT_SEND,str);
//配置設定記憶體的長度一般是字元串的長度加1用來存放空字元,否則系統将自動覆寫掉現有字元串的最後一位用來存放空字元,空字元作為結尾辨別
hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);
pBuf=(char*)GlobalLock(hClip); //将句柄轉換為指針,傳回記憶體對象位址并加鎖,如果GlobalAlloc參數是GMEM_FIXED,則這樣不需要這樣的轉換。 GMEM_FIXED鎖計數總為零,該語句将增長Lock數
strcpy(pBuf,str); //為配置設定好的記憶體空間填充想賦的值
GlobalUnlock(hClip); //如果GlobalAlloc參數是GMEM_FIXED,則不起作用。該語句将減少Lock數,如果Lock數為0,則指定動态記憶體區域将可被移動和抛棄
SetClipboardData(CF_TEXT,hClip); //以指定格式存放資料,不完成指定格式轉換,不能完成粘貼
CloseClipboard();
}
從剪貼闆上提取資料:
具體代碼如下:
if(OpenClipboard())
{ GMEM_FIXED
if(IsClipboardFormatAvailable(CF_TEXT)) //指定格式資料在接貼闆上是否存在
{
HANDLE hClip=GetClipboardData(CF_TEXT); //從剪貼闆上得到資料,且拿到了資料塊的句柄
char* pBuf;
pBuf=(char*)GlobalLock(hClip);
GlobalUnlock(hClip);
SetDlgItemText(IDC_EDIT_RECV,pBuf);
}
CloseClipboard();