博文

给VC应用程序加一个启动画面(2008-07-07 19:14:00)

摘要:给应用程序加一个启动画面





  你的应用程序是否也想拥有一个像VB,VC的程序启动画面呢?本文用VC++6.0所提供的“Splash Screen”组件给应用程序加上一个闪屏显示的功能。

  1、添加组件
  打开选项“Projects”选“Add To Project”,打开“Component and Controls”,在文件框中选择“Splash Screen”。这样我们就将所需要的CsplashWnd类加入到应用程序项目中。

  2、为程序加入代码
  利用ClassView打开CMyChapterApp.cpp,在文件头上加上“#include splash.h",在函数CMyChapterApp::InitInstance()中的LoadStdProfileSettings()函数后填入以下代码:
  CSplashWnd::ShowSplashScreen();
  Sleep(1000);
  Sleep()函数是为了模拟缓慢的装载过程,你可以在此处加入自己的代码来装载文件信息,如读写数据库中的记录等等……与之等效的是你可以用ClassView打开CSplashWnd类,在CSplashWnd::OnCreate()中修改SetTimer()中的第二个参数,将时间延长。现在你要做的是用ResourceView打开Bitmap资源,换上自己想要的位图,就可以编译应用程序了,效果怎么样?

3、用SetTimer()和EndTimer()同样可以实现......

阅读全文(2696) | 评论:1

进一步理解VC中的句柄(2008-07-07 19:13:00)

摘要:进一步理解VC中的句柄





正文:

  <<Microsoft Windows 3 Developer's Workshop>>(Microsoft Press,by Richard Wilton)一书中句柄的概念是这样的:在Windows环境中,句柄是用来标识项目的,这些项目包括:模块(module)、任务(task)、实例(instance)、文件(file)、内存块(block of memory)、菜单(menu)、控制(control)、字体(font)、资源(resource),包括图标(icon),光标(cursor),字符串(string)等、GDI对象(GDI object),包括位图(bitmap),画刷(brush),元文件(metafile),调色板(palette),画笔(pen),区域(region),以及设备描述表(device context)。

  在<<WINDOWS编程短平快>>(南京大学出版社)一书中是这么说的:句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。

  从上面的两个定义中我们可以看到,句柄实际上是一个标识符,是用来标识对象或者项目的,句柄是一个 32 位的正整数,Microsoft&reg; Windows&reg; 用它来识别窗体或其他对象,例如字体或位图。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用这个句柄,以引用相应的对象。在WINDOWS编程中会用到大量的句柄,比如:HINSTANCE(实例句柄),HBITMAP(位图句柄),HDC(设备描述表句柄),HICON(图标句柄)等等,这当中还有一个通用的句柄HANDLE。

  一个WINDOWS应用程序可以用不同的方法获得一个特定项的句柄。许多API函数,诸如CreateWindow,GlobalAlloc,OpenFile的返回值都是一个句柄值。另外,WINDOWS也能通过应用程序的引出函......

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

浅谈内存泄漏(2008-07-07 19:12:00)

摘要:浅谈内存泄漏




  对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题。已经有许多技术被研究出来以应对这个问题,比如Smart Pointer,Garbage Collection等。Smart Pointer技术比较成熟,STL中已经包含支持Smart Pointer的class,但是它的使用似乎并不广泛,而且它也不能解决所有的问题;Garbage Collection技术在Java中已经比较成熟,但是在c/c++领域的发展并不顺畅,虽然很早就有人思考在C++中也加入GC的支持。现实世界就是这样的,作为一个c/c++程序员,内存泄漏是你心中永远的痛。不过好在现在有许多工具能够帮助我们验证内存泄漏的存在,找出发生问题的代码。


内存泄漏的定义
  一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内存。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。以下这段小程序演示了堆内存发生泄漏的情形:

void MyFunction(int nSize)
{
char* p= new char[nSize];
if( !GetStringFrom( p, nSize ) ){
MessageBox(“Error”);
return;
}
…//using the string pointed by p;
delete p;
}


  当函数GetStringFrom()返回零的时候,指针p指向的内存就不会被释放。这是一种常见的发生内存泄漏的情形。程序在入口处分配内存,在出口处释放内存,但是c函数可以在任何地方退出,所以一旦有某个出口处没有释放应该释放的内存,就会发生内存泄漏。
