VC其它- VC常用小技巧

 

让窗口一启动就最大化
把应用程序类(CxxxApp)的 InitInstance() 函数中的
m_pMainWnd->ShowWindow(SW_SHOW);
改为
m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
则窗口一启动就最大化显示。

如何设置窗口的初始尺寸
在将应用程序类(CxxAPP)的 InitInstance() 函数中加入:
m_pMainWnd->SetWindowPos(NULL,x,y,Width,Height,SWP_NOMOVE);
Width
为窗口宽度,Height为窗口高度
SWP_NOMOVE
表示忽略位置(x,y)
如:

让窗口居中显示
以下两种方法可任选其一:
在应用程序类(CxxxApp)的 InitInstance() 函数中加入:
在主框架类(MainFrm.cpp)OnCreate()函数中加入:
CenterWindow( GetDesktopWindow() );
如:如何修改窗口标题
窗口标题一般形式为:文档标题 - 程序标题
1
、设置文档标题:
在文档类(CxxxDoc)OnNewDocument()函数中加入语句:SetTitle("文档名");
如:TextEditorDoc.cpp
可删除Debug文件夹和Release文件夹;
原则上还可删除主文件夹中所有图标为 的文件,包括.aps.ncb.opt.plg等文件,它们都能在编译时重建。但一般.clw不要删除,它可能导致ClassWizard不好用。



控件
如何隐藏和显示控件
CWnd类的函数BOOL ShowWindow(int nCmdShow)可以隐藏或显示一个控件。
1
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //
获取控件指针,IDC_EDIT为控件ID
pWnd->ShowWindow( SW_HIDE ); //
隐藏控件
2
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //
获取控件指针,IDC_EDIT为控件ID
pWnd->ShowWindow( SW_SHOW ); //
显示控件

按钮的使能与禁止
ClassWizardMember Variables为按钮定义变量,如:m_Button1

m_Button1.EnableWindow(true);
使按钮处于允许状态
m_Button1.EnableWindow(false);
使按钮被禁止,并变灰显示

改变控件的大小和位置
CWnd类的函数MoveWindow()SetWindowPos()可以改变控件的大小和位置。
void MoveWindow(int x,int y,int nWidth,int nHeight);
void MoveWindow(LPCRECT lpRect);
第一种用法需给出控件新的坐标和宽度、高度;
第二种用法给出存放位置的CRect对象;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //
获取控件指针,IDC_EDIT1为控件ID
pWnd->MoveWindow( CRect(0,0,100,100) ); //
在窗口左上角显示一个宽100、高100的编辑控件
SetWindowPos()
函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:
BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);
第一个参数一般设为NULL;
x
y控件位置;cxcy控件宽度和高度;
nFlags
常用取值:
SWP_NOZORDER
:忽略第一个参数;
SWP_NOMOVE
:忽略xy,维持位置不变;
SWP_NOSIZE
:忽略cxcy,维持大小不变;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_BUTTON1 ); //
获取控件指针,IDC_BUTTON1为控件ID
pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE ); //
把按钮移到窗口的(50,80)
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE ); //
把编辑控件的大小设为(100,80),位置不变
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER ); //
编辑控件的大小和位置都改变
以上方法也适用于各种窗口。

单选按钮控件(Radio Button)的使用
一、对单选按钮进行分组:
每组的第一个单选按钮设置属性:GroupTabstopAuto;其余按钮设置属性TabstopAuto
如:
Radio1
Radio2Radio3为一组,Radio4Radio5为一组
设定Radio1属性:GroupTabstopAuto
设定Radio2属性:TabstopAuto
设定Radio3属性:TabstopAuto
设定Radio4属性:GroupTabstopAuto
设定Radio5属性:TabstopAuto
二、用ClassWizard为单选控件定义变量,每组只能定义一个。如:m_Radio1m_Radio4
三、用ClassWizard生成各单选按钮的单击消息函数,并加入内容:
void CWEditView::OnRadio1()
{
m_Radio1 = 0; //
第一个单选按钮被选中
}
void CWEditView::OnRadio2()
{
m_Radio1 = 1; //
第二个单选按钮被选中
}
void CWEditView::OnRadio3()
{
m_Radio1 = 2; //
第三个单选按钮被选中
}
void CWEditView::OnRadio4()
{
m_Radio4 = 0; //
第四个单选按钮被选中
}
void CWEditView::OnRadio5()
{
m_Radio4 = 1; //
第五个单选按钮被选中
}
当控件变量值为0时,它对应组的第一个单选按钮处于选中状态。

