利用vc实现图形在特定位置的显示 菜鸟日记1+
实现起来是个很简单的东西,十几行代码,不过里面涉及的东西倒蛮多。总结一下,以便举一反三。 如发现错误,欢迎指出。
1.VC中图像的加载
- 第一种是直接以添加资源的方式直接加载(只能加载.bmp, 一般会命名为IDB_BITMAP1.)
然后利用CBitmap类的LoadBitmap函数进行加载
形如 CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
- 第二种是直接给出文件路径的方式加载(采用此方式,一定要把图片文件放在程序目录下,以便程序的传播)
然后利用LoadImage函数进行加载
形如 HBITMAP hbitmap = (HBITMAP)LoadImage(NULL,"图片名.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
注:后面要用到DeleteObject(hbitmap)以释放资源.
2.VC中控件坐标的定位
习惯用group控件事先确定图片的放置位置,然后再提取出此控件的坐标.
其中GetWindowRect函数得到是屏幕坐标(坐标原点位于屏幕左上角),GetClientRect函数得到的客户坐标(程序界面的左上角为原点).
形如 CRect rc;
GetDlgItem(IDC_IMAGE)->GetWindowRect(rc);
ScreenToClient(rc);
注:CRect类派生于tagRECT结构体(RECT的别名),一个CRect对象可以被当做RECT,LPCRECT,LPRECT来传递。
3.VC中图像的显示
是用dc进行显示,可采用双缓存机制,来提升效率,避免闪烁.
形如: CClientDC dc(this);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(&dc);
dc.BitBlt(rc.left,rc.top,rc.Width(),rc.Height(),&dcCompatible,0,0,SRCCOPY);
注:dc相关知识后来补上.
4.完整代码如下
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CRect rc;
GetDlgItem(IDC_IMAGE)->GetWindowRect(rc);
ScreenToClient(rc);
CClientDC dc(this); CDC dcCompatible;
dcCompatible.CreateCompatibleDC(&dc);
dcCompatible.SelectObject(&bitmap);
dc.BitBlt(rc.left,rc.top,rc.Width(),rc.Height(),&dcCompatible,0,0,SRCCOPY);
5.疑问
- 为什么需要从屏幕坐标系转换到客户区坐标系?
- 为什么用的不是GetDlgItem(IDC_IMAGE)->ScreenToClient(rc);
6.答
答1:很可能是因为bilblt类的GDI绘图函数使用的都是客户区坐标进行绘制,所以要转化。
但是是如果直接使用 GetDlgItem(IDC_IMAGE)->GetClientRect(rc); 得到的以该控件左上角为原点的坐标。
所以要写成 GetDlgItem(IDC_IMAGE)->GetClientRect(rc);
GetDlgItem(IDC_IMAGE)->ClientToScreen(rc);
ScreenToClient(rc);
注:测试通过,可是可以看出这样更麻烦了.
答2:dc相关知识
DC(Device Context)设备描述表,一个包含设备信息的结构体内存块,通过DC绘图可避免与设备驱动程序打交道。
有以下方式可以得到dc句柄或则指针
- 使用SDK全局函数
形如: HDC hdc; hdc = :: GetDC(m_hWnd); ::ReleaseDC(m_hWnd,hdc);
- 使用CDC类
形如 CDC *pDC = GetDC(); ReleaseDC(pDC);
- 使用CClientDC类
形如:CClientdc dc(this);
- 使用CWindowDC类
形如:CWindowDC dc(this);
注:CClientDC 可用于在视类客户区,框架类客户区;CWindowDC 还可以框架类非客户区进行绘制。其他调用需注意释放内存。