TRACE宏对于VC下程序调试来说是很有用的东西,有着类似printf的功能;该宏仅仅在程序的DEBUG版本中出现,当RELEASE的时候该宏就完全消失了,从而帮助你调试也在RELEASE的时候减少代码量。

使用非常简单,格式如下:

TRACE("DDDDDDDDDDD");

TRACE("wewe%d",333);

同样还存在TRACE0,TRACE1,TRACE2。。。分别对应0,1,2。。个参数

TRACE信息输出到VC IDE环境的输出窗口(该窗口是你编译项目出错提示的那个窗口),但仅限于你在VC中运行你的DEBUG版本的程序。

TRACE信息还可以使用DEBUGVIEW来捕获到。这种情况下,你不能在VC的IDE环境中运行你的程序,而将BUILD好的DEBUG版本的程序单独运行,这个时候可以在DEBUGVIEW的窗口看到DEBUGVIE格式的输出了。

VC中TRACE的用法有以下四种:

1:

TRACE ,就是不带动态参数输出字符串, 类似C的printf("输出字符串");

2:

TRACE 中的字符串可以带一个参数输出 , 类似C的printf("...%d",变量);

3:

TRACE 可以带两个参数输出,类似C的printf("...%d...%f",变量1,变量2);

4:

TRACE 可以带三个参数输出,类似C的printf("...%d,%d,%d",变量1,变量2,变量3);

TRACE 宏有点象我们以前在C语言中用的Printf函数,使程序在运行过程中输出一些调试信息,使我们能了解程序的一些状态。但有一点不同的是:


TRACE 宏只有在调试状态下才有所输出,而以前用的Printf 函数在任何情况下都有输出。和Printf 函数一样,TRACE函数可以接受多个参数如:

int x = 1;
int y = 16;
float z = 32.0;
TRACE( "This is a TRACE statement\n" );
TRACE( "The value of x is %d\n", x );
TRACE( "x = %d and y = %d\n", x, y );
TRACE( "x = %d and y = %x and z = %f\n", x, y, z );

要注意的是TRACE宏只对Debug 版本的工程产生作用,在Release 版本的工程中,TRACE宏将被忽略。
posted @ 2009-02-21 08:35 wrh 阅读(601) | 评论 (0)编辑 收藏
这个问题在论坛中的出现频率很高。在解决这个问题时,首先要明确Windows处理用户输入的方法完全不同于Dos操作系统。当用户按键后,Dos应用向操作系统提出请求,而在Windows中,当用户事件发生时,是由Windows请求调用相应的代码,代码实现自己必须的处理,最后将控制返回到操作系统。

    当你从Dos操作系统编程转向Windows的时候,你会很不习惯Windows的面向事件与消息的处理模式,但是面向对象的处理方法在Windows中非常灵活实用。

    本文要讨论的问题是如何在应用程序中实现用户事件的轮询。例如,当你的应用程序在忙碌状态时,如何探测用户按键(Escape)来终止正在进行的处理或操作。

    当用户按键或移动鼠标导致系统事件发生时,操作系统将这些事件存储在相应的应用程序消息队列中,事件会一直以消息的形式存储在消息队列中直到应用程序完消息并将控制返回到Windows,这时Windows将把消息队列中的下一条消息发送到应用程序。

   所以,为了确定是否用户已经按下了某一个按键,应用程序需要确定某一按键的消息当前是否在消息队列中。为此可以调用PeekMessage函数,例如:

MSG msg;
// 检查是否按下 Escape 键
if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,
WM_KEYLAST, PM_REMOVE)) {
if (msg.message == WM_KEYDOWN && msg.wParam 
== VK_ESCAPE)
// 退出循环或者停止处理;
}

    第一个参数MSG结构接收与消息有关的信息。第二个参数是window句柄,如果程序是基于MFC的应用,这个参数传递m_hWnd即可。下两个参数是确定类型的消息,PeekMessage将返回消息队列中落在这两个值之间的第一个消息。因为这里我们感兴趣的是按键,所以就用WM_KEYFIRST 和 WM_KEYLAST作为参数。最后一个参数可以是PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否应该从消息队列中删除。

     如果PeekMessage在请求范围内寻找消息,他返回非零值。这样上面的代码检查是否发现WM_KEYDOWN消息并且wParam等于VK_ESCAPE,如果发现则退出循环并终止代码的处理。
posted @ 2009-02-21 08:29 wrh 阅读(213) | 评论 (0)编辑 收藏
摘 要伪随机数在计算机软件设计中有很广泛的用途。本文介绍了基于数学方法的利用计算机产生伪随机数的一种方法,即线性同余法,任何伪随机数的产生都是运用递推的原理来生成的。
以及在Visual C++环境中产生伪随机数的两个重要函数,rand和srand函数,正确地使用这两个函数是产生性能良好的伪随机数的关键,最后介绍了利用伪随机数生成技术在MFC中生成基于C/S模式应用程序的随机校验码以及利用一种软件工具ImagePassword产生随机密码。

  关键词伪随机数生成;线性同余法;Visual C++;随机校验码

  为追求真正的随机序列,人们曾采用很多种原始的物理方法用于生成一定范围内满足精度(位数)的均匀分布序列,其缺点在于:速度慢、效率低、需占用大量存储空间且不可重现等。为满足计算机模拟研究的需求,人们转而研究用算法生成模拟各种概率分布的伪随机序列。伪随机数是指用数学递推公式所产生的随机数。从实用的角度看,获取这种数的最简单和最自然的方法是利用计算机语言的函数库提供的随机数发生器。典型情况下,它会输出一个均匀分布在0和1区间内的伪随机变量的值。其中应用的最为广泛、研究最彻底的一个算法即线性同余法。

  线性同余法LCG(Linear Congruence Generator)

  选取足够大的正整数M和任意自然数n0,a,b,由递推公式:

