学习MFC做个简单画图软件遇到的问题

gumuguo 2008-10-08 06:41:11
1.在画图时,如画直线,长方形,在view中的mousemove消息时显示图像变化,但是不刷新前会留下以前鼠标拖动时留下的痕迹,如果在每次mousemove的末尾加入this->invalidate(NULL)又会使画面极度闪动,而且当前鼠标拖到的位置都不会显示出图像,只有在LBUTTONUP时才显示.知如何解决.
2.我可以保存文件,但是保存文件没有后缀名,即保存文件时的那个对话框是*.*,不知如何加入后缀名。
3.我想加入移动图形的功能,即可以选中图形后,随鼠标拖动而图形移动,BUTTONUP时,图形确定位置,给些提示。
...全文
548 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hhhh63 2008-10-09
  • 打赏
  • 举报
回复
GDI+
alphawb 2008-10-09
  • 打赏
  • 举报
回复
学习一下
我是苦力 2008-10-09
  • 打赏
  • 举报
回复
顶一下看看!
job82824 2008-10-09
  • 打赏
  • 举报
回复
一般的都是在LBUTTONUP消息中显示最后的图像,而绘图时在MOUSEMOVE中可以仅仅显示一个轮廓--比如虚线框,跟随着鼠标变化;

保存文件后缀名为.dat
//获取保存文件名
CFileDialog dlgFile(FALSE, NULL, NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"dat文件(*.dat)|*.dat");
if(dlgFile.DoModal()!=IDOK)
return;
CString str = dlgFile.GetPathName();

//保存文件
FILE *f = fopen((LPSTR)(LPCTSTR)str, "write");
if(!f)
{
AfxMessageBox("File open failed!");
return;
}
......//文件书写部分略


移动图形位置,首先LBUTTONDOWM时将图形变灰,也就是将它的颜色变灰--可以RGB(X1,X2,X3)-->RGB(X1-y,X2-y,X3-y);不过这样可能速度较慢,可以考虑使用一个图层罩在原背景上,两者进行透明颜色运算;
接着MOUSEMOVE中绘制一个空心的虚线框--用于表示图形移动后的位置,虚线框可以用pDC->MoveTo,pDC->LineTo绘制四条直线组成,并且跟随鼠标运动;
最后当然是LBUTTONUP事件,需要完成两个动作--擦除背景和重新绘制,将原先图形所在的矩形区域擦除掉--用你的背景色擦出,然后在新的矩形区域上面将图像绘制出来。
这样就完成了一个图形的移动了。

使用MS的产品VC++来做就这么简单。
FireBirdCN 2008-10-09
  • 打赏
  • 举报
回复
第一个第三个问题基本差不多
双缓冲是不错的解决方法
另外建议楼主也看看 GDI+方面的东西

第二个问题是保存文件时 FileDialog的过滤器设置

CFileDialog Save(FALSE,NULL,NULL,OFN_HIDEREADONLY,NULL,NULL); //函数构造时要传参
Save.m_ofn.lpstrTitle="保存文件"; //对话框标题
Save.m_ofn.lpstrFilter="文本文件(*.txt)\0*.txt\0所有文件(*.*)\0*.*\0\0";//文件过滤
yangsh3002 2008-10-09
  • 打赏
  • 举报
回复
1,首先设置一个结构,保存你要画的东西:
struct sLine
{
CPoint startPoint;
CPoint endPoint;
}
2,然后设置画图模式:
pDC->SetRop2(R2_NOTXORPEN);
3,然后开始画图,在鼠标按下事件中画图:
sLine.startPoint.x = x;
sLine.startPoint.y = y;
sLine.endPoint.x = x;
sLine.endPoint.y = y;
pDC->MoveTo(sLine.startPoint.x,sLine.startPoint.y);
pDC->LineTo(sLine.endPoint.x,sLine.endPoint.y);
//设置画图状态
bDrawLine = true;
在鼠标移动事件中:
//检测画图状态
if(!bDrawLine)
return;
//擦掉原来的图
pDC->MoveTo(sLine.startPoint.x,sLine.startPoint.y);
pDC->LineTo(sLine.endPoint.x,sLine.endPoint.y);
//画新图
pDC->MoveTo(sLine.startPoint.x,sLine.startPoint.y);
pDC->MoveTo(x,y);
//存储新图
sLine.endPoint.x = x;
sLine.endPoint.y = y;
在鼠标抬起事件中:
//取消画图状态
bDrawLine = false;
LIUMQX 2008-10-09
  • 打赏
  • 举报
回复
使用双缓存,在内存中先画出来,然后再贴出来。
zongran 2008-10-09
  • 打赏
  • 举报
回复
1.调用CDC类里面的SetRop2(R2_XORPEN)函数在绘图方法的前面.

2.保存文件的后最缀名不需要改,如果一定要改就在后缀名选择上选一个.

3.方法和1类似.只需要在处理鼠标点击消息的时候做些处理.还有一点注意判断鼠标和图形的位子.
gumuguo 2008-10-08
  • 打赏
  • 举报
回复
可以说清楚点么,比如调用哪些函数。
harry330 2008-10-08
  • 打赏
  • 举报
回复
用异或方式檫除之前画的。如画直线
pDC->SetROP2(R2_XORPEN);

pDC->MoveTo(...);
//第一次调用,画线
pDC->LineTo(...);
//第二次调用,檫除之前的线(两次画在同一位置)
pDC->LineTo(...);
ok208043624 2008-10-08
  • 打赏
  • 举报
回复
1.避免闪烁,使用双缓存绘图....
2....
3.同1,如果使用了双缓存绘图,这个功能就很好实现了...只需在调用BitBlt时改变坐标值就行了...

16,548

社区成员

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

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

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