??xml version="1.0" encoding="utf-8" standalone="yes"?> 1 不会pQCS源于国Q重量的文档都是英文的。不会英语,那么你只能忍受拙 2 急于求成Q什么都没学习就开始编E是最大的忌讳。写C++E序语法都能错,数据 3 q于好问Q勤学好问是一U很好的品质Q但是如果把勤学丢了Q只留下好问Q就是一个恶劣的素质了。事无巨l都去请教别人,一则会让h厌烦Q二则由于没有系l学习过E,也是不可能学习好的?/p>
4 只会艳M别h和说别h不该拉K么多钱,而自己却收入微薄Q老实_l大多数情况下,收入的高低和你的水^是有正相兛_pȝ。不是否认有关系的存在,但是l对不会10个h?个h有关p而独独你没有。少抱怨一些多学习一些,提升自己才是最重要的?/p>
5 q于不求甚解和过于求甚解。了解ؓ什么是很重要的Q但是要学习的东西很多,如果什么都弄明白,那么估计头发白了q没有找到所有答案。当然如果什么都不想l致了解Q那么只能去做蓝领了?/p>
6 q分崇拜他hQ我想信很多人都是很厉害的,值得大家崇拜Q但是如果过于崇拜,把他们的话当成圣l就没有必要了。你需要突破他们,而不是崇拜他们?/p>
7 不想吃苦QIT业高收入和高竞争是联pd一L。没有付出永q别惌步?br />
劣的译和大延迟的文档(译出来的文档几乎都是很久以前出版的东西Q?/p>
l构q线性表都不知道Q数据库不知道关pL型,TCP~程不知道socketQ还是先坐下来学习几q再_如果说工作急需Q我只能_早干嘛去了)
]]>
思? : 公^永远有不同角度的公^
思? : q个游戏只有站在切换器旁边的人可以决定结?br />
有一小朋友在外面玩 而那个地Ҏ两条铁轨Q?br /> 一条还在用, 一条已l停?br /> 只有一个小朋友选择在停用的铁轨上玩
其它的小朋友全都在仍在用的铁轨上玩
很不巧,火R来了(而且理所当然的往上面有很多小孩的Q仍在用的铁轨上行Ӟ
而你正站在铁轨的切换器旁Q因此你能让火R转往停用的铁?br /> q样的话你就可以救了大多数的朋? 但是那名在停用铁轨上的小朋友被牺牲
你会怎么办?
据说大多Ch会选择救多一些的?换句话说Q牺牲那名在停用铁轨上玩的小?..
但是q又引出另一个问?br /> 那一名选择停用铁轨的小孩显然是做出正确军_
q了他的朋友而选择了安全的地方
而他的朋友们则是无知或Q性的选择在不该玩耍的地方?br /> Z么做出正抉择的Z大多Ch的无知而牺牲呢Q?br />
[响应与挑战]
q篇文章蛮发人深省的,看完了感触很?
我们常被教育要顾全大局,但公q_?
g当大安做的理所当然的时?
我们必随波逐流,否则׃被放逐而不容于?
如渔父中那位老翁劝屈原所说的:
世h皆浊,何不淈其泥而扬其L?
众h皆醉,何不其p而歠光?
何故深思高?自o放ؓ?
当一个h太坚持自己是"??
最后的下场可能是被牺牲的可怜鬼!
又有谁会Z掬一把同情之? 只会嘲笑他的愚蠢!
我们已经q了C会,学习的就是圆滑的做h,
当你是主? 像文章中那位切换轨道的?
内心的正义与现实冲突? 你会如何抉择?
不过- 换另一个角度,如不选择切换轨道
因ؓQ那小朋友一定知道那是活的轨?br /> 所以,当他们听到火车的声音Ӟ׃知道要跑!
但若Q将轨道切换后那个乖孩必定惨死Q?br /> 因ؓQ他从来没想q火车还会开到废轨道?br /> 所以,你认为呢Q?br />
或许q样的想法与理念Q?br /> C时才会发现
自己成ؓ一个不断被牺牲的可怜鬼Q?br /> 但这个社会又Z么要把是与非颠倒来又颠倒去呢?
另外Q再xQ一条铁道会被停止用,自由它的道理?br /> 是否代表着q个铁道本n有问题,未经验证׃用它会遇到潜藏的危机呢?
如果切过M后,被牺牲的׃只是一个或一小孩了Q?br /> 而是整R的乘客呢Q?br />
]]>
引言
一些Windowspȝ自带E序如资源管理器、Internet Explorer{程序的工具条看上去和其他一些程序的工具条不太一P在颜色上要漂亮许多。其实这些程序的工具条上的图标均?56Ԍ而普通应用程?在工h上所昄图标的颜色通常只有16Ԍq就军_了后者在视觉上远没有前者美观。由于Windows随系l而带的程序也是由开发h员编写的应用E序Q?q就说明通过E序~码可以实现256色甚x多色彩的图标在工h上的昄。ؓ此笔者经q摸索,通过MFC~程在应用程序中实现了高彩色工具条。现实?的主要方法介l如下,以飨q大读者?br />
基本设计思\
在实现高彩色工具条之前,先研I一下普?6色的工具条的实现q程Qƈ从中ȝ出改q方法。在VC的资源视图中工具条是一个资源名?IDR_MAINFRAME的Toolbar型资源,q可通过在编辑按钮上的图标来完成工具条上图标的绘制。虽然在资源视图中工h上各按钮的图标是怺 独立的,但在存储时ƈ非像图标一样保存ؓico格式文g而是以bmp位图格式保存在磁盘上的。该位图是一个由工具条上的按钮图标组成的长条型位囑֛像,?间没有Q何缝隙,在程序运行和在资源视囑֯工具条进行编辑时该图像首先装载到一个图像列表中Q然后工hҎ索引依次从图像列表中图像显C到工具条的?个按钮上。由于VC限制工具栏上的图标不能超?6Ԍ因此不论是在资源视图直接~辑位图q是用复制粘贴等手段均无法获取超?56色的工具条(注:用复 制粘贴的Ҏ虽然在编辑视图中可以暂时昄?56色的图标Q但在程序运行时仍会退化成16Ԍ?br />
׃不能在资源视图中通过~辑Toolbar资源实现16色以上的图标Q加之工h在显C时有ƈ不直接从Toolbar获取图标而是从图像列表中?取,因此可以通过其他一些图像处理Y件做好类g工具条的bmp囑փQ仅颜色比普通工hbmp囑փ丰富Q其余完全一PQƈ以位囄形式加入到程序资 源。在使用Ӟ先将其读取到囑փ列表Q这样图像列表中用于昄到工h上的图标的颜色就可以?56?4位、甚?2位色的了。由于工h~省时将直接 加蝲资源名ؓIDR_MAINFRAME的Toolbar型资源作为图标的来源Q因此还必须通过SetImageListQ)函数含有高彩色工具条位?的图像列表指定ؓ工具条的图标来源?br />
真彩工具条的实现
׃工具条的创徏是在L架类的OnCreateQ)函数中完成的Q因此高彩色囑փ的装载和囑փ列表的替换工作必M在此q行。在q行E序设计之前Q?需要做好各U准备工作,比如高彩色工h位图的绘制、高彩色位图加入到资源等。绘制工h位图Ӟ必须控制好图像的寸Q如需要有N个边长ؓ M的图标,那么需要绘制的位图寸为长=N*MQ宽=M。真彩位囑֜加入到工E之后就不能再在VC的资源视图中q行~辑了。由于这个彩色位图仅起到化?面的作用Q因此具体对的事件响应等工作q要通过讄原有的Toolbar资源来完成?br />
准备工作qA后,先要把工h位图装蝲到图像列表,q样才能被工h做获取。在作这一步时Q必ȝ::LoadImageQ)函数d载工h位图Qƈ通过宏MAKEINTRESOURCE()来指定具体要加蝲哪一个资源位图:
HBITMAP hbm = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_TOOLBAR), //加蝲IDB_TOOLBAR
IMAGE_BITMAP, //按位图格?br />0,0, // cx,cy
LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS );
LoadImageq回一个位囑֏柄HBITMAPQ但在MFC下用CBitmaps会更加方便,可创Z?br />CBitmap对象q用Attach()成员函数它与位囑֏柄联pv来:
CBitmap bm;
bm.Attach(hbm);
MFC加蝲工具栏位图时使用了一个内部函数AfxLoadSysColorBitmapQ)缺省颜色设定ؓ16Ԍ因此Z昄16色以上的囑փQ必d调用囑փ列表cCImageList的CreateQ)函数创徏囑փ列表时对囑փ清单做进一步的处理Q?br />
m_ilToolBar.Create(32,32,ILC_COLOR8, 4, 4);
m_ilToolBar.Add(&bm,(CBitmap*)NULL);
q里用ILC_COLOR8标明了创建的囑փ列表?56色的Q在VC的commctrl.h中对其有定义Qƈ且还提供有其他几U颜色位深度的预定义Q?br />
#define ILC_COLOR4 0x0004 //16?br />#define ILC_COLOR8 0x0008 //256?br />#define ILC_COLOR16 0x0010 //16位色
#define ILC_COLOR24 0x0018 //24位色
#define ILC_COLOR32 0x0020 //32位色
如果使用的工h位图只有256Ԍ对于多数E序q样已经_Q,则显然没有必要再使用更高U别的位深度定义。最后一步,也是最关键的一步,必须通过 SetImageListQ)函数指定工具条m_wndToolBar的图标来源不再是原来~省的图像列表而是含有高彩色位囄囑փ列表 m_ilToolBarQ?br />
m_wndToolBar.GetToolBarCtrl().SetImageList(&m_ilToolBar);
到此为止可以通过MFC在自q写的E序中实现类gIE{Y件的漂亮的工h了。下囑ְ是笔者用上述Ҏ得到的程序界面:
结
本文通过对作为工h图标来源的图像列表的替换Q实C在普通MFC应用E序中具备了以往只有Windowspȝ自带E序才具备的高彩色工h。较?地美化了E序的界面。本文程序在Windows 98下,由Microsoft Visual C++ 6.0~译通过?br />
用VC制作非常L工具?
自微软推出Windows 95?一大批全新的控件我们的应用程序更加美?使用也更加方ѝ其中一个显著的变化是工具条不再是一个突出的3D方?而是变成了^面的状??是只要把鼠标UdC?它就会自动地出来,大大方便了用戗?
W者经q一D|间摸?l于扑ֈ了制作这U工h的方法。原来Windows 95装了许多常用的控g,大都被放在Comctrl32.dll中,其中Toolbar控g是用于制作工h的。下?要介l一下如何在VC5.0中添加一个Toolbar?
众所周知,所有的控g都是某一cd的窗?所以制作Toolbar也要从制作窗口开始。由于MFC的Toolbarcdƈ不支持新的功?所以我们只好用SDKҎ,通过API调用来完成整个过E?Q该q程与制作一个传l的工具条类伹{?
Toolbar是属于comctrl32.dll的扩展功?所以要先调用InitCommonControlsEx()的函 数。该函数有一个重要的参数军_了对Toolbar的支?它的主要作用是注册ToolbarH口,?便在以后的程序中制作q种H口,而普通的工具条则要调用InitCommandControls()。需要注意的是这两个函数的写法?
INITCOMMONCONTROLSEX icex;
DWORD dwStyle;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
//注意下面q两个参数决定了是否注册Toolbar
icex.dwICC=ICC_COOL_CLASSES|ICC_BAR_ CLASSES;
InitCommonControlsEx(Qicex);
然后可以调用CreateWindowExq个函数来徏立ToolbarH口:
HWND hwndTB = CreateWindowEx(
WS_EX_TOOLWINDOW, //扩展工具条风?
TOOLBARCLASSNAME, //Toolbarcd
NULL,
WS_CHILD|WS_VISIBLE|TBSTYLE_FLATQ?//H口风格
0,0,0,0, //大小
AfxGetApp()Q>GetMainWnd(), //父窗口名
NULL,
AfxGetInstanceHandle(), //实例
NULL);
判断一下窗口句?如果不ؓI?pC窗口徏立成功。此时的Toolbar不过是一个空I的H口Q我们可以根据需要向里面d按钮。向Toolbar 中添加按钮是通过向它发送消息来 实现?以下q程与制作传l的工具条基本一致。首?建立一个ImageList控g,然后通过定义按钮的数据结构来定每个按钮的类型?
// 建立一个Imagelist 控g,
HWND himl;
//MYICON_CX,MYICON_CY是每个按钮的大小
himl= ImageList_Create(MYICON_CX,MYICON_CY,ILC_COLOR4,0,4);
//加入事先作好的工h位图IDB_BITMAP2
ImageList_Add( himl,
LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP2)),NULL);
//通过消息把位囑֊入到Toolbar?
SendMessage(hwndTB, TB_SETIMAGELIST, 0, (LPARAM)himl);
下面加入5个普通的按钮:
TBBUTTON tbArray[5]; //按钮的数据结?
for(i=0;iQ?;iQ+)
{
tbArray[i].iBitmap = i; //Wi个位?
tbArray[i].idCommand = IDM_BUTTONSTARTQi;
//命oID
tbArray[i].fsState = TBSTATE_ENABLED;
tbArray[i].fsStyle = TBSTYLE_BUTTON;
//按钮风格
tbArray[i].dwData = 0;
tbArray[i].iString = i; //昄的字W串
}
//讄按钮l构的大?
::SendMessage(hwndTB,TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
//d按钮到Toolbar?
::SendMessage(hwndTB,TB_ADDBUTTONS,(UINT)5, (LPARAM)tbArray);
x,一个很L工具条基本上制作完成,最后再调用函数ShowWindow()卛_: ShowWindow(hwndTB, SW_SHOWMAXIMIZED);
当点L钮时,Toolbar把消息传送到父窗口中,qH口响应消息。Toolbar中按钮的ID包含在消息函数的wParam参数?可以讄 它来调度不同的模块。这时可以重载父H口的O nCommand()函数,ҎwParam参数判断点击了哪个按钮。假定父H口是主H口框架,代码如下:
BOOL CMainFrame::OnCommand(WPARAM wParam,LPARAM lParam)
{
switch(wParam)
{
case IDM_BUTTONSTARTQ?:
AfxMessageBox(“你点中了第一个按?!", MB_ICONINFORMATION);
break;
case IDM_BUTTONSTARTQ?:
AfxMessageBox(“你点中了第二个按钮!!",MB_ICONINFORMATION);
break;
case IDM_BUTTONSTARTQ?:
AfxMessageBox(“你点中了第三个按钮!!", MB_ICONINFORMATION);
break;
}
return CMainFrame::OnCommand(wParam,lParam);
}
Visual C++ 版本6中工h的新特色
Dave Schmi
微Y在www.microsoft.com/visualc已经推出Visual C++6.0预览版几个月了。正式版预计Cq年底发布。同Ӟ预览版显C出版本6包含大量的改进和提高,包括支持Internet控g,例如扁^工具 条等。虽然改q的控g包与Internet无关Q但它首先出现在Internet Explorer中,因此它就被取做这个名字了。事实上Q官方发布的预览版的标题是“针对Internet Explorer 4.0的Visual C++ 5.0技术预览”?br />
在以前关于MFC工具条类的讨Z题中Q我曄应提供一个在版本6中工h的外观演C。有一个很好的消息Q那是你现在用CToolBar所作的所?工作在新的版本中都是有效的,包括那些在以前的栏目中所描述的一些扩展功能。因此,你将很容易修改现存的E序以获得象Internet Explorer和Visual Studio中那样“酷”的界面。此外,q没有什么坏消息?br />
工具条的新特?br />
早在版本4中,CToolBar已被MFC库完全实C。一旦公用控件动态链接库Q命名ؓcomctl32.dllQ变得无所不在了, CToolBar成了如今已包含在操作系l中的工h控g的代名词了。然而,CToolBarq没有揭C公用工h控g的所有能力。如今,通过 CreateEx()函数Q它成功了?br />
公用控g动态链接库现在包含了至三c风|最初的、在Internet Explorer3.0中加入的以及在Internet Explorer 4.0中加入的。虽然这些版本理Z是向下兼容的Q但某些专业人员曑ֆZ些不能在后来版本中正常运行的应用E序Q这可能是这些程序采用了一些没有公开?功能Q而这些功能ƈ没有被包含在所有的版本中?
Visual C++E序员没有这Ll历Q因为在Visual C++4.0?.0中comctl32.dllq不是一个可以再分发的组Ӟ它在安装Internet Explorer时被更新Q因此MFCE序员无法依靠最新版本的某些功能来用于他们的E序。这是CToolBar仅仅h最初的DLL的有限功能的?因。CToolBar能够实现最新的特色意味着微Y在Visual C++6.0中包含最新的DLLq将其作Z个可以再分发的组件?br />
l大多数新特色将由在调用CreateEx()和其它CToolBar成员函数时指定的新的风格标志来确定。下面是commctrl.h的一部分Q它定义了TBSTYLEcL识符Q?br />
#define TBSTYLE_BUTTON 0x0000
#define TBSTYLE_SEP 0x0001
#define TBSTYLE_CHECK 0x0002
#define TBSTYLE_GROUP 0x0004
#define TBSTYLE_CHECKGROU TBSTYLE_GROUP | TBSTYLE_CHECK)
#if (_WIN32_IE $#@62;= 0x0300)
#define TBSTYLE_DROPDOWN 0x0008
#endif
#if (_WIN32_IE $#@62;= 0x0400)
#define TBSTYLE_AUTOSIZE 0x0010
#define TBSTYLE_NOPREFIX 0x0020
#endif
#define TBSTYLE_TOOLTIPS 0x0100
#define TBSTYLE_WRAPABLE 0x0200
#define TBSTYLE_ALTDRAG 0x0400
#if (_WIN32_IE $#@62;= 0x0300)
#define TBSTYLE_FLAT 0x0800
#define TBSTYLE_LIST 0x1000
#define TBSTYLE_CUSTOMERASE 0x2000
#endif
#if (_WIN32_IE $#@62;= 0x0400)
#define TBSTYLE_REGISTERDROP 0x4000
#define TBSTYLE_TRANSPARENT 0x8000
#define TBSTYLE_EX_DRAWDDARROWS 0x00000001
#endif
你会注意到其中的一些采用了条g~译Q依赖于_WIN32_IE的|它缺省指的是Internet Explorer 4.0Q即取gؓ0x0400Q。对于Internet Explorer 3.0Q即取gؓ0x0300Q以前的版本Q大多数的TBSTYLE标识W指的是按钮或是一l按钮。Internet Explorer3.0引入了扁q钮、文本标{、下拉列表和自定义绘制。Internet Explorer 4.0增强了下拉列表和自定义绘制功能,q且增加了支持OLE拖动目标C个工h?br />
扁^钮和把手
在过ȝ18个月中我常常被问及该如何获得象Internet Explorer和Visual Studio中的工具条一样不使用雕按钮而是用扁q钮q且带有便于Ud和定位的把手那样L界面。这些特色ƈ不被MFC所支持Q因此最单获取的Ҏ?是购C个扩展库。而对于Visual C++ 6.0来说却无d此一举,因ؓ它得CToolBarcdCҎq钮、把手和其它新的视觉效果的支持?br />
在预览版中,AppWizardq不会自动包括这些新特色Q但它们却很Ҏ被加入。表1昄了AppWizard创徏的主框架H口的OnCreate ()函数Q表2昄了需要做哪些修改以获得具有扁q钮和把手的工具条。图1昄了表1创徏出的工具条,而图2昄Z?实现的工h?
?1: CMainFrame::OnCreate as generated by AppWizard
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if(!m_wndToolBar.Create(this)||!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)))
?
?: Adding flat buttons and the gripper
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if(!m_wndToolBar.CreateEx(this)||!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
}
// TODO: Remove this if you dont want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// TODO: Delete these three lines if you dont want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
?
Z作出扁^按钮我必M用CreateEx()来代替Create()。这个新的函数在afxext.h中声明:
BOOL CreateEx
(
CWnd* pParentWnd, // parent window
DWORD dwCtrlStyle = TBSTYLE_FLAT, // extended style
DWORD dwStyle = // style
WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP,
CRect rcBorders = CRect(0,0,0,0), // border rectangle
UINT nID = AFX_IDW_TOOLBAR // identifier
);
因ؓ扩展风格~省指的是TBSTYLE_FLATQ因此我要得到扁qx钮就只需要简单地AppWizard形成的代码中的Create()改ؓ CreateEx()卛_。我在后面实现其它的扩展风根{ؓ了获得把手,我必d调用SetBarStyle()函数时包含CBRS_GRIPPER?志,参看?。这是CControlBarcȝ一个新风格Q而CToolBarcL从它l承而来的。请注意到我也加入了CBRS_BORDER_3D?志,q是Z修正一个未知的l制问题Q该问题会在工h的边~绘制一些多余的炏V这也许意味着预览版确实有q个问题Q因Z旦我?D标志加入q卌 决了q且也似乎没有媄响到别的什么?br />
上面所作的两个单的改变是得一个已存程序获得酷界面的最省力的方法。在一个程序具有了扁^钮和把手的同Ӟ它也不会发生不应有的其它改变?br />
]]>
出处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 />
Class Diagrams
Class diagrams are the backbone of almost every object oriented method, including UML. They describe the static structure of a system.
Object Diagrams
Object diagrams describe the static structure of a system at a particular time. They can be used to test class diagrams for accuracy.
Use Case Diagrams
Use case diagrams model the functionality of system using actors and use cases.
Activity Diagrams
Activity diagrams illustrate the dynamic nature of a system by modeling the flow of control from activity to activity. An activity represents an operation on some class in the system that results in a change in the state of the system. Typically, activity diagrams are used to model workflow or business processes and internal operation.
Sequence Diagrams
Sequence diagrams describe interactions among classes in terms of an exchange of messages over time.
Collaboration Diagrams
Collaboration diagrams represent interactions between objects as a series of sequenced messages. Collaboration diagrams describe both the static structure and the dynamic behavior of a system.
Statechart Diagrams
Statechart diagrams describe the dynamic behavior of a system in response to external stimuli. Statechart diagrams are especially useful in modeling reactive objects whose states are triggered by specific events.
Component Diagrams
Component diagrams describe the organization of physical software components, including source code, run-time (binary) code, and executables.
Deployment Diagrams
Deployment diagrams depict the physical resources in a system, including nodes, components, and connections.
二、前期准?
首先我们建立一张名为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 />
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 ; |
首先误位看以下一D“危险”的C++代码Q?/p>
void function( void ) |
之所以说其危险,是因是一D完全合乎语法的代码Q编译的时候完得一炚w误也不会有,然而当q行到strcpy一句的时候,问题׃出现Q因为在q之前,str的空间已l被delete掉了Q所以strcpy当然不会成功。对于这U类似的情况Q在林锐博士的书中有q介l,U其为“野指针”?/p>
那么Q诸位有没有见过安全的“野指针”呢Q下面请看我的一DC++E序Q灵感来自CSDN上的一ơ讨论。在此,我只需要C++的“类”,C++的其余一概不需要,因此我没有用Q何的C++标准库,q输出都是用printf完成的?/p>
#include <stdio.h> |
OKQ程序到此ؓ止,怽可以~译q行一下看看结果如何。你也许会惊异地发现Q没有Q何的出错信息Q屏q上竟然乖乖地出Cq么一行字W串Q?/p>
This is a test function.
奇怪吗Q不要急,q有更奇怪的呢,你可以把dC加上一句更不可理喻的:
((CTestClass*)NULL)->Function(); |
q仍然没有问题!Q?/p>
我这q有呢,哈哈。现在你在主函数中这么写Q倘说上一句不可理喻,那么以下可以叫做无法无天了:
int i = 888; |
你看C什么?是的Q“This is a test function.”如U而至Q没有Q何的错误?/p>
你也许要问ؓ什么,但是在我解答你之前,请你在主函数中加入如下代码:
printf( "%d, %d", sizeof( CTestClass ), sizeof( int ) ); |
q时你就会看到真怺Q输出结果是——得到的两个十进制数相等。对Q由sizeof得到的CTestClass的大其实就是它的成员m_nInteger的大。亦x_对于CTestClass的一个实例化的对象(设ؓaQ而言Q只有a.m_nInteger是属于aq个对象的,而a.Function()却是属于CTestClassq个cȝ。所以以上看似危险的操作其实都是可行且无误的?/p>
现在你明白ؓ什么我的“野指针”是安全的了Q那么以下我所列出的,是在什么情况下Q我的“野指针”不安全Q?/p>
以上的两U情况,目的是野指针用属于自q东西D不安全,比如W一U情况中操作本n的m_nIntegerQ第二种情况中变函数的Function成ؓ了属于对象的函数Q这一点可以从sizeof看出来)?/p>
其实Q安全的野指针在实际的程序设计中是几乎毫无用处的。我写这一文章,意图q不是像孔乙׃样去琢磨回字有几U写法,而是想通过q个例子向怽写明白C++的对象实例化本质Q希望大家不但要明白what和howQ更要明白why。李马二雉三年二月二十日作于自宅?/p>
关于成员函数CTestClass::Function的补充说?/b>
q个函数是一个普通的成员函数Q它在编译器的处理下Q会成ؓcM如下的代码:
void Function( const CTestClass * this ) // ?/font> |
那么p->Function();一句将被编译器解释为:
Function( p ); |
q就是说Q普通的成员函数必须l由一个对象来调用Q经由this指针ȀzZQ。那么由上例的delete之后Qp指针会指向一个无效的地址Q然而p本n是一个有效的变量Q因此编译能够通过。ƈ且在~译通过之后Q由于CTestClass::Function的函C内ƈ未对q个传入的this指针q行M的操作,所以在q里Q“野指针”便成了一个看似安全的东西?/p>
然而若q样改写CTestClass::FunctionQ?/p>
void CTestClass::Function( void ) |
那么它将会被~译器解释ؓQ?/p>
void Function( const CTestClass * this ) |
你看CQ在p->Function();的时候,pȝ会试在传入的q个无效地址中寻找m_nInteger成员q将其赋gؓ0Q剩下的我不用说了——非法操作出C?/p>
至于virtual虚函敎ͼ如果在类定义之中CTestClass声明函数Q?/p>
class CTestClass |
那么C++在构建CTestClasscȝ对象模型Ӟ会Z分配一个虚函数表vptrQ可以从sizeof看出来)。vptr是一个指针,它指向一个函数指针的数组Q数l中的成员即是在CTestClass中声明的所有虚函数。在调用虚函数的时候,必须l由q个vptrQ这也就是ؓ什么虚函数较之普通成员函数要消耗一些成本的~故。以本例而言Qp->Function();一句将被编译器解释为:
(*p->vptr[1])( p ); // 调用vptr表中索引号ؓ1的函敎ͼ即FunctionQ③ |
上面的代码已l说明了Q如果p指向一个无效的地址Q那么必然会有非法操作?/p>
备注Q?/p>
①关于函数的命名Q我采用了原名而没有变化。事实上~译器ؓ了避免函数重载造成的重名情况,会对函数的名字进行处理,使之成ؓ独一无二的名U?br />②将成员函数声明为staticQ可以成员函数不经由this指针便可调用?br />③vptr表中Q烦引号0为类的type_info?/p>
二、自动配|数据源
很多的程序都要用到数据库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++;
}
q个隐隐的痛处,是在GUI~程领域?/p>
现有的大部分成熟GUI框架和工具库Q其定型旉都在90q代早期Q不是因ؓ什么原因,M我们Ҏ看不到template技术在q些环境中的M重要q用。无论是专有MFC和OWLQ还是开源的wxWindow和Mozilla, 以至于是专有q是开源都说不清楚的QtQ它们在其他斚w有着诸多不同Q偏偏倒是在对待模板技术上I前一_严格限制在底层的数据l构领域内,抵制模板技术流入GUIMl构。最q分的wxWindow和MozillaQ在代码~写规范里严厉禁止?990q之后发展出来的MC++Ҏ,模板、异常、多l承、STL{等Q均在黑名单上。诸位有兴趣Q不妨去看看Q那与其说是一份C++代码~写规范Q倒不如说是对C++CҎ在GUI领域应用的一份不公正的判决书?
N模板技术真的在GUI领域无用武之地吗Q?
WTLl出了一个响亮的回答?
WTL是微软ATL开发组成员Nenad Stefanovic先生在ATL Windowing机制上发展v来的一整套GUI框架Q运用template技术组l和创徏GUI对象Q构{了_致的面向对象框Ӟ没错Q在q里object oriented与template达成了精致的融合Q。虽然没有获得微软的官方支持Q虽然其使用者h数很,但是实是“用q的都说好”,有位微YMVP人士甚至_q是微Y有史以来推出的最优秀的一个framework。真是一个有的讽刺Q最好的东西居然不被官方支持。有关于WTL的流a不少Q比如这东西原本是微软内部专用,只是因ؓ不小心才被泄漏出来等{,q更加剧它的秘色彩。相信大家对它一定有不少问题。我们特别邀请到了WTL之父Nenad Stefanovic先生Q进行了一ơ网上的访谈Q希望能帮助大家了解WTL的真面目?
【C++ View】:I think most of our readers are not very familiar with you, so would you please tell us your story here? We are very fond of that. What do you think about China and Chinese people?
【C++ View】:我想Q可能我们的读者中有很多hҎq不是很熟悉Q您能不能在此给我们单介l一下您自己呢?我们非怹意听到您的自q。还有,您能不能也对我们讲述一下您对于中国以及中国人民的基本看法呢Q?/p>
【Nenad? I am a software developer at Microsoft. Your readers will probably know me as a creator of Windows Template Library, WTL. I am from former Yugoslavia, where I finished school and started working on software development. I've been living in US for 10 years now.
I am intrigued and impressed by the Chinese culture and tradition. I think that China is now in a great position of progress as a country and a nation. I discovered that, being from former Yugoslavia, I already know many things about China, and getting to know people from China gave me a bit of the "everyday" life perspective as well. I'd like to learn more, so I hope to visit China one day.
【Nenad】:好的。我现在在Microsoft工作Q是它里面的一个Y件开发h员。你们杂志的读者中可能有h知道Q我是Windows Template Library QWTLQ的创作者。我来自于前南斯拉夫Q在那我完成了我的学业ƈ开始了我作Y件开发h员的工作生。现在,我在国居住的时间已l超q了10q了?
中国的文化以及传l给我留下了极ؓ深刻的印象,我对此十分感兴趣。我惻I作ؓ一个国家以及民族,中国已经处于一个伟大ƈ且不断在成长中的位置上。作Z个从前南斯拉夫来的hQ我早就了解到关于中国的很多事情。在与来自中国的人民的接触过E中Q我q了解到了你们日常生zȝ一些状c我q想了解更多Q有关中国的事情Q,希望有一天我可以C国来游览?
【C++ View】:When and why did you first think about WTL? What's its original purpose? How do you see its future?
【C++ View】:您是什么时候开始想赯开发WTL呢?Z么?您在开发它时的最初目的是什么?您又是如何地看待它未来的发展呢?
【Nenad】:WTL was born while I was working on ATL (Active Template Library). We were extending ATL to support ActiveX controls, and I was working on the windowing support. I started thinking that the same techniques can be applied to much broader windowing support, for the much richer UI for controls, components, and also applications. So, WTL was created as a part of ATL that would extend ATL to support any kind of UI related component or application. It did not ship with ATL in Visual Studio, however, so I decided to ship it as a standalone library that extends ATL.
I think that WTL will continue to be a great option for developers writing Windows applications and components. I don't see big changes or additions to WTL, because one of the design principles for WTL was to follow the Win32 UI API and design. It will continue to do so.
【Nenad】:WTL是我在从事ATL QActive Template LibraryQ开发工作时的物。那时我们正在扩展ATLQ之得以支持ActiveX controlQ而我负责的就是其中对于窗口机刉分的支持。这Ӟ我就开始想Q是不是可以把同L技术应用到更ؓq泛的窗口机制中Q以获得更丰富的UI控制、组件、以至于应用E序呢?于是Q作为ATL的一部分QWTL被开发出来了。它ATLq行了扩展,以得它可以支持各种cd的与UI相关的组件或者应用程序。然而,它ƈ没有随着ATL一同集成在Visual Studio中被发布Q于是我决定将它作Z个单独的ATL扩展库发布出厅R?
我认为WTL一直是那些在Windows下开发应用程序以及组件的开发者的一个很好的选择。我q不认ؓ在以后,我们会对WTL有一个大的改动(或者增添)Q因为WTL的一个设计宗旨就是“遵循Win32 UI的API及其设计”。现在如此,来q是会如此下厅R?
【C++ View】:I first heard about WTL in July, 2000. At that time, I thought: "No official support, no documentation, no commercial hype, it will die in 6 months." Now, fifteen months passed, it spreads wider and be more vigorous. Lots of C++ programmers, esp. the ones we regard them as "gurus and masters" involved in WTL. I know it's surely because WTL is a wonderful library, but it must be more than a wonderful library to gain such attentions without official force.What do you think WTL's relative success? What's the reason?
【C++ View】:我第一ơ接触WTL是在2000q?月。在那时Q我想Q“没有官方的支持Q没有文档,也没有商业吹捧,它最多只能够存活6个月。”但现在15个月q去了,它反而流传得更ؓq泛Q更加的生机勃勃。许多C++E序员,其是一些我们所认知的“专家”以及“大师”,都在使用WTL。我当然知道q主要是因ؓWTL的出Ԍ但我惻I能够在没有官方的力量牉|的情况下吸引如此多的注意QWTL一定还有更的东西,请问您是如何看待WTL的成功呢Q它成功的原因又是什么?
【Nenad】: I think that the main reason of WTL's success is that it did fit the need of developers at the right time. More and more developers started using ATL, and it was natural for them to start using WTL when they needed more UI support. It seems that WTL was perceived as a more open project than others, judging by the support provided by other parties in the development community. Many people did a wonderful job of creating samples, documentation and support for WTL. The support from the programming community is very important part of the acceptance and success of WTL.
【Nenad】:我认为WTL成功的最主要原因是Q它实而且及时地满了开发者的需求。越来越多的开发h员开始用ATLQ当他们需要更多的UI支持Ӟ他们很自然的׃开始用WTL?从其他的开发团队所提供支持来看QWTL看v来似乎要比其他的目更加开放。许许多多h为WTL做了大量工作Q如Q创建示例代码,撰写文档{。WTL之所以能够被qؓ接受q获得如此大的成功,来自于这些开发团队的支持l对是一个重要的因素?
【C++ View】:What do you think about MFC? Do you like it? If you don't, why? And the most confusing thing is Managed C++, is it C++? Do the leaders of MC++ really think some C++ users will go to learn it? Do you believe?
【C++ View】:请问您对于MFC是怎么看的Q您喜欢它吗Q如果不Qؓ什么呢Q还有,最让hqh不解的就是Managed C++了,它是不是C++呢?MC++的提倡者是不是真的认ؓ会有一些C++的用戯{而去学习它呢Q您的看法又是如何呢Q?/p>
【Nenad】: I think that MFC is a great framework library. Don't forget that MFC was designed at the time that C++ compiler was rather limited, and the main platform was 16-bit Windows. Unfortunately, because MFC was designed as a framework, it was really hard to evolve it to use better C++ support in newer compilers, and to add support for new features added to Windows in the meantime. What I don't like about MFC is the DLL approach, which causes many compatibility problems, and framework design, which dictates too many things about app design.
Managed C++ is an extension to C++ which allows C++ programs to use managed code. It is very important to understand that you can compile your existing C++ code using MC++ without any changes. MC++ allows developers to use both familiar non-managed C++ and managed code in the same module. That provides an excellent way to extend existing code to interact with managed code, as well to create new projects that can use both managed and traditional C++.
【Nenad】:我认为MFC是一个了不v的框架库。请不要忘了Q在MFC被设计出来初期,那时的C++~译器还h很多的限Ӟq且那时主要的^台还只是16位的Windows。不q的是,׃MFC被设计成Z个框Ӟ使得我们很难利用新编译器中那些更好的C++Ҏ来改进它,也很隑ְWindows中的很多新特性添加到MFC中。我不喜ƢMFC的地Ҏ它高度依赖DLL的特性——因为它导致许多兼Ҏ方面的问题Q还有就是MFC的整个框架设计——它在应用程序的设计中限定了太多东西?
Managed C++是C++的一个扩展,它允许C++E序得以使用受管QmanagedQ代码。我们需要了解的一个很重要的特性就是,我们可以使用MC++来编译已有的C++代码而无需对它们进行Q何改动。MC++允许开发者同时用他们所熟悉的非受管代码以及受管代码来开发同一个模块。这提供了一个非常好的途径Q已有的代码与新的受管代码怺作用Qƈ也可使得我们创徏一个项目,同时使用受管的和传统的C++代码?
【C++ View】:In the past 15 years or more, C and C++ is the base of almost all Microsoft's technologies(OS, COM, etc.). We C++ user paid a lot of hard work to catch them, because we felt what we paid was worthy(?). Now, it seems the climate changed. .NET is coming, the world is going to be full of CLRs and/or JVMs. There has been a decampment from C++. So what do you think about the future of C++ (not MC++) in Mircosoft technologies? Will it go away? Will it become a marginal language?
【C++ View】:在过ȝ15q中Q甚x长的一D|间内Q,C以及C++构成了几乎所有Microsoft技术的基础Q如QOSQCOM{)。我们这些C++用户p了大量的旉来熟悉ƈ掌握它们QC以及C++Q,因ؓ我们怿我们所付出的一定会有回报(?Q。但现在的风向好像有了很大的改变?NET出现了,世界gp充斥CLR QCommon Language RuntimeQ公paq行库)以及Q或JVM QJava Virtual MachineQJava虚拟机)。现在C++已经出现了退潮的q象。那么,请问您对于C++Q不是MC++Q在Microsoft技术中的前景如何看待?它是否会由此消亡Q还是就此落ؓ一门边~语aQ?/p>
【Nenad】:Well, the world is changing too. The new type of development for Web services and connected applications is on the horizon. I think that new languages, like Java, C#, and VB.NET, were developed to address two main issues - to simplify software development and to provide better support for Internet development. Simplifying software development allows more developers to write good applications and cuts down on time needed to finish a project. Supporting Internet development is obviously very important in this time when Internet is used more and more in every part of everyday life.
I think that C++ will continue to be an important language, especially for ISV's and for system development. On the other hand, I believe that .NET will be very important platform soon. .NET has the potential to be the main programming platform for the future, but it is reasonable to expect that the transition will take some time.
【Nenad】:是的Q世界也已经发生了变化。对于网l服务以及连接这L新型应用E序的开发已lQ上了水面。我认ؓ那些新的~程语言Q如JavaQC#Q以及VB.NETQ都是针对以下两个主要的问题而开发出来的——简化Y件的开发过E以及对于Internet应用E序开发提供更好的的支持。简化Y件的开发过E得更多的开发者可以写出更多更好的应用E序q减完成开发项目所需要的旉。而支持Internet的开发,对于q个Internet来深入到我们的日常生zM的时代来_毫无疑问是一仉帔R要的事情?
我认为C++会l作Z门重要的~程语言发挥作用Q尤其是寚w些独立Y件开发商和那些系l开发来说更是如此。从另一斚w来说Q我怿.NET会在不久以后成为另外一个非帔R要的开发^台。对于未来来_.NET拥有成ؓL~程q_的潜力,但我们必认识到Q这Lq渡阶段肯定要持l一D|间?
【C++ View】:There a lots of beginners in our readers, after they learn (standard) C++, they want to seek a path to master enought Microsoft technologies to be practical and proficient programmers. Could you recommend such a path? Should they learn Win32 API programming? Is it worthy of studying MFC? Is WTL/ATL/STL a reliable solution? Or goto C# directly? Many many people will thank you if you give them frank advice.
【C++ View】:我们的读者中有很多是初学者,在他们学习完Q标准)C++后,他们希望能够扑ֈ一条道路,掌握到够多的Microsoft的技术自己成ؓl验丰富的、熟l的E序员。您能不能给我们指出q样的一条道路来呢?我们是不是应该学习Win32 API~程Q学习MFC是否是值得的?WTL/ATL/STL得上是一个可靠的解决Ҏ吗?又或是我们应该直接学习C#Q如果您能够l我们一些徏议,怿会有很多的h为此而感Ȁ您的?/p>
【Nenad】:I think that depends on their plans and ambitions. The more of those things you do, the better you are off in the long run. But, you also have to balance that with the practical issues. So, I think that people who see their future in the Internet development can go directly to C# or VB.NET, and study .NET platform. Those who would like to have more knowledge of the Windows platform and services it provides should certainly learn more about Win32 API and libraries that support Windows programming.
【Nenad】:我认主要取决于他们的计划以及雄心。你所做的多Q在长时间竞争中你就占据优ѝ不q你也要注意保持与实际问题的q。我那些军_以后只做Internet相关开发的人可以直接去学习C#或者VB.NETQ同时学?NETq_。而那些更多地了解Windowsq_以及它所提供的服务方面知识的人,当然必需要更多地了解有关Win32 API以及那些支持Windows~程的库相关的知识?
【C++ View】:Soon after I began to learn WTL, a warm-hearted man posted me a email. He wrote: "You won't be a good WTL programmer if not a good ATL programmer, you won't be a good ATL programmer if not a COM programmer. And once you decide to learn COM, you are beginning your travel to hell." Is COM so difficult to learn? How to study WTL? We must learn API, COM, ATL and WTL in sequence, do we? And what about COM, will it remain to be the core technology of Microsoft, or just be substituted by .NET and dismiss?
【C++ View】:在我刚开始学习WTL后不久,有一位热心hl我发了份邮件。他写道Q“如果你不是一个好的ATLE序员的话,你就不可能成Z个好的WTLE序员;如果你不会COM~程的话Q你׃可能成ؓ一个好的ATLE序员;但一旦你军_开始学习COMQ你pZt向地狱的第一步。”COM是不是真的那么难学?我们应该如何地来学习WTL呢?我们是不是应该按照这L序学下来呢QAPI->COM->ATL->WTLQ还有,COM会变得如何Q他是不是还能够保持Microsoft的核心技术这一头衔Q抑或是?NETl替换掉然后此消失Q?/p>
【Nenad】:I don't think it is necessary to master COM to use and understand WTL. Win32 UI knowledge is more important than COM to understand WTL. But it is true that knowledge of ATL is required, and ATL mainly supports COM. So, COM knowledge is desirable, but not required.
I don't think that COM is hell, but it sure does require a lot to learn to be an expert. Keep in mind that many people don't have to be COM experts to use COM, or to use WTL. Just understanding basic principles of COM is enough to use it, and then people can learn more when needed.
【Nenad】:我不认ؓ使用和理解WTL׃定要掌握COM。相比于COM来说QWin32 UI的知识对于理解WTL昑־更ؓ重要。但毫无疑问的是QATL的相关知识是必不可少的。由于ATL主要d是支持COMQ所以,有COM的知识只是会更好一些而已Q但它们q不是必需的?
我也不认为COM是一个噩梦,但毫无疑问的是,惌成ؓ一个COM专家Q要学的东西实在是太多了。但误住一件事情,很多使用COM或者WTL的hq不都是COM斚w的专家。要想用它们,Z所需了解的只是一些COM的基本原理就够了Q其他的相关的知识则可以在需要时再去学习?
【C++ View】:What do you think about Generic Programming? Is it a whole different paradigm from OOP, or just OOP's supplemental facility? Can we combine GP and OOP? In the hard work of design and implement WTL, you must had got an insight about the relationship between OOP and GP, what's it?
【C++ View】:请问您对于泛型程序设计是如何看待的?它到底是OOP的一个补充呢Q还是完全不同于OOP的另外一个程序设计范型呢Q我们是否可以将GP以及OOP一同联合用?我想Q在设计和实作出WTL的艰苦过E中Q对于OOP以及GP之间的关p,您一定有了自q看法Q您能不能给我们说一下呢Q?/p>
【Nenad】:Generic Programming and OOP are very different, mostly because Generic Programming doesn't explicitly express relationships between design elements. They can, however, be used together very efficiently.
WTL uses a combination of Generic Programming and OOP design. Templates are mostly used to implement traditional OOP classes. I'd like to point out that WTL doesn't use any "pure" design, and it doesn't strictly follow any design guidelines or styles. I do think, though, that WTL does use one of the main strengths of the C++ language - it uses appropriate paradigm that is the most suitable for a particular problem.
【Nenad】:GP和OOP非常不同Q这主要是由于GP从不昑ּ地表辑և设计元素之间的关联来。然而,它们也可以被非常高效地组合运用?
WTL中用了一UGPq同OOP的设计。我在其中大量用了模板来实作出传统的OOP中的cR我很乐意指出的是,WTL中ƈ没有使用一U“纯”设计,它也没有遵@M的设计指导方针或者设计规根{可是,我还是认为WTL使用CC++语言中的最主要的精髓处——对于一个特定的问题使用一U最适合它的适当典范?
【C++ View】:Recently, the famous C++ pioneer Stanley Lippman joined Microsoft and became a member of Visual C++.NET group. How do you think about this? What message do you think your company like to pass to public? Does this mean Microsoft want to make VC.NET a full-standardized C++ compiler and hold C++ as your core system language?
【C++ View】:最q,著名的C++元老大师Stanley Lippman加入了Microsoftq成为其VC.NET开发小l中的一员。请问您对于此事是如何看待的Q您认ؓMicrosoft试图向公众传播一U什么样的信息呢Q这是否也意味着Microsoft希望VC.NET成ؓ一个完全标准化的C++~译器,ql保持C++的核心系l语aC呢?
【Nenad】:I think that shows that Microsoft is committed to advance the C++ compiler and language, and ready to get the best people to help. I am sure that VC++.NET will continue to be powerful tool for developing applications, and that it will also include additional capabilities for the .NET development. Compliance with the C++ Standard is an ongoing work, and we will see further improvements there, too.
【Nenad】:我认昄了Microsoft对于促进C++~译器以及语al箋发展的决心,qؓ此找C最佳h选来获取帮助。我信VC.NET会l箋是开发应用程序的强有力工Pq且它同时还包含有.NET开发能力。目前我们正在进行兼容C++标准斚w的工作,不久我们׃看到成效?
【C++ View】:I'm learning WTL and ATL, since you are the author of WTL and a member of ATL group, can you give me some advice?
【C++ View】:我现在正在学习WTL以及ATLQ既然您是WTL的作者,同时又是ATL开发小l中的一员,您能不能l我一些徏议呢Q?/p>
【Nenad】:There are several areas of programming that are very important for WTL and ATL: knowledge of the C++ language in general, understanding of templates, COM for ATL, and Windows UI programming for WTL. Solid knowledge in these areas is very beneficial for WTL and ATL developers, and it also helps to understand the source code for both libraries.
I would also like to encourage everybody to write programs. That is the best way to learn how to use any library, or a programming language or operating system. Writing programs often brings problems that must be solved that are not addressed in books. Reading about something is very useful to start learning, writing programs is the best next step.
【Nenad】:对于WTL和ATL来说Q有好几个编E方面的领域是十分重要的Q大体上的C++语言知识Q了解模板,COMQ对ATL而言Q,以及Windows UI~程Q对WTL而言Q。在q些领域有着坚实的基对于WTL以及ATL开发h员来说有着很大的好处,同时对于理解q两个的源代码也能够起到帮助作用?
我同样也很乐意去鼓励大家多写E序。这也是学习如何使用一个程序库Q或者一门编E语aQ或者一个操作系l的一个最好的Ҏ。在写程序的q程中经怼出现一些书本上没有提及但又必须被解决的问题。在开始学习时M些东西是很有用的Q而写E序则是向纵深发展的最x式?
【C++ View】:They say we are in the gate of Post-PC times, it will be a embedded world, and there will be embedded smart device everywhere, and the embedded industry will build a far large market compare to PC's. Do you believe it? Do you think WTL and other C++ template libraries are available and appropriate for embedded development? Are there available for Internet development?
【C++ View】:有h_我们现在已经处于后PC时代的门口,未来会是一个嵌入系l的世界Q嵌入式的智能设备将会无所不在Qƈ且对比PC来说Q嵌入系l的产业会是一个更大的市场。您是否怿q些呢?您是否认为WTL以及其他的一些C++模板库对于嵌入式开发也适用呢?它们是否适合Internet开发?
【Nenad】:Yes, I think that large number of various devices that we use everyday will become small, specialized computers. That doesn't mean that the number and importance of PCs will go down, just that there are many other devices that will be enhanced to be programmable and connected. Those new devices will provide a great opportunity for software developers, because they will all have software and somebody has to write it.
Many of the C++ libraries are quite appropriate for embedded development, and WTL would also be in cases where Windows based user interface is important (for example, Pocket PC platform). Great flexibility and small footprint are always very important features for embedded development, so template libraries are in the very good position there.
【Nenad】:是的Q我认ؓ我们C所使用的各U设备中的大部分在以后都会演变成ؓ一些小的,h专门用途的计算机。但qƈ不意味着PC的数目以及重要性将会由此降低,只不q是表明q有着许多其他的设备需要被加强以得我们可以对其进行编Eƈ且连接。由于必需要有软g的支持,而Y件又需要有人来写,q些新的讑֤会lY件开发h员带来极大的机遇?
有许多的C++函数库都可用于嵌入系l的开发,WTL也将会在那些Windows用户界面较ؓ重要的开发中Q例如,在Pocket PCq_上面开发)占有一席之地。对于嵌入式开发来_良好的弹性,微小的内存耗用永远都会是很重要的特性,而模板库在这斚w占据了一个非常好的地位?
【C++ View】:In the past 7 years or more, COM is Microsoft's core technology. And we now can see that in the next decade, the core role may be .NET. My question is, what's wrong with COM? Where will COM be? Will it disappear? Will it be substituted by something else? What's the relationship between COM and .NET? Is .NET based on COM? Is it worthy of learning COM now?
【C++ View】:在过ȝ7q_甚至更长的一D|_内,COM都是Microsoft中的核心技术。现在我们可以预见到Q在下一个十q间Q这个核心将会变?NET。我的问题就是,COM有什么过错?COM何M从?它是否会逐渐消失呢,q是会被其他的一些技术给替代QCOM?NET之间的关pL什么样的情况?.NET是否是基于COM之上呢?现在学习COM是不是还值得Q?/p>
【Nenad】:Maybe you shouldn't ask what is wrong with COM, but just think of .NET as the evolution of COM. .NET extends what was started with COM- creating reusable binary components - and brings additional important features: rich metadata, great run-time, built-in security, versioning, etc. All of these new features are important for development today, and it is really great that .NET has extensive support for them. Interoperability between .NET and COM is also provided, so that the previously developed COM components can still be used in the .NET environment.
I still think that it is a good idea to learn COM - it is a great first step even for people who want to learn .NET, and it also provides better understanding of the design and implementation of .NET itself.
【Nenad】:或许你不应该问COM有什么过错,而是应该?NET看成COM的进化?NET扩展了COM最初的目的——创建可重用的二q制E序lg——ƈ向其中添加了很多重要的特性:丰富的元数据Q了不v的运行库Q内建的安全机制Q版本机制等。对于现今的软g开发来_所有的q些新的Ҏ都非常重要Q所?NET能够q泛地支持它们,是一件很伟大的品。Microsoft同时也提供了?NET和COM之间q行互操作的能力Q这使得以前所开发出来的COMlg?NET环境中同样也能够得到使用?
我仍然认为学习COM是一个很好的L——它甚至对于那些希望学习.NET的h们来说也是一个很好的开端,学习COM同时也有助于我们更深入地理解 .NET本n的设计和实现?
【C++ View】:I know you must be a C++ fan. Now the language is facing lots of challenges. To counterattack, Dr. Stroustrup suggest to develop many useful libraries, and teach the programmers to use C++ as a high level language. Now there are several wonderful modern C++ libraries. Aside of ATL, WTL and STL, there are still Boost library, MTL, ACE/TAO, DTL, etc. It seems the C++ community is preparing a movement. Do you think the movement will success? Why? What are your colleagues'(in Microsoft VC.NET group) attitude towards such a movement?
【C++ View】:我猜x肯定是一个C++爱好者。现在这门语a面对着许多的挑战。作为反L施,Stroustrup博士提议开发许多有用的库,q引导C++E序员把C++当作一门高U语a来用。现在我们已l可以得到好几个极好的现代的C++库,除去ATL、WTL以及STL之外Q还有Boost库、MTL、ACE/TAO、DTL{。一切都昄着C++C正在酝酿着一ơ变革。请问您觉得q场变革能否成功Qؓ什么?您的那些Microsoft中的VC.NET开发小l中的同事对于此态度是怎样的?
【Nenad】:C++ is a great language and its importance remains high, even with the new challenges. Libraries are an excellent addition to the language itself, as they provide very useful reusable code for developers. The existence of many great C++ libraries shows the size and strength of the C++ community. I think that is already a success, and that it will continue. You can be sure that the VC++.NET group is aware of the existing libraries, and I expect them to continue to enhance the support for them.
【Nenad】:C++是一门伟大的语言Q即侉KC新的挑战Q它仍然是非常重要的。程序库对于语言本n是极好的补充Q它们ؓ开发者提供了一些十分有用的可重用代码。存在如此众多的、了不vC++E序库,qg事情本np明了C++C的庞大和强大。我认ؓq场变革已经成功了,q且会一直成功下厅R你们可以放心,VC.NET开发组是不会对q些已有的程序库熟视无睹的,我预期他们会不断地加强对于这些库的支持?
【C++ View】:The last question. Since lots of people don’t acquaint themselves with WTL, now we have a chance for you, the father of WTL, to introduce WTL in a short speech here. What would you like to speak?
【C++ View】:最后一个问题。既然许多hq不了解WTLQ作为WTL之父Q您现在有机会在q里做一个演ԌL短地介绍一下WTL?/p>
【Nenad】:WTL is a template based library for user interface development. It extends ATL to provide classes for implementing user interface for applications, components, and controls. It provides classes for various user interface elements: top-level windows, MDI, standard and common controls, common dialogs, property sheets and pages, GDI objects, UI updating, scrollable windows, splitter windows, command bars, etc.
WTL is implemented using the same template architecture as ATL, so it is a natural fit for ATL developers. It also doesn't alter or hide Windows specific constructs, thus allowing Windows programmers to use WTL without surprises. The important design goal of WTL was to avoid inter-dependencies - classes themselves do not reference other WTL classes. That means that your program will contain just the code that you actually use, and nothing else. Coupled with the use of templates, this allows creation of very small programs without run-time dependencies.
WTL delivers the object oriented way to program for the Windows user interface, while keeping the code size small. It also provides a great foundation that developers can extend with their own classes.
And finally - WTL was written with a hope that developers will enjoy using it. I hope you will use it and enjoy it, too.
WTL是一个基于模板的、专为开发用L面的E序库。它扩展了ATLQƈ提供了一些类用来实现应用E序的用L面、组件和控g。它提供了各U类来支持各U各L用户界面元素Q顶U窗口、MDI、标准控件和通用控g、通用的对话框、属性表以及属性页、GDI对象、UI更新、可卷动的窗口、分割窗口、命令条{等…?
WTL的实C用了和ATL一L模板架构Q所以对于ATL开发者显得很自然。同时它q没有改变或者是隐藏那些Windows相关l构Q那些WindowsE序员在使用WTL时也不会感到很吃惊。WTL的一个主要设计原则就是避免在没有引用到其他WTLcLQ出C必要的内部依赖。这意味着我们的程序将只包含有我们实际上所使用的代码,除此之外再无其他的东ѝ加上了模板的用后Q这样做得到的结果就是一些非常小的,不依赖于q行库的E序?
WTL专注于用面向对象的方法来~写Windows的用L面程序,同时保持代码的尺寸很。同Ӟ它也为开发者提供了一个很好的基础Q可以写新的cL扩展WTL?
最后,我在~写WTL时就希望开发者能够喜Ƣ在开发中使用它。我同样也希望您能够使用它ƈ喜欢上它?/p>