广义的说,内存泄漏不仅仅包含堆内存的泄漏,还包含系统资源的泄漏(resource leak),比如核心态HANDLE,GDI Object,SOCKET,Inter......

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

深入理解C语言指针的奥秘(2008-07-07 19:10:00)

摘要:深入理解C语言指针的奥秘


指针的概念

  指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。 要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的 类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。让我们分别说明。

  先声明几个指针放着做例子:

  例一:

  (1)int* ptr;

  (2)char* ptr;

  (3)int** ptr;

  (4)int(*ptr)[3];

  (5)int*(*ptr)[4];

  如果看不懂后几个例子的话,请参阅我前段时间贴出的文章<<如何理解c和c ++的复杂类型声明>>。

指针的类型

  从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:

  (1)int* ptr;//指针的类型是int*

  (2)char* ptr;//指针的类型是char*

  (3)int** ptr;//指针的类型是int**

  (4)int(*ptr)[3];//指针的类型是int(*)[3]

  (5)int*(*ptr)[4];//指针的类型是int*(*)[4]

  怎么样?找出指针的类型的方法是不是很简单?

指针所指向的类型

  当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。

  从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。例如:

  (1)int* ptr;//指针所指向的类型是int

  (2)char* ptr;//指针所指向的的类型是char

  (3)int** ptr;//指针所指向的的类型是int*

  (4)int(*ptr)[3]......

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

有关注册表API函数(2008-07-07 19:08:00)

摘要:有关注册表API函数




  注册表的操作,API为我们提供了大约25个函数。他提供了对注册表的读取,写入,删除,以及打开注册表及键值时所有函数,并且可以达到对注册表的备份,连接和对远端注册表进行查看等等。注册表对整个系统十分重要,你在进行操作时,一定要先考虑清楚。这些函数有:
RegCloseKey RegConnectRegistry RegCreateKey RegCreateKeyEx RegDeleteKey RegDeleteVale
RegEnumKey RegFlushKey RegGetKeySecurity(此函数,98不适用) RegLoadKey
RegNotifyChangeKeyValue(98不适用) RegOpenKey RegOpenKeyEx RegQueryInfoKey RegQueryValue
RegQueryValueEx RegReplaceKey RegRestoreKey(98不适用) RegSaveKey RegSetKeySecurity(98不适用) RegSetValue RegSetValueEx RegUnLoadKey
  我们对经常使用的几个函数进行介绍。
1·RegClose()
原形:LONG RegCloseKey(
HKEY hKey // 释放已经打开的注册表句柄
);
  返回值:不成功返回非0,成功返回ERROR_SUCCESS
  解释:关闭指定的主册表键,释放句柄。当对一个或多个键或值操作完成以后,需要关闭其键来进行保存操作结果。关闭一个键后,句柄变为非法,以使其不可再次被使用。为系统重新使用而释放句柄。
例子
BOOL bRet = TRUE;
if( m_hKey == NULL )
return( FALSE );
bRet = ( ::RegCloseKey( m_hKey ) == ERROR_SUCCESS );
m_hKey = NULL;
return( bRet );

2·RegCreateKeyEx()和RegCreateKey()
原形:LONG RegCrea......

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

函数调用的几个概念:_stdcall,_cdecl....(2008-07-07 19:07:00)

摘要:函数调用的几个概念:_stdcall,_cdecl....

 

  参数通过栈传递,被调用的函数在返回前清理传送参数的内存栈,但不同的是函数名的修饰部分(关于函数名的修饰部分在后面将详细说明)。

  1、_stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数。

  2、C调用约定(即用__cdecl关键字说明)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约定)。另外,在函数名修饰约定方面也有所不同。

  _cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数名前面加上下划线前缀。是MFC缺省调用约定。

  3、__fastcall调用约定是“人”如其名,它的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。

  _fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上"@"前缀,在函数名后加上"@"和参数的字节数。

  4、thiscall仅仅应用于“C++”成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。

  5、naked call采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。

  关键字 __stdcall、__cdecl和__fastcall可......

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

单向链表的实现(2008-07-07 19:02:00)

摘要:单向链表的实现
原 作 者:querw
原 出 处:VC在线

代码:http://www.vczx.com/article/file/20040822213844_TestQueue.rar


  独立于MFC的单项链表模板,多余的话我就不多说了.有附带功能演示用法.希望能给有同样需求的读者一点帮助.
  以下是源代码.(不用cpp文件,使用时只要把文件Queue.h包含到工程中即可)