BOOL CDzyApp::InitInstance() 

AfxEnableControlContainer(); 
…… 

// The one and only window has been initialized, so show and update it. 
m_pMainWnd->SetWindowPos(NULL,0,0,750,555,SWP_NOMOVE);//设置窗口的初始大小为750*555 
m_pMainWnd->ShowWindow(SW_SHOW); 
m_pMainWnd
->UpdateWindow(); 

return TRUE; 
}

 

m_pMainWnd -> CenterWindow( GetDesktopWindow() );

 

int  CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
if (CFrameWnd::OnCreate(lpCreateStruct) == -1
return -1
…… 

// TODO: Delete these three lines if you don't want the toolbar to 
// be dockable 
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); 
EnableDocking(CBRS_ALIGN_ANY); 
DockControlBar(
&m_wndToolBar); 

CenterWindow( GetDesktopWindow() ); 
//使窗口打开时处于屏幕正中

return 0
}

 

BOOL CTextEditorDoc::OnNewDocument() 
if (!CDocument::OnNewDocument()) 
return FALSE; 
// TODO: add reinitialization code here 
// (SDI documents will reuse this document) 
SetTitle("未命名.txt"); //设置文档标题 
return TRUE; 
}


2、设置程序标题:
在框架类(CMainFrame)PreCreateWindow()函数中加入语句:m_strTitle = _T("程序标题");
如:MainFrm.cpp

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT &  cs) 
if!CFrameWnd::PreCreateWindow(cs) ) 
return FALSE; 
// TODO: Modify the Window class or styles here by modifying 
// the CREATESTRUCT cs 
cs.style&=~FWS_ADDTOTITLE;//去除标题栏文字前面的"无标题"
m_strTitle = _T("文本整理器"); //设置程序标题 
return TRUE; 
}

以上两点比较适用于视图-文档结构的程序,在新建文档时,系统会自动运行OnNewDocument()函数,在其中可以设置合适的标题。对于未采用文档的程序可以用下面的方法修改标题:
3
、修改窗口标题:
修改窗口标题一般在打开文件函数OnFileOpen()和另存为函数OnFileSaveAs()中进行,可以使用下面的函数:其中文档标题和程序标题可使用定义过的串变量。



项目
如何干净的删除一个类?
1、先删除项目中对应的.h.cpp文件,(选中后用Delete键删除)
2
、保存后退出项目,到文件夹中删除实际的.h.cpp文件;
3
、删除.clw文件;
4
、重新进入项目,进行全部重建(rebuild all)。

如何建立一个新类?
   
插入”(Insert)菜单中选择新建类”(New Class),在弹出的对话框中选择基类(Base class),在Name中输入新类的名字(一般都以C开头)即可。
如果想要建立一个没有基类的自定义类,则在New Class对话框中把Class type设置为generic,再输入类名即可。

如何把外来文件添加到项目中?
   
先把外来文件复制到当前项目的目录下,从项目”(Project)菜单下选择添加项目”(Add to Project)下的“Files”菜单项,从弹出的打开文件对话框中把外来文件打开即可。

如何在一个工作区中打开多个项目?
   
一般编程者都有这样的经历:做了一个项目,由于不满意,想从头重做,但又想把旧项目的一些可用内容拷到新项目中来,以免做重复工作,这时就需要在新项目中打开旧项目。
   
先打开新项目,从项目”(Project)菜单下选择插入项目到工作区”(Insert Project into Workspace),从弹出的打开文件对话框中打开旧项目的.asp文件即可。
   
之后,可以利用项目”(Project)菜单下的设置活动项目”(Select Active Project)的选项中切换各打开的项目。
注意:在一个工作区中打开的各项目不能同名。

如何把项目中的文件分类存放?
当我们往项目中添加新类时,它会把源文件放在Source Files下,头文件放在Header Files下。当项目中文件很多时,管理不便,最好添加新节点,把文件分类放置。
右击项目节点树的根节点,选择“New Folder...”,在弹出的对话框中填入新节点名,则新节点就建立了,用鼠标节点树中的文件拖入新节点,就可以把文件分类了。
以上分类只是在项目的节点树中分类,它不影响文件在磁盘上的位置,所有.cpp文件和.h文件仍在项目的根目录下,最好文件本身也能分类存放在不同文件夹中。
Windows下,用新建文件夹在项目的根目录下建立子文件夹,如DialogClass,把所有对话框类的.cpp文件和.h文件拖入其中。
回到VC下,右键单击项目树中更改了路径的节点,选择“Properties”,在弹出的对话框中修改文件路径,如:把原路径“./Dialog1.cpp”改为“./DialogClass/Dialog1.cpp”
打开Dialog1.cpp文件,修改它包含的文件路径。如:
#include "stdafx.h"
#include "PluckBox.h"
#include "Dialog1.h"
改为:
#include "stdafx.h"
#include "..//PluckBox.h"
#include "Dialog1.h"
打开ClassWizard,它会提示你文件不存在,单击确定后,从对话框中用“Browse...”选择文件所在路径,则ClassWizard也可正常使用了。



