高分求救,如何把CBitmap放到剪贴板上,我试了半天了,就是不行.请大家进来看看,谢谢啦!

rejoise 2005-08-08 04:10:42
代码很简单,用来Load bmp图片的,我不想用LoadImage,因为LoadImage在win98下面不能装载大图片,所以从网上找了一个方法LoadPictureFromFile.

Load完后我把图片放到剪贴板上,但是粘贴时就是死活说剪贴板数据出错.

LoadPictureFromFile这个方法是正确的,因为CBitmap已经取得,所以估计是剪贴板编程出错了

请大虾指教!


void LoadPictureFromFile(LPCTSTR szFile, CBitmap *pBitmap, CSize &mSize)
{
// open file
HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
_ASSERTE(INVALID_HANDLE_VALUE != hFile);

// get file size
DWORD dwFileSize = GetFileSize(hFile, NULL);
_ASSERTE(-1 != dwFileSize);

LPVOID pvData = NULL;
// alloc memory based on file size
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
_ASSERTE(NULL != hGlobal);

pvData = GlobalLock(hGlobal);
_ASSERTE(NULL != pvData);

DWORD dwBytesRead = 0;
// read file and store in global memory
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
_ASSERTE(FALSE != bRead);
GlobalUnlock(hGlobal);
CloseHandle(hFile);

LPSTREAM pstm = NULL;
// create IStream* from global memory
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
_ASSERTE(SUCCEEDED(hr) && pstm);

// Create IPicture from image file
LPPICTURE gpPicture;

hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);

_ASSERTE(SUCCEEDED(hr) && gpPicture);
pstm->Release();

OLE_HANDLE m_picHandle;

gpPicture->get_Handle(&m_picHandle);
pBitmap->DeleteObject();
pBitmap->Attach((HGDIOBJ) m_picHandle);

BITMAP bm;
GetObject(pBitmap->m_hObject, sizeof(bm), &bm);
mSize.cx = bm.bmWidth; //nWidth;
mSize.cy = bm.bmHeight; //nHeight;
}


void CSelfTest2Dlg::OnBnClickedButton1()
{
//我想装载一个bmp图片,不想用LoadImage,因为LoadImage在win98下面不能装载大图片,所以从网上找了一个方法LoadPictureFromFile
CBitmap* bmp =new CBitmap();
CSize sz;
//sz用来获得图片宽度和高度

LoadPictureFromFile("c:\\a.bmp",bmp,sz);
//跟踪代码可发现宽度和高度是正确的.所有bmp已经装载了
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,bmp->GetSafeHandle());
//SetClipboardData(CF_BITMAP,bmp->m_hObject); 这句也不行
CloseClipboard();
delete bmp;
//结果很奇怪,粘贴时剪贴板会数据报错.

}
...全文
228 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
rejoise 2005-08-08
  • 打赏
  • 举报
回复
这是我修改后的代码,同样是不行的
void CSelfTestDlg::OnBnClickedButton1()
{
//我想装载一个bmp图片,不想用LoadImage,因为LoadImage在win98下面不能装载大图片,所以从网上找了一个方法LoadPictureFromFile

HGLOBAL clipbuffer;
OpenClipboard();
EmptyClipboard();

clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(CBitmap));
CBitmap * buffer = (CBitmap*)GlobalLock(clipbuffer);

CSize sz;
//sz用来获得图片宽度和高度

LoadPictureFromFile("c:\\a.bmp",buffer,sz);

GlobalUnlock(clipbuffer);
//SetClipboardData(CF_BITMAP,buffer->m_hObject); //不行
SetClipboardData(CF_DIB,clipbuffer); //同样不行
CloseClipboard();
}
rejoise 2005-08-08
  • 打赏
  • 举报
回复
那我上面的代码到底应该怎么改呢?我试了你说的不行
Mr-Chen 2005-08-08
  • 打赏
  • 举报
回复
上有很多例子
Mr-Chen 2005-08-08
  • 打赏
  • 举报
回复
先使用GlobalAlloc申请一块内存,GlobalAlloc的返回值就是SetClipboardData的第二个参数。然后,使用GlobalLock获得指向这个地址的指针,强制转换为你要的类型,然后将你的数据拷贝到这个区域即可。
http://www.codeguru.com/Cpp/W-P/clipboard/
rejoise 2005-08-08
  • 打赏
  • 举报
回复
错误就是剪贴板无法获取数据
chenang(cha)请指教,详细一点,非常谢谢
chenang 2005-08-08
  • 打赏
  • 举报
回复
剪切板用的是共享内存区域,要被别的程序用到嘛,如果像楼主那样你关闭程序别人还怎么用啊,所以你要先申请一块共享内存区域,然后将数据填到这块内存区域中,再将这个地址传给SetClipboardData
注意,SetClipboardData函数的第二个参数要用GlobalAlloc函数申请,楼主先试一下你那种方法写文本到剪切板行不行,我想应该也会出错的,所以原因不在你是不是读图片成功,而是你用了局部内存,其它代码不允许访问该区域,出错信息楼主贴出来看看.
lixiaosan 2005-08-08
  • 打赏
  • 举报
回复
//copy
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;
}

//paste
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();
}
xqk 2005-08-08
  • 打赏
  • 举报
回复
upup
rejoise 2005-08-08
  • 打赏
  • 举报
回复
不好使啊,把delete bmp;注释掉还是报错
--------------------------
获取剪贴板数据出错!
快乐鹦鹉 2005-08-08
  • 打赏
  • 举报
回复
先别管是否泄漏,你将delete bmp;注释掉,然后再试试是否可以。
rejoise 2005-08-08
  • 打赏
  • 举报
回复
Load肯定是没问题的,我测试过,CBitmap可以保存到硬盘中
所以我估计是剪贴板编程错了
dirdirdir3 2005-08-08
  • 打赏
  • 举报
回复
CBitmap能不能够显示出来?

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