Archive for the ‘C/C++’ Category

VC的若干实用小技巧

Thursday, June 8th, 2006

Visual C++6.0开发工具功能非常强大,但是对于初学者来说,却有很多细节的问题需要注意。搜集整理了以下一些实用小技巧,希望对初学者有所帮助。

1:使用vc开发项目时,常会遇到这种情况:
即明明只改动了一个文件,却要把整个项目全部重新编译连接一次。刚刚连接好,一运行,又提示重新编译连接一次,非常讨厌。这是因为出现了未来文件的缘故。
解决方法:
找出对应文件夹下的debug目录,将未来文件全部delete, 再rebuild all一次。(未来文件即其创建和修改时间都比系统时间靠后)

2:有时,workspace中的classview显示混乱。其表现如下:
(1):添加的成员变量或函数不能显示;
(2):即使显示出来了变量或函数,双击后不能跳至正确的位置。
解决方法:
删除.ncb文件,再rebuild all.

3:如何干净的删除一个类?
1:先从workspace中的fileview中删除对应的.h和.cpp文件。
2.再关闭项目,从实际的文件夹中删除对应的.h和.cpp文件。
3.再删除.clw文件。
打开项目,rebuild all。

4:初学者常有这样的疑惑:
直接望工程文件里加入一个cpp原文件再编译连接的话老是提示没有找到预编译头
解决方法:
#include “stdafx.h”

5:如何向项目中加入自己定义的类?
方法很多,介绍一个简便的:
选择insert/new class菜单
弹出对话框;
选择class type为generic;
输入类名。
当然,也可以自己决定该类的基类

6:如何在工作区(workspace)导入多个项目(project)?
在打开一个项目(*.dsp文件)后,在利用”project” 菜单下insert project into workspace 子菜单选择另一个项目文件(*.dsp文件),可插入另一个项目。
在classview 视图中,右键可以激活其中某个项目,工作区插入多个项目能方便不同项目间拷贝代码、资源等。

7: 在classview 视图中类太多如何整理?
我们可以在classview 视图中右键新建文件夹(new folder),再把具有相近性质的类拖到对应的文件夹中,使整个视图看上去清晰明了。

8:如何快速删除项目下debug 文件夹中临时文件?
在fileview视图中选中对应项目,右键clean即可。

9: 打开一个源文件较大的项目编辑操作非常慢,怎么办?
不要打开项目文件(*.dsp文件),直接打开要编辑的单个源文件(*.h或*.cpp)进行编辑,要快得多。

10:如果想把整个项目拷贝到软盘,那些文件可以删掉?
除了项目文件夹中debug文件夹可以删除外,.ncb,.clw,.opt 等文件也可以删除,这些文件rebuilt all后可以重新生成。

11:怎样快速生成一个与现有项目除了项目名外完全相同的新项目?
利用file菜单下生成新项目中的custom appwizard ,选择 an existing project ,然后选择现有项目的项目文件名(*.dsp)finish,编译后就生成一个可以生成与现有项目相同但可以重新取名的项目的appwizard。你可以象用mfc appwizard一样用它。如果不想用了,可以在vc 安装目录下common\msdev98\template目录中删除该wizard中.awx和 .pdb文件。

12:如何在源文件中定位光标到对称的{ }和 #if, #endif ?
前者使用ctrl和 “} “键 ,后者使用ctrl和”k”键。

13:如何在vc中设置头文件和库文件?
除了vc缺省头文件和库文件外,如果经常要用到第三方的头文件和库文件可以在tools options 的directories中设置。如果只是本项目要用到,可以在project setting->link object/library modules中设置库文件。

14:如果让控制台应用程序支持mfc类库?
可以在控制台应用程序中include 来引入mfc库,但是控制台应用程序缺省是单线程的,mfc是多线程的,为解决该矛盾,在project setting->c/c++ 选项,选择code generation,在use run-time library 下拉框中选择debug multithread。

15:如何为一个mfc应用程序添加odbc功能?
(1)在文件stdafx.h文件末尾添加下面一行:
#include // mfc odbc database classes
(2)在文本模式下编辑rc文件(利用file->open as text 方式)
在下面的程序行(共有两处)
#include “l.chs\afxprint.rc” // printing/print preview resources
添加下一行:
#include “l.chs\afxdb.rc” // database resources

16:数据库表修改后,如何快速更新一个绑定到表的crecordset记录集?
利用classwizard 中 member variables标签下选中记录集类后,利用updatecoloumns和bind all。

17:如何汉化只有可执行代码的.exe 文件?
在nt 下利用vc open file 以resources方式打开*.exe 文件,直接修改资源文件,然后保存即可。

