剪析板基本操作

Clipboard 问答集
在我们自己的VC++ / MFC应用程序中增加剪贴板功能其实是很简单的事情。为了让你的程序可以与剪贴板对话,本文就其实现中的一些基本问题做一些实例讲解。
拷贝与粘贴文本
下边的源代码演示了如何将文本(包含在CString对象“source”中)拷贝到剪贴板上。
CString source;
//put your text in source
if(OpenClipboard())
{
        HGLOBAL clipbuffer;
        char * buffer;
        EmptyClipboard();
        clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength()+1);
        buffer = (char*)GlobalLock(clipbuffer);
        strcpy(buffer, LPCSTR(source));
        GlobalUnlock(clipbuffer);
        SetClipboardData(CF_TEXT,clipbuffer);
        CloseClipboard();
}
反过来,下面的代码是用来实现从剪贴板上取得文本的。
char * buffer = NULL;
//open the clipboard
CString fromClipboard;
if ( OpenClipboard() )
{
        HANDLE hData = GetClipboardData( CF_TEXT );
        char * buffer = (char*)GlobalLock( hData );
        fromClipboard = buffer;
        GlobalUnlock( hData );
        CloseClipboard();
}
拷贝与粘贴WMF(enhanced)数据
你想在你的程序中往剪贴板上“画”以及向剪贴板读取图形吗?请放心,这个不难!示范代码如下,其实现的是往剪贴板上写一enhanced metafile。
if ( OpenClipboard() )
{
        EmptyClipboard();
        //create the metafile DC
        CMetaFileDC * cDC = new CMetaFileDC();
        cDC->CreateEnhanced(GetDC(),NULL,NULL,"the_name");
        //call draw routine here that makes GDI calls int cDC
        //close meta CMetafileDC and get its handle
        HENHMETAFILE handle = cDC->CloseEnhanced();
        //place it on the clipboard
        SetClipboardData(CF_ENHMETAFILE,handle);
        CloseClipboard();
        //delete the dc
        delete cDC;
}
好啦,该演示反过来怎么做的代码了。我们从剪贴板上取得metafile并将其画到自己的应用程序的客户区DC(设备上下文)上(仅仅是个试验而已,实际上你可能更想将它拷贝一份儿)。
if ( OpenClipboard() )
{
        //Get the clipboard data
        HENHMETAFILEhandle=
(HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE);
        //play it into a DC (our own DC in this example)
        CClientDC dc(this);
        CRect client(0,0,200,200);
        dc.PlayMetaFile(handle,client);
        //close the clipboard
        CloseClipboard();
}
拷贝与粘贴一张位图(BitMap)
拷贝和粘贴位图可是需要一些微妙的处理的,不过基本的思想还是一样。请看下面的代码。
if ( OpenClipboard() )
{
        EmptyClipboard();
        //create some data
        CBitmap * junk = new CBitmap();
        CClientDC cdc(this);
        CDC dc;
        dc.CreateCompatibleDC(&cdc);
        CRect client(0,0,200,200);
        junk->CreateCompatibleBitmap(&cdc,client.Width(),client.Height());
        dc.SelectObject(junk);
        //call draw routine here that makes GDI calls
        DrawImage(&dc,CString("Bitmap"));
        //put the data on the clipboard
        SetClipboardData(CF_BITMAP,junk->m_hObject);
        CloseClipboard();
        //copy has been made on clipboard so we can delete
        delete junk;
}
如下示例代码是从剪贴板上取得一张位图,将它粘贴到客户区DC中。
if ( OpenClipboard() )
{
        //Get the clipboard data
        HBITMAP handle = (HBITMAP)GetClipboardData(CF_BITMAP);
        CBitmap * bm = CBitmap::FromHandle(handle);
        CClientDC cdc(this);
        CDC dc;
        dc.CreateCompatibleDC(&cdc);
        dc.SelectObject(bm);
        cdc.BitBlt(0,0,200,200,&dc,0,0,SRCCOPY);
        CloseClipboard();
}
建立并使用你自己定做的数据格式
如果你要拷贝、粘贴其它格式的数据,可以用RegisterClipboardFormat() API函数先将此格式注册,然后就可以“为所欲为”了。这简直是太有用了,尤其是在我们自己的应用程序中拷贝资料。假设我们有下面的结构:
struct MyFormatData
{
        long val1;
        int val2;
};
想将此结构的数据拷贝到剪贴板上。可以这样实现:
UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
if(OpenClipboard())
{
        //make some dummy data
        MyFormatData data;
        data.val1 = 100;
        data.val2 = 200;
        //allocate some global memory
        HGLOBAL clipbuffer;
        EmptyClipboard();
        clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(MyFormatData));
        MyFormatData * buffer = (MyFormatData*)GlobalLock(clipbuffer);
        //put the data into that memory
        *buffer = data;
        //Put it on the clipboard
        GlobalUnlock(clipbuffer);
        SetClipboardData(format,clipbuffer);
        CloseClipboard();
}
想把它从剪贴板上读下来的话,也容易:
// 第二次调用时,此格式已经注册过了,读下来就行了
UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
MyFormatData data;
if ( OpenClipboard() )
{
        //get the buffer
        HANDLE hData = GetClipboardData(format);
        MyFormatData * buffer = (MyFormatData *)GlobalLock( hData );
        // 留一份儿当地拷贝
        data = *buffer;
        GlobalUnlock( hData );
        CloseClipboard();
}
取得剪贴板变化通知(Getting notified of clipboard changes)
一旦剪贴板上的内容发生改变,我们都希望能够获知(经由windows消息),这是很有用的。你可以用函数SetClipboardViewer()来捕获WM_DRAWCLIPBOARD消息。
在你的初始化代码中调用:
        SetClipboardViewer(); //add us to clipboard change notification chain
在你的消息映射(message map)中添加:
        ON_MESSAGE(WM_DRAWCLIPBOARD, OnClipChange) //clipboard change notification
将其定义为:
        afx_msg void OnClipChange(); //clipboard change notification
实现为:
void CDetectClipboardChangeDlg::OnClipChange()
{
        //do something here, for example
        CTime time = CTime::GetCurrentTime();
        SetDlgItemText(IDC_CHANGED_DATE,time.Format("%a, %b %d, %Y -- %H:%M:%S"));
        DisplayClipboardText();
}
将数据粘贴到其它应用程序窗口中的方法
我觉得如果能把文本拷贝到剪贴板上(参见上面的代码),然后再在另外一个应用程序中将这些文本粘贴过来,那样才有用。我写了一个很不错的本地应用程序,此程序使用了含有此技术的第三方的语言翻译包。很简单,仅是取得目标窗口的句柄,并向它发送“PASTE”消息就OK了。
        SendMessage(m_hTextWnd, WM_PASTE, 0, 0);
 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值