博文

转MFC通用类的使用(2007-12-19 12:11:00)

摘要:一、数组类:
CByteArray、CDWordArray、CPtrArray、CUIntArray、CWordArray、CstringArray
成员函数有:
Add() 在数组的最后追加一个元素,可以根据需要增大数组大小
ElementAt() 获得一个指向数组元素的指针
FreeExtra() 释放不用的数组内存
GetAt() 获取数组内指定位置处的值
GetSize() 获取数组中包含的元素个数
GetUpperBound() 获取数组的上界值
InserAt() 在数组的指定位置处插入一个元素,后面的元素的下标加1
RemoveAll() 删除数组中所有的元素
SetAt() 设定数组指定位置处的值。因为制革函数不会增加数组的大小,故这个下标此时一定有效
SetAtGrow() 设定数组的指定位置处的值,可以根据需要增大数组大小
SetSize() 设置数组的初始大小
首先,在View类中声明一个数组对象,如下:
CUIntArray array;
在View类的构造函数中初始化数组,将其设置成包含十个元素:
array.SetSize(10,5); SetSize()函数有两个参数,第一个参数是数组的初始大小,第二个参数是数组元素每次增加的个数。
现在就可以在应用程序中用了!
二、列表类的使用:
Clist() Clist类的构造函数,其中的参数指定分配内存的基本单元
GetHead() 获得列表的第一个元素的值
GetTail() 获得列表的最后一个元素的值
RemoveHead() 删除列表中第一个元素
RemoveTail() 风险列表中最后一个元素
AddHead() 在列表的头部添加一个节点,使这个节点成为列表的新的头
AddTail() 在列表的尾部添加一个节点,使这个节点成为列表的新的尾
RemoveAll() 删除节点中所有的元素
GetHeadPosition() 获得列表的头节点的位置
GetTailPosition() 获得列表中尾节点的位置
GetNext() 获得指定位置下一个节点外的值
GetPrev() 获得指定位置上一个节点外的值......

阅读全文(3066) | 评论:0

转unresolved external symbol _main相关错误(2007-12-02 20:16:00)

摘要:2006年09月12日 星期二 下午 09:02 在创建MFC项目时, 不使用MFC AppWizard向导, 如果没有设置好项目参数, 就会在编译时产生很多连接错误, 如error LNK2001错误, 典型的错误提示有:

libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main

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

msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16

nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex

nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex





下面介绍解决的方法:

1. Windows子系统设置错误, 提示:

libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main

Windows项目要使用Windows子系统, 而不是Console, 可以这样设置:

[Project] --> [Settings] --> 选择"Link"属性页,

在Project Options中将/subsystem:console改成/subsystem:windows





2. Console子系统设置错误, 提示:

LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _W......

阅读全文(1659) | 评论:0

“右左法则”[重要!!!] (2007-11-26 12:02:00)

摘要:The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.

  这是一个简单的法则,但能让你准确理解所有的声明。这个法则运用如下:从最内部的括号开始阅读声明,向右看,然后向左看。当你碰到一个括号时就调转阅读的方向。括号内的所有内容都分析完毕就跳出括号的范围。这样继续,直到整个声明都被分析完毕。

  对上述“右左法则”做一个小小的修正:当你第一次开始阅读声明的时候,你必须从变量名开始,而不是从最内部的括号。

  下面结合例子来演示一下“右左法则”的使用。

  int * (* (*fp1) (int) ) [10];

  阅读步骤:

  1. 从变量名开始 -------------------------------------------- fp1

  2. 往右看,什么也没有,碰到了),因此往左看,碰到一个* ------ 一个指针

  3. 跳出括号,碰到了(int) ----------------------------------- 一个带一个int参数的函数

  4. 向左看,发现一个* --------------------------------------- (函数)返回一个指针

  5. 跳出括号,向右看,碰到[10] ------------------------------ 一个10元素的数组

  6. 向左看,发现一个* --------------------------------------- 指针

  7. 向左......

阅读全文(2795) | 评论:0

WritePrivateProfileString函数说明(2007-11-22 13:42:00)

