??xml version="1.0" encoding="utf-8" standalone="yes"?>精品久久久久久久久免费影院,久久精品成人国产午夜,婷婷国产天堂久久综合五月http://m.shnenglu.com/weiyan/archive/2006/07/06/9500.htmlwillwillThu, 06 Jul 2006 10:42:00 GMThttp://m.shnenglu.com/weiyan/archive/2006/07/06/9500.htmlhttp://m.shnenglu.com/weiyan/comments/9500.htmlhttp://m.shnenglu.com/weiyan/archive/2006/07/06/9500.html#Feedback0http://m.shnenglu.com/weiyan/comments/commentRss/9500.htmlhttp://m.shnenglu.com/weiyan/services/trackbacks/9500.html C/C+语言struct深层探烦

出处QPConline

1. struct的巨大作?br />  面对一个h的大型C/C++E序Ӟ只看其对struct的用情冉|们就可以对其~写者的~程l验q行评估。因Z个大型的C/C++E序Q势必要涉及一?甚至大量)q行数据l合的结构体Q这些结构体可以原本意义属于一个整体的数据l合在一赗从某种E度上来_会不会用structQ怎样用struct是区别一个开发h员是否具备丰富开发经历的标志?/font>

  在网l协议、通信控制、嵌入式pȝ的C/C++~程中,我们l常要传送的不是单的字节(char型数l)Q而是多种数据l合h的一个整体,其表现Ş式是一个结构体?/font>

  l验不的开发h员往往所有需要传送的内容依顺序保存在char型数l中Q通过指针偏移的方法传送网l报文等信息。这样做~程复杂Q易出错Q而且一旦控制方式及通信协议有所变化Q程序就要进行非常细致的修改?/font>

  一个有l验的开发者则灉|q用l构体,举一个例子,假设|络或控制协议中需要传送三U报文,其格式分别ؓpacketA、packetB、packetCQ?/font>

struct structA
{
int a;
char b;
};

struct structB
{
char a;
short b;
};

struct structC
{
int a;
char b;
float c;
}
  优秀的程序设计者这栯计传送的报文Q?/font>

struct CommuPacket
{
int iPacketType;  //报文cd标志
union      //每次传送的是三U报文中的一U,使用union
{
  struct structA packetA;
  struct structB packetB;
  struct structC packetC;
}
};
  在进行报文传送时Q直接传送struct CommuPacket一个整体?/font>

  假设发送函数的原Ş如下Q?/font>

// pSendDataQ发送字节流的首地址QiLenQ要发送的长度
Send(char * pSendData, unsigned int  iLen);
发送方可以直接q行如下调用发送struct CommuPacket的一个实例sendCommuPacketQ?br />Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
假设接收函数的原形如下:
// pRecvDataQ发送字节流的首地址QiLenQ要接收的长?br />//q回|实际接收到的字节?br />unsigned int Recv(char * pRecvData, unsigned int  iLen)Q?br />  接收方可以直接进行如下调用将接收到的数据保存在struct CommuPacket的一个实例recvCommuPacket中:

Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
  接着判断报文cdq行相应处理Q?/font>

switch(recvCommuPacket. iPacketType)
{
    case PACKET_A:
    …  ?//AcL文处?br />    break;
    case PACKET_B:
    …   //BcL文处?br />    break;
    case PACKET_C:
    … ?//CcL文处?br />    break;
}
  以上E序中最值得注意的是

Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
  中的强制cd转换Q?char *)&sendCommuPacket?char *)&recvCommuPacketQ先取地址Q再转化为char型指针,q样可以直接利用处理字节流的函数?/font>

  利用q种强制cd转化Q我们还可以方便E序的编写,例如要对sendCommuPacket所处内存初始化?Q可以这栯用标准库函数memset()Q?/font>

memset((char *)&sendCommuPacket,0, sizeof(CommuPacket));

