VisualC开发工具与调试技巧整理.doc_第1页
VisualC开发工具与调试技巧整理.doc_第2页
VisualC开发工具与调试技巧整理.doc_第3页
VisualC开发工具与调试技巧整理.doc_第4页
VisualC开发工具与调试技巧整理.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Visual C+开发工具与调试技巧整理1、如何在Release状态下进行调试ProjectSettingProjectSetting对话框,选择Release状态。C/C+标签中的Category选General,Optimizations选Disable(Debug),Debut info选Program Database。在Link标签中选中Generate debug info复选框。注:只是一个介乎Debug和Release的中间状态,所有的ASSERT、VERIFY都不起作用,函数调用方式已经是真正的调用,而不查表,但是这种状态下QuickWatch、调用队列跟踪功能仍然有效,和Debug版一样。2、Release和Debug有什么不同Release版称为发行版,Debug版称为调试版。Debug中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。Release版运行速度较快,可执行文件较小,但在其编译条件下无法执行调试功能。Release的exe文件链接的是标准的MFC DLL(Use MFC in a shared or static dll)。这些DLL在安装Windows的时候,已经配置,所以这些程序能够在没有安装Visual C+ 6.0的机器上运行。而Debug版本的exe链接了调试版本的MFC DLL文件,在没有安装Visual C+6.0的机器上不能运行,因为缺相应的DLL,除非选择use static dll when link。3、ASSERT和VERIFY有什么区别ASSERT里面的内容在Release版本中不编译,VERIFY里面的内容仍然翻译,但不再判断真假。所以后者更安全一点。例如ASSERT(file.Open(strFileName)。一旦到了Release版本中,这一行就忽略了,file根本就不Open()了,而且没有任何出错的信息。如果用VERIFY()就不会有这个问题。4、Workspace和Project之间是什么样的关系每个Workspace可以包括几个project,但只有一个处于Active状态,各个project之间可以有依赖关系,在project的Setting.中可以设定,比如那个Active状态的project可以依赖于其他的提供其函数调用的静态库。5、如何在非MFC程序中使用ClassWizard在工程目录下新建一个空的.RC文件,然后加入到工程中就可以了。6、如何设置断点按F9在当前光标处增加一个断点和取消一个断点。另外,在编辑状态下,按Ctrl+B组合键,弹出断点设置对话框。然后单击【Condition】按钮弹出设置断点条件的对话框进行设置。7、在编辑状态下发现成员变量或函数不能显示提示是如何打开显示功能这似乎是目前这个Visual C+ 6.0版本的一个bug,可按如下步骤使其正常,如再出现,可如法炮制:(1)关闭Project(2)删除“工程名.ncb”文件(3)重新打开工程8、如何将一个通过ClassWizard生成的类彻底删除首先在工作区的FileView中选中该类的.h和.cpp文件,按delete删除,然后在文件管理器中将这两个文件删除,再运行ClassWizard,这时出现是否移走该类的提示,选择remove就可以了。9、如何将在workspace中消失的类找出来打开该类对应的头文件,然后将其类名随便改一下,这个时候工作区就会出现新的类,再将这个类改回原来的名字就可以了。10、如何清除所有的断点菜单【Edit】【Breakpoints】,打开“Breakpoints”对话框,单击【Remove All】按钮即可。快捷键是“Ctrl + Shift + F8”。11、如何再ClassWizard中选择未列出的信息打开“ClassWizard”对话框,然后切换到“Class Info”页面。改变“Message filter”,如选择“Window”,“Message”页面就会出现Window的信息。12、如何检测程序中的括号是否匹配 把光标移动到需要检测的括号前面,按快捷键“Ctrl + ”。如果括号匹配正确,光标就跳到匹配的括号处,否则光标不移动,并且机箱喇叭还会发出一声警告。13、如何查看一个宏(或变量、函数)的定义 把光标移动到要查看的一个宏上,就比如说最常见的DECLARE_MAP_MESSAGE上按一下F12(或右键菜单中的相关菜单),如果没有建立浏览文件,就会出现提示对话框,按【确定】按钮,然后就会跳到该宏(或变量、函数)定义的地方。14、如何添加Lib文件到当前工程单击菜单【Project】【Settings】弹出“Project Setting”对话框,切换到“Link”标签页,在“Object/library modules”处输入Lib文件名称,不同的Lib之间用空格格开。15、如何快速删除项目下的Debug文件夹中临时文件在工作区的FileView视图中选中对应的项目,单击右键弹出菜单,选择【Clean(selection only)】菜单即可。16、如何快速生成一个现有工程除了工程名外完全相同的新工程在新建工程的“New”对话框中选择“Custom Appwizard”项,输入新工程的名字,单击【OK】按钮。出现“Custom AppWizard”项,输入新工程的名字,单击【OK】按钮。出现“Custom AppWizardStep 1 of 2”对话框,选择“An existing Project”项,单击【Next】按钮。出现“Custom AppWizardStep 2 of 2”对话框,选择现有工程的工程文件名,最后单击【Finish】按钮。编译后就生成一个与现有工程相同但可以重新取名的工程AppWizard。现在就可以项用MFC AppWizard一样用这个定制的向导。如果不想用了,可以在Visual C+ 6.0安装目录下CommonMSDev98Template目录中删除该Wizard对应的.awx和.pdb文件。17、如何解决Visual C+ 6.0不正确连接的问题情景:明明改动了一个文件,却要把整个项目全部重新编译链接一次。刚刚链接好,一运行,又提示重新编译链接一次。这是因为出现了未来文件(修改时间和创建时间比系统时间晚)的缘故。可以这样处理:找到工程文件夹下的debug目录,将创建和修改时间都比系统时间的文件全部删除,然后再从新“Rebuild All”一次。18、引起LNK2001的常见错误都有哪些遇到的LNK2001错误主要为:unresolved external symbol “symbol”。如果链接程序不能在所有的库和目标文件内找到所引用的函数、变量或标签,将产生此错误信息。一般来说,发生错误的原因有两个:一是所引用的函数、变量不存在,拼写不正确或者使用错误;其次可能使用了不同版本的链接库。以下是可能产生LNK2001错误的原因:由于编码错误导致的LNK2001错误(1)不相匹配的程序代码或模块定义(.DEF)文件导致LNK2001。例如,如果在C+源文件了内声明了一变量“var1”,却试图在另一个文件内以变量“var1”访问改变量。(2)如果使用的内联函数是在.cpp文件内定义的,而不是在头文件内定义将导致LNK2001错误。(3)调用函数时如果所用的参数类型和头函数声明时的类型不符将会产生LNK2001错误。(4)试图从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001错误。(5)要注意函数和变量的可公用性,只有全局变量、函数是可公用的。静态函数和静态变量具有相同的使用范围限制。当试图从文件外部方位任何没有在该文件内声明的静态变量时将导致编译错误或LNK2001错误。由于编译和联机的设置而造成的LNK2001错误(1)如果编译时使用的是/NOD(/NODERAULTLIB)选项,程序所需要的运行库和MFC时将得到又编译器写入目标文件模块,但除非在文件中明确包含这些库名,否则这些库不会被链接进工程文件。这种情况下使用/NOD将导致LNK2001错误。(2)如果没有为wWinMainCRTStartup设定程序入口,在使用Unicode和MFC时将出现“unresolved external on _WinMain16”的LNK2001错误信息。(3)使用/MD选项编译时,既然所有的运行库都被保留在动态链接库之内,源文件中对“func”的引用,在目标文件里即对“_imp_func”的引用。如果试图使用静态库LIBC.LIB或LIBCMT.LIB进行链接,将在_imp_func上发生LNK2001错误。如果不使用/MD选项编译,在使用MSVCxx.LIB链接时也会发生LNK2001错误。(4)使用/ML选项编译时,如用LIBCMT.LIB链接会在_errno上发生LNK2001错误。(5)当编译调试版的应用程序时,如果采用发行版模态库进行链接也会产生LNK2001错误;同样,使用调试版模态库链接发行版应用程序时也会产生相同的错误。(6)不同版本的库和编译器的混合使用也能产生问题,因为新版的库里可能包含早先的版本没有的符号和说明。(7)在不同的模块中使用内联和非内联的编译选项能够导致LNK2001错误。如果创建C+库时打开了函数内联(/Ob1或/Ob2),但是在描述该函数的相应头文件里却关闭了函数内联(没有inline关键字),只是将得到错误信息。为避免该问题的发生,应该在相应的头文件中用inline关键字标志为内联函数。(8)不正确的/SUBSYSTEM或ENTRY设置也能导致LNK2001错误。19、如何调试一个没有源码的exe文件调用的dll在Visual C+ 6.0中,进入“Project Setting”对话框然后选择Debug标签页。通常Visual Studio默认“executable for debug session”为可执行文件名,但可以将他改成任何你想要的程序。甚至可以指定不同的工作目录以及传递参数到你的程序。这个技术常用来调试Dlls、名字空间扩展、COM对象和其他从某些EXE以及从第三方的EXE中调用的plug-in程序。20、Visual C+ 6.0工程中的项目文件都表示什么.opt:工程关于开发环境的参数文件。如工具条位置等信息。.aps(AppStudio File)资源辅助文件,二进制格式,一般不用去管它。.clw:ClassWizard信息文件,实际上是INI文件格式,有兴趣可以研究一下。有时候ClassWizard出了问题,手工修改CLW文件可以解决。如果此文件不存在的话,每次用ClassWizard的时候回提示是否重建。.dsp(DevelopStudio Project):项目文件,文本格式,不过不熟悉的不要手工修改。.dsw(DevelopStudio Workspace):是工作区文件,其他特点和.dsp差不多。.plg:是编译信息文件,编译时的error和warning信息文件(实际上是一个html文件),一般用处不大。在单击菜单【Tool】【Option】弹出的对话框里面有个选项可以控制这个文件的生成。.hpj(Help Project):是生成帮助文件的工程,用microsoft Help Compiler可以处理。.mdp(Microsoft DevStudio Project):是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的.dsp格式。.bsc:是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件。如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,这样可以加快编译速度。.map是执行文件的映象信息记录文件,除非对系统底层,这个文件一般用不着。.pch(Pre-Compiled File):是与编译文件,可以加快编译速度,但是文件非常大。.pdb(Program Database):记录了程序有关的一些数据和调试信息,在调试的时候可能有用。.exp:只有在编译DLL的时候才会生成,记录了DLL文件的一些信息,一般也没有用。.ncb:无编译浏览文件(no compile browser)。当自动完成功能出问题时可以删除此文件。编译工程后会自动生成。动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的。 一、创建动态控件: 为了对照,我们先来看一下静态控件的创建。放置静态控件时必须先建立一个容器,一般是对话框,这时我们在对话框编辑窗口中,从工具窗口中拖出所需控件放在对话框中即可,再适当修改控件ID,设置控件属性,一个静态控件就创建好了,当对话框被显示时,其上的控件也会显示。静态控件不需要调用Create()函数来创建。而创建动态控件有很大不同,以下以按钮为例,看一下动态控件的创建过程: 1.建立控件ID号: ID号是控件的标识,创建控件前必须先为它设置一个ID号。打开资源中的“String Table”,在空白行上双击鼠标,这时会弹出一个ID属性对话框,在其中的ID编辑框中输入ID,如:IDC_MYBUTTON,在Caption中输入控件标题或注解(注:Caption框不能为空,为空会导致创建失败),这里我输入的是按钮上要显示的文字-动态按钮。 2.建立控件对象: 不同种类的控件应创建不同的类对象, 按钮控件 CButton (包括普通按钮、单选按钮和复选按钮) 编辑控件 CEdit 静态文本控件 CStatic 标签控件 CTabCtrl 旋转控件 CSpinButtonCtrl 滑标控件 CSliderCtrl 多信息编辑控件 CRichEditCtrl 进度条控件 CProgressCtrl 滚动条控件 CSrcollBar 组合框控件 CComboBox 列表框控件 CListBox 图像列表控件 CImageCtrl 树状控件 CTreeCtrl 动画控件 CAnimateCtrl 本例中我们创建一个CButton类的普通按钮。注意不能直接定义CButton对象,如:CButton m_MyBut;这种定义只能用来给静态控件定义控制变量,不能用于动态控件。 正确做法是用new调用CButton构造函数生成一个实例: CButton *p_MyBut = new CButton(); 然后用CButton类的Create()函数创建,该函数原型如下: BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID ); lpszCaption是按钮上显示的文本; dwStyle指定按钮风格,可以是按钮风格与窗口风格的组合,取值有:窗口风格: WS_CHILD 子窗口,必须有 WS_VISIBLE 窗口可见,一般都有 WS_DISABLED 禁用窗口,创建初始状态为灰色不可用的按钮时使用 WS_TABSTOP 可用Tab键选择 WS_GROUP 成组,用于成组的单选按钮中的第一个按钮按钮风格: BS_PUSHBUTTON 下压式按钮,也即普通按钮 BS_AUTORADIOBUTTON 含自动选中状态的单选按钮 BS_RADIOBUTTON 单选按钮,不常用 BS_AUTOCHECKBOX 含自动选中状态的复选按钮 BS_CHECKBOX 复选按钮,不常用 BS_AUTO3STATE 含自动选中状态的三态复选按钮 BS_3STATE 三态复选按钮,不常用以上风格指定了创建的按钮类型,不能同时使用,但必须有其一。 BS_BITMAP 按钮上将显示位图 BS_DEFPUSHBUTTON 设置为默认按钮,只用于下压式按钮,一个对话框中只能指定一个默认按钮 rect指定按钮的大小和位置; pParentWnd指示拥有按钮的父窗口,不能为NULL; nID指定与按钮关联的ID号,用上一步创建的ID号。不同控件类的Create()函数略有不同,可参考相关资料。 例:p_MyBut-Create( 动态按钮, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, CRect(20,10,80,40), this, IDC_MYBUTTON ); 这样,我们就在当前对话框中的(20,10)处创建了宽60,高30,按钮文字为“动态按钮”的下压式按钮。 为了使创建过程更方便易用,我定义了如下函数: CButton* CTextEditorView:NewMyButton(int nID,CRect rect,int nStyle) CString m_Caption; m_Caption.LoadString( nID ); /取按钮标题 CButton *p_Button = new CButton(); ASSERT_VALID(p_Button); p_Button-Create( m_Caption, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | nStyle, rect, this, nID ); /创建按钮 return p_Button; 其中m_Caption.LoadString( nID )是从字符串表中读取按钮文本,这样在创建按钮ID时,应该把文本设置好,参数nStyle为除必须风格外的额外风格。以下,我调用该函数创建三个按钮,并指定第一个按钮为默认按钮,按钮的ID已预先设置好了: CButton *p_MyBut3; p_MyBut0 = NewMyButton( ID_MYBUT1, CRect(10,20,50,35), BS_DEFPUSHBUTTON ); p_MyBut1 = NewMyButton( ID_MYBUT2, CRect(55,20,95,35), 0 ); p_MyBut2 = NewMyButton( ID_MYBUT3, CRect(100,20,140,35), 0 );二、动态控件的响应: 动态控件的响应函数不能用ClassWizard添加,只能手动添加。仍以上面的按钮为例,我们制作按钮的单击响应函数。 1.在MESSAGE_MAP中添加响应函数: MESSAGE_MAP表中定义了消息响应函数,其格式为:消息名(ID,函数名),当我们用ClassWizard添加函数时,会自动添加在AFX_MSG_MAP括起的区间内,如: BEGIN_MESSAGE_MAP(CTextEditorView, CFormView) /AFX_MSG_MAP(CTextEditorView) ON_BN_CLICKED(IDC_ICONBUT0, OnIconbut0) / AFX_MSG_MAP END_MESSAGE_MAP() 手工添加时不要添加到AFX_MSG_MAP区间内,以防ClassWizard不能正常工作,如: BEGIN_MESSAGE_MAP(CTextEditorView, CFormView) /AFX_MSG_MAP(CTextEditorView) ON_BN_CLICKED(IDC_ICONBUT0, OnIconbut0) / AFX_MSG_MAP ON_BN_CLICKED(ID_MYBUT1, OnMybut1) ON_BN_CLICKED(ID_MYBUT2, OnMybut2) ON_BN_CLICKED(ID_MYBUT3, OnMybut3) END_MESSAGE_MAP() 其中ON_BN_CLICKED是按钮单击消息。 2.在头文件中添加函数定义: 用ClassWizard添加函数时,会在头文件的AFX_MSG区间内添加函数定义,如: protected: /AFX_MSG(CTextEditorView) afx_msg void OnIconbut0();/ AFX_MSG DECLARE_MESSAGE_MAP() 我们模仿这种形式,只是把函数定义添加到AFX_MSG区间外就行了: protected: /AFX_MSG(CTextEditorView) afx_msg void OnIconbut0();/ AFX_MSG afx_msg void OnMybut1(); afx_msg void OnMybut2(); afx_msg void OnMybut3(); DECLARE_MESSAGE_MAP() 3.编写消息响应函数: 以上是把消息和函数关联起来了,具体在单击按钮后应做的工作在函数中完成: void CTextEditorView:OnMybut1() MessageBox( 哈!你单击了动态按钮。 ); void CTextEditorView:OnMybut2() void CTextEditorView:OnMybut3() 除了按钮的响应函数外,你还可以用上面获得的指针访问按钮,如:修改按钮的大小和位置:p_MyBut0-MoveWindow(); 修改按钮文本:p_MyBut0-SetWindowText(); 显示/隐藏按钮:p_MyBut0-ShowWindow();等等。 三、回收资源: 由于动态控件对象是由new生成的,它不会被程序自动释放,所以需手工释放。在控件不再使用时可以删除它: if( p_MyBut0 ) delete p_MyBut0; 以上就是按钮控件动态生成的方法。下面,再看一下单选按钮的动态生成问题。四、实例:单选按钮组的动态生成 单选按钮也属于CButton类,但由于单选按钮总是成组使用的,所以它在制作和使用上与普通按钮有一定区别。 假设有三个单选按钮组成一组,初始时,第一个单选按钮处于选中状态。 我们先来看静态制作方法:在对话框中放置三个单选按钮,设置属性如下: Radio1属性:Visible、Group、Tab stop、Auto Radio2属性:Visible、Tab stop、Auto Radio3属性:Visible、Tab stop、Auto 这样的属性设置就把三个单选按钮分成了一组,它们一次只能有一个被选中,若对话框中还有其它成组的单选按钮,使用时也会互不干扰。但这时还没有使第一个按钮处于选中状态。接着就用ClassWizard为这组单选按钮添加变量,这里只需为第一个单选按钮添加变量即可。设变量名为m_Radio,类型选为int型。在构造函数中ClassWizard把m_Radio的值设置为-1,我们把它改为0,这样在运行程序时可以看到第一个单选按钮处于选中状态了。之后,还应该用ClassWizard为三个单选按钮添加单击响应函数,在里面修改m_Radio的值对应三个单选按钮就可以了。以上就是通常制作单选按钮组的办法,现我们欲改为动态生成,主要要解决按钮分组和单击控制问题。以下为制作步骤: 1.定义三个单选按钮的ID: 打开资源中的“String Table”,在其中添加三个ID值: 第一个:ID为IDC_MYRADIO1,Caption为单选1 第二个:ID为IDC_MYRADIO2,Caption为单选2 第三个:ID为IDC_MYRADIO3,Caption为单选3 其中Caption为按钮上要显示的文字,可根据需要设置。 2.用CButton类的Create()函数生成三个单选按钮: 为方便起见,先定义一个函数生成单选按钮: CButton* CTextEditorView:NewMyRadio(int nID,CRect rect,int nStyle) CString m_Caption; m_Caption.LoadString( nID ); /取按钮标题 CButton *p_Radio = new CButton(); ASSERT_VALID(p_Radio); p_Radio-Create( m_Caption, WS_CHILD | WS_VISIBLE | nStyle | WS_TABSTOP | BS_AUTORADIOBUTTON, rect, this, nID ); /创建按钮 return p_Radio; 函数LoadString()用于从“String Table”中读取按钮文本,Create()函数中设定了单选按钮必须的属性,其中就包括了Visible、Tab stop、Auto属性。参数nID为单选按钮ID号,rect为单选按钮尺寸,nStyle为除必要属性外的其它属性。返回值为指向新建按钮的指针。 有了这个函数后,创建单选按钮组时只要依次调用该函数即可,其中单选按钮组的第一个单选按钮必须指定WS_GROUP属性。 CButton *p_MyRadio3; p_MyRadio0 = NewMyRadio( IDC_MYRADIO1, CRect(15,90,60,105), WS_GROUP ); p_MyRadio1 = NewMyRadio( IDC_MYRADIO2, CRect(15,108,60,123), 0 ); p_MyRadio2 = NewMyRadio( IDC_MYRADIO3, CRect(15,126,60,141), 0 ); 3.定义单选按钮组的控制变量,设置第一个单选按钮为选中状态: 这里不能用ClassWizard添加变量,也不要在DoDataExchange()中添加控制变量,因为动态控件一开始并不存在,在DoDataExchange()中添加控制变量会造成运行错误。这里我们只需在头文件中随意定义一个int型变量作为控制变量即可,如: int m_SelRadio; 在构造函数中设置其初值为0:m_SelRadio = 0; 在上面的创建按钮的语句中,用SetCheck()函数设置初始选中的按钮: CButton *p_MyRadio3; p_MyRadio0 = NewMyRadio( IDC_MYRADIO1, CRect(15,90,60,105), WS_GROUP ); p_MyRadio1 = NewMyRadio( IDC_MYRADIO2, CRect(15,108,60,123), 0 ); p_MyRadio2 = NewMyRadio( IDC_MYRADIO3, C

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论