摘要: 在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入INI文件中,程序初始化时再读入.具体应用如下:   一.将信息写入.INI文件中.   1.所用的WINAPI函数原型为: BOOL WritePrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpString,
LPCTSTR lpFileName
);   其中各参数的意义:    LPCTSTR lpAppName 是INI文件中的一个字段名.    LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名.    LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的.    LPCTSTR lpFileName 是完整的INI文件名.   2.具体使用方法:设现有一名学生,需把他的姓名和年龄写入 c:\stud\student.ini 文件中. CString strName,strTemp;
int nAge;
strName="张三";
nAge=12;
::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini");   此时c:\stud\student.ini文件中的内容如下:    [StudentInfo]
   Name=张三   3.要将学生的年龄保存下来,只需将整型的值变为字符型即可: strTemp.format("%d",nAge);
::WritePrivateProfileString("StudentInfo","Age",strTemp,"c:\\stud\\student.ini"); 二.将信息从INI文件中读入程序中的变量.   1.所用的WINAPI函数原型为: DWORD GetPrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpDe......

阅读全文(8621) | 评论:4

转使用LARGE_INTEGER查看系统运行时间  (2007-11-21 14:10:00)

摘要:众所周知,windows ce是一个实时操作,因此提供了不少的优先级给用户.优先级最高为0级,也就是说使用0优先级的程序,  可以挂起整个系统,  来运行你的程序 对于实时性比较的领域,  我们作为程序员的  应该清楚的知道你的程序模块运行的时间 是非常必要的. 当然这个模块运行的时间也不是完全的稳定的,  几次运行的时间相差几十毫秒是很正常的.  因此我们只要知道大概的时间就可以了. 当然,  大家非常容易的想到,   先用 GetSystemTime() 获取系统时间1 ,然后处理程序  , 再获取系统时间2  ; 系统时间2 - 系统时间1 , 就是程序的运行时间?    这个方法当然行(在XP 或者 2000下是可以的),   在windows ce下就不行了,  你也可以试一试,   我试的结果,  我知道 这个方法只能精确到秒,   非常的不可靠.  自然而然 我们想到了另一种方法  也是wince下特有的. LARGE_INTEGER Freg;
LARGE_INTEGER Count1, Count2;
QueryPerformanceFrequency(&Freg);  //调用API函数,  这个API函数可是优先级0的函数啊.
QueryPerformanceCounter(&Count1);  //获取时间一 //测试程序;
QueryPerformanceCounter(&Count2);   //获取时间2
double d = (double)(Count2.QuadPart - Count1.QuadPart) / (double)Freg.QuadPart * 1000.0;
//都放大了1000倍拉!    这样的结果还是毫秒级的!!   够强 够牛吧! 当然我们可以利用函数可以做很多很多事,  包括做更精确的定......

阅读全文(6261) | 评论:0

大虾对C指针的理解(2007-11-09 14:24:00)

摘要:77535518 13:58:32
 
77535518 13:58:44
这就是
77535518 13:59:00
当定义char c[6]="abc";
77535518 13:59:19
和定义char *d;
_BAT_姜维 13:59:48
图片还没完全打开
77535518 14:00:04
 
_BAT_姜维 14:00:21
o
77535518 14:00:55
看到图了吗?
_BAT_姜维 14:01:02
看到了上一个
_BAT_姜维 14:01:16
o
77535518 14:01:17
呵呵,下一个我又重发的,不用看了
77535518 14:01:54
这样c中的地址是固定的,以后c就不能再被赋值了,像c="123"之类的就不行了
_BAT_姜维 14:02:11
o
77535518 14:03:01
而d作为指针在刚定义时,里面的值是个随机值,它就可以进行赋值操作,比如d=c
_BAT_姜维 14:03:09
o
77535518 14:03:18
这时候,内存图如下:
_BAT_姜维 14:03:28
en
77535518 14:04:31
 
77535518 14:04:53
又贴多了
_BAT_姜维 14:04:57
he
_BAT_姜维 14:05:08
看到了
77535518 14:05:35
那你画一个 d=c+1;的图给我
_BAT_姜维 14:06:27
==
77535518 14:06:30
指针可以任意赋值,甚至可以赋值不同类型的指针
77535518 14:07:27
而数组则不容许赋值,你如果想让C数组内容是“789”就不能用c="789"来进行
77535518 14:07:50
而必须用strcpy(c, "789")来进行了
77535518 14:07:56
内存图如下:
_BAT_姜维 14:07:59
o
_BAT_姜维......