18:我怎样才能建立一个等待光标?
调用BeginWaitCursor函数来启动等待光标,调用EndWaitCursor函数 来结束等待光标。要注意,二者都要调用App的成员函数,如下所示:
AfxGetApp()->BeginWaitCursor(); // 要做的事 AfxGetApp()->EndWaitCursor();

19:什么是COLORREF? 我该怎样用它?
COLORREF是一个32-bit整型数值,它代表了一种颜色。你可以使用RGB函数来初始化COLORREF。
例如: COLORREF color = RGB(0, 255, 0); RGB函数接收三个0-255数值,一个代表红色,一个代表绿色,一个代表蓝色。在上面的例子中,红色和蓝色值都为0,所以在该颜色中没有红色和蓝色。绿色为最大值255。所以该颜色为绿色。0,0,0为黑色,255,255,255为白色。

20:我在我的程序中使用了CDWordArray。我向它添加了约10,000个整数,这使得它变得非常非常慢。
CDWordArray是很好用的,只是因为你没有指定数组的最大尺寸。
因此,当你添加新元素时,该类会从堆中重新分配空间。不幸的是,该类会在每次插入新元素时都为数组重新分配空间。如果你向它添加了很多新元素,所有这些分配和复制数组的操作会就会使它变慢。
解决该问题的方法是,你可以使用SetSize 函数的第二个参数来改变这种重新分配的频率。例如,如果你把该参数设置为500 ,则每次数组空间超出时它才重新分配并添加500个新空间,而不是1个。这样一来 ,你就可以不用重新分配而添加了另外499个元素空间,这也会大大提高程序的运行速度。

21:AppWizard所产生的STDAFX文件是干什么用的?
它主要是协助产生预编译头文件的。通常你是不需要修改它的。

22:在我的程序的某些部分,我可以调用 MessageBox 函数来建立一个信息对话框,例如在视类中。但是,在其它部分我却不能,如文档类中。为什么?我怎样才能在我的应用程序类中建立一个信息对话框?
MessageBox函数来自CWnd类,所以你只能在从CWnd继承的类(如CView)中调用它。但是,MFC也提供了AfxMessageBox函数,你可以在任何地方调用它。

23:我需要在我的程序中设置全局变量,以使文档中的所有类都能访问。我应该把它放到哪儿?
把该变量放到该应用程序类的头文件中的attribute处。然后,在程序的任何地方,你都可以用下面的方法来访问该变量:
CMyApp *m_App = (CMyApp *)AfxGetApp();
m_App->MyGlobalVariable = …;

24:我听说MFC可以发现内存漏洞,我怎样使用该特性?
如果你在Debug菜单中的Go选项(不是Project菜单中的Execute选项)来运行你的应用程序,MFC应该在程序终止时报告内存漏洞。如果没有,那么试试运行MFC Tracer 工具程序(在VC++程序组中),并启动跟踪。然后返回应用程序。

25:我怎样才能在我的应用程序中循环浏览已经打开的文档?
使用CDocTemplate中未公开的GetFirstDocPosition()和GetNextDoc()函数。

26:我怎样才能在我的应用程序中循环浏览已经打开的视?
使用CDocument中未公开的GetFirstViewPosition()和GetNextView()函数。

27:虚拟函数PreCreateWindow是干什么用的?
PreCreateWindow允许你在调用CreateWindow之前来改变窗口属性。

28:我应该怎样防止MFC在窗口标题栏上添加文档名?
在PreCreateWindow函数中删除FWS_ADDTOTITLE标志的窗口样式:
cs.style &= ~FWS_ADDTOTITLE ;

29:我应该怎样防止MFC在窗口标题栏上把文档名预置成应用程序名?
在PreCreateWindow函数中删除FWS_PREFIXTITLE标志的窗口样式:
cs.style &= ~FWS_PREFIXTITLE;

30:我有一无模式对话框。我怎样才能在窗口退出时删除CDialog对象?
把”delete this”加到PostNcDestroy中。这主要用在需要自动删除对象的场合。

31:为什么把”delete this”放在PostNcDestroy中而不是OnNcDestroy?
OnNcDestroy只被已建立的窗口调用。如果建立窗口失败(如PreCreateWindow), 则没有窗口处来发送WM_NCDESTROY消息。PostNcDestroy是在对象窗口被完全删除, 在OnNcDestroy后,甚至在窗口建立失败之后调用的。

32:File菜单中的MRU列表是从哪儿来的?列表中的名字放在哪儿了?我怎样才能改变列表中项目的最大值?
在应用程序类的InitInstance函数中对LoadStdProfileSettings的调用中。该调用接受一个参数(在缺省情况下如果没有传递值则为4)。MRU文件名是从INI文件中调用的。如果你有带有ID_FILE_MRU_FILE1的ID的菜单选项,它会为调入的MRU列表所替换。如果你改变传递给LoadStdProfileSettings的数值(最大为16),则你就改变了所装如文件名的最大值。