编辑
编辑代码时,跟随提示消失了怎么办?
单 击工具”(Tools)菜单中的设置”(Options)菜单项,在弹出的Options对话框中选择Editor制表页,把它最下方的四个复选框都 选中(Auto list memberAuto type infoCode commentsAuto parameter info),这样,当用户输入“->”“.”时,会自动显示跟随提示,减少了输入负担。



对话框
如何修改对话框的背景色
在对话框的OnPaint()函数中加入下面语句:
CRect rect;
GetClientRect(&rect); //
计算对话框的尺寸
dc.FillSolidRect(&rect,RGB(192,248,202)); //
绘制对话框背景色

如何让弹出式对话框具有统一的背景色
在应用程序类CxxxAppInitInstance()函数中加入下面的语句:
SetDialogBkColor( RGB(192,248,202) );
则所有用户定义的弹出式对话框都以RGB(192,248,202)为背景色,就不需要逐个进行设置了。


如何让打开文件对话框能进行多项选择
在定制打开文件对话框时,增加OFN_ALLOWMULTISELECT属性,就可以使打开文件对话框进行多选了。
如:
CFileDialog m_Dlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT
| OFN_ALLOWMULTISELECT, NULL, NULL );
之后,用GetStartPosition()函数获取选择的起始文件位置,用GetNextPathName()函数获取各位置上的文件名。
如:
if( m_Dlg.DoModal() == IDOK )
{
POSITION pos;
pos = m_Dlg.GetStartPosition();
while( pos )
{
m_Path = m_Dlg.GetNextPathName(pos);
…………
}
}

为什么用打开文件对话框选择多个文件到一定数目时,文件没有打开?
CFileDialog
为文件列表设置有缓冲区,当选择文件过多时,会造成缓冲区溢出,造成一些文件没有被打开。可以采用自定义大缓冲区代替系统缓冲区的方法解决。
如:
CFileDialog m_Dlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT
| OFN_ALLOWMULTISELECT, NULL, NULL );//
定制打开文件对话框
char* pBuf = new char[20480]; //
申请缓冲区
m_Dlg.m_ofn.nMaxFile = 20480; //
pBuf代替CFileDialog缓冲区
m_Dlg.m_ofn.lpstrFile = pBuf;
m_Dlg.m_ofn.lpstrFile[0] = NULL;
…………
delete []pBuf; //
回收缓冲区

