tips_7 面向VisualBasic程序员的杂志 第7版.docx
WelcometotheSeventhEditionoftheVBPJTechnicalTipsSupplement!VB3,VB416/32,VB51.evel:BeginningDeletinganArrayElementConventionalwisdomsuggeststhattodeleteanarrayelement,youmustmoveupallthesubsequentelementstoclosethegap"leftbythedeleteditem.However,ifthesequenceoftheelementsisn'tsignificant(asinanunsortedarray),thisalgorithmquicklydeletesanitem:,Elementtodelete(Delete=5'NumberofelementsbeforedeletionnElements三UBound(Array)'ReplaceiDeletewithlastiteminarrayArray(IDeIete)=Array(nElements)*UseReDimPreservetoshrinkarraybyoneReDimPreserveArray(1.Bound(Array)_TonElements-1)一BasilHubbard,Hammon,Omario,CanadaVB432,VB5,VBA1.evel:IntermediateInvokehOpenWith.,DialogBoxWhenlaunchingadatafilewiththeSheIIExecuteOfunction,Windowstriestofindtheassociatedapplicationandopenthedatafilewiththisapplication.Butwhathappensifnoassociationexists?SheIIExecuteOsimplyreturnserrorde31(noassociation)andnothinghappens.Wouldn'titbeniceifyourprograminvokedthe41Openwith."dialogboxsoyoucanchsewhichapplicationyouwanttoassociatewithyourdatafile?Here'sasolution-calltheSheIIDocroutineandpassafullyqualifiedpath/filenameofthedatafileyouwishtoopen:OptionExplicitDeclareFunctionGetDesktopWindow1.ib,tuser32,()As1.ongDeclareFunctionSheIIExecute1.ib_,shell32.drAlias"SheIIExecuteA'.(ByVaIhW11dAs1.ong,ByVaIIpOperation_AsString,ByVaIIpFiIeAsString,_ByVaIIpParametersAsString,_ByVaIIpDirectoryAsString,_ByVaInShowCmdAs1.ong)As1.ongDeclareFunctionGetSystemDIrectoryUb_“kemel32"Alias"GetSystemDirectoryA"_(ByVaIIpBufferAsString,ByVaInSize_As1.ong)As1.ongPrivateConstSE-ERR-NOASSOC=31PublicSubShellDoc(strFileAsString)DimIngRetAs1.ongDimStrDirAsStringIngRet=SheHEXeCUte(GetDeSktoPWindOw,_"open”,StrFiIe,_VbNuIIString1VbNuIIString.VbNormaIFocus)IfIngRet=SE_ERR_NOASSOCThen'noassociationexistsStrDir三Space(260)IngRet=GetSyStemDireCtOry(StrDir,_1.en(StrDIr)StrDir三1.eft(strDir,IngRet)'showtheOpenwithdialogboxCallShellExecutefGetDesktopWindow,_VbNuIIString,RUND1.1.32.EXE-,Mshell32.dll,OpenAs.RunD1.1.”&_StrFite1StrDir1VbNormaIFocus)EndIfEndSub-ThomaSWeidmannjeceivedbyemailVB432,VB51.evel:BeginningSSTABVs.OptionButtonsAlthoughVB,sSSTabntrolbehavesasifeachtabpageisacontainer,itactuallyusesasinglecontainerforalltabpages.Thiscancauseunexpectedbehaviorifyouhavegroupsofoptionbuttonsondifferentpages.Clickingonanoptionbuttonononepageclearsalltheuncontainedoptionbuttonsontheother,seeminglyunrelated,pages.Solvethisproblembyaddingyourowncontainersframesorpictureboxes)foreachgroupofoptionsyouwanttobemutuallyexclusive.SteveCiSCoandROIandSOUtharaFranklin,TenneSSeeVB432,VB51.evel:BeginningChangetheAppearancePropertyofaTextBoxatRunTimeSorry,youcan'tchangetheAppearancepropertyofatextboxatruntimebutyoucanmakeitlooklikeyouhave!Ifsettonone,a3-DpictureboxhasaflatBorderStyIeproperty.Putyourtextbox(withaflatappearance)insideapicturebox(witha3-Dappearance)andchangethepicturebox'sborderstyle.UsethiscompletecodebesureyouplaceText1insidePicturel:Privatem_TextVAppearanceAs1.ongPrivateSubForm_1.oad()WithText1Picturel.Width=.WidthPicturel-Height三.Height.MoveO,OEndWithText1_Appearance1,3DEndSubPublicProperty1.et_Text1_Appearance(nAppearanceAs1.ong)WithPicturelSelectCasenAppearanceCaseO'Flat.BorderStyIe三nAppearanceCase1,3D.BorderStyIe=nAppearanceEndSelectm_Text1_Appearance三.BorderStyIeEndWitfCEndPropertyPublicPropertyGetText1_AppearanceOAs1.ongTeXt1.APPearanCe三m_Text1_AppearanceEndPropertyJimDeutch,CaZenOvia,NeWYorkVB432,VB51.evel:BeginningDealingWithNullValuesReturnedFromRDOResultsetsIfyou,rassigningthevaluesoflumnsyoureturnfromRDOqueriesintostringvariables,you,llgetan"InvaliduseofNulerrorifoneofthecolumnshasaNullvalue.Formostpurposes,dratherhavethevalueasanemptystringanyway.RatherthancodeforthateachtimeIaccessacolumn,l,vewrittenafunctioncalledCleanthatturnsNullvaluesintoemptystrings.Icallitlikethis:strMyString=Clean(rdoResultset(MMyVarCharColumnM)IalsoconvertEmptyvaluesaswell,forusewithVariants:PublicFunctionClean(ByValvarDataAsVariant)AsStringIfIsNuII(VarData)ThenClean三"ElselfIsEmpty(VarData)ThenClean=ElseClean=CStr(VarData)EndlfEndFunction-JameST.Stanley,MuncieJndianaVB3,VB416/32,VB51.evel:BeginningInSearchofSampleCodemalwayslookingforsamplecode,andthesetup1.vbpfileisanexcellentsourceofreusablecode.ItcomeswithVBandispartoftheVBsetupkit.Thecontentsvary,dependingonwhatversionofVByouhave,butyou'llfindusefulexamplesineachversion.Forexample,theVB5filesamplecodedoesthesethings: GetstheWindowsdirectory. GetstheWindowsSystemdirectory. Determinesifafileordirectoryexists. Determinesifyou'rerunningWinNTorWin95.,Determinesdrivetype. Checksdiskspace. Createsanewpath. ReadsfromanINIfile. Parsesdateandtime. Retrievestheshortpathnameofafilentaininglongfilenames.Plus,awholemoduleworkstologerrorstoanerrorfile.Thisdeiswell-commentedandcaneasilybecutandpastedintoyourproject.CaroleMCCIlISke1.Seattle,WaShingtOnVB416/32,VB51.evel:IntermediateFloatinganEditBoxTominimizethenumberofcontrolsonmyforms,IuseatextboxasafloatinginputcontrolthatIeitheroverlayontoagridorswapwithalabel.Hereismyswapsubroutine:PublicSubSW叩COntrOIS(CHideAsControl,_eShowAsControl,OptionalValue)WithcHlde.Visible三FalsecShow.Move.1.eft,.Top,.Width,.HeightEndWithIfIsMIssing(VaIue)ThenWTypeOfeShowIsTextBoxOr_TypeOfeShowIs1.abelTheneShow=cHideEndIfEISeeShow=ValueEndIfWitheShow.Visible三True.ZOrderHTypeOfeShowIsTextBoxThen.SeIStart三O.SeI1.ength=1.n(cShow)If.VisibleThen.SetFocusEndHEndIfEndWithEndSubWhenIenterthestatementwSwapControIsIbIData,txtData,"IbIDatadisappearsandtxtDataappearsinitsplacewiththevalueofIbIDataselectedandthefocussettoit.Afteryoumakeyourentry,executethestatement"SwapControlstxtData,IbIData."-CaIogeroS.Cumbo,Waterloo,Ontario,CanadaVB432,VB51.evel:IntermediateYetAnotherCenterFormRoutineIntheApril1997issueofVBPJ,youpublishedatipcalled"ConsidertheTaskbarWhenCenteringForms."YoucancenterformsmoreeasilywiththeSystemParametersInfoAPIcall:PrivateDeclareFunction_SystemParametersInfo1.ib'user32"Allas_"SystemParametersInfoAt'(ByVaIuAction_As1.ong,ByVaIuParamAs1.ong,RAsAny,_ByVaIfuWinlniAs1.ong)As1.ongPrivateTypeRECT1.eftAs1.ongTopAs1.ongRightAs1.ongBottomAs1.ongEndTypePrivateConstSPI_GETWORKAREA=48PublicSubCenterForm(frmAsForm)DimRAsRECT,IResAs1.ong,DimIWAs1.ong,IHAs1.ongIRes三SystemParameterslnfo(_Splgetworkarea,o,r,o)IfIResThenWithR.1.eft=Screen-TwipsPerPixeIX.1.eft.Top=Scrn.TwlpsPrPlxlY.Top.RightsScreensTwipsPerPixeIXw.Right.Bottom=Screen.TwipsPerPixeIY*.BottomIW=.Right-.1.eftIH=.Bottom-.Topfrm.Move.1.eft(IW-frm.Width)2,_.Top(IH-frm.Height)2EndWithEndIfEndSubNiCholaSSorokin,Sarasota,FloridaVB51.evel:IntermediateTieaMessageBoxtoDebg.AssertforAdvancedDebuggingPlacingamessageboxinanerrortrapcanprovideusefuldebugginginformation,butitdoesn'tallowyoutoreturntothesubroutineorfunctiontopokearoundandfurtherdebugthecode.Thisversionofamessageboxexpeditesdesign-timedebuggingbybreakingexecutionifthedeveloperpressesOK:PrivateFunctionMyDebugMsg(ByValaMessage_AsString)AsBoolean'Thisfunctionisusedforexpediting'developmentIfMSgBOX(aMessage,VbOKCanceI,_,0KputsyouintotheErrorTrap")=vbOKThenMyDebugMsg=FalseElseMyDebugMsg=TrueEndIfEndFunction'SamplesubPublicSubSetColor()OnErrorGoToSetCoIorError'bodyofthesubroutinewouldgohere,forceanerrortodemonstrateError5SetCoIorErrorExit:ExitSubSetCoIorError:*Inanerrortrapplacethislineinadditiontoany'othererrorhandlingcodeDebugaAssertMyDebugMsg(Err.Description&°InSetCoIoru)'othererrorhandlingcodeResumeSetCoIorErrorExitEndSub一SianMlynek,Burlington,Ontario,CanadaVB432,VB51.evel:IntermediateModernizeYourToolbar1.ookUsingonlyafewWindowsAPIcalls,youcanchangethestandardVB5toolbarintoanOffice97lk-alike.I,veimplementedtwodisplaystylesforthetoolbar.ThefirstallowsyoutochangethetoolbartoanOffice97-styletoolbar(similartotheoneusedbyVB5),andthesecondallowsyoutochangethetlbartotheInternetExplorer4.0-styletoolbar.Ifyouwanttousethesecondstyle,youmustsupplyeachbuttonwithsometextinordertoachievetheeffect.Inbothcases,thebuttonedgesareflatandonlyappearraisedwhenthemousepassesoverthebutton.Toimplementit,addthiscodetoaBASmodule:PrivateDeclareFunctionSendMessage1.ib"usr32"Alias_"SendMessageA"(ByVaIhwndAs1.ong,ByVaIWMSgAs1.ong,_ByVaIwParamAsInteger,ByVaIIParamAsAny)As1.ongPrivateDeclareFunctionFindWindowEx1.ib"usr32"Alias_"FIndWIndowExA"(ByVaIhWnd1As1.ong,ByVaIhWnd2_As1.ong,ByVaIIpsz1AsString,ByVaIIpsz2As_String)As1.ongPrivateConstWM_USER=&H400PrivateConstTB_SETSTY1.E=WM_USER56PrivateConstTB_GETSTY1.E=WM_USER+57PrivateConstTBSTY1.E_F1.AT=&H800PrivateConstTBSTY1.E_1.IST=&H1000PublicSub0ffice97Toolbar(tlbAsToolbar,_tlbToolbarStyteAs1.ong)DimIngStyIeAs1.ongDimIngResuttAs1.ongDimIngHWNDAs1.ong'FindchildwindowandgetstylebitsIngHWND=FindWindowEx(tlb.hwnd,0&,_'TlbarWindow32",VbNuIIString)IngStyIe=SendMeSSage(IngHWND,一TB_GETSTY1.E,0&,0&)'UseacasestatementtogettheeffectSelectCaseIlbTooIbarStyIeCase 1:'CreatesanOffice97liketoolbarIngStyIe=IngStyIeOrTBSTY1.E_F1.ATCase 2:'CreatesanExplorer4.0liketoolbar,'withtexttotheright'ofthepicture.Youmustprovidetext'inordertogettheeffect.IngStyIe=IngStyIeOrTBSTY1.E_F1.AT_OrTBSTY1.E_1.ISTCaseElseIngStyIe=IngStyIeOrTBSTY1.E_F1.ATEndSelect'UsetheAPIcalltochangethetoolbarIngResuIt=SendMessage(lngHWND,_TB_SETSTY1.E,0,IngStyIe)'Showtheeffectstlb.RefreshEndSubCallthisroutinewhileaformwithatoolbarisloading:PrivateSubForm_1.oad()CallOffice97Toolbar(Me.Toolbar1,2)'whatever.EndSub-Michiel1.eij,TheNetherlandsVB3,VB416/32,VB51.evel:IntermediateForceanMDIWindowRefreshIsometimeswantanMDIparentwindowtoberepainted.Forexample,ifamodaldialogisdisplayedovertheMDIformandyouclickonOK,thedialogishiddenandanoperationoccurs,whichtakesafewsecondstocomplete.Inthemeantime,remnantsofthedialogarestillvisiblebecauseWindowsdoesn'thavetimetocompletethepaintoperation,andthescreenlooksmessy.MDIformsdon'thaveaRefreshmethod,andIdon'twanttothrowaDoEventsintomycodebecauseit'sdangerous.ThiscodegivesmyMDIformaRefreshmethod:PublicSubRefresh()CallRedrawWindow(Me.hWndt0&,0&,_RDW_A1.1.CHI1.DRENOrRDWjJPDATENOW)EndSubYouneedtodeclaretheseAPInstants:PublicConstRDW_A1.1.CHI1.DREN=&H80PublicConstRDWeUPDATENOW=&H100'Note:ThedatatypeoftheIprcUpdate'parameterhasbeenchanged,fromRECTtoAnyso0&(NU1.1.)canbepassed.MfWin32ThenDeclareFunctionRedrawWincJow1.ib_,user32,t(ByVaIhwndAs1.ong,_IprcUpdateAsAny,ByVaIhrgnUpdate_As1.ong,ByVaIfuRedrawAs1.ong)As1.ong#EISelfWin16ThenDeclareFunctionRedrawWindow1.ib”User”_(ByVaIhWndAsInteger,IprcUpdateAsAny,_ByVaIhrgnUpdateAsInteger,ByVaIfuRedrawAs_Integer)AsInteger#EndifThomasWeiss,BUffaloGroveJIinoisVB51.evel:BeginningTakeAdvantageofRelatedDocumentsAreainProjectWindowIfyouusearesourcefileinyourapplication,youcanseetheRESfileappearintheprojectwindowunder"RelatedDocuments."ThisistheonlytypeoffilethatVBautomaticallyaddstothisnodeoftheprojecttree.Youcanaddanytypeoffileyouliketothisareamanually,though.FromtheProjectmenu,selectAddFile,orright-clickontheprojectwindowandselectAddFilefromthecontextmenu.Inthedialogbox,selectAllFilesforthefiletypeandchecktheAddAsRelatedDocumentoption.Addingadditionalrelatedfilesherehelpsorganizeyourprojectandgivesyouquickaccesstousefulitems,includingdesigndocuments,databases,resourcescripts,help-projectfiles,andsoon.Onceafilehasbeenadded,double-clickonitintheprojectwindowtoopenitwiththeappropriateapplication.JoeGarrick,CoonRapids,MinneSe)IaVB432,VB51.evel:AdvancedCopyDrawnPicturetoClipboardTheVBPicturecontrolcanholdseveraldifferentformatsofpictures:BMP1DIB,ICO,CUR,WMF,andothersunderVB5.Additionally,youcanusegraphicsmethodsto"draw"onthecontrol.Theonlynativemethodthatnvertstheimageonthepicturecontrol,includingthedrawngraphics,toabitmapandtransfersthebitmaptothesystemclipboardrequiresyoutouseAutoRedraw.However,thistechniquecausesproblems.ThiscodeshowsthedeclarationsandfunctionsrequiredtotransfertheimageonaVBpicturentroltothesystemclipboardasabitmap.AddthiscodetoaBASmodule,callPicToCIip,andpassthepictureboxastheonlyparameter:#APIDeclarations#BitmapPrivateDeclareFunctionBItBIt1.ibMgdl32M_(ByVaIhDestDCAs1.ong,ByVaIxAs1.ong,_ByVaIyAs1.ong,ByVaInWidthAs1.ong._ByVaInHeightAs1.ong.ByVaIhSrcDCAs_1.onglByVaIxSrcAs1.ong,ByVaIySrcAs_1.ong1ByVaIdwRopAs1.ong)As1.ongPrivateDeclareFunction_CreateCompatibIeBitmap1.ibMgdi320(ByVaIhDCAs1.ong,ByVaInWidthAs1.ong,ByVaInHeightAs1.ong)As1.ongPrivateDeclareFunctionCreateCompatibIeDC_1.ib',gdi32,(ByVaIhDCAs1.ong)As1.ongPrivateDeclareFunctionDeIeteDC1.lb_“gdi32"(ByVaIhDCAs1.ong)As1.ongPrivateDeclareFunctionGetDC1.ibMuser32M_(ByVaIhWndAs1.ong)As1.ongPrivateDeclareFunctionReIeaseDC1.ib"user32"_(ByVaIhWndAs1.ong,ByVaIhDCAs1.ong)As1.ongPrivateDeclareFunctionSeIectObject1.ib”gdi32"_(ByVaIhDCAs1.ong.ByVaIhbjectAs1.ong)As1.ong'ClipboardPrivateDeclareFunctionOpenCIipboard1.ib_Muser32M(ByVaIhWndAs1.ong)As1.ongPrivateDeclareFunctionCloseCIIpboard1.ib_uuser32()As1.ongPrivateDeclareFunctionEmptyCIipboard1.ib_*,user32,()As1.ongPrivateDeclareFunctionSetCIipboardData1.lb,user32*-(ByVaIwFormatAs1.ong,ByVaIhMemAs1.ong)As1.ong*#APIConstants#ClipboardformatsPrivateConstCF_BITMAP=2ROPPrivateConstSRCCOPY=&HCC0020PublicSubPicToClip(picAsPictureBox)DimhSourceDCAs1.ongDimhMemoryDCAs1.ongDimIWidthAs1.ongDimIHeightAs1.ongDimhBltmapAs1.ongDimhOldBitmapAs1.ong#NOTE:Errortrappinghasbeenremovedforthesakeofclarity*Withpic'DeterminebitmapsizeIWidth=.Parent.ScaleX(.ScaleWidth,_.ScaIeMode,vbPIxels)IHeight=.Parent.ScaleY(.ScaleHeight,_.ScaIeMode,vbPixels),GethBltmaploadedwithImageon,PicturecontrolhSourceDC=GetDC(.hWnd)KMemoryDC=CreateCompatibleDC(.hDC)hBltmap=CreateCompatlbleBltmap(_.hDC,!Width,!Height)hOIdBitmap=SelectObject(hMemoryDC,_hBrtmap)CallBitBlt(hMemoryDC,O,O,IWidth,_(Height,pic.hDC,O.O.SRCCOPY)hBitmap三SelectObject(hMemoryDC,_hOldBltmap)'CopytoclipboardCallOpenClipboard(.Parent.hWnd)CallEmptyCIIpboardCallSetCliPboardData(CF_BlTMAP,_hBitmap)CallCloseCIipboard'CleanupGDICallReleaseDC(.hWnd,hSourceDC)CallSelectObject(hMemoryDC,hBitmap)CallDeleteDC(hMemoryDC)EndWithEndSubTomMcCormick.Bedford.MaSSaChUSettSVB416/32,VB51.evel:BeginningEraseaVariantArrayYou'llfindtheIsArrayOfunctionhelpfulwhenyouuseVariantarraysthatyoucansetorunsetthroughyourcodeandneedtotestoften.However,onceyoudeclarethearray,IsArrayOreturnsTrue,evenifthearrayhasbeenerasedusingtheErasekeyword.Tosolvethis,resetaVariantarraybyassigningzeroornull,sotheIsArrayOfunctionreturnsthepropervalue:DimmyVarAsVariantDebug.PrintlsArray(myVar)'ReturnsFalseReDimmyVar(OTo5)Debug.PrintlsArray(myVar)'ReturnsTrueErasemyVarDebug.PrintlsArray(myVar)'ReturnsTruemyVar三ODebug.Printls