| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453 |
- {******************************************************************************}
- { CnPack For Delphi/C++Builder }
- { 中国人自己的开放源码第三方开发包 }
- { (C)Copyright 2001-2018 CnPack 开发组 }
- { ------------------------------------ }
- { }
- { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
- { 改和重新发布这一程序。 }
- { }
- { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
- { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
- { }
- { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
- { 还没有,可访问我们的网站: }
- { }
- { 网站地址:http://www.cnpack.org }
- { 电子邮件:master@cnpack.org }
- { }
- {******************************************************************************}
- {*******************************************************}
- { }
- { 停靠服务和客户控件 }
- { CnDockFormControl 单元 }
- { }
- { 版权 (C) 2002,2003 鲁小班 }
- { }
- {*******************************************************}
- unit CnDockFormControl;
- {* |<PRE>
- ================================================================================
- * 软件名称:不可视工具组件包停靠单元
- * 单元名称:停靠服务和客户控件单元
- * 单元作者:CnPack开发组 周益波(鲁小班)
- * 备 注:本单元由原作者授权CnPack开发组移植,已保留原作者版权信息
- * 开发平台:
- * 兼容测试:PWin9X/2000/XP + Delphi 5/6/7
- * 本 地 化:该单元中的字符串均符合本地化处理方式
- * 单元标识:$Id$
- * 修改记录:2007.07.13 V1.0
- * 移植单元
- ================================================================================
- |</PRE>}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.00
- 作者: 周益波
- E-mail: zhouyibo2000@sina.com
- QQ: 51571811
- 开始时间 -- 2002-01-14
- 结束时间 -- 2002-01-20
- 主要功能:
- 使窗体具有停靠功能,并且管理停靠窗体。
- 如何使用:
- 在您的主窗体上放一个TCnDockServer,在一般的工具窗体上放一个TCnDockClient
- 控件,这样,工具窗体就可以停靠到主窗体上了,可以停靠到主窗体的上下左右
- 四个方向上。同时,两个工具窗体还有相互停靠的功能,它们可以停靠成平铺型和
- 分页型的窗体。
- CnDockFormControl单元还提供了一些函数和过程来操作停靠窗体,它们的定义见下面的
- 注释。
- 在下面的代码中,还定义了两个类的引用,这样,用户就可以用自定义的类替换掉原先
- 的类,改变她们的默认特性。
- BUG--
- 1.在进行停靠操作时,停靠窗体的第一个Windows标准控件里面的内容有可能被清空,
- 2.停靠窗体的Caption有可能被清空。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.01
- 结束时间 -- 2002-02-09
- 增加了保存停靠信息和还原停靠信息的功能,
- 用户不但可以把停靠信息存储在INI文件中,还可以保存在注册表中。
- 因为在还原停靠信息的时候把桌面锁住了,所以不会产生闪烁现象。
- 增加了对停靠选项的处理函数
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.02
- 结束时间 -- 2002-02-20
- 增加了辅助控件TCnBasicDockStyle,用来改变停靠的风格,如:
- 停靠的预览效果,停靠后把手的外观等。
- 而且用户可以继承TCnBasicDockStyle,用来自定义外观,提供最大的灵活性
- 用户可以分别继承TCnDockSplitter,TCnDockPanel,TCnConjoinPanel,
- TCnTabPageControl,TCnDockZone和TCnDockTree类来改变停靠风格。
- 目前增加的停靠风格类是CnDelphiDockStyle和CnVCDockStyle,
- 她们分别表示类似Delphi和类似VC++的风格。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.03
- 结束时间 -- 2002-03-10
- 修正了0.00版中的两个BUG,程序运行的更加稳定、可靠了。
- 增加了TCnVIDDockStyle类,她是模仿Visual InderDev的停靠的风格,还没有完全完成,
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.031
- 结束时间 -- 2002-03-17
- 完成了一个很有难度的功能,就是当停靠控件是TCnConjoinDockHostForm的时候,
- 就把它上面的TCnConjoinPanel的停靠信息保存起来,然后再把它还原到DropOnControl中。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.04
- 结束时间 -- 2002-04-17
- 对程序的底层代码进行了大幅度的修改,现在,这套控件已经不再受Delphi的VCL类库的
- 限制了,我们完全可以根据自己的意愿来设置停靠的风格了。
- 其中增加了TCnDockPresident类,这个类用于当鼠标拖动控件的时候处理停靠事件。
- 又增加了TCnCustomDockControl类,这个类从TCustomControl继承过来,在她里面定义
- 了一些和停靠相关的函数和方法。后面的TCnDockPanel, TCnConjoinPanel和
- TCnTabPageControl都从TCnCustomDockControl继承。这样,只要把她们三个类中相同的
- 代码都放在TCnCustomDockControl中,就起到了代码重用的作用;还有,当检测这个类
- 的级别的时候也很方便。由于代码大幅度的修改,暂时停靠风格类还不能完全使用,
- 不过应该马上可以修改好的。关于停靠风格,以后还要增加:
- TCnWPSDockStyle(类似WPS的停靠风格),
- TCnPhotoShopDockStyle(类似PhotoShop的停靠风格),
- TCnTancentDockStyle(类似腾讯浏览器的停靠风格),
- TCnOfficeDockStyle(类似Office XP的停靠风格),
- TCnNETDockStyle(类似.NET的停靠风格),
- TCnVBDockStyle(类似Visual Basic的停靠风格),
- TCnCustomDockStyle(自定义的停靠风格)。
- ...
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.041
- 结束时间 -- 2002-04-24
- 增加了一些TCnDockClient中的属性,如:
- DirectDrag(当鼠标点击标题栏的时候是否立刻进行停靠操作),
- NCPopupMenu(当鼠标右键点击标题栏的时候是否产生弹出菜单),
- ShowHint(当鼠标移动到标题栏上的时候是否显示提示信息)。
- 又增加了一些TCnDockClient的事件,如:
- OnFormShowHint(当提示信息显示的时候触发)
- OnNCButtonDown(当鼠标在标题栏上按下的时候触发)
- OnNCButtonUp(当鼠标在标题栏上释放的时候触发)
- OnNCMouseMove(当鼠标在标题栏上移动的时候触发)
- OnNCButtonDblClk(当鼠标在标题栏上双击的时候触发)
- OnPaintDockGrabber(当重画把手的时候触发)
- OnPaintDockSplitter(当重画分割条的时候触发)
- 对TCnVCDockStyle类进行了一些改进,使它看上去更象VC的停靠风格,不过有些地方
- 还有待改进,这只是时间问题。
- 现在这套控件看上去功能越来越强大了,嘻嘻,不过我还不急着发布她,希望把她做地完美
- 无缺后再发布。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.041
- 结束时间 -- 2002-05-10
- 对TCnVCDockStyle类进行了进一步的改进,现在她的特性已经很类似于VC++的停靠风格了。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.042
- 结束时间 -- 2002-05-24
- 做了一个类似Visual C++界面的程序,用来演示TCnVCDockStyle控件,做的很酷哦.
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.050
- 结束时间 -- 2002-06-13
- 初步完成了Visual InterDev中的停靠分页的界面。而且有一个副产物TCnVIDTabPageControl
- 控件,可以作为一般的分页控件来使用。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.051
- 结束时间 -- 2002-07-03
- 基本上完成了Visual InterDev中的停靠分页的界面。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.060
- 结束时间 -- 2002-08-11
- 已经完成Visual InterDev中的停靠分页的界面,在TCnBasicDockStyle类中增加了两个
- 属性:TCnBasicConjoinServerOption和TCnBasicTabServerOption,用户可以继承这
- 两个类来实现自己的停靠风格的属性。
- 并且制作了一个帮助文件,接下去就开始测试了,准备在十月份发布这套控件。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.065
- 结束时间 -- 2002-08-20
- 找到了一些BUG,并且已经改正,继续测试,可靠性是软件的根本。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.070
- 结束时间 -- 2002-09-14
- 增加了一个很重要的功能,就是当用户关闭一个已经停靠了的窗体后,可以把这个窗体
- 在停靠服务器中的原来的位置保存下来,用户再次显示它的时候,可以还原到原来的位置
- 和大小,这个功能在Visual C++和Visual InterDev中都有,可是在Delphi中没有,
- 现在我把这个功能也加到CnDelphiDockStyle中了。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.100
- 结束时间 -- 2002-11-20
- 程序的试用版已经发布了,反响还不错,用户发现了一些Bug,现在已经修改了。
- 后来又增加了一个类似Visual InterDev的Demo,本来想增加一个双击标题栏还原的
- 功能,结果改啊改,但是最后发现改不下去了,为什么?说出来丢脸,由于刚开始做
- 这个控件的时候没有想到会做成象现在功能这么强大,程序结构没有设计好,到后来
- 发觉再改下去的话,程序就会发展到不可控制的混乱程度。最后,只能忍痛割爱,暂时
- 把双击还原的功能去掉,然后初步决定等到做完了类似VS.NET的停靠风格后就发布正式
- 版,所以这几天正忙着做类似VS.NET的停靠风格TCnVSNETDockStyle呢。大概能到12月中
- 能做完,然后还要测试,恐怕只能等到2003年1月份才能发布了。
- 等正式版发布的时候,我还要把帮助文件翻译成English,让老外也来用我们中国人的
- 控件,但是我还不知道是作为免费软件还是共享软件发布,到时候再说吧。
- 本人初步打算把DockPresident移植到C#上面,不过不知道能在什么时候开始,因为我
- 对C#也是一知半解,前一阵子学了一下,现在又放下了,唉,没时间啊。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.0110
- 结束时间 -- 2002-12-14
- 初步完成了类似VS.NET停靠风格的类TCnVSNETDockStyle,功能基本上和VS.NET停靠风格
- 差不多,不过由于Delphi的特殊性,有些地方没有办法和VS.NET停靠风格完全一样,如果
- 读者想了解VS.NET的停靠风格,请参看《VS.NET的停靠风格》。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.0112
- 结束时间 -- 2002-12-20
- 做了一个类似MSDN2002停靠风格的Demo,效果还不错,呵呵。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.0120
- 结束时间 -- 2003-1-4
- 新版本的控件已经基本上完成,现在进入测试阶段,预计春节后发布。接下去的时间主要
- 是作测试,并且修改一些细节的东东,完善帮助,补全文档等等。
- 程序的代码量已经突破25000行,如果去掉注释部分应该也有20000多行,也算是中等规模
- 的控件了,呵呵,足足花了我一年的业余时间,中途也曾经打过退堂鼓,但还是咬牙坚持
- 了下来,不管这个控件以后的命运会怎么样,能够完成她其实已经是一种胜利了,呵呵。
- 接下去的任务就是要把她养大,花点时间来推广她,如果哪位朋友觉得Dock President
- 还不错,就请向您的朋友推荐一下,在这里鲁小班先向您表示感谢了。
- +------------------------------------------------------------------------------}
- {------------------------------------------------------------------------------+
- CnDockFormControl -- 版本 0.0121
- 结束时间 -- 2003-2-16
- 改正了一个问题,那就是在WinXP下面装载停靠信息的时候,屏幕会闪烁,其实这个
- 问题在98或者2000以下是没有的,因为程序已经调用了LockWindowUpdate函数,
- 但是在XP下面不知道是什么原因,还是会出现这种闪烁的情况,后来没办法,只能在
- 装载的时候过滤掉CM_SHOWINGCHANGED消息,然后在装载的最后把应该显示但是没有
- 显示的客户窗体显示出来。
- +------------------------------------------------------------------------------}
- {$P+,S-,W-,R-,T-,H+,X+}
- interface
- {$I CnPack.inc}
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Menus,
- Extctrls, Comctrls, Stdctrls, Consts, Inifiles, CommCtrl, Registry, CnDockTree,
- CnDockSupportClass, CnDockSupportControl, CnClasses, CnConsts, CnCompConsts;
- const
- { 停靠的状态 }
- DS_Unknow = 0; // 不知道是什么状态
- DS_Docking = 1; // 停靠状态
- DS_Floating = 2; // 浮动状态
- type
- TCnSplitterSize = 0..32767;
- TCnDockBaseControl = class;
- TCnDockServer = class;
- TCnDockClient = class;
- TCnConjoinPanel = class;
- TCnTabPageControl = class;
- TCnConjoinDockHostForm = class;
- TCnTabDockHostForm = class;
- { 用来在停靠服务端中调整客户端的分割条 }
- TCnDockSplitter = class({TSplitter)//}TCustomDockPanelSplitter)
- private
- { 表示被哪个TDockServer拥有 }
- FDockServer: TCnDockServer;
- function GetSplitterIndex: Integer;
- protected
- function FindControl: TControl; override;
- property DockServer: TCnDockServer read FDockServer write FDockServer;
- public
- constructor Create(AOwner: TComponent); override;
- property SplitterIndex: Integer read GetSplitterIndex;
- end;
- // 当调用ShowDockPanel函数设置DockPanel的宽度或者高度的时候,
- // 用来指定到底是按照DockPanel本身的TBDockHeight和LRDockWidth
- // 还是按照Client的TBDockHeight和LRDockWidth来设置。
- TSetDockPanelSizeFrom = (sdfDockPanel, sdfClient);
- { 停靠服务端中用来停靠客户端的Panel }
- TCnDockPanel = class(TCnCustomDockPanel)
- private
- { 表示被哪个TDockServer拥有 }
- FDockServer: TCnDockServer;
- function GetPanelIndex: Integer;
- protected
- procedure SetDockServer(const Value: TCnDockServer); virtual;
- procedure ReloadDockedControl(const AControlName: string;
- var AControl: TControl); override;
- { ------------------------------------------------------------------------ }
- procedure CustomStartDock(var Source: TCnDragDockObject); override;
- procedure CustomGetSiteInfo(Source: TCnDragDockObject; Client: TControl; var InfluenceRect: TRect; MousePos: TPoint;
- var CanDock: Boolean); override;
- procedure CustomDockOver(Source: TCnDragDockObject; X, Y: Integer;
- State: TDragState; var Accept: Boolean); override;
- procedure CustomPositionDockRect(Source: TCnDragDockObject; X, Y: Integer); override;
- procedure CustomDockDrop(Source: TCnDragDockObject; X, Y: Integer); override;
- procedure CustomEndDock(Target: TObject; X, Y: Integer); override;
- function CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl; Client: TControl): Boolean; override;
- { ------------------------------------------------------------------------ }
- function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
- { ------------------------------------------------------------------------ }
- procedure Resize; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
- { 显示停靠的窗体 }
- procedure ShowDockPanel(MakeVisible: Boolean; Client: TControl;
- PanelSizeFrom: TSetDockPanelSizeFrom = sdfClient); virtual;
- procedure ResetPosition;
- property PanelIndex: Integer read GetPanelIndex;
- property DockServer: TCnDockServer read FDockServer write SetDockServer;
- end;
- TCnAdvDockPanel = class(TCnDockPanel)
- private
- procedure CMUnDockClient(var Message: TCMUnDockClient); message CM_UNDOCKCLIENT;
- protected
- procedure CustomDockDrop(Source: TCnDragDockObject; X, Y: Integer); override;
- function CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl; Client: TControl): Boolean; override;
- { ------------------------------------------------------------------------ }
- function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
- public
- procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
- end;
- TCnDockPanelClass = class of TCnDockPanel;
- TCnDockSplitterClass = class of TCnDockSplitter;
- TCnConjoinPanelClass = class of TCnConjoinPanel;
- TCnTabDockClass = class of TCnTabPageControl;
- { 分割条的风格 }
- TCnSplitterStyle = class(TPersistent)
- private
- FSplitter: TCnDockSplitter;
- FDockServer: TCnDockServer;
- FColor: TColor;
- FCursor: TCursor;
- FParentColor: Boolean;
- FResizeStyle: TResizeStyle;
- FSize: TCnSplitterSize; // 大小,当是[左,右]时就是宽度,当是[上,下]时就是高度。
- FMinSize: TCnSplitterSize; // 距离父控件最小的位置
- procedure SetColor(const Value: TColor);
- procedure SetCursor(const Value: TCursor);
- procedure SetParentColor(const Value: Boolean);
- procedure SetResizeStyle(const Value: TResizeStyle);
- procedure SetSize(const Value: TCnSplitterSize);
- procedure SetMinSize(const Value: TCnSplitterSize);
- protected
- procedure AssignTo(Dest: TPersistent); override;
- procedure AssignToSplitter(Dest: TCnDockSplitter);
- procedure SetSplitterStyle;
- property Splitter: TCnDockSplitter read FSplitter write FSplitter;
- public
- constructor Create(ASplitter: TCnDockSplitter; ACursor: TCursor); virtual;
- procedure Assign(Source: TPersistent); override;
- published
- property Color: TColor read FColor write SetColor default clBtnFace;
- property Cursor: TCursor read FCursor write SetCursor;
- property ParentColor: Boolean read FParentColor write SetParentColor default True;
- property ResizeStyle: TResizeStyle read FResizeStyle write SetResizeStyle
- default rsPattern;
- property Size: TCnSplitterSize read FSize write SetSize default 3;
- property MinSize: TCnSplitterSize read FMinSize write SetMinSize default 30;
- end;
- TCnBasicDockStyle = class;
- { TCnBasicConjoinServerOption和TCnBasicTabServerOption共同的父类 }
- TCnBasicServerOption = class(TPersistent)
- private
- FDockStyle: TCnBasicDockStyle;
- protected
- { 重新设置和DockStyle有联系的TCnDockBaseControl的配置 }
- procedure ResetDockControlOption; virtual; abstract;
- { 重新设置ADockServer的配置 }
- procedure ResetDockServerOption(ADockServer: TCnDockServer); virtual;// abstract;
- { 重新设置ADockClient的配置 }
- procedure ResetDockClientOption(ADockClient: TCnDockClient); virtual;// abstract;
- property DockStyle: TCnBasicDockStyle read FDockStyle write FDockStyle;
- public
- constructor Create(ADockStyle: TCnBasicDockStyle); virtual;
- destructor Destroy; override;
- procedure Assign(Source: TPersistent); override;
- end;
- TGrabbersSize = 1..MaxInt;
- TSplitterWidth = 1..MaxInt;
- { 平铺服务器的选项类 }
- TCnBasicConjoinServerOption = class(TCnBasicServerOption)
- private
- FGrabbersSize: TGrabbersSize;
- FSplitterWidth: TSplitterWidth;
- protected
- procedure SetGrabbersSize(const Value: TGrabbersSize); virtual;
- procedure SetSplitterWidth(const Value: TSplitterWidth); virtual;
- { ------------------------------------------------------------------------ }
- procedure ResetDockControlOption; override;
- procedure ResetDockServerOption(ADockServer: TCnDockServer); override;
- procedure ResetDockClientOption(ADockClient: TCnDockClient); override;
- { 重新设置TCnDockPanel的属性 }
- procedure ResetDockPanel(APanel: TCnDockPanel); virtual;
- { 重新设置TCnConjoinPanel的属性 }
- procedure ResetConjoinPanel(APanel: TCnConjoinPanel); virtual;
- public
- constructor Create(ADockStyle: TCnBasicDockStyle); override;
- destructor Destroy; override;
- procedure Assign(Source: TPersistent); override;
- procedure SetGrabbersSize_WithoutChangeSystemInfo(const Value: TGrabbersSize);
- procedure SetSplitterWidth_WithoutChangeSystemInfo(const Value: TSplitterWidth);
- published
- property GrabbersSize: TGrabbersSize read FGrabbersSize write SetGrabbersSize;
- property SplitterWidth: TSplitterWidth read FSplitterWidth write SetSplitterWidth;
- end;
- { 分页服务器的选项类 }
- TCnBasicTabServerOption = class(TCnBasicServerOption)
- private
- FTabPosition: TTabPosition;
- FHotTrack: Boolean;
- protected
- procedure SetTabPosition(const Value: TTabPosition); virtual;
- procedure SetHotTrack(const Value: Boolean); virtual;
- { ------------------------------------------------------------------------ }
- procedure ResetDockControlOption; override;
- procedure ResetDockServerOption(ADockServer: TCnDockServer); override;
- procedure ResetDockClientOption(ADockClient: TCnDockClient); override;
- { 重新设置TCnTabPageControl的属性 }
- procedure ResetTabPageControl(APage: TCnTabPageControl); virtual;
- public
- constructor Create(ADockStyle: TCnBasicDockStyle); override;
- destructor Destroy; override;
- procedure Assign(Source: TPersistent); override;
- published
- property HotTrack: Boolean read FHotTrack write SetHotTrack default False;
- property TabPosition: TTabPosition read FTabPosition write SetTabPosition
- default tpTop;
- end;
- TCnBasicConjoinServerOptionClass = class of TCnBasicConjoinServerOption;
- TCnBasicTabServerOptionClass = class of TCnBasicTabServerOption;
- { 所有停靠风格的基类 }
- TCnBasicDockStyle = class(TCnComponent)
- private
- FCnDockPanelClass: TCnDockPanelClass; // TCnDockServer中四个TCnDockPanel的类的引用
- FCnDockSplitterClass: TCnDockSplitterClass;// TCnDockServer中四个TSplitter的类的引用
- FCnConjoinPanelClass: TCnConjoinPanelClass;// 平铺服务器的类的引用
- FCnTabDockClass: TCnTabDockClass; // 分页服务器的类的引用
- FCnDockPanelTreeClass: TCnDockTreeClass; // TCnDockPanel中IDockManager的类的引用
- FCnDockPanelZoneClass: TCnDockZoneClass; // TCnDockPanel中IDockManager的节点类的引用
- FCnConjoinPanelTreeClass: TCnDockTreeClass;// TCnConjoinPanel中IDockManager的类的引用
- FCnConjoinPanelZoneClass: TCnDockZoneClass;
- FCnConjoinServerOptionClass: TCnBasicConjoinServerOptionClass;
- FCnTabServerOptionClass: TCnBasicTabServerOptionClass;
- FCnConjoinServerOption: TCnBasicConjoinServerOption;
- FCnTabServerOption: TCnBasicTabServerOption;
- FParentForm: TForm; // 父窗体
- FOldWindowProc: TWndMethod;
- { 一个列表,用来存储所有引用了TCnBasicDockStyle对象的TCnDockBaseControl对象 }
- FDockBaseControlList: TList;
- function GetDockBaseControlListCount: Integer;
- function GetDockBaseControlLists(Index: Integer): TCnDockBaseControl;
- protected
- procedure GetComponentInfo(var AName, Author, Email, Comment: string); override;
- procedure FormStartDock(DockClient: TCnDockClient; var Source: TCnDragDockObject); virtual;
- procedure FormGetSiteInfo(Source: TCnDragDockObject; DockClient: TCnDockClient; Client: TControl;
- var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean); virtual;
- procedure FormDockOver(DockClient: TCnDockClient; Source: TCnDragDockObject; X, Y: Integer;
- State: TDragState; var Accept: Boolean); virtual;
- procedure FormPositionDockRect(DockClient: TCnDockClient; Source: TCnDragDockObject); virtual;
- procedure FormDockDrop(DockClient: TCnDockClient; Source: TCnDragDockObject; X, Y: Integer); virtual;
- procedure FormEndDock(DockClient: TCnDockClient; Target: TObject; X, Y: Integer); virtual;
- function FormUnDock(DockClient: TCnDockClient; NewTarget: TWinControl; Client: TControl): Boolean; virtual;
- procedure FormGetDockEdge(DockClient: TCnDockClient; Source: TCnDragDockObject;
- MousePos: TPoint; var DropAlign: TAlign); virtual;
- { ------------------------------------------------------------------------ }
- { 创建平铺停靠分割的选项类 }
- procedure CreateConjoinServerOption(var Option: TCnBasicConjoinServerOption); virtual;
- { 创建分页停靠分割的选项类 }
- procedure CreateTabServerOption(var Option: TCnBasicTabServerOption); virtual;
- { 创建平铺和分页停靠分割的选项类 }
- procedure CreateServerOption; virtual;
- { 释放平铺和分页停靠分割的选项类 }
- procedure FreeServerOption; virtual;
- { ------------------------------------------------------------------------ }
- procedure SetDockBaseControl(IsCreate: Boolean;
- DockBaseControl: TCnDockBaseControl); virtual;
- { 捕获TCnDockServer的WindowProc消息,如果要还要执行默认的消息处理就返回False,否则就返回True }
- function DockServerWindowProc(DockServer: TCnDockServer; var Message: TMessage): Boolean; virtual;
- { 捕获TCnDockClient的WindowProc消息,如果要还要执行默认的消息处理就返回False,否则就返回True }
- function DockClientWindowProc(DockClient: TCnDockClient; var Message: TMessage): Boolean; virtual;
- { 捕获父控件的WindowProc消息 }
- procedure ParentFormWindowProc(var Message: TMessage); virtual;
- { 把ADockBaseControl添加到FDockBaseControlList中,
- 如果已经存在了就不插入,反之插入到列表的结尾处 }
- procedure AddDockBaseControl(ADockBaseControl: TCnDockBaseControl); virtual;
- { 把ADockBaseControl从FDockBaseControlList中删除,
- 如果不存在了就不删除,反之删除 }
- procedure RemoveDockBaseControl(ADockBaseControl: TCnDockBaseControl); virtual;
- { ------------------------------------------------------------------------ }
- procedure SetConjoinServerOption(
- const Value: TCnBasicConjoinServerOption); virtual;
- procedure SetTabServerOption(const Value: TCnBasicTabServerOption); virtual;
- function GetConjoinServerOption: TCnBasicConjoinServerOption; virtual;
- function GetTabServerOption: TCnBasicTabServerOption; virtual;
- { 给当前的APanel的平铺的风格赋值,子类可以重载这个方法添加新的属性 }
- procedure AssignConjoinServerOption(APanel: TCnCustomDockPanel); virtual;
- { 给当前的APage的分页的风格赋值,子类可以重载这个方法添加新的属性 }
- procedure AssignTabServerOption(APage: TCnTabPageControl); virtual;
- procedure Loaded; override;
- property DockBaseControlList: TList read FDockBaseControlList;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure AfterConstruction; override;
- function CanSetEnableDocked(ADockBaseControl: TCnDockBaseControl): Boolean; virtual;
- function CanSetLeftDocked(ADockBaseControl: TCnDockBaseControl): Boolean; virtual;
- function CanSetRightDocked(ADockBaseControl: TCnDockBaseControl): Boolean; virtual;
- function CanSetTopDocked(ADockBaseControl: TCnDockBaseControl): Boolean; virtual;
- function CanSetBottomDocked(ADockBaseControl: TCnDockBaseControl): Boolean; virtual;
- function CanSetEachOtherDocked(ADockBaseControl: TCnDockBaseControl): Boolean; virtual;
- function GetControlName: string; virtual;
- function GetDockStyleVersion: string; virtual;
- { 重新设置光标的形状 }
- procedure ResetCursor(Source: TCnDragDockObject); virtual;
- { 获得DockClient参数的停靠状态 }
- function GetDockState(DockClient: TCnDockClient): Integer; virtual;
- procedure ResetDockControlConjoinOption;
- procedure ResetDockControlTabOption;
- { ------------------------------------------------------------------------ }
- procedure ShowDockForm(ADockClient: TCnDockClient); virtual;// 显示ADockClient中的ParentForm;
- procedure HideDockForm(ADockClient: TCnDockClient); virtual;// 隐藏ADockClient中的ParentForm;
- function GetDockFormVisible(ADockClient: TCnDockClient): Boolean; virtual;// 得到ADockClient中的ParentForm是否可见.
- { ------------------------------------------------------------------------ }
- property DockBaseControlListCount: Integer read GetDockBaseControlListCount;
- property DockBaseControlLists[Index: Integer]: TCnDockBaseControl read GetDockBaseControlLists;
- { 还原原先的客户的状态 }
- procedure RestoreClient(DockClient: TCnDockClient); virtual;
- { ------------------------------------------------------------------------ }
- property Version: string read GetDockStyleVersion;// 版本号
- property ControlName: string read GetControlName; // 控件名称
- { ------------------------------------------------------------------------ }
- property CnDockPanelClass: TCnDockPanelClass
- read FCnDockPanelClass write FCnDockPanelClass;
- property CnDockSplitterClass: TCnDockSplitterClass
- read FCnDockSplitterClass write FCnDockSplitterClass;
- property CnConjoinPanelClass: TCnConjoinPanelClass
- read FCnConjoinPanelClass write FCnConjoinPanelClass;
- property CnTabDockClass: TCnTabDockClass
- read FCnTabDockClass write FCnTabDockClass;
- property CnDockPanelTreeClass: TCnDockTreeClass
- read FCnDockPanelTreeClass write FCnDockPanelTreeClass;
- property CnDockPanelZoneClass: TCnDockZoneClass
- read FCnDockPanelZoneClass write FCnDockPanelZoneClass;
- property CnConjoinPanelTreeClass: TCnDockTreeClass
- read FCnConjoinPanelTreeClass write FCnConjoinPanelTreeClass;
- property CnConjoinPanelZoneClass: TCnDockZoneClass
- read FCnConjoinPanelZoneClass write FCnConjoinPanelZoneClass;
- { ------------------------------------------------------------------------ }
- property CnConjoinServerOptionClass: TCnBasicConjoinServerOptionClass
- read FCnConjoinServerOptionClass write FCnConjoinServerOptionClass;
- property CnTabServerOptionClass: TCnBasicTabServerOptionClass
- read FCnTabServerOptionClass write FCnTabServerOptionClass;
- { ------------------------------------------------------------------------ }
- property ParentForm: TForm read FParentForm write FParentForm;
- { ------------------------------------------------------------------------ }
- property ConjoinServerOption: TCnBasicConjoinServerOption
- read GetConjoinServerOption write SetConjoinServerOption;
- property TabServerOption: TCnBasicTabServerOption
- read GetTabServerOption write SetTabServerOption;
- end;
- TCnAdvDockStyle = class(TCnBasicDockStyle)
- protected
- function DockClientWindowProc(DockClient: TCnDockClient; var Message: TMessage): Boolean; override;
- end;
- { 停靠服务端和客户端共同的父类 }
- TCnDockBaseControl = class(TCnComponent)
- private
- FEnableDock, // 是否可以停靠在服务端
- FLeftDock, // 是否可以停靠在服务端的左边
- FTopDock, // 是否可以停靠在服务端的上边
- FRightDock, // 是否可以停靠在服务端的右边
- FBottomDock, // 是否可以停靠在服务端的下边
- FEachOtherDock: Boolean;// 是否可以相互停靠
- FDockStyle: TCnBasicDockStyle;
- FOldOnClose: TCloseEvent;
- FOldOnCreate: TNotifyEvent;
- FParentForm: TForm;
- FOldWindowProc: TWndMethod;
- protected
- procedure Loaded; override;
- procedure SetParentComponent(Value: TComponent); override;
- { ------------------------------------------------------------------------ }
- function CanSetEnableDocked: Boolean; virtual;
- function CanSetLeftDocked: Boolean; virtual;
- function CanSetRightDocked: Boolean; virtual;
- function CanSetTopDocked: Boolean; virtual;
- function CanSetBottomDocked: Boolean; virtual;
- function CanSetEachOtherDocked: Boolean; virtual;
- { ------------------------------------------------------------------------ }
- procedure DoFormOnClose(Sender: TObject; var Action: TCloseAction); virtual;
- procedure DoFormOnCreate(Sender: TObject); virtual;
- { ------------------------------------------------------------------------ }
- procedure SetBottomDock(const Value: Boolean); virtual;
- procedure SetEachotherDock(const Value: Boolean); virtual;
- procedure SetEnableDock(const Value: Boolean); virtual;
- procedure SetLeftDock(const Value: Boolean); virtual;
- procedure SetRightDock(const Value: Boolean); virtual;
- procedure SetTopDock(const Value: Boolean); virtual;
- procedure SetDockStyle(const Value: TCnBasicDockStyle); virtual;
- { ------------------------------------------------------------------------ }
- procedure Notification(AComponent: TComponent;
- Operation: TOperation); override;
- procedure WindowProc(var Message: TMessage); virtual;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Assign(Source: TPersistent); override;
- property ParentForm: TForm read FParentForm;
- { ------------------------------------------------------------------------ }
- // class function GetDockStyleVersion: string; virtual;
- function GetDockStyleVersion: string; virtual;
- { ------------------------------------------------------------------------ }
- property EnableDock: Boolean read FEnableDock write SetEnableDock default True;
- property LeftDock: Boolean read FLeftDock write SetLeftDock default True;
- property TopDock: Boolean read FTopDock write SetTopDock default True;
- property RightDock: Boolean read FRightDock write SetRightDock default True;
- property BottomDock: Boolean read FBottomDock write SetBottomDock default True;
- property EachOtherDock: Boolean read FEachotherDock write SetEachotherDock default True;
- { ------------------------------------------------------------------------ }
- property Version: string read GetDockStyleVersion; // 版本号
- { ------------------------------------------------------------------------ }
- property DockStyle: TCnBasicDockStyle read FDockStyle write SetDockStyle;
- end;
- TGetClientAlignSizeEvent = procedure(Align: TAlign; var Value: Integer) of object;
- TFinishSetDockPanelSizeEvent = procedure(DockPanel: TCnDockPanel) of object;
- { 停靠服务端 }
- TCnDockServer = class(TCnDockBaseControl)
- private
- FDockPanelClass: TCnDockPanelClass;
- FLeftDockPanel, // 左边的停靠面板
- FTopDockPanel, // 上边的停靠面板
- FBottomDockPanel, // 下边的停靠面板
- FRightDockPanel: TCnDockPanel; // 右边的停靠面板
- FDockSplitterClass: TCnDockSplitterClass;
- FLeftSplitter, // 左边的分割条
- FTopSplitter, // 上边的分割条
- FBottomSplitter, // 下边的分割条
- FRightSplitter: TCnDockSplitter; // 右边的分割条
- FLeftSplitterStyle, // 左边的分割条风格
- FTopSplitterStyle, // 上边的分割条风格
- FRightSplitterStyle, // 下边的分割条风格
- FBottomSplitterStyle: TCnSplitterStyle; // 右边的分割条风格
- FOnGetClientAlignSize: TGetClientAlignSizeEvent;
- FOnFinishSetDockPanelSize: TFinishSetDockPanelSizeEvent;
- procedure CreateDockPanelAndSplitter; // 创建四个停靠面板和分割条
- // procedure DestroyDockPanelAndSplitter;// 释放四个停靠面板和分割条
- procedure CreateSplitterStyle; // 创建风格条的风格
- procedure DestroySplitterStyle; // 释放风格条的风格
- { 设置分割条的风格 }
- procedure SetSplitterStyle; // 设置风格条的风格
- { 设置左边的风格条的风格 }
- procedure SetLeftSplitterStyle(const Value: TCnSplitterStyle);
- { 设置上边的风格条的风格 }
- procedure SetTopSplitterStyle(const Value: TCnSplitterStyle);
- { 设置右边的风格条的风格 }
- procedure SetRightSplitterStyle(const Value: TCnSplitterStyle);
- { 设置下边的风格条的风格 }
- procedure SetBottomSplitterStyle(const Value: TCnSplitterStyle);
- { 获得索引为Index的TCnDockPanel }
- function GetDockPanel(Index: Integer): TCnDockPanel;
- { 获得索引为Index的TCnDockSplitter }
- function GetDockSplitter(Index: Integer): TCnDockSplitter;
- procedure DoGetClientAlignControl(Align: TAlign; var Value: Integer);
- function GetDockPanelWithAlign(Index: TAlign): TCnDockPanel;
- function GetDockSplitterWithAlign(Index: TAlign): TCnDockSplitter;
- protected
- procedure GetComponentInfo(var AName, Author, Email, Comment: string); override;
- procedure Loaded; override;
- { ------------------------------------------------------------------------ }
- procedure DoFinishSetDockPanelSize(DockPanel: TCnDockPanel);
- procedure DoFloatDockClients(DockPanel: TCnDockPanel);
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- procedure SetBottomDock(const Value: Boolean); override;
- procedure SetEnableDock(const Value: Boolean); override;
- procedure SetLeftDock(const Value: Boolean); override;
- procedure SetRightDock(const Value: Boolean); override;
- procedure SetTopDock(const Value: Boolean); override;
- { ------------------------------------------------------------------------ }
- procedure WMActivate(var Message: TWMActivate);
- procedure WindowProc(var Message: TMessage); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- function GetClientAlignControl(Align: TAlign): Integer;
- property LeftDockPanel: TCnDockPanel read FLeftDockPanel;
- property RightDockPanel: TCnDockPanel read FRightDockPanel;
- property TopDockPanel: TCnDockPanel read FTopDockPanel;
- property BottomDockPanel: TCnDockPanel read FBottomDockPanel;
- property LeftSplitter: TCnDockSplitter read FLeftSplitter;
- property RightSplitter: TCnDockSplitter read FRightSplitter;
- property TopSplitter: TCnDockSplitter read FTopSplitter;
- property BottomSplitter: TCnDockSplitter read FBottomSplitter;
- property DockPanel[Index: Integer]: TCnDockPanel read GetDockPanel;
- property DockPanelWithAlign[Index: TAlign]: TCnDockPanel read GetDockPanelWithAlign;
- property DockSplitter[Index: Integer]: TCnDockSplitter read GetDockSplitter;
- property DockSplitterWithAlign[Index: TAlign]: TCnDockSplitter read GetDockSplitterWithAlign;
- property Version: string read GetDockStyleVersion; // 版本号
- published
- property LeftSplitterStyle: TCnSplitterStyle read FLeftSplitterStyle write SetLeftSplitterStyle;
- property TopSplitterStyle: TCnSplitterStyle read FTopSplitterStyle write SetTopSplitterStyle;
- property RightSplitterStyle: TCnSplitterStyle read FRightSplitterStyle write SetRightSplitterStyle;
- property BottomSplitterStyle: TCnSplitterStyle read FBottomSplitterStyle write SetBottomSplitterStyle;
- property OnGetClientAlignSize: TGetClientAlignSizeEvent
- read FOnGetClientAlignSize write FOnGetClientAlignSize;
- property OnFinishSetDockPanelSize: TFinishSetDockPanelSizeEvent
- read FOnFinishSetDockPanelSize write FOnFinishSetDockPanelSize;
- property EnableDock;
- property LeftDock;
- property TopDock;
- property RightDock;
- property BottomDock;
- property DockStyle;
- end;
- { 鼠标的位置,分别是'在浮动窗体上','在平铺服务器上','在分页服务器上' }
- TMouseStation = (msFloat, msConjoin, msTabPage);
- TNCButtonEvent = procedure(DockClient: TCnDockClient; Button: TMouseButton;
- X, Y: Smallint; HitTest: Longint; MouseStation: TMouseStation) of object;
- TNCButtonDownEvent = TNCButtonEvent;
- TNCButtonUpEvent = TNCButtonEvent;
- TNCButtonDblClkEvent = TNCButtonEvent;
- TNCMouseMoveEvent = procedure(DockClient: TCnDockClient;
- X, Y: Smallint; HitTest: Longint; MouseStation: TMouseStation) of object;
- TPaintDockEvent = procedure(Canvas: TCanvas;
- Control: TControl; const ARect: TRect) of object;
- TPaintDockGrabberEvent = TPaintDockEvent;
- TPaintDockSplitterEvent = TPaintDockEvent;
- TFormHintEvent = procedure(HTFlag: Integer; var HintStr: string; var CanShow: Boolean) of object;
- { 停靠客户端 }
- TCnDockClient = class(TCnDockBaseControl)
- private
- FConjoinPanelClass: TCnConjoinPanelClass;
- FTabDockClass: TCnTabDockClass;
- FParentVisible: Boolean; // 父窗口是否是可见的。
- FNCPopupMenu: TPopupMenu; // 当在窗体的标题栏上右击鼠标右键时,弹出的菜单。
- FDirectDrag: Boolean; // 当鼠标按下的时候是否立即进行停靠操作。
- FShowHint: Boolean; // 是否显示提示信息
- FCanFloat: Boolean; // 是否可以浮动,这个功能是应一个用户的要求添加的,
- // 为了防止程序的界面过于凌乱,有时候用户并不希望
- // 停靠的窗体浮动出来,就用这个属性来限制,如果是True,
- // 就允许浮动,否者就不允许,只能停靠到服务器上,
- // 当然在服务器之间是可以相互拖动的,默认为True.
- FRelativeServer: TCnDockServer; // 有关系的TCnDockServer的实例,这个功能也是应一个
- // 用户的要求添加的,当一个客户窗体打算停靠到服务器
- // 上面的时候,需要判断FRelativeServer和当前打算停靠
- // 的服务器是否是同一个,如果不是,就不能停靠,否者就
- // 能够停靠,默认值为nil,当这个属性是nil的时候,就说明
- // 可以停靠到所有的服务器上面.
- FDockLevel: Integer; // 停靠的级别,只有相同级别的客户窗体才可以相互停靠
- FEnableCloseBtn: Boolean; // 是否允许关闭按钮可用.
- FOnNCButtonDown: TNCButtonDownEvent;
- FOnNCButtonUp: TNCButtonUpEvent;
- FOnNCMouseMove: TNCMouseMoveEvent;
- FOnNCButtonDblClk: TNCButtonDblClkEvent;
- FOnPaintDockGrabber: TPaintDockGrabberEvent;
- FOnPaintDockSplitter: TPaintDockSplitterEvent;
- FOnFormShowHint: TFormHintEvent;
- FOnFormShow: TNotifyEvent;
- FOnFormHide: TNotifyEvent;
- FCurrentDockSite,
- FLastDockSite: TWinControl;// 上一次停靠的服务器
- FUnDockLeft, // 浮动时候的左边的位置
- FUnDockTop: Integer; // 浮动时候的右边的位置
- FVSPaneWidth: Integer; // 面板的宽度
- procedure SetParentVisible(const Value: Boolean);
- function GetLRDockWidth: Integer;
- function GetTBDockHeight: Integer;
- procedure SetLRDockWidth(const Value: Integer);
- procedure SetTBDockHeight(const Value: Integer);
- procedure SetNCPopupMenu(const Value: TPopupMenu);
- { ------------------------------------------------------------------------ }
- procedure WMNCLButtonDown(var Message: TWMNCHitMessage);
- procedure WMNCLButtonUp(var Message: TWMNCHitMessage);
- procedure WMNCLButtonDblClk(var Message: TWMNCHitMessage);
- procedure WMNCMButtonDown(var Message: TWMNCHitMessage);
- procedure WMNCMButtonUp(var Message: TWMNCHitMessage);
- procedure WMNCMButtonDblClk(var Message: TWMNCHitMessage);
- procedure WMNCRButtonDown(var Message: TWMNCHitMessage);
- procedure WMNCRButtonUp(var Message: TWMNCHitMessage);
- procedure WMNCRButtonDblClk(var Message: TWMNCHitMessage);
- procedure WMNCMouseMove(var Message: TWMNCHitMessage);
- procedure CMVisibleChanged(var Message: TMessage);
- procedure SetCurrentDockSite(const Value: TWinControl);
- procedure SetLastDockSite(const Value: TWinControl);
- procedure SetVSPaneWidth(const Value: Integer);
- procedure SetUnDockLeft(const Value: Integer);
- procedure SetUnDockTop(const Value: Integer);
- function GetDockState: Integer;
- procedure SetCanFloat(const Value: Boolean);
- procedure SetRelativeServer(const Value: TCnDockServer);
- procedure SetDockLevel(const Value: Integer);
- procedure SetEnableCloseBtn(const Value: Boolean);
- protected
- procedure GetComponentInfo(var AName, Author, Email, Comment: string); override;
- procedure Loaded; override;
- procedure DoMenuPopup(X, Y: Integer); virtual;
- { ------------------------------------------------------------------------ }
- procedure Deactivate; virtual;
- procedure Activate; virtual;
- { ------------------------------------------------------------------------ }
- procedure Notification(AComponent: TComponent;
- Operation: TOperation); override;
- { ------------------------------------------------------------------------ }
- procedure DoFloatDockClients(PanelAlign: TAlign);
- procedure DoFloatDockEachOther;
- procedure SetBottomDock(const Value: Boolean); override;
- procedure SetEachotherDock(const Value: Boolean); override;
- procedure SetEnableDock(const Value: Boolean); override;
- procedure SetLeftDock(const Value: Boolean); override;
- procedure SetRightDock(const Value: Boolean); override;
- procedure SetTopDock(const Value: Boolean); override;
- { ------------------------------------------------------------------------ }
- procedure DoFormOnClose(Sender: TObject;
- var Action: TCloseAction); override;
- { ------------------------------------------------------------------------ }
- procedure WMSize(var Message: TWMSize);
- procedure WMActivate(var Message: TWMActivate);
- // procedure WMWindowPosChanged(var Message: TWMWindowPosChanged)
- procedure WindowProc(var Message: TMessage); override;
- property RelativeServer: TCnDockServer read FRelativeServer write SetRelativeServer default nil;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- { ------------------------------------------------------------------------ }
- procedure FormStartDock(var Source: TCnDragDockObject); virtual;
- procedure FormPositionDockRect(Source: TCnDragDockObject); virtual;
- procedure FormDockOver(Source: TCnDragDockObject; X, Y: Integer;
- State: TDragState; var Accept: Boolean); virtual;
- procedure FormDockDrop(Source: TCnDragDockObject; X, Y: Integer); virtual;
- procedure FormEndDock(Target: TObject; X, Y: Integer); virtual;
- function FormUnDock(NewTarget: TWinControl; Client: TControl): Boolean; virtual;
- procedure FormGetSiteInfo(Source: TCnDragDockObject;
- Client: TControl; var InfluenceRect: TRect; MousePos: TPoint;
- var CanDock: Boolean); virtual;
- procedure FormGetDockEdge(Source: TCnDragDockObject; MousePos: TPoint; var DropAlign: TAlign); virtual;
- { ------------------------------------------------------------------------ }
- procedure Assign(Source: TPersistent); override;
- { 触发OnFormShow事件 }
- procedure MakeShowEvent;
- { 触发OnFormClose事件 }
- procedure MakeHideEvent;
- { 创建DefaultConjoinPanelClass的实例 }
- function CreateConjoinPanelClass(ConjoinHost: TForm): TCnConjoinPanel;
- { 创建DefaultTabDockClass的实例 }
- function CreateTabDockClass(TabHost: TForm): TCnTabPageControl;
- { ------------------------------------------------------------------------ }
- function CreateConjoinHostAndDockControl(Control1,
- Control2: TControl; DockType: TAlign): TCnConjoinDockHostForm; virtual;
- function CreateTabHostAndDockControl(Control1,
- Control2: TControl): TCnTabDockHostForm; virtual;
- { ------------------------------------------------------------------------ }
- procedure DoNCButtonDown(Message: TWMNCHitMessage; Button: TMouseButton;
- MouseStation: TMouseStation); virtual;
- procedure DoNCButtonUp(Message: TWMNCHitMessage; Button: TMouseButton;
- MouseStation: TMouseStation); virtual;
- procedure DoNCMouseMove(Message: TWMNCHitMessage;
- MouseStation: TMouseStation); virtual;
- procedure DoNCButtonDblClk(Message: TWMNCHitMessage; Button: TMouseButton;
- MouseStation: TMouseStation); virtual;
- { ------------------------------------------------------------------------ }
- procedure DoPaintDockGrabber(Canvas: TCanvas;
- Control: TControl; const ARect: TRect);
- procedure DoPaintDockSplitter(Canvas: TCanvas;
- Control: TControl; const ARect: TRect);
- procedure DoFormShowHint(HTFlag: Integer; var HintStr: string; var CanShow: Boolean);
- { ------------------------------------------------------------------------ }
- procedure ShowParentForm; // 显示ParentForm
- procedure HideParentForm; // 隐藏ParentForm
- { 还原所有的停靠客户 }
- procedure RestoreChild;
- { ------------------------------------------------------------------------ }
- property VSPaneWidth: Integer read FVSPaneWidth write SetVSPaneWidth;
- { ------------------------------------------------------------------------ }
- { 表示父控件的可见性 }
- property ParentVisible: Boolean read FParentVisible write SetParentVisible;
- { ------------------------------------------------------------------------ }
- { 当前的停靠服务器 }
- property CurrentDockSite: TWinControl read FCurrentDockSite write SetCurrentDockSite;
- { 当前的停靠服务器 }
- property LastDockSite: TWinControl read FLastDockSite write SetLastDockSite;
- property UnDockLeft: Integer read FUnDockLeft write SetUnDockLeft;
- property UnDockTop: Integer read FUnDockTop write SetUnDockTop;
- { 停靠客户的状态,是在浮动状态或者停靠状态,还是其他别的状态 }
- property DockState: Integer read GetDockState;
- published
- property OnFormShow: TNotifyEvent read FOnFormShow write FOnFormShow;
- property OnFormHide: TNotifyEvent read FOnFormHide write FOnFormHide;
- property OnNCButtonDown: TNCButtonDownEvent read FOnNCButtonDown write FOnNCButtonDown;
- property OnNCButtonUp: TNCButtonUpEvent read FOnNCButtonUp write FOnNCButtonUp;
- property OnNCMouseMove: TNCMouseMoveEvent read FOnNCMouseMove write FOnNCMouseMove;
- property OnNCButtonDblClk: TNCButtonDblClkEvent read FOnNCButtonDblClk write FOnNCButtonDblClk;
- property OnPaintDockGrabber: TPaintDockGrabberEvent read FOnPaintDockGrabber write FOnPaintDockGrabber;
- property OnPaintDockSplitter: TPaintDockSplitterEvent read FOnPaintDockSplitter write FOnPaintDockSplitter;
- property OnFormShowHint: TFormHintEvent read FOnFormShowHint write FOnFormShowHint;
- { ------------------------------------------------------------------------ }
- property LRDockWidth: Integer read GetLRDockWidth write SetLRDockWidth;
- property TBDockHeight: Integer read GetTBDockHeight write SetTBDockHeight;
- property NCPopupMenu: TPopupMenu read FNCPopupMenu write SetNCPopupMenu;
- property DirectDrag: Boolean read FDirectDrag write FDirectDrag;
- property ShowHint: Boolean read FShowHint write FShowHint;
- property CanFloat: Boolean read FCanFloat write SetCanFloat default True;
- property DockLevel: Integer read FDockLevel write SetDockLevel default 0;
- property EnableCloseBtn: Boolean read FEnableCloseBtn write SetEnableCloseBtn;
- property EnableDock;
- property LeftDock;
- property TopDock;
- property RightDock;
- property BottomDock;
- property EachOtherDock;
- property DockStyle;
- end;
- TCnConjoinPanel = class(TCnCustomDockPanel)
- private
- FDockClient: TCnDockClient;
- function GetParentForm: TCnConjoinDockHostForm;
- // procedure SetUnDockControl(const Value: TControl);
- procedure CMUnDockClient(var Message: TCMUnDockClient); message CM_UNDOCKCLIENT;
- protected
- procedure ReloadDockedControl(const AControlName: string;
- var AControl: TControl); override;
- { ------------------------------------------------------------------------ }
- procedure CustomStartDock(var Source: TCnDragDockObject); override;
- procedure CustomGetSiteInfo(Source: TCnDragDockObject;
- Client: TControl; var InfluenceRect: TRect; MousePos: TPoint;
- var CanDock: Boolean); override;
- procedure CustomDockOver(Source: TCnDragDockObject; X, Y: Integer;
- State: TDragState; var Accept: Boolean); override;
- procedure CustomPositionDockRect(Source: TCnDragDockObject; X, Y: Integer); override;
- procedure CustomDockDrop(Source: TCnDragDockObject; X, Y: Integer); override;
- procedure CustomEndDock(Target: TObject; X, Y: Integer); override;
- function CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl; Client: TControl): Boolean; override;
- { ------------------------------------------------------------------------ }
- procedure DoDockOver(Source: TDragDockObject; X, Y: Integer; State: TDragState;
- var Accept: Boolean); override;
- procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
- MousePos: TPoint; var CanDock: Boolean); override;
- function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
- public
- constructor Create(AOwner: TComponent); override;
- procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
- property DockClient: TCnDockClient read FDockClient write FDockClient;
- property ParentForm: TCnConjoinDockHostForm read GetParentForm;
- end;
- TCnAdvConjoinPanel = class(TCnConjoinPanel)
- private
- procedure CMUnDockClient(var Message: TCMUnDockClient); message CM_UNDOCKCLIENT;
- protected
- procedure CustomDockDrop(Source: TCnDragDockObject; X, Y: Integer); override;
- function CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl; Client: TControl): Boolean; override;
- { ------------------------------------------------------------------------ }
- function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
- public
- procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
- end;
- TCnTabPageControl = class(TCnDockPageControl)
- private
- FDockClient: TCnDockClient;
- FVersion: Integer;
- function GetParentForm: TCnTabDockHostForm;
- protected
- { ------------------------------------------------------------------------ }
- procedure AdjustClientRect(var Rect: TRect); override;
- procedure ReloadDockedControl(const AControlName: string;
- var AControl: TControl); override;
- { ------------------------------------------------------------------------ }
- procedure CustomStartDock(var Source: TCnDragDockObject); override;
- procedure CustomGetSiteInfo(Source: TCnDragDockObject; Client: TControl; var InfluenceRect: TRect; MousePos: TPoint;
- var CanDock: Boolean); override;
- procedure CustomDockOver(Source: TCnDragDockObject; X, Y: Integer;
- State: TDragState; var Accept: Boolean); override;
- procedure CustomPositionDockRect(Source: TCnDragDockObject; X, Y: Integer); override;
- procedure CustomDockDrop(Source: TCnDragDockObject; X, Y: Integer); override;
- procedure CustomEndDock(Target: TObject; X, Y: Integer); override;
- function CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl; Client: TControl): Boolean; override;
- procedure CustomGetDockEdge(Source: TCnDragDockObject; MousePos: TPoint; var DropAlign: TAlign); override;
- { ------------------------------------------------------------------------ }
- function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
- procedure LoadFromStream(Stream: TStream); virtual;
- procedure SaveToStream(Stream: TStream); virtual;
- property DockClient: TCnDockClient read FDockClient write FDockClient;
- property ParentForm: TCnTabDockHostForm read GetParentForm;
- property TabPosition;
- end;
- TCnAdvTabPageControl = class(TCnTabPageControl)
- private
- procedure CMUnDockClient(var Message: TCMUnDockClient); message CM_UNDOCKCLIENT;
- protected
- procedure CustomDockDrop(Source: TCnDragDockObject; X, Y: Integer); override;
- function CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl; Client: TControl): Boolean; override;
- { ------------------------------------------------------------------------ }
- function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
- public
- destructor Destroy; override;
- procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
- end;
- // TCnDockableForm是TCnConjoinDockHostForm和TCnTabDockHostForm共同的父类
- // 处理一些这两个类共同的事件。
- // 她上面也有一个TCnDockClient控件,也就是说她也是一个可停靠控件。
- // 和一般的放了TCnDockClient控件的窗口有一样的特性。
- TCnDockableForm = class(TForm)
- private
- FDockClient: TCnDockClient;
- FDockableControl: TWinControl;
- FUnDockControl: TControl;
- FFloatingChild: TControl;
- function GetDockableControl: TWinControl;
- procedure SetDockableControl(const Value: TWinControl);
- procedure SetUnDockControl(const Value: TControl);
- protected
- procedure DoClose(var Action: TCloseAction); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- property DockClient: TCnDockClient read FDockClient write FDockClient;
- property DockableControl: TWinControl read GetDockableControl write SetDockableControl;
- property UnDockControl: TControl read FUnDockControl write SetUnDockControl;
- property FloatingChild: TControl read FFloatingChild;
- published
- end;
- { 平铺的服务窗体 }
- TCnConjoinDockHostForm = class(TCnDockableForm)
- protected
- procedure DoClose(var Action: TCloseAction); override;
- public
- Panel: TCnConjoinPanel;
- constructor Create(AOwner: TComponent); override;
- property DockClient;
- published
- end;
- { 分页的服务窗体 }
- TCnTabDockHostForm = class(TCnDockableForm)
- public
- PageControl: TCnTabPageControl;
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- function GetActiveDockForm: TForm;
- property DockClient;
- published
- end;
- var
- { 默认的TDockServer停靠Panel是TCnDockPanel }
- DefaultDockPanelClass: TCnDockPanelClass = TCnDockPanel;
- { 默认的停靠分割条是TCnDockSplitter }
- DefaultDockSplitterClass: TCnDockSplitterClass = TCnDockSplitter;
- { 默认的平铺停靠类是TCnConjoinPanel }
- DefaultConjoinPanelClass: TCnConjoinPanelClass = TCnConjoinPanel;
- { 默认的分页停靠类是TCnTabPageControl }
- DefaultTabDockClass: TCnTabDockClass = TCnTabPageControl;
- { 默认的停靠管理器节点是TCnDockZone }
- DefaultDockZoneClass: TCnDockZoneClass = TCnDockZone;
- { 默认的停靠管理器是TCnDockTree }
- DefaultDockTreeClass: TCnDockTreeClass = TCnDockTree;
- // FCnConjoinServerOptionClass: TCnBasicConjoinServerOptionClass;
- // FCnTabServerOptionClass: TCnBasicTabServerOptionClass;
- { 显示窗体 }
- procedure ShowDockForm(DockWindow: TWinControl);
- { 隐藏窗体 }
- procedure HideDockForm(DockWindow: TControl);
- { 使在Host上的TDockClient控件触发OnShowEvent或OnHideEvent,递归调用 }
- procedure MakeDockClientEvent(Host: TControl; Visible: Boolean);
- { 获得窗体的可见性 }
- function GetFormVisible(DockWindow: TWinControl): Boolean;
- { 设置分页的服务窗体中的PageControl的PopMenu }
- procedure SetDockPageControlPopupMenu(Value: TPopupMenu);
- { 设置分页的服务窗体中的PageControl的HotTrack }
- procedure SetDockPageControlHotTrack(Value: Boolean);
- { 设置分页的服务窗体的显示风格 }
- procedure SetTabDockHostBorderStyle(Value: TFormBorderStyle);
- { 设置平铺的服务窗体的显示风格 }
- procedure SetConjoinDockHostBorderStyle(Value: TFormBorderStyle);
- { 把停靠窗体的信息保存进文件 }
- procedure SaveDockTreeToFile(FileName: string);
- { 从文件里读出停靠窗体的信息 }
- procedure LoadDockTreeFromFile(FileName: string);
- { 把停靠窗体的信息保存进注册表 }
- procedure SaveDockTreeToReg(RootKey: DWORD; RegPath: string);
- { 从注册表里读出停靠窗体的信息 }
- procedure LoadDockTreeFromReg(RootKey: DWORD; RegPath: string);
- { 在窗体上查找TDockBaseControl控件 }
- function FindDockBaseControl(Client: TControl): TCnDockBaseControl;
- { 在窗体上查找TDockClient控件 }
- function FindDockClient(Client: TControl): TCnDockClient;
- { 在窗体上查找TDockServer控件 }
- function FindDockServer(Client: TControl): TCnDockServer;
- { 检查停靠服务器和客户端或者停靠客户端之间是否有停靠关系 }
- function IsDockable(Sender: TWinControl; Client: TControl;
- DropCtl: TControl = nil; DockAlign: TAlign = alNone): Boolean;
- { 计算停靠的区域 }
- function ComputeDockingRect(AControl: TControl;
- var DockRect: TRect; MousePos: TPoint): TAlign;
- { 使停靠窗体AControl从Sender中拖出来 }
- procedure DoFloat(Sender, AControl: TControl);
- { 设置控件的DockSite属性 }
- procedure SetDockSite(Control: TWinControl; SiteValue: Boolean);
- { 使DockForm控件浮动,包括它上面的DockClients }
- procedure DoFloatForm(DockForm: TControl);
- { 删除所有无用的TCnDockableForm窗体 }
- procedure FreeAllDockableForm;
- { 使应用程序的所有的窗体都浮动 }
- procedure DoFloatAllForm;
- { 得到AControl客户区中Align方向排列的子控件累加的大小到AControl边框的距离 }
- function GetClientAlignControlArea(AControl: TWinControl; Align: TAlign; Exclude: TControl = nil): Integer;
- procedure ResetDockClient(Control: TControl; NewTarget: TControl); overload;
- procedure ResetDockClient(DockClient: TCnDockClient; NewTarget: TControl); overload;
- procedure ReshowAllVisibleWindow;
- { 释放所有没有客户的服务窗体 }
- //procedure FreeAllHostOfNotClient;
- implementation
- uses Dialogs, Math, CnDockSupportProc, CnDockGlobal, CnDockInfo, CnVSNETDockStyle;//, CnVSNETDockStyle;
- var { 停靠的PageConrol的弹出菜单,默认为没有 }
- DockPageControlPopupMenu: TPopupMenu = nil;
- { 停靠的PageConrol是否高亮显示,默认为False }
- DockPageControlHotTrack: Boolean = False;
- { 分页式窗口的风格,默认为bsSizeToolWin }
- TabDockHostBorderStyle: TFormBorderStyle = bsSizeToolWin;
- { 平铺式窗体的风格,默认为bsSizeToolWin }
- ConjoinDockHostBorderStyle: TFormBorderStyle = bsSizeToolWin;
- { 操作系统是否是WinXP }
- IsWinXP: Boolean;
- type
- TCnControlAccess = class(TControl);
- TCnWinControlAccess = class(TWinControl);
- {$R CnDockableForm.DFM}
- {$R CnConjoinDockHost.DFM}
- {$R CnTabDockHost.DFM}
- { 在窗体上查找TDockBaseControl控件 }
- function FindDockBaseControl(Client: TControl): TCnDockBaseControl;
- var i: Integer;
- begin
- Result := nil;
- if Client <> nil then
- begin
- for i := 0 to Client.ComponentCount - 1 do
- if (Client.Components[i] is TCnDockBaseControl) then
- begin
- Result := TCnDockBaseControl(Client.Components[i]);
- Exit;
- end;
- end;
- end;
- { 在窗体上查找TDockServer控件 }
- function FindDockServer(Client: TControl): TCnDockServer;
- var ADockControl: TCnDockBaseControl;
- begin
- ADockControl := FindDockBaseControl(Client);
- if ADockControl is TCnDockServer then
- Result := TCnDockServer(ADockControl)
- else Result := nil;
- end;
- { 在窗体上查找TDockClient控件 }
- function FindDockClient(Client: TControl): TCnDockClient;
- var ADockControl: TCnDockBaseControl;
- begin
- ADockControl := FindDockBaseControl(Client);
- if ADockControl is TCnDockClient then
- Result := TCnDockClient(ADockControl)
- else Result := nil;
- end;
- { 检查停靠服务器和客户端或者停靠客户端之间是否有停靠关系 }
- function IsDockable(Sender: TWinControl; Client: TControl; DropCtl: TControl = nil;
- DockAlign: TAlign = alNone): Boolean;
- var ADockClient: TCnDockClient;
- i: Integer;
- SenderDockStyle,
- ClientDockStyle: TCnBasicDockStyle;
- SenderStyleName,
- ClientStyleName: string;
- // Level_1: Integer;
- Label JudgeRelation;
- begin
- ADockClient := FindDockClient(Client);
- Result := False;
- if (ADockClient <> nil) and (ADockClient.EnableDock) then
- begin
- if Sender is TCnDockPanel then
- begin
- with TCnDockPanel(Sender) do
- begin
- Result := DockServer.EnableDock and
- // ((DockAlign <> alClient) or (ADockClient.EachOtherDock and (DockAlign = alClient))) and
- (((Align = alLeft) and DockServer.LeftDock and (ADockClient.LeftDock)) or
- ((Align = alTop) and DockServer.TopDock and (ADockClient.TopDock)) or
- ((Align = alRight) and DockServer.RightDock and (ADockClient.RightDock)) or
- ((Align = alBottom) and DockServer.BottomDock and (ADockClient.BottomDock)));
- SenderDockStyle := DockServer.DockStyle;
- end;
- end else
- begin
- if (Sender <> nil) and (Sender.Parent is TCnDockableForm) then
- begin
- with TCnDockableForm(Sender.Parent).DockableControl do
- for i := 0 to DockClientCount - 1 do
- if DockClients[i] = Client then
- Exit;
- end;
- Result := ADockClient.EachOtherDock;
- if Sender <> nil then
- ADockClient := FindDockClient(Sender.Parent);
- if ADockClient <> nil then
- Result := Result and ADockClient.EachOtherDock;
- // else Result := False;
- if ADockClient <> nil then
- SenderDockStyle := ADockClient.DockStyle
- else Exit;
- end;
- ADockClient := FindDockClient(Client);
- if ADockClient <> nil then
- ClientDockStyle := ADockClient.DockStyle
- else Exit;
- if SenderDockStyle = nil then
- SenderStyleName := ''
- else SenderStyleName := SenderDockStyle.ClassName;
- if ClientDockStyle = nil then
- ClientStyleName := ''
- else ClientStyleName := ClientDockStyle.ClassName;
- Result := Result and (SenderStyleName = ClientStyleName);
- JudgeRelation:
- { if Result and (GlobalDockClient <> nil) then
- begin
- ADockClient := nil;
- Level_1 := GlobalDockClient.DockLevel;
- if DropCtl <> nil then
- ADockClient := FindDockClient(DropCtl);
- if ADockClient = nil then
- begin
- if Sender.Parent is TCnDockableForm then
- ADockClient := FindDockClient(Sender.Parent)
- else
- ADockClient := FindDockClient(Sender);
- end;
- if ADockClient <> nil then
- Result := Level_1 = ADockClient.DockLevel;
- end;}
- (* ADockClient := GlobalDockClient;
- if Result and (Sender <> nil) and (ADockClient <> nil) then
- begin
- ADockServer := FindDockServer(Sender.Parent);
- if (ADockServer <> nil) and (ADockClient.RelativeServer <> nil) then
- Result := Result and (ADockServer = ADockClient.RelativeServer)
- else
- begin
- ADockServer := ADockClient.RelativeServer;
- if Sender.Parent is TCnDockableForm then
- ADockClient := FindDockClient(Sender.Parent)
- else
- ADockClient := FindDockClient(Sender);
- if ((ADockClient <> nil) and (ADockClient.RelativeServer = nil)) or (ADockServer = nil) then
- Exit;
- if (ADockClient <> nil){ or (ADockServer <> nil) }then
- Result := Result and (ADockServer = ADockClient.RelativeServer);
- end;
- end;*)
- end;
- end;
- { 更新窗体的Caption,同时更新父窗口的Caption,递归调用 }
- procedure UpdateCaption(Source: TWinControl; Exclude: TControl);
- var i: Integer;
- Host: TCnDockableForm;
- begin
- if (Source <> nil) and (Source.Parent is TCnDockableForm) then
- begin
- Host := TCnDockableForm(Source.Parent);
- Host.Caption := '';
- { 更新本身的Caption }
- for I := 0 to Source.DockClientCount - 1 do
- begin
- if Source.DockClients[I].Visible and (Source.DockClients[I] <> Exclude) then
- Host.Caption := Host.Caption + TCustomForm(Source.DockClients[I]).Caption + gs_CnStringSplitter;
- end;
- { 更新TCnTabPageControl的标签 }
- if (Host.HostDockSite is TCnTabPageControl) then
- begin
- with TCnTabPageControl(Host.HostDockSite) do
- if (ActivePage <> nil) and (ActivePage.Controls[0] = Source) then
- ActivePage.Caption := Host.Caption;
- end;
- UpdateCaption(Host.HostDockSite, nil);
- end;
- end;
- { 使停靠窗体AControl从Sender中拖出来 }
- procedure DoFloat(Sender, AControl: TControl);
- var
- ARect: TRect;
- CH{ CaptionHeight }, BW{ BorderWidth }: Integer;
- begin
- { 获得标题栏的高度和边框的宽度 }
- BW := Cn_GetSysBorderWidth;
- CH := Cn_GetSysCaptionHeight;
- { 进行坐标转换 }
- ARect.TopLeft := Sender.ClientToScreen(Point(
- -(BW + 3), -(CH + BW + 1)));
- ARect.BottomRight := Sender.ClientToScreen(Point(
- Sender.UndockWidth - (BW + 3),
- Sender.UndockHeight - (BW + CH + 1)));
- // Cn_LockWindow(TWinControl(Sender));
- try
- { 使AControl浮动 }
- AControl.ManualFloat(ARect);
- finally
- // Cn_UnLockWindow;
- end;
- if (AControl.Left <> ARect.Left) or (AControl.Top <> ARect.Top) then
- begin
- AControl.Left := ARect.Left;
- AControl.Top := ARect.Top;
- end;
- // SetDockSite(AControl, True);
- end;
- { 计算停靠的区域 }
- function ComputeDockingRect(AControl: TControl; var DockRect: TRect; MousePos: TPoint): TAlign;
- var
- DockTopRect,
- DockLeftRect,
- DockBottomRect,
- DockRightRect,
- DockCenterRect: TRect;
- begin
- Result := alNone;
- // 划分停靠区域
- if AControl = nil then Exit;
- with AControl do
- begin
- DockLeftRect.TopLeft := Point(0, 0);
- DockLeftRect.BottomRight := Point(ClientWidth div 5, ClientHeight);
- DockTopRect.TopLeft := Point(ClientWidth div 5, 0);
- DockTopRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight div 5);
- DockRightRect.TopLeft := Point(ClientWidth div 5 * 4, 0);
- DockRightRect.BottomRight := Point(ClientWidth, ClientHeight);
- DockBottomRect.TopLeft := Point(ClientWidth div 5, ClientHeight div 5 * 4);
- DockBottomRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight);
- DockCenterRect.TopLeft := Point(ClientWidth div 5, ClientHeight div 5);
- DockCenterRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight div 5 * 4);
- // 发现鼠标在哪个停靠区域
- if PtInRect(DockLeftRect, MousePos) then
- begin
- Result := alLeft;
- DockRect := DockLeftRect;
- DockRect.Right := ClientWidth div 2;
- end else if PtInRect(DockTopRect, MousePos) then
- begin
- Result := alTop;
- DockRect := DockTopRect;
- DockRect.Left := 0;
- DockRect.Right := ClientWidth;
- DockRect.Bottom := ClientHeight div 2;
- end else if PtInRect(DockRightRect, MousePos) then
- begin
- Result := alRight;
- DockRect := DockRightRect;
- DockRect.Left := ClientWidth div 2;
- end else if PtInRect(DockBottomRect, MousePos) then
- begin
- Result := alBottom;
- DockRect := DockBottomRect;
- DockRect.Left := 0;
- DockRect.Right := ClientWidth;
- DockRect.Top := ClientHeight div 2;
- end else if PtInRect(DockCenterRect, MousePos) then
- begin
- Result := alClient;
- DockRect := DockCenterRect;
- end;
- if Result = alNone then Exit;
- // DockRect是屏幕坐标
- DockRect.TopLeft := ClientToScreen(DockRect.TopLeft);
- DockRect.BottomRight := ClientToScreen(DockRect.BottomRight);
- end;
- end;
- { 显示窗体,如果父窗口也是不可见的,就显示父窗口,递归调用 }
- procedure ShowDockForm(DockWindow: TWinControl);
- procedure ShowClient(Client, DockParent: TWinControl);
- var ADockClient: TCnDockClient;
- i: Integer;
- begin
- { 如果窗体上面还有停靠窗体,就分别调用她们的MakeDockClientEvent }
- if (DockParent is TCnDockableForm) and (Client <> nil) then
- begin
- with TCnDockableForm(DockParent).DockableControl do
- for i := 0 to DockClientCount - 1 do
- begin
- if DockClients[i] <> Client then
- MakeDockClientEvent(DockClients[i], True);
- end;
- if Client.HostDockSite is TCnCustomDockControl then
- TCnCustomDockControl(Client.HostDockSite).UpdateCaption(nil);
- end else
- begin
- { 否则就调用自己的MakeShowEvent }
- ADockClient := FindDockClient(DockParent);
- if ADockClient <> nil then
- begin
- ADockClient.DockStyle.ShowDockForm(ADockClient);
- if DockParent.CanFocus then
- DockParent.SetFocus;
- end;
- end;
- if DockParent.Parent = nil then
- SetForegroundWindow(DockParent.Handle);
- end;
- { 显示TCnDockPanel }
- function ShowDockPanel(Client: TWinControl): TWinControl;
- begin
- Result := Client;
- if Client <> nil then
- begin
- if Client.HostDockSite is TCnDockPanel then
- begin
- { 根据具体情况显示TCnDockPanel }
- TCnDockPanel(Client.HostDockSite).ShowDockPanel(True, Client, sdfDockPanel);
- Result := nil;
- end;
- end;
- end;
- { 显示分页窗体 }
- function ShowTabDockHost(Client: TWinControl): TWinControl;
- var i: Integer;
- begin
- Result := Client;
- if Client <> nil then
- begin
- ShowClient(nil, Client);
- if Client.HostDockSite is TCnTabPageControl then
- begin
- with TCnTabPageControl(Client.HostDockSite) do
- for i:=0 to PageCount - 1 do
- begin
- if Pages[i].Controls[0] = Client then
- begin
- Pages[i].Show;
- Break;
- end;
- end;
- if (Client.HostDockSite <> nil) and not (Client.HostDockSite is TCnDockPanel) then
- begin
- Result := Client.HostDockSite.Parent;
- ShowClient(Client, Result);
- if (Result <> nil) and (Result.HostDockSite is TCnTabPageControl) then
- Result := ShowTabDockHost(Result);
- end;
- end;
- end;
- end;
- { 显示平铺窗体 }
- function ShowConjoinDockHost(Client: TWinControl): TWinControl;
- begin
- Result := Client;
- if Client <> nil then
- begin
- ShowClient(nil, Client);
- if (Client.HostDockSite <> nil) and not (Client.HostDockSite is TCnDockPanel) then
- begin
- if Client.HostDockSite.Parent <> nil then
- begin
- Result := Client.HostDockSite.Parent;
- ShowClient(Client, Result);
- if (Result <> nil) and (Result.HostDockSite is TCnConjoinPanel) then
- Result := ShowConjoinDockHost(Result);
- end;
- end;
- end;
- end;
- procedure ShowPopupPanel(Client: TWinControl);
- begin
- if Client.HostDockSite is TCnVSPopupPanel then
- TCnVSPopupPanel(Client.HostDockSite).VSChannel.PopupDockForm(Client)
- else if (Client.HostDockSite <> nil) and (Client.HostDockSite.Parent <> nil) then
- begin
- if (Client.HostDockSite.Parent.HostDockSite is TCnVSPopupPanel) then
- TCnVSPopupPanel(Client.HostDockSite.Parent.HostDockSite).VSChannel.PopupDockForm(Client)
- else if (Client.HostDockSite.Parent.HostDockSite is TCnDockPanel) then
- Client.HostDockSite.Parent.HostDockSite.Invalidate;
- end;
- end;
- var TmpDockWindow: TWinControl;
- begin
- TmpDockWindow := DockWindow;
- repeat
- DockWindow := ShowTabDockHost(DockWindow);
- DockWindow := ShowConjoinDockHost(DockWindow);
- DockWindow := ShowDockPanel(DockWindow);
- until (DockWindow = nil) or (DockWindow.Parent = nil);
- ShowPopupPanel(TmpDockWindow);
- end;
- { 隐藏窗体,递归调用 }
- procedure HideDockForm(DockWindow: TControl);
- { 隐藏停靠客户窗体 }
- procedure HideDockChild(DockWindow: TControl);
- var i: Integer;
- DockClient: TCnDockClient;
- begin
- if DockWindow = nil then Exit;
- if (DockWindow is TCnDockableForm) and (DockWindow.Visible) then
- begin
- { 如果窗体上还有子窗体并且窗体是可见的,就调用子窗体的DockStyle的HideDockForm }
- with TCnDockableForm(DockWindow).DockableControl do
- for i := 0 to DockClientCount - 1 do
- HideDockChild(DockClients[i]);
- end;
- DockClient := FindDockClient(DockWindow);
- if (DockWindow is TForm) and (TForm(DockWindow).FormStyle <> fsMDIChild) then
- DockClient.DockStyle.HideDockForm(DockClient);
- end;
- { 隐藏停靠父窗体 }
- procedure HideDockParent(DockWindow: TControl);
- var
- Host: TWinControl;
- DockClient: TCnDockClient;
- begin
- if (DockWindow <> nil) and (DockWindow.HostDockSite <> nil) then
- begin
- Host := DockWindow.HostDockSite;
- if Host.VisibleDockClientCount = 0 then
- begin
- { 如果停靠窗体的父的上面的可见停靠窗体的个数为0,就应该隐藏这个停靠窗体的父 }
- if Host is TCnDockPanel then
- { 调整TCnDockPanel的大小 }
- TCnDockPanel(Host).ShowDockPanel(False, nil)
- else begin
- if Host.Parent <> nil then
- begin
- { 使停靠窗体的父隐藏,并且调用她上面的TCnDockClient的DockStyle的HideDockForm函数 }
- DockClient := FindDockClient(Host.Parent);
- DockClient.DockStyle.HideDockForm(DockClient);
- HideDockParent(Host.Parent);
- end;
- end
- end;
- end;
- end;
- procedure HidePopupPanel(Client: TWinControl);
- begin
- if Client.HostDockSite is TCnVSPopupPanel then
- TCnVSPopupPanel(Client.HostDockSite).VSChannel.HidePopupPanel(Client)
- else if (Client.HostDockSite <> nil) and (Client.HostDockSite.Parent <> nil) then
- begin
- if (Client.HostDockSite.Parent.HostDockSite is TCnVSPopupPanel) then
- TCnVSPopupPanel(Client.HostDockSite.Parent.HostDockSite).VSChannel.HidePopupPanel(Client)
- else if (Client.HostDockSite.Parent.HostDockSite is TCnDockPanel) then
- Client.HostDockSite.Parent.HostDockSite.Invalidate
- end;
- end;
- var TmpDockWindow: TWinControl;
- begin
- TmpDockWindow := TWinControl(DockWindow);
- HideDockChild(DockWindow);
- HideDockParent(DockWindow);
- if (DockWindow.HostDockSite is TCnCustomDockControl) then
- TCnCustomDockControl(DockWindow.HostDockSite).UpdateCaption(DockWindow);
- HidePopupPanel(TmpDockWindow);
- end;
- { 使在Host上的TDockClient控件触发OnShowEvent或OnHideEvent,递归调用 }
- procedure MakeDockClientEvent(Host: TControl; Visible: Boolean);
- var i: Integer;
- ADockClient: TCnDockClient;
- begin
- ADockClient := FindDockClient(Host);
- if ADockClient <> nil then
- begin
- if Visible then ADockClient.MakeShowEvent
- else ADockClient.MakeHideEvent;
- if (Host is TCnDockableForm) and (Host.Visible) then
- begin
- with TCnDockableForm(Host).DockableControl do
- for i := 0 to DockClientCount - 1 do
- MakeDockClientEvent(DockClients[i], Visible);
- end;
- end;
- end;
- { 获得窗体的可见性,递归调用 }
- function GetFormVisible(DockWindow: TWinControl): Boolean;
- var
- ADockClient: TCnDockClient;
- begin
- Result := True;
- ADockClient := FindDockClient(DockWindow);
- if ADockClient <> nil then
- begin
- Result := ADockClient.DockStyle.GetDockFormVisible(ADockClient);
- end;
- end;
- { 设置分页的服务窗体中的PageControl的PopMenu }
- procedure SetDockPageControlPopupMenu(Value: TPopupMenu);
- var i: Integer;
- begin
- DockPageControlPopupMenu := Value;
- for i := 0 to Screen.FormCount - 1 do
- begin
- if Screen.CustomForms[i] is TCnTabDockHostForm then
- TCnTabDockHostForm(Screen.CustomForms[i]).PageControl.PopupMenu := Value;
- end;
- end;
- { 设置分页的服务窗体中的PageControl的HotTrack }
- procedure SetDockPageControlHotTrack(Value: Boolean);
- var i: Integer;
- begin
- DockPageControlHotTrack := Value;
- for i := 0 to Screen.FormCount - 1 do
- begin
- if Screen.CustomForms[i] is TCnTabDockHostForm then
- TCnTabDockHostForm(Screen.CustomForms[i]).PageControl.HotTrack := Value;
- end;
- end;
- { 设置分页的服务窗体的显示风格 }
- procedure SetTabDockHostBorderStyle(Value: TFormBorderStyle);
- var i: Integer;
- begin
- TabDockHostBorderStyle := Value;
- for i := 0 to Screen.FormCount - 1 do
- begin
- if (Screen.CustomForms[i] is TCnTabDockHostForm) and (Screen.CustomForms[i].HostDockSite = nil) then
- TCnTabDockHostForm(Screen.CustomForms[i]).BorderStyle := Value;
- end;
- end;
- { 设置平铺的服务窗体的显示风格 }
- procedure SetConjoinDockHostBorderStyle(Value: TFormBorderStyle);
- var i: Integer;
- begin
- ConjoinDockHostBorderStyle := Value;
- for i := 0 to Screen.FormCount - 1 do
- begin
- if (Screen.CustomForms[i] is TCnConjoinDockHostForm) and (Screen.CustomForms[i].HostDockSite = nil) then
- TCnConjoinDockHostForm(Screen.CustomForms[i]).BorderStyle := Value;
- end;
- end;
- { 把停靠窗体的信息保存进文件 }
- procedure SaveDockTreeToFile(FileName: string);
- var CnDockInfoTree: TCnDockInfoTree;
- i: Integer;
- begin
- HideAllPopupPanel(nil);
- { 创建停靠信息树 }
- CnDockInfoTree := TCnDockInfoTree.Create(TCnDockInfoZone);
- try
- { 遍历应用程序的所有窗口 }
- for i := 0 to Screen.CustomFormCount - 1 do
- begin
- if (Screen.CustomForms[i].Parent = nil) and
- ((FindDockClient(Screen.CustomForms[i]) <> nil) or (FindDockServer(Screen.CustomForms[i]) <> nil)) then
- { 把符合条件的窗体的停靠信息保存到信息树中 }
- CnDockInfoTree.CreateZoneAndAddInfoFromApp(Screen.CustomForms[i]);
- end;
- { 打开INI文件 }
- CnDockInfoTree.DockInfoIni := TIniFile.Create(FileName);
- try
- { 把信息树中的停靠信息写到INI文件中 }
- CnDockInfoTree.WriteInfoToIni;
- finally
- { 关闭INI文件 }
- CnDockInfoTree.DockInfoIni.Free;
- end;
- finally
- { 释放停靠信息树 }
- CnDockInfoTree.Free;
- end;
- end;
- procedure ReshowAllVisibleWindow;
- var i: Integer;
- begin
- if IsWinXP then
- begin
- for i := 0 to Screen.FormCount - 1 do
- begin
- if Screen.Forms[i].Visible then
- Windows.ShowWindow(Screen.Forms[i].Handle, SW_SHOW)
- else
- Windows.ShowWindow(Screen.Forms[i].Handle, SW_HIDE);
- end;
- end;
- end;
- { 从文件里读出停靠窗体的信息 }
- procedure LoadDockTreeFromFile(FileName: string);
- var CnDockInfoTree: TCnDockInfoTree;
- Form: TForm;
- begin
- HideAllPopupPanel(nil);
- // 创建一个没有边框,大小为0的窗体,这个窗体的作用是防止屏幕闪烁
- Form := TForm.CreateNew(nil);
- Form.BorderStyle := bsNone;
- Form.BoundsRect := Rect(0,0,0,0);
- Form.Visible := True;
- Form.Name := 'A_B_C_D_E_F_G_H_I_J_K_L_M_N';
- { 创建停靠信息树 }
- CnDockInfoTree := TCnDockInfoTree.Create(TCnDockInfoZone);
- { 锁住Windows桌面 }
- Cn_LockWindow(nil);
- try
- { 打开INI文件 }
- CnDockInfoTree.DockInfoIni := TIniFile.Create(FileName);
- try
- IsLoading := True;
- { 从INI文件里读出数据并且还原停靠信息 }
- CnDockInfoTree.ReadInfoFromIni;
- finally
- { 关闭INI文件 }
- CnDockInfoTree.DockInfoIni.Free;
- IsLoading := False;
- end;
- finally
- Form.Release;
- { 解锁Windows桌面 }
- Cn_UnLockWindow;
- { 释放停靠信息树 }
- CnDockInfoTree.Free;
- end;
- ReshowAllVisibleWindow;
- end;
- { 把停靠窗体的信息保存进注册表 }
- procedure SaveDockTreeToReg(RootKey: DWORD; RegPath: string);
- var CnDockInfoTree: TCnDockInfoTree;
- i: Integer;
- begin
- HideAllPopupPanel(nil);
- { 创建停靠信息树 }
- CnDockInfoTree := TCnDockInfoTree.Create(TCnDockInfoZone);
- try
- { 遍历应用程序的所有窗口 }
- for i := 0 to Screen.CustomFormCount - 1 do
- begin
- if (Screen.CustomForms[i].Parent = nil) and
- (FindDockClient(Screen.CustomForms[i]) <> nil) then
- { 把符合条件的窗体的停靠信息保存到信息树中(接着是停靠客户) }
- CnDockInfoTree.CreateZoneAndAddInfoFromApp(Screen.CustomForms[i]);
- end;
- for i := 0 to Screen.CustomFormCount - 1 do
- begin
- if (Screen.CustomForms[i].Parent = nil) and
- (FindDockServer(Screen.CustomForms[i]) <> nil) then
- { 把符合条件的窗体的停靠信息保存到信息树中(首先是停靠服务器) }
- CnDockInfoTree.CreateZoneAndAddInfoFromApp(Screen.CustomForms[i]);
- end;
- { 打开TRegistry }
- CnDockInfoTree.DockInfoReg := TRegistry.Create;
- try
- { 把信息树中的停靠信息写到注册表中 }
- CnDockInfoTree.DockInfoReg.RootKey := RootKey;
- CnDockInfoTree.WriteInfoToReg(RegPath);
- finally
- { 关闭注册表 }
- CnDockInfoTree.DockInfoReg.Free;
- end;
- finally
- { 释放停靠信息树 }
- CnDockInfoTree.Free;
- end;
- end;
- { 从注册表里读出停靠窗体的信息 }
- procedure LoadDockTreeFromReg(RootKey: DWORD; RegPath: string);
- var CnDockInfoTree: TCnDockInfoTree;
- Form: TForm;
- begin
- HideAllPopupPanel(nil);
- // 创建一个没有边框,大小为0的窗体,这个窗体的作用是防止屏幕闪烁
- Form := TForm.CreateNew(nil);
- Form.BorderStyle := bsNone;
- Form.BoundsRect := Rect(0,0,0,0);
- Form.Visible := True;
- Form.Name := 'A_B_C_D_E_F_G_H_I_J_K_L_M_N';
- { 创建停靠信息树 }
- CnDockInfoTree := TCnDockInfoTree.Create(TCnDockInfoZone);
- { 锁住Windows桌面 }
- Cn_LockWindow(nil);
- try
- { 打开TRegistry }
- CnDockInfoTree.DockInfoReg := TRegistry.Create;
- try
- IsLoading := True;
- { 从注册表里读出数据并且还原停靠信息 }
- CnDockInfoTree.DockInfoReg.RootKey := RootKey;
- CnDockInfoTree.ReadInfoFromReg(RegPath);
- finally
- { 关闭TRegistry }
- CnDockInfoTree.DockInfoReg.Free;
- IsLoading := False;
- end;
- finally
- { 解锁Windows桌面 }
- Cn_UnLockWindow;
- { 释放停靠信息树 }
- CnDockInfoTree.Free;
- Form.Release;
- end;
- ReshowAllVisibleWindow;
- end;
- { 设置控件的DockSite属性 }
- procedure SetDockSite(Control: TWinControl; SiteValue: Boolean);
- begin
- TCnWinControlAccess(Control).DockSite := SiteValue;
- if (not (csDesigning in Control.ComponentState)) and (CnGlobalDockPresident <> nil) then
- CnGlobalDockPresident.RegisterDockSite(Control, SiteValue);
- end;
- { 使DockForm控件浮动,包括它上面的DockClients }
- procedure DoFloatForm(DockForm: TControl);
- var i, j: Integer;
- ADockServer: TCnDockServer;
- ARect: TRect;
- begin
- if (DockForm is TCnDockableForm) then
- begin
- {如果窗体是TCnDockableForm,就使她上面的停靠窗体浮动}
- with TCnDockableForm(DockForm).DockableControl do
- begin
- for i := DockClientCount - 1 downto 0 do
- begin
- DoFloatForm(DockClients[i]);
- end;
- // DockForm.Hide;
- DockForm.ManualDock(nil);
- end;
- end else
- begin
- ADockServer := FindDockServer(DockForm);
- if ADockServer <> nil then
- begin
- {如果窗体上有TCnDockServer,就使她四个上面的TCnDockPanel上面的窗体浮动}
- for i := 0 to 3 do
- begin
- for j := ADockServer.DockPanel[i].DockClientCount - 1 downto 0 do
- DoFloatForm(ADockServer.DockPanel[i].DockClients[j]);
- if ADockServer.DockPanel[i] is TCnVSNETDockPanel then
- begin
- with TCnVSNETDockPanel(ADockServer.DockPanel[i]).VSChannel do
- begin
- RemoveAllBlock;
- HidePopupPanel(ActiveDockForm);
- end;
- end;
- end;
- end else
- begin
- if DockForm.HostDockSite <> nil then
- begin
- {如果窗体是停靠状态的,就转换坐标系}
- if (DockForm.HostDockSite.Parent is TCnDockableForm) and
- (DockForm.HostDockSite.DockClientCount <= 2) then
- PostMessage(DockForm.HostDockSite.Parent.Handle, WM_CLOSE, 0, 0);
- end else ARect := DockForm.BoundsRect;
- // DockForm.Hide;
- {使窗体浮动}
- if DockForm.HostDockSite is TCnVSPopupPanel then
- begin
- TCnVSPopupPanel(DockForm.HostDockSite).VSNETDockPanel.VSChannel.RemoveDockControl(TWinControl(DockForm));
- DockForm.Dock(nil, Bounds(DockForm.Left, DockForm.Top, DockForm.UndockWidth, DockForm.UndockHeight));
- end else
- DockForm.ManualDock(nil);
- end;
- end;
- end;
- { 删除所有无用的TCnDockableForm窗体 }
- procedure FreeAllDockableForm;
- var i: Integer;
- begin
- Assert(CnGlobalDockPresident <> nil);
- for i := CnGlobalDockPresident.DockableFormList.Count - 1 downto 0 do
- begin
- if TCnDockableForm(CnGlobalDockPresident.DockableFormList[i]).DockableControl.DockClientCount = 0 then
- TCnDockableForm(CnGlobalDockPresident.DockableFormList[i]).Free;
- end;
- end;
- { 使应用程序的所有的窗体都浮动 }
- procedure DoFloatAllForm;
- var i: Integer;
- TempList: TList;
- begin
- TempList := TList.Create;
- try
- for i := 0 to Screen.CustomFormCount - 1 do
- begin
- // 遍历整个应用程序的所有窗体,然后把一般的窗体保存到TempList中
- if not (Screen.CustomForms[i] is TCnDockableForm) then
- TempList.Add(Screen.CustomForms[i]);
- end;
- {遍历应用程序的窗口,使她们浮动}
- for i := 0 to TempList.Count - 1 do
- DoFloatForm(TempList[i]);
- finally
- TempList.Free;
- end;
- FreeAllDockableForm;
- end;
- { 得到AControl客户区中Align方向排列的子控件累加的大小到AControl边框的距离 }
- function GetClientAlignControlArea(AControl: TWinControl; Align: TAlign; Exclude: TControl): Integer;
- var i: Integer;
- begin
- Result := 0;
- for i := 0 to AControl.ControlCount - 1 do
- begin
- if (AControl.Controls[i].Align = Align) and AControl.Controls[i].Visible and (AControl.Controls[i] <> Exclude) and
- not ((AControl.Controls[i] is TCnDockSplitter) or (AControl.Controls[i] is TCnDockPanel)) then
- begin
- if Align in [alLeft, alRight] then
- Inc(Result, AControl.Controls[i].Width)
- else Inc(Result, AControl.Controls[i].Height);
- end;
- end;
- end;
- {******************************************************************************}
- { 下面的函数和方法都是内部函数 }
- {******************************************************************************}
- function GetActiveControl(AForm: TCustomForm): TWinControl;
- var AControl: TWinControl;
- begin
- Result := nil;
- AControl := AForm.ActiveControl;
- while AControl <> nil do
- begin
- if (AControl.HostDockSite <> nil) then
- begin
- Result := AControl;
- Exit;
- end;
- AControl := AControl.Parent;
- end;
- end;
- function GetHostDockParent(AControl: TWinControl): TWinControl;
- begin
- Result := nil;
- while AControl <> nil do
- begin
- if (AControl.HostDockSite <> nil) then
- begin
- Result := AControl.HostDockSite;
- Exit;
- end;
- AControl := AControl.Parent;
- end;
- end;
- { 重新设置在Control上的TCnDockClint对象的属性 }
- procedure ResetDockClient(Control: TControl; NewTarget: TControl);
- begin
- ResetDockClient(FindDockClient(Control), NewTarget);
- end;
- procedure ResetDockClient(DockClient: TCnDockClient; NewTarget: TControl);
- var point: TPoint;
- begin
- if DockClient <> nil then
- begin
- if (DockClient.ParentForm.HostDockSite is TCnDockPanel) and (NewTarget is TCnDockPanel) then
- begin
- end else
- begin
- if (DockClient.LastDockSite is TCnDockPanel) and (NewTarget is TCnDockPanel) and (DockClient.LastDockSite <> NewTarget) then
- begin
- with TCnDockPanel(DockClient.LastDockSite) do
- begin
- if UseDockManager and (CnDockManager <> nil) then
- CnDockManager.RemoveControl(DockClient.ParentForm);
- end;
- end;
- if (DockClient.ParentForm.HostDockSite is TCnDockPanel) then
- begin
- // if (NewTarget is TCnTabPageControl) or (NewTarget is TCnConjoinPanel) then
- // DockClient.LastDockSite := nil
- // else
- DockClient.LastDockSite := DockClient.ParentForm.HostDockSite;
- end
- else //if not (DockClient.LastDockSite is TCnDockPanel) then
- DockClient.LastDockSite := nil;
- if DockClient.ParentForm.HostDockSite = nil then
- begin
- DockClient.UnDockLeft := DockClient.ParentForm.BoundsRect.TopLeft.x;
- DockClient.UnDockTop := DockClient.ParentForm.BoundsRect.TopLeft.y;
- end else
- begin
- point := DockClient.ParentForm.BoundsRect.TopLeft;
- point := DockClient.ParentForm.HostDockSite.ClientToScreen(point);
- DockClient.UnDockLeft := point.x;
- DockClient.UnDockTop := point.y;
- end;
- end;
- end;
- end;
- { TCnDockPanel }
- constructor TCnDockPanel.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- DoubleBuffered := True;
- BevelOuter := bvNone;
- Width := 10;
- Height := 10;
- end;
- destructor TCnDockPanel.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TCnDockPanel.CustomDockDrop(Source: TCnDragDockObject; X,
- Y: Integer);
- begin
- inherited CustomDockDrop(Source, X, Y);
- // 如果Source.Control是TCnDockableForm,就有可能被释放掉,如果它已经被释放掉了,
- // 就不要再调用ShowDockPanel函数了,不然会使TCnDockPanel宽度或者高度为0。
- if Source.Control <> nil then
- ShowDockPanel(True, Source.Control);
- end;
- procedure TCnDockPanel.CustomDockOver(Source: TCnDragDockObject; X,
- Y: Integer; State: TDragState; var Accept: Boolean);
- begin
- Accept := IsDockable(Self, Source.Control, Source.DropOnControl, Source.DropAlign);
- if Accept then
- inherited CustomDockOver(Source, X, Y, State, Accept);
- end;
- procedure TCnDockPanel.CustomEndDock(Target: TObject; X, Y: Integer);
- begin
- inherited CustomEndDock(Target, X, Y);
- end;
- procedure TCnDockPanel.CustomGetSiteInfo(Source: TCnDragDockObject; Client: TControl;
- var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
- begin
- inherited CustomGetSiteInfo(Source, Client, InfluenceRect, MousePos, CanDock);
- CanDock := IsDockable(Self, Client, Source.DropOnControl, Source.DropAlign);
- end;
- procedure TCnDockPanel.CustomPositionDockRect(Source: TCnDragDockObject; X, Y: Integer);
- var
- ARect: TRect;
- // Tmp: Integer;
- { function GetParentClientW(Control: TWinControl): Integer;
- var i: Integer;
- begin
- Result := Control.ClientWidth;
- for i := 0 to Control.ControlCount - 1 do
- begin
- if (Control.Controls[i].Align in [alLeft, alRight])
- and (Control.Controls[i] <> Self)
- and (Control.Controls[i].Visible) then
- Result := Result - Control.Controls[i].Width;
- end;
- end;
- function GetParentClientH(Control: TWinControl): Integer;
- var i: Integer;
- begin
- Result := Control.ClientHeight;
- for i := 0 to Control.ControlCount - 1 do
- begin
- if (Control.Controls[i].Align in [alTop, alBottom])
- and (Control.Controls[i] <> Self)
- and (Control.Controls[i].Visible) then
- Result := Result - Control.Controls[i].Height;
- end;
- end;
- var ParentClientW, ParentClientH: Integer;}
- begin
- inherited CustomPositionDockRect(Source, X, Y);
- if VisibleDockClientCount = 0 then
- begin
- // 记住DockRect预览停靠区域.
- if GlobalDockClient <> nil then
- begin
- case Align of
- alTop:
- begin
- ARect.TopLeft := ClientToScreen(Point(0, 0));
- ARect.BottomRight := ClientToScreen(
- Point(Width, Source.Control.TBDockHeight));
- end;
- alBottom:
- begin
- ARect.TopLeft := ClientToScreen(
- Point(0, -Source.Control.TBDockHeight));
- ARect.BottomRight := ClientToScreen(
- Point(Width, 0));
- end;
- alLeft:
- begin
- ARect.TopLeft := ClientToScreen(Point(0, 0));
- ARect.BottomRight := ClientToScreen(
- Point(Source.Control.LRDockWidth, Height));
- end;
- alRight:
- begin
- ARect.TopLeft := ClientToScreen(Point(-Source.Control.LRDockWidth, 0));
- ARect.BottomRight := ClientToScreen(Point(Width, Height));
- end;
- end;
- Source.DockRect := ARect;
- end;
- end;
- end;
- procedure TCnDockPanel.CustomStartDock(var Source: TCnDragDockObject);
- begin
- inherited CustomStartDock(Source);
- end;
- function TCnDockPanel.CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- ShowDockPanel(False, nil);
- Result := inherited CustomUnDock(Source, NewTarget, Client);
- if not (Client is TCnDockableForm) then
- SetDockSite(TForm(Client), True);
- end;
- procedure TCnDockPanel.ReloadDockedControl(const AControlName: string;
- var AControl: TControl);
- begin
- { 在整个应用程序中查找名字为AControlName的窗体 }
- AControl := Cn_FindDockFormWithName(AControlName);
- end;
- procedure TCnDockPanel.ShowDockPanel(MakeVisible: Boolean;
- Client: TControl; PanelSizeFrom: TSetDockPanelSizeFrom);
- const
- DefaultDockSize = 100; // 默认的宽度或者大小
- var
- DockHeight, DockWidth: Integer;
- //Label Loop;
- begin
- if (not MakeVisible and (VisibleDockClientCount > 1)) or
- (GlobalDockClient = nil){ or IsLoading }then Exit;
- { 设置TCnDockSplitter的属性 }
- DockServer.DockSplitter[Integer(Align) - 1].Visible := MakeVisible;
- if (MakeVisible and (Client <> nil)) then// or ((not MakeVisible) and (Client <> nil)) then
- begin
- if (Width * Height = 0) then
- begin
- { 如果宽度和高度有一个是0 }
- if (PanelSizeFrom = sdfDockPanel) or (Client = nil) then
- begin
- DockHeight := TBDockHeight;
- DockWidth := LRDockWidth;
- end else
- begin
- DockHeight := Client.TBDockHeight;
- DockWidth := Client.LRDockWidth;
- end;
- { 不能等于0,不然显示会不正常 }
- if DockHeight = 0 then
- DockHeight := DefaultDockSize;
- if DockWidth = 0 then
- DockWidth := DefaultDockSize;
- Parent.DisableAlign;
- try
- case Align of
- alTop:
- begin
- { 如果主窗体的客户区的上边有别的控件,就把这个高度计算在内 }
- Top := DockServer.GetClientAlignControl(alTop);
- Height := DockHeight;
- DockServer.TopSplitter.Top := Top + Height;
- end;
- alBottom:
- begin
- { 如果主窗体的客户区的下边有别的控件,就把这个高度计算在内 }
- Top := Parent.ClientHeight - DockServer.GetClientAlignControl(alBottom) - DockHeight + 1;
- Height := DockHeight;
- DockServer.BottomSplitter.Top := Top + DockServer.BottomSplitter.Height;
- end;
- alLeft:
- begin
- { 如果主窗体的客户区的左边有别的控件,就把这个宽度计算在内 }
- Left := DockServer.GetClientAlignControl(alLeft);
- Width := DockWidth;
- DockServer.LeftSplitter.Left := Left + Width;
- end;
- alRight:
- begin
- { 如果主窗体的客户区的右边有别的控件,就把这个宽度计算在内 }
- Width := DockWidth;
- Left := Parent.ClientWidth - DockServer.GetClientAlignControl(alRight) - DockWidth + 1;
- DockServer.RightSplitter.Left := Left - DockServer.RightSplitter.Width;
- end;
- end;
- finally
- Parent.EnableAlign;
- if UseDockManager and (CnDockManager <> nil) then
- CnDockManager.ResetBounds(True);
- end;
- DockServer.DoFinishSetDockPanelSize(Self);
- end;
- end else
- begin
- // if (Client <> nil) and (not Client.Visible) then goto Loop;
- if (PanelSizeFrom = sdfDockPanel) or (Client = nil) then
- begin
- if Height > 0 then
- TBDockHeight := Height;
- if Width > 0 then
- LRDockWidth := Width;
- end else
- begin
- if Height > 0 then
- Client.TBDockHeight := Height;
- if Width > 0 then
- Client.LRDockWidth := Width;
- end;
- if Align in [alLeft, alRight] then
- Width := 0
- else Height := 0;
- { 重新设置位置 }
- ResetPosition;
- end;
- { 条件满足的话就显示Client }
- //Loop:
- if MakeVisible and (Client <> nil) then
- begin
- if (not Client.Visible) then
- Client.Show;
- if (not TWinControl(Client).Focused) and (TWinControl(Client).CanFocus) then
- TWinControl(Client).SetFocus;
- end;
- end;
- function TCnDockPanel.DoUnDock(NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- Result := IsDockable(Self, Client);
- ShowDockPanel(False, nil);
- Result := Result and (Perform(CM_UNDOCKCLIENT, Integer(NewTarget), Integer(Client)) = 0);
- if Result then
- begin
- if not (Client is TCnDockableForm) then
- SetDockSite(TForm(Client), True);
- end;
- end;
- procedure TCnDockPanel.DockDrop(Source: TDragDockObject; X, Y: Integer);
- begin
- if Perform(CM_DOCKCLIENT, Integer(Source), Integer(SmallPoint(X, Y))) >= 0 then
- begin
- if Source.Control is TForm then
- begin
- TForm(Source.Control).ActiveControl := nil;
- { ------------------------------------------------------------------------ }
- SetDockSite(TForm(Source.Control), False);
- end;
- UpdateCaption(nil);
- end;
- ShowDockPanel(TWinControl(Source.DragTarget).VisibleDockClientCount > 0, Source.Control);
- end;
- function TCnDockPanel.GetPanelIndex: Integer;
- begin
- case Align of
- alTop: Result := 0;
- alBottom: Result := 1;
- alLeft: Result := 2;
- alRight: Result := 3;
- else
- Result := -1;
- end;
- end;
- procedure TCnDockPanel.Resize;
- begin
- inherited;
- end;
- procedure TCnDockPanel.SetDockServer(const Value: TCnDockServer);
- begin
- FDockServer := Value;
- end;
- procedure TCnDockPanel.ResetPosition;
- begin
- { 调整TCnDockPanel的位置,使它总是在服务窗体的客户区的最内层 }
- case Align of
- alLeft:
- Left := GetClientAlignControlArea(Parent, Align) + 1;
- alRight:
- Left := Parent.ClientWidth - GetClientAlignControlArea(Parent, Align) - Width - 1;
- alTop:
- Top := GetClientAlignControlArea(Parent, Align) + 1;
- alBottom:
- Top := Parent.ClientHeight - GetClientAlignControlArea(Parent, Align) - Height - 1;
- end;
- end;
- { TCnAdvDockPanel }
- //procedure TCnAdvDockPanel.CMDockClient(var Message: TCMDockClient);
- //var DockClient: TCnDockClient;
- //begin
- { with Message do
- begin
- DockClient := FindDockClient(DockSource.Control);
- if DockClient <> nil then
- begin
- if (DockClient.LastDockSite is TCnDockPanel) then
- begin
- with TCnDockPanel(DockClient.LastDockSite) do
- begin
- if UseDockManager and (CnDockManager <> nil) then
- CnDockManager.RemoveControl(DockSource.Control);
- end;
- end else
- begin
- end;
- end;
- end;}
- //end;
- procedure TCnAdvDockPanel.CMUnDockClient(var Message: TCMUnDockClient);
- var DockClient: TCnDockClient;
- begin
- if IsLoading then Exit;
- with Message do
- begin
- Result := 0;
- if UseDockManager and (CnDockManager <> nil) then
- begin
- DockClient := FindDockClient(Client);
- if (NewTarget <> nil) or
- ((Client <> nil) and (csDestroying in Client.ComponentState)) then
- begin
- if DockClient <> nil then
- DockClient.LastDockSite := nil;
- CnDockManager.RemoveControl(Client);
- end else
- begin
- if (DockClient <> nil) then
- DockClient.LastDockSite := Self;
- CnDockManager.HideControl(Client);
- end;
- end;
- end;
- end;
- procedure TCnAdvDockPanel.CustomDockDrop(Source: TCnDragDockObject; X,
- Y: Integer);
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, Source.TargetControl);
- inherited;
- end;
- function TCnAdvDockPanel.CustomUnDock(Source: TCnDragDockObject;
- NewTarget: TWinControl; Client: TControl): Boolean;
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, NewTarget);
- Result := inherited CustomUnDock(Source, NewTarget, Client)
- end;
- procedure TCnAdvDockPanel.DockDrop(Source: TDragDockObject; X, Y: Integer);
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, TControl(Source.DragTarget));
- inherited;
- end;
- function TCnAdvDockPanel.DoUnDock(NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Client, NewTarget);
- Result := inherited DoUnDock(NewTarget, Client);
- end;
- { TCnSplitterStyle }
- procedure TCnSplitterStyle.Assign(Source: TPersistent);
- begin
- if Source is TCnSplitterStyle then
- begin
- Color := TCnSplitterStyle(Source).Color;
- Cursor := TCnSplitterStyle(Source).Cursor;
- ParentColor := TCnSplitterStyle(Source).ParentColor;
- ResizeStyle := TCnSplitterStyle(Source).ResizeStyle;
- Size := TCnSplitterStyle(Source).Size;
- end;
- inherited Assign(Source);
- end;
- procedure TCnSplitterStyle.AssignTo(Dest: TPersistent);
- begin
- if Dest is TCnSplitterStyle then
- with TCnSplitterStyle(Dest) do
- begin
- Color := Self.Color;
- Cursor := Self.Cursor;
- ParentColor := Self.ParentColor;
- ResizeStyle := Self.ResizeStyle;
- Size := Self.Size;
- end
- else inherited AssignTo(Dest);
- end;
- procedure TCnSplitterStyle.AssignToSplitter(Dest: TCnDockSplitter);
- begin
- Dest.Color := Color;
- Dest.Cursor := Cursor;
- Dest.ParentColor := ParentColor;
- Dest.ResizeStyle := ResizeStyle;
- if Dest.Align in [alTop, alBottom] then
- Dest.Height := Size
- else Dest.Width := Size;
- end;
- constructor TCnSplitterStyle.Create(ASplitter: TCnDockSplitter; ACursor: TCursor);
- begin
- inherited Create;
- FSplitter := ASplitter;
- Color := clBtnFace;
- Cursor := ACursor;
- ParentColor := False;
- ResizeStyle := rsPattern;
- FSize := 3;
- FMinSize := 30;
- end;
- procedure TCnSplitterStyle.SetColor(const Value: TColor);
- begin
- if FColor <> Value then
- begin
- FColor := Value;
- ParentColor := False;
- if Assigned(FSplitter) then
- FSplitter.Color := Value;
- end;
- end;
- procedure TCnSplitterStyle.SetCursor(const Value: TCursor);
- begin
- FCursor := Value;
- if Assigned(FSplitter) then
- FSplitter.Cursor := Value;
- end;
- procedure TCnSplitterStyle.SetMinSize(const Value: TCnSplitterSize);
- begin
- FMinSize := Value;
- if Assigned(FSplitter) then
- FSplitter.MinSize := Value;
- end;
- procedure TCnSplitterStyle.SetParentColor(const Value: Boolean);
- begin
- if FParentColor <> Value then
- begin
- FParentColor := Value;
- if Value then FColor := FDockServer.ParentForm.Color;
- if Assigned(FSplitter) then
- FSplitter.ParentColor := Value;
- end;
- end;
- procedure TCnSplitterStyle.SetResizeStyle(const Value: TResizeStyle);
- begin
- FResizeStyle := Value;
- if Assigned(FSplitter) then
- FSplitter.ResizeStyle := Value;
- end;
- procedure TCnSplitterStyle.SetSize(const Value: TCnSplitterSize);
- begin
- FSize := Value;
- if Assigned(FSplitter) then
- begin
- if FSplitter.Align in [alTop, alBottom] then
- FSplitter.Height := Value
- else FSplitter.Width := Value;
- end;
- end;
- procedure TCnSplitterStyle.SetSplitterStyle;
- begin
- AssignToSplitter(FSplitter);
- end;
- { TCnDockBaseControl }
- destructor TCnDockBaseControl.Destroy;
- begin
- if not (csDesigning in ComponentState) then
- begin
- if @FOldWindowProc <> nil then
- FParentForm.WindowProc := FOldWindowProc;
- FOldWindowProc := nil;
- if Assigned(FDockStyle) and not (FDockStyle is TCnBasicDockStyle) then
- FDockStyle.SetDockBaseControl(False, Self);
- end;
- if FDockStyle <> nil then
- FDockStyle.RemoveDockBaseControl(Self);
- inherited Destroy;
- end;
- constructor TCnDockBaseControl.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FParentForm := TForm(AOwner);
- FEnableDock := True;
- FLeftDock := True;
- FTopDock := True;
- FRightDock := True;
- FBottomDock := True;
- FEachOtherDock := True;
- FDockStyle := nil;
- if not (csDesigning in ComponentState) then
- begin
- FOldOnClose := FParentForm.OnClose;
- ParentForm.OnClose := DoFormOnClose;
- FOldOnCreate := FParentForm.OnCreate;
- ParentForm.OnCreate := DoFormOnCreate;
- { 保存老的窗口过程 }
- FOldWindowProc := FParentForm.WindowProc;
- { 重载窗口过程 }
- FParentForm.WindowProc := WindowProc;
- end;
- end;
- procedure TCnDockBaseControl.SetBottomDock(const Value: Boolean);
- begin
- if CanSetBottomDocked then
- FBottomDock := Value;
- end;
- procedure TCnDockBaseControl.SetEachotherDock(const Value: Boolean);
- begin
- if CanSetEachOtherDocked then
- FEachotherDock := Value;
- end;
- procedure TCnDockBaseControl.SetEnableDock(const Value: Boolean);
- begin
- if CanSetEnableDocked then
- FEnableDock := Value;
- end;
- procedure TCnDockBaseControl.SetLeftDock(const Value: Boolean);
- begin
- if CanSetLeftDocked then
- FLeftDock := Value;
- end;
- procedure TCnDockBaseControl.SetRightDock(const Value: Boolean);
- begin
- if CanSetRightDocked then
- FRightDock := Value;
- end;
- procedure TCnDockBaseControl.SetTopDock(const Value: Boolean);
- begin
- if CanSetTopDocked then
- FTopDock := Value;
- end;
- procedure TCnDockBaseControl.Assign(Source: TPersistent);
- begin
- if Source is TCnDockBaseControl then
- begin
- FEnableDock := TCnDockBaseControl(Source).EnableDock;
- FLeftDock := TCnDockBaseControl(Source).LeftDock;
- FTopDock := TCnDockBaseControl(Source).TopDock;
- FRightDock := TCnDockBaseControl(Source).RightDock;
- FBottomDock := TCnDockBaseControl(Source).BottomDock;
- FEachOtherDock := TCnDockBaseControl(Source).EachOtherDock;
- FDockStyle := TCnDockBaseControl(Source).DockStyle;
- if FDockStyle <> nil then
- FDockStyle.AddDockBaseControl(Self);
- end else inherited Assign(Source);
- end;
- procedure TCnDockBaseControl.SetDockStyle(const Value: TCnBasicDockStyle);
- begin
- { 根据原来的FDockStyle和输入的Value添加TCnDockBaseControl对象 }
- if FDockStyle <> nil then
- FDockStyle.RemoveDockBaseControl(Self);
- if Value <> nil then
- Value.AddDockBaseControl(Self);
- if (csDesigning in ComponentState) or (csLoading in ComponentState) then
- begin
- // 当前是设计期,就修改FDockStyle的值。
- if Value <> nil then
- begin
- Value.SetDockBaseControl(True, Self);
- // 调用FreeNotification函数来使一个窗体的TCnDockBaseControl设置DockStyle
- // 属性,这个DockStyle属性是另一个窗体上的控件,不会出现异常。
- Value.FreeNotification(ParentForm);
- end;
- FDockStyle := Value;
- end else
- begin
- // 在运行期不能设置DockStyle属性。
- ShowMessage(gs_CannotChangeDockStyleProperty);
- end;
- end;
- procedure TCnDockBaseControl.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- // 当DockStyle属性的控件插入或者释放的时候,会调用Notification函数。
- inherited Notification(AComponent, Operation);
- if Operation = opRemove then
- // 如果是释放,就要把DockStyle属性设成nil。
- if AComponent = FDockStyle then
- begin
- FDockStyle.SetDockBaseControl(False, Self);
- FDockStyle := nil;
- end;
- end;
- procedure TCnDockBaseControl.Loaded;
- begin
- if not (csDesigning in ComponentState) then
- begin
- // 默认的DockStyle属性是TCnBasicDockStyle类。
- if not Assigned(DockStyle) then
- DockStyle := TCnBasicDockStyle.Create(ParentForm);
- if Assigned(DockStyle) then
- begin
- DockStyle.SetDockBaseControl(True, Self);
- end;
- end;
- inherited Loaded;
- end;
- function TCnDockBaseControl.GetDockStyleVersion: string;
- begin
- Result := gs_CnDockManagerVersion;
- end;
- procedure TCnDockBaseControl.DoFormOnClose(Sender: TObject;
- var Action: TCloseAction);
- begin
- if (Action = caFree) and (CnGlobalDockPresident <> nil) then
- begin
- { 把ParentForm添加到CnDockManager中 }
- if Self is TCnDockServer then
- CnGlobalDockPresident.RemoveDockServerFromDockManager(ParentForm)
- else if Self is TCnDockClient then
- CnGlobalDockPresident.RemoveDockClientFromDockManager(ParentForm);
- end;
- if Assigned(FOldOnClose) then
- FOldOnClose(Sender, Action);
- end;
- procedure TCnDockBaseControl.DoFormOnCreate(Sender: TObject);
- begin
- if CnGlobalDockPresident <> nil then
- begin
- { 从CnDockManager清除ParentForm }
- if Self is TCnDockServer then
- CnGlobalDockPresident.AddDockServerToDockManager(ParentForm)
- else if Self is TCnDockClient then
- CnGlobalDockPresident.AddDockClientToDockManager(ParentForm);
- end;
- if Assigned(FOldOnCreate) then
- FOldOnCreate(Sender);
- end;
- procedure TCnDockBaseControl.WindowProc(var Message: TMessage);
- begin
- if not (csDesigning in ComponentState) then
- begin
- if Assigned(FOldWindowProc) then
- FOldWindowProc(Message);
- end;
- end;
- procedure TCnDockBaseControl.SetParentComponent(Value: TComponent);
- var ADockBaseControl: TCnDockBaseControl;
- begin
- ADockBaseControl := FindDockBaseControl(ParentForm);
- if (Assigned(ADockBaseControl)) and (ADockBaseControl <> Self) then
- raise EInvalidOperation.Create(Format(gs_CannotLayAnother, [ADockBaseControl.ClassName, ClassName]));
- inherited SetParentComponent(Value);
- end;
- function TCnDockBaseControl.CanSetBottomDocked: Boolean;
- begin
- Result := True;
- if DockStyle <> nil then
- Result := DockStyle.CanSetBottomDocked(Self);
- end;
- function TCnDockBaseControl.CanSetEachOtherDocked: Boolean;
- begin
- Result := True;
- if DockStyle <> nil then
- Result := DockStyle.CanSetEachOtherDocked(Self);
- end;
- function TCnDockBaseControl.CanSetEnableDocked: Boolean;
- begin
- Result := True;
- if DockStyle <> nil then
- Result := DockStyle.CanSetEnableDocked(Self);
- end;
- function TCnDockBaseControl.CanSetLeftDocked: Boolean;
- begin
- Result := True;
- if DockStyle <> nil then
- Result := DockStyle.CanSetLeftDocked(Self);
- end;
- function TCnDockBaseControl.CanSetRightDocked: Boolean;
- begin
- Result := True;
- if DockStyle <> nil then
- Result := DockStyle.CanSetRightDocked(Self);
- end;
- function TCnDockBaseControl.CanSetTopDocked: Boolean;
- begin
- Result := True;
- if DockStyle <> nil then
- Result := DockStyle.CanSetTopDocked(Self);
- end;
- { TCnDockServer }
- constructor TCnDockServer.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- CreateSplitterStyle;
- end;
- destructor TCnDockServer.Destroy;
- begin
- // if not (csDesigning in ComponentState) then
- // DestroyDockPanelAndSplitter;
- DestroySplitterStyle;
- inherited Destroy;
- end;
- procedure TCnDockServer.CreateDockPanelAndSplitter;
- var ControlList: TList;
- function CreatePanel(Align: TAlign; Name: string): TCnDockPanel;
- begin
- if (FDockPanelClass <> nil) and
- (FDockPanelClass <> TCnDockPanelClass(ClassType)) then
- begin
- Result := FDockPanelClass.Create(Owner);
- Result.Parent := ParentForm;
- Result.Name := Name;
- Result.Caption := '';
- Result.Align := Align;
- Result.DockServer := Self;
- Result.ResetPosition;
- if Align in [alTop, alBottom] then
- Result.Height := 0
- else
- Result.Width := 0;
- SetDockSite(Result, True);
- { 调用DockStyle的AssignConjoinServerOption函数重新设置平铺属性 }
- if DockStyle <> nil then
- DockStyle.AssignConjoinServerOption(Result);
- end else Result := nil;
- end;
- function CreateSplitter(Align: TAlign; Name: string): TCnDockSplitter;
- begin
- if (FDockSplitterClass <> nil) and
- (FDockSplitterClass <> TCnDockSplitterClass(ClassType)) then
- begin
- Result := FDockSplitterClass.Create(Owner);
- Result.Parent := ParentForm;
- Result.Name := Name;
- Result.Visible := False;
- Result.Align := Align;
- Result.DockServer := Self;
- end else Result := nil;
- end;
- begin
- ControlList := TList.Create;
- try
- FLeftDockPanel := CreatePanel(alLeft, 'LeftDockPanel_A_B_C_D_E_F_G');
- FLeftSplitter := CreateSplitter(alLeft, 'LeftSplitter_A_B_C_D_E_F_G');
- FRightDockPanel := CreatePanel(alRight, 'RightDockPanel_A_B_C_D_E_F_G');
- FRightSplitter := CreateSplitter(alRight, 'RightSplitter_A_B_C_D_E_F_G');
- FTopDockPanel := CreatePanel(alTop, 'TopDockPanel_A_B_C_D_E_F_G');
- FTopSplitter := CreateSplitter(alTop, 'TopSplitter_A_B_C_D_E_F_G');
- FBottomDockPanel := CreatePanel(alBottom, 'BottomDockPanel_A_B_C_D_E_F_G');
- FBottomSplitter := CreateSplitter(alBottom, 'BottomSplitter_A_B_C_D_E_F_G');
- finally
- ControlList.Free;
- end;
- end;
- procedure TCnDockServer.CreateSplitterStyle;
- begin
- FLeftSplitterStyle := TCnSplitterStyle.Create(FLeftSplitter, crHSplit);
- FTopSplitterStyle := TCnSplitterStyle.Create(FTopSplitter, crVSplit);
- FRightSplitterStyle := TCnSplitterStyle.Create(FRightSplitter, crHSplit);
- FBottomSplitterStyle := TCnSplitterStyle.Create(FBottomSplitter, crVSplit);
- FLeftSplitterStyle.FDockServer := Self;
- FTopSplitterStyle.FDockServer := Self;
- FRightSplitterStyle.FDockServer := Self;
- FBottomSplitterStyle.FDockServer := Self;
- end;
- procedure TCnDockServer.DestroySplitterStyle;
- begin
- FLeftSplitterStyle.Free;
- FTopSplitterStyle.Free;
- FRightSplitterStyle.Free;
- FBottomSplitterStyle.Free;
- end;
- procedure TCnDockServer.SetLeftSplitterStyle(
- const Value: TCnSplitterStyle);
- begin
- FLeftSplitterStyle.Assign(Value);
- end;
- procedure TCnDockServer.SetTopSplitterStyle(
- const Value: TCnSplitterStyle);
- begin
- FTopSplitterStyle.Assign(Value);
- end;
- procedure TCnDockServer.SetRightSplitterStyle(
- const Value: TCnSplitterStyle);
- begin
- FRightSplitterStyle.Assign(Value);
- end;
- procedure TCnDockServer.SetBottomSplitterStyle(
- const Value: TCnSplitterStyle);
- begin
- FBottomSplitterStyle.Assign(Value);
- end;
- procedure TCnDockServer.SetSplitterStyle;
- begin
- LeftSplitterStyle.Splitter := FLeftSplitter;
- LeftSplitterStyle.SetSplitterStyle;
- TopSplitterStyle.Splitter := FTopSplitter;
- TopSplitterStyle.SetSplitterStyle;
- RightSplitterStyle.Splitter := FRightSplitter;
- RightSplitterStyle.SetSplitterStyle;
- BottomSplitterStyle.Splitter := FBottomSplitter;
- BottomSplitterStyle.SetSplitterStyle;
- end;
- procedure TCnDockServer.WindowProc(var Message: TMessage);
- begin
- { 执行FDockStyle的消息处理 }
- if Assigned(FDockStyle) then
- begin
- if FDockStyle.DockServerWindowProc(Self, Message) then
- { 如果DockStyle已经执行了消息处理,就不执行默认的处理 }
- Exit;
- end;
- if not (csDesigning in ComponentState) then
- begin
- if Message.Msg = WM_ACTIVATE then
- WMActivate(TWMActivate(Message));
- end;
- inherited WindowProc(Message);
- end;
- function TCnDockServer.GetDockPanel(Index: Integer): TCnDockPanel;
- begin
- Result := nil;
- case Index of
- 0: Result := FTopDockPanel;
- 1: Result := FBottomDockPanel;
- 2: Result := FLeftDockPanel;
- 3: Result := FRightDockPanel;
- end;
- end;
- function TCnDockServer.GetDockSplitter(Index: Integer): TCnDockSplitter;
- begin
- Result := nil;
- case Index of
- 0: Result := FTopSplitter;
- 1: Result := FBottomSplitter;
- 2: Result := FLeftSplitter;
- 3: Result := FRightSplitter;
- end;
- end;
- procedure TCnDockServer.SetBottomDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(BottomDockPanel);
- inherited SetBottomDock(Value);
- end;
- procedure TCnDockServer.SetEnableDock(const Value: Boolean);
- begin
- if not Value then
- begin
- DoFloatDockClients(TopDockPanel);
- DoFloatDockClients(BottomDockPanel);
- DoFloatDockClients(LeftDockPanel);
- DoFloatDockClients(RightDockPanel);
- end;
- inherited SetEnableDock(Value);
- end;
- procedure TCnDockServer.SetLeftDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(LeftDockPanel);
- inherited SetLeftDock(Value);
- end;
- procedure TCnDockServer.SetRightDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(RightDockPanel);
- inherited SetRightDock(Value);
- end;
- procedure TCnDockServer.SetTopDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(TopDockPanel);
- inherited SetTopDock(Value);
- end;
- procedure TCnDockServer.DoFloatDockClients(DockPanel: TCnDockPanel);
- var
- i: Integer;
- ADockClient: TCnDockClient;
- begin
- if not (csDesigning in ComponentState) and (DockPanel <> nil) then
- begin
- for i := DockPanel.DockClientCount - 1 downto 0 do
- begin
- ADockClient := FindDockClient(DockPanel.DockClients[i]);
- if ADockClient <> nil then
- ADockClient.RestoreChild;
- end;
- end;
- end;
- procedure TCnDockServer.GetComponentInfo(var AName, Author, Email, Comment: string);
- begin
- AName := SCnDockServerName;
- Author := SCnPack_LuXiaoban;
- Email := SCnPack_LuXiaobanEmail;
- Comment := SCnDockServerComment;
- end;
- procedure TCnDockServer.Loaded;
- begin
- if Assigned(DockStyle) and Assigned(DockStyle.CnDockPanelClass) then
- FDockPanelClass := DockStyle.CnDockPanelClass
- else FDockPanelClass := DefaultDockPanelClass;
- { ------------------------------------------------------------------------ }
- if Assigned(DockStyle) and Assigned(DockStyle.CnDockSplitterClass) then
- FDockSplitterClass := DockStyle.CnDockSplitterClass
- else FDockSplitterClass := DefaultDockSplitterClass;
- { ------------------------------------------------------------------------ }
- if not (csDesigning in ComponentState) then
- begin
- CreateDockPanelAndSplitter;
- SetSplitterStyle;
- end;
- inherited Loaded;
- end;
- procedure TCnDockServer.WMActivate(var Message: TWMActivate);
- var i: Integer;
- Control: TWinControl;
- begin
- if (Message.Active = WA_INACTIVE) then
- begin
- for i := 0 to 3 do
- DockPanel[i].CnDockManager.ActiveControl := nil;
- end else
- begin
- Control := GetActiveControl(ParentForm);
- for i := 0 to 3 do
- begin
- if GetHostDockParent(Control) = DockPanel[i] then
- begin
- DockPanel[i].CnDockManager.ActiveControl := Control;
- if Control.CanFocus then
- Control.SetFocus;
- end;
- end;
- end;
- end;
- procedure TCnDockServer.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- end;
- procedure TCnDockServer.DoGetClientAlignControl(Align: TAlign; var Value: Integer);
- begin
- if Assigned(FOnGetClientAlignSize) then
- FOnGetClientAlignSize(Align, Value);
- end;
- procedure TCnDockServer.DoFinishSetDockPanelSize(DockPanel: TCnDockPanel);
- begin
- if Assigned(FOnFinishSetDockPanelSize) then
- FOnFinishSetDockPanelSize(DockPanel);
- end;
- function TCnDockServer.GetClientAlignControl(Align: TAlign): Integer;
- begin
- Result := GetClientAlignControlArea(ParentForm, Align);
- DoGetClientAlignControl(Align, Result);
- end;
- function TCnDockServer.GetDockPanelWithAlign(Index: TAlign): TCnDockPanel;
- begin
- Result := nil;
- case Index of
- alLeft: Result := FLeftDockPanel;
- alRight: Result := FRightDockPanel;
- alTop: Result := FTopDockPanel;
- alBottom: Result := FBottomDockPanel;
- end;
- end;
- function TCnDockServer.GetDockSplitterWithAlign(
- Index: TAlign): TCnDockSplitter;
- begin
- Result := nil;
- case Index of
- alLeft: Result := FLeftSplitter;
- alRight: Result := FRightSplitter;
- alTop: Result := FTopSplitter;
- alBottom: Result := FBottomSplitter;
- end;
- end;
- { TCnDockClient }
- constructor TCnDockClient.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FParentVisible := ParentForm.Visible;
- ParentForm.DragKind := dkDock;
- ParentForm.DragMode := dmAutomatic;
- ParentForm.UseDockManager := False;
- if not (ParentForm is TCnDockableForm) then
- SetDockSite(ParentForm, True);
- LRDockWidth := 100;
- TBDockHeight := 100;
- if GlobalDockClient = nil then
- GlobalDockClient := Self;
- FDirectDrag := False;
- FShowHint := True;
- FCanFloat := True;
- FRelativeServer := nil;
- FDockLevel := 0;
- EnableCloseBtn := True;
- end;
- destructor TCnDockClient.Destroy;
- begin
- if not (ParentForm is TCnDockableForm) then
- SetDockSite(ParentForm, False);
- ParentForm.DragKind := dkDrag;
- ParentForm.DragMode := dmManual;
- inherited Destroy;
- end;
- procedure TCnDockClient.Assign(Source: TPersistent);
- begin
- if Source is TCnDockClient then
- begin
- FConjoinPanelClass := TCnDockClient(Source).FConjoinPanelClass;
- FTabDockClass := TCnDockClient(Source).FTabDockClass;
- FParentVisible := TCnDockClient(Source).FParentVisible;
- FNCPopupMenu := TCnDockClient(Source).FNCPopupMenu;
- FDirectDrag := TCnDockClient(Source).FDirectDrag;
- FShowHint := TCnDockClient(Source).FShowHint;
- FCanFloat := TCnDockClient(Source).FCanFloat;
- FRelativeServer := TCnDockClient(Source).FRelativeServer;
- FDockLevel := TCnDockClient(Source).DockLevel;
- end;
- inherited Assign(Source);
- end;
- procedure TCnDockClient.WindowProc(var Message: TMessage);
- var OldOrient: TDockOrientation;
- begin
- { 执行FDockStyle的消息处理 }
- if Assigned(FDockStyle) then
- begin
- if FDockStyle.DockClientWindowProc(Self, Message) then
- { 如果DockStyle已经执行了消息处理,就不执行默认的处理 }
- Exit;
- end;
- if not (csDesigning in ComponentState) then
- begin
- case Message.Msg of
- CM_SHOWINGCHANGED:
- begin
- { 在WinXP中,当在装载的时候,会出现闪烁,在这里把显示改变的消息捕获掉。
- 在98或者2000中是没有这种情况的,因为已经调用了LockWindowUpdate函数,
- 但是在XP下面不知道是什么原因,还是会出现这种闪烁的情况,没办法,只能
- 在装载的时候先过滤掉CM_SHOWINGCHANGED消息,然后在装载的最后把应该显示
- 但是没有显示的客户窗体显示出来。}
- if IsWinXP and IsLoading then
- Exit;
- end;
- WM_NCLBUTTONDOWN:
- begin
- // 如果捕获到WM_NCLBUTTONDOWN消息,就调用WMNCLButtonDown函数。
- WMNCLButtonDown(TWMNCHitMessage(Message));
- if (Message.Result = 1) then
- Exit;
- end;
- WM_NCLBUTTONUP:
- WMNCLButtonUp(TWMNCHitMessage(Message));
- WM_NCLBUTTONDBLCLK:
- WMNCLButtonDblClk(TWMNCHitMessage(Message));
- WM_NCMBUTTONDOWN:
- WMNCMButtonDown(TWMNCHitMessage(Message));
- WM_NCMBUTTONUP:
- WMNCMButtonUp(TWMNCHitMessage(Message));
- WM_NCMBUTTONDBLCLK:
- WMNCMButtonDblClk(TWMNCHitMessage(Message));
- WM_NCRBUTTONDOWN:
- begin
- WMNCRButtonDown(TWMNCHitMessage(Message));
- { 如果有自定义的弹出菜单,就不要调用系统默认的弹出菜单,
- 要实现这个功能,只要不把这个消息发送给Windows就可以办到。 }
- if FNCPopupMenu <> nil then
- Exit;
- end;
- WM_NCRBUTTONUP:
- WMNCRButtonUp(TWMNCHitMessage(Message));
- WM_NCRBUTTONDBLCLK:
- WMNCRButtonDblClk(TWMNCHitMessage(Message));
- WM_NCMOUSEMOVE:
- WMNCMOUSEMOVE(TWMNCHitMessage(Message));
- WM_SIZE:
- WMSize(TWMSize(Message));
- WM_ACTIVATE:
- WMActivate(TWMActivate(Message));
- WM_WINDOWPOSCHANGED:
- begin
- //下面一条代码的作用是使TControl.CalcDockSizes方法失效,
- //请参看Controls.pas文件中的4462--4466行(D5版本),或者4816--4820行(D6版本)
- ParentForm.ControlState := ParentForm.ControlState + [csDocking];
- OldOrient := ParentForm.DockOrientation;
- ParentForm.DockOrientation := doNoOrient;
- try
- inherited WindowProc(Message);
- finally
- ParentForm.ControlState := ParentForm.ControlState - [csDocking];
- ParentForm.DockOrientation := OldOrient;
- end;
- Exit;
- end;
- CM_ENTER:
- Activate;
- CM_EXIT:
- Deactivate;
- CM_VISIBLECHANGED:
- CMVisibleChanged(Message);
- end;
- end;
- inherited WindowProc(Message);
- end;
- { 创建平铺的服务窗体并且把控件停靠进去 }
- function TCnDockClient.CreateConjoinHostAndDockControl(
- Control1, Control2: TControl; DockType: TAlign): TCnConjoinDockHostForm;
- var APanel: TCnConjoinPanel;
- OldDockWidth, OldDockHeight: Integer;
- begin
- { 创建一个TCnConjoinDockHostForm窗体作为TCnConjoinPanel的Parent }
- Result := TCnConjoinDockHostForm.Create(Application);
- { 创建一个TCnConjoinPanel,并且把它放在Result上 }
- APanel := CreateConjoinPanelClass(Result);
- { Result的位置大小和Control1的相同,所以在调用CreateConjoinHostAndDockControl
- 的时候要注意:Control1为停靠目标窗体,Control2为停靠源窗体 }
- Result.BoundsRect := Control1.BoundsRect;
- { 调整Result的宽度和高度为UndockWidth和UndockHeight }
- Result.Width := Control1.UndockWidth;
- Result.Height := Control1.UndockHeight;
- { 分别把Control1和Control2停靠进APage }
- OldDockWidth := Control1.LRDockWidth;
- OldDockHeight := Control1.TBDockHeight;
- Control1.ManualDock(APanel, nil, alNone);
- Control1.LRDockWidth := OldDockWidth;
- Control1.TBDockHeight := OldDockHeight;
- {============================================================================}
- OldDockWidth := Control2.LRDockWidth;
- OldDockHeight := Control2.TBDockHeight;
- Control2.ManualDock(APanel, nil, DockType);
- Control2.LRDockWidth := OldDockWidth;
- Control2.TBDockHeight := OldDockHeight;
- { 把Result的DockSite属性设置成False }
- SetDockSite(Result, False);
- end;
- { 创建分页的服务窗体并且把控件停靠进去 }
- function TCnDockClient.CreateTabHostAndDockControl(
- Control1, Control2: TControl): TCnTabDockHostForm;
- var APage: TCnTabPageControl;
- OldDockWidth, OldDockHeight: Integer;
- begin
- { 创建一个TCnTabDockHostForm窗体作为TCnTabPageControl的Parent }
- Result := TCnTabDockHostForm.Create(Application);
- { 创建一个TCnTabPageControl,并且把它放在Result上 }
- APage := CreateTabDockClass(Result);
- { Result的位置大小和Control1的相同,所以在调用CreateTabHostAndDockControl
- 的时候要注意:Control1为停靠目标窗体,Control2为停靠源窗体 }
- Result.BoundsRect := Control1.BoundsRect;
- { 调整Result的宽度和高度为UndockWidth和UndockHeight }
- Result.Width := Control1.UndockWidth;
- Result.Height := Control1.UndockHeight;
- { 分别把Control1和Control2停靠进APage }
- OldDockWidth := Control1.LRDockWidth;
- OldDockHeight := Control1.TBDockHeight;
- Control1.ManualDock(APage, nil, alClient);
- Control1.LRDockWidth := OldDockWidth;
- Control1.TBDockHeight := OldDockHeight;
- {============================================================================}
- OldDockWidth := Control2.LRDockWidth;
- OldDockHeight := Control2.TBDockHeight;
- Control2.ManualDock(APage, nil, alClient);
- Control2.LRDockWidth := OldDockWidth;
- Control2.TBDockHeight := OldDockHeight;
- { 把Result的DockSite属性设置成False }
- SetDockSite(Result, False);
- end;
- procedure TCnDockClient.MakeHideEvent;
- begin
- ParentVisible := False;
- if Assigned(FOnFormHide) then
- FOnFormHide(Self);
- end;
- procedure TCnDockClient.MakeShowEvent;
- begin
- if {(not ParentVisible) and }ParentForm.Visible then
- begin
- if Assigned(FOnFormShow) then
- FOnFormShow(Self);
- ParentVisible := True;
- end;
- end;
- procedure TCnDockClient.SetParentVisible(const Value: Boolean);
- begin
- FParentVisible := Value;
- end;
- procedure TCnDockClient.DoFloatDockClients(PanelAlign: TAlign);
- begin
- if (ParentForm.HostDockSite is TCnDockPanel) and
- (PanelAlign = ParentForm.HostDockSite.Align) then
- RestoreChild;
- end;
- procedure TCnDockClient.SetBottomDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(alBottom);
- inherited SetBottomDock(Value);
- end;
- procedure TCnDockClient.SetEachotherDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockEachOther;
- inherited SetEachotherDock(Value);
- end;
- procedure TCnDockClient.SetEnableDock(const Value: Boolean);
- begin
- if not Value then
- begin
- DoFloatDockClients(alTop);
- DoFloatDockClients(alBottom);
- DoFloatDockClients(alLeft);
- DoFloatDockClients(alRight);
- DoFloatDockEachOther;
- end;
- if ParentForm <> nil then
- begin
- if Value then
- ParentForm.DragKind := dkDock
- else
- ParentForm.DragKind := dkDrag;
- end;
- inherited SetEnableDock(Value);
- end;
- procedure TCnDockClient.SetLeftDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(alLeft);
- inherited SetLeftDock(Value);
- end;
- procedure TCnDockClient.SetRightDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(alRight);
- inherited SetRightDock(Value);
- end;
- procedure TCnDockClient.SetTopDock(const Value: Boolean);
- begin
- if not Value then
- DoFloatDockClients(alTop);
- inherited SetTopDock(Value);
- end;
- procedure TCnDockClient.DoFloatDockEachOther;
- begin
- if (ParentForm.HostDockSite <> nil) and
- (ParentForm.HostDockSite.Parent is TCnDockableForm) then
- RestoreChild;
- end;
- procedure TCnDockClient.WMSize(var Message: TWMSize);
- begin
- { if (ParentForm.HostDockSite <> nil) and (Message.Width * Message.Height <> 0) then
- begin
- if ParentForm.DockOrientation = doVertical then // 垂直
- ParentForm.LRDockWidth := Message.Width
- else if ParentForm.DockOrientation = doHorizontal then
- ParentForm.TBDockHeight := Message.Height
- else
- begin
- if (ParentForm.HostDockSite is TCnDockPanel) and
- (ParentForm.HostDockSite.FindChildControl(ParentForm.Name) <> nil) then
- begin
- if ParentForm.HostDockSite.Align in [alLeft, alRight] then
- ParentForm.LRDockWidth := Message.Width
- else
- ParentForm.TBDockHeight := Message.Height;
- end;
- end;
- end;}
- inherited;
- end;
- procedure TCnDockClient.GetComponentInfo(var AName, Author, Email, Comment: string);
- begin
- AName := SCnDockClientName;
- Author := SCnPack_LuXiaoban;
- Email := SCnPack_LuXiaobanEmail;
- Comment := SCnDockClientComment;
- end;
- procedure TCnDockClient.Loaded;
- begin
- { 设置FConjoinPanelClass }
- if Assigned(DockStyle) and Assigned(DockStyle.CnConjoinPanelClass) then
- FConjoinPanelClass := DockStyle.CnConjoinPanelClass
- else FConjoinPanelClass := DefaultConjoinPanelClass;
- { 设置FTabDockClass }
- if Assigned(DockStyle) and Assigned(DockStyle.CnTabDockClass) then
- FTabDockClass := DockStyle.CnTabDockClass
- else FTabDockClass := DefaultTabDockClass;
- inherited Loaded;
- end;
- function TCnDockClient.CreateConjoinPanelClass(
- ConjoinHost: TForm): TCnConjoinPanel;
- begin
- Result := nil;
- TCnConjoinDockHostForm(ConjoinHost).DockClient.Assign(Self);
- if (FConjoinPanelClass <> nil) and
- (FConjoinPanelClass <> TCnConjoinPanelClass(ClassType)) then
- begin
- Result := FConjoinPanelClass.Create(ConjoinHost);
- Result.Align := alClient;
- TCnConjoinDockHostForm(ConjoinHost).DockableControl := Result;
- TCnConjoinDockHostForm(ConjoinHost).Panel := Result;
- SetDockSite(Result, True);
- { 调用DockStyle.AssignConjoinServerOption来设置一些在DockStyle中设置的属性 }
- DockStyle.AssignConjoinServerOption(TCnConjoinDockHostForm(ConjoinHost).Panel);
- end;
- end;
- function TCnDockClient.CreateTabDockClass(
- TabHost: TForm): TCnTabPageControl;
- begin
- Result := nil;
- TCnTabDockHostForm(TabHost).DockClient.Assign(Self);
- if (FTabDockClass <> nil) and
- (FTabDockClass <> TCnTabDockClass(ClassType)) then
- begin
- Result := FTabDockClass.Create(TabHost);
- Result.Align := alClient;
- TCnTabDockHostForm(TabHost).DockableControl := Result;
- TCnTabDockHostForm(TabHost).PageControl := Result;
- SetDockSite(Result, True);
- { 调用DockStyle.AssignTabServerOption来设置一些在DockStyle中设置的属性 }
- DockStyle.AssignTabServerOption(TCnTabDockHostForm(TabHost).PageControl);
- end;
- end;
- procedure TCnDockClient.WMActivate(var Message: TWMActivate);
- begin
- if (ParentForm is TCnConjoinDockHostForm) then
- begin
- if (Message.Active = WA_INACTIVE) then
- TCnConjoinPanel(TCnConjoinDockHostForm(ParentForm).Panel).CnDockManager.ActiveControl := nil
- else
- begin
- TCnConjoinPanel(TCnConjoinDockHostForm(ParentForm).Panel).CnDockManager.ActiveControl :=
- GetActiveControl(ParentForm);
- end;
- end;
- end;
- procedure TCnDockClient.Activate;
- begin
- if ParentForm.HostDockSite is TCnCustomDockPanel then
- begin
- TCnCustomDockPanel(
- ParentForm.HostDockSite).CnDockManager.ActiveControl := ParentForm;
- end;
- end;
- procedure TCnDockClient.Deactivate;
- begin
- if ParentForm.HostDockSite is TCnCustomDockPanel then
- begin
- if TCnCustomDockPanel(ParentForm.HostDockSite).CnDockManager <> nil then
- TCnCustomDockPanel(ParentForm.HostDockSite).CnDockManager.ActiveControl := nil;
- end;
- end;
- procedure TCnDockClient.DoFormOnClose(Sender: TObject;
- var Action: TCloseAction);
- begin
- if Action = caHide then
- begin
- HideDockForm(ParentForm);
- FParentVisible := True;
- end;
- end;
- procedure TCnDockClient.FormDockDrop(Source: TCnDragDockObject; X,
- Y: Integer);
- begin
- if Assigned(DockStyle) then
- DockStyle.FormDockDrop(Self, Source, X, Y);
- end;
- procedure TCnDockClient.FormDockOver(Source: TCnDragDockObject; X,
- Y: Integer; State: TDragState; var Accept: Boolean);
- begin
- FormPositionDockRect(Source);
- if Assigned(DockStyle) then
- DockStyle.FormDockOver(Self, Source, X, Y, State, Accept);
- end;
- procedure TCnDockClient.FormEndDock(Target: TObject; X, Y: Integer);
- begin
- if Assigned(DockStyle) then
- DockStyle.FormEndDock(Self, Target, X, Y);
- end;
- procedure TCnDockClient.FormPositionDockRect(Source: TCnDragDockObject);
- begin
- if Assigned(DockStyle) then
- DockStyle.FormPositionDockRect(Self, Source);
- end;
- procedure TCnDockClient.FormStartDock(var Source: TCnDragDockObject);
- begin
- if Assigned(DockStyle) then
- DockStyle.FormStartDock(Self, Source);
- end;
- function TCnDockClient.FormUnDock(NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- if Assigned(DockStyle) then
- Result := DockStyle.FormUnDock(Self, Newtarget, Client)
- else Result := False;
- end;
- procedure TCnDockClient.FormGetSiteInfo(Source: TCnDragDockObject; Client: TControl;
- var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
- begin
- GetWindowRect(ParentForm.Handle, InfluenceRect);
- InflateRect(InfluenceRect, -4, -4);
- if Assigned(DockStyle) then
- DockStyle.FormGetSiteInfo(Source, Self, Client, InfluenceRect, MousePos, CanDock);
- end;
- function TCnDockClient.GetLRDockWidth: Integer;
- begin
- Result := ParentForm.LRDockWidth;
- end;
- function TCnDockClient.GetTBDockHeight: Integer;
- begin
- Result := ParentForm.TBDockHeight;
- end;
- procedure TCnDockClient.SetLRDockWidth(const Value: Integer);
- begin
- if ParentForm.LRDockWidth <> Value then
- ParentForm.LRDockWidth := Value;
- end;
- procedure TCnDockClient.SetTBDockHeight(const Value: Integer);
- begin
- if ParentForm.TBDockHeight <> Value then
- ParentForm.TBDockHeight := Value;
- end;
- procedure TCnDockClient.DoNCButtonDown(Message: TWMNCHitMessage;
- Button: TMouseButton; MouseStation: TMouseStation);
- begin
- if Assigned(FOnNCButtonDown) then
- FOnNCButtonDown(Self, Button, Message.XCursor, Message.YCursor,
- Message.HitTest, MouseStation);
- end;
- procedure TCnDockClient.DoNCButtonUp(Message: TWMNCHitMessage;
- Button: TMouseButton; MouseStation: TMouseStation);
- begin
- if Assigned(FOnNCButtonUp) then
- FOnNCButtonUp(Self, Button, Message.XCursor, Message.YCursor,
- Message.HitTest, MouseStation);
- if Button = mbRight then
- { 如果是鼠标右键,就弹出菜单 }
- DoMenuPopup(Message.XCursor, Message.YCursor);
- end;
- procedure TCnDockClient.DoNCMouseMove(Message: TWMNCHitMessage;
- MouseStation: TMouseStation);
- begin
- if Assigned(FOnNCMouseMove) then
- FOnNCMouseMove(Self, Message.XCursor, Message.YCursor,
- Message.HitTest, MouseStation);
- end;
- procedure TCnDockClient.DoNCButtonDblClk(Message: TWMNCHitMessage; Button: TMouseButton;
- MouseStation: TMouseStation);
- begin
- if Assigned(FOnNCButtonDblClk) then
- FOnNCButtonDblClk(Self, Button, Message.XCursor, Message.YCursor,
- Message.HitTest, MouseStation);
- end;
- procedure TCnDockClient.WMNCLButtonDown(var Message: TWMNCHitMessage);
- begin
- DoNCButtonDown(Message, mbLeft, msFloat);
- GlobalDockClient := Self;
-
- if (Message.HitTest = HTCAPTION) and (ParentForm.DragKind = dkDock) and not
- (csDesigning in ComponentState) and not IsIconic(ParentForm.Handle) then
- begin
- { Activate window since we override WM_NCLBUTTON behavior }
- SetWindowPos(ParentForm.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or SWP_NOMOVE or
- SWP_NOSIZE);
- PostMessage(ParentForm.Handle, WM_NCLBUTTONUP, TMessage(Message).WParam,
- TMessage(Message).LParam);
- if ParentForm.Active then
- CnGlobalDockPresident.BeginDrag(ParentForm, DirectDrag, Integer(DirectDrag) * 2 - 1);
- Message.Result := 1;
- end else
- Message.Result := 0;
- end;
- procedure TCnDockClient.WMNCLButtonUp(var Message: TWMNCHitMessage);
- begin
- DoNCButtonUp(Message, mbLeft, msFloat);
- end;
- procedure TCnDockClient.WMNCMButtonDown(var Message: TWMNCHitMessage);
- begin
- DoNCButtonDown(Message, mbMiddle, msFloat);
- end;
- procedure TCnDockClient.WMNCMButtonUp(var Message: TWMNCHitMessage);
- begin
- DoNCButtonUp(Message, mbMiddle, msFloat);
- end;
- procedure TCnDockClient.WMNCRButtonDown(var Message: TWMNCHitMessage);
- begin
- DoNCButtonDown(Message, mbRight, msFloat);
- end;
- procedure TCnDockClient.WMNCRButtonUp(var Message: TWMNCHitMessage);
- begin
- DoNCButtonUp(Message, mbRight, msFloat);
- end;
- procedure TCnDockClient.WMNCMOUSEMOVE(var Message: TWMNCHitMessage);
- begin
- DoNCMouseMove(Message, msFloat);
- end;
- procedure TCnDockClient.WMNCLButtonDblClk(var Message: TWMNCHitMessage);
- begin
- DoNCButtonDblClk(Message, mbLeft, msFloat);
- end;
- procedure TCnDockClient.WMNCMButtonDblClk(var Message: TWMNCHitMessage);
- begin
- DoNCButtonDblClk(Message, mbMiddle, msFloat);
- end;
- procedure TCnDockClient.WMNCRButtonDblClk(var Message: TWMNCHitMessage);
- begin
- DoNCButtonDblClk(Message, mbRight, msFloat);
- end;
- procedure TCnDockClient.SetNCPopupMenu(const Value: TPopupMenu);
- begin
- FNCPopupMenu := Value;
- end;
- procedure TCnDockClient.DoMenuPopup(X, Y: Integer);
- begin
- if FNCPopupMenu <> nil then
- begin
- FNCPopupMenu.PopupComponent := ParentForm;
- FNCPopupMenu.Popup(X, Y);
- end;
- end;
- procedure TCnDockClient.DoPaintDockGrabber(
- Canvas: TCanvas; Control: TControl; const ARect: TRect);
- begin
- if Assigned(FOnPaintDockGrabber) then
- FOnPaintDockGrabber(Canvas, Control, ARect);
- end;
- procedure TCnDockClient.DoPaintDockSplitter(Canvas: TCanvas;
- Control: TControl; const ARect: TRect);
- begin
- if Assigned(FOnPaintDockSplitter) then
- FOnPaintDockSplitter(Canvas, Control, ARect);
- end;
- procedure TCnDockClient.FormGetDockEdge(Source: TCnDragDockObject; MousePos: TPoint; var DropAlign: TAlign);
- begin
- if Assigned(DockStyle) then
- DockStyle.FormGetDockEdge(Self, Source, MousePos, DropAlign)
- else DropAlign := alNone;
- end;
- procedure TCnDockClient.DoFormShowHint(HTFlag: Integer; var HintStr: string;
- var CanShow: Boolean);
- begin
- if Assigned(FOnFormShowHint) then
- FOnFormShowHint(HTFlag, HintStr, CanShow);
- end;
- procedure TCnDockClient.SetCurrentDockSite(const Value: TWinControl);
- begin
- FCurrentDockSite := Value;
- end;
- procedure TCnDockClient.SetLastDockSite(const Value: TWinControl);
- begin
- FLastDockSite := Value;
- end;
- procedure TCnDockClient.SetVSPaneWidth(const Value: Integer);
- begin
- FVSPaneWidth := Value;
- end;
- procedure TCnDockClient.RestoreChild;
- begin
- DockStyle.RestoreClient(Self);
- end;
- procedure TCnDockClient.SetUnDockLeft(const Value: Integer);
- begin
- FUnDockLeft := Value;
- end;
- procedure TCnDockClient.SetUnDockTop(const Value: Integer);
- begin
- FUnDockTop := Value;
- end;
- procedure TCnDockClient.HideParentForm;
- begin
- HideDockForm(ParentForm);
- end;
- procedure TCnDockClient.ShowParentForm;
- begin
- ShowDockForm(ParentForm);
- end;
- function TCnDockClient.GetDockState: Integer;
- begin
- Result := DS_Unknow;
- if DockStyle <> nil then
- Result := DockStyle.GetDockState(Self);
- end;
- procedure TCnDockClient.CMVisibleChanged(var Message: TMessage);
- begin
- end;
- procedure TCnDockClient.SetCanFloat(const Value: Boolean);
- begin
- FCanFloat := Value;
- end;
- procedure TCnDockClient.SetRelativeServer(const Value: TCnDockServer);
- begin
- if (csDesigning in ComponentState){ or (csLoading in ComponentState) }then
- begin
- if Value <> nil then
- Value.FreeNotification(ParentForm);
- end;
- FRelativeServer := Value;
- end;
- procedure TCnDockClient.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited;
- if (Operation = opRemove) and (AComponent = FRelativeServer) then
- // 如果是释放,就要把FRelativeServer属性设成nil。
- FRelativeServer := nil;
- end;
- procedure TCnDockClient.SetDockLevel(const Value: Integer);
- begin
- if not ParentForm.Floating then
- begin
- if FDockLevel <> Value then
- DoFloatForm(ParentForm);
- end;
- FDockLevel := Value;
- end;
- procedure TCnDockClient.SetEnableCloseBtn(const Value: Boolean);
- begin
- FEnableCloseBtn := Value;
- end;
- { TCnDockableForm }
- constructor TCnDockableForm.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- DragKind := dkDock;
- FDockClient := TCnDockClient.Create(self);
- CnGlobalDockPresident.DockableFormList.Add(Self);
- FFloatingChild := nil;
- TBDockHeight := FDockClient.TBDockHeight;
- LRDockWidth := FDockClient.LRDockWidth;
- end;
- destructor TCnDockableForm.Destroy;
- var Index: Integer;
- begin
- if CnGlobalDockPresident <> nil then
- begin
- Index := CnGlobalDockPresident.DockableFormList.IndexOf(Self);
- if Index <> -1 then
- CnGlobalDockPresident.DockableFormList.Delete(Index);
- end;
- if DockClient.LastDockSite is TCnDockPanel then
- TCnDockPanel(DockClient.LastDockSite).CnDockManager.RemoveControl(Self);
- inherited Destroy;
- FFloatingChild := nil;
- end;
- procedure TCnDockableForm.DoClose(var Action: TCloseAction);
- var i: Integer;
- begin
- if DockableControl.DockClientCount = 1 then
- begin
- { 保存这个客户,可能以后还要重新停靠到服务器上面 }
- FFloatingChild := DockableControl.DockClients[0];
- { 如果HostDockSite不为空,说明以后要把它停靠到服务器上面,为了防止闪烁,先把
- FFloatingChild隐藏掉,然后等到重新停靠后再显示出来,就可以防止闪烁,显示的
- 函数见CnDockSupportControl.pas的TCnCustomDockPanel.WndProc函数 }
- if HostDockSite <> nil then
- FFloatingChild.Visible := False;
- { 如果停靠客户的个数为1,就把她拖出,并且释放本身 }
- DoFloat(Self, DockableControl.DockClients[0]);
- Action := caFree;
- end else if DockableControl.DockClientCount = 0 then
- { 如果已经没有停靠客户,就把窗体释放掉 }
- Action := caFree
- else
- begin
- { 否则就隐藏 }
- Action := caHide;
- { 如果查找到DockableControl中的客户有一个是FUnDockControl,就不隐藏自己 }
- if (FUnDockControl <> nil) and (DockableControl.DockClientCount = 2) then
- begin
- for i := 0 to DockableControl.DockClientCount - 1 do
- if FUnDockControl = DockableControl.DockClients[i] then
- begin
- Action := caNone;
- Break;
- end;
- end;
- end;
- if (HostDockSite is TCnDockPanel) and (HostDockSite.VisibleDockClientCount = 1) and
- (FFloatingChild = nil) then
- // 如果停靠服务器是TDockServer中的DockPanel,就调用ShowDockPanel函数。
- TCnDockPanel(HostDockSite).ShowDockPanel(False, Self);
-
- inherited DoClose(Action);
- FUnDockControl := nil;
- end;
- function TCnDockableForm.GetDockableControl: TWinControl;
- begin
- Result := FDockableControl;
- end;
- procedure TCnDockableForm.SetDockableControl(const Value: TWinControl);
- begin
- FDockableControl := Value;
- end;
- procedure TCnDockableForm.SetUnDockControl(const Value: TControl);
- begin
- FUnDockControl := Value;
- end;
- { TCnConjoinDockHostForm }
- constructor TCnConjoinDockHostForm.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- BorderStyle := ConjoinDockHostBorderStyle;
- end;
- procedure TCnConjoinDockHostForm.DoClose(var Action: TCloseAction);
- begin
- inherited DoClose(Action);
- end;
- { TCnTabDockHostForm }
- constructor TCnTabDockHostForm.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- BorderStyle := TabDockHostBorderStyle;
- end;
- destructor TCnTabDockHostForm.Destroy;
- begin
- inherited;
- end;
- function TCnTabDockHostForm.GetActiveDockForm: TForm;
- begin
- if PageControl.ActivePage.ControlCount = 1 then
- Result := TForm(PageControl.ActivePage.Controls[0])
- else Result := nil;
- end;
- { TCnConjoinPanel }
- constructor TCnConjoinPanel.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Parent := TWinControl(AOwner);
- DockClient := TCnConjoinDockHostForm(AOwner).DockClient;
- Align := alClient;
- BevelOuter := bvNone;
- DoubleBuffered := True;
- ParentFont := False;
- Caption := '';
- end;
- procedure TCnConjoinPanel.DockDrop(Source: TDragDockObject; X, Y: Integer);
- begin
- if Perform(CM_DOCKCLIENT, Integer(Source), Integer(SmallPoint(X, Y))) >= 0 then
- begin
- if Source.Control is TForm then
- begin
- { 下面两行代码是为了防止窗体的标题栏和窗体上面的控件的内容被清空 }
- ParentForm.ActiveControl := nil;
- TForm(Source.Control).ActiveControl := nil;
- { ------------------------------------------------------------------------ }
- SetDockSite(TForm(Source.Control), False);
- if TForm(Source.Control).FormStyle = fsStayOnTop then
- TForm(Parent).FormStyle := fsStayOnTop;
- end;
- UpdateCaption(nil);
- end;
- end;
- procedure TCnConjoinPanel.DoDockOver(Source: TDragDockObject; X,
- Y: Integer; State: TDragState; var Accept: Boolean);
- begin
- { 如果停靠客户是TDockableForm,并且停靠客户上面有TDockClient控件,就同意停靠 }
- Accept := IsDockable(Self, Source.Control, Source.DropOnControl, Source.DropAlign);
- end;
- function TCnConjoinPanel.DoUnDock(NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- ParentForm.FUnDockControl := Client;
- { 如果停靠客户是TDockableForm,就还原停靠客户的DockSite属性为True }
- if not (Client is TCnDockableForm) then
- SetDockSite(TForm(Client), True);
- if (VisibleDockClientCount = 1) or
- (DockClientCount <= 2){ and (NewTarget <> Self) }then
- PostMessage(Parent.Handle, WM_CLOSE, 0, 0);
- UpdateCaption(Client);
- Result := Perform(CM_UNDOCKCLIENT, Integer(NewTarget), Integer(Client)) = 0;
- end;
- function TCnConjoinPanel.GetParentForm: TCnConjoinDockHostForm;
- begin
- Result := TCnConjoinDockHostForm(Parent);
- end;
- procedure TCnConjoinPanel.GetSiteInfo(Client: TControl;
- var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
- begin
- CanDock := IsDockable(Self, Client);
- if CanDock then
- begin
- GetWindowRect(Handle, InfluenceRect);
- end;
- end;
- procedure TCnConjoinPanel.CustomDockDrop(Source: TCnDragDockObject; X,
- Y: Integer);
- begin
- inherited CustomDockDrop(Source, X, Y);
- if Source.Control is TForm then
- begin
- { 下面代码是为了防止窗体的标题栏和窗体上面的控件的内容被清空 }
- ParentForm.ActiveControl := nil;
- if TForm(Source.Control).FormStyle = fsStayOnTop then
- TForm(Parent).FormStyle := fsStayOnTop;
- end;
- UpdateCaption(nil);
- end;
- procedure TCnConjoinPanel.CustomDockOver(Source: TCnDragDockObject; X,
- Y: Integer; State: TDragState; var Accept: Boolean);
- begin
- inherited CustomDockOver(Source, X, Y, State, Accept);
- { 如果停靠客户是TDockableForm,并且停靠客户上面有TDockClient控件,就同意停靠 }
- Accept := IsDockable(Self, Source.Control, Source.DropOnControl, Source.DropAlign);
- end;
- procedure TCnConjoinPanel.CustomEndDock(Target: TObject; X, Y: Integer);
- begin
- inherited CustomEndDock(Target, X, Y);;
- end;
- procedure TCnConjoinPanel.CustomGetSiteInfo(Source: TCnDragDockObject; Client: TControl;
- var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
- begin
- CanDock := IsDockable(Self, Client, Source.DropOnControl, Source.DropAlign);
- inherited CustomGetSiteInfo(Source, Client, InfluenceRect, MousePos, CanDock);
- end;
- procedure TCnConjoinPanel.CustomPositionDockRect(Source: TCnDragDockObject; X, Y: Integer);
- begin
- inherited CustomPositionDockRect(Source, X, Y);
- end;
- procedure TCnConjoinPanel.CustomStartDock(var Source: TCnDragDockObject);
- begin
- ParentForm.FUnDockControl := nil;
- inherited CustomStartDock(Source);
- end;
- function TCnConjoinPanel.CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- ParentForm.FUnDockControl := Client;
- { 如果停靠客户是TDockableForm,就还原停靠客户的DockSite属性为True }
- if not (Client is TCnDockableForm) then
- SetDockSite(TForm(Client), True);
- if ((VisibleDockClientCount = 1) or
- (DockClientCount <= 2)) and (NewTarget <> ParentForm.DockableControl) then
- begin
- PostMessage(Parent.Handle, WM_CLOSE, 0, 0);
- end;
- UpdateCaption(Client);
- Result := inherited CustomUnDock(Source, NewTarget, Client);
- end;
- procedure TCnConjoinPanel.ReloadDockedControl(
- const AControlName: string; var AControl: TControl);
- begin
- AControl := Cn_FindDockFormWithName(AControlName);
- end;
- procedure TCnConjoinPanel.CMUnDockClient(var Message: TCMUnDockClient);
- begin
- inherited;
- { 如果有两个停靠客户,就要释放ParentForm }
- if (DockClientCount = 2) and (VisibleDockClientCount = 1) then
- PostMessage(ParentForm.Handle, WM_CLOSE, 0, 0);
- if VisibleDockClientCount <= 2 then
- CnDockFormControl.UpdateCaption(Self, Message.Client);
- if UseDockManager and (CnDockManager <> nil) then
- CnDockManager.ResetBounds(True);
- end;
- { TCnTabPageControl }
- procedure TCnTabPageControl.AdjustClientRect(var Rect: TRect);
- begin
- inherited AdjustClientRect(Rect);
- case TabPosition of
- tpLeft:
- Inc(Rect.Left, 2);
- tpRight:
- Dec(Rect.Right, 2);
- tpBottom:
- begin
- Dec(Rect.Top, 1);
- Dec(Rect.Bottom, 2);
- end;
- end;
- end;
- constructor TCnTabPageControl.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Parent := TWinControl(AOwner);
- DockClient := FindDockClient(Parent);
- SetDockSite(Self, True);
- PopupMenu := DockPageControlPopupMenu;
- HotTrack := DockPageControlHotTrack;
- DoubleBuffered := True;
- Caption := '';
- FVersion := $00040000;
- end;
- var TabPageStreamEndFlag: Integer = -10;
- destructor TCnTabPageControl.Destroy;
- begin
- SetDockSite(Self, False);
- inherited Destroy;
- end;
- procedure TCnTabPageControl.DockDrop(Source: TDragDockObject; X,
- Y: Integer);
- begin
- if Perform(CM_DOCKCLIENT, Integer(Source), Integer(SmallPoint(X, Y))) >= 0 then
- begin
- if Source.Control is TForm then
- begin
- { 下面一行代码是为了防止窗体的标题栏和窗体上面的控件的内容被清空 }
- TForm(Source.Control).ActiveControl := nil;
- SetDockSite(TWinControl(Source.Control), False);
- if TForm(Source.Control).FormStyle = fsStayOnTop then
- TForm(Parent).FormStyle := fsStayOnTop;
- end;
- UpdateCaption(nil);
- end;
- end;
- function TCnTabPageControl.DoUnDock(NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- { 如果停靠客户是TDockableForm,就还原停靠客户的DockSite属性为True }
- if not (Client is TCnDockableForm) then
- SetDockSite(TForm(Client), True);
- if (VisibleDockClientCount = 1) or
- (DockClientCount <= 2){ and (NewTarget <> Self) }then
- PostMessage(Parent.Handle, WM_CLOSE, 0, 0);
- UpdateCaption(Client);
- Result := Perform(CM_UNDOCKCLIENT, Integer(NewTarget), Integer(Client)) = 0;
- end;
- function TCnTabPageControl.GetParentForm: TCnTabDockHostForm;
- begin
- Result := TCnTabDockHostForm(Parent);
- end;
- procedure TCnTabPageControl.LoadFromStream(Stream: TStream);
- var i, Count, NameLen, SheetVisible, ActiveSheetIndex: Integer;
- ControlName: string;
- AControl: TControl;
- begin
- try
- Stream.Read(i, Sizeof(i));
- { 从流中读出标签的个数,并且依次从流中读出她们的信息 }
- Stream.Read(Count, Sizeof(Count));
- for i := 0 to Count - 1 do
- begin
- ControlName := '';
- { 读出名字的长度 }
- Stream.Read(NameLen, SizeOf(NameLen));
- if NameLen > 0 then
- begin
- { 读出名字的字符串 }
- SetLength(ControlName, NameLen);
- Stream.Read(Pointer(ControlName)^, NameLen * SizeOf(Char));
- end;
- if ControlName <> '' then
- begin
- { 找到名字为ControlName的停靠窗体,并且把她停靠进TCnTabPageControl }
- ReloadDockedControl(ControlName, AControl);
- if AControl <> nil then
- AControl.ManualDock(Self, nil, alClient);
- end;
- { 读出标签的Visible }
- Stream.Read(SheetVisible, SizeOf(SheetVisible));
- DockClients[i].Visible := Boolean(SheetVisible);
- end;
- { 读出被激活的标签 }
- Stream.Read(ActiveSheetIndex, SizeOf(ActiveSheetIndex));
- ActivePageIndex := ActiveSheetIndex;
- finally
- end;
- end;
- procedure TCnTabPageControl.SaveToStream(Stream: TStream);
- var i, Count, NameLen, SheetVisible, ActiveSheetIndex: Integer;
- ControlName: string;
- CurrentControl: TControl;
- begin
- { 写入流的版本 }
- Stream.Write(FVersion, SizeOf(FVersion));
- Count := PageCount;
- { 写入TabSheet的个数 }
- Stream.Write(Count, SizeOf(Count));
- for i := 0 to PageCount - 1 do
- begin
- CurrentControl := Pages[i].Controls[0];
- ControlName := CurrentControl.Name;
- NameLen := Length(ControlName);
- { 写入名字的长度 }
- Stream.Write(NameLen, SizeOf(NameLen));
- { 写入名字 }
- if NameLen > 0 then Stream.Write(Pointer(ControlName)^, NameLen * SizeOf(Char));
- SheetVisible := 0;
- if (Self is TCnVSNETTabPageControl) and (ParentForm.HostDockSite is TCnDockPanel) then
- SheetVisible := Integer(TCnVSNETDockTabSheet(Pages[i]).OldVisible)
- else
- SheetVisible := SheetVisible + Integer(CurrentControl.Visible);
- { 写入是否可见 }
- Stream.Write(SheetVisible, SizeOf(SheetVisible));
- end;
- ActiveSheetIndex := ActivePageIndex;
- { 写入激活的TabSheet的索引 }
- Stream.Write(ActiveSheetIndex, SizeOf(ActiveSheetIndex));
- { 写入结束标志 }
- Stream.Write(TabPageStreamEndFlag, SizeOf(TabPageStreamEndFlag));
- end;
- procedure TCnTabPageControl.CustomDockDrop(Source: TCnDragDockObject; X,
- Y: Integer);
- var DragDockObject: TDragDockObject;
- begin
- if Source.DropAlign in [alClient, alNone] then
- begin
- DragDockObject := TDragDockObject.Create(Source.Control);
- try
- DragDockObject.DockRect := Source.DockRect;
- DragDockObject.Control := Source.Control;
- Perform(CM_DOCKCLIENT, Integer(DragDockObject), Integer(SmallPoint(X, Y)));
- UpdateCaption(nil);
- finally
- DragDockObject.Free;
- end;
- end else
- begin
- inherited CustomDockDrop(Source, X, Y);
- end;
- if Source.Control is TForm then
- begin
- { 下面一行代码是为了防止窗体的标题栏和窗体上面的控件的内容被清空 }
- TForm(Source.Control).ActiveControl := nil;
- { ------------------------------------------------------------------------ }
- SetDockSite(TForm(Source.Control), False);
- end;
- end;
- procedure TCnTabPageControl.CustomDockOver(Source: TCnDragDockObject; X,
- Y: Integer; State: TDragState; var Accept: Boolean);
- var ARect: TRect;
- begin
- inherited CustomDockOver(Source, X, Y, State, Accept);
- { 如果停靠客户上面有TDockClient控件,就同意停靠 }
- Accept := IsDockable(Self, Source.Control, Source.DropOnControl, Source.DropAlign);
- // 画停靠客户的预览停靠位置
- if Accept then
- begin
- ComputeDockingRect(self, ARect,
- Point(ClientWidth div 2, ClientHeight div 2));
- Source.DockRect := ARect;
- end;
- end;
- procedure TCnTabPageControl.CustomEndDock(Target: TObject; X, Y: Integer);
- begin
- inherited CustomEndDock(Target, X, Y);
- end;
- procedure TCnTabPageControl.CustomGetSiteInfo(Source: TCnDragDockObject; Client: TControl;
- var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
- begin
- inherited CustomGetSiteInfo(Source, Client, InfluenceRect, MousePos, CanDock);
- CanDock := IsDockable(Self, Client, Source.DropOnControl, Source.DropAlign);
- end;
- procedure TCnTabPageControl.CustomPositionDockRect(
- Source: TCnDragDockObject; X, Y: Integer);
- begin
- inherited CustomPositionDockRect(Source, X, Y);
- end;
- procedure TCnTabPageControl.CustomStartDock(var Source: TCnDragDockObject);
- begin
- inherited CustomStartDock(Source);
- end;
- function TCnTabPageControl.CustomUnDock(Source: TCnDragDockObject; NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- { 如果停靠客户是TDockableForm,就还原停靠客户的DockSite属性为True }
- if not (Client is TCnDockableForm) then
- SetDockSite(TForm(Client), True);
- if (VisibleDockClientCount = 1) or
- (DockClientCount <= 2) then
- PostMessage(Parent.Handle, WM_CLOSE, 0, 0);
- UpdateCaption(Client);
- Result := Perform(CM_UNDOCKCLIENT, Integer(NewTarget), Integer(Client)) = 0;
- end;
- procedure TCnTabPageControl.ReloadDockedControl(
- const AControlName: string; var AControl: TControl);
- begin
- AControl := Cn_FindDockFormWithName(AControlName);
- end;
- procedure TCnTabPageControl.CustomGetDockEdge(Source: TCnDragDockObject;
- MousePos: TPoint; var DropAlign: TAlign);
- var ARect: TRect;
- begin
- ARect := Source.DockRect;
- DropAlign := ComputeDockingRect(Source.Control, ARect, MousePos);
- end;
- { TCnBasicDockStyle }
- constructor TCnBasicDockStyle.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- { 设置一些默认的类的引用 }
- CnDockPanelClass := DefaultDockPanelClass;
- CnDockSplitterClass := DefaultDockSplitterClass;
- CnConjoinPanelClass := DefaultConjoinPanelClass;
- CnTabDockClass := DefaultTabDockClass;
- CnDockPanelTreeClass := DefaultDockTreeClass;
- CnDockPanelZoneClass := DefaultDockZoneClass;
- CnConjoinPanelTreeClass := DefaultDockTreeClass;
- CnConjoinPanelZoneClass := DefaultDockZoneClass;
- FCnConjoinServerOptionClass := TCnBasicConjoinServerOption;
- FCnTabServerOptionClass := TCnBasicTabServerOption;
- FDockBaseControlList := TList.Create;
- if AOwner is TCustomForm then
- FParentForm := TForm(AOwner)
- else FParentForm := nil;
- if not (csDesigning in ComponentState) then
- begin
- { 保存老的窗口过程 }
- FOldWindowProc := FParentForm.WindowProc;
- { 重载窗口过程 }
- FParentForm.WindowProc := ParentFormWindowProc;
- end;
- end;
- function TCnBasicDockStyle.GetControlName: string;
- begin
- Result := gs_CnDockStyleName;
- end;
- function TCnBasicDockStyle.GetDockStyleVersion: string;
- begin
- Result := gs_CnDockStyleVersion;
- end;
- procedure TCnBasicDockStyle.SetDockBaseControl(IsCreate: Boolean;
- DockBaseControl: TCnDockBaseControl);
- begin
- { 没有事做 }
- end;
- procedure TCnBasicDockStyle.FormDockDrop(DockClient: TCnDockClient; Source: TCnDragDockObject; X,
- Y: Integer);
- var
- ARect,DRect: TRect;
- DockType: TAlign;
- Host: TCustomForm;
- APanelDock: TWinControl;
- begin
- if IsDockable(DockClient.ParentForm, Source.Control, Source.DropOnControl, Source.DropAlign) then
- begin
- Host := nil;
- { 锁住Windows桌面 }
- if not IsLoading then
- Cn_LockWindow(nil);
- try
- // 调用ComputeDockingRect函数知道停靠的类型
- with DockClient do
- begin
- DockType := ComputeDockingRect(DockClient.ParentForm, ARect, Point(X, Y));
- if (ParentForm.HostDockSite is TCnDockPanel) then
- begin
- // 如果停靠服务器是TDockPanel,就停靠在TDockServer的DockPanel上。
- if DockType = alClient then
- begin
- // 如果停靠类型是alClient
- if Source.Control is TCnTabDockHostForm then
- begin
- // 如果停靠客户是TCnTabDockHostForm,
- // 就先把Parent停靠到TCnTabDockHostForm中,
- // 再把TCnTabDockHostForm停靠到TCnDockPanel中。
- APanelDock := ParentForm.HostDockSite;
- ARect := ParentForm.BoundsRect;
- ParentForm.ManualDock(TCnTabDockHostForm(Source.Control).PageControl, nil, alClient);
- TCnTabDockHostForm(Source.Control).PageControl.ActivePage.PageIndex := 0;
- Source.Control.BoundsRect := ARect;
- Source.Control.ManualDock(APanelDock, nil, alClient);
- if ParentForm.FormStyle = fsStayOnTop then
- TForm(Source.Control).FormStyle := fsStayOnTop;
- end else
- begin
- // 否则就创建TCnTabDockHostForm,
- // 把把Parent停靠到TCnTabDockHostForm中,
- // 再把TCnTabDockHostForm停靠到TCnDockPanel中。
- APanelDock := ParentForm.HostDockSite;
- DRect.TopLeft := ParentForm.HostDockSite.ClientToScreen(Point(0, 0));
- Host := CreateTabHostAndDockControl(ParentForm, Source.Control);
- SetDockSite(ParentForm, False);
- SetDockSite(TWinControl(Source.Control), False);
- Host.Top := DRect.Top;
- Host.Left := DRect.Left;
- Host.ManualDock(APanelDock, nil, alClient);
- Host.Visible := True;
- end;
- end
- else
- begin
- // 如果停靠类型不是alClient,
- // 就把停靠窗体停靠到TCnDockPanel.
- DRect := ParentForm.HostDockSite.BoundsRect;
- Source.Control.ManualDock(ParentForm.HostDockSite, nil, DockType);
- ParentForm.HostDockSite.BoundsRect := DRect;
- end;
- Exit;
- end;
- // 创建分页的服务窗体
- if DockType = alClient then
- begin
- Host := CreateTabHostAndDockControl(ParentForm, Source.Control);
- SetDockSite(ParentForm, False);
- SetDockSite(TWinControl(Source.Control), False);
- Host.Visible := True;
- end
- // 创建平铺的服务窗体
- else if DockType <> alNone then
- begin
- Host := CreateConjoinHostAndDockControl(ParentForm, Source.Control, DockType);
- SetDockSite(ParentForm, False);
- SetDockSite(TWinControl(Source.Control), False);
- Host.Visible := True;
- end;
- if Host <> nil then
- begin
- Host.LRDockWidth := Source.Control.LRDockWidth;
- Host.TBDockHeight := Source.Control.TBDockHeight;
- end;
- end;
- finally
- { 解锁Windows桌面 }
- if not IsLoading then
- Cn_UnLockWindow;
- end;
- end;
- end;
- procedure TCnBasicDockStyle.FormDockOver(DockClient: TCnDockClient; Source: TCnDragDockObject; X,
- Y: Integer; State: TDragState; var Accept: Boolean);
- var
- ARect: TRect;
- begin
- with DockClient do
- begin
- Accept := EnableDock and EachOtherDock and
- IsDockable(ParentForm.HostDockSite, Source.Control, Source.DropOnControl, Source.DropAlign);
- if Accept and (State = dsDragMove) and
- (ComputeDockingRect(ParentForm, ARect, Point(X, Y)) <> alNone) then
- Source.DockRect := ARect;
- end;
- end;
- procedure TCnBasicDockStyle.FormEndDock(DockClient: TCnDockClient; Target: TObject; X, Y: Integer);
- begin
- { 没事做 }
- end;
- procedure TCnBasicDockStyle.FormPositionDockRect(DockClient: TCnDockClient;
- Source: TCnDragDockObject);
- var
- NewWidth, NewHeight: Integer;
- TempX, TempY: Double;
- begin
- with Source do
- begin
- if (DragTarget = nil) or (not TCnWinControlAccess(DragTarget).UseDockManager) then
- begin
- NewWidth := Control.UndockWidth;
- NewHeight := Control.UndockHeight;
- // Drag position for dock rect is scaled relative to control's click point.
- TempX := DragPos.X - ((NewWidth) * MouseDeltaX);
- TempY := DragPos.Y - ((NewHeight) * MouseDeltaY);
- with DockRect do
- begin
- Left := Round(TempX);
- Top := Round(TempY);
- Right := Left + NewWidth;
- Bottom := Top + NewHeight;
- end;
- { Allow DragDockObject final say on this new dock rect }
- AdjustDockRect(DockRect);
- end
- else begin
- GetWindowRect(TargetControl.Handle, DockRect);
- if TCnWinControlAccess(DragTarget).UseDockManager then
- begin
- if TargetControl is TCnCustomDockPanel then
- begin
- if (TCnCustomDockPanel(DragTarget).CnDockManager <> nil) then
- TCnCustomDockPanel(DragTarget).CnDockManager.PositionDockRect(Control,
- DropOnControl, DropAlign, DockRect);
- end;
- end;
- end;
- end;
- end;
- procedure TCnBasicDockStyle.GetComponentInfo(var AName, Author, Email, Comment: string);
- begin
- // 基类不干
- end;
- procedure TCnBasicDockStyle.FormStartDock(DockClient: TCnDockClient; var Source: TCnDragDockObject);
- begin
- { 没事做 }
- end;
- function TCnBasicDockStyle.FormUnDock(DockClient: TCnDockClient; NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- Result := True;
- end;
- procedure TCnBasicDockStyle.FormGetSiteInfo(Source: TCnDragDockObject;
- DockClient: TCnDockClient;
- Client: TControl; var InfluenceRect: TRect; MousePos: TPoint;
- var CanDock: Boolean);
- begin
- with DockClient do
- CanDock := EnableDock and EachOtherDock and
- IsDockable(ParentForm, Client, Source.DropOnControl, Source.DropAlign);
- end;
- function TCnBasicDockStyle.DockClientWindowProc(DockClient: TCnDockClient; var Message: TMessage): Boolean;
- begin
- { 默认要执行原来的消息过程 }
- Result := False;
- end;
- procedure TCnBasicDockStyle.FormGetDockEdge(DockClient: TCnDockClient;
- Source: TCnDragDockObject; MousePos: TPoint; var DropAlign: TAlign);
- begin
- DropAlign := TCnControlAccess(DockClient.ParentForm).GetDockEdge(MousePos);
- end;
- procedure TCnBasicDockStyle.SetConjoinServerOption(
- const Value: TCnBasicConjoinServerOption);
- begin
- FCnConjoinServerOption.Assign(Value);
- end;
- procedure TCnBasicDockStyle.SetTabServerOption(
- const Value: TCnBasicTabServerOption);
- begin
- FCnTabServerOption.Assign(Value);
- end;
- procedure TCnBasicDockStyle.CreateConjoinServerOption(
- var Option: TCnBasicConjoinServerOption);
- begin
- Option := TCnBasicConjoinServerOption.Create(Self);
- end;
- procedure TCnBasicDockStyle.CreateTabServerOption(
- var Option: TCnBasicTabServerOption);
- begin
- Option := TCnBasicTabServerOption.Create(Self);
- end;
- procedure TCnBasicDockStyle.CreateServerOption;
- begin
- if FCnConjoinServerOption = nil then
- FCnConjoinServerOption := FCnConjoinServerOptionClass.Create(Self);
- if FCnTabServerOption = nil then
- FCnTabServerOption := FCnTabServerOptionClass.Create(Self);
- end;
- function TCnBasicDockStyle.GetConjoinServerOption: TCnBasicConjoinServerOption;
- begin
- Result := FCnConjoinServerOption;
- end;
- function TCnBasicDockStyle.GetTabServerOption: TCnBasicTabServerOption;
- begin
- Result := FCnTabServerOption;
- end;
- procedure TCnBasicDockStyle.FreeServerOption;
- begin
- if FCnConjoinServerOption <> nil then
- FCnConjoinServerOption.Free;
- if FCnTabServerOption <> nil then
- FCnTabServerOption.Free;
- end;
- destructor TCnBasicDockStyle.Destroy;
- begin
- if not (csDesigning in ComponentState) then
- begin
- if @FOldWindowProc <> nil then
- FParentForm.WindowProc := FOldWindowProc;
- FOldWindowProc := nil;
- end;
- FDockBaseControlList.Free;
- FreeServerOption;
- inherited Destroy;
- end;
- procedure TCnBasicDockStyle.AssignConjoinServerOption(
- APanel: TCnCustomDockPanel);
- begin
- APanel.CnDockManager.GrabberSize := ConjoinServerOption.GrabbersSize;
- APanel.CnDockManager.SplitterWidth := ConjoinServerOption.SplitterWidth;
- end;
- procedure TCnBasicDockStyle.AssignTabServerOption(
- APage: TCnTabPageControl);
- begin
- APage.HotTrack := TabServerOption.HotTrack;
- APage.TabPosition := TabServerOption.TabPosition;
- end;
- procedure TCnBasicDockStyle.Loaded;
- begin
- inherited;
- end;
- procedure TCnBasicDockStyle.AfterConstruction;
- begin
- inherited AfterConstruction;
- CreateServerOption;
- end;
- procedure TCnBasicDockStyle.ParentFormWindowProc(var Message: TMessage);
- begin
- if not (csDesigning in ComponentState) then
- begin
- if Assigned(FOldWindowProc) then
- FOldWindowProc(Message);
- end;
- end;
- procedure TCnBasicDockStyle.AddDockBaseControl(
- ADockBaseControl: TCnDockBaseControl);
- begin
- if ADockBaseControl = nil then Exit;
- if FDockBaseControlList.IndexOf(ADockBaseControl) = -1 then
- begin
- FDockBaseControlList.Add(ADockBaseControl);
- ConjoinServerOption.ResetDockControlOption;
- TabServerOption.ResetDockControlOption;
- end;
- end;
- procedure TCnBasicDockStyle.RemoveDockBaseControl(
- ADockBaseControl: TCnDockBaseControl);
- begin
- if ADockBaseControl = nil then Exit;
- FDockBaseControlList.Remove(ADockBaseControl);
- end;
- procedure TCnBasicDockStyle.ResetDockControlConjoinOption;
- begin
- end;
- procedure TCnBasicDockStyle.ResetDockControlTabOption;
- begin
- end;
- function TCnBasicDockStyle.GetDockBaseControlListCount: Integer;
- begin
- Result := FDockBaseControlList.Count;
- end;
- function TCnBasicDockStyle.GetDockBaseControlLists(
- Index: Integer): TCnDockBaseControl;
- begin
- Result := FDockBaseControlList[Index];
- end;
- function TCnBasicDockStyle.DockServerWindowProc(DockServer: TCnDockServer;
- var Message: TMessage): Boolean;
- begin
- { 默认要执行原来的消息过程 }
- Result := False;
- end;
- function TCnBasicDockStyle.GetDockState(
- DockClient: TCnDockClient): Integer;
- begin
- Result := DS_Unknow;
- if (DockClient <> nil) and (DockClient.ParentForm <> nil) then
- begin
- if DockClient.ParentForm.Floating then
- Result := DS_Floating
- else Result := DS_Docking;
- end;
- end;
- function TCnBasicDockStyle.CanSetBottomDocked(ADockBaseControl: TCnDockBaseControl): Boolean;
- begin
- Result := True;
- end;
- function TCnBasicDockStyle.CanSetEachOtherDocked(ADockBaseControl: TCnDockBaseControl): Boolean;
- begin
- Result := True;
- end;
- function TCnBasicDockStyle.CanSetEnableDocked(ADockBaseControl: TCnDockBaseControl): Boolean;
- begin
- Result := True;
- end;
- function TCnBasicDockStyle.CanSetLeftDocked(ADockBaseControl: TCnDockBaseControl): Boolean;
- begin
- Result := True;
- end;
- function TCnBasicDockStyle.CanSetRightDocked(ADockBaseControl: TCnDockBaseControl): Boolean;
- begin
- Result := True;
- end;
- function TCnBasicDockStyle.CanSetTopDocked(ADockBaseControl: TCnDockBaseControl): Boolean;
- begin
- Result := True;
- end;
- procedure TCnBasicDockStyle.ResetCursor(Source: TCnDragDockObject);
- begin
- if (Source.TargetControl = nil) and (Source.Control <> nil) and (Source.Control.Floating) then
- Windows.SetCursor(Screen.Cursors[crDefault])
- else if (Source.TargetControl = nil) and (not GlobalDockClient.CanFloat) then
- Windows.SetCursor(Screen.Cursors[crNo])
- else
- Windows.SetCursor(Screen.Cursors[crDefault]);
- end;
- procedure TCnBasicDockStyle.HideDockForm(ADockClient: TCnDockClient);
- begin
- { 调用窗体上的TCnDockClient的MakeHideEvent函数 }
- if ADockClient <> nil then
- begin
- ADockClient.ParentForm.Visible := False;
- ADockClient.MakeHideEvent;
- end;
- end;
- procedure TCnBasicDockStyle.ShowDockForm(ADockClient: TCnDockClient);
- begin
- { 调用窗体上的TCnDockClient的MakeShowEvent函数 }
- if ADockClient <> nil then
- begin
- ADockClient.ParentForm.Visible := True;
- ADockClient.MakeShowEvent;
- end;
- end;
- function TCnBasicDockStyle.GetDockFormVisible(ADockClient: TCnDockClient): Boolean;
- begin
- Result := True;
- if ADockClient <> nil then
- begin
- if ADockClient.ParentForm.Visible then
- begin
- if ADockClient.ParentForm.HostDockSite <> nil then
- begin
- if ADockClient.ParentForm.HostDockSite is TCnDockPanel then
- Result := ADockClient.ParentForm.HostDockSite.Width * ADockClient.ParentForm.HostDockSite.Height > 0
- else
- Result := GetFormVisible(ADockClient.ParentForm.HostDockSite.Parent);
- end;
- end else Result := False;
- end;
- end;
- procedure TCnBasicDockStyle.RestoreClient(DockClient: TCnDockClient);
- var TmpLastDockSite: TWinControl;
- TmpUnDockLeft, TmpUnDockTop: Integer;
- i: Integer;
- ADockClient: TCnDockClient;
- ADockServer: TCnDockServer;
- ARect: TRect;
- procedure DoFloatParentForm;
- begin
- with DockClient do
- begin
- if (ParentForm.HostDockSite <> nil) then
- begin
- ARect := Bounds(TmpUnDockLeft, TmpUnDockTop, ParentForm.UndockWidth, ParentForm.UndockHeight);
- ParentForm.ManualFloat(ARect);
- if (ParentForm.Left <> ARect.Left) or (ParentForm.Top <> ARect.Top) then
- begin
- ParentForm.Left := ARect.Left;
- ParentForm.Top := ARect.Top;
- end;
- end;
- end;
- end;
- begin
- if DockClient = nil then Exit;
- if not DockClient.CanFloat then Exit;
- with DockClient do
- begin
- { 必须是能够符合停靠条件的才行 }
- if not EnableDock then Exit;
- if LastDockSite is TCnDockPanel then
- begin
- with TCnDockPanel(LastDockSite) do
- begin
- { 对于停靠客户 }
- if ((not LeftDock) and (Align = alLeft)) or
- ((not RightDock) and (Align = alRight)) or
- ((not TopDock) and (Align = alTop)) or
- ((not BottomDock) and (Align = alBottom)) then
- begin
- DoFloatParentForm;
- Exit;
- end;
- { 对于停靠服务器 }
- ADockServer := DockServer;
- if ADockServer <> nil then
- if (not ADockServer.EnableDock) or
- ((not ADockServer.LeftDock) and (Align = alLeft)) or
- ((not ADockServer.RightDock) and (Align = alRight)) or
- ((not ADockServer.TopDock) and (Align = alTop)) or
- ((not ADockServer.BottomDock) and (Align = alBottom)) then
- begin
- DoFloatParentForm;
- Exit;
- end;
- end;
- end;
- if ParentForm is TCnConjoinDockHostForm then
- begin
- with TCnConjoinDockHostForm(ParentForm).Panel do
- begin
- for i := DockClientCount - 1 downto 0 do
- begin
- ADockClient := FindDockClient(DockClients[i]);
- if (ADockClient <> nil) and (ADockClient.LastDockSite is TCnDockPanel) then
- ADockClient.RestoreChild;
- end;
- end;
- Exit;
- end;
- { 保存原先的LastDockSite,因为在调用一些函数后会覆盖掉原先的LastDockSite }
- TmpLastDockSite := LastDockSite;
- TmpUnDockLeft := UnDockLeft;
- TmpUnDockTop := UnDockTop;
- { 重新设置DockClient的一些属性 }
- ResetDockClient(DockClient, nil);
- DoFloatParentForm;
- if TmpLastDockSite is TCnDockPanel then
- begin
- with TCnDockPanel(TmpLastDockSite) do
- begin
- if UseDockManager and (CnDockManager <> nil) then
- begin
- if not CnDockManager.HasZoneWithControl(ParentForm) then Exit;
- DisableAlign;
- try
- { 调用ParentForm的Dock函数把ParentForm停靠到LastDockSite中 }
- ParentForm.Dock(TmpLastDockSite, Rect(0,0,0,0));
- { 由于在LastDockSite的CnDockManager接口中已经有一个ParentForm的Zone,
- 所以只要把它show出来就可以了 }
- CnDockManager.ShowControl(ParentForm);
- { 下面一行代码是为了防止窗体的标题栏和窗体上面的控件的内容被清空 }
- ParentForm.ActiveControl := nil;
- SetDockSite(ParentForm, False);
- { 使ParentForm获得焦点 }
- if ParentForm.Visible and ParentForm.CanFocus then
- ParentForm.SetFocus;
- ShowDockPanel(True, ParentForm, sdfDockPanel);
- finally
- EnableAlign;
- end;
- end;
- end;
- end;
- end;
- end;
- { TCnAdvDockStyle }
- function TCnAdvDockStyle.DockClientWindowProc(DockClient: TCnDockClient;
- var Message: TMessage): Boolean;
- begin
- if (DockClient <> nil) and (Message.Msg = WM_NCLBUTTONDBLCLK) then
- if DockClient.CanFloat then
- DockClient.RestoreChild;
- Result := inherited DockClientWindowProc(DockClient, Message);
- end;
- { TCnDockSplitter }
- constructor TCnDockSplitter.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- AutoSnap := False;
- end;
- function TCnDockSplitter.FindControl: TControl;
- begin
- if DockServer <> nil then
- Result := DockServer.GetDockPanelWithAlign(Align)
- else
- Result := inherited FindControl;
- end;
- function TCnDockSplitter.GetSplitterIndex: Integer;
- begin
- case Align of
- alTop: Result := 0;
- alBottom: Result := 1;
- alLeft: Result := 2;
- alRight: Result := 3;
- else
- Result := -1;
- end;
- end;
- { TCnBasicServerOption }
- procedure TCnBasicServerOption.Assign(Source: TPersistent);
- begin
- if Source is TCnBasicServerOption then
- begin
- end;
- inherited Assign(Source);
- end;
- constructor TCnBasicServerOption.Create(ADockStyle: TCnBasicDockStyle);
- begin
- FDockStyle := ADockStyle;
- end;
- destructor TCnBasicServerOption.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TCnBasicServerOption.ResetDockClientOption(
- ADockClient: TCnDockClient);
- begin
- // 本来这个函数是一个纯虚函数,但是不知道怎么回事编译要出错,只好改成一般的虚函数
- end;
- procedure TCnBasicServerOption.ResetDockServerOption(
- ADockServer: TCnDockServer);
- begin
- // 本来这个函数是一个纯虚函数,但是不知道怎么回事编译要出错,只好改成一般的虚函数
- end;
- { TCnBasicTabServerOption }
- procedure TCnBasicTabServerOption.Assign(Source: TPersistent);
- begin
- if Source is TCnBasicTabServerOption then
- begin
- FTabPosition := TCnBasicTabServerOption(Source).FTabPosition;
- FHotTrack := TCnBasicTabServerOption(Source).FHotTrack;
- end;
- inherited Assign(Source);
- end;
- constructor TCnBasicTabServerOption.Create(ADockStyle: TCnBasicDockStyle);
- begin
- inherited Create(ADockStyle);
- FHotTrack := False;
- FTabPosition := tpTop;
- end;
- destructor TCnBasicTabServerOption.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TCnBasicTabServerOption.ResetDockClientOption(
- ADockClient: TCnDockClient);
- var PageControl: TCnTabPageControl;
- begin
- if ADockClient = nil then Exit;
- { 得到这个ADockClient所在的窗体的PageControl }
- PageControl := TCnTabPageControl(TCnTabDockHostForm(ADockClient.ParentForm).PageControl);
- ResetTabPageControl(PageControl);
- if PageControl <> nil then
- PageControl.Invalidate;
- end;
- procedure TCnBasicTabServerOption.ResetDockControlOption;
- var i: Integer;
- ADockClient: TCnDockClient;
- begin
- { 循环DockStyle的DockBaseControlList列表,然后把每一个
- TCnDockClient取出来,然后调用各自的函数重新设置它们的选项 }
- for i := 0 to DockStyle.DockBaseControlListCount - 1 do
- begin
- if DockStyle.DockBaseControlLists[i] is TCnDockClient then
- begin
- ADockClient := TCnDockClient(DockStyle.DockBaseControlLists[i]);
- if ADockClient.ParentForm is TCnTabDockHostForm then
- begin
- { 重新设置TCnDockClient的选项 }
- ResetDockClientOption(ADockClient);
- end;
- end;
- end;
- end;
- procedure TCnBasicTabServerOption.ResetDockServerOption(
- ADockServer: TCnDockServer);
- begin
- { do nothing }
- end;
- procedure TCnBasicTabServerOption.ResetTabPageControl(
- APage: TCnTabPageControl);
- begin
- if APage = nil then Exit;
- APage.HotTrack := FHotTrack;
- APage.TabPosition := FTabPosition;
- end;
- procedure TCnBasicTabServerOption.SetHotTrack(const Value: Boolean);
- begin
- if FHotTrack <> Value then
- begin
- FHotTrack := Value;
- ResetDockControlOption;
- end;
- end;
- procedure TCnBasicTabServerOption.SetTabPosition(
- const Value: TTabPosition);
- begin
- if FTabPosition <> Value then
- begin
- FTabPosition := Value;
- ResetDockControlOption;
- end;
- end;
- { TCnBasicConjoinServerOption }
- procedure TCnBasicConjoinServerOption.Assign(Source: TPersistent);
- begin
- if Source is TCnBasicConjoinServerOption then
- begin
- FGrabbersSize := TCnBasicConjoinServerOption(Source).FGrabbersSize;
- FSplitterWidth := TCnBasicConjoinServerOption(Source).FSplitterWidth;
- end;
- inherited Assign(Source);
- end;
- constructor TCnBasicConjoinServerOption.Create(
- ADockStyle: TCnBasicDockStyle);
- begin
- inherited Create(ADockStyle);
- GrabbersSize := 12;
- SplitterWidth := 4;
- end;
- destructor TCnBasicConjoinServerOption.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TCnBasicConjoinServerOption.ResetConjoinPanel(
- APanel: TCnConjoinPanel);
- begin
- APanel.CnDockManager.GrabberSize := FGrabbersSize;
- APanel.CnDockManager.SplitterWidth := FSplitterWidth;
- end;
- procedure TCnBasicConjoinServerOption.ResetDockClientOption(
- ADockClient: TCnDockClient);
- var
- ConjoinPanel: TCnConjoinPanel;
- begin
- if ADockClient = nil then Exit;
- { 得到这个ADockClient所在的窗体的Panel }
- ConjoinPanel := TCnConjoinPanel(TCnConjoinDockHostForm(ADockClient.ParentForm).Panel);
- ResetConjoinPanel(ConjoinPanel);
- ConjoinPanel.Invalidate;
- end;
- procedure TCnBasicConjoinServerOption.ResetDockControlOption;
- var
- i: Integer;
- ADockServer: TCnDockServer;
- ADockClient: TCnDockClient;
- begin
- if DockStyle = nil then Exit;
- { 循环DockStyle的DockBaseControlList列表,然后把每一个TCnDockServer或者
- TCnDockClient取出来,然后调用各自的函数重新设置它们的选项 }
- for i := 0 to DockStyle.DockBaseControlListCount - 1 do
- begin
- if DockStyle.DockBaseControlLists[i] is TCnDockServer then
- begin
- { 重新设置TCnDockServer的选项 }
- ADockServer := TCnDockServer(DockStyle.DockBaseControlLists[i]);
- ResetDockServerOption(ADockServer);
- end else if DockStyle.DockBaseControlLists[i] is TCnDockClient then
- begin
- ADockClient := TCnDockClient(DockStyle.DockBaseControlLists[i]);
- if ADockClient.ParentForm.HostDockSite is TCnConjoinPanel then
- begin
- { 重新设置TCnDockClient的选项 }
- ADockClient := FindDockClient(ADockClient.ParentForm.HostDockSite.Parent);
- ResetDockClientOption(ADockClient);
- end;
- end;
- end;
- end;
- procedure TCnBasicConjoinServerOption.ResetDockPanel(APanel: TCnDockPanel);
- begin
- APanel.CnDockManager.GrabberSize := FGrabbersSize;
- APanel.CnDockManager.SplitterWidth := FSplitterWidth;
- end;
- procedure TCnBasicConjoinServerOption.ResetDockServerOption(
- ADockServer: TCnDockServer);
- var
- i: Integer;
- begin
- // Panel必须不能为空
- if ADockServer = nil then Exit;
- for i := 0 to 3 do
- begin
- if ADockServer.DockPanel[i] = nil then
- break;
- ResetDockPanel(ADockServer.DockPanel[i]);
- ADockServer.DockPanel[i].Invalidate;
- end;
- end;
- procedure TCnBasicConjoinServerOption.SetGrabbersSize(
- const Value: TGrabbersSize);
- begin
- if FGrabbersSize <> Value then
- begin
- FGrabbersSize := Value;
- ResetDockControlOption;
- end;
- end;
- procedure TCnBasicConjoinServerOption.SetGrabbersSize_WithoutChangeSystemInfo(
- const Value: TGrabbersSize);
- begin
- FGrabbersSize := Value;
- end;
- procedure TCnBasicConjoinServerOption.SetSplitterWidth(
- const Value: TSplitterWidth);
- begin
- if FSplitterWidth <> Value then
- begin
- FSplitterWidth := Value;
- ResetDockControlOption;
- end;
- end;
- procedure TCnBasicConjoinServerOption.SetSplitterWidth_WithoutChangeSystemInfo(
- const Value: TSplitterWidth);
- begin
- FSplitterWidth := Value;
- end;
- { TCnAdvTabPageControl }
- procedure TCnAdvTabPageControl.CMUnDockClient(
- var Message: TCMUnDockClient);
- begin
- inherited;
- end;
- procedure TCnAdvTabPageControl.CustomDockDrop(Source: TCnDragDockObject; X,
- Y: Integer);
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, Source.TargetControl);
- inherited;
- end;
- function TCnAdvTabPageControl.CustomUnDock(Source: TCnDragDockObject;
- NewTarget: TWinControl; Client: TControl): Boolean;
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, NewTarget);
- Result := inherited CustomUnDock(Source, NewTarget, Client)
- end;
- destructor TCnAdvTabPageControl.Destroy;
- var DockClient: TCnDockClient;
- begin
- DockClient := FindDockClient(Parent);
- if (DockClient <> nil) and (DockClient.LastDockSite is TCnDockPanel) then
- begin
- with TCnDockPanel(DockClient.LastDockSite) do
- begin
- if UseDockManager and (CnDockManager <> nil) then
- CnDockManager.RemoveControl(Self.Parent);
- end;
- end;
- inherited;
- end;
- procedure TCnAdvTabPageControl.DockDrop(Source: TDragDockObject; X,
- Y: Integer);
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, TControl(Source.DragTarget));
- inherited;
- end;
- function TCnAdvTabPageControl.DoUnDock(NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Client, NewTarget);
- Result := inherited DoUnDock(NewTarget, Client);
- end;
- { TCnAdvConjoinPanel }
- procedure TCnAdvConjoinPanel.CMUnDockClient(var Message: TCMUnDockClient);
- begin
- inherited;
- end;
- procedure TCnAdvConjoinPanel.CustomDockDrop(Source: TCnDragDockObject; X,
- Y: Integer);
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, Source.TargetControl);
- inherited;
- end;
- function TCnAdvConjoinPanel.CustomUnDock(Source: TCnDragDockObject;
- NewTarget: TWinControl; Client: TControl): Boolean;
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, NewTarget);
- Result := inherited CustomUnDock(Source, NewTarget, Client)
- end;
- procedure TCnAdvConjoinPanel.DockDrop(Source: TDragDockObject; X,
- Y: Integer);
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Source.Control, TControl(Source.DragTarget));
- inherited;
- end;
- function TCnAdvConjoinPanel.DoUnDock(NewTarget: TWinControl;
- Client: TControl): Boolean;
- begin
- // 设置Client上的TCnDockClient控件的LastDockSite
- if not IsLoading then
- ResetDockClient(Client, NewTarget);
- Result := inherited DoUnDock(NewTarget, Client);
- end;
- { Initialization and cleanup }
- procedure InitDockPresident;
- var OSVERSIONINFO: TOSVERSIONINFO;
- begin
- { 创建一个TCnDockPresident的实例 }
- if CnGlobalDockPresident <> nil then
- CnGlobalDockPresident.Free;
- CnGlobalDockPresident := TCnDockPresident.Create;
- { 判断当前操作系统的版本, 是WindowsXP还是其他, 以后会用到的 }
- OSVERSIONINFO.dwOSVersionInfoSize := sizeof(TOSVERSIONINFO);
- GetVersionEx(OSVERSIONINFO);
- IsWinXP := (OSVERSIONINFO.dwMajorVersion = 5) and (OSVERSIONINFO.dwMinorVersion = 1);
- end;
- procedure DoneDockPresident;
- begin
- { 释放这个TCnDockPresident的实例 }
- if CnGlobalDockPresident <> nil then
- begin
- CnGlobalDockPresident.Free;
- CnGlobalDockPresident := nil;
- end;
- end;
- initialization
- InitDockPresident;
- finalization
- DoneDockPresident;
- end.
|