提示对话框(MessageBox
在视类和对话框类中可使用MFC函数中用的MessageBox()函数弹出提示对话框。这个函数原型为:
int MessageBox(LPCTSTR lpszText,LPCTSTR lpsCaption=NULL,UINT nType=MB_OK);
参数:lpszText 显示的字符串
lpsCaption
对话框的标题
nType
风格,可为如下值的组合:
指定下列标志中的一个来显示消息框中的按钮,标志的含义如下。
MB_ABORTRETRYIGNORE
:消息框含有三个按钮:AbortRetryIgnore
MB_OK
:消息框含有一个按钮:OK。这是缺省值。
MB_OKCANCEL
:消息框含有两个按钮:OKCancel
MB_RETRYCANCEL
:消息框含有两个按钮:RetryCancel
MB_YESNO
:消息框含有两个按钮:YesNo
MB_YESNOCANCEL
:消息框含有三个按钮:YesNoCancel
指定下列标志中的一个来显示消息框中的图标:标志的含义如下。
MB_ICONEXCLAMATION:
MB_ICONWARNING
:一个惊叹号出现在消息框。
MB_ICONINFORMATION

MB_ICONASTERISK
:一个圆圈中小写字母i组成的图标出现在消息框。
MB_ICONOUESTION:
一个问题标记图标出现在消息框。
MB_ICONSTOP:
MB_ICONERROR

MB_ICONHAND
:一个停止消息图标出现在消息框。
指定下列标志中的一个来指定缺省的按钮:标志的含义如下。
MB_DEFBUTTON1
:第一个按钮为缺省按钮。如果MB_DEFBUTTON2MB_DEFBUTTON3MB_DEFBUTTON4没有被指定,则MB_DEFBUTTON1为缺省值。
MB_DEFBUTTON2
;第二个按钮为缺省按钮。
MB_DEFBUTTON3
:第三个按钮为缺省按钮。
MB_DEFBUTTON4
:第四个按钮为缺省按钮。
例:提示文件是否存盘:
int t;
t=MessageBox(m_PathName+"
的文字已经改变,要存盘吗?",
"
警告",MB_YESNOCANCEL | MB_ICONWARNING);
if(t==0 || t==IDCANCEL)
return;
if(t==IDYES)
OnFileSave();
在文档类等其它类中不能使用MFC中的MessageBox()函数,只能使用API函数中的MessageBox()函数:
int MessageBox(HWND hWnd,LPCTSTR lpszText,LPCTSTR lpCaption,UINT UType);
hWnd:
标识将被创建的消息框的拥有窗口。如果此参数为NULL,则消息框没有拥有窗口。
后三个参数与视类的MessageBox相同,但没有缺省值,必须设置。
例:::MessageBox(NULL,m_PathName+"的文字已经改变,要存盘吗?",
"
警告",MB_YESNOCANCEL | MB_ICONWARNING);



调试
error C2146: syntax error : missing ';' before identifier ……
如果出现这个错误且错误数目很多,通常并不是缺失了分号引起的,而是忘记了添加某头文件引起的。
最常见的是新加入了对话框,然后用它的类定义了一个对象,再编译出现上面的错误。
解决方法是在引用新类的文件中加入#include "类名.h",再编译,错误消失。

fatal error C1010: unexpected end of file while looking for precompiled header directive
在一个项目中,如果用“New”向工程中添加了一个.cpp文件,编译,出错。
解决方法:
                  1)  在新建的.cpp文件的开头加入#include "stdafx.h"
                  2)  可以使用右键点击项目工程中的该cpp文件,选择setting,在c/c++栏,选择PreCompiled headers,然后设置第一选项,选择不使用预编译头,解决这个问题。发布
Debug
模式和Release模式
早就发现用VC编译出来的.exe文件比用Turbo C编译出来的文件大了许多,于是就认为VC编译时一定加了很多没用的东西,记得当时还做过把VC自动生成的项目中自认为没用的函数都删掉的傻事。后来才从网上的文章中了解到还有编译模式一说。
Debug
模式是用来调试用的,它生成的执行文件中含有大量调试信息,所以很大;
Release
模式生成的执行文件消除了这些调试信息,可用来作为成品发布。
默 认情况下是Debug模式,切换方法是在编译”(Build)菜单中选设置项目配置”(Set Active Configure)。从弹出的对话框中选择Win32 Release模式,然后再重新编译。这时在工作目录下会多出一个Release目录,其中的exe文件比Debug目录下的那个要小得多。

动态链接库和静态链接库
VC 做好了一个程序,拿到别人那里却不能运行,这也是很多编程者都经历过的,这样的软件只能在安装有VC的机器上运行,也不应拿出去发布。实际上如果你没有使 用ActiveX控件和自定义的动态DLL技术,只需把MFC的动态链接库打包到你的程序里就可以了,也就是使用静态链接库。
设置方法:从项目”(Project)菜单下选择设置” (Settings),在弹出的对话框中的General选项卡下,把“User MFC in a Shared DLL”改为“User MFC in a Static Library”,关闭对话框后重新编译即可。
在静态链接库下编译的文件比动态链接库的要大很多,不过,如果使用Release模式编译,一般也就几百K,它就可以在没有安装VC的机器上运行了。

发布VC源代码时,哪些文件可以删除?

AfxGetMainWnd() -> SetWindowText( " 文档标题 " + "  -  " + " 程序标题 " );

 


四、设置默认按钮:
在定义控件变量时,ClassWizard在构造函数中会把变量初值设为-1,只需把它改为其它值即可。
如:
//{{AFX_DATA_INIT(CWEditView)
m_Ridio1 = 0; //
初始时第一个单选按钮被选中
m_Ridio4 = 0; //
初始时第四个单选按钮被选中
//}}AFX_DATA_INIT

旋转控件(Spin)的使用
当单击旋转控件上的按钮时,相应的编辑控件值会增大或减小。其设置的一般步骤为:
一、在对话框中放入一个Spin控件和一个编辑控件作为Spin控件的伙伴窗口
设置Spin控件属性:Auto buddySet buddy integerArrow keys
设置文本控件属性:Number
二、用ClassWizardSpin控件定义变量m_Spin,为编辑控件定义变量m_Edit,定义时注意要把m_Edit设置为int型。
三、在对话框的OnInitDialog()函数中加入语句:
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();

m_Spin.SetBuddy( GetDlgItem( IDC_EDIT1 ) ); //
设置编辑控件为Spin控件的伙伴窗口
m_Spin.SetRange( 0, 10 ); //
设置数据范围为0-10
return TRUE;
}
四、用ClassWizard为编辑控件添加EN_CHANGE消息处理函数,再加入语句:
void CMyDlg::OnChangeEdit1()
{
m_Edit = m_Spin.GetPos(); //
获取Spin控件当前值
}