33:我在菜单中添加了新的项。但是,当我选该项时,在状态栏上没有出现任何提示信息。为什么?
打开资源文件中的菜单模板。打开新菜单选项的属性对话框。在对话框的底部的Prompt编辑框中,你可以如下指定状态栏上的提示信息和工具栏上的提示信息 (如果你已经建立的工具栏按钮): Status bar string\nFlying tag
 

 

Technorati : ,
Del.icio.us : ,
Ice Rocket : ,

关于volatile关键字的说明以及测试

Tuesday, May 16th, 2006

volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

使用该关键字的例子如下:

int volatile nVint;

当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指

令刚刚从该处读取过数据。而且读取的数据立刻被保存。

例如:

volatile int i=10;
int a = i;
。。。//其他代码,并未明确告诉编译器,对i进行过操作
int b = i;

volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的

汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间

的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果

i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问

注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编

代码,测试有无volatile关键字,对程序最终代码的影响:

首先用classwizard建一个win32 console工程,插入一个voltest.cpp文件,输入下面的代码:

#include <stdio.h>
void main()
{
int i=10;
int a = i;

printf(”i= %d\n”,a);
//下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
__asm {
mov dword ptr [ebp-4], 20h
}

int b = i;
printf(”i= %d\n”,b);
}

然后,在调试版本模式运行程序,输出结果如下:
i = 10
i = 32

然后,在release版本模式运行程序,输出结果如下:
i = 10
i = 10

输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。

下面,我们把 i的声明加上volatile关键字,看看有什么变化:

#include <stdio.h>
void main()
{
volatile int i=10;
int a = i;

printf(”i= %d\n”,a);
__asm {
mov dword ptr [ebp-4], 20h
}

int b = i;
printf(”i= %d\n”,b);
}

分别在调试版本和release版本运行程序,输出都是:
i = 10
i = 32

这说明这个关键字发挥了它的作用!

From: http://blog.vckbase.com/iwaswzq/archive/2004/12/05/1896.aspx

Protected: 我收藏的C++书籍

Monday, January 2nd, 2006

This post is password protected. To view it please enter your password below:


Visual Assist X v10.1.1301 特别版

Friday, December 23rd, 2005

软件名称:Visual Assist X v10.1.1301 特别版

软件介绍:

Visual Assist X是一款非常好的Visual Studio .NET 2003、2002插件,支持C/C++,C#,Visual Basic等语言,能自动识别各种关键字、系统函数、成员变量、自动给出输入提示、自动更正大小写错误、自动标示错误等,有助于提高开发过程的自动化和开发效率。

从Microsoft Visual C/C++ 6.0开始,所有的Microsoft IDE都为您的编辑环境提供了轻巧的剖析器,为您的代码编写提供方便,他们不生成目标码,这种默认帮助形式称为Intellisense。其特性包括成员列表框、完成列表框、停驻工具提示、自动参数信息。您可以在IDE对话框选项内设定每个组件的工作状态。

Visual Assist X去除了默认Intellisense的几个不足之处,采用一系列新的特性对其进行了补充,提高了IDE的可用性。其中,帮助的数量决定于IDE、所用编程语言和您设定的选项。

如同默认Intellisense,Visual Assist X也包括剖析器,运行于您的编辑过程中。该培训器同默认剖析器的不同之处在于,他们不装载预先设置的符号数据库,因此扩大了Intellisense的范围。Visual Assist X只收集您工程中的头文件和对象信息,这些头文件和对象可以包含在系统、第三方库、MFC或ATL/WTL/STL中。这意味着Intellisence的活动更加频繁,结果也更加准确。

Visual Assist X作为一种低优先度的后台线程插件,不影响您的IDE环境性能。该线程在idle期间活动,当您开始输入代码时,又回复为静默状态。并且它的剖析器不生成目标码,因此,同传统剖析器相比,占用更少的资源。

Visual Assist X提高了工作的自动化,简化了浏览,并且显示您开发过程的关键信息。其功能完全集成到IDE中,实现了二者的充分融合。为Microsoft Visual Studio .NET 2003和2002的所有编程语言提供编程助手,包括C/C++, C#, ASP, Visual Basic, Java 和 HTML,另外,还为Microsoft Visual C++ 6.0和 5.0的C/C++用户提供编程帮助。

注册信息:

Name: SSG Team

Key: xdaRF G4bKE Ic87U J7pF8 /XGEV Iz/oP YcNmg JVjaU GqzkI M1QtN ZRg9V Q

下载地址:链接1

Technorati :
Del.icio.us :
Flickr :