2. struct的成员对?br />  Intel、微软等公司曄一道类似的面试题:
1. #include <iostream.h>
2. #pragma pack(8)
3. struct example1
4. {
5. short a;
6. long b;
7. };
8. struct example2
9. {
10. char c;
11. example1 struct1;
12. short e;   
13. };
14. #pragma pack()
15. int main(int argc, char* argv[])
16. {
17. example2 struct2;
18. cout << sizeof(example1) << endl;
19. cout << sizeof(example2) << endl;
20. cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl;
21. return 0;
22. }
  问程序的输入l果是什么?
  {案是:
8
16
4
  不明白?q是不明白?下面一一道来Q?br />2.1 自然对界
  struct是一U复合数据类型,其构成元素既可以是基本数据类型(如int、long、float{)的变量,也可以是一些复合数据类型(如array、struct、union{)的数据单元。对于结构体Q编译器会自动进行成员变量的寚wQ以提高q算效率。缺省情况下Q编译器为结构体的每个成员按其自然对界(natural alignmentQ条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,W一个成员的地址和整个结构的地址相同?br />  自然对界(natural alignment)即默认对齐方式,是指按结构体的成员中size最大的成员寚w?br />  例如Q?br />struct naturalalign
{
char a;
short b;
char c;
};
  在上q结构体中,size最大的是shortQ其长度?字节Q因而结构体中的char成员a、c都以2为单位对齐,sizeof(naturalalign)的结果等?Q?br />  如果改ؓQ?br />struct naturalalign
{
char a;
int b;
char c;
};
  其结果显然ؓ12?/font>

2.2指定对界
  一般地Q可以通过下面的方法来改变~省的对界条Ӟ
  · 使用伪指?pragma pack (n)Q编译器按照n个字节对齐;
  · 使用伪指?pragma pack ()Q取消自定义字节寚w方式?br />  注意Q如?pragma pack (n)中指定的n大于l构体中最大成员的sizeQ则其不起作用,l构体仍然按照size最大的成员q行对界?br />  例如Q?br />#pragma pack (n)
struct naturalalign
{
char a;
int b;
char c;
};
#pragma pack ()
  当n???6Ӟ其对齐方式均一Psizeof(naturalalign)的结果都{于12。而当n?Ӟ其发挥了作用Q得sizeof(naturalalign)的结果ؓ8?br />  在VC++ 6.0~译器中Q我们可以指定其对界方式Q其操作方式Zơ选择projetct > setting > C/C++菜单Q在struct member alignment中指定你要的对界方式?br />  另外Q通过__attribute((aligned (n)))也可以让所作用的结构体成员寚w在n字节边界上,但是它较被使用Q因而不作详l讲解?/font>

2.3 面试题的解答
  xQ我们可以对Intel、微软的面试题进行全面的解答?br />  E序中第2?pragma pack (8)虽然指定了对界ؓ8Q但是由于struct example1中的成员最大size?Qlong变量size?Q,故struct example1仍然?字节对界Qstruct example1的size?Q即W?8行的输出l果Q?br />  struct example2中包含了struct example1Q其本n包含的简单数据成员的最大size?Qshort变量eQ,但是因ؓ其包含了struct example1Q而struct example1中的最大成员size?Qstruct example2也应?对界Q?pragma pack (8)中指定的对界对struct example2也不起作用,?9行的输出l果?6Q?br />  ׃struct example2中的成员?为单位对界,故其char变量c后应补充3个空Q其后才是成员struct1的内存空_20行的输出l果??br />



will 2006-07-06 18:42 发表评论
]]>
数据库中存取BMP囑փhttp://m.shnenglu.com/weiyan/archive/2006/07/06/9482.htmlwillwillThu, 06 Jul 2006 03:56:00 GMThttp://m.shnenglu.com/weiyan/archive/2006/07/06/9482.htmlhttp://m.shnenglu.com/weiyan/comments/9482.htmlhttp://m.shnenglu.com/weiyan/archive/2006/07/06/9482.html#Feedback1http://m.shnenglu.com/weiyan/comments/commentRss/9482.htmlhttp://m.shnenglu.com/weiyan/services/trackbacks/9482.html二进制大对象BLOB(Binary Large Object)
其存取的方式与普通数据有所区别。本文将介绍利用ADO在数据库中存取BLOB数据的具体实现过E,q给出实现图像存取显C的完整CZ工程?

二、前期准?

首先我们建立一张名为userinfo的表Q包含三个字D?id,username,old,photo,其中photo是一个可以存储二q制数据的字Dc?

2.1 在SQL SERVER中我们可以在Query Analyzer中直接输入如下语句创建:

CREATE TABLE [dbo].[userphoto] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[username] [varchar] (50) NULL ,
[old] [int] NULL ,
[photo] [image] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
其中photo我们定义为imagecd的字Dc?

2.2 在ACCESS中创建的Ҏ如下Q?

建立一张新表包括id,username,old,photo四个字段Q然后打开表,选视图菜单中设计视图Q将id讄动编L递增长整型,username为文本,old为数字,photo为OLE对象?
在我们的CZ工程中已l包含了一个徏立好的ACCESS2000的库Q你可以直接拿来使用?

三、具体步?

3.1 BLOB数据的保?

BLOBcd的数据无法用普通的方式q行存储Q我们需要用AppendChunk函数QAppendChunk包含在Field对象中,原型如下Q?
HRESULT AppendChunk (const _variant_t & Data );
从函数原型中可以看到关键的问题是我们需把二q制数据赋值给VARIANTcd的变量,下面我们l出具体的代码ƈ作简单的分析:

///假设m_pBMPBuffer指针指向一块长度ؓm_nFileLen的二q制数据,q且已经成功打开了记录集对象m_pRecordset///

char *pBuf = m_pBMPBuffer ;
VARIANT varBLOB;
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];

m_pRecordset->AddNew(); ///d新记?
m_pRecordset->PutCollect("username",_variant_t("李")); ///为新记录填充username字段
m_pRecordset->PutCollect("old",_variant_t((long)28); ///填充old字段

if(pBuf){
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = m_nFileLen;
psa = SafeArrayCreate(VT_UI1, 1, rgsabound); ///创徏SAFEARRAY对象

for (long i = 0; i < (long)m_nFileLen; i++)
SafeArrayPutElement (psa, &i, pBuf++); ///pBuf指向的二q制数据保存到SAFEARRAY对象psa?

varBLOB.vt = VT_ARRAY | VT_UI1;///varBLOB的类型设|ؓBYTEcd的数l?

varBLOB.parray = psa; ///为varBLOB变量赋?

m_pRecordset->GetFields()->GetItem("photo")->AppendChunk(varBLOB); ///加入BLOBcd的数?
}

m_pRecordset->Update(); ///保存我们的数据到库中

x我们的数据已l成功地保存C数据库中,接下来我们所要做的工作便是将该数据提取出?让我们l吧!

3.2 BLOB数据的读?

对应于保存数据时我们所使用的AppendChunk函数Q读取数据应该用GetChunk函数,GetChunk的原型如?
_variant_t GetChunk (long Length );
l出数据的长度后GetChunk返回包含数据的VARIANTcd变量,然后我们可以利用SafeArrayAccessData函数得到VARIANT变量中指向数据的char *cd的指?以方便我们的处理Q具体代码如下:

long lDataSize = m_pRecordset->GetFields()->GetItem("photo")->ActualSize;
///得到数据的长?

if(lDataSize > 0)
{
_variant_t varBLOB;

varBLOB = m_pRecordset->GetFields()->GetItem("photo")->GetChunk(lDataSize);

if(varBLOB.vt == (VT_ARRAY | VT_UI1)) ///判断数据cd是否正确
{
   char *pBuf = NULL;
   SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
   ///得到指向数据的指?/*****在这里我们可以对pBuf中的数据q行处理*****/
   SafeArrayUnaccessData (varBLOB.parray);
   }

}

以上我们成功实现了BLOB数据在数据库中的存取Qؓ了让大家有现成的例子可以参考,本文提供了示例工E,在示例工E中我们在数据库中保存图像数据,q可以对q些囑փq行览、修改,该例子还涉及到如何用char *指向的BMP文g数据创徏BITMAP对象然后昄出来?br />



will 2006-07-06 11:56 发表评论
]]>
SAFEARRAY使用ҎCZhttp://m.shnenglu.com/weiyan/archive/2006/07/05/9452.htmlwillwillWed, 05 Jul 2006 12:09:00 GMThttp://m.shnenglu.com/weiyan/archive/2006/07/05/9452.htmlhttp://m.shnenglu.com/weiyan/comments/9452.htmlhttp://m.shnenglu.com/weiyan/archive/2006/07/05/9452.html#Feedback0http://m.shnenglu.com/weiyan/comments/commentRss/9452.htmlhttp://m.shnenglu.com/weiyan/services/trackbacks/9452.html l         创徏

                            long i = 0;

                            VARIANT va = {0};

                            va . vt = VT_BSTR ;

                           

                            SAFEARRAYBOUND bounds [1] = {0};

                            bounds [0]. cElements = 5;

                            SAFEARRAY * psa = SafeArrayCreate ( VT_VARIANT , 1, bounds );

 

l         存入元素

                            for ( i = 0; i < 5; i ++)

                            {

                                     va . bstrVal = SysAllocString (L "test" );

                                     SafeArrayPutElement ( psa , & i , & va );

                            }

 

l         获取元素

                            for ( i = 0; i < 5; i ++)

                            {

                                     va . bstrVal = SysAllocString (L "test" );

                                     SafeArrayGetElement ( psa , & i , & va );

                                     SysFreeString ( va . bstrVal );

                            }

 

l         销?/span>

                            SafeArrayDestroy ( psa );

 

l         生成 VARIANT 变量

                            VARIANT vsa = {0};

                            vsa . vt = VT_ARRAY | VT_BSTR ;

                            vsa . parray = psa ;



will 2006-07-05 20:09 发表评论
]]>
野指?/title><link>http://m.shnenglu.com/weiyan/archive/2006/07/05/9409.html</link><dc:creator>will</dc:creator><author>will</author><pubDate>Tue, 04 Jul 2006 16:32:00 GMT</pubDate><guid>http://m.shnenglu.com/weiyan/archive/2006/07/05/9409.html</guid><wfw:comment>http://m.shnenglu.com/weiyan/comments/9409.html</wfw:comment><comments>http://m.shnenglu.com/weiyan/archive/2006/07/05/9409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/weiyan/comments/commentRss/9409.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/weiyan/services/trackbacks/9409.html</trackback:ping><description><![CDATA[         野指针,也就是指向不可用内存区域的指针。通常对这U指针进行操作的话,会使程序发生不可预知的错误。但是,我在文中要说的,是野指针的“安全”用方法以及其内部的原?<br /><br /><p>首先误位看以下一D“危险”的C++代码Q?/p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code><font color="blue">void</font> function( <font color="blue">void</font> )<br />{<br />    <font color="blue">char</font>* str = <font color="blue">new</font> <font color="blue">char</font>[100];<br />    <font color="blue">delete</font>[] str;<br />    <font color="green">// Do something</font><br />    strcpy( str, "Dangerous!!" );<br />}</code></td></tr></tbody></table><p>之所以说其危险,是因是一D完全合乎语法的代码Q编译的时候完得一炚w误也不会有,然而当q行到strcpy一句的时候,问题׃出现Q因为在q之前,str的空间已l被delete掉了Q所以strcpy当然不会成功。对于这U类似的情况Q在林锐博士的书中有q介l,U其为“野指针”?/p><p>那么Q诸位有没有见过安全的“野指针”呢Q下面请看我的一DC++E序Q灵感来自CSDN上的一ơ讨论。在此,我只需要C++的“类”,C++的其余一概不需要,因此我没有用Q何的C++标准库,q输出都是用printf完成的?/p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code><font color="blue">#include</font> <stdio.h><br /><br /><font color="blue">class</font> CTestClass<br />{<br /><font color="blue">public</font>:<br />    CTestClass( <font color="blue">void</font> );<br />    <font color="blue">int</font> m_nInteger;<br />    <font color="blue">void</font> Function( <font color="blue">void</font> );<br />};<br /><br />CTestClass::CTestClass( <font color="blue">void</font> )<br />{<br />    m_nInteger = 0;<br />}<br /><br /><font color="blue">void</font> CTestClass::Function( <font color="blue">void</font> )<br />{<br />    printf( "This is a test function.\n" );<br />}<br /><br /><font color="blue">void</font> main( <font color="blue">void</font> )<br />{<br />    CTestClass* p = <font color="blue">new</font> CTestClass;<br />    <font color="blue">delete</font> p;<br />    p->Function();<br />}</code></td></tr></tbody></table><p>OKQ程序到此ؓ止,怽可以~译q行一下看看结果如何。你也许会惊异地发现Q没有Q何的出错信息Q屏q上竟然乖乖地出Cq么一行字W串Q?/p><p>This is a test function.</p><p>奇怪吗Q不要急,q有更奇怪的呢,你可以把dC加上一句更不可理喻的:</p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code>((CTestClass*)NULL)->Function();</code></td></tr></tbody></table><p>q仍然没有问题!Q?/p><p>我这q有呢,哈哈。现在你在主函数中这么写Q倘说上一句不可理喻,那么以下可以叫做无法无天了:</p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code><font color="blue">int</font> i = 888;<br />CTestClass* p2 = (CTestClass*)&i;<br />p2->Function();</code></td></tr></tbody></table><p>你看C什么?是的Q“This is a test function.”如U而至Q没有Q何的错误?/p><p>你也许要问ؓ什么,但是在我解答你之前,请你在主函数中加入如下代码:</p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code>printf( "%d, %d", <font color="blue">sizeof</font>( CTestClass ), <font color="blue">sizeof</font>( <font color="blue">int</font> ) );</code></td></tr></tbody></table><p>q时你就会看到真怺Q输出结果是——得到的两个十进制数相等。对Q由sizeof得到的CTestClass的大其实就是它的成员m_nInteger的大。亦x_对于CTestClass的一个实例化的对象(设ؓaQ而言Q只有a.m_nInteger是属于aq个对象的,而a.Function()却是属于CTestClassq个cȝ。所以以上看似危险的操作其实都是可行且无误的?/p><p>现在你明白ؓ什么我的“野指针”是安全的了Q那么以下我所列出的,是在什么情况下Q我的“野指针”不安全Q?/p><ol><li>在成员函数Function中对成员变量m_nIntegerq行操作Q? </li><li>成员函数Function声明函数QvirtualQ?</li></ol><p>以上的两U情况,目的是野指针用属于自q东西D不安全,比如W一U情况中操作本n的m_nIntegerQ第二种情况中变函数的Function成ؓ了属于对象的函数Q这一点可以从sizeof看出来)?/p><p>其实Q安全的野指针在实际的程序设计中是几乎毫无用处的。我写这一文章,意图q不是像孔乙׃样去琢磨回字有几U写法,而是想通过q个例子向怽写明白C++的对象实例化本质Q希望大家不但要明白what和howQ更要明白why。李马二雉三年二月二十日作于自宅?/p><p><br /><b>关于成员函数CTestClass::Function的补充说?/b><br /><br /></p><p>q个函数是一个普通的成员函数Q它在编译器的处理下Q会成ؓcM如下的代码:</p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code><font color="blue">void</font> Function( <font color="blue">const</font> CTestClass * <font color="blue">this</font> ) <font color="green">// ?/font><br />{<br />    printf("This is a test function.\n");<br />}</code></td></tr></tbody></table><p>那么p->Function();一句将被编译器解释为:</p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code>Function( p ); </code></td></tr></tbody></table><p>q就是说Q普通的成员函数必须l由一个对象来调用Q经由this指针ȀzZQ。那么由上例的delete之后Qp指针会指向一个无效的地址Q然而p本n是一个有效的变量Q因此编译能够通过。ƈ且在~译通过之后Q由于CTestClass::Function的函C内ƈ未对q个传入的this指针q行M的操作,所以在q里Q“野指针”便成了一个看似安全的东西?/p><p>然而若q样改写CTestClass::FunctionQ?/p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code><font color="blue">void</font> CTestClass::Function( <font color="blue">void</font> )<br />{<br />    m_nInteger = 0;<br />}</code></td></tr></tbody></table><p>那么它将会被~译器解释ؓQ?/p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code><font color="blue">void</font> Function( <font color="blue">const</font> CTestClass * <font color="blue">this</font> )<br />{<br />    <font color="blue">this</font>->m_nInteger = 0;<br />}</code></td></tr></tbody></table><p>你看CQ在p->Function();的时候,pȝ会试在传入的q个无效地址中寻找m_nInteger成员q将其赋gؓ0Q剩下的我不用说了——非法操作出C?/p><p>至于virtual虚函敎ͼ如果在类定义之中CTestClass声明函数Q?/p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code><font color="blue">class</font> CTestClass<br />{<br /><font color="blue">public</font>:<br />    <font color="green">// ...</font><br />    <font color="blue">virtual</font> <font color="blue">void</font> Function( <font color="blue">void</font> );<br />};</code></td></tr></tbody></table><p>那么C++在构建CTestClasscȝ对象模型Ӟ会Z分配一个虚函数表vptrQ可以从sizeof看出来)。vptr是一个指针,它指向一个函数指针的数组Q数l中的成员即是在CTestClass中声明的所有虚函数。在调用虚函数的时候,必须l由q个vptrQ这也就是ؓ什么虚函数较之普通成员函数要消耗一些成本的~故。以本例而言Qp->Function();一句将被编译器解释为:</p><p></p><table class="codetable" cellspacing="1" border="0"><tbody><tr><td><code>(*p->vptr[1])( p ); <font color="green">// 调用vptr表中索引号ؓ1的函敎ͼ即FunctionQ③</font></code></td></tr></tbody></table><p>上面的代码已l说明了Q如果p指向一个无效的地址Q那么必然会有非法操作?/p><p>备注Q?/p><p>①关于函数的命名Q我采用了原名而没有变化。事实上~译器ؓ了避免函数重载造成的重名情况,会对函数的名字进行处理,使之成ؓ独一无二的名U?br />②将成员函数声明为staticQ可以成员函数不经由this指针便可调用?br />③vptr表中Q烦引号0为类的type_info?/p><br /><br /><img src ="http://m.shnenglu.com/weiyan/aggbug/9409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/weiyan/" target="_blank">will</a> 2006-07-05 00:32 <a href="http://m.shnenglu.com/weiyan/archive/2006/07/05/9409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VISUAL C++软g开发中几个常用功能http://m.shnenglu.com/weiyan/archive/2006/07/05/9408.htmlwillwillTue, 04 Jul 2006 16:26:00 GMThttp://m.shnenglu.com/weiyan/archive/2006/07/05/9408.htmlhttp://m.shnenglu.com/weiyan/comments/9408.htmlhttp://m.shnenglu.com/weiyan/archive/2006/07/05/9408.html#Feedback0http://m.shnenglu.com/weiyan/comments/commentRss/9408.htmlhttp://m.shnenglu.com/weiyan/services/trackbacks/9408.html一、设|程序自动运行。 ?br />       很多监控软g要求软g能够在系l重新启动后不用用户ȝd标启动项目,而是直接能够启动q行Q方法是写注册表Software\\Microsoft\\Windows\\CurrentVersion\\Run。参考程序可以见下:(查找E序目录的执行文Ӟ存在则进行添加注册表操作) 
         HKEY RegKey; 
         CString sPath; 
         GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH); 
         sPath.ReleaseBuffer(); 
         int nPos; 
    nPos=sPath.ReverseFind(’\\?; 
    sPath=sPath.Left(nPos); 
    CString lpszFile=sPath+"\\****.exe";//q里加上你要查找的执行文件名UW?
    CFileFind fFind; 
    BOOL bSuccess; 
    bSuccess=fFind.FindFile(lpszFile); 
    fFind.Close(); 
    if(bSuccess) 
    { 
        CString fullName; 
        fullName=lpszFile; 
        RegKey=NULL; 
        RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&RegKey); 
        RegSetValueEx(RegKey,"*****",0,REG_SZ,(const unsigned char*)(LPCTSTR)fullName,fullName.GetLength());//q里加上你需要在注册表中注册的内容?
        this->UpdateData(FALSE); 
    } 
    else 
    { 
        theApp.SetMainSkin(); 
        ::AfxMessageBox("没找到执行程序,自动q行p|"); 
        exit(0); 
    } 