UpdateData()
对于可以接收数据的控件,如编辑控件来说,UpdateData()函数至关重要。当控件内容发生变化时,对应的控件变量的值并没有跟着变化,同样,当控件变量值变化时,控件内容也不会跟着变。
UpdateData()
函数就是解决这个问题的。
UpdateData(true);
把控件内容装入控件变量
UpdateData(false);
用控件变量的值更新控件
如:有编辑控件IDC_EDIT1,对应的变量为字符串m_Edit1
1
、修改变量值并显示在控件中:
m_Edit1 = _T("结果为50");
UpdateData(false);
2
、读取控件的值到变量中:
ClassWizardIDC_EDIT1添加EN_CHANGE消息处理函数,这个函数在编辑控件内容发生变化时执行。
void CEditView::OnChangeEdit1()
{
UpdateData(true); //
更新变量值
}



其它
如何获取程序所在的路径
也就是获取你这个程序本身所在的路径。
在应用程序类CxxApp的头文件中定义一个变量CString m_exePath;用来放置程序的路径名,在应用程序类CxxAppInitInstance()函数中加入如下语句:
TCHAR m_Path[MAX_PATH];
GetModuleFileName( NULL, m_Path, MAX_PATH ); //
获取程序路径(包括程序名)
int i = 0, j;
while( m_Path[i]!=0 )
{
if( m_Path[i]=='//' )
j = i;
i++;
}
m_Path[j+1] = '/0';
m_exePath.Format( "%s", m_Path ); //
分离路径名(去掉程序名)
这段程序执行后,字符串变量m_exePath中放置的就是程序所在路径,其中不包括程序名。
获取程序的位置有什么用呢?
1
、打开与应用程序在一起放置的数据文件:
如果你运行程序过程中使用过打开文件对话框打开过其它路径下的文件,这时系统的默认路径就发生了改变,有可能使你原定的数据文件打不开了,如果采用以下方法就可以没问题了:
CFile file;
file.Open( m_exePath+"
数据文件名", CFile::modeRead );
2
、放置程序运行中的临时文件:
同样,当系统的默认路径发生改变后,程序中生成的临时文件就会放得到处都是,成了一个个垃圾文件,采用以下方法可使临时文件只放在程序所在路径下:
CFile file;
file.Open( m_exePath+"
临时文件名", CFile::modeCreate | CFile::modeWrite );
……
程序结束时,用下面的方法删除临时文件:
CFile::Remove( m_exePath+"
临时文件名" );

如何在你的程序中执行其它程序
在自己的程序中调用其它程序的方法有好几种,这里我介绍我用过的两种:
一、WinExec()函数:
一般用法:WinExec(m_PathName,SW_SHOWNORMAL);
m_PathName
为执行程序的路径名,必须为可执行文件。
如:WinExec("C://Program Files//Internet Explorer//iexplore.exe",SW_SHOWNORMAL);为打开IE浏览器

 

 

BOOL CEditDoc::CanCloseFrame(CFrameWnd *  pFrame) 
{
    CFile file;
    
if(b_Flag) //b_Flag为文档修改标志,在修改文档时将其置为True
    {
        
int t;
        t
=::MessageBox(NULL,"文字已经改变,要存盘吗?","警告",MB_YESNOCANCEL | MB_ICONWARNING); //弹出提示对话框
        if(t==0 || t==IDCANCEL)
            
return false;
        
if(t==IDYES)
        
{
            CString sFilter
="Text File(*.txt)|*.txt||";
            CFileDialog m_Dlg(FALSE,
"txt",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,(LPCTSTR)sFilter,NULL); //定制文件对话框
            int k=m_Dlg.DoModal(); //弹出文件对话框
            if(k==IDCANCEL || k==0)
                
return false;
            m_PathName
=m_Dlg.GetPathName(); //获取选择的文件路径名            
            file.Open(m_PathName,CFile::modeCreate | CFile::modeWrite);
            file.Write(m_Text,m_TextLen); 
//数据写入文件
            file.Close();
        }

    }

return CDocument::CanCloseFrame(pFrame);
}

 

 




 

二、ShellExecute()函数:

一般用法:ShellExecute(NULL,NULL,m_PathName,NULL,_T("c://temp"),SW_SHOWNORMAL);
m_PathName
为打开的程序路径名;
_T("c://temp")
为工作目录;
WinExec()不同的是ShellExecute()函数也可以打开非可执行文件,比如你指定的文件为.txt,结果会打开记事本装入该文件。我用这种方法调用自己制作的帮助文件(.chm)效果很好。

如果不使用串行化,如何在程序结束时保存文件?
在文档-视图结构中,用串行化自动保存文件在各种VC书上都有介绍。现在的问题是我不使用串行化,而是自己动手保存,当点击窗口的关闭按钮时,如何提示并保存文档。
ClassWizard在文档类(CxxDoc)中添加函数CanCloseFrame(),再在其中加入保存文件的语句就可以了。
例:

BOOL CEditDoc::CanCloseFrame(CFrameWnd *  pFrame) 
{
    CFile file;
    
if(b_Flag) //b_Flag为文档修改标志,在修改文档时将其置为True
    {
        
int t;
        t
=::MessageBox(NULL,"文字已经改变,要存盘吗?","警告",MB_YESNOCANCEL | MB_ICONWARNING); //弹出提示对话框
        if(t==0 || t==IDCANCEL)
            
return false;
        
if(t==IDYES)
        
{
            CString sFilter
="Text File(*.txt)|*.txt||";
            CFileDialog m_Dlg(FALSE,
"txt",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,(LPCTSTR)sFilter,NULL); //定制文件对话框
            int k=m_Dlg.DoModal(); //弹出文件对话框
            if(k==IDCANCEL || k==0)
                
return false;
            m_PathName
=m_Dlg.GetPathName(); //获取选择的文件路径名            
            file.Open(m_PathName,CFile::modeCreate | CFile::modeWrite);
            file.Write(m_Text,m_TextLen); 
//数据写入文件
            file.Close();
        }

    }

return CDocument::CanCloseFrame(pFrame);
}


//

 

 

这样当你单击窗口上的关闭按钮时,如果数据已修改了,就会弹出一个提示保存数据的对话框,提示你保存数据。
程序中的b_Flag是数据修改标志,应该在修改数据时进行设置,m_Text是准备保存的数据,放在文档内。

POSITION
怎么用?
POSITION
类型数据用于表征各种列表中元素的位置,它类似于数组的下标,但又有所不同。主要区别是:
我们不能访问POSITION型数据的值,也不能对POSITION数据型数据进行加减、比较等运算。
POSITION型数据访问列表时,都是采用迭代法,一般格式为:
POSITION pos; //
定义pos型变量
pos = GetHeadPosition(); //
获取列表起始元素位置
while( pos )
{
x = GetNext(pos); //
获取pos处的列表值,同时修改pos为下一个元素位置
}
GetNext()
就是一种迭代,其格式为:
TYPE GetNext(POSITION& rPosition);
首先,它返回当前pos位置处的元素;再就是把pos值修改为下一个元素位置。这样循环时,可依次取得列表中各元素的值;当到达列表尾时,posNULL,循环结束。
所以使用POSITION型数据时,你不要试图用加减等操作去修改它,只能用GetNext()(向后迭代)或GetPrev()(向前迭代)反复迭代来修改它的值。
如果你想直接到达指定值,还可以用Find()函数或FindIndex()函数获得指定值的POSITION值。
POSITION Find(TYPE Value);
用于在列表中查找值为Value的元素的POSITION值;
POSITION FindIndex(int nIndex);
用于获取列表中第nIndex个元素的POSITION值,nIndex0开始。
如:
pos = FindIndex(5); //
求列表中第5个元素的位置
x = GetNext(pos); //
读取元素的值
总之,POSITION类型在多种涉及列表的类中提供,不同的类提供的函数有所不同,但用法都是类似的。

如何从完整的文件路径中分离文件名和路径名?
从路径中分离文件名:

退出程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值