// Queue.h: interface for the CQueue class.
//
/********************************************************************
created: 2004/08/09
created: 9:8:2004 23:33
file base: queue
file ext: h
author: 阙荣文(北方工业大学计算机2000级)

purpose: 构建一个通用的,独立于MFC的单向链表
我想c++的标准库模板应该也有类似功能的类,但是我还是决定自己实现
这样可以使用我自己喜欢的参数调用方式.
希望对用同样需求的编程爱好者有用
*********************************************************************/

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_QUEUE_H__57C46373_D485_43F2_998C_D3EA4984E59A__INCLUDED_)
#define AFX_QUEUE_H__57C46373_D485_43F2_998C_D3EA4984E59A__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
template <......

阅读全文(3041) | 评论:1

C++中三个修饰符的深层剖析Static Const Inline(2008-07-07 19:00:00)

摘要:C++中三个修饰符的深层剖析Static Const Inline



  static 是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因、作用谈起,全面分析static 修饰符的实质。

  static 的两大作用:

  一、控制存储方式:

  static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间。

  1、引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现?

  最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

  2、 解决方案:因此c++ 中引入了static,用它来修饰变量,它能够指示编译器将此变量在程序的静态存储区分配空间保存,这样即实现了目的,又使得此变量的存取范围不变。

  二、控制可见性与连接类型 :

  static还有一个作用,它会把变量的可见范围限制在编译单元中,使它成为一个内部连接,这时,它的反义词为”extern”.

  static作用分析总结:static总是使得变量或对象的存储形式变成静态存储,连接方式变成内部连接,对于局部变量(已经是内部连接了),它仅改变其存储方式;对于全局变量(已经是静态存储了),它仅改变其连接类型。

  类中的static成员:

  一、出现原因及作用:

  1、需要在一个类的各个对象间交互,即需要一个数据对象为整个类而非某个对象服务。

  2、同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

  类的static成员满足了上述的要求,因为它具有如下特征:有独立的存储区,属于整个类。

  二、注意:

  1、对于静态的数据成员,连接器会保证它拥有一个单一的外部定义。静态......

阅读全文(3378) | 评论:2

VC中利用CArchive类存取数据(2007-06-18 20:32:00)

摘要:VC中利用CArchive类存取数据

1、MSDN关于CArchive的翻译
The CArchive class allows you to save a complex network of objects in a permanent binary form (usually disk storage) that persists after those objects are deleted. Later you can load the objects from persistent storage, reconstituting them in memory. This process of making data persistent is called “serialization.”


CArchive 类允许在永久的二进制形式上(通常为磁盘存储器)保存复杂的对象网络,并在对象被删除后(对象的生命周期结束被销毁)保持持久性。之后,你可以从持久的存储器上加载这些对象并可在内存中重新构建他们。使数据持久性的过程叫“串行化”

You can think of an archive object as a kind of binary stream. Like an input/output stream, an archive is associated with a file and......

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

如何使用ActiveSync 连接 Pocket PC 2003 模拟器?(2007-06-18 00:53:00)

摘要:     在WinCE/PPC应用程序的开发过程中,经常使用模拟器来代替实机进行调试工作。
    PPC2000及以前版本的模拟器,都是使用开发机上的真实目录来虚拟模拟器上的目录,所以将文件复制到相应的开发机目录中,便能在模拟器上访问。而从PPC2003开始,则是使用了Virtual PC的技术来构建模拟器,模拟器所有的内容都在一个bin镜像文件中,所以只能用远程文件查看器“Remote File Viewer”来访问模拟器上的目录和传输文件。
    然而,如果您正在开发的程序与RAPI、Synchronization Providers相关的时候,那就不得不使用ActiveSync来连接模拟器了。
  Windows Mobile 5.0 的模拟器直接支持ActiveSync连接,PPC2003模拟器则不然,因此要稍费功夫进行一下设置。
  PPC2003模拟器连接ActiveSync的有两种方式,一种是串口方式,一种是虚拟网络方式,笔者将此两种方式的具体说明原文摘录如下:

  http://www.technetchina.com/html/developer/mobile/20070503/6558.html

说白了,就是要机了上有俩串口,用连接线连起来!然后看帮助,搞定......

阅读全文(4928) | 评论:2