二、自动配|数据源 
    很多的程序都要用到数据库l合的操作,q里举例ACCESSQ因为ACCESS在中型VCpȝ开发中是最常用到的Q如果程序的ULQ如果对于很初的用h_你还需要他到配|面板中q行数据源配|的话,那就有点说不q去了。?
         #include <odbcinst.h> 
         //配置数据源,数据库在应用E序目录?q里比如数据库文件名?**.mdbQ程序运行时候可以将数据库文件拷贝到E序目录下面。?
    CString sPath; 
    GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH); 
    sPath.ReleaseBuffer(); 
    int nPos; 
    nPos=sPath.ReverseFind(’\\?; 
    sPath=sPath.Left(nPos); 
    CString lpszFileName = sPath + "\\***.mdb";//q里修改成你的数据库文g名称 
    CFileFind  fFind; 
    if(!fFind.FindFile(lpszFileName)) 
    { 
        ::AfxMessageBox("没有扑ֈ数据?); 
        exit(0); 
    }  
    CString szDesc; 
    szDesc.Format( "DSN=****;Description=****;DESCRIPTION=The DataBase For ***;FIL=MicrosoftAccess;DEFAULTDIR=%s;DBQ=%s;" ,sPath,lpszFileName);//q里***号可以添加成你的描述 

    //d数据源?
    if(!::SQLConfigDataSource(NULL,ODBC_ADD_DSN, "Microsoft Access Driver (*.mdb)",(LPCSTR)szDesc)) 
    { 
        ::AfxMessageBox("32位ODBC数据源配|错?"); 
        exit(0); 
    } 

三、设|显C模式: 
    很多的程序的UL的运行环境是改变的。有可能你的原来开发环境是1024X768Q但是到了那些显C器大于17的时候(分L率超q你的开发时的分辨率ӞQ程序的昄可能׃好看了。?
         DEVMODE lpDevMode; 
    lpDevMode.dmPelsHeight=768;//Y方向象素点?
    lpDevMode.dmPelsWidth=1024;//X方向象素点?
    lpDevMode.dmDisplayFrequency=85;//屏幕h率?
    lpDevMode.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY; 
    ChangeDisplaySettings(&lpDevMode,0); 

四、在你的E序中间加蝲其他应用E序Q?
    你的E序除了调用到各个模块进行协同工作外QDLLQ,q有可能调用不是同一个开发环境下的应用程序,比如VC环境下调用DELPHIQVB开发的执行E序Q你可以用C面的ҎQ将调用的应用程序拷贝程序目录中Q: 
         CString sPath; 
    GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH); 
    sPath.ReleaseBuffer(); 
    int nPos; 
    nPos=sPath.ReverseFind(’\\?; 
    sPath=sPath.Left(nPos); 
    CString lpszFileName = sPath + "\\***.exe";//q里修改成你的调用应用程序的文g名称 
    CFileFind  fFind; 
    if(!fFind.FindFile(lpszFileName)) 
    { 
        ::AfxMessageBox("没有扑ֈ调用的应用程序!");  
        return FALSE; 
    } 
    else 
        ShellExecute(NULL,NULL,_T("***.exe"),NULL,sPath,NULL);  

五、结束进E: 
    在你的程序中l束别的E序q程Q采用的Ҏ是进行进E列举,然后采用查找的方法进行: 
         #include "TLHELP32.H" 
         DWORD ProcessID[50]; 
    CString kkk[50]; 
    HANDLE SnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);  
    PROCESSENTRY32* info=new PROCESSENTRY32; 
    PROCESSENTRY32 ProcessInfo;//声明q程信息变量 
    ProcessInfo.dwSize=sizeof(ProcessInfo);//讄ProcessInfo的大?
    //q回pȝ中第一个进E的信息 
    BOOL Status=Process32First(SnapShot,&ProcessInfo); 
    int m_nProcess=0;  
    while(Status) 
    { 
        CString s,str1,str2; 
        s.Format("%d",ProcessInfo.cntThreads); 
        str1.Format("%s",ProcessInfo.szExeFile); 
        str1=ProcessInfo.szExeFile; 
        kkk[m_nProcess]=ProcessInfo.szExeFile;  
        ProcessID[m_nProcess]=ProcessInfo.th32ProcessID;  
        if(str1=="***.exe")//***.exe是你要l束的进E的名称 
        { 
            HANDLE ProcessHandle; 
            ProcessHandle=OpenProcess (PROCESS_ALL_ACCESS,FALSE,ProcessID[m_nProcess]); 
            TerminateProcess(ProcessHandle,0);     
        } 
        Status=Process32Next(SnapShot,&ProcessInfo); 
        m_nProcess++; 
    } 



will 2006-07-05 00:26 发表评论
]]>
在VC中添加响应自定义的消息的代码步骤http://m.shnenglu.com/weiyan/archive/2006/07/02/9288.htmlwillwillSun, 02 Jul 2006 10:00:00 GMThttp://m.shnenglu.com/weiyan/archive/2006/07/02/9288.htmlhttp://m.shnenglu.com/weiyan/comments/9288.htmlhttp://m.shnenglu.com/weiyan/archive/2006/07/02/9288.html#Feedback0http://m.shnenglu.com/weiyan/comments/commentRss/9288.htmlhttp://m.shnenglu.com/weiyan/services/trackbacks/9288.html1. 首先定义一个消息代?/p>