ni+1=(af(ni)+b)mod M i=0,1,…,M-1
  生成的数值序列称为是同余序列。当函数f(n)为线性函数时,即得到线性同余序列:

ni+1=(a*ni+b)mod M i=0,1,…,M-1
  以下是线性同余法生成伪随机数的伪代码:

Random(n,m,seed,a,b)
{
 r0 = seed;
 for (i = 1;i<=n;i++)
 ri = (a*ri-1 + b) mod m
}

  其中种子参数seed可以任意选择,常常将它设为计算机当前的日期或者时间;m是一个较大数,可以把它取为2w,w是计算机的字长;a可以是0.01w和0.99w之间的任何整数。

  应用递推公式产生均匀分布随机数时,式中参数n0,a,b,M的选取十分重要。

  例如,选取M=10,a=b =n0=7,生成的随机序列为{6,9,0,7,6,9,……},周期为4。

  取M=16,a=5,b =3,n0=7,生成的随机序列为{6,1,8,11,10,5,12,15,14,9,0,3,2,13,4,7,6,1……},周期为16。

  取M=8,a=5,b =1,n0=1,生成的随机序列为{6,7,4,5,2,3,0,1,6,7……},周期为8。

  Visual C++中伪随机数生成机制

  用VC产生随机数有两个函数,分别为rand(void)和srand(seed)。rand()产生的随机整数是在0~RAND_MAX之间平均分布的,RAND_MAX是一个常量(定义为:#define RAND_MAX 0x7fff)。它是short型数据的最大值,如果要产生一个浮点型的随机数,可以将rand()/1000.0,这样就得到一个0~32.767之间平均分布的随机浮点数。如果要使得范围大一点,那么可以通过产生几个随机数的线性组合来实现任意范围内的平均分布的随机数。

  其用法是先调用srand函数,如

srand( (unsigned)time( NULL ) )
  这样可以使得每次产生的随机数序列不同。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。也可以使用srand函数来人为指定种子数。
分析以下两个程序段,

  程序段1:

//包含头文件
void main() {
 int count=0;
 for (int i=0;i<10;i++){
  srand((unsigned)time(NULL));
  count++;
  cout<<"No"<
  程序段1中由于将srand()函数放在循环体内,而程序执行的CPU时间较快,调用time函数获取的时间精度却较低(55ms),这样循环体内每次产生随机数用到的种子数都是一样的,因此产生的随机数也是一样的。而程序段2中第1次产生的随机数要用到随机种子,以后的每次产生随机数都是利用递推关系得到的。
基于MFC的随机校验码生成

  Web应用程序中经常要利用到随机校验码,校验码的主要作用是防止黑客利用工具软件在线破译用户登录密码,校验码、用户名、密码三者配合组成了进入Web应用系统的钥匙。在利用VC开发的基于客户机/浏览器(Client/Server)模式的应用软件系统中,为了防止非法用户入侵系统,通常也要运用随机校验码生成技术。

  本实现要用到以上介绍到的伪随机数生成技术。校验码数据将以16进制码方式显示。主要代码如下:

void CRandompasswordDlg::OnCreatekey() {
 int RanCheckNum = 0;
 char out[25]={0};
 char keytemp[5]={0};
 memset(out,0x30,18);
 srand((unsigned)timeGetTime());//产生随机数种子
 for(int i=0;i<6;i++){
  RanCheckNum = rand();//产生随机数
  _itoa(RanCheckNum,keytemp,16);//将随机数转换成16进制
  memcpy(&out[i*4],keytemp,strlen(keytemp));
 }
 out[24]=0x00;
 strcpy(m_key.GetBuffer(18),out);
 UpdateData(FALSE);
}

  运行结果如图1所示:

伪随机数生成及在VC++中的实现(图一)
图1 利用伪随机数生成随机校验码

  程序运行时,由于每一次点击"产生随机校验码"的系统时间不同,生成随机数的种子就不一样,因此产生的随机数也是不一样的,从而保证了校验码生成的随机性。

  利用ImagePassword工具产生随机密码

  ImagePassword提供一个可选择的图形阵列,通过随机改变图形阵列中的阵点图形来产生随机密码。当随机点击图象阵列中的图象阵点,该阵点中的图象发生变化。其运行界面如图2所示:

伪随机数生成及在VC++中的实现(图二)
图2 ImagePassword运行界面

  点击OK按钮后所产生的随机密码如图3所示:

伪随机数生成及在VC++中的实现(图三)
图3 ImagePassword运行结果

  ImagePassword产生的密码的随机性依赖于用户对图象阵列中阵点图象的随机选择,一般来说用户在图象阵列中随机点击鼠标的次数越多,最后产生的密码的随机性越强。

  结束语

  伪随机数在不同的软件系统中都得到了很广泛的应用,如何选择随机数生成种子使得生成的伪随机数性能更佳是软件设计者追求的目标之一。本文提到了利用系统时间作为种子参数在一定条件下可以满足软件的随机性需要。利用所产生的随机数在游戏编程,如扑克类游戏中的随机发牌,俄罗斯方块的随机生成等等其他应用中都起到很重要的作用。
posted @ 2009-02-21 08:28 wrh 阅读(734) | 评论 (0)编辑 收藏

预编译头文件(precompiled header)

今天在写程序的时候,突然发现要测试的代码是用c写的,还是用gcc编译的,可是我已经建立了测试的相关环境,没办法,只能一步步的改了,将相关的头文件、结构和变量移植以后,编译了一下(只编译了C文件),竟然出错,出错信息为:fatal error C1010: unexpected end of file while looking for precompiled header directive

然后无论怎么改代码都是这一句出错信息,最后改成了一个最简单的空函数,仍然不行,改成cpp文件,然后前面加上#include "stdafx.h",编译通过,再改成c文件,还是出错,然后郁闷了半天,后来想到是编译器问题,改了半天设置也没搞定,最后没办法只好去网上求助了,输出precompiled header directive,想不到网上那么多的结果,看了几篇,轻松搞定,真后悔没有早点在网上搜索,浪费了不少时间。。

解决方法:

1、如果发生错误的文件是由其他的C代码文件添加进入当前工程而引起的,则Alt+F7进入当前工程的 Settings,选择C/C++选项卡,从Category组合框中选中Precompiled Headers,选择Not Using Precompiled headers。确定。

2、在文件开头添加:

#include "stdafx.h"

对预编译头文件说明如下:  

   

所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。  

   

预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。  

   

编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include   "stdafx.h"前的代码都是预编译的,它跳过#include   "stdafx.   h"指令,使用projectname.pch编译这条指令之后的所有代码。  

   

因此,所有的CPP实现文件第一条语句都是:#include   "stdafx.h"。

------------------------------------

unexpected end of file while looking for precompiled header directive Error executing cl.exe.我在文件头上添加了:

#include "stdafx.h" 还是不能运行,请多指教!

Alt+F7进入当前工程的Settings,选择C/C++选项卡,从Category组合框中选中Precompiled Headers,选择Not Using Precompiled headers。确定。

如果发生错误的文件原本是该工程中的,则检查该文件头部有没有#i nclude "stdafx.h"语句,没有的话添加。

如果还不行,也有可能是定义的类或结构体等最后忘了加分号,注意一下

------------------------------------------

问题:我在编译程序中老出现“fatal error C1010: unexpected end of file while looking for precompiled header directive”这一句,但我查看了程序并没有错,请问这是怎么一回事?

A回答:

    肯定是一个新添加的类的.cpp文件开头没包含stdafx.h,在该文件最前面加上即可。

    

BOBO的意见:

    有时可以使用右键点击项目工程中的该cpp文件,选择setting,在c/c++栏,选择PreCompiled headers,然后设置第一选项,选择不使用预编译头,解决这个问题。

---------------------------------------

编译出现问题:unexpected end of file while looking for precompiled header directive

解决方案:

需要在文件头上添加一句:

#include "stdafx.h"

这个文件定义了源程序为C++格式。

否则文件需要保存为.C格式

--------------------------------

错误:fatal error C1083: Cannot open precompiled header file: 'Debug\test4.pch': No such file or directory

解决方案:

或rebuild all,或重新编译一下stdafx.cpp就OK了,呵呵,又长知识了。

---------------------------------

今天在改一个很大的程序,慢慢看,慢慢改。突然发现一个.c文件,里面什么也没有, 就几个头文件,我一看,我靠,这不是把简单的问题搞复杂了吗,随手删掉那个c文件。 结果不能编译了,我靠:

fatal error C1083: Cannot open precompiled header file: \'Debug/v13_3.pch\':

No such file or directory

怎么rebuild all都不行。

上网查了一下,才搞懂了:

----------------总结------

如果工程很大,头文件很多,而有几个头文件又是经常要用的,那么

1。把这些头文件全部写到一个头文件里面去,比如写到preh.h

2。写一个preh.c,里面只一句话:#include "preh.h"

3。对于preh.c,在project setting里面设置creat precompiled headers,对于其他.c文件,设置use precompiled header file

//

哈哈

我试了一下,效果很明显,不用precompiled header,编译一次我可以去上个厕所,用 precompiled header,编译的时候,我可以站起来伸个懒腰,活动活动就差不多啦

---------转载的文章----------

预编译头的概念:

所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译头文件这些预先编译好的代码可以是任何的 C/C++代码--------甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会 被经常改变。如果这些代码被修改,则需要重新编译生成预编译头文件。注意生成预编 译头文件是很耗时间的。同时你得注意预编译头文件通常很大,通常有6-7M大。注意及 时清理那些没有用的预编译头文件。 也许你会问:现在的编译器都有Time stamp的功能,编译器在编译整个工程的时候,它 只会编译那些经过修改的文件,而不会去编译那些从上次编译过,到现在没有被修改过的文件。那么为什么还要预编译头文件呢?答案在这里,我们知道编译器是以文件为单 位编译的,一个文件经过修改后,会重新编译整个文件,当然在这个文件里包含的所有 头文件中的东西(.eg Macro, Preprocesser )都要重新处理一遍。VC的预编译头文件保存的正是这部分信息,以避免每次都要重新处理这些头文件。

预编译头的作用:

根据上文介绍,预编译头文件的作用当然就是提高编译速度了,有了它你没有必要每次都编译那些不需要经常改变的代码,编译性能当然就提高了。

预编译头的使用:

要使用预编译头,我们必须指定一个头文件,这个头文件包含我们不会经常改变的 代码和其他的头文件,然后我们用这个头文件来生成一个预编译头文件(.pch文件)

想必大家都知道 StdAfx.h这个文件。很多人都认为这是VC提供的一个“系统级别”的编译器带的一个头文件。其实不是的,这个文件可以是任何名字的。我们来考察一个典型的由AppWizard生成的MFC Dialog Based 程序的预编译头文件。(因为AppWizard 会为我们指定好如何使用预编译头文件,默认的是StdAfx.h,这是VC起的名字)。我们会发现这个头文件里包含了以下的头文件:

#include <afxwin.h> // MFC core and standard components

#include <afxext.h> // MFC extensions

#include <afxdisp.h> // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#include <afxcmn.h>

这些正是使用MFC的必须包含的头文件,当然我们不太可能在我们的工程中修改这些头文件的,所以说他们是稳定的。那么我们如何指定它来生成预编译头文件。我们知道一个头文件是不能编译的。所以我们还需要一个cpp文件来生成.pch 文件。这个文件默认的就是StdAfx.cpp。在这个文件里只有一句代码就是:#include “Stdafx.h”。原因是理所当然的,我们仅仅是要它能够编译而已,也就是说,要的只是它的.cpp的扩展名。我们可以用/Yc编译开关来指定StdAfx.cpp来生成一个.pch文件,通过/Fp编译开关来指定生成的pch文件的名字。打开project ->Setting->C/C++ 对话框,把Category指向Precompiled Header。在左边的树形视图里选择整个工程 Project Options(右下角的那个白的地方)可以看到 /Fp “debug/PCH.pch”,这就是指定生成的.pch文件的名字,默认的通常是 <工程名>.pch(我的示例工程名就是PCH)。

然后,在左边的树形视图里选择StdAfx.cpp.//这时只能选一个cpp文件!

这时原来的Project Option变成了 Source File Option(原来是工程,现在是一个文件,当然变了)。在这里我们可以看到 /Yc开关,/Yc的作用就是指定这个文件来创建一个Pch文件。/Yc后面的文件名是那个包含了稳定代码的头文件,一个工程里只能有一个文件的可以有YC开关。VC就根据这个选项把 StdAfx.cpp编译成一个Obj文件和一个PCH文件 。

然后我们再选择一个其它的文件来看看,//其他cpp文件在这里,Precomplier 选择了 Use Precompiled Header 一项,头文件是我们指定创建PCH 文件的stdafx.h 文件。事实上,这里是使用工程里的设置,(如图1)/Yu”stdafx.h”,这样我们就设置好了预编译头文件,也就是说,我们可以使用预编译头功能了。

以下是注意事项:

1):如果使用了/Yu,就是说使用了预编译,我们在每个.cpp文件的最开头,我强调一遍是最开头,包含你指定产生pch文件的.h文件(默认是stdafx.h)不然就会有问题。如果你没有包含这个文件,就告诉你Unexpected file end. 如果你不是在最开头包含的,

你自己试以下就知道了,绝对有很惊人的效果?..

fatal error C1010: unexpected end of file while looking for precompiled

header directive

Generating Code...

2)如果你把pch文件不小心丢了,编译的时候就会产生很多的不正常的行为。根据以上的分析,你只要让编译器生成一个pch文件,也就是说把 stdafx.cpp(即指定/Yc的那个cpp文件)从新编译一遍,当然你可以傻傻的 Rebuild All,简单一点就是选择那个cpp文件,按一下Ctrl + F7就可以了,不然可是很浪费时间的哦。

posted @ 2009-02-20 13:36 wrh 阅读(4051) | 评论 (0)编辑 收藏

是新加的类里没加入头文件stdafx.h
方法1:在新增加的类的文件前#include "stdafx.h"
方法2:在project->settings->C\C++ ->project options里的/Yu"stdafx.h" 删除

posted @ 2009-02-20 10:49 wrh 阅读(2076) | 评论 (0)编辑 收藏

1.unexpected end of file while looking for precompiled header directive

A1、右键点工程名,选设置,然后选c/c++属性页,再选catagory选单中选 precompiled header ,将选项置成no use 或者autometic

A2、好像是工程中设置了预编译头文件,但你的程序中事实上没有添加这个头文件. 主要是stdafx.h Project Setting->C/C++ -> Category(Precompiled header)->not using Precompiled header试试

下面是msdn的说法: Fatal Error C1010 unexpected end of file while looking for precompiled header directive A precompiled header was specified, but it did not contain a precompiled header directive. This error can be caused by specifying an incorrect file as a header file, or by specifying an include file with the /Yu (Use Precompiled Header) command line option that is not listed in the source file as an include file.

 注:http://hi.baidu.com/chinapegasus/blog/item/27ede14f949d5133afc3ab9a.html

2.

LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16 >

[Project] --> [Settings] --> 选择"Link"属性页, 在Project Options中将/subsystem:console改成/subsystem:windows  

2. Console子系统设置错误, 提示:  LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16 >

控制台项目要使用Console子系统, 而不是Windows, 设置:

[Project] --> [Settings] --> 选择"Link"属性页,  在Project Options中将/subsystem:windows改成/subsystem:console

3. 程序入口设置错误, 提示: msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16 

通常, MFC项目的程序入口函数是WinMain, 如果编译项目的Unicode版本, 程序入口必须改为wWinMainCRTStartup, 所以需要重新设置程序入口:

[Project] --> [Settings] --> 选择"Link"属性页,  在Category中选择Output,  再在Entry-point symbol中填入wWinMainCRTStartup, 即可

4. 线程运行时库设置错误, 提示:   nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex  nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex

这是因为MFC要使用多线程时库, 需要更改设置:

[Project] --> [Settings] --> 选择"C/C++"属性页,   在Category中选择Code Generation,  再在Use run-time library中选择Debug Multithreaded或者multithreaded  咸鱼游侠(75374355) 12:11:11  其中,  Single-Threaded 

          

   单线程静态链接库(release版本)  Multithreaded              

   多线程静态链接库(release版本)  multithreaded DLL            

 多线程动态链接库(release版本)  Debug Single-Threaded

  单线程静态链接库(debug版本)  Debug Multithreaded         

  多线程静态链接库(debug版本)  Debug Multithreaded DLL   

 多线程动态链接库(debug版本)

单线程: 不需要多线程调用时, 多用在DOS环境下 

多线程: 可以并发运行

 静态库: 直接将库与程序Link, 可以脱离MFC库运行

 动态库: 需要相应的DLL动态库, 程序才能运行

 release版本: 正式发布时使用  debug版本: 调试阶段使用


文章出处:http://www.diybl.com/course/3_program/c++/cppjs/2008619/126655.html

posted @ 2009-02-20 10:41 wrh 阅读(7162) | 评论 (0)编辑 收藏

1、fatal error C1010: unexpected end of file while looking for precompiled header directive。
寻找预编译头文件路径时遇到了不该遇到的文件尾。(一般是没有#include "stdafx.h")

2、fatal error C1083: Cannot open include file: 'R…….h': No such file or directory
不能打开包含文件“R…….h”:没有这样的文件或目录。

3、error C2011: 'C……': 'class' type redefinition
类“C……”重定义。

4、error C2018: unknown character '0xa3'
不认识的字符'0xa3'。(一般是汉字或中文标点符号)

5、error C2057: expected constant expression
希望是常量表达式。(一般出现在switch语句的case分支中)

6、error C2065: 'IDD_MYDIALOG' : undeclared identifier
“IDD_MYDIALOG”:未声明过的标识符。

7、error C2082: redefinition of formal parameter 'bReset'
函数参数“bReset”在函数体中重定义。

8、error C2143: syntax error: missing ':' before '{'
句法错误:“{”前缺少“;”。

9、error C2146: syntax error : missing ';' before identifier 'dc'
句法错误:在“dc”前丢了“;”。

10、error C2196: case value '69' already used
值69已经用过。(一般出现在switch语句的case分支中)

11、error C2509: 'OnTimer' : member function not declared in 'CHelloView'
成员函数“OnTimer”没有在“CHelloView”中声明。

12、error C2511: 'reset': overloaded member function 'void (int)' not found in 'B'
重载的函数“void reset(int)”在类“B”中找不到。

13、error C2555: 'B::f1': overriding virtual function differs from 'A::f1' only by return type or calling convention
类B对类A中同名函数f1的重载仅根据返回值或调用约定上的区别。

14、error C2660: 'SetTimer' : function does not take 2 parameters
“SetTimer”函数不传递2个参数。

15、warning C4035: 'f……': no return value
“f……”的return语句没有返回值。

16、warning C4553: '= =' : operator has no effect; did you intend '='?
没有效果的运算符“= =”;是否改为“=”?

17、warning C4700: local variable 'bReset' used without having been initialized
局部变量“bReset”没有初始化就使用。

18、error C4716: 'CMyApp::InitInstance' : must return a value
“CMyApp::InitInstance”函数必须返回一个值。

19、LINK : fatal error LNK1168: cannot open Debug/P1.exe for writing
连接错误:不能打开P1.exe文件,以改写内容。(一般是P1.Exe还在运行,未关闭)

20、error LNK2001: unresolved external symbol "public: virtual _ _thiscall C……::~C……(void)"
连接时发现没有实现的外部符号(变量、函数等)。

function call missing argument list 调用函数的时候没有给参数。

member function definition looks like a ctor, but name does not match enclosing class 成员函数声明了但没有使用

unexpected end of file while looking for precompiled header directive 在寻找预编译头文件时文件意外结束,编译不正常终止可能造成这种情况。

posted @ 2009-02-20 10:35 wrh 阅读(327) | 评论 (0)编辑 收藏

如何抛出(throw)由CUserException派生的异常?

当我试图捕获(catch)一个派生类异常时,我得到以下错误"error C2039:'classCMyException': is not a member of 'CMyException' 'classCMyException': undeclared identifier 'IsKindOf': cannot convert parameter 1 from 'int*' to 'const struct CRuntimeClass*"

你必需通过使用DECLARE_DYNAMIC()和IMPLEMENT_DYNAMIC()宏来使你的CMyException类可以动态地创建。CATCH宏希望能够得到关于被抛出类的运行时刻信息。

异常类一定要从CUserException中派生出来吗?

不,CUserException中的"User"仅仅指用户产生的异常。而把它当作你所能派生的唯一异常是种常见的误解。

如何从HDC建立一个CDC类?

有时Windows API将会给你一个DC句柄,你可以通过它建立一个CDC类。例如:下拉式列表、组合框和按钮。通过hDC你将接收到绘制消息。下面是将HDC转换成你更熟悉的CDC的程序段。你也可以将该技巧用在其他任何MFC类和Windows句柄的转换中。

void MyODList::DrawItem(LPDRAWITEMSTRUCT lpDrawItem)
{
CDC myDC;
myDC.Attach(lpDrawItem->hDC);
//在此插入其他需要的代码。
//如果你不将句柄分离,它将被删除,从而导致问题。
myDC.Detach();
}
另一个方法是调用CDC类的FromHandle方法:
CDC * pDC = CDC:FromHandle(lpDrawItem->hDC);
目前还不清楚哪种方法更优越―使用FromHandle()的错误也许会更少些,因为它不要求你分离(detach)句柄。

如何从磁盘上读取256色位图文件?

当前,MFC并不支持直接读取和显示DIB文件和BMP文件。然而,有很多样例应用程序能够说明如何完成该项任务。第一个例子是MFC样例程序DIBLOOK。样例MULTDOCS用DIBLOOK提供的相同源代码来读取并显示DIB文件和BMP文件。其他两个VC++中附带的例子是SDK软件包中的DIBVIEW程序和SHOWDIB程序。

如何改变一个视图的大小?

通常,你可以调用函数MoveWindow()来改变窗口的大小。在用MFC库开发的应用程序中, 视图是被框架窗口所围绕的一个子窗口。为了改变一个视图的大小,你可以通过调用函数GetParentFrame()来得到框架窗口的指针,然后调用函数MoveWindow()来改变父窗口的大小。当父框架窗口改变大小时,视图也会自动地改变大小来适应父窗口。

如何改变一个CFormView的大小?

要想详细了解的话,你可以看有关Visual C++基础知识的文章Q98598 《Using CFormView in SDI and MDI Applications》。基本上,在从CFormView类派生出来的类中,你必须覆盖函数OnInitialUpdate()。其他有关建立CFormView的细节问题,可以从该文章中获得。

在类ClikethisView中声明如下函数:
virtual void OnInitialUpdate();
在ClikethisView的代码中,函数如下:
void ClikethisView::OnInitialUpdate()
{
//使窗口与主对话框同样大小
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit( /*FALSE*/ );
}

如何使用一个文档模板的新视图?

在用AppWizard创建的应用程序中,你有两种选择:改变当前视图的派生关系或者建立一个新视图并且在你的MDI程序中同时利用新视图和原先的视图。


为了创建一个新视图,你可以用ClassWizard由CView派生一个新的类。当新类创建以后,利用新视图或修改由AppWizard提供的视图,两者的步骤是相同的。


修改视类的头文件,从而将所有对CView类的引用改名为你所想要的名称。本例中的类由CScrollView派生而来。通常,这个步骤包括对类的改变,视类将由如下方式派生而来:
    class CMyView : public CScrollView


修改视类的实现文件,从而将所有对CView的引用改名为你所想要的名称。这包括将IMPLEMENT_DYNCREATE那一行的语句改为:
    IMPLEMENT_DYNCREATE(CMyView, CScrollView)


将BEGIN_MESSAGE_MAP那一行的语句改为:
    BEGIN_MESSAGE_MAP(CMyView, CScrollView)


并且将其他所有的CView改成CScrollView.


假如你修改的视图是由AppWizard生成的,那么就不需要作更多的修改了。而如果你在创建一个新视图,先在CWinApp::InitInstance()函数中找到对AddDocTemplate()函数的调用。AddDocTemplate()函数的第三个参数是RUNTIME_CLASS(CSomeView),用CMyView来代替CSomeView,就可以将当前视图改为新视图。在MDI应用程序中,你可以增加第二个AddDocTemplate()函数调用来使用多视图类型,将RUNTIME_CLASS(CSomeView)改为RUNTIME_CLASS (CMyView)。

要想获得更多的信息请参阅Q99562中相关文章《Switching Views in a Single Document Interface Program》 。

如何改变视图的背景色?

你可以通过处理WM_ERASEBKGND消息来改变CView、CFrameWnd或CWnd对象的背景色。请看如下的程序段:

  BOOL CSampleView::OnEraseBkgnd(CDC* pDC)
{
// 设置所要求背景色的刷子
CBrush backBrush(RGB(255, 128, 128));
// 保存旧刷子
CBrush* pOldBrush = pDC->SelectObject(&backBrush);
CRect rect;
pDC->GetClipBox(&rect);     // 擦除所需的区域
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
pDC->SelectObject(pOldBrush);
return TRUE;
}
而我则用如下方法解决这个问题:
  HBRUSH dlgtest::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
switch (nCtlColor)
{
case CTLCOLOR_BTN:
case CTLCOLOR_STATIC:
{
pDC->SetBkMode(TRANSPARENT);
}
case CTLCOLOR_DLG:
{
CBrush*     back_brush;
COLORREF    color;
color = (COLORREF) GetSysColor(COLOR_BTNFACE);
back_brush = new CBrush(color);
return (HBRUSH) (back_brush->m_hObject);
}
}
return(CFormView::OnCtlColor(pDC, pWnd, nCtlColor));
}

如何得到当前视图?

最佳方法是将视图当作一个参数来传递。如果不能这样做,但你确信它是当前激活文档和当前激活视图的话,你也可以得到该视图。具体细节见Visual C++文章Q108587《Get Current CDocument or CView from Anywhere》。

简单说来,用:
((CFrameWnd*) AfxGetApp()->m_pMainWnd))->GetActiveDocument()
和:
((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView()
来得到文档和视图。一个好的方法是将它们封装在你的CMyDoc和CMyView类的静态函数中,并且核对它们是否属于正确的RUNTIME_CLASS。然而,假如这个视图不是当前激活视图或者你在运行OLE本地激活,这样将不成功。

如何在一个文档中建立多个视图?

CDocTemplate::CreateNewFrame()函数创建MFC MDI应用程序中的文档的附加视图。为了调用该函数,要指定一个指向CDocument对象(指将为之建立视图的文档)的指针和一个指向可从中复制属性的框架窗口的指针。一般情形下,该函数的第二个参数为NULL。

当应用程序调用函数CreateNewFrame()时,该函数就创建一个框架窗口和在该窗口内的视图。框架窗口和它的视图的类型由与CreateNewFrame()函数调用指定的文档相关的文档摸板(CDocTemplate)决定。

Visual C++中的CHKBOOK MFC样例程序也演示了如何为文档建立附加的框架和视图。检查CHKBOOK.CPP文件中的CChkBookApp::OpenDocumentfile()函数。

另一个用函数CreateNewFrame()的例子是MULTVIEW样本程序。

CreateNewFrame()函数建立了一个框架和一个视图,而不仅仅是一个视图。假如CreateNewFrame()函数不能完全符合你的需要,可参考CreateNewFrame()函数的源程序来了解对建立结构和视图所必须的步骤。

如何在MDI程序中得到所有的视图?

你必须用一些文档中没有记载的函数:

  CDocument::GetFirstViewPosition(); // DOCCORE.CPP
CDocument::GetNextView(); // DOCCORE.CPP
CMultiDocTemplate::GetFirstDocPosition(); // DOCMULTI.CPP
CMultiDocTemplate::GetNextDoc(); // DOCMULTI.CPP

你还需要与CWinApp的成员m_templateList打交道。
注意:在MFC 版本4.0中已改变。现在已经有一个叫CDocManager的类可以帮助你显示所有的视图和文档。请参考《MFC Internals》获得更详细的信息。

如何建立一个可用鼠标拉动的CScrollView类

在CIS上从MSMFC库下载AUTOSV.LZH。这个程序告诉你如何实现一个辅助消息循环来管理鼠标的活动,并提供了钩挂来对代码进行定制。这是一个免费软件。

一定要用视图/文档结构吗?

MFC并不一定要求你使用文档/视图结构。查看HELLO、 MDI和HELLOAPP例子―它们就没有用那种结构。大多数MFC特性都可以在非文档/视图应用程序中得到运用。但是当你不用文档 / 视图结构时,你确实会失去一些特性,例如打印预览和许多OLE特性。

如何得到当前文档?

请详细参阅"如何得到当前视图?"章节。

文档何时被析构?

在SDI程序中,程序退出后文档就被删除。在MDI程序中,与该文档相关的最后一个视图关闭时文档就被删除。为了在SDI和MDI中同时用这个文档,你应该在虚函数DeleteContents()函数中删除该文档的数据,而不是在析构器中。

如何建立多文档?

为了加入对附加文档类型的支持,你可以在CWinApp派生类中创建和注册附加CmultiDocTemplate对象。这种方法已经在MULTDOCS样例程序中得以说明。将一个附加文档类型加入到MFC程序的一般步骤如下:

用AppWizard来创建一个新的文档类和视图类。
用资源编辑器增加新的资源字串来支持新的文档类。要想知道关于文档样板字符串格式的更多内容,请参阅"如何理解文档样板字符串"。

用资源编辑器增加附加的应用程序图标和菜单资源。注意,这些资源中每一个的ID都必须与在步骤2中创建的文档模板字符串的ID是相同的。这个ID被CmultiDocTemplate类用来识别与附加文档类型相关的资源。

在应用程序的InitInstance()函数中,创建了另一个CMultiDocTemplate对象并且用CWinApp::AddDocTemplate()函数来注册。例如:

CMultiDocTemplate* pDocTemplate2 = new CMultiDocTemplate(
IDR_DOC2TYPE, RUNTIME_CLASS(CDoc2),
RUNTIME_CLASS(CMDIChildWnd),RUNTIME_CLASS(CView2));
AddDocTemplate(pDocTemplate2);
最后,将定制的序列化和绘图代码加入到你的新文档和视图类中。

如何得到一个打开文档的列表?

下面的程序段指明如何得到用CDocTemplate对象建立的所有文档的指针列表。
下面的程序段中,CMyApp由CWinApp派生而来。变量m_templateList是一个CPtrList对象,它是CwinApp的成员变量,包含一个所有文档模板指针的列表。文档模板函数GetFirstDocPosition()和GetNextDoc()被用来在文档模板列表中进行迭代来得到每一个文档模板。

  void CMyApp::GetDocumentList(CObList * pDocList)
{
ASSERT(pDocList->IsEmpty());
POSITION pos = m_templateList.GetHeadPosition();
while (pos)
{
CDocTemplate* pTemplate =
(CDocTemplate*)m_templateList.GetNext(pos);
POSITION pos2 = pTemplate->GetFirstDocPosition();
while (pos2)
{
CDocument * pDocument;
if ((pDocument=pTemplate->GetNextDoc(pos2)) != NULL)
pDocList->AddHead(pDocument);
}
}
}

在参考手册或在线帮助中,有两个CdocTemplate类的公共成员函数没有被说明。然而, 这些公共成员函数在CDocTemplate类中被定义,并且为在打开文档的列表中前后搜索提供了简单的支持。

这些函数如下:


Function virtual POSITION GetFirstDocPosition() const;
调用该函数得到在打开的文档列表中与模板相关联的第一个文档的位置。返回的POSITION的值能够被GetNextDoc成员函数反复使用。

Function Virtual CDocument* GetNextDoc(POSITION& rPosition) const;
rPostion是前面调用GetNextDoc 或GetFirstDocPosition成员函数返回的POSITION值。这个值不能是NULL。调用该函数来在所有打开的文档中进行迭代。该函数返回被rPosition所标识的文档并将rPosition设置为列表中的下一个文档的POSITION值。假如所检索的是列表中的最后一个文档,rPosition将被设为空值。

注意,这仅对MFC3.2版本或更低版本有效,对MFC4.0版本请参考下面:

  void CMyApp::DoSomethingToAllDocs()
{
CObList  pDocList;
POSITION pos = GetFirstDocTemplatePosition();
while(pos)
{
CDocTemplate* pTemplate = GetNextDocTemplate(pos);
POSITION pos2 = pTemplate->GetFirstDocPosition();
while(pos2)
{
CDocument* pDocument;
if(pDocument = pTemplate->GetNextDoc(pos2))
pDocList.AddHead(pDocument);
}
}
if(!pDocList.IsEmpty()){
pos = pDocList.GetHeadPosition();
while(pos)
{
//为每一个文档调用CDocument函数
( (CDocument*)pDocList.GetNext(pos) )
->UpdateAllViews(NULL);
}
}

如何使我的程序在启动时不创建一个新文档?

在程序的InitInstance中的ProcessShellCommand函数之前加入: cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing

posted @ 2008-12-26 16:45 wrh 阅读(206) | 评论 (0)编辑 收藏

格式:文件指针名=fopen(文件名,使用文件方式)

参数:
文件名 意义
"C:/temp/temp.txt" 文件 C:\temp\temp.txt

文件使用方式   意 义
“rt”     只读打开一个文本文件,只允许读数据
“wt”        只写打开或建立一个文本文件,只允许写数据
“at”        追加打开一个文本文件,并在文件末尾写数据
“rb”       只读打开一个二进制文件,只允许读数据
“wb”       只写打开或建立一个二进制文件,只允许写数据
“ab”     追加打开一个二进制文件,并在文件末尾写数据
“rt+”    读写打开一个文本文件,允许读和写。用fseek确定读写位置,写多少覆盖多少,
                          后面的内容保留。因为磁盘空间是连续的,所以你不能在中间插入,在中间一旦
                           写入就是覆盖与写入内容等长的那些内容。
“wt+”    读写打开或建立一个文本文件,允许读写
“at+”    读写打开一个文本文件,允许读,或在文件末追加数据
“rb+”    读写打开一个二进制文件,允许读和写
“wb+”    读写打开或建立一个二进制文件,允许读和写
“ab+”     读写打开一个二进制文件,允许读,或在文件末追加数据

对于文件使用方式有以下几点说明:

  1. 文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:

  r(read): 读
  w(write): 写
  a(append): 追加
  t(text): 文本文件,可省略不写
  b(banary): 二进制文件
  +: 读和写

  2. 凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。

  3. 用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。

  4. 若要向一个已存在的文件追加新的信息,只能用“a ”方式打开文件。但此时该文件必须是存在的,否则将会出错。

  5. 在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。

如果成功的打开一个文件, fopen()函数返回文件指针, 否则返回空指针
(NULL)。由此可判断文件打开是否成功。




fclose()函数用来关闭一个由fopen()函数打开的文件 , 其调用格式为:
       int fclose(FILE *stream);
     该函数返回一个整型数。当文件关闭成功时, 返回0, 否则返回一个非零值。
可以根据函数的返回值判断文件是否关闭成功

posted @ 2008-12-18 21:46 wrh 阅读(907) | 评论 (0)编辑 收藏

1)(CStuDlg*)AfxGetMainWnd()  //AfxGetMainWnd() 得到主程序的指针!~~

2)GetDlgItem(IDC_EDIT3)   //GetDlgItem()得到控件指针!~~

3)GetDlgItem(IDC_ENGLISH)->SetFocus();  //SetFocus()光标所在区!~~~

4)SetGlgItemText(dlg,IDC_WIDTH,"");设置控件的名称!~~

5)MessageBox(

                               LPCTSTR lpszText,//消息字符串

                               LPCTSTR lpszCaption=NULL,//消息框标题

                               UINT nType=MB_OK  //消息框风格

                               );

posted @ 2008-12-15 21:21 wrh 阅读(188) | 评论 (0)编辑 收藏
仅列出标题
共25页: First 14 15 16 17 18 19 20 21 22 Last 

导航

<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(19)

随笔档案

文章档案

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