下载
加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 VC深入内幕编程

VC深入内幕编程.doc

VC深入内幕编程

Evan大军
2017-09-20 0人阅读 举报 0 0 暂无简介

简介:本文档为《VC深入内幕编程doc》,可适用于IT/计算机领域

VC深入内幕编程深入编程内幕VisualC一走进VISUALC理解VC工程MFC编程特点使用WIZARD二MFC程序结构分析WINDOWS程序工作原理建立应用程序程序结构剖析(类CMYAPP(类CMAINFRAME(类CMyView与CMyDoc三深入MFC类库处理用户输入(定义对话框资源(定义对话框类有关屏幕输出(设备上下文工作原理(实例绘图原理剖析(绘图操作实现(有关屏幕映射方式文件处理(对象持续化简述(实例分析(与文件处理关系密切的类CFileDAO技术(DAO与ODBC(使用MFC实现DAO技术打印打印和显示打印分页打印工作的开始和结束打印程序实例四、VC程序调试(调试环境的建立(调试的一般过程(如何设置断点(控制程序的运行(查看工具的使用高级调试技术TRACE宏的利用ASSERT宏的利用ASSERTVALID宏的利用以及类的AssertValid()成员函的重载对象的DUMP函数的利用内存漏洞的检查Pageno深入编程内幕VisualC五VISUALC与多媒体对声音的处理(媒体控制接口(波形混音器多媒体文件IO多媒体图形图像技术图像合成FLC动画热点Pageno深入编程内幕VisualC一走进VisualCVisualC作为一个功能非常强大的可视化应用程序开发工具是计算机界公认的最优秀的应用开发工具之一。Microsoft的基本类库MFC使得开发Windows应用程序比以往任何时候都要容易。本光盘教学软件的目的就是为了让你学会在VisualC环境下利用微软的基本类库MFC开发出功能强大的Windows应用程序。在本章节的内容当中我们将向您介绍使用VC开发软件需要用到的一些基本概念使用MFC进行编程的基本特点以及VISUALC集成开发环境提供的一系列编程辅助工具WIZARD的使用方法。理解VC工程VisualC作为一种程序设计语言它同时也是一个集成开发工具提供了软件代码自动生成和可视化的资源编辑功能。在使用VisualC开发应用程序的过程中系统为我们生成了大量的各种类型的文件在本节中将要详细介绍VisualC中这些不同类型的文件分别起到什么样的作用在此基础上对VisualC如何管理应用程序所用到的各种文件有一个全面的认识。首先要介绍的是扩展名为dsw的文件类型这种类型的文件在VC中是级别最高的称为Workspace文件。在VC中应用程序是以Project的intx,inty,intx,inty,intx,inty,BYTEr,BYTEg,BYTEb,BYTEr,BYTEg,BYTEb)这个函数的用法有点类似于BitBlt函数它的意思为:把己方缓冲区内的数据拷贝到类dib的缓冲区中去其中从RGB(r,g,b)至RGB(r,g,b)的颜色为透明色x、y、x、y、x、y为目标坐标、拷贝范围、源坐标其意义与BitBlt相同。在Show函数的实现过程中我们首先算出要改变的源数据、目标数据地址然后分析要拷贝的数据颜色是否属于屏蔽色假如是屏蔽色则不拷贝数据否则拷贝。另外一种透明位图方式透明色固然是一种比较简单的实现方式但是有的时候也需要另外一种实现方式这就是直接指定颜色索引方式我们可以指定在调色板中某某号至某某号为透明色。因此在classMYDIB中再增加一个函数Show(MYDIB*dib,intx,inty,intx,inty,intx,inty,registerBYTEx,registerBYTEy)这个函数的原理与前一种方式差不多只是比前一种方式少了四个参数由以颜色指定透明色改成以颜色索引指定透明色。透明位图的刷新速度到底更改数据缓冲区方式的速度快还是BitBlt速度快,要是BitBlt速度快的话以前的一番心血岂非成了滚滚长江东逝水为此我们要用实例分析一下建立一个名为Tp的基于对话框的程序加入源程序mybmpcpp和mybmph在tpdlgh文件头中加入#include"mybmph"在类CTPDlg中加入两个成员变量bmp和bmp。在窗口初始化时设置定时器打开文件“bmp”、Pageno深入编程内幕VisualC“bmp”在定时器消息响应过程中完成拷贝和刷新过程编译并运行程序。我们可以看到一个“AllTime”参数它显示刷新张位图需要大约秒左右。现在注释掉定时器消息响应过程中的透底函数bmpShow((MYDIB*)bmp,,,,,,,,,,i,i,i)再看刷新张位图大约需要秒这是单纯使用函数StretchDIBits所需的时间。可见此处一个透明位图完成时间相当于一点四个BitBlt时间比照BitBlt方式的三个BitBlt时间(差效果)、五个BitBlt时间(好效果)要好得多。当然这与直接写屏比又差得多了。现在再将透底函数换成bmpShow((MYDIB*)bmp,,,,,,,,i)我们不由惊喜地看到现在刷新张位图的时间为秒几乎可以认为缓冲区读写时间已经可以忽略不计。图实例分析在这个实例中我们要实现一个动画背景是一位绝代佳人前面有一只狗牵着它的宠物跑来跑去。素材需要五张图片其中背景一张动画四张。我们分析一下它的实现方式:在类CMovieDlg中我们首先用语句BMPbmp定义了五张图片然后用语句MYDIBtemp定义了一个临时图片。在对话框初始化过程函数中分别读入五张位图设定定时器为一百毫秒在定时器响应函数中操作过程如下:首先将背景写入临时图片再将小狗透去白色写入临时图片最后将临时图片写上屏幕。图Pageno深入编程内幕VisualCFLC动画FLC和FLI动画同属于AutoDesk公司的产品它们采用帧与帧之间求差及单帧RLE编码的方式其特点是易于解码和编码。当然它们没有为音频提供便利限制了它的应用范围。在FLC和FLI之间FLI由于大小仅局限于x调色板仅色最多帧长度使它已差不多退出了历史舞台。因此我们在此不再讲述FLI只介绍FLC动画原理及实现方式。FLC文件的结构FLC文件的结构图示如下:文件头数据结构如下:FLC帧头数据结构:Pageno深入编程内幕VisualC块头数据结构:块的类型及解释:FLC动画播放源程序简介我们分析一下FLC动画源程序:打开文件flcwh可以看见文件中定义了FLC文件头、帧头、块头及块类型的宏。另外我们可以发现类FLCW是从类MYDIB中派生来的这是因为不管FLC动画本身如何复杂只要是往屏幕上画图最后都是要在内存中转换成位图形式。FLC动画实现过程中在Open阶段就生成了一个大小与FLC动画相同的内存位图以后每次读取下一帧就把数据写入内存位图再将内存位图贴到屏幕上。FLCWh:interfacefortheFLCWclass#if!defined(AFXFLCWHABACDFBBBAINCLUDED)#defineAFXFLCWHABACDFBBBAINCLUDED#ifMSCVER>=#pragmaonce#endifMSCVER>=#ifdefcplusplusextern"C"{#endif*#ifndefGlobalPtrHandle#defineGlobalPtrHandle(lp)((HGLOBAL)LOWORD(GlobalHandle(FPSEG(lp))))#endifPageno深入编程内幕VisualC#defineIsOverSegAlians(lp,off)(((DWORD)FPOFF(lp)(WORD)off)>XFFFFL:)#include"mybmph"#definePALVERSIONx#defineDIBSTORAGEWIDTH(x)((x)~)#defineWIDTHBYTES(i)((i)*)#defineMAXPALETTE*max#supportedpaletteentries*#pragmapack()*FlicHeader*typedefstruct{longsize*Sizeofflicincludingthisheader*WORDtype*EitherFLITYPEorFLCTYPEbelow*WORDframes*Numberofframesinflic*WORDwidth*Flicwidthinpixels*WORDheight*Flicheightinpixels*WORDdepth*Bitsperpixel(Alwaysnow)*WORDflags*FLIFINISHED|FLILOOPEDideally*longspeed*Delaybetweenframes*shortreserved*Settozero*DWORDcreated*Dateoffliccreation(FLConly)*DWORDcreator*Serial#offliccreator(FLConly)*DWORDupdated*Dateofflicupdate(FLConly)*DWORDupdater*Serial#offlicupdater(FLConly)*WORDaspectdx*Widthofsquarerectangle(FLConly)*WORDaspectdy*Heightofsquarerectangle(FLConly)*charreserved*Settozero*longoframe*Offsettoframe(FLConly)*longoframe*Offsettoframe(FLConly)*charreserved*Settozero*}FLICHEADtypedefFLICHEAD*LPFLICHEAD*ValuesforFlicHeadtype*#defineFLITYPExAFu*xFLItypeID*#defineFLCTYPExAFu*VariablerezFLCtypeID**ValuesforFlicHeadflags*#defineFLIFINISHEDx#defineFLILOOPEDx*OptionalPrefixHeader*typedefstruct{longsize*Sizeofprefixincludingheader*WORDtype*AlwaysPREFIXTYPE*shortchunks*Numberofsubchunksinprefix*Pageno深入编程内幕VisualCcharreserved*Always*}PrefixHead*ValueforPrefixHeadtype*#definePREFIXTYPExFu*FrameHeader*typedefstruct{longsize*Sizeofframeincludingheader*WORDtype*AlwaysFRAMETYPE*shortchunks*Numberofchunksinframe*charreserved*Always*}FRAMEHEADtypedefFRAMEHEAD*LPFRAMEHEAD*ValueforFrameHeadtype*#defineFRAMETYPExFFAu*ChunkHeader*typedefstruct{LONGsize*Sizeofchunkincludingheader*WORDtype*ValuefromChunkTypesbelow*}CHUNKHEADtypedefCHUNKHEAD*LPCHUNKHEAD#pragmapack()enumChunkTypes{COLOR=,*levelcolorpalletteinfo(FLConly)*DELTAFLC=,*Wordorienteddeltacompression(FLConly)*COLOR=,*levelcolorpalletteinfo*DELTAFLI=,*Byteorienteddeltacompression*BLACK=,*wholeframeiscolor*BYTERUN=,*Byterunlengthcompression*LITERAL=,*Uncompressedpixels*PSTAMP=,*"Postagestamp"chunk(FLConly)*}typedefstruct{BYTErBYTEgBYTEb}COLORtypedefCOLOR*LPCOLORtypedefstruct{WORDxWORDyPageno深入编程内幕VisualCWORDwidthWORDheight}WRYRECTdefineloadmethod#defineFLCNONE#defineFLCLOADINMEM#defineFLCSKIPFIRST#defineFLCAUTO#defineFLCLOOPSdefineerrormessage#defineFLCERROPEN#defineFLCERRHEADER#defineFLCERRFRAME#defineFLCERRCHUNK#defineFLCERRCOLOR#defineFLCSUCCESSdefineflcplaystatus#defineFLCSTOPPED#defineFLCPLAYING#defineFLCPAUSED#defineFLCNOTREADYtypedefuniontagWPT{short*wBYTE*ubchar*b}WPTiffps=,thisfunctionisGetFlcSpeedreturnisframepersecondiiserror#ifdefcplusplus}#endif#defineSUCCESSFUL#defineFLCERRREADHEAD#defineFLCERRNOTFLC#defineFLCERRNOMEMORY#defineFLCERRREADFILE#defineFLCERRREADFRAME#defineFLCERRREADCHUNKPageno深入编程内幕VisualC#defineSKIPFRAMEclassFLCW:publicMYDIB{private:PALETTE*pal:havn'tpalette!:havepaletteWORDwmNotifyWORDwidthWORDheightlongsizeWORDframesDWORDspeedWORDloopsWORDcurrframeWORDcurrloopshortflagslongoframeWORDStartFrameDWORDdwNextTimeHFILEhFileHWNDhPlayWndshortfStatusWORDxOrgWORDyOrgWRYRECTrcChangevoidDecodeColor(LPSTRBody)voidDecodeBRun(LPSTRBody)voidDecodeCopy(LPSTRBody)voidDecodeBlack()voidDecodeDeltaFli(LPSTRBody)voidDecodeDeltaFlc(LPSTRBody)public:FLCW(){memset(this,,sizeof(FLCW))}FLCW(){lpInfoHead>biSize=sizeof(BITMAPINFOHEADER)lpInfoHead>biPlanes=lpInfoHead>biBitCount=lpInfoHead>biCompression=BIRGB}~FLCW(){CloseFlc()}BOOLSDIFlcMessageLoop(HWNDhMainWnd,HACCELhAccel,MSG*msg)BOOLMDIFlcMessageLoop(HWNDhFrameWnd,HWNDhClientWnd,HACCELhAccel,MSG*msg)intOpen(LPCSTR,PALETTE*)BOOLCloseFlc()Pageno深入编程内幕VisualCvoidPlayFlc(HWNDhwnd,WORDxOrg,WORDyOrg,WORDwmnotify)voidStopFlc()voidPauseFlc()shortQueryFlc()intLoop(WORDwLoops)floatSpeed(floatfps)WORDGetTotalFrame()WORDGetCurFrame()BOOLShowFlc(HDChdc)BOOLFlcIdle()shortReadFrame()voidPlayFlcAFrame()}#endif!defined(AFXFLCWHABACDFBBBAINCLUDED)FLCWcpp:implementationoftheFLCWclass#include"stdafxh"#include"flcwh"#ifdefDEBUG#undefTHISFILEstaticcharTHISFILE=FILE#definenewDEBUGNEW#endif#include"testcpp"ConstructionDestructionmodefyin:TJClassFLCWPageno深入编程内幕VisualC*voidFLCW::DecodeColor(LPSTRBody){shortstart=BYTE*cbuf=(BYTE*)(Body)shortops=*(short*)BodyWORDcountshortnumber=shortiwhile(ops>=){start=*cbufif((count=*cbuf)==)count=number=countfor(i=starti<(startcount)i){lpInfo>bmiColorsirgbRed=*cbuflpInfo>bmiColorsirgbGreen=*cbuflpInfo>bmiColorsirgbBlue=*cbuflpInfo>bmiColorsirgbReserved=}start=count}lpInfo>bmiHeaderbiBitCount=lpInfoHead>biClrUsed=numberif(pal)CreatePal(lpInfo)}*voidFLCW::DecodeColor(LPSTRBody){intpoint=BYTE*cbuf=(BYTE*)(Body)shortops=*(short*)BodyWORDcountintiwhile(ops>=){point=*cbufif((count=*cbuf)==)count=i=pointcountfor(point<ipoint){lpInfo>bmiColorspointrgbRed=*cbuflpInfo>bmiColorspointrgbGreen=*cbuflpInfo>bmiColorspointrgbBlue=*cbuflpInfo>bmiColorspointrgbReserved=*PCNOCOLLAPSE*Pageno深入编程内幕VisualC}}lpInfo>bmiHeaderbiBitCount=lpInfoHead>biClrUsed=pointif(!pal)CreatePal(lpInfo)}voidFLCW::DecodeBRun(LPSTRBody){shortx,y=WORDbytewidthcharpsizeLPSTRlpDibLPSTRlpTempLPSTRtLPSTRtbytewidth=DIBSTORAGEWIDTH(width)lpDib=(LPSTR)GlobalLock(hData)if(!lpDib)returnlpTemp=lpDib(LPSTR)MoveToDibData(lpDib)t=Bodytt=lpTemp(unsignedlong)(height)*(unsignedlong)bytewidthwhile(y<height){x=tpsize=while(x<width){psize=*tif(psize>=){shortjmemset(t,*t,psize)t=psize}else{psize=psizememcpy(t,t,psize)t=psizet=psize}x=psize}yt=lpTemp(unsignedlong)(heighty)*(unsignedlong)bytewidth}GlobalUnlock(hData)rcChangex=Pageno深入编程内幕VisualCrcChangey=rcChangewidth=widthrcChangeheight=height}voidFLCW::DecodeDeltaFlc(LPSTRBody){shortlpcount,ishortopcountshortminx,miny,maxx,maxyWORDbytewidthLPSTRtempLPSTRt,tLPSTRlpDibWPTwptshortjshortpsizesignedcurrx,curryminx=miny=maxx=maxy=currx=curry=heightbytewidth=WIDTHBYTES(width*)lpDib=(LPSTR)GlobalLock(hData)if(!lpDib)returntemp=lpDibtemp=temp(DWORD)(height)*bytewidtht=tempi=wptub=(BYTE*)Bodylpcount=*wptwwhile(i<=lpcount){if((opcount=*wptw)>=){ifor(j=j<opcountj){currx=*wptubpsize=*wptbt=tempcurrxif(currx!=*(wptub)||*wptub!=||*t!=*(wptub)||*(t)!=*(wptub)){if(minx>currx)minx=currx}wptbPageno深入编程内幕VisualCif((psize=psize)>=){memcpy(t,wptub,psize)currx=psizet=psizewptub=psizeif(maxx<currx)maxx=currx}else{BYTEjpsize=psizecurrx=psizepsize=psize>>for(j=j<psizej){*(short*)t=*wptwtt}wptwif(maxx<currx)maxx=currx}}if(i==lpcount)breakcurrx=curryif((WORD)miny>(heightcurry))miny=heightcurrytemp=temp(DWORD)bytewidthcontinue}if(((WORD)opcount)x){skiplinesopcount=opcountcurry=opcounttemp=temp(DWORD)opcount*(DWORD)bytewidthif((WORD)miny>(heightcurry))miny=heightcurrycurrx=continue}t=temp(DWORD)bytewidthLt=(LPSTR)(wptw)*t=*tmaxx=widthcontinue}GlobalUnlock(hData)maxy=heightcurryif(miny==)miny=rcChangex=minxrcChangey=minyrcChangewidth=maxxminxrcChangeheight=maxyminyPageno深入编程内幕VisualCreturn}voidFLCW::DecodeDeltaFli(LPSTRBody){short*wBYTE*cptshortlinesBYTEopcountcharpsizeLPSTRlpDibLPSTRt,tempWORDminx,miny,maxx,maxyWORDcurrx,curryshortishortbytewidthbytewidth=WIDTHBYTES(width*)minx=miny=maxx=maxy=w=(short*)Bodycpt=(BYTE*)(w)lpDib=(LPSTR)GlobalLock(hData)if(!lpDib)returncurry=*wlines=*wtemp=lpDib(DWORD)(heightcurry)*bytewidthcurry=heightcurryif((unsigned)miny>(heightcurry))miny=heightcurryif((unsigned)maxy<(heightcurry))maxy=heightcurryfor(i=i<linesi){currx=opcount=*cptwhile(opcount>){currx=*cptif((WORD)minx>currx)minx=currxif((WORD)maxx<currx)maxx=currxt=lpDib(Ulong)curry*(Ulong)bytewidthcurrxt=tempcurrxpsize=*cptif(psize<){psize=psizememset(t,*cpt,psize)currx=psizePageno深入编程内幕VisualCt=psize}else{memcpy(t,cpt,psize)t=psizecpt=psizecurrx=psize}if(minx>currx)minx=currxif(maxx<currx)maxx=currxopcount}currytemp=bytewidthif(miny>(heightcurry))miny=heightcurryif(maxy<(heightcurry))maxy=heightcurry}GlobalUnlock(hData)rcChangex=minxrcChangey=minyrcChangewidth=maxxminxrcChangeheight=maxyminyreturn}voidFLCW::DecodeBlack(){DWORDs=GlobalSize(hData)LPSTRp=(LPSTR)GlobalLock(hData)memset(p,,s)GlobalUnlock(hData)rcChangex=rcChangey=rcChangewidth=widthrcChangeheight=height}voidFLCW::DecodeCopy(LPSTRBody){shortbytewidthLPSTRlpDibLPSTRtWORDilpDib=(LPSTR)GlobalLock(hData)if(!lpDib)returnbytewidth=WIDTHBYTES(width*)t=lpDibt=t(DWORD)(height)*bytewidthfor(i=i<heighti){Pageno深入编程内幕VisualCmemcpy(t,Body,bytewidth)t=bytewidthBody=bytewidth}GlobalUnlock(hData)rcChangex=rcChangey=rcChangewidth=widthrcChangeheight=heightreturn}intFLCW::Open(LPCSTRlpszFile,PALETTE*p){func::readFlicHeadFLICHEADflicHeadlongoframelongdibSizeif(hFile)lclose(hFile)hFile=lopen(lpszFile,OFREAD)if(hFile==HFILEERROR)returnif(hread(hFile,(LPSTR)flicHead,sizeof(FLICHEAD))!=sizeof(FLICHEAD)){lclose(hFile)returnFALSEFLCERRREADHEAD}if(flicHeadtype!=FLCTYPE){lclose(hFile)returnFALSEFLCERRNOTFLC}width=flicHeadwidthheight=flicHeadheightsize=flicHeadsizeflicHeadoframeframes=flicHeadframesspeed=flicHeadspeedloops=currframe=currloop=pal=pflags=nFlagoframe=flicHeadoframeoframe=flicHeadoframefStatus=FLCNOTREADYPageno深入编程内幕VisualCdibSize=(LONG)(WIDTHBYTES(width*)*(LONG)height)if(hData)GlobalFree(hData)hData=GlobalAlloc(GHND,dibSize)if(!hData)returnFLCERRNOMEMORYlpInfoHead>biWidth=widthlpInfoHead>biHeight=heightlpInfoHead>biSizeImage=dibSizellseek(hFile,oframe,)returnTRUE}BOOLFLCW::CloseFlc(){lclose(hFile)returnTRUE}voidFLCW::PlayFlcAFrame(){HDChdccurrframedwNextTime=speedGetTickCount()if(ReadFrame()==SUCCESSFUL){hdc=GetDC(hPlayWnd)if(pal)pal>SetPal(hdc)elseSetPal(hdc)Show(hdc,xOrgrcChangex,yOrgrcChangey,rcChangewidth,rcChangeheight,rcChangex,rcChangey,rcChangewidth,rcChangeheight)if(pal)pal>ResetPal(hdc)elseResetPal(hdc)ReleaseDC(hPlayWnd,hdc)}if(currframe>frames){currframe=llseek(hFile,oframe,)currloop}return}shortFLCW::ReadFrame()Pageno深入编程内幕VisualC{HGLOBALhBodyLPSTRlpBodyLPSTRlpBufWORDnChunkNumberWORDiCHUNKHEADChunkHeadWORDtypelonglilongsizeFRAMEHEADFrameHeadif(hread(hFile,FrameHead,sizeof(FRAMEHEAD))!=sizeof(FRAMEHEAD))returnFLCERRREADFRAMEif(FrameHeadtype!=FRAMETYPE)returnFLCERRREADFRAMEnChunkNumber=FrameHeadchunksfor(i=i<nChunkNumberi){{if(hread(hFile,ChunkHead,sizeof(CHUNKHEAD))!=sizeof(CHUNKHEAD)){returnFLCERRREADFRAME}type=ChunkHeadtypesize=ChunkHeadsizesizeof(CHUNKHEAD)#ifdefMNCDROMdwReadSize=size#endif}if(type==LITERAL)size=if(size){LPSTRlpTemphBody=GlobalAlloc(GMEMMOVEABLE,size)lpBody=(LPSTR)GlobalLock(hBody)lpTemp=lpBody{if(hread(hFile,(LPSTR)lpBody,size)!=size){GlobalUnlock(hBody)GlobalFree(hBody)returnFLCERRREADCHUNK}}}switch(type){caseCOLOR:,FLICOLORDecodeColor(lpBody)if(nChunkNumber==)memset(rcChange,,sizeof(RECT))breakPageno深入编程内幕VisualCcaseDELTAFLC:,FLIWORLDLCDecodeDeltaFlc(lpBody)breakcaseDELTAFLI:,FLILCDecodeDeltaFli(lpBody)breakcaseBLACK:,FLIBALCKDecodeBlack()breakcaseBYTERUN:,FLIBRUNDecodeBRun(lpBody)breakcaseLITERAL:,FLICOPYDecodeCopy(lpBody)breakcasePSTAMP:,FLIPREVIEWbreak}GlobalUnlock(hBody)GlobalFree(hBody)}if(nChunkNumber==){rcChangex=rcChangey=rcChangewidth=rcChangeheight=}returnSUCCESSFUL}voidFLCW::PlayFlc(HWNDhwnd,WORDxorg,WORDyorg,WORDwmnotify){wmNotify=wmnotifyxOrg=xorgyOrg=yorghPlayWnd=hwndif(fStatus!=FLCPLAYING){fStatus=FLCPLAYINGStartFrame=currframedwNextTime=GetTickCount()}return}voidFLCW::StopFlc(){currframe=Pageno深入编程内幕VisualCllseek(hFile,oframe,)fStatus=FLCSTOPPEDPostMessage(hPlayWnd,wmNotify,FLCSTOPPED,MAKELONG(currframe,))}voidFLCW::PauseFlc(){if(fStatus!=FLCPAUSEDfStatus!=FLCNOTREADY){fStatus=FLCPAUSEDPostMessage(hPlayWnd,wmNotify,FLCPAUSED,MAKELONG(currframe,))}return}BOOLFLCW::ShowFlc(HDChdc){if(hPal==)returnFALSEif(hData==)returnFALSESetPal(hdc)Show(hdc,xOrg,yOrg)ResetPal(hdc)returnTRUE}shortFLCW::QueryFlc(){returnfStatus}WORDFLCW::GetTotalFrame(){returnframes}intFLCW::Loop(WORDwLoops){intLastloop=loopsif(wLoops>=)loops=wLoopsreturnLastloop}WORDFLCW::GetCurFrame(){returncurrframe}Pageno深入编程内幕VisualCfloatFLCW::Speed(floatfps){floatoldfps=(float)(speed)if(fps>)speed=(DWORD)(fps)returnoldfps}BOOLFLCW::FlcIdle(){if(GetCapture())returnTRUEif(fStatus==FLCPLAYING){if(GetTickCount()>=dwNextTime)PlayFlcAFrame()if(currloop>=loops){currloop=fStatus=FLCSTOPPEDPostMessage(hPlayWnd,wmNotify,fStatus,currframe)}}returnFALSE}程序员调用FLC流程用Open(LPCSTRlpszFile,intid)函数打开FLC文件其参数lpszFile指要打开的文件名参数id意义与类BMP中Open函数相同值为零表示使用FLC文件中内建的调色板否则忽略这个调色板当在屏幕上播放多个动画或既有动画又有图片时要用到这个参数。程序首先打开指定文件读入文件头根据文件头信息申请内存建立内存位图初始化部分参数并将文件指针指向文件起始数据区。PlayFlc(HWNDhwnd,WORDxorg,WORDyorg,WORDwmnotify)开始播放动画。在类FLCW内部用参数fStatus决定动画播放与否只要这个参数值为FLCPLAYING就播放动画我们还可以用这个参数检验当前播放状态函数QueryFlc()就是返回fStatus值。参数xorg和yorg指定播放位置假如在播放过程中想移动位置可以用这个函数重新指定。参数wmnotify指定当动画播放完成后将发送什么消息给父窗口。FlcIdle()函数是使用整个FLC类的关键。由于FLC播放是一个过程不是一转眼就能完成的事我们当然不能把整个程序的控制权交给它让它播放完后再交回来只好每隔一段时间关照它一下让它检查一下现在的状态假如时间到了可以播放下一帧了就放下一帧后返回否则直接返回。因此在程序中需要有一个定时器不停地调用FlcIdle。在FlcIdle函数中核心又是if(GetTickCount()>=dwNextTime)PlayFlcAFrame()函数这个函数的作用是检测是否到了播放下一帧的时间然后调用PlayFlcAFrame函数播放下一帧。FLC播放单帧图片机理PlayFlcAFrame()PlayFlcAFrame()的作用是逐帧播放FLC它首先调用ReadFrame()函数如读取成功则使用MYDIB类函数Show将内存位图拷贝至屏幕。ReadFrame()ReadFrame()函数是整个FLC类的核心所在它的作用是读取文件数据再将Pageno深入编程内幕VisualC数据解码至内存中。其操作过程如下:读取帧头获取当前帧内块数循环读取块头、块数据根据块类型解码数据至内存位图中。块类型FLICOLOR、FLIWORLDLC、FLILC、FLIBALCK、FLIBRUN、FLICOPY分别对应于函数DecodeColor()、DecodeDeltaFlc()、DecodeDeltaFli()、DecodeBlack()、DecodeBRun()、DecodeCopy()。实例分析在这个实例中我们要在一个窗口中同时播放三个FLC动画注意这三个动画的调色板是不同的为了协调这三个动画的颜色干脆这三个调色板一个都不要使用一个photoshop内置公用调色板这个调色板在二百五十六种颜色范围内采用每种颜色兼顾一点的办法在实际应用中要使用抖动算法才能模拟出与原来颜色乱真的效果在此自己算太累系统又不提供算法况且这个算法与我们的主题关系不大因此你看到的颜色会有些失真除非系统设置大于二百五十六色。建立一个基于对话框的应用程序playflc在类CPlayflcDlg内定义三个FLCW类flc外加一个BMP类bmpbmp类的作用是取得一个调色板我们已事先用photoshop作了一个长宽分别为比的图片当然它包含了公用调色板的信息。在对话框初始化过程函数OnInitDialog()中我们设定一个定时器并分别读入文件flc、flc、flc、bmp注意读FLC时第二个参数为(PALETTE*)bmp这就是告诉程序使用bmp的调色板。我们打算当用户按下ok键时开始播放动画因此增加一个按键响应函数OnOK()添加三个PlayFlc函数在定时器响应过程函数中填入三个FlcIdle函数。运行程序。图热点所谓热点是指在指定窗口上设定一些区域当用户在此区域上有所动作时会发生一些事情这些区域就是热点热点的作用类似于在窗口上开了若干按钮窗口当然它的功能要比button强大得多最重要的是热点可以是不规则的而button必须是矩形。热点的原理热点涉及到极复杂的坐标系统比如一个四边形需要四个坐标确定它的形状六边形就需要六个坐标确定形状若是再复杂一些比如需在世界地图上区分中国和其它国家那就不Pageno深入编程内幕VisualC是几个几十个坐标就能解决问题了。假如一个中大型的多媒体程序涉及到比较多的热点就算一个热点由四个坐标设定二十个热点就需要个坐标。若是这些热点都由手工设定那么以后的麻烦事就层出不穷。因为二个图像吻合得不好就算有一个点的误差人的肉眼也是看得出来的。有没有比较简单的办法可以减少程序员处理坐标的工作量甚至可以不理会热点坐标,还好Windows提供了处理区域的函数这就是RGN。RGN的处理过程如下:程序员向系统提供一串坐标值系统返回一个HRGN句柄以后程序员就可以使用这个句柄管理应用程序。比如说程序员可以在指定区域范围内画图而不影响到区域外面的部位。热点制作工具我们首先介绍一下热点制作工具Hospotexe这个程序的作用是由用户自定义热点再将热点写入指定文件。打开Hospotexe文件读入文件“bmp”然后在菜单上选择“定义”就可以开始定义热点了。读入的bmp文件一般是程序中要用到的背景文件在上面按键应该已经画好所以一般只要照着画好的按键轮廓描当描完后点取左键鼠标在文件菜单上选择存盘输入定义的热点名既可。然后又可以定义下一个热点。照此顺序做完所有热点退出查看上多了一个文件*dat这个dat文件就是热点配置文件。热点类ClassHot#ifndefHOTH#defineHOTH#include<windowsh>#defineMAXPOINTS#defineMAXHOTtypedefstruct{HRGNhRGNhandleofhotregioncharimageimagenamechartargethotspotnameBOOLactivetagthehotspotenableordisable}POLYHOTclassHOT{private:HRGNhOldRgnpublic:intHotNumberPOLYHOTPHotMAXHOTpublic:HOT(){memset(this,,sizeof(HOT))}~HOT(){DeleteAll()}voidDeleteAll()intOpen(LPCTSTRfilename)Pageno深入编程内幕VisualCintCurInHot(POINTpt)intEnableHot(intid,intstatue)enableordisnableonehotspotHRGNSetRgn(HDChdc,intid)voidResetRgn(HDChdc)}#endif#include"stdafxh"#include"hotspoth"intHOT::Open(LPCTSTRfilename){HFILEfhcharpolyheaderstruct{charimageimagenamechartargethotspotnameintnumnumberofhotspotsPOINTpointsMAXPOINTSpointarrayforeveryhotspot}hsrif(HotNumber)DeleteAll()fh=lopen(filename,OFREAD)lread(fh,polyheader,)polyheader=''if(strcmp(polyheader,"POLY")){lclose(fh)returnFALSE}for(HotNumber){if(lread(fh,hsr,sizeof(hsr))!=sizeof(hsr))breakPHotHotNumberhRGN=CreatePolygonRgn(hsrpoints,hsrnum,ALTERNATE)strcpy(PHotHotNumberimage,hsrimage)strcpy(PHotHotNumbertarget,hsrtarget)PHotHotNumberactive=}lclose(fh)returnHotNumber}intHOT::CurInHot(POINTpt){for(inti=i<HotNumberi)Pageno深入编程内幕VisualCif(PtInRegion(PHotihRGN,ptx,pty)PHotiactive)returnireturn}voidHOT::DeleteAll(){for(inti=i<HotNumberi)if(PHotihRGN)DeleteObject(PHotihRGN)memset(this,,sizeof(HOT))}ifstatue<returnCurrentactiveelsesetactive=statueandreturnlastactiveintHOT::EnableHot(intid,intstatue){if(id>=HotNumber||id<)returninti=PHotidactiveif(statue<)returniPHotidactive=statuereturni}HRGNHOT::SetRgn(HDChdc,intid){if(id>=HotNumber||id<)returnFALSEif(hdc,PHotidhRGN)hOldRgn=(HRGN)SelectObject(hdc,PHotidhRGN)returnhOldRgn}voidHOT::ResetRgn(HDChdc){if(hOldRgn)SelectObject(hdc,hOldRgn)hOldRgn=}热点类实现将dat文件转化为RGN并且对RGN进行操作功能。热点类由以下成员函数组成:open(LPCTSTRfilename)打开名为filename的热点文件并将热点坐标转成HRGN。CurInHot(pointpt)检查点point是否属于热点区域内假如是则返回属于哪一个热点。EnableHot(intid,intstatue)把第id个热点设置成使用或不使用状态假如Statue是负数则返回第id个热点的状态。DeletAll()删除所有热点。SetRgn()设置HDC上可使用区域便将以后对HDC的操作只限制在指定区域范围内而对范围外的区域无效。Pageno深入编程内幕VisualCResetRgn()返回设置RGN以前的状态。在程序中使用类HOT现在我们要编一个安装程序假设这个安装程序有如下功能:有四个按键分别是"install"、"uninstall"、"Run"、"Exit"其中“Run”键为禁止状态当鼠标移到任何一个按键上除禁止状态外按钮都要变成加亮状态鼠标形状变成手状当鼠标在按钮上按下时按钮形状变成按下状态鼠标形状变成按下的手状。为了编好这个程序要美工做出四张图片第一张为正常状态第二张为四个按钮全为加亮状态第三张为四个按钮全部按下状态第四张为四个按钮全部禁止状态。我们如下构造应用程序:建立一个基于对话框的应用程序HOT在类CHotDLgpt增加七个成员变量其中一个热点类HOThot四个bmp类BMPbmp分别表示四张位图二个鼠标HCURSORhcu。在对话框初始化函数中分别读入四个bmp位图一个热点资源文件“dat”两个鼠标资源。注意四个位图文件只有一个有调色板并且要用SetClassLong函数将窗口类属性设成没有缺省鼠标否则不能用SetCusor函数设置当前鼠标。然后用Classwizard添加三个成员函数OnMouseMove、OnLButtonDown、OnLButtonUp。处理OnMouseMove函数过程如下:检查鼠标是否被按下。检查鼠标移到了哪个热点内根据热点及鼠标状态确定当前应该用哪个鼠标。检查当前热点是否刚才热点如果两个相同表示状态没有发生改变那么就没有必要进行进一步的处理函数就可以返回了。若发生了改变则要区分进行进一步的处理函数就可以返回了若发生了改变则要区分两种状态:一种是从外面进入热点那么要重画当前热点假如鼠标移出热点那么要重画刚才热点。处理鼠标键按下过程如下:检查当前鼠标在哪个热点内并重画这个热点再将鼠标形状设成手指按下状。处理鼠标键放开过程如下:检查当前鼠标在哪个热点并重画这个热点并将鼠标设回手指状。编译并运行程序。图(源码网整理:wwwcodepubcom)Pagen

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/195

VC深入内幕编程

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利