博文

多线程程序的分析浅见(2008-11-05 17:41:00)

摘要:     多线程程序的分析浅见 注:这只是我个人在学习过程中的理解,如有不正确之外还望大家批评指正。 情况1: #include<windows.h> #include<iostream.h> DWORD WINAPI Fun1Proc(LPVOID lpParameter); DWORD WINAPI Fun2Proc(LPVOID lpParameter); int tickets=100; HANDLE hMutex; void main() {        HANDLE hThread1;        HANDLE hThread2;        hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);        hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);        CloseHandle(hThread1);        CloseHandle(hThread2);        hMutex=CreateMutex(NULL,FALSE,NULL);        Sleep(4000); } DWORD WINAPI Fun1Proc(LPVOID lpParameter) {        while(TRUE)        {         &nb......

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

在VC中使用Flash 美化你的程序(2008-05-05 21:26:00)

摘要:在VC中使用 Flash 美化你的程序   利用flash可以作出很漂亮的动画,想不想让自己的程序也有这样漂亮的界面呢? ^_^,其实,要做到这点也不难。在这里将介绍怎样把falsh制作的界面嵌入到自己的程序中,并让flash动画和自己的程序进行交互。     我们分为两步来走:   一、将flash动画嵌入自己的程序中,这一点比较简单,使用shockwave flash object控件就可以实现。这个控件在安装flash的时候就装到你的系统上了,flash5.0以下的文件名是swflash.ocx,5.0以上版本的名字是flash.ocx,在系统目录里面应该可以找得到;     二、在flash动画和自己的程序中传递消息进行交互。这一点也是要通过控件来实现,不过得在flash动画和自己的程序中做些处理。 下面我们来具体说明操作过程: 一、将flash动画嵌入自己的程序中。所有在windows平台上的支持ocx控件的软件开发工具都可以做到这一点。我使用的是vc++6.0,就以这个的做法来介绍。   1、检查你的系统上是否有shockwave flash object控件并已注册。如果你的系统上装有flash,则就有这个控件,否则的话,可以到网上下载一个过来安装。   2、新建一个MFC对话框应用程序,假设命名为PlayFlash。   3、添加shockwave flash object控件。建立对话框应用程序后,在主菜单里选择“工程->添加工程->components and controls”菜单选项,这时会弹出一个components and controls gallery文件选择对话框,里面有两个文件夹,一个是registered activex controls,一个是visual c++ components。选择第一文件夹后会出现一系列系统上已注册过的activex控件。在里面选择shockwave flash object(如果你系统上没这个控件,这里面就找不到了,可以去download个下来安装),点击insert将它插入工程。因为在vc中插入工程的控件要通过一个类来操作,所以这时vc会提示你为这个控件指定一个类名,可以使用默认的类名就行了。插入后vc会自动把这个类加入工程里面。   4......

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

在Visual C++中如何利用UDL文件来建立ADO连接(2008-05-05 20:18:00)

摘要:在Visual C++中如何利用UDL文件来建立ADO连接   使用通用数据连接文件(*.UDL,以下简称文件)来创建ADO连接,可以和ODBC一样可视化地定义要连接的数据源,从而实现数据访问的透明性。   1.使用UDL文件来创建ADO连接   创建ADO的连接,首先要设置ADO连接对象的ConnectionString属性,该属性提供所要连接的数据库类型、数据所处服务器、要访问的数据库和数据库访问的安全认证信息。比较专业的方法是在ConnectionString中直接提供以上信息,下面是访问不同类型数据源设置ConnectionString的标准: 访问ODBC数据 "Provider=MSDASQL;DSN=dsnName;UID=userName;PWD=userPassword;" 访问ORACLE数据库 "Provider=MSDAORA;Data Source=serverName;User ID=userName; Password=userPassword;" 访问MS SQL数据库 "Provider=SQLOLEDB;Data Source=serverName;Initial Catalog=databaseName; User ID=userName;Password=userPassword;" 访问ACCESS 数据库 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassword;"    上述的连接属性设置标准随着数据源的类型不同而变化,软件用户常常不习惯这种设置方式,都希望有可视化的数据源设置方法。为此Microsoft提供了通用数据连接文件(.UDL)来建立和测试ADO连接属性。ADO连接对象可以很方便地使用UDL文件来连接数据源,下面例子使用my_data1.udl来创建ADO连接。 _ConnectionPtr m_pDBConn; m_pDBConn.CreateInstance(__uuidof(Connection)); m_pDBConn->ConnectionString ="File Name=c:\mydir\......

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

C++的虚函数(2007-11-18 11:06:00)

摘要:C++的虚函数 一,让我们进入内存——I will come back(阿诺的口头禅)
首先,我觉得了解一个含有虚拟函数的类在内存中的结构是有必要的。
假设一个这样的类:
class CShape
{
       int b1;
public:
       void MyTest()
       {
              cout << "CShape::MyTest \n";
       }
};
在栈区,它仅仅只是占据了四个字节,用于存放成员数据——b1。
奇怪,那么它的成员函数在那里呢?对于普通的成员函数,编译器采取的是“名字粉碎法”,对于VC++6.0,它将CShape::MyTest()编修改为:“?MyTest@CTestA@@QAEXXZ”,真是个奇怪的名字,但是在这个名字中却保存了重要的信息,比如所属类,参数类型等,具体的大家可以查查相关资料,不好意思,我忘记了。
现在我们讨论虚拟函数, 假设另外的一个类:
class CShape_V {
       int b1;
public:
       virtual void play()
       {
             cout << "CShape::play \n";        }
&nbs......

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

C++五大内存分区(2007-11-18 10:50:00)

摘要:   C++五大内存分区     在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
    栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
    堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
    自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
    全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
    常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)
明确区分堆与栈
    在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。
    首先,我们举一个例子:
    void f() { int* p=new int[5]; }
    这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:
    00401028   push     &n......

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

progma 语法(2007-10-27 18:38:00)

摘要:progma 语法 progma 是一个C语言中的预处理指令,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
其格式一般为: #pragma Para
其中Para 为参数,下面来看一些常用的参数。
(1)message 参数。 Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗
口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:
#Pragma message(“消息文本”)
当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。
当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_
X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了
。 (2)另一个使用得比较多的pragma参数是code_seg。格式如:
#pragma code_seg( ["section-name"[,"section-class"] ] )
它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。 (3)#pragma once (比较常用)
只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。 (4)#pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级......

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

九九乘法表-1(2007-10-27 06:20:00)

摘要:......

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

MFC-dll与ADO结合注意点(2007-09-03 21:00:00)

摘要:......

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

函数传值与传地址的比较(2007-09-03 20:00:00)

摘要:......

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

指针函数与函数调用机制内存布局图(2007-09-03 19:53:00)

摘要:......

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