我在内存中用CClientDC中绘制位图,定义的尺寸很大,怎么总是不能完全显示?子窗体位置变化后,对应的位图大小也跟着变,总是残缺不全。是不是用的DC类型不对?在后台绘制的位图,受当前活动视(子窗体)的大小影响吗?有没有解决办法?
解决方案 »
- 模拟键盘输入Ctrl+C后,GetClipboardData()却得不到文本内容?
- ON_NOTIFY 和 ON_NOTIFY_REFLECT 消息传递 ++急
- 菜鸟发问:VC中的ODBC和SQL运行中的问题,急
- 怎么动态修改string table里的值
- xp下,关于任务栏,修改注册表需要, 重启的问题。
- 关于MFC的一个BUG,没发现能修正的人!看大家有没有什么头绪?是关于CFileDialog的,代码请进来看。谁能解决此问题,100分相送!!
- 为什么switch(strT)当strT是字符串变量时不能用?
- 菜鸟问题:怎么样在运行时调整数组的大小?
- 求助把数据保存成biBitCount=16的位图的方法
- 线程函数!!
- 为什么使用ShellExecute()启动程序,当被调用程序关闭后,调用者的内存降不下来?如:
- 高分相送...关于VC连接MS SQL SERVER问题.有兴趣就进来.
2、响应ID_FILE_NEW,什么也不做。
3、响应DeleteContents函数,清除位图对象
if(m_Bitmap.m_hObject!=NULL)
m_Bitmap.DeleteObject();
4、在文档类的OnOpenDocument函数打开位图文件,初始化位图对象
if (IsModified())
TRACE0("Warning: OnOpenDocument replaces an unsaved document\n");
DeleteContents();
//设置等待鼠标
BeginWaitCursor();
//打开位图文件
HBITMAP hImage = (HBITMAP)LoadImage(NULL, lpszPathName, IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
EndWaitCursor();
if (!hImage) {
DWORD LastError = GetLastError();
// Error message should be fomatted with LastError included
AfxMessageBox("LoadImage failed");
return FALSE;
}
//构造位图对象
if (!m_Bitmap.Attach(hImage)) {
AfxMessageBox("Bitmap could not be attached");
return FALSE;
}
SetModifiedFlag(FALSE);
//更新所有视图
UpdateAllViews(NULL);
return TRUE;
5、在文档类头文件中添加代码
public:
HBITMAP GetHandle() const {return (HBITMAP)m_Bitmap.m_hObject;};
void SelectOldBitmap(CDC *pDCMem) {pDCMem->SelectObject(m_pOldBitmap);};
void SelectBitmap(CDC *pDCMem)
{m_pOldBitmap=pDCMem->SelectObject(&m_Bitmap);};
int GetBitmap(BITMAP* pBitMap) {return m_Bitmap.GetBitmap(pBitMap);};
protected:
CBitmap m_Bitmap;
CBitmap* m_pOldBitmap;
6、用类向导删除视类的OnInitialUpdate.
7、用类向导响应视类的OnUpdate函数.
void CXXXXView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
CXXXXDoc* pDoc = GetDocument();
//获得主窗口指针
CFrameWnd* pParentFrame = GetParentFrame();
BITMAP BitMap;
if (!pDoc->GetHandle())
return;
//获得位图结构
pDoc->GetBitmap(&BitMap);
//设置滚动条范围
SetScrollSizes(MM_TEXT, CSize(BitMap.bmWidth, BitMap.bmHeight));
//重新规划主窗口大小
pParentFrame->RecalcLayout();
ResizeParentToFit();
}
7、在视类的OnDraw显示
CXXXXDoc* pDoc = GetDocument();
BITMAP BitMap;
CDC DCMem;
// Do not call CWnd::OnPaint() for painting messages
ASSERT_VALID(pDoc);
if (!pDoc->GetHandle())
return;
//创建内存设备场景
if (!DCMem.CreateCompatibleDC(pDC))
TRACE0("DCMem.CreateCompatibleDC failed\n");
pDoc->SelectBitmap(&DCMem);
pDoc->GetBitmap(&BitMap);
//将位图拷贝到显示设备场景中,进行显示,这是没有缩放的显示
if (!pDC->BitBlt(0, 0, BitMap.bmWidth, BitMap.bmHeight, &DCMem, 0, 0, SRCCOPY))
TRACE0("BitBlt failed\n");
pDoc->SelectOldBitmap(&DCMem);
DCMem.DeleteDC();
8、用StrechBlt来实现图片的缩放,你可以先设定好自己的缩放模式和缩放参数。比如在头文件中
添加缩放参数变量int m_nStretchType;并在构造函数中初始化m_nStretch=STRECH_1_1;
#define STRECH_1_1 0
#define STRECH_FULL_X 1
#define STRECH_FULL_Y 2
#define STRECH_FULL 3
#define STRECH_CENTER 4
9、增加函数SetStrechType(int nStrechType)
{
m_nStrechType = nStrechType;
Invalidate();
}
10、实现缩放显示
在OnDraw()函数中先获得位图参数:
BITMAP bmp;
m_bmpImage.GetBitmap(&bmp);
//开始缩放
switch(m_nStrechType)
{
case STRECH_1_1://1:1
dc.BitBlt(r.left,r.top,r.Width(),r.Height(),&memdc,0,0,SRCCOPY);
break;
case STRECH_FULL_X://按宽度
dc.StretchBlt(r.left,r.top,r.Width(),bmp.bmHeight,&memdc,0,0,
bmp.bmWidth,bmp.bmHeight,SRCCOPY);
break;
case STRECH_FULL_Y://按高度
dc.StretchBlt(r.left,r.top,bmp.bmWidth,r.Height(),&memdc,0,0,
bmp.bmWidth,bmp.bmHeight,SRCCOPY);
break;
case STRECH_FULL://充满窗口
dc.StretchBlt(r.left,r.top,r.Width(),r.Height(),&memdc,0,0,
bmp.bmWidth,bmp.bmHeight,SRCCOPY);
break;
case STRECH_CENTER://居中显示,大小为窗口的一半
dc.StretchBlt(r.Width()/4,r.Height()/4,r.Width()/2,r.Height()/2,&memdc,0,0,
bmp.bmWidth,bmp.bmHeight,SRCCOPY);
break;
}
再创建内存设备场景,参考上面的OnDraw函数,然后if(!pDC->StretchBlt(.......))后面差不多一致,应该差不多了吧。