#define WM_DEBUG     WM_USER + 1999

2. 在窗口头文g中添?/p>

class CStreamServerDlg : public CDialog
{
 // Generated message map functions
 //{{AFX_MSG(CStreamServerDlg)
...
 //}}AFX_MSG
 afx_msg void OnDebug(WPARAM wParam, LPARAM lParam); 
...
}

3. 在窗口的cpp文g中添?/p>


BEGIN_MESSAGE_MAP(CStreamServerDlg, CDialog)
...
 ON_MESSAGE(WM_DEBUG, OnDebug)
END_MESSAGE_MAP()

LRESULT  CStreamServerDlg::OnDebug(WPARAM wParam, LPARAM lParam)
{
}

4. 其他地方可以发送消?/p>

pWnd->PostMessage(WM_DEBUG,  (WPARAM)p, 0) )


说明Q?br />
#define ON_MESSAGE(message, memberFxn)
{ message, 0, 0, 0, AfxSig_lwl,
(AFX_PMSG)(AFX_PMSGW)(LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))&memberFxn },




will 2006-07-02 18:00 发表评论
]]>
ŷþһ| þó18վ| ŷ޾þþþƷ| þŮcc98cm| ˾þþƷӰԺ| aëƬþѲ| ޹Ʒ˾þ| þþùһ| ޾Ʒþþþþ | 9191ƷѾþ| Ʒ˾þ˵Ӱ| þۺϸۺϾþ| þþƷAVһ| þúݺɫݺɫۺ| ޹þþþþþ| Avþ| ŷ龫Ʒþþþþ| ھƷþþþþþ97ţţ| þþ뾫Ʒպ| Vþþ| þô̫㽶av| Ʒþþþþþþþ| 66þôýվȸ| ƷþþĻ| ƷŮþþþ| þֻоƷ4| Ʒþþþþ| ƷһþþƷ| ޾Ʒþþþþþþþþþ | þ99ڹ| 97þþþ| þeֻйľƷ99| þþƷר | þþþһ| þþƷŮAV| Ʒŷ޺ձþ| ھƷþþþӰԺ| þһҹ| þþþþþòҰ¸߳| þݺҹҹ| þþƷƷëƬ|