假如窗口的绘图函数
void DrawObject(HDC hdc)
{
rectangle(hdc, 100, 100, 200, 200);
}
void ondraw(HDC hdc)
{
DrawObject(hdc);
}
以上的代码在窗口的 100 100的位置绘制一个矩形。我现在是这样的,我要首先创建一个内存DC,尺寸是100 ,100 然后再绘制这个矩形在窗口的100,100 位置。
可是我不希望修改 DrawObject 函数。void ondraw(HDC hdc)
{
HDC hmemdc = CreateCompatibleDC(hdc);
HBitmap bmp = CreateCompatibleBitmap(hDC, 100, 100);
SelectObject(hmemdc, bmp);
DrawObject(hmemdc); //注意这里,新建的内存DC,默认左上角是0, 0, 和原始的hdc坐标是不一样的
BitBlt( 100, 100, 100, 100, 0, 0, SRCCOPY);
}** 我不希望修改 drawobject. 也许需要调用 SetViewportOrgEx 之类的函数修改 内存dc的左上角坐标吧。总之就是第一个方法和第2个方法绘制的位置是一样的。 我试了很多不太会弄。谢谢各位了!
void DrawObject(HDC hdc)
{
rectangle(hdc, 100, 100, 200, 200);
}
void ondraw(HDC hdc)
{
DrawObject(hdc);
}
以上的代码在窗口的 100 100的位置绘制一个矩形。我现在是这样的,我要首先创建一个内存DC,尺寸是100 ,100 然后再绘制这个矩形在窗口的100,100 位置。
可是我不希望修改 DrawObject 函数。void ondraw(HDC hdc)
{
HDC hmemdc = CreateCompatibleDC(hdc);
HBitmap bmp = CreateCompatibleBitmap(hDC, 100, 100);
SelectObject(hmemdc, bmp);
DrawObject(hmemdc); //注意这里,新建的内存DC,默认左上角是0, 0, 和原始的hdc坐标是不一样的
BitBlt( 100, 100, 100, 100, 0, 0, SRCCOPY);
}** 我不希望修改 drawobject. 也许需要调用 SetViewportOrgEx 之类的函数修改 内存dc的左上角坐标吧。总之就是第一个方法和第2个方法绘制的位置是一样的。 我试了很多不太会弄。谢谢各位了!
解决方案 »
- OnSizing 问题
- 请问个人空间里上传的资源如何删除,200分(急)
- 求MFC实现类似MS的cmd.exe的界面。只要有界面就可以了
- 问一个有关CString的问题
- 谁知道BCGControlbar Pro 621的密码是多少?
- 以指针返回静态字符串,然后用ofstream输出时,可能会引起不正确的结果?为什么?
- 怎样能让AfxMessageBox()的窗口,自定义(如,我希望平面的不是立体的)
- NT4 支不支持USB鼠标
- 急用:怎样防止图象拖动是的抖动问题
- 莱鸟提问:怎样在整数型数列中统计连续2个...4,4,....的个数?
- :: 与 -> 的区别
- mfc opengl 绘图只显示一半是怎么回事啊??请高手帮忙看看。
在函数外部建好内存DC并初始化,传hDC进去就行了。 HDC hmemdc = CreateCompatibleDC(hdc);
HBitmap bmp = CreateCompatibleBitmap(hDC, 100, 100);
SelectObject(hmemdc, bmp);
ondraw(hmemdc);
第一个参数输入是DC句柄,你想修改哪个内存就用DC的HDC
第二个参数输入是X,不解释
第三个参数输入是Y,不解释
第四个参数是输出的POINT点
{
HDC hmemdc = CreateCompatibleDC(hdc);
HBitmap bmp = CreateCompatibleBitmap(hDC, 100, 100);
SelectObject(hmemdc, bmp);
POINT mypoint;
SetViewportOrgEx(hmemdc,x,y,&mypoint);
DrawObject(hmemdc); //注意这里,新建的内存DC,默认左上角是0, 0, 和原始的hdc坐标是不一样的
BitBlt(hdc, 100, 100, 100,100,hmemdc 0, 0, SRCCOPY); //这句有问题吧??要从hdc画,从hmemdc 读出
}
this->GetClientRect(rect);
CBitmap bmpFace;
bmpFace.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());(1)注意把握rect的尺寸为客户区域大小;
之后将这幅画选入内存DC中,
CBitmap* pOldBmp = NULL;
pOldBmp = MemDC.SelectObject(&bmpFace);; (2)
之后可以开始在内存DC中进行任何绘制动作;
CBrush brush(RGB(255,255,255));
MemDC.FillRect(rect,&brush);
for(int i=0;i<500;i++)
{
MemDC.MoveTo(22+i,22);
MemDC.LineTo(22+i,277);
}
绘制完后将内存DC中的这幅图绘制到屏幕DC中来,
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,rect.left,rect.top,SRCCOPY); (3)
最后进行相关的资源回收动作,
MemDC.SelectObject(pOldBmp);
bmpFace.DeleteObject();。上述代码至少有三处需要注意的地方,我已经标上了序号。其中(1)创建了一个与显示DC相兼容的位图,参数2,3指明了位图的大小,(2)处将这个 位图选入了内存DC中,默认位图的左上角与内存DC的(0,0)处相对应,这一步的作用是让内存DC “有地方用来作画”。经过接下来的一番涂抹之后,在第(3)步把内存DC中的内容复制到显示DC中,前4个参数指明了目的DC(也就是显示DC)的区域坐 标和大小,即我们想把内存DC中的内容复制到显示DC的什么位置,第5个参数指明了源DC(也就是内存DC),第6,7个参数指明了源DC的起始坐标,即 我们想对内存DC中从什么地方开始的内容进行复制。上述的例子中的矩形rect选用的是整个窗口客户区的矩形,所以下面的那些坐标都用的是这个矩形的坐标,这样就掩盖了坐标映射的问题。但是在我的工 程中并不是对整个窗口客户区进行双缓冲绘图,而是对窗口中的一个小矩形,于是我改变了rect的位置和大小,但其它的代码都没动,因此就显示不出东西了。 事实上,所有的绘图工作都顺利地进行了,只是都画在了我们看不到的地方。如果双缓冲的区域不是整个客户区的话,我建议这样做:在内存DC的(0,0)起始点作图,画完之后把内存DC中的内容复制到显示DC的所需的位置; 而不是在内存DC中的相应位置作图,然后在复制到显示DC所需位置,因为这样做的话需要在绘图时在内存DC中做太多的坐标变换,太麻烦。这个描述的就是我前面提到的我的问题。我从baidu找到的。 我现在要做的就是
“而不是在内存DC中的相应位置作图,然后在复制到显示DC所需位置,因为这样做的话需要在绘图时在内存DC中做太多的坐标变换”。因为我原先的那个绘图DrawObject 函数有特别多的代码。我不可能修改这个东西。所以就求坐标变换
{
HDC hmemdc = CreateCompatibleDC(hdc);
HBITMAP bmp = CreateCompatibleBitmap(hdc, 100, 100);
SelectObject(hmemdc, bmp);
RECT rect;
rect.bottom=100;
rect.right=100;
rect.top=rect.left=0;
HBRUSH brush=CreateSolidBrush(RGB(255,255,255));
::FillRect(hmemdc,&rect,brush);
POINT oldpoint,newpoint;
oldpoint.x=oldpoint.y=0;
newpoint.x=newpoint.y=-100;
SetViewportOrgEx(hmemdc,newpoint.x,newpoint.y,&oldpoint);
DrawObject(hmemdc);
SetViewportOrgEx(hmemdc,oldpoint.x,oldpoint.y,&newpoint);
BitBlt(hdc,100, 100, 100, 100,hmemdc,0, 0, SRCCOPY);
DeleteObject(bmp);
DeleteObject(hmemdc);
}
this->GetClientRect(rect);
CBitmap bmpFace;
bmpFace.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());(1)注意把握rect的尺寸为客户区域大小;
之后将这幅画选入内存DC中,
CBitmap* pOldBmp = NULL;
pOldBmp = MemDC.SelectObject(&bmpFace);; (2)
之后可以开始在内存DC中进行任何绘制动作;
CBrush brush(RGB(255,255,255));
MemDC.FillRect(rect,&brush);
for(int i=0;i<500;i++)
{
MemDC.MoveTo(22+i,22);
MemDC.LineTo(22+i,277);
}
绘制完后将内存DC中的这幅图绘制到屏幕DC中来,
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,rect.left,rect.top,SRCCOPY); (3)
最后进行相关的资源回收动作,
MemDC.SelectObject(pOldBmp);
bmpFace.DeleteObject();。上述代码至少有三处需要注意的地方,我已经标上了序号。其中(1)创建了一个与显示DC相兼容的位图,参数2,3指明了位图的大小,(2)处将这个 位图选入了内存DC中,默认位图的左上角与内存DC的(0,0)处相对应,这一步的作用是让内存DC “有地方用来作画”。经过接下来的一番涂抹之后,在第(3)步把内存DC中的内容复制到显示DC中,前4个参数指明了目的DC(也就是显示DC)的区域坐 标和大小,即我们想把内存DC中的内容复制到显示DC的什么位置,第5个参数指明了源DC(也就是内存DC),第6,7个参数指明了源DC的起始坐标,即 我们想对内存DC中从什么地方开始的内容进行复制。上述的例子中的矩形rect选用的是整个窗口客户区的矩形,所以下面的那些坐标都用的是这个矩形的坐标,这样就掩盖了坐标映射的问题。但是在我的工 程中并不是对整个窗口客户区进行双缓冲绘图,而是对窗口中的一个小矩形,于是我改变了rect的位置和大小,但其它的代码都没动,因此就显示不出东西了。 事实上,所有的绘图工作都顺利地进行了,只是都画在了我们看不到的地方。如果双缓冲的区域不是整个客户区的话,我建议这样做:在内存DC的(0,0)起始点作图,画完之后把内存DC中的内容复制到显示DC的所需的位置; 而不是在内存DC中的相应位置作图,然后在复制到显示DC所需位置,因为这样做的话需要在绘图时在内存DC中做太多的坐标变换,太麻烦。这个描述的就是我前面提到的我的问题。我从baidu找到的。 我现在要做的就是
“而不是在内存DC中的相应位置作图,然后在复制到显示DC所需位置,因为这样做的话需要在绘图时在内存DC中做太多的坐标变换”。因为我原先的那个绘图DrawObject 函数有特别多的代码。我不可能修改这个东西。所以就求坐标变换