??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
2
3 if (condition1) break;
4
5 if (condition2) break;
6
7 } while (0);
]]>
1.引言
C++语言的创建初h“a better C”Q但是这q不意味着C++中类似C语言的全局变量和函数所采用的编译和q接方式与C语言完全相同。作ZU欲与C兼容的语aQC++保留了一部分q程 式语a的特点(被世人称?#8220;不彻底地面向对象”Q,因而它可以定义不属于Q何类的全局变量和函数。但是,C++毕竟是一U面向对象的E序设计语言Qؓ(f)了支 持函数的重蝲QC++对全局函数的处理方式与C有明昄不同?br> 2.从标准头文g说v
某企业曾l给出如下的一道面试题Q?/p>
面试?br> Z么标准头文g都有cM以下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
#endif /* __INCvxWorksh */
分析
昄Q头文g中的~译?#8220;#ifndef __INCvxWorksh?define __INCvxWorksh?endif” 的作用是防止该头文g被重复引用?/p>
那么
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
的作用又是什么呢Q我们将在下文一一道来?br>
3.深层揭密extern "C"
extern "C" 包含双重含义Q从字面上即可得刎ͼ(x)首先Q被它修饰的目标?#8220;extern”的;其次Q被它修饰的目标?#8220;C”的。让我们来详l解读这两重含义?/p>
被extern "C"限定的函数或变量是externcd的;
extern是C/C++语言中表明函数和全局变量作用范围Q可见性)的关键字Q该关键字告诉编译器Q其声明的函数和变量可以在本模块或其它模块中使用。记住,下列语句Q?/p>
extern int a;
仅仅是一个变量的声明Q其q不是在定义变量aQƈ未ؓ(f)a分配内存I间。变量a在所有模块中作ؓ(f)一U全局变量只能被定义一ơ,否则?x)出现连接错误?/p>
通常Q在模块的头文g中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块BƲ引用该模块A中定义的全局? 量和函数时只需包含模块A的头文g卛_。这P模块B中调用模块A中的函数Ӟ在编译阶D,模块B虽然找不到该函数Q但是ƈ不会(x)报错Q它?x)在q接阶段中从 模块A~译生成的目标代码中扑ֈ此函数?/p>
与extern对应的关键字是staticQ被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块用时Q其不可能被extern “C”修饰?/p>
被extern "C"修饰的变量和函数是按照C语言方式~译和连接的Q?/p>
未加extern “C”声明时的~译方式
首先看看C++中对cMC的函数是怎样~译的?/p>
作ؓ(f)一U面向对象的语言QC++支持函数重蝲Q而过E式语言C则不支持。函数被C++~译后在W号库中的名字与C语言的不同。例如,假设某个函数的原型ؓ(f)Q?
void foo( int x, int y );
该函数被C~译器编译后在符号库中的名字为_fooQ而C++~译器则?x)生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机Ӟ生成的新名字UCؓ(f)“mangled name”Q?/p>
_foo_int_intq样的名字包含了函数名、函数参数数量及(qing)cd信息QC++是靠这U机制来实现函数重蝲的。例如,在C++中,函数 void foo( int x, int y )与void foo( int x, float y )~译生成的符h不相同的Q后者ؓ(f)_foo_int_float?br> 同样圎ͼC++中的变量除支持局部变量外Q还支持cL员变量和全局变量? 用户所~写E序的类成员变量可能与全局变量同名Q我们以"."来区分。而本质上Q编译器在进行编译时Q与函数的处理相|也ؓ(f)cM的变量取了一个独一无二 的名字,q个名字与用L(fng)序中同名的全局变量名字不同?/p>
未加extern "C"声明时的q接方式
假设在C++中,模块A的头文g如下Q?/p>
// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
int foo( int x, int y );
#endif
在模块B中引用该函数Q?/p>
// 模块B实现文g moduleB.cpp
#include "moduleA.h"
foo(2,3);
实际上,在连接阶D,q接器会(x)从模块A生成的目标文件moduleA.obj中寻找_foo_int_intq样的符P
加extern "C"声明后的~译和连接方?/p>
加extern "C"声明后,模块A的头文g变ؓ(f)Q?/p>
// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
extern "C" int foo( int x, int y );
#endif
在模块B的实现文件中仍然调用foo( 2,3 )Q其l果是:(x)
Q?Q模块A~译生成foo的目标代码时Q没有对其名字进行特D处理,采用了C语言的方式;
Q?Q连接器在ؓ(f)模块B的目标代码寻找foo(2,3)调用ӞL的是未经修改的符号名_foo?/p>
如果在模块A中函数声明了foo为extern "C"cdQ而模块B中包含的是extern int foo( int x, int y ) Q则模块B找不到模块A中的函数Q反之亦然?/p>
所以,可以用一句话概括extern
“C”q个声明的真实目的(M语言中的M语法Ҏ(gu)的诞生都不是随意而ؓ(f)的,来源于真实世界的需求驱动。我们在思考问题时Q不能只停留在这个语a是怎么
做的Q还要问一问它Z么要q么做,动机是什么,q样我们可以更深入地理解许多问题Q:(x)
实现C++与C?qing)其它语a的合编E?br> 明白了C++中extern "C"的设立动机,我们下面来具体分析extern "C"通常的用技巧?br> 4.extern "C"的惯用法
Q?Q在C++中引用C语言中的函数和变量,在包含C语言头文Ӟ假设为cExample.hQ时Q需q行下列处理Q?/p>
extern "C"
{
#include "cExample.h"
}
而在C语言的头文g中,对其外部函数只能指定为externcdQC语言中不支持extern "C"声明Q在.c文g中包含了extern "C"时会(x)出现~译语法错误?/p>
W者编写的C++引用C函数例子工程中包含的三个文g的源代码如下Q?/p>
/* c语言头文Ӟ(x)cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y); // "extern" is optional [Zero]
#endif
/* c语言实现文gQcExample.c */
#include "cExample.h"
int add( int x, int y )
{
return x + y;
}
// c++实现文gQ调用addQcppFile.cpp
/*
[Zero] below, can be written as
extern "C" int add(int,int);
#include "cExample.h"
*/
extern "C"
{
#include "cExample.h"
}
int main(int argc, char* argv[])
{
add(2,3);
return 0;
}
如果C++调用一个C语言~写?DLLӞ当包?DLL的头文g或声明接口函数时Q应加extern "C" { }?/p>
Q?Q在C中引用C++语言中的函数和变量时QC++的头文g需dextern "C"Q但是在C语言中不能直接引用声明了extern "C"的该头文Ӟ应该仅将C文g中将C++中定义的extern "C"函数声明为externcd?br> W者编写的C引用C++函数例子工程中包含的三个文g的源代码如下Q?/p>
//C++头文?cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern "C" int add( int x, int y );
#endif
//C++实现文g cppExample.cpp
#include "cppExample.h"
int add( int x, int y )
{
return x + y;
}
/* C实现文g cFile.c
/* q样?x)编译出错?x)#include "cExample.h" */
extern int add( int x, int y );
int main( int argc, char* argv[] )
{
add( 2, 3 );
return 0;
}
先看下面的测试代?1)?2)Q?br> =====================================================================
试代码(1) :
const char* a[] = { "a", "bcedf" };
// 试下面?/span>sizeof(a)Q它的结果是’8’, 原因在于a是指针数l,里面存储的是指针元素?/span>
// 在这里是两个指针元素的数l。故?/span>4*2=8.
cout << sizeof(a) << endl; // print '8'
// test sizeof(*a), sizeof(a[0]), sizeof(a[0][0])
cout << sizeof(*a) << endl; // print '4' q里*a是求出第一个字W串的地址,注意a是指针的指针?/span>
cout << sizeof(a[0]) << endl;// print '4' q里?/span>a[0] = *a,跟上面的一栗?/span>
cout << sizeof(a[0][0]) << endl; // print '1' q里是第一个字W串的第一个字WaQ一个字节?br>
试代码(2) :
struct TestStruct {
char c_elem; // 1 bytes
int int_elem; // 4 bytes
};
cout << sizeof(TestStruct) << endl; // it prints '8' .
struct TestStruct1 {
char c_elem1;
char c_elem2:
char c_elem3;
... // num 个charcd数据成员
};
cout << sizeof(TestStruct1) <<endl; // it prints num.
// 输出的结果与具体的系l结构有养I此处?2位机Q故Zd的快捷和方便Q系l会(x)自动的填?padding).
// intcd?个字节,charcd?个字节,但是此处?x)自动填?个字节到structl构中其成?个字节?br> // 但是如果struct中只有一U类型,譬如char或intcdӞ不会(x)产生此种填补的情c但是如果不是,它会(x)输出
// 4的倍数个字节?br>======================================================================
*
比较宽的知识面,q且能够时时补充自己的知识和完善自己的知识结?/span>
*
耐心好,特别是在调试和学?fn)阶D,世界上没有聪明的人只有刻苦的人。做开发其实就两g事情学习(fn)和改错,在这两g事情中间的开发过E其实是比较单的
*
永远CQ代码是lh看的而不是给机器q行的,计算机在执行E序时是不怕篏的,而h在看代码时是非常累的
*
良好的编码习(fn)惯,臛_保证自己能够随时看懂几个月前自己所写的代码
*
量让你的代码能够很Ҏ(gu)的被别h理解Q写代码时想想你?x)不会(x)在两个月后被别人?/span>
*
不要容忍自己犯重复的错误和写重复的代?/span>
*
知道如何做比得到代码更重?/span>
*
量不要做已l有很多人已l做q的事情
*
学会(x)重别h的开发成果,除非不得已不要下军_全面替换以前的系l?/span>
*
珍惜自己的时间与工作成果Q尽量让别h分n自己的开发成?/span>
*
避免假设Q多思考极端情况与引v错误的可能性,努力减少低错误
*
不要怿臛_是不要轻信自׃ؓ(f)自己所做的试l果
*
懂得坚持自己的开发思\Qƈ懂得理解与吸收别人的思想
*
学会(x)与其他h保持一_(d)但不能放弃自q开发特?/span>
*
懂得向你周围的h学习(fn)Q不论是开发能力上的还是开发经验上?/span>
*
懂得软gl构的的重要性,分析代码前先分析代码的结?/span>
*
学会(x)ȝQ定期ȝ自己所学会(x)的知识,看看自己前段旉因ؓ(f)各种原因所费的时?/span>
*
学会(x)计划Q尽量不要认为通过廉自己的工作时间来完成d
*
学会(x)正确估计自己的能力和工作旉
下面q些是我认ؓ(f)一些比较适合我自q斚wQ不一定对每个人都合适:(x)
*
多看些杂志,没事情的时候可以看看以前看q的参考书Q书中很可能有你以前没有注意到的一些细?/span>
*
不要太早d一些与开发无关的事情Q因为学?fn)的黄金时期是很短暂?/span>
*
学会(x)分析别h的系l,多看看别人所开发的pȝ的先q的一面。这里包括别人的开发思\Q实现时所采用的结?/span>
*
时常感到自己被淘汰Q经常埋怨自q不努?/span>
*
知道自己~少什?/span>
*
自己做一些自׃喜欢做的事情Q比如说写文?/span>
*
能够有勇气重写自己所开发的pȝQ但当你重做时你应该采取和前一ơ不同的工作方式和方法,否则重做没有必?/span>
*
问题简单化而不是复杂化
*
维护时?x)生的一部分问题转移到开发时或是设计时来解决
*
有时候也不妨问问自己Q我不做开发时d什?/span>
*
坚持己做每周的开发计划,在事情没有做完以前不要轻易{U自q注意?/span>
*
可能多的将你所做的教给别hQ因Z有一天可能不再负责这个系l?/span>
*
做事一定要有始有终Q除非是有不得已的理由否则不要在工作完成前提前离开
*
不要你为公司做的东西带赎ͼ你因该带走的是开发经验和对开发的认识而不是代码和产品
* 感到累时׃息一下,l自己放个假也无妨,毕竟Z是机?/span>
认真考虑一下,得到最有天赋的目开发h员的最x法是培养Q而非购买?br />
在阅Lx捷开发的材料Ӟ我发玎ͼ无论是传l的软g开发技术,q是敏捷Ҏ(gu)Q都要高度依赖熟l的开发h员才能确保成功。这一事实让我触动。由于许多因素的影响Q具有相似经历的开发h员的表现水^却相差很大,q点已ؓ(f)Z所接受Q所以h们对优秀的开发h员比较关注也׃ؓ(f)奇了。尽如此,一个或一群开发h员,利用“英雄模式”开发,通过他们的奉献精与坚韧毅力Q还是完成了许多开发工作?br />
很明显,我们需要优U的开发h员。但问题是,到哪L优秀的开发h员呢Q?br />
十几q来我一直参与招聘工作,我可以毫不迟疑地告诉你:(x)有可能找到最优秀的开发h员,但是可能性不大。这不是一件容易的事,即d一千䆾历,可能也只能找C两个真正优秀的开发h员?br />
认真考虑一下,你会(x)发现Q只有通过培养Q而不是购乎ͼ才能得到最优秀的开发h员?br />
什么造就最优秀的开发h员?
关于是什么造就最优秀的开发h员,大家持不同的看法。不是敏捷q是传统的开发技巧都需要开发h员拥有稍异于人的东西。但是,无论开发h员应用哪U技巧,q都归结Z个词Q思考?br />
位于Bloom认知技能教育目标分cL底层的是知识。即回想Q或识别Q数据与信息。应用在开发方面,q就意味着识别C#语法或回惛_执行循环的正语法?br />
位于认知分类最层的是l合与评估。综合指能够合成不同的因素以形成全新的解x案。而评估是指对观念、方法或材料做出判断的能力。在工作q程中,开发h员需要不断地应用q些高层ơ的认知能力?br />
许多为,与描q认知过E的差异相比Q将q一观念表达为思考更然。通常Q对高层ơ的观念Q例如如何综合片D|形成解决Ҏ(gu)Q所做的思考越多,开发h员就更优U?br />
底捞针
在完全放弃招聘(购买Q最优秀的开发h员之前,我们先通过验专业技能来了解一下招聘过E。我例行公事地对应聘开发职位的候选hq行了一ơ口头测试。由于我面试的大多数开发h员需要能够熟l地操作数据库,我问他们一个简单的问题Q?br />
l你一个带客户id域与名称的客戯Q以?qing)一个带序号idQ客户id与其它细节的序号索引表,用什么查询可q回不带序号的客戯Q?br />
此问题的{案需要应用外部连接(outer joinQ知识。(在SQL-87语法中,你可以应?=Q但q一{案正日益少见。)我的非正式统计表明,{对此问题的人数?0%以下。^均来_(d)我面试的开发h员拥有大专学历,??q的工作l验。但是,据我的观察,多年的工作经验与他们是否{对此问题关pM大?br />
Ҏ(gu)而言Q无力回{此问题表明开发h员ƈ不完全了解SQL所要求的以集合为基的逻辑方式。我认ؓ(f)q是一个优U开发h员的基本技能?br />
另一个问题更有趣Q因为它没有正确{案Q?/strong>
你最喜欢微Y.NET中的哪项功能Q?br />
明显圎ͼ你可以在q个问题中插入Q何技术。问题的{案可以清楚地告诉你开发h员的思考方向。如果它告诉我是IntelliSenseQ帮助你记忆对象与方法界面的Visual Studio功能Q,我就知道他们主要兛_如何代码加入编辑器Q这q不是优U开发h员的思考方式。顺便说一下,如果他们l出那个{案Q他们可获得“加几Z。(另一击?即“你q喜Ƣ哪功能?”)
我在L一c表明他们正在思考文本编辑框以外的事情的{案。我在寻找这L(fng){案Q“因行时间类型的信息Q可~写灉|代码的能力。”这L(fng){案表明他们对工作进行了深入思考,q是成ؓ(f)最优秀的开发h员的基本条g?br />
“你最不喜Ƣ什么?”这个问题同样富于启C。“忘记C#中的分号”这L(fng){案让我怀疑候选开发h员是否达到正的思考层ơ。“无力有效应用垃圾收集器”这L(fng){案表明他们既不了解q_的需要,也缺乏处理复杂问题的l验?br />
问题“你最喜欢/不喜Ƣ什么?”的回答比SQL问题的回{要好得多,但仍然ƈ不乐观。参加面试的开发h员,过70%回答的是琐碎的问题,其它10%左右的答案表明他们要么编码的水^不高Q要么缺乏高层次的思考?br />
最l的l果表明Q要扑ֈ最优秀的开发h员几乎是不可能的事情。实际上Q我也可能只招聘??个可UC为最?jng)_发h员的人?br />
培养优秀的开发h?br />
扑ֈ有潜质,卛_奇心强、个性好学的开发h员要更容易一些。这些开发h员确实希望在自己与他人的生活中发挥重要的作用。他们可能ƈ不了解关pL据库Q但他们乐于学习(fn)。他们带来学?fn)的热情Q让周围的h充满zd?br />
在许多机构,q种热情却以服从的名义受到压制。“我们一样那样做”的心态打消了M改善状况的尝试。因此,开发h员常常感到困惑。因为组l一斚w声明希望l徏世界U的开发团队(每个l织都希望拥有这L(fng)团队Q;另一斚wQ他们又不愿意做出变革?br />
但是Q我们可以采取行动,以保证新开发h员的q劲与期望不?x)受到压制。以下是我就培养优秀开发h员提出的一些徏议:(x)
指导Q?/strong>指定一个导师来帮助开发h员。这个h必须是一个资深开发h员,开发权威或兛_团队和进E改善、乐于助人的构架师。这个h不应是开发h员的直接领导或经理(如果可能的话Q。指g谈应该以开发h员,而不是组l的需求ؓ(f)中心?
代码审查Q?/strong>代码审查是提高开发能力的有效手段。但很多l织却极这样做。另外,Z很少把它当作是学?fn)机会(x),而把它当作贬低开发h员的时机。请q行代码审查Q把它当作培训与教育Q而非压制的手Dc?
渐进体验Q?/strong>向开发h员提供增量分配来鼓励他们不断成长。由于我们无法控制将来的目Q这可能是最难以执行的方法。但是,提供可能多的渐q分配结构将?x)取得长期回报?
学习(fn)挑战Q?/strong>除了渐进分配以外Q还要找出其它方式激励开发h员学?fn)尽可能多的知识Q即使这些知识不能立卌v作用。例如,如果你有一家网l开发商店,鼓励开发h员学?fn)智能客PSmart ClientQ技术,以帮助开发h员养成学?fn)?fn)惯?
内部培养
管你想Z一个项目找CU的开发h员,但优U的开发h员ƈ不容易找到。项目的成功主要q是依靠现在团队里的开发h员。他们越优秀Q你成功的机?x)就大。找到技术熟l的可靠人才来完成你的需求肯定会(x)很困难。自己培d发h员,是获得你所需要的开发h员唯一现实的方法?/p>
自定义的cM某种意义上来Ԍ也是一U用戯定义的数据,形如struct?br />Z此考虑Q完全可以从非MFC扩展DLL中导入非MFC的用戯定义的类?/font>
Ҏ(gu)如下Q?br />1) 首先建立一个DLL( WIN32 DLL)工程Q创建头文g*.dllQ自定义一个类Q?br />在类的前面添?__declspec(dllexport)"关键字,表示该工E到处这个类?br />例如: class __declspec(dllexport) myClass ...
2) 在其实现文g中,d头文?#include "*.h""Qƈ实现相应的类实现部分?/font>
3) ~译执行生成*.dll文gQ将其COPY到应用测试工E的执行目录?debug/release)
下,COPY DLL工程的头文g*.h到应用测试工E的目录下,dq项目中Qƈ其中的
"__declspec(dllexport)"修改?__declspec(dllimport)"?/font>
4) 在其实现文g中添加头文g"#include "*.h""Q然后对其导入的c进行相应的操作?/font>
5) ~译q行试E序Q便可以实现cȝ关的操作?/font>
NOTE: 对于静?动态链接到MFC的规则DLL也可以达到同L(fng)效果Q导入自定义的类?/font>
1Q?span style="FONT: 7pt 'Times New Roman'"> ?/span> scbarg.h Q?/span> scbarg.cpp Q?/span> sizecbar.h Q?/span> sizecbar.cpp Q?/span> mybar.h Q?/span> mybar.cpp 文g copy C的工E目录下Q打开 vc Q将q几个文件添加进工程?/span>
2Q?span style="FONT: 7pt 'Times New Roman'"> 打开 stdafx.h 文gQ在其中加入Q?/span> #include "sizecbar.h" Q?/span> #include "scbarg.h" ?/span>
3Q?span style="FONT: 7pt 'Times New Roman'"> ?/span> CmainFrame cL加成员变量:(x) CMyBar m_wndMyBar ?/span>
4Q?span style="FONT: 7pt 'Times New Roman'"> 重蝲 CMainFrame::DestroyWindow() Q在其中加入
CString sProfile(_T("BarState"));
m_wndMyBar.SaveState(sProfile);
SaveBarState(sProfile);
5Q?span style="FONT: 7pt 'Times New Roman'"> 修改 CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 如下Q?/span>
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
if (!m_wndMyBar.Create(_T("My Bar"), this, 123))
{
TRACE0("Failed to create mybar\n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndMyBar.SetBarStyle(m_wndMyBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndMyBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
DockControlBar(&m_wndMyBar, AFX_IDW_DOCKBAR_LEFT);
CString sProfile(_T("BarState"));
if (VerifyBarState(sProfile))
{
m_wndMyBar.LoadState(sProfile);
LoadBarState(sProfile);
}
return 0;
}
注:(x)U色字体部分为所加内宏V?/font>
6Q?span style="FONT: 7pt 'Times New Roman'"> 在“查看”菜单下d菜单?/span> mybar Q设?/span> id 为:(x) ID_VIEW_MYBAR.
7Q?span style="FONT: 7pt 'Times New Roman'"> 为其d CMainFrame::OnViewMybar() Q?/span> CMainFrame::OnUpdateViewMybar(CCmdUI* pCmdUI) 函数Q内容ؓ(f)Q?/span>
void CMainFrame::OnViewMybar()
{
// TODO: Add your command handler code here
BOOL bShow = m_wndMyBar.IsVisible();
ShowControlBar(&m_wndMyBar, !bShow, FALSE);
}
void CMainFrame::OnUpdateViewMybar(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable();
pCmdUI->SetCheck(m_wndMyBar.IsVisible());
}
~译q行卛_Q如果你x?/span>
workshop
中的
cedit
成员变量Q如本例
workshop
中的?wi))Q只需改变
mybar
中的代码卛_?br />下蝲q接Q?font color="#0000ff">CMyBar.rar(http://www.shnenglu.com/zerolee/admin/Files.aspx)