vc++深入详解学习笔记.docx
《vc++深入详解学习笔记.docx》由会员分享,可在线阅读,更多相关《vc++深入详解学习笔记.docx(87页珍藏版)》请在冰豆网上搜索。
vc++深入详解学习笔记
学习笔记
在程序运行时,当对话框及其子控件创建完成将要显示之前发送一个WM_INITDIALOG
因此在此消息响应函数中修改编辑框的串口过程。
比如设置焦点
WM_CTLCOLOR消息:
在一个子控件绘制时,会向父窗口发送此消息,来准备设备上下文,以便使用正确的的颜色来绘制该控件
响应函数:
OnCtlColor包含pDC指针:
绘制控件上下文
当前指针pWnd和一个要绘制的控件类型。
其值返回到画刷
10.7
位图的显示
1.创建位图
2.创建兼容DC
3.将位图选入兼容DC
4.将兼容DC中的位图贴到当前DC中
当擦除窗口时消息:
WM_ERASRBKGND
OnEraseBkgnd(CDC*pDC)
BOOLCMoniView:
:
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
CBitmapbitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CDCdcCompatible;
dcCompatible.CreateCompatibleDC(pDC);//创建一个和pDC指向DC兼容DC,
dcCompatible.SelectObject(&bitmap);
CRectrect;
GetClientRect(&rect);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
returnCView:
OnEraseBkgnd(pDC);
}
然而,BitBlt是1:
1复制的
此时就需要另外一个复制函数StretchBIt
BITMAPbmp;
bitmap.GetBitmap(&bmp);
在构建好bitmap后用GetBitmap函数来获取其结构体BITMAP对象bmp的值。
并使用到StretchBIt来表明对象的宽和高
实现代码:
pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
本例子在擦除窗口的时候来完成的也可以用视类提供的类似WM_PAINT消息响应函数的OnDraw函数在窗口重绘的时候来完成。
11图形的保存和重绘
WIN32应用程序编程接口(API)
四种坐标系:
1.世界坐标空间
2.页面空间
以上是逻辑空间,用世界坐标来完成旋转,斜切或者反射
3.设备空间
4.物理设备空间物理设备随(:
打印机,显示器)设置尺寸而变化
当应用程序调用SetWorldTransform
1->2->3->4(多为屏幕)
在实际编程中主要是从页面空间开始
页面空间到设备空间的转换,所用的是两个矩形的宽高比例从窗口原点到视口原点的转换
设备空间到物理空间转换只用于平移,而这是由Windows控制的
只需要考虑从页面空间到设备空间的转换
Windows对所有消息,所有非GDI函数和一些GDI函数永远使用设备坐标
映射模式
默认为像素模式MM_TEXT可以用SetMapMode来改变模式
逻辑坐标和设备坐标
而在事件如鼠标单击中是以设备坐标为单位即为像素为单位的值
CDC中提供2个成员函数:
SetViewportOrg和SetWindowOrg
对于重绘图形只需要在OnDraw函数中利用结构体来保存
起点终点和绘制类型就可以重绘了
创建结构体后我们可以用数组来保存这些创建的对象了
但是数组对象有个缺点就是只能存储一定的容量的元素
而每次绘制的图形个数是不定的因此要采用动态的存储结构来保存这些对象
如链表
集合类:
CString的集合类CStringArray容量是可以动态增加的
CPtrArray 支持void类型的指针数组,void*,任何类型的指针都能够直接赋值给他,无需进行强制类型转换:
为什么设置开关后会要先点一下才能使用铅笔工具
因为事件是在mousedown的时候开始的
当mouseup中case5运行时
才调用mousemove函数。
因此要循环中的case5要在mousedown判断。
关于连续线的重绘
分析:
画直线
设置一个点变量,当发生mousedown的时候
记录变量值=当前鼠标所点的坐标值
当发生mouseup的时候
首先移动到这个变量的点
然后画线到当前鼠标的点
画不规则线
在mousemove的事件中
dc.MoveTo(m_ptOrigin);
dc.LineTo(point)
不停地画直线并
m_ptOrigin=point;
将远不停变化
这和画多个矩形一样,点一样还需要一个结构体类来保存改变量。
结构体参数完成以后考虑如何调用这个保存结构体
因为是在mousemove事件中完成的
所以我们在此函数中完成保存结构体
以下是编写的可以进行矩形,点,直线,以及任意线的重绘的代码
for(inti=0;i{switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType){case1:pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0));break;case2:pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin);pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd);break;case3:pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)));break;case4:pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)));break;}//TODO:adddrawcodefornativedatahere}for(inty=0;y{if(((CLineh*)m_ptrArray1.GetAt(y))->m_nDrawType==5)//此处要判断一下函数,否则将会造成死循环,另只要注意在结构体中保存了点的坐标就可以完成任意线的绘制了{pDC->MoveTo(((CLineh*)m_ptrArray1.GetAt(y))->m_ptOrigin);pDC->LineTo(((CLineh*)m_ptrArray1.GetAt(y))->m_ptEnd);}}总结:先尝试用开关来完成鼠标按下时绘制连续线这个有个关键点在此函数中设置判断语句来用bool型变量开关来控制mousemove函数中绘线语句if(m_Ben==TRUE){//m_nDrawType=5;因为这个变量的值只能唯一,当按下铅笔按钮时就已经赋值给m_nDrawType了dc.MoveTo(m_ptOrigin);dc.LineTo(point);CLineh*plineh=newCLineh(m_nDrawType,m_ptOrigin,point);m_ptrArray1.Add(plineh);m_ptOrigin=point;}另在CGraph中我们只保存了一维数组我们也可以将CLINE结构体写入CGrpah中来用一个语句完成操作但是结构体必须要保存2个使用兼容设备描述表利用兼容DC来实现图形的保存和重绘首先创建一个兼容DC对象voidCDCclientView::OnLButtonUp(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandlercodehereand/orcalldefaultCClientDCdc(this);CPenpen(0,1,RGB(0,0,255));dc.SelectObject(&pen);CBrush*pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));dc.SelectObject(pBrush);if(!m_dcCompatible.m_hDC){m_dcCompatible.CreateCompatibleDC(&dc);CRectrect;GetClientRect(&rect);CBitmapbitmap;bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());m_dcCompatible.SelectObject(&bitmap);m_dcCompatible.SelectObject(pBrush);m_dcCompatible.SelectObject(&pen);m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);}switch(m_type){case1:dc.SetPixel(point,RGB(0,255,255));m_dcCompatible.SetPixel(point,RGB(0,255,255));break;case2:dc.MoveTo(Startpoint);dc.LineTo(point);m_dcCompatible.MoveTo(Startpoint);m_dcCompatible.LineTo(point);break;case3:dc.Rectangle(CRect(Startpoint,point));m_dcCompatible.Rectangle(CRect(Startpoint,point));break;case4:dc.Ellipse(CRect(Startpoint,point));m_dcCompatible.Ellipse(CRect(Startpoint,point));break;}CView::OnLButtonUp(nFlags,point);}注意首先创建一个兼容DC,用IF语句使之不能重复创建。将DC的地址指向此兼容DC2.因为不是调用现有的的位图必然要创建一个兼容位图,获取当前窗口的大小创建该位图将位图地址笔刷写入兼容设备描述表,但此时只包含位图的信息头而没有保存颜色表和像素块。所以在调用BitBlt复制像素块到兼容设备描述表中并且将所用绘制的方法也写入兼容设备描述表中然后调用重绘CRectrect;GetClientRect(&rect);pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatible,0,0,SRCCOPY);将位图重新绘制到当前DC中。文件和注册表操作常量指针:Constchar*常量指针不能修改其内存内容,但是可以修改其指向的内存地址。指针常量:Char*const指针常量不能修改其指向的地址,但是可以修改其指向内容两个指针都要在定义的时候赋值。在C语言中文件的操作是利用file结构体完成的。利用fopen函数返回一个指向FILE的指针FILE*fopen(constchar*filename,constchar*mode);指向文件名的常量指针,指向文件打开的模式的常量指针FILE*pFile=fopen("1.txt","w");fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile);w为写操作打开一个文件,如果给定文件以存在则清空具体使用表见P438如果写入后想立即看到数据可以用fclose关闭文件表示写操作以完成。这是会把缓冲区的内容写入磁盘。fclose(pFile);但一旦调用FCLOSE函数再次访问就必须重新打开文件可以使用FFLUSH函数fflush(pFile);fflush函数来刷新缓冲区数据。这样就可以不必要不停的先关闭文件再写入磁盘文件、文件定位指针对于C语言来说它有一个文件指针,会占据写入数据占用的下一个位置。如果需要文件指针移动到指定的位置需要使用fseek函数来实现SEEK_CUR//当前位置SEEK_END//结尾位置SEEK_SET//开始位置FILE*pFile=fopen("2.txt","w");charch[3];ch[0]='a';ch[1]=10;ch[2]='b';fwrite(ch,1,3,pFile);fclose(pFile); FILE*pFile=fopen("2.txt","r");charch[100];fread(ch,1,3,pFile);ch[3]=0;fclose(pFile);MessageBox(ch);文件分为二进制文件和文本文件给你一个整数98341写入文本文件中,打开文件显示98341FILE*pFile=fopen("3.txt","w");charbuf[6]="98314";buf[5]='\0';fwrite(buf,1,6,pFile);fclose(pFile);这么写是不对的因为给的是整数而不是字符;FILE*pFile=fopen("3.txt","w");inti=98314;fwrite(&i,4,1,pFile);fclose(pFile);打开后乱码因为显示的时候是5个字符使用ITOA函数对此整型转化为字符型FILE*pFile=fopen("3.txt","w");inti=98314;charch[5];itoa(i,ch,10);fwrite(ch,1,5,pFile);fclose(pFile);12.3c++对文件操作的支持Ofstream读操作ifstreamifs("4.txt");charch[100];memset(ch,0,100);ifs.read(ch,100);ifs.close();MessageBox(ch);写操作ofstreamofs("4.txt");ofs.write("http://www.sunxin,org",strlen("http://www.sunxin,org"));ofs.close();12.4win32api对文件操作的支持文件的创建或者打开1.文件2.管道3.邮槽4.通信资源5.磁盘设备6.控制台7.目录(只适用打开操作)HANDLECreateFile(LPCTSTRlpFileName,//filenameDWORDdwDesiredAccess,//accessmodeDWORDdwShareMode,//sharemodeLPSECURITY_ATTRIBUTESlpSecurityAttributes,//SDDWORDdwCreationDisposition,//howtocreateDWORDdwFlagsAndAttributes,//fileattributesHANDLEhTemplateFile//handletotemplatefile);文件的写入HANDLEhFile;hFile=CreateFile("5.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);DWORDdwWrites;WriteFile(hFile,"http://www.sunxing.org",strlen("http://www.sunxing.org"),&dwWrites,NULL);CloseHandle(hFile);文件的读取HANDLEhFile;hFile=CreateFile("5.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);charch[100];DWORDdwReads;ReadFile(hFile,ch,100,&dwReads,NULL);ch[dwReads]=0;CloseHandle(hFile);MessageBox(ch);在这个可以看到WriteFile和ReadFile最后一个lpOverlapped指针都为空如果要这个指针有效地话必须在文件的创建方式FLAG中设置为FILE_FLAG_OVERLAPPED否则将同步运行不会中断不会返回错误标示。12.4MFC对文件操作的支持MFC的特点就是CFile基类该类不使用二进制格式的文件输入输入功能,间接的支持文本文件和内存文件读:char*pBuf;DWORDdwFileLen;dwFileLen=file.GetLength();pBuf=newchar[dwFileLen+1];pBuf[dwFileLen]=0;file.Read(pBuf,dwFileLen);file.Close();MessageBox(pBuf);在读操作时分配一个堆内存。写:CFilefile("6.txt",CFile::modeCreate|CFile::modeWrite);file.Write("http://www.sunxing.org",strlen("http://www.sunxing.org"));file.Close();现在总结C:建立一个指向fopen的指针,使用fwrite,fread,fclose来操作C++:使用fstream.h头文件使用ofstreamifstream来建立对象,使用writereadclose方法来进行操作API:使用CreateFile建立文件句柄使用WriteFileReadFileCloseHandle(hFile),相对来说使用到多个参数值。更加复杂和强大。MFC使用CFile类,建立类对象writereadclose方法来进行操作,但因为不使用缓冲区所以要分配堆内存。可以看到MFC的方法是最方便的。因此利用MFC编程,最好使用CFile类来完成CFileDialogCFileDialogfileDlg(FALSE);fileDlg.DoModal();fileDlg.m_ofn.lpstrTitle="测试";fileDlg.m_ofn.lpstrFilter="TextFiles(0*.txt)\0AllFiles(*.*)\0*.*\0\0";仔细分析此代码发现fileDlg为FALSE是另存为这个不是不能更改标题的原因仔细分析发现在建立对话框以后再进行设置,所以导致不能正常运行的原因。故更改代码CFileDialogCFileDialogfileDlg(FALSE);fileDlg.m_ofn.lpstrTitle="测试";fileDlg.m_ofn.lpstrFilter="TextFiles(0*.txt)\0AllFiles(*.*)\0*.*\0\0";fileDlg.DoModal();发现可以了但是选择里看不到TXT文件。修改代码:fileDlg.m_ofn.lpstrFilter="TextFiles(*.txt)\0*.txt\0AllFiles(*.*)\0*.*\0\0";再字符串前+0/在设置好选择地字符串后再填上红字内容连续两个\0\0字符结尾。fileDlg.m_ofn.lpstrDefExt="txt";//设置默认格式设置另存为写入文本if(IDOK==fileDlg.DoModal()){CFilefile(fileDlg.GetFileName(),CFile::modeCreate|CFile::modeWrite);file.Write("http://www.sunxin.org",strlen("http://www.sunxin.org"));file.Close();}设置读取操作CFileDialogfileDlg(TRUE);fileDlg.m_ofn.lpstrTitle="测试";fileDlg.m_ofn.lpstrFilter="TextFiles(*.txt)\0*.txt\0AllFiles(*.*)\0*.*\0\0";fileDlg.m_ofn.lpstrDefExt="txt";//设置默认格式if(IDOK==fileDlg.DoModal()){CFilefile(fileDlg.GetFileName(),CFile::modeRead);char*pBuf;DWORDdwFileLen;dwFileLen=file.GetLength();pBuf=newchar[dwFileLen+1];pBuf[dwFileLen]=0;file.Read(pBuf,dwFileLen);file.Close();MessageBox(pBuf);
switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType)
case1:
pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0));
break;
case2:
pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin);
pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd);
case3:
pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)));
case4:
pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)));
}//TODO:
adddrawcodefornativedatahere
for(inty=0;y{if(((CLineh*)m_ptrArray1.GetAt(y))->m_nDrawType==5)//此处要判断一下函数,否则将会造成死循环,另只要注意在结构体中保存了点的坐标就可以完成任意线的绘制了{pDC->MoveTo(((CLineh*)m_ptrArray1.GetAt(y))->m_ptOrigin);pDC->LineTo(((CLineh*)m_ptrArray1.GetAt(y))->m_ptEnd);}}总结:先尝试用开关来完成鼠标按下时绘制连续线这个有个关键点在此函数中设置判断语句来用bool型变量开关来控制mousemove函数中绘线语句if(m_Ben==TRUE){//m_nDrawType=5;因为这个变量的值只能唯一,当按下铅笔按钮时就已经赋值给m_nDrawType了dc.MoveTo(m_ptOrigin);dc.LineTo(point);CLineh*plineh=newCLineh(m_nDrawType,m_ptOrigin,point);m_ptrArray1.Add(plineh);m_ptOrigin=point;}另在CGraph中我们只保存了一维数组我们也可以将CLINE结构体写入CGrpah中来用一个语句完成操作但是结构体必须要保存2个使用兼容设备描述表利用兼容DC来实现图形的保存和重绘首先创建一个兼容DC对象voidCDCclientView::OnLButtonUp(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandlercodehereand/orcalldefaultCClientDCdc(this);CPenpen(0,1,RGB(0,0,255));dc.SelectObject(&pen);CBrush*pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));dc.SelectObject(pBrush);if(!m_dcCompatible.m_hDC){m_dcCompatible.CreateCompatibleDC(&dc);CRectrect;GetClientRect(&rect);CBitmapbitmap;bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());m_dcCompatible.SelectObject(&bitmap);m_dcCompatible.SelectObject(pBrush);m_dcCompatible.SelectObject(&pen);m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);}switch(m_type){case1:dc.SetPixel(point,RGB(0,255,255));m_dcCompatible.SetPixel(point,RGB(0,255,255));break;case2:dc.MoveTo(Startpoint);dc.LineTo(point);m_dcCompatible.MoveTo(Startpoint);m_dcCompatible.LineTo(point);break;case3:dc.Rectangle(CRect(Startpoint,point));m_dcCompatible.Rectangle(CRect(Startpoint,point));break;case4:dc.Ellipse(CRect(Startpoint,point));m_dcCompatible.Ellipse(CRect(Startpoint,point));break;}CView::OnLButtonUp(nFlags,point);}注意首先创建一个兼容DC,用IF语句使之不能重复创建。将DC的地址指向此兼容DC2.因为不是调用现有的的位图必然要创建一个兼容位图,获取当前窗口的大小创建该位图将位图地址笔刷写入兼容设备描述表,但此时只包含位图的信息头而没有保存颜色表和像素块。所以在调用BitBlt复制像素块到兼容设备描述表中并且将所用绘制的方法也写入兼容设备描述表中然后调用重绘CRectrect;GetClientRect(&rect);pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatible,0,0,SRCCOPY);将位图重新绘制到当前DC中。文件和注册表操作常量指针:Constchar*常量指针不能修改其内存内容,但是可以修改其指向的内存地址。指针常量:Char*const指针常量不能修改其指向的地址,但是可以修改其指向内容两个指针都要在定义的时候赋值。在C语言中文件的操作是利用file结构体完成的。利用fopen函数返回一个指向FILE的指针FILE*fopen(constchar*filename,constchar*mode);指向文件名的常量指针,指向文件打开的模式的常量指针FILE*pFile=fopen("1.txt","w");fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile);w为写操作打开一个文件,如果给定文件以存在则清空具体使用表见P438如果写入后想立即看到数据可以用fclose关闭文件表示写操作以完成。这是会把缓冲区的内容写入磁盘。fclose(pFile);但一旦调用FCLOSE函数再次访问就必须重新打开文件可以使用FFLUSH函数fflush(pFile);fflush函数来刷新缓冲区数据。这样就可以不必要不停的先关闭文件再写入磁盘文件、文件定位指针对于C语言来说它有一个文件指针,会占据写入数据占用的下一个位置。如果需要文件指针移动到指定的位置需要使用fseek函数来实现SEEK_CUR//当前位置SEEK_END//结尾位置SEEK_SET//开始位置FILE*pFile=fopen("2.txt","w");charch[3];ch[0]='a';ch[1]=10;ch[2]='b';fwrite(ch,1,3,pFile);fclose(pFile); FILE*pFile=fopen("2.txt","r");charch[100];fread(ch,1,3,pFile);ch[3]=0;fclose(pFile);MessageBox(ch);文件分为二进制文件和文本文件给你一个整数98341写入文本文件中,打开文件显示98341FILE*pFile=fopen("3.txt","w");charbuf[6]="98314";buf[5]='\0';fwrite(buf,1,6,pFile);fclose(pFile);这么写是不对的因为给的是整数而不是字符;FILE*pFile=fopen("3.txt","w");inti=98314;fwrite(&i,4,1,pFile);fclose(pFile);打开后乱码因为显示的时候是5个字符使用ITOA函数对此整型转化为字符型FILE*pFile=fopen("3.txt","w");inti=98314;charch[5];itoa(i,ch,10);fwrite(ch,1,5,pFile);fclose(pFile);12.3c++对文件操作的支持Ofstream读操作ifstreamifs("4.txt");charch[100];memset(ch,0,100);ifs.read(ch,100);ifs.close();MessageBox(ch);写操作ofstreamofs("4.txt");ofs.write("http://www.sunxin,org",strlen("http://www.sunxin,org"));ofs.close();12.4win32api对文件操作的支持文件的创建或者打开1.文件2.管道3.邮槽4.通信资源5.磁盘设备6.控制台7.目录(只适用打开操作)HANDLECreateFile(LPCTSTRlpFileName,//filenameDWORDdwDesiredAccess,//accessmodeDWORDdwShareMode,//sharemodeLPSECURITY_ATTRIBUTESlpSecurityAttributes,//SDDWORDdwCreationDisposition,//howtocreateDWORDdwFlagsAndAttributes,//fileattributesHANDLEhTemplateFile//handletotemplatefile);文件的写入HANDLEhFile;hFile=CreateFile("5.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);DWORDdwWrites;WriteFile(hFile,"http://www.sunxing.org",strlen("http://www.sunxing.org"),&dwWrites,NULL);CloseHandle(hFile);文件的读取HANDLEhFile;hFile=CreateFile("5.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);charch[100];DWORDdwReads;ReadFile(hFile,ch,100,&dwReads,NULL);ch[dwReads]=0;CloseHandle(hFile);MessageBox(ch);在这个可以看到WriteFile和ReadFile最后一个lpOverlapped指针都为空如果要这个指针有效地话必须在文件的创建方式FLAG中设置为FILE_FLAG_OVERLAPPED否则将同步运行不会中断不会返回错误标示。12.4MFC对文件操作的支持MFC的特点就是CFile基类该类不使用二进制格式的文件输入输入功能,间接的支持文本文件和内存文件读:char*pBuf;DWORDdwFileLen;dwFileLen=file.GetLength();pBuf=newchar[dwFileLen+1];pBuf[dwFileLen]=0;file.Read(pBuf,dwFileLen);file.Close();MessageBox(pBuf);在读操作时分配一个堆内存。写:CFilefile("6.txt",CFile::modeCreate|CFile::modeWrite);file.Write("http://www.sunxing.org",strlen("http://www.sunxing.org"));file.Close();现在总结C:建立一个指向fopen的指针,使用fwrite,fread,fclose来操作C++:使用fstream.h头文件使用ofstreamifstream来建立对象,使用writereadclose方法来进行操作API:使用CreateFile建立文件句柄使用WriteFileReadFileCloseHandle(hFile),相对来说使用到多个参数值。更加复杂和强大。MFC使用CFile类,建立类对象writereadclose方法来进行操作,但因为不使用缓冲区所以要分配堆内存。可以看到MFC的方法是最方便的。因此利用MFC编程,最好使用CFile类来完成CFileDialogCFileDialogfileDlg(FALSE);fileDlg.DoModal();fileDlg.m_ofn.lpstrTitle="测试";fileDlg.m_ofn.lpstrFilter="TextFiles(0*.txt)\0AllFiles(*.*)\0*.*\0\0";仔细分析此代码发现fileDlg为FALSE是另存为这个不是不能更改标题的原因仔细分析发现在建立对话框以后再进行设置,所以导致不能正常运行的原因。故更改代码CFileDialogCFileDialogfileDlg(FALSE);fileDlg.m_ofn.lpstrTitle="测试";fileDlg.m_ofn.lpstrFilter="TextFiles(0*.txt)\0AllFiles(*.*)\0*.*\0\0";fileDlg.DoModal();发现可以了但是选择里看不到TXT文件。修改代码:fileDlg.m_ofn.lpstrFilter="TextFiles(*.txt)\0*.txt\0AllFiles(*.*)\0*.*\0\0";再字符串前+0/在设置好选择地字符串后再填上红字内容连续两个\0\0字符结尾。fileDlg.m_ofn.lpstrDefExt="txt";//设置默认格式设置另存为写入文本if(IDOK==fileDlg.DoModal()){CFilefile(fileDlg.GetFileName(),CFile::modeCreate|CFile::modeWrite);file.Write("http://www.sunxin.org",strlen("http://www.sunxin.org"));file.Close();}设置读取操作CFileDialogfileDlg(TRUE);fileDlg.m_ofn.lpstrTitle="测试";fileDlg.m_ofn.lpstrFilter="TextFiles(*.txt)\0*.txt\0AllFiles(*.*)\0*.*\0\0";fileDlg.m_ofn.lpstrDefExt="txt";//设置默认格式if(IDOK==fileDlg.DoModal()){CFilefile(fileDlg.GetFileName(),CFile::modeRead);char*pBuf;DWORDdwFileLen;dwFileLen=file.GetLength();pBuf=newchar[dwFileLen+1];pBuf[dwFileLen]=0;file.Read(pBuf,dwFileLen);file.Close();MessageBox(pBuf);
if(((CLineh*)m_ptrArray1.GetAt(y))->m_nDrawType==5)
//此处要判断一下函数,否则将会造成死循环,另只要注意在结构体中保存了点的坐标就可以完成任意线的绘制了
pDC->MoveTo(((CLineh*)m_ptrArray1.GetAt(y))->m_ptOrigin);
pDC->LineTo(((CLineh*)m_ptrArray1.GetAt(y))->m_ptEnd);
总结:
先尝试用开关来完成鼠标按下时绘制连续线
这个有个关键点在此函数中设置判断语句来用bool型变量开关
来控制mousemove函数中绘线语句
if(m_Ben==TRUE)
//m_nDrawType=5;因为这个变量的值只能唯一,当按下铅笔按钮时就已经赋值给m_nDrawType了
dc.LineTo(point);
CLineh*plineh=newCLineh(m_nDrawType,m_ptOrigin,point);
m_ptrArray1.Add(plineh);
另在CGraph中我们只保存了一维数组
我们也可以将CLINE结构体写入CGrpah中来用一个语句完成操作
但是结构体必须要保存2个
使用兼容设备描述表
利用兼容DC来实现图形的保存和重绘
首先创建一个兼容DC对象
voidCDCclientView:
OnLButtonUp(UINTnFlags,CPointpoint)
CClientDCdc(this);
CPenpen(0,1,RGB(0,0,255));
dc.SelectObject(&pen);
CBrush*pBrush=CBrush:
FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
dc.SelectObject(pBrush);
if(!
m_dcCompatible.m_hDC)
m_dcCompatible.CreateCompatibleDC(&dc);
bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
m_dcCompatible.SelectObject(&bitmap);
m_dcCompatible.SelectObject(pBrush);
m_dcCompatible.SelectObject(&pen);
m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
switch(m_type)
dc.SetPixel(point,RGB(0,255,255));
m_dcCompatible.SetPixel(point,RGB(0,255,255));
dc.MoveTo(Startpoint);
m_dcCompatible.MoveTo(Startpoint);
m_dcCompatible.LineTo(point);
dc.Rectangle(CRect(Startpoint,point));
m_dcCompatible.Rectangle(CRect(Startpoint,point));
dc.Ellipse(CRect(Startpoint,point));
m_dcCompatible.Ellipse(CRect(Startpoint,point));
CView:
OnLButtonUp(nFlags,point);
注意首先创建一个兼容DC,用IF语句使之不能重复创建。
将DC的地址指向此兼容DC
2.因为不是调用现有的的位图必然要创建一个兼容位图,获取当前窗口的大小创建该位图
将位图地址笔刷写入兼容设备描述表,但此时只包含位图的信息头而没有保存颜色表和像素块。
所以在调用BitBlt复制像素块到兼容设备描述表中
并且将所用绘制的方法也写入兼容设备描述表中
然后调用重绘
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatible,0,0,SRCCOPY);
将位图重新绘制到当前DC中。
文件和注册表操作
常量指针:
Constchar*常量指针不能修改其内存内容,但是可以修改其指向的内存地址。
指针常量:
Char*const指针常量不能修改其指向的地址,但是可以修改其指向内容
两个指针都要在定义的时候赋值。
在C语言中文件的操作是利用file结构体完成的。
利用fopen函数返回一个指向FILE的指针
FILE*fopen(constchar*filename,constchar*mode);
指向文件名的常量指针,指向文件打开的模式的常量指针
FILE*pFile=fopen("1.txt","w");
fwrite("http:
//www.sunxin.org",1,strlen("http:
//www.sunxin.org"),pFile);
w为写操作打开一个文件,如果给定文件以存在则清空
具体使用表见P438
如果写入后想立即看到数据可以用fclose关闭文件表示写操作以完成。
这是会把缓冲区的内容写入磁盘。
fclose(pFile);
但一旦调用FCLOSE函数再次访问就必须重新打开文件可以使用FFLUSH函数
fflush(pFile);
fflush函数来刷新缓冲区数据。
这样就可以不必要不停的先关闭文件再写入磁盘文件
、
文件定位指针
对于C语言来说它有一个文件指针,会占据写入数据占用的下一个位置。
如果需要文件指针移动到指定的位置需要使用fseek函数来实现
SEEK_CUR//当前位置
SEEK_END//结尾位置
SEEK_SET//开始位置
FILE*pFile=fopen("2.txt","w");
charch[3];
ch[0]='a';
ch[1]=10;
ch[2]='b';
fwrite(ch,1,3,pFile);
FILE*pFile=fopen("2.txt","r");
charch[100];
fread(ch,1,3,pFile);
ch[3]=0;
MessageBox(ch);
文件分为二进制文件和文本文件
给你一个整数98341写入文本文件中,打开文件显示98341
FILE*pFile=fopen("3.txt","w");
charbuf[6]="98314";
buf[5]='\0';
fwrite(buf,1,6,pFile);
这么写是不对的因为给的是整数而不是字符;
inti=98314;
fwrite(&i,4,1,pFile);
打开后乱码因为显示的时候是5个字符
使用ITOA函数对此整型转化为字符型
charch[5];
itoa(i,ch,10);
fwrite(ch,1,5,pFile);
12.3c++对文件操作的支持
Ofstream
读操作
ifstreamifs("4.txt");
memset(ch,0,100);
ifs.read(ch,100);
ifs.close();
写操作
ofstreamofs("4.txt");
ofs.write("http:
//www.sunxin,org",strlen("http:
//www.sunxin,org"));
ofs.close();
12.4win32api对文件操作的支持
文件的创建或者打开
1.文件
2.管道
3.邮槽
4.通信资源
5.磁盘设备
6.控制台
7.目录(只适用打开操作)
HANDLECreateFile(
LPCTSTRlpFileName,//filename
DWORDdwDesiredAccess,//accessmode
DWORDdwShareMode,//sharemode
LPSECURITY_ATTRIBUTESlpSecurityAttributes,//SD
DWORDdwCreationDisposition,//howtocreate
DWORDdwFlagsAndAttributes,//fileattributes
HANDLEhTemplateFile//handletotemplatefile
);
文件的写入
HANDLEhFile;
hFile=CreateFile("5.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
DWORDdwWrites;
WriteFile(hFile,"http:
//www.sunxing.org",strlen("http:
//www.sunxing.org"),&dwWrites,NULL);
CloseHandle(hFile);
文件的读取
hFile=CreateFile("5.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DWORDdwReads;
ReadFile(hFile,ch,100,&dwReads,NULL);
ch[dwReads]=0;
在这个可以看到WriteFile和ReadFile最后一个lpOverlapped指针都为空如果要这个指针有效地话必须在文件的创建方式FLAG中设置为FILE_FLAG_OVERLAPPED
否则将同步运行不会中断不会返回错误标示。
12.4MFC对文件操作的支持
MFC的特点就是CFile基类
该类不使用二进制格式的文件输入输入功能,间接的支持文本文件和内存文件
读:
char*pBuf;
DWORDdwFileLen;
dwFileLen=file.GetLength();
pBuf=newchar[dwFileLen+1];
pBuf[dwFileLen]=0;
file.Read(pBuf,dwFileLen);
file.Close();
MessageBox(pBuf);
在读操作时分配一个堆内存。
写:
CFilefile("6.txt",CFile:
modeCreate|CFile:
modeWrite);
file.Write("http:
//www.sunxing.org"));
现在总结
C:
建立一个指向fopen的指针,使用fwrite,fread,fclose来操作
C++:
使用fstream.h头文件
使用ofstreamifstream来建立对象,使用writereadclose方法来进行操作
API:
使用CreateFile建立文件句柄使用WriteFileReadFileCloseHandle(hFile),相对来说使用到多个参数值。
更加复杂和强大。
MFC使用CFile类,建立类对象writereadclose方法来进行操作,但因为不使用缓冲区所以要分配堆内存。
可以看到MFC的方法是最方便的。
因此利用MFC编程,最好使用CFile类来完成
CFileDialog
CFileDialogfileDlg(FALSE);
fileDlg.DoModal();
fileDlg.m_ofn.lpstrTitle="测试";
fileDlg.m_ofn.lpstrFilter="TextFiles(0*.txt)\0AllFiles(*.*)\0*.*\0\0";
仔细分析此代码发现fileDlg为FALSE是另存为
这个不是不能更改标题的原因
仔细分析发现在建立对话框以后再进行设置,所以导致不能正常运行的原因。
故更改代码
发现可以了但是选择里看不到TXT文件。
修改代码:
fileDlg.m_ofn.lpstrFilter="TextFiles(*.txt)\0*.txt\0AllFiles(*.*)\0*.*\0\0";
再字符串前+0/
在设置好选择地字符串后再填上红字内容连续两个\0\0字符结尾。
fileDlg.m_ofn.lpstrDefExt="txt";//设置默认格式
设置另存为写入文本
if(IDOK==fileDlg.DoModal())
CFilefile(fileDlg.GetFileName(),CFile:
//www.sunxin.org",strlen("http:
//www.sunxin.org"));
设置读取操作
CFileDialogfileDlg(TRUE);
{CFilefile(fileDlg.GetFileName(),CFile:
modeRead);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1