孙鑫 第十七课进程间通信之一 剪贴板

说明

剪贴板是内存中的一块共享区域,两个进程间通过共享剪贴板中的数据实现进程间通信的目的。

在本节课中,主要讲了当剪贴板中的数据是内存块对象时的操作方法。

在剪贴板编程时,对于数据是内存块对象的情况,在申请内存块时必须使用函数GlobalAlloc(),并且必须指定标识GMEM_MOVEALBLE,

在从剪贴板中取数据时也要对这一情况进行处理:获得内存块对象句柄,转换为指针再使用。


★ 写剪贴板步骤

①打开剪贴板(OpenClipboard)

②清空剪贴板(获得该剪贴板使用权)(EmptyClipboard)

③申请内存块(GlobalAlloc)

④锁定该内存块,使内存块对象句柄转换为指针以获得地址从而往该地址写数据(GlobalLock)

⑤往该地址写数据

⑥往剪贴板写数据(SetClipboardData)

⑦解除锁定(GlobalUnlock)

⑧关闭剪贴板(CloseClipboard)



★ 从剪贴板取数据步骤 

①打开剪贴板(OpenClipboard)

②判断是否是可以取的数据类型或根据不同数据类型做不同处理(IsClipboardFormatAvailable)

③获得某种类型的剪贴板对象句柄(GetClipboardData)

④锁定该句柄,获得指针(GlobalLock)

⑤使用该指针

⑥解除锁定(GlobalUnlock)

⑦关闭剪贴板

NOTE:从剪贴板取数据不能清空(EmptyClipboard), 原因你懂的!

关于解除锁定的调用位置,我认为可以放在关闭剪贴板之前的最后位置,当然孙鑫老师在视频里讲的时候把接触锁定操作放在紧接着获得指针之后的位置程序也没有问题。



相关函数

①打开剪贴板

BOOL   OpenClipboard(

HWND  hWndNewOwner //[in] 拥有打开的剪贴板的窗口句柄,如果为NULL则打开的剪贴板和当前任务关联

);

成功返回非0,失败返回0

eg.

if(::OpenClipboard(m_hWnd)) //打开,从CWnd类继承来的类都有m_hWnd句柄成员

{

    MessageBox(_T("打开剪贴板成功"));

}


②清空剪贴板

BOOL   EmptyClipboard(

void

);

成功返回非0,失败返回0

eg.

EmptyClipboard();


③申请内存块

HGLOBAL   GlobalAlloc(

UINT   uFlags,  //属性,常用的有GMEM_FIXED,  GMEM_MOVEABLE

SIZE_T   dwBytes //申请大小,字节单位

);

eg.

HGLOBAL  hMem = GlobalAlloc(GMEM_MOVEABLE, 100); //申请100字节内存块



④锁定,获得指针

LPVOID   GlobalLock(

HGOBAL  hMem

);

返回值为空指针,要根据需要把空指针转换为任何想要的指针。

eg.

char* pBuf = (char*)GlobalAlloc(GMEM_MOVEABLE, 100);      //锁定,获得指针

strcpy(pBuf, "hello world!");                                                //使用该指针

GlobalUnlock(hMem);                                                          //解除锁定



⑤往剪贴板写数据

HANDLE   SetClipboardData(

UINT  uFormat, //剪贴板格式,分为标准格式和注册格式

HANDLE  hMem //要写的数据句柄,如果是内存对象则是该对象的句柄

);

eg.

SetClipboardData(CF_TEXT, hMem); //写文本格式数据,该数据在内存块对象句柄hMem对应的块中



⑥从剪贴板读取数据

HANDLE   GetClipboardData(

UINT  uFormat //剪贴板格式

);

以内存块对象为例

eg.

HANDLE  hData = GetClipboardData(CF_TEXT);  //获得该内存块对象句柄

char* pBuf = (char*)GlobalLock(hData);            //根据句柄获得指针值

SetDlgItemText(IDC_EDIT_INFO, pBuf);            //使用该指针对应数据

GlobalUnlock(hMem);                                       //解除锁定



⑦判断是否是可以处理的剪贴板类型

BOOL   IsClipboardFormatAvailable(

UINT  format  //[in]  剪贴板格式

);

如果是可用的返回非0,不可用返回0

eg.

if(IsClipboardFormatAvailable(CF_TEXT))

{

    //codes

}

else if(IsClipboardFormatAvailable(CF_BITMAP))

{

    //codes

}

    //codes



⑧关闭剪贴板

BOOL   CloseClipboard(

void

);

eg.

CloseClipboard();





例子

/往剪贴板写数据,数据为一个内存块对象

if(::OpenClipboard(m_hWnd))

{

    EmptyClipboard(); //清空

    HGLOBAL  hMem = NULL;

    CString str = "";

    GetDlgItemText(IDC_EDIT_INFO, str);                                  //取得编辑框控件中的值

    hMem = GlobalAlloc(GMEM_MOVEABLE, str.GetLength() + 1); //分配空间

    char* pBuf = GlobalLock(hMem);                                          //锁定,获得地址

    strcpy(pBuf, str);                                                               //往该内存区域写值

    SetClipboardData(CF_TEXT, hMem);                                     //设置剪贴板值

    GlobalUnlock(hMem);                                                          //解除锁定

    CloseClipboard();                                                               //关闭剪贴板

}




/从剪贴板取数据,数据为一个内存块对象

if(::OpenClipboard(m_hWnd))

{

    if(IsClipboardFormatAvailable(CF_TEXT)         //如果是这种类型的数据做这种处理

    {

        HANDLE  hData = GetClipboardData(CF_TEXT); //获得该类型数据

        char* pBuf = (char*)GlobalLock(hData);           //锁定,句柄转换为指针

        SetDlgItemText(IDC_EDIT_INFO2, pBuf);         //设置编辑框值

        GlobalUnlock(hMem);                                      //解除锁定

    }


    else                                                       //其他类型数据

    {

        //codes

    }


    CloseClipboard();                                           //关闭剪贴板

}



补充

如果是位图格式的数据则不涉及到锁定解锁等步骤,因此锁定的目的是获得指针并往内存区域写值,而如果是位图则可以写剪贴板数据的时候写该位图的句柄就可以。

eg.

//写剪贴板

if(::OpenClipboard(m_hWnd))

{

    EmptyClipboard();

    HBITMAP  hBitmap = NULL;

    hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_BITMAP1));  //加载位图,获得该位图句柄

    SetClipboardData(CF_BITMAP, hBitmap); //写剪贴板数据,类型为CF_BITMAP

    CloseClipboard();

}


//读剪贴板

if(::OpenClipboard(m_hWnd))

{

    HANDLE  hData = GetClipboardData(CF_BITMAP); //获得该位图句柄

    //codes

}


孙鑫 第十七课进程间通信之一 剪贴板 - 大灰狼 - 大灰狼 的博客



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值