阅读全文(2348) | 评论:0

转HMODULE GetModuleHandle( PCTSTR pszModu(2007-10-31 13:13:00)

摘要:当调用该函数时,你传递一个以0 结尾的字符串,用于设定加载到调用进程的地址空间的可执行文件或D L L 文件的名字。如果系统找到了指定的可 执行文件或D L L 文件名,G e t M o d u l e H a n d l e 便返回该可执行文件或D L L 文件映象加载到的基地址。如果系统没有找到该文件,则 返回N U L L 。也可以调用G e t M o d u l e H a n d l e ,为p s z M o d u l e 参数传递N U L L ,G e t M o d u l e H a n d l e 返回调 用的可执行文件的基地址。这正是C 运行期启动代码调用( w ) Wi n M a i n函数时该代码执行的操作。 请记住G e t M o d u l e H a n d l e 函数的两个重要特性。首先,它只查看调用进程的地址空间。如果调用进程不使用常用的对话框函数,那么 调用G e t M o d u l e H a n d l e 并为它传递“C o m D l g 3 2 ”后,就会返回N U L L ,尽管C o m D l g 3 2 . d l l 可能加载到了其他 进程的地址空间。第二,调用G e t M o d u l e H a n d l e 并传递N U L L 值,就会返回进程的地址空间中可执行文件的基地址。因此,即使通 过包含在D L L 中的代码来调用(N U L L ),返回的值也是可执行文件的基地址,而不是D L L 文件的基地址。    ......

阅读全文(3440) | 评论:0

转 VC其它-善用GetLastError函数     (2007-10-30 16:51:00)

摘要:在编程过程中,当程序出现错误,却又不知道错误的原因时,可以使用GetLastError函数,它可以帮助你快速找到出错的原因和语句。
      可以直接使用GetLastError函数得到错误代码,然后查找MSDN找到代码对应的错误原因,也可使用下面函数直接把错误原因显示出来: void ShowErrMsg() 
...{ 
    TCHAR szBuf[80]; 
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

  &nb......

阅读全文(4824) | 评论:0

转VC中char *name 与 char name[]的区别(基础知识)(2007-10-29 10:57:00)

摘要:VC中char *name 与 char name[]的区别(基础知识) 2007-06-09 15:36 在学习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="abc",前者改变其内容程序是会崩溃的,而后者完全正确。
程序演示:
测试环境Devc++
代码 #include <stdio.h>
#include <string.h>
main()
...{
   char *c1 = "abc";
   char c2[] = "abc";
   char *c3 = ( char* )malloc(3);
    c3 = "abc";
    printf("%d %d %s ",&c1,c1,c1);
    printf("%d %d %s ",&c2,c2,c2);
    printf("%d %d %s ",&c3,c3,c3);
    getchar();
}   

运行结果
2293628 4199056 abc
2293624 2293624 abc
2293620 4199056 abc 参考资料:
首先要搞清楚编译程序占用的内存的分区形式:
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,......

阅读全文(8495) | 评论:0

VC中的一些常用方法(20条)(2007-08-08 13:57:00)

摘要:一、打开CD-ROM 
mciSendString("Set cdAudio door open wait",NULL,0,NULL); 
二、关闭CD_ROM 
mciSendString("Set cdAudio door closed wait",NULL,0,NULL); 
三、关闭计算机 
OSVERSIONINFO OsVersionInfo; //包含操作系统版本信息的数据结构 
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
GetVersionEx(&OsVersionInfo); //获取操作系统版本信息 
if(OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) 

//Windows98,调用ExitWindowsEx()函数重新启动计算机 

DWORD dwReserved; 
ExitWindowsEx(EWX_REBOOT,dwReserved); //可以改变第一个参数,实现注销用户、 
//关机、关闭电源等操作 
// 退出前的一些处理程序 

四、重启计算机 
typedef int (CALLBACK *SHUTDOWNDLG)(int); //显示关机对话框函数的指针 
HINSTANCE hInst = LoadLibrary("shell32.dll"); //装入shell32.dll 
SHUTDOWNDLG ShutDownDialog; //指向shell32.dll库中显示关机对话框......

阅读全文(2286) | 评论:0