我在打开菜单中调用如下函数显示一个数值图像,
怎么在SDI的客户区显示时,有时有图,有时没有图显示啊!
而且窗口被覆盖的地方的图也没有了。???求高手指点。
我原来用VB在PICTURE控件中用如下方法显示图时就没有这个问题啊!
BOOL CQViewView::ReadDatFile(CString FName)
{
FILE *ip;
int x=0,y=0;
char buf[1024];
if((ip=fopen((LPSTR)(LPCTSTR)FName,"rb"))==NULL)
{
AfxMessageBox("LoadImage failed");
return FALSE;
}
CPaintDC dc(this);
while(!feof(ip))
{
fread(buf,1024,1,ip);
y++;//帧计数
for(x=0;x<1024;x++)
{
dc.SetPixel(x,y,RGB(buf[x],buf[x],buf[x]);
}
} fclose(ip);
return TRUE;
}
怎么在SDI的客户区显示时,有时有图,有时没有图显示啊!
而且窗口被覆盖的地方的图也没有了。???求高手指点。
我原来用VB在PICTURE控件中用如下方法显示图时就没有这个问题啊!
BOOL CQViewView::ReadDatFile(CString FName)
{
FILE *ip;
int x=0,y=0;
char buf[1024];
if((ip=fopen((LPSTR)(LPCTSTR)FName,"rb"))==NULL)
{
AfxMessageBox("LoadImage failed");
return FALSE;
}
CPaintDC dc(this);
while(!feof(ip))
{
fread(buf,1024,1,ip);
y++;//帧计数
for(x=0;x<1024;x++)
{
dc.SetPixel(x,y,RGB(buf[x],buf[x],buf[x]);
}
} fclose(ip);
return TRUE;
}
正在为MFC头晕中呢!
里面pDC
就相当于你用的 CPaintDC dc(this); 给你个小例子吧!http://www.vckbase.com/code/listcode.asp?mclsid=7&sclsid=701
CDC *dc=GetDC(this);
后图像正常显示了,
但是还是窗口一被别的窗口覆盖或最小化后图像就没有了
在paint中draw到View中,
但我不知如何去做啊?
WINDOWS机制使得一个窗口在作被令一个窗口覆盖后又重新出现或者最小化、最大化等动作时都需要重画。然而重画时必需要有相应的数据才能画出您需要的东西来。
你在点菜单时画好了图,同时也关掉了存有图片数据的文件,这样当窗口重画时自然找不到图象数据,也只能画出白白的一片。
解决这个问题有两种途径,其一,将你的这段代码转移到CQViewView的OnDraw函数(应该VC已经给你添加了这个函数,找找看)里,这样一来每次重画窗口时都会读文件画图,就不会出现白画面了,缺点是它不会理你的菜单操作,自己早早的就把图画出来了。第二种方法就麻烦了,你要先把图象文件里的内容读到程序中来,放到某个能贮存它们的地方,比如说文档类,然后在View类里将这些数据画出来;画图代码可以在OnDraw里实现,读取图片信息可以在你的菜单响应函数里实现,至于各函数间如何共享图片数据,那方法就更多了,这里就不多讲了。
当窗口变化时,windows 总会调用Ondraw 函数, 如果你不在里面调用,那么再好看
的图片也会被重画命令覆盖掉
可以我的程序是通过菜单打开CFileDIALOG后
选一个文件,然后显示啊!这个功能不能写在ONDRAW或ONPAINT中啊!
而且,显示图时是向上滚动显示的。
晕晕。。
其实最好的办法是利用“文档——视图”结构来实现画图(此处不熬述),因为这样你可以利用很多文档类的良好性质(比如说永久性存贮)。如果你的目的仅仅是画图,那也可以不用文档类。
你可以直接在你的CQViewView(它应当是继承于CView的)类里添加一个成员变量:m_buff,
把你的菜单响应函数(BOOL CQViewView::ReadDatFile)里的画图部分删除,替换成给m_buff附值的语句(具体怎么实现你应当知道了,我认为m_buff应当是一个二维数组,来存放像素的颜色信息),在函数的末尾加一句Invalidate();。接下来你应当在OnDraw函数里利用SetPixel把m_buff的信息画到屏幕上来就行了。其效果完全等同于你原来的做法,而且也解决了图片失踪的问题。
原来用BCB时是在内存在NEW一个BITMAP对象,
再设置BITMAP对象的象素位,再动态根据窗口的
TRECT大小设置BITMAP的Width与Height,就可以用setpixel
在BITMAP中绘图了,在BCB的OnPaint()中将BITMAP给
Form1->Canvas->Draw(...)上。但是在VC中我
一直想也用如上方法,但没完成这个功能。
CClientDC dc(this);
CDC MemDC;//声明内存设备文本对象
MemDC.CreateCompatibleDC(&dc);//创建兼容内存设备
将位图选入内存设备文本对象
CBitmap*pbmpOld=MemDC.SelectObject(&m_Bitmap);《《--这里是否要选定一张位图(白底)
pDC->StretchBlt(0,0,m_Width,m_Height,&MemDC,
0,0,m_Width,m_Height,SRCCOPY);//显示位图
CRect rcClientRect;//定义一个矩形对象
GetClientRect(&rcClientRect);//取得窗口客户区尺寸
pDC->StretchBlt(0,0,rcClientRect.right,rcClientRect.bottom,
&MemDC,0,0,m_Width,m_Height,SRCCOPY);//显示改变后的位图
MemDC.SelectObject(pbmpOld);//恢复原状
没试成啊!滚动:就是象电影字幕向上滚动那样。我是在窗口的最下面一行绘图,再用StretchBlt
将图像COPY到RECT(0,0,Width,Heigh-1)的位置,接下来再在最后一行象素绘新数据,
之后,再将图像COPY到RECT(0,0,Width,Heigh-1)的位置,循环下去就是滚动显示图像了。
重载OnPaint()函数,你把显示图片的函数放到OnPaint()里,然后定义全局变量
BOOL m_DrawFlag=FALSE;
在加一个响应显示图片消息的函数
比如
void CQViewView::OnShow()
{
m_DrawFlag=TRUE;
S endMessage(WM_PAINT);
}
void CQViewView::OnPaint()
{
if(m_DrawFlag)
ReadDatFile(CString FName);
}
BOOL CQViewView::ReadDatFile(CString FName)
{
FILE *ip;
int x=0,y=0;
char buf[1024];
if((ip=fopen((LPSTR)(LPCTSTR)FName,"rb"))==NULL)
{
AfxMessageBox("LoadImage failed");
return FALSE;
}
CPaintDC dc(this);
while(!feof(ip))
{
fread(buf,1024,1,ip);
y++;//帧计数
for(x=0;x<1024;x++)
{
dc.SetPixel(x,y,RGB(buf[x],buf[x],buf[x]);
}
} fclose(ip);
return TRUE;
}