You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

KOL.PAS 1.8MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984
  1. //[START OF KOL.pas]
  2. {****************************************************************
  3. KKKKK KKKKK OOOOOOOOO LLLLL
  4. KKKKK KKKKK OOOOOOOOOOOOO LLLLL
  5. KKKKK KKKKK OOOOO OOOOO LLLLL
  6. KKKKK KKKKK OOOOO OOOOO LLLLL
  7. KKKKKKKKKK OOOOO OOOOO LLLLL
  8. KKKKK KKKKK OOOOO OOOOO LLLLL
  9. KKKKK KKKKK OOOOO OOOOO LLLLL
  10. KKKKK KKKKK OOOOOOOOOOOOO LLLLLLLLLLLLL
  11. KKKKK KKKKK OOOOOOOOO LLLLLLLLLLLLL
  12. Key Objects Library (C) 2000-2007 by Kladov Vladimir.
  13. WinCE port by Yury Sidorov.
  14. This library is free software and may be redistributed and/or modified under
  15. the terms of the wxWindows Library License, Version 3 or (at your option)
  16. any later version. The full license is in the LICENSE.txt file included
  17. with this distribution.
  18. This library is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. wxWindows Library License for more details.
  22. //[VERSION]
  23. ****************************************************************
  24. * VERSION 2.80.3
  25. ****************************************************************
  26. //[END OF VERSION]
  27. K.O.L. - is a set of objects to create small programs
  28. with the Delphi, but without the VCL. KOL allows to
  29. create executables of size about 10 times smaller then
  30. those created with the VCL. But this does not mean that
  31. KOL is less power then the VCL - perhaps just the opposite...
  32. Copyright (C) 2000-2007 by Vladimir Kladov.
  33. mailto: bonanzas@online.sinor.ru
  34. Web-Page: http://bonanzas.rinet.ru
  35. WinCE port by Yury Sidorov, yury_sidorov@mail.ru
  36. See also Mirror Classes Kit (M.C.K.) which allows
  37. to create KOL programs visually.
  38. ****************************************************************}
  39. //[UNIT DEFINES]
  40. {$ifdef FPC} {$mode delphi} {$endif FPC}
  41. {$I KOLDEF.inc}
  42. {$IFDEF EXTERNAL_KOLDEFS}
  43. {$INCLUDE PROJECT_KOL_DEFS.INC}
  44. {$ENDIF}
  45. {$IFDEF EXTERNAL_DEFINES}
  46. {$INCLUDE EXTERNAL_DEFINES.INC}
  47. {$ENDIF EXTERNAL_DEFINES}
  48. {$DEFINE GDI}
  49. {$UNDEF LIN} {$UNDEF WIN} {$UNDEF GDI}
  50. {$IFDEF LINUX}
  51. {$DEFINE LIN}
  52. {$DEFINE PAS_VERSION}
  53. {$DEFINE NOT_USE_RICHEDIT}
  54. {$IFNDEF GTK}
  55. {$IFNDEF XQT}
  56. {$DEFINE GTK} // it is also possible to define GTK as a project option
  57. {$ENDIF XQT} // even for Windows system
  58. {$ENDIF GTK}
  59. {$ELSE} // to exploit GTK under Win32 rather then native GDI
  60. {$DEFINE WIN}
  61. {$DEFINE GDI}
  62. {$ENDIF}
  63. {$IFDEF GTK} {$UNDEF GDI} {$DEFINE _X_}
  64. {$DEFINE NOT_USE_RICHEDIT}
  65. {$ENDIF}
  66. //{$IFDEF Q_T} {$UNDEF GDI} {$DEFINE _X_} {$ENDIF}
  67. {$IFDEF WIN} {$IFDEF GDI}
  68. {$DEFINE WIN_GDI}
  69. {$ENDIF GDI} {$ENDIF WIN}
  70. {$INCLUDE delphidef.inc}
  71. {$IFDEF WIN_GDI}
  72. //test
  73. {$ENDIF WIN_GDI}
  74. {$IFDEF LIN}
  75. //test
  76. {$ENDIF LIN}
  77. //[START OF UNIT]
  78. unit KOL;
  79. {-}
  80. (*
  81. {*
  82. Please note, that KOL does not use keyword 'class'. Instead,
  83. poor Pascal 'object' is the base of our objects. So, remember,
  84. how we worked earlier with such Object Pascal's objects:
  85. |<br>
  86. - to create objects dynamically, use P<objname> instead of
  87. T<objname> to allocate a pointer for dynamically created
  88. object instance;
  89. |<br>
  90. - remember, that constructors of objects can not be virtual.
  91. Override procedure Init instead in your own derived objects;
  92. |<br>
  93. - rather then call constructors of objects, call global procedures
  94. New<objname> (e.g. NewLabel). If not, first (for virtualally
  95. created objects) call New( ); then call constructor Create
  96. (which calls Init) - but this is possible only if the constructor
  97. is overriden by a new one.
  98. |<br>
  99. - the operator 'is' is not applicable to objects. And operator 'as'
  100. is not necessary (and is not applicable too), use typecast to desired
  101. object type, e.g.: "PSomeObjectType( C )" inplace of "C as TSomeClassType".
  102. |<br>
  103. |<hr>
  104. Also remember, that IF [ MyObj: PMyObj ] THEN
  105. NOT[ with MyObj do ] BUT[ with MyObj^ do ]
  106. Though it is possible to skip '^' symbol when accessing member
  107. fields, methods, properties, e.g. [ MyObj.Execute; ]
  108. |<hr>
  109. |&U=&nbsp;&nbsp;&nbsp;<a href="#%0">%0</a><br>
  110. |&B=<a href="%1.htm">%0</a><br>
  111. |&C=<a href="%1.htm">%0</a>
  112. | <table border=1 cellpadding=6 width=100%>
  113. | <colgroup valign=top span=2>
  114. | <tr>
  115. | <td> objects </td> <td> functions by category </td>
  116. | </tr>
  117. | <td>
  118. <C _TObj> <B TObj>
  119. <C TList> <C TListEx> <C TStrList> <B TStrListEx>
  120. <C TTree> <C TDirList> <C TIniFile> <C TCabFile>
  121. <B TStream>
  122. <B TControl>
  123. <C TGraphicTool> <C TCanvas> <C TImageList> <C TIcon> <C TBitmap>
  124. <C TGif> <C TGifDecoder> <B TJpeg>
  125. <C TTimer> <C TThread> <C TTrayIcon> <C TDirChange> <B TMediaPlayer>
  126. <C TMenu> <C TOpenSaveDialog> <C TOpenDirDialog> <B TColorDialog>
  127. <C TAction> <B TActionList>
  128. <B Exception>
  129. | </td>
  130. | <td>
  131. |<a href="kol_pas.htm#visual_objects_constructors">
  132. Visual objects constructing functions
  133. |</a><br><br>
  134. <U Working with null-terminated and ansi strings>
  135. <U Small bit arrays (max 32 bits in array)>
  136. <U Arithmetics, geometry and other utility functions>
  137. <U Data sorting (quicksort implementation)>
  138. <U String to number and number to string conversions>
  139. <U 64-bit integer numbers>
  140. <U Floating point numbers>
  141. <U Date and time handling>
  142. <U File and directory routines>
  143. <U System functions and working with windows>
  144. <U Text in clipboard operations>
  145. <U Wrappers to registry API functions>
  146. <U WinCE specific functions>
  147. | </td>
  148. | </table>
  149. Several conditional symbols can be used in a project
  150. (Project | Options | Directories/Conditional Defines)
  151. to change code generated a bit. There are following:
  152. |<pre>
  153. LINUX - version for Linux (only PAS_VERSION)
  154. PAS_VERSION - to use Pascal version of the code.
  155. PARANOIA - to force short versions of asm instructions (for D5
  156. and below, D6 and higher use those instructions always).
  157. SMALLEST_CODE - to create minimal code application (affected:
  158. (o) SimpleGetCtlBrushHandle - returns solid silver brush
  159. always;
  160. (o) _NewWindowed
  161. - only default system font used by default;
  162. font of the parent control is not applied to its
  163. children automatically (but see SMALLEST_CODE_PARENTFONT);
  164. - fBrush always set to NIL by default (parent Brush
  165. is not applied);
  166. (o) WndProcDoEraseBkgnd
  167. - child controls windows are not created in WM_ERASEBKGND
  168. if were not created earlier (in most case, all OK
  169. with this - controls are created BTW);
  170. - SetBkColor, SetBkMode, SetBrushOrgEx are not
  171. called (all OK therefore)
  172. (o) by default, NOT_UNLOAD_RICHEDITLIB is defined if
  173. UNLOAD_RICHEDITLIB is not defined in project options
  174. (this minimizes finalization section).
  175. (o) _NewControl
  176. - BoundsRect initialized with a rectangle
  177. (aParent.fMarginLeft, aParent.fMarginTop,
  178. aParent.fMarginLeft+64, aParent.fMargin+64)
  179. rather then with (aParent.fMargin+aParent.fMarginLeft,
  180. aParent.fMargin+aParent.fMarginTop,
  181. aParent.fMargin+aParent.fMarginLeft+64,
  182. aParent.fMargin+aParent.fMarginTop+64).
  183. In most cases this is enough.
  184. (o) Int2Hex
  185. there are no check for second perameter > 15
  186. (o) .... other see in code
  187. SMALLER_CODE - like smallest code, but fuctionality is the same.
  188. The speed can be lower therefore.
  189. SMALLEST_CODE_PARENTFONT - Parent font therefore is applied for child controls,
  190. but initially only.
  191. USE_NAMES - to use property Name with any TObj. This makes also
  192. available method TObj.FindObj( name ): PObj.
  193. (USE_CONSTRUCTORS - to use constructors like in VCL. Note: this option is
  194. not carefully tested!)
  195. USE_CUSTOMEXTENSIONS - to extend TControl with custom additions.
  196. UNICODE_CTRLS - to use Unicode versions of controls (WM_XXXXW messages,
  197. etc.)
  198. USE_MHTOOLTIP - to use MHTOOLTIP.
  199. USE_OnIdle - to use OnIdle event
  200. ENUM_DYN_HANDLERS_AFTER_RUN - to allow all the events handling even when
  201. AppletTerminated become TRUE.
  202. BUTTON_DBLCLICK - to prevent clicking buttons with double click,
  203. this takes smaller code but buttons can not
  204. be pressed with mouse fast. When SMALLEST_CODE on,
  205. this option also is on.
  206. ALL_BUTTONS_RESPOND_TO_ENTER - obvious (by default, buttons respond to key
  207. SPACE, since those are working this way in Windows).
  208. CLICK_DEFAULT_CANCEL_BTN_DIRECTLY - to prevent visual effect of default/cancel
  209. button pressing with Enter/Escape keys. Also, button
  210. don't become focused in such case.
  211. DEFAULT_CANCEL_BTN_EXCLUSIVE - to disable assigning to a button properties
  212. DefaultBtn and CancelBtn simultaneously.
  213. NO_DEFAULT_BUTTON_BOLD - to prevent DefaultBtn to be visually with
  214. a bold border.
  215. BITBTN_DISABLEDGLYPH2 - to restore old behaviour of multi-glyph bitbtn, when
  216. index 2 was used to represent the button in disabled
  217. state, and glyph with index 1 was used forpressed dtate.
  218. Now by default index 1 corresponds to the disabled state,
  219. and index 2 to the pressed state, i.e. these are swapped.
  220. ESC_CLOSE_DIALOGS - to allow closing all dialogs with ESCAPE.
  221. KEY_PREVIEW - form also receive WM_KEYDOWN (OnKeyDown event fired)
  222. SUPPORT_ONDEADCHAR - to support OnKeyDeadChar event in responce to
  223. WM_DEADCHAR, WM_SYSDEADCHAR
  224. OpenSaveDialog_Extended - to allow using custom extensions for OpenSaveDialog.
  225. AUTO_CONTEXT_HELP - to use automatic respond to WM_CONTEXTMENU to call
  226. context help.
  227. NOT_FIX_CURINDEX - to use old version of TControl.SetItems, which could
  228. lead to loose CurIndex value (e.g. for Combobox)
  229. NOT_FIX_MODAL - not to fix modal (if fixed, click on any window
  230. activates the application. If not fixed, code is
  231. smaller very a little, but only click on modal form
  232. activates the application). This does not fix calling
  233. MsgBox though.
  234. NEW_MODAL - to use extended modalness.
  235. USE_SETMODALRESULT - to guarantee ModalResult property assigning handling.
  236. USE_MENU_CURCTL - to use CurCtl property in popup menu to detect which
  237. control initiated a pop-up.
  238. NEW_MENU_ACCELL - to use new menu accelerators handling, without
  239. AcceleratorTable (not tested for all cases)
  240. USE_DROPDOWNCOUNT - to force setting combobox dropdown count.
  241. NOT_UNLOAD_RICHEDITLIB - to stop unload Rich Edit library in finalization
  242. section (to economy several byte of code).
  243. NOT_USE_RICHEDIT - not use richedit (it will not be possible to create richedit)
  244. USE_PROP - to use GetProp / SetProp (old style) in place of
  245. Get / SetWindowLong( wnd, GWL_USERDATA... ) (slower?)
  246. PROVIDE_EXITCODE - PostQuitMessage( value ) assigns value to ExitCode
  247. INITIALFORMSIZE_FIXMENU - form size initially is really the same as defined at
  248. design time even for forms having main menu bar
  249. USE_GRAPHCTLS - to use graphic (non-windowed) controls
  250. GRAPHCTL_XPSTYLES - to use XP themed Visual styles for drawing graphic
  251. controls. This does not affect windowed controls
  252. which visual style is controlled by the manifest.
  253. GRAPHCTL_HOTTRACK - to use hot-tracking also together with XP themed
  254. graphic controls (otherwise only static XP themed
  255. view is provided). Also, turn this option on if you
  256. want to handle OnMouseEnter and OnMouseLeabe events
  257. for graphic controls.
  258. ICON_DIFF_WH - to support icons having Width <> Height
  259. AUTO_REPLACE_CLEARTYPE- to replace automatically CLEARTYPE_QUALITY fonts
  260. with ANTIALIASED_QUALITY when running under elder
  261. Windows version than XP.
  262. NEW_GRADIENT - to use new gradient painting by homm (fast).
  263. OLD_ALIGN - to prevent using new Align by Galkov (new Align is faster).
  264. FILE_EXISTS_EX - to use more correct (but a bit large code in FileExists functon)
  265. NOT_USE_AUTOFREE4CONTROLS - from 2.40, most of control sub-objects are destroying
  266. using Add2AutoFree (smaller code). This option returns
  267. to previous behaviour (to compare size). Will be
  268. deprecated in future versions.
  269. ENDSESSION_HALT - to halt the process when WM_ENDSESSION comes.
  270. FILESTREAM_POSITION - in PAS_VERSION, Stream..fData.fPosition always show
  271. current position (for debug purposes)
  272. PSEUDO_THREADS - to use pseudo-threads instead of normal threads.
  273. WAIT_SLEEP - to sleep 10 ms in WaitForMultipleObjects loop (for PSEUDO_THREADS)
  274. DEBUG_MENU - to debug menu.
  275. DEBUG_GDIOBJECTS - to allow counting all the GDI objects used.
  276. CHK_BITBLT - to check BitBlt operations.
  277. DEBUG_ENDSESSION - to allow debugging WM_ENDSESSION handling.
  278. DEBUG_CREATEWINDOW - to debug CreateWindow.
  279. CRASH_DEBUG - to fill object memory with $DD before freeing it
  280. (program really crashes when the object is
  281. attempted to destroy more then once and in most
  282. cases when a destroyed object is accessed after the
  283. destruction).
  284. DEBUG - other debugging.
  285. EXTERNAL_DEFINES - if count of options necessary to set is very large
  286. Delphi ignores past of those. To avoid this problem,
  287. set only this option in Project's options, and place
  288. all other options to ExternalDefines.inc file as a
  289. sequence of {$DEFINE ... directives.
  290. But note, such file should be located in a
  291. project directory, but not in the directory where KOL.pas
  292. is located. This is enough to provide different sets
  293. of defines for each project.
  294. |</pre>
  295. }
  296. *)
  297. {= K.O.L - êëþ÷åâàÿ áèáëèîòåêà îáúåêòîâ. (C) Êëàäîâ Âëàäèìèð, 2000-2003.
  298. }
  299. //[OPTIONS]
  300. {$ifdef cpu86}
  301. {$A-} // align off, otherwise code is not good
  302. {$endif cpu86}
  303. {+}
  304. {$Q-} // no overflow check: this option makes code wrong
  305. {$R-} // no range checking: this option makes code wrong
  306. {$T-} // not typed @-operator
  307. //{$D+}
  308. //______________________________________________________________________________
  309. //
  310. //{$DEFINE INPACKAGE} // Uncomment this line while rebuild MCK package
  311. // for Delphi3 only, then restore the comment mark!!!!!!!!!!!!!!!!!!!!
  312. //______________________________________________________________________________
  313. {$IFDEF INPACKAGE} // use this symbol in packages requiring kol.pas
  314. {$WARNINGS OFF}
  315. {$DEFINE NOT_USE_AUTOFREE4CONTROLS}
  316. {$DEFINE PAS_VERSION}
  317. {$UNDEF ASM_VERSION}
  318. {$UNDEF ASM_UNICODE}
  319. {$ENDIF}
  320. {$IFDEF _D7orHigher}
  321. {$WARN UNSAFE_TYPE OFF} // Too many such warnings in Delphi7
  322. {$WARN UNSAFE_CODE OFF}
  323. {$WARN UNSAFE_CAST OFF}
  324. {$ENDIF}
  325. //[START OF INTERFACE]
  326. interface
  327. {$IFDEF NEW_ALIGN}
  328. {$UNDEF OLD_ALIGN}
  329. {$ELSE}
  330. {$IFNDEF OLD_ALIGN}
  331. {$DEFINE NEW_ALIGN}
  332. {$ENDIF}
  333. {$ENDIF}
  334. {$IFDEF OLD_ALIGN}
  335. {$UNDEF NEW_ALIGN}
  336. {$ELSE}
  337. {$IFNDEF NEW_ALIGN}
  338. {$DEFINE NEW_ALIGN}
  339. {$ENDIF}
  340. {$ENDIF}
  341. {$IFNDEF OLD_TRANSPARENT}
  342. {$DEFINE NEW_TRANSPARENT}
  343. {$ENDIF}
  344. {$IFNDEF NOT_USE_AUTOFREE4CONTROLS}
  345. {$DEFINE USE_AUTOFREE4CONTROLS}
  346. {$DEFINE USE_AUTOFREE4CHILDREN}
  347. {$ENDIF}
  348. {$IFDEF SMALLEST_CODE}
  349. {$DEFINE NOT_UNLOAD_RICHEDITLIB}
  350. {$DEFINE SMALLER_CODE}
  351. {$ENDIF}
  352. {$IFDEF NOT_USE_RICHEDIT}
  353. {$DEFINE NOT_UNLOAD_RICHEDITLIB}
  354. {$ENDIF}
  355. //{$DEFINE DEBUG_GDIOBJECTS}
  356. //{$DEFINE CHK_GDI}
  357. //[USES]
  358. uses {$IFDEF WIN}messages, windows {$IFNDEF NOT_USE_RICHEDIT}, RichEdit {$ENDIF}{$ENDIF WIN}
  359. {$IFDEF LIN}Libc, Xlib{$ENDIF}
  360. {$IFDEF GTK}, Glib2 , Gdk2, Gtk2, pango {$ENDIF GTK}
  361. {$IFDEF CHK_GDI}, ChkGdi {$ENDIF}
  362. {$ifdef FPC}{$ifdef wince}{$ifndef VER2_2_0},commctrl,commdlg,aygshell,shellapi{$endif}{$endif}{$endif};
  363. //[END OF USES]
  364. {$IFDEF LIN}
  365. {$DEFINE global_declare} {$I KOL_Linux.inc} {$UNDEF global_declare}
  366. ////type HDC = TGC; // from Xlib (temporary definition?)
  367. {$ENDIF LIN}
  368. {$ifdef wince}
  369. {$R KOL-CE.rc}
  370. {$endif wince}
  371. var
  372. AppTheming: boolean;
  373. {$IFDEF DEBUG_GDIOBJECTS}
  374. var
  375. BrushCount: Integer;
  376. FontCount: Integer;
  377. PenCount: Integer;
  378. {$ENDIF}
  379. {$IFDEF UNICODE_CTRLS}
  380. {$IFDEF _D2}
  381. {$ERROR 'Delphi 2 cannot compile with UNICODE_CTRLS defined!'}
  382. {$ENDIF}
  383. const
  384. SizeOfKOLChar = SizeOf(WideChar);
  385. {$ifdef wince}
  386. I_SKIP = -2;
  387. {$endif wince}
  388. type
  389. KOLString = WideString;
  390. KOL_String = type WideString;
  391. KOLChar = type WideChar;
  392. PKOLChar = PWideChar;
  393. PKOL_Char = type PWideChar;
  394. {$ELSE}
  395. const
  396. SizeOfKOLChar = SizeOf(AnsiChar);
  397. type
  398. KOLString = String;
  399. KOL_String = type String;
  400. KOLChar = type AnsiChar;
  401. PKOLChar = PAnsiChar;
  402. PKOL_Char = type PAnsiChar;
  403. {$IFDEF ASM_VERSION}
  404. {$DEFINE ASM_UNICODE}
  405. {$UNDEF PAS_VERSION}
  406. {$ENDIF}
  407. {$ENDIF}
  408. {$IFNDEF ASM_VERSION}
  409. {$DEFINE PAS_VERSION}
  410. {$ENDIF ASM_VERSION}
  411. {BCB++}(*type DWORD = Windows.DWORD;*){--BCB}
  412. {$IFDEF WIN}
  413. //{_#IF [DELPHI]}
  414. {$IFDEF WIN32}
  415. {$INCLUDE delphicommctrl.inc}
  416. {$IFDEF UNICODE_CTRLS}
  417. {$DEFINE interface_part} {$I KOL_unicode.inc} {$UNDEF interface_part}
  418. {$ENDIF UNICODE_CTRLS}
  419. {$ENDIF WIN32}
  420. //{_#ENDIF}
  421. {$ENDIF WIN}
  422. type
  423. //[_TObj DEFINITION]
  424. {-}
  425. _TObj = object
  426. {* auxiliary object type. See TObj. }
  427. protected
  428. procedure Init; virtual;
  429. {* Is called from a constructor to initialize created object instance
  430. filling its fields with 0. Can be overriden in descendant objects
  431. to add another initialization code there. (Main reason of intending
  432. is what constructors can not be virtual in poor objects). }
  433. {= Âûçûâàåòñÿ äëÿ èíèöèàëèçàöèè îáúåêòà. }
  434. public
  435. function VmtAddr: Pointer;
  436. {* Returns addres of virtual methods table of object. ? }
  437. {= âîçâðàùàåò àäðåñ òàáëèöû âèðòóàëüíûõ ìåòîäîâ (VMT). ? }
  438. end;
  439. {+}
  440. {++}(* TObj = class;*){--}
  441. PObj = {-}^{+}TObj;
  442. {* }
  443. {++}(* TList = class;*){--}
  444. PList = {-}^{+}TList;
  445. {* }
  446. //[TObjectMethod DECLARATION]
  447. TObjectMethod = procedure of object;
  448. {* }
  449. TOnEvent = procedure( Sender: PObj ) of object;
  450. {* This type of event is the most common - event handler when called can
  451. know only what object was a sender of this call. Replaces good known
  452. VCL TNotifyEvent event type. }
  453. TOnEventMoving = procedure( Sender: PObj; P: PRect ) of object;
  454. //[TPointerList DECLARATION]
  455. PPointerList = ^TPointerList;
  456. TPointerList = array[0..MaxInt div 4 - 1] of Pointer;
  457. { ---------------------------------------------------------------------
  458. TObj - base object to derive all others
  459. ---------------------------------------------------------------------- }
  460. //[TObj DEFINITION]
  461. TObj = {-} object( _TObj ) {+}{++}(*class*){--}
  462. {* Prototype for all objects of KOL. All its methods are important to
  463. implement objects in a manner similar to Delphi TObject class. }
  464. {= Áàçîâûé êëàññ äëÿ âñåõ ïðî÷èõ îáúåêòîâ KOL. }
  465. protected
  466. fRefCount: Integer;
  467. fOnDestroy: TOnEvent;
  468. {$IFDEF OLD_REFCOUNT}
  469. procedure DoDestroy;
  470. {$ENDIF}
  471. protected
  472. fAutoFree: PList;
  473. {* Is called from a constructor to initialize created object instance
  474. filling its fields with 0. Can be overriden in descendant objects
  475. to add another initialization code there. (Main reason of intending
  476. is what constructors can not be virtual in poor objects). }
  477. {= Âûçûâàåòñÿ äëÿ èíèöèàëèçàöèè îáúåêòà. }
  478. fTag: DWORD;
  479. {* Custom data. }
  480. public
  481. destructor Destroy; {-} virtual; {+}{++}(* override; *){--}
  482. {* Disposes memory, allocated to an object. Does not release huge strings,
  483. dynamic arrays and so on. Such memory should be freeing in overriden
  484. destructor. }
  485. {= Îñâîáîæäàåò ïàìÿòü, âûäåëåííóþ äëÿ îáúåêòà. Íå îñâîáîæäàåò ïàìÿòü, âûäåëåííóþ
  486. äëÿ ñòðîê, äèíàìè÷èñêèõ ìàññèâîâ è ò.ï. Òàêàÿ ïàìÿòü äîëæíà áûòü îñâîáîæäåíà
  487. â ïåðåîïðåäåëåííîì äåñòðóêòîðå îáúåêòà. }
  488. {++}(*protected*){--}
  489. {++}(*
  490. procedure Init; virtual;
  491. {* Can be overriden in descendant objects
  492. to add initialization code there. (Main reason of intending
  493. is what constructors can not be virtual in poor objects). }
  494. *){--}
  495. procedure Final;
  496. {* It is called in destructor to perform OnDestroy event call and to
  497. released objects, added to fAutoFree list. }
  498. public
  499. procedure RefInc;
  500. {* See comments below. }
  501. {= Ñì. RefDec íèæå. }
  502. function RefDec: Integer;
  503. {* Decrements reference count. If it is becoming <0, and Free
  504. method was already called, object is (self-) destroyed. Otherwise,
  505. Free method does not destroy object, but only sets flag
  506. "Free was called".
  507. |<br>
  508. Use RefInc..RefDec to provide a block of code, where
  509. object can not be destroyed by call of Free method.
  510. This makes code more safe from intersecting flows of processing,
  511. where some code want to destroy object, but others suppose that it
  512. is yet existing.
  513. |<br>
  514. If You want to release object at the end of block RefInc..RefDec,
  515. do it immediately BEFORE call of last RefDec (to avoid situation,
  516. when object is released in result of RefDec, and attempt to
  517. destroy it follow leads to AV exception).
  518. |<br>
  519. Actually, this "function" is a procedure and does not return
  520. any sensible value. It is declared as a function for internal
  521. needs (to avoid creating separate code for Free method)
  522. }
  523. {= Óìåíüøàåò ñ÷åò÷èê èñïîëüçîâàíèÿ. Åñëè â ðåçóëüòàòå ñ÷åò÷èê ñòàíîâèòñÿ
  524. < 0, è ìåòîä Free óæå áûë âûçâàí, îáúåêò (ñàìî-) ðàçðóøàåòñÿ. Èíà÷å,
  525. ìåòîä Free íå ðàçðóøàåò îáúåêò, à òîëüêî óñòàíàâëèâàåò ôëàã "Free áûë
  526. âûçâàí".
  527. |<br>
  528. Èñïîëüçóéòå RefInc..RefDec äëÿ ïðåäîòâðàùåíèÿ ðàçðóøåíèÿ îáúåêòà íà
  529. íåêîòîðîì ó÷àñòêå êîäà (åñëè åñòü òàêàÿ íåîáõîäèìîñòü).
  530. |<br>
  531. Åñëè íóæíî óáèòü (âðåìåííûé) îáúåêò âìåñòå ñ ïîñëåäíèì RefDec, ñäåëàéòå
  532. âûçîâ Free íåìåäëåííî ÏÅÐÅÄ ïîñëåäíèì RefDec. }
  533. property RefCount: Integer read fRefCount;
  534. {* }
  535. {$IFDEF OLD_FREE}
  536. procedure Free;
  537. {$ELSE NEW_FREE}
  538. property Free: Integer read RefDec;
  539. {* Before calling destructor of object, checks if passed pointer is not
  540. nil - similar what is done in VCL for TObject. It is ALWAYS recommended
  541. to use Free instead of Destroy - see also comments to RefInc, RefDec. }
  542. {= Äî âûçîâà äåñòðóêòîðà, ïðîâåðÿåò, íå ïåðåäàí ëè nil â êà÷åñòâå ïàðàìåòðà.
  543. ÂÑÅÃÄÀ ðåêîìåíäóåòñÿ èñïîëüçîâàòü Free âìåñòî Destroy - ñì. òàê æå RefInc,
  544. RefDec. }
  545. {$ENDIF NEW_FREE}
  546. {-}
  547. // By Vyacheslav Gavrik:
  548. function InstanceSize: Integer;
  549. {* Returns a size of object instance. }
  550. {+}
  551. constructor Create;
  552. {* Constructor. Do not call it. Instead, use New<objectname> function
  553. call for certain object, e.g., NewLabel( AParent, 'caption' ); }
  554. {= Êîíñòðóêòîð. Íå ñëåäóåò âûçûâàòü åãî. Äëÿ êîíñòðóèðîâàíèÿ îáúåêòîâ,
  555. âûçûâàéòå ñîîòâåòñòâóþùóþ ãëîáàëüíóþ ôóíêöèþ New<èìÿ-îáúåêòà>. Íàïðèìåð,
  556. NewLabel( MyForm, 'Ìåòêà¹1' ); }
  557. {-}
  558. class function AncestorOfObject( Obj: Pointer ): Boolean;
  559. {* Is intended to replace 'is' operator, which is not applicable to objects. }
  560. {= }
  561. function VmtAddr: Pointer;
  562. {* Returns addres of virtual methods table of object. }
  563. {= âîçâðàùàåò àëðåñ òàáëèöû âèðòóàëüíûõ ìåòîäîâ (VMT). }
  564. {+}
  565. property OnDestroy: TOnEvent read fOnDestroy write fOnDestroy;
  566. {* This event is provided for any KOL object, so You can provide your own
  567. OnDestroy event for it. }
  568. {= Äàííîå ñîáûòèå îáåñïå÷èâàåòñÿ äëÿ âñåõ îáúåêòîâ KOL. Ïîçâîëÿåò ñäåëàòü
  569. ÷òî-íèáóäü â ñâÿçè ñ ðàçðóøåíèåì îáúåêòà. }
  570. procedure Add2AutoFree( Obj: PObj );
  571. {* Adds an object to the list of objects, destroyed automatically
  572. when the object is destroyed. Do not add here child controls of
  573. the TControl (these are destroyed by another way). Only non-control
  574. objects, which are not destroyed automatically, should be added here. }
  575. procedure Add2AutoFreeEx( Proc: TObjectMethod );
  576. {* Adds an event handler to the list of events, called in destructor.
  577. This method is mainly for internal use, and allows to auto-destroy
  578. VCL components, located on KOL form at design time (in MCK project). }
  579. procedure RemoveFromAutoFree( Obj: PObj );
  580. {* Removes an object from auto-free list }
  581. procedure RemoveFromAutoFreeEx( Proc: TObjectMethod );
  582. {* Removes a procedure from auto-free list }
  583. property Tag: DWORD read fTag write fTag;
  584. {* Custom data field. }
  585. protected
  586. {$IFDEF USE_NAMES}
  587. fName: String;
  588. fNamedObjList: Plist;
  589. fOwnerObj: PObj;
  590. {$ENDIF}
  591. public
  592. {$IFDEF USE_NAMES}
  593. procedure SetName( NewOwnerObj: PObj; const NewName: String);
  594. property Name: string read FName;
  595. property NamedObjList : PList read fNamedObjList;
  596. property OwnerObj: PObj read FOwnerObj;
  597. function FindObj(const ObjName: string): PObj;
  598. {$ENDIF}
  599. end;
  600. //[END OF TObj DEFINITION]
  601. { ---------------------------------------------------------------------
  602. TList - object to implement list of pointers (or dwords)
  603. ---------------------------------------------------------------------- }
  604. //[TList DEFINITION]
  605. TList = object( TObj )
  606. {* Simple list of pointers. It is used in KOL instead of standard VCL
  607. TList to store any kind data (or pointers to these ones). Can be created
  608. calling function NewList. }
  609. {= Ïðîñòîé ñïèñîê óêàçàòåëåé. }
  610. protected
  611. fItems: PPointerList;
  612. fCount: Integer;
  613. fCapacity: Integer;
  614. fAddBy: Integer;
  615. procedure SetCount(const Value: Integer);
  616. procedure SetAddBy(Value: Integer);
  617. {++}(*public*){--}
  618. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  619. {* Destroys list, freeing memory, allocated for pointers. Programmer
  620. is resposible for destroying of data, referenced by the pointers. }
  621. {= }
  622. {++}(*protected*){--}
  623. procedure SetCapacity( Value: Integer );
  624. function Get( Idx: Integer ): Pointer;
  625. procedure Put( Idx: Integer; Value: Pointer );
  626. {$IFDEF USE_CONSTRUCTORS}
  627. procedure Init; virtual;
  628. {$ENDIF}
  629. protected
  630. {$IFDEF TLIST_FAST}
  631. fUseBlocks: Boolean;
  632. fBlockList: PList;
  633. fLastKnownBlockIdx: Integer;
  634. fLastKnownCountBefore: Integer;
  635. {$ENDIF}
  636. public
  637. procedure Clear;
  638. {* Makes Count equal to 0. Not responsible for freeing (or destroying)
  639. data, referenced by released pointers. }
  640. procedure Add( Value: Pointer );
  641. {* Adds pointer to the end of list, increasing Count by one. }
  642. procedure Insert( Idx: Integer; Value: Pointer );
  643. {* Inserts pointer before given item. Returns Idx, i.e. index of
  644. inserted item in the list. Indeces of items, located after insertion
  645. point, are increasing. To add item to the end of list, pass Count
  646. as index parameter. To insert item before first item, pass 0 there. }
  647. function IndexOf( Value: Pointer ): Integer;
  648. {* Searches first (from start) item pointer with given value and returns
  649. its index (zero-based) if found. If not found, returns -1. }
  650. procedure Delete( Idx: Integer );
  651. {* Deletes given (by index) pointer item from the list, shifting all
  652. follow item indeces up by one. }
  653. procedure DeleteRange( Idx, Len: Integer );
  654. {* Deletes Len items starting from Idx. }
  655. procedure Remove( Value: Pointer );
  656. {* Removes first entry of a Value in the list. }
  657. property Count: Integer read fCount write SetCount;
  658. {* Returns count of items in the list. It is possible to delete a number
  659. of items at the end of the list, keeping only first Count items alive,
  660. assigning new value to Count property (less then Count it is). }
  661. property Capacity: Integer read fCapacity write SetCapacity;
  662. {* Returns number of pointers which could be stored in the list
  663. without reallocating of memory. It is possible change this value
  664. for optimize usage of the list (for minimize number of reallocating
  665. memory operations). }
  666. property Items[ Idx: Integer ]: Pointer read Get write Put; default;
  667. {* Provides access (read and write) to items of the list. Please note,
  668. that TList is not responsible for freeing memory, referenced by stored
  669. pointers. }
  670. function Last: Pointer;
  671. {* Returns the last item (or nil, if the list is empty). }
  672. procedure Swap( Idx1, Idx2: Integer );
  673. {* Swaps two items in list directly (fast, but without testing of
  674. index bounds). }
  675. procedure MoveItem( OldIdx, NewIdx: Integer );
  676. {* Moves item to new position. Pass NewIdx >= Count to move item
  677. after the last one. }
  678. procedure Release;
  679. {* Especially for lists of pointers to dynamically allocated memory.
  680. Releases all pointed memory blocks and destroys object itself. }
  681. procedure ReleaseObjects;
  682. {* Especially for a list of objects derived from TObj.
  683. Calls Free for every of the object in the list, and then calls
  684. Free for the object itself. }
  685. property AddBy: Integer read fAddBy write SetAddBy;
  686. {* Value to increment capacity when new items are added or inserted
  687. and capacity need to be increased. }
  688. property DataMemory: PPointerList read fItems;
  689. {* Raw data memory. Can be used for direct access to items of a list.
  690. Do not use it for TLIST_FAST ! }
  691. procedure Assign( SrcList: PList );
  692. {* Copies all source list items. }
  693. {$IFDEF _D4orHigher}
  694. procedure AddItems( const AItems: array of Pointer );
  695. {* Adds a list of items given by a dynamic array. }
  696. {$ENDIF}
  697. function ItemAddress( Idx: Integer ): Pointer;
  698. {* Returns an address of memory occupying by the item with index Idx.
  699. (If the item is a pointer, returned value is a pointer to a pointer).
  700. Item with index requested must exist. }
  701. end;
  702. //[END OF TList DEFINITION]
  703. //[NewList DECLARATION]
  704. function NewList: PList;
  705. {* Returns pointer to newly created TList object. Use it instead usual
  706. TList.Create as it is done in VCL or XCL. }
  707. {$IFDEF _D4orHigher}
  708. function NewListInit( const AItems: array of Pointer ): PList;
  709. {* Creates a list filling it initially with certain Items. }
  710. {$ENDIF}
  711. procedure FastIncNum2Elements( List: TList; FromIdx, Count, Value: Integer );
  712. {* Very fast adds Value to List elements from List[FromIdx] to List[FromIdx+Count-1].
  713. Given elements must exist. Count must be > 0. }
  714. procedure Free_And_Nil( var Obj );
  715. {* Obj.Free and Obj := nil, where Obj *MUST* be TObj or its descendant
  716. (TControl, TMenu, etc.) This procedure is not compatible with VCL's
  717. FreeAndNil, which works with TObject, since this it has another name. }
  718. //[DummyObjProc, DummyObjProcParam DECLARATION]
  719. procedure DummyObjProc( Sender: PObj );
  720. procedure DummyObjProcParam( Sender: PObj; Param: Pointer );
  721. {$IFDEF WIN_GDI}
  722. { --- threads --- }
  723. //[THREADS]
  724. const
  725. ABOVE_NORMAL_PRIORITY_CLASS = $8000; // only for Windows 2K
  726. BELOW_NORMAL_PRIORITY_CLASS = $4000; // and higher !
  727. type
  728. {++}(*TThread = class;*){--}
  729. PThread = {-}^{+}TThread;
  730. TThreadMethod = procedure of object;
  731. TThreadMethodEx = procedure( Sender: PThread; Param: Pointer ) of object;
  732. TOnThreadExecute = function(Sender:PThread): Integer of object;
  733. {* Event to be called when Execute method is called for TThread }
  734. { ---------------------------------------------------------------------
  735. TThread object
  736. ---------------------------------------------------------------------- }
  737. //[TThread DEFINITION]
  738. TThread = object(TObj)
  739. private
  740. function GetPriorityBoost: Boolean;
  741. procedure SetPriorityBoost(const Value: Boolean);
  742. {* Thread object. It is possible not to derive Your own thread-based
  743. object, but instead create thread Suspended and assign event
  744. OnExecute. To create, use one of NewThread of NewThreadEx functions,
  745. or derive Your own descendant object and write creation function
  746. (or constructor) for it.
  747. |<br><br>
  748. Aknowledgements. Originally class ZThread was developed for XCL:
  749. |<br> * By: Tim Slusher : junior@nlcomm.com
  750. |<br> * Home: http://www.nlcomm.com/~junior
  751. }
  752. protected
  753. FSuspended,
  754. FTerminated: boolean;
  755. FHandle: THandle;
  756. FThreadId: DWORD;
  757. FOnSuspend: TObjectMethod;
  758. FOnResume: TOnEvent;
  759. FData : Pointer;
  760. FOnExecute : TOnThreadExecute;
  761. FMethod: TThreadMethod;
  762. FMethodEx: TThreadMethodEx;
  763. F_AutoFree: Boolean;
  764. FPriority: Integer;
  765. function GetPriorityCls: Integer;
  766. function GetThrdPriority: Integer;
  767. procedure SetPriorityCls(Value: Integer);
  768. procedure SetThrdPriority(Value: Integer);
  769. procedure Init; virtual;
  770. {++}(*public*){--}
  771. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  772. {* }
  773. public
  774. {$IFDEF PSEUDO_THREADS}
  775. FPrtyCls: Integer;
  776. DoNotWakeUntil: DWORD;
  777. AllThreads: PList; // only for MainThread
  778. CurrentThread: PThread;
  779. StackBottom: Pointer; // except for MainThread
  780. CurStackPos: Pointer;
  781. Stack_Empty: Boolean;
  782. procedure SwitchToThread( T: PThread ); // methods of MainThread
  783. procedure NextThread;
  784. {$ENDIF}
  785. public
  786. FResult: Integer;
  787. function Execute: integer; virtual;
  788. {* Executes thread. Do not call this method from another thread! (Even do
  789. not call this method at all!) Instead, use Resume.
  790. |<br>
  791. Note also that in contrast to VCL, it is not necessary to create your
  792. own descendant object from TThread and override Execute method. In KOL,
  793. it is sufficient to create an instance of TThread object (see NewThread,
  794. NewThreadEx, NewThreadAutoFree functions) and assign OnExecute event
  795. handler for it. }
  796. procedure Resume;
  797. {* Continues executing. It is necessary to make call for every
  798. nested Suspend. }
  799. procedure Suspend;
  800. {* Suspends thread until it will be resumed. Can be called from another
  801. thread or from the thread itself. }
  802. procedure Terminate;
  803. {* Terminates thread. }
  804. function WaitFor: Integer;
  805. {* Waits (infinitively) until thead will be finished. }
  806. function WaitForTime( T: DWORD ): Integer;
  807. {* Waits (T milliseconds) until thead will be finished. }
  808. property Handle: THandle read FHandle;
  809. {* Thread handle. It is created immediately when object is created
  810. (using NewThread). }
  811. property Suspended: boolean read FSuspended;
  812. {* True, if suspended. }
  813. property Terminated: boolean read FTerminated;
  814. {* True, if terminated. }
  815. property ThreadId: DWORD read FThreadId;
  816. {* Thread id. }
  817. property PriorityClass: Integer read GetPriorityCls write SetPriorityCls;
  818. {* Thread priority class. One of following values: HIGH_PRIORITY_CLASS,
  819. IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS. }
  820. property ThreadPriority: Integer read GetThrdPriority write SetThrdPriority;
  821. {* Thread priority value. One of following values: THREAD_PRIORITY_ABOVE_NORMAL,
  822. THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_IDLE,
  823. THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_TIME_CRITICAL. }
  824. property Data : Pointer read FData write FData;
  825. {* Custom data pointer. Use it for Youe own purpose. }
  826. property OnExecute: TOnThreadExecute read FOnExecute write FOnExecute;
  827. {* Is called, when Execute is starting. }
  828. property OnSuspend: TObjectMethod read FOnSuspend write FOnSuspend;
  829. {* Is called, when Suspend is performed. }
  830. property OnResume: TOnEvent read FOnResume write FOnResume;
  831. {* Is called, when resumed. }
  832. procedure Synchronize( Method: TThreadMethod );
  833. {* Call it to execute given method in main thread context. Applet variable
  834. must exist for that time. }
  835. procedure SynchronizeEx( Method: TThreadMethodEx; Param: Pointer );
  836. {* Call it to execute given method in main thread context, with a given
  837. parameter. Applet variable must exist for that time. Param must not be nil. }
  838. {$IFDEF USE_CONSTRUCTORS}
  839. constructor ThreadCreate;
  840. constructor ThreadCreateEx( const Proc: TOnThreadExecute );
  841. {$ENDIF USE_CONSTRUCTORS}
  842. property AutoFree: Boolean read F_AutoFree write F_AutoFree;
  843. {* Set this property to true to provide automatic destroying of thread
  844. object when its executing is finished. }
  845. property PriorityBoost: Boolean read GetPriorityBoost write SetPriorityBoost;
  846. {* By default, priority boost is enabled for all threads. }
  847. end;
  848. //[END OF TThread DEFINITION]
  849. //[NewThread, NewThreadEx, NewThreadAutoFree DECLARATIONS]
  850. function NewThread: PThread;
  851. {* Creates thread object (always suspended). After creating, set event
  852. OnExecute and perform Resume operation. }
  853. function NewThreadEx( const Proc: TOnThreadExecute ): PThread; {$ifdef wince}cdecl{$else}stdcall{$endif};
  854. {* Creates thread object, assigns Proc to its OnExecute event and runs
  855. it. }
  856. function NewThreadAutoFree( const Proc: TOnThreadExecute ): PThread;
  857. {* Creates thread object similar to NewThreadEx, but freeing automatically
  858. when executing of such thread finished. Be sure that a thread is resumed
  859. at least to provide its object keeper freeing. }
  860. {$IFDEF PSEUDO_THREADS}
  861. var MainThread: PThread;
  862. PseudoThreadStackSize: DWORD = 1024 * 1024;
  863. CreatingMainThread: Boolean;
  864. function WaitForSingleObject( hHandle: THandle; dwMilliseconds: DWORD ): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  865. function WaitForMultipleObjects( nCount: DWORD;
  866. lpHandles: PHandle; fWaitAll: BOOL; dwMilliseconds: DWORD ): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  867. procedure Sleep( n: DWORD );
  868. {$ENDIF}
  869. { -- streams -- }
  870. //[STREAMS]
  871. {$ENDIF WIN_GDI}
  872. type
  873. TMoveMethod = ( spBegin, spCurrent, spEnd );
  874. {$IFDEF WIN_GDI}
  875. type
  876. {++}(*TStream = class;*){--}
  877. PStream = {-}^{+}TStream;
  878. PStreamMethods = ^TStreamMethods;
  879. TStreamMethods = {$ifndef wince}packed{$endif} Record
  880. fSeek: function( Strm: PStream; MoveTo: Integer; MoveMethod: TMoveMethod ): DWORD;
  881. fGetSiz: function( Strm: PStream ): DWORD;
  882. fSetSiz: procedure( Strm: PStream; Value: DWORD );
  883. fRead: function( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  884. fWrite: function( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  885. fClose: procedure( Strm: PStream );
  886. fCustom: Pointer;
  887. fWait: procedure( Strm: PStream );
  888. end;
  889. TStreamData = {$ifndef wince}packed{$endif} Record
  890. fHandle: THandle;
  891. fCapacity, fSize, fPosition: DWORD;
  892. fThread: PThread;
  893. end;
  894. { ---------------------------------------------------------------------
  895. TStream - streaming objects incapsulation
  896. ---------------------------------------------------------------------- }
  897. //[TStream DEFINITION]
  898. TStream = object(TObj)
  899. {* Simple stream object. Can be opened for file, or as memory stream (see
  900. NewReadFileStream, NewWriteFileStream, NewMemoryStream, etc.). And, another
  901. type of streaming object can be derived (without inheriting new object
  902. type, just by writing another New...Stream method, which calls
  903. _NewStream and pass methods record to it). }
  904. protected
  905. fPMethods: PStreamMethods;
  906. fMethods: TStreamMethods;
  907. fMemory: Pointer;
  908. fData: TStreamData;
  909. fParam1, fParam2: DWORD; // parameters to use in thread
  910. function GetCapacity: DWORD;
  911. procedure SetCapacity(Value: DWORD);
  912. function DoAsyncRead( Sender: PThread ): Integer;
  913. function DoAsyncWrite( Sender: PThread ): Integer;
  914. function DoAsyncSeek( Sender: PThread ): Integer;
  915. protected
  916. function GetFileStreamHandle: THandle;
  917. procedure SetPosition(Value: DWord);
  918. function GetPosition: DWord;
  919. function GetSize: DWord;
  920. procedure SetSize(NewSize: DWord);
  921. {++}(*public*){--}
  922. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  923. public
  924. function Read(var Buffer; Count: DWord): DWord;
  925. {* Reads Count bytes from a stream. Returns number of bytes read. }
  926. function Seek(MoveTo: Integer; MoveMethod: TMoveMethod): DWord;
  927. {* Allows to change current position or to obtain it. Property
  928. Position uses this method both for get and set position. }
  929. function Write(var Buffer; Count: DWord): DWord;
  930. {* Writes Count bytes from Buffer, starting from current position
  931. in a stream. Returns how much bytes are written. }
  932. function WriteVal( Value: DWORD; Count: DWORD ): DWORD;
  933. {* Writes maximum 4 bytes of Value to a stream. Allows writing constants
  934. easier than via Write. }
  935. function WriteStr( S: String ): DWORD;
  936. {* Writes string to the stream, not including ending #0. Exactly
  937. Length( S ) characters are written. }
  938. function WriteStrZ( S: String ): DWORD;
  939. {* Writes string, adding #0. Number of bytes written is returned. }
  940. {$IFDEF _D3orHigher}
  941. function WriteWStrZ( S: WideString ): DWORD;
  942. {* Writes string, adding #0. Number of bytes written is returned. }
  943. {$ENDIF}
  944. function ReadStrZ: String;
  945. {* Reads string, finished by #0. After reading, current position in
  946. the stream is set to the byte, follows #0. }
  947. {$IFDEF _D3orHigher}
  948. function ReadWStrZ: WideString;
  949. {* Reads string, finished by #0. After reading, current position in
  950. the stream is set to the byte, follows #0. }
  951. {$ENDIF}
  952. function ReadStr: String;
  953. {* Reads string, finished by #13, #10 or #13#10 symbols. Terminating symbols
  954. #13 and/or #10 are not added to the end of returned string though
  955. stream positioned follow it. }
  956. function ReadStrLen( Len: Integer ): String;
  957. {* Reads string of the given length Len. }
  958. function WriteStrEx(S: String): DWord;
  959. {* Writes string S to stream, also saving its size for future use by
  960. ReadStrEx* functions. Returns number of actually written characters. }
  961. function ReadStrExVar(var S: String): DWord;
  962. {* Reads string from stream and assigns it to S.
  963. Returns number of actually read characters.
  964. Note:
  965. String must be written by using WriteStrEx function.
  966. Return value is count of characters READ, not the length of string. }
  967. function ReadStrEx: String;
  968. {* Reads string from stream and returns it. }
  969. function WriteStrPas( S: String ): DWORD;
  970. {* Writes a string in Pascal short string format - 1 byte length, then string
  971. itself without trailing #0 char. S parameter length should not exceed 255
  972. chars, rest chars are truncated while writing. Total amount of bytes
  973. written is returned. }
  974. function ReadStrPas: String;
  975. {* Reads 1 byte from a stream, then treat it as a length of following string
  976. which is read and returned. A purpose of this function is reading strings
  977. written using WriteStrPas. }
  978. property Size: DWord read GetSize write SetSize;
  979. {* Returns stream size. For some custom streams, can be slow
  980. operation, or even always return undefined value (-1 recommended). }
  981. property Position: DWord read GetPosition write SetPosition;
  982. {* Current position. }
  983. property Memory: Pointer read fMemory;
  984. {* Only for memory stream. }
  985. property Handle: THandle read GetFileStreamHandle;
  986. {* Only for file stream. It is possible to check that Handle <>
  987. INVALID_HANDLE_VALUE to ensure that file stream is created OK. }
  988. //---------- for asynchronous operations (using thread - not tested):
  989. procedure SeekAsync(MoveTo: Integer; MoveMethod: TMoveMethod);
  990. {* Changes current position asynchronously. To wait for finishing the
  991. operation, use method Wait. }
  992. procedure ReadAsync(var Buffer; Count: DWord);
  993. {* Reads Count bytes from a stream asynchronously. To wait finishing the
  994. operation, use method Wait. }
  995. procedure WriteAsync(var Buffer; Count: DWord);
  996. {* Writes Count bytes from Buffer, starting from current position
  997. in a stream - asynchronously. To wait finishing the operation,
  998. use method Wait. }
  999. function Busy: Boolean;
  1000. {* Returns TRUE until finishing the last asynchronous operation
  1001. started by calling SeekAsync, ReadAsync, WriteAsync methods. }
  1002. procedure Wait;
  1003. {* Waits for finishing the last asynchronous operation. }
  1004. property Methods: PStreamMethods read fPMethods;
  1005. {* Pointer to TStreamMethods record. Useful to implement custom-defined
  1006. streams, which can access its fCustom field, or even to change
  1007. methods when necessary. }
  1008. property Data: TStreamData read fData;
  1009. {* Pointer to TStreamData record. Useful to implement custom-defined
  1010. streams, which can access Data fields directly when implemented. }
  1011. property Capacity: DWORD read GetCapacity write SetCapacity;
  1012. {* Amound of memory allocated for data (MemoryStream). }
  1013. procedure SaveToFile( const Filename: KOLString; Start, CountSave: DWORD );
  1014. {* }
  1015. end;
  1016. //[END OF TStream DEFINITION]
  1017. //[_NewStream DECLARATION]
  1018. function _NewStream( const StreamMethods: TStreamMethods ): PStream;
  1019. {* Use this method only to define your own stream type. See also declared
  1020. below (in KOL.pas) methods used to implement standard KOL streams. You can use it in
  1021. your code to create streams, which are partially based on standard
  1022. methods. }
  1023. // Methods below are declared here to simplify creating your
  1024. // own streams with some methods standard and some non-standard
  1025. // together:
  1026. function SeekFileStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  1027. function GetSizeFileStream( Strm: PStream ): DWORD;
  1028. function ReadFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  1029. var ReadFileStreamProc: function( Strm: PStream; var Buffer; Count: DWORD ): DWORD
  1030. = ReadFileStream;
  1031. function WriteFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  1032. function WriteFileStreamEOF( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  1033. procedure CloseFileStream( Strm: PStream );
  1034. function SeekMemStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  1035. function GetSizeMemStream( Strm: PStream ): DWORD;
  1036. var CapacityMask: DWORD = $4000 - 1; // must be 2**n-1
  1037. procedure SetSizeMemStream( Strm: PStream; NewSize: DWORD );
  1038. function ReadMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  1039. function WriteMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  1040. procedure CloseMemStream( Strm: PStream );
  1041. procedure SetSizeFileStream( Strm: PStream; NewSize: DWORD );
  1042. procedure DummyCloseStream( Strm: PStream );
  1043. function DummyReadWrite( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  1044. procedure DummySetSize( Strm: PStream; Value: DWORD );
  1045. procedure DummyStreamProc(Strm: PStream);
  1046. //[NewFileStream DECLARATION]
  1047. function NewFileStream( const FileName: KOLString; Options: DWORD ): PStream;
  1048. {* Creates file stream for read and write. Exact set of open attributes
  1049. should be passed through Options parameter (see FileCreate where those
  1050. flags are listed). }
  1051. function NewReadFileStream( const FileName: KOLString ): PStream;
  1052. {* Creates file stream for read only. }
  1053. function NewWriteFileStream( const FileName: KOLString ): PStream;
  1054. {* Creates file stream for write only. Truncating of file (if needed)
  1055. is provided automatically. }
  1056. function NewReadWriteFileStream( const FileName: KOLString ): PStream;
  1057. {* Creates stream for read and write file. To truncate file, if it is
  1058. necessary, change Size property. }
  1059. {$IFDEF _D3orHigher}
  1060. function NewReadFileStreamW( const FileName: WideString ): PStream;
  1061. {* Creates file stream for read only. }
  1062. function NewWriteFileStreamW( const FileName: WideString ): PStream;
  1063. {* Creates file stream for write only. Truncating of file (if needed)
  1064. is provided automatically. }
  1065. function NewReadWriteFileStreamW( const FileName: WideString ): PStream;
  1066. {* Creates stream for read and write file. To truncate file, if it is
  1067. necessary, change Size property. }
  1068. {$ENDIF}
  1069. function NewExFileStream( F: HFile ): PStream;
  1070. {* Creates read only stream to read from opened file or pipe from the current
  1071. position.
  1072. When stream is destroyed, file handle still not closed (your code should do
  1073. this) and file position is not changed (after the last read operation). }
  1074. //[NewMemoryStream DECLARATION]
  1075. function NewMemoryStream: PStream;
  1076. {* Creates memory stream (read and write). }
  1077. function NewExMemoryStream( ExistingMem: Pointer; Size: DWORD ): PStream;
  1078. {* Creates memory stream on base of existing memory. It is not possible
  1079. to write out of top bound given by Size (i.e. memory can not be resized,
  1080. or reallocated. When stream object is destroyed this memory is not freed. }
  1081. //[Stream2Stream DECLARATION]
  1082. function Stream2Stream( Dst, Src: PStream; Count: DWORD ): DWORD;
  1083. {* Copies Count (or less, if the rest of Src is not sufficiently long)
  1084. bytes from Src to Dst, but with optimizing in cases, when Src or/and
  1085. Dst are memory streams (intermediate buffer is not allocated). }
  1086. function Stream2StreamEx( Dst, Src: PStream; Count: DWORD ): DWORD;
  1087. {* Copies Count bytes from Src to Dst, but without any optimization.
  1088. Unlike Stream2Stream function, it can be applied to very large streams.
  1089. See also Stream2StreamExBufSz. }
  1090. function Stream2StreamExBufSz( Dst, Src: PStream; Count, BufSz: DWORD ): DWORD;
  1091. {* Copies Count bytes from Src to Dst using buffer of given size, but without
  1092. other optimizations.
  1093. Unlike Stream2Stream function, it can be applied to very large streams }
  1094. //[Resource2Stream DECLARATION]
  1095. function Resource2Stream( DestStrm : PStream; Inst : HInst;
  1096. ResName : PKOLChar; ResType : PKOLChar ): Integer;
  1097. {* Loads given resource to DestStrm. Useful for non-standard
  1098. resources to load it into memory (use memory stream for such
  1099. purpose). Use one of following resource types to pass as ResType:
  1100. |<pre>
  1101. RT_ACCELERATOR Accelerator table
  1102. RT_ANICURSOR Animated cursor
  1103. RT_ANIICON Animated icon
  1104. RT_BITMAP Bitmap resource
  1105. RT_CURSOR Hardware-dependent cursor resource
  1106. RT_DIALOG Dialog box
  1107. RT_FONT Font resource
  1108. RT_FONTDIR Font directory resource
  1109. RT_GROUP_CURSOR Hardware-independent cursor resource
  1110. RT_GROUP_ICON Hardware-independent icon resource
  1111. RT_ICON Hardware-dependent icon resource
  1112. RT_MENU Menu resource
  1113. RT_MESSAGETABLE Message-table entry
  1114. RT_RCDATA Application-defined resource (raw data)
  1115. RT_STRING String-table entry
  1116. RT_VERSION Version resource
  1117. |</pre>
  1118. |<br>For example:
  1119. !var MemStrm: PStream;
  1120. ! JpgObj: PJpeg;
  1121. !......
  1122. ! MemStrm := NewMemoryStream;
  1123. ! JpgObj := NewJpeg;
  1124. !......
  1125. ! Resource2Stream( MemStrm, hInstance, 'MYJPEG', RT_RCDATA );
  1126. ! MemStrm.Position := 0;
  1127. ! JpgObj.LoadFromStream( MemStrm );
  1128. ! MemStrm.Free;
  1129. !......
  1130. }
  1131. {$ENDIF WIN_GDI}
  1132. { -- string list objects -- }
  1133. //[TStrList]
  1134. type
  1135. {++}(*TStrList = class;*){--}
  1136. PStrList = {-}^{+}TStrList;
  1137. { ---------------------------------------------------------------------
  1138. TStrList - string list
  1139. ---------------------------------------------------------------------- }
  1140. //[TStrList DEFINITION]
  1141. TStrList = object(TObj)
  1142. {* Easy string list implementation (non-visual, just to store
  1143. string data). It is well improved and has very high performance
  1144. allowing to work fast with huge text files (more then megabyte
  1145. of text data).
  1146. |
  1147. Please note that #0 charaster if stored in string lines, will cut it
  1148. preventing reading the rest of a line. Be careful, if your data
  1149. contain such characters. }
  1150. protected
  1151. procedure Init; virtual;
  1152. protected
  1153. fList: PList;
  1154. fCount: Integer;
  1155. fCaseSensitiveSort: Boolean;
  1156. fTextBuf: PChar;
  1157. fTextSiz: DWORD;
  1158. function GetPChars(Idx: Integer): PChar;
  1159. //procedure AddTextBuf( Src: PChar; Len: DWORD );
  1160. protected
  1161. function Get(Idx: integer): string;
  1162. function GetTextStr: string;
  1163. procedure Put(Idx: integer; const Value: string);
  1164. procedure SetTextStr(const Value: string);
  1165. {++}(*public*){--}
  1166. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  1167. protected
  1168. // by Dod:
  1169. procedure SetValue(const AName, Value: string);
  1170. function GetValue(const AName: string): string;
  1171. public
  1172. // by Dod:
  1173. function IndexOfName(AName: string): Integer;
  1174. {* by Dod. Returns index of line starting like Name=... }
  1175. property Values[const AName: string]: string read GetValue write SetValue;
  1176. {* by Dod. Returns right side of a line starting like Name=... }
  1177. public
  1178. function Add(const S: string): integer;
  1179. {* Adds a string to list. }
  1180. procedure AddStrings(Strings: PStrList);
  1181. {* Merges string list with given one. Very fast - more preferrable to
  1182. use than any loop with calling Add method. }
  1183. procedure Assign(Strings: PStrList);
  1184. {* Fills string list with strings from other one. The same as AddStrings,
  1185. but Clear is called first. }
  1186. procedure Clear;
  1187. {* Makes string list empty. }
  1188. procedure Delete(Idx: integer);
  1189. {* Deletes string with given index (it *must* exist). }
  1190. procedure DeleteLast;
  1191. {* Deletes the last string (it *must* exist). }
  1192. function IndexOf(const S: string): integer;
  1193. {* Returns index of first string, equal to given one. }
  1194. function IndexOf_NoCase(const S: string): integer;
  1195. {* Returns index of first string, equal to given one (while comparing it
  1196. without case sensitivity). }
  1197. function IndexOfStrL_NoCase( Str: PChar; L: Integer ): integer;
  1198. {* Returns index of first string, equal to given one (while comparing it
  1199. without case sensitivity). }
  1200. function Find(const S: String; var Index: Integer): Boolean;
  1201. {* Returns Index of the first string, equal or greater to given pattern, but
  1202. works only for sorted TStrList object. Returns TRUE if exact string found,
  1203. otherwise nearest (greater then a pattern) string index is returned,
  1204. and the result is FALSE. }
  1205. procedure Insert(Idx: integer; const S: string);
  1206. {* Inserts string before one with given index. }
  1207. procedure Move(CurIndex, NewIndex: integer);
  1208. {* Moves string to another location. }
  1209. procedure SetText(const S: string; Append2List: boolean);
  1210. {* Allows to set strings of string list from given string (in which
  1211. strings are separated by $0D,$0A or $0D characters). Text must not
  1212. contain #0 characters. Works very fast. This method is used in
  1213. all others, working with text arrays (LoadFromFile, MergeFromFile,
  1214. Assign, AddStrings). }
  1215. procedure SetUnixText( const S: String; Append2List: Boolean );
  1216. {* Allows to assign UNIX-style text (with #10 as string separator). }
  1217. property Count: integer read fCount;
  1218. {* Number of strings in a string list. }
  1219. property Items[Idx: integer]: string read Get write Put; default;
  1220. {* Strings array items. If item does not exist, empty string is returned.
  1221. But for assign to property, string with given index *must* exist. }
  1222. property ItemPtrs[ Idx: Integer ]: PChar read GetPChars;
  1223. {* Fast access to item strings as PChars. }
  1224. function Last: String;
  1225. {* Last item (or '', if string list is empty). }
  1226. property Text: string read GetTextStr write SetTextStr;
  1227. {* Content of string list as a single string (where strings are separated
  1228. by characters $0D,$0A). }
  1229. procedure Swap( Idx1, Idx2 : Integer );
  1230. {* Swaps to strings with given indeces. }
  1231. procedure Sort( CaseSensitive: Boolean );
  1232. {* Call it to sort string list. }
  1233. procedure AnsiSort( CaseSensitive: Boolean );
  1234. {* Call it to sort ANSI string list. }
  1235. // by Alexander Pravdin:
  1236. protected
  1237. fNameDelim: Char;
  1238. function GetLineName( Idx: Integer ): String;
  1239. procedure SetLineName( Idx: Integer; const NV: String );
  1240. function GetLineValue(Idx: Integer): string;
  1241. procedure SetLineValue(Idx: Integer; const Value: string);
  1242. public
  1243. property LineName[ Idx: Integer ]: string read GetLineName write SetLineName;
  1244. property LineValue[ Idx: Integer ]: string read GetLineValue write SetLineValue;
  1245. property NameDelimiter: Char read fNameDelim write fNameDelim;
  1246. function Join( const sep: String ): String;
  1247. {* by Sergey Shishmintzev. }
  1248. {$IFDEF WIN_GDI}
  1249. function LoadFromFile(const FileName: KOLstring): Boolean;
  1250. {* Loads string list from a file. (If file does not exist, nothing
  1251. happens). Very fast even for huge text files. }
  1252. procedure LoadFromStream(Stream: PStream; Append2List: boolean);
  1253. {* Loads string list from a stream (from current position to the end of
  1254. a stream). Very fast even for huge text. }
  1255. procedure MergeFromFile(const FileName: KOLstring);
  1256. {* Merges string list with strings in a file. Fast. }
  1257. function SaveToFile(const FileName: KOLstring): Boolean;
  1258. {* Stores string list to a file. }
  1259. procedure SaveToStream(Stream: PStream);
  1260. {* Saves string list to a stream (from current position). }
  1261. function AppendToFile(const FileName: KOLstring): Boolean;
  1262. {* Appends strings of string list to the end of a file. }
  1263. {$ENDIF WIN_GDI}
  1264. end;
  1265. //[END OF TStrList DEFINITION]
  1266. //[DefaultNameDelimiter]
  1267. var DefaultNameDelimiter: Char = '=';
  1268. ThsSeparator: Char = ',';
  1269. //[NewStrList DECLARATION]
  1270. function NewStrList: PStrList;
  1271. {* Creates string list object. }
  1272. {$IFDEF WIN}
  1273. function GetFileList(const dir: string): PStrList;
  1274. {* By Alexander Shakhaylo. Returns list of file names of the given directory. }
  1275. {$ENDIF WIN}
  1276. {$IFNDEF _FPC}
  1277. function WStrLen( W: PWideChar ): Integer;
  1278. {* Returns Length of null-terminated Unicode string. }
  1279. {$IFDEF _D3orHigher} {$ifdef win32}
  1280. function UTF8_2WideString( const s: AnsiString ): WideString;
  1281. {$ENDIF}{$ENDIF}
  1282. {$ENDIF _FPC}
  1283. //[TStrListEx]
  1284. type
  1285. {++}(*TStrListEx = class;*){--}
  1286. PStrListEx = {-}^{+}TStrListEx;
  1287. //[TStrListEx DEFINITION]
  1288. TStrListEx = object( TStrList )
  1289. {* Extended string list object. Has additional capability to associate
  1290. numbers or objects with string list items. }
  1291. protected
  1292. FObjects: PList;
  1293. function GetObjects(Idx: Integer): DWORD;
  1294. function GetObjectCount: Integer;
  1295. procedure SetObjects(Idx: Integer; const Value: DWORD);
  1296. procedure Init; {-}virtual;{+}{++}(*override;*){--}
  1297. procedure ProvideObjCapacity( NewCap: Integer );
  1298. public
  1299. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  1300. {* }
  1301. property Objects[ Idx: Integer ]: DWORD read GetObjects write SetObjects;
  1302. {* Objects are just 32-bit values. You can treat and use it as pointers to
  1303. any other data in the memory. But it is your task to free allocated
  1304. memory in such case therefore.
  1305. |<br>
  1306. If the last item of a string list is deleted vis DeleteLast method (but
  1307. not via Delete method), it's object still is preserved. As well, it is
  1308. possible to set Objects[idx] for idx >= Count.
  1309. To get know object's count, rather then strings count, use ObjectCount
  1310. property. }
  1311. property ObjectCount: Integer read GetObjectCount;
  1312. {* Returns number of objects available. This value can differ from Count
  1313. after some operations: objects are stored in the independant list and
  1314. only synchronization is provided while using methods Delete, Insert,
  1315. Add, AddObject, InsertObject while changing the list. }
  1316. procedure AddStrings(Strings: PStrListEx);
  1317. {* Merges string list with given one. Very fast - more preferrable to
  1318. use than any loop with calling Add method. }
  1319. procedure Assign(Strings: PStrListEx);
  1320. {* Fills string list with strings from other one. The same as AddStrings,
  1321. but Clear is called first. }
  1322. procedure Clear;
  1323. {* Makes string list empty. }
  1324. procedure Delete(Idx: integer);
  1325. {* Deletes string with given index (it *must* exist). }
  1326. procedure Move(CurIndex, NewIndex: integer);
  1327. {* Moves string to another location. }
  1328. procedure Swap( Idx1, Idx2 : Integer );
  1329. {* Swaps to strings with given indeces. }
  1330. procedure Sort( CaseSensitive: Boolean );
  1331. {* Call it to sort string list. }
  1332. procedure AnsiSort( CaseSensitive: Boolean );
  1333. {* Call it to sort ANSI string list. }
  1334. function LastObj: DWORD;
  1335. {* Object assotiated with the last string. }
  1336. function AddObject( const S: String; Obj: DWORD ): Integer;
  1337. {* Adds a string and associates given number with it. Index of the item added
  1338. is returned. }
  1339. procedure InsertObject( Before: Integer; const S: String; Obj: DWORD );
  1340. {* Inserts a string together with object associated. }
  1341. function IndexOfObj( Obj: Pointer ): Integer;
  1342. {* Returns an index of a string associated with the object passed as a
  1343. parameter. If there are no such strings, -1 is returned. }
  1344. end;
  1345. //[END OF TStrListEx DEFINITION]
  1346. //[NewStrListEx DECLARATION]
  1347. function NewStrListEx: PStrListEx;
  1348. {* Creates extended string list object. }
  1349. //[TWStrList]
  1350. {-}
  1351. {$IFNDEF _FPC}
  1352. procedure WStrCopy( Dest, Src: PWideChar );
  1353. {* Copies null-terminated Unicode string (terminated null also copied). }
  1354. procedure WStrLCopy( Dest, Src: PWideChar; MaxLen: Integer );
  1355. {* Copies null-terminated Unicode string (terminated null also copied). }
  1356. function WStrCmp( W1, W2: PWideChar ): Integer;
  1357. {* Compares two null-terminated Unicode strings. }
  1358. {$ENDIF _FPC}
  1359. {$IFDEF WIN_GDI}
  1360. {$IFNDEF _D2} //------------------ WideString is not supported in D2 -----------
  1361. type
  1362. PWStrList = ^TWstrList;
  1363. {* }
  1364. //[TWstrList DEFINITION]
  1365. TWStrList = object( TObj )
  1366. {* String list to store Unicode (null-terminated) strings. }
  1367. protected
  1368. function GetCount: Integer;
  1369. function GetItems(Idx: Integer): WideString;
  1370. procedure SetItems(Idx: Integer; const Value: WideString);
  1371. function GetPtrs(Idx: Integer): PWideChar;
  1372. function GetText: WideString;
  1373. protected
  1374. fList: PList;
  1375. fText: PWideChar;
  1376. fTextBufSz: Integer;
  1377. fTmp1, fTmp2: WideString;
  1378. procedure Init; virtual;
  1379. public
  1380. procedure SetText(const Value: WideString);
  1381. {* See also TStrList.SetText }
  1382. destructor Destroy; virtual;
  1383. {* }
  1384. procedure Clear;
  1385. {* See also TStrList.Clear }
  1386. property Items[ Idx: Integer ]: WideString read GetItems write SetItems;
  1387. {* See also TStrList.Items }
  1388. property ItemPtrs[ Idx: Integer ]: PWideChar read GetPtrs;
  1389. {* See also TStrList.ItemPtrs }
  1390. property Count: Integer read GetCount;
  1391. {* See also TStrList.Count }
  1392. function Add( const W: WideString ): Integer;
  1393. {* See also TStrList.Add }
  1394. procedure Insert( Idx: Integer; const W: WideString );
  1395. {* See also TStrList.Insert }
  1396. procedure Delete( Idx: Integer );
  1397. {* See also TStrList.Delete }
  1398. property Text: WideString read GetText write SetText;
  1399. {* See also TStrList.Text }
  1400. procedure AddWStrings( WL: PWStrList );
  1401. {* See also TStrList.AddStrings }
  1402. procedure Assign( WL: PWStrList );
  1403. {* See also TStrList.Assign }
  1404. function LoadFromFile( const Filename: KOLString ): Boolean;
  1405. {* See also TStrList.LoadFromFile }
  1406. procedure LoadFromStream( Strm: PStream );
  1407. {* See also TStrList.LoadFromStream }
  1408. function MergeFromFile( const Filename: KOLString ): Boolean;
  1409. {* See also TStrList.MergeFromFile }
  1410. procedure MergeFromStream( Strm: PStream );
  1411. {* See also TStrList.MergeFromStream }
  1412. function SaveToFile( const Filename: KOLString ): Boolean;
  1413. {* See also TStrList.SaveToFile }
  1414. procedure SaveToStream( Strm: PStream );
  1415. {* See also TStrList.SaveToStream }
  1416. function AppendToFile( const Filename: KOLString ): Boolean;
  1417. {* See also TStrList.AppendToFile }
  1418. procedure Swap( Idx1, Idx2: Integer );
  1419. {* See also TStrList.Swap }
  1420. procedure Sort( CaseSensitive: Boolean );
  1421. {* See also TStrList.Sort }
  1422. procedure Move( IdxOld, IdxNew: Integer );
  1423. {* See also TStrList.Move }
  1424. function IndexOf( const s: WideString ): Integer;
  1425. {* }
  1426. end;
  1427. //[END OF TWStrList DEFINITION]
  1428. //[TWStrListEx]
  1429. PWStrListEx = ^TWStrListEx;
  1430. //[TWStrListEx DEFINITION]
  1431. TWStrListEx = object( TWStrList )
  1432. {* Extended Unicode string list (with Objects). }
  1433. protected
  1434. function GetObjects(Idx: Integer): DWORD;
  1435. procedure SetObjects(Idx: Integer; const Value: DWORD);
  1436. procedure ProvideObjectsCapacity( NewCap: Integer );
  1437. protected
  1438. fObjects: PList;
  1439. procedure Init; virtual;
  1440. public
  1441. destructor Destroy; virtual;
  1442. {* }
  1443. property Objects[ Idx: Integer ]: DWORD read GetObjects write SetObjects;
  1444. {* }
  1445. procedure AddWStrings( WL: PWStrListEx );
  1446. {* }
  1447. procedure Assign( WL: PWStrListEx );
  1448. {* }
  1449. procedure Clear;
  1450. {* }
  1451. procedure Delete( Idx: Integer );
  1452. {* }
  1453. procedure Move( IdxOld, IdxNew: Integer );
  1454. {* }
  1455. function AddObject( const S: WideString; Obj: DWORD ): Integer;
  1456. {* Adds a string and associates given number with it. Index of the item added
  1457. is returned. }
  1458. procedure InsertObject( Before: Integer; const S: WideString; Obj: DWORD );
  1459. {* Inserts a string together with object associated. }
  1460. function IndexOfObj( Obj: Pointer ): Integer;
  1461. {* Returns an index of a string associated with the object passed as a
  1462. parameter. If there are no such strings, -1 is returned. }
  1463. end;
  1464. //[END OF TWStrListEx DEFINITION]
  1465. //[NewWStrList DECLARATION]
  1466. function NewWStrList: PWStrList;
  1467. {* Creates new TWStrList object and returns a pointer to it. }
  1468. //[NewWStrListEx DECLARATION]
  1469. function NewWStrListEx: PWStrListEx;
  1470. {* Creates new TWStrListEx objects and returns a pointer to it. }
  1471. {$ENDIF not _D2}
  1472. {$ENDIF WIN_GDI}
  1473. {$IFDEF UNICODE_CTRLS}
  1474. {$IFNDEF _D2}
  1475. type TKOLStrList = TWStrList;
  1476. PKOLStrList = PWStrList;
  1477. {$ELSE}
  1478. type TKOLStrList = TStrList;
  1479. PKOLStrList = PStrList;
  1480. {$ENDIF}
  1481. {$ELSE}
  1482. type TKOLStrList = TStrList;
  1483. PKOLStrList = PStrList;
  1484. {$ENDIF}
  1485. {+}
  1486. ////////////////////////////////////////////////////////////////////////////////
  1487. // GRAPHIC OBJECTS //
  1488. ////////////////////////////////////////////////////////////////////////////////
  1489. //[GRAPHIC OBJECTS]
  1490. {
  1491. It is very important, that the most of code, implementing graphic objets
  1492. from this section, is included into executable ONLY if really accessed in your
  1493. project directly (e.g., if Font or Brush properies of a control are accessed
  1494. or changed).
  1495. }
  1496. type
  1497. TColor = Integer;
  1498. const
  1499. //[COLOR CONSTANTS]
  1500. clScrollBar = TColor(COLOR_SCROLLBAR or $80000000);
  1501. clBackground = TColor(COLOR_BACKGROUND or $80000000);
  1502. clActiveCaption = TColor(COLOR_ACTIVECAPTION or $80000000);
  1503. clInactiveCaption = TColor(COLOR_INACTIVECAPTION or $80000000);
  1504. clMenu = TColor(COLOR_MENU or $80000000);
  1505. clWindow = TColor(COLOR_WINDOW or $80000000);
  1506. clWindowFrame = TColor(COLOR_WINDOWFRAME or $80000000);
  1507. clMenuText = TColor(COLOR_MENUTEXT or $80000000);
  1508. clWindowText = TColor(COLOR_WINDOWTEXT or $80000000);
  1509. clCaptionText = TColor(COLOR_CAPTIONTEXT or $80000000);
  1510. clActiveBorder = TColor(COLOR_ACTIVEBORDER or $80000000);
  1511. clInactiveBorder = TColor(COLOR_INACTIVEBORDER or $80000000);
  1512. clAppWorkSpace = TColor(COLOR_APPWORKSPACE or $80000000);
  1513. clHighlight = TColor(COLOR_HIGHLIGHT or $80000000);
  1514. clHighlightText = TColor(COLOR_HIGHLIGHTTEXT or $80000000);
  1515. clBtnFace = TColor(COLOR_BTNFACE or $80000000);
  1516. clBtnShadow = TColor(COLOR_BTNSHADOW or $80000000);
  1517. clGrayText = TColor(COLOR_GRAYTEXT or $80000000);
  1518. clBtnText = TColor(COLOR_BTNTEXT or $80000000);
  1519. clInactiveCaptionText = TColor(COLOR_INACTIVECAPTIONTEXT or $80000000);
  1520. clBtnHighlight = TColor(COLOR_BTNHIGHLIGHT or $80000000);
  1521. cl3DDkShadow = TColor(COLOR_3DDKSHADOW or $80000000);
  1522. cl3DLight = TColor(COLOR_3DLIGHT or $80000000);
  1523. clInfoText = TColor(COLOR_INFOTEXT or $80000000);
  1524. clInfoBk = TColor(COLOR_INFOBK or $80000000);
  1525. clBlack = TColor($000000);
  1526. clMaroon = TColor($000080);
  1527. clGreen = TColor($008000);
  1528. clOlive = TColor($008080);
  1529. clNavy = TColor($800000);
  1530. clPurple = TColor($800080);
  1531. clTeal = TColor($808000);
  1532. clGray = TColor($808080);
  1533. clSilver = TColor($C0C0C0);
  1534. clRed = TColor($0000FF);
  1535. clLime = TColor($00FF00);
  1536. clYellow = TColor($00FFFF);
  1537. clBlue = TColor($FF0000);
  1538. clFuchsia = TColor($FF00FF);
  1539. clAqua = TColor($FFFF00);
  1540. clLtGray = TColor($C0C0C0);
  1541. clDkGray = TColor($808080);
  1542. clWhite = TColor($FFFFFF);
  1543. clNone = TColor($1FFFFFFF);
  1544. clDefault = TColor($20000000);
  1545. clMoneyGreen = TColor($C0DCC0);
  1546. clSkyBlue = TColor($F0CAA6);
  1547. clCream = TColor($F0FBFF);
  1548. clMedGray = TColor($A4A0A0);
  1549. clGRushHiLight = TColor( $F3706C );
  1550. clGRushLighten = TColor( $F1EEDF );
  1551. clGRushLight = TColor( $e1cebf );
  1552. clGRushNormal = TColor( $D1beaf );
  1553. clGRushMedium = TColor( $b6bFc6 );
  1554. clGRushDark = TColor( $9EACB4 );
  1555. //[END OF COLOR CONSTANTS]
  1556. const
  1557. //[TGraphicTool FIELD OFFSET CONSTANTS]
  1558. go_Color = 0;
  1559. go_FontHeight = 4;
  1560. go_FontWidth = 8;
  1561. go_FontEscapement = 12;
  1562. go_FontOrientation = 16;
  1563. go_FontWeight = 20;
  1564. go_FontItalic = 24;
  1565. go_FontUnderline = 25;
  1566. go_FontStrikeOut = 26;
  1567. go_FontCharSet = 27;
  1568. go_FontOutPrecision = 28;
  1569. go_FontClipPrecision = 29;
  1570. go_FontQuality = 30;
  1571. go_FontPitch = 31;
  1572. go_FontName = 32;
  1573. go_BrushBitmap = 4;
  1574. go_BrushStyle = 8;
  1575. go_BrushLineColor = 9;
  1576. go_PenBrushBitmap = 4;
  1577. go_PenBrushStyle = 8;
  1578. go_PenStyle = 9;
  1579. go_PenWidth = 10;
  1580. go_PenMode = 14;
  1581. go_PenGeometric = 15;
  1582. go_PenEndCap = 16;
  1583. go_PenJoin = 17;
  1584. //[END OF TGraphicTool FIELD OFFSET CONSTANTS]
  1585. //[TGraphicTool]
  1586. type
  1587. TGraphicToolType = ( gttBrush, gttFont, gttPen );
  1588. {* Graphic object types, mainly for internal use. }
  1589. {++}(*TGraphicTool = class;*){--}
  1590. PGraphicTool = {-}^{+}TGraphicTool;
  1591. {* }
  1592. TOnGraphicChange = procedure ( Sender: PGraphicTool ) of object;
  1593. {* An event mainly for internal use. }
  1594. TBrushStyle = (bsSolid, bsClear, bsHorizontal, bsVertical,
  1595. bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross);
  1596. {* Available brush styles. }
  1597. TFontStyles = (fsBold, fsItalic, fsUnderline, fsStrikeOut);
  1598. {* Available font styles. }
  1599. TFontStyle = set of TFontStyles;
  1600. {* Font style is representing as a set of XFontStyles. }
  1601. TFontPitch = (fpDefault, fpFixed, fpVariable);
  1602. {* Availabe font pitch values. }
  1603. TFontName = type string;
  1604. {* Font name is represented as a string. }
  1605. TFontCharset = 0..255;
  1606. {* Font charset is represented by number from 0 to 255. }
  1607. TFontQuality = (fqDefault, fqDraft, fqProof, fqNonAntialiased, fqAntialiased
  1608. , fqClearType);
  1609. {* Font quality. }
  1610. TPenStyle = (psSolid, psDash, psDot, psDashDot, psDashDotDot, psClear,
  1611. psInsideFrame);
  1612. {* Available pen styles. For more info see Delphi or Win32 help files. }
  1613. TPenMode = (pmBlack, pmNotMerge, pmMaskNotPen, pmNotCopy, pmMaskPenNot,
  1614. pmNot, pmXor, pmNotMask, pmMask, pmNotXor, pmNop, pmMergePenNot,
  1615. pmCopy, pmMergeNotPen, pmMerge, pmWhite);
  1616. {* Available pen modes. For more info see Delphi or Win32 help files. }
  1617. TPenEndCap = (pecRound, pecSquare, pecFlat);
  1618. {* Avalable (for geometric pen) end cap styles. }
  1619. TPenJoin = (pjRound, pjBevel, pjMiter);
  1620. {* Available (for geometric pen) join styles. }
  1621. //[TGdiFont]
  1622. TGDIFont = packed record
  1623. Height: Integer;
  1624. Width: Integer;
  1625. Escapement: Integer;
  1626. Orientation: Integer;
  1627. Weight: Integer;
  1628. Italic: Boolean;
  1629. Underline: Boolean;
  1630. StrikeOut: Boolean;
  1631. CharSet: TFontCharset;
  1632. OutPrecision: Byte;
  1633. ClipPrecision: Byte;
  1634. Quality: TFontQuality;
  1635. Pitch: TFontPitch;
  1636. Name: array[0..LF_FACESIZE - 1] of KOLChar;
  1637. end;
  1638. //[TGDIBrush]
  1639. TGDIBrush = packed record
  1640. Bitmap: HBitmap;
  1641. Style: TBrushStyle;
  1642. LineColor: TColor;
  1643. end;
  1644. //[TGDIPen]
  1645. TGDIPen = packed record
  1646. BrushBitmap: HBitmap;
  1647. BrushStyle: TBrushStyle;
  1648. Style: TPenStyle;
  1649. Width: Integer;
  1650. Mode: TPenMode;
  1651. Geometric: Boolean;
  1652. EndCap: TPenEndCap;
  1653. Join: TPenJoin;
  1654. end;
  1655. //[TGDIToolData]
  1656. TGDIToolData = packed record
  1657. Color: TColor;
  1658. case Integer of
  1659. 1: (Font: TGDIFont);
  1660. 2: (Pen: TGDIPen);
  1661. 3: (Brush: TGDIBrush);
  1662. end;
  1663. //[TNewGraphicTool]
  1664. TNewGraphicTool = function: PGraphicTool;
  1665. { ---------------------------------------------------------------------
  1666. TGraphicTool - object to implement GDI-tools (brush, pen, font)
  1667. ---------------------------------------------------------------------- }
  1668. //[TGraphicTool DEFINITION]
  1669. TGraphicTool = object( TObj )
  1670. {* Incapsulates all GDI objects: Pen, Brush and Font. }
  1671. protected
  1672. fType: TGraphicToolType;
  1673. {$IFDEF GDI}
  1674. fHandle: THandle;
  1675. fParentGDITool: PGraphicTool;
  1676. {$ENDIF GDI}
  1677. fColorRGB: TColor;
  1678. fOnChange: TOnGraphicChange;
  1679. fData: TGDIToolData;
  1680. fNewProc: TNewGraphicTool;
  1681. {$IFDEF GDI}
  1682. fMakeHandleProc: function( Self_: PGraphicTool ): THandle;
  1683. {$ENDIF GDI}
  1684. procedure SetInt( const Index: Integer; Value: Integer );
  1685. function GetInt( const Index: Integer ): Integer;
  1686. procedure SetColor( Value: TColor );
  1687. {$IFDEF GDI}
  1688. function GetBrushBitmap: HBitmap; // for BCB only
  1689. procedure SetBrushBitmap(const Value: HBitmap);
  1690. function GetBrushStyle: TBrushStyle; // for BCB only
  1691. {$ENDIF GDI}
  1692. procedure SetBrushStyle(const Value: TBrushStyle);
  1693. function GetFontName: KOLString;
  1694. procedure SetFontName(const Value: KOLString);
  1695. function GetFontStyle: TFontStyle;
  1696. procedure SetFontStyle(const Value: TFontStyle);
  1697. function GetFontWeight: Integer; // for BCB only
  1698. procedure SetFontWeight(const Value: Integer);
  1699. {$IFDEF GDI}
  1700. function GetFontCharset: TFontCharset; // for BCB only
  1701. procedure SetFontCharset(const Value: TFontCharset);
  1702. function GetFontQuality: TFontQuality; // for BCB only
  1703. procedure SetFontQuality(const Value: TFontQuality);
  1704. function GetFontOrientation: Integer; // for BCB only
  1705. procedure SetFontOrientation(Value: Integer);
  1706. function GetFontPitch: TFontPitch; // for BCB only
  1707. procedure SetFontPitch(const Value: TFontPitch);
  1708. function GetPenMode: TPenMode; // for BCB only
  1709. procedure SetPenMode(const Value: TPenMode);
  1710. function GetPenStyle: TPenStyle; // for BCB only
  1711. procedure SetPenStyle(const Value: TPenStyle);
  1712. function GetGeometricPen: Boolean; // for BCB only
  1713. procedure SetGeometricPen(const Value: Boolean);
  1714. function GetPenEndCap: TPenEndCap; // for BCB only
  1715. procedure SetPenEndCap(const Value: TPenEndCap);
  1716. function GetPenJoin: TPenJoin; // for BCB only
  1717. procedure SetPenJoin(const Value: TPenJoin);
  1718. procedure SetLogFontStruct(const Value: TLogFont);
  1719. function GetLogFontStruct: TLogFont;
  1720. {$ENDIF GDI}
  1721. protected
  1722. procedure Changed;
  1723. {* }
  1724. {$IFDEF GDI}
  1725. function GetHandle: THandle;
  1726. {* }
  1727. {$ENDIF GDI}
  1728. protected
  1729. {$IFDEF _X_}
  1730. {$IFDEF GTK}
  1731. fPangoFontDesc: PPangoFontDescription;
  1732. function GetPangoFontDesc: PPangoFontDescription;
  1733. {$ENDIF GTK}
  1734. {$ENDIF _X_}
  1735. public
  1736. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  1737. {* }
  1738. {$IFDEF _X_}
  1739. {$IFDEF GTK}
  1740. property FontHandle: PPangoFontDescription read GetPangoFontDesc;
  1741. {$ENDIF GTK}
  1742. {$ENDIF _X_}
  1743. {$IFDEF GDI}
  1744. property Handle: THandle read GetHandle;
  1745. {* Every time, when accessed, real GDI object is created (if it is
  1746. not yet created). So, to prevent creating of the handle, use
  1747. HandleAllocated instead of comparing Handle with value 0. }
  1748. function HandleAllocated: Boolean;
  1749. {* Returns True, if handle is allocated (i.e., if real GDI
  1750. objet is created. }
  1751. {$ENDIF GDI}
  1752. property OnChange: TOnGraphicChange read fOnChange write fOnChange;
  1753. {* Called, when object is changed. }
  1754. {$IFDEF GDI}
  1755. function ReleaseHandle: Integer;
  1756. {* Returns Handle value (if allocated), releasing it from the
  1757. object (so, it is no more knows about this handle and its
  1758. HandleAllocated function returns False. }
  1759. {$ENDIF GDI}
  1760. property Color: TColor {index go_Color} read fData.Color write SetColor;
  1761. {* Color is the most common property for all Pen, Brush and
  1762. Font objects, so it is placed in its common for all of them. }
  1763. function Assign( Value: PGraphicTool ): PGraphicTool;
  1764. {* Assigns properties of the same (only) type graphic object,
  1765. excluding Handle. If assigning is really leading to change
  1766. object, procedure Changed is called. }
  1767. {$IFDEF GDI}
  1768. procedure AssignHandle( NewHandle: Integer );
  1769. {* Assigns value to Handle property. }
  1770. property BrushBitmap: HBitmap read {-BCB-}fData.Brush.Bitmap{+BCB+}
  1771. {BCB++}(*GetBrushBitmap*){--BCB}
  1772. write SetBrushBitmap;
  1773. {* Brush bitmap. For more info about using brush bitmap,
  1774. see Delphi or Win32 help files. }
  1775. {$ENDIF GDI}
  1776. property BrushStyle: TBrushStyle read {-BCB-}fData.Brush.Style{+BCB+}
  1777. {BCB++}(*GetBrushStyle*){--BCB}
  1778. write SetBrushStyle;
  1779. {$IFDEF GDI}
  1780. {* Brush style. }
  1781. property BrushLineColor: TColor index go_BrushLineColor
  1782. {$IFDEF F_P}
  1783. read GetInt
  1784. {$ELSE DELPHI}
  1785. read {-BCB-}fData.Brush.LineColor{+BCB+}
  1786. {BCB++}(*GetInt*){--BCB}
  1787. {$ENDIF F_P/DELPHI}
  1788. write SetInt;
  1789. {* Brush line color, used to represent lines in hatched brush. Default value is clBlack. }
  1790. {$ENDIF GDI}
  1791. property FontHeight: Integer index go_FontHeight
  1792. {$IFDEF F_P}
  1793. read GetInt
  1794. {$ELSE DELPHI}
  1795. read {-BCB-}fData.Font.Height{+BCB+}
  1796. {BCB++}(*GetInt*){--BCB}
  1797. {$ENDIF F_P/DELPHI}
  1798. write SetInt;
  1799. {* Font height. Value 0 (default) seys to use system default value,
  1800. negative values are to represent font height in "points", positive
  1801. - in pixels. In XCL usually positive values (if not 0) are used to
  1802. make appearance independent from different local settings. }
  1803. {$IFDEF GDI}
  1804. property FontWidth: Integer index go_FontWidth
  1805. {$IFDEF F_P}
  1806. read GetInt
  1807. {$ELSE DELPHI}
  1808. read {-BCB-}fData.Font.Width{+BCB+}
  1809. {BCB++}(*GetInt*){--BCB}
  1810. {$ENDIF F_P/DELPHI}
  1811. write SetInt;
  1812. {* Font width in logical units. If FontWidth = 0, then as it is said
  1813. in Win32.hlp, "the aspect ratio of the device is matched against the
  1814. digitization aspect ratio of the available fonts to find the closest match,
  1815. determined by the absolute value of the difference." }
  1816. property FontPitch: TFontPitch read {-BCB-}fData.Font.Pitch{+BCB+}
  1817. {BCB++}(*GetFontPitch*){--BCB}
  1818. write SetFontPitch;
  1819. {* Font pitch. Change it very rare. }
  1820. {$ENDIF GDI}
  1821. property FontStyle: TFontStyle read GetFontStyle write SetFontStyle;
  1822. {* Very useful property to control text appearance. }
  1823. {$IFDEF GDI}
  1824. property FontCharset: TFontCharset read {-BCB-}fData.Font.Charset{+BCB+}
  1825. {BCB++}(*GetFontCharset*){--BCB}
  1826. write SetFontCharset;
  1827. {* Do not change it if You do not know what You do. }
  1828. property FontQuality: TFontQuality read {-BCB-}fData.Font.Quality{+BCB+}
  1829. {BCB++}(*GetFontQuality*){--BCB}
  1830. write SetFontQuality;
  1831. {* Font quality. }
  1832. property FontOrientation: Integer read {-BCB-}fData.Font.Orientation{+BCB+}
  1833. {BCB++}(*GetFontOrientation*){--BCB}
  1834. write SetFontOrientation;
  1835. {* It is possible to rotate text in XCL just by changing this
  1836. property of a font (tenths of degree, i.e. value 900 represents
  1837. 90 degree - text written from bottom to top). }
  1838. {$ENDIF GDI}
  1839. property FontWeight: Integer read {-BCB-}fData.Font.Weight{+BCB+}
  1840. {BCB++}(*GetFontWeight*){--BCB}
  1841. write SetFontWeight;
  1842. {* Additional font weight for bold fonts (must be 0..1000). When set to
  1843. value <> 0, fsBold is added to FontStyle. And otherwise, when set to 0,
  1844. fsBold is removed from FontStyle. Value 700 corresponds to Bold,
  1845. 400 to Normal. }
  1846. property FontName: KOLString read GetFontName write SetFontName;
  1847. {* Font face name. }
  1848. {$IFDEF GDI}
  1849. function IsFontTrueType: Boolean;
  1850. {* Returns True, if font is True Type. Requires of creating of a Handle,
  1851. if it is not yet created. }
  1852. property PenWidth: Integer index go_PenWidth
  1853. {$IFDEF F_P}
  1854. read GetInt
  1855. {$ELSE DELPHI}
  1856. read {-BCB-}fData.Pen.Width{+BCB+}
  1857. {BCB++}(*GetInt*){--BCB}
  1858. {$ENDIF F_P/DELPHI}
  1859. write SetInt;
  1860. {* Value 0 means default pen width. }
  1861. property PenStyle: TPenStyle read {-BCB-}fData.Pen.Style{+BCB+}
  1862. {BCB++}(*GetPenStyle*){--BCB}
  1863. write SetPenStyle;
  1864. {* Pen style. }
  1865. property PenMode: TPenMode read {-BCB-}fData.Pen.Mode{+BCB+}
  1866. {BCB++}(*GetPenMode*){--BCB}
  1867. write SetPenMode;
  1868. {* Pen mode. }
  1869. property GeometricPen: Boolean read {-BCB-}fData.Pen.Geometric{+BCB+}
  1870. {BCB++}(*GetGeometricPen*){--BCB}
  1871. write SetGeometricPen;
  1872. {* True if Pen is geometric. Note, that under Win95/98 only pen styles
  1873. psSolid, psNull, psInsideFrame are supported by OS. }
  1874. property PenBrushStyle: TBrushStyle read {-BCB-}fData.Pen.BrushStyle{+BCB+}
  1875. {BCB++}(*GetBrushStyle*){--BCB}
  1876. write SetBrushStyle;
  1877. {* Brush style for hatched geometric pen. }
  1878. property PenBrushBitmap: HBitmap read {-BCB-}fData.Pen.BrushBitmap{+BCB+}
  1879. {BCB++}(*GetBrushBitmap*){--BCB}
  1880. write SetBrushBitmap;
  1881. {* Brush bitmap for geometric pen (if assigned Pen is functioning as
  1882. its style = BS_PATTERN, regadless of PenBrushStyle value). }
  1883. property PenEndCap: TPenEndCap read {-BCB-}fData.Pen.EndCap{+BCB+}
  1884. {BCB++}(*GetPenEndCap*){--BCB}
  1885. write SetPenEndCap;
  1886. {* Pen end cap mode - for GeometricPen only. }
  1887. property PenJoin: TPenJoin read {-BCB-}fData.Pen.Join{+BCB+}
  1888. {BCB++}(*GetPenJoin*){--BCB}
  1889. write SetPenJoin;
  1890. {* Pen join mode - for GeometricPen only. }
  1891. property LogFontStruct: TLogFont read GetLogFontStruct write SetLogFontStruct;
  1892. {* by Alex Pravdin: a property to change all font structure items at once. }
  1893. {$ENDIF GDI}
  1894. end;
  1895. //[END OF TGraphicTool DEFINITION]
  1896. //[Color2XXX FUNCTIONS]
  1897. function Color2RGB( Color: TColor ): TColor;
  1898. {* Function to get RGB color from system color. Parameter can be also RGB
  1899. color, in that case result is just equal to a parameter. }
  1900. {$IFDEF GTK}
  1901. function Color2GDKColor( Color: TColor ): TGdkColor;
  1902. {$ENDIF GTK}
  1903. function ColorsMix( Color1, Color2: TColor ): TColor;
  1904. {* Returns color, which RGB components are build as an (approximate)
  1905. arithmetic mean of correspondent RGB components of both source
  1906. colors (these both are first converted from system to RGB, and
  1907. result is always RGB color). Please note: this function is fast,
  1908. but can be not too exact. }
  1909. {$IFDEF WIN_GDI}
  1910. function Color2RGBQuad( Color: TColor ): TRGBQuad;
  1911. {* Converts color to RGB, used to represent RGB values in palette entries
  1912. (actually swaps R and B bytes). }
  1913. function Color2Color16( Color: TColor ): WORD;
  1914. {* Converts Color to RGB, packed to word (as it is used in format pf16bit). }
  1915. function Color2Color15( Color: TColor ): WORD;
  1916. {* Converts Color to RGB, packed to word (as it is used in format pf15bit). }
  1917. {$ifdef wince}
  1918. procedure CeFrameRect(DC: HDC; const Rect: TRect; Color: TColor);
  1919. {$endif wince}
  1920. //[DefFont VARIABLE]
  1921. var // New TFont instances are intialized with the values in this structure:
  1922. DefFont: TGDIFont = (
  1923. Height: 0;
  1924. Width: 0;
  1925. Escapement: 0;
  1926. Orientation: 0;
  1927. Weight: 0;
  1928. Italic: FALSE;
  1929. Underline: FALSE;
  1930. StrikeOut: FALSE;
  1931. CharSet: 1;
  1932. OutPrecision: 0;
  1933. ClipPrecision: 0;
  1934. Quality: fqDefault;
  1935. Pitch: fpDefault;
  1936. {$IFDEF UNICODE_CTRLS}
  1937. Name: ( 'M', 'S', ' ', 'S', 'a', 'n', 's', ' ', 'S', 'e', 'r', 'i', 'f',
  1938. #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0,
  1939. #0, #0 );
  1940. {$ELSE}
  1941. Name: 'MS Sans Serif';
  1942. {$ENDIF}
  1943. );
  1944. DefFontColor: TColor = clWindowText;
  1945. {* Default font color. }
  1946. //[GlobalGraphics_UseFontOrient]
  1947. GlobalGraphics_UseFontOrient: Boolean;
  1948. {* Global flag. If stays False (default), Orientation property of Font
  1949. objects is ignored. This flag is set to True automatically in
  1950. RotateFonts add-on. }
  1951. {$ENDIF WIN_GDI}
  1952. { -- Constructors for different GDI tools -- }
  1953. //[New FUNCTIONS FOR TGraphicTool]
  1954. function NewFont: PGraphicTool;
  1955. {* Creates and returns font graphic tool object. }
  1956. function NewBrush: PGraphicTool;
  1957. {* Creates and returns new brush object. }
  1958. function NewPen: PGraphicTool;
  1959. {* Creates and returns new pen object. }
  1960. { -- TCanvas object -- }
  1961. //[TCanvas]
  1962. const
  1963. HandleValid = 1;
  1964. PenValid = 2;
  1965. BrushValid = 4;
  1966. FontValid = 8;
  1967. ChangingCanvas = 16;
  1968. {$IFDEF WIN_GDI}
  1969. type
  1970. TFillStyle = (fsSurface, fsBorder);
  1971. {* Available filling styles. For more info see Win32 or Delphi help files. }
  1972. TFillMode = (fmAlternate, fmWinding);
  1973. {* Available filling modes. For more info see Win32 or Delphi help files. }
  1974. TCopyMode = Integer;
  1975. {* Available copying modes are following:
  1976. | cmBlackness<br>
  1977. | cmDstInvert<br>
  1978. | cmMergeCopy<br>
  1979. | cmMergePaint<br>
  1980. | cmNotSrcCopy<br>
  1981. | cmNotSrcErase<br>
  1982. | cmPatCopy<br>
  1983. | cmPatInvert<br>
  1984. | cmPatPaint<br>
  1985. | cmSrcAnd<br>
  1986. | cmSrcCopy<br>
  1987. | cmSrcErase<br>
  1988. | cmSrcInvert<br>
  1989. | cmSrcPaint<br>
  1990. | cmWhiteness<br>&nbsp;&nbsp;&nbsp;
  1991. Also it is possible to use any other available ROP2 modes. For more info,
  1992. see Win32 help files. }
  1993. const
  1994. cmBlackness = BLACKNESS;
  1995. cmDstInvert = DSTINVERT;
  1996. cmMergeCopy = MERGECOPY;
  1997. cmMergePaint = MERGEPAINT;
  1998. cmNotSrcCopy = NOTSRCCOPY;
  1999. cmNotSrcErase = NOTSRCERASE;
  2000. cmPatCopy = PATCOPY;
  2001. cmPatInvert = PATINVERT;
  2002. cmPatPaint = PATPAINT;
  2003. cmSrcAnd = SRCAND;
  2004. cmSrcCopy = SRCCOPY;
  2005. cmSrcErase = SRCERASE;
  2006. cmSrcInvert = SRCINVERT;
  2007. cmSrcPaint = SRCPAINT;
  2008. cmWhiteness = WHITENESS;
  2009. {$ENDIF WIN_GDI}
  2010. type
  2011. {$IFDEF _X_}
  2012. {$IFDEF GTK}
  2013. HDC = PGdkGC;
  2014. {$ENDIF GTK}
  2015. {$ENDIF _X_}
  2016. {++}(*TCanvas = class;*){--}
  2017. PCanvas = {-}^{+}TCanvas;
  2018. {* }
  2019. TOnGetHandle = function( Canvas: PCanvas ): HDC of object;
  2020. {* For internal use mainly. }
  2021. TOnTextArea = procedure( Sender: PCanvas; var Size : TSize; var P0 : TPoint );
  2022. {* Event to calculate actual area, occupying by a text. It is used
  2023. to optionally extend calculating of TextArea taking into considaration
  2024. font Orientation property. }
  2025. { ---------------------------------------------------------------------
  2026. TCanvas - high-level drawing helper object
  2027. ----------------------------------------------------------------------- }
  2028. //[TCanvas DEFINITION]
  2029. TCanvas = object( TObj )
  2030. {* Very similar to VCL's TCanvas object. But with some changes, specific
  2031. for KOL: there is no necessary to use canvases in all applications.
  2032. And graphic tools objects are not created with canvas, but only
  2033. if really accessed in program. (Actually, even if paint box used,
  2034. only programmer decides, if to implement painting using Canvas or
  2035. to call low level API drawing functions working directly with DC).
  2036. Therefore TCanvas has some powerful extensions: rotated text support,
  2037. geometric pen support - just by changing correspondent properties
  2038. of certain graphic tool objects (Font.FontOrientation, Pen.GeometricPen).
  2039. See also additional Font properties (Font.FontWeight, Font.FontQuality,
  2040. etc. }
  2041. protected
  2042. fOwnerControl: Pointer; //PControl;
  2043. {$IFDEF _X_}
  2044. {$IFDEF GTK}
  2045. fDrawable: PGdkDrawable;
  2046. fTmpColor: PGdkColor;
  2047. {$ENDIF GTK}
  2048. {$ENDIF _X_}
  2049. fHandle : HDC;
  2050. fPenPos : TPoint;
  2051. fState : Byte;
  2052. fBrush, fPen: PGraphicTool;
  2053. fFont : PGraphicTool; // order is important for ASM version
  2054. {$IFDEF GDI}
  2055. fCopyMode : TCopyMode;
  2056. fOnChange: TOnEvent;
  2057. {$ENDIF GDI}
  2058. fOnGetHandle: TOnGetHandle;
  2059. {$IFDEF _X_}
  2060. {$IFDEF GTK}
  2061. fSavedState: TGdkGCValues;
  2062. procedure SaveState;
  2063. procedure RestoreState;
  2064. {$ENDIF GTK}
  2065. {$ENDIF _X_}
  2066. {$IFDEF GDI}
  2067. procedure SetHandle( Value : HDC );
  2068. {$ENDIF GDI}
  2069. procedure SetPenPos( const Value : TPoint );
  2070. {$IFDEF GDI}
  2071. procedure CreatePen;
  2072. procedure CreateBrush;
  2073. procedure CreateFont;
  2074. procedure Changing;
  2075. {$ENDIF GDI}
  2076. procedure ObjectChanged( Sender : PGraphicTool );
  2077. function GetBrush: PGraphicTool;
  2078. function GetFont: PGraphicTool;
  2079. function GetPen: PGraphicTool;
  2080. function GetHandle: HDC;
  2081. procedure AssignChangeEvents;
  2082. {$IFDEF GDI}
  2083. function GetPixels(X, Y: Integer): TColor;
  2084. procedure SetPixels(X, Y: Integer; const Value: TColor);
  2085. protected
  2086. fIsPaintDC : Boolean;
  2087. {* TRUE, if DC obtained during current WM_PAINT (or WM_ERASEBKGND?)
  2088. processing for a control. This affects a way how Handle is released. }
  2089. {++}(*public*){--}
  2090. destructor Destroy;{-}virtual;{+}{++}(*override;*){--}
  2091. {* }
  2092. {++}(*protected*){--}
  2093. {$ENDIF GDI}
  2094. property OnGetHandle: TOnGetHandle read fOnGetHandle write fOnGetHandle;
  2095. {* For internal use only. }
  2096. {$IFDEF GDI}
  2097. {$ENDIF GDI}
  2098. public
  2099. property Handle : HDC read GetHandle {$IFDEF GDI} write SetHandle {$ENDIF GDI};
  2100. {* GDI device context object handle. Never created by
  2101. Canvas itself (to use Canvas with memory bitmaps,
  2102. always create DC by yourself and assign it to the
  2103. Handle property of Canvas object, or use property
  2104. Canvas of a bitmap). }
  2105. property PenPos : TPoint read FPenPos write SetPenPos;
  2106. {* Position of a pen. }
  2107. property Pen : PGraphicTool read GetPen;
  2108. {* Pen of Canvas object. Do not change its Pen.OnChange event value. }
  2109. property Brush : PGraphicTool read GetBrush;
  2110. {* Brush of Canvas object. Do not change its Brush.OnChange event value. }
  2111. property Font : PGraphicTool read GetFont;
  2112. {* Font of Canvas object. Do not change its Font.OnChange event value. }
  2113. {$IFNDEF NOT_USE_KOLMATH} // if using KOLmath disabled, Arc becomes unavailable
  2114. procedure Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); {$ifdef wince}cdecl{$else}stdcall{$endif};
  2115. {* Draws arc. For more info, see Delphi TCanvas help. }
  2116. {$ENDIF NOT_USE_KOLMATH}
  2117. {$IFDEF GDI}
  2118. procedure Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); {$ifdef wince}cdecl{$else}stdcall{$endif};
  2119. {* Draws chord. For more info, see Delphi TCanvas help. }
  2120. procedure DrawFocusRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  2121. {* Draws rectangle to represent focused visual object.
  2122. For more info, see Delphi TCanvas help. }
  2123. procedure Ellipse(X1, Y1, X2, Y2: Integer);
  2124. {* Draws an ellipse. For more info, see Delphi TCanvas help. }
  2125. {$ENDIF GDI}
  2126. procedure FillRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  2127. {* Fills rectangle. For more info, see Delphi TCanvas help. }
  2128. {$IFDEF GDI}
  2129. procedure FillRgn( const Rgn : HRgn );
  2130. {* Fills region. For more info, see Delphi TCanvas help. }
  2131. procedure FloodFill(X, Y: Integer; Color: TColor; FillStyle: TFillStyle);
  2132. {* Fills a figure with givien color, floodfilling its surface.
  2133. For more info, see Delphi TCanvas help. }
  2134. procedure FrameRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  2135. {* Draws a rectangle using Brush settings (color, etc.).
  2136. For more info, see Delphi TCanvas help. }
  2137. {$ENDIF GDI}
  2138. procedure MoveTo( X, Y : Integer );
  2139. {* Moves current PenPos to a new position.
  2140. For more info, see Delphi TCanvas help. }
  2141. procedure LineTo( X, Y : Integer );
  2142. {* Draws a line from current PenPos up to new position.
  2143. For more info, see Delphi TCanvas help. }
  2144. {$IFDEF GDI}
  2145. procedure Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); {$ifdef wince}cdecl{$else}stdcall{$endif};
  2146. {* Draws a pie. For more info, see Delphi TCanvas help. }
  2147. procedure Polygon(const Points: array of TPoint);
  2148. {* Draws a polygon. For more info, see Delphi TCanvas help. }
  2149. procedure Polyline(const Points: array of TPoint);
  2150. {* Draws a bound for polygon. For more info, see Delphi TCanvas help. }
  2151. procedure Rectangle(X1, Y1, X2, Y2: Integer);
  2152. {* Draws a rectangle using current Pen and/or Brush.
  2153. For more info, see Delphi TCanvas help. }
  2154. procedure RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
  2155. {* Draws a rounded rectangle. For more info, see Delphi TCanvas help. }
  2156. {$ENDIF GDI}
  2157. procedure TextOut(X, Y: Integer; const Text: KOLString); {$ifdef wince}cdecl{$else}stdcall{$endif};
  2158. {* Draws a text. For more info, see Delphi TCanvas help. }
  2159. procedure ExtTextOut( X, Y: Integer; Options: DWORD; const Rect: TRect; const Text: KOLString;
  2160. const Spacing: array of Integer );
  2161. {* }
  2162. procedure TextRect(const Rect: TRect; X, Y: Integer; const Text: KOLString);
  2163. {* Draws a text, clipping output into given rectangle.
  2164. For more info, see Delphi TCanvas help. }
  2165. {$IFDEF GDI}
  2166. procedure DrawText(Text:KOLString; var Rect:TRect; Flags:DWord);
  2167. {* }
  2168. {$ENDIF GDI}
  2169. function TextExtent(const Text: KOLstring): TSize;
  2170. {* Calculates size of a Text, using current Font settings.
  2171. Does not need in Handle for Canvas object (if it is not
  2172. yet allocated, temporary device context is created and used. }
  2173. procedure TextArea( const Text : KOLString; var Sz : TSize; var P0 : TPoint );
  2174. {* Calculates size and starting point to output Text,
  2175. taking into considaration all Font attributes, including
  2176. Orientation (only if GlobalGraphics_UseFontOrient flag
  2177. is set to True, i.e. if rotated fonts are used).
  2178. Like for TextExtent, does not need in Handle (and if this
  2179. last is not yet allocated/assigned, temporary device context
  2180. is created and used). }
  2181. function TextWidth(const Text: KOLstring): Integer;
  2182. {* Calculates text width (using TextArea). }
  2183. function TextHeight(const Text: KOLstring): Integer;
  2184. {* Calculates text height (using TextArea). }
  2185. {$IFDEF GDI}
  2186. function ClipRect: TRect;
  2187. {* returns ClipBox. by Dmitry Zharov. }
  2188. {$IFNDEF _FPC}
  2189. {$IFNDEF _D2} //------- WideString not supported in D2
  2190. procedure WTextOut(X, Y: Integer; const WText: WideString); {$ifdef wince}cdecl{$else}stdcall{$endif};
  2191. {* Draws a Unicode text. }
  2192. procedure WExtTextOut( X, Y: Integer; Options: DWORD; const Rect: TRect;
  2193. const WText: WideString; const Spacing: array of Integer );
  2194. {* }
  2195. procedure WDrawText(WText: WideString; var Rect:TRect; Flags:DWord);
  2196. {* }
  2197. procedure WTextRect(const Rect: TRect; X, Y: Integer;
  2198. const WText: WideString);
  2199. {* Draws a Unicode text, clipping output into given rectangle. }
  2200. function WTextExtent( const WText: WideString ): TSize;
  2201. {* Calculates Unicode text width and height. }
  2202. function WTextWidth( const WText: WideString ): Integer;
  2203. {* Calculates Unicode text width. }
  2204. function WTextHeight( const WText: WideString ): Integer;
  2205. {* Calculates Unicode text height. }
  2206. {$ENDIF _D2}
  2207. {$ENDIF _FPC}
  2208. property ModeCopy : TCopyMode read fCopyMode write fCopyMode;
  2209. {* Current copy mode. Is used in CopyRect method. }
  2210. procedure CopyRect( const DstRect : TRect; SrcCanvas : PCanvas; const SrcRect : TRect );
  2211. {* Copyes a rectangle from source to destination, using StretchBlt. }
  2212. property OnChange: TOnEvent read fOnChange write fOnChange;
  2213. {* }
  2214. function Assign( SrcCanvas : PCanvas ) : Boolean;
  2215. {* }
  2216. {$ENDIF GDI}
  2217. {$IFDEF _X_}
  2218. protected // for _X_ case, RequiredState is protected yet (???)
  2219. procedure ForeBack(fg_color, bk_color: TColor); // install colors just before drawing
  2220. {$ENDIF _X_}
  2221. {$IFDEF GDI}
  2222. function RequiredState( ReqState : DWORD ): HDC; {$ifdef wince}cdecl{$else}stdcall{$endif};// public now
  2223. {* It is possible to call this method before using Handle property
  2224. to pass it into API calls - to provide valid combinations of
  2225. pen, brush and font, selected into device context. This method
  2226. can not provide valid Handle - You always must create it by
  2227. yourself and assign to TCanvas.Handle property manually.
  2228. To optimize assembler version, returns Handle value. }
  2229. public
  2230. {$ENDIF GDI}
  2231. procedure DeselectHandles;
  2232. {* Call this method to deselect all graphic tool objects from the canvas. }
  2233. {$IFDEF GDI}
  2234. property Pixels[ X, Y: Integer ]: TColor read GetPixels write SetPixels;
  2235. {* Obvious. }
  2236. {$ENDIF GDI}
  2237. end;
  2238. //[END OF TCanvas DEFINITION]
  2239. //[NewCanvas DECLARATION]
  2240. function NewCanvas( DC: HDC ): PCanvas;
  2241. {* Use to construct Canvas on base of memory DC. }
  2242. //[GlobalCanvas_OnTextArea]
  2243. var
  2244. GlobalCanvas_OnTextArea : TOnTextArea;
  2245. {* Global event to extend Canvas with possible add-ons, applied
  2246. when rotated fonts are used only (to take into consideration
  2247. Font.Orientation property in TextArea method). }
  2248. {$IFDEF WIN_GDI}
  2249. { -- Image list object -- }
  2250. //[IMAGE LIST]
  2251. type
  2252. TImageListColors = (ilcColor,ilcColor4,ilcColor8,ilcColor16,
  2253. ilcColor24,ilcColor32,ilcColorDDB,ilcDefault);
  2254. {* ImageList color schemes available. }
  2255. TDrawingStyles = ( dsBlend25, dsBlend50, dsMask, dsTransparent );
  2256. {* ImageList drawing styles available. }
  2257. TDrawingStyle = Set of TDrawingStyles;
  2258. {* Style of drawing is a combination of all available drawing styles. }
  2259. TImageType = (itBitmap,itIcon,itCursor);
  2260. {* ImageList types available. }
  2261. {++}(*TImageList = class;*){--}
  2262. PImageList = {-}^{+}TImageList;
  2263. {* }
  2264. TImgLOVrlayIdx = 1..15;
  2265. { ---------------------------------------------------------------------
  2266. TImageList - images container
  2267. ----------------------------------------------------------------------- }
  2268. //[TImageList DEFINITION]
  2269. TImageList = object( TObj )
  2270. {* ImageList incapsulation. }
  2271. protected
  2272. FHandle: THandle;
  2273. FControl: Pointer; // PControl;
  2274. fPrev, fNext: PImageList;
  2275. FColors: TImageListColors;
  2276. FMasked: Boolean;
  2277. FImgWidth: Integer;
  2278. FImgHeight: Integer;
  2279. FDrawingStyle: TDrawingStyle;
  2280. FBlendColor: TColor;
  2281. fBkColor: TColor;
  2282. FAllocBy: Integer;
  2283. FShareImages: Boolean;
  2284. FOverlay: array[ TImgLOVrlayIdx ] of Integer;
  2285. function HandleNeeded : Boolean;
  2286. procedure SetColors(const Value: TImageListColors);
  2287. procedure SetMasked(const Value: Boolean);
  2288. procedure SetImgWidth(const Value: Integer);
  2289. procedure SetImgHeight(const Value: Integer);
  2290. function GetCount: Integer;
  2291. function GetBkColor: TColor;
  2292. procedure SetBkColor(const Value: TColor);
  2293. function GetBitmap: HBitmap;
  2294. function GetMask: HBitmap;
  2295. function GetDrawStyle : DWord;
  2296. procedure SetAllocBy(const Value: Integer);
  2297. function GetHandle: THandle;
  2298. function GetOverlay(Idx: TImgLOVrlayIdx): Integer;
  2299. procedure SetOverlay(Idx: TImgLOVrlayIdx; const Value: Integer);
  2300. protected
  2301. procedure SetHandle(const Value: THandle);
  2302. {*}
  2303. public
  2304. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  2305. {*}
  2306. property Handle : THandle read GetHandle write SetHandle;
  2307. {* Handle of ImageList object. }
  2308. property ShareImages : Boolean read FShareImages write FShareImages;
  2309. {* True if images are shared between processes (it is set to True,
  2310. if its Handle is assigned to given value, which is a handle of
  2311. already existing ImageList object). }
  2312. property Colors : TImageListColors read FColors write SetColors;
  2313. {* Colors used to represent images. }
  2314. property Masked : Boolean read FMasked write SetMasked;
  2315. {* True, if mask is used. It is set to True, if first added image
  2316. is icon, e.g. }
  2317. property ImgWidth : Integer read FImgWidth write SetImgWidth;
  2318. {* Width of every image in list. If change, ImageList is cleared. }
  2319. property ImgHeight : Integer read FImgHeight write SetImgHeight;
  2320. {* Height of every image in list. If change, ImageList is cleared. }
  2321. property Count : Integer read GetCount;
  2322. {* Number of images in list. }
  2323. property AllocBy : Integer read FAllocBy write SetAllocBy;
  2324. {* Allocation factor. Default is 1. Set it to size of ImageList if this
  2325. value is known - to optimize speed of allocation. }
  2326. property BkColor : TColor read GetBkColor write SetBkColor;
  2327. {* Background color. }
  2328. property BlendColor : TColor read FBlendColor write FBlendColor;
  2329. {* Blend color. }
  2330. property Bitmap : HBitmap read GetBitmap;
  2331. {* Bitmap, containing all ImageList images (tiled horizontally). }
  2332. property Mask : HBitmap read GetMask;
  2333. {* Monochrome bitmap, containing masks for all images in list (if not
  2334. Masked, always returns nil). }
  2335. function ImgRect( Idx : Integer ) : TRect;
  2336. {* Rectangle occupied of given image in ImageList. }
  2337. function Add( Bmp, Msk : HBitmap ) : Integer;
  2338. {* Adds bitmap and given mask to ImageList. }
  2339. function AddMasked( Bmp : HBitmap; Color : TColor ) : Integer;
  2340. {* Adds bitmap to ImageList, using given color to create mask. }
  2341. function AddIcon( Ico : HIcon ) : Integer;
  2342. {* Adds icon to ImageList (always masked). }
  2343. procedure Delete( Idx : Integer );
  2344. {* Deletes given image from ImageList. }
  2345. procedure Clear;
  2346. {* Makes ImageList empty. }
  2347. function Replace( Idx : Integer; Bmp, Msk : HBitmap ) : Boolean;
  2348. {* Replaces given (by index) image with bitmap and its mask with mask bitmap. }
  2349. function ReplaceIcon( Idx : Integer; Ico : HIcon ) : Boolean;
  2350. {* Replaces given (by index) image with an icon. }
  2351. function Merge( Idx : Integer; ImgList2 : PImageList; Idx2 : Integer; X, Y : Integer )
  2352. : PImageList;
  2353. {* Merges two ImageList objects, returns resulting ImageList. }
  2354. function ExtractIcon( Idx : Integer ) : HIcon;
  2355. {* Extracts icon by index. }
  2356. function ExtractIconEx( Idx : Integer ) : HIcon;
  2357. {* Extracts icon (is created using current drawing style). }
  2358. property DrawingStyle : TDrawingStyle read FDrawingStyle write FDrawingStyle;
  2359. {* Drawing style. }
  2360. procedure Draw( Idx : Integer; DC : HDC; X, Y : Integer );
  2361. {* Draws given (by index) image from ImageList onto passed Device Context. }
  2362. procedure StretchDraw( Idx : Integer; DC : HDC; const Rect : TRect );
  2363. {* Draws given image with stratching. }
  2364. function LoadBitmap( ResourceName : PKOLChar; TranspColor : TColor ) : Boolean;
  2365. {* Loads ImageList from resource. }
  2366. //function LoadIcon( ResourceName : PChar ) : Boolean;
  2367. //function LoadCursor( ResourceName : PChar ) : Boolean;
  2368. function LoadFromFile( FileName : PKOLChar; TranspColor : TColor; ImgType : TImageType ) : Boolean;
  2369. {* Loads ImageList from file. }
  2370. function LoadSystemIcons( SmallIcons : Boolean ) : Boolean;
  2371. {* Assigns ImageList to system icons list (big or small). }
  2372. property Overlay[ Idx: TImgLOVrlayIdx ]: Integer read GetOverlay write SetOverlay;
  2373. {* Overlay images for image list (images, used as overlay images to draw over
  2374. other images from the image list). These overalay images can be used in
  2375. listview and treeview as overlaying images (up to four masks at the same
  2376. time). }
  2377. {$IFDEF USE_CONSTRUCTORS}
  2378. constructor CreateImageList( POwner: Pointer );
  2379. {$ENDIF USE_CONSTRUCTORS}
  2380. end;
  2381. //[END OF TImageList DEFINITION]
  2382. //[IMAGE LIST API]
  2383. {$ifdef win32}
  2384. const
  2385. CLR_NONE = $FFFFFFFF;
  2386. CLR_DEFAULT = $FF000000;
  2387. type
  2388. HImageList = THandle;
  2389. const
  2390. ILC_MASK = $0001;
  2391. ILC_COLOR = $00FE;
  2392. ILC_COLORDDB = $00FE;
  2393. ILC_COLOR4 = $0004;
  2394. ILC_COLOR8 = $0008;
  2395. ILC_COLOR16 = $0010;
  2396. ILC_COLOR24 = $0018;
  2397. ILC_COLOR32 = $0020;
  2398. ILC_PALETTE = $0800;
  2399. const
  2400. ILD_NORMAL = $0000;
  2401. ILD_TRANSPARENT = $0001;
  2402. ILD_MASK = $0010;
  2403. ILD_IMAGE = $0020;
  2404. ILD_BLEND25 = $0002;
  2405. ILD_BLEND50 = $0004;
  2406. ILD_OVERLAYMASK = $0F00;
  2407. const
  2408. ILD_SELECTED = ILD_BLEND50;
  2409. ILD_FOCUS = ILD_BLEND25;
  2410. ILD_BLEND = ILD_BLEND50;
  2411. CLR_HILIGHT = CLR_DEFAULT;
  2412. function ImageList_Create(CX, CY: Integer; Flags: UINT;
  2413. Initial, Grow: Integer): HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2414. function ImageList_Destroy(ImageList: HImageList): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2415. function ImageList_GetImageCount(ImageList: HImageList): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2416. function ImageList_SetImageCount(ImageList: HImageList; Count: Integer): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2417. function ImageList_Add(ImageList: HImageList; Image, Mask: HBitmap): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2418. function ImageList_ReplaceIcon(ImageList: HImageList; Index: Integer;
  2419. Icon: HIcon): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2420. function ImageList_SetBkColor(ImageList: HImageList; ClrBk: TColorRef): TColorRef; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2421. function ImageList_GetBkColor(ImageList: HImageList): TColorRef; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2422. function ImageList_SetOverlayImage(ImageList: HImageList; Image: Integer;
  2423. Overlay: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2424. function ImageList_AddIcon(ImageList: HImageList; Icon: HIcon): Integer;
  2425. function Index2OverlayMask(Index: Integer): Integer;
  2426. function ImageList_Draw(ImageList: HImageList; Index: Integer;
  2427. Dest: HDC; X, Y: Integer; Style: UINT): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2428. function ImageList_Replace(ImageList: HImageList; Index: Integer;
  2429. Image, Mask: HBitmap): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2430. function ImageList_AddMasked(ImageList: HImageList; Image: HBitmap;
  2431. Mask: TColorRef): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2432. function ImageList_DrawEx(ImageList: HImageList; Index: Integer;
  2433. Dest: HDC; X, Y, DX, DY: Integer; Bk, Fg: TColorRef; Style: Cardinal): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2434. function ImageList_Remove(ImageList: HImageList; Index: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2435. function ImageList_GetIcon(ImageList: HImageList; Index: Integer;
  2436. Flags: Cardinal): HIcon; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2437. {$IFDEF UNICODE_CTRLS}
  2438. function ImageList_LoadImage(Instance: THandle; Bmp: PWideChar; CX, Grow: Integer;
  2439. Mask: TColorRef; pType, Flags: Cardinal): HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2440. {$ELSE}
  2441. function ImageList_LoadImage(Instance: THandle; Bmp: PAnsiChar; CX, Grow: Integer;
  2442. Mask: TColorRef; pType, Flags: Cardinal): HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2443. {$ENDIF}
  2444. function ImageList_BeginDrag(ImageList: HImageList; Track: Integer;
  2445. XHotSpot, YHotSpot: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2446. function ImageList_EndDrag: Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2447. function ImageList_DragEnter(LockWnd: HWnd; X, Y: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2448. function ImageList_DragLeave(LockWnd: HWnd): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2449. function ImageList_DragMove(X, Y: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2450. function ImageList_SetDragCursorImage(ImageList: HImageList; Drag: Integer;
  2451. XHotSpot, YHotSpot: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2452. function ImageList_DragShowNolock(Show: Bool): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2453. function ImageList_GetDragImage(Point, HotSpot: PPoint): HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2454. { macros }
  2455. procedure ImageList_RemoveAll(ImageList: HImageList); {$ifdef wince}cdecl{$else}stdcall{$endif};
  2456. function ImageList_ExtractIcon(Instance: THandle; ImageList: HImageList;
  2457. Image: Integer): HIcon; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2458. function ImageList_LoadBitmap(Instance: THandle; Bmp: PKOLChar;
  2459. CX, Grow: Integer; MasK: TColorRef): HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2460. //function ImageList_Read(Stream: IStream): HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2461. //function ImageList_Write(ImageList: HImageList; Stream: IStream): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2462. //[TImageInfo]
  2463. type
  2464. PImageInfo = ^TImageInfo;
  2465. TImageInfo = {$ifndef wince}packed{$endif} record
  2466. hbmImage: HBitmap;
  2467. hbmMask: HBitmap;
  2468. Unused1: Integer;
  2469. Unused2: Integer;
  2470. rcImage: TRect;
  2471. end;
  2472. function ImageList_GetIconSize(ImageList: HImageList; var CX, CY: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2473. function ImageList_SetIconSize(ImageList: HImageList; CX, CY: Integer): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2474. function ImageList_GetImageInfo(ImageList: HImageList; Index: Integer;
  2475. var ImageInfo: TImageInfo): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2476. function ImageList_Merge(ImageList1: HImageList; Index1: Integer;
  2477. ImageList2: HImageList; Index2: Integer; DX, DY: Integer)://Bool - ERROR IN VCL
  2478. HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2479. {$endif win32}
  2480. //[LoadBmp]
  2481. function LoadBmp( Instance: Integer; Rsrc: PKOLChar; MasterObj: PObj ): HBitmap;
  2482. //[BITMAPS]
  2483. type
  2484. tagBitmap = Windows.TBitmap;
  2485. TPixelFormat = ( pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit,
  2486. pf32bit, pfCustom );
  2487. {* Available pixel formats. }
  2488. TBitmapHandleType = ( bmDIB, bmDDB );
  2489. {* Available bitmap handle types. }
  2490. {++}(*TBitmap = class;*){--}
  2491. PBitmap = {-}^{+}TBitmap;
  2492. { ----------------------------------------------------------------------
  2493. TBitmap - bitmap image
  2494. ----------------------------------------------------------------------- }
  2495. //[TBitmap DEFINITION]
  2496. TBitmap = object( TObj )
  2497. {* Bitmap incapsulation object. }
  2498. protected
  2499. fHeight: Integer;
  2500. fWidth: Integer;
  2501. fHandle: HBitmap;
  2502. fCanvas: PCanvas;
  2503. fScanLineSize: Integer;
  2504. fBkColor: TColor;
  2505. fApplyBkColor2Canvas: procedure( Sender: PBitmap );
  2506. fDetachCanvas: procedure( Sender: PBitmap );
  2507. fCanvasAttached : Integer;
  2508. fHandleType: TBitmapHandleType;
  2509. fDIBHeader: PBitmapInfo;
  2510. fDIBBits: Pointer;
  2511. fDIBSize: Integer;
  2512. fNewPixelFormat: TPixelFormat;
  2513. fFillWithBkColor: procedure( BmpObj: PBitmap; DC: HDC; oldW, oldH: Integer );
  2514. fTransMaskBmp: PBitmap;
  2515. fTransColor: TColor;
  2516. fGetDIBPixels: function( Bmp: PBitmap; X, Y: Integer ): TColor;
  2517. fSetDIBPixels: procedure( Bmp: PBitmap; X, Y: Integer; Value: TColor );
  2518. fScanLine0: PByte;
  2519. fScanLineDelta: Integer;
  2520. fPixelMask: DWORD;
  2521. fPixelsPerByteMask: Integer;
  2522. fBytesPerPixel: Integer;
  2523. fDIBAutoFree: Boolean;
  2524. procedure SetHeight(const Value: Integer);
  2525. procedure SetWidth(const Value: Integer);
  2526. function GetEmpty: Boolean;
  2527. function GetHandle: HBitmap;
  2528. function GetHandleAllocated: Boolean;
  2529. procedure SetHandle(const Value: HBitmap);
  2530. procedure SetPixelFormat(Value: TPixelFormat);
  2531. procedure FormatChanged;
  2532. function GetCanvas: PCanvas;
  2533. procedure CanvasChanged( Sender: PObj );
  2534. function GetScanLine(Y: Integer): Pointer;
  2535. function GetScanLineSize: Integer;
  2536. procedure ClearData;
  2537. procedure ClearTransImage;
  2538. procedure SetBkColor(const Value: TColor);
  2539. function GetDIBPalEntries(Idx: Integer): TColor;
  2540. function GetDIBPalEntryCount: Integer;
  2541. procedure SetDIBPalEntries(Idx: Integer; const Value: TColor);
  2542. procedure SetHandleType(const Value: TBitmapHandleType);
  2543. function GetPixelFormat: TPixelFormat;
  2544. function GetPixels(X, Y: Integer): TColor;
  2545. procedure SetPixels(X, Y: Integer; const Value: TColor);
  2546. function GetDIBPixels(X, Y: Integer): TColor;
  2547. procedure SetDIBPixels(X, Y: Integer; const Value: TColor);
  2548. function GetBoundsRect: TRect;
  2549. protected
  2550. {++}(*public*){--}
  2551. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  2552. public
  2553. property Width: Integer read fWidth write SetWidth;
  2554. {* Width of bitmap. To make code smaller, avoid changing Width or Height
  2555. after bitmap is created (using NewBitmap) or after it is loaded from
  2556. file, stream of resource. }
  2557. property Height: Integer read fHeight write SetHeight;
  2558. {* Height of bitmap. To make code smaller, avoid changing Width or Height
  2559. after bitmap is created (using NewBitmap) or after it is loaded from
  2560. file, stream of resource. }
  2561. property BoundsRect: TRect read GetBoundsRect;
  2562. {* Returns rectangle (0,0,Width,Height). }
  2563. property Empty: Boolean read GetEmpty;
  2564. {* Returns True if Width or Height is 0. }
  2565. procedure Clear;
  2566. {* Makes bitmap empty, setting its Width and Height to 0. }
  2567. procedure LoadFromFile( const Filename: KOLString );
  2568. {* Loads bitmap from file (LoadFromStream used). }
  2569. function LoadFromFileEx( const Filename: KOLString ): Boolean;
  2570. {* Loads bitmap from a file. If necessary, bitmap is RLE-decoded. Code given
  2571. by Vyacheslav A. Gavrik. }
  2572. procedure SaveToFile( const Filename: KOLString );
  2573. {* Stores bitmap to file (SaveToStream used). }
  2574. procedure LoadFromStream( Strm: PStream );
  2575. {* Loads bitmap from stream. Follow loading, bitmap has DIB format (without
  2576. handle allocated). It is possible to draw DIB bitmap without creating
  2577. handle for it, which can economy GDI resources. }
  2578. function LoadFromStreamEx( Strm: PStream ): Boolean;
  2579. {* Loads bitmap from a stream. Difference is that RLE decoding supported.
  2580. Code given by Vyacheslav A. Gavrik. }
  2581. procedure SaveToStream( Strm: PStream );
  2582. {* Saves bitmap to stream. If bitmap is not DIB, it is converted to DIB
  2583. before saving. }
  2584. procedure LoadFromResourceID( Inst: DWORD; ResID: Integer );
  2585. {* Loads bitmap from resource using integer ID of resource. To load by name,
  2586. use LoadFromResurceName. To load resource of application itself, pass
  2587. hInstance as first parameter. This method also can be used to load system
  2588. predefined bitmaps, if 0 is passed as Inst parameter:
  2589. |<pre>
  2590. OBM_BTNCORNERS OBM_REDUCE
  2591. OBM_BTSIZE OBM_REDUCED
  2592. OBM_CHECK OBM_RESTORE
  2593. OBM_CHECKBOXES OBM_RESTORED
  2594. OBM_CLOSE OBM_RGARROW
  2595. OBM_COMBO OBM_RGARROWD
  2596. OBM_DNARROW OBM_RGARROWI
  2597. OBM_DNARROWD OBM_SIZE
  2598. OBM_DNARROWI OBM_UPARROW
  2599. OBM_LFARROW OBM_UPARROWD
  2600. OBM_LFARROWD OBM_UPARROWI
  2601. OBM_LFARROWI OBM_ZOOM
  2602. OBM_MNARROW OBM_ZOOMD
  2603. |</pre> }
  2604. procedure LoadFromResourceName( Inst: DWORD; ResName: PKOLChar );
  2605. {* Loads bitmap from resurce (using passed name of bitmap resource. }
  2606. function Assign( SrcBmp: PBitmap ): Boolean;
  2607. {* Assigns bitmap from another. Returns False if not success.
  2608. Note: remember, that Canvas is not assigned - only bitmap image
  2609. is copied. And for DIB, handle is not allocating due this process. }
  2610. property Handle: HBitmap read GetHandle write SetHandle;
  2611. {* Handle of bitmap. Created whenever property accessed. To check if handle
  2612. is allocated (without allocating it), use HandleAllocated property. }
  2613. property HandleAllocated: Boolean read GetHandleAllocated;
  2614. {* Returns True, if Handle already allocated. }
  2615. function ReleaseHandle: HBitmap;
  2616. {* Returns Handle and releases it, so bitmap no more know about handle.
  2617. This method does not destroy bitmap image, but converts it into DIB.
  2618. Returned Handle actually is a handle of copy of original bitmap. If
  2619. You need not in keping it up, use Dormant method instead. }
  2620. procedure Dormant;
  2621. {* Releases handle from bitmap and destroys it. But image is not destroyed
  2622. and its data are preserved in DIB format. Please note, that in KOL, DIB
  2623. bitmaps can be drawn onto given device context without allocating of
  2624. handle. So, it is very useful to call Dormant preparing it using
  2625. Canvas drawing operations - to economy GDI resources. }
  2626. property HandleType: TBitmapHandleType read fHandleType write SetHandleType;
  2627. {* bmDIB, if DIB part of image data is filled and stored internally in
  2628. TBitmap object. DIB image therefore can have Handle allocated, which
  2629. require resources. Use HandleAllocated funtion to determine if handle
  2630. is allocated and Dormant method to remove it, if You want to economy
  2631. GDI resources. (Actually Handle needed for DIB bitmap only in case
  2632. when Canvas is used to draw on bitmap surface). Please note also, that
  2633. before saving bitmap to file or stream, it is converted to DIB. }
  2634. property PixelFormat: TPixelFormat read GetPixelFormat write SetPixelFormat;
  2635. {* Current pixel format. If format of bitmap is unknown, or bitmap is DDB,
  2636. value is pfDevice. Setting PixelFormat to any other format converts
  2637. bitmap to DIB, back to pfDevice converts bitmap to DDB again. Avoid
  2638. such conversations for large bitmaps or for numerous bitmaps in your
  2639. application to keep good performance. }
  2640. function BitsPerPixel: Integer;
  2641. {* Returns bits per pixel if possible. }
  2642. procedure Draw( DC: HDC; X, Y: Integer );
  2643. {* Draws bitmap to given device context. If bitmap is DIB, it is always
  2644. drawing using SetDIBitsToDevice API call, which does not require bitmap
  2645. handle (so, it is very sensible to call Dormant method to free correspondent
  2646. GDI resources). }
  2647. procedure StretchDraw( DC: HDC; const Rect: TRect );
  2648. {* Draws bitmap onto DC, stretching it to fit given rectangle Rect. }
  2649. procedure DrawTransparent( DC: HDC; X, Y: Integer; TranspColor: TColor );
  2650. {* Draws bitmap onto DC transparently, using TranspColor as transparent.
  2651. See function DesktopPixelFormat also. }
  2652. procedure StretchDrawTransparent( DC: HDC; const Rect: TRect; TranspColor: TColor );
  2653. {* Draws bitmap onto given rectangle of destination DC (with stretching it
  2654. to fit Rect) - transparently, using TranspColor as transparent.
  2655. See function DesktopPixelFormat also. }
  2656. procedure DrawMasked( DC: HDC; X, Y: Integer; Mask: HBitmap );
  2657. {* Draws bitmap to destination DC transparently by mask. It is possible
  2658. to pass as a mask handle of another TBitmap, previously converted to
  2659. monochrome mask using Convert2Mask method. }
  2660. procedure StretchDrawMasked( DC: HDC; const Rect: TRect; Mask: HBitmap );
  2661. {* Like DrawMasked, but with stretching image onto given rectangle. }
  2662. procedure Convert2Mask( TranspColor: TColor );
  2663. {* Converts bitmap to monochrome (mask) bitmap with TranspColor replaced
  2664. to clBlack and all other ones to clWhite. Such mask bitmap can be used
  2665. to draw original bitmap transparently, with given TranspColor as
  2666. transparent. (To preserve original bitmap, create new instance of
  2667. TBitmap and assign original bitmap to it). See also DrawTransparent and
  2668. StretchDrawTransparent methods. }
  2669. procedure Invert;
  2670. {* Obvious. }
  2671. property Canvas: PCanvas read GetCanvas;
  2672. {* Canvas can be used to draw onto bitmap. Whenever it is accessed, handle
  2673. is allocated for bitmap, if it is not yet (to make it possible
  2674. to select bitmap to display compatible device context). }
  2675. procedure RemoveCanvas;
  2676. {* Call this method to destroy Canvas and free GDI resources. }
  2677. property BkColor: TColor read fBkColor write SetBkColor;
  2678. {* Used to fill background for Bitmap, when its width or height is increased.
  2679. Although this value always synchronized with Canvas.Brush.Color, use it
  2680. instead if You do not use Canvas for drawing on bitmap surface. }
  2681. property Pixels[ X, Y: Integer ]: TColor read GetPixels write SetPixels;
  2682. {* Allows to obtain or change certain pixels of a bitmap. This method is
  2683. both for DIB and DDB bitmaps, and leads to allocate handle anyway. For
  2684. DIB bitmaps, it is possible to use property DIBPixels[ ] instead,
  2685. which is much faster and does not require in Handle. }
  2686. property ScanLineSize: Integer read GetScanLineSize;
  2687. {* Returns size of scan line in bytes. Use it to measure size of a single
  2688. ScanLine. To calculate increment value from first byte of ScanLine to
  2689. first byte of next ScanLine, use difference
  2690. ! Integer(ScanLine[1]-ScanLine[0])
  2691. (this is because bitmap can be oriented from bottom to top, so
  2692. step can be negative). }
  2693. property ScanLine[ Y: Integer ]: Pointer read GetScanLine;
  2694. {* Use ScanLine to access DIB bitmap pixels in memory to direct access it
  2695. fast. Take in attention, that for different pixel formats, different
  2696. bit counts are used to represent bitmap pixels. Also do not forget, that
  2697. for formats pf4bit and pf8bit, pixels actually are indices to palette
  2698. entries, and for formats pf16bit, pf24bit and pf32bit are actually
  2699. RGB values (for pf16bit B:5-G:6-R:5, for pf15bit B:5-G:5-R:5 (high order
  2700. bit not used), for pf24bit B:8-G:8-R:8, and for pf32bit high order byte
  2701. of TRGBQuad structure is not used). }
  2702. property DIBPixels[ X, Y: Integer ]: TColor read GetDIBPixels write SetDIBPixels;
  2703. {* Allows direct access to pixels of DIB bitmap, faster then Pixels[ ]
  2704. property. Access to read is slower for pf15bit, pf16bit formats (because
  2705. some conversation needed to translate packed RGB color to TColor). And
  2706. for write, operation performed most slower for pf4bit, pf8bit (searching
  2707. nearest color required) and fastest for pf24bit, pf32bit and pf1bit. }
  2708. property DIBPalEntryCount: Integer read GetDIBPalEntryCount;
  2709. {* Returns palette entries count for DIB image. Always returns 2 for pf1bit,
  2710. 16 for pf4bit, 256 for pf8bit and 0 for other pixel formats. }
  2711. property DIBPalEntries[ Idx: Integer ]: TColor read GetDIBPalEntries write
  2712. SetDIBPalEntries;
  2713. {* Provides direct access to DIB palette. }
  2714. function DIBPalNearestEntry( Color: TColor ): Integer;
  2715. {* Returns index of entry in DIB palette with color nearest (or matching)
  2716. to given one. }
  2717. property DIBBits: Pointer read fDIBBits;
  2718. {* This property is mainly for internal use. }
  2719. property DIBSize: Integer read fDIBSize;
  2720. {* Size of DIBBits array. }
  2721. property DIBHeader: PBitmapInfo read fDIBHeader;
  2722. {* This property is mainly for internal use. }
  2723. procedure DIBDrawRect( DC: HDC; X, Y: Integer; const R: TRect );
  2724. {* This procedure copies given rectangle to the target device context,
  2725. but only for DIB bitmap (using SetDIBBitsToDevice API call). }
  2726. procedure RotateRight;
  2727. {* Rotates bitmap right (90 degree). Bitmap must be DIB. If You definitevely
  2728. know format of a bitmap, use instead one of methods RotateRightMono,
  2729. RotateRight4bit, RotateRight8bit, RotateRight16bit or RotateRightTrueColor
  2730. - this will economy code. But if for most of formats such methods are
  2731. called, this can be more economy just to call always universal method
  2732. RotateRight. }
  2733. procedure RotateLeft;
  2734. {* Rotates bitmap left (90 degree). Bitmap must be DIB. If You definitevely
  2735. know format of a bitmap, use instead one of methods RotateLeftMono,
  2736. RotateLeft4bit, RotateLeft8bit, RotateLeft16bit or RotateLeftTrueColor
  2737. - this will economy code. But if for most of formats such methods are
  2738. called, this can be more economy just to call always universal method
  2739. RotateLeft. }
  2740. procedure RotateRightMono;
  2741. {* Rotates bitmat right, but only if bitmap is monochrome (pf1bit). }
  2742. procedure RotateLeftMono;
  2743. {* Rotates bitmap left, but only if bitmap is monochrome (pf1bit). }
  2744. procedure RotateRight4bit;
  2745. {* Rotates bitmap right, but only if PixelFormat is pf4bit. }
  2746. procedure RotateLeft4bit;
  2747. {* Rotates bitmap left, but only if PixelFormat is pf4bit. }
  2748. procedure RotateRight8bit;
  2749. {* Rotates bitmap right, but only if PixelFormat is pf8bit. }
  2750. procedure RotateLeft8bit;
  2751. {* Rotates bitmap left, but only if PixelFormat is pf8bit. }
  2752. procedure RotateRight16bit;
  2753. {* Rotates bitmap right, but only if PixelFormat is pf16bit. }
  2754. procedure RotateLeft16bit;
  2755. {* Rotates bitmap left, but only if PixelFormat is pf16bit. }
  2756. procedure RotateRightTrueColor;
  2757. {* Rotates bitmap right, but only if PixelFormat is pf24bit or pf32bit. }
  2758. procedure RotateLeftTrueColor;
  2759. {* Rotates bitmap left, but only if PixelFormat is pf24bit or pf32bit. }
  2760. procedure FlipVertical;
  2761. {* Flips bitmap vertically }
  2762. procedure FlipHorizontal;
  2763. {* Flips bitmap horizontally }
  2764. procedure CopyRect( const DstRect : TRect; SrcBmp : PBitmap; const SrcRect : TRect );
  2765. {* It is possible to use Canvas.CopyRect for such purpose, but if You
  2766. do not want use TCanvas, it is possible to copy rectangle from one
  2767. bitmap to another using this function. }
  2768. function CopyToClipboard: Boolean;
  2769. {* Copies bitmap to clipboard. }
  2770. function PasteFromClipboard: Boolean;
  2771. {* Takes CF_DIB format bitmap from clipboard and assigns it to the
  2772. TBitmap object. }
  2773. end;
  2774. //[END OF TBitmap DEFINITION]
  2775. //
  2776. function Bits2PixelFormat( BitsPerPixel: Integer ): TPixelFormat;
  2777. //[NewBitmap DECLARATION]
  2778. function NewBitmap( W, H: Integer ): PBitmap;
  2779. {* Creates bitmap object of given size. If it is possible, do not change its
  2780. size (Width and Heigth) later - this can economy code a bit. See TBitmap. }
  2781. function NewDIBBitmap( W, H: Integer; PixelFormat: TPixelFormat ): PBitmap;
  2782. {* Creates DIB bitmap object of given size and pixel format. If it is possible,
  2783. do not change its size (Width and Heigth) later - this can economy code a bit.
  2784. See TBitmap. }
  2785. //[CalcScanLineSize DECLARATION]
  2786. function CalcScanLineSize( Header: PBitmapInfoHeader ): Integer;
  2787. {* May be will be useful. }
  2788. //[DefaultPixelFormat VARIABLE]
  2789. var
  2790. //DefaultBitsPerPixel: Integer = 16;
  2791. DefaultPixelFormat: TPixelFormat = pf16bit;
  2792. //[Mapped bitmaps]
  2793. { -- Function to load bitmap mapping some its colors. -- }
  2794. function LoadMappedBitmap( hInst: THandle; BmpResID: Integer; const Map: array of TColor )
  2795. : HBitmap;
  2796. {* This function can be used to load bitmap and replace some it colors to
  2797. desired ones. This function especially useful when loaded by the such way
  2798. bitmap is used as toolbar bitmap - to replace some original colors to
  2799. system default colors. To use this function properly, the bitmap shoud
  2800. be prepared as 16-color bitmap, which uses only system colors. To do so,
  2801. create a new 16-color bitmap with needed dimensions in Borland Image Editor
  2802. and paste a bitmap image, copyed in another graphic tool, and then save it.
  2803. If this is not done, bitmap will not be loaded correctly! }
  2804. function LoadMappedBitmapEx( MasterObj: PObj; hInst: THandle; BmpResName: PKOLChar;
  2805. const Map: array of TColor ): HBitmap;
  2806. {* by Alex Pravdin: like LoadMappedBitmap, but much powerful. It uses
  2807. CreateMappedBitmapEx, so it understands any bitmap color format, including
  2808. pf24bit. Also, LoadMappedBitmapEx provides auto-destroying loaded resource
  2809. when MasterObj is destroyed. }
  2810. function CreateMappedBitmap(Instance: THandle; Bitmap: Integer;
  2811. Flags: UINT; ColorMap: PColorMap; NumMaps: Integer): HBitmap; {$ifdef wince}cdecl{$else}stdcall{$endif};
  2812. {* Creates mapped bitmap replacing colors correspondently to the
  2813. ColorMap (each pare of colors defines color replaced and a color
  2814. used for replace it in the bitmap). See also CreateMappedBitmapEx. }
  2815. function CreateMappedBitmapEx(Instance: THandle; BmpRsrcName: PKOLChar; Flags:
  2816. Cardinal; ColorMap: PColorMap; NumMaps: Integer): HBitmap;
  2817. {* By Alex Pravdin.
  2818. Creates mapped bitmap independently from bitmap color format (works
  2819. correctly with bitmaps having format deeper than 8bit per pixel). }
  2820. //[ICONS]
  2821. type
  2822. {++}(*TIcon = class;*){--}
  2823. PIcon = {-}^{+}TIcon;
  2824. { ----------------------------------------------------------------------
  2825. TIcon - icon image
  2826. ----------------------------------------------------------------------- }
  2827. //[TIcon DEFINITION]
  2828. TIcon = object( TObj )
  2829. {* Object type to incapsulate icon or cursor image. }
  2830. protected
  2831. {$IFDEF ICON_DIFF_WH}
  2832. FWidth: Integer;
  2833. FHeight: Integer;
  2834. {$ELSE}
  2835. FSize : Integer;
  2836. {$ENDIF}
  2837. FHandle: HIcon;
  2838. FShareIcon: Boolean;
  2839. procedure SetSize(const Value: Integer);
  2840. {$IFDEF ICON_DIFF_WH}
  2841. function GetIconSize: Integer;
  2842. {$ENDIF}
  2843. procedure SetHandle(const Value: HIcon);
  2844. function GetHotSpot: TPoint;
  2845. function GetEmpty: Boolean;
  2846. protected
  2847. {++}(*public*){--}
  2848. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  2849. public
  2850. {$IFDEF ICONLOAD_PRESERVEBMPS}
  2851. ImgBmp, MskBmp : PBitmap;
  2852. Only_Bmp: Boolean;
  2853. {$ENDIF ICONLOAD_PRESERVEBMPS}
  2854. property Size : Integer read
  2855. {$IFDEF ICON_DIFF_WH}
  2856. GetIconSize
  2857. {$ELSE}
  2858. FSize
  2859. {$ENDIF}
  2860. write SetSize;
  2861. {* Icon dimension (width and/or height, which are equal to each other always). }
  2862. {$IFDEF ICON_DIFF_WH}
  2863. property Width: Integer read FWidth;
  2864. property Height: Integer read FHeight;
  2865. {$ENDIF}
  2866. property Handle : HIcon read FHandle write SetHandle;
  2867. {* Windows icon object handle. }
  2868. procedure Clear;
  2869. {* Clears icon, freeing image and allocated GDI resource (Handle). }
  2870. property Empty: Boolean read GetEmpty;
  2871. {* Returns True if icon is Empty. }
  2872. property ShareIcon : Boolean read FShareIcon write FShareIcon;
  2873. {* True, if icon object is shared and can not be deleted when TIcon object
  2874. is destroyed (set this flag is to True, if an icon is obtained from another
  2875. TIcon object, for example). }
  2876. property HotSpot : TPoint read GetHotSpot;
  2877. {* Hot spot point - for cursors. }
  2878. procedure Draw( DC : HDC; X, Y : Integer );
  2879. {* Draws icon onto given device context. Icon always is drawn transparently
  2880. using its transparency mask (stored internally in icon object). }
  2881. procedure StretchDraw( DC : HDC; Dest : TRect );
  2882. {* Draws icon onto given device context with stretching it to fit destination
  2883. rectangle. See also Draw. }
  2884. procedure LoadFromStream( Strm : PStream );
  2885. {* Loads icon from stream. If stream contains several icons (of
  2886. different dimentions), icon with the most appropriate size is loading. }
  2887. procedure LoadFromFile( const FileName : KOLString );
  2888. {* Load icon from file. If file contains several icons (of
  2889. different dimensions), icon with the most appropriate size is loading. }
  2890. procedure LoadFromResourceID( Inst: Integer; ResID: Integer; DesiredSize: Integer );
  2891. {* Loads icon from resource. To load system default icon, pass 0 as Inst and
  2892. one of followin values as ResID:
  2893. |<pre>
  2894. IDI_APPLICATION Default application icon.
  2895. IDI_ASTERISK Asterisk (used in informative messages).
  2896. IDI_EXCLAMATION Exclamation point (used in warning messages).
  2897. IDI_HAND Hand-shaped icon (used in serious warning messages).
  2898. IDI_QUESTION Question mark (used in prompting messages).
  2899. IDI_WINLOGO Windows logo.
  2900. |</pre> It is also possible to load icon from resources of another module,
  2901. if pass instance handle of loaded module as Inst parameter. }
  2902. procedure LoadFromResourceName( Inst: Integer; ResName: PKOLChar; DesiredSize: Integer );
  2903. {* Loads icon from resource. To load own application resource, pass
  2904. hInstance as Inst parameter. It is possible to load resource from
  2905. another module, if pass its instance handle as Inst. }
  2906. procedure LoadFromExecutable( const FileName: KOLString; IconIdx: Integer );
  2907. {* Loads icon from executable (exe or dll file). Always default sized icon
  2908. is loaded. It is possible also to get know how much icons are contained
  2909. in executable using gloabl function GetFileIconCount. To obtain icon of
  2910. another size, try to load given executable and use LoadFromResourceID
  2911. method. }
  2912. {$ifdef win32}
  2913. procedure SaveToStream( Strm : PStream );
  2914. {* Saves single icon to stream. To save icons with several different
  2915. dimensions, use global procedure SaveIcons2Stream. }
  2916. procedure SaveToFile( const FileName : KOLString );
  2917. {* Saves single icon to file. To save icons with several different
  2918. dimensions, use global procedure SaveIcons2File. }
  2919. {$endif win32}
  2920. function Convert2Bitmap( TranColor: TColor ): HBitmap;
  2921. {* Converts icon to bitmap, returning Windows GDI bitmap resource as
  2922. a result. It is possible later to assign returned bitmap handle to
  2923. Handle property of TBitmap object to use features of TBitmap.
  2924. Pass TranColor to replace transparent area of icon with given color. }
  2925. end;
  2926. //[END OF TIcon DEFINITION]
  2927. //[Icon save functions]
  2928. {$ifdef win32}
  2929. procedure SaveIcons2Stream( const Icons : array of PIcon; Strm : PStream );
  2930. {* Saves several icons (of different dimentions) to stream. }
  2931. function SaveIcons2StreamEx( const BmpHandles: array of HBitmap; Strm: PStream ): Boolean;
  2932. {* Saves icons creating it from pairs of bitmaps and their masks.
  2933. BmpHandles array must contain pairs of bitmap handles, each pair
  2934. of color bitmap and mask bitmap of the same size. }
  2935. procedure SaveIcons2File( const Icons : array of PIcon; const FileName : KOLString );
  2936. {* Saves several icons (of different dimentions) to file. (Single file
  2937. with extension .ico can contain several different sized icon images
  2938. to use later one with the most appropriate size). }
  2939. {$endif win32}
  2940. //[NewIcon DECLARATION]
  2941. function NewIcon: PIcon;
  2942. {* Creates new icon object, setting its Size to 32 by default. Created icon
  2943. is Empty. }
  2944. //[GetFileIconCount DECLARATION]
  2945. function GetFileIconCount( const FileName: KOLString ): Integer;
  2946. {* Returns number of icon resources stored in given (executable) file. }
  2947. //[ICON STRUCTURES]
  2948. type
  2949. TIconHeader = packed record
  2950. idReserved: Word; (* Always set to 0 *)
  2951. idType: Word; (* Always set to 1 *)
  2952. idCount: Word; (* Number of icon images *)
  2953. (* immediately followed by idCount TIconDirEntries *)
  2954. end;
  2955. TIconDirEntry = packed record
  2956. bWidth: Byte; (* Width *)
  2957. bHeight: Byte; (* Height *)
  2958. bColorCount: Byte; (* Nr. of colors used *)
  2959. bReserved: Byte; (* not used, 0 *)
  2960. wPlanes: Word; (* not used, 0 *)
  2961. wBitCount: Word; (* not used, 0 *)
  2962. dwBytesInRes: Longint; (* total number of bytes in images *)
  2963. dwImageOffset: Longint;(* location of image from the beginning of file *)
  2964. end;
  2965. //[LoadImgIcon DECLARATION]
  2966. function LoadImgIcon( RsrcName: PKOLChar; Size: Integer ): HIcon;
  2967. {* Loads icon of specified size from the resource. }
  2968. ////////////////////////////////////////////////////////////////////////////////
  2969. // UNIVERSAL CONTROL OBJECT //
  2970. ////////////////////////////////////////////////////////////////////////////////
  2971. //[CM_XXX CONSTANTS]
  2972. const
  2973. CM_EXECPROC = $8FFF;
  2974. CM_BASE = $B000;
  2975. CM_ACTIVATE = CM_BASE + 0;
  2976. CM_DEACTIVATE = CM_BASE + 1;
  2977. CM_ENTER = CM_BASE + 2;
  2978. CM_RELEASE = CM_BASE + 3;
  2979. CM_QUIT = CM_BASE + 4;
  2980. CM_COMMAND = CM_BASE + 5;
  2981. CM_MEASUREITEM = CM_BASE + 6;
  2982. CM_DRAWITEM = CM_BASE + 7;
  2983. CM_TRAYICON = CM_BASE + 8;
  2984. CM_INVALIDATE = CM_BASE + 9;
  2985. CM_UPDATE = CM_BASE + 10;
  2986. CM_NCUPDATE = CM_BASE + 11;
  2987. CM_SIZEPOS = CM_BASE + 12;
  2988. CM_SIZE = CM_BASE + 13;
  2989. CM_SETFOCUS = CM_BASE + 14;
  2990. CM_CBN_SELCHANGE = 15;
  2991. CM_UIACTIVATE = CM_BASE + 16;
  2992. CM_UIDEACTIVATE = CM_BASE + 17;
  2993. CM_PROCESS = CM_BASE + 18;
  2994. CM_SHOW = CM_BASE + 19;
  2995. CM_AUTOSIZE = CM_BASE + 20;
  2996. CM_MDIClientShowEdge = CM_BASE + 21;
  2997. CM_INVALIDATECHILD = CM_BASE + 22;
  2998. CM_FOCUSGRAPHCTL = CM_BASE + 23;
  2999. WM_SYNCPAINT = $88;
  3000. //[CN_XXX CONSTANTS]
  3001. CN_BASE = $BC00;
  3002. CN_CHARTOITEM = CN_BASE + WM_CHARTOITEM;
  3003. CN_COMMAND = CN_BASE + WM_COMMAND;
  3004. CN_COMPAREITEM = CN_BASE + WM_COMPAREITEM;
  3005. CN_CTLCOLORMSGBOX = CN_BASE + WM_CTLCOLORMSGBOX;
  3006. CN_CTLCOLOREDIT = CN_BASE + WM_CTLCOLOREDIT;
  3007. CN_CTLCOLORLISTBOX = CN_BASE + WM_CTLCOLORLISTBOX;
  3008. CN_CTLCOLORBTN = CN_BASE + WM_CTLCOLORBTN;
  3009. CN_CTLCOLORDLG = CN_BASE + WM_CTLCOLORDLG;
  3010. CN_CTLCOLORSCROLLBAR = CN_BASE + WM_CTLCOLORSCROLLBAR;
  3011. CN_CTLCOLORSTATIC = CN_BASE + WM_CTLCOLORSTATIC;
  3012. CN_DELETEITEM = CN_BASE + WM_DELETEITEM;
  3013. CN_DRAWITEM = CN_BASE + WM_DRAWITEM;
  3014. CN_HSCROLL = CN_BASE + WM_HSCROLL;
  3015. CN_MEASUREITEM = CN_BASE + WM_MEASUREITEM;
  3016. CN_PARENTNOTIFY = CN_BASE + WM_PARENTNOTIFY;
  3017. CN_VKEYTOITEM = CN_BASE + WM_VKEYTOITEM;
  3018. CN_VSCROLL = CN_BASE + WM_VSCROLL;
  3019. CN_KEYDOWN = CN_BASE + WM_KEYDOWN;
  3020. CN_KEYUP = CN_BASE + WM_KEYUP;
  3021. CN_CHAR = CN_BASE + WM_CHAR;
  3022. CN_SYSKEYDOWN = CN_BASE + WM_SYSKEYDOWN;
  3023. CN_SYSCHAR = CN_BASE + WM_SYSCHAR;
  3024. CN_NOTIFY = CN_BASE + WM_NOTIFY;
  3025. {$ENDIF WIN_GDI}
  3026. //[ID_SELF DEFINED]
  3027. const
  3028. ID_SELF: array[ 0..5 ] of KOLChar = ( 'S','E','L','F','_',#0 );
  3029. {* Identifier for window property "Self", stored directly in window, when
  3030. it is created. This property is used to [fast] find TControl object,
  3031. correspondent to given window handle (using API call GetProp). }
  3032. {$IFDEF WIN_GDI}
  3033. //[ID_PREVPROC DEFINED]
  3034. ID_PREVPROC: array[ 0..9 ] of KOLChar = ( 'P','R','E','V','_','P','R','O','C',#0 );
  3035. {* }
  3036. {$ENDIF WIN_GDI}
  3037. //[MK_ALT DEFINED]
  3038. const
  3039. MK_LBUTTON = 1;
  3040. MK_RBUTTON = 2;
  3041. MK_SHIFT = 4;
  3042. MK_CONTROL = 8;
  3043. MK_MBUTTON = $10;
  3044. MK_ALT = $20;
  3045. MK_LOCK = $40; // CAPS LOCK or SHIFT LOCK
  3046. {$IFDEF WIN_GDI}
  3047. {$IFNDEF NOT_USE_RICHEDIT}
  3048. //[RICHEDIT STRUCTURES]
  3049. type
  3050. TCharFormat2 = {$ifndef wince}packed{$endif} record
  3051. cbSize: UINT;
  3052. dwMask: DWORD;
  3053. dwEffects: DWORD;
  3054. yHeight: Longint;
  3055. yOffset: Longint;
  3056. crTextColor: TColorRef;
  3057. bCharSet: Byte;
  3058. bPitchAndFamily: Byte;
  3059. szFaceName: array[0..LF_FACESIZE - 1] of KOLChar;
  3060. R2Bytes: Word;
  3061. wWeight: Word; { Font weight (LOGFONT value) }
  3062. sSpacing: Smallint; { Amount to space between letters }
  3063. crBackColor: TColorRef; { Background color }
  3064. lid: LCID; { Locale ID }
  3065. dwReserved: DWORD; { Reserved. Must be 0 }
  3066. sStyle: Smallint; { Style handle }
  3067. wKerning: Word; { Twip size above which to kern char pair }
  3068. bUnderlineType: Byte; { Underline type }
  3069. bAnimation: Byte; { Animated text like marching ants }
  3070. bRevAuthor: Byte; { Revision author index }
  3071. bReserved1: Byte;
  3072. end;
  3073. //TCharFormat2 = TCharFormat2A;
  3074. TParaFormat2 = {$ifndef wince}packed{$endif} record
  3075. cbSize: UINT;
  3076. dwMask: DWORD;
  3077. wNumbering: Word;
  3078. wReserved: Word;
  3079. dxStartIndent: Longint;
  3080. dxRightIndent: Longint;
  3081. dxOffset: Longint;
  3082. wAlignment: Word;
  3083. cTabCount: Smallint;
  3084. rgxTabs: array [0..MAX_TAB_STOPS - 1] of Longint;
  3085. dySpaceBefore: Longint; { Vertical spacing before para }
  3086. dySpaceAfter: Longint; { Vertical spacing after para }
  3087. dyLineSpacing: Longint; { Line spacing depending on Rule }
  3088. sStyle: Smallint; { Style handle }
  3089. bLineSpacingRule: Byte; { Rule for line spacing (see tom.doc) }
  3090. bCRC: Byte; { Reserved for CRC for rapid searching }
  3091. wShadingWeight: Word; { Shading in hundredths of a per cent }
  3092. wShadingStyle: Word; { Nibble 0: style, 1: cfpat, 2: cbpat }
  3093. wNumberingStart: Word; { Starting value for numbering }
  3094. wNumberingStyle: Word; { Alignment, roman/arabic, (), ), ., etc. }
  3095. wNumberingTab: Word; { Space bet 1st indent and 1st-line text }
  3096. wBorderSpace: Word; { Space between border and text (twips) }
  3097. wBorderWidth: Word; { Border pen width (twips) }
  3098. wBorders: Word; { Byte 0: bits specify which borders }
  3099. { Nibble 2: border style, 3: color index }
  3100. end;
  3101. TGetTextLengthEx = {$ifndef wince}packed{$endif} record
  3102. flags: DWORD; { flags (see GTL_XXX defines) }
  3103. codepage: UINT; { code page for translation (CP_ACP for default,
  3104. 1200 for Unicode }
  3105. end;
  3106. const
  3107. PFM_SPACEBEFORE = $00000040;
  3108. PFM_SPACEAFTER = $00000080;
  3109. PFM_LINESPACING = $00000100;
  3110. PFM_STYLE = $00000400;
  3111. PFM_BORDER = $00000800; { (*) }
  3112. PFM_SHADING = $00001000; { (*) }
  3113. PFM_NUMBERINGSTYLE = $00002000; { (*) }
  3114. PFM_NUMBERINGTAB = $00004000; { (*) }
  3115. PFM_NUMBERINGSTART = $00008000; { (*) }
  3116. PFM_RTLPARA = $00010000;
  3117. PFM_KEEP = $00020000; { (*) }
  3118. PFM_KEEPNEXT = $00040000; { (*) }
  3119. PFM_PAGEBREAKBEFORE = $00080000; { (*) }
  3120. PFM_NOLINENUMBER = $00100000; { (*) }
  3121. PFM_NOWIDOWCONTROL = $00200000; { (*) }
  3122. PFM_DONOTHYPHEN = $00400000; { (*) }
  3123. PFM_SIDEBYSIDE = $00800000; { (*) }
  3124. PFM_TABLE = $c0000000; { (*) }
  3125. EM_REDO = WM_USER + 84;
  3126. EM_AUTOURLDETECT = WM_USER + 91;
  3127. EM_GETAUTOURLDETECT = WM_USER + 92;
  3128. CFM_UNDERLINETYPE = $00800000; { (*) }
  3129. CFM_HIDDEN = $0100; { (*) }
  3130. CFM_BACKCOLOR = $04000000;
  3131. CFE_AUTOBACKCOLOR = CFM_BACKCOLOR;
  3132. GTL_USECRLF = 1; { compute answer using CRLFs for paragraphs }
  3133. GTL_PRECISE = 2; { compute a precise answer }
  3134. GTL_CLOSE = 4; { fast computation of a "close" answer }
  3135. GTL_NUMCHARS = 8; { return the number of characters }
  3136. GTL_NUMBYTES = 16; { return the number of _bytes_ }
  3137. EM_GETTEXTLENGTHEX = WM_USER + 95;
  3138. EM_SETLANGOPTIONS = WM_USER + 120;
  3139. EM_GETLANGOPTIONS = WM_USER + 121;
  3140. EM_SETEDITSTYLE = $400 + 204;
  3141. EM_GETEDITSTYLE = $400 + 205;
  3142. SES_EMULATESYSEDIT = 1;
  3143. SES_BEEPONMAXTEXT = 2;
  3144. SES_EXTENDBACKCOLOR = 4;
  3145. SES_MAPCPS = 8;
  3146. SES_EMULATE10 = 16;
  3147. SES_USECRLF = 32;
  3148. SES_USEAIMM = 64;
  3149. SES_NOIME = 128;
  3150. SES_ALLOWBEEPS = 256;
  3151. SES_UPPERCASE = 512;
  3152. SES_LOWERCASE = 1024;
  3153. SES_NOINPUTSEQUENCECHK = 2048;
  3154. SES_BIDI = 4096;
  3155. SES_SCROLLONKILLFOCUS = 8192;
  3156. SES_XLTCRCRLFTOCR = 16384;
  3157. EM_GETSCROLLPOS = WM_USER + 221;
  3158. EM_SETSCROLLPOS = WM_USER + 222;
  3159. EM_GETZOOM = WM_USER + 224;
  3160. EM_SETZOOM = WM_USER + 225;
  3161. {$ENDIF NOT_USE_RICHEDIT}
  3162. {$ENDIF WIN_GDI}
  3163. //[CONTROLS]
  3164. type
  3165. {++}(*TControl = class;*){--}
  3166. PControl = {-}^{+}TControl;
  3167. {* Type of pointer to TControl visual object. All
  3168. |<a href="kol_pas.htm#visual_objects_constructors">
  3169. constructing functions
  3170. |</a>
  3171. New[ControlName] are returning
  3172. pointer of this type. Do not forget about some difference
  3173. of using objects from using classes. Identifier Self for
  3174. methods of object is not of pointer type, and to pass
  3175. pointer to Self, it is necessary to pass @Self instead.
  3176. At the same time, to use pointer to object in 'WITH' operator,
  3177. it is necessary to apply suffix '^' to pointer to get know
  3178. to compiler, what do You want. }
  3179. {$IFDEF WIN}
  3180. //[TWindowFunc TYPE]
  3181. TWindowFunc = function( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  3182. : Boolean;
  3183. {$ENDIF WIN}
  3184. {* Event type to define custom extended message handlers (as pointers to
  3185. procedure entry points). Such handlers are usually defined like add-ons,
  3186. extending behaviour of certain controls and attached using AttachProc
  3187. method of TControl. If the handler detects, that it is necessary to stop
  3188. further message processing, it should return True. }
  3189. //[Mouse TYPES]
  3190. TMouseButton = ( mbNone, mbLeft, mbRight, mbMiddle );
  3191. {* Available mouse buttons. mbNone is useful to get know, that
  3192. there were no mouse buttons pressed. }
  3193. TMouseEventData = {$ifndef wince}packed{$endif} Record
  3194. {* Record to pass it to mouse handling routines, assigned to OnMouseXXXX
  3195. events. }
  3196. Button: TMouseButton;
  3197. StopHandling: Boolean; // Set it to True in OnMouseXXXX event handler to
  3198. // stop further processing
  3199. R1, R2: Byte; // Not used
  3200. Shift : DWORD; // HiWord( Shift ) = zDelta in WM_MOUSEWHEEL
  3201. X, Y : SmallInt;
  3202. end;
  3203. TOnMouse = procedure( Sender: PControl; var Mouse: TMouseEventData ) of object;
  3204. {* Common mouse handling event type. }
  3205. //[Key TYPES]
  3206. TOnKey = procedure( Sender: PControl; var Key: Longint; Shift: DWORD ) of object;
  3207. {* Key events. Shift is a combination of flags MK_SHIFT, MK_CONTROL, MK_ALT.
  3208. (See GetShiftState funtion). }
  3209. TOnChar = procedure( Sender: PControl; var Key: KOLChar; Shift: DWORD ) of object;
  3210. {* Char event. Shift is a combination of flags MK_SHIFT, MK_CONTROL, MK_ALT. }
  3211. TTabKey = ( tkTab, tkLeftRight, tkUpDown, tkPageUpPageDn );
  3212. {* Available tabulating key groups. }
  3213. TTabKeys = Set of TTabKey;
  3214. {* Set of tabulating key groups, allowed to be used in with a control
  3215. (are installed by TControl.LookTabKey property). }
  3216. //[Event TYPES]
  3217. {$IFDEF WIN}
  3218. TOnMessage = function( var Msg: TMsg; var Rslt: Integer ): Boolean of object;
  3219. {* Event type for events, which allows to extend behaviour of windowed controls
  3220. descendants using add-ons. }
  3221. {$ENDIF WIN}
  3222. TOnEventAccept = procedure( Sender: PObj; var Accept: Boolean ) of object;
  3223. {* Event type for OnClose event. }
  3224. TCloseQueryReason = ( qClose, qShutdown, qLogoff );
  3225. {* Request reason type to call OnClose and OnQueryEndSession. }
  3226. TWindowState = ( wsNormal, wsMinimized, wsMaximized );
  3227. {* Avalable states of TControl's window object. }
  3228. TOnSplit = function( Sender: PControl; NewSize1, NewSize2: Integer ): Boolean of object;
  3229. {* Event type for OnSplit event handler, designed specially for splitter
  3230. control. Event handler must return True to accept new size of previous
  3231. (to splitter) control and new size of the rest of client area of parent. }
  3232. TOnTVBeginDrag = procedure( Sender: PControl; Item: THandle ) of object;
  3233. {* Event type for OnTVBeginDrag event (defined for tree view control). }
  3234. TOnTVBeginEdit = function( Sender: PControl; Item: THandle ): Boolean of object;
  3235. {* Event type for OnTVBeginEdit event (for tree view control). }
  3236. TOnTVEndEdit = function( Sender: PControl; Item: THandle; const NewTxt: KOL_String )
  3237. : Boolean of object;
  3238. {* Event type for TOnTVEndEdit event. }
  3239. TOnTVExpanding = function( Sender: PControl; Item: THandle; Expand: Boolean )
  3240. : Boolean of object;
  3241. {* Event type for TOnTVExpanding event. }
  3242. TOnTVExpanded = procedure( Sender: PControl; Item: THandle; Expand: Boolean )
  3243. of object;
  3244. {* Event type for OnTVExpanded event. }
  3245. TOnTVDelete = procedure( Sender: PControl; Item: THandle ) of object;
  3246. {* Event type for OnTVDelete event. }
  3247. //--------- by Sergey Shisminzev:
  3248. TOnTVSelChanging = function(Sender: PControl; oldItem, newItem: THandle): Boolean //~ss
  3249. of object;
  3250. {* When the handler returns False, selection is not changed. }
  3251. //-------------------------------
  3252. TOnDrag = function( Sender: PControl; ScrX, ScrY: Integer; var CursorShape: Integer;
  3253. var Stop: Boolean ): Boolean of object;
  3254. {* Event, called during dragging operation (it is initiated
  3255. with method Drag, where callback function of type TOnDrag is
  3256. passed as a parameter). Callback function receives Stop parameter True,
  3257. when operation is finishing. Otherwise, it can set it to True to force
  3258. finishing the operation (in such case, returning False means cancelling
  3259. drag operation, True - successful drag and in this last case callback is
  3260. no more called). During the operation, when input Stop value is False,
  3261. callback function can control Cursor shape, and return True, if the operation
  3262. can be finished successfully at the given ScrX, ScrY position.
  3263. ScrX, ScrY are screen coordinates of the mouse cursor. }
  3264. {$IFDEF WIN}
  3265. //[Create Window STRUCTURES]
  3266. TCreateParams = {$ifndef wince}packed{$endif} record
  3267. {* Record to pass it through CreateSubClass method. }
  3268. Caption: PKOLChar;
  3269. Style: cardinal;
  3270. ExStyle: cardinal;
  3271. X, Y: Integer;
  3272. Width, Height: Integer;
  3273. WndParent: HWnd;
  3274. Param: Pointer;
  3275. WindowClass: TWndClass;
  3276. WinClassName: array[0..63] of KOLChar;
  3277. end;
  3278. TCreateWndParams = {$ifndef wince}packed{$endif} Record
  3279. ExStyle: DWORD;
  3280. WinClassName: PKOLChar;
  3281. Caption: PKOLChar;
  3282. Style: DWORD;
  3283. X, Y, Width, Height: Integer;
  3284. WndParent: HWnd;
  3285. Menu: HMenu;
  3286. Inst: THandle;
  3287. Param: Pointer;
  3288. WinClsNamBuf: array[ 0..63 ] of KOLChar;
  3289. WindowClass: TWndClass;
  3290. end;
  3291. //[COMMAND ACTIONS TYPE FOR DIFFERENT CONTROLS]
  3292. PCommandActions = ^TCommandActions;
  3293. TCommandActions = {$ifndef wince}packed{$endif} Record
  3294. aClear: procedure( Sender: PControl );
  3295. aAddText: procedure( Sender: PControl; const S: String );
  3296. aClick, aEnter, aLeave: WORD; aChange: SmallInt; aSelChange: SmallInt;
  3297. aGetCount, aSetCount, aGetItemLength, aGetItemText, aSetItemText,
  3298. aGetItemData, aSetItemData: WORD;
  3299. aAddItem, aDeleteItem, aInsertItem: WORD;
  3300. aFindItem, aFindPartial: WORD;
  3301. aItem2Pos, aPos2Item: BYTE;
  3302. {aGetSelStart,} aGetSelCount, aGetSelected, aGetSelRange,
  3303. {aExGetSelRange,} aGetCurrent,
  3304. aSetSelected, aSetCurrent, aSetSelRange, aExSetSelRange,
  3305. aGetSelection, aReplaceSel: WORD;
  3306. aTextAlignLeft, aTextAlignRight, aTextAlignCenter: WORD;
  3307. aTextAlignMask: Byte;
  3308. aVertAlignCenter, aVertAlignTop, aVertAlignBottom: Byte;
  3309. aDir, aSetLimit: Word; aSetImgList: Word;
  3310. aAutoSzX, aAutoSzY: Word;
  3311. aSetBkColor: Word;
  3312. aItem2XY: Word;
  3313. end;
  3314. {$ENDIF WIN}
  3315. //[Align TYPES]
  3316. TTextAlign = ( taLeft, taRight, taCenter );
  3317. {* Text alignments available. }
  3318. TRichTextAlign = ( raLeft, raRight, raCenter,
  3319. // all other are only set but can not be displayed:
  3320. raJustify, // displayed like raLeft (though stored normally)
  3321. raInterLetter, raScaled, raGlyphs, raSnapGrid );
  3322. {* Text alignment styles, available for RichEdit control. }
  3323. TVerticalAlign = ( vaCenter, vaTop, vaBottom );
  3324. {* Vertical alignments available. }
  3325. TControlAlign = ( caNone, caLeft, caTop, caRight, caBottom, caClient );
  3326. {* Control alignments available. }
  3327. TAligning = (oaWaitAlign,oaFromSelf,oaAligning);
  3328. TAlignings = set of TAligning;
  3329. //[BitBtn TYPES]
  3330. TBitBtnOption = ( bboImageList,
  3331. bboNoBorder,
  3332. bboNoCaption,
  3333. bboFixed,
  3334. bboFocusRect );
  3335. {* Options available for NewBitBtn. }
  3336. TBitBtnOptions = set of TBitBtnOption;
  3337. {* Set of options, available for NewBitBtn. }
  3338. TGlyphLayout = ( glyphLeft, glyphTop, glyphRight, glyphBottom, glyphOver );
  3339. {* Layout of glyph (for NewBitBtn). Layout glyphOver means that text is
  3340. drawn over glyph. }
  3341. TOnBitBtnDraw = function( Sender: PControl; BtnState: Integer ): Boolean of object;
  3342. {* Event type for TControl.OnBitBtnDraw event (which is called just before
  3343. drawing the BitBtn). If handler returns True, there are no drawing occure.
  3344. BtnState, passed to a handler, determines current button state and can
  3345. be following: 0 - not pressed, 1 - disabled, 2 - pressed, 3 - focused.
  3346. Value 4 is reserved for highlight state (then mouse is over it), but
  3347. highlighting is provided only if property Flat is set to True (or one
  3348. of events OnMouseEnter / OnMouseLeave is assigned to something). }
  3349. //[ListView TYPES]
  3350. TListViewStyle = ( lvsIcon, lvsSmallIcon, lvsList, lvsDetail, lvsDetailNoHeader );
  3351. {* Styles of view for ListView control (see NewListVew). }
  3352. TListViewItemStates = ( lvisFocus, lvisSelect, lvisBlend, lvisHighlight );
  3353. TListViewItemState = Set of TListViewItemStates;
  3354. TListViewOption = (
  3355. lvoIconLeft, // in lvsIcon, lvsSmallIcon place icon left from text (rather then top)
  3356. lvoAutoArrange, // keep icons auto arranged in lvsIcon and lvsSmallIcon view
  3357. lvoButton, // icons look like buttons in lvsIcon view
  3358. lvoEditLabel, // allows edit labels inplace (first column #0 text)
  3359. lvoNoLabelWrap, // item text on a single line in lvsIcon view (by default, item text may wrap in lvsIcon view).
  3360. lvoNoScroll, // obvious
  3361. lvoNoSortHeader, // click on header button does not lead to sort items
  3362. lvoHideSel, // hide selection when not in focus
  3363. lvoMultiselect, // allow to select multiple items
  3364. lvoSortAscending,
  3365. lvoSortDescending,
  3366. // extended styles (not documented in my Win32.hlp :( , got from VCL source:
  3367. lvoGridLines,
  3368. lvoSubItemImages,
  3369. lvoCheckBoxes,
  3370. lvoTrackSelect,
  3371. lvoHeaderDragDrop,
  3372. lvoRowSelect,
  3373. lvoOneClickActivate,
  3374. lvoTwoClickActivate,
  3375. lvoFlatsb,
  3376. lvoRegional,
  3377. lvoInfoTip,
  3378. lvoUnderlineHot,
  3379. lvoMultiWorkares,
  3380. // virtual list view style:
  3381. lvoOwnerData,
  3382. // custom draw style:
  3383. lvoOwnerDrawFixed
  3384. );
  3385. TListViewOptions = Set of TListViewOption;
  3386. TOnEditLVItem = function( Sender: PControl; Idx, Col: Integer; NewText: PKOL_Char ): Boolean
  3387. of object;
  3388. {* Event type for OnEndEditLVItem. Return True in handler to accept new text value. }
  3389. TOnDeleteLVItem = procedure( Sender: PControl; Idx: Integer ) of object;
  3390. {* Event type for OnDeleteLVItem event. }
  3391. TOnLVData = procedure( Sender: PControl; Idx, SubItem: Integer;
  3392. var Txt: KOL_String; var ImgIdx: Integer; var State: DWORD;
  3393. var Store: Boolean ) of object;
  3394. {* Event type for OnLVData event. Used to provide virtual list view control
  3395. (i.e. having lvoOwnerData style) with actual data on request. Use parameter
  3396. Store as a flag if control should store obtained data by itself or not. }
  3397. {$IFDEF ENABLE_DEPRECATED}
  3398. {$DEFINE interface_1} {$I KOL_deprecated.inc} {$UNDEF interface_1}
  3399. {$ENDIF DISABLE_DEPRECATED}
  3400. TOnCompareLVItems = function( Sender: PControl; Idx1, Idx2: Integer ): Integer
  3401. of object;
  3402. {* Event type to compare two items of the list view (while sorting it). }
  3403. TOnLVColumnClick = procedure( Sender: PControl; Idx: Integer ) of object;
  3404. {* Event type for OnColumnClick event. }
  3405. TOnLVStateChange = procedure( Sender: PControl; IdxFrom, IdxTo: Integer; OldState, NewState: DWORD )
  3406. of object;
  3407. {* Event type for OnLVStateChange event, called in responce to select/unselect
  3408. a single item or items range in list view control). }
  3409. TDrawActions = ( odaEntire, odaFocus, odaSelect );
  3410. TDrawAction = Set of TDrawActions;
  3411. TDrawStates = ( odsSelected, odsGrayed, odsDisabled, odsChecked, odsFocused,
  3412. odsDefault, odsHotlist, odsInactive,
  3413. odsNoAccel, odsNoFocusRect,
  3414. ods400reserved, ods800reserved,
  3415. odsComboboxEdit,
  3416. // specific for common controls:
  3417. odsMarked, odsIndeterminate );
  3418. {* Possible draw states.
  3419. |<br>odsSelected - The menu item's status is selected.
  3420. |<br>odsGrayed - The item is to be grayed. This bit is used only in a menu.
  3421. |<br>odsDisabled - The item is to be drawn as disabled.
  3422. |<br>odsChecked - The menu item is to be checked. This bit is used only in
  3423. a menu.
  3424. |<br>odsFocused - The item has the keyboard focus.
  3425. |<br>odsDefault - The item is the default item.
  3426. |<br>odsHotList - <b>Windows 98, Windows 2000:</b> The item is being
  3427. hot-tracked, that is, the item will be highlighted when
  3428. the mouse is on the item.
  3429. |<br>odsInactive - <b>Windows 98, Windows 2000:</b> The item is inactive
  3430. and the window associated with the menu is inactive.
  3431. |<br>odsNoAccel - <b>Windows 2000:</b> The control is drawn without the
  3432. keyboard accelerator cues.
  3433. |<br>odsNoFocusRect - <b>Windows 2000:</b> The control is drawn without
  3434. focus indicator cues.
  3435. |<br>odsComboboxEdit - The drawing takes place in the selection field
  3436. (edit control) of an owner-drawn combo box.
  3437. |<br>odsMarked - for Common controls only. The item is marked. The meaning
  3438. of this is up to the implementation.
  3439. |<br>odsIndeterminate - for Common Controls only. The item is in an
  3440. indeterminate state. }
  3441. TDrawState = Set of TDrawStates;
  3442. {* Set of possible draw states. }
  3443. TOnDrawItem = function( Sender: PObj; DC: HDC; const Rect: TRect; ItemIdx: Integer;
  3444. DrawAction: TDrawAction; ItemState: TDrawState ): Boolean of object;
  3445. {* Event type for OnDrawItem event (applied to list box, combo box, list view). }
  3446. TOnMeasureItem = function( Sender: PObj; Idx: Integer ): Integer of object;
  3447. {* Event type for OnMeasureItem event. The event handler must return height of list box
  3448. item as a result. }
  3449. TGetLVItemPart = ( lvipBounds, lvipIcon, lvipLabel, lvupIconAndLabel );
  3450. {* }
  3451. TWherePosLVItem = ( lvwpOnIcon, lvwpOnLabel, lvwpOnStateIcon, lvwpOnColumn,
  3452. lvwpOnItem );
  3453. {* }
  3454. TOnLVCustomDraw = function( Sender: PControl; DC: HDC; Stage: DWORD;
  3455. ItemIdx, SubItemIdx: Integer; const Rect: TRect;
  3456. ItemState: TDrawState; var TextColor, BackColor: TColor )
  3457. : DWORD of object;
  3458. {* Event type for OnLVCustomDraw event. }
  3459. //[Paint TYPES]
  3460. TOnPaint = procedure( Sender: PControl; DC: HDC ) of object;
  3461. TPaintProc = procedure( DC: HDC ) of object;
  3462. TGradientStyle = ( gsVertical, gsHorizontal, gsRectangle, gsElliptic, gsRombic,
  3463. gsTopToBottom, gsBottomToTop );
  3464. {* Gradient fill styles. See also TGradientLayout. }
  3465. TGradientLayout = ( glTopLeft, glTop, glTopRight,
  3466. glLeft, glCenter, glRight,
  3467. glBottomLeft, glBottom, glBottomRight );
  3468. {* Position of starting line / point for gradient filling. Depending on
  3469. TGradientStyle, means either position of first line of first rectangle
  3470. (ellipse) to be expanded in a loop to fit entire gradient panel area. }
  3471. //[Edit TYPES]
  3472. TEditOption = ( eoNoHScroll, eoNoVScroll, eoLowercase, eoMultiline,
  3473. eoNoHideSel, eoOemConvert, eoPassword, eoReadonly,
  3474. eoUpperCase, eoWantReturn, eoWantTab, eoNumber );
  3475. {* Available edit options.
  3476. |<br> Please note, that eoWantTab option just removes TAB key from a list
  3477. of keys available to tabulate from the edit control. To provide insertion
  3478. of tabulating key, do so in TControl.OnChar event handler. Sorry for
  3479. inconvenience, but this is because such behaviour is not must in all cases.
  3480. See also TControl.EditTabChar property. }
  3481. TEditOptions = Set of TEditOption;
  3482. {* Set of available edit options. }
  3483. TEditPositions = {$ifndef wince}packed{$endif} record
  3484. SelStart: Integer;
  3485. SelLength: Integer;
  3486. TopLine: Integer;
  3487. TopColumn: Integer;
  3488. ScrollPos: TPoint;
  3489. RestoreScroll: Boolean;
  3490. end;
  3491. TRichFmtArea = ( raSelection, raWord, raAll );
  3492. {* Characters formatting area for RichEdit. }
  3493. TRETextFormat = ( reRTF, reText, rePlainRTF, reRTFNoObjs, rePlainRTFNoObjs,
  3494. reTextized, reUnicode, reTextUnicode );
  3495. {* Available formats for transfer RichEdit text using property
  3496. TControl.RE_Text.
  3497. |<pre>
  3498. reRTF - normal rich text (no transformations)
  3499. reText - plain text only (without OLE objects)
  3500. reTextized - plain text with text representation of COM objects
  3501. rePlainRTF - reRTF without language-specific keywords
  3502. reRTFNoObjs - reRTF without OLE objects
  3503. rePlainRTFNoObjs - rePlainRTF without OLE objects
  3504. reUnicode - stream is 2-byte Unicode characters rather then 1-byte Ansi
  3505. |</pre> }
  3506. TRichUnderline = ( ruSingle, ruWord, ruDouble, ruDotted,
  3507. //all other - only for RichEditv3.0:
  3508. ruDash, ruDashDot, ruDashDotDot, ruWave, ruThick, ruHairLine );
  3509. {* Rich text exteded underline styles (available only for RichEdit v2.0,
  3510. and even for RichEdit v2.0 additional styles can not displayed - but
  3511. ruDotted under Windows2000 is working). }
  3512. TRichTextSizes = ( rtsNoUseCRLF, rtsNoPrecise, rtsClose, rtsBytes );
  3513. {* Options to calculate size of rich text. Available only for RichEdit2.0
  3514. or higher. }
  3515. TRichTextSize = set of TRichTextSizes;
  3516. {* Set of all available optioins to calculate rich text size using
  3517. property TControl.RE_TextSize[ options ]. }
  3518. TRichNumbering = ( rnNone, rnBullets, rnArabic, rnLLetter, rnULetter,
  3519. rnLRoman, rnURoman );
  3520. {* Advanced numbering styles for paragraph (RichEdit).
  3521. |<pre>
  3522. rnNone - no numbering
  3523. rnBullets - bullets only
  3524. rnArabic - 1, 2, 3, 4, ...
  3525. rnLLetter - a, b, c, d, ...
  3526. rnULetter - A, B, C, D, ...
  3527. rnLRoman - i, ii, iii, iv, ...
  3528. rnURoman - I, II, III, IV, ...
  3529. rnNoNumber - do not show any numbers (but numbering is taking place).
  3530. |</pre> }
  3531. TRichNumBrackets = ( rnbRight, rnbBoth, rnbPeriod, rnbPlain, rnbNoNumber );
  3532. {* Brackets around number:
  3533. |<pre>
  3534. rnbRight - 1) 2) 3) - this is default !
  3535. rnbBoth - (1) (2) (3)
  3536. rnbPeriod - 1. 2. 3.
  3537. rnbPlain - 1 2 3
  3538. |</pre> }
  3539. TBorderEdge = (beLeft, beTop, beRight, beBottom);
  3540. {* Borders of rectangle. }
  3541. {$IFNDEF NOT_USE_RICHEDIT}
  3542. TCharFormat = TCharFormat2;
  3543. TParaFormat = TParaFormat2;
  3544. {$ENDIF NOT_USE_RICHEDIT}
  3545. TOnTestMouseOver = function( Sender: PControl ): Boolean of object;
  3546. {* Event type for TControl.OnTestMouseOver event. The handler should
  3547. return True, if it dectects, that mouse is over control. }
  3548. TEdgeStyle = ( esRaised, esLowered, esNone, esTransparent );
  3549. {* Edge styles (for panel - see NewPanel). }
  3550. //[List TYPES]
  3551. TListOption = ( loNoHideScroll, loNoExtendSel, loMultiColumn, loMultiSelect,
  3552. loNoIntegralHeight, loNoSel, loSort, loTabstops,
  3553. loNoStrings, loNoData, loOwnerDrawFixed, loOwnerDrawVariable,
  3554. loHScroll );
  3555. {* Options for ListBox (see NewListbox).
  3556. To use loHScroll, you also have to send LB_SETHORIZONTALEXTENT with a
  3557. maximum width of a line in pixels (wParam)! }
  3558. TListOptions = Set of TListOption;
  3559. {* Set of available options for Listbox. }
  3560. TComboOption = ( coReadOnly, coNoHScroll, coAlwaysVScroll, coLowerCase,
  3561. coNoIntegralHeight, coOemConvert, coSort, coUpperCase,
  3562. coOwnerDrawFixed, coOwnerDrawVariable, coSimple );
  3563. {* Options for combobox. }
  3564. TComboOptions = Set of TComboOption;
  3565. {* Set of options available for combobox. }
  3566. //[Progress TYPES]
  3567. TProgressbarOption = ( pboVertical, pboSmooth );
  3568. {* Options for progress bar. }
  3569. TProgressbarOptions = set of TProgressbarOption;
  3570. {* Set of options available for progress bar. }
  3571. //[TreeView TYPES]
  3572. TTreeViewOption = ( tvoNoLines, tvoLinesRoot, tvoNoButtons, tvoEditLabels, tvoHideSel,
  3573. tvoDragDrop, tvoNoTooltips, tvoCheckBoxes, tvoTrackSelect,
  3574. tvoSingleExpand, tvoInfoTip, tvoFullRowSelect, tvoNoScroll,
  3575. tvoNonEvenHeight );
  3576. {* Tree view options. }
  3577. TTreeViewOptions = set of TTreeViewOption;
  3578. {* Set of tree view options. }
  3579. //[TabControl TYPES]
  3580. TTabControlOption = ( tcoButtons, tcoFixedWidth, tcoFocusTabs,
  3581. tcoIconLeft, tcoLabelLeft,
  3582. tcoMultiline, tcoMultiselect, tcoFitRows, tcoScrollOpposite,
  3583. tcoBottom, tcoVertical, tcoFlat, tcoHotTrack, tcoBorder,
  3584. tcoOwnerDrawFixed );
  3585. {* Options, available for TabControl. }
  3586. TTabControlOptions = set of TTabControlOption;
  3587. {* Set of options, available for TAbControl during its creation (by
  3588. NewTabControl function). }
  3589. //[Toolbar TYPES]
  3590. TToolbarOption = ( tboTextRight, tboTextBottom, tboFlat, tboTransparent,
  3591. tboWrapable, tboNoDivider, tbo3DBorder, tboCustomErase );
  3592. {* Toolbar options. When tboFlat is set and toolbar is placed onto panel,
  3593. set its property Transparent to TRUE to provide its correct view. }
  3594. TToolbarOptions = Set of TToolbarOption;
  3595. {* Set of toolbar options. }
  3596. TOnToolbarButtonClick = procedure( Sender: PControl; BtnID: Integer ) of object;
  3597. {* Special event type to handle separate toolbar buttons click events. }
  3598. {$ifndef wince}
  3599. TOnTBCustomDraw = function( Sender: PControl; var NMCD: TNMTBCustomDraw ): Integer of object;
  3600. {* Event type for OnTBCustomDraw event. }
  3601. {$endif wince}
  3602. TDateTimePickerOption = ( dtpoTime, dtpoDateLong, dtpoUpDown, dtpoRightAlign,
  3603. dtpoShowNone, dtpoParseInput );
  3604. {* }
  3605. TDateTimePickerOptions = set of TDateTimePickerOption;
  3606. {* }
  3607. TDTParseInputEvent = procedure(Sender: PControl; const UserString: string;
  3608. var DateAndTime: TDateTime; var AllowChange: Boolean) of object;
  3609. {* }
  3610. TDateTimeRange = {$ifndef wince}packed{$endif} record
  3611. FromDate, ToDate: TDateTime;
  3612. end;
  3613. {* }
  3614. TDateTimePickerColor = ( dtpcBackground, dtpcMonthBk, dtpcText, dtpcTitleBk,
  3615. dtpcTitleText, dtpcTrailingText );
  3616. //[TOnDropFiles TYPE]
  3617. TOnDropFiles = procedure( Sender: PControl; const FileList: KOL_String; const Pt: TPoint ) of object;
  3618. {* An event type for OnDropFiles event. When the event is occur, FileList
  3619. parameter contains a list of files dropped. File names in a list are
  3620. separated with #13 character. This allows You to assign it to TStrList
  3621. object using its property Text (for example):
  3622. ! procedure TSomeObject.DropFiles( Sender: PControl; const FileList: String;
  3623. ! const Pt: TPoint ); )
  3624. ! var FList: PStrList;
  3625. ! I: Integer;
  3626. ! begin
  3627. ! FList := NewStrList;
  3628. ! FList.Text := FileList;
  3629. ! for I := 0 to FList.Count-1 do
  3630. ! begin
  3631. ! // do something with FList.Items[ I ]
  3632. ! end;
  3633. ! FList.Free;
  3634. ! end; }
  3635. //[Scroll TYPES]
  3636. TScrollerBar = ( sbHorizontal, sbVertical );
  3637. TScrollerBars = set of TScrollerBar;
  3638. TOnScroll = procedure( Sender: PControl; Bar: TScrollerBar; ScrollCmd: DWORD;
  3639. ThumbPos: DWORD ) of object;
  3640. //[TOnHelp EVENT TYPE]
  3641. TOnHelp = procedure( var Sender: PControl; var Context: Integer; var Popup: Boolean )
  3642. of object;
  3643. //[ScrollBar TYPES]
  3644. TOnSBBeforeScroll =
  3645. procedure(
  3646. Sender: PControl; OldPos, NewPos: Integer; Cmd: Word;
  3647. var AllowChange: Boolean) of object;
  3648. TOnSBScroll = procedure(Sender: PControl; Cmd: Word) of object;
  3649. {$IFDEF WIN_GDI}
  3650. TOnGraphCtlMouse = procedure( var Msg: TMsg ) of object;
  3651. {$ENDIF WIN_GDI}
  3652. TTriStateCheck = (tsUnchecked{=0}, tsChecked{=1}, tsIndeterminate{=2});
  3653. {$IFDEF _X_}
  3654. //---- in GTK+, each type of widget requieres its own getcaption/setcaption call
  3655. TGetCaption = function( Ctl: PControl ): KOLString;
  3656. TSetCaption = procedure( Ctl: PControl; const Value: KOLString );
  3657. {$IFDEF GTK}
  3658. //---- in GTK+, to allow setting absolute position for children,
  3659. // we should use one of special clients like gtk_fixed, gtk_layout
  3660. TGetClientArea = function( Ctl: PControl ): PGtkWidget;
  3661. TChildSetPos = procedure( Ctl, Chld: PControl; x, y: Integer );
  3662. {$ENDIF GTK}
  3663. {$ENDIF _X_}
  3664. {$IFDEF USE_MHTOOLTIP}
  3665. {$DEFINE pre_interface}
  3666. {$I KOLMHToolTip.pas}
  3667. {$UNDEF pre_interface}
  3668. {$ENDIF}
  3669. { ----------------------------------------------------------------------
  3670. TControl - object to implement any visual control
  3671. ----------------------------------------------------------------------- }
  3672. //[TControl DEFINITION]
  3673. TControl = object( TObj )
  3674. {* Object to implement any visual control }
  3675. {$IFDEF GDI}
  3676. protected
  3677. fSBMinMax: TPoint;
  3678. fSBPageSize: Integer;
  3679. fSBPosition: Integer;
  3680. procedure SetSBMax(Value: Longint);
  3681. procedure SetSBMin(Value: Longint);
  3682. procedure SetSBPageSize(Value: Integer);
  3683. procedure SetSBPosition(Value: Integer);
  3684. procedure SetSBMinMax(const Value: TPoint);
  3685. function GetDate: TDateTime;
  3686. function GetTime: TDateTime;
  3687. procedure SetDate(const Value: TDateTime);
  3688. procedure SetTime(const Value: TDateTime);
  3689. {*! TControl is the basic visual object of KOL. And now, all visual
  3690. objects have the same type PControl, differing only in "constructor",
  3691. which during creating of object adjusts it so it can play role of
  3692. desired control. Idea of incapsulating of all visual objects having
  3693. the most common set of properties, is belonging to Vladimir Kladov,
  3694. (C) 2000.
  3695. |<br>&nbsp;&nbsp;&nbsp;<b> Since all visual objects are represented
  3696. in KOL by this single object type, not all methods, properties and
  3697. events defined in TControl, are applicable to different visual objects.
  3698. See also notes about certain control kinds, located together with its
  3699. |<a href="kol_pas.htm#visual_objects_constructors">
  3700. |constructing functions definitions</a></b>. }
  3701. {$ENDIF GDI}
  3702. protected
  3703. {$IFDEF GDI}
  3704. function GetHelpPath: KOLString;
  3705. procedure SetHelpPath(const Value: KOLString);
  3706. procedure SetOnQueryEndSession(const Value: TOnEventAccept);
  3707. procedure SetOnMinMaxRestore(const Index: Integer; const Value: TOnEvent);
  3708. procedure SetOnMinimize( const Value: TOnEvent );
  3709. procedure SetOnMaximize( const Value: TOnEvent );
  3710. procedure SetOnRestore( const Value: TOnEvent );
  3711. procedure SetConstraint(const Index, Value: Integer);
  3712. {$IFDEF F_P}
  3713. function GetOnMinMaxRestore(const Index: Integer): TOnEvent;
  3714. function GetConstraint(const Index: Integer): Integer;
  3715. {$ENDIF F_P}
  3716. procedure SetOnScroll(const Value: TOnScroll);
  3717. function GetLVColalign(Idx: Integer): TTextAlign;
  3718. procedure SetLVColalign(Idx: Integer; const Value: TTextAlign);
  3719. {$ENDIF GDI}
  3720. procedure SetParent( Value: PControl );
  3721. function GetLeft: Integer;
  3722. procedure SetLeft( Value: Integer );
  3723. function GetTop: Integer;
  3724. procedure SetTop( Value: Integer );
  3725. function GetWidth: Integer;
  3726. procedure SetWidth( Value: Integer );
  3727. function GetHeight: Integer;
  3728. procedure SetHeight( Value: Integer );
  3729. function GetPosition: TPoint;
  3730. procedure Set_Position( Value: TPoint );
  3731. function GetMembers(Idx: Integer): PControl;
  3732. function GetFont: PGraphicTool;
  3733. procedure FontChanged( Sender: PGraphicTool );
  3734. {$IFDEF GDI}
  3735. function GetBrush: PGraphicTool;
  3736. procedure BrushChanged( Sender: PGraphicTool );
  3737. function GetClientHeight: Integer;
  3738. function GetClientWidth: Integer;
  3739. procedure SetClientHeight(const Value: Integer);
  3740. procedure SetClientWidth(const Value: Integer);
  3741. function GetHasBorder: Boolean;
  3742. procedure SetHasBorder(const Value: Boolean);
  3743. function GetHasCaption: Boolean;
  3744. procedure SetHasCaption(const Value: Boolean);
  3745. function GetCanResize: Boolean;
  3746. procedure SetCanResize( const Value: Boolean );
  3747. function GetStayOnTop: Boolean;
  3748. procedure SetStayOnTop(const Value: Boolean);
  3749. function GetChecked: Boolean;
  3750. procedure Set_Checked(const Value: Boolean);
  3751. function GetCheck3: TTriStateCheck;
  3752. procedure SetCheck3(value: TTriStateCheck);
  3753. function GetSelStart: Integer;
  3754. procedure SetSelStart(const Value: Integer);
  3755. function GetSelLength: Integer;
  3756. procedure SetSelLength(const Value: Integer);
  3757. function GetItems(Idx: Integer): KOLString;
  3758. procedure SetItems(Idx: Integer; const Value: KOLString);
  3759. function GetItemsCount: Integer;
  3760. function GetItemSelected(ItemIdx: Integer): Boolean;
  3761. procedure SetItemSelected(ItemIdx: Integer; const Value: Boolean);
  3762. procedure SetCtl3D(const Value: Boolean);
  3763. function GetCurIndex: Integer;
  3764. procedure SetCurIndex(const Value: Integer);
  3765. {$ENDIF GDI}
  3766. function GetTextAlign: TTextAlign;
  3767. procedure SetTextAlign(const Value: TTextAlign);
  3768. function GetVerticalAlign: TVerticalAlign;
  3769. procedure SetVerticalAlign(const Value: TVerticalAlign);
  3770. function GetCanvas: PCanvas;
  3771. {$IFDEF _X_}
  3772. {$IFDEF GTK}
  3773. protected
  3774. fInBkPaint: Boolean;
  3775. fSetTextAlign: procedure( Self_: PControl );
  3776. function ProvideCanvasHandle( Sender: PCanvas ): HDC;
  3777. {$ENDIF GTK}
  3778. {$ENDIF _X_}
  3779. {$IFDEF GDI}
  3780. function Dc2Canvas( Sender: PCanvas ): HDC;
  3781. procedure SetShadowDeep(const Value: Integer);
  3782. procedure SetDoubleBuffered(const Value: Boolean);
  3783. procedure SetStatusText(Index: Integer; Value: PKOLChar);
  3784. function GetStatusText( Index: Integer ): PKOLChar;
  3785. function GetStatusPanelX(Idx: Integer): Integer;
  3786. procedure SetStatusPanelX(Idx: Integer; const Value: Integer);
  3787. procedure SetTransparent(const Value: Boolean);
  3788. function GetImgListIdx(const Index: Integer): PImageList;
  3789. procedure SetImgListIdx(const Index: Integer; const Value: PImageList);
  3790. function GetLVColText(Idx: Integer): KOLString;
  3791. procedure SetLVColText(Idx: Integer; const Value: KOLString);
  3792. {$IFDEF ENABLE_DEPRECATED}
  3793. {$DEFINE interface_2} {$I KOL_deprecated.inc} {$UNDEF interface_2}
  3794. {$ENDIF DISABLE_DEPRECATED}
  3795. protected
  3796. function LVGetItemText(Idx, Col: Integer): KOLString;
  3797. procedure LVSetItemText(Idx, Col: Integer; const Value: KOLString);
  3798. procedure SetLVOptions(const Value: TListViewOptions);
  3799. procedure SetLVStyle(const Value: TListViewStyle);
  3800. function GetLVColEx(Idx: Integer; const Index: Integer): Integer;
  3801. procedure SetLVColEx(Idx: Integer; const Index: Integer;
  3802. const Value: Integer);
  3803. {$ENDIF GDI}
  3804. function GetChildCount: Integer;
  3805. {$IFDEF GDI}
  3806. function LVGetItemPos(Idx: Integer): TPoint;
  3807. procedure LVSetItemPos(Idx: Integer; const Value: TPoint);
  3808. procedure LVSetColorByIdx(const Index: Integer; const Value: TColor);
  3809. {$IFDEF F_P}
  3810. function LVGetColorByIdx(const Index: Integer): TColor;
  3811. {$ENDIF F_P}
  3812. function GetIntVal(const Index: Integer): Integer;
  3813. procedure SetIntVal(const Index, Value: Integer);
  3814. function GetItemVal(Item: Integer; const Index: Integer): Integer;
  3815. procedure SetItemVal(Item: Integer; const Index, Value: Integer);
  3816. function TBGetButtonVisible(BtnID: Integer): Boolean;
  3817. procedure TBSetButtonVisible(BtnID: Integer; const Value: Boolean);
  3818. function TBGetBtnStt(BtnID: Integer; const Index: Integer): Boolean;
  3819. procedure TBSetBtnStt(BtnID: Integer; const Index: Integer; const Value: Boolean);
  3820. function TBGetButtonText(BtnID: Integer): KOLString;
  3821. function TBGetButtonRect(BtnID: Integer): TRect;
  3822. function TBGetRows: Integer;
  3823. procedure TBSetRows(const Value: Integer);
  3824. procedure SetProgressColor(const Value: TColor);
  3825. function TBGetBtnImgIdx(BtnID: Integer): Integer;
  3826. procedure TBSetBtnImgIdx(BtnID: Integer; const Value: Integer);
  3827. procedure TBSetButtonText(BtnID: Integer; const Value: KOLString);
  3828. function TBGetBtnWidth(BtnID: Integer): Integer;
  3829. procedure TBSetBtnWidth(BtnID: Integer; const Value: Integer);
  3830. procedure TBSetBtMinMaxWidth(const Idx: Integer; const Value: Integer);
  3831. {$IFDEF F_P}
  3832. function TBGetBtMinMaxWidth(const Idx: Integer): Integer;
  3833. {$ENDIF F_P}
  3834. procedure TBFreeTBevents;
  3835. procedure Set_Align(const Value: TControlAlign);
  3836. function GetSelection: KOLString;
  3837. procedure SetSelection(const Value: KOLString);
  3838. procedure SetTabOrder(const Value: Integer);
  3839. function GetFocused: Boolean;
  3840. procedure SetFocused(const Value: Boolean);
  3841. {$IFNDEF NOT_USE_RICHEDIT}
  3842. function REGetFont: PGraphicTool;
  3843. procedure RESetFont(Value: PGraphicTool);
  3844. procedure RESetFontEx(const Index: Integer);
  3845. function REGetFontEffects(const Index: Integer): Boolean;
  3846. function REGetFontMask(const Index: Integer): Boolean;
  3847. procedure RESetFontEffect(const Index: Integer; const Value: Boolean);
  3848. function REGetFontAttr(const Index: Integer): Integer;
  3849. procedure RESetFontAttr(const Index, Value: Integer);
  3850. procedure RESetFontAttr1(const Index, Value: Integer);
  3851. function REGetFontSizeValid: Boolean;
  3852. function REGetCharformat: TCharFormat;
  3853. procedure RESetCharFormat(const Value: TCharFormat);
  3854. function REReadText(Format: TRETextFormat;
  3855. SelectionOnly: Boolean): KOLString;
  3856. procedure REWriteText(Format: TRETextFormat; SelectionOnly: Boolean;
  3857. const Value: KOLString);
  3858. function REGetFontName: KOLString;
  3859. procedure RESetFontName(const Value: KOLString);
  3860. function REGetParaFmt: TParaFormat;
  3861. procedure RESetParaFmt(const Value: TParaFormat);
  3862. function REGetNumbering: Boolean;
  3863. function REGetParaAttr( const Index: Integer ): Integer;
  3864. function REGetParaAttrValid( const Index: Integer ): Boolean;
  3865. function REGetTabCount: Integer;
  3866. function REGetTabs(Idx: Integer): Integer;
  3867. function REGetTextAlign: TRichTextAlign;
  3868. procedure RESetNumbering(const Value: Boolean);
  3869. procedure RESetParaAttr(const Index, Value: Integer);
  3870. procedure RESetTabCount(const Value: Integer);
  3871. procedure RESetTabs(Idx: Integer; const Value: Integer);
  3872. procedure RESetTextAlign(const Value: TRichTextAlign);
  3873. function REGetStartIndentValid: Boolean;
  3874. function REGetAutoURLDetect: Boolean;
  3875. procedure RESetAutoURLDetect(const Value: Boolean);
  3876. procedure RESetZoom( const Value: TSmallPoint );
  3877. function REGetZoom: TSmallPoint;
  3878. {$ENDIF NOT_USE_RICHEDIT}
  3879. function GetMaxTextSize: DWORD;
  3880. procedure SetMaxTextSize(const Value: DWORD);
  3881. function GetTextSize: Integer;
  3882. procedure SetOnResize(const Value: TOnEvent);
  3883. procedure DoSelChange;
  3884. {$IFNDEF NOT_USE_RICHEDIT}
  3885. function REGetUnderlineEx: TRichUnderline;
  3886. procedure RESetUnderlineEx(const Value: TRichUnderline);
  3887. function REGetTextSize(Units: TRichTextSize): Integer;
  3888. function REGetNumStyle: TRichNumbering;
  3889. procedure RESetNumStyle(const Value: TRichNumbering);
  3890. function REGetNumBrackets: TRichNumBrackets;
  3891. procedure RESetNumBrackets(const Value: TRichNumBrackets);
  3892. function REGetNumTab: Integer;
  3893. procedure RESetNumTab(const Value: Integer);
  3894. function REGetNumStart: Integer;
  3895. procedure RESetNumStart(const Value: Integer);
  3896. function REGetSpacing(const Index: Integer): Integer;
  3897. procedure RESetSpacing(const Index, Value: Integer);
  3898. function REGetSpacingRule: Integer;
  3899. procedure RESetSpacingRule(const Value: Integer);
  3900. function REGetLevel: Integer;
  3901. function REGetBorder(Side: TBorderEdge; const Index: Integer): Integer;
  3902. procedure RESetBorder(Side: TBorderEdge; const Index: Integer;
  3903. const Value: Integer);
  3904. function REGetParaEffect(const Index: Integer): Boolean;
  3905. procedure RESetParaEffect(const Index: Integer; const Value: Boolean);
  3906. function REGetOverwite: Boolean;
  3907. procedure RESetOverwrite(const Value: Boolean);
  3908. procedure RESetOvrDisable(const Value: Boolean);
  3909. function REGetTransparent: Boolean;
  3910. procedure RESetTransparent(const Value: Boolean);
  3911. procedure RESetOnURL(const Index: Integer; const Value: TOnEvent);
  3912. procedure SetOnRE_URLClick( const Value: TOnEvent );
  3913. procedure SetOnRE_OverURL( const Value: TOnEvent );
  3914. {$IFDEF F_P}
  3915. function REGetOnURL(const Index: Integer): TOnEvent;
  3916. {$ENDIF F_P}
  3917. function REGetLangOptions(const Index: Integer): Boolean;
  3918. procedure RESetLangOptions(const Index: Integer; const Value: Boolean);
  3919. {$ENDIF NOT_USE_RICHEDIT}
  3920. function LVGetItemImgIdx(Idx: Integer): Integer;
  3921. procedure LVSetItemImgIdx(Idx: Integer; const Value: Integer);
  3922. procedure SetFlat(const Value: Boolean);
  3923. procedure SetOnMouseEnter(const Value: TOnEvent);
  3924. procedure SetOnMouseLeave(const Value: TOnEvent);
  3925. procedure EdSetTransparent(const Value: Boolean);
  3926. procedure SetOnTestMouseOver(const Value: TOnTestMouseOver);
  3927. function GetPages(Idx: Integer): PControl;
  3928. function TCGetItemText(Idx: Integer): KOLString;
  3929. procedure TCSetItemText(Idx: Integer; const Value: KOLString);
  3930. function TCGetItemImgIDx(Idx: Integer): Integer;
  3931. procedure TCSetItemImgIdx(Idx: Integer; const Value: Integer);
  3932. function TCGetItemRect(Idx: Integer): TRect;
  3933. function TVGetItemIdx(const Index: Integer): THandle;
  3934. procedure TVSetItemIdx(const Index: Integer; const Value: THandle);
  3935. function TVGetItemNext(Item: THandle; const Index: Integer): THandle;
  3936. function TVGetItemRect(Item: THandle; TextOnly: Boolean): TRect;
  3937. function TVGetItemVisible(Item: THandle): Boolean;
  3938. procedure TVSetITemVisible(Item: THandle; const Value: Boolean);
  3939. function TVGetItemStateFlg(Item: THandle; const Index: Integer): Boolean;
  3940. procedure TVSetItemStateFlg(Item: THandle; const Index: Integer;
  3941. const Value: Boolean);
  3942. function TVGetItemImage(Item: THandle; const Index: Integer): Integer;
  3943. procedure TVSetItemImage(Item: THandle; const Index: Integer;
  3944. const Value: Integer);
  3945. function TVGetItemText(Item: THandle): KOLString;
  3946. procedure TVSetItemText(Item: THandle; const Value: KOLString);
  3947. function TV_GetItemHasChildren(Item: THandle): Boolean;
  3948. procedure TV_SetItemHasChildren(Item: THandle; const Value: Boolean);
  3949. function TV_GetItemChildCount(Item: THandle): Integer;
  3950. function TVGetItemData(Item: THandle): Pointer;
  3951. procedure TVSetItemData(Item: THandle; const Value: Pointer);
  3952. function GetToBeVisible: Boolean;
  3953. procedure SetAlphaBlend(const Value: Integer);
  3954. procedure SetMaxProgress(const Index, Value: Integer);
  3955. procedure SetDroppedWidth(const Value: Integer);
  3956. function LVGetItemState(Idx: Integer): TListViewItemState;
  3957. procedure LVSetItemState(Idx: Integer; const Value: TListViewItemState);
  3958. function LVGetSttImgIdx(Idx: Integer): Integer;
  3959. procedure LVSetSttImgIdx(Idx: Integer; const Value: Integer);
  3960. function LVGetOvlImgIdx(Idx: Integer): Integer;
  3961. procedure LVSetOvlImgIdx(Idx: Integer; const Value: Integer);
  3962. function LVGetItemData(Idx: Integer): DWORD;
  3963. procedure LVSetItemData(Idx: Integer; const Value: DWORD);
  3964. function LVGetItemIndent(Idx: Integer): Integer;
  3965. procedure LVSetItemIndent(Idx: Integer; const Value: Integer);
  3966. procedure SetOnDeleteAllLVItems(const Value: TOnEvent);
  3967. procedure SetOnDeleteLVItem(const Value: TOnDeleteLVItem);
  3968. procedure SetOnEndEditLVItem(const Value: TOnEditLVItem);
  3969. procedure SetOnLVData(const Value: TOnLVData);
  3970. procedure SetOnColumnClick(const Value: TOnLVColumnClick);
  3971. procedure SetOnDrawItem(const Value: TOnDrawItem);
  3972. procedure SetOnMeasureItem(const Value: TOnMeasureItem);
  3973. procedure SetItemsCount(const Value: Integer);
  3974. function GetItemData(Idx: Integer): DWORD;
  3975. procedure SetItemData(Idx: Integer; const Value: DWORD);
  3976. function GetLVCurItem: Integer;
  3977. procedure SetLVCurItem(const Value: Integer);
  3978. function GetLVFocusItem: Integer;
  3979. procedure SetOnDropFiles(const Value: TOnDropFiles);
  3980. procedure SetOnHide(const Value: TOnEvent);
  3981. procedure SetOnShow(const Value: TOnEvent);
  3982. procedure SetClientMargin(const Index, Value: Integer);
  3983. {$IFDEF F_P}
  3984. function GetClientMargin(const Index: Integer): Integer;
  3985. {$ENDIF F_P}
  3986. {$ENDIF GDI}
  3987. protected
  3988. {$IFDEF _X_}
  3989. {$IFDEF GTK}
  3990. fExposeEvent: Integer;
  3991. {$ENDIF GTK}
  3992. {$ENDIF _X_}
  3993. procedure SetOnPaint(const Value: TOnPaint);
  3994. {$IFDEF GDI}
  3995. procedure SetOnEraseBkgnd(const Value: TOnPaint);
  3996. procedure SetTVRightClickSelect(const Value: Boolean);
  3997. procedure SetOnLVStateChange(const Value: TOnLVStateChange);
  3998. procedure SetOnMove(const Value: TOnEvent);
  3999. procedure SetOnMoving(const Value: TOnEventMoving);
  4000. procedure SetColor1(const Value: TColor);
  4001. procedure SetColor2(const Value: TColor);
  4002. procedure SetGradientLayout(const Value: TGradientLayout);
  4003. procedure SetGradientStyle(const Value: TGradientStyle);
  4004. procedure SetDroppedDown(const Value: Boolean);
  4005. function get_ClassName: KOLString;
  4006. procedure set_ClassName(const Value: KOLString);
  4007. procedure SetClsStyle( Value: DWord );
  4008. {$IFDEF GRAPHCTL_XPSTYLES}
  4009. procedure SetEdgeStyle( Value: TEdgeStyle );
  4010. {$ENDIF}
  4011. procedure SetStyle( Value: DWord );
  4012. procedure SetExStyle( Value: DWord );
  4013. procedure SetCursor( Value: HCursor );
  4014. procedure SetIcon( Value: HIcon );
  4015. procedure SetMenu( Value: HMenu );
  4016. {$ENDIF GDI}
  4017. protected
  4018. {$IFDEF _X_}
  4019. fGetCaption: TGetCaption;
  4020. fSetCaption: TSetCaption;
  4021. {$ENDIF _X_}
  4022. function GetCaption: KOLString;
  4023. procedure SetCaption( const Value: KOLString );
  4024. {$IFDEF GDI}
  4025. procedure SetWindowState( Value: TWindowState );
  4026. function GetWindowState: TWindowState;
  4027. {$ENDIF GDI}
  4028. procedure ApplyFont2Wnd;
  4029. {$IFDEF GDI}
  4030. procedure DoClick;
  4031. function TBAddInsButtons( Idx: Integer; const Buttons: array of PKOLChar;
  4032. const BtnImgIdxArray: array of Integer ): Integer;
  4033. procedure SetBitBtnDrawMnemonic(const Value: Boolean);
  4034. function GetBitBtnImgIdx: Integer;
  4035. procedure SetBitBtnImgIdx(const Value: Integer);
  4036. function GetBitBtnImageList: THandle;
  4037. procedure SetBitBtnImageList(const Value: THandle);
  4038. function GetModal: Boolean;
  4039. {$IFDEF USE_SETMODALRESULT}
  4040. procedure SetModalResult( const Value: Integer );
  4041. {$ENDIF}
  4042. {$ENDIF GDI}
  4043. protected
  4044. {$IFDEF GDI}
  4045. fHandle: HWnd;
  4046. {$ELSE}
  4047. {$IFDEF GTK} fHandle: PGtkWidget;
  4048. fCaptionHandle: PGtkWidget;
  4049. fEventboxHandle: PGtkWidget;
  4050. fGetClientArea: TGetClientArea;
  4051. fClient: PGtkWidget;
  4052. fChildPut: TChildSetPos;
  4053. fChildSetPos: TChildSetPos;
  4054. {$ENDIF}
  4055. {$IFDEF Q_T} fHandle: sometypehere ; {$ENDIF}
  4056. {$ENDIF}
  4057. {$IFDEF GDI}
  4058. fFocusHandle: HWnd;
  4059. fClsStyle: DWord;
  4060. fStyle: DWord;
  4061. fExStyle: DWord;
  4062. fCursor: HCursor;
  4063. fCursorShared: Boolean;
  4064. fIcon: HIcon;
  4065. fIconShared: Boolean;
  4066. {$ENDIF GDI}
  4067. fIgnoreWndCaption: Boolean;
  4068. {$IFDEF GDI}
  4069. {$IFDEF GRAPHCTL_XPSTYLES}
  4070. fEdgeStyle : TEdgeStyle;
  4071. {$ENDIF}
  4072. fWindowState: TWindowState;
  4073. //fShowAction: Integer;
  4074. fDefWndProc: Pointer;
  4075. fNCDestroyed: Boolean;
  4076. {$ENDIF GDI}
  4077. FParent: PControl;
  4078. fEnabled: Boolean; // Caution!!! fVisible must follow fEnabled! ___
  4079. fVisible: Boolean; //____________________________________________//
  4080. fTabstop: Boolean;
  4081. fTabOrder: Integer;
  4082. fTextAlign: TTextAlign;
  4083. fVerticalAlign: TVerticalAlign;
  4084. fWordWrap: Boolean;
  4085. fPreventResize: Boolean;
  4086. {$IFDEF GDI}
  4087. fAlphaBlend: Integer;
  4088. {$ENDIF GDI}
  4089. FDroppedWidth: Integer;
  4090. // Caution!!! order of following 5 fields is important!!!
  4091. fDynHandlers: PList;
  4092. fChildren: PList;
  4093. {* List of children. }
  4094. {$ifndef wince}
  4095. fTBttCmd: PList;
  4096. {$endif wince}
  4097. fTBttTxt: {$IFDEF UNICODE_CTRLS} PWStrList {$ELSE} PStrList {$ENDIF};
  4098. {$IFDEF GDI}
  4099. fTmpFont: PGraphicTool;
  4100. {$ENDIF GDI}
  4101. //________________________________________________________//
  4102. {$IFDEF GDI}
  4103. fMDIClient: PControl;
  4104. {* MDI client window control }
  4105. fMDIChildren: PList;
  4106. {* List of MDI children. It is filled for MDI client window. }
  4107. fWndFunc: Pointer;
  4108. {* Initially pointer to WndFunc. For MDI child window, points to DefMDIChildProc. }
  4109. fExMsgProc: function( Applet: PControl; var Msg: TMsg ): Boolean;
  4110. {* Additional message handler called directly from Applet.ProcessMessage.
  4111. Used to call TranslateMDISysAccel API function for MDI application. }
  4112. fMDIDestroying: Boolean;
  4113. {* }
  4114. fTmpBrush: HBrush;
  4115. {* Brush handle to return in response to some color set messages.
  4116. Intended for internal use instead of Brush.Color if possible
  4117. to avoid using it. }
  4118. fTmpBrushColorRGB: TColor;
  4119. { }
  4120. fMembersCount: Integer;
  4121. {* Memebers count is first used in XCustomControl to separate
  4122. some internal child controls from common XControl.Children
  4123. and make it invisible among Children[]. }
  4124. fDrawCtrl1st: PControl;
  4125. {* Child control to draw it first, i.e. foreground of others. }
  4126. FCreating: Boolean;
  4127. {* True, when creating of object is in progress. }
  4128. fDestroying: Boolean;
  4129. {* True, when destroying of the window is started. }
  4130. fBeginDestroying: Boolean;
  4131. {* true, when destroying of the window is initiated by the system, i.e.
  4132. message WM_DESTROY fired }
  4133. fNestedMsgHandling: Integer;
  4134. {* level of nested message handling for a control. Only when it is 0 at
  4135. the end of message handling and fBeginDestroying set, the control is
  4136. destroyed. }
  4137. fMenu: HMenu;
  4138. {* Usually used to store handle of attached main menu, but sometimes
  4139. is used to store control ID (for standard GUI controls only). }
  4140. {$ENDIF GDI}
  4141. fMenuObj: PObj;
  4142. {* PMenu pointer to TMenu object. Freed automatically with entire
  4143. chain of menu objects attached to a control (or form). }
  4144. {$IFDEF _X_}
  4145. {$IFDEF GTK}
  4146. //fMenuBar: PGtkWidget;
  4147. {$ENDIF GTK}
  4148. {$ENDIF _X_}
  4149. {$IFDEF GDI}
  4150. {$IFNDEF NEW_MENU_ACCELL}
  4151. fAccelTable: HAccel;
  4152. procedure DoDestroyAccelTable;
  4153. {$ENDIF}
  4154. {$ENDIF GDI}
  4155. protected
  4156. {$IFDEF GDI}
  4157. {* Handle of accelerator table created by menu(s). }
  4158. fImageList: PImageList;
  4159. {* Pointer to first private image list. Control can own several image,
  4160. lists, linked to a chain of image list objects. All these image lists
  4161. are released automatically, when control is destroyed. }
  4162. fCtlImageListSml: PImageList;
  4163. {* ImageList object (with small icons 16x16) to use with a control (e.g.,
  4164. with ListView control).
  4165. If not set, but control has a list of image list objects, last added
  4166. image list with small icons is used automatically. }
  4167. fCtlImageListNormal: PImageList;
  4168. {* ImageList object (with big icons 32x32) to use with a control.
  4169. If not set, last added image list with big icons is used. }
  4170. fCtlImgListState: PImageList;
  4171. {* ImageList object to use as a state image list (for ListView control). }
  4172. {$ENDIF GDI}
  4173. fIsApplet: Boolean;
  4174. {* True, if the object represent application taskbar button. }
  4175. fIsForm: Boolean;
  4176. {* True, if the object is form. }
  4177. fIsButton: Boolean;
  4178. {$IFDEF GDI}
  4179. fSizeGrip: Boolean;
  4180. {$ENDIF GDI}
  4181. fIsMDIChild: Boolean;
  4182. {* TRUE, if the object is MDI child form. }
  4183. fIsControl: Boolean;
  4184. {* True, if it is a control on form. }
  4185. fIsStaticControl: Byte;
  4186. {* True, if it is static control with a caption. (To prevent flickering
  4187. it in DoubleBuffered mode. }
  4188. {$IFDEF GDI}
  4189. fIsCommonControl: Boolean;
  4190. {* True, if it is common control. }
  4191. {$ENDIF GDI}
  4192. fChangedPosSz: Byte;
  4193. {* Flags of changing left (1), top (2), width (4) or height (8) }
  4194. {$IFDEF GDI}
  4195. fCannotDoubleBuf: Boolean;
  4196. {* True, if cannot set DoubleBuffered to True (RichEdit). }
  4197. fUpdRgn: HRgn;
  4198. fCollectUpdRgn: HRGN;
  4199. fEraseUpdRgn: Boolean;
  4200. fPaintDC: HDC;
  4201. {$ENDIF GDI}
  4202. fLookTabKeys: TTabKeys;
  4203. {$IFDEF GDI}
  4204. fNotUpdate: Boolean;
  4205. fColumn: Integer;
  4206. FSupressTab: Boolean;
  4207. fUpdateCount: Integer;
  4208. fPaintLater: Boolean;
  4209. fOnLeave: TOnEvent;
  4210. fEditing: Boolean;
  4211. fAutoPopupMenu: PObj;
  4212. fHelpContext: Integer;
  4213. {$IFDEF USE_GRAPHCTLS}
  4214. fDoInvalidate: procedure of object;
  4215. {$ENDIF}
  4216. {$IFDEF GTK}
  4217. fDeltaX, fDeltaY: Integer;
  4218. {$ENDIF GTK}
  4219. // Order of following fields is important:
  4220. //_______________________________________________________________________________________________
  4221. fPass2DefProc: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  4222. fOnDynHandlers: TWindowFunc; //
  4223. fWndProcKeybd: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; //
  4224. fControlClick: procedure( Sender : PObj ); //
  4225. {$ENDIF GDI}
  4226. fAutoSize: procedure( Self_: PObj );
  4227. fControlClassName: PKOLChar; //
  4228. {$IFDEF GDI}
  4229. fWindowed: Boolean; //
  4230. {* True, if control is windowed (or is a form). It is set to FALSE only for
  4231. graphic controls. }
  4232. // //
  4233. fCtlClsNameChg: Boolean; //
  4234. {* True, if control class name changed and memory is allocated to store it. } //
  4235. fWndProcResizeFlicks: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; //
  4236. {$ENDIF GDI}
  4237. fGotoControl: function( Self_: PControl; Key: DWORD; CheckOnly: Boolean ): Boolean; //
  4238. {$IFDEF GDI}
  4239. fCtl3Dchild: Boolean; //
  4240. fCtl3D: Boolean; //
  4241. {$ENDIF GDI}
  4242. fTextColor: TColor; //
  4243. fColor: TColor; //
  4244. {* Color of text. Used instead of fFont.Color internally to //
  4245. avoid usage of Font object if user is not accessing and changing it. } //
  4246. fFont: PGraphicTool; //
  4247. fBrush: PGraphicTool; //
  4248. fCanvas: PCanvas;
  4249. {* Color of control background. } //
  4250. fMargin: Integer; //
  4251. fBoundsRect: TRect; //
  4252. fClientTop, fClientBottom, fClientLeft, fClientRight: Integer; //
  4253. {* Store adjustment factor of ClientRect for some 'idiosincrasies' windows, //
  4254. such as Groupbox or Tabcontrol. } //
  4255. //_____________________________________________________________________________________________//
  4256. // this is the end of fiels set, which order is important
  4257. {$IFDEF GDI}
  4258. fDoubleBuffered: Boolean;
  4259. fTransparent: Boolean;
  4260. {$IFDEF GRAPHCTL_XPSTYLES}
  4261. fClassicTransparent : boolean;
  4262. {$ENDIF}
  4263. fRETransparent: Boolean;
  4264. fParentRequirePaint: boolean;
  4265. fSelfRequirePaint: boolean;
  4266. fDblExcludeRgn: HDC;
  4267. fOnMessage: TOnMessage;
  4268. fOldOnMessage: TOnMessage;
  4269. {$ENDIF GDI}
  4270. fOnClick: TOnEvent;
  4271. fClickedEvent: Integer;
  4272. {$IFDEF _X_}
  4273. procedure SetOnClick( const Value: TOnEvent );
  4274. {$ENDIF _X_}
  4275. protected
  4276. {$IFDEF GDI}
  4277. fRightClick: Boolean;
  4278. fCurrentControl: PControl;
  4279. fCreateVisible, fCreateHidden: Boolean;
  4280. fRadio1st, fRadioLast : THandle;
  4281. fDropDownProc: procedure( Sender : PObj );
  4282. fDropped: Boolean;
  4283. fCurIdxAtDrop: Integer;
  4284. fPrevWndProc: Pointer;
  4285. fClickDisabled: Byte;
  4286. fCurItem, fCurIndex: Integer;
  4287. FOnScroll: TOnScroll;
  4288. FScrollLineDist: array[ 0..1 ] of Integer;
  4289. fDefaultBtn: Boolean;
  4290. fCancelBtn: Boolean;
  4291. fDefaultBtnCtl: PControl;
  4292. fCancelBtnCtl: PControl;
  4293. fAllBtnReturnClick: Boolean;
  4294. fIgnoreDefault: Boolean;
  4295. {$ENDIF GDI}
  4296. fOnMouseDown: TOnMouse; // CAUTION!!! Order of mouse event handlers is important. ____
  4297. fOnMouseUp: TOnMouse; //
  4298. fOnMouseMove: TOnMouse; //
  4299. fOnMouseDblClk: TOnMouse; //
  4300. fOnMouseWheel: TOnMouse; //_____________________________________________________//
  4301. f3ButtonPress: Boolean;
  4302. {$IFDEF GDI}
  4303. fOldDefWndProc: Pointer;
  4304. fOnChange: TOnEvent;
  4305. fOnEnter: TOnEvent;
  4306. FOnLVCustomDraw: TOnLVCustomDraw;
  4307. FOnSBBeforeScroll: TOnSBBeforeScroll;
  4308. FOnSBScroll: TOnSBScroll;
  4309. protected
  4310. procedure SetOnLVCustomDraw(const Value: TOnLVCustomDraw);
  4311. public
  4312. fCommandActions: TCommandActions;
  4313. {$ENDIF GDI}
  4314. protected
  4315. {$IFDEF GDI}
  4316. fOnChar: TOnChar;
  4317. {$IFDEF SUPPORT_ONDEADCHAR}
  4318. fOnDeadChar: TOnChar;
  4319. {$ENDIF SUPPORT_ONDEADCHAR}
  4320. fOnKeyUp: TOnKey;
  4321. fOnKeyDown: TOnKey;
  4322. {$ENDIF GDI}
  4323. fOnPaint: TOnPaint;
  4324. {$IFDEF GDI}
  4325. fOnPaint2: TOnPaint;
  4326. fPaintMsg: TMsg;
  4327. fOnPrepaint: TOnPaint;
  4328. fOnPostPaint: TOnPaint;
  4329. fPaintProc: TPaintProc;
  4330. {$ENDIF GDI}
  4331. FMaxWidth: Integer;
  4332. FMinWidth: Integer;
  4333. FMaxHeight: Integer;
  4334. FMinHeight: Integer;
  4335. {$IFDEF GDI}
  4336. fShadowDeep: Integer;
  4337. fStatusCtl: PControl;
  4338. fStatusWnd: HWnd;
  4339. fColor1: TColor;
  4340. fColor2: TColor;
  4341. fLVColCount: Integer;
  4342. fLVOptions: TListViewOptions;
  4343. fLVStyle: TListViewStyle;
  4344. fOnEndEditLVITem: TOnEditLVItem;
  4345. fLVTextBkColor: TColor;
  4346. fLVItemHeight: Integer;
  4347. fOnDropDown: TOnEvent;
  4348. fOnCloseUp: TOnEvent;
  4349. fModalResult: Integer;
  4350. fModal: Integer;
  4351. fModalForm: PControl;
  4352. {$ENDIF GDI}
  4353. fAlign: TControlAlign;
  4354. fAligning:TAlignings;
  4355. fNotUseAlign: Boolean;
  4356. {$IFDEF GDI}
  4357. fDragCallback: TOnDrag;
  4358. fDragging, fInDoDrag: Boolean;
  4359. fDragStartPos: TPoint;
  4360. fMouseStartPos: TPoint;
  4361. fSplitStartPos: TPoint;
  4362. fSplitStartPos2: TPoint;
  4363. fSplitStartSize: Integer;
  4364. fSplitMinSize1, fSplitMinSize2: Integer;
  4365. fOnSplit: TOnSplit;
  4366. fSecondControl: PControl;
  4367. fOnSelChange: TOnEvent;
  4368. {$IFNDEF NOT_USE_RICHEDIT}
  4369. fRECharFormatRec: TCharFormat2;
  4370. fREError: Integer;
  4371. fREStream: PStream;
  4372. fREStrLoadLen: DWORD;
  4373. fREParaFmtRec: TParaFormat2;
  4374. {$ENDIF NOT_USE_RICHEDIT}
  4375. FOnResize: TOnEvent;
  4376. fOnProgress: TOnEvent;
  4377. fCharFmtDeltaSz: Integer;
  4378. fParaFmtDeltaSz: Integer;
  4379. fREOvr: Boolean;
  4380. fReOvrDisable: Boolean;
  4381. fOnREInsModeChg: TOnEvent;
  4382. fREScrolling: Boolean;
  4383. fUpdCount: Integer;
  4384. fOnREOverURL: TOnEvent;
  4385. fOnREURLClick: TOnEvent;
  4386. fRECharArea: TRichFmtArea;
  4387. fBitBtnOptions : TBitBtnOptions;
  4388. fGlyphLayout : TGlyphLayout;
  4389. fGlyphBitmap : HBitmap;
  4390. fGlyphCount : Integer;
  4391. fGlyphWidth, fGlyphHeight: Integer;
  4392. fOnBitBtnDraw: TOnBitBtnDraw;
  4393. fFlat: Boolean;
  4394. fSizeRedraw: Boolean; {YS}
  4395. fOnMouseLeave: TOnEvent;
  4396. fOnMouseEnter: TOnEvent;
  4397. fOnTestMouseOver: TOnTestMouseOver;
  4398. fMouseInControl: Boolean;
  4399. fRepeatInterval: Integer;
  4400. fChecked: Boolean;
  4401. fPushed: Boolean;
  4402. fPrevFocusWnd: HWnd;
  4403. fOnTVBeginDrag: TOnTVBeginDrag;
  4404. fOnTVBeginEdit: TOnTVBeginEdit;
  4405. fOnTVEndEdit: TOnTVEndEdit;
  4406. fOnTVExpanded: TOnTVExpanded;
  4407. fOnTVExpanding: TOnTVExpanding;
  4408. fOnTVDelete: TOnTVDelete;
  4409. fOnDeleteLVItem: TOnDeleteLVItem;
  4410. fOnDeleteAllLVItems: TOnEvent;
  4411. fOnLVData: TOnLVData;
  4412. fOnCompareLVItems: TOnCompareLVItems;
  4413. fOnColumnClick: TOnLVColumnClick;
  4414. fOnDrawItem: TOnDrawItem;
  4415. fOnMeasureItem: TOnMeasureItem;
  4416. fREUrl: KOLString;
  4417. FMinimizeWnd: PControl;
  4418. FFixWidth: Integer;
  4419. FFixHeight: Integer;
  4420. FOnDropFiles: TOnDropFiles;
  4421. FOnHide: TOnEvent;
  4422. FOnShow: TOnEvent;
  4423. fOnEraseBkgnd: TOnPaint;
  4424. {$ENDIF GDI}
  4425. //----- order of following 3 events important: //
  4426. fCaption: KOLString;
  4427. fCustomData: Pointer;
  4428. {$IFDEF GDI}
  4429. fStatusTxt: PKOLChar;
  4430. //---------------------------------------------//
  4431. fCustomObj: PObj;
  4432. fOnTVSelChanging: TOnTVSelChanging;
  4433. fOnClose: TOnEventAccept;
  4434. fOnQueryEndSession: TOnEventAccept;
  4435. fCloseQueryReason: TCloseQueryReason;
  4436. fShowAction: DWORD;
  4437. //----- order of following 3 events important: //
  4438. fOnMinimize: TOnEvent; //
  4439. fOnMaximize: TOnEvent; //
  4440. fOnRestore: TOnEvent; //
  4441. //---------------------------------------------//
  4442. //fCreateParamsExt: procedure( Self_: PControl; var Params: TCreateParams );
  4443. fCreateWndExt: procedure( Sender: PControl );
  4444. fTBevents: PList; // events for TBAssignEvents
  4445. fTBBtnImgWidth: Integer; // custom toolbar bitmap width
  4446. FTBBtMinWidth: Integer;
  4447. FTBBtMaxWidth: Integer;
  4448. fGradientStyle: TGradientStyle;
  4449. fGradientLayout: TGradientLayout;
  4450. fVisibleWoParent: Boolean;
  4451. fTVRightClickSelect: Boolean;
  4452. FOnMove: TOnEvent;
  4453. FOnMoving: TOnEventMoving;
  4454. FOnLVStateChange: TOnLVStateChange;
  4455. fNotAvailable: Boolean;
  4456. FPressedMnemonic: DWORD;
  4457. FBitBtnDrawMnemonic: Boolean;
  4458. FBitBtnGetCaption: function( Self_: PControl; const S: String ): String;
  4459. FBitBtnExtDraw: procedure( Self_: PControl; DC: HDC; X, Y: Integer; const R: TRect;
  4460. const CapText, CapTxtOrig: KOLString; Color: TColor );
  4461. FTextShiftX, FTextShiftY: Integer;
  4462. fNotifyChild: procedure( Self_, Child: PControl );
  4463. fScrollChildren: procedure( Self_: PControl );
  4464. fOnHelp: TOnHelp;
  4465. FOnDTPUserString: TDTParseInputEvent;
  4466. {$ifndef wince}
  4467. fOnTBCustomDraw: TOnTBCustomDraw;
  4468. {$endif wince}
  4469. {$IFDEF USE_MHTOOLTIP}
  4470. {$DEFINE var}
  4471. {$I KOLMHToolTip.pas}
  4472. {$UNDEF var}
  4473. {$DEFINE function}
  4474. {$I KOLMHToolTip.pas}
  4475. {$UNDEF function}
  4476. {$ENDIF}
  4477. {$ENDIF GDI}
  4478. procedure Init; {-}virtual;{+}{++}(*override;*){--}
  4479. {* } //CLASSES //BCB_CLASSES
  4480. {$IFDEF GDI}
  4481. procedure InitParented( AParent: PControl ); virtual;
  4482. {* Initialization of visual object. }
  4483. {$ENDIF GDI}
  4484. {$IFDEF _X_}
  4485. {$IFDEF GTK}
  4486. procedure InitParented( AParent: PControl; widget: PGtkWidget;
  4487. need_eventbox: Boolean ); virtual;
  4488. {* Initialization of visual object. }
  4489. {$ENDIF GTK}
  4490. {$ENDIF _X_}
  4491. {$IFDEF GDI}
  4492. procedure DestroyChildren;
  4493. {* Destroys children. Is called in destructor, and can be
  4494. called in descending classes as earlier as needed to
  4495. prevent problems of too late destroying of visuals.
  4496. |<br>
  4497. Note: since v 2.40, used only for case when a symbol NOT_USE_AUTOFREE4CONTROLS
  4498. is defined, otherwise all children are destroyed using common mechanism of
  4499. Add2AutoFree. }
  4500. function GetParentWnd( NeedHandle: Boolean ): HWnd;
  4501. {* Returns handle of parent window. }
  4502. function GetParentWindow: HWnd;
  4503. {* }
  4504. procedure SetEnabled( Value: Boolean );
  4505. {* Changes Enabled property value. Overriden here to change enabling
  4506. status of a window. }
  4507. function GetEnabled: Boolean;
  4508. {* Returns True, if Enabled. Overriden here to obtain real window
  4509. state. }
  4510. procedure SetVisible( Value: Boolean );
  4511. {* Sets Visible property value. Overriden here to change visibility
  4512. of correspondent window. }
  4513. procedure Set_Visible( Value: Boolean );
  4514. {* }
  4515. function GetVisible: Boolean;
  4516. {* Returns True, if correspondent window is Visible. Overriden
  4517. to get visibility of real window, not just value stored in object. }
  4518. function Get_Visible: Boolean;
  4519. {* Returns True, if correspondent window is Visible, for forms and applet,
  4520. or if fVisible flag is set, for controls. }
  4521. {$ENDIF GDI}
  4522. procedure SetCtlColor( Value: TColor );
  4523. {* Sets TControl's Color property value. }
  4524. procedure SetBoundsRect( const Value: TRect );
  4525. {* Sets BoudsRect property value. }
  4526. function GetBoundsRect: TRect;
  4527. {* Returns bounding rectangle. }
  4528. {$IFDEF GDI}
  4529. function GetIcon: HIcon;
  4530. {* Returns Icon property. By default, if it is not set,
  4531. returns Icon property of an Applet. }
  4532. procedure CreateSubclass( var Params: TCreateParams; ControlClassName: PKOLChar );
  4533. {* Can be used in descending classes to subclass window with given
  4534. standard Windows ControlClassName - must be called after
  4535. creating Params but before CreateWindow. Usually it is called
  4536. in overriden method CreateParams after calling of the inherited one. }
  4537. function UpdateWndStyles: PControl;
  4538. {* Updates fStyle, fExStyle, fClsStyle from window handle }
  4539. procedure SetOnChar(const Value: TOnChar);
  4540. {* }
  4541. {$IFDEF SUPPORT_ONDEADCHAR}
  4542. procedure SetOnDeadChar(const Value: TOnChar);
  4543. {* }
  4544. {$ENDIF SUPPORT_ONDEADCHAR}
  4545. procedure SetOnKeyDown(const Value: TOnKey);
  4546. {* }
  4547. procedure SetOnKeyUp(const Value: TOnKey);
  4548. {* }
  4549. {$ENDIF GDI}
  4550. procedure SetOnMouseDown(const Value: TOnMouse);
  4551. {* }
  4552. procedure SetOnMouseMove(const Value: TOnMouse);
  4553. {* }
  4554. procedure SetOnMouseUp(const Value: TOnMouse);
  4555. {* }
  4556. procedure SetOnMouseWheel(const Value: TOnMouse);
  4557. {* }
  4558. procedure SetOnMouseDblClk(const Value: TOnMouse);
  4559. {* }
  4560. {$IFDEF GDI}
  4561. procedure SetHelpContext( Value: Integer );
  4562. {* }
  4563. procedure SetOnTVDelete( const Value: TOnTVDelete );
  4564. {* }
  4565. procedure SetDefaultBtn(const Index: Integer; const Value: Boolean);
  4566. {$IFDEF F_P}
  4567. function GetDefaultBtn(const Index: Integer): Boolean;
  4568. {$ENDIF F_P}
  4569. function DefaultBtnProc( var Msg: TMsg; var Rslt: Integer ): Boolean;
  4570. {* }
  4571. procedure SetDateTime( Value: TDateTime );
  4572. function GetDateTime: TDateTime;
  4573. procedure SetDateTimeRange( Value: TDateTimeRange );
  4574. function GetDateTimeRange: TDateTimeRange;
  4575. procedure SetDateTimePickerColor( Index: TDateTimePickerColor; Value: TColor );
  4576. function GetDateTimePickerColor( Index: TDateTimePickerColor ): TColor;
  4577. procedure SetDateTimeFormat( const Value: KOLString );
  4578. function Get_SystemTime: TSystemTime;
  4579. procedure Set_SystemTime(const Value: TSystemTime);
  4580. {$ifndef wince}
  4581. procedure SetOnTBCustomDraw( const Value: TOnTBCustomDraw );
  4582. {$endif wince}
  4583. {$ENDIF GDI}
  4584. procedure DoAutoSize;
  4585. function InternalProcessMessage(AMsg: PMsg): Boolean;
  4586. public
  4587. {$IFDEF GDI}
  4588. constructor CreateParented( AParent: PControl );
  4589. {* Creates new instance of TControl object, calling InitParented }
  4590. {$ENDIF GDI}
  4591. {$IFDEF _X_}
  4592. {$IFDEF GTK}
  4593. constructor CreateParented( AParent: PControl; widget: PGtkWidget;
  4594. need_eventbox: Boolean );
  4595. {* Creates new instance of TControl object, calling InitParented }
  4596. {$ENDIF GTK}
  4597. {$ENDIF _X_}
  4598. {$IFDEF GDI}
  4599. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  4600. {* Destroyes object. First of all, destructors for all children
  4601. are called. }
  4602. function GetWindowHandle: HWnd;
  4603. {* Returns window handle. If window is not yet created,
  4604. method CreateWindow is called. }
  4605. procedure CreateChildWindows;
  4606. {* Enumerates all children recursively and calls CreateWindow for all
  4607. of these. }
  4608. {$ENDIF GDI}
  4609. property Parent: PControl read fParent write SetParent;
  4610. {* Parent of TParent object. Also must be of TParent type or derived from TParent. }
  4611. //property Tag: Integer read FTag write FTag; //--------- moved to TObj --------
  4612. {* User-defined pointer, which can contain any data or reference to
  4613. anywhere in memory (when used as a pointer).
  4614. }
  4615. function ChildIndex( Child: PControl ): Integer;
  4616. {* Returns index of given child. }
  4617. procedure MoveChild( Child: PControl; NewIdx: Integer );
  4618. {* Moves given Child into new position. }
  4619. {$IFDEF GDI}
  4620. property Enabled: Boolean read GetEnabled write SetEnabled;
  4621. {* Enabled usually used to decide if control can get keyboard focus
  4622. or been clicked by mouse. }
  4623. procedure EnableChildren( Enable, Recursive: Boolean );
  4624. {* Enables (Enable = TRUE) or disables (Enable = FALSE) all the children
  4625. of the control. If Recursive = TRUE then all the children of all the
  4626. children are enabled or disabled recursively. }
  4627. property Visible: Boolean read Get_Visible write SetVisible;
  4628. {* Obvious. }
  4629. property ToBeVisible: Boolean read GetToBeVisible;
  4630. {* Returns True, if a control is supposed to be visible when its
  4631. form is showing. Thus is, True is returned if either control
  4632. is Visible or hidden, but marked with flag fCreateHidden. }
  4633. property CreateVisible: Boolean read fCreateVisible write fCreateVisible;
  4634. {* False by default. If You want your form to be created visible and
  4635. flick due creation, set it to True. This does not affect size of
  4636. executable anyway. }
  4637. property Align: TControlAlign read FAlign write Set_Align;
  4638. {* Align style of a control. If this property is not used in your
  4639. application, there are no additional code added. Aligning of
  4640. controls is made in KOL like in VCL. To align controls when
  4641. initially create ones, use "transparent" function SetAlign
  4642. ("transparent" means that it returns @Self as a result).
  4643. |<br>
  4644. Note, that it is better not to align combobox caClient, caLeft or
  4645. caRight (better way is to place a panel with Border = 0 and
  4646. EdgeStyle = esNone, align it as desired and to place a combobox on it
  4647. aligning caTop or caBottom). Otherwise, big problems could be under
  4648. Win9x/Me, and some delay could occur under any other systems.
  4649. |<br> Do not attempt to align some kinds of controls (like combobox)
  4650. caLeft or caRight, this can cause infinite recursion. }
  4651. {$ENDIF GDI}
  4652. property BoundsRect: TRect read GetBoundsRect write SetBoundsRect;
  4653. {* Bounding rectangle of the visual. Coordinates are relative
  4654. to top left corner of parent's ClientRect, or to top left corner
  4655. of screen (for TForm). }
  4656. property Left: Integer read GetLeft write SetLeft;
  4657. {* Left horizontal position. }
  4658. property Top: Integer read GetTop write SetTop;
  4659. {* Top vertical position. }
  4660. property Width: Integer read GetWidth write SetWidth;
  4661. {* Width of TVisual object. }
  4662. property Height: Integer read GetHeight write SetHeight;
  4663. {* Height of TVisual object. }
  4664. property Position: TPoint read GetPosition write Set_Position;
  4665. {* Represents top left position of the object. See also BoundsRect. }
  4666. {$IFDEF GDI}
  4667. property MinWidth: Integer index 0
  4668. {$IFDEF F_P} read GetConstraint
  4669. {$ELSE DELPHI} read FMinWidth
  4670. {$ENDIF F_P/DELPHI} write SetConstraint;
  4671. {* Minimal width constraint. }
  4672. property MinHeight: Integer index 1
  4673. {$IFDEF F_P} read GetConstraint
  4674. {$ELSE DELPHI} read FMinHeight
  4675. {$ENDIF F_P/DELPHI} write SetConstraint;
  4676. {* Minimal height constraint. }
  4677. property MaxWidth: Integer index 2
  4678. {$IFDEF F_P} read GetConstraint
  4679. {$ELSE DELPHI} read FMaxWidth
  4680. {$ENDIF F_P/DELPHI} write SetConstraint;
  4681. {* Maximal width constraint. }
  4682. property MaxHeight: Integer index 3
  4683. {$IFDEF F_P} read GetConstraint
  4684. {$ELSE DELPHI} read FMaxHeight
  4685. {$ENDIF F_P/DELPHI} write SetConstraint;
  4686. {* Maximal height constraint. }
  4687. {$ENDIF GDI}
  4688. function ClientRect: TRect;
  4689. {* Client rectangle of TControl. Contrary to VCL, for some
  4690. classes (e.g. for graphic controls) can be relative
  4691. not to itself, but to top left corner of the parent's ClientRect
  4692. rectangle. }
  4693. {$IFDEF GDI}
  4694. property ClientWidth: Integer read GetClientWidth write SetClientWidth;
  4695. {* Obvious. Accessing this property, program forces window latent creation. }
  4696. property ClientHeight: Integer read GetClientHeight write SetClientHeight;
  4697. {* Obvious. Accessing this property, program forces window latent creation. }
  4698. function ControlRect: TRect;
  4699. {* Absolute bounding rectangle relatively to nearest
  4700. Windowed parent client rectangle (at least to a form, but usually to
  4701. a Parent).
  4702. Useful while drawing on device context, provided by such
  4703. Windowed parent. For form itself is the same as BoundsRect. }
  4704. function ControlAtPos( X, Y: Integer; IgnoreDisabled: Boolean ): PControl;
  4705. {* Searches control at the given position (relatively to top left
  4706. corner of the ClientRect). }
  4707. {$ENDIF GDI}
  4708. procedure Invalidate;
  4709. {* Invalidates rectangle, occupied by the visual (but only if Showing =
  4710. True). }
  4711. {$IFDEF GDI}
  4712. protected
  4713. {$IFDEF USE_GRAPHCTLS}
  4714. procedure InvalidateWindowed;
  4715. procedure InvalidateNonWindowed;
  4716. {$ENDIF}
  4717. public
  4718. procedure InvalidateEx;
  4719. {* Invalidates the window and all its children. }
  4720. procedure InvalidateNC( Recursive: Boolean );
  4721. {* Invalidates the window and all its children including non-client area. }
  4722. procedure Update;
  4723. {* Updates control's window and calls Update for all child controls. }
  4724. procedure BeginUpdate;
  4725. {* |<#treeview>
  4726. |<#listview>
  4727. |<#richedit>
  4728. |<#memo>
  4729. |<#listbox>
  4730. Call this method to stop visual updates of the control until correspondent
  4731. EndUpdate called (pairs BeginUpdate - EndUpdate can be nested). }
  4732. procedure EndUpdate;
  4733. {* See BeginUpdate. }
  4734. property Windowed: Boolean read fWindowed write fWindowed;
  4735. {* Constantly returns True, if object is windowed (i.e. owns
  4736. correspondent window handle). Otherwise, returns False.
  4737. |<br>
  4738. By now, all the controls are windowed (there are no controls in KOL, which are
  4739. emulating window, acually belonging to Parent - like TGraphicControl
  4740. in VCL).
  4741. |<br>
  4742. Writing of this property provided only for internal purposes,
  4743. do not change it directly unless you understand well what you do. }
  4744. function HandleAllocated: Boolean;
  4745. {* Returns True, if window handle is allocated. Has no sense for
  4746. non-Windowed objects (but now, the KOL has no non-Windowed controls). }
  4747. property MDIClient: PControl read fMDIClient;
  4748. {* For MDI forms only: returns MDI client window control, containng all MDI
  4749. children. Use this window to send specific messages to rule MDI children. }
  4750. {$ENDIF GDI}
  4751. property ChildCount: Integer read GetChildCount;//GetChildCountWOMembers;
  4752. {* Returns number of commonly accessed child objects (without
  4753. MembersCount). }
  4754. property Children[ Idx: Integer ]: PControl read GetMembers;
  4755. {* Child items of TVisual object. Property is reintroduced here
  4756. to separate access to always visible Children[] from restricted
  4757. a bit Members[]. }
  4758. {$IFDEF GDI}
  4759. property MembersCount: Integer read FMembersCount;
  4760. {* Returns number of "internal" child objects, which are
  4761. not accessible through common Children[] property. }
  4762. property Members[ Idx: Integer ]: PControl read GetMembers;
  4763. {* Members and children array of the object (first from 0 to
  4764. MembersCount-1 are Members[], and Children[] are followed by
  4765. them. Usually You do not need to use this list. Use instead
  4766. Children[0..ChildCount] property, Members[] is intended for
  4767. internal needs of XCL (and in KOL by now Members and Children
  4768. actually are the same properties). }
  4769. procedure PaintBackground( DC: HDC; Rect: PRect );
  4770. {* Is called to paint background in given rectangle. This
  4771. method is filling clipped area of the Rect rectangle with
  4772. Color, but only if global event Global_OnPaintBkgnd is
  4773. not assigned. If assigned, this one is called instead here.
  4774. |<br>&nbsp;&nbsp;&nbsp;
  4775. This method made public, so it can be called directly to
  4776. fill some device context's rectangle. But remember, that
  4777. independantly of Rect, top left corner of background piece
  4778. will be located so, if drawing is occure into ControlRect
  4779. rectangle. }
  4780. property WindowedParent: PControl read fParent;
  4781. {* Returns nearest windowed parent, the same as Parent. }
  4782. {$ENDIF GDI}
  4783. function ParentForm: PControl;
  4784. {* |<#form>
  4785. Returns parent form for a control (of @Self for form itself. }
  4786. {$IFDEF GDI}
  4787. property ActiveControl: PControl read fCurrentControl write fCurrentControl;
  4788. {* }
  4789. function Client2Screen( const P: TPoint ): TPoint;
  4790. {* Converts the client coordinates of a specified point to screen coordinates. }
  4791. function Screen2Client( const P: TPoint ): TPoint;
  4792. {* Converts screen coordinates of a specified point to client coordinates. }
  4793. function CreateWindow: Boolean; virtual;
  4794. {* |<#form>
  4795. Creates correspondent window object. Returns True if success (if
  4796. window is already created, False is returned). If applied to a form,
  4797. all child controls also allocates handles that time.
  4798. |<br>&nbsp;&nbsp;&nbsp;
  4799. Call this method to ensure, that a hanle is allocated for a form,
  4800. an application button or a control. (It is not necessary to do so in
  4801. the most cases, even if You plan to work with control's handle directly.
  4802. But immediately after creating the object, if You want to pass its
  4803. handle to API function, this can be helpful). }
  4804. {$ENDIF GDI}
  4805. {$IFDEF _X_}
  4806. procedure VisualizyWindow; // for _X_, makes actually visible a window and
  4807. // all its subwindows recursively, if they are having Visible = TRUE
  4808. {$ENDIF _X_}
  4809. {$IFDEF GDI}
  4810. procedure Close;
  4811. {* |<#appbutton>
  4812. |<#form>
  4813. Closes window. If a window is the main form, this closes application,
  4814. terminating it. Also it is possible to call Close method for Applet
  4815. window to stop application. }
  4816. {$IFDEF USE_MHTOOLTIP}
  4817. {$DEFINE public}
  4818. {$I KOLMHToolTip.pas}
  4819. {$UNDEF public}
  4820. {$ENDIF}
  4821. property Handle: HWnd read fHandle; //GetHandle;
  4822. {* Returns descriptor of system window object. If window is not yet
  4823. created, 0 is returned. To allocate handle, call CreateWindow method. }
  4824. property ParentWindow: HWnd read GetParentWindow;
  4825. {* Returns handle of parent window (not TControl object, but system
  4826. window object handle). }
  4827. property ClsStyle: DWord read fClsStyle write SetClsStyle;
  4828. {* Window class style. Available styles are:
  4829. |<table border=0>
  4830. |&L=<tr><td valign=top><font face=Fixedsys>%1</font></td><td>
  4831. |&E=</td></tr>
  4832. |&N=<br>&nbsp;&nbsp;&nbsp;
  4833. <L CS_BYTEALIGNCLIENT> - Aligns the window's client area on the byte boundary
  4834. (in the x direction) to enhance performance during
  4835. drawing operations. <E>
  4836. <L CS_BYTEALIGNWINDOW> - Aligns a window on a byte boundary (in the x
  4837. direction). <E>
  4838. <L CS_CLASSDC> - Allocates one device context to be shared by all
  4839. windows in the class. <E>
  4840. <L CS_DBLCLKS> - Sends double-click messages to the window
  4841. procedure when the user double-clicks the mouse while the
  4842. cursor is within a window belonging to the class. <E>
  4843. <L CS_GLOBALCLASS> - Allows an application to create a window of
  4844. the class regardless of the value of the hInstance parameter.
  4845. <N> You can create a global class by creating
  4846. the window class in a dynamic-link library (DLL) and listing the
  4847. name of the DLL in the registry under specific keys. <E>
  4848. <L CS_HREDRAW> - Redraws the entire window if a movement or
  4849. size adjustment changes the width of the client area. <E>
  4850. <L CS_NOCLOSE> - Disables the Close command on the System menu. <E>
  4851. <L CS_OWNDC> - Allocates a unique device context for each window
  4852. in the class. <E>
  4853. <L CS_PARENTDC> - Sets the clipping region of the child window to
  4854. that of the parent window so that the child can draw on the parent. <E>
  4855. <L CS_SAVEBITS> - Saves, as a bitmap, the portion of the screen
  4856. image obscured by a window. Windows uses the saved bitmap to re-create
  4857. the screen image when the window is removed. <E>
  4858. <L CS_VREDRAW> - Redraws the entire window if a movement or size
  4859. adjustment changes the height of the client area. <E>
  4860. |</table> For more info, see Win32.hlp (keyword 'WndClass');
  4861. }
  4862. {$IFDEF GRAPHCTL_XPSTYLES}
  4863. property edgeStyle : TEdgeStyle read fEdgeStyle write SetEdgeStyle;
  4864. {$ENDIF}
  4865. property Style: DWord read fStyle write SetStyle;
  4866. {* Window styles. Available styles are:
  4867. |<table border=0>
  4868. <L WS_BORDER> Creates a window that has a thin-line border. <E>
  4869. <L WS_CAPTION> Creates a window that has a title bar (includes the
  4870. WS_BORDER style). <E>
  4871. <L WS_CHILD> Creates a child window. This style cannot be used with
  4872. the WS_POPUP style. <E>
  4873. <L WS_CHILDWINDOW> Same as the WS_CHILD style. <E>
  4874. <L WS_CLIPCHILDREN> Excludes the area occupied by child windows
  4875. when drawing occurs within the parent window. This style is used
  4876. when creating the parent window. <E>
  4877. <L WS_CLIPSIBLINGS> Clips child windows relative to each other;
  4878. that is, when a particular child window receives a WM_PAINT message,
  4879. the WS_CLIPSIBLINGS style clips all other overlapping child windows
  4880. out of the region of the child window to be updated. If
  4881. WS_CLIPSIBLINGS is not specified and child windows overlap, it is
  4882. possible, when drawing within the client area of a child window,
  4883. to draw within the client area of a neighboring child window. <E>
  4884. <L WS_DISABLED> Creates a window that is initially disabled. A
  4885. disabled window cannot receive input from the user. <E>
  4886. <L WS_DLGFRAME> Creates a window that has a border of a style
  4887. typically used with dialog boxes. A window with this style cannot
  4888. have a title bar. <E>
  4889. <L WS_GROUP> Specifies the first control of a group of controls.
  4890. The group consists of this first control and all controls defined
  4891. after it, up to the next control with the WS_GROUP style.
  4892. The first control in each group usually has the WS_TABSTOP
  4893. style so that the user can move from group to group. The user
  4894. can subsequently change the keyboard focus from one control in
  4895. the group to the next control in the group by using the direction
  4896. keys. <E>
  4897. <L WS_HSCROLL> Creates a window that has a horizontal scroll bar. <E>
  4898. <L WS_ICONIC> Creates a window that is initially minimized. Same as
  4899. the WS_MINIMIZE style. <E>
  4900. <L WS_MAXIMIZE> Creates a window that is initially maximized. <E>
  4901. <L WS_MAXIMIZEBOX> Creates a window that has a Maximize button.
  4902. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU
  4903. style must also be specified. <E>
  4904. <L WS_MINIMIZE> Creates a window that is initially minimized.
  4905. Same as the WS_ICONIC style. <E>
  4906. <L WS_MINIMIZEBOX> Creates a window that has a Minimize button.
  4907. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU
  4908. style must also be specified. <E>
  4909. <L WS_OVERLAPPED> Creates an overlapped window. An overlapped
  4910. window has a title bar and a border. Same as the WS_TILED style. <E>
  4911. <L WS_OVERLAPPEDWINDOW> Creates an overlapped window with the
  4912. WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX,
  4913. and WS_MAXIMIZEBOX styles. Same as the WS_TILEDWINDOW style. <E>
  4914. <L WS_POPUP> Creates a pop-up window. This style cannot be used with
  4915. the WS_CHILD style. <E>
  4916. <L WS_POPUPWINDOW> Creates a pop-up window with WS_BORDER,
  4917. WS_POPUP, and WS_SYSMENU styles. The WS_CAPTION and WS_POPUPWINDOW
  4918. styles must be combined to make the window menu visible. <E>
  4919. <L WS_SIZEBOX> Creates a window that has a sizing border. Same as the
  4920. WS_THICKFRAME style. <E>
  4921. <L WS_SYSMENU> Creates a window that has a window-menu on its title
  4922. bar. The WS_CAPTION style must also be specified. <E>
  4923. <L WS_TABSTOP> Specifies a control that can receive the keyboard focus
  4924. when the user presses the TAB key. Pressing the TAB key changes
  4925. the keyboard focus to the next control with the WS_TABSTOP style. <E>
  4926. <L WS_THICKFRAME> Creates a window that has a sizing border.
  4927. Same as the WS_SIZEBOX style. <E>
  4928. <L WS_TILED> Creates an overlapped window. An overlapped window has
  4929. a title bar and a border. Same as the WS_OVERLAPPED style. <E>
  4930. <L WS_TILEDWINDOW> Creates an overlapped window with the
  4931. WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME,
  4932. WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles. Same as the
  4933. WS_OVERLAPPEDWINDOW style. <E>
  4934. <L WS_VISIBLE> Creates a window that is initially visible. <E>
  4935. <L WS_VSCROLL> Creates a window that has a vertical scroll bar. <E>
  4936. |</table>
  4937. See also Win32.hlp (topic CreateWindow).
  4938. }
  4939. property ExStyle: DWord read fExStyle write SetExStyle;
  4940. {* Extra window styles. Available flags are following:
  4941. |<table border=0>
  4942. <L WS_EX_ACCEPTFILES> Specifies that a window created with this style
  4943. accepts drag-drop files. <E>
  4944. <L WS_EX_APPWINDOW> Forces a top-level window onto the taskbar
  4945. when the window is minimized. <E>
  4946. <L WS_EX_CLIENTEDGE> Specifies that a window has a border with a
  4947. sunken edge. <E>
  4948. <L WS_EX_CONTEXTHELP> Includes a question mark in the title bar of
  4949. the window. When the user clicks the question mark, the cursor
  4950. changes to a question mark with a pointer. If the user then clicks
  4951. a child window, the child receives a WM_HELP message. The child
  4952. window should pass the message to the parent window procedure,
  4953. which should call the WinHelp function using the HELP_WM_HELP
  4954. command. The Help application displays a pop-up window that
  4955. typically contains help for the child window.WS_EX_CONTEXTHELP
  4956. cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles. <E>
  4957. <L WS_EX_CONTROLPARENT> Allows the user to navigate among the child
  4958. windows of the window by using the TAB key. <E>
  4959. <L WS_EX_DLGMODALFRAME> Creates a window that has a double border;
  4960. the window can, optionally, be created with a title bar by
  4961. specifying the WS_CAPTION style in the dwStyle parameter. <E>
  4962. <L WS_EX_LEFT> Window has generic "left-aligned" properties. This
  4963. is the default. <E>
  4964. <L WS_EX_LEFTSCROLLBAR> If the shell language is Hebrew, Arabic, or
  4965. another language that supports reading order alignment, the
  4966. vertical scroll bar (if present) is to the left of the client
  4967. area. For other languages, the style is ignored and not treated
  4968. as an error. <E>
  4969. <L WS_EX_LTRREADING> The window text is displayed using Left to
  4970. Right reading-order properties. This is the default. <E>
  4971. <L WS_EX_MDICHILD> Creates an MDI child window. <E>
  4972. <L WS_EX_NOPARENTNOTIFY> Specifies that a child window created
  4973. with this style does not send the WM_PARENTNOTIFY message to its
  4974. parent window when it is created or destroyed. <E>
  4975. <L WS_EX_OVERLAPPEDWINDOW> Combines the WS_EX_CLIENTEDGE and
  4976. WS_EX_WINDOWEDGE styles. <E>
  4977. <L WS_EX_PALETTEWINDOW> Combines the WS_EX_WINDOWEDGE,
  4978. WS_EX_TOOLWINDOW, and WS_EX_TOPMOST styles. <E>
  4979. <L WS_EX_RIGHT> Window has generic "right-aligned" properties.
  4980. This depends on the window class. This style has an effect only
  4981. if the shell language is Hebrew, Arabic, or another language that
  4982. supports reading order alignment; otherwise, the style is
  4983. ignored and not treated as an error. <E>
  4984. <L WS_EX_RIGHTSCROLLBAR> Vertical scroll bar (if present) is to the
  4985. right of the client area. This is the default. <E>
  4986. <L WS_EX_RTLREADING> If the shell language is Hebrew, Arabic, or
  4987. another language that supports reading order alignment, the
  4988. window text is displayed using Right to Left reading-order
  4989. properties. For other languages, the style is ignored and not
  4990. treated as an error. <E>
  4991. <L WS_EX_STATICEDGE> Creates a window with a three-dimensional
  4992. border style intended to be used for items that do not accept
  4993. user input. <E>
  4994. <L WS_EX_TOOLWINDOW> Creates a tool window; that is, a window
  4995. intended to be used as a floating toolbar. A tool window has
  4996. a title bar that is shorter than a normal title bar, and the
  4997. window title is drawn using a smaller font. A tool window does
  4998. not appear in the taskbar or in the dialog that appears when
  4999. the user presses ALT+TAB. <E>
  5000. <L WS_EX_TOPMOST> Specifies that a window created with this style
  5001. should be placed above all non-topmost windows and should stay
  5002. above them, even when the window is deactivated. To add or remove
  5003. this style, use the SetWindowPos function. <E>
  5004. <L WS_EX_TRANSPARENT> Specifies that a window created with this
  5005. style is to be transparent. That is, any windows that are
  5006. beneath the window are not obscured by the window. A window
  5007. created with this style receives WM_PAINT messages only after
  5008. all sibling windows beneath it have been updated. <E>
  5009. <L WS_EX_WINDOWEDGE> Specifies that a window has a border with
  5010. a raised edge. <E>
  5011. |</table>
  5012. See also Win32.hlp (topic CreateWindowEx).
  5013. }
  5014. property Cursor: HCursor read fCursor write SetCursor;
  5015. {* Current cursor. For most of controls, sets initially to IDC_ARROW. See
  5016. also ScreenCursor. }
  5017. procedure CursorLoad( Inst: Integer; ResName: PKOLChar );
  5018. {* Loads Cursor from the resource. See also comments for Icon property. }
  5019. property Icon: HIcon read {$IFDEF SMALLEST_CODE} fIcon {$ELSE} GetIcon {$ENDIF}
  5020. write SetIcon;
  5021. {* |<#appbutton>
  5022. |<#form>
  5023. Icon. By default, icon of the Applet is used. To load icon from the
  5024. resource, use IconLoad or IconLoadCursor method - this is more correct, because
  5025. in such case a special flag is set to prevent attempts to destroy
  5026. shared icon object in the destructor of the control. }
  5027. procedure IconLoad( Inst: Integer; ResName: PKOLChar );
  5028. {* |<#appbutton>
  5029. |<#form>
  5030. See Icon property. }
  5031. procedure IconLoadCursor( Inst: Integer; ResName: PKOLChar );
  5032. {* |<#appbutton>
  5033. |<#form>
  5034. Loads Icon from the cursor resource. See also Icon property. }
  5035. property Menu: HMenu read fMenu write SetMenu;
  5036. {* Menu (or ID of control - for standard GUI controls). }
  5037. property HelpContext: Integer read fHelpContext write SetHelpContext;
  5038. {* Help context. }
  5039. function AssignHelpContext( Context: Integer ): PControl;
  5040. {* Assigns HelpContext and returns @ Self (can be used in initialization
  5041. of a control in a chain of "transparent" calls). }
  5042. procedure CallHelp( Context: Integer; CtxCtl: PControl {; CtlID: Integer} );
  5043. {* Method of a form or Applet. Call it to show help with the given context
  5044. ID. If the Context = 0, help contents is displayed. By default,
  5045. WinHelp is used. To allow using HtmlHelp, call AssignHtmlHelp global
  5046. function. When WinHelp used, HelpPath variable can be assigned directly.
  5047. If HelpPath variable is not assigned, application name
  5048. (and path) is used, with extension replaced to '.hlp'. }
  5049. property HelpPath: KOLString read GetHelpPath write SetHelpPath;
  5050. {* Property of a form or an Applet. Change it to provide custom path to
  5051. WinHelp format help file. If HtmlHelp used, call global procedure
  5052. AssignHtmlHelp instead. }
  5053. property OnHelp: TOnHelp read fOnHelp write fOnHelp;
  5054. {* An event of a form, it is called when F1 pressed or help topic requested
  5055. by any other way. To prevent showing help, nullify Sender. Set Popup to
  5056. TRUE to provide showing help in a pop-up window. It is also possible to
  5057. change Context dynamically. }
  5058. {$ENDIF GDI}
  5059. property Caption: KOLString read GetCaption write SetCaption;
  5060. {* |<#appbutton>
  5061. |<#form>
  5062. |<#button>
  5063. |<#bitbtn>
  5064. |<#label>
  5065. |<#wwlabel>
  5066. |<#3dlabel>
  5067. Caption of a window. For standard Windows buttons, labels and so on
  5068. not a caption of a window, but text of the window. }
  5069. property Text: KOLString read GetCaption write SetCaption;
  5070. {* |<#edit>
  5071. |<#memo>
  5072. The same as Caption. To make more convenient with Edit controls. For
  5073. Rich Edit control, use property RE_Text. }
  5074. {$IFDEF GDI}
  5075. property SelStart: Integer read GetSelStart write SetSelStart;
  5076. {* |<#edit>
  5077. |<#memo>
  5078. |<#richedit>
  5079. Start of selection (editbox - character position). }
  5080. property SelLength: Integer read GetSelLength write SetSelLength;
  5081. {* |<#edit>
  5082. |<#memo>
  5083. |<#richedit>
  5084. |<#listbox>
  5085. |<#listview>
  5086. Length of selection (editbox - number of characters selected, multiselect
  5087. listbox or listview - number of items selected).
  5088. |<br>
  5089. Note, that for combobox and single-select listbox it always returns 0
  5090. (though for single-select listview, returns 1, if there is an item
  5091. selected).
  5092. |<br>
  5093. It is possible to set SelLength only for memo and richedit controls. }
  5094. property Selection: KOLString read GetSelection write SetSelection;
  5095. {* |<#edit>
  5096. |<#memo>
  5097. |<#richedit>
  5098. Selected text (editbox, richedit) as string. Can be useful to replace
  5099. selection. For rich edit, use RE_Text[ reText, TRUE ], if you want to
  5100. read correctly characters from another locale then ANSI only. }
  5101. procedure SelectAll;
  5102. {* |<#edit>
  5103. |<#memo>
  5104. |<#richedit>
  5105. Makes all the text in editbox or RichEdit, or all items in listbox
  5106. selected. }
  5107. procedure ReplaceSelection( const Value: KOLString; aCanUndo: Boolean );
  5108. {* |<#edit>
  5109. |<#memo>
  5110. |<#richedit>
  5111. Replaces selection (in edit, RichEdit). Unlike assigning new value
  5112. to Selection property, it is possible to specify, if operation can
  5113. be undone. }
  5114. procedure DeleteLines( FromLine, ToLine: Integer );
  5115. {* |<#edit>
  5116. |<#memo>
  5117. |<#richedit>
  5118. Deletes lines from FromLine to ToLine (inclusively, i.e. 0 to 0 deletes
  5119. one line with index 0). Current selection is restored as possible. }
  5120. property CurIndex: Integer read GetCurIndex write SetCurIndex;
  5121. {* |<#listbox>
  5122. |<#combo>
  5123. |<#toolbar>
  5124. Index of current item (for listbox, combobox) or button index pressed
  5125. or dropped down (for toolbar button, and only in appropriate event
  5126. handler call).
  5127. |<br>
  5128. You cannot use it to set or remove a selection in a multiple-selection
  5129. list box, so you should set option loNoExtendSel to true.
  5130. |<br>
  5131. In OnClick event handler, CurIndex has not yet changed for listbox or combobox.
  5132. Use OnSelChange to respond to selection changes. }
  5133. property Count: Integer read GetItemsCount write SetItemsCount;
  5134. {* |<#listbox>
  5135. |<#combo>
  5136. |<#listview>
  5137. |<#treeview>
  5138. |<#edit>
  5139. |<#memo>
  5140. |<#richedit>
  5141. |<#toolbar>
  5142. Number of items (listbox, combobox, listview) or lines (multiline
  5143. editbox, richedit control) or buttons (toolbar). It is possible to
  5144. assign a value to this property only for listbox control with loNoData
  5145. style and for list view control with lvoOwnerData style (virtual list
  5146. box and list view). }
  5147. property Items[ Idx: Integer ]: KOLString read GetItems write SetItems;
  5148. {* |<#edit>
  5149. |<#listbox>
  5150. |<#combo>
  5151. |<#memo>
  5152. |<#richedit>
  5153. Obvious. Used with editboxes, listbox, combobox. With list view, use
  5154. property LVItems instead. }
  5155. function Item2Pos( ItemIdx: Integer ): DWORD;
  5156. {* |<#edit>
  5157. |<#memo>
  5158. Only for edit controls: converts line index to character position. }
  5159. function Pos2Item( Pos: Integer ): DWORD;
  5160. {* |<#edit>
  5161. |<#memo>
  5162. Only for edit controls: converts character position to line index. }
  5163. function SavePosition: TEditPositions;
  5164. {* |<#edit>
  5165. |<#memo>
  5166. Only for edit controls: saves current editor selection and scroll
  5167. positions. To restore position, use RestorePosition with a structure,
  5168. containing saved position as a parameter. }
  5169. procedure RestorePosition( const p: TEditPositions );
  5170. {* |<#edit>
  5171. |<#memo>
  5172. Call RestorePosition with a structure, containing saved position
  5173. as a parameter (this structure filled in in SavePosition method).
  5174. If you set RestoreScroll to FALSE, only selection is restored,
  5175. without scroll position. }
  5176. procedure UpdatePosition( var p: TEditPositions; FromPos,
  5177. CountInsertDelChars, CountInsertDelLines: Integer );
  5178. {* |<#edit>
  5179. |<#memo>
  5180. If you called SavePosition and then make some changes in the edit control,
  5181. calling RestorePosition will fail if chages are affecting selection size.
  5182. The problem can be solved updating saved position info using this method.
  5183. Pass a count of inserted characters and lines as a positive number and a
  5184. count of deleted characters as a negative number here. CountInsertDelLines
  5185. is optional paramters: if you do not specify it, only selection is fixed.
  5186. }
  5187. function EditTabChar: PControl;
  5188. {* |<#edit>
  5189. |<#memo>
  5190. Call this method (once) to provide insertion of tab character (code #9)
  5191. when tab key is pressed on keyboard. }
  5192. function IndexOf( const S: KOLString ): Integer;
  5193. {* |<#listbox>
  5194. |<#combobox>
  5195. |<#tabcontrol>
  5196. Works for the most of control types, though some of those
  5197. have its own methods to search given item. If a control is not
  5198. list box or combobox, item is finding by enumerating all
  5199. the Items one by one. See also SearchFor method. }
  5200. function SearchFor( const S: KOLString; StartAfter: Integer; Partial: Boolean ): Integer;
  5201. {* |<#listbox>
  5202. |<#combobox>
  5203. |<#tabcontrol>
  5204. Works for the most of control types, though some of those
  5205. have its own methods to search given item. If a control is not
  5206. list box or combobox, item is finding by enumerating all
  5207. the Items one by one. See also IndexOf method. }
  5208. property ItemSelected[ ItemIdx: Integer ]: Boolean read GetItemSelected write SetItemSelected;
  5209. {* |<#edit>
  5210. |<#memo>
  5211. |<#listbox>
  5212. |<#combo>
  5213. |<#listview>
  5214. Returns True, if a line (in editbox) or an item (in listbox, combobox,
  5215. listview) is selected.
  5216. Can be set only for listboxes. For listboxes, which are not multiselect, and
  5217. for combo lists, it is possible only to set to True, to change selection. }
  5218. property ItemData[ Idx: Integer ]: DWORD read GetItemData write SetItemData;
  5219. {* |<#listbox>
  5220. |<#combo>
  5221. Access to user-defined data, associated with the item of a list box and
  5222. combo box. }
  5223. property OnDropDown: TOnEvent read fOnDropDown write fOnDropDown;
  5224. {* |<#combo>
  5225. |<#toolbar>
  5226. Is called when combobox is dropped down (or drop-down button of
  5227. toolbar is pressed - see also OnTBDropDown). }
  5228. property OnCloseUp: TOnEvent read fOnCloseUp write fOnCloseUp;
  5229. {* |<#combo>
  5230. Is called when combobox is closed up. When drop down list is closed
  5231. because user pressed "Escape" key, previous selection is restored.
  5232. To test if it is so, call GetKeyState( VK_ESCAPE ) and check, if
  5233. negative value is returned (i.e. Escape key is pressed when event
  5234. handler is calling). }
  5235. property DroppedWidth: Integer read FDroppedWidth write SetDroppedWidth;
  5236. {* |<#combo>
  5237. Allows to change width of dropped down items list for combobox (only!)
  5238. control. }
  5239. property DroppedDown: Boolean read fDropped write SetDroppedDown;
  5240. {* |<#combo>
  5241. Dropped down state for combo box. Set it to TRUE or FALSE to change
  5242. dropped down state. }
  5243. procedure AddDirList( const Filemask: KOLString; Attrs: DWORD );
  5244. {* |<#listbox>
  5245. |<#combo>
  5246. Can be used only with listbox and combobox - to add directory list items,
  5247. filtered by given Filemask (can contain wildcards) and Attrs. Following
  5248. flags can be combined in Attrs:
  5249. |<table border=0>
  5250. |&L=<tr><td>%1</td><td>
  5251. <L DDL_ARCHIVE> Include archived files. <E>
  5252. <L DDL_DIRECTORY> Includes subdirectories. Subdirectory names are
  5253. enclosed in square brackets ([ ]). <E>
  5254. <L DDL_DRIVES> Includes drives. Drives are listed in the form [-x-],
  5255. where x is the drive letter. <E>
  5256. <L DDL_EXCLUSIVE> Includes only files with the specified attributes.
  5257. By default, read-write files are listed even if DDL_READWRITE is
  5258. not specified. Also, this flag needed to list directories only,
  5259. etc. <E>
  5260. <L DDL_HIDDEN> Includes hidden files. <E>
  5261. <L DDL_READONLY> Includes read-only files. <E>
  5262. <L DDL_READWRITE> Includes read-write files with no additional
  5263. attributes. <E>
  5264. <L DDL_SYSTEM> Includes system files. <E>
  5265. </table>
  5266. If the listbox is sorted, directory items will be sorted (alpabetically). }
  5267. property OnBitBtnDraw: TOnBitBtnDraw read fOnBitBtnDraw write fOnBitBtnDraw;
  5268. {* |<#bitbtn>
  5269. Special event for BitBtn. Using it, it is possible to provide
  5270. additional effects, such as highlighting button text (by changing
  5271. its Font and other properties). If the handler returns True, it is
  5272. supposed that it made all drawing and there are no further drawing
  5273. occure. }
  5274. property BitBtnDrawMnemonic: Boolean read FBitBtnDrawMnemonic write SetBitBtnDrawMnemonic;
  5275. {* |<#bitbtn>
  5276. Set this property to TRUE to provide correct drawing of bit btn control
  5277. caption with '&' characters (to remove such characters, and underline
  5278. follow ones). }
  5279. property TextShiftX: Integer read fTextShiftX write fTextShiftX;
  5280. {* |<#bitbtn>
  5281. Horizontal shift for bitbtn text when the bitbtn is pressed. }
  5282. property TextShiftY: Integer read fTextShiftY write fTextShiftY;
  5283. {* |<#bitbtn>
  5284. Vertical shift for bitbtn text when the bitbtn is pressed. }
  5285. property BitBtnImgIdx: Integer read GetBitBtnImgIdx write SetBitBtnImgIdx;
  5286. {* |<#bitbtn>
  5287. BitBtn image index for the first image in list view, used as bitbtn
  5288. image. It is used only in case when BitBtn is created with bboImageList
  5289. option. }
  5290. property BitBtnImgList: THandle read GetBitBtnImageList write SetBitBtnImageList;
  5291. {* |<#bitbtn>
  5292. BitBtn Image list. Assign image list handle to change it. }
  5293. function SetButtonIcon( aIcon: HIcon ): PControl;
  5294. {* |<#button>
  5295. Sets up button icon image and changes its styles. Returns button itself. }
  5296. function SetButtonBitmap( aBmp: HBitmap ): PControl;
  5297. {* |<#button>
  5298. Sets up button icon image and changes its styles. Returns button itself. }
  5299. property OnMeasureItem: TOnMeasureItem read fOnMeasureItem write SetOnMeasureItem;
  5300. {* |<#combo>
  5301. |<#listbox>
  5302. |<#listview>
  5303. This event is called for owner-drawn controls, such as list box, combo box,
  5304. list view with appropriate owner-drawn style. For fixed item height controls
  5305. (list box with loOwnerDrawFixed style, combobox with coOwnerDrawFixed and
  5306. list view with lvoOwnerDrawFixed option) this event is called once. For
  5307. list box with loOwnerDrawVariable style and for combobox with coOwnerDrawVariable
  5308. style this event is called for every item. }
  5309. property DefaultBtn: Boolean index 13
  5310. {$IFDEF F_P} read GetDefaultBtn
  5311. {$ELSE DELPHI} read fDefaultBtn
  5312. {$ENDIF F_P/DELPHI} write SetDefaultBtn;
  5313. {* |<#button>
  5314. |<#bitbtn>
  5315. Set this property to true to make control clicked when ENTER key is pressed.
  5316. This property uses OnMessage event of the parent form, storing it into
  5317. fOldOnMessage field and calling in chain. So, assign default button
  5318. after setting OnMessage event for the form. }
  5319. property CancelBtn: Boolean index 27
  5320. {$IFDEF F_P} read GetDefaultBtn
  5321. {$ELSE DELPHI} read fCancelBtn
  5322. {$ENDIF F_P/DELPHI} write SetDefaultBtn;
  5323. {* |<#button>
  5324. |<#bitbtn>
  5325. Set this property to true to make control clicked when escape key is pressed.
  5326. This property uses OnMessage event of the parent form, storing it into
  5327. fOldOnMessage field and calling in chain. So, assign cancel button
  5328. after setting OnMessage event for the form. }
  5329. function AllBtnReturnClick: PControl;
  5330. {* Call this method for a form or any its control to provide clicking
  5331. a focused button when ENTER pressed. By default, a button can be clicked
  5332. only by SPACE key from the keyboard, or by mouse. }
  5333. property IgnoreDefault: Boolean read fIgnoreDefault write fIgnoreDefault;
  5334. {* Change this property to TRUE to ignore default button reaction on
  5335. press ENTER key when a focus is grabbed of the control. Default
  5336. value is different for different controls. By default, DefaultBtn
  5337. ignored in memo, richedit (even if read-only). }
  5338. {$ENDIF GDI}
  5339. property Color: TColor read fColor write SetCtlColor;
  5340. {* Property Color is one of the most common for all visual
  5341. elements (like form, control etc.) Please note, that standard GUI button
  5342. can not change its color and the most characteristics of the Font. Also,
  5343. standard button can not become Transparent. Use bitbtn for such purposes.
  5344. Also, changing Color property for some kinds of control has no effect (rich edit,
  5345. list view, tree view, etc.). To solve this, use native (for such controls)
  5346. color property, or call Perform method with appropriate message to set the
  5347. background color. }
  5348. property Font: PGraphicTool read GetFont;
  5349. {* If the Font property is not accessed, correspondent TGraphicTool object
  5350. is not created and its methods are not included into executable. Leaving
  5351. properties Font and Brush untouched can economy executable size a lot. }
  5352. {$IFDEF GDI}
  5353. property Brush: PGraphicTool read GetBrush;
  5354. {* If not accessed, correspondent TGraphicTool object is not created
  5355. and its methods are not referenced. See also note on Font property. }
  5356. property Ctl3D: Boolean read fCtl3D write SetCtl3D;
  5357. {* Inheritable from parent controls to child ones. }
  5358. procedure Show;
  5359. {* |<#appbutton>
  5360. |<#form>
  5361. Makes control visible and activates it. }
  5362. function ShowModal: Integer;
  5363. {* |<#form>
  5364. Can be used only with a forms to show it modal. See also global function
  5365. ShowMsgModal.
  5366. |<br>
  5367. To use a form as a modal, it is possible to make it either auto-created
  5368. or dynamically created. For a first case, You (may be prefer to hide a
  5369. form after showing it as a modal:
  5370. !
  5371. ! procedure TForm1.Button1Click( Sender: PObj );
  5372. ! begin
  5373. ! Form2.Form.ShowModal;
  5374. ! Form2.Form.Hide;
  5375. ! end;
  5376. !
  5377. Another way is to create modal form just before showing it (this economies
  5378. system resources):
  5379. !
  5380. ! procedure TForm1.Button1Click( Sender: PObj );
  5381. ! begin
  5382. ! NewForm2( Form2, Applet );
  5383. ! Form2.Form.ShowModal;
  5384. ! Form2.Form.Free; // Never call Form2.Free or Form2.Form.Close
  5385. ! end; // but always Form2.Form.Free; (!)
  5386. !
  5387. In samples above, You certainly can place any wished code before and after
  5388. calling ShowModal method.
  5389. |<br>
  5390. Do not forget that if You have more than a single form in your project,
  5391. separate Applet object should be used.
  5392. |<br>
  5393. See also ShowModalEx.
  5394. }
  5395. function ShowModalParented( const AParent: PControl ): Integer;
  5396. {* by Alexander Pravdin. The same as ShowModal, but with a certain
  5397. form as a parent. }
  5398. function ShowModalEx: Integer;
  5399. {* The same as ShowModal, but all the windows of current thread are
  5400. disabled while showing form modal. This is useful if KOL form from
  5401. a DLL is used modally in non-KOL application. }
  5402. property ModalResult: Integer read fModalResult write
  5403. {$IFDEF USE_SETMODALRESULT}
  5404. SetModalResult;
  5405. {$ELSE}
  5406. fModalResult;
  5407. {$ENDIF}
  5408. {* |<#form>
  5409. Modal result. Set it to value<>0 to stop modal dialog. By agreement,
  5410. value 1 corresponds 'OK', 2 - 'Cancel'. But it is totally by decision
  5411. of yours how to interpret this value. }
  5412. property Modal: Boolean read GetModal;
  5413. {* |<#form>
  5414. TRUE, if the form is shown modal. }
  5415. property ModalForm: PControl read fModalForm write fModalForm;
  5416. {* |<#form>
  5417. |<#appbutton>
  5418. Form currently shown modal from this form or from Applet. }
  5419. procedure Hide;
  5420. {* |<#appbutton>
  5421. |<#form>
  5422. Makes control hidden. }
  5423. property OnShow: TOnEvent read FOnShow write SetOnShow;
  5424. {* Is called when a control or form is to be shown. This event is not fired
  5425. for a form, if its WindowState initially is set to wsMaximized or
  5426. wsMinimized. This behaviour is by design (the window does not receive
  5427. WM_SHOW message in such case). }
  5428. property OnHide: TOnEvent read FOnHide write SetOnHide;
  5429. {* Is called when a control or form becomes hidden. }
  5430. property WindowState: TWindowState read GetWindowState write SetWindowState;
  5431. {* |<#form>
  5432. Window state. }
  5433. {$ENDIF GDI}
  5434. property Canvas: PCanvas read GetCanvas;
  5435. {* |<#paintbox>
  5436. Placeholder for Canvas: PCanvas. But in KOL, it is possible to
  5437. create applets without canvases at all. To do so, avoid using
  5438. Canvas and use DC directly (which is passed in OnPaint event). }
  5439. {$IFDEF GDI}
  5440. function CallDefWndProc( var Msg: TMsg ): Integer;
  5441. {* Function to be called in WndProc method to redirect message handling
  5442. to default window procedure. }
  5443. function DoSetFocus: Boolean;
  5444. {* Sets focus for Enabled window. Returns True, if success. }
  5445. procedure MinimizeNormalAnimated;
  5446. {* |<#form>
  5447. Apply this method to a main form (not to another form or Applet,
  5448. even when separate Applet control is not used and main form matches it!).
  5449. This provides normal animated visual minimization for the application.
  5450. It therefore has no effect, if animation during minimize/resore is
  5451. turned off by user.
  5452. |<br>
  5453. Applying this method also provides for the main form (only for it)
  5454. correct restoring the form maximized if it was maximized while
  5455. minimizing the application. See also RestoreNormalMaximized method. }
  5456. procedure RestoreNormalMaximized;
  5457. {* |<#form>
  5458. Apply to any form for which it is important to restore it maximized
  5459. when the application was minimizing while such form was maximized.
  5460. If the method MinimizeNormalAnimated was called for the main form,
  5461. then the correct behaviour is already provided for the main form, so
  5462. in such case it is no more necessary to call also this method, but
  5463. calling it therefore is not an error. }
  5464. property OnMessage: TOnMessage read fOnMessage write fOnMessage;
  5465. {* |<#appbutton>
  5466. |<#form>
  5467. Is called for every message processed by TControl object. And for
  5468. Applet window, this event is called also for all messages, handled by
  5469. all its child windows (forms). }
  5470. {$ENDIF GDI}
  5471. function IsMainWindow: Boolean;
  5472. {* |<#appbutton>
  5473. |<#form>
  5474. Returns True, if a window is the main in application (created first
  5475. after the Applet, or matches the Applet). }
  5476. property IsApplet: Boolean read FIsApplet;
  5477. {* Returns true, if the control is created using NewApplet (or CreateApplet).
  5478. }
  5479. property IsForm: Boolean read fIsForm;
  5480. {* Returns True, if the object is form window. }
  5481. property IsMDIChild: Boolean read fIsMDIChild;
  5482. {* Returns TRUE, if the object is MDI child form. In such case, IsForm also
  5483. returns TRUE. }
  5484. property IsControl: Boolean read fIsControl;
  5485. {* Returns True, is the control is control (not form or applet). }
  5486. property IsButton: Boolean read fIsButton;
  5487. {* Returns True, if the control is button-like or containing buttons (button,
  5488. bitbtn, checkbox, radiobox, toolbar). }
  5489. {$IFDEF GDI}
  5490. function ProcessMessage: Boolean;
  5491. {* |<#appbutton>
  5492. Processes one message. See also ProcessMessages. }
  5493. procedure ProcessMessages;
  5494. {* |<#appbutton>
  5495. Processes pending messages during long cycle of calculation,
  5496. allowing to window to be repainted if needed and to respond to other
  5497. messages. But if there are no such messages, your application can be
  5498. stopped until such one appear in messages queue. To prevent such
  5499. situation, use method ProcessPendingMessages instead. }
  5500. procedure ProcessMessagesEx;
  5501. {* Version of ProcessMessages, which works always correctly, even if
  5502. the application is minimized or background. }
  5503. procedure ProcessPendingMessages;
  5504. {* |<#appbutton>
  5505. Similar to ProcessMessages, but without waiting of
  5506. message in messages queue. I.e., if there are no pending
  5507. messages, this method immediately returns control to your
  5508. code. This method is better to call during long cycle of
  5509. calculation (then ProcessMessages). }
  5510. procedure ProcessPaintMessages;
  5511. {* }
  5512. procedure WaitAndProcessMessages;
  5513. {* }
  5514. function WndProc( var Msg: TMsg ): Integer; virtual; //{$IFNDEF DEBUG_MCK} virtual; {$ENDIF}
  5515. {* Responds to all Windows messages, posted (sended) to the
  5516. window, before all other proceeding. You can override it in
  5517. derived controls, but in KOL there are several other ways
  5518. to control message flow of existing controls without deriving
  5519. another costom controls for only such purposes. See OnMessage,
  5520. AttachProc. }
  5521. property HasBorder: Boolean read GetHasBorder write SetHasBorder;
  5522. {* |<#form>
  5523. Obvious. Form-aware. }
  5524. property HasCaption: Boolean read GetHasCaption write SetHasCaption;
  5525. {* |<#form>
  5526. Obvious. Form-aware. }
  5527. property CanResize: Boolean read GetCanResize write SetCanResize;
  5528. {* |<#form>
  5529. Obvious. Form-aware. }
  5530. property StayOnTop: Boolean read GetStayOnTop write SetStayOnTop;
  5531. {* |<#form>
  5532. Obvious. Form-aware, but can be applied to controls. }
  5533. property Border: Integer read fMargin write fMargin;
  5534. {* |<#form>
  5535. Distance between edges and child controls and between child
  5536. controls by default (if methods PlaceRight, PlaceDown, PlaceUnder,
  5537. ResizeParent, ResizeParentRight, ResizeParentBottom are called).
  5538. |<br>
  5539. Originally was named Margin, now I recommend to use the name 'Border' to
  5540. avoid confusion with MarginTop, MarginBottom, MarginLeft and
  5541. MarginRight properties.
  5542. |<br>
  5543. Initial value is always 2. Border property is used in realigning
  5544. child controls (when its Align property is not caNone), and value
  5545. of this property determines size of borders between edges of children
  5546. and its parent and between aligned controls too.
  5547. |<br>
  5548. See also properties MarginLeft, MarginRight, MarginTop, MarginBottom. }
  5549. function SetBorder( Value: Integer ): PControl;
  5550. {* Assigns new Border value, and returns @ Self. }
  5551. property Margin: Integer read fMargin write fMargin;
  5552. {* |<#form>
  5553. Old name for property Border. }
  5554. property MarginTop: Integer index 1
  5555. {$IFDEF F_P} read GetClientMargin
  5556. {$ELSE DELPHI} read fClientTop
  5557. {$ENDIF F_P/DELPHI} write SetClientMargin;
  5558. {* Additional distance between true window client top and logical top of
  5559. client rectangle. This value is added to Top of rectangle, returning
  5560. by property ClientRect. Together with other margins and property Border,
  5561. this property allows to change view of form for case, that Align property
  5562. is used to align controls on parent (it is possible to provide some
  5563. distance from child controls to its parent, and between child controls.
  5564. |<br>
  5565. Originally this property was introduced to compensate incorrect
  5566. ClientRect property, calculated for some types of controls.
  5567. |<br>
  5568. See also properties Border, MarginBottom, MarginLeft, MarginRight. }
  5569. property MarginBottom: Integer index 2
  5570. {$IFDEF F_P} read GetClientMargin
  5571. {$ELSE DELPHI} read fClientBottom
  5572. {$ENDIF F_P/DELPHI} write SetClientMargin;
  5573. {* The same as MarginTop, but a distance between true window Bottom of
  5574. client rectangle and logical bottom one. Take in attention, that this value
  5575. should be POSITIVE to make logical bottom edge located above true edge.
  5576. |<br>
  5577. See also properties Border, MarginTop, MarginLeft, MarginRight. }
  5578. property MarginLeft: Integer index 3
  5579. {$IFDEF F_P} read GetClientMargin
  5580. {$ELSE DELPHI} read fClientLeft
  5581. {$ENDIF F_P/DELPHI} write SetClientMargin;
  5582. {* The same as MarginTop, but a distance between true window Left of
  5583. client rectangle and logical left edge.
  5584. |<br>
  5585. See also properties Border, MarginTop, MarginRight, MarginBottom. }
  5586. property MarginRight: Integer index 4
  5587. {$IFDEF F_P} read GetClientMargin
  5588. {$ELSE DELPHI} read fClientRight
  5589. {$ENDIF F_P/DELPHI} write SetClientMargin;
  5590. {* The same as MarginLeft, but a distance between true window Right of
  5591. client rectangle and logical bottom one. Take in attention, that this value
  5592. should be POSITIVE to make logical right edge located left of true edge.
  5593. |<br>
  5594. See also properties Border, MarginTop, MarginLeft, MarginBottom. }
  5595. property Tabstop: Boolean read fTabstop write fTabstop;
  5596. {* True, if control can be focused using tabulating between controls.
  5597. Set it to False to make control unavailable for keyboard, but only
  5598. for mouse. }
  5599. property TabOrder: Integer read fTabOrder write SetTabOrder;
  5600. {* Order of tabulating of controls. Initially, TabOrder is equal to
  5601. creation order of controls. If TabOrder changed, TabOrder of
  5602. all controls with not less value of one is shifted up. To place
  5603. control before another, assign TabOrder of one to another.
  5604. For example:
  5605. ! Button1.TabOrder := EditBox1.TabOrder;
  5606. In code above, Button1 is placed just before EditBox1 in tabulating
  5607. order (value of TabOrder of EditBox1 is incremented, as well as
  5608. for all follow controls). }
  5609. property Focused: Boolean read GetFocused write SetFocused;
  5610. {* True, if the control is current on form (but check also, what form
  5611. itself is focused). For form it is True, if the form is active (i.e.
  5612. it is foreground and capture keyboard). Set this value to True to make
  5613. control current and focused (if applicable). }
  5614. function BringToFront: PControl;
  5615. {* Changes z-order of the control, bringing it to the topmost level. }
  5616. function SendToBack: PControl;
  5617. {* Changes z-order of the control, sending it to the back of siblings. }
  5618. {$ENDIF GDI}
  5619. property TextAlign: TTextAlign read GetTextAlign write SetTextAlign;
  5620. {* |<#label>
  5621. |<#panel>
  5622. |<#button>
  5623. |<#bitbtn>
  5624. |<#edit>
  5625. |<#memo>
  5626. Text horizontal alignment. Applicable to labels, buttons,
  5627. multi-line edit boxes, panels. }
  5628. property VerticalAlign: TVerticalAlign read GetVerticalAlign write SetVerticalAlign;
  5629. {* |<#button>
  5630. |<#label>
  5631. |<#panel>
  5632. Text vertical alignment. Applicable to buttons, labels and panels. }
  5633. {$IFDEF GDI}
  5634. property WordWrap: Boolean read fWordWrap write fWordWrap;
  5635. {* TRUE, if this is a label, created using NewWordWrapLabel. }
  5636. property ShadowDeep: Integer read FShadowDeep write SetShadowDeep;
  5637. {* |<#3dlabel>
  5638. Deep of a shadow (for label effect only, created calling NewLabelEffect). }
  5639. property CannotDoubleBuf: Boolean read fCannotDoubleBuf write fCannotDoubleBuf;
  5640. {* }
  5641. property DoubleBuffered: Boolean read fDoubleBuffered write SetDoubleBuffered;
  5642. {* Set it to true for some controls, which are flickering in repainting
  5643. (like label effect). Slow, and requires additional code. This property
  5644. is inherited by all child controls.
  5645. |<br>&nbsp;&nbsp;&nbsp;
  5646. Note: RichEdit control can not become DoubleBuffered. }
  5647. function DblBufTopParent: PControl;
  5648. {* Returns the topmost DoubleBuffered Parent control. }
  5649. property Transparent: Boolean read fTransparent write SetTransparent;
  5650. {* Set it to true to get special effects. Transparency also uses
  5651. DoubleBuffered and inherited by child controls.
  5652. |<br>&nbsp;&nbsp;&nbsp;
  5653. Please note, that some controls can not be shown properly, when
  5654. Transparent is set to True for it. If You want to make edit control
  5655. transparent (e.g., over gradient filled panel), handle its OnChanged
  5656. property and call there Invalidate to provide repainting of edit
  5657. control content. Note also, that for RichEdit control property
  5658. Transparent has no effect (as well as DoubleBuffered). But special
  5659. property RE_Transparent is designed especially for RichEdit control
  5660. (it works fine, but with great number of flicks while resizing
  5661. of a control). Another note is about Edit control. To allow editing
  5662. of transparent edit box, it is necessary to invalidate it for
  5663. every pressed character. Or, use Ed_Transparent property instead. }
  5664. property Ed_Transparent: Boolean read fTransparent write EdSetTransparent;
  5665. {* |<#edit>
  5666. |<#memo>
  5667. Use this property for editbox to make it really Transparent. Remember,
  5668. that though Transparent property is inherited by child controls from
  5669. its parent, this is not so for Ed_Transparent. So, it is necessary to
  5670. set Ed_Transparent to True for every edit control explicitly. }
  5671. property AlphaBlend: Integer read fAlphaBlend write SetAlphaBlend;
  5672. {* |<#form>
  5673. If assigned to 0..254, makes window (form or control) semi-transparent
  5674. (Win2K only).
  5675. |<br>
  5676. Depending on value assigned, it is possible to adjust transparency
  5677. level ( 0 - totally transparent, 255 - totally opaque). }
  5678. function MouseTransparent: PControl;
  5679. {* Call this method to set up mouse transparent control (which always
  5680. returns HTTRANSPARENT in responce to WM_NCHITTEST). This function
  5681. returns a pointer to a control itself. }
  5682. property LookTabKeys: TTabKeys read fLookTabKeys write fLookTabKeys;
  5683. {* Set of keys which can be used as tabulation keys in a control. }
  5684. procedure GotoControl( Key: DWORD );
  5685. {* |<#form>
  5686. Emulates tabulation key press w/o sending message to current control.
  5687. Can be applied to a form or to any its control. If VK_TAB is used,
  5688. state of shift kay is checked in: if it is pressed, tabulate is in
  5689. backward direction. }
  5690. property SubClassName: KOLString read get_ClassName write set_ClassName;
  5691. {* Name of window class - unique for every window class
  5692. in every run session of a program. }
  5693. protected
  5694. procedure SetOnClose( const AOnClose: TOnEventAccept );
  5695. procedure SetFormOnClick( const AOnClick: TOnEvent );
  5696. public
  5697. property OnClose: TOnEventAccept read fOnClose write SetOnClose;
  5698. {* |<#form>
  5699. |<#applet>
  5700. Called before closing the window. It is possible to set Accept
  5701. parameter to False to prevent closing the window. This event events
  5702. is not called when windows session is finishing (to handle this
  5703. event, handle WM_QUERYENDSESSION message, or assign OnQueryEndSession
  5704. event to another or the same event handler). }
  5705. property OnQueryEndSession: TOnEventAccept read fOnQueryEndSession write SetOnQueryEndSession;
  5706. {* |<#form>
  5707. |<#applet>
  5708. Called when WM_QUERYENDSESSION message come in. It is possible to set Accept
  5709. parameter to False to prevent closing the window (in such case session ending
  5710. is halted). It is possible to check CloseQueryReason property to find out,
  5711. why event occur.
  5712. |<br>
  5713. To provide normal application close while handling OnQueryEndSession,
  5714. call in your code PostQuitMessage( 0 ) or call method Close for the main form,
  5715. this is enough to provide all OnClose and OnDestroy handlers to be called. }
  5716. property CloseQueryReason: TCloseQueryReason read fCloseQueryReason;
  5717. {* Reason why OnClose or OnQueryEndSession called. }
  5718. property OnMinimize: TOnEvent index 0
  5719. {$IFDEF F_P} read GetOnMinMaxRestore
  5720. {$ELSE DELPHI} read fOnMinimize
  5721. {$ENDIF F_P/DELPHI} write SetOnMinMaxRestore;
  5722. {* |<#form>
  5723. Called when window is minimized. }
  5724. property OnMaximize: TOnEvent index 8
  5725. {$IFDEF F_P} read GetOnMinMaxRestore
  5726. {$ELSE DELPHI} read fOnMaximize
  5727. {$ENDIF F_P/DELPHI} write SetOnMinMaxRestore;
  5728. {* |<#form>
  5729. Called when window is maximized. }
  5730. property OnRestore: TOnEvent index 16
  5731. {$IFDEF F_P} read GetOnMinMaxRestore
  5732. {$ELSE DELPHI} read fOnRestore
  5733. {$ENDIF F_P/DELPHI} write SetOnMinMaxRestore;
  5734. {* |<#form>
  5735. Called when window is restored from minimized or maximized state. }
  5736. property UpdateRgn: HRgn read fUpdRgn;
  5737. {* A handle of update region. Valid only in OnPaint method. You
  5738. can use it to improve painting (for speed), if necessary. When
  5739. UpdateRgn is obtained in response to WM_PAINT message, value
  5740. of the property EraseBackground is used to pass it to the API
  5741. function GetUpdateRgn. If UpdateRgn = 0, this means that entire
  5742. window should be repainted. Otherwise, You (e.g.) can check
  5743. if the rectangle is in clipping region using API function
  5744. RectInRegion. }
  5745. property EraseBackground: Boolean read fEraseUpdRgn write fEraseUpdRgn;
  5746. {* This value is used to pass it to the API function GetUpdateRgn,
  5747. when UpadateRgn property is obtained first in responce to WM_PAINT
  5748. message. If EraseBackground is set to True, system is responsible
  5749. for erasing background of update region before painting. If not
  5750. (default), the entire region invalidated should be painted by your
  5751. event handler. }
  5752. {$ENDIF GDI}
  5753. property OnPaint: TOnPaint read fOnPaint write SetOnPaint;
  5754. {* Event to set to override standard control painting. Can be applied
  5755. to any control (though originally was designed only for paintbox
  5756. control). When an event handler is called, it is possible to use
  5757. UpdateRgn to examine what parts of window require painting to
  5758. improve performance of the painting operation. }
  5759. {$IFDEF GDI}
  5760. property OnPrePaint: TOnPaint read fOnPrePaint write fOnPrePaint;
  5761. {* Only for graphic controls. If you assign it, call Invalidate also. }
  5762. property OnPostPaint: TOnPaint read fOnPostPaint write fOnPostPaint;
  5763. {* Only for graphic controls. If you assign it, call Invalidate also. }
  5764. property OnEraseBkgnd: TOnPaint read fOnEraseBkgnd write SetOnEraseBkgnd;
  5765. {* This event allows to override erasing window background in response
  5766. to WM_ERASEBKGND message. This allows to add some decorations to
  5767. standard controls without overriding its painting in total.
  5768. Note: When erase background, remember, that property ClientRect can
  5769. return not true client rectangle of the window - use GetClientRect
  5770. API function instead. For example:
  5771. !
  5772. !var BkBmp: HBitmap;
  5773. !
  5774. !procedure TForm1.KOLForm1FormCreate(Sender: PObj);
  5775. !begin
  5776. ! Toolbar1.OnEraseBkgnd := DecorateToolbar;
  5777. ! BkBmp := LoadBitmap( hInstance, 'BK1' );
  5778. !end;
  5779. !
  5780. !procedure TForm1.DecorateToolbar(Sender: PControl; DC: HDC);
  5781. !var CR: TRect;
  5782. !begin
  5783. ! GetClientRect( Sender.Handle, CR );
  5784. ! Sender.Canvas.Brush.BrushBitmap := BkBmp;
  5785. ! Sender.Canvas.FillRect( CR );
  5786. !end;
  5787. !
  5788. }
  5789. {$ENDIF GDI}
  5790. property OnClick: TOnEvent read fOnClick write
  5791. {$IFDEF GDI} fOnClick
  5792. {$ELSE _X_} SetOnClick {$ENDIF _X_};
  5793. {* |<#button>
  5794. |<#checkbox>
  5795. |<#radiobox>
  5796. |<#toolbar>
  5797. Called on click at control. For buttons, checkboxes and radioboxes
  5798. is called regadless if control clicked by mouse or keyboard. For toolbar,
  5799. the same event is used for all toolbar buttons and toolbar itself.
  5800. To determine which toolbar button is clicked, check CurIndex property.
  5801. And note, that all the buttons including separator buttons are enumerated
  5802. starting from 0. Though images are stored (and prepared) only for
  5803. non-separator buttons. And to determine, if toolbar button was clicked
  5804. with right mouse button, check RightClick property.
  5805. |<br>
  5806. This event does not work on a Form, still it is fired in responce to
  5807. WM_COMMAND window message mainly rather direct to mouse down. But, if
  5808. you want to have OnClick event to be fired on a Form, use (following)
  5809. property OnFormClick to assign it. }
  5810. {$IFDEF GDI}
  5811. property OnFormClick: TOnEvent read fOnClick write SetFormOnClick;
  5812. {* |<#form>
  5813. Assign you OnClick event handler using this property, if you want it to
  5814. be fired in result of mouse click on a form surface. Use to assign the
  5815. event only for forms (to avoid doublicated firing the handler).
  5816. |<br>
  5817. Note: for a form, in case of WM_xDOUBLECLK event, this event is fired
  5818. for both clicks. So if you install both OnFormClick and OnMouseDblClk,
  5819. handlers will be called in the following sequence for each double click:
  5820. OnFormClick; OnMouseDblClk; OnFormClick. }
  5821. property RightClick: Boolean read fRightClick;
  5822. {* |<#toolbar>
  5823. |<#listview>
  5824. Use this property to determine which mouse button was clicked
  5825. (applicable to toolbar in the OnClick event handler). }
  5826. property OnEnter: TOnEvent read fOnEnter write fOnEnter;
  5827. {* Called when control receives focus. }
  5828. property OnLeave: TOnEvent read fOnLeave write fOnLeave;
  5829. {* Called when control looses focus. }
  5830. property OnChange: TOnEvent read fOnChange write fOnChange;
  5831. {* |<#edit>
  5832. |<#memo>
  5833. |<#listbox>
  5834. |<#combo>
  5835. |<#tabcontrol>
  5836. Called when edit control is changed, or selection in listbox or
  5837. current index in combobox is changed (but if OnSelChanged assigned,
  5838. the last is called for change selection). To respond to check/uncheck
  5839. checkbox or radiobox events, use OnClick instead. }
  5840. property OnSelChange: TOnEvent read fOnSelChange write fOnSelChange;
  5841. {* |<#richedit>
  5842. |<#listbox>
  5843. |<#combo>
  5844. |<#treeview>
  5845. Called for rich edit control, listbox, combobox or treeview when current selection
  5846. (range, or current item) is changed. If not assigned, but OnChange is
  5847. assigned, OnChange is called instead. }
  5848. property OnResize: TOnEvent read FOnResize write SetOnResize;
  5849. {* Called whenever control receives message WM_SIZE (thus is, if
  5850. control is resized. }
  5851. property OnMove: TOnEvent read FOnMove write SetOnMove;
  5852. {* Called whenever control receives message WM_MOVE (i.e. when control is
  5853. moved over its parent). }
  5854. property OnMoving: TOnEventMoving read FOnMoving write SetOnMoving;
  5855. {* Called whenever control receives message WM_MOVE (i.e. when control is
  5856. moved over its parent). }
  5857. property MinSizePrev: Integer read fSplitMinSize1 write fSplitMinSize1;
  5858. {* |<#splitter>
  5859. Minimal allowed (while dragging splitter) size of previous control
  5860. for splitter (see NewSplitter). }
  5861. property SplitMinSize1: Integer read fSplitMinSize1 write fSplitMinSize1;
  5862. {* The same as MinSizePrev. }
  5863. property MinSizeNext: Integer read fSplitMinSize2 write fSplitMinSize2;
  5864. {* |<#splitter>
  5865. Minimal allowed (while dragging splitter) size of the rest of parent
  5866. of splitter or of SecondControl (see NewSplitter). }
  5867. property SplitMinSize2: Integer read fSplitMinSize2 write fSplitMinSize2;
  5868. {* The same as MinSizeNext. }
  5869. property SecondControl: PControl read fSecondControl write fSecondControl;
  5870. {* |<#splitter>
  5871. Second control to check (while dragging splitter) if its size not less
  5872. than SplitMinSize2 (see NewSplitter). By default, second control is
  5873. not necessary, and needed only in rare case when SecondControl can not
  5874. be determined automatically to restrict splitter right (bottom) position. }
  5875. property OnSplit: TOnSplit read fOnSplit write fOnSplit;
  5876. {* |<#splitter>
  5877. Called when splitter control is dragging - to allow for
  5878. your event handler to decide if to accept new size of
  5879. left (top) control, and new size of the rest area of parent. }
  5880. property Dragging: Boolean read FDragging;
  5881. {* |<#splitter>
  5882. True, if splitter control is dragging now by user with left
  5883. mouse button. Also, this property can be used to detect if the control
  5884. is dragging with mouse (after calling DragStartEx method). }
  5885. procedure DragStart;
  5886. {* Call this method for a form or control to drag it with left mouse button,
  5887. when mouse left button is already down. Dragging is stopped when left mouse
  5888. button is released. See also DragStartEx, DragStopEx. }
  5889. procedure DragStartEx;
  5890. {* Call this method to start dragging the form by mouse. To stop
  5891. dragging, call DragStopEx method. (Tip: to detect mouse up event,
  5892. use OnMouseUp event of the dragging control). This method can be used
  5893. to move any control with the mouse, not only entire form. State of
  5894. mouse button is not significant. Determine dragging state of the control
  5895. checking its Dragging property. }
  5896. procedure DragStopEx;
  5897. {* Call this method to stop dragging the form (started by DragStopEx). }
  5898. procedure DragItem( OnDrag: TOnDrag );
  5899. {* Starts dragging something with mouse. During the process,
  5900. callback function OnDrag is called, which allows to control
  5901. drop target, change cursor shape, etc. }
  5902. property OnKeyDown: TOnKey read fOnKeyDown write SetOnKeyDown;
  5903. {* Obvious. }
  5904. property OnKeyUp: TOnKey read fOnKeyUp write SetOnKeyUp;
  5905. {* Obvious. }
  5906. property OnChar: TOnChar read fOnChar write SetOnChar;
  5907. {* Deprecated event, use OnKeyChar. }
  5908. property OnKeyChar: TOnChar read fOnChar write SetOnChar;
  5909. {* Obviuos. }
  5910. {$IFDEF SUPPORT_ONDEADCHAR}
  5911. property OnKeyDeadChar: TOnChar read fOnDeadChar write SetOnDeadChar;
  5912. {* Obviuos. }
  5913. {$ENDIF SUPPORT_ONDEADCHAR}
  5914. {$ENDIF GDI}
  5915. property OnMouseUp: TOnMouse read fOnMouseUp write SetOnMouseUp;
  5916. {* Obvious. }
  5917. property OnMouseDown: TOnMouse read fOnMouseDown write SetOnMouseDown;
  5918. {* Obvious. }
  5919. property OnMouseMove: TOnMouse read fOnMouseMove write SetOnMouseMove;
  5920. {* Obvious. }
  5921. property OnMouseDblClk: TOnMouse read fOnMouseDblClk write SetOnMouseDblClk;
  5922. {* Obvious. }
  5923. property ThreeButtonPress: Boolean read f3ButtonPress;
  5924. {* TRUE, if 3 button press detected. Check this flag in OnMouseDblClk event
  5925. handler. If 3rd button click is done for a short period of time after the
  5926. double click, the control receives OnMouseDblClk the second time and this
  5927. flag is set. (Applicable to the GDK and other Linux systems). }
  5928. property OnMouseWheel: TOnMouse read fOnMouseWheel write SetOnMouseWheel;
  5929. {* Mouse wheel (up or down) event. In Windows, only focused controls and
  5930. controls having scrollbars (or a scrollbar iteself) receive such
  5931. message. To get direction and amount of wheel, use typecast:
  5932. SmallInt( HiWord( Mouse.Shift ) ). Value 120 corresponds to one wheel
  5933. step (-120 - for step back). }
  5934. {$IFDEF GDI}
  5935. property OnMouseEnter: TOnEvent read fOnMouseEnter write SetOnMouseEnter;
  5936. {* Is called when mouse is entered into control. See also OnMouseLeave. }
  5937. property OnMouseLeave: TOnEvent read fOnMouseLeave write SetOnMouseLeave;
  5938. {* Is called when mouse is leaved control. If this event is assigned,
  5939. then mouse is captured on mouse enter event to handle all other
  5940. mouse events until mouse cursor leaves the control. }
  5941. property OnTestMouseOver: TOnTestMouseOver read fOnTestMouseOver write SetOnTestMouseOver;
  5942. {* |<#bitbtn>
  5943. Special event, which allows to extend OnMouseEnter / OnMouseLeave
  5944. (and also Flat property for BitBtn control). If a handler is assigned
  5945. to this event, actual testing whether mouse is in control or not,
  5946. is occuring in the handler. So, it is possible to simulate more
  5947. careful hot tracking for controls with non-rectangular shape (such
  5948. as glyphed BitBtn control). }
  5949. property MouseInControl: Boolean read fMouseInControl;
  5950. {* |<#bitbtn>
  5951. This property can return True only if OnMouseEnter / OnMouseLeave
  5952. event handlers are set for a control (or, for BitBtn, property Flat
  5953. is set to True. Otherwise, False is returned always. }
  5954. property Flat: Boolean read fFlat write SetFlat;
  5955. {* |<#bitbtn>
  5956. Set it to True for BitBtn, to provide either flat border for a button
  5957. or availability of "highlighting" (correspondent to glyph index 4).
  5958. |<br>
  5959. Note: this can work incorrectly a bit under win95 without comctl32.dll
  5960. updated. Therefore, application will launch. To enforce correct working
  5961. even under Win95, use your own timer, which event handler checks for
  5962. mouse over bitbtn control, e.g.:
  5963. ! procedure TForm1.Timer1Timer(Sender: PObj);
  5964. ! var P: TPoint;
  5965. ! begin
  5966. ! if not BitBtn1.MouseInControl then Exit;
  5967. ! GetCursorPos( P );
  5968. ! P := BitBtn1.Screen2Client( P );
  5969. ! if not PtInRect( BitBtn1.ClientRect, P ) then
  5970. ! begin
  5971. ! BitBtn1.Flat := FALSE;
  5972. ! BitBtn1.Flat := TRUE;
  5973. ! end;
  5974. ! end;
  5975. }
  5976. property RepeatInterval: Integer read fRepeatInterval write fRepeatInterval;
  5977. {* |<#bitbtn>
  5978. If this property is set to non-zero, it is interpreted (for BitBtn
  5979. only) as an interval in milliseconds between repeat button down events,
  5980. which are generated after first mouse or button click and until
  5981. button is released. Though, if the button is pressed with keyboard (with
  5982. space key), RepeatInterval value is ignored and frequency of repeatitive
  5983. clicking is determined by user keyboard settings only. }
  5984. function LikeSpeedButton: PControl;
  5985. {* |<#button>
  5986. |<#bitbtn>
  5987. Transparent method (returns control itself). Makes button not focusable. }
  5988. function Add( const S: KOLString ): Integer;
  5989. {* |<#listbox>
  5990. |<#combo>
  5991. Only for listbox and combobox. }
  5992. function Insert( Idx: Integer; const S: KOLString ): Integer;
  5993. {* |<#listbox>
  5994. |<#combo>
  5995. Only for listbox and combobox. }
  5996. procedure Delete( Idx: Integer );
  5997. {* |<#listbox>
  5998. |<#combo>
  5999. Only for listbox and combobox. }
  6000. procedure Clear;
  6001. {* Clears object content. Has different sense for different controls.
  6002. E.g., for label, editbox, button and other simple controls it
  6003. assigns empty string to Caption property. For listbox, combobox,
  6004. listview it deletes all items. For toolbar, it deletes all buttons.
  6005. Et so on. }
  6006. property Progress: Integer index ((PBM_SETPOS or $8000) shl 16) or PBM_GETPOS
  6007. read GetIntVal write SetIntVal;
  6008. {* |<#progressbar>
  6009. Only for ProgressBar. }
  6010. property MaxProgress: Integer index ((PBM_SETRANGE32 or $8000) shl 16) or PBM_GETRANGE
  6011. read GetIntVal write SetMaxProgress;
  6012. {* |<#progressbar>
  6013. Only for ProgressBar. 100 is the default value. }
  6014. property ProgressColor: TColor read fTextColor write SetProgressColor;
  6015. {* |<#progressbar>
  6016. Only for ProgressBar. }
  6017. property ProgressBkColor: TColor read fColor write SetCtlColor; //SetProgressBkColor;
  6018. {* |<#progressbar>
  6019. Obsolete. Now the same as Color. }
  6020. property StatusText[ Idx: Integer ]: PKOLChar read GetStatusText write SetStatusText;
  6021. {* |<#form>
  6022. Only for forms to set/retrieve status text to/from given status panel.
  6023. Panels are enumerated from 0 to 254, 255 is to indicate simple
  6024. status bar. Size grip in right bottom corner of status window is
  6025. displayed only if form still CanResize.
  6026. |<br>
  6027. When a status text is set first time, status bar window is created
  6028. (always aligned to bottom), and form is resizing to preset client height.
  6029. While status bar is showing, client height value is returned without
  6030. height of status bar. To remove status bar, call RemoveStatus method for
  6031. a form.
  6032. |<br>
  6033. By default, text is left-aligned within the specified part of a status
  6034. window. You can embed tab characters (#9) in the text to center or
  6035. right-align it. Text to the right of a single tab character is centered,
  6036. and text to the right of a second tab character is right-aligned.
  6037. |<br>
  6038. If You use separate status bar onto several panels, these automatically
  6039. align its widths to the same value (width divided to number of panels).
  6040. To adjust status panel widths for every panel, use property StatusPanelRightX.
  6041. }
  6042. property SimpleStatusText: PKOLChar index 255 read GetStatusText write SetStatusText;
  6043. {* |<#form>
  6044. Only for forms to set/retrive status text to/from simple status bar.
  6045. Size grip in right bottom corner of status window is displayed only
  6046. if form CanResize.
  6047. |<br>
  6048. When status text set first time, (simple) status bar window is created
  6049. (always aligned to bottom), and form is resizing to preset client height.
  6050. While status bar is showing, client height value is returned without
  6051. height of status bar. To remove status bar, call RemoveStatus method for
  6052. a form.
  6053. |<br>
  6054. By default, text is left-aligned within the specified part of a status
  6055. window. You can embed tab characters (#9) in the text to center or
  6056. right-align it. Text to the right of a single tab character is centered,
  6057. and text to the right of a second tab character is right-aligned.
  6058. }
  6059. property StatusCtl: PControl read fStatusCtl;
  6060. {* Pointer to Status bar control. To "create" child controls on
  6061. the status bar, first create it as a child of form, for instance, and
  6062. then change its property Parent, e.g.:
  6063. ! var Progress1: PControl;
  6064. ! ...
  6065. ! Progress1 := NewProgressBar( Form1 );
  6066. ! Progress1.Parent := Form1.StatusCtl;
  6067. (If you use MCK, code should be another a bit, and in this case it is
  6068. possible to create and adjust the control at design-time, and at run-time
  6069. change its parent control. E.g. (Progress1 is created at run-time here too):
  6070. ! Progress1 := NewProgressBar( Form );
  6071. ! Progress1.Parent := Form.StatusCtl;
  6072. ).
  6073. Do not forget to provide StatusCtl to be existing first (e.g. assign
  6074. one-space string to SimpleStatusText property of the form, for MCK do
  6075. so using Object Inspector).
  6076. }
  6077. property SizeGrip: Boolean read fSizeGrip write fSizeGrip;
  6078. {* Size grip for status bar. Has effect only before creating window. }
  6079. procedure RemoveStatus;
  6080. {* |<#form>
  6081. Call it to remove status bar from a form (created in result of assigning
  6082. value(s) to StatusText[], SimpleStatusText properties). When status bar is
  6083. removed, form is resized to preset client height. }
  6084. function StatusPanelCount: Integer;
  6085. {* |<#form>
  6086. Returns number of status panels defined in status bar. }
  6087. property StatusPanelRightX[ Idx: Integer ]: Integer read GetStatusPanelX write SetStatusPanelX;
  6088. {* |<#form>
  6089. Use this property to adjust status panel right edges (if the status bar is
  6090. divided onto several subpanels). If the right edge for the last panel is
  6091. set to -1 (by default) it is expanded to the right edge of a form window.
  6092. Otherwise, status bar can be shorter then form width. }
  6093. property StatusWindow: HWND read fStatusWnd;
  6094. {* |<#form>
  6095. Provided for case if You want to use API direct message sending to
  6096. status bar. }
  6097. property Color1: TColor read fColor1 write SetColor1;
  6098. {* |<#gradient>
  6099. Top line color for GradientPanel. }
  6100. property Color2: TColor read fColor2 write SetColor2;
  6101. {* |<#gradient>
  6102. |<#3Dlabel>
  6103. Bottom line color for GradientPanel, or shadow color for LabelEffect.
  6104. (If clNone, shadow color for LabelEffect is calculated as a mix bitween
  6105. TextColor and clBlack). }
  6106. property GradientStyle: TGradientStyle read FGradientStyle write SetGradientStyle;
  6107. {* |<#gradient>
  6108. Styles other then gsVertical and gsHorizontal has effect only for
  6109. gradient panel, created by NewGradientPanelEx. }
  6110. property GradientLayout: TGradientLayout read FGradientLayout write SetGradientLayout;
  6111. {* |<#gradient>
  6112. Has only effect for gradient panel, created by NewGradientPanelEx.
  6113. Ignored for styles gsVertical and gsHorizontal. }
  6114. //======== Image lists (for ListView, TreeView, ToolBar and TabControl):
  6115. property ImageListSmall: PImageList index 16 read GetImgListIdx write SetImgListIdx;
  6116. {* |<#listview>
  6117. Image list with small icons used with List View control. If not set,
  6118. last added (i.e. created with a control as an owner) image list with
  6119. small icons is used. }
  6120. property ImageListNormal: PImageList index 32 read GetImgListIdx write SetImgListIdx;
  6121. {* |<#listview>
  6122. |<#treeview>
  6123. |<#tabcontrol>
  6124. |<#bitbtn>
  6125. Image list with normal size icons used with List View control (or with
  6126. icons for BitBtn, TreeView or TabControl). If not set,
  6127. last added (i.e. created with a control as an owner) image list is used.
  6128. }
  6129. property ImageListState: PImageList index 0 read GetImgListIdx write SetImgListIdx;
  6130. {* |<#listview>
  6131. |<#treeview>
  6132. Image list used as a state images list for ListView or TreeView control. }
  6133. //========
  6134. function SetUnicode( Unicode: Boolean ): PControl;
  6135. {* |<#listview>
  6136. |<#treeview>
  6137. |<#tabcontrol>
  6138. Sets control as Unicode or not. The control itself is returned as for
  6139. other "transparent" functions. A conditional define UNICODE_CTRLS must
  6140. be added to a project to provide handling unicode messages. }
  6141. //======== TabControl-specific properties and methods:
  6142. property Pages[ Idx: Integer ]: PControl read GetPages;
  6143. {* |<#tabcontrol>
  6144. Returns controls, which can be used as parent for controls, placed on
  6145. different pages of a tab control. Use it like in follows example:
  6146. | Label1 := NewLabel( TabControl1.Pages[ 0 ], 'Label1' );
  6147. To find number of pages available, check out Count property of the tab
  6148. control. Pages are enumerated from 0 to Count - 1, as usual. }
  6149. property TC_Pages[ Idx: Integer ]: PControl read GetPages;
  6150. {* |<#tabcontrol>
  6151. The same as above. }
  6152. function TC_Insert( Idx: Integer; const TabText: KOLString; TabImgIdx: Integer ): PControl;
  6153. {* |<#tabcontrol>
  6154. Inserts new tab before given, returns correspondent page control
  6155. (which can be used as a parent for controls to place on the page). }
  6156. procedure TC_Delete( Idx: Integer );
  6157. {* |<#tabcontrol>
  6158. Removes tab from tab control, destroying all its child controls. }
  6159. {$IFNDEF OLD_ALIGN}
  6160. procedure TC_InsertControl( Idx: Integer; const TabText: KOLString; TabImgIdx: Integer; Page: PControl);
  6161. {* |<#tabcontrol>
  6162. Inserts new tab before given, but not construt this Page
  6163. (this control must be created before inserting, and may be not a Panel). }
  6164. function TC_Remove( Idx: Integer ):PControl;
  6165. {* |<#tabcontrol>
  6166. Only removes tab from tab control, and return this Page as Result. }
  6167. {$ENDIF}
  6168. property TC_Items[ Idx: Integer ]: KOLString read TCGetItemText write TCSetItemText;
  6169. {* |<#tabcontrol>
  6170. Text, displayed on tab control tabs. }
  6171. property TC_Images[ Idx: Integer ]: Integer read TCGetItemImgIDx write TCSetItemImgIdx;
  6172. {* |<#tabcontrol>
  6173. Image index for a tab in tab control. }
  6174. property TC_ItemRect[ Idx: Integer ]: TRect read TCGetItemRect;
  6175. {* |<#tabcontrol>
  6176. Item rectangle for a tab in tab control. }
  6177. procedure TC_SetPadding( cx, cy: Integer );
  6178. {* |<#tabcontrol>
  6179. Sets space padding around tab text in a tab of tab control. }
  6180. function TC_TabAtPos( x, y: Integer ): Integer;
  6181. {* |<#tabcontrol>
  6182. Returns index of tab, found at the given position (relative to
  6183. a client rectangle of tab control). If no tabs found at the
  6184. position, -1 is returned. }
  6185. function TC_DisplayRect: TRect;
  6186. {* |<#tabcontrol>
  6187. Returns rectangle, occupied by a page rather then tab. }
  6188. function TC_IndexOf(const S: KOLString): Integer;
  6189. {* |<#tabcontrol>
  6190. By Mr Brdo. Index of page by its Caption. }
  6191. function TC_SearchFor(const S: KOLString; StartAfter: Integer; Partial: Boolean): Integer;
  6192. {* |<#tabcontrol>
  6193. By Mr Brdo. Index of page by its Caption. }
  6194. //======== ListView style and options:
  6195. property LVStyle: TListViewStyle read fLVStyle write SetLVStyle;
  6196. {* |<#listview>
  6197. ListView style of view. Can be changed at run time. }
  6198. property LVOptions: TListViewOptions read fLVOptions write SetLVOptions;
  6199. {* |<#listview>
  6200. ListView options. Can be changed at run time. }
  6201. property LVTextColor: TColor index LVM_GETTEXTCOLOR
  6202. {$IFDEF F_P} read LVGetColorByIdx
  6203. {$ELSE DELPHI} read fTextColor
  6204. {$ENDIF F_P/DELPHI} write LVSetColorByIdx;
  6205. {* |<#listview>
  6206. ListView text color. Use it instead of Font.Color. }
  6207. property LVTextBkColor: TColor index LVM_GETTEXTBKCOLOR
  6208. {$IFDEF F_P} read LVGetColorByIdx
  6209. {$ELSE DELPHI} read fLVTextBkColor
  6210. {$ENDIF F_P/DELPHI} write LVSetColorByIdx;
  6211. {* |<#listview>
  6212. ListView background color for text. }
  6213. property LVBkColor: TColor read fColor write SetCtlColor; //LVSetBkColor;
  6214. {* |<#listview>
  6215. ListView background color. Use it instead of Color. }
  6216. //======== List View columns handling:
  6217. property LVColCount: Integer read fLVColCount;
  6218. {* |<#listview>
  6219. ListView (additional) column count. Value 0 means that there are
  6220. no columns (single item text / icon is used). If You want
  6221. to provide several columns, first call LVColAdd to "insert" column 0,
  6222. i.e. to provide header text for first column (with index 0).
  6223. If there are no column, nothing will be shown in lvsDetail /
  6224. lvsDetailNoHeader view style. }
  6225. procedure LVColAdd( const aText: KOLString; aalign: TTextAlign; aWidth: Integer );
  6226. {* |<#listview>
  6227. Adds new column. Pass 'width' <= 0 to provide default column width.
  6228. 'text' is a column header text. }
  6229. procedure LVColInsert( ColIdx: Integer; const aText: KOLString; aAlign: TTextAlign; aWidth: Integer );
  6230. {* |<#listview>
  6231. Inserts new column at the Idx position (1-based column index). }
  6232. procedure LVColDelete( ColIdx: Integer );
  6233. {* |<#listview>
  6234. Deletes column from List View }
  6235. property LVColWidth[ Item: Integer ]: Integer index LVM_GETCOLUMNWIDTH
  6236. read GetItemVal write SetItemVal;
  6237. {* |<#listview>
  6238. Retrieves or changes column width. For lvsList view style, the same width
  6239. is returned for all columns (ColIdx is ignored). It is possible to use
  6240. special values to assign to a property:
  6241. |<br> LVSCW_AUTOSIZE - Automatically sizes the column
  6242. |<br> LVSCW_AUTOSIZE_USEHEADER - Automatically sizes the column to fit
  6243. the header text
  6244. |<br>
  6245. To set coumn width in lvsList view mode, column index must be -1
  6246. (and Width to set must be in range 0..32767 always). }
  6247. property LVColText[ Idx: Integer ]: KOLString read GetLVColText write SetLVColText;
  6248. {* |<#listview>
  6249. Allows to get/change column header text at run time. }
  6250. property LVColAlign[ Idx: Integer ]: TTextAlign read GetLVColalign write SetLVColalign;
  6251. {* |<#listview>
  6252. Column text aligning. }
  6253. property LVColImage[ Idx: Integer ]: Integer index LVCF_IMAGE or (24 shl 16) read GetLVColEx write SetLVColEx;
  6254. {* |<#listview>
  6255. Only starting from comctrl32.dll of version 4.70 (IE4+). Allows to
  6256. set an image for list view column itself from the ImageListSmall.
  6257. }
  6258. property LVColOrder[ Idx: Integer ]: Integer index LVCF_ORDER or (28 shl 16) read GetLVColEx write SetLVColEx;
  6259. {* |<#listview>
  6260. Only starting from comctrl32.dll of version 4.70 (IE4+). Allows to
  6261. set visual order of the list view column from the ImageListSmall.
  6262. This value does not affect the index, by which the column is still
  6263. accessible in the column array.
  6264. }
  6265. //======== List View items handling:
  6266. property LVCount: Integer read GetItemsCount write SetItemsCount;
  6267. {* |<#listview>
  6268. Returns item count for ListView control. It is possible to use Count
  6269. property instead when obtaining of item count is needed only. But this this
  6270. property allows also to set actual count of list view items when a list
  6271. view is virtual. }
  6272. property LVCurItem: Integer read GetLVCurItem write SetLVCurItem;
  6273. {* |<#listview>
  6274. Returns first selected item index in a list view. See also LVNextSelected,
  6275. LVNextItem and LVFocusItem functions. }
  6276. property LVFocusItem: Integer read GetLVFocusItem;
  6277. {* |<#listview>
  6278. Returns focused item index in a list view. See also LVCurItem. }
  6279. function LVNextItem( IdxPrev: Integer; Attrs: DWORD ): Integer;
  6280. {* |<#listview>
  6281. Returns an index of the next after IdxPrev item with given attributes in
  6282. the list view. Attributes can be:
  6283. LVNI_ALL - Searches for a subsequent item by index, the default value.
  6284. |<br><br>
  6285. Searchs by physical relationship to the index of the item where the
  6286. search is to begin.
  6287. LVNI_ABOVE - Searches for an item that is above the specified item.
  6288. LVNI_BELOW - Searches for an item that is below the specified item.
  6289. LVNI_TOLEFT - Searches for an item to the left of the specified item.
  6290. LVNI_TORIGHT - Searches for an item to the right of the specified item.
  6291. |<br><br>
  6292. The state of the item to find can be specified with one or a combination
  6293. of the following values:
  6294. LVNI_CUT - The item has the LVIS_CUT state flag set.
  6295. LVNI_DROPHILITED - The item has the LVIS_DROPHILITED state flag set
  6296. LVNI_FOCUSED - The item has the LVIS_FOCUSED state flag set.
  6297. LVNI_SELECTED - The item has the LVIS_SELECTED state flag set.}
  6298. function LVNextSelected( IdxPrev: Integer ): Integer;
  6299. {* |<#listview>
  6300. Returns an index of next (after IdxPrev) selected item in a list view. }
  6301. function LVAdd( const aText: KOLString; ImgIdx: Integer; State: TListViewItemState;
  6302. StateImgIdx, OverlayImgIdx: Integer; Data: DWORD ): Integer;
  6303. {* |<#listview>
  6304. Adds new line to the end of ListView control. Only content of item itself
  6305. is set (aText, ImgIdx). To change other column text and attributes of
  6306. item added, use appropriate properties / methods ().
  6307. |<br>
  6308. Returns an index of added item.
  6309. |<br>
  6310. There is no Unicode version defined, use LVItemAddW instead. }
  6311. function LVItemAdd( const aText: KOLString ): Integer;
  6312. {* |<#listview>
  6313. Adds an item to the end of list view. Returns an index of the item added. }
  6314. function LVInsert( Idx: Integer; const aText: KOLString; ImgIdx: Integer;
  6315. State: TListViewItemState; StateImgIdx, OverlayImgIdx: Integer; Data: DWORD ): Integer;
  6316. {* |<#listview>
  6317. Inserts new line before line with index Idx in ListView control. Only
  6318. content of item itself is set (aText, ImgIdx). To change other column
  6319. text and attributes of item added, use appropriate properties / methods ().
  6320. if ImgIdx = I_IMAGECALLBACK, event handler OnGetLVItemImgIdx is responsible
  6321. for returning image index for an item ( /// not implemented yet /// )
  6322. Pass StateImgIdx and OverlayImgIdx = 0 (ignored in that case) or 1..15 to
  6323. use correspondent icon from ImageListState image list.
  6324. |<br> Returns an index of item inserted.
  6325. |<br> There is no unicode version of this method, use LVItemInsertW. }
  6326. function LVItemInsert( Idx: Integer; const aText: KOLString ): Integer;
  6327. {* |<#listview>
  6328. Inserts an item to Idx position. }
  6329. procedure LVDelete( Idx: Integer );
  6330. {* |<#listview>
  6331. Deletes item of ListView with subitems (full row - in lvsDetail view style. }
  6332. procedure LVSetItem( Idx, Col: Integer; const aText: KOLString; ImgIdx: Integer;
  6333. State: TListViewItemState; StateImgIdx, OverlayImgIdx: Integer; Data: DWORD );
  6334. {* |<#listview>
  6335. Use this method to set item data and item columns data for ListView control.
  6336. It is possible to pass I_SKIP as ImgIdx, StateImgIdx, OverlayImgIdx values to
  6337. skip setting this fields. But all other are set always. Like in LVInsert /
  6338. LVAdd, ImgIdx can be I_IMAGECALLBACK to determine that image will be
  6339. retrieved in OnGetItemImgIdx event handler when needed.
  6340. |<br>
  6341. If this method is called to set data for column > 0, parameters ImgIdx and
  6342. Data are ignored anyway.
  6343. |<br> There is no unicode version of this method, use other methods
  6344. to set up listed properties separately using correspondent W-functions. }
  6345. property LVItemState[ Idx: Integer ]: TListViewItemState read LVGetItemState write LVSetItemState;
  6346. {* |<#listview>
  6347. Access to list view item states set [lvisBlend, lvisHighlight, lvisFocus,
  6348. lvisSelect]. When assign new value to the property, it is possible to use
  6349. special index value -1 to change state for all items for a list view
  6350. (but only when lvoMultiselect style is applied to the list view, otherwise
  6351. index -1 is referring to the last item of the list view). }
  6352. property LVItemIndent[ Idx: Integer ]: Integer read LVGetItemIndent write LVSetItemIndent;
  6353. {* Item indentation. Indentation is calculated as this value multiplied to
  6354. image list ImgWidth value (Image list must be applied to list view).
  6355. Note: indentation supported only if IE3.0 or higher installed. }
  6356. property LVItemStateImgIdx[ Idx: Integer ]: Integer read LVGetSttImgIdx write LVSetSttImgIdx;
  6357. {* |<#listview>
  6358. Access to state image of the item. Use index -1 to assign the same state
  6359. image index to all items of the list view at once (fast).
  6360. Option lvoCheckBoxes just means, that control itself creates special inner
  6361. image list for two state images. Later it is possible to examine checked
  6362. state for items or set checked state programmatically by changing
  6363. LVItemStateImgIdx[ ] property. Value 1 corresponds to unchecked state,
  6364. 2 to checked. Value 0 allows to remove checkbox at all. So, to check all
  6365. added items by default (e.g.), do following:
  6366. ! ListView1.LVItemStateImgIdx[ -1 ] := 2;
  6367. |<br>Use 1-based index of the image
  6368. in image list ImageListState. Value 0 reserved to use as "no state image".
  6369. Values 1..15 can be used only - this is the Windows restriction on
  6370. state images. }
  6371. property LVItemOverlayImgIdx[ Idx: Integer ]: Integer read LVGetOvlImgIdx write LVSetOvlImgIdx;
  6372. {* |<#listview>
  6373. Access to overlay image of the item. Use index -1 to assign the same
  6374. overlay image to all items of the list view at once (fast). }
  6375. property LVItemData[ Idx: Integer ]: DWORD read LVGetItemData write LVSetItemData;
  6376. {* |<#listview>
  6377. Access to user defined data, assiciated with the item of the list view. }
  6378. procedure LVSelectAll;
  6379. {* |<#listview>
  6380. Call this method to select all the items of the list view control. }
  6381. property LVSelCount: Integer read GetSelLength; // write SetSelLength;
  6382. {* |<#listview>
  6383. Returns number of items selected in listview. }
  6384. property LVItemImageIndex[ Idx: Integer ]: Integer read LVGetItemImgIdx write LVSetItemImgIdx;
  6385. {* |<#listview>
  6386. Image index of items in listview. When an item is created (using LVItemAdd
  6387. or LVItemInsert), image index 0 is set by default (not -1 like in VCL!). }
  6388. property LVItems[ Idx, Col: Integer ]: KOLString read LVGetItemText write LVSetItemText;
  6389. {* |<#listview>
  6390. Access to List View item text. }
  6391. function LVItemRect( Idx: Integer; Part: TGetLVItemPart ): TRect;
  6392. {* |<#listview>
  6393. Returns rectangle occupied by given item part(s) in ListView window.
  6394. Empty rectangle is returned, if the item is not viewing currently. }
  6395. function LVSubItemRect( Idx, ColIdx: Integer ): TRect;
  6396. {* |<#listview>
  6397. Returns rectangle occupied by given item's subitem in ListView window,
  6398. in lvsDetail or lvsDetailNoHeader style. Empty rectangle (0,0,0,0) is
  6399. returned if the item is not viewing currently. Left or/and right bounds
  6400. of the rectangle returned can be outbound item rectangle if only a part
  6401. of the subitem is visible or the subitem is not visible in the item,
  6402. which is visible itself. }
  6403. property LVItemPos[ Idx: Integer ]: TPoint read LVGetItemPos write LVSetItemPos;
  6404. {* |<#listview>
  6405. Position of List View item (can be changed in icon or small icon view). }
  6406. function LVItemAtPos( X, Y: Integer ): Integer;
  6407. {* |<#listview>
  6408. Return index of item at the given position. }
  6409. function LVItemAtPosEx( X, Y: Integer; var Where: TWherePosLVItem ): Integer;
  6410. {* |<#listview>
  6411. Retrieves index of item and sets in Where, what part of item is under
  6412. given coordinates. If there are no items at the specified position,
  6413. -1 is returned. }
  6414. procedure LVMakeVisible( Item: Integer; PartiallyOK: Boolean );
  6415. {* |<#listview>
  6416. Makes listview item visible. Ignred when Item passed < 0. }
  6417. procedure LVEditItemLabel( Idx: Integer );
  6418. {* |<#listview>
  6419. Begins in-place editing of item label (first column text). }
  6420. procedure LVSort;
  6421. {* |<#listview>
  6422. Initiates sorting of list view items. This sorting procedure is available only
  6423. for Win2K, WinNT4 with IE5, Win98 or Win95 with IE5. See also LVSortData. }
  6424. procedure LVSortData;
  6425. {* |<#listview>
  6426. Initiates sorting of list view items. This sorting procedure is always available
  6427. in Windows95/98, NT/2000. But OnCompareLVItems procedure receives not indexes of
  6428. items compared but its Data field associated instead. }
  6429. procedure LVSortColumn( Idx: Integer );
  6430. {* |<#listview>
  6431. This is a method to simplify sort by column. Just call it in your OnColumnClick
  6432. event passing column index and enjoy with your list view sorted automatically
  6433. when column header is clicked. Requieres Windows2000 or Winows98, not supported
  6434. under WinNT 4.0 and below and under Windows95.
  6435. |<br>
  6436. Either lvoSortAscending or lvoSortDescending option must be set in
  6437. LVOptions, otherwise no sorting is performed. }
  6438. function LVIndexOf( const S: KOLString ): Integer;
  6439. {* Returns first list view item index with caption matching S.
  6440. The same as LVSearchFor( S, -1, FALSE ). }
  6441. function LVSearchFor( const S: KOLString; StartAfter: Integer; Partial: Boolean ): Integer;
  6442. {* Searches an item with Caption equal to S (or starting from S, if Partial = TRUE).
  6443. Searching is started after an item specified by StartAfter parameter. }
  6444. //======== List view page:
  6445. property LVTopItem: Integer index LVM_GETTOPINDEX read GetIntVal; //LVGetTopItem;
  6446. {* |<#listview>
  6447. Returns index of topmost visible item of ListView in lvsList view style. }
  6448. property LVPerPage: Integer index LVM_GETCOUNTPERPAGE read GetIntVal; //LVGetPerPage;
  6449. {* |<#listview>
  6450. Returns the number of fully-visible items if successful. If the current
  6451. view is icon or small icon view, the return value is the total number
  6452. of items in the list view control. }
  6453. //======== List View specific events:
  6454. property OnEndEditLVItem: TOnEditLVItem read fOnEndEditLVITem write SetOnEndEditLVItem;
  6455. {* |<#listview>
  6456. Called when edit of an item label in ListView control finished. Return
  6457. True to accept new label text, or false - to not accept it (item label
  6458. will not be changed). If handler not set to an event, all changes are
  6459. accepted. }
  6460. property OnLVDelete: TOnDeleteLVItem read fOnDeleteLVItem write SetOnDeleteLVItem;
  6461. {* |<#listview>
  6462. This event is called when an item is deleted in the listview.
  6463. Do not add, delete, or rearrange items in the list view while processing
  6464. this notification. }
  6465. property OnDeleteLVItem: TOnDeleteLVItem read fOnDeleteLVItem write SetOnDeleteLVItem;
  6466. {* |<#listview>
  6467. Called for every deleted list view item. }
  6468. property OnDeleteAllLVItems: TOnEvent read fOnDeleteAllLVItems write SetOnDeleteAllLVItems;
  6469. {* |<#listview>
  6470. Called when all the items of the list view control are to be deleted. If after
  6471. returning from this event handler event OnDeleteLVItem is yet assigned,
  6472. an event OnDeleteLVItem will be called for every deleted item. }
  6473. property OnLVData: TOnLVData read fOnLVData write SetOnLVData;
  6474. {* |<#listview>
  6475. Called to provide virtual list view with actual data. To use list view as
  6476. virtaul list view, define also lvsOwnerData style and set Count property
  6477. to actual row count of the list view. This manner of working with list view
  6478. control can greatly improve performance of an application when working with
  6479. huge data sets represented in listview control. }
  6480. property OnCompareLVItems: TOnCompareLVItems read fOnCompareLVItems write fOnCompareLVItems;
  6481. {* |<#listview>
  6482. Event to compare two list view items during sort operation (initiated by
  6483. LVSort method call). Do not send any messages to the list view control
  6484. while it is sorting - results can be unpredictable! }
  6485. property OnColumnClick: TOnLVColumnClick read fOnColumnClick write SetOnColumnClick;
  6486. {* |<#listview>
  6487. This event handler is called when column of the list view control is clicked.
  6488. You can use this event to initiate sorting of list view items by this column. }
  6489. property OnLVStateChange: TOnLVStateChange read FOnLVStateChange write SetOnLVStateChange;
  6490. {* |<#listview>
  6491. This event occure when an item or items range in list view control are
  6492. changing its state (e.g. selected or unselected). }
  6493. property OnDrawItem: TOnDrawItem read fOnDrawItem write SetOnDrawItem;
  6494. {* |<#listview>
  6495. |<#listbox>
  6496. |<#combo>
  6497. This event can be used to implement custom drawing for list view, list box, dropped
  6498. list of a combobox. For a list view, custom drawing using this event is possible
  6499. only in lvsDetail and lvsDetailNoHeader styles, and OnDrawItem is called to draw
  6500. entire row at once only. See also OnLVCustomDraw event. }
  6501. property OnLVCustomDraw: TOnLVCustomDraw read FOnLVCustomDraw write SetOnLVCustomDraw;
  6502. {* |<#listview>
  6503. Custom draw event for listview. For every item to be drawn, this event
  6504. can be called several times during a single drawing cycle - depending on
  6505. a result, returned by an event handler. Stage can have one of following
  6506. values:
  6507. |<pre>
  6508. CDDS_PREERASE
  6509. CDDS_POSTERASE
  6510. CDDS_ITEMPREERASE
  6511. CDDS_PREPAINT
  6512. CDDS_ITEMPREPAINT
  6513. CDDS_ITEM
  6514. CDDS_SUBITEM + CDDS_ITEMPREPAINT
  6515. CDDS_SUBITEM + CDDS_ITEMPOSTPAINT
  6516. CDDS_ITEMPOSTPAINT
  6517. CDDS_POSTPAINT
  6518. </pre>
  6519. When called, see on Stage to get know, on what stage the event is
  6520. activated. And depend on the stage and on what you want to paint,
  6521. return a value as a result, which instructs the system, if to use
  6522. default drawing on this (and follows) stage(s) for the item, and if
  6523. to notify further about different stages of drawing the item during
  6524. this drawing cycle. Possible values to return are:
  6525. |<pre>
  6526. CDRF_DODEFAULT - perform default drawing. Do not notify further for this
  6527. item (subitem) (or for entire listview, if called with
  6528. flag CDDS_ITEM reset - ?);
  6529. CDRF_NOTIFYITEMDRAW - return this value, when the event is called the
  6530. first time in a cycle of drawing, with ItemIdx = -1 and
  6531. flag CDDS_ITEM reset in Stage parameter;
  6532. CDRF_NOTIFYPOSTERASE - usually can be used to provide default erasing,
  6533. if you want to perform drawing immediately after that;
  6534. CDRF_NOTIFYPOSTPAINT - return this value to provide calling the event
  6535. after performing default drawing. Useful when you wish
  6536. redraw only a part of the (sub)item;
  6537. CDRF_SKIPDEFAULT - return this value to inform the system that all
  6538. drawing is done and system should not peform any more
  6539. drawing for the (sub)item during this drawing cycle.
  6540. CDRF_NEWFONT - informs the system, that font is changed and default
  6541. drawing should be performed with changed font;
  6542. |</pre>
  6543. If you want to get notifications for each subitem, do not use option
  6544. lvoOwnerDrawFixed, because such style prevents system from notifying
  6545. the application for each subitem to be drawn in the listview and only
  6546. notifications will be sent about entire items.
  6547. |<br>
  6548. See also NM_CUSTOMDRAW in API Help.
  6549. }
  6550. procedure Set_LVItemHeight(Value: Integer);
  6551. function SetLVItemHeight(Value: Integer): PControl;
  6552. property LVItemHeight: Integer read fLVItemHeight write Set_LVItemHeight;
  6553. {* |<#listview>
  6554. |<#listbox>
  6555. |#combo>
  6556. It is possible to assign a value to LVItemHeight property only to
  6557. control with "owner-draw" style (lvoOwnerDrawFixed for listview,
  6558. loOwnerDrawFixed or loOwnerDrawVariable for listbox and
  6559. coOwnerDrawFixed or coOwnerDrawVariable for combobox. At least, the
  6560. control should have such option while creating it (after showing it
  6561. the first time it is possible to change its options to avoid owner
  6562. drawing later). }
  6563. //======== TreeView specific properties and methods:
  6564. function TVInsert( nParent, nAfter: THandle; const Txt: KOLString ): THandle;
  6565. {* |<#treeview>
  6566. Inserts item to a tree view. If nParent is 0 or TVI_ROOT, the item is
  6567. inserted at the root of tree view. It is possible to pass following special
  6568. values as nAfter parameter:
  6569. |<pre>
  6570. TVI_FIRST Inserts the item at the beginning of the list.
  6571. TVI_LAST Inserts the item at the end of the list.
  6572. TVI_SORT Inserts the item into the list in alphabetical order.
  6573. |</pre> }
  6574. procedure TVDelete( Item: THandle );
  6575. {* |<#treeview>
  6576. Removes an item from the tree view. If value TVI_ROOT is passed, all items
  6577. are removed. }
  6578. property TVSelected: THandle index TVGN_CARET read TVGetItemIdx write TVSetItemIdx;
  6579. {* |<#treeview>
  6580. Returns or sets currently selected item handle in tree view. }
  6581. property TVDropHilighted: THandle index TVGN_DROPHILITE read TVGetItemIdx write TVSetItemIdx;
  6582. {* |<#treeview>
  6583. Returns or sets item, which is currently highlighted as a drop target. }
  6584. property TVDropHilited: THandle index TVGN_DROPHILITE read TVGetItemIdx write TVSetItemIdx;
  6585. {* The same as TVDropHilighted. }
  6586. property TVFirstVisible: THandle index TVGN_FIRSTVISIBLE read TVGetItemIdx write TVSetItemIdx;
  6587. {* |<#treeview>
  6588. Returns or sets given item to top of tree view. }
  6589. property TVIndent: Integer index TVM_GETINDENT read GetIntVal write SetIntVal;
  6590. {* |<#treeview>
  6591. The amount, in pixels, that child items are indented relative to their
  6592. parent items. }
  6593. property TVVisibleCount: Integer index TVM_GETVISIBLECOUNT read GetIntVal;
  6594. {* |<#treeview>
  6595. Returns number of fully (not partially) visible items in tree view. }
  6596. property TVRoot: THandle index TVGN_ROOT read TVGetItemIdx;
  6597. {* |<#treeview>
  6598. Returns handle of root item in tree view (or 0, if tree is empty). }
  6599. property TVItemChild[ Item: THandle ]: THandle index TVGN_CHILD read TVGetItemNext;
  6600. {* |<#treeview>
  6601. Returns first child item for given one. }
  6602. property TVItemHasChildren[ Item: THandle ]: Boolean read TV_GetItemHasChildren write TV_SetItemHasChildren;
  6603. {* |<#treeview>
  6604. TRUE, if an Item has children. Set this value to true if you want to
  6605. force [+] sign appearing left from the node, even if there are no
  6606. subnodes added to the node yet. }
  6607. property TVItemChildCount[ Item: THandle ]: Integer read TV_GetItemChildCount;
  6608. {* |<#treeview>
  6609. Returns number of node child items in tree view.
  6610. }
  6611. property TVItemNext[ Item: THandle ]: THandle index TVGN_NEXT read TVGetItemNext;
  6612. {* |<#treeview>
  6613. Returns next sibling item handle for given one (or 0, if passed item is
  6614. the last child for its parent node). }
  6615. property TVItemPrevious[ Item: THandle ]: THandle index TVGN_PREVIOUS read TVGetItemNext;
  6616. {* |<#treeview>
  6617. Returns previous sibling item (or 0, if the is no such item). }
  6618. property TVItemNextVisible[ Item: THandle ]: THandle index TVGN_NEXTVISIBLE read TVGetItemNext;
  6619. {* |<#treeview>
  6620. Returns next visible item (passed item must be visible too, to determine,
  6621. if it is really visible, use property TVItemRect or TVItemVisible. }
  6622. property TVItemPreviousVisible[ Item: THandle ]: THandle index TVGN_PREVIOUSVISIBLE read TVGetItemNext;
  6623. {* |<#treeview>
  6624. Returns previous visible item. }
  6625. property TVItemParent[ Item: THandle ]: THandle index TVGN_PARENT read TVGetItemNext;
  6626. {* |<#treeview>
  6627. Returns parent item for given one (or 0 for root item). }
  6628. property TVItemText[ Item: THandle ]: KOLString read TVGetItemText write TVSetItemText;
  6629. {* |<#treeview>
  6630. Text of tree view item. }
  6631. function TVItemPath( Item: THandle; Delimiter: KOLChar ): KOLString;
  6632. {* |<#treeview>
  6633. Returns full path from the root item to given item. Path is calculated
  6634. as a concatenation of all parent nodes text strings, separated by
  6635. given delimiter character.
  6636. |<br>Please note, that returned path has no trailing delimiter, this
  6637. character is only separating different parts of the path.
  6638. |<br>If Item is not specified ( =0 ), path is returned
  6639. for Selected item. }
  6640. property TVItemRect[ Item: THandle; TextOnly: Boolean ]: TRect read TVGetItemRect;
  6641. {* |<#treeview>
  6642. Returns rectangle, occupied by an item in tree view. }
  6643. property TVItemVisible[ Item: THandle ]: Boolean read TVGetItemVisible write TVSetITemVisible;
  6644. {* |<#treeview>
  6645. Returs True, if item is visible in tree view. It is also possible to
  6646. assign True to this property to ensure that a tree view item is visible
  6647. (if False is assigned, this does nothing). }
  6648. function TVItemAtPos( x, y: Integer; var Where: DWORD ): THandle;
  6649. {* |<#treeview>
  6650. Returns handle of item found at specified position (relative to upper left
  6651. corener of client area of the tree view). If no item found, 0 is returned.
  6652. Variable Where receives additional flags combination, describing more
  6653. detailed, on which part of item or tree view given point is located,
  6654. such as:
  6655. |<pre>
  6656. TVHT_ABOVE Above the client area
  6657. TVHT_BELOW Below the client area
  6658. TVHT_NOWHERE In the client area, but below the last item
  6659. TVHT_ONITEM On the bitmap or label associated with an item
  6660. TVHT_ONITEMBUTTON On the button associated with an item
  6661. TVHT_ONITEMICON On the bitmap associated with an item
  6662. TVHT_ONITEMINDENT In the indentation associated with an item
  6663. TVHT_ONITEMLABEL On the label (string) associated with an item
  6664. TVHT_ONITEMRIGHT In the area to the right of an item
  6665. TVHT_ONITEMSTATEICON On the state icon for a tree-view item that is in a user-defined state
  6666. TVHT_TOLEFT To the right of the client area
  6667. TVHT_TORIGHT To the left of the client area
  6668. |</pre> }
  6669. property TVRightClickSelect: Boolean read fTVRightClickSelect write SetTVRightClickSelect;
  6670. {* |<#treeview>
  6671. Set this property to True to allow change selection to an item, clicked with right mouse button. }
  6672. property TVEditing: Boolean read fEditing;
  6673. {* |<#treeview>
  6674. Returns True, if tree view control is editing its item label. }
  6675. property TVItemBold[ Item: THandle ]: Boolean index TVIS_BOLD read TVGetItemStateFlg write TVSetItemStateFlg;
  6676. {* |<#treeview>
  6677. True, if item is bold. }
  6678. property TVItemCut[ Item: THandle ]: Boolean index TVIS_CUT read TVGetITemStateFlg write TVSetItemStateFlg;
  6679. {* |<#treeview>
  6680. True, if item is selected as part of "cut and paste" operation. }
  6681. property TVItemDropHighlighted[ Item: THandle ]: Boolean index TVIS_DROPHILITED read TVGetITemStateFlg write TVSetItemStateFlg;
  6682. {* |<#treeview>
  6683. True, if item is selected as drop target. }
  6684. property TVItemDropHilited[ Item: THandle ]: Boolean index TVIS_DROPHILITED read TVGetITemStateFlg write TVSetItemStateFlg;
  6685. {* The same as TVItemDropHighlighted. }
  6686. property TVItemExpanded[ Item: THandle ]: Boolean index TVIS_EXPANDED read TVGetITemStateFlg; // write TVSetItemStateFlg;
  6687. {* |<#treeview>
  6688. True, if item's list of child items is currently expanded. To change
  6689. expanded state, use method TVExpand. }
  6690. property TVItemExpandedOnce[ Item: THandle ]: Boolean index TVIS_EXPANDEDONCE read TVGetITemStateFlg; // write TVSetItemStateFlg;
  6691. {* |<#treeview>
  6692. True, if item's list of child items has been expanded at least once. }
  6693. property TVItemSelected[ Item: THandle ]: Boolean index TVIS_SELECTED read TVGetITemStateFlg write TVSetItemStateFlg;
  6694. {* |<#treeview>
  6695. True, if item is selected. }
  6696. procedure TVExpand( Item: THandle; Flags: DWORD );
  6697. {* |<#treeview>
  6698. Call it to expand/collapse item's child nodes. Possible values for Flags
  6699. parameter are:
  6700. <pre>
  6701. TVE_COLLAPSE Collapses the list.
  6702. TVE_COLLAPSERESET Collapses the list and removes the child items. Note
  6703. that TVE_COLLAPSE must also be specified.
  6704. TVE_EXPAND Expands the list.
  6705. TVE_TOGGLE Collapses the list if it is currently expanded or
  6706. expands it if it is currently collapsed.
  6707. </pre>
  6708. }
  6709. procedure TVSort( N: THandle );
  6710. {* |<#treeview>
  6711. By Alex Mokrov. Sorts treeview. If N = 0, entire treeview is sorted.
  6712. Otherwise, children of the given node only.
  6713. }
  6714. property TVItemImage[ Item: THandle ]: Integer index TVIF_IMAGE read TVGetItemImage write TVSetItemImage;
  6715. {* |<#treeview>
  6716. Image index for an item of tree view. To tell that there are no image
  6717. set, use index -2 (value -1 is reserved for callback image). }
  6718. property TVItemSelImg[ Item: THandle ]: Integer index TVIF_SELECTEDIMAGE read TVGetItemImage write TVSetItemImage;
  6719. {* |<#treeview>
  6720. Image index for an item of tree view in selected state. Use value -2 to
  6721. provide no image, -1 used for callback image. }
  6722. property TVItemOverlay[ Item: THandle ]: Integer index TVIS_OVERLAYMASK or $80000
  6723. read TVGetItemImage write TVSetItemImage;
  6724. {* |<#treeview>
  6725. Overlay image index for an item in tree view.
  6726. Values 1..15 can be used only - this is the Windows restriction on
  6727. overlay images. }
  6728. property TVItemStateImg[ Item: THandle ]: Integer index TVIS_STATEIMAGEMASK or $C0000
  6729. read TVGetItemImage write TVSetItemImage;
  6730. {* |<#treeview>
  6731. State image index for an item in tree view. Use 1-based index of the image
  6732. in image list ImageListState. Value 0 reserved to use as "no state image".
  6733. }
  6734. property TVItemData[ Item: THandle ]: Pointer read TVGetItemData write TVSetItemData;
  6735. {* |<#treeview>
  6736. Stores any program-defined pointer with the item. }
  6737. procedure TVEditItem( Item: THandle );
  6738. {* |<#treeview>
  6739. Begins editing given item label in tree view. }
  6740. procedure TVStopEdit( Cancel: Boolean );
  6741. {* |<#treeview>
  6742. Ends editing item label, started by user or explicitly by TVEditItem method. }
  6743. property OnTVBeginDrag: TOnTVBeginDrag read fOnTVBeginDrag write fOnTVBeginDrag;
  6744. {* |<#treeview>
  6745. Is called for tree view, when its item is to be dragging. }
  6746. property OnTVBeginEdit: TOnTVBeginEdit read fOnTVBeginEdit write fOnTVBeginEdit;
  6747. {* |<#treeview>
  6748. Is called for tree view, when its item label is to be editing. }
  6749. property OnTVEndEdit: TOnTVEndEdit read fOnTVEndEdit write fOnTVEndEdit;
  6750. {* |<#treeview>
  6751. Is called when item label is edited. It is possible to cancel
  6752. edit, returning False as a result. }
  6753. property OnTVExpanding: TOnTVExpanding read fOnTVExpanding write fOnTVExpanding;
  6754. {* |<#treeview>
  6755. Is called just before expanding/collapsing item. It is possible to
  6756. return TRUE to prevent expanding item, otherwise FALSE should be returned. }
  6757. property OnTVExpanded: TOnTVExpanded read fOnTVExpanded write fOnTVExpanded;
  6758. {* |<#treeview>
  6759. Is called after expanding/collapsing item children. }
  6760. property OnTVDelete: TOnTVDelete read fOnTVDelete write SetOnTVDelete;
  6761. {* |<#treeview>
  6762. Is called just before deleting item. You may use this event to free
  6763. resources, associated with an item (see TVItemData property). }
  6764. //----------------- by Sergey Shisminzev:
  6765. property OnTVSelChanging: TOnTVSelChanging read fOnTVSelChanging write fOnTVSelChanging;
  6766. {* |<#treeview>
  6767. Is called before changing the selection. The handler can return FALSE
  6768. to prevent changing the selection. }
  6769. //--------------------------------------
  6770. //======== Toolbar specific methods:
  6771. procedure TBAddBitmap( Bitmap: HBitmap );
  6772. {* |<#toolbar>
  6773. Adds bitmaps to a toolbar. You can pass special values as Bitmap to
  6774. add one of predefined system button images bitmaps:
  6775. |<br> THandle(-1) to add standard small icons,
  6776. |<br> THandle(-2) to add standard large icons,
  6777. |<br> THandle(-5) to add standard small view icons,
  6778. |<br> THandle(-6) to add standard large view icons,
  6779. |<br> THandle(-9) to add standard small history icons,
  6780. |<br> THandle(-10) to add standard large history icons,
  6781. (in that case use following values as indexes to the standard and view
  6782. bitmaps:
  6783. |<br>
  6784. STD_COPY, STD_CUT, STD_DELETE, STD_FILENEW, STD_FILEOPEN, STD_FILESAVE,
  6785. STD_FIND, STD_HELP, STD_PASTE, STD_PRINT, STD_PRINTPRE, STD_PROPERTIES,
  6786. STD_REDO, STD_REPLACE, STD_UNDO,
  6787. |<br>
  6788. VIEW_LARGEICONS, VIEW_SMALLICONS,
  6789. VIEW_LIST, VIEW_DETAILS, VIEW_SORTNAME, VIEW_SORTSIZE, VIEW_SORTDATE,
  6790. VIEW_SORTTYPE (use it as parameters BtnImgIdxArray in TBAddButtons or
  6791. TBInsertButtons methods, and in assigning value to TBButtonImage[ ]
  6792. property).
  6793. Added bitmaps have indeces starting from previous count of images
  6794. (as these are appended to existing - if any).
  6795. |<br>
  6796. Note, that if You add your own (custom) bitmap, it is not transparent.
  6797. Do not assume that clSilver is always equal to clBtnFace. Use API
  6798. function CreateMappedBitmap to load bitmap from resource and map
  6799. desired colors as you wish (e.g., convert clTeal to clBtnFace). Or,
  6800. call defined in KOL function LoadMappedBitmap to do the same more easy.
  6801. Unfortunately, resource identifier for bitmap to pass it to LoadMappedBitmap
  6802. or to CreateMappedBitmap seems must be integer, so it is necessary to
  6803. create rc-file manually and compile using Borland Resource Compiler to
  6804. figure it out. }
  6805. function TBAddButtons( const Buttons: array of PKOLChar; const BtnImgIdxArray: array
  6806. of Integer ): Integer;
  6807. {* |<#toolbar>
  6808. Adds buttons to toolbar. Last string in Buttons array *must* be empty
  6809. ('' or nil), so to add buttons without text, pass ' ' string (one space
  6810. char). It is not necessary to provide image indexes for all
  6811. buttons (it is sufficient to assign index for first button only).
  6812. But in place, correspondent to separator button (defined by string '-'),
  6813. any integer must be passed to assign follow image indexes correctly.
  6814. See example.
  6815. |*Toolbar adding buttons sample.
  6816. Code below shows how to call TBAddButtons method to add two buttons with
  6817. a separator between these buttons. idxNew and idxOld are integer
  6818. expressions assigning image indexes to buttons 'New' and 'Old'. This
  6819. indexes are zero-based and refer to bitmap images, added earlier (either
  6820. in creating toolbar by call of NewToolbar or later in call of TBAddBitmap).
  6821. !
  6822. ! TBAddButtons( [ '&New', '-', '&Old', '' ], [ idxNew, 0, idxOld ] );
  6823. !
  6824. |*
  6825. To add check buttons, use prefix '+' or '-' in button definition
  6826. string. If next character is '!', such buttons are grouped to a
  6827. radio-group. Also, it is possible to use '^' prefix (must be first) to
  6828. define button with small drop-down section (use also OnTBDropDown event
  6829. to respond to clicking drop down section of such buttons).
  6830. |<br>
  6831. This function returns command id for first added button (other
  6832. id's can be calculated incrementing the result by one for each
  6833. button, except separators, which have no command id).
  6834. |<br>
  6835. Note: for static toolbar (single in application and created
  6836. once) ids are started from value 100. }
  6837. function TBInsertButtons( BeforeIdx: Integer; Buttons: array of PKOLChar;
  6838. BtnImgIdxArray: array of Integer ): Integer;
  6839. {* |<#toolbar>
  6840. Inserts buttons before button with given index on toolbar. Returns
  6841. command identifier for first button inserted (other can be calculated
  6842. incrementing returned value needed times. See also TBAddButtons. }
  6843. procedure TBDeleteButton( BtnID: Integer );
  6844. {* |<#toolbar>
  6845. Deletes single button given by its command id. To delete separator,
  6846. use TBDeleteBtnByIdx instead. }
  6847. procedure TBDeleteBtnByIdx( Idx: Integer );
  6848. {* |<#toolbar>
  6849. Deletes single button given by its index in toolbar (not by command ID). }
  6850. procedure TBAssignEvents( BtnID: Integer; Events: array of TOnToolbarButtonClick );
  6851. {* |<#toolbar>
  6852. Allows to assign separate OnClick events for every toolbar button.
  6853. BtnID should be toolbar button ID or index of the first button to
  6854. assign event. If it is an ID, events are assigned to buttons in
  6855. creation order. Otherwise, events are assigned in placement order.
  6856. Anyway, separator buttons are not skipped, so pass at least nil for such
  6857. button as an event.
  6858. |<br>
  6859. Please note, that though not all buttons should exist before
  6860. assigning events to it, therefore at least the first button
  6861. (specified by BtnID) must be already added before calling TBAssignEvents. }
  6862. procedure TBResetImgIdx( BtnID, BtnCount: Integer );
  6863. {* |<#toolbar>
  6864. Resets image index for BtnCount buttons starting from BtnID. }
  6865. property CurItem: Integer read fCurItem;
  6866. {* |<#toolbar>
  6867. For toolbar, in OnClick event this property can be used to determine
  6868. which button was clicked (100-based button id in toolbar). It is also
  6869. possible to use CurIndex property (zero-based) for this purpose as
  6870. well, but do not assume, that CurItem always equal to CurIndex+100.
  6871. At least, it is possible to call TBItem2Index function to convert
  6872. button ID to its index in toolbar.
  6873. }
  6874. property TBButtonCount: Integer read GetItemsCount; //TBGetButtonCount;
  6875. {* |<#toolbar>
  6876. Returns count of buttons on toolbar. The same as Count. }
  6877. property TBBtnImgWidth: Integer read fTBBtnImgWidth write fTBBtnImgWidth;
  6878. {* |<#toolbar>
  6879. Custom toolbar buttons width. Set it before assigning buttons bitmap.
  6880. Changing this property after assigning the bitmap has no effect. }
  6881. function TBItem2Index( BtnID: Integer ): Integer;
  6882. {* |<#toolbar>
  6883. Converts button command id to button index for tool bar. }
  6884. function TBIndex2Item( Idx: Integer ): Integer;
  6885. {* |<#toolbar>
  6886. Converts toolbar button index to its command ID. }
  6887. procedure TBConvertIdxArray2ID( const IdxVars: array of PDWORD );
  6888. {* |<#toolbar>
  6889. Converts toolbar button indexes to its command IDs for an array
  6890. of indexes (each item in the array passed is a pointer to
  6891. Integer, containing button index when the procedure is callled,
  6892. then all these indexes are relaced with a correspondent button ID).}
  6893. property TBButtonEnabled[ BtnID: Integer ]: Boolean index TB_ENABLEBUTTON
  6894. read TBGetBtnStt write TBSetBtnStt;
  6895. {* |<#toolbar>
  6896. Obvious. }
  6897. property TBButtonVisible[ BtnID: Integer ]: Boolean read TBGetButtonVisible
  6898. write TBSetButtonVisible;
  6899. {* |<#toolbar>
  6900. Allows to hide/show some of toolbar buttons. }
  6901. property TBButtonChecked[ BtnID: Integer ]: Boolean index TB_CHECKBUTTON
  6902. read TBGetBtnStt write TBSetBtnStt;
  6903. {* |<#toolbar>
  6904. Allows to determine 'checked' state of a button (e.g., radio-button),
  6905. and to check it programmatically. }
  6906. {$ifdef win32}
  6907. property TBButtonMarked[ BtnID: Integer ]: Boolean index TB_MARKBUTTON
  6908. read TBGetBtnStt write TBSetBtnStt;
  6909. {* |<#toolbar>
  6910. Returns True if toolbar button is marked (highlighted). Allows to
  6911. highlight buttons assigning True to this value. }
  6912. {$endif}
  6913. property TBButtonPressed[ BtnID: Integer ]: Boolean index TB_PRESSBUTTON
  6914. read TBGetBtnStt write TBSetBtnStt;
  6915. {* |<#toolbar>
  6916. Allows to detrmine if toolbar button (given by its command ID) pressed,
  6917. and press/unpress it programmatically. }
  6918. property TBButtonText[ BtnID: Integer ]: KOLString read TBGetButtonText write TBSetButtonText;
  6919. {* |<#toolbar>
  6920. Obtains toolbar button text and allows to change it. Be sure that text
  6921. is not empty for all buttons, if You want for it to be shown (if at least
  6922. one button has empty text, no text labels will be shown at all). At
  6923. least set it to ' ' for buttons, which You do not want to show labels,
  6924. if You want from other ones to have it. }
  6925. property TBButtonImage[ BtnID: Integer ]: Integer read TBGetBtnImgIdx write TBSetBtnImgIdx;
  6926. {* |<#toolbar>
  6927. Allows to access/change button image. Do not read this property for
  6928. separator buttons, returning value is not proper. If you do not know,
  6929. is the button a separator, using function below. }
  6930. function TBButtonSeparator( BtnID: Integer ): Boolean;
  6931. {* |<#toolbar>
  6932. Returns TRUE, if a toolbar button is separator. }
  6933. property TBButtonRect[ BtnID: Integer ]: TRect read TBGetButtonRect;
  6934. {* |<#toolbar>
  6935. Obtains rectangle occupied by toolbar button in toolbar window.
  6936. (It is not possible to obtain rectangle for buttons, currently
  6937. not visible). See also function ToolbarButtonRect. }
  6938. property TBButtonWidth[ BtnID: Integer ]: Integer read TBGetBtnWidth write TBSetBtnWidth;
  6939. {* |<#toolbar>
  6940. Allows to obtain / change toolbar button width. }
  6941. property TBButtonsMinWidth: Integer index 0
  6942. {$IFDEF F_P} read TBGetBtMinMaxWidth
  6943. {$ELSE DELPHI} read FTBBtMinWidth
  6944. {$ENDIF F_P/DELPHI} write TBSetBtMinMaxWidth;
  6945. {* |<#toolbar>
  6946. Allows to set minimal width for all toolbar buttons. }
  6947. property TBButtonsMaxWidth: Integer index 1
  6948. {$IFDEF F_P} read TBGetBtMinMaxWidth
  6949. {$ELSE DELPHI} read FTBBtMaxWidth
  6950. {$ENDIF F_P/DELPHI} write TBSetBtMinMaxWidth;
  6951. {* |<#toolbar>
  6952. Allows to set maximal width for all toolbar buttons. }
  6953. function TBButtonAtPos( X, Y: Integer ): Integer;
  6954. {* |<#toolbar>
  6955. Returns command ID of button at the given position on toolbar,
  6956. or -1, if there are no button at the position. Value 0 is returned
  6957. for separators. }
  6958. function TBBtnIdxAtPos( X, Y: Integer ): Integer;
  6959. {* |<#toolbar>
  6960. Returns index of button at the given position on toolbar.
  6961. This also can be index of separator button. -1 is returned if
  6962. there are no buttons found at the position. }
  6963. function TBMoveBtn( FromIdx, ToIdx: Integer ): Boolean;
  6964. {* |<#toolbar>
  6965. By TR"]F. Moves button from one position to another. }
  6966. property TBRows: Integer read TBGetRows write TBSetRows;
  6967. {* |<#toolbar>
  6968. Returns number of rows for toolbar and allows to try to set
  6969. desired number of rows (but system can set another number of
  6970. rows in some cases). This property has no effect if tboWrapable
  6971. style not present in Options when toolbar is created. }
  6972. procedure TBSetTooltips( BtnID1st: Integer; const Tooltips: array of PKOLChar );
  6973. {* |<#toolbar>
  6974. Allows to assign tooltips to several buttons. Until this procedure
  6975. is not called, tooltips list is not created and no code is added
  6976. to executable. This method of tooltips maintainance for toolbar buttons
  6977. is useful both for static and dynamic toolbars (meaning "dynamic" -
  6978. toolbars with buttons, deleted and inserted at run-time). }
  6979. property OnTBDropDown: TOnEvent read fOnDropDown write fOnDropDown;
  6980. {* |<#toolbar>
  6981. This event is called for drop down buttons, when user click drop part
  6982. of drop down button. To determine for which button event is called,
  6983. look at CurItem or CurIndex property. It is also possible to use
  6984. common (with combobox) property OnDropDown. }
  6985. property OnTBClick: TOnEvent read fOnClick write fOnClick;
  6986. {* |<#toolbar>
  6987. The same as OnClick. }
  6988. {$ifndef wince}
  6989. property OnTBCustomDraw: TOnTBCustomDraw read fOnTBCustomDraw write SetOnTBCustomDraw;
  6990. {* |<#toolbar>
  6991. An event (mainly) to customize toolbar background. }
  6992. {$endif wince}
  6993. property MaxTextSize: DWORD read GetMaxTextSize write SetMaxTextSize;
  6994. {* |<#richedit>
  6995. This property valid also for simple edit control, not only for RichEdit.
  6996. But for usual edit control, maximum text size available is 32K. For
  6997. RichEdit, limit is 4Gb. By default, RichEdit is limited to
  6998. 32767 bytes (to set maximum size available to 2Gb, assign MaxInt value
  6999. to a property). Also, to get current text size of RichEdit, use property
  7000. TextSize or RE_TextSize[ ]. }
  7001. property TextSize: Integer read GetTextSize;
  7002. {* |<#richedit>
  7003. Common for edit and rich edit controls property, which returns size of
  7004. text in edit control. Also, for any other control (or form, or applet
  7005. window) returns size (in characters) of Caption or Text (what is, the
  7006. same property actually). }
  7007. //================== RichEdit specific: ==================
  7008. {$IFNDEF NOT_USE_RICHEDIT}
  7009. property RE_TextSize[ Units: TRichTextSize ]: Integer read REGetTextSize;
  7010. {* |<#richedit>
  7011. For RichEdit control, it returns text size, measured in desired units
  7012. (rtsChars - characters, including OLE objects, counted as a single
  7013. character; rtsBytes - presize length of text image (if it would be stored
  7014. in file or stream). Please note, that for RichEdit1.0, only size in
  7015. characters can be obtained. }
  7016. function RE_TextSizePrecise: Integer;
  7017. {* |<#richedit>
  7018. By Savva. Returns length of rich edit text. }
  7019. property RE_CharFmtArea: TRichFmtArea read fRECharArea write fRECharArea;
  7020. {* |<#richedit>
  7021. By default, this property is raSelection. Changing it, You determine in
  7022. for which area characters format is applyed, when changing
  7023. character formatting properties below (not paragraph formatting).
  7024. |&A=<a href=#RE_CharFmtArea target=main>%0</a>
  7025. }
  7026. property RE_CharFormat: TCharFormat read REGetCharformat write RESetCharFormat;
  7027. {* |<#richedit>
  7028. In differ to follow properties, which allow to control certain formatting
  7029. attributes, this property provides low level access for formatting current
  7030. character area (see RE_CharFmtArea). It returns TCharFormat structure,
  7031. filled in with formatting attributes, and by assigning another value to
  7032. this property You can change desired attributes as You wish. Even if
  7033. RichEdit1.0 is used, TCharFormat2 is returned (but extended fields are
  7034. ignored for RichEdit1.0). }
  7035. property RE_Font: PGraphicTool read REGetFont write RESetFont;
  7036. {* |<#richedit>
  7037. Font of the first character in current selection (when retrieve).
  7038. When set (or subproperties of RE_Font are set), all font attributes are
  7039. applied to entire <A area>. To apply only needed attributes, use another
  7040. properties: RE_FmtBold, RE_FmtItalic, RE_FmtStrikeout, RE_FmtUnderline,
  7041. RE_FmtName, etc.
  7042. |<br>
  7043. Note, that font size is measured in twips, which is about 1/10 of pixel. }
  7044. property RE_FmtBold: Boolean index CFM_BOLD read REGetFontEffects write RESetFontEffect;
  7045. {* |<#richedit>
  7046. Formatting flag. When retrieve, returns True, if fsBold style RE_Font.FontStyle
  7047. is valid for a first character in the selection. When set, changes fsBold
  7048. style (True - set, False - reset) for all characters in <A area>. }
  7049. property RE_FmtBoldValid: Boolean index CFM_BOLD read REGetFontMask;
  7050. {* }
  7051. property RE_FmtItalic: Boolean index CFM_ITALIC read REGetFontEffects write RESetFontEffect;
  7052. {* |<#richedit>
  7053. Formatting flag. Like RE_FmtBold, when retrieving, shows, is fsItalic
  7054. style valid for the first character of the selection, and when set, changes
  7055. only fsItalic style for an <A area>. }
  7056. property RE_FmtItalicValid: Boolean index CFM_ITALIC read REGetFontMask;
  7057. {* }
  7058. property RE_FmtStrikeout: Boolean index CFM_STRIKEOUT read REGetFontEffects write RESetFontEffect;
  7059. {* |<#richedit>
  7060. Formatting flag. Like RE_FmtBold, when retrieving, shows, is fsStrikeout
  7061. style valid for the first selected character, and when set, changes only
  7062. fsStrikeout style for an <A area>. }
  7063. property RE_FmtStrikeoutValid: Boolean index CFM_STRIKEOUT read REGetFontMask;
  7064. {* }
  7065. property RE_FmtUnderline: Boolean index CFM_UNDERLINE read REGetFontEffects write RESetFontEffect;
  7066. {* |<#richedit>
  7067. Formatting flag. Like RE_FmtBold, when retrieving, shows, is fsUnderline
  7068. style valid for the first selected character, and when set, changes
  7069. fsUnderline style for an <A area>. }
  7070. property RE_FmtUnderlineValid: Boolean index CFM_UNDERLINE read REGetFontMask;
  7071. {* }
  7072. property RE_FmtUnderlineStyle: TRichUnderline
  7073. read REGetUnderlineEx write RESetUnderlineEx;
  7074. {* |<#richedit>
  7075. Extended underline style. To check, if this property is valid for
  7076. entire selection, examine RE_FmtUnderlineValid value. }
  7077. property RE_FmtProtected: Boolean index CFM_PROTECTED read REGetFontEffects write RESetFontEffect;
  7078. {* |<#richedit>
  7079. Formatting flag. When retrieving, shows, is the first character of the selection
  7080. is protected from changing it by user (True) or not (False). To get know,
  7081. if retrived value is valid for entire selection, check the property
  7082. RE_FmtProtectedValid. When set, makes all characters in <A area> protected (
  7083. True) or not (False). }
  7084. property RE_FmtProtectedValid: Boolean index CFM_PROTECTED read REGetFontMask;
  7085. {* |<#richedit>
  7086. True, if property RE_FmtProtected is valid for entire selection, when
  7087. retrieving it. }
  7088. property RE_FmtHidden: Boolean index CFM_HIDDEN read REGetFontEffects write RESetFontEffect;
  7089. {* |<#richedit>
  7090. For RichEdit3.0, makes text hidden (not displayed). }
  7091. property RE_FmtHiddenValid: Boolean index CFM_HIDDEN read REGetFontMask;
  7092. {* |<#richedit>
  7093. Returns True, if RE_FmtHidden style is valid for entire selection. }
  7094. property RE_FmtLink: Boolean index $20 {CFM_LINK} read REGetFontEffects write RESetFontEffect;
  7095. {* |<#richedit>
  7096. Returns True, if the first selected character is a part of link (URL). }
  7097. // by Sergey Shisminzev
  7098. property RE_FmtLinkValid: Boolean index $20 {CFM_LINK} read REGetFontMask;
  7099. {* }
  7100. property RE_FmtFontSize: Integer index (12 shl 16) or CFM_SIZE read REGetFontAttr write RESetFontAttr;
  7101. {* |<#richedit>
  7102. Formatting value: font size, in twips (1/1440 of an inch, or 1/20 of a
  7103. printer's point, or about 1/10 of pixel). When retrieving, returns
  7104. RE_Font.FontHeight.
  7105. When set, changes font size for entire <A area> (but does not change
  7106. other font attributes). }
  7107. property RE_FmtFontSizeValid: Boolean read REGetFontSizeValid;
  7108. {* |<#richedit>
  7109. Returns True, if property RE_FmtFontSize is valid for entire selection,
  7110. when retrieving it. }
  7111. property RE_FmtAutoBackColor: Boolean index CFM_BACKCOLOR read REGetFontEffects write RESetFontEffect;
  7112. {* |<#richedit>
  7113. True, when automatic back color is used. }
  7114. property RE_FmtAutoBackColorValid: Boolean index CFM_BACKCOLOR read REGetFontMask;
  7115. {* }
  7116. property RE_FmtFontColor: Integer index (20 shl 16) or CFM_COLOR read REGetFontAttr write RESetFontAttr1;
  7117. {* |<#richedit>
  7118. Formatting value (font color). When retrieving, returns RE_Font.Color.
  7119. When set, changes font color for entire <A area> (but does not change
  7120. other font attributes). }
  7121. property RE_FmtFontColorValid: Boolean index CFM_COLOR read REGetFontMask;
  7122. {* |<#richedit>
  7123. Returns True, if property RE_FmtFontColor valid for entire selection,
  7124. when retrieving it. }
  7125. property RE_FmtAutoColor: Boolean index CFM_COLOR read REGetFontEffects write RESetFontEffect;
  7126. {* |<#richedit>
  7127. True, when automatic text color is used (in such case, RE_FmtFontColor
  7128. assignment is ignored for current area). }
  7129. property RE_FmtAutoColorValid: Boolean index CFM_COLOR read REGetFontMask;
  7130. {* }
  7131. property RE_FmtBackColor: Integer index ((64
  7132. {$IFDEF UNICODE_CTRLS} + 32 {$ENDIF}
  7133. ) shl 16) or CFM_BACKCOLOR read REGetFontAttr write RESetFontAttr1;
  7134. {* |<#richedit>
  7135. Formatting value (back color). Only available for Rich Edit 2.0 and higher.
  7136. When set, changes background color for entire <A area> (but does not change
  7137. other font attributes). }
  7138. property RE_FmtBackColorValid: Boolean index CFM_BACKCOLOR read REGetFontMask;
  7139. {* }
  7140. property RE_FmtFontOffset: Integer index (16 shl 16) or CFM_OFFSET read REGetFontAttr write RESetFontAttr;
  7141. {* |<#richedit>
  7142. Formatting value (font vertical offset from baseline, positive values
  7143. correspond to subscript). When retrieving, returns offset for first
  7144. character in the selection. When set, changes font offset for entire
  7145. <A area>. To get know, is retrieved value valid for entire selction,
  7146. check RE_FmtFontOffsetValid property. }
  7147. property RE_FmtFontOffsetValid: Boolean index CFM_OFFSET read REGetFontMask;
  7148. {* |<#richedit>
  7149. Returns True, if property RE_FmtFontOffset is valid for entire selection,
  7150. when retrieving it. }
  7151. property RE_FmtFontCharset: Integer index (25 shl 16) or CFM_CHARSET read REGetFontAttr write RESetFontAttr;
  7152. {* |<#richedit>
  7153. Returns charset for first character in current selection, when retrieved
  7154. (and to get know, if this value is valid for entire selection, check
  7155. property RE_FmtFontCharsetValid). When set, changes charset for all
  7156. characters in <A area>, but does not alter other formatting attributes. }
  7157. property RE_FmtFontCharsetValid: Boolean index CFM_CHARSET read REGetFontMask;
  7158. {* |<#richedit>
  7159. Returns True, only if rerieved property RE_FmtFontCharset is valid for
  7160. entire selection. }
  7161. property RE_FmtFontName: KOLString read REGetFontName write RESetFontName;
  7162. {* |<#richedit>
  7163. Returns font face name for first character in the selection, when retrieved,
  7164. and sets font name for entire <A area>, wnen assigned to (without
  7165. changing of other formatting attributes). To get know, if retrived
  7166. font name valid for entire selection, examine property RE_FmtFontNameValid. }
  7167. property RE_FmtFontNameValid: Boolean index CFM_FACE read REGetFontMask;
  7168. {* |<#richedit>
  7169. Returns True, only if the font name is the same for entire selection,
  7170. thus is, if rerieved property value RE_FmtFontName is valid for entire
  7171. selection. }
  7172. property RE_ParaFmt: TParaFormat read REGetParaFmt write RESetParaFmt;
  7173. {* |<#richedit>
  7174. Allows to retrieve or set paragraph formatting attributes for currently
  7175. selected paragraph(s) in RichEdit control. See also following properties,
  7176. which allow to do the same for certain paragraph format attributes
  7177. separately. }
  7178. property RE_TextAlign: TRichTextAlign read REGetTextAlign write RESetTextAlign;
  7179. {* |<#richedit>
  7180. Returns text alignment for current selection and allows to change it
  7181. (without changing other formatting attributes). }
  7182. property RE_TextAlignValid: Boolean index PFM_ALIGNMENT read REGetParaAttrValid;
  7183. {* |<#richedit>
  7184. Returns True, if property RE_TextAlign is valid for entire selection. If
  7185. False, it is concerning only start of selection. }
  7186. property RE_Numbering: Boolean read REGetNumbering write RESetNumbering;
  7187. {* |<#richedit>
  7188. Returns True, if selected text is numbered (or has style of list with
  7189. bullets). To get / change numbering style, see properties
  7190. RE_NumStyle and RE_NumBrackets. }
  7191. property RE_NumStyle: TRichNumbering read REGetNumStyle write RESetNumStyle;
  7192. {* |<#richedit>
  7193. Advanced numbering style, such as rnArabic etc. If You use it, do not
  7194. change RE_Numbering property simultaneously - this can cause changing
  7195. style to rnBullets only. }
  7196. property RE_NumStart: Integer read REGetNumStart write RESetNumStart;
  7197. {* |<#richedit>
  7198. Starting number for advanced numbering style. If this property is not
  7199. set, numbering is starting by default from 0. For rnLRoman and rnURoman
  7200. this cause, that first item has no number to be shown (ancient Roman
  7201. people did not invent '0'). }
  7202. property RE_NumBrackets: TRichNumBrackets read REGetNumBrackets write RESetNumBrackets;
  7203. {* |<#richedit>
  7204. Brackets style for advanced numbering. rnbPlain is default
  7205. brackets style, and every time, when RE_NumStyle is changed,
  7206. RE_NumBrackets is reset to rnbPlain. }
  7207. property RE_NumTab: Integer read REGetNumTab write RESetNumTab;
  7208. {* |<#richedit>
  7209. Tab between start of number and start of paragraph text. If too small too
  7210. view number, number is not displayed. (Default value seems to be sufficient
  7211. though). }
  7212. property RE_NumberingValid: Boolean index PFM_NUMBERING read REGetParaAttrValid;
  7213. {* |<#richedit>
  7214. Returns True, if RE_Numbering, RE_NumStyle, RE_NumBrackets, RE_NumTab,
  7215. RE_NumStart properties are valid for entire selection. }
  7216. property RE_Level: Integer read REGetLevel;
  7217. {* |<#richedit>
  7218. Outline level (for numbering paragraphs?). Read only. }
  7219. property RE_SpaceBefore: Integer index 0 or PFM_SPACEBEFORE read REGetSpacing write RESetSpacing;
  7220. {* |<#richedit>
  7221. Spacing before paragraph. }
  7222. property RE_SpaceBeforeValid: Boolean index PFM_SPACEBEFORE read REGetParaAttrValid;
  7223. {* |<#richedit>
  7224. True, if RE_SpaceBefore value is valid for all selected paragraph (if
  7225. False, this value is valid only for first paragraph. }
  7226. property RE_SpaceAfter: Integer index 4 or PFM_SPACEAFTER read REGetSpacing write RESetSpacing;
  7227. {* |<#richedit>
  7228. Spacing after paragraph. }
  7229. property RE_SpaceAfterValid: Boolean index PFM_SPACEAFTER read REGetParaAttrValid;
  7230. {* |<#richedit>
  7231. True, only if RE_SpaceAfter value is valid for all selected paragraphs. }
  7232. property RE_LineSpacing: Integer index 8 or PFM_LINESPACING read REGetSpacing write RESetSpacing;
  7233. {* |<#richedit>
  7234. Linespacing in paragraph (this value is based on RE_SpacingRule property). }
  7235. property RE_SpacingRule: Integer read REGetSpacingRule write RESetSpacingRule;
  7236. {* |<#richedit>
  7237. Linespacing rule. Do not know what is it. }
  7238. property RE_LineSpacingValid: Boolean index PFM_LINESPACING read REGetParaAttrValid;
  7239. {* |<#richedit>
  7240. True, only if RE_LineSpacing and RE_SpacingRule values are valid for
  7241. entire selection. }
  7242. property RE_Indent: Integer index (20 shl 16) or PFM_OFFSET read REGetParaAttr write RESetParaAttr;
  7243. {* |<#richedit>
  7244. Returns left indentation for paragraph in current selection and allows
  7245. to change it (without changing other formatting attributes). }
  7246. property RE_IndentValid: Boolean index PFM_OFFSET read REGetParaAttrValid;
  7247. {* |<#richedit>
  7248. Returns True, if RE_Indent property is valid for entire selection. }
  7249. property RE_StartIndent: Integer index (12 shl 16) or PFM_STARTINDENT read REGetParaAttr write RESetParaAttr;
  7250. {* |<#richedit>
  7251. Returns left indentation for first line in paragraph for current
  7252. selection, and allows to change it (without changing other formatting
  7253. attributes). }
  7254. property RE_StartIndentValid: Boolean read REGetStartIndentValid;
  7255. {* |<#richedit>
  7256. Returns True, if property RE_StartIndent is valid for entire selection. }
  7257. property RE_RightIndent: Integer index (16 shl 16) or PFM_RIGHTINDENT read REGetParaAttr write RESetParaAttr;
  7258. {* |<#richedit>
  7259. Returns right indent for paragraph in current selection, and allow to
  7260. change it (without changing other formatting attributes). }
  7261. property RE_RightIndentValid: Boolean index PFM_RIGHTINDENT read REGetParaAttrValid;
  7262. {* |<#richedit>
  7263. Returns True, if property RE_RightIndent is valid for entire selection only. }
  7264. property RE_TabCount: Integer read REGetTabCount write RESetTabCount;
  7265. {* |<#richedit>
  7266. Number of tab stops in current selection. This value can not be set greater
  7267. then MAX_TAB_COUNT (32). }
  7268. property RE_Tabs[ Idx: Integer ]: Integer read REGetTabs write RESetTabs;
  7269. {* |<#richedit>
  7270. Tab stops for RichEdit control. }
  7271. property RE_TabsValid: Boolean index PFM_TABSTOPS read REGetParaAttrValid;
  7272. {* |<#richedit>
  7273. Returns True, if properties RE_Tabs[ ] and RE_TabCount are valid for
  7274. entire selection. }
  7275. // following does not work now :
  7276. property RE_BorderWidth[ Side: TBorderEdge ]: Integer index 2 read REGetBorder write RESetBorder;
  7277. { * |<#richedit>
  7278. Border width. }
  7279. property RE_BorderSpace[ Side: TBorderEdge ]: Integer index 0 read REGetBorder write RESetBorder;
  7280. { * |<#richedit>
  7281. Border space. }
  7282. property RE_BorderStyle[ Side: TBorderEdge ]: Integer index 4 read REGetBorder write RESetBorder;
  7283. { * |<#richedit>
  7284. Border style. }
  7285. property RE_BorderValid: Boolean index PFM_BORDER read REGetParaAttrValid;
  7286. { * |<#richedit>
  7287. Returns True, if border style, space and width are the same for all
  7288. paragraphs in selection. }
  7289. property RE_Table: Boolean index $C000 read REGetParaEffect write RESetParaEffect;
  7290. { * |<#richedit>
  7291. True, if current paragraph is a part of table (row, cell or cell end).
  7292. seems working as read only property. }
  7293. // end of experiment section
  7294. function RE_FmtStandard: PControl;
  7295. {* |<#richedit>
  7296. "Transparent" method (returns @Self as a result), which (when called)
  7297. provides "standard" keyboard interface for formatting Rich text (just
  7298. call this method, for example:
  7299. ! RichEd1 := NewRichEdit( Panel1, [ ] ).SetAlign( caClient ).RE_FmtStandard;
  7300. Following keys will be maintained additionally:
  7301. |<pre>
  7302. CTRL+I - switch "Italic",
  7303. CTRL+B - switch "Bold",
  7304. CTRL+U - switch "Underline",
  7305. CTRL+SHIFT+U - swith underline type
  7306. and turn underline on (note, that some of underline styles
  7307. can not be shown properly in RichEdit v2.0 and lower,
  7308. though RichEdit2.0 stores data successfully).
  7309. CTRL+O - switch "StrikeOut",
  7310. CTRL+'gray+' - increase font size,
  7311. CTRL+'gray-' - decrease font size,
  7312. CTRL+SHIFT+'gray+' - superscript,
  7313. CTRL+SHIFT+'gray-' - subscript.
  7314. CTRL+SHIFT+Z - ReDo
  7315. |</pre>
  7316. And, though following standard formatting keys are provided by RichEdit
  7317. control itself in Windows2000, some of these are not functioning
  7318. automatically in earlier Windows versions, even for RichEdit2.0. So,
  7319. functionality of some of these (marked with (*) ) are added here too:
  7320. |<pre>
  7321. CTRL+L - align paragraph left, (*)
  7322. CTRL+R - align paragraph right, (*)
  7323. CTRL+E - align paragraph center, (*)
  7324. CTRL+A - select all, (*)
  7325. double-click on word - select word,
  7326. CTRL+Right - to next word,
  7327. CTRL+Left - to previous word,
  7328. CTRL+Home - to the beginning of text,
  7329. CTRL+End - to the end of text.
  7330. CTRL+Z - UnDo
  7331. |</pre>
  7332. If You originally assign some (plain) text to Text property, switching "underline"
  7333. can also change other font attributes, e.g., "bold" - if fsBold style is
  7334. in default Font. To prevent such behavior, select entire text first (see
  7335. SelectAll) and make assignment to RE_Font property, e.g.:
  7336. ! RichEd1.SelectAll;
  7337. ! RichEd1.RE_Font := RichEd1.RE_Font;
  7338. ! RichEd1.SelLength := 0;
  7339. |<br>
  7340. And, some other notices about formatting. Please remember, that only True
  7341. Type fonts can be succefully scaled and transformed to get desired effects
  7342. (e.g., bold). By default, RichEdit uses System font face name, which can
  7343. even have problems with fsBold style. Please remember also, that assigning
  7344. RE_Font to RE_Font just initializying formatting attributes, making all
  7345. those valid in entire text, but does not change font attributes. To use
  7346. True Type font, directly assign face name You wish, e.g.:
  7347. ! RichEd1.SelectAll;
  7348. ! RichEd1.RE_Font := RichEd1.RE_Font;
  7349. ! RichEd1.RE_Font.FontName := 'Arial';
  7350. ! RichEd1.SelLength := 0;
  7351. }
  7352. procedure RE_CancelFmtStandard;
  7353. {* Cancels RE_FmtStandard (detaching window procedure handler). }
  7354. property RE_AutoKeyboard: Boolean index 1 read REGetLangOptions write RESetLangOptions;
  7355. {* |<#richedit>
  7356. True if autokeyboard on (lovely "feature" of automatic switching keyboard
  7357. language when caret is over another language text). For older RichEdit,
  7358. is 'on' always, for newest - 'off' by default. }
  7359. property RE_AutoFont: Boolean index 2 read REGetLangOptions write RESetLangOptions;
  7360. {* |<#richedit>
  7361. True if autofont on (automatic switching font when keyboard layout is
  7362. changes). By default, is 'on' always. It is suggested to turn this option
  7363. off for Unicode control. }
  7364. property RE_AutoFontSizeAdjust: Boolean index 16 read REGetLangOptions write RESetLangOptions;
  7365. {* |<#richedit>
  7366. See IMF_AUTOFONTSIZEADJUST option in SDK:
  7367. Font-bound font sizes are scaled from insertion point size according to
  7368. script. For example, Asian fonts are slightly larger than Western ones.
  7369. This option is turned on by default. }
  7370. property RE_DualFont: Boolean index 128 read REGetLangOptions write RESetLangOptions;
  7371. {* |<#richedit>
  7372. See IMF_DUALFONT option in SDK:
  7373. Sets the control to dual-font mode. Used for Asian language support.
  7374. The control uses an English font for ASCII text and a Asian font for
  7375. Asian text. }
  7376. property RE_UIFonts: Boolean index 32 read REGetLangOptions write RESetLangOptions;
  7377. {* |<#richedit>
  7378. See IMF_UIFONTS option in SDK:
  7379. Use user-interface default fonts. This option is turned off by default. }
  7380. property RE_IMECancelComplete: Boolean index 4 read REGetLangOptions write RESetLangOptions;
  7381. {* |<#richedit>
  7382. See IMF_IMECANCELCOMPLETE option in SDK:
  7383. This flag determines how the control uses the composition string of an
  7384. IME if the user cancels it. If this flag is set, the control discards
  7385. the composition string. If this flag is not set, the control uses the
  7386. composition string as the result string. }
  7387. property RE_IMEAlwaysSendNotify: Boolean index 8 read REGetLangOptions write RESetLangOptions;
  7388. {* |<#richedit>
  7389. See IMF_IMEALWAYSSENDNOTIFY option in SDK:
  7390. Controls how Rich Edit notifies the client during IME composition:
  7391. |<br>
  7392. 0: No EN_CHANGED or EN_SELCHANGE notifications during undetermined state.
  7393. Send notification when final string comes in. (default)
  7394. |<br>
  7395. 1: Send EN_CHANGED and EN_SELCHANGE events during undetermined state. }
  7396. property RE_OverwriteMode: Boolean read REGetOverwite write RESetOverwrite;
  7397. {* |<#richedit>
  7398. This property allows to control insert/overwrite mode. First, to examine, if
  7399. insert or overwrite mode is current (but it is necessary either to
  7400. access this property, at least once, immediately after creating RichEdit
  7401. control, or to assign event OnRE_InsOvrMode_Change to your handler).
  7402. Second, to set desired mode programmatically - by assigning value to
  7403. this property (You also have to initialize monitoring procedure by either
  7404. reading RE_OverwriteMode property or assigning handler to event
  7405. OnRE_InsOvrMode_Change immediately following RichEdit control creation). }
  7406. property OnRE_InsOvrMode_Change: TOnEvent read fOnREInsModeChg write fOnREInsModeChg;
  7407. {* |<#richedit>
  7408. This event is called, whenever key INSERT is pressed in control (and for
  7409. RichEdit, this means, that insert mode is changed). }
  7410. property RE_DisableOverwriteChange: Boolean read fReOvrDisable write RESetOvrDisable;
  7411. {* |<#richedit>
  7412. It is possible to disable switching between "insert" and "overwrite" mode
  7413. by user (therefore, event OnRE_InsOvrMode_Change continue works, but it
  7414. just called when key INSERT is pressed, though RE_OverwriteMode property
  7415. is not actually changed if switching is disabled). }
  7416. function RE_LoadFromStream( Stream: PStream; Length: Integer;
  7417. Format: TRETextFormat; SelectionOnly: Boolean ): Boolean;
  7418. {* |<#richedit>
  7419. Use this method rather then assignment to RE_Text property, if
  7420. source is stored in file or stream (to minimize resources during
  7421. loading of RichEdit content). Data is loading starting from current
  7422. position in stream and no more then Length bytes are loaded (use -1
  7423. value to load to the end of stream). Loaded data replaces entire
  7424. content of RichEdit control, or selection only, depending on SelectionOnly
  7425. flag.
  7426. |<br>&nbsp;&nbsp;&nbsp;
  7427. If You want to provide progress (e.g. in form of progress bar), assign
  7428. OnProgress event to your handler - and to examine current position of
  7429. loading, read TSream.Position property of soiurce stream). }
  7430. function RE_SaveToStream( Stream: PStream; Format: TRETextFormat; SelectionOnly: Boolean ): Boolean;
  7431. {* |<#richedit>
  7432. Use this method rather then RE_TextProperty to store data to file
  7433. or stream (to minimize resources during saving of RichEdit content).
  7434. Data is saving starting from current position in a stream (until
  7435. end of RichEdit data). If SelectionOnly flag is True, only selected
  7436. part of RichEdit text is saved.
  7437. |<br>&nbsp;&nbsp;&nbsp;
  7438. Like for RE_LoadFromStream, it is possible to assign your method to
  7439. OnProgress event (but to calculate progress of save-to-stream operation,
  7440. compare current stream position with RE_Size[ rsBytes ] property
  7441. value). }
  7442. property OnProgress: TOnEvent read fOnProgress write fOnProgress;
  7443. {* |<#richedit>
  7444. This event is called during RE_SaveToStream, RE_LoadFromStream (and also
  7445. during RE_SaveToFile, RE_LoadFromFile and while accessing or changing
  7446. RE_Text property). To calculate relative progress, it is possible to
  7447. examine current position in stream/file with its total size while reading,
  7448. or with rich edit text size, while writing (property RE_TextSize[ rsBytes ]).
  7449. }
  7450. function RE_LoadFromFile( const Filename: KOLString; Format: TRETextFormat;
  7451. SelectionOnly: Boolean ): Boolean;
  7452. {* |<#richedit>
  7453. Use this method rather then other assignments to RE_Text property,
  7454. if a source for RichEdit is the file. See also RE_LoadFromStream. }
  7455. function RE_SaveToFile( const Filename: KOLString; Format: TRETextFormat;
  7456. SelectionOnly: Boolean ): Boolean;
  7457. {* |<#richedit>
  7458. Use this method rather then other similar, if You want to store
  7459. entire content of RichEdit or selection only of RichEdit to a file. }
  7460. property RE_Text[ Format: TRETextFormat; SelectionOnly: Boolean ]: KOLString read REReadText write REWriteText;
  7461. {* |<#richedit>
  7462. This property allows to get / replace content of RichEdit control
  7463. (entire text or selection only). Using different formats, it is
  7464. possible to exclude or replace undesired formatting information
  7465. (see TRETextFormat specification). To get or replace entire text
  7466. in reText mode (plain text only), it is possible to use habitual
  7467. for edit controls Text property.
  7468. |<br>&nbsp;&nbsp;&nbsp;
  7469. Note: it is possible to append text to the end of RichEdit control
  7470. using method Add, but only if property RE_Text is accessed at least
  7471. once:
  7472. ! RichEdit1.RE_Text[ reText, True ];
  7473. (This line can be written immediatelly after creating RichEdit control). }
  7474. procedure RE_Append( const S: KOLString; ACanUndo: Boolean );
  7475. {* }
  7476. procedure RE_InsertRTF( const S: KOLString );
  7477. {* }
  7478. property RE_Error: Integer read fREError;
  7479. {* |<#richedit>
  7480. Contains error code, if access to RE_Text failed. }
  7481. procedure RE_HideSelection( aHide: Boolean );
  7482. {* |<#richedit>
  7483. Allows to hide / show selection in RichEdit. }
  7484. function RE_SearchText( const Value: KOLString; MatchCase, WholeWord, ScanForward: Boolean;
  7485. SearchFrom, SearchTo: Integer ): Integer;
  7486. {* |<#richedit>
  7487. Searches given string starting from SearchFrom position up to SearchTo
  7488. position (to the end of text, if SearchTo is -1). Returns zero-based
  7489. character position of the next match, or -1 if there are no more matches.
  7490. To search in bacward direction, set ScanForward to False, and pass
  7491. SearchFrom > SearchTo (or even SearchFrom = -1 and SearchTo = 0). }
  7492. {$IFNDEF DISABLE_DEPRECATED}
  7493. {$IFNDEF _FPC}
  7494. {$IFNDEF _D2} //------- WideString not supported in D2
  7495. function RE_WSearchText( const Value: WideString; MatchCase, WholeWord, ScanForward: Boolean;
  7496. SearchFrom, SearchTo: Integer ): Integer;
  7497. {* |<#richedit>
  7498. Searches given string starting from SearchFrom position up to SearchTo
  7499. position (to the end of text, if SearchTo is -1). Returns zero-based
  7500. character position of the next match, or -1 if there are no more matches.
  7501. To search in bacward direction, set ScanForward to False, and pass
  7502. SearchFrom > SearchTo (or even SearchFrom = -1 and SearchTo = 0). }
  7503. {$ENDIF}
  7504. {$ENDIF}
  7505. {$ENDIF DISABLE_DEPRECATED}
  7506. property RE_AutoURLDetect: Boolean read REGetAutoURLDetect write RESetAutoURLDetect;
  7507. {* |<#richedit>
  7508. If set to True, automatically detects URLs (and highlights it with
  7509. blue color, applying fsItalic and fsUnderline font styles (while
  7510. typing and loading). Default value is False. Note: if event OnRE_URLClick
  7511. or event OnRE_OverURL are set, property RE_AutoURLDetect is set to True
  7512. automatically. }
  7513. property RE_URL: KOLString read fREUrl;
  7514. {* |<#richedit>
  7515. Detected URL (valid in OnRE_OverURL and OnRE_URLClick event handlers). }
  7516. property OnRE_OverURL: TOnEvent index 0
  7517. {$IFDEF F_P} read REGetOnURL
  7518. {$ELSE DELPHI} read fOnREOverURL
  7519. {$ENDIF F_P/DELPHI} write RESetOnURL;
  7520. {* |<#richedit>
  7521. Is called when mouse is moving over URL. This can be used to set
  7522. cursor, for example, depending on type of URL (to determine URL type
  7523. read property RE_URL). }
  7524. property OnRE_URLClick: TOnEvent index 8
  7525. {$IFDEF F_P} read REGetOnURL
  7526. {$ELSE DELPHI} read fOnREURLClick
  7527. {$ENDIF F_P/DELPHI} write RESetOnURL;
  7528. {* |<#richedit>
  7529. Is called when click on URL detected. }
  7530. //property RE_SelectionBar: Boolean read REGetSelectionBar write RESetSelectionBar;
  7531. //{* ??? - don't know that is this... }
  7532. function RE_NoOLEDragDrop: PControl;
  7533. {* |<#richedit>
  7534. Just prevents drop OLE objects to the rich edit control. Seems not
  7535. working for some cases. }
  7536. //function RE_Wyswig: PControl;
  7537. function RE_Bottomless: PControl;
  7538. // finished ?
  7539. property RE_Transparent: Boolean read REGetTransparent write RESetTransparent;
  7540. {* |<#richedit>
  7541. Use this property to make richedit control transparent, instead of
  7542. Ed_Transparent or Transparent. But do not place such transparent
  7543. richedit control directly on form - it can be draw incorrectly when
  7544. form is activated and rich editr control is not current active control.
  7545. Use at least panel as a parent instead.
  7546. }
  7547. property RE_Zoom: TSmallPoint read REGetZoom write RESetZoom;
  7548. {* |<#richedit>
  7549. To set zooming for rich edit control (3.0 and above), pass X as numerator
  7550. and Y as denominator. Resulting X/Y must be between 1/64 and 64. }
  7551. {$ENDIF NOT_USE_RICHEDIT}
  7552. //========== both for Edit and RichEdit: =====================
  7553. function CanUndo: Boolean;
  7554. {* |<#richedit>
  7555. |<#edit>
  7556. |<#memo>
  7557. Returns True, if the edit (or RichEdit) control can correctly process
  7558. the EM_UNDO message. }
  7559. procedure EmptyUndoBuffer;
  7560. {* |<#richedit>
  7561. |<#edit>
  7562. |<#memo>
  7563. Reset the undo flag of an edit control, preventing undoing all previous
  7564. changes. }
  7565. function Undo: Boolean;
  7566. {* |<#richedit>
  7567. |<#edit>
  7568. |<#memo>
  7569. For a single-line edit control, the return value is always TRUE. For a
  7570. multiline edit control and RichEdit control, the return value is TRUE if
  7571. the undo operation is successful, or FALSE if the undo operation fails. }
  7572. {$IFNDEF NOT_USE_RICHEDIT}
  7573. function RE_Redo: Boolean;
  7574. {* |<#richedit>
  7575. Only for RichEdit control: Returns True if successful. }
  7576. {$ENDIF NOT_USE_RICHEDIT}
  7577. //----------------------------------------------------------------------
  7578. // DateTimePicker
  7579. property OnDTPUserString: TDTParseInputEvent read FOnDTPUserString
  7580. write FOnDTPUserString;
  7581. {* Special event to parse input from the application. Option dtpoParseInput
  7582. must be set when control is created. }
  7583. property DateTime: TDateTime read GetDateTime write SetDateTime;
  7584. {* DateTime for DateTimePicker control only. }
  7585. property Date: TDateTime read GetDate write SetDate;
  7586. {* Date only for DateTimePicker control only. }
  7587. property Time: TDateTime read GetTime write SetTime;
  7588. {* Time only for DateTimePicker control only. }
  7589. property SystemTime: TSystemTime read Get_SystemTime write Set_SystemTime;
  7590. {* Date and Time as TSystemTime. When assing, use year 0 to set "no value". }
  7591. property DateTimeRange: TDateTimeRange read GetDateTimeRange
  7592. write SetDateTimeRange;
  7593. {* DateTimePicker range. If first date in the agrument assigned is NAN,
  7594. minimum system allowed value is used as the left bound, and if the second is
  7595. NAN, maximum system allowed is used as the right one. }
  7596. property DateTimePickerColors[ Index: TDateTimePickerColor ]: TColor
  7597. read GetDateTimePickerColor write SetDateTimePickerColor;
  7598. property DateTimeFormat: KOLString write SetDateTimeFormat;
  7599. //----------------------------------------------------------------------
  7600. //----------------------------------------------------------------------
  7601. // ScrollBar
  7602. property SBMin: Longint read fSBMinMax.X write SetSBMin;
  7603. {* }
  7604. property SBMax: Longint read fSBMinMax.Y write SetSBMax;
  7605. {* }
  7606. property SBMinMax: TPoint read fSBMinMax write SetSBMinMax;
  7607. {* }
  7608. property SBPosition: Integer read fSBPosition write SetSBPosition;
  7609. {* }
  7610. property SBPageSize: Integer read fSBPageSize write SetSBPageSize;
  7611. {* }
  7612. property OnSBBeforeScroll: TOnSBBeforeScroll read FOnSBBeforeScroll write FOnSBBeforeScroll;
  7613. {* }
  7614. property OnSBScroll: TOnSBScroll read FOnSBScroll write FOnSBScroll;
  7615. {* }
  7616. function SBSetScrollInfo(const SI: TScrollInfo): Integer;
  7617. function SBGetScrollInfo(var SI: TScrollInfo): Boolean;
  7618. function GetSBMinMax: TPoint;
  7619. function GetSBPageSize: Integer;
  7620. function GetSBPosition: Integer;
  7621. //----------------------------------------------------------------------
  7622. // "Through", or "transparent" methods to simplify initial
  7623. // adjustment of controls and make non-visual designing of
  7624. // forms more easy. All these functions return @Self as a
  7625. // result, so, it is possible to use such methods immediately
  7626. // in constructing statement, concatenating it with dots, e.g.:
  7627. //
  7628. // NewButton( MyForm, 'Click here' ).PlaceUnder.ResizeParentBottom;
  7629. //
  7630. {$ENDIF GDI}
  7631. function PlaceRight: PControl;
  7632. {* Places control right (to previously created on the same parent). }
  7633. function PlaceDown: PControl;
  7634. {* Places control below (to previously created on the same parent).
  7635. Left position is not changed (thus is, kept equal to Parent.Margin). }
  7636. function PlaceUnder: PControl;
  7637. {* Places control below (to previously created one, aligning its
  7638. Left position to Left position of previous control). }
  7639. function SetSize( W, H: Integer ): PControl;
  7640. {* Changes size of a control. If W or H less or equal to 0,
  7641. correspondent size is not changed. }
  7642. {$IFDEF GDI}
  7643. function Size( W, H: Integer ): PControl;
  7644. {* Like SetSize, but provides automatic resizing of parent control
  7645. (recursively). Especially useful for aligned controls. }
  7646. function SetClientSize( W, H: Integer ): PControl;
  7647. {* Like SetSize, but works setting W = ClientWidth, H = ClientHeight.
  7648. Use this method for forms, which can not be resized (dialogs). }
  7649. {$ENDIF GDI}
  7650. function AutoSize( AutoSzOn: Boolean ): PControl;
  7651. {$IFDEF GDI}
  7652. function MakeWordWrap: PControl;
  7653. {* Determines if to autosize control (like label, button, etc.) }
  7654. function IsAutoSize: Boolean;
  7655. {* TRUE, if a control is autosizing. }
  7656. function AlignLeft( P: PControl ): PControl;
  7657. {* assigns Left := P.Left }
  7658. function AlignTop( P: PControl ): PControl;
  7659. {* assigns Top := P.Top }
  7660. function ResizeParent: PControl;
  7661. {* Resizes parent, calling ResizeParentRight and ResizeParentBottom. }
  7662. function ResizeParentRight: PControl;
  7663. {* Resizes parent right edge (Margin of parent is added to right
  7664. coordinate of a control). If called second time (for the same
  7665. parent), resizes only for increasing of right edge of parent. }
  7666. function ResizeParentBottom: PControl;
  7667. {* Resizes parent bottom edge (Margin of parent is added to
  7668. bottom coordinate of a control). }
  7669. function CenterOnParent: PControl;
  7670. {* Centers control on parent, or if applied to a form, centers
  7671. form on screen. }
  7672. function Shift( dX, dY : Integer ): PControl;
  7673. {* Moves control respectively to current position (Left := Left + dX,
  7674. Top := Top + dY). }
  7675. {$ENDIF GDI}
  7676. function SetPosition( X, Y: Integer ): PControl;
  7677. {* Moves control directly to the specified position. }
  7678. {$IFDEF GDI}
  7679. function Tabulate: PControl;
  7680. {* Call it once for form/applet to provide tabulation between controls on
  7681. form/on all forms using TAB / SHIFT+TAB and arrow keys. }
  7682. function TabulateEx: PControl;
  7683. {* Call it once for form/applet to provide tabulation between controls on
  7684. form/on all forms using TAB / SHIFT+TAB and arrow keys. Arrow keys are
  7685. used more smart, allowing go to nearest control in certain direction. }
  7686. function SetAlign( AAlign: TControlAlign ): PControl;
  7687. {* Assigns passed value to property Align, aligning control on parent,
  7688. and returns @Self (so it is "transparent" function, which can be
  7689. used to adjust control at the creation, e.g.:
  7690. ! MyLabel := NewLabel( MyForm, 'Label1' ).SetAlign( caBottom );
  7691. See also property Align. }
  7692. function PreventResizeFlicks: PControl;
  7693. {* If called, prevents resizing flicks for child controls, aligned to
  7694. right and bottom (but with a lot of code added to executable - about 3,5K).
  7695. There is sensible to set DoubleBuffered to True also to eliminate the
  7696. most of flicks.
  7697. |<br>&nbsp;&nbsp;&nbsp;
  7698. This method been applied to a form, prevents, resizing flicks for
  7699. form and all controls on the form. If it is called for applet window,
  7700. all forms are affected. And if You want, You can apply it for certain
  7701. control only - in such case only given control and its children will
  7702. be resizing without flicks (e.g., using splitter control). }
  7703. property Checked: Boolean read GetChecked write Set_Checked;
  7704. {* |<#checkbox>
  7705. |<#radiobox>
  7706. For checkbox and radiobox - if it is checked. Do not assign
  7707. value for radiobox - use SetRadioChecked instead. }
  7708. function SetChecked(const Value: Boolean): PControl;
  7709. {* |<#checkbox>
  7710. Use it to check/uncheck check box control or push button.
  7711. Do not apply it to check radio buttons - use SetRadioChecked
  7712. method below. }
  7713. function SetRadioChecked : PControl;
  7714. {* |<#radiobox>
  7715. Use it to check radio button item correctly (unchecking all
  7716. alternative ones). Actually, method Click is called, and control
  7717. itself is returned. }
  7718. function SetRadioCheckedOld: PControl;
  7719. {* |<#radiobox>
  7720. Old version of SetRadioChecked (implemented using recommended API
  7721. call. It does not work properly, if control is not visible
  7722. (together with its form). }
  7723. property Check3: TTriStateCheck read GetCheck3 write SetCheck3;
  7724. {* |<#checkbox>
  7725. State of checkbox with BS_AUTO3STATE style. }
  7726. procedure Click;
  7727. {* |<#button>
  7728. |<#checkbox>
  7729. |<#radiobox>
  7730. Emulates click on control programmatically, sending WM_COMMAND
  7731. message with BN_CLICKED code. This method is sensible only for
  7732. buttons, checkboxes and radioboxes. }
  7733. function Perform( msgcode: DWORD; wParam, lParam: Integer): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  7734. {* Sends message to control's window (created if needed). }
  7735. function Postmsg( msgcode: DWORD; wParam, lParam: Integer): Boolean; {$ifdef wince}cdecl{$else}stdcall{$endif};
  7736. {* Sends message to control's window (created if needed). }
  7737. procedure AttachProc( Proc: TWindowFunc );
  7738. {* It is possible to attach dynamically any message handler to window
  7739. procedure using this method. Last attached procedure is called first.
  7740. If procedure returns True, further processing of a message is stopped.
  7741. Attached procedure can be detached using DetachProc (but do not
  7742. attach/detach procedures during handling of attached procedure -
  7743. this can hang application). }
  7744. procedure AttachProcEx( Proc: TWindowFunc; ExecuteAfterAppletTerminated: Boolean );
  7745. {* The same as AttachProc, but a handler is executed even after terminating
  7746. the main message loop processing (i.e. after assigning true to
  7747. AppletTerminated global variable. }
  7748. function IsProcAttached( Proc: TWindowFunc ): Boolean;
  7749. {* Returns True, if given procedure is already in chain of attached
  7750. ones for given control window proc. }
  7751. procedure DetachProc( Proc: TWindowFunc );
  7752. {* Detaches procedure attached earlier using AttachProc. }
  7753. property OnDropFiles: TOnDropFiles read FOnDropFiles write SetOnDropFiles;
  7754. {* Assign this event to your handler, if You want to accept drag and drop
  7755. files from other applications such as explorer onto your control. When
  7756. this event is assigned to a control or form, this has effect also for
  7757. all its child controls too. }
  7758. property CustomData: Pointer read fCustomData write fCustomData;
  7759. {* Can be used to exend the object when new type of control added. Memory,
  7760. pointed by this pointer, released automatically in the destructor. }
  7761. property CustomObj: PObj read fCustomObj write fCustomObj;
  7762. {* Can be used to exend the object when new type of control added. Object,
  7763. pointed by this pointer, released automatically in the destructor. }
  7764. procedure SetAutoPopupMenu( PopupMenu: PObj );
  7765. {* To assign a popup menu to the control, call SetAutoPopupMenu method of
  7766. the control with popup menu object as a parameter. }
  7767. function SupportMnemonics: PControl;
  7768. {* This method provides supporting mnemonic keys in menus, buttons, checkboxes,
  7769. toolbar buttons. }
  7770. property OnScroll: TOnScroll read FOnScroll write SetOnScroll;
  7771. {* }
  7772. protected
  7773. {$IFDEF USE_DROPDOWNCOUNT}
  7774. fDropDownCount: Cardinal;
  7775. {$ENDIF}
  7776. fGraphCtlMouseEvent: TOnGraphCtlMouse;
  7777. public
  7778. {$IFDEF USE_DROPDOWNCOUNT}
  7779. property DropDownCount: Cardinal read fDropDownCount write fDropDownCount;
  7780. {$ENDIF}
  7781. protected
  7782. fPushedBtn: PControl;
  7783. fFocused: Boolean;
  7784. fEditOptions: TEditOptions;
  7785. fEditCtl: PControl;
  7786. fSetFocus: procedure of object;
  7787. fSaveCursor: HCursor;
  7788. fLeave: TOnEvent;
  7789. fKeyboardProcess: TOnMessage;
  7790. fHot: Boolean;
  7791. fPressed : boolean;
  7792. fHotCtl: PControl;
  7793. fMouseLeaveProc: TOnEvent;
  7794. fIsGroupBox: Boolean;
  7795. fIsBitBtn: Boolean;
  7796. fIsSplitter: Boolean;
  7797. fErasingBkgnd: Boolean;
  7798. fButtonIcon: HIcon;
  7799. fActivating: Boolean;
  7800. fFixingModal: Integer;
  7801. {$IFDEF USE_GRAPHCTLS}
  7802. function DoGraphCtlPrepaint: TRect;
  7803. procedure GraphicLabelPaint( DC: HDC );
  7804. procedure GraphicCheckBoxPaint( DC: HDC );
  7805. procedure GraphicCheckBoxMouse( var Msg: TMsg );
  7806. procedure GraphicRadioBoxPaint( DC: HDC );
  7807. procedure GraphicButtonPaint( DC: HDC );
  7808. procedure GraphicButtonMouse( var Msg: TMsg );
  7809. procedure GraphButtonSetFocus;
  7810. function GraphButtonKeyboardProcess( var Msg: TMsg; var Rslt: Integer ): Boolean;
  7811. procedure LeaveGraphButton( Sender: PObj );
  7812. procedure GraphicEditPaint( DC: HDC );
  7813. procedure GraphicEditMouse( var Msg: TMsg );
  7814. function EditGraphEdit: PControl;
  7815. procedure DestroyGraphEdit( Sender: PObj );
  7816. procedure LeaveGraphEdit( Sender: PObj );
  7817. procedure ChangeGraphEdit( Sender: PObj );
  7818. procedure GraphEditboxSetFocus;
  7819. procedure GraphCtlDrawFocusRect( DC: HDC; const R: TRect );
  7820. {$IFDEF GRAPHCTL_HOTTRACK}
  7821. procedure MouseLeaveFromParentOfGraphCtl( Sender: PObj );
  7822. {$ENDIF GRAPHCTL_HOTTRACK}
  7823. procedure GroupBoxPaint( DC: HDC );
  7824. {$ENDIF USE_GRAPHCTLS}
  7825. {$IFDEF KEY_PREVIEW}
  7826. protected
  7827. fKeyPreview: Boolean;
  7828. fKeyPreviewing: Boolean;
  7829. fKeyPreviewCount: Integer;
  7830. public
  7831. property KeyPreview: Boolean read fKeyPreview write fKeyPreview;
  7832. property KeyPreviewing: Boolean read fKeyPreviewing write fKeyPreviewing;
  7833. {$ENDIF KEY_PREVIEW}
  7834. protected
  7835. fAnchorLeft: Boolean; //+Sormart
  7836. fAnchorTop: Boolean; //+Sormart
  7837. fAnchorRight: Boolean;
  7838. fAnchorBottom: Boolean;
  7839. fOldWidth, fOldHeight: Integer;
  7840. procedure SetAnchorLeft(const Value: Boolean); //+Sormart
  7841. procedure SetAnchorTop(const Value: Boolean); //+Sormart
  7842. procedure SetAnchorRight( Value: Boolean );
  7843. procedure SetAnchorBottom( Value: Boolean );
  7844. public
  7845. property AnchorLeft: Boolean read fAnchorLeft write SetAnchorLeft default true; //+Sormart
  7846. property AnchorTop: Boolean read fAnchorTop write SetAnchorTop default true; //+Sormart
  7847. property AnchorRight: Boolean read fAnchorRight write SetAnchorRight;
  7848. property AnchorBottom: Boolean read fAnchorBottom write SetAnchorBottom;
  7849. function Anchor( aLeft, aTop, aRight, aBottom: Boolean ): PControl;
  7850. public
  7851. {$IFDEF USE_CONSTRUCTORS}
  7852. //------------------------------------------------------------
  7853. // constructors here:
  7854. constructor CreateWindowed( AParent: PControl; AClassName: PKOLChar; ACtl3D: Boolean );
  7855. constructor CreateApplet( const ACaption: String );
  7856. constructor CreateForm( AParent: PControl; const ACaption: String );
  7857. constructor CreateControl( AParent: PControl; AClassName: PChar; AStyle: DWORD;
  7858. ACtl3D: Boolean; Actions: PCommandActions );
  7859. constructor CreateButton( AParent: PControl; const ACaption: String );
  7860. constructor CreateBitBtn( AParent: PControl; const ACaption: String;
  7861. AOptions: TBitBtnOptions; ALayout: TGlyphLayout; AGlyphBitmap: HBitmap;
  7862. AGlyphCount: Integer);
  7863. constructor CreateLabel( AParent: PControl; const ACaption: String );
  7864. constructor CreateWordWrapLabel( AParent: PControl; const ACaption: String );
  7865. constructor CreateLabelEffect( AParent: PControl; ACaption: String; AShadowDeep: Integer );
  7866. constructor CreatePaintBox( AParent: PControl );
  7867. constructor CreateGradientPanel( AParent: PControl; AColor1, AColor2: TColor );
  7868. constructor CreateGradientPanelEx( AParent: PControl; AColor1, AColor2: TColor;
  7869. AStyle: TGradientStyle; ALayout: TGradientLayout );
  7870. constructor CreateGroupbox( AParent: PControl; const ACaption: String );
  7871. constructor CreateCheckbox( AParent: PControl; const ACaption: String );
  7872. constructor CreateRadiobox( AParent: PControl; const ACaption: String );
  7873. constructor CreateEditbox( AParent: PControl; AOptions: TEditOptions );
  7874. constructor CreatePanel( AParent: PControl; AStyle: TEdgeStyle );
  7875. constructor CreateSplitter( AParent: PControl; AMinSizePrev, AMinSizeNext: Integer;
  7876. EdgeStyle: TEdgeStyle );
  7877. constructor CreateListbox( AParent: PControl; AOptions: TListOptions );
  7878. constructor CreateCombobox( AParent: PControl; AOptions: TComboOptions );
  7879. constructor CreateCommonControl( AParent: PControl; AClassName: PChar; AStyle: DWORD;
  7880. ACtl3D: Boolean; Actions: PCommandActions );
  7881. constructor CreateRichEdit( AParent: PControl; AOptions: TEditOptions );
  7882. constructor CreateRichEdit1( AParent: PControl; AOptions: TEditOptions );
  7883. constructor CreateProgressbar( AParent: PControl );
  7884. constructor CreateProgressbarEx( AParent: PControl; AOptions: TProgressbarOptions );
  7885. constructor CreateListView( AParent: PControl; AStyle: TListViewStyle; AOptions: TListViewOptions;
  7886. AImageListSmall, AImageListNormal, AImageListState: PImageList );
  7887. constructor CreateTreeView( AParent: PControl; AOptions: TTreeViewOptions;
  7888. AImgListNormal, AImgListState: PImageList );
  7889. constructor CreateTabControl( AParent: PControl; ATabs: array of String;
  7890. AOptions: TTabControlOptions; AImgList: PImageList; AImgList1stIdx: Integer );
  7891. constructor CreateToolbar( AParent: PControl; AAlign: TControlAlign; AOptions: TToolbarOptions;
  7892. ABitmap: HBitmap; AButtons: array of PChar;
  7893. ABtnImgIdxArray: array of Integer );
  7894. {$ENDIF USE_CONSTRUCTORS}
  7895. {$IFDEF USE_CUSTOMEXTENSIONS}
  7896. {$I CUSTOM_TCONTROL_EXTENSION.inc}
  7897. {$ENDIF}
  7898. // If an option USE_CUSTOMEXTENSIONS is enabled (at the beginning of this
  7899. // unit), You can freely extend TControl definition by your own fields,
  7900. // methods and properties. This provides You with capability to extend
  7901. // TControl implementing another kinds of visual controls without deriving
  7902. // new descendant objects from TControl. This way is provided to avoid too
  7903. // large grow of executable size. You also can derive your own controls
  7904. // from TControl using standard OOP capabilities. In such case an option
  7905. // USE_CONSTRUCTORS should be turned on (see it at the start of this unit).
  7906. // If You choose this "flat" model of extending the TControl with your
  7907. // own properties, fieds, methods, events, etc. You should provide three
  7908. // inc-files: CUSTOM_TCONTROL_EXTENSION.inc, containing such definitions
  7909. // for TControl, CUSTOM_KOL_EXTENSION.inc, containing needed global
  7910. // declarations, and CUSTOM_CODE_EXTENSION.inc, the implementation of those
  7911. // two.
  7912. // Because KOL is always grow and constantly is extending by me, I also can
  7913. // add my own complements for TControl. To avoid naming conflicts, I suggest
  7914. // to use the same naming rule for all of You. Name your fields, properies, etc.
  7915. // using a form idx_SomeName, where idx is a prefix, containing several
  7916. // (at least one) letters and digits. E.g. ZK65_OnSomething.
  7917. protected
  7918. fParentCoordX: Integer;
  7919. fParentCoordY: Integer;
  7920. // last changes (1-Jul-06) from ECM [Michalichenko Eugeny, rest in peace, friend]:
  7921. //======== ListBox
  7922. private
  7923. function GetLBTopIndex: Integer;
  7924. procedure SetLBTopIndex(const Value: Integer);
  7925. public
  7926. function LBItemAtPos(X,Y: Integer): Integer;
  7927. {* |<#listbox>
  7928. Return index of item at the given position. }
  7929. property LBTopIndex: Integer read GetLBTopIndex write SetLBTopIndex;
  7930. {* |<#listbox>
  7931. Index of the first visible item in a list box}
  7932. //_________
  7933. procedure MakeScrollable;
  7934. {* Adds scrollbars to the control if its children do not fit client area. Useful for PocketPC dialog boxes. }
  7935. {$ENDIF GDI}
  7936. procedure DisableAlign;
  7937. {* Disable alignment of child controls. }
  7938. procedure EnableAlign;
  7939. {* Enable alignment of child controls. }
  7940. end;
  7941. //[END OF TControl DEFINITION]
  7942. {$IFDEF USE_MHTOOLTIP}
  7943. {$DEFINE interface}
  7944. {$I KOLMHToolTip.pas}
  7945. {$UNDEF interface}
  7946. {$ENDIF}
  7947. {$IFDEF WIN_GDI}
  7948. function ToolbarButtonRect( Toolbar: PControl; BtnID: Integer ): TRect;
  7949. {* Use this function instead of reading TControl.TBButtonRect, if you want
  7950. to have it working the same way when standard toolbar is used or GRushControl
  7951. toolbar provided in ToGRush.pas unit.
  7952. }
  7953. procedure ToolbarSetTooltips( Toolbar: PControl; BtnID1st: Integer; const Tooltips: array of PKOLChar );
  7954. {* Use this function instead of TContol.TBSetTooltips in your project, when
  7955. you use ToGRush unit.
  7956. }
  7957. function ToolbarButtonEnabled( Toolbar: PControl; BtnID: Integer ): Boolean;
  7958. {* Use this function instead of reading the property TControl.TBButtonEnabled
  7959. when tou use ToGRush unit. }
  7960. procedure EnableToolbarButton( Toolbar: PControl; BtnID: Integer; Enable: Boolean );
  7961. {* Use this procedure instead of writing the property TControl.TBButtonEnabled
  7962. when you use ToGRush unit. }
  7963. function ToolbarButtonVisible( Toolbar: PControl; BtnID: Integer ): Boolean;
  7964. {* Use this function instead of reading the property TControl.TBButtonVisible
  7965. when tou use ToGRush unit. }
  7966. procedure ShowHideToolbarButton( Toolbar: PControl; BtnID: Integer; Show: Boolean );
  7967. {* Use this procedure instead of writing the property TControl.TBButtonVisible
  7968. when you use ToGRush unit. }
  7969. function ToolbarButtonChecked( Toolbar: PControl; BtnID: Integer): Boolean;
  7970. {* }
  7971. procedure ToolbarButtonSetChecked( Toolbar: PControl; BtnID: Integer; Checked: Boolean );
  7972. {* }
  7973. {$ENDIF WIN_GDI}
  7974. var ToolbarsIDcmd: Integer = 100;
  7975. //[Paint Background PROCEDURE]
  7976. type
  7977. TOnPaintBkgnd = procedure( Sender: PControl; DC: HDC; Rect: PRect );
  7978. {* Global event definition. Used to define Global_OnPaintBackground
  7979. event placeholder. }
  7980. procedure DefaultPaintBackground( Sender: PControl; DC: HDC; Rect: PRect );
  7981. var
  7982. Global_OnPaintBkgnd: TOnPaintBkgnd = DefaultPaintBackground;
  7983. {* Global event. It is assigned in XBackgounds.pas add-on to replace
  7984. PaintBackground method for all TVisual objects, allowing great
  7985. visualization effect: transparent controls over [animated] bitmap
  7986. background. Idea:
  7987. | <a href=mailto:"bw@sunv.com">Wei&nbsp;Bao</a>. Implementation:
  7988. | <a href=mailto:"bonanzas@xcl.cjb.net">Kladov&nbsp;Vladimir</a>. }
  7989. procedure DummyPaintProc( Sender: PControl; DC: HDC );
  7990. //[GetShiftState DECLARATION]
  7991. function GetShiftState: DWORD;
  7992. {* Returns shift state. }
  7993. {$IFDEF WIN_GDI}
  7994. //[WndProcXXX DECLARATIONS]
  7995. function WndProcMouse( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7996. function WndProcKeybd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7997. function WndProcDummy( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7998. function WndProcMenu( Sender: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  7999. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  8000. function WndProcBtnReturnClick( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  8001. {$ENDIF}
  8002. function AutoMinimizeApplet(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  8003. {* By Sergey Shishmintzev.
  8004. Attach this handler to your modal dialog form handle to provide automatic
  8005. minimization of all other forms in the application together with the dialog. }
  8006. //[InitCommonXXXX DECLARATIONS]
  8007. procedure InitCommonControlSizeNotify( Ctrl: PControl );
  8008. procedure InitCommonControlCommonNotify( Ctrl: PControl );
  8009. //[Buffered Draw DECLARATIONS]
  8010. procedure DummyAttachProcExtension ( DynHandlers: PList );
  8011. {$ifdef win32}
  8012. procedure TransparentAttachProcExtension ( DynHandlers: PList );
  8013. {$endif win32}
  8014. {$IFNDEF SMALLEST_CODE}
  8015. var Global_AttachProcExtension: procedure( DynHandlers: PList ) = DummyAttachProcExtension;
  8016. {$ENDIF}
  8017. {$ENDIF WIN_GDI}
  8018. var HelpFilePath: PChar;
  8019. {* Path to application help file. If not assigned, application path with
  8020. extension replaced to '.hlp' used. To use '.chm' file (HtmlHelp),
  8021. call AssignHtmlHelp with a path to a html help file (or a name). }
  8022. {$IFDEF WIN_GDI}
  8023. //[Html Help DECLARATIONS]
  8024. procedure AssignHtmlHelp( const HtmlHelpPath: KOLString );
  8025. procedure HtmlHelpCommand( Wnd: HWnd; const HelpFilePath: String; Cmd, Data: Integer );
  8026. {* Use this wrapper procedure to call HtmlHelp API function. }
  8027. //+++++++++++ HTML HELP DEFINITIONS SECTION:
  8028. // this section is from
  8029. // HTML Help API Interface Unit
  8030. // Copyright (c) 1999 The Helpware Group
  8031. // provided for KOL by Alexey Babenko
  8032. const
  8033. HH_DISPLAY_TOPIC = $0000; {**}
  8034. HH_HELP_FINDER = $0000; // WinHelp equivalent
  8035. HH_DISPLAY_TOC = $0001; // not currently implemented
  8036. HH_DISPLAY_INDEX = $0002; // not currently implemented
  8037. HH_DISPLAY_SEARCH = $0003; // not currently implemented
  8038. HH_SET_WIN_TYPE = $0004;
  8039. HH_GET_WIN_TYPE = $0005;
  8040. HH_GET_WIN_HANDLE = $0006;
  8041. HH_ENUM_INFO_TYPE = $0007; // Get Info type name, call repeatedly to enumerate, -1 at end
  8042. HH_SET_INFO_TYPE = $0008; // Add Info type to filter.
  8043. HH_SYNC = $0009;
  8044. HH_RESERVED1 = $000A;
  8045. HH_RESERVED2 = $000B;
  8046. HH_RESERVED3 = $000C;
  8047. HH_KEYWORD_LOOKUP = $000D;
  8048. HH_DISPLAY_TEXT_POPUP = $000E; // display string resource id or text in a popup window
  8049. HH_HELP_CONTEXT = $000F; {**}// display mapped numeric value in dwData
  8050. HH_TP_HELP_CONTEXTMENU = $0010; // text popup help, same as WinHelp HELP_CONTEXTMENU
  8051. HH_TP_HELP_WM_HELP = $0011; // text popup help, same as WinHelp HELP_WM_HELP
  8052. HH_CLOSE_ALL = $0012; // close all windows opened directly or indirectly by the caller
  8053. HH_ALINK_LOOKUP = $0013; // ALink version of HH_KEYWORD_LOOKUP
  8054. HH_GET_LAST_ERROR = $0014; // not currently implemented // See HHERROR.h
  8055. HH_ENUM_CATEGORY = $0015; // Get category name, call repeatedly to enumerate, -1 at end
  8056. HH_ENUM_CATEGORY_IT = $0016; // Get category info type members, call repeatedly to enumerate, -1 at end
  8057. HH_RESET_IT_FILTER = $0017; // Clear the info type filter of all info types.
  8058. HH_SET_INCLUSIVE_FILTER = $0018; // set inclusive filtering method for untyped topics to be included in display
  8059. HH_SET_EXCLUSIVE_FILTER = $0019; // set exclusive filtering method for untyped topics to be excluded from display
  8060. HH_INITIALIZE = $001C; // Initializes the help system.
  8061. HH_UNINITIALIZE = $001D; // Uninitializes the help system.
  8062. HH_PRETRANSLATEMESSAGE = $00fd; // Pumps messages. (NULL, NULL, MSG*).
  8063. HH_SET_GLOBAL_PROPERTY = $00fc; // Set a global property. (NULL, NULL, HH_GPROP)
  8064. { window properties }
  8065. const
  8066. HHWIN_PROP_TAB_AUTOHIDESHOW = $00000001; // (1 << 0) Automatically hide/show tri-pane window
  8067. HHWIN_PROP_ONTOP = $00000002; // (1 << 1) Top-most window
  8068. HHWIN_PROP_NOTITLEBAR = $00000004; // (1 << 2) no title bar
  8069. HHWIN_PROP_NODEF_STYLES = $00000008; // (1 << 3) no default window styles (only HH_WINTYPE.dwStyles)
  8070. HHWIN_PROP_NODEF_EXSTYLES = $00000010; // (1 << 4) no default extended window styles (only HH_WINTYPE.dwExStyles)
  8071. HHWIN_PROP_TRI_PANE = $00000020; // (1 << 5) use a tri-pane window
  8072. HHWIN_PROP_NOTB_TEXT = $00000040; // (1 << 6) no text on toolbar buttons
  8073. HHWIN_PROP_POST_QUIT = $00000080; // (1 << 7) post WM_QUIT message when window closes
  8074. HHWIN_PROP_AUTO_SYNC = $00000100; // (1 << 8) automatically ssync contents and index
  8075. HHWIN_PROP_TRACKING = $00000200; // (1 << 9) send tracking notification messages
  8076. HHWIN_PROP_TAB_SEARCH = $00000400; // (1 << 10) include search tab in navigation pane
  8077. HHWIN_PROP_TAB_HISTORY = $00000800; // (1 << 11) include history tab in navigation pane
  8078. HHWIN_PROP_TAB_FAVORITES = $00001000; // (1 << 12) include favorites tab in navigation pane
  8079. HHWIN_PROP_CHANGE_TITLE = $00002000; // (1 << 13) Put current HTML title in title bar
  8080. HHWIN_PROP_NAV_ONLY_WIN = $00004000; // (1 << 14) Only display the navigation window
  8081. HHWIN_PROP_NO_TOOLBAR = $00008000; // (1 << 15) Don't display a toolbar
  8082. HHWIN_PROP_MENU = $00010000; // (1 << 16) Menu
  8083. HHWIN_PROP_TAB_ADVSEARCH = $00020000; // (1 << 17) Advanced FTS UI.
  8084. HHWIN_PROP_USER_POS = $00040000; // (1 << 18) After initial creation, user controls window size/position
  8085. HHWIN_PROP_TAB_CUSTOM1 = $00080000; // (1 << 19) Use custom tab #1
  8086. HHWIN_PROP_TAB_CUSTOM2 = $00100000; // (1 << 20) Use custom tab #2
  8087. HHWIN_PROP_TAB_CUSTOM3 = $00200000; // (1 << 21) Use custom tab #3
  8088. HHWIN_PROP_TAB_CUSTOM4 = $00400000; // (1 << 22) Use custom tab #4
  8089. HHWIN_PROP_TAB_CUSTOM5 = $00800000; // (1 << 23) Use custom tab #5
  8090. HHWIN_PROP_TAB_CUSTOM6 = $01000000; // (1 << 24) Use custom tab #6
  8091. HHWIN_PROP_TAB_CUSTOM7 = $02000000; // (1 << 25) Use custom tab #7
  8092. HHWIN_PROP_TAB_CUSTOM8 = $04000000; // (1 << 26) Use custom tab #8
  8093. HHWIN_PROP_TAB_CUSTOM9 = $08000000; // (1 << 27) Use custom tab #9
  8094. HHWIN_TB_MARGIN = $10000000; // (1 << 28) the window type has a margin
  8095. { window parameters }
  8096. const
  8097. HHWIN_PARAM_PROPERTIES = $00000002; // (1 << 1) valid fsWinProperties
  8098. HHWIN_PARAM_STYLES = $00000004; // (1 << 2) valid dwStyles
  8099. HHWIN_PARAM_EXSTYLES = $00000008; // (1 << 3) valid dwExStyles
  8100. HHWIN_PARAM_RECT = $00000010; // (1 << 4) valid rcWindowPos
  8101. HHWIN_PARAM_NAV_WIDTH = $00000020; // (1 << 5) valid iNavWidth
  8102. HHWIN_PARAM_SHOWSTATE = $00000040; // (1 << 6) valid nShowState
  8103. HHWIN_PARAM_INFOTYPES = $00000080; // (1 << 7) valid apInfoTypes
  8104. HHWIN_PARAM_TB_FLAGS = $00000100; // (1 << 8) valid fsToolBarFlags
  8105. HHWIN_PARAM_EXPANSION = $00000200; // (1 << 9) valid fNotExpanded
  8106. HHWIN_PARAM_TABPOS = $00000400; // (1 << 10) valid tabpos
  8107. HHWIN_PARAM_TABORDER = $00000800; // (1 << 11) valid taborder
  8108. HHWIN_PARAM_HISTORY_COUNT = $00001000; // (1 << 12) valid cHistory
  8109. HHWIN_PARAM_CUR_TAB = $00002000; // (1 << 13) valid curNavType
  8110. { button constants }
  8111. const
  8112. HHWIN_BUTTON_EXPAND = $00000002; // (1 << 1) Expand/contract button
  8113. HHWIN_BUTTON_BACK = $00000004; // (1 << 2) Back button
  8114. HHWIN_BUTTON_FORWARD = $00000008; // (1 << 3) Forward button
  8115. HHWIN_BUTTON_STOP = $00000010; // (1 << 4) Stop button
  8116. HHWIN_BUTTON_REFRESH = $00000020; // (1 << 5) Refresh button
  8117. HHWIN_BUTTON_HOME = $00000040; // (1 << 6) Home button
  8118. HHWIN_BUTTON_BROWSE_FWD = $00000080; // (1 << 7) not implemented
  8119. HHWIN_BUTTON_BROWSE_BCK = $00000100; // (1 << 8) not implemented
  8120. HHWIN_BUTTON_NOTES = $00000200; // (1 << 9) not implemented
  8121. HHWIN_BUTTON_CONTENTS = $00000400; // (1 << 10) not implemented
  8122. HHWIN_BUTTON_SYNC = $00000800; // (1 << 11) Sync button
  8123. HHWIN_BUTTON_OPTIONS = $00001000; // (1 << 12) Options button
  8124. HHWIN_BUTTON_PRINT = $00002000; // (1 << 13) Print button
  8125. HHWIN_BUTTON_INDEX = $00004000; // (1 << 14) not implemented
  8126. HHWIN_BUTTON_SEARCH = $00008000; // (1 << 15) not implemented
  8127. HHWIN_BUTTON_HISTORY = $00010000; // (1 << 16) not implemented
  8128. HHWIN_BUTTON_FAVORITES = $00020000; // (1 << 17) not implemented
  8129. HHWIN_BUTTON_JUMP1 = $00040000; // (1 << 18)
  8130. HHWIN_BUTTON_JUMP2 = $00080000; // (1 << 19)
  8131. HHWIN_BUTTON_ZOOM = $00100000; // (1 << 20)
  8132. HHWIN_BUTTON_TOC_NEXT = $00200000; // (1 << 21)
  8133. HHWIN_BUTTON_TOC_PREV = $00400000; // (1 << 22)
  8134. HHWIN_DEF_BUTTONS = (HHWIN_BUTTON_EXPAND
  8135. OR HHWIN_BUTTON_BACK
  8136. OR HHWIN_BUTTON_OPTIONS
  8137. OR HHWIN_BUTTON_PRINT);
  8138. { Button IDs }
  8139. const
  8140. IDTB_EXPAND = 200;
  8141. IDTB_CONTRACT = 201;
  8142. IDTB_STOP = 202;
  8143. IDTB_REFRESH = 203;
  8144. IDTB_BACK = 204;
  8145. IDTB_HOME = 205;
  8146. IDTB_SYNC = 206;
  8147. IDTB_PRINT = 207;
  8148. IDTB_OPTIONS = 208;
  8149. IDTB_FORWARD = 209;
  8150. IDTB_NOTES = 210; // not implemented
  8151. IDTB_BROWSE_FWD = 211;
  8152. IDTB_BROWSE_BACK = 212;
  8153. IDTB_CONTENTS = 213; // not implemented
  8154. IDTB_INDEX = 214; // not implemented
  8155. IDTB_SEARCH = 215; // not implemented
  8156. IDTB_HISTORY = 216; // not implemented
  8157. IDTB_FAVORITES = 217; // not implemented
  8158. IDTB_JUMP1 = 218;
  8159. IDTB_JUMP2 = 219;
  8160. IDTB_CUSTOMIZE = 221;
  8161. IDTB_ZOOM = 222;
  8162. IDTB_TOC_NEXT = 223;
  8163. IDTB_TOC_PREV = 224;
  8164. { Notification codes }
  8165. const
  8166. HHN_FIRST = (0-860);
  8167. HHN_LAST = (0-879);
  8168. HHN_NAVCOMPLETE = (HHN_FIRST-0);
  8169. HHN_TRACK = (HHN_FIRST-1);
  8170. HHN_WINDOW_CREATE = (HHN_FIRST-2);
  8171. type
  8172. {*** Used by command HH_GET_LAST_ERROR
  8173. NOTE: Not part of the htmlhelp.h but documented in HH Workshop help
  8174. You must call SysFreeString(xx.description) to free BSTR
  8175. }
  8176. tagHH_LAST_ERROR = {$ifndef wince}packed{$endif} record
  8177. cbStruct: Integer; // sizeof this structure
  8178. hr: Integer; // Specifies the last error code.
  8179. description: PWideChar; // (BSTR) Specifies a Unicode string containing a description of the error.
  8180. end;
  8181. HH_LAST_ERROR = tagHH_LAST_ERROR;
  8182. THHLastError = tagHH_LAST_ERROR;
  8183. type
  8184. {*** Notify event info for HHN_NAVCOMPLETE, HHN_WINDOW_CREATE }
  8185. PHHNNotify = ^THHNNotify;
  8186. tagHHN_NOTIFY = {$ifndef wince}packed{$endif} record
  8187. hdr: TNMHdr;
  8188. pszUrl: PChar; //PCSTR: Multi-byte, null-terminated string
  8189. end;
  8190. HHN_NOTIFY = tagHHN_NOTIFY;
  8191. THHNNotify = tagHHN_NOTIFY;
  8192. {** Use by command HH_DISPLAY_TEXT_POPUP}
  8193. PHHPopup = ^THHPopup;
  8194. tagHH_POPUP = {$ifndef wince}packed{$endif} record
  8195. cbStruct: Integer; // sizeof this structure
  8196. hinst: HINST; // instance handle for string resource
  8197. idString: cardinal; // string resource id, or text id if pszFile is specified in HtmlHelp call
  8198. pszText: PChar; // used if idString is zero
  8199. pt: TPOINT; // top center of popup window
  8200. clrForeground: COLORREF; // use -1 for default
  8201. clrBackground: COLORREF; // use -1 for default
  8202. rcMargins: TRect; // amount of space between edges of window and text, -1 for each member to ignore
  8203. pszFont: PChar; // facename, point size, char set, BOLD ITALIC UNDERLINE
  8204. end;
  8205. HH_POPUP = tagHH_POPUP;
  8206. THHPopup = tagHH_POPUP;
  8207. {** Use by commands - HH_ALINK_LOOKUP, HH_KEYWORD_LOOKUP}
  8208. PHHAKLink = ^THHAKLink;
  8209. tagHH_AKLINK = {$ifndef wince}packed{$endif} record
  8210. cbStruct: integer; // sizeof this structure
  8211. fReserved: BOOL; // must be FALSE (really!)
  8212. pszKeywords: PChar; // semi-colon separated keywords
  8213. pszUrl: PChar; // URL to jump to if no keywords found (may be NULL)
  8214. pszMsgText: PChar; // Message text to display in MessageBox if pszUrl is NULL and no keyword match
  8215. pszMsgTitle: PChar; // Message text to display in MessageBox if pszUrl is NULL and no keyword match
  8216. pszWindow: PChar; // Window to display URL in
  8217. fIndexOnFail: BOOL; // Displays index if keyword lookup fails.
  8218. end;
  8219. HH_AKLINK = tagHH_AKLINK;
  8220. THHAKLink = tagHH_AKLINK;
  8221. const
  8222. HHWIN_NAVTYPE_TOC = 0;
  8223. HHWIN_NAVTYPE_INDEX = 1;
  8224. HHWIN_NAVTYPE_SEARCH = 2;
  8225. HHWIN_NAVTYPE_FAVORITES = 3;
  8226. HHWIN_NAVTYPE_HISTORY = 4; // not implemented
  8227. HHWIN_NAVTYPE_AUTHOR = 5;
  8228. HHWIN_NAVTYPE_CUSTOM_FIRST = 11;
  8229. const
  8230. IT_INCLUSIVE = 0;
  8231. IT_EXCLUSIVE = 1;
  8232. IT_HIDDEN = 2;
  8233. type
  8234. PHHEnumIT = ^THHEnumIT;
  8235. tagHH_ENUM_IT = {$ifndef wince}packed{$endif} record //tagHH_ENUM_IT, HH_ENUM_IT, *PHH_ENUM_IT
  8236. cbStruct: Integer; // size of this structure
  8237. iType: Integer; // the type of the information type ie. Inclusive, Exclusive, or Hidden
  8238. pszCatName: PAnsiChar; // Set to the name of the Category to enumerate the info types in a category; else NULL
  8239. pszITName: PAnsiChar; // volitile pointer to the name of the infotype. Allocated by call. Caller responsible for freeing
  8240. pszITDescription: PAnsiChar; // volitile pointer to the description of the infotype.
  8241. end;
  8242. THHEnumIT = tagHH_ENUM_IT;
  8243. type
  8244. PHHEnumCat = ^THHEnumCat;
  8245. tagHH_ENUM_CAT = {$ifndef wince}packed{$endif} record //tagHH_ENUM_CAT, HH_ENUM_CAT, *PHH_ENUM_CAT
  8246. cbStruct: Integer; // size of this structure
  8247. pszCatName: PAnsiChar; // volitile pointer to the category name
  8248. pszCatDescription: PAnsiChar; // volitile pointer to the category description
  8249. end;
  8250. THHEnumCat = tagHH_ENUM_CAT;
  8251. type
  8252. PHHSetInfoType = ^THHSetInfoType;
  8253. tagHH_SET_INFOTYPE = {$ifndef wince}packed{$endif} record //tagHH_SET_INFOTYPE, HH_SET_INFOTYPE, *PHH_SET_INFOTYPE
  8254. cbStruct: Integer; // the size of this structure
  8255. pszCatName: PAnsiChar; // the name of the category, if any, the InfoType is a member of.
  8256. pszInfoTypeName: PAnsiChar; // the name of the info type to add to the filter
  8257. end;
  8258. THHSetInfoType = tagHH_SET_INFOTYPE;
  8259. type
  8260. HH_INFOTYPE = DWORD;
  8261. THHInfoType = HH_INFOTYPE;
  8262. PHHInfoType = ^THHInfoType; //PHH_INFOTYPE
  8263. const
  8264. HHWIN_NAVTAB_TOP = 0;
  8265. HHWIN_NAVTAB_LEFT = 1;
  8266. HHWIN_NAVTAB_BOTTOM = 2;
  8267. const
  8268. HH_MAX_TABS = 19; // maximum number of tabs
  8269. const
  8270. HH_TAB_CONTENTS = 0;
  8271. HH_TAB_INDEX = 1;
  8272. HH_TAB_SEARCH = 2;
  8273. HH_TAB_FAVORITES = 3;
  8274. HH_TAB_HISTORY = 4;
  8275. HH_TAB_AUTHOR = 5;
  8276. HH_TAB_CUSTOM_FIRST = 11;
  8277. HH_TAB_CUSTOM_LAST = HH_MAX_TABS;
  8278. HH_MAX_TABS_CUSTOM = (HH_TAB_CUSTOM_LAST - HH_TAB_CUSTOM_FIRST + 1);
  8279. { HH_DISPLAY_SEARCH Command Related Structures and Constants }
  8280. const
  8281. HH_FTS_DEFAULT_PROXIMITY = (-1);
  8282. type
  8283. {** Used by command HH_DISPLAY_SEARCH}
  8284. PHHFtsQuery = ^THHFtsQuery;
  8285. tagHH_FTS_QUERY = {$ifndef wince}packed{$endif} record //tagHH_FTS_QUERY, HH_FTS_QUERY
  8286. cbStruct: integer; // Sizeof structure in bytes.
  8287. fUniCodeStrings: BOOL; // TRUE if all strings are unicode.
  8288. pszSearchQuery: PChar; // String containing the search query.
  8289. iProximity: LongInt; // Word proximity.
  8290. fStemmedSearch: Bool; // TRUE for StemmedSearch only.
  8291. fTitleOnly: Bool; // TRUE for Title search only.
  8292. fExecute: Bool; // TRUE to initiate the search.
  8293. pszWindow: PChar; // Window to display in
  8294. end;
  8295. THHFtsQuery = tagHH_FTS_QUERY;
  8296. { HH_WINTYPE Structure }
  8297. type
  8298. {** Used by commands HH_GET_WIN_TYPE, HH_SET_WIN_TYPE}
  8299. PHHWinType = ^THHWinType;
  8300. tagHH_WINTYPE = {$ifndef wince}packed{$endif} record //tagHH_WINTYPE, HH_WINTYPE, *PHH_WINTYPE;
  8301. cbStruct: Integer; // IN: size of this structure including all Information Types
  8302. fUniCodeStrings: BOOL; // IN/OUT: TRUE if all strings are in UNICODE
  8303. pszType: PChar; // IN/OUT: Name of a type of window
  8304. fsValidMembers: DWORD; // IN: Bit flag of valid members (HHWIN_PARAM_)
  8305. fsWinProperties: DWORD; // IN/OUT: Properties/attributes of the window (HHWIN_)
  8306. pszCaption: PChar; // IN/OUT: Window title
  8307. dwStyles: DWORD; // IN/OUT: Window styles
  8308. dwExStyles: DWORD; // IN/OUT: Extended Window styles
  8309. rcWindowPos: TRect; // IN: Starting position, OUT: current position
  8310. nShowState: Integer; // IN: show state (e.g., SW_SHOW)
  8311. hwndHelp: HWND; // OUT: window handle
  8312. hwndCaller: HWND; // OUT: who called this window
  8313. paInfoTypes: PHHInfoType; // IN: Pointer to an array of Information Types
  8314. { The following members are only valid if HHWIN_PROP_TRI_PANE is set }
  8315. hwndToolBar: HWND; // OUT: toolbar window in tri-pane window
  8316. hwndNavigation: HWND; // OUT: navigation window in tri-pane window
  8317. hwndHTML: HWND; // OUT: window displaying HTML in tri-pane window
  8318. iNavWidth: Integer; // IN/OUT: width of navigation window
  8319. rcHTML: TRect; // OUT: HTML window coordinates
  8320. pszToc: PChar; // IN: Location of the table of contents file
  8321. pszIndex: PChar; // IN: Location of the index file
  8322. pszFile: PChar; // IN: Default location of the html file
  8323. pszHome: PChar; // IN/OUT: html file to display when Home button is clicked
  8324. fsToolBarFlags: DWORD; // IN: flags controling the appearance of the toolbar (HHWIN_BUTTON_)
  8325. fNotExpanded: BOOL; // IN: TRUE/FALSE to contract or expand, OUT: current state
  8326. curNavType: Integer; // IN/OUT: UI to display in the navigational pane
  8327. tabpos: Integer; // IN/OUT: HHWIN_NAVTAB_TOP, HHWIN_NAVTAB_LEFT, or HHWIN_NAVTAB_BOTTOM
  8328. idNotify: Integer; // IN: ID to use for WM_NOTIFY messages
  8329. tabOrder: packed array[0..HH_MAX_TABS] of Byte; // IN/OUT: tab order: Contents, Index, Search, History, Favorites, Reserved 1-5, Custom tabs
  8330. cHistory: Integer; // IN/OUT: number of history items to keep (default is 30)
  8331. pszJump1: PChar; // Text for HHWIN_BUTTON_JUMP1
  8332. pszJump2: PChar; // Text for HHWIN_BUTTON_JUMP2
  8333. pszUrlJump1: PChar; // URL for HHWIN_BUTTON_JUMP1
  8334. pszUrlJump2: PChar; // URL for HHWIN_BUTTON_JUMP2
  8335. rcMinSize: TRect; // Minimum size for window (ignored in version 1)
  8336. cbInfoTypes: Integer; // size of paInfoTypes;
  8337. pszCustomTabs: PChar; // multiple zero-terminated strings
  8338. end;
  8339. HH_WINTYPE = tagHH_WINTYPE;
  8340. THHWinType = tagHH_WINTYPE;
  8341. const
  8342. HHACT_TAB_CONTENTS = 0;
  8343. HHACT_TAB_INDEX = 1;
  8344. HHACT_TAB_SEARCH = 2;
  8345. HHACT_TAB_HISTORY = 3;
  8346. HHACT_TAB_FAVORITES = 4;
  8347. HHACT_EXPAND = 5;
  8348. HHACT_CONTRACT = 6;
  8349. HHACT_BACK = 7;
  8350. HHACT_FORWARD = 8;
  8351. HHACT_STOP = 9;
  8352. HHACT_REFRESH = 10;
  8353. HHACT_HOME = 11;
  8354. HHACT_SYNC = 12;
  8355. HHACT_OPTIONS = 13;
  8356. HHACT_PRINT = 14;
  8357. HHACT_HIGHLIGHT = 15;
  8358. HHACT_CUSTOMIZE = 16;
  8359. HHACT_JUMP1 = 17;
  8360. HHACT_JUMP2 = 18;
  8361. HHACT_ZOOM = 19;
  8362. HHACT_TOC_NEXT = 20;
  8363. HHACT_TOC_PREV = 21;
  8364. HHACT_NOTES = 22;
  8365. HHACT_LAST_ENUM = 23;
  8366. type
  8367. {*** Notify event info for HHN_TRACK }
  8368. PHHNTrack = ^THHNTrack;
  8369. tagHHNTRACK = {$ifndef wince}packed{$endif} record //tagHHNTRACK, HHNTRACK;
  8370. hdr: TNMHdr;
  8371. pszCurUrl: PChar; // Multi-byte, null-terminated string
  8372. idAction: Integer; // HHACT_ value
  8373. phhWinType: PHHWinType; // Current window type structure
  8374. end;
  8375. HHNTRACK = tagHHNTRACK;
  8376. THHNTrack = tagHHNTRACK;
  8377. ///////////////////////////////////////////////////////////////////////////////
  8378. //
  8379. // Global Control Properties.
  8380. //
  8381. const
  8382. HH_GPROPID_SINGLETHREAD = 1; // VARIANT_BOOL: True for single thread
  8383. HH_GPROPID_TOOLBAR_MARGIN = 2; // long: Provides a left/right margin around the toolbar.
  8384. HH_GPROPID_UI_LANGUAGE = 3; // long: LangId of the UI.
  8385. HH_GPROPID_CURRENT_SUBSET = 4; // BSTR: Current subset.
  8386. HH_GPROPID_CONTENT_LANGUAGE = 5; // long: LandId for desired content.
  8387. type
  8388. tagHH_GPROPID = HH_GPROPID_SINGLETHREAD..HH_GPROPID_CONTENT_LANGUAGE; //tagHH_GPROPID, HH_GPROPID
  8389. HH_GPROPID = tagHH_GPROPID;
  8390. THHGPropID = HH_GPROPID;
  8391. ///////////////////////////////////////////////////////////////////////////////
  8392. //
  8393. // Global Property structure
  8394. //
  8395. {type
  8396. PHHGlobalProperty = ^THHGlobalProperty;
  8397. tagHH_GLOBAL_PROPERTY = record //tagHH_GLOBAL_PROPERTY, HH_GLOBAL_PROPERTY
  8398. id: THHGPropID;
  8399. Dummy: Integer; // Added to enforce 8-byte packing
  8400. var_: VARIANT;
  8401. end;
  8402. HH_GLOBAL_PROPERTY = tagHH_GLOBAL_PROPERTY;
  8403. THHGlobalProperty = tagHH_GLOBAL_PROPERTY;}
  8404. //[END OF HTMLHELP DECLARATIONS]
  8405. {$ENDIF WIN_GDI}
  8406. {$IFDEF WIN_GDI}
  8407. //[GetCtlBrush DECLARATIONS]
  8408. function SimpleGetCtlBrushHandle( Sender: PControl ): HBrush;
  8409. var
  8410. Global_GetCtlBrushHandle: function( Sender: PControl ): HBrush = SimpleGetCtlBrushHandle;
  8411. {* Is called to obtain brush handle. }
  8412. {$ENDIF WIN_GDI}
  8413. Global_Align: procedure( Sender: PObj ) = DummyObjProc;
  8414. {* Is set to perform aligning of control, and only if property Align
  8415. is changed for TControl, or SetAlign method is called for it. }
  8416. {$IFDEF WIN_GDI}
  8417. //[WndFunc DECLARATION]
  8418. function WndFunc( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  8419. : Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  8420. {* Global message handler for window. Redirects all messages to
  8421. destination windows, obtaining target TControl object address from
  8422. window itself, using GetProp API call. }
  8423. {$ENDIF WIN_GDI} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  8424. //[Applet VARIABLES]
  8425. var AppletRunning: Boolean;
  8426. {* Is set to True while message loop is processing (in Run procedure). }
  8427. AppletTerminated: Boolean;
  8428. {* Is set to True when message loop is terminated. }
  8429. Applet: PControl;
  8430. {* Applet window object. Actually, can be set to main form if program
  8431. not needed in special applet button window (useful to make applet
  8432. button invisible on taskbar, or to have several forms with single
  8433. applet button - crete it in that case using NewApplet). }
  8434. AppButtonUsed: Boolean;
  8435. {* True if special window to represent applet button (may be invisible)
  8436. is used. If no, every form is represented with its own taskbar button
  8437. (always visible). }
  8438. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  8439. //[Screen DECLARATIONS]
  8440. ScreenCursor: HCursor;
  8441. {* Set this global variable to override any cursor settings of current
  8442. form or control. }
  8443. function ScreenWidth: Integer;
  8444. {* Returns screen width in pixels. }
  8445. function ScreenHeight: Integer;
  8446. {* Returns screen height in pixels. }
  8447. //[Status DECLARATIONS]
  8448. type
  8449. TStatusOption = ( soNoSizeGrip, soTop );
  8450. {* Options available for status bars. }
  8451. TStatusOptions = Set of TStatusOption;
  8452. {* Status bar options. }
  8453. procedure DrawFormattedText( Ctl: PControl; DC: HDC; var R: TRect; Flags: DWORD {EditCtl: Boolean} );
  8454. {* This procedure can be useful to draw control's text in custom-defined controls. }
  8455. {$IFDEF USE_GRAPHCTLS}
  8456. {$IFDEF GRAPHCTL_XPSTYLES}
  8457. var DoNotDrawGraphCtlsUsingXPStyles: Boolean;
  8458. procedure DrawFormattedTextXP( Theme: THandle; Ctl: PControl; DC: HDC;
  8459. var R: TRect; CtlType, CtlStates, Flags1, Flags2: Integer );
  8460. {* This procedure can be useful to draw control's text in custom-defined controls. }
  8461. {$ENDIF}
  8462. function _NewGraphCtl( AParent: PControl; ATabStop: Boolean ): PControl;
  8463. {* Creates graphic control basics. }
  8464. function NewGraphLabel( AParent: PControl; const ACaption: String ): PControl;
  8465. {* Creates graphic label, which does not require a window handle. }
  8466. function NewWordWrapGraphLabel( AParent: PControl; const ACaption: KOLString ): PControl;
  8467. {* Creates graphic label, which does not require a window handle. }
  8468. function NewGraphPaintBox( AParent: PControl ): PControl;
  8469. {* Creates graphic paint box (just the same as graphic label, but with empty Caption). }
  8470. function NewGraphCheckBox( AParent: PControl; const ACaption: KOLString ): PControl;
  8471. {* Creates graphic checkbox. }
  8472. function NewGraphRadioBox( AParent: PControl; const ACaption: KOLString ): PControl;
  8473. {* Creates graphic radiobox. }
  8474. function NewGraphButton( AParent: PControl; const ACaption: KOLString ): PControl;
  8475. {* Creates graphic button. }
  8476. function NewGraphEditbox( AParent: PControl; Options: TEditOptions ): PControl;
  8477. {* Creates graphic edit box. To do editing, this box should be replaced with
  8478. real edit box with a handle (actually, it is enough to place an edit box
  8479. on the same Parent having the same BoundsRect). }
  8480. {$ENDIF USE_GRAPHCTLS}
  8481. {$ENDIF WIN_GDI}
  8482. //[Run DECLARATION]
  8483. procedure Run( var AppletWnd: PControl );
  8484. {* |<#appbutton>
  8485. Call this procedure to process messages loop of your program.
  8486. Pass here pointer to applet button object (if You have created it
  8487. - see NewApplet) or your main form object of type PControl (created
  8488. using NewForm).
  8489. |<br><br>
  8490. |<h1 align=center><font color=#FF8040><a name="visual_objects_constructors"></a>
  8491. Visual objects constructing functions
  8492. |</font></h1>
  8493. Following constructing functions for visual controls are available:
  8494. |#control
  8495. }
  8496. {$IFDEF WIN_GDI}
  8497. procedure TerminateExecution( var AppletWnd: PControl );
  8498. //[Applet FUNCTIONS DECLARATIONS]
  8499. procedure AppletMinimize;
  8500. {* Minimizes the application (Applet should be assigned to have effect). }
  8501. procedure AppletHide;
  8502. {* Minimizes and hides application. }
  8503. procedure AppletRestore;
  8504. {* Restores Applet when minimized. }
  8505. {$IFDEF USE_OnIdle}
  8506. //[Idle handler DECALRATIONS]
  8507. {YS+}
  8508. procedure RegisterIdleHandler( const OnIdle: TOnEvent );
  8509. {* Registers new Idle handler. Idle handler is called each time when
  8510. message queue becomes empty. }
  8511. procedure UnRegisterIdleHandler( const OnIdle: TOnEvent );
  8512. {* Unregisters Idle handler. }
  8513. {YS-}
  8514. {$ENDIF USE_OnIdle}
  8515. //[InitCommonXXXX ANOTHER DECLARATIONS]
  8516. {* ComCtrl32 controls initialization. }
  8517. {$ifdef win32}
  8518. procedure InitCommonControls; {$ifdef wince}cdecl{$else}stdcall{$endif};
  8519. {$endif win32}
  8520. procedure DoInitCommonControls( dwICC: DWORD );
  8521. {* Calls extended initialization for Common Controls (from ComCtrl32).
  8522. Pass one of following constants:
  8523. |<pre>
  8524. ICC_LISTVIEW_CLASSES = $00000001; // listview, header
  8525. ICC_TREEVIEW_CLASSES = $00000002; // treeview, tooltips
  8526. ICC_BAR_CLASSES = $00000004; // toolbar, statusbar, trackbar, tooltips
  8527. ICC_TAB_CLASSES = $00000008; // tab, tooltips
  8528. ICC_UPDOWN_CLASS = $00000010; // updown
  8529. ICC_PROGRESS_CLASS = $00000020; // progress
  8530. ICC_HOTKEY_CLASS = $00000040; // hotkey
  8531. ICC_ANIMATE_CLASS = $00000080; // animate
  8532. ICC_WIN95_CLASSES = $000000FF;
  8533. ICC_DATE_CLASSES = $00000100; // month picker, date picker, time picker, updown
  8534. ICC_USEREX_CLASSES = $00000200; // comboex
  8535. ICC_COOL_CLASSES = $00000400; // rebar (coolbar) control
  8536. ICC_INTERNET_CLASSES = $00000800;
  8537. ICC_PAGESCROLLER_CLASS = $00001000; // page scroller
  8538. ICC_NATIVEFNTCTL_CLASS = $00002000; // native font control
  8539. |</pre>
  8540. }
  8541. const
  8542. ICC_LISTVIEW_CLASSES = $00000001; // listview, header
  8543. ICC_TREEVIEW_CLASSES = $00000002; // treeview, tooltips
  8544. ICC_BAR_CLASSES = $00000004; // toolbar, statusbar, trackbar, tooltips
  8545. ICC_TAB_CLASSES = $00000008; // tab, tooltips
  8546. ICC_UPDOWN_CLASS = $00000010; // updown
  8547. ICC_PROGRESS_CLASS = $00000020; // progress
  8548. ICC_HOTKEY_CLASS = $00000040; // hotkey
  8549. ICC_ANIMATE_CLASS = $00000080; // animate
  8550. ICC_WIN95_CLASSES = $000000FF;
  8551. ICC_DATE_CLASSES = $00000100; // month picker, date picker, time picker, updown
  8552. ICC_USEREX_CLASSES = $00000200; // comboex
  8553. ICC_COOL_CLASSES = $00000400; // rebar (coolbar) control
  8554. ICC_INTERNET_CLASSES = $00000800;
  8555. ICC_PAGESCROLLER_CLASS = $00001000; // page scroller
  8556. ICC_NATIVEFNTCTL_CLASS = $00002000; // native font control
  8557. {$ifdef win32}
  8558. //[Ole DECLARATIONS]
  8559. function OleInit: Boolean;
  8560. {* Calls OleInitialize (once - all other calls are simulated by incrementing
  8561. call counter. Every OleInit shoud be complemented with correspondent OleUninit.
  8562. (Though, it is possible to call API function OleUnInitialize once to
  8563. cancel all OleInit calls). }
  8564. procedure OleUnInit;
  8565. {* Decrements counter and calls OleUnInitialize when it is zeroed. }
  8566. var OleInitCount: Integer;
  8567. {-}
  8568. function StringToOleStr(const Source: string): PWideChar;
  8569. {* }
  8570. {+}
  8571. function SysAllocStringLen(psz: PWideChar; len: Integer): PWideChar; {$ifdef wince}cdecl{$else}stdcall{$endif};
  8572. procedure SysFreeString( psz: PWideChar ); {$ifdef wince}cdecl{$else}stdcall{$endif};
  8573. {$endif win32}
  8574. {$ENDIF WIN_GDI}
  8575. { -- Contructors for visual controls -- }
  8576. //[NewXXXX DECLARATIONS]
  8577. //[_NewWindowed DECLARATION]
  8578. {$IFDEF GDI}
  8579. function _NewWindowed( AParent: PControl; ControlClassName: PKOLChar; Ctl3D: Boolean ): PControl;
  8580. {$ENDIF GDI}
  8581. {$IFDEF _X_}
  8582. {$IFDEF GTK}
  8583. function _NewWindowed( AParent: PControl; ControlClassName: PChar;
  8584. widget: PGtkWidget; need_eventbox: Boolean ): PControl;
  8585. {$ENDIF GTK}
  8586. {$ENDIF _X_}
  8587. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  8588. //[NewApplet DECLARATION]
  8589. function NewApplet( const Caption: KOLString ): PControl;
  8590. {* |<#control>
  8591. Creates applet button window, which has to be parent of all other forms
  8592. in your project (but this is *not must*). See also comments about NewForm.
  8593. |<br>
  8594. Following methods, properties and events are useful to work with applet
  8595. control:
  8596. |#appbutton }
  8597. {$ENDIF WIN_GDI}
  8598. //[NewForm DECLARATION]
  8599. function NewForm( AParent: PControl; const Caption: KOLString ): PControl;
  8600. {* |<#control>
  8601. Creates form window object and returns pointer to it. If You use only one form,
  8602. and You are not going to do applet button on task bar invisible, it is not
  8603. necessary to create also special applet button window - just pass
  8604. your (main) form object to Run procedure. In that case, it is a good
  8605. idea to assign pointer to your main form object to Applet variable
  8606. immediately following creating it - because some objects (e.g. TTimer)
  8607. want to have Applet assigned to something.
  8608. |<br>
  8609. |&D=<a href="tcontrol.htm#%1" target=_top> %0 </a>
  8610. Following methods, properties and events are useful to work with forms
  8611. (ones common for all visual objects, such as <D Left>, <D Top>, <D Width>,
  8612. <D Height>, etc. are not listed here - look TControl for it):
  8613. |#form }
  8614. //[_NewControl DECLARATION]
  8615. {$IFDEF GDI}
  8616. function _NewControl( AParent: PControl; ControlClassName: PKOLChar;
  8617. Style: DWORD; Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  8618. {$ENDIF GDI}
  8619. {$IFDEF _X_}
  8620. {$IFDEF GTK}
  8621. function _NewControl( AParent: PControl; ControlClassName: PChar;
  8622. Style: DWORD; Ctl3D: Boolean; widget: PGtkWidget; need_eventbox: Boolean ): PControl;
  8623. {$ENDIF GTK}
  8624. {$ENDIF _X_}
  8625. //[NewButton DECLARATION]
  8626. function NewButton( AParent: PControl; const Caption: KOLString ): PControl;
  8627. {* |<#control>
  8628. Creates button on given parent control or form.
  8629. Please note, that in Windows, buttons can not change its <D Font> color
  8630. and to be <D Transparent>.
  8631. |<br> Following methods, properies and events are (especially) useful with
  8632. a button:
  8633. |#button }
  8634. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  8635. //[NewBitBtn DECLARATION]
  8636. function NewBitBtn( AParent: PControl; const Caption: KOLString;
  8637. Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap; GlyphCount: Integer ): PControl;
  8638. {* |<#control>
  8639. Creates image button (actually implemented as owner-drawn). In Options,
  8640. it is possible to determine, whether bitmap or image list used to contain
  8641. one or more (up to 5) images, correspondent to certain BitBtn state.
  8642. |<br>&nbsp;&nbsp;&nbsp;
  8643. For case of imagelist (option bboImageList), it is possible to use a
  8644. number of glyphs from the image list, starting from image index given
  8645. by GlyphCount parameter. Number of used glyphs is passed in that case
  8646. in high word of GlyphCount parameter (if 0, one image is used therefore).
  8647. For bboImageList, BitBtn can be Transparent (and in that case bboNoBorder
  8648. style can be useful to draw custom buttons of non-rectangular shape).
  8649. |<br>&nbsp;&nbsp;&nbsp;
  8650. For case of bitmap BitBtn, image is stretched down (if too big), but can
  8651. not be transparent. It is not necessary for bitmap BitBtn to pass correct
  8652. GlyphCount - it is calculated on base of bitmap size, if 0 is passed.
  8653. |<br>&nbsp;&nbsp;&nbsp;
  8654. And, certainly, BitBtn can be without glyph image (text only). For that
  8655. case, it is therefore is more flexible and power than usual Button (but
  8656. requires more code). E.g., BitBtn can change its <D Font>, <D Color>,
  8657. and to be totally <D Transparent>.
  8658. Moreover, BitBtn can be <D Flat>, bboFixed, <D SpeedButton> and
  8659. have property <D RepeatInterval>.
  8660. |<br>&nbsp;&nbsp;&nbsp;
  8661. Note: if You use bboFixed Style, use OnChange event instead of OnClick,
  8662. because <D Checked> state is changed immediately however OnClick occure
  8663. only when mouse or space key released (and can be not called at all if
  8664. mouse button is released out of BitBtn bounds). Also, bboFixed defines
  8665. only which glyph to show (the border if it is not turned off behaves as
  8666. usual for a button, i.e. it becomes lowered and then raised again at any click).
  8667. Here You can find references to other properties, events and methods
  8668. applicable to BitBtn:
  8669. |#bitbtn }
  8670. {$ENDIF GDI}
  8671. //[NewLabel DECLARATION]
  8672. function NewLabel( AParent: PControl; const Caption: KOLString ): PControl;
  8673. {* |<#control>
  8674. Creates static text control (native Windows STATIC control).
  8675. Use property <D Caption> at run time to change label text. Also
  8676. it is possible to adjust label <D Font>, <D Brush> or <D Color>.
  8677. Label can be <D Transparent>. If You want to have rotated text
  8678. label, call NewLabelEffect instead and change its <D Font>.FontOrientation.
  8679. Other references certain for a label:
  8680. |#label }
  8681. {$IFDEF GDI}
  8682. //[NewWordWrapLabel DECLARATION]
  8683. function NewWordWrapLabel( AParent: PControl; const Caption: KOLString ): PControl;
  8684. {* |<#control>
  8685. Creates multiline static text control (native Windows STATIC control),
  8686. which can wrap long text onto several lines. See also NewLabel.
  8687. See also:
  8688. |#wwlabel
  8689. |#label }
  8690. //[NewLabelEffect DECLARATION]
  8691. function NewLabelEffect( AParent: PControl; const Caption: KOLString; ShadowDeep: Integer ): PControl;
  8692. {* |<#control>
  8693. Creates 3D-label with capability to rotate its text <D Caption>, which
  8694. is controlled by changing <D Font>.FontOrientation property. If You want
  8695. to get flat effect label (e.g. to rotate it only), pass <D ShadowDeep> = 0.
  8696. Please note, that drawing procedure uses <D Canvas> property, so using of
  8697. LabelEffect leads to increase size of executable.
  8698. See also:
  8699. |#3dlabel
  8700. |#label }
  8701. {$ENDIF GDI}
  8702. //[NewPaintbox DECLARATION]
  8703. function NewPaintbox( AParent: PControl ): PControl;
  8704. {* |<#control>
  8705. Creates owner-drawn STATIC control. Set its <D OnPaint> event to
  8706. perform custom painting.
  8707. |#paintbox }
  8708. {$IFDEF GDI}
  8709. //[NewImageShow DECLARATION]
  8710. function NewImageShow( AParent: PControl; AImgList: PImageList; ImgIdx: Integer ): PControl;
  8711. {* |<#control>
  8712. Creates an image show control, implemented as a paintbox which is used to
  8713. draw an image from the imagelist. At run-time, use property CurIndex to
  8714. select another image from the imagelist, and a property ImageListNormal to
  8715. use another image list. When the control is created, its size becomes
  8716. equal to dimensions of imagelist (if any). }
  8717. //[NewScrollBar DECLARATION]
  8718. function NewScrollBar( AParent: PControl; BarSide: TScrollerBar ): PControl;
  8719. {* |<#control>
  8720. Creates simple scroll bar. }
  8721. //[NewScrollBox DECLARATION]
  8722. function NewScrollBox( AParent: PControl; EdgeStyle: TEdgeStyle;
  8723. Bars: TScrollerBars ): PControl;
  8724. {* |<#control>
  8725. Creates simple scrolling box, which can be used any way you wish, e.g. to scroll
  8726. certain large image. To provide automatic scrolling of a set of child controls,
  8727. use advanced scroll box, created with NewScrollBoxEx. }
  8728. procedure NotifyScrollBox( Self_, Child: PControl );
  8729. function NewScrollBoxEx( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
  8730. {* |<#control>
  8731. Creates extended scrolling box control, which automatically scrolls child
  8732. controls (if any). }
  8733. //[NewGradientPanel DECLARATION]
  8734. function NewGradientPanel( AParent: PControl; Color1, Color2: TColor ): PControl;
  8735. {* |<#control>
  8736. Creates gradient-filled STATIC control. To adjust colors at the
  8737. run time, change <D Color1> and <D Color2> properties (which initially are
  8738. assigned from Color1, Color2 parameters), and call <D Invalidate> method
  8739. to repaint control. }
  8740. function NewGradientPanelEx( AParent: PControl; Color1, Color2: TColor;
  8741. Style: TGradientStyle; Layout: TGradientLayout ): PControl;
  8742. {* |<#control>
  8743. Creates gradient-filled STATIC control. To adjust colors at the
  8744. run time, change <D Color1> and <D Color2> properties (which initially are
  8745. assigned from Color1, Color2 parameters), and call <D Invalidate> method
  8746. to repaint control. Depending on style and first line/point layout, can
  8747. looking different. Idea: Vladimir Stojiljkovic. }
  8748. //[NewPanel DECLARATION]
  8749. function NewPanel( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
  8750. {* |<#control>
  8751. Creates panel, which can be parent for other controls (though, any
  8752. control can be used as a parent for other ones, but panel is specially
  8753. designed for such purpose). }
  8754. {$ifdef win32}
  8755. //[NewMDIxxx DECLARATIONS]
  8756. function NewMDIClient( AParent: PControl; WindowMenu: THandle ): PControl;
  8757. {* |<#control>
  8758. Creates MDI client window, which is a special type of child window,
  8759. containing all MDI child windows, created calling NewMDIChild function.
  8760. On a form, MDI client behaves like a panel, so it can be placed and sized
  8761. (or aligned) like any other controls. To minimize flick during resizing
  8762. main form having another aligned controls, place MDI client window on
  8763. a panel and align it caClient in the panel.
  8764. |<br>Note:
  8765. MDI client must be a single on the form. }
  8766. function NewMDIChild( AParent: PControl; const ACaption: String ): PControl;
  8767. {* |<#control>
  8768. Creates MDI client window. AParent should be a MDI client window,
  8769. created with NewMDIClient function. }
  8770. {$endif win32}
  8771. //[NewSplitter DECLARATIONS]
  8772. function NewSplitter( AParent: PControl; MinSizePrev, MinSizeNext: Integer ): PControl;
  8773. {* |<#control>
  8774. Creates splitter control, which will separate previous one (i.e. last
  8775. created one before splitter on the same parent) from created
  8776. next, allowing to user to adjust size of separated controls by dragging
  8777. the splitter in desired direction. Created splitter becomes vertical
  8778. or horizontal depending on Align style of previous control on the same
  8779. parent (if caLeft/caRight then vertical, if caTop/caBottom then horizontal).
  8780. |<br>&nbsp;&nbsp;&nbsp;
  8781. Please note, what if previous control has no Align equal to caLeft/caRight
  8782. or caTop/caBottom, splitter will not be able to function normally. If
  8783. previous control does not exist, it is yet possible to use splitter as
  8784. a resizeable panel (but set its initial Align value first - otherwise it
  8785. is not set by default. Also, change Cursor property as You wish in that
  8786. case, since it is not set too in case, when previous control does not
  8787. exist).
  8788. |<br>&nbsp;&nbsp;&nbsp;
  8789. Additional parameters determine, which minimal size (width or height -
  8790. correspondently to split direction) is allowed for left (top) control
  8791. and to rest of client area of parent, correspondently. (It is possible
  8792. later to set second control for checking its size with MinSizeNext
  8793. value - using TControl.SecondControl property). If -1 passed,
  8794. correspondent control size is not checked during dragging of splitter.
  8795. Usually 0 is more suitable value (with this value, it is garantee, that
  8796. splitter will be always available even if mouse was released far from the
  8797. edge of form).
  8798. |<br>&nbsp;&nbsp;&nbsp;
  8799. It is possible for user to press Escape any time while dragging splitter
  8800. to abort all adjustments made starting from left mouse button push and
  8801. begin of drag the splitter. But remember please, that such event is
  8802. controlled using timer, and therefore correspondent keyboard events
  8803. are received by currently focused control. Be sure, that pressing Escape
  8804. will not affect to any control on form, which could be focused, otherwise
  8805. filter keyboard messages (by yourself) to prevent undesired handling of
  8806. Escape key by certain controls while splitting. (Use Dragging property
  8807. to check if splitter is dragging by user with mouse).
  8808. |<br>&nbsp;&nbsp;&nbsp;
  8809. See also:
  8810. NewSplitterEx
  8811. |#splitter }
  8812. function NewSplitterEx( AParent: PControl; MinSizePrev, MinSizeNext: Integer;
  8813. EdgeStyle: TEdgeStyle ): PControl;
  8814. {* |<#control>
  8815. Creates splitter control. Difference from NewSplitter is what it is possible
  8816. to determine if a splitter will be beveled or not. See also NewSplitter. }
  8817. //[NewGroupbox DECLARATION]
  8818. function NewGroupbox( AParent: PControl; const Caption: KOLString ): PControl;
  8819. {* |<#control>
  8820. Creates group box control. Note, that to group radio items, group
  8821. box is not necessary - any parent can play role of group for radio items.
  8822. See also NewPanel. }
  8823. //[NewCheckbox DECLARATION]
  8824. function NewCheckbox( AParent: PControl; const Caption: KOLString ): PControl;
  8825. {* |<#control>
  8826. Creates check box control. Special properties, methods, events:
  8827. |#checkbox }
  8828. function NewCheckBox3State( AParent: PControl; const Caption: KOLString ): PControl;
  8829. {* |<#control>
  8830. Creates check box control with 3 states. Special properties, methods,
  8831. events:
  8832. |#checkbox }
  8833. //[NewRadiobox DECLARATION]
  8834. function NewRadiobox( AParent: PControl; const Caption: KOLString ): PControl;
  8835. {* |<#control>
  8836. Creates radio box control. Alternative radio items must have the
  8837. same parent window (regardless of its kind, either groupbox (NewGroupbox),
  8838. panel (NewPanel) or form itself). Following properties, methods and events
  8839. are specially for radiobox controls:
  8840. |#radiobox }
  8841. //[NewEditbox DECLARATION]
  8842. function NewEditbox( AParent: PControl; Options: TEditOptions ): PControl;
  8843. {* |<#control>
  8844. Creates edit box control. To create multiline edit box, similar to
  8845. TMemo in VCL, apply eoMultiline in Options. Following properties, methods,
  8846. events are special for edit controls:
  8847. |#edit }
  8848. {$IFNDEF NOT_USE_RICHEDIT}
  8849. var FRichEditModule: Integer;
  8850. RichEditClass: PKOLChar;
  8851. const RichEditLibnames: array[ 0..3 ] of PKOLChar =
  8852. ( 'msftedit', 'riched20',
  8853. 'riched32', 'riched' );
  8854. RichEditClasses: array[ 0..3 ] of PKOLChar =
  8855. ( 'RichEdit50W', 'RichEdit20A',
  8856. 'RichEdit', 'RichEdit' );
  8857. var RichEditIdx: Byte = High( RichEditLibnames );
  8858. //[NewRichEdit DECLARATION]
  8859. function NewRichEdit( AParent: PControl; Options: TEditOptions ): PControl;
  8860. {* |<#control>
  8861. Creates rich text edit control. A rich edit control is a window in which
  8862. the user can enter and edit text. The text can be assigned character and
  8863. paragraph formatting, and can include embedded OLE objects. Rich edit
  8864. controls provide a programming interface for formatting text. However, an
  8865. application must implement any user interface components necessary to make
  8866. formatting operations available to the user.
  8867. |<br>&nbsp;&nbsp;&nbsp;
  8868. Note: eoPassword, eoMultiline options have no effect for RichEdit control.
  8869. Some operations are supersided with special versions of those, created
  8870. especially for RichEdit, but in some cases it is necessary to use
  8871. another properties and methods, specially designed for RichEdit (see
  8872. methods and properties, which names are starting from RE_...).
  8873. |<br>&nbsp;&nbsp;&nbsp;
  8874. Following properties, methods, events are special for edit controls:
  8875. |#richedit
  8876. }
  8877. function NewRichEdit1( AParent: PControl; Options: TEditOptions ): PControl;
  8878. {* |<#control>
  8879. Like NewRichEdit, but to work with older RichEdit control version 1.0
  8880. (window class 'RichEdit' forced to use instead of 'RichEdit20A', even
  8881. if library RICHED20.DLL found and loaded successfully). One more
  8882. difference - OleInit is not called, so the most of OLE capabilities
  8883. of RichEdit could not working. }
  8884. {$ENDIF NOT_USE_RICHEDIT}
  8885. //[NewListbox DECLARATION]
  8886. function NewListbox( AParent: PControl; Options: TListOptions ): PControl;
  8887. {* |<#control>
  8888. Creates list box control. Following properties, methods and events are
  8889. special for Listbox:
  8890. |#listbox }
  8891. //[NewCombobox DECLARATION]
  8892. function NewCombobox( AParent: PControl; Options: TComboOptions ): PControl;
  8893. {* |<#control>
  8894. Creates new combo box control. Note, that it is not possible to align
  8895. combobox caLeft or caRight: this can cause infinite recursion in the
  8896. application.
  8897. |<br>Following properties, methods and events are
  8898. special for Combobox:
  8899. |#combo }
  8900. //[_NewCommonControl DECLARATION]
  8901. function _NewCommonControl( AParent: PControl; ClassName: PKOLChar; Style: DWORD;
  8902. Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  8903. //[NewProgressbar DECLARATION]
  8904. function NewProgressbar( AParent: PControl ): PControl;
  8905. {* |<#control>
  8906. Creates progress bar control. Following properties are special for
  8907. progress bar:
  8908. |#progressbar
  8909. See also NewProgressEx. }
  8910. function NewProgressbarEx( AParent: PControl; Options: TProgressbarOptions ): PControl;
  8911. {* |<#control>
  8912. Can create progress bar with smooth style (progress is not segmented
  8913. onto bricks) or/and vertical progress bar - using additional parameter.
  8914. For list of properties, suitable for progress bars, see NewProgressbar. }
  8915. //[NewListVew DECLARATION]
  8916. function NewListView( AParent: PControl; Style: TListViewStyle; Options: TListViewOptions;
  8917. ImageListSmall, ImageListNormal, ImageListState: PImageList ): PControl;
  8918. {* |<#control>
  8919. Creates list view control. It is very powerful control, which can partially
  8920. compensate absence of grid controls (in lvsDetail view mode). Properties,
  8921. methods and events, special for list view control are:
  8922. |#listview }
  8923. //[NewTreeView DECLARATION]
  8924. function NewTreeView( AParent: PControl; Options: TTreeViewOptions;
  8925. ImgListNormal, ImgListState: PImageList ): PControl;
  8926. {* |<#control>
  8927. Creates tree view control. See tree view methods and properties:
  8928. |#treeview }
  8929. //[NewTabControl DECLARATION]
  8930. function NewTabControl( AParent: PControl; const Tabs: array of KOLString; Options: TTabControlOptions;
  8931. ImgList: PImageList; ImgList1stIdx: Integer ): PControl;
  8932. {* |<#control>
  8933. Creates new tab control (like notebook). To place child control on a certain
  8934. page of TabControl, use property Pages[ Idx ], for example:
  8935. ! Label1 := NewLabel( TabControl1.Pages[ 0 ], 'Label1' );
  8936. | &nbsp;&nbsp;&nbsp;
  8937. To determine number of pages at run time, use property <D Count>;
  8938. |<br> to determine which page is currently selected (or to change
  8939. selection), use property <D CurIndex>;
  8940. |<br> to feedback to switch between tabs assign your handler to OnSelChange
  8941. event;
  8942. |<br>Note, that by default, tab control is created with a border lowered to
  8943. tab control's parent. To remove it, you can apply WS_EX_TRANSPARENT extended
  8944. style (see TControl.ExStyle property), but painting of some child controls
  8945. can be strange a bit in this case (no border drawing for edit controls was
  8946. found, but not always...). You can also apply style WS_THICKFRAME (TControl.Style
  8947. property) to make the border raised.
  8948. |<br> Other methods and properties, suitable for tab control, are:
  8949. |#tabcontrol }
  8950. {$IFNDEF OLD_ALIGN}
  8951. function NewTabEmpty( AParent: PControl; Options: TTabControlOptions;
  8952. ImgList: PImageList ): PControl;
  8953. {* |<#control>
  8954. Creates new empty tab control for using metods TC_Insert (to create Pages as Panel),
  8955. or TC_InsertControl (if you want using your custom Pages).}
  8956. {$ENDIF}
  8957. //[NewToolbar DECLARATION]
  8958. function NewToolbar( AParent: PControl; Align: TControlAlign; Options: TToolbarOptions;
  8959. Bitmap: HBitmap; const Buttons: array of PKOLChar;
  8960. const BtnImgIdxArray: array of Integer ) : PControl;
  8961. {* |<#control>
  8962. Creates toolbar control. Bitmap (if present) must contain images for all buttons
  8963. excluding separators (defined by string '-' in Buttons array) and system images,
  8964. otherwise last buttons will no have images at all. Image width for every button
  8965. is assumed to be equal to Bitmap height (if last of "squares" has
  8966. insufficient width, it will not be used). To define fixed buttons, use
  8967. characters '+' or '-' as a prefix for button string (even empty). To
  8968. create groups of (radio-)buttons, use also '!' follow '+' or '-'. (These rules
  8969. are similar used in menu creation). To define drop down button, use (as
  8970. first) prefix '^'. (Do not forget to set <D OnTBDropDown> event for this
  8971. case). If You want to assign images to buttons not in the same order
  8972. how these are placed in Bitmap (or You use system bitmap), define for every
  8973. button (in BtnImgIdxArray array) indexes for every button (excluding
  8974. separator buttons). Otherwise, it is possible to define index only for first
  8975. button (e.g., [0]). It is also possible to change TBImages[ ] property
  8976. for such purpose, or do the same in method TBSetBtnImgIdx).
  8977. |<br>
  8978. Following properties, methods and event are specially designed to work with
  8979. toolbar control:
  8980. |#toolbar
  8981. |<br>&nbsp;&nbsp;&nbsp;
  8982. If your project uses Align property to align controls, this can conflict with
  8983. toolbar native aligning. To solve such problem, place toolbar to parent panel,
  8984. which has its own Align property assigned to desired value.
  8985. |<br>
  8986. To create toolbar with buttons, drawn from top to bottom, instead from left
  8987. to right, combine caLeft / caRight in Align parameter and style tboWrapable
  8988. when create toolbar. To adjust width of vertically aligned toolbar, it is
  8989. possible to call ResizeParentLeft for it. E.g.:
  8990. ! P0 := NewPanel( W, esRaised ) .SetSize( 30, 0 ) .SetAlign( caLeft );
  8991. ! // ^^^^^^^^^^^^^^^^^ //////
  8992. !TB := NewToolbar( P0, caLeft, [ tboNoDivider, tboWrapable ], DWORD(-1),
  8993. ! // ////// ///////////
  8994. ! [ ' ', ' ', ' ', '-', ' ', ' ' ],
  8995. ! [ STD_FILEOPEN ] ).ResizeParentRight;
  8996. !//Note, that caLeft is *must*, and tboWrapable style too. SetSize for
  8997. !//parent panel is not necessary, but only if ResizeParentRight is called
  8998. !//than for Toolbar.
  8999. |<br><br>
  9000. One more note: if You create toolbar without text labels (passing ' ' for
  9001. each button You add), include also option tboTextRight to fix incorrect
  9002. sizing of buttons under Windows9x.
  9003. |<br>
  9004. And, certainly, if you use image lists rather then bitmap, all written
  9005. above about Bitmap become absolutely incorrect.
  9006. }
  9007. //[NewDateTimePicker DECLARATION]
  9008. function NewDateTimePicker( AParent: PControl; Options: TDateTimePickerOptions )
  9009. : PControl;
  9010. {* |<#control>
  9011. Creates date and time picker common control.
  9012. }
  9013. { -- Constructor for Image List objet -- }
  9014. //[NewImageList DECLARATION]
  9015. function NewImageList( AOwner: PControl ): PImageList;
  9016. {* Constructor of TImageList object. Unlike other non-visual objects, image list
  9017. can be parented by TControl object (but this does not *must*), and in that
  9018. case it is destroyed automatically when its parent control is destroyed.
  9019. Every control can have several TImageList objects, linked to a simple list.
  9020. But if any TImageList object is destroyed, all following ones are destroyed
  9021. too (at least, now I implemented it so). }
  9022. {$ENDIF WIN_GDI}
  9023. //[TIMER]
  9024. type
  9025. TTimerKind = ( tkReal, tkProcess, tkProfiler ); // only for UNIX!
  9026. {++}(*TTimer = class;*){--}
  9027. PTimer = {-}^{+}TTimer;
  9028. { ----------------------------------------------------------------------
  9029. TTimer object
  9030. ----------------------------------------------------------------------- }
  9031. //[TTimer DEFINITION]
  9032. TTimer = object( TObj )
  9033. {* Easy timer incapsulation object. It uses separate topmost window,
  9034. common for all timers in the application, to handle WM_TIMER message.
  9035. This allows using timers in non-windowed application (but anyway it
  9036. should contain message handling loop for a thread).
  9037. |<br>
  9038. Note: in UNIX, there are no special windows created, certainly. }
  9039. protected
  9040. fHandle : Integer;
  9041. fEnabled: Boolean;
  9042. fInterval: Integer;
  9043. fOnTimer: TOnEvent;
  9044. {$IFDEF LIN}
  9045. {$IFNDEF GTK}
  9046. {$IFNDEF QT}
  9047. fPrev, fNext: PTimer; // äâóñâÿçíûé ñïèñîê âñåõ _àêòèâíûõ_ òàéìåðîâ
  9048. fTimeStart: clock_t;
  9049. fExpireNext: clock_t;
  9050. fExpireTotal: Int64;
  9051. fTimerHandled: Boolean;
  9052. fResolution: Integer;
  9053. fPeriodic: Boolean;
  9054. fMultimedia: Boolean;
  9055. {$ENDIF QT}
  9056. {$ENDIF GTK}
  9057. {$ENDIF}
  9058. procedure SetEnabled(const Value: Boolean); {$IFDEF WIN} virtual; {$ENDIF}
  9059. procedure SetInterval(const Value: Integer);
  9060. protected
  9061. {++}(*public*){--}
  9062. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9063. {* Destructor. }
  9064. public
  9065. property Handle : Integer read fHandle;
  9066. {* Windows timer object handle. }
  9067. property Enabled : Boolean read fEnabled write SetEnabled;
  9068. {* True, is timer is on. Initially, always False. }
  9069. property Interval : Integer read fInterval write SetInterval;
  9070. {* Interval in milliseconds (1000 is default and means 1 second).
  9071. Note: in UNIX, if an Interval can be set to a value large then 30 minutes,
  9072. add a conditional definition SUPPORT_LONG_TIMER to the project options. }
  9073. property OnTimer : TOnEvent read fOnTimer write fOnTimer;
  9074. {* Event, which is called when time interval is over. }
  9075. {$IFDEF LIN}
  9076. {$IFNDEF GTK}
  9077. {$IFNDEF QT}
  9078. property Resolution: Integer read fResolution write fResolution; // dummy property, just for compatibility
  9079. property Periodic: Boolean read fPeriodic write fPeriodic;
  9080. {$ENDIF QT}
  9081. {$ENDIF GTK}
  9082. {$ENDIF LIN}
  9083. end;
  9084. //[END OF TTimer DEFINITION]
  9085. //[NewTimer DECLARATION]
  9086. function NewTimer( Interval: Integer ): PTimer;
  9087. {* Constructs initially disabled timer with interval 1000 (1 second). }
  9088. {$IFDEF WIN}
  9089. {$ifdef win32}
  9090. //[MULTIMEDIA TIMER]
  9091. type
  9092. {++}(*TMMTimer = class;*){--}
  9093. PMMTimer = {-}^{+}TMMTimer;
  9094. //[TMMTimer DEFINITION]
  9095. TMMTimer = object( TTimer )
  9096. {* Multimedia timer incapsulation object. Does not require Applet or special
  9097. window to handle it. System creates a thread for each high resolution
  9098. timer, so using many such objects can degrade total PC performance. }
  9099. protected
  9100. FResolution: Integer;
  9101. FPeriodic: Boolean;
  9102. procedure SetEnabled(const Value: Boolean); {-}virtual;{+}{++}(*override;*){--}
  9103. public
  9104. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9105. {* }
  9106. property Resolution: Integer read FResolution write FResolution;
  9107. {* Minimum timer resolution. The less the more accuracy (0 is exactly
  9108. Interval milliseconds between timer shots). It is recommended to set
  9109. this property greater to prevent entire system from reducing overhead.
  9110. If you change this value, reset and then set Enabled again to apply
  9111. changes. }
  9112. property Periodic: Boolean read FPeriodic write FPeriodic;
  9113. {* TRUE, if timer is periodic (default). Otherwise, timer is one-shot
  9114. (set it Enabled every time in such case for each shot). If you change
  9115. this property, reset and set Enabled property again to get effect. }
  9116. end;
  9117. //[END OF TMMTimer DEFINITION]
  9118. //[NewMMTimer DECLARATION]
  9119. function NewMMTimer( Interval: Integer ): PMMTimer;
  9120. {* Creates multimedia timer object. Initially, it has Resolution = 0,
  9121. Periodic = TRUE and Enabled = FALSE. Do not forget also to assign your
  9122. event handler to OnTimer to do something on timer shot. }
  9123. {$endif win32}
  9124. {$ENDIF WIN}
  9125. {$IFDEF LIN}
  9126. function NewMMTimer( Interval: Integer ): PTimer;
  9127. {$ENDIF LIN}
  9128. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  9129. { -- TTrayIcon object -- }
  9130. //[TRAYICON]
  9131. type
  9132. TOnTrayIconMouse = procedure( Sender: PObj; Message : Word ) of object;
  9133. {* Event type to be called when Applet receives a message from an icon,
  9134. added to the taskbar tray. }
  9135. {++}(*TTrayIcon = class;*){--}
  9136. PTrayIcon = {-}^{+}TTrayIcon;
  9137. { ----------------------------------------------------------------------
  9138. TTrayIcon - icon in tray area of taskbar
  9139. ----------------------------------------------------------------------- }
  9140. //[TTrayIcon DEFINITION]
  9141. TTrayIcon = object(TObj)
  9142. {* Object to place (and change) a single icon onto taskbar tray. }
  9143. protected
  9144. FIcon: HIcon;
  9145. FActive: Boolean;
  9146. FTooltip: KOLString;
  9147. FOnMouse: TOnTrayIconMouse;
  9148. FControl: PControl;
  9149. fAutoRecreate: Boolean;
  9150. FNoAutoDeactivate: Boolean;
  9151. FWnd: HWnd;
  9152. procedure SetIcon(const Value: HIcon);
  9153. procedure SetActive(const Value: Boolean);
  9154. procedure SetTrayIcon( const Value : DWORD );
  9155. procedure SetTooltip(const Value: KOLString);
  9156. procedure SetAutoRecreate(const Value: Boolean);
  9157. protected
  9158. {++}(*public*){--}
  9159. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9160. {* Destructor. Use Free method instead (as usual). }
  9161. public
  9162. property Icon : HIcon read FIcon write SetIcon;
  9163. {* Icon to be shown on taskbar tray. If not set, value of Active
  9164. property has no effect. It is also possible to assign a value
  9165. to Icon property after assigning True to Active to install
  9166. icon first time or to replace icon with another one (e.g. to
  9167. get animation effect).
  9168. |<br>&nbsp;&nbsp;&nbsp;
  9169. Previously allocated icon (if any) is not deleted using
  9170. DeleteObject. This is normal for icons, loaded from resource
  9171. (e.g., by LoadIcon API call). But if icon was created (e.g.) by
  9172. CreateIconIndirect, your code is responsible for destroying
  9173. of it). }
  9174. property Active : Boolean read FActive write SetActive;
  9175. {* Set it to True to show assigned Icon on taskbar tray. Default
  9176. is False. Has no effect if Icon property is not assigned.
  9177. TrayIcon is deactivated automatically when Applet is finishing
  9178. (but only if Applet window is used as a "parent" for tray
  9179. icon object). }
  9180. property Tooltip : KOLString read FTooltip write SetTooltip;
  9181. {* Tooltip string, showing automatically when mouse is moving
  9182. over installed icon. Though "huge string" type is used, only
  9183. first 63 characters are considered. Also note, that only in
  9184. most recent versions of Windows multiline tooltips are supported. }
  9185. property OnMouse : TOnTrayIconMouse read FOnMouse write FOnMouse;
  9186. {* Is called then mouse message is taking place concerning installed
  9187. icon. Only type of message can be obtained (e.g. WM_MOUSEMOVE,
  9188. WM_LBUTTONDOWN etc.) }
  9189. property AutoRecreate: Boolean read fAutoRecreate write SetAutoRecreate;
  9190. {* If set to TRUE, auto-recreating of tray icon is proveded in case,
  9191. when Explorer is restarted for some (unpredictable) reasons. Otherwise,
  9192. your tray icon is disappeared forever, and if this is the single way
  9193. to communicate with your application, the user nomore can achieve it. }
  9194. property NoAutoDeactivate: Boolean read FNoAutoDeactivate write FNoAutoDeactivate;
  9195. {* If set to true, tray icon is not removed from tray automatically on
  9196. WM_CLOSE message receive by owner control. Set Active := FALSE in
  9197. your code for such case before accepting closing the form. }
  9198. property Wnd: HWnd read FWnd write FWnd;
  9199. {* A window to use as a base window for tray icon messages. Overrides
  9200. parent Control handle is assigned. Note, that if Wnd property used,
  9201. message handling is not done automatically, and you should do this in
  9202. your code, or at least for one tray icon object, call AttachProc2Wnd. }
  9203. procedure AttachProc2Wnd;
  9204. {* Call this method for a tray icon object in case if Wnd used rather then
  9205. control. It is enough to call this method once for each Wnd used, even
  9206. if several other tray icons are also based on the same Wnd. See also
  9207. DetachProc2Wnd method. }
  9208. procedure DetachProc2Wnd;
  9209. {* Call this method to detach window procedure attached via AttachProc2Wnd.
  9210. Do it once for a Wnd, used as a base to handle tray icon messages.
  9211. Caution! If you do not call this method before destroying Wnd, the
  9212. application will not functioning normally. }
  9213. end;
  9214. {* When You create invisible application, which should be represented by
  9215. only the tray icon, prepare a handle for the window, resposible for
  9216. messages handling. Remember, that window handle is created automatically
  9217. only when a window is showing first time. If window's property Visible is
  9218. set to False, You should to call CreateWindow manually.
  9219. <br>
  9220. There is a known bug exist with similar invisible tray-iconized applications.
  9221. When a menu is activated in response to tray mouse event, if there was
  9222. not active window, belonging to the application, the menu is not disappeared
  9223. when mouse is clicked anywhere else. This bug is occure in Windows9x/ME.
  9224. To avoid it, activate first your form window. This last window shoud have
  9225. status visible (but, certainly, there are no needs to place it on visible
  9226. part of screen - change its position, so it will not be visible for user,
  9227. if You wish).
  9228. <br>
  9229. Also, to make your application "invisible" but until special event is occure,
  9230. use Applet separate from the main form, and make for both Visible := False.
  9231. This allows for You to make your form visible any time You wish, and without
  9232. making application button visible if You do not wish.
  9233. }
  9234. {= Êîãäà Âû äåëàåòå íåâèäèìîå ïðèëîæåíèå, êîòîðîå äîëæíî áûòü ïðåäñòàâëåíî
  9235. òîëüêî èêîíêîé â òðåå, îáåñïå÷üòå íåíóëåâîé Handle äëÿ îêíà, îòâå÷àþùåãî
  9236. çà îáðàáîòêó ñîîáùåíèé. Ïîìíèòå, ÷òî Handle îêíà ñîçäàåòñÿ àâòîìàòè÷åñêè
  9237. òîëüêî â òîò ìîìåíò, êîãäà îíî äîëæíî ïîÿâèòüñÿ â ïåðâûé ðàç. Åñëè ñâîéñòâî
  9238. îêíà Visible óñòàíîâëåíî â FALSE, íåîáõîäèìî âûçâàòü CreateWindow ñàìîñòîÿòåëüíî.
  9239. <br>
  9240. Ñóùåñòâóåò èçâåñòíûé BUG ñ ïîäîáíûìè íåâèäèìûìè ìèíèìèçèðîâàííûìè â òðåé
  9241. ïðèëîæåíèÿìè. Êîãäà â îòâåò íà ñîáûòèå ìûøè àêòèâèçèðâàíî âûïàäàþùåå ìåíþ,
  9242. îíî íå èñ÷åçàåò ïî ùåë÷êó ìûøè âíå ýòîãî ìåíþ. Ïðîèñõîäèò ýòî â Windows9x/ME.
  9243. ÷òîáû ðåøèòü ýòó ïðîáëåìó, ñíà÷àëà àêòèâèçèðóéòå ñâîå îêíî (ôîðìó). Ýòî îêíî
  9244. äîëæíî áûòü âèäèìûì (íî, êîíå÷íî, åãî ìîæíî ðàçìåñòèòü âíå ïðåäåëîâ âèäèìîé
  9245. ÷àñòè ýêðàíà, òàê ÷òî ïîëüçîâàòåëþ åãî âèäíî íå áóäåò).
  9246. <br>
  9247. Òàê æå, ÷òîáû ñäåëàòü ïðèëîæåíèå íåâèäèìûì, ïî êðàéíåé ìåðå, ïîêà ýòî íå
  9248. ïîòðåáóåòñÿ, èñïîëüçóéòå îòäåëüíûé ïðåäñòàâèòåëü êëàññà TControl - ãëîáàëüíóþ
  9249. ïåðåìåííóþ Applet, è ïðèñâîéòå FALSE åå ñâîéñòâó Visible.
  9250. }
  9251. //[END OF TTrayIcon DEFINITION]
  9252. //[NewTrayIcon DECLARATION]
  9253. function NewTrayIcon( Wnd: PControl; Icon: HIcon ): PTrayIcon;
  9254. {* Constructor of TTrayIcon object. Pass main form or applet as Wnd
  9255. parameter. }
  9256. //[JUST ONE]
  9257. { -- JustOne -- }
  9258. {$ifndef wince}
  9259. type
  9260. TOnAnotherInstance = procedure( const CmdLine: KOLString ) of object;
  9261. {* Event type to use in JustOneNotify function. }
  9262. {$endif wince}
  9263. function JustOne( Wnd: PControl; const Identifier : KOLString ) : Boolean;
  9264. {* Returns True, if this is a first instance. For all other instances
  9265. (application is already running), False is returned. }
  9266. function JustOneActivate( Wnd: PControl; const Identifier : KOLString ) : HWND;
  9267. {* Returns 0, if this is the first instance. If application is running already,
  9268. it will be activated and its window handle will be returned. }
  9269. {$ifndef wince}
  9270. function JustOneNotify( Wnd: PControl; const Identifier : KOLString;
  9271. const aOnAnotherInstance: TOnAnotherInstance ) : Boolean;
  9272. {* Returns True, if this is a first instance. For all other instances
  9273. (application is already running), False is returned. If handler
  9274. aOnAnotherInstance passed, it is called (in first instance) every time
  9275. when another instance of an application is started, receiving command
  9276. line used to run it. }
  9277. {$endif wince}
  9278. { -- string (mainly) utility procedures and functions. -- }
  9279. {$IFDEF GDI}
  9280. //[Message Box DECLARATIONS]
  9281. function MsgBox( const S: KOLString; Flags: DWORD ): DWORD;
  9282. {* Displays message box with the same title as Applet.Caption. If applet
  9283. is not running, and Applet global variable is not assigned, caption
  9284. 'Error' is displayed (but actually this is not an error - the system
  9285. does so, if nil is passed as a title).
  9286. |<br>&nbsp;&nbsp;&nbsp;
  9287. Returns ID_... result (correspondently to flags passed (MB_OK, MBYESNO,
  9288. etc. -> ID_OK, ID_YES, ID_NO, etc.) }
  9289. procedure MsgOK( const S: KOLString );
  9290. {* Displays message box with the same title as Applet.Caption (or 'Error',
  9291. if Applet is not running). }
  9292. function ShowMsg( const S: KOLString; Flags: DWORD ): DWORD;
  9293. {* Displays message box like MsgBox, but uses Applet.Handle as a parent
  9294. (so the message has no button on a task bar). }
  9295. procedure ShowMessage( const S: KOLString );
  9296. {* Like ShowMsg, but has only styles MB_OK and MB_SETFOREGROUND. }
  9297. {$ENDIF GDI}
  9298. {$IFDEF WIN}
  9299. procedure SpeakerBeep( Freq: Word; Duration: DWORD );
  9300. {* On Windows NT, calls Windows.Beep. On Windows 9x, produces beep on speaker
  9301. of desired frequency during given duration time (in milliseconds). }
  9302. {$ENDIF WIN}
  9303. {++}(*
  9304. function FormatMessage(dwFlags: DWORD; lpSource: Pointer; dwMessageId: DWORD; dwLanguageId: DWORD;
  9305. lpBuffer: PChar; nSize: DWORD; Arguments: Pointer): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  9306. *){--}
  9307. function SysErrorMessage(ErrorCode: Integer): KOLString;
  9308. {* Creates and returns a string containing formatted system error message.
  9309. It is possible then to display this message or write it to a log
  9310. file, e.g.:
  9311. ! ShowMsg( SysErrorMessage( GetLastError ) );
  9312. |&R=<a name="%0"></a><font color=#FF8040><h1>%0</h1></font>
  9313. <R 64-bit integer numbers>
  9314. }
  9315. {$ENDIF WIN_GDI}
  9316. //[I64 TYPE]
  9317. type
  9318. I64 = record
  9319. {* 64 bit integer record. Use it and correspondent functions below in KOL
  9320. projects to avoid dependancy from Delphi version (earlier versions of
  9321. Delphi had no Int64 type). }
  9322. Lo, Hi: DWORD;
  9323. end;
  9324. PI64 = ^I64;
  9325. {* }
  9326. {-}
  9327. {$IFNDEF _D4orHigher}
  9328. Int64 = I64;
  9329. PInt64 = PI64;
  9330. {$ENDIF}
  9331. function MakeInt64( Lo, Hi: DWORD ): I64;
  9332. {* }
  9333. function Int2Int64( X: Integer ): I64;
  9334. {* }
  9335. procedure IncInt64( var I64: I64; Delta: Integer );
  9336. {* I64 := I64 + Delta; }
  9337. procedure DecInt64( var I64: I64; Delta: Integer );
  9338. {* I64 := I64 - Delta; }
  9339. function Add64( const X, Y: I64 ): I64;
  9340. {* Result := X + Y; }
  9341. function Sub64( const X, Y: I64 ): I64;
  9342. {* Result := X - Y; }
  9343. function Neg64( const X: I64 ): I64;
  9344. {* Result := -X; }
  9345. function Mul64i( const X: I64; Mul: Integer ): I64;
  9346. {* Result := X * Mul; }
  9347. function Div64i( const X: I64; D: Integer ): I64;
  9348. {* Result := X div D; }
  9349. function Mod64i( const X: I64; D: Integer ): Integer;
  9350. {* Result := X mod D; }
  9351. function Sgn64( const X: I64 ): Integer;
  9352. {* Result := sign( X ); i.e.:
  9353. |<br>
  9354. if X < 0 then -1
  9355. |<br>
  9356. if X = 0 then 0
  9357. |<br>
  9358. if X > 0 then 1 }
  9359. function Cmp64( const X, Y: I64 ): Integer;
  9360. {* Result := sign( X - Y ); i.e.
  9361. |<br>
  9362. if X < Y then -1
  9363. |<br>
  9364. if X = Y then 0
  9365. |<br>
  9366. if X > Y then 1 }
  9367. function Int64_2Str( X: I64 ): String;
  9368. {* }
  9369. function Int64_2Hex( X: I64; MinDigits: Integer ): String;
  9370. {* }
  9371. function Str2Int64( const S: String ): I64;
  9372. {* }
  9373. function Int64_2Double( const X: I64 ): Double;
  9374. {* }
  9375. function Double2Int64( D: Double ): I64;
  9376. {*
  9377. <R Floating point numbers>
  9378. }
  9379. const
  9380. NAN = 0.0 / 0.0;
  9381. Infinity = 1.0 / 0.0;
  9382. {+}
  9383. {++}(*const NAN = 1e-100;*){--}
  9384. function IsNan(const AValue: Double): Boolean;
  9385. {* Checks if an argument passed is NAN. }
  9386. function IsInfinity(const AValue: Double): Boolean;
  9387. {* Checks if an argument passed is Infinite. }
  9388. function IntPower(Base: Extended; Exponent: Integer): Extended;
  9389. {* Result := Base ^ Exponent; }
  9390. //[String<->Double DECLARATIONS]
  9391. function Str2Double( const S: String ): Double;
  9392. {* }
  9393. function Str2Extended( const S: String ): Extended;
  9394. {* }
  9395. function Double2Str( D: Double ): String;
  9396. {* }
  9397. function Extended2Str( E: Extended ): String;
  9398. {* }
  9399. function Double2StrEx( D: Double ): String;
  9400. {* experimental, do not use }
  9401. function TruncD( D: Double ): Double;
  9402. {* Result := trunc( D ) as Double;
  9403. |<hr>
  9404. <R Small bit arrays (max 32 bits in array)>
  9405. See also TBits object.
  9406. }
  9407. function IfThenElseBool( t, e, Cond: Boolean ): Boolean;
  9408. function IfThenElseInt( t, e: Integer; Cond: Boolean ): Integer;
  9409. function IfThenElseStr( const t, e: String; Cond: Boolean ): String;
  9410. {$IFDEF _D5orHigher}
  9411. function IfThenElse( t, e: Boolean; Cond: Boolean ): Boolean; overload;
  9412. function IfThenElse( t, e: Integer; Cond: Boolean ): Integer; overload;
  9413. function IfThenElse( t, e: String; Cond: Boolean ): String; overload;
  9414. function IfThenElse( t, e: Double; Cond: Boolean ): Double; overload;
  9415. {$ENDIF}
  9416. //[SMALL BIT ARRAYS DECLARATIONS]
  9417. function GetBits( N: DWORD; first, last: Byte ): DWord;
  9418. {* Retuns bits straing from <first> and to <last> inclusively. }
  9419. function GetBitsL( N: DWORD; from, len: Byte ): DWord;
  9420. {* Retuns len bits starting from index <from>.
  9421. |<hr>
  9422. <R Arithmetics, geometry and other utility functions>
  9423. See also units KolMath.pas, CplxMath.pas and Err.pas.
  9424. }
  9425. //[MulDiv DECLARATION]
  9426. {$IFNDEF FPC}
  9427. function MulDiv( A, B, C: Integer ): Integer;
  9428. {* Returns A * B div C. Small and fast. }
  9429. {$ENDIF}
  9430. //[TMethod TYPE]
  9431. type
  9432. ///////////////////////////////////////////
  9433. {$ifndef _D6orHigher} //
  9434. ///////////////////////////////////////////
  9435. TMethod = {$ifndef wince}packed{$endif} record
  9436. {* Is defined here because using of VCL classes.pas unit is
  9437. not recommended in XCL. This record type is used often
  9438. to set/access event handlers, referring to a procedure
  9439. of object (usually to set such event to an ordinal
  9440. procedure setting Data field to nil. }
  9441. Code: Pointer; // Pointer to method code.
  9442. {* If used to fake assigning to event handler of type 'procedure
  9443. of object' with ordinal procedure pointer, use symbol '@'
  9444. before method:
  9445. |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Courier"><b>
  9446. | Method.Code := @MyProcedure;
  9447. |</b></font> }
  9448. Data: Pointer; // Pointer to object, owning the method.
  9449. {* To fake event of type 'procedure of object' with setting it to
  9450. ordinal procedure assign here NIL; }
  9451. end;
  9452. {* When assigning TMethod record to event handler, typecast it with
  9453. desired event type, e.g.:
  9454. |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Courier"><b>
  9455. | SomeObject.OnSomeEvent := TOnSomeEvent( Method );
  9456. |</b></font><br> }
  9457. ///////////////////////////////////////////
  9458. {$endif} //
  9459. ///////////////////////////////////////////
  9460. PMethod = ^TMethod;
  9461. {* }
  9462. function MakeMethod( Data, Code: Pointer ): TMethod;
  9463. {* Help function to construct TMethod record. Can be useful to
  9464. assign regular type procedure/function as event handler for
  9465. event, defined as object method (do not forget, that in that
  9466. case it must have first dummy parameter to replace @Self,
  9467. passed in EAX to methods of object). }
  9468. //[Rectangles&Points DECLARATIONS]
  9469. function MakeRect( Left, Top, Right, Bottom: Integer ): TRect; {$ifdef wince}cdecl{$else}stdcall{$endif};
  9470. {* Use it instead of VCL Rect function }
  9471. function RectsEqual( const R1, R2: TRect ): Boolean;
  9472. {* Returns True if rectangles R1 and R2 have the same bounds }
  9473. function RectsIntersected( const R1, R2: TRect ): Boolean;
  9474. {* Returns TRUE if rectangles R1 and R2 have at least one common point.
  9475. Note, that right and bottom bounds of rectangles are not their part,
  9476. so, if such points are lying on that bounds, FALSE is returned. }
  9477. function PointInRect( const P: TPoint; const R: TRect ): Boolean;
  9478. {* Returns True if point P is located in rectangle R (including
  9479. left and top bounds but without right and bottom bounds of the
  9480. rectangle). }
  9481. function OffsetPoint( const T: TPoint; dX, dY: Integer ): TPoint;
  9482. {* }
  9483. function OffsetSmallPoint( const T: TSmallPoint; dX, dY: SmallInt ): TSmallPoint;
  9484. {* }
  9485. function Point2SmallPoint( const T: TPoint ): TSmallPoint;
  9486. {* }
  9487. function SmallPoint2Point( const T: TSmallPoint ): TPoint;
  9488. {* }
  9489. function MakePoint( X, Y: Integer ): TPoint;
  9490. {* Use instead of VCL function Point }
  9491. function MakeSmallPoint( X, Y: Integer ): TSmallPoint;
  9492. {* Use to construct TSmallPoint }
  9493. //[MakeFlags DECLARATION]
  9494. function MakeFlags( FlgSet: PDWORD; FlgArray: array of Integer): Integer;
  9495. {* }
  9496. function MakeDateTimeRange( D1, D2: TDateTime ): TDateTimeRange;
  9497. {* Returns TDateTimeRange from two TDateTime bounds. }
  9498. //[Integer FUNCTIONS DECLARATIONS]
  9499. procedure Swap( var X, Y: Integer );
  9500. {* exchanging values }
  9501. function Min( X, Y: Integer ): Integer;
  9502. {* minimum of two integers }
  9503. function Max( X, Y: Integer ): Integer;
  9504. {* maximum of two integers }
  9505. {$IFDEF REDEFINE_ABS}
  9506. function Abs( X: Integer ): Integer;
  9507. {* absolute value }
  9508. {$ENDIF}
  9509. function Sgn( X: Integer ): Integer;
  9510. {* sign of X: if X < 0, -1 is returned, if > 0, then +1, otherwise 0. }
  9511. function iSqrt( X: Integer ): Integer;
  9512. {* square root }
  9513. function iCbrt( X: DWORD ): Integer;
  9514. {* cubic root
  9515. |<hr>
  9516. <R String to number and number to string conversions>
  9517. }
  9518. //[Integer<->String DECLARATIONS]
  9519. function Int2Hex( Value : DWord; Digits : Integer ) : String;
  9520. {* Converts integer Value into string with hex number. Digits parameter
  9521. determines minimal number of digits (will be completed by adding
  9522. necessary number of leading zeroes). }
  9523. function Int2Str( Value : Integer ) : String;
  9524. {* Obvious. }
  9525. procedure Int2PChar( s: PChar; Value: Integer );
  9526. {* Converts Value to string and puts it into buffer s. Buffer must have
  9527. enough size to store the number converted: buffer overflow does
  9528. not checked anyway! }
  9529. function UInt2Str( Value: DWORD ): String;
  9530. {* The same as Int2Str, but for unsigned integer value. }
  9531. function Int2StrEx( Value, MinWidth: Integer ): String;
  9532. {* Like Int2Str, but resulting string filled with leading spaces to provide
  9533. at least MinWidth characters. }
  9534. function Int2Rome( Value: Integer ): String;
  9535. {* Represents number 1..8999 to Rome numer. }
  9536. function Int2Ths( I : Integer ) : String;
  9537. {* Converts integer into string, separating every three digits from each
  9538. other by character ThsSeparator. (Convert to thousands). You }
  9539. function Int2Digs( Value, Digits : Integer ) : String;
  9540. {* Converts integer to string, inserting necessary number of leading zeroes
  9541. to provide desired length of string, given by Digits parameter. If
  9542. resulting string is greater then Digits, string is not truncated anyway. }
  9543. function Num2Bytes( Value : Double ) : String;
  9544. {* Converts double float to string, considering it as a bytes count.
  9545. If Value is sufficiently large, number is represented in kilobytes (with
  9546. following letter K), or in megabytes (M), gigabytes (G) or terabytes (T).
  9547. Resulting string number is truncated to two decimals (.XX) or to one (.X),
  9548. if the second is 0. }
  9549. function S2Int( S: PChar ): Integer;
  9550. {* Converts null-terminated string to Integer. Scanning stopped when any
  9551. non-digit character found. Even empty string or string not containing
  9552. valid integer number silently converted to 0. }
  9553. function Str2Int(const Value : String) : Integer;
  9554. {* Converts string to integer. First character, which can not be
  9555. recognized as a part of number, regards as a separator. Even
  9556. empty string or string without number silently converted to 0. }
  9557. function Hex2Int( const Value : String) : Integer;
  9558. {* Converts hexadecimal number to integer. Scanning is stopped
  9559. when first non-hexadicimal character is found. Leading dollar ('$')
  9560. character is skept (if present). Minus ('-') is not concerning as
  9561. a sign of number and also stops scanning.}
  9562. function cHex2Int( const Value : String) : Integer;
  9563. {* As Hex2Int, but also checks for leading '0x' and skips it. }
  9564. function Octal2Int( const Value: String ) : Integer;
  9565. {* Converts octal number to integer. Scanning is stopped on first
  9566. non-octal digit (any char except 0..7). There are no checking if
  9567. there octal numer in the parameter. If the first char is not octal
  9568. digit, 0 is returned. }
  9569. function Binary2Int( const Value: String ) : Integer;
  9570. {* Converts binary number to integer. Like Octal2Int, but only digits
  9571. 0 and 1 are allowed. }
  9572. {$IFDEF WIN}
  9573. {$IFNDEF _FPC}
  9574. function Format( const fmt: KOLString; params: array of const ): KOLString;
  9575. {* Uses API call to wvsprintf, so does not understand extra formats,
  9576. such as floating point, date/time, currency conversions. See list of
  9577. available formats in win32.hlp (topic wsprintf).
  9578. |<hr>
  9579. <R Working with null-terminated and ansi strings>
  9580. }
  9581. {$ENDIF _FPC}
  9582. {$ENDIF WIN}
  9583. //[String FUNCTIONS DECLARATIONS]
  9584. function StrComp(const Str1, Str2: PChar): Integer;
  9585. {* Compares two strings fast. -1: Str1<Str2; 0: Str1=Str2; +1: Str1>Str2 }
  9586. function StrComp_NoCase(const Str1, Str2: PChar): Integer;
  9587. {* Compares two strings fast without case sensitivity.
  9588. Returns: -1 when Str1<Str2; 0 when Str1=Str2; +1 when Str1>Str2 }
  9589. function StrLComp(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  9590. {* Compare two strings (fast). Terminating 0 is not considered, so if
  9591. strings are equal, comparing is continued up to MaxLen bytes.
  9592. Since this, pass minimum of lengths as MaxLen. }
  9593. function StrLComp_NoCase(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  9594. {* Compare two strings fast without case sensitivity.
  9595. Terminating 0 is not considered, so if strings are equal,
  9596. comparing is continued up to MaxLen bytes.
  9597. Since this, pass minimum of lengths as MaxLen. }
  9598. function StrCopy( Dest, Source: PChar ): PChar;
  9599. {* Copy source string to destination (fast). Pointer to Dest is returned. }
  9600. function StrCat( Dest, Source: PChar ): PChar;
  9601. {* Append source string to destination (fast). Pointer to Dest is returned. }
  9602. function StrLen(const Str: PChar): Cardinal;
  9603. {* StrLen returns the number of characters in Str, not counting the null
  9604. terminator. }
  9605. function StrScanLen(Str: PChar; Chr: Char; Len: Integer): PChar;
  9606. {* Fast scans string Str of length Len searching character Chr.
  9607. Pointer to a character next to found or to Str[Len] (if no one found)
  9608. is returned. }
  9609. function StrScan(Str: PChar; Chr: Char): PChar;
  9610. {* Fast search of given character in a string. Pointer to found character
  9611. (or nil) is returned. }
  9612. function StrRScan(const Str: PChar; Chr: Char): PChar;
  9613. {* StrRScan returns a pointer to the last occurrence of Chr in Str. If Chr
  9614. does not occur in Str, StrRScan returns NIL. The null terminator is
  9615. considered to be part of the string. }
  9616. function StrIsStartingFrom( Str, Pattern: PKOLChar ): Boolean;
  9617. {* Returns True, if string Str is starting from Pattern, i.e. if
  9618. Copy( Str, 1, StrLen( Pattern ) ) = Pattern. Str must not be nil! }
  9619. function StrIsStartingFromNoCase( Str, Pattern: PChar ): Boolean;
  9620. {* Like StrIsStartingFrom above, but without case sensitivity. }
  9621. function TrimLeft(const S: KOLstring): KOLstring;
  9622. {* Removes spaces, tabulations and control characters from the starting
  9623. of string S. }
  9624. function TrimRight(const S: KOLstring): KOLstring;
  9625. {* Removes spaces, tabulates and other control characters from the
  9626. end of string S. }
  9627. function Trim( const S : KOLstring): KOLstring;
  9628. {* Makes TrimLeft and TrimRight for given string. }
  9629. function RemoveSpaces( const S: String ): String;
  9630. {* Removes all characters less or equal to ' ' in S and returns it. }
  9631. procedure Str2LowerCase( S: PChar );
  9632. {* Converts null-terminated string to lowercase (inplace). }
  9633. function LowerCase(const S: string): string;
  9634. {* Obvious. }
  9635. function UpperCase(const S: string): string;
  9636. {* Obvious. }
  9637. function AnsiUpperCase(const S: string): string;
  9638. {* Obvious. }
  9639. function AnsiLowerCase(const S: string): string;
  9640. {* Obvious. }
  9641. {$IFNDEF _D2}
  9642. {$IFNDEF _FPC}
  9643. function WAnsiUpperCase(const S: WideString): WideString;
  9644. {* Obvious. }
  9645. function WAnsiLowerCase(const S: WideString): WideString;
  9646. {* Obvious. }
  9647. function WStrComp(const S1, S2: WideString): Integer;
  9648. {* }
  9649. function _WStrComp(S1, S2: PWideChar): Integer;
  9650. {* }
  9651. function WStrScan(Str: PWideChar; Chr: WideChar): PWideChar;
  9652. {* Fast search of given character in a string. Pointer to found character
  9653. (or nil) is returned. }
  9654. function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar;
  9655. {* StrRScan returns a pointer to the last occurrence of Chr in Str. If Chr
  9656. does not occur in Str, StrRScan returns NIL. The null terminator is
  9657. considered to be part of the string. }
  9658. {$ENDIF _FPC}
  9659. {$ENDIF _D2}
  9660. function AnsiCompareStr(const S1, S2: KOLString): Integer;
  9661. {* AnsiCompareStr compares S1 to S2, with case-sensitivity. The compare
  9662. operation is controlled by the current Windows locale. The return value
  9663. is the same as for CompareStr. }
  9664. function _AnsiCompareStr(S1, S2: PKOLChar): Integer;
  9665. {* The same, but for PChar ANSI strings }
  9666. function AnsiCompareStrNoCase(const S1, S2: KOLString): Integer;
  9667. {* AnsiCompareStr compares S1 to S2, with case-sensitivity. The compare
  9668. operation is controlled by the current Windows locale. The return value
  9669. is the same as for CompareStr. }
  9670. function _AnsiCompareStrNoCase(S1, S2: PKOLChar): Integer;
  9671. {* The same, but for PChar ANSI strings }
  9672. function AnsiCompareText( const S1, S2: String ): Integer;
  9673. {* }
  9674. {$IFDEF WIN}
  9675. {$IFNDEF _FPC}
  9676. function LStrFromPWCharLen(Source: PWideChar; Length: Integer): String;
  9677. {* from Delphi5 - because D2 does not contain it. }
  9678. function LStrFromPWChar(Source: PWideChar): String;
  9679. {* from Delphi5 - because D2 does not contain it. }
  9680. {$ENDIF _FPC}
  9681. {$ENDIF WIN}
  9682. function CopyEnd( const S : KOLString; Idx : Integer ) : KOLString;
  9683. {* Returns copy of source string S starting from Idx up to the end of
  9684. string S. Works correctly for case, when Idx > Length( S ) (returns
  9685. empty string for such case). }
  9686. function CopyTail( const S : KOLString; Len : Integer ) : KOLString;
  9687. {* Returns last Len characters of the source string. If Len > Length( S ),
  9688. entire string S is returned. }
  9689. procedure DeleteTail( var S : KOLString; Len : Integer );
  9690. {* Deletes last Len characters from string. }
  9691. function IndexOfChar( const S : String; Chr : Char ) : Integer;
  9692. {* Returns index of given character (1..Length(S)), or
  9693. -1 if a character not found. }
  9694. function IndexOfCharsMin( const S, Chars : String ) : Integer;
  9695. {* Returns index (in string S) of those character, what is taking place
  9696. in Chars string and located nearest to start of S. If no such
  9697. characters in string S found, -1 is returned. }
  9698. {$IFNDEF _D2}
  9699. {$IFNDEF _FPC}
  9700. function IndexOfWideCharsMin( const S, Chars : WideString ) : Integer;
  9701. {* Returns index (in wide string S) of those wide character, what
  9702. is taking place in Chars wide string and located nearest to start of S.
  9703. If no such characters in string S found, -1 is returned. }
  9704. {$ENDIF _FPC}
  9705. {$ENDIF _D2}
  9706. function IndexOfStr( const S, Sub : String ) : Integer;
  9707. {* Returns index of given substring in source string S. If found,
  9708. 1..Length(S)-Length(Sub), if not found, -1. }
  9709. function Parse( var S : KOLString; const Separators : KOLString ) : KOLString;
  9710. {* Returns first characters of string S, separated from others by
  9711. one of characters, taking place in Separators string, assigning
  9712. a tail of string (after found separator) to source string. If
  9713. no separator characters found, source string S is returned, and
  9714. source string itself becomes empty. }
  9715. {$IFNDEF _FPC}
  9716. {$IFNDEF _D2}
  9717. function WParse( var S : WideString; const Separators : WideString ) : WideString;
  9718. {* Returns first wide characters of wide string S, separated from others
  9719. by one of wide characters, taking place in Separators wide string,
  9720. assigning a tail of wide string (following found separator) to the
  9721. source one. If there are no separator characters found, source wide
  9722. string S is returned, and source wide string itself becomes empty. }
  9723. {$ENDIF _D2}
  9724. {$ENDIF _FPC}
  9725. function ParsePascalString( var S : String; const Separators : String ) : String;
  9726. {* Returns first characters of string S, separated from others by
  9727. one of characters, taking place in Separators string, assigning
  9728. a tail of string (after the found separator) to source string. If
  9729. there are no separator characters found, the source string S is returned,
  9730. and the source string itself becomes empty. Additionally: if the first (after
  9731. a blank space) is the quote "'" or '#', pascal string is assumung first
  9732. and is converted to usual string (without quotas) before analizing
  9733. of other separators. }
  9734. function String2PascalStrExpr( const S : String ) : String;
  9735. {* Converts string to Pascal-like string expression (concatenation of
  9736. strings with quotas and characters with leading '#'). }
  9737. function StrEq( const S1, S2 : String ) : Boolean;
  9738. {* Returns True, if LowerCase(S1) = LowerCase(S2). I.e., if strings
  9739. are equal to each other without caring of characters case sensitivity
  9740. (ASCII only). }
  9741. function AnsiEq( const S1, S2 : String ) : Boolean;
  9742. {* Returns True, if AnsiLowerCase(S1) = AnsiLowerCase(S2). I.e., if ANSI
  9743. stringsare equal to each other without caring of characters case
  9744. sensitivity. }
  9745. {$IFNDEF _D2}
  9746. {$IFNDEF _FPC}
  9747. function WAnsiEq( const S1, S2 : WideString ) : Boolean;
  9748. {* Returns True, if AnsiLowerCase(S1) = AnsiLowerCase(S2). I.e., if ANSI
  9749. stringsare equal to each other without caring of characters case
  9750. sensitivity. }
  9751. {$ENDIF _FPC}
  9752. {$ENDIF _D2}
  9753. function StrIn( const S : String; const A : array of String ) : Boolean;
  9754. {* Returns True, if S is "equal" to one of strings, taking place
  9755. in A array. To check equality, StrEq function is used, i.e.
  9756. comaprison is taking place without case sensitivity. }
  9757. {$IFNDEF _FPC}
  9758. type TSetOfChar = Set of Char;
  9759. {$IFNDEF _D2}
  9760. function WStrIn( const S : WideString; const A : array of WideString ) : Boolean;
  9761. {* Returns True, if S is "equal" to one of strings, taking place
  9762. in A array. To check equality, WAnsiEq function is used, i.e.
  9763. comaprison is taking place without case sensitivity. }
  9764. function CharIn( C: KOLChar; const A: TSetOfChar ): Boolean;
  9765. {* To replace expressions like S[1] in [ '0'..'z' ] to CharIn( S[ 1 ], [ '0'..'z' ] )
  9766. (and to avoid problems with Unicode version of code). }
  9767. {$ENDIF _D2}
  9768. {$ENDIF _FPC}
  9769. function StrIs( const S : String; const A : array of String; var Idx: Integer ) : Boolean;
  9770. {* Returns True, if S is "equal" to one of strings, taking place
  9771. in A array, and in such Case Idx also is assigned to an index of A element
  9772. equal to S. To check equality, StrEq function is used, i.e.
  9773. comaprison is taking place without case sensitivity. }
  9774. function IntIn( Value: Integer; const List: array of Integer ): Boolean;
  9775. {* Returns TRUE, if Value is found in a List. }
  9776. function _StrSatisfy( S, Mask : PKOLChar ) : Boolean;
  9777. {* }
  9778. function _2StrSatisfy( S, Mask: PKOLChar ): Boolean;
  9779. {* }
  9780. function StrSatisfy( const S, Mask : KOLString ) : Boolean;
  9781. {* Returns True, if S is satisfying to a given Mask (which can contain
  9782. wildcard symbols '*' and '?' interpeted correspondently as 'any
  9783. set of characters' and 'single any character'. If there are no
  9784. such wildcard symbols in a Mask, result is True only if S is maching
  9785. to Mask string.) }
  9786. function StrReplace( var S: String; const From, ReplTo: String ): Boolean;
  9787. {* Replaces first occurance of From to ReplTo in S, returns True,
  9788. if pattern From was found and replaced. }
  9789. function KOLStrReplace( var S: KOLString; const From, ReplTo: KOLString ): Boolean;
  9790. {* Replaces first occurance of From to ReplTo in S, returns True,
  9791. if pattern From was found and replaced. }
  9792. {$IFNDEF _FPC}
  9793. {$IFNDEF _D2}
  9794. function WStrReplace( var S: WideString; const From, ReplTo: WideString ): Boolean;
  9795. {* Replaces first occurance of From to ReplTo in S, returns True,
  9796. if pattern From was found and replaced. See also function StrReplace.
  9797. This function is not available in Delphi2 (this version of Delphi
  9798. does not support WideString type). }
  9799. {$ENDIF _D2}
  9800. {$ENDIF _FPC}
  9801. function StrRepeat( const S: String; Count: Integer ): String;
  9802. {* Repeats given string Count times. E.g., StrRepeat( 'A', 5 ) gives 'AAAAA'. }
  9803. {$IFNDEF _FPC}
  9804. {$IFNDEF _D2}
  9805. function WStrRepeat( const S: WideString; Count: Integer ): WideString;
  9806. {* Repeats given wide string Count times. E.g., StrRepeat( 'A', 5 ) gives 'AAAAA'. }
  9807. {$ENDIF _D2}
  9808. {$ENDIF _FPC}
  9809. procedure NormalizeUnixText( var S: String );
  9810. {* In the string S, replaces all occurances of character #10 (without leading #13)
  9811. to the character #13. }
  9812. procedure Koi8ToAnsi( s: PChar );
  9813. {* Converts Koi8 text to Ansi (in place) }
  9814. function StrPCopy(Dest: PChar; const Source: string): PChar;
  9815. {* Copyes Pascal-style string into null-terminaed one. }
  9816. function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;
  9817. {* Copyes first MaxLen characters of Pascal-style string into
  9818. null-terminated one. }
  9819. function DelimiterLast( const Str, Delimiters: KOLString ): Integer;
  9820. {* Returns index of the last of delimiters given by same named parameter
  9821. among characters of Str. If there are no delimiters found, length of
  9822. Str is returned. This function is intended mainly to use in filename
  9823. parsing functions. }
  9824. function __DelimiterLast( Str, Delimiters: PKOLChar ): PKOLChar;
  9825. {* Returns address of the last of delimiters given by Delimiters parameter
  9826. among characters of Str. If there are no delimeters found, position of
  9827. the null terminator in Str is returned. This function is intended
  9828. mainly to use in filename parsing functions. }
  9829. {$IFDEF _D3orHigher}
  9830. function W__DelimiterLast( Str, Delimiters: PWideChar ): PWideChar;
  9831. {* }
  9832. {$ENDIF _D3orHigher}
  9833. function SkipSpaces( P: PKOLChar ): PKOLChar;
  9834. {* Skips all characters #1..' ' in a string.
  9835. }
  9836. {$IFDEF F_P}
  9837. function DummyStrFun( const S: String ): String;
  9838. {$ENDIF}
  9839. //[Memory FUNCTIONS DECLARATIONS]
  9840. function CompareMem(P1, P2: Pointer; Length: Integer): Boolean;
  9841. {* Fast compare of two memory blocks. }
  9842. function AllocMem( Size : Integer ) : Pointer;
  9843. {* Allocates global memory and unlocks it. }
  9844. procedure DisposeMem( var Addr : Pointer );
  9845. {* Locks global memory block given by pointer, and frees it.
  9846. Does nothing, if the pointer is nil.
  9847. |<hr>
  9848. <R Text in clipboard operations>
  9849. }
  9850. {$IFDEF WIN_GDI}
  9851. //[clipboard FUNCTIONS DECLARATIONS]
  9852. function ClipboardHasText: Boolean;
  9853. {* Returns true, if the clipboard contain text to paste from. }
  9854. function Clipboard2Text: String;
  9855. {* If clipboard contains text, this function returns it for You. }
  9856. {$IFNDEF _FPC}
  9857. {$IFNDEF _D2}
  9858. function Clipboard2WText: WideString;
  9859. {* If clipboard contains text, this function returns it for You (as Unicode string). }
  9860. {$ENDIF _D2}
  9861. {$ENDIF _FPC}
  9862. function Text2Clipboard( const S: String ): Boolean;
  9863. {* Puts given string to a clipboard. }
  9864. {$IFNDEF _FPC}
  9865. {$IFNDEF _D2}
  9866. function WText2Clipboard( const WS: WideString ): Boolean;
  9867. {* Puts given Unicode string to a clipboard.
  9868. |<hr>
  9869. }
  9870. {$ENDIF _D2}
  9871. {$ENDIF _FPC}
  9872. {$ifdef win32}
  9873. //[Mnemonics FUNCTIONS DECLARATIONS]
  9874. var SearchMnemonics: function ( const S: KOLString ): KOLString
  9875. = {$IFDEF F_P} DummyStrFun {$ELSE}
  9876. {$IFDEF UNICODE_CTRLS} WAnsiUpperCase {$ELSE} AnsiUpperCase {$ENDIF} {$ENDIF};
  9877. MnemonicsLocale: Integer;
  9878. procedure SupportAnsiMnemonics( LocaleID: Integer );
  9879. {* Provides encoding to work with given locale. Call this global function to
  9880. extend TControl.SupportMnemonics capability (also should be called for a form
  9881. or for Applet variable).
  9882. <R Date and time handling>
  9883. }
  9884. {$endif win32}
  9885. {$ENDIF WIN_GDI}
  9886. {$IFDEF WIN_GDI}
  9887. //[TDateTime TYPE DEFINITION]
  9888. type
  9889. //TDateTime = Double; // well, it is already defined so in System.pas
  9890. {* Basic date and time type. Integer part represents year and days (as is,
  9891. i.e. 1-Jan-2000 is representing by value 730141, which is a number of
  9892. days from 1-Jan-0001 to 1-Jan-2000 inclusively). Fractional part is
  9893. representing hours, minutes, seconds and milliseconds of a day
  9894. proportionally (like in VCL TDateTime type, e.g. 0.5 = 12:00, 0.25 = 6:00,
  9895. etc.). }
  9896. PDayTable = ^TDayTable;
  9897. TDayTable = array[1..12] of Word;
  9898. TDateFormat = ( dfShortDate, dfLongDate );
  9899. {* Date formats available to use in formatting date/time to string. }
  9900. TTimeFormatFlag = ( tffNoMinutes, tffNoSeconds, tffNoMarker, tffForce24 );
  9901. {* Additional flags, used for formatting time. }
  9902. TTimeFormatFlags = Set of TTimeFormatFlag;
  9903. {* Set of flags, used for formatting time. }
  9904. const
  9905. MonthDays: array [Boolean] of TDayTable =
  9906. ((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
  9907. (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));
  9908. {* The MonthDays array can be used to quickly find the number of
  9909. days in a month: MonthDays[IsLeapYear(Y), M]. }
  9910. SecsPerDay = 24 * 60 * 60;
  9911. {* Seconds per day. }
  9912. MSecsPerDay = SecsPerDay * 1000;
  9913. {* Milliseconds per day. }
  9914. VCLDate0 = 693594;
  9915. {* Value to convert VCL "date 0" to KOL "date 0" and back.
  9916. This value corresponds to 30-Dec-1899, 0:00:00. So,
  9917. to convert VCL date to KOL date, just subtract this
  9918. value from VCL date. And to convert back from KOL date
  9919. to VCL date, add this value to KOL date.}
  9920. {++}(*
  9921. procedure GetLocalTime(var lpSystemTime: TSystemTime); {$ifdef wince}cdecl{$else}stdcall{$endif};
  9922. procedure GetSystemTime(var lpSystemTime: TSystemTime); {$ifdef wince}cdecl{$else}stdcall{$endif};
  9923. *){--}
  9924. //[Date&Time FUNCTIONS DECLARATIONS]
  9925. function Now : TDateTime;
  9926. {* Returns local date and time on running PC. }
  9927. function Date: TDateTime;
  9928. {* Returns todaylocal date. }
  9929. procedure DecodeDateFully( DateTime: TDateTime; var Year, Month, Day, DayOfWeek: WORD );
  9930. {* Decodes date. }
  9931. procedure DecodeDate( DateTime: TDateTime; var Year, Month, Day: WORD );
  9932. {* Decodes date. }
  9933. function EncodeDate( Year, Month, Day: WORD; var DateTime: TDateTime ): Boolean;
  9934. {* Encodes date. }
  9935. function CompareSystemTime(const D1, D2 : TSystemTime) : Integer;
  9936. {* Compares to TSystemTime records. Returns -1, 0, or 1 if, correspondantly,
  9937. D1 < D2, D1 = D2 and D1 > D2. }
  9938. procedure IncDays( var SystemTime : TSystemTime; DaysNum : Integer );
  9939. {* Increases/decreases day in TSystemTime record onto given days count
  9940. (can be negative). }
  9941. procedure IncMonths( var SystemTime : TSystemTime; MonthsNum : Integer );
  9942. {* Increases/decreases month number in TSystemTime record onto given
  9943. months count (can be negative). Correct result is not garantee if
  9944. day number is incorrect for newly obtained month. }
  9945. function IsLeapYear(Year: Integer): Boolean;
  9946. {* Returns True, if given year is "leap" (i.e. has 29 days in the February). }
  9947. function DayOfWeek(Date: TDateTime): Integer;
  9948. {* Returns day of week (0..6) for given date. }
  9949. function SystemTime2DateTime(const SystemTime : TSystemTime; var DateTime : TDateTime ) : Boolean;
  9950. {* Converts TSystemTime record to XDateTime variable. }
  9951. function DateTime2SystemTime(const DateTime : TDateTime; var SystemTime : TSystemTime ) : Boolean;
  9952. {* Converts TDateTime variable to TSystemTime record. }
  9953. function DateTime_System2Local( DTSys: TDateTime ): TDateTime;
  9954. {* Converts DTSys representing system time (+0 Grinvich) to local time. }
  9955. function DateTime_Local2System( DTLoc: TDateTime ): TDateTime;
  9956. {* Converts DTLoc representing local time to system time (+0 Grinvich) }
  9957. function FileTime2DateTime( const ft: TFileTime; var DT: TDateTime ): Boolean;
  9958. {* }
  9959. function DateTime2FileTime( DT: TDateTime; var ft: TFileTime ): Boolean;
  9960. {* }
  9961. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
  9962. {* Dividing of integer onto divisor with obtaining both result of division
  9963. and remainder. }
  9964. function SystemDate2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  9965. const DfltDateFormat : TDateFormat;
  9966. const DateFormat : PKOLChar ) : KOLString;
  9967. {* Formats date, stored in TSystemTime record into string, using given locale
  9968. and date/time formatting flags. (E.g.: GetUserDefaultLangID). }
  9969. function SystemTime2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  9970. const Flags : TTimeFormatFlags;
  9971. const TimeFormat : PKOLChar ) : KOLString;
  9972. {* Formats time, stored in TSystemTime record into string, using given locale
  9973. and date/time formatting flags. }
  9974. function Date2StrFmt( const Fmt: KOLString; D: TDateTime ): KOLString;
  9975. {* Represents date as a string correspondently to Fmt formatting string.
  9976. See possible pictures in definition of the function Str2DateTimeFmt
  9977. (the first part). If Fmt string is empty, default system date format
  9978. for short date string used. }
  9979. function Time2StrFmt( const Fmt: KOLString; D: TDateTime ): KOLString;
  9980. {* Represents time as a string correspondently to Fmt formatting string.
  9981. See possible pictures in definition of the function Str2DateTimeFmt
  9982. (the second part). If Fmt string is empty, default system time format
  9983. for short date string used. }
  9984. function DateTime2StrShort( D: TDateTime ): String;
  9985. {* Formats date and time to string in short date format using current user
  9986. locale. }
  9987. function Str2DateTimeFmt( const sFmtStr, sS: KOLString ): TDateTime;
  9988. {* Restores date or/and time from string correspondently to a format string.
  9989. Date and time formatting string can contain following pictures (case
  9990. sensitive):
  9991. |<pre>
  9992. DATE PICTURES
  9993. d Day of the month as digits without leading zeros for single digit days.
  9994. dd Day of the month as digits with leading zeros for single digit days
  9995. ddd Day of the week as a 3-letter abbreviation as specified by a
  9996. LOCALE_SABBREVDAYNAME value.
  9997. dddd Day of the week as specified by a LOCALE_SDAYNAME value.
  9998. M Month as digits without leading zeros for single digit months.
  9999. MM Month as digits with leading zeros for single digit months
  10000. MMM Month as a three letter abbreviation as specified by a LOCALE_SABBREVMONTHNAME value.
  10001. MMMM Month as specified by a LOCALE_SMONTHNAME value.
  10002. y Year represented only be the last digit.
  10003. yy Year represented only be the last two digits.
  10004. yyyy Year represented by the full 4 digits.
  10005. gg Period/era string as specified by the CAL_SERASTRING value. The gg
  10006. format picture in a date string is ignored if there is no associated era
  10007. string. In Enlish locales, usual values are BC or AD.
  10008. TIME PICTURES
  10009. h Hours without leading zeros for single-digit hours (12-hour clock).
  10010. hh Hours with leading zeros for single-digit hours (12-hour clock).
  10011. H Hours without leading zeros for single-digit hours (24-hour clock).
  10012. HH Hours with leading zeros for single-digit hours (24-hour clock).
  10013. m Minutes without leading zeros for single-digit minutes.
  10014. mm Minutes with leading zeros for single-digit minutes.
  10015. s Seconds without leading zeros for single-digit seconds.
  10016. ss Seconds with leading zeros for single-digit seconds.
  10017. t One character–time marker string (usually P or A, in English locales).
  10018. tt Multicharacter–time marker string (usually PM or AM, in English locales).
  10019. |</pre>
  10020. E.g., 'D, yyyy/MM/dd h:mm:ss'.
  10021. See also Str2DateTimeShort function.
  10022. }
  10023. function Str2DateTimeShort( const S: String ): TDateTime;
  10024. {* Restores date and time from string correspondently to current user locale. }
  10025. function Str2DateTimeShortEx( const S: KOLString ): TDateTime;
  10026. {* Like Str2DateTimeShort above, but uses locale defined date and time
  10027. separators to avoid recognizing time as a date in some cases.
  10028. |<hr>
  10029. <R File and directory routines>
  10030. }
  10031. {$ENDIF WIN_GDI}
  10032. //[OpenFile CONSTANTS]
  10033. const
  10034. ofOpenRead = {$IFDEF LIN} O_RDONLY {$ELSE} $80000000 {$ENDIF};
  10035. {* Use this flag (in combination with others) to open file for "read" only. }
  10036. ofOpenWrite = {$IFDEF LIN} O_WRONLY {$ELSE} $40000000 {$ENDIF};
  10037. {* Use this flag (in combination with others) to open file for "write" only. }
  10038. ofOpenReadWrite = {$IFDEF LIN} O_RDWR {$ELSE} $C0000000 {$ENDIF};
  10039. {* Use this flag (in combination with others) to open file for "read" and "write". }
  10040. ofShareExclusive = {$IFDEF LIN} $10 {$ELSE} $00 {$ENDIF};
  10041. {* Use this flag (in combination with others) to open file for exclusive use. }
  10042. ofShareDenyWrite = {$IFDEF LIN} $20 {$ELSE} $01 {$ENDIF};
  10043. {* Use this flag (in combination with others) to open file in share mode, when
  10044. only attempts to open it in other process for "write" will be impossible.
  10045. I.e., other processes could open this file simultaneously for read only
  10046. access. }
  10047. ofShareDenyRead = {$IFDEF LIN} 0 {not supported} {$ELSE} $02 {$ENDIF};
  10048. {* Use this flag (in combination with others) to open file in share mode, when
  10049. only attempts to open it for "read" in other processes will be disabled.
  10050. I.e., other processes could open it for "write" only access. }
  10051. ofShareDenyNone = {$IFDEF LIN} $30 {$ELSE} $03 {$ENDIF};
  10052. {* Use this flag (in combination with others) to open file in full sharing mode.
  10053. I.e. any process will be able open this file using the same share flag. }
  10054. ofCreateNew = {$IFDEF LIN} O_CREAT or O_TRUNC {$ELSE} $100 {$ENDIF};
  10055. {* Default creation disposition. Use this flag for creating new file (usually
  10056. for write access. }
  10057. ofCreateAlways = {$IFDEF LIN} O_CREAT {$ELSE} $200 {$ENDIF};
  10058. {* Use this flag (in combination with others) to open existing or creating new
  10059. file. If existing file is opened, it is truncated to size 0. }
  10060. ofOpenExisting = {$IFDEF LIN} 0 {$ELSE} $300 {$ENDIF};
  10061. {* Use this flag (in combination with others) to open existing file only. }
  10062. ofOpenAlways = {$IFDEF LIN} O_CREAT {$ELSE} $400 {$ENDIF};
  10063. {* Use this flag (in combination with others) to open existing or create new
  10064. (if such file is not yet exists). }
  10065. ofTruncateExisting = {$IFDEF LIN} O_TRUNC {$ELSE} $500 {$ENDIF};
  10066. {* Use this flag (in combination with others) to open existing file and truncate
  10067. it to size 0. }
  10068. ofAttrReadOnly = {$IFDEF LIN} 0 {$ELSE} $10000 {$ENDIF};
  10069. {* Use this flag to create Read-Only file (?). }
  10070. ofAttrHidden = {$IFDEF LIN} 0 {$ELSE} $20000 {$ENDIF};
  10071. {* Use this flag to create hidden file. }
  10072. ofAttrSystem = {$IFDEF LIN} 0 {$ELSE} $40000 {$ENDIF};
  10073. {* Use this flag to create system file. }
  10074. ofAttrTemp = {$IFDEF LIN} 0 {$ELSE} $1000000 {$ENDIF};
  10075. {* Use this flag to create temp file. }
  10076. ofAttrArchive = {$IFDEF LIN} 0 {$ELSE} $200000 {$ENDIF};
  10077. {* Use this flag to create archive file. }
  10078. ofAttrCompressed = {$IFDEF LIN} 0 {$ELSE} $8000000 {$ENDIF};
  10079. {* Use this flag to create compressed file. Has effect only on NTFS, and
  10080. only if ofAttrCompressed is not specified also. }
  10081. ofAttrOffline = {$IFDEF LIN} 0 {$ELSE} $10000000 {$ENDIF};
  10082. {* Use this flag to create offline file. }
  10083. //[END OF OpenFileConstants]
  10084. //[File FUNCTIONS DECLARATIONS]
  10085. {$IFDEF _D3orHigher}
  10086. function WFileCreate(const FileName: WideString; OpenFlags: DWord): THandle;
  10087. {* }
  10088. {$ENDIF}
  10089. function FileCreate(const FileName: KOLString; OpenFlags: DWord): THandle;
  10090. {* Call this function to open existing or create new file. OpenFlags
  10091. parameter can be a combination of up to three flags (by one from
  10092. each group:
  10093. |<table border=0>
  10094. |&L=<tr><td valign=top>%0</td><td valign=top>
  10095. |&E=</td></tr>
  10096. <L ofOpenRead, ofOpenWrite, ofOpenReadWrite> - 1st group. Here You decide
  10097. wish You open file for read, write or read-and-write operations; <E>
  10098. <L ofShareExclusive, ofShareDenyWrite, ofShareDenyRead, ofShareDenyNone> -2nd
  10099. group - sharing. Here You can mark out sharing mode, which is used to
  10100. open file. <E>
  10101. <L ofCreateNew, ofCreateAlways, ofOpenExisting, ofOpenAlways, ofTruncateExisting>
  10102. - 3rd group - creation disposition. Here You determine, either to create new
  10103. or open existing file and if to truncate existing or not.
  10104. |</table> }
  10105. function FileClose(Handle: THandle): Boolean;
  10106. {* Call it to close opened earlier file. }
  10107. function FileExists( const FileName: KOLString ) : Boolean;
  10108. {* Returns True, if given file exists.
  10109. |<br>Note (by Dod):
  10110. It is not documented in a help for GetFileAttributes, but it seems that
  10111. under NT-based Windows systems, FALSE is always returned for files
  10112. opened for excluseve use like pagefile.sys. }
  10113. {$IFDEF _D3orHigher}
  10114. function WFileExists( const FileName: WideString ) : Boolean;
  10115. {* Returns True, if given file exists.
  10116. |<br>Note (by Dod):
  10117. It is not documented in a help for GetFileAttributes, but it seems that
  10118. under NT-based Windows systems, FALSE is always returned for files
  10119. opened for excluseve use like pagefile.sys. }
  10120. {$ENDIF}
  10121. function FileSeek(Handle: THandle; MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  10122. {* Changes current position in file. }
  10123. {$IFDEF _D4orHigher}
  10124. function FileFarSeek(Handle: THandle; MoveTo: Int64; MoveMethod: TMoveMethod): DWord;
  10125. {* Changes current position in file. }
  10126. {$ENDIF _D4orHigher}
  10127. function FileRead(Handle: THandle; var Buffer; Count: DWord): DWord;
  10128. {* Reads bytes from current position in file to buffer. Returns number of
  10129. read bytes. }
  10130. {$IFDEF LIN}
  10131. function GetFileSize( Handle: THandle; HiSize: PDWORD ): DWORD;
  10132. {$ENDIF LIN}
  10133. function File2Str(Handle: THandle): String;
  10134. {* Reads file from current position to the end and returns result as ansi string. }
  10135. {$IFNDEF _D2}
  10136. function File2WStr(Handle: THandle): WideString;
  10137. {* Reads file from current position to the end and returns result as unicode string. }
  10138. {$ENDIF}
  10139. function FileWrite(Handle: THandle; const Buffer; Count: DWord): DWord;
  10140. {* Writes bytes from buffer to file from current position, extending its
  10141. size if needed. }
  10142. function FileEOF( Handle: THandle ) : Boolean;
  10143. {* Returns True, if EOF is achieved during read operations or last byte is
  10144. overwritten or append made to extend file during last write operation. }
  10145. function FileFullPath( const FileName : KOLString ) : KOLString;
  10146. {* Returns full path name for given file. Validness of source FileName path
  10147. is not checked at all. }
  10148. {$IFDEF WIN} //--------------- these functions have not sense in Linux: --------
  10149. function FileShortPath( const FileName: KOLString ): KOLString;
  10150. {* Returns short path to the file or directory. }
  10151. function FileIconSystemIdx( const Path: KOLString ): Integer;
  10152. {* Returns index of the index of the system icon correspondent to the file or
  10153. directory in system icon image list. }
  10154. function FileIconSysIdxOffline( const Path: KOLString ): Integer;
  10155. {* The same as FileIconSystemIdx, but an icon is calculated for the file
  10156. as it were offline (it is possible to get an icon for file even if
  10157. it is not existing, on base of its extension only). }
  10158. function DirIconSysIdxOffline( const Path: KOLString ): Integer;
  10159. {* The same as FileIconSysIdxOffline, but for a folder rather then for a file. }
  10160. {$ENDIF WIN} //-----------------------------------------------------------------
  10161. procedure LogFileOutput( const filepath, str: String );
  10162. {* Debug function. Use it to append given string to the end of the given file. }
  10163. function StrSaveToFile( const Filename: KOLString; const Str: String ): Boolean;
  10164. {* Saves a string to a file without any changes. If file does not exists, it is
  10165. created. If it exists, it is overriden. If operation failed, FALSE is returned. }
  10166. function StrLoadFromFile( const Filename: KOLString ): String;
  10167. {* Reads entire file and returns its content as a string. If operation failed,
  10168. an empty strinng is returned.
  10169. |<br>by Sergey Shishmintzev: it is possible to pass Filename = 'CON' to
  10170. read input from redirected console output. }
  10171. {$IFNDEF _D2}
  10172. function WStrSaveToFile( const Filename: KOLString; const Str: WideString ): Boolean;
  10173. {* Saves a string to a file without any changes. If file does not exists, it is
  10174. created. If it exists, it is overriden. If operation failed, FALSE is returned. }
  10175. function WStrLoadFromFile( const Filename: KOLString ): WideString;
  10176. {* Reads entire file and returns its content as a string. If operation failed,
  10177. an empty strinng is returned.
  10178. |<br>by Sergey Shishmintzev: it is possible to pass Filename = 'CON' to
  10179. read input from redirected console output. }
  10180. {$ENDIF}
  10181. function Mem2File( Filename: PKOLChar; Mem: Pointer; Len: Integer ): Integer;
  10182. {* Saves memory block to a file (if file exists it is overriden, created new if
  10183. not exists). }
  10184. function File2Mem( Filename: PKOLChar; Mem: Pointer; MaxLen: Integer ): Integer;
  10185. {* Loads file content to memory. }
  10186. {$IFDEF WIN}
  10187. type
  10188. PFindFileData = ^TFindFileData;
  10189. TFindFileData = {$ifndef wince}packed{$endif} record
  10190. // from TWin32FindData: -------------
  10191. dwFileAttributes: DWORD;
  10192. ftCreationTime: TFileTime;
  10193. ftLastAccessTime: TFileTime;
  10194. ftLastWriteTime: TFileTime;
  10195. nFileSizeHigh: DWORD;
  10196. nFileSizeLow: DWORD;
  10197. dwReserved0: DWORD;
  10198. {$ifndef wince}dwReserved1: DWORD;{$endif}
  10199. cFileName: array[0..MAX_PATH - 1] of KOLChar;
  10200. {$ifndef wince}cAlternateFileName: array[0..13] of KOLChar;{$endif}
  10201. //-------- + handle:
  10202. FindHandle: THandle;
  10203. end;
  10204. {$ENDIF WIN}
  10205. function Find_First( const FilePathName: KOLString; var F: TFindFileData ): Boolean;
  10206. function Find_Next( var F: TFindFileData ): Boolean;
  10207. procedure Find_Close( var F: TFindFileData );
  10208. {$IFDEF _D2orD3}
  10209. function FileSize( const Path: KOLString ) : Integer;
  10210. {$ELSE}
  10211. function FileSize( const Path: KOLString ) : Int64;
  10212. {$ENDIF}
  10213. {* Returns file size in bytes without opening it. If file too large
  10214. to represent its size as Integer, -1 is returned. }
  10215. procedure FileTime( const Path: KOLString;
  10216. CreateTime, LastAccessTime, LastModifyTime: PFileTime );
  10217. {* Returns file times without opening it. }
  10218. function GetUniqueFilename( PathName: KOLstring ) : KOLString;
  10219. {* If file given by PathName exists, modifies it to create unique
  10220. filename in target folder and returns it. Modification is performed
  10221. by incrementing last number in name (if name part of file does not
  10222. represent a number, such number is generated and concatenated to
  10223. it). E.g., if file aaa.aaa is already exist, the function checks
  10224. names aaa1.aaa, aaa2.aaa, ..., aaa10.aaa, etc. For name abc123.ext,
  10225. names abc124.ext, abc125.ext, etc. will be checked. }
  10226. function FileTimeCompare( const FT1, FT2 : TFileTime ) : Integer;
  10227. {* Compares time of file (createing, writing, accessing. Returns
  10228. -1, 0, 1 if correspondantly FT1<FT2, FT1=FT2, FT1>FT2. }
  10229. function DirectoryExists(const Name: KOLString): Boolean;
  10230. {* Returns True if given directory (folder) exists. }
  10231. function DiskPresent( const DrivePath: KOLString ): Boolean;
  10232. {* Returns TRUE if the disk is present }
  10233. {$IFDEF _D3orHigher}
  10234. function WDirectoryExists(const Name: WideString): Boolean;
  10235. {* }
  10236. {$ENDIF}
  10237. function CheckDirectoryContent( const Name: KOLString; SubDirsOnly: Boolean; const Mask: String ): Boolean;
  10238. {* Returns TRUE if directory does not contain files (or directories only)
  10239. satisfying given mask. }
  10240. function DirectoryEmpty(const Name: KOLString): Boolean;
  10241. {* Returns True if given directory is not exists or empty. }
  10242. //[Directory FUNCTIONS DECLARATIONS]
  10243. function DirectoryHasSubdirs( const Path: KOLString ): Boolean;
  10244. {* Returns TRUE if given directory exists and has subdirectories. }
  10245. function GetStartDir: KOLString;
  10246. {* Returns path to directory where executable is located (regardless
  10247. of current directory). }
  10248. function ExePath: KOLString;
  10249. {* Returns the path to the module (exe, dll) itself. }
  10250. //---------------------------------------------------------
  10251. // Following functions/procedures are created by Edward Aretino:
  10252. // IncludeTrailingPathDelimiter, ExcludeTrailingPathDelimiter,
  10253. // ForceDirectories, CreateDir, ChangeFileExt
  10254. //---------------------------------------------------------
  10255. function ExcludeTrailingChar( const S: KOLString; C: KOLChar ): KOLString;
  10256. {* If S is finished with character C, it is excluded. }
  10257. function IncludeTrailingChar( const S: KOLString; C: KOLChar ): KOLString;
  10258. {* If S is not finished with character C, it is added. }
  10259. function IncludeTrailingPathDelimiter(const S: KOLString): KOLstring;
  10260. {* by Edward Aretino. Adds '\' to the end if it is not present. }
  10261. function ExcludeTrailingPathDelimiter(const S: KOLString): KOLstring;
  10262. {* by Edward Aretino. Removes '\' at the end if it is present. }
  10263. function ExtractFileDrive( const Path: KOLString ) : KOLString;
  10264. {* Returns only drive part from exact path to a file or a directory.
  10265. For network paths, returns a computer name together with a following
  10266. name of shared directory (like '\\compname\shared\' ). }
  10267. function ExtractFilePath( const Path: KOLString ) : KOLString;
  10268. {* Returns only path part from exact path to file. }
  10269. {$IFDEF _D3orHigher}
  10270. function WExtractFilePath( const Path: WideString ) : WideString;
  10271. {* Returns only path part from exact path to file. }
  10272. {$ENDIF}
  10273. function IsNetworkPath( const Path: KOLString ): Boolean;
  10274. {* Returns TRUE, if Path is starting from '\\'. }
  10275. function ExtractFileName( const Path: KOLString ) : KOLString;
  10276. {* Extracts file name from exact path to file. }
  10277. function ExtractFileNameWOext( const Path: KOLString ) : KOLString;
  10278. {* Extracts file name from path to file or from filename. }
  10279. function ExtractFileExt( const Path: KOLString ) : KOLString;
  10280. {* Extracts extention from file name (returns it with dot '.' first) }
  10281. function ReplaceExt( const Path, NewExt: KOLString ): KOLString;
  10282. {* Returns Path to a file with extension replaced to a new extension.
  10283. Pass a new extension started with '.', e.g. '.txt'. }
  10284. function ForceDirectories(Dir: KOLString): Boolean;
  10285. {* by Edward Aretino. Creates given directory if not present. All needed
  10286. subdirectories are created if necessary. }
  10287. function CreateDir(const Dir: KOLString): Boolean;
  10288. {* by Edward Aretino. Creates given directory. }
  10289. function ChangeFileExt(FileName: KOLString; const Extension: KOLstring): KOLstring;
  10290. {* by Edward Aretino. Changes file extention. }
  10291. function ReplaceFileExt( const Path, NewExt: KOLString ): KOLString;
  10292. {* Returns a path with extension replaced to a given one. }
  10293. {$IFDEF WIN} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  10294. function ExtractShortPathName( const Path: KOLString ): KOLString;
  10295. {* }
  10296. {$IFDEF GDI}
  10297. function FilePathShortened( const Path: KOLString; MaxLen: Integer ): KOLString;
  10298. {* Returns shortened file path to fit MaxLen characters. }
  10299. function FilePathShortenPixels( const Path: KOLString; DC: HDC; MaxPixels: Integer ): KOLString;
  10300. {* Returns shortened file path to fit MaxPixels for a given DC. If you pass
  10301. Canvas.Handle of any control or bitmap object, ensure that font is valid
  10302. for it (or call TCanvas.RequiredState( FontValid ) method before. If DC passed
  10303. = 0, call is equivalent to call FilePathShortened, and MaxPixels means in such
  10304. case maximum number of characters. }
  10305. function MinimizeName( const Path: KOLString; DC: HDC; MaxPixels: Integer ): KOLString;
  10306. {* Exactly the same as MinimizeName in FileCtrl.pas (VCL). }
  10307. {$ENDIF GDI}
  10308. function GetSystemDir: KOLString;
  10309. {* Returns path to windows system directory. }
  10310. function GetWindowsDir : KOLstring;
  10311. {* Returns path to Windows directory. }
  10312. {$ENDIF WIN} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  10313. function GetWorkDir : KOLstring;
  10314. {* Returns path to application's working directory. }
  10315. function GetTempDir : KOLstring;
  10316. {* Returns path to default temp folder (directory to place temporary files). }
  10317. function CreateTempFile( const DirPath, Prefix: KOLString ): KOLString;
  10318. {* Returns path to just created temporary file. }
  10319. function GetFileListStr(FPath{e.g.'c:\tmp\'}, FMask{e.g.'*.*'}: KOLstring): KOLstring;
  10320. {* List of files in string, separating each path from others with a character stored
  10321. in FileOpSeparator variables (#13 by default).
  10322. E.g.: 'c:\tmp\unit1.dcu'#13'c:\tmp\unit1.~pa' (for use with DeleteFile2Recycle())}
  10323. function DeleteFiles( const DirPath: KOLString ): Boolean;
  10324. {* Deletes files by file mask (given with wildcards '*' and '?'). }
  10325. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  10326. var FileOpSeparator: KOLChar = {$IFDEF OLD_COMPAT}';'{$ELSE}#13{$ENDIF};
  10327. function DoFileOp( const FromList, ToList: KOLString; FileOp: UINT; Flags: Word;
  10328. Title: PKOLChar): Boolean;
  10329. {* By Unknown Mystic. FileOp can be: FO_MOVE, FO_COPY, FO_DELETE, FO_RENAME.
  10330. Flags can be a combination of values: FOF_MULTIDESTFILES, FOF_CONFIRMMOUSE,
  10331. FOF_SILENT, FOF_RENAMEONCOLLISION, FOF_NOCONFIRMATION, FOF_WANTMAPPINGHANDLE,
  10332. FOF_ALLOWUNDO, FOF_FILESONLY, FOF_SIMPLEPROGRESS, FOF_NOCONFIRMMKDIR,
  10333. FOF_NOERRORUI. Title used only with FOF_SIMPLEPROGRESS. }
  10334. function DeleteFile2Recycle( const Filename : KOLString ) : Boolean;
  10335. {* Deletes file to recycle bin. This operation can be very slow, when
  10336. called for a single file. To delete group of files at once (fast),
  10337. pass a list of paths to files to be deleted, separating each path
  10338. from others with a character stored in FileOpSeparator variable (by default #13,
  10339. but in case when OLD_COMPAT symbol added - ';'). E.g.: 'unit1.dcu'#13'unit1.~pa'
  10340. |<br>
  10341. FALSE is returned only in case when at least one file was not deleted
  10342. successfully.
  10343. |<br>
  10344. Note, that files are deleted not to recycle bin, if wildcards are
  10345. used or not fully qualified paths to files. }
  10346. function CopyMoveFiles( const FromList, ToList: KOLString; Move: Boolean ): Boolean;
  10347. {* }
  10348. {-}
  10349. function DiskFreeSpace( const Path: KOLString ): I64; {+}
  10350. {* Returns disk free space in bytes. Pass a path to root directory,
  10351. e.g. 'C:\'.
  10352. |<hr>
  10353. <R Wrappers to registry API functions>
  10354. These functions can be used independently to simplify access to Windows
  10355. registry. }
  10356. {$ENDIF WIN_GDI} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  10357. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  10358. //[Registry FUNCTIONS DECLARATIONS]
  10359. {++}(*
  10360. function RegSetValueEx(hKey: HKEY; lpValueName: PChar;
  10361. Reserved: DWORD; dwType: DWORD; lpData: Pointer; cbData: DWORD): Longint; {$ifdef wince}cdecl{$else}stdcall{$endif};
  10362. *){--}
  10363. function RegKeyOpenRead( Key: HKey; const SubKey: KOLString ): HKey;
  10364. {* Opens registry key for read operations (including enumerating of subkeys).
  10365. Pass either handle of opened earlier key or one of constans
  10366. HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS
  10367. as a first parameter. If not successful, 0 is returned. }
  10368. function RegKeyOpenWrite( Key: HKey; const SubKey: KOLString ): HKey;
  10369. {* Opens registry key for write operations (including adding new values or
  10370. subkeys), as well as for read operations too. See also RegKeyOpenRead. }
  10371. function RegKeyOpenCreate( Key: HKey; const SubKey: KOLString ): HKey;
  10372. {* Creates and opens key. }
  10373. function RegKeyGetStr( Key: HKey; const ValueName: KOLString ): KOLString;
  10374. {* Reads key, which must have type REG_SZ (null-terminated string). If
  10375. not successful, empty string is returned. This function as well as all
  10376. other registry manipulation functions, does nothing, if Key passed is 0
  10377. (without producing any error). }
  10378. function RegKeyGetStrEx( Key: HKey; const ValueName: KOLString ): KOLString;
  10379. {* Like RegKeyGetStr, but accepts REG_EXPAND_SZ type, expanding all
  10380. environment variables in resulting string.
  10381. |<br>
  10382. Code provided by neuron, e-mailto:neuron@hollowtube.mine.nu }
  10383. function RegKeyGetDw( Key: HKey; const ValueName: KOLString ): DWORD;
  10384. {* Reads key value, which must have type REG_DWORD. If ValueName passed
  10385. is '' (empty string), unnamed (default) value is reading. If not
  10386. successful, 0 is returned. }
  10387. function RegKeySetStr(Key: HKey; const ValueName: KOLString; const Value: KOLString ): Boolean;
  10388. {* Writes new key value as null-terminated string (type REG_SZ). If not
  10389. successful, returns False. }
  10390. function RegKeySetStrEx( Key: HKey; const ValueName: KOLString; const Value: KOLString;
  10391. expand: boolean): Boolean;
  10392. {* Writes new key value as REG_SZ or REG_EXPAND_SZ. - by neuron, e-mailto:neuron@hollowtube.mine.nu }
  10393. function RegKeySetDw( Key: HKey; const ValueName: KOLString; Value: DWORD ): Boolean;
  10394. {* Writes new key value as dword (with type REG_DWORD). Returns False,
  10395. if not successful. }
  10396. procedure RegKeyClose( Key: HKey );
  10397. {* Closes key, opened using RegKeyOpenRead or RegKeyOpenWrite. (But does
  10398. nothing, if Key passed is 0). }
  10399. function RegKeyDelete( Key: HKey; const SubKey: KOLString ): Boolean;
  10400. {* Deletes key. Does nothing if key passed is 0 (returns FALSE). }
  10401. function RegKeyDeleteValue( Key: HKey; const SubKey: KOLString ): Boolean;
  10402. {* Deletes value. - by neuron, e-mailto:neuron@hollowtube.mine.nu }
  10403. function RegKeyExists( Key: HKey; const SubKey: String ): Boolean;
  10404. {* Returns TRUE, if given subkey exists under given Key. }
  10405. function RegKeyValExists( Key: HKey; const ValueName: KOLString ): Boolean;
  10406. {* Returns TRUE, if given value exists under the Key.
  10407. }
  10408. function RegKeyValueSize( Key: HKey; const ValueName: KOLString ): Integer;
  10409. {* Returns a size of value. This is a size of buffer needed to store
  10410. registry key value. For string value, size returned is equal to a
  10411. length of string plus 1 for terminated null character. }
  10412. function RegKeyGetBinary( Key: HKey; const ValueName: KOLString; var Buffer; Count: Integer ): Integer;
  10413. {* Reads binary data from a registry, writing it to the Buffer.
  10414. It is supposed that size of Buffer provided is at least Count bytes.
  10415. Returned value is actul count of bytes read from the registry and written
  10416. to the Buffer.
  10417. |<br>
  10418. This function can be used to get data of any type from the registry, not
  10419. only REG_BINARY. }
  10420. function RegKeySetBinary( Key: HKey; const ValueName: KOLString; const Buffer; Count: Integer ): Boolean;
  10421. {* Stores binary data in the registry. }
  10422. function RegKeyGetDateTime(Key: HKey; const ValueName: KOLString): TDateTime;
  10423. {* Returns datetime variable stored in registry in binary format. }
  10424. function RegKeySetDateTime(Key: HKey; const ValueName: KOLString; DateTime: TDateTime): Boolean;
  10425. {* Stores DateTime variable in the registry. }
  10426. //-------------------------------------------------------
  10427. // registry functions by Valerian Luft <luft@valerian.de>
  10428. //-------------------------------------------------------
  10429. function RegKeyGetSubKeys( const Key: HKEY; List: PStrList): Boolean;
  10430. {* The function enumerates subkeys of the specified open registry key.
  10431. True is returned, if successful.
  10432. }
  10433. function RegKeyGetValueNames(const Key: HKEY; List: PStrList): Boolean;
  10434. {* The function enumerates value names of the specified open registry key.
  10435. True is returned, if successful.
  10436. }
  10437. function RegKeyGetValueTyp (const Key:HKEY; const ValueName: KOLString) : DWORD;
  10438. {* The function receives the type of data stored in the specified value.
  10439. |<br>
  10440. If the function fails, the return value is the Key value.
  10441. |<br>
  10442. If the function succeeds, the return value return will be one of the following:
  10443. |<br>
  10444. REG_BINARY , REG_DWORD, REG_DWORD_LITTLE_ENDIAN,
  10445. REG_DWORD_BIG_ENDIAN, REG_EXPAND_SZ, REG_LINK , REG_MULTI_SZ,
  10446. REG_NONE, REG_RESOURCE_LIST, REG_SZ
  10447. |<hr>
  10448. <R Data sorting (quicksort implementation)>
  10449. This part contains implementation of 'quick sort' algorithm,
  10450. based on following code:
  10451. |<pre>
  10452. | TQSort by Mike Junkin 10/19/95.
  10453. | DoQSort routine adapted from Peter Szymiczek's QSort procedure which
  10454. | was presented in issue#8 of The Unofficial Delphi Newsletter.
  10455. | TQSort changed by Vladimir Kladov (Mr.Bonanzas) to allow 32-bit
  10456. | sorting (of big arrays with more than 64K elements).
  10457. |</pre>
  10458. Finally, this sort procedure is adapted to XCL (and then to KOL)
  10459. requirements (no references to SysUtils, Classes etc. TQSort object
  10460. is transferred to a single procedure call and DoQSort method is
  10461. renamed to SortData - which is a regular procedure now). }
  10462. {$ENDIF WIN_GDI} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  10463. //[Sorting TYPES]
  10464. type
  10465. TCompareEvent = function (const Data: Pointer; const e1,e2 : Dword) : Integer;
  10466. {* Event type to define comparison function between two elements of an array.
  10467. This event handler must return -1 or +1 (correspondently for cases e1<e2
  10468. and e2>e2). Items are enumerated from 0 to uNElem. }
  10469. TSwapEvent = procedure (const Data : Pointer; const e1,e2 : Dword);
  10470. {* Event type to define swap procedure which is swapping two elements of an
  10471. array. }
  10472. //[SortData FUNCTIONS DECLARATIONS]
  10473. procedure SortData( const Data: Pointer; const uNElem: Dword;
  10474. const CompareFun: TCompareEvent;
  10475. const SwapProc: TSwapEvent );
  10476. {* Call it to sort any array of data of any kind, passing total
  10477. number of items in an array and two defined (regular) function
  10478. and procedure to perform custom compare and swap operations.
  10479. First procedure parameter is to pass it to callback function
  10480. CompareFun and procedure SwapProc. Items are enumerated from
  10481. 0 to uNElem-1. }
  10482. procedure SwapListItems( const L: Pointer; const e1, e2: DWORD );
  10483. {* Use this function as the last parameter for SortData call when a PList
  10484. object is sorting. SwapListItems just exchanges two items of the list. }
  10485. procedure SortIntegerArray( var A : array of Integer );
  10486. {* procedure to sort array of integers. }
  10487. procedure SortDwordArray( var A : array of DWORD );
  10488. {* Procedure to sort array of unsigned 32-bit integers.
  10489. |<hr>
  10490. }
  10491. { -- directory list object -- }
  10492. //[DirList Object]
  10493. type
  10494. TDirItemAction = ( diSkip, diAccept, diCancel );
  10495. TOnDirItem = procedure( Sender: PObj; var DirItem: TFindFileData; var Accept: TDirItemAction )
  10496. of object;
  10497. TSortDirRules = ( sdrNone, sdrFoldersFirst, sdrCaseSensitive, sdrByName, sdrByExt,
  10498. sdrBySize, sdrBySizeDescending, sdrByDateCreate, sdrByDateChanged,
  10499. sdrByDateAccessed );
  10500. {* List of rules (options) to sort directories. Rules are passed to Sort
  10501. method in an array, and first placed rules are applied first. }
  10502. {++}(*TDirList = class;*){--}
  10503. PDirList = {-}^{+}TDirList;
  10504. { ----------------------------------------------------------------------
  10505. TDirList - Directory scanning
  10506. ----------------------------------------------------------------------- }
  10507. //[TDirList DEFINITION]
  10508. TDirList = object( TObj )
  10509. {* Allows easy directory scanning. This is not visual object, but
  10510. storage to simplify working with directory content. }
  10511. protected
  10512. FList : PList;
  10513. FPath: KOLString;
  10514. fFilters: {$IFDEF UNICODE_CTRLS} PWStrList {$ELSE} PStrList {$ENDIF};
  10515. fOnItem: TOnDirItem;
  10516. function Get(Idx: Integer): PFindFileData;
  10517. function GetCount: Integer;
  10518. function GetNames(Idx: Integer): KOLString;
  10519. function GetIsDirectory(Idx: Integer): Boolean;
  10520. protected
  10521. function SatisfyFilter( FileName : PKOLChar; FileAttr, FindAttr : DWord ) : Boolean;
  10522. {++}(*public*){--}
  10523. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  10524. {* Destructor. As usual, call Free method to destroy an object. }
  10525. public
  10526. property Items[ Idx : Integer ] : PFindfileData read Get; default;
  10527. {* Full access to scanned items (files and subdirectories). }
  10528. property IsDirectory[ Idx: Integer ]: Boolean read GetIsDirectory;
  10529. {* Returns TRUE, if specified item represents a directory, not a file. }
  10530. property Count : Integer read GetCount;
  10531. {* Number of items. }
  10532. property Names[ Idx : Integer ] : KOLString read GetNames;
  10533. {* Full long names of directory items. }
  10534. property Path : KOLString read FPath;
  10535. {* Path of scanned directory. }
  10536. procedure Clear;
  10537. {* Call it to clear list of files. }
  10538. procedure ScanDirectory( const DirPath, Filter : KOLString; Attr : DWord );
  10539. {* Call it to rescan directory or to scan another directory content
  10540. (method Clear is called first). Pass path to directory, file filter
  10541. and attributes to scan directory immediately.
  10542. |<br>&nbsp;&nbsp;&nbsp;
  10543. Note: Pass FILE_ATTRIBUTE_... constants or-combination as Attr
  10544. parameter. If 0 passed, both files and directories are listed. }
  10545. procedure ScanDirectoryEx( const DirPath, Filters : KOLString; Attr : DWord );
  10546. {* Call it to rescan directory or to scan another directory content
  10547. (method Clear is called first). Pass path to directory, file filter
  10548. and attributes to scan directory immediately.
  10549. |<br>&nbsp;&nbsp;&nbsp;
  10550. Note: Pass FILE_ATTRIBUTE_... constants or-combination as Attr
  10551. parameter. }
  10552. procedure Sort( Rules : array of TSortDirRules );
  10553. {* Sorts directory entries. If empty rules array passed, default rules
  10554. array DefSortDirRules is used. }
  10555. function FileList( const Separator {e.g.: ';', or #13}: KOLString;
  10556. Dirs, FullPaths: Boolean ): KOLString;
  10557. {* Returns a string containing all names separated with Separator.
  10558. If Dirs=FALSE, only files are returned. }
  10559. property OnItem: TOnDirItem read fOnItem write fOnItem;
  10560. {* This event is called on reading each item while scanning directory.
  10561. To use it, first create PDirList object with empty path to scan, then
  10562. assign OnItem event and call ScanDirectory with correct path. }
  10563. end;
  10564. //[END OF TDirList DEFINITION]
  10565. //[NewDirList DECLARATIONS]
  10566. function NewDirList( const DirPath, Filter: KOLString; Attr: DWORD ): PDirList;
  10567. {* Creates directory list object using easy one-string filter. If Attr = FILE_ATTRIBUTE_NORMAL,
  10568. only files are scanned without directories. If Attr = 0, both files and
  10569. directories are listed. }
  10570. function NewDirListEx( const DirPath, Filters: KOLString; Attr: DWORD ): PDirList;
  10571. {* Creates directory list object using several filters, separated by ';'.
  10572. Filters starting from '^' consider to be anti-filters, i.e. files,
  10573. satisfying to those masks, are skept during scanning. }
  10574. const DefSortDirRules : array[ 0..3 ] of TSortDirRules = ( sdrFoldersFirst,
  10575. sdrByName, sdrBySize, sdrByDateCreate );
  10576. {* Default rules to sort directory entries. }
  10577. //[DirectorySize DECLARATION]
  10578. {-}
  10579. function DirectorySize( const Path: KOLString ): I64;
  10580. {* Returns directory size in bytes as large 64 bit integer. }
  10581. {+}
  10582. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  10583. //[OpenSaveDialog OPTIONS]
  10584. type
  10585. TOpenSaveOption = ( OSCreatePrompt,
  10586. OSExtensionDiffent,
  10587. OSFileMustExist,
  10588. OSHideReadonly,
  10589. OSNoChangedir,
  10590. OSNoReferenceLinks,
  10591. OSAllowMultiSelect,
  10592. OSNoNetworkButton,
  10593. OSNoReadonlyReturn,
  10594. OSOverwritePrompt,
  10595. OSPathMustExist,
  10596. OSReadonly,
  10597. OSNoValidate
  10598. //{$IFDEF OpenSaveDialog_Extended}
  10599. ,
  10600. OSTemplate,
  10601. OSHook
  10602. //{$ENDIF}
  10603. );
  10604. TOpenSaveOptions = set of TOpenSaveOption;
  10605. {* Options available for TOpenSaveDialog. }
  10606. {++}(*TOpenSaveDialog = class;*){--}
  10607. POpenSaveDialog = {-}^{+}TOpenSaveDialog;
  10608. { ----------------------------------------------------------------------
  10609. TOpenSaveDialog
  10610. ----------------------------------------------------------------------- }
  10611. //[TOpenSaveDialog DEFINITION]
  10612. TOpenSaveDialog = object( TObj )
  10613. {* Object to show standard Open/Save dialog. Initially provided
  10614. for XCL by Carlo Kok. }
  10615. protected
  10616. FFilter : KOLString;
  10617. fFilterIndex : Integer;
  10618. fOpenDialog : Boolean;
  10619. FInitialDir : KOLString;
  10620. FDefExtension : KOLString;
  10621. FFilename : KOLString;
  10622. FTitle : KOLString;
  10623. FOptions : TOpenSaveOptions;
  10624. fWnd: THandle;
  10625. fOpenReadOnly: Boolean;
  10626. public
  10627. TemplateName: KOLString; // do not forget to add OpenSaveDialog_Extended
  10628. HookProc: Pointer; // to project options conditionals!
  10629. NoPlaceBar: Boolean; // TRUE, if place bar is disabled in the new style
  10630. // dialogs (if the symbol OpenSaveDialog_Extended is
  10631. // not added in project options, place bar is always
  10632. // enabled in Windows 2000 and higher).
  10633. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  10634. {* destructor }
  10635. Function Execute : Boolean;
  10636. {* Call it after creating to perform selecting of file by user. }
  10637. property Filename : KOLString read FFilename write FFileName;
  10638. {*
  10639. Filename is separated by #13 when multiselect is true and the first
  10640. file, is the path of the files selected.
  10641. |<pre>
  10642. | C:\Projects
  10643. | Test1.Dpr
  10644. | Test2.Dpr
  10645. |</pre>
  10646. If only one file is selected, it is provided as (e.g.)
  10647. C:\Projects\Test1.dpr
  10648. |<br> For case when OSAllowMultiselect option used, after each
  10649. call initial value for a Filename containing several files prevents
  10650. system from opening the dialog. To fix this, assign another initial
  10651. value to Filename property in your code, when you use multiselect.
  10652. }
  10653. property InitialDir : KOLString read FInitialDir write FInitialDir;
  10654. {* Initial directory path. If not set, current directory (usually
  10655. directory when program is started) is used. }
  10656. property Filter : KOLString read FFilter write FFilter;
  10657. {* A list of pairs of filter names and filter masks, separated with '|'.
  10658. If a mask contains more than one mask, it should be separated with ';'.
  10659. E.g.:
  10660. ! 'All files|*.*|Text files|*.txt;*.1st;*.diz' }
  10661. property FilterIndex : Integer read FFilterIndex write FFilterIndex;
  10662. {* Index of default filter mask (0 by default, which means "first"). }
  10663. property OpenDialog : Boolean read FOpenDialog write FOpenDialog;
  10664. {* True, if "Open" dialog. False, if "Save" dialog. True is default. }
  10665. property Title : KOLString read Ftitle write Ftitle;
  10666. {* Title for dialog. }
  10667. property Options : TOpenSaveOptions read FOptions write FOptions;
  10668. {* Options. }
  10669. property DefExtension : KOLString read FDefExtension write FDefExtension;
  10670. {* Default extention. Set it to desired extension without leading period,
  10671. e.g. 'txt', but not '.txt'. }
  10672. property WndOwner: THandle read fWnd write fWnd;
  10673. {* Owner window handle. If not assigned, Applet.Handle is used (whenever
  10674. possible). Assign it, if your application has stay-on-top forms, and
  10675. a separate Applet object is used. }
  10676. property OpenReadOnly: Boolean read fOpenReadOnly;
  10677. {* TRUE after Execute, if Read Only check box was checked by the user.
  10678. Options are not affected anyway. }
  10679. end;
  10680. //[END OF TOpenSaveDialog DEFINITION]
  10681. //[Default OpenSaveDialog OPTIONS]
  10682. const DefOpenSaveDlgOptions: TOpenSaveOptions = [ OSHideReadonly,
  10683. OSOverwritePrompt, OSFileMustExist, OSPathMustExist ];
  10684. //[NewOpenSaveDialog DECLARATION]
  10685. function NewOpenSaveDialog( const Title, StrtDir: KOLString;
  10686. Options: TOpenSaveOptions ): POpenSaveDialog;
  10687. {* Creates object, which can be used (several times) to open file(s)
  10688. selecting dialog. }
  10689. //[OpenDirectory Object]
  10690. type
  10691. {++}(*TOpenDirDialog = class;*){--}
  10692. POpenDirDialog = {-}^{+}TOpenDirDialog;
  10693. TOpenDirOption = ( odBrowseForComputer, odBrowseForPrinter, odDontGoBelowDomain,
  10694. odOnlyFileSystemAncestors, odOnlySystemDirs, odStatusText,
  10695. odBrowseIncludeFiles, odEditBox, odNewDialogStyle );
  10696. {* Flags available for TOpenDirDialog object. }
  10697. // odfStatusText - do not support status callback
  10698. TOpenDirOptions = set of TOpenDirOption;
  10699. {* Set of all flags used to control ZOpenDirDialog class. }
  10700. TOnODSelChange = procedure( Sender: POpenDirDialog; NewSelDir: PKOL_Char;
  10701. var EnableOK: Integer; var StatusText: KOL_String )
  10702. of object;
  10703. {* Event type to be called when user select another directory in OpenDirDialog.
  10704. Set EnableOK to -1 to disable OK button, or to +1 to enable it.
  10705. It is also possible to set new StatusText string. }
  10706. {$ifdef wince}
  10707. {$define read_interface}
  10708. {$I KOLCEOpenDir.inc}
  10709. {$undef read_interface}
  10710. {$else}
  10711. { ----------------------------------------------------------------------
  10712. TOpenDirDialog
  10713. ----------------------------------------------------------------------- }
  10714. //[TOpenDirDialog DEFINITION]
  10715. TOpenDirDialog = object( TObj )
  10716. {* Dialog for open directories, uses SHBrowseForFolder. }
  10717. protected
  10718. FTitle: KOLString;
  10719. FOptions: TOpenDirOptions;
  10720. FCallBack: Pointer;
  10721. FCenterProc: procedure( Wnd: HWnd );
  10722. FBuf : array[ 0..MAX_PATH ] of KOLChar;
  10723. FInitialPath: String;
  10724. FCenterOnScreen: Boolean;
  10725. FDoSelChanged: procedure( Wnd: HWnd; Msg: DWORD; lParam, lpData: LParam ); {$ifdef wince}cdecl{$else}stdcall{$endif};
  10726. FOnSelChanged: TOnODSelChange;
  10727. FStatusText: KOLString;
  10728. FWnd, FDialogWnd: HWnd;
  10729. function GetPath: KOLString;
  10730. procedure SetInitialPath(const Value: KOLString);
  10731. procedure SetCenterOnScreen(const Value: Boolean);
  10732. procedure SetOnSelChanged(const Value: TOnODSelChange);
  10733. function GetInitialPath: KOLString;
  10734. public
  10735. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  10736. {* destructor }
  10737. function Execute : Boolean;
  10738. {* Call it to select directory by user. Returns True, if operation was
  10739. not cancelled by user. }
  10740. property Title : KOLString read FTitle write FTitle;
  10741. {* Title for a dialog. }
  10742. property Options : TOpenDirOptions read FOptions write FOptions;
  10743. {* Option flags. }
  10744. property Path : KOLString read GetPath;
  10745. {* Resulting (selected by user) path. }
  10746. property InitialPath: KOLString read GetInitialPath write SetInitialPath;
  10747. {* Set this property to a path of directory to be selected initially
  10748. in a dialog. }
  10749. property CenterOnScreen: Boolean read FCenterOnScreen write SetCenterOnScreen;
  10750. {* Set it to True to center dialog on screen. }
  10751. property OnSelChanged: TOnODSelChange read FOnSelChanged write SetOnSelChanged;
  10752. {* This event is called every time, when user selects another directory.
  10753. It is possible to enable/disable OK button in dialog and/or change
  10754. dialog status text in responce to event. }
  10755. property WndOwner: HWnd read FWnd write FWnd;
  10756. {* Owner window. If you want to provide your dialog visible over stay-on-top
  10757. form, fire it as a child of the form, assigning the handle of form window
  10758. to this property first. }
  10759. property DialogWnd: HWnd read FDialogWnd;
  10760. {* Handle to the open directory dialog itself, become available on the
  10761. first call of callback procedure (i.e. on the first call to OnSelChanged).
  10762. }
  10763. end;
  10764. //[END OF TOpenDirDialog DEFINITION]
  10765. {$endif wince}
  10766. //[NewOpenSaveDialog DECLARATION]
  10767. function NewOpenDirDialog( const Title: KOLString; Options: TOpenDirOptions ):
  10768. POpenDirDialog;
  10769. {* Creates object, which can be used (several times) to open directory
  10770. selecting dialog (using SHBrowseForFolder API call). }
  10771. //[Color Dialog Object]
  10772. type
  10773. TColorCustomOption = ( ccoFullOpen, ccoShortOpen, ccoPreventFullOpen );
  10774. type TKOLOpenDirDialog = POpenDirDialog;
  10775. {++}(*TColorDialog = class;*){--}
  10776. PColorDialog = {-}^{+}TColorDialog;
  10777. { ----------------------------------------------------------------------
  10778. TColorDialog
  10779. ----------------------------------------------------------------------- }
  10780. //[TColorDialog DEFINITION]
  10781. TColorDialog = object( TObj )
  10782. {* Color choosing dialog. }
  10783. protected
  10784. public
  10785. OwnerWindow: HWnd;
  10786. {* Owner window (can be 0). }
  10787. CustomColors: array[ 1..16 ] of TColor;
  10788. {* Array of stored custom colors. }
  10789. ColorCustomOption: TColorCustomOption;
  10790. {* Options (how to open a dialog). }
  10791. Color: TColor;
  10792. {* Returned color (if the result of Execute is True). }
  10793. function Execute: Boolean;
  10794. {* Call this method to open a dialog and wait its result. }
  10795. end;
  10796. //[END OF TColorDialog DEFINITION]
  10797. //[NewColorDialog DECLARATION]
  10798. function NewColorDialog( FullOpen: TColorCustomOption ): PColorDialog;
  10799. {* Creates color choosing dialog object. }
  10800. {$ENDIF WIN_GDI}
  10801. {$IFDEF WIN_GDI}
  10802. //[Ini files]
  10803. type
  10804. TIniFileMode = ( ifmRead, ifmWrite );
  10805. {* ifmRead is default mode (means "read" data from ini-file.
  10806. Set mode to ifmWrite to write data to ini-file, correspondent to
  10807. TIniFile. }
  10808. {$ifdef wince}
  10809. {$define read_interface}
  10810. {$I KOLCE_IniFile.inc}
  10811. {$undef read_interface}
  10812. {$else}
  10813. {++}(*TIniFile = class;*){--}
  10814. PIniFile = {-}^{+}TIniFile;
  10815. { ----------------------------------------------------------------------
  10816. TIniFile - store/load data to ini-files
  10817. ----------------------------------------------------------------------- }
  10818. //[TIniFile DEFINITION]
  10819. TIniFile = object( TObj )
  10820. {* Ini file incapsulation. The main feature is what the same block of
  10821. read-write operations could be defined (difference must be only in
  10822. Mode value).
  10823. |*Ini file sample.
  10824. This sample shows how the same Pascal operators can be used both
  10825. for read and write for the same variables, when working with TIniFile:
  10826. ! procedure ReadWriteIni( Write: Boolean );
  10827. ! var Ini: PIniFile;
  10828. ! begin
  10829. ! Ini := OpenIniFile( 'MyIniFile.ini' );
  10830. ! Ini.Section := 'Main';
  10831. ! if Write then // if Write, the same operators will save
  10832. ! Ini.Mode := ifmWrite; // data rather then load.
  10833. ! MyForm.Left := Ini.ValueInteger( 'Left', MyForm.Left );
  10834. ! MyForm.Top := Ini.ValueInteger( 'Top', MyForm.Top );
  10835. ! Ini.Free;
  10836. ! end;
  10837. !
  10838. |* }
  10839. protected
  10840. fMode: TIniFileMode;
  10841. fFileName: KOLString;
  10842. fSection: KOLString;
  10843. protected
  10844. public
  10845. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  10846. {* destructor }
  10847. property Mode: TIniFileMode read fMode write fMode;
  10848. {* ifmWrite, if write data to ini-file rather than read it. }
  10849. property FileName: KOLString read fFileName;
  10850. {* Ini file name. }
  10851. property Section: KOLString read fSection write fSection;
  10852. {* Current ini section. }
  10853. function ValueInteger( const Key: KOLString; Value: Integer ): Integer;
  10854. {* Reads or writes integer data value. }
  10855. function ValueString( const Key: KOLString; const Value: KOLString ): KOLString;
  10856. {* Reads or writes string data value. }
  10857. function ValueBoolean( const Key: KOLString; Value: Boolean ): Boolean;
  10858. {* Reads or writes boolean data value. }
  10859. function ValueData( const Key: KOLString; Value: Pointer; Count: Integer ): Boolean;
  10860. {* Reads or writes data from/to buffer. Returns True, if success. }
  10861. procedure ClearAll;
  10862. {* Clears all sections of ini-file. }
  10863. procedure ClearSection;
  10864. {* Clears current Section of ini-file. }
  10865. procedure ClearKey( const Key: KOLString );
  10866. {* Clears given key in current section. }
  10867. /////////////// + by Vyacheslav A. Gavrik:
  10868. {$IFDEF UNICODE_CTRLS}
  10869. procedure GetSectionNames(Names:PWStrList);
  10870. {$ELSE}
  10871. procedure GetSectionNames(Names:PStrList);
  10872. {$ENDIF}
  10873. {* Retrieves section names, storing it in string list passed as a parameter.
  10874. String list does not cleared before processing. Section names are added
  10875. to the end of the string list. }
  10876. {$IFDEF UNICODE_CTRLS}
  10877. procedure SectionData(Names:PWStrList);
  10878. {$ELSE}
  10879. procedure SectionData(Names:PStrList);
  10880. {$ENDIF}
  10881. {* Read/write current section content to/from string list. (Depending on
  10882. current Mode value). }
  10883. ///////////////
  10884. end;
  10885. //[END OF TIniFile DEFINITION]
  10886. {$endif wince}
  10887. //[OpenIniFile DECLARATION]
  10888. function OpenIniFile( const FileName: KOLString ): PIniFile;
  10889. {* Opens ini file, creating TIniFile object instance to work with it. }
  10890. {$ENDIF WIN_GDI}
  10891. //[MENU OBJECT]
  10892. {$ifdef win32}
  10893. {$ifndef FPC}
  10894. type
  10895. TMenuitemInfo = {$ifndef wince}packed{$endif} record
  10896. cbSize: UINT;
  10897. fMask: UINT;
  10898. fType: UINT; { used if MIIM_TYPE}
  10899. fState: UINT; { used if MIIM_STATE}
  10900. wID: UINT; { used if MIIM_ID}
  10901. hSubMenu: HMENU; { used if MIIM_SUBMENU}
  10902. hbmpChecked: HBITMAP; { used if MIIM_CHECKMARKS}
  10903. hbmpUnchecked: HBITMAP; { used if MIIM_CHECKMARKS}
  10904. dwItemData: DWORD; { used if MIIM_DATA}
  10905. dwTypeData: PKOLChar; { used if MIIM_TYPE}
  10906. cch: UINT; { used if MIIM_TYPE}
  10907. hbmpItem: HBITMAP; { used if MIIM_BITMAP - not exists under Windows95 }
  10908. end;
  10909. {$endif FPC}
  10910. {$endif win32}
  10911. const
  10912. TPM_HORPOSANIMATION = $0400;
  10913. TPM_HORNEGANIMATION = $0800;
  10914. TPM_VERPOSANIMATION = $1000;
  10915. TPM_VERNEGANIMATION = $2000;
  10916. TPM_NOANIMATION = $4000;
  10917. type
  10918. {++}(*TMenu = class;*){--}
  10919. PMenu = {-}^{+}TMenu;
  10920. TOnMenuItem = procedure( Sender : PMenu; Item : Integer ) of object;
  10921. {* Event type to define OnMenuItem event. }
  10922. TMenuAccelerator = {$ifndef wince}packed{$endif} Record
  10923. {* Menu accelerator record. Use MakeAccelerator function to combine desired
  10924. attributes into a record, describing the accelerator. }
  10925. fVirt: Byte; // or-combination of FSHIFT, FCONTROL, FALT, FVIRTKEY, FNOINVERT
  10926. Key: Word; // character or virtual key code (FVIRTKEY flag is present above)
  10927. NotUsed: Byte; // not used
  10928. end;
  10929. // by Sergey Shisminzev:
  10930. TMenuOption = (moDefault, moDisabled, moChecked,
  10931. moCheckMark, moRadioMark, moSeparator, moBitmap, moSubMenu,
  10932. moBreak, moBarBreak);
  10933. {* Options to add menu items dynamically. }
  10934. TMenuOptions = set of TMenuOption;
  10935. {* Set of options for menu item to use it in TMenu.AddItem method. }
  10936. TMenuBreak = ( mbrNone, mbrBreak, mbrBarBreak );
  10937. {* Possible menu item break types. }
  10938. { ----------------------------------------------------------------------
  10939. TMenu - main, popup menu and menu item
  10940. ----------------------------------------------------------------------- }
  10941. //[TMenu DEFINITION]
  10942. TMenu = object( TObj )
  10943. protected
  10944. {$IFDEF GDI}
  10945. function GetItemHelpContext(Idx: Integer): Integer;
  10946. procedure SetItemHelpContext(Idx: Integer; const Value: Integer);
  10947. {* Dynamic menu incapsulation object. Can play role of form main menu or popup
  10948. menu, depending on kind of parent window (form or control) and order of
  10949. creation (created first (for a form) become main menu). Does not allow
  10950. merging menus, but items can be hidden. Additionally checkmark bitmaps,
  10951. shortcut key accelerators and other features are available. }
  10952. protected
  10953. FHandle: HMenu;
  10954. FId: Integer;
  10955. FControl: PControl;
  10956. {$ENDIF GDI}
  10957. fNextMenu : PMenu;
  10958. {$IFDEF GDI}
  10959. FMenuBreak: TMenuBreak;
  10960. FOnMenuItem : TOnMenuItem;
  10961. FOnRadioOff : TOnMenuItem;
  10962. fOnPopup: TOnEvent;
  10963. fByAccel: Boolean;
  10964. FPopupFlags: DWORD;
  10965. //fAutoPopup: Boolean;
  10966. FSavedState: DWORD;
  10967. FData: Pointer;
  10968. FOwnerDraw: Boolean;
  10969. {$ENDIF GDI}
  10970. FParentMenu: PMenu;
  10971. FItems: PList;
  10972. FRadioGroup: Integer;
  10973. FIsCheckItem: Boolean;
  10974. FIsSeparator: Boolean;
  10975. FVisible: Boolean;
  10976. FCaption: KOLString;
  10977. {$IFDEF _X_}
  10978. {$IFDEF GTK}
  10979. fChecked: Boolean;
  10980. fMnemonics: String;
  10981. fGtkMenuItem: PGtkWidget;
  10982. fGtkMenuShell: PGtkWidget;
  10983. fGtkMenuBar: PGtkWidget;
  10984. {$ENDIF GTK}
  10985. {$ENDIF _X_}
  10986. {$IFDEF GDI}
  10987. FBitmap: HBitmap;
  10988. FBmpChecked: HBitmap;
  10989. FBmpItem: HBitmap;
  10990. ClearBitmapsProc: procedure( Sender: PMenu );
  10991. FClearBitmaps: Boolean;
  10992. FNotPopup: Boolean;
  10993. FAccelerator: TMenuAccelerator;
  10994. FHelpContext: Integer;
  10995. FOnMeasureItem: TOnMeasureItem;
  10996. FOnDrawItem: TOnDrawItem;
  10997. {$IFDEF USE_MENU_CURCTL}
  10998. fCurCtl: PControl;
  10999. {$ENDIF USE_MENU_CURCTL}
  11000. function GetItems( Id: HMenu ): PMenu;
  11001. function GetCount: Integer;
  11002. function GetTopParent: PMenu;
  11003. function GetState( const Index: Integer ): Boolean;
  11004. procedure SetState( const Index: Integer; Value: Boolean );
  11005. procedure SetVisible( Value: Boolean );
  11006. procedure SetData( Value: Pointer );
  11007. procedure SetMenuItemCaption( const Value: KOLString );
  11008. function FillMenuItems(AHandle: HMenu; StartIdx: Integer;
  11009. const Template: array of PKOLChar): Integer;
  11010. procedure SetMenuBreak( Value: TMenuBreak );
  11011. function GetControl: PControl;
  11012. function GetInfo( var MII: TMenuItemInfo ): Boolean;
  11013. function SetInfo( var MII: TMenuItemInfo ): Boolean;
  11014. function SetTypeInfo( var MII: TMenuItemInfo ): Boolean;
  11015. procedure SetBitmap( Value: HBitmap );
  11016. procedure SetBmpChecked( Value: HBitmap );
  11017. procedure SetBmpItem( Value: HBitmap );
  11018. procedure ClearBitmaps;
  11019. procedure SetAccelerator( const Value: TMenuAccelerator );
  11020. {$IFDEF GDI}
  11021. procedure SetHelpContext( Value: Integer );
  11022. {$ENDIF GDI}
  11023. procedure SetSubmenu( Value: HMenu );
  11024. procedure SetOnMeasureItem( const Value: TOnMeasureItem );
  11025. procedure SetOnDrawItem( const Value: TOnDrawItem );
  11026. procedure SetOwnerDraw( Value: Boolean );
  11027. protected
  11028. function GetItemChecked( Item : Integer ) : Boolean;
  11029. procedure SetItemChecked( Item : Integer; Value : Boolean );
  11030. function GetItemBitmap(Idx: Integer): HBitmap;
  11031. procedure SetItemBitmap(Idx: Integer; const Value: HBitmap);
  11032. function GetItemText(Idx: Integer): KOLString;
  11033. procedure SetItemText(Idx: Integer; const Value: KOLString);
  11034. function GetItemEnabled(Idx: Integer): Boolean;
  11035. procedure SetItemEnabled(Idx: Integer; const Value: Boolean);
  11036. function GetItemVisible(Idx: Integer): Boolean;
  11037. procedure SetItemVisible(Idx: Integer; const Value: Boolean);
  11038. function GetItemAccelerator(Idx: Integer): TMenuAccelerator;
  11039. procedure SetItemAccelerator(Idx: Integer; const Value: TMenuAccelerator);
  11040. function GetItemSubMenu( Idx: Integer ): HMenu;
  11041. {$ENDIF GDI}
  11042. {$ifdef wince}
  11043. procedure ReCreate;
  11044. procedure SaveState;
  11045. {$endif wince}
  11046. public
  11047. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  11048. {* To release menu dynamically, call Free method instead. All (popup)
  11049. menus created after this (for the same control) are destroyed in
  11050. that case too.
  11051. |<br>
  11052. It is not necessary to release menu object manually: all menus,
  11053. created with given form (or control), are automatically released,
  11054. when owner form (or control) is destroyed.
  11055. }
  11056. {$IFDEF GDI}
  11057. property Handle : HMenu read FHandle;
  11058. {* Handle of Windows menu object. }
  11059. property MenuId: Integer read FId;
  11060. {* Id of the menu item object. If menu item has subitems, it has
  11061. also submenu Handle. Top parent menu object itself has no Id.
  11062. Id-s areassigned automatically starting from 4096. Do not
  11063. (re)create menu items instantly, because such values are not
  11064. reused, and maximum possible Id value must not exceed 65535. }
  11065. property Parent: PMenu read FParentMenu;
  11066. {* Parent menu item (or parent menu). }
  11067. property TopParent: PMenu read GetTopParent;
  11068. {* Top parent menu, owning all nested subitems. }
  11069. property Owner: PControl read GetControl;
  11070. {* Parent control or form. }
  11071. property Caption: KOLString read FCaption write SetMenuItemCaption;
  11072. {* Menu item caption text (including '&' indicating mnemonic characters,
  11073. and keyboard accelerator representation string, usually following
  11074. tabulation character). }
  11075. property Items[ Id: HMenu ]: PMenu read GetItems;
  11076. {* Returns menu item object by its index or by menu id. Since menu id
  11077. values are starting from 4096, values from 0 to 4095 are interpreted
  11078. as absolute index of menu item. Be careful accessing menu items or
  11079. submenus by index, if you dynamically insert or delete items or
  11080. submenus. In this version, separators are enumerating too, like
  11081. all other items. Use index -1 to access object itself. The first
  11082. item of a menu (or the first subitem of submenu item) has index 0.
  11083. Children are enumerating before all siblings. The maximum available
  11084. index is (Count - 1), when accessing menu items by index. }
  11085. property Count: Integer read GetCount;
  11086. {* Count of items together with all its nested subitems. }
  11087. function IndexOf( Item: PMenu ): Integer;
  11088. {* Returns index of an item. This index can be used to access
  11089. menu item. Value -2 is returned, if the Item is not a child for menu
  11090. or menu item, and has no parents, which are children for it, etc.
  11091. Menu object itself always has index -1. }
  11092. property OnMenuItem : TOnMenuItem read FOnMenuItem write FOnMenuItem;
  11093. {* Is called when menu item is clicked. Absolute index of menu item
  11094. clicked is passed as the second parameter. TopParent always is
  11095. passed as a Sender parameter. }
  11096. property ByAccel: Boolean read fByAccel;
  11097. {* True, when OnMenuItem is called not by mouse, but by accelerator key.
  11098. Check this flag for entire menu (TopParent), not for item itself.
  11099. (Note, that Sender in OnMenuItem always is TopParent menu object). )
  11100. }
  11101. property IsSeparator: Boolean read FIsSeparator;
  11102. {* TRUE, if a separator menu item. }
  11103. property MenuBreak: TMenuBreak read FMenuBreak write SetMenuBreak;
  11104. {* Menu item break type. }
  11105. property OnUncheckRadioItem : TOnMenuItem read FOnRadioOff write FOnRadioOff;
  11106. {* Is called when radio item becomes unchecked in menu in result of
  11107. checking another radio item of the same radio group. }
  11108. property RadioGroup: Integer read FRadioGroup write FRadioGroup;
  11109. {* Radio group index. Several neighbour items with the same radio group
  11110. index form radio group. Only single item from the same group can be
  11111. checked at a time. }
  11112. property IsCheckItem: Boolean read FIsCheckItem;
  11113. {* If menu item is defined as check item, it is checked automatically
  11114. when clicked. }
  11115. procedure RadioCheckItem;
  11116. {* Call this method to check radio item. (Calling this method for
  11117. an item, which is not belonging to a radio group, just sets its
  11118. Checked state to TRUE). }
  11119. property Checked: Boolean index MFS_CHECKED read GetState write SetState;
  11120. {* Checked state of the item. }
  11121. property Enabled: Boolean
  11122. {$IFDEF F_P}
  11123. index $80000000 or MFS_DISABLED
  11124. {$ELSE DELPHI}
  11125. index Integer( $80000000 or MFS_DISABLED )
  11126. {$ENDIF F_P/DELPHI}
  11127. read GetState write SetState;
  11128. {* Enabled state of the item. Whaen assigned, Grayed state also is
  11129. set to arbitrary value (i.e., when Enabled is set to true, Grayed
  11130. is set to FALSE. }
  11131. property DefaultItem: Boolean index MFS_DEFAULT read GetState write SetState;
  11132. {* Set this property to TRUE to make menu item default. Default item
  11133. is drawn with bold.
  11134. |<br>If you change DefaultItem at run-time and whant
  11135. to provide changing its visual state, recreate the item first resetting
  11136. Visible property, then setting it again. }
  11137. property Highlight: Boolean index MFS_HILITE read GetState write SetState;
  11138. {* Highlight state of the item. }
  11139. property Visible: Boolean read FVisible write SetVisible;
  11140. {* Visibility of menu item. }
  11141. property Data: Pointer read FData write SetData;
  11142. {* Data pointer, associated with the menu item. }
  11143. property Bitmap: HBitmap read FBitmap write SetBitmap;
  11144. {* Bitmap used for unchecked state of the menu item. }
  11145. property BitmapChecked: HBitmap read FBmpChecked write SetBmpChecked;
  11146. {* Bitmap used for checked state of the menu item. }
  11147. property BitmapItem: HBitmap read FBmpItem write SetBmpItem;
  11148. {* Bitmap used for item itself. In addition, following special values
  11149. are possible:
  11150. HBMMENU_CALLBACK, HBMMENU_MBAR_CLOSE, HBMMENU_MBAR_CLOSE_D,
  11151. HBMMENU_MBAR_MINIMIZE, HBMMENU_MBAR_MINIMIZE_D, HBMMENU_MBAR_RESTORE,
  11152. HBMMENU_POPUP_CLOSE, HBMMENU_POPUP_MAXIMIZE, HBMMENU_POPUP_MINIMIZE,
  11153. HBMMENU_POPUP_RESTORE, HBMMENU_SYSTEM. }
  11154. property Accelerator: TMenuAccelerator read FAccelerator write SetAccelerator;
  11155. {* Accelerator for menu item. }
  11156. {$IFDEF GDI}
  11157. property HelpContext: Integer read FHelpContext write SetHelpContext;
  11158. {* Help context for entire menu (help context can not be assigned to
  11159. individual menu items). }
  11160. {$ENDIF GDI}
  11161. procedure AssignEvents( StartIdx: Integer; const Events: array of TOnMenuItem );
  11162. {* It is possible to assign its own event handler to every menu item
  11163. using this call. This procedure also is called automatically in
  11164. a constructor NewMenuEx. }
  11165. function Popup( X, Y : Integer ): Integer; {!ecm}
  11166. {* Only for popup menu - to popup it at the given position on screen.
  11167. Return: If you specify TPM_RETURNCMD in the uFlags parameter, the return
  11168. value is the menu-item identifier of the item that the user selected.
  11169. If the user cancels the menu without making a selection, or if an error
  11170. occurs, then the return value is zero.
  11171. If you do not specify TPM_RETURNCMD in the uFlags parameter, the return
  11172. value is nonzero if the function succeeds and zero if it fails. }
  11173. function PopupEx( X, Y: Integer ): Integer; {!ecm}
  11174. {* This version of popup command is very useful, when popup menu is activated
  11175. when its parent window is not visible (e.g., for a kind of applications,
  11176. which always are invisible, and can be activated only using tray icon).
  11177. PopupEx method provides correct tracking of menu disappearing when mouse
  11178. is clicked anywhere else on screen, fixing strange menu behavior in some
  11179. Windows versions (NT).
  11180. |<br>
  11181. Actually, when PopupEx used, parent form is shown but below of visible
  11182. screen, and when menu is disappearing, previous state of the form (visibility
  11183. and position) are restored. If such solvation is not satisfying You,
  11184. You can do something else (e.g., use region clipping, etc.) }
  11185. property OnPopup: TOnEvent read fOnPopup write fOnPopup;
  11186. {* This event occurs before the popup menu is shown. }
  11187. property NotPopup: Boolean read FNotPopup write FNotPopup;
  11188. {* Set this property to true to prevent popup of popup menu, e.g. in
  11189. OnPopup event handler. }
  11190. property Flags: DWORD read FPopupFlags write FPopupFlags;
  11191. {* Pop-up flags, which are used to call TrackPopupMenuEx, when Popup or
  11192. PopupEx method is called. Can be a combination of following values:
  11193. |<br>
  11194. TPM_CENTERALIGN or TPM_LEFTALIGN or TPM_RIGHTALIGN
  11195. |<br>
  11196. TPM_BOTTOMALIGN or TPM_TOPALIGN or TPM_VCENTERALIGN
  11197. |<br>
  11198. TPM_NONOTIFY or TPM_RETURNCMD
  11199. |<br>
  11200. TPM_LEFTBUTTON or TPM_RIGHTBUTTON
  11201. |<br>
  11202. TPM_HORNEGANIMATION or TPM_HORPOSANIMATION or TPM_NOANIMATION or
  11203. TPM_VERNEGANIMATION or TPM_VERPOSANIMATION
  11204. |<br>
  11205. TPM_HORIZONTAL or TPM_VERTICAL.
  11206. |<br>
  11207. By default, a combination TPM_LEFTALIGN or TPM_LEFTBUTTON is used. }
  11208. function Insert(InsertBefore: Integer; ACaption: PKOLChar; Event: TOnMenuItem;
  11209. Options: TMenuOptions): PMenu;
  11210. {* Inserts new menu item before item, given by Id (>=4096) or index
  11211. value InsertBefore. Pointer to an object created is returned. }
  11212. property SubMenu: HMenu read FHandle; // write SetSubMenu;
  11213. {* Submenu associated with the menu item. The same as Handle. It was possible
  11214. in ealier versions to change this value, replacing (removing, assigning)
  11215. entire popup menu as a submenu for menu item.
  11216. But in modern version of TMenu, this is not possible.
  11217. Instead, entire menu object should be added or removed using
  11218. InsertSubmenu or RemoveSubmenu methods. }
  11219. procedure InsertSubMenu( SubMenuToInsert: PMenu; InsertBefore: Integer );
  11220. {* Inserts existing menu item (together with its subitems if any present)
  11221. into given position. See also RemoveSubMenu. }
  11222. function RemoveSubMenu( ItemToRemove: Integer ): PMenu;
  11223. {* Removes menu item from the menu, returning TMenu object, representing it,
  11224. if submenu item, having its own children, detached. If an individual menu
  11225. item is removed, nil is returned.
  11226. This function can be useful to add or remove dynamically entire submenus
  11227. (created together with its subitems). }
  11228. property OnMeasureItem: TOnMeasureItem read FOnMeasureItem write SetOnMeasureItem;
  11229. {* This event is called for owner-drawn menu items. Event handler should return
  11230. menu item height in lower word of a result and item width (for menu) in
  11231. high word of result. If either for height or for width returned value is 0,
  11232. a default one is used. }
  11233. property OnDrawItem: TOnDrawItem read FOnDrawItem write SetOnDrawItem;
  11234. {* This event is called for owner-drawn menu items. }
  11235. property OwnerDraw: Boolean read FOwnerDraw write SetOwnerDraw;
  11236. {* Set this property to true for some items to make it owner-draw. }
  11237. // For compatibility with old code (be sure that item with given index
  11238. // actually exists):
  11239. function GetMenuItemHandle( Idx : Integer ): DWORD;
  11240. {* Returns Id of menu item with given index. }
  11241. property ItemHandle[ Idx: Integer ]: DWORD read GetMenuItemHandle;
  11242. {* Returns handle for item given by index. }
  11243. property ItemChecked[ Idx : Integer ] : Boolean read GetItemChecked write SetItemChecked;
  11244. {* True, if correspondent menu item is checked. }
  11245. procedure RadioCheck( Idx : Integer );
  11246. {* Call this method to check radio item. For radio items, do not
  11247. use assignment to ItemChecked or Checked properties. }
  11248. property ItemBitmap[ Idx: Integer ]: HBitmap read GetItemBitmap write SetItemBitmap;
  11249. {* This property allows to assign bitmap to menu item (for unchecked state
  11250. only - for checked menu items default checkmark bitmap is used). }
  11251. procedure AssignBitmaps( StartIdx: Integer; Bitmaps: array of HBitmap );
  11252. {* Can be used to assign bitmaps to several menu items during one call. }
  11253. property ItemText[ Idx: Integer ]: KOLString read GetItemText write SetItemText;
  11254. {* This property allows to get / modify menu item text at run time. }
  11255. property ItemEnabled[ Idx: Integer ]: Boolean read GetItemEnabled write SetItemEnabled;
  11256. {* Controls enabling / disabling menu items. Disabled menu items are
  11257. displayed (grayed) but inaccessible to click. }
  11258. property ItemVisible[ Idx: Integer ]: Boolean read GetItemVisible write SetItemVisible;
  11259. {* This property allows to simulate visibility of menu items (implementing
  11260. it by removing or inserting again if needed. For items of submenu, which
  11261. is made invisible, True is returned. If such item made Visible, entire
  11262. submenu with all its parent menu items becomes visible. To release menu
  11263. properly it is necessary to make before all its items visible again.
  11264. This does not matter, if menu is released at the end of execution, but
  11265. can be sensible if owner form is destroyed and re-created at run time
  11266. dynamically. }
  11267. property ItemHelpContext[ Idx: Integer ]: Integer read GetItemHelpContext
  11268. write SetItemHelpContext;
  11269. function ParentItem( Idx: Integer ): Integer;
  11270. {* Returns index of parent menu item (for submenu item). If there are no
  11271. such item (Idx corresponds to root level menu item), -1 is returned. }
  11272. property ItemAccelerator[ Idx: Integer ]: TMenuAccelerator read GetItemAccelerator write SetItemAccelerator;
  11273. {* Allows to get / change accelerator key kodes assigned to menu items.
  11274. Has no effect unless SupportMnemonics called for a form. }
  11275. property ItemSubmenu[ Idx: Integer ]: HMenu read GetItemSubmenu; // write SetItemSubmenu;
  11276. {* Retrieves submenu item dynamically. See also SubMenu property. }
  11277. // by Sergey Shisminzev:
  11278. function AddItem(ACaption: PKOLChar; Event: TOnMenuItem; Options: TMenuOptions): Integer;
  11279. {* Adds menu item dynamically. Returns ID of the added item. }
  11280. function InsertItem(InsertBefore: Integer; ACaption: PKOLChar; Event: TOnMenuItem; Options: TMenuOptions): Integer;
  11281. {* Inserts menu item before an item with ID, given by InsertBefore parameter. }
  11282. function InsertItemEx(InsertBefore: Integer; ACaption: PKOLChar; Event: TOnMenuItem; Options: TMenuOptions;
  11283. ByPosition: Boolean): Integer;
  11284. {* Inserts menu item by command or by position, dependant on ByPosition parameter }
  11285. procedure RedrawFormMenuBar;
  11286. {* }
  11287. {$IFDEF USE_MENU_CURCTL}
  11288. property CurCtl: PControl read fCurCtl write fCurCtl;
  11289. {* By Alexander Pravdin. This property is assigned to a control which were
  11290. initiated a pop-up, for popup menu. }
  11291. {$ENDIF USE_MENU_CURCTL}
  11292. {$ENDIF GDI}
  11293. end;
  11294. //[END OF TMenu DEFINITION]
  11295. {$IFDEF WIN_GDI}
  11296. //[MenuStructSize VARIABLE]
  11297. function MenuStructSize: Integer;
  11298. {* Returns 44 under Windows95, and 48 (=sizeof(TMenuItemInfo) under all other
  11299. Windows versions. }
  11300. var FDynamicMenuID: DWORD = $1000;
  11301. {$ENDIF WIN_GDI}
  11302. //[NewMenu DECLARATION]
  11303. function NewMenu( AParent : PControl; MaxCmdReserve: DWORD;
  11304. const Template : array of PKOLChar; aOnMenuItem: TOnMenuItem ): PMenu;
  11305. {* Menu constructor. First created menu becomes main menu of form (if AParent
  11306. is a form). All other menus becomes popup (can be activated using Popup
  11307. method). To provide dynamic replacing of main menu, create all popup
  11308. menus as children of any other control, not form itself.
  11309. When Menu is created, pass FirstCmd integer value to set it
  11310. as ID of first menu item (all other ID's obtained by incrementing this value),
  11311. and Template, which is an array of PChar (usually array of string constants),
  11312. containing list of menu item identifiers and/or formatting characters.
  11313. |<br>&nbsp;&nbsp;&nbsp;
  11314. FirstCmd value is assigned to first menu item created as its ID,
  11315. all follow menu items are assigned to ID's obtained from FirstCmd incrementing
  11316. it by 1. It is desirable to provide not intersected ranges of ID's for
  11317. defferent menus in the applet.
  11318. |<br>&nbsp;&nbsp;&nbsp;
  11319. Following formatting characters can be used in menu template strings:
  11320. |&L=<br><b>%1</b>
  11321. <L &amp; (in identifier)> - to underline next character and use it as a shortcut character
  11322. when possible;
  11323. <L + (in front of identifier)> - to make item checked. If also
  11324. |<b>!</b> is used before <b>
  11325. &
  11326. |</b> than radioitem is defined;
  11327. <L - (in front of identifier)> - item not checked;
  11328. <L - (separate)> - separator (between two items);
  11329. <L ( (separate)> - start of submenu;
  11330. <L ) (separate)> - end of submenu;
  11331. |<br>&nbsp;&nbsp;&nbsp;
  11332. To get access to menu items, use constants 0, 1, etc. It is a good idea
  11333. to create special enumerated type to index correspondent menu items
  11334. using Ord( ) operator. Note in that case, that it is necessary only to
  11335. define constants correspondent to identifiers (positions, correspondent
  11336. to separators or submenu brackets are not identified by numbers).
  11337. |<br>&nbsp;&nbsp;&nbsp;
  11338. }
  11339. function NewMenuEx( AParent : PControl; FirstCmd : Integer;
  11340. const Template : array of PKOLChar; aOnMenuItems: array of TOnMenuItem ): PMenu;
  11341. {* Creates menu, assigning its own event handler for every (enough) menu item. }
  11342. {$IFDEF WIN_GDI}
  11343. //[MakeAccelerator DECLARATION]
  11344. function MakeAccelerator( fVirt: Byte; Key: Word ): TMenuAccelerator;
  11345. {* Creates accelerator item to assign it to TMenu.ItemAccelerator[ ] property
  11346. easy.}
  11347. //[GetAcceleratorText DECLARATION]
  11348. // {YS} added 7 Aug 2004
  11349. function GetAcceleratorText( const Accelerator: TMenuAccelerator ): KOLstring;
  11350. {* Returns text representation of accelerator.
  11351. |<hr>
  11352. <R System functions and working with windows>
  11353. }
  11354. //[Window FUNCTIONS DECLARATIONS]
  11355. type
  11356. TWindowChildKind = ( wcActive, wcFocus, wcCapture, wcMenuOwner,
  11357. wcMoveSize, wcCaret );
  11358. {* Type of window child kind. Used in function GetWindowChild. }
  11359. function GetWindowChild( Wnd: HWnd; Kind: TWindowChildKind ): HWnd;
  11360. {* Returns child of given top-level window, having given characteristics.
  11361. For example, it is possible to get know for foreground window,
  11362. which of its child window has focus. This function does not work in old
  11363. Windows 95 (returns Wnd in that case). But for Windows 98, Windows NT/2000
  11364. this function works fine. To obtain focused child of the window,
  11365. use GetFocusedWindow, which is independant from Windows version. }
  11366. {$ifdef win32}
  11367. function GetFocusedChild( Wnd: HWnd ): HWnd;
  11368. {* Returns focused child of given window (which should be foreground
  11369. and active, certainly). 0 is returned either if Wnd is not active
  11370. or Wnd has no focused child window. }
  11371. function Stroke2Window( Wnd: HWnd; const S: String ): Boolean;
  11372. {* Posts characters from string S to those child window of Wnd, which
  11373. has focus now (top-level window Wnd must be foreground, and have
  11374. focused edit-aware control to receive the stroke).
  11375. |<br>
  11376. This function allows only to post typeable characters (including
  11377. such special symbols as #13 (Enter), #9 (Tab), #8 (BackSpace), etc.
  11378. |<br>
  11379. See also function Stroke2WindowEx, which allows to post any key down
  11380. and up events, simulating keyboard for given (automated) application. }
  11381. function Stroke2WindowEx( Wnd: HWnd; const S: String; Wait: Boolean ): Boolean;
  11382. {* In addition to function Stroke2Window, this one can send special keys
  11383. to given window, including functional keys and navigation keys. To
  11384. post special key to target window, place a combination of names of
  11385. such key together with keys, which should be passed simultaneously,
  11386. between square or figure brackets. For example, [Ctrl F1], [Alt Shift Home],
  11387. [Ctrl E]. For letters and usual characters, it is not necessary to
  11388. simulate pressing it with determining all Shift combinations and it is
  11389. sufficient to pass characters as is. (E.g., not '[Shift 1]', but '!'). }
  11390. {$endif win32}
  11391. function FindWindowByThreadID( ThreadID : DWORD ) : HWnd;
  11392. {* Searches for window, belonging to a given thread. }
  11393. function DesktopPixelFormat: TPixelFormat;
  11394. {* Returns the pixel format correspondent to current desktop color resolution.
  11395. Use this function to decide which format to use for converting bitmap,
  11396. planned to draw transparently using TBitmap.DrawTransparent or
  11397. TBitmap.StretchDrawTransparent methods. }
  11398. function GetDesktopRect : TRect;
  11399. {* Returns rectangle of screen, free of taskbar and other
  11400. similar app-bars, which reduces size of available desktop
  11401. when created. }
  11402. function GetWorkArea: TRect;
  11403. {* The same as GetDesktopRect, but obtained calling SystemParametersInfo. }
  11404. function ExecuteWait( const AppPath, CmdLine, DfltDirectory: KOLString;
  11405. Show: DWORD; TimeOut: DWORD; ProcID: PDWORD ): Boolean;
  11406. {* Allows to execute an application and wait when it is finished. Pass
  11407. INFINITE constant as TimeOut, if You sure that application is finished
  11408. anyway. If another value passed as a TimeOut (in milliseconds), and
  11409. application was not finished for that time, ExecuteWait is returning
  11410. FALSE, and if ProcID is not nil, than ProcID^ contains started process
  11411. handle (it can be used to wait it more, or to terminate it using
  11412. TerminateProcess API function).
  11413. |<br>
  11414. Launching application can be console or GUI - it does not matter.
  11415. Pass SW_SHOW, SW_HIDE or other SW_XXX constant as Show parameter
  11416. as appropriate.
  11417. |<br>
  11418. True is returned only in case when application specified was launched
  11419. successfully and finished for TimeOut specified. Otherwise, check
  11420. ProcID^ variable: if it is 0, process could not be launched (and it
  11421. is possible to get information about error using GetLastError API
  11422. function in a such case). You can freely pass nil in place of ProcID
  11423. parameter, but this is acually correct only when TimeOut is INFINITE. }
  11424. {$ifdef win32}
  11425. function ExecuteIORedirect( const AppPath, CmdLine, DfltDirectory: KOLString;
  11426. Show: DWORD; ProcID: PDWORD; InPipe, OutPipeWr, OutPipeRd: PHandle ): Boolean;
  11427. {* Executes an application with its console input and output redirection.
  11428. Terminating of the application is not waiting, but if ProcID pointer
  11429. is defined, it receives process Id launched, so it is possible to
  11430. call WaitForSingleObject for it. InPipe is a pointer to THandle variable
  11431. which receives a handle to input pipe of the console redirected. The same
  11432. is for OutPipeWr and OutPipeRd, but for output of the console redirected.
  11433. Before reading from OutPipeRd^, first close OutPipeWr^. If you run
  11434. simple console application, for which you want to read results after its
  11435. termination, you can use ExecuteConsoleAppIORedirect instead.
  11436. |<br>&nbsp;&nbsp;&nbsp;
  11437. Notes: if your application is not console and it does not create console
  11438. using AllocConsole, this function will fail to redirect input-output. }
  11439. function ExecuteConsoleAppIORedirect( const AppPath, CmdLine, DfltDirectory: String;
  11440. Show: DWORD; const InStr: String; var OutStr: String; WaitTimeout: DWORD )
  11441. : Boolean;
  11442. {* Executes an application, redirecting its console input and output.
  11443. After redirecting input and output and launching the application,
  11444. content of InStr is written to input stream of the application, then
  11445. the application is waiting for its termination (WaitTimeout milliseconds
  11446. or INFINITE, as passed) and console output of the application is read to
  11447. OutStr. TRUE is returned only in case, when all these tasks are
  11448. completed successfully.
  11449. |<br>&nbsp;&nbsp;&nbsp;
  11450. Notes: if your application is not console and it does not create console
  11451. using AllocConsole, this function will fail to redirect input-output. }
  11452. function WindowsShutdown( const Machine : KOLString; Force, Reboot : Boolean ) : Boolean;
  11453. {* Shut down of Windows NT. Pass Machine = '' to shutdown this PC.
  11454. Pass Reboot = True to reboot immediatelly after shut down. }
  11455. {$endif win32}
  11456. type
  11457. TWindowsVersion = ( wv31, wv95, wv98, wvME, wvNT, wvY2K, wvXP, wvServer2003,
  11458. wvVista, wvCE );
  11459. {* Windows versions constants. }
  11460. TWindowsVersions = Set of TWindowsVersion;
  11461. {* Set of Windows version (e.g. to define a range of versions supported by the
  11462. application). }
  11463. function WinVer : TWindowsVersion;
  11464. {* Returns Windows version. }
  11465. function IsWinVer( Ver : TWindowsVersions ) : Boolean;
  11466. {* Returns True if Windows version is in given range of values. }
  11467. //[Parameters FUNCTIONS DECLARATIONS]
  11468. function ParamStr( Idx: Integer ): KOLString;
  11469. {* Returns command-line parameter by index. This function supersides
  11470. standard ParamStr function. }
  11471. function ParamCount: Integer;
  11472. {* Returns number of parameters in command line.
  11473. |<hr>
  11474. }
  11475. {$ifdef wince}
  11476. type
  11477. TCePlatform = (cpWinCE, cpPocketPC, cpSmartphone);
  11478. {*
  11479. Windows CE platfrom constants.
  11480. <R WinCE specific functions> }
  11481. function CePlatform: TCePlatform;
  11482. {* Returns Windows CE platfrom. }
  11483. procedure CeFormSIPAware(Form: PControl; ShowSIP: boolean);
  11484. {* Call this procedure to resize form when SIP is activated
  11485. |<hr>
  11486. }
  11487. {$endif wince}
  11488. {$ENDIF WIN_GDI}
  11489. {$IFDEF INPACKAGE}
  11490. {$IFDEF ASM_VERSION}
  11491. {$UNDEF ASM_VERSION}
  11492. {$ENDIF}
  11493. {$ENDIF}
  11494. {$IFDEF WIN_GDI}
  11495. //{$DEFINE CHK_BITBLT}
  11496. procedure Chk_BitBlt;
  11497. {$IFDEF ASM_VERSION}
  11498. {$DEFINE ASM_DC}
  11499. {$ENDIF}
  11500. {$IFDEF ASM_DC}
  11501. procedure StartDC;
  11502. procedure FinishDC;
  11503. {$ENDIF ASM_VERSION}
  11504. //[WndProcXXX OTHER DECLARATIONS]
  11505. function WndProcCtrl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  11506. function WndProcDoEraseBkgnd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  11507. var CreatingWindow: PControl;
  11508. //ActiveWindow: HWnd;
  11509. {$ENDIF WIN_GDI}
  11510. //[Assert OPERATOR DECLARATION]
  11511. {-}
  11512. {$IFDEF _D2}
  11513. // Assert operator was not available in Delphi2. Provide here easy Assert
  11514. // procedure for Delphi2.
  11515. procedure Assert( Cond: Boolean; const Msg: String );
  11516. var AssertErrorProc: procedure( const Message, Filename: AnsiString; LineNumber: Integer );
  11517. {$ENDIF}
  11518. {+}
  11519. //[CUSTOM EXTENSIONS]
  11520. {$IFDEF USE_CUSTOMEXTENSIONS}
  11521. {$I CUSTOM_KOL_EXTENSION.inc} // See comments in TControl
  11522. {$ENDIF}
  11523. {$IFDEF DEBUG_ENDSESSION}
  11524. var EndSession_Initiated: Boolean;
  11525. {$ENDIF}
  11526. {$IFDEF WIN_GDI}
  11527. //[FMMNotify VARIABLE]
  11528. var
  11529. FMMNotify: procedure( var Msg: TMsg );
  11530. //[procedure ClearText forward declaration]
  11531. procedure ClearText( Sender: PControl );
  11532. //[procedure ClearListbox forward declaration]
  11533. procedure ClearListbox( Sender: PControl );
  11534. //[procedure ClearCombobox forward declaration]
  11535. procedure ClearCombobox( Sender: PControl );
  11536. //[procedure ClearListView forward declaration]
  11537. procedure ClearListView( Sender: PControl );
  11538. //[procedure ClearTreeView forward declaration]
  11539. procedure ClearTreeView( TV: PControl );
  11540. //[START OF ACTIONS]
  11541. const
  11542. ButtonActions: TCommandActions = (
  11543. aClear: ClearText;
  11544. aAddText: nil;
  11545. aClick: BN_CLICKED;
  11546. aEnter: BN_SETFOCUS;
  11547. aLeave: BN_KILLFOCUS;
  11548. aChange: 0; //BN_CLICKED;
  11549. aSelChange: 0;
  11550. aGetCount: 0;
  11551. aSetCount: 0;
  11552. aGetItemLength: 0;
  11553. aGetItemText: 0;
  11554. aSetItemText: 0;
  11555. aGetItemData: 0;
  11556. aSetItemData: 0;
  11557. aAddItem: 0;
  11558. aDeleteItem: 0;
  11559. aInsertItem: 0;
  11560. aFindItem: 0;
  11561. aFindPartial: 0;
  11562. aItem2Pos: 0;
  11563. aPos2Item: 0;
  11564. //aGetSelStart: 0;
  11565. aGetSelCount: 0;
  11566. aGetSelected: 0;
  11567. aGetSelRange: 0;
  11568. //aExGetSelRange: 0;
  11569. aGetCurrent: 0;
  11570. aSetSelected: 0;
  11571. aSetCurrent: 0;
  11572. aSetSelRange: 0;
  11573. aExSetSelRange: 0;
  11574. aGetSelection: 0;
  11575. aReplaceSel: 0;
  11576. aTextAlignLeft: BS_LEFT;
  11577. aTextAlignRight: BS_RIGHT;
  11578. aTextAlignCenter: BS_CENTER;
  11579. aTextAlignMask: 0;
  11580. aVertAlignCenter: BS_VCENTER shr 8;
  11581. aVertAlignTop: BS_TOP shr 8;
  11582. aVertAlignBottom: BS_BOTTOM shr 8;
  11583. aDir: 0;
  11584. aSetLimit: 0;
  11585. aSetImgList: 0;
  11586. aAutoSzX: 14;
  11587. aAutoSzY: 6;
  11588. aSetBkColor: 0;
  11589. aItem2XY: 0;
  11590. );
  11591. const
  11592. LabelActions: TCommandActions = (
  11593. aClear: ClearText;
  11594. aAddText: nil;
  11595. aClick: 0;
  11596. aEnter: 0;
  11597. aLeave: 0;
  11598. aChange: 0;
  11599. aSelChange: 0;
  11600. aGetCount: 0;
  11601. aSetCount: 0;
  11602. aGetItemLength: 0;
  11603. aGetItemText: 0;
  11604. aSetItemText: 0;
  11605. aGetItemData: 0;
  11606. aSetItemData: 0;
  11607. aAddItem: 0;
  11608. aDeleteItem: 0;
  11609. aInsertItem: 0;
  11610. aFindItem: 0;
  11611. aFindPartial: 0;
  11612. aItem2Pos: 0;
  11613. aPos2Item: 0;
  11614. //aGetSelStart: 0;
  11615. aGetSelCount: 0;
  11616. aGetSelected: 0;
  11617. aGetSelRange: 0;
  11618. //aExGetSelRange: 0;
  11619. aGetCurrent: 0;
  11620. aSetSelected: 0;
  11621. aSetCurrent: 0;
  11622. aSetSelRange: 0;
  11623. aExSetSelRange: 0;
  11624. aGetSelection: 0;
  11625. aReplaceSel: 0;
  11626. aTextAlignLeft: SS_LEFT;
  11627. aTextAlignRight: SS_RIGHT;
  11628. aTextAlignCenter: SS_CENTER;
  11629. aTextAlignMask: SS_LEFTNOWORDWRAP;
  11630. aVertAlignCenter: SS_CENTERIMAGE shr 8;
  11631. aVertAlignTop: 0;
  11632. aVertAlignBottom: 0;
  11633. aDir: 0;
  11634. aSetLimit: 0;
  11635. aSetImgList: 0;
  11636. aAutoSzX: 1;
  11637. aAutoSzY: 1;
  11638. aSetBkColor: 0;
  11639. aItem2XY: 0;
  11640. );
  11641. const
  11642. EN_LINK = $070b;
  11643. EditActions: TCommandActions = (
  11644. aClear: ClearText;
  11645. aAddText: nil;
  11646. aClick: 0;
  11647. aEnter: EN_SETFOCUS;
  11648. aLeave: EN_KILLFOCUS;
  11649. aChange: EN_CHANGE;
  11650. aSelChange: 0;
  11651. aGetCount: EM_GETLINECOUNT;
  11652. aSetCount: 0;
  11653. aGetItemLength: EM_LINELENGTH;
  11654. aGetItemText: EM_GETLINE;
  11655. aSetItemText: EM_REPLACESEL;
  11656. aGetItemData: 0;
  11657. aSetItemData: 0;
  11658. aAddItem: 0;
  11659. aDeleteItem: 0;
  11660. aInsertItem: 0;
  11661. aFindItem: 0;
  11662. aFindPartial: 0;
  11663. aItem2Pos: EM_LINEINDEX;
  11664. aPos2Item: EM_LINEFROMCHAR;
  11665. //aGetSelStart: 0;
  11666. aGetSelCount: EM_GETSEL;
  11667. aGetSelected: 0;
  11668. aGetSelRange: EM_GETSEL;
  11669. //aExGetSelRange: 0;
  11670. aGetCurrent: EM_LINEINDEX;
  11671. aSetSelected: 0;
  11672. aSetCurrent: 0;
  11673. aSetSelRange: EM_SETSEL;
  11674. aExSetSelRange: 0;
  11675. aGetSelection: 0;
  11676. aReplaceSel: EM_REPLACESEL;
  11677. aTextAlignLeft: ES_LEFT;
  11678. aTextAlignRight: ES_RIGHT;
  11679. aTextAlignCenter: ES_CENTER;
  11680. aTextAlignMask: 0;
  11681. aVertAlignCenter: 0;
  11682. aVertAlignTop: 0;
  11683. aVertAlignBottom: 0;
  11684. aDir: 0;
  11685. aSetLimit: EM_SETLIMITTEXT;
  11686. aSetImgList: 0;
  11687. aAutoSzX: 0;
  11688. aAutoSzY: 6;
  11689. aSetBkColor: 0;
  11690. aItem2XY: EM_POSFROMCHAR;
  11691. );
  11692. const
  11693. ListActions: TCommandActions = (
  11694. aClear: ClearListbox;
  11695. aAddText: nil;
  11696. aClick: LBN_DBLCLK;
  11697. aEnter: LBN_SETFOCUS;
  11698. aLeave: LBN_KILLFOCUS;
  11699. aChange: 0;
  11700. aSelChange: LBN_SELCHANGE;
  11701. aGetCount: LB_GETCOUNT;
  11702. aSetCount: LB_SETCOUNT;
  11703. aGetItemLength: LB_GETTEXTLEN;
  11704. aGetItemText: LB_GETTEXT;
  11705. aSetItemText: 0;
  11706. aGetItemData: LB_GETITEMDATA;
  11707. aSetItemData: LB_SETITEMDATA;
  11708. aAddItem: LB_ADDSTRING;
  11709. aDeleteItem: LB_DELETESTRING;
  11710. aInsertItem: LB_INSERTSTRING;
  11711. aFindItem: LB_FINDSTRINGEXACT;
  11712. aFindPartial: LB_FINDSTRING;
  11713. aItem2Pos: 0;
  11714. aPos2Item: 0;
  11715. //aGetSelStart: 0;
  11716. aGetSelCount: LB_GETSELCOUNT;
  11717. aGetSelected: LB_GETSEL;
  11718. aGetSelRange: 0;
  11719. //aExGetSelRange: 0;
  11720. aGetCurrent: LB_GETCURSEL;
  11721. aSetSelected: LB_SETSEL;
  11722. aSetCurrent: LB_SETCURSEL;
  11723. aSetSelRange: 0;
  11724. aExSetSelRange: 0;
  11725. aGetSelection: 0;
  11726. aReplaceSel: 0;
  11727. aTextAlignLeft: 0;
  11728. aTextAlignRight: 0;
  11729. aTextAlignCenter: 0;
  11730. aTextAlignMask: 0;
  11731. aVertAlignCenter: 0;
  11732. aVertAlignTop: 0;
  11733. aVertAlignBottom: 0;
  11734. aDir: LB_DIR;
  11735. aSetLimit: 0;
  11736. aSetImgList: 0;
  11737. aAutoSzX: 0;
  11738. aAutoSzY: 0;
  11739. aSetBkColor: 0;
  11740. aItem2XY: LB_GETITEMRECT;
  11741. );
  11742. const
  11743. ComboActions: TCommandActions = (
  11744. aClear: ClearCombobox;
  11745. aAddText: nil;
  11746. aClick: CBN_DBLCLK;
  11747. aEnter: CBN_SETFOCUS;
  11748. aLeave: CBN_KILLFOCUS;
  11749. aChange: CBN_EDITCHANGE;
  11750. aSelChange: CM_CBN_SELCHANGE; // CBN_SELCHANGE;
  11751. aGetCount: CB_GETCOUNT;
  11752. aSetCount: 0;
  11753. aGetItemLength: CB_GETLBTEXTLEN;
  11754. aGetItemText: CB_GETLBTEXT;
  11755. aSetItemText: 0;
  11756. aGetItemData: CB_GETITEMDATA;
  11757. aSetItemData: CB_SETITEMDATA;
  11758. aAddItem: CB_ADDSTRING;
  11759. aDeleteItem: CB_DELETESTRING;
  11760. aInsertItem: CB_INSERTSTRING;
  11761. aFindItem: CB_FINDSTRINGEXACT;
  11762. aFindPartial: CB_FINDSTRING;
  11763. aItem2Pos: 0;
  11764. aPos2Item: 0;
  11765. //aGetSelStart: 0;
  11766. aGetSelCount: 0;
  11767. aGetSelected: CB_GETCURSEL;
  11768. aGetSelRange: 0;
  11769. //aExGetSelRange: 0;
  11770. aGetCurrent: CB_GETCURSEL;
  11771. aSetSelected: 0;
  11772. aSetCurrent: CB_SETCURSEL;
  11773. aSetSelRange: 0;
  11774. aExSetSelRange: 0;
  11775. aGetSelection: 0;
  11776. aReplaceSel: 0;
  11777. aTextAlignLeft: 0; //ES_LEFT;
  11778. aTextAlignRight: 0; //ES_RIGHT;
  11779. aTextAlignCenter: 0; //ES_CENTER;
  11780. aTextAlignMask: 0;
  11781. aVertAlignCenter: 0;
  11782. aVertAlignTop: 0;
  11783. aVertAlignBottom: 0;
  11784. aDir: CB_DIR;
  11785. aSetLimit: 0;
  11786. aSetImgList: 0;
  11787. aAutoSzX: 0;
  11788. aAutoSzY: 6;
  11789. aSetBkColor: 0;
  11790. aItem2XY: 0;
  11791. );
  11792. const
  11793. ListViewActions: TCommandActions = (
  11794. aClear: ClearListView;
  11795. aAddText: nil;
  11796. aClick: 0;
  11797. aEnter: 0;
  11798. aLeave: 0;
  11799. aChange: LVN_ITEMCHANGED;
  11800. aSelChange: 0;
  11801. aGetCount: LVM_GETITEMCOUNT;
  11802. aSetCount: LVM_SETITEMCOUNT;
  11803. aGetItemLength: 0;
  11804. aGetItemText: 0;
  11805. aSetItemText: 0;
  11806. aGetItemData: 0;
  11807. aSetItemData: 0;
  11808. aAddItem: 0;
  11809. aDeleteItem: 0;
  11810. aInsertItem: 0;
  11811. aFindItem: 0;
  11812. aFindPartial: 0;
  11813. aItem2Pos: 0;
  11814. aPos2Item: 0;
  11815. //aGetSelStart: LVM_GETSELECTIONMARK;
  11816. aGetSelCount: { $8000 or} LVM_GETSELECTEDCOUNT;
  11817. aGetSelected: LVM_GETITEMSTATE;
  11818. aGetSelRange: 0;
  11819. //aExGetSelRange: 0;
  11820. aGetCurrent: LVM_GETNEXTITEM;
  11821. aSetSelected: 0;
  11822. aSetCurrent: 0;
  11823. aSetSelRange: 0;
  11824. aExSetSelRange: 0;
  11825. aGetSelection: 0;
  11826. aReplaceSel: 0;
  11827. aTextAlignLeft: 0;
  11828. aTextAlignRight: 0;
  11829. aTextAlignCenter: 0;
  11830. aTextAlignMask: 0;
  11831. aVertAlignCenter: 0;
  11832. aVertAlignTop: 0;
  11833. aVertAlignBottom: 0;
  11834. aDir: 0;
  11835. aSetLimit: 0;
  11836. aSetImgList: LVM_SETIMAGELIST;
  11837. aAutoSzX: 0;
  11838. aAutoSzY: 0;
  11839. aSetBkColor: LVM_SETBKCOLOR;
  11840. aItem2XY: LVM_GETITEMRECT;
  11841. );
  11842. const
  11843. TreeViewActions: TCommandActions = (
  11844. aClear: ClearTreeView;
  11845. aAddText: nil;
  11846. aClick: 0;
  11847. aEnter: 0;
  11848. aLeave: 0;
  11849. aChange: TVN_ENDLABELEDIT;
  11850. aSelChange: TVN_SELCHANGED;
  11851. aGetCount: TVM_GETCOUNT;
  11852. aSetCount: 0;
  11853. aGetItemLength: 0;
  11854. aGetItemText: 0;
  11855. aSetItemText: 0;
  11856. aGetItemData: 0;
  11857. aSetItemData: 0;
  11858. aAddItem: 0;
  11859. aDeleteItem: 0;
  11860. aInsertItem: 0;
  11861. aFindItem: 0;
  11862. aFindPartial: 0;
  11863. aItem2Pos: 0;
  11864. aPos2Item: 0;
  11865. //aGetSelStart: 0;
  11866. aGetSelCount: 0;
  11867. aGetSelected: 0;
  11868. aGetSelRange: 0;
  11869. //aExGetSelRange: 0;
  11870. aGetCurrent: 0;
  11871. aSetSelected: 0;
  11872. aSetCurrent: 0;
  11873. aSetSelRange: 0;
  11874. aExSetSelRange: 0;
  11875. aGetSelection: 0;
  11876. aReplaceSel: 0;
  11877. aTextAlignLeft: 0;
  11878. aTextAlignRight: 0;
  11879. aTextAlignCenter: 0;
  11880. aTextAlignMask: 0;
  11881. aVertAlignCenter: 0;
  11882. aVertAlignTop: 0;
  11883. aVertAlignBottom: 0;
  11884. aDir: CB_DIR;
  11885. aSetLimit: 0;
  11886. aSetImgList: TVM_SETIMAGELIST;
  11887. aAutoSzX: 0;
  11888. aAutoSzY: 0;
  11889. aSetBkColor: {$ifdef wince}0{$else}TVM_SETBKCOLOR{$endif};
  11890. aItem2XY: TVM_GETITEMRECT;
  11891. );
  11892. const
  11893. TabControlActions: TCommandActions = (
  11894. aClear: ClearText;
  11895. aAddText: nil;
  11896. aClick: 0;
  11897. aEnter: 0;
  11898. aLeave: 0;
  11899. aChange: TCN_SELCHANGE;
  11900. aSelChange: TCN_SELCHANGE;
  11901. aGetCount: TCM_GETITEMCOUNT;
  11902. aSetCount: 0;
  11903. aGetItemLength: 0;
  11904. aGetItemText: 0;
  11905. aSetItemText: 0;
  11906. aGetItemData: 0;
  11907. aSetItemData: 0;
  11908. aAddItem: 0;
  11909. aDeleteItem: 0;
  11910. aInsertItem: 0;
  11911. aFindItem: 0;
  11912. aFindPartial: 0;
  11913. aItem2Pos: 0;
  11914. aPos2Item: 0;
  11915. //aGetSelStart: 0;
  11916. aGetSelCount: 0;
  11917. aGetSelected: 0;
  11918. aGetSelRange: 0;
  11919. //aExGetSelRange: 0;
  11920. aGetCurrent: TCM_GETCURSEL;
  11921. aSetSelected: 0;
  11922. aSetCurrent: TCM_SETCURSEL; //TCM_SETCURFOCUS;
  11923. aSetSelRange: 0;
  11924. aExSetSelRange: 0;
  11925. aGetSelection: 0;
  11926. aReplaceSel: 0;
  11927. aTextAlignLeft: 0;
  11928. aTextAlignRight: 0;
  11929. aTextAlignCenter: 0;
  11930. aTextAlignMask: 0;
  11931. aVertAlignCenter: 0;
  11932. aVertAlignTop: 0;
  11933. aVertAlignBottom: 0;
  11934. aDir: CB_DIR;
  11935. aSetLimit: 0;
  11936. aSetImgList: TCM_SETIMAGELIST;
  11937. aAutoSzX: 0;
  11938. aAutoSzY: 0;
  11939. aSetBkColor: 0;
  11940. aItem2XY: TCM_GETITEMRECT;
  11941. );
  11942. {$IFNDEF NOT_USE_RICHEDIT}
  11943. const
  11944. RichEditActions: TCommandActions = (
  11945. aClear: ClearText;
  11946. aAddText: nil;
  11947. aClick: 0;
  11948. aEnter: EN_SETFOCUS;
  11949. aLeave: EN_KILLFOCUS;
  11950. aChange: EN_CHANGE;
  11951. aSelChange: EN_SELCHANGE;
  11952. aGetCount: EM_GETLINECOUNT;
  11953. aSetCount: 0;
  11954. aGetItemLength: EM_LINELENGTH;
  11955. aGetItemText: EM_GETLINE;
  11956. aSetItemText: EM_REPLACESEL;
  11957. aGetItemData: 0;
  11958. aSetItemData: 0;
  11959. aAddItem: 0;
  11960. aDeleteItem: 0;
  11961. aInsertItem: 0;
  11962. aFindItem: 0;
  11963. aFindPartial: 0;
  11964. aItem2Pos: EM_LINEINDEX;
  11965. aPos2Item: EM_LINEFROMCHAR;
  11966. //aGetSelStart: 0;
  11967. aGetSelCount: EM_GETSEL;
  11968. aGetSelected: 0;
  11969. aGetSelRange: EM_GETSEL;
  11970. //aExGetSelRange: EM_EXGETSEL;
  11971. aGetCurrent: EM_LINEINDEX;
  11972. aSetSelected: 0;
  11973. aSetCurrent: 0;
  11974. aSetSelRange: 0;
  11975. aExSetSelRange: EM_EXSETSEL;
  11976. aGetSelection: EM_GETSELTEXT;
  11977. aReplaceSel: EM_REPLACESEL;
  11978. aTextAlignLeft: ES_LEFT;
  11979. aTextAlignRight: ES_RIGHT;
  11980. aTextAlignCenter: ES_CENTER;
  11981. aTextAlignMask: 0;
  11982. aVertAlignCenter: 0;
  11983. aVertAlignTop: 0;
  11984. aVertAlignBottom: 0;
  11985. aDir: 0;
  11986. aSetLimit: EM_EXLIMITTEXT;
  11987. aSetImgList: 0;
  11988. aAutoSzX: 0;
  11989. aAutoSzY: 0;
  11990. aSetBkColor: EM_SETBKGNDCOLOR;
  11991. aItem2XY: EM_POSFROMCHAR;
  11992. );
  11993. {$ENDIF NOT_USE_RICHEDIT}
  11994. const
  11995. BaseFileMethods: TStreamMethods = (
  11996. fSeek: SeekFileStream;
  11997. fGetSiz: GetSizeFileStream;
  11998. fSetSiz: DummySetSize;
  11999. fRead: DummyReadWrite;
  12000. fWrite: DummyReadWrite;
  12001. fClose: CloseFileStream;
  12002. fCustom: nil;
  12003. fWait: nil;
  12004. );
  12005. MemoryMethods: TStreamMethods = (
  12006. fSeek: SeekMemStream;
  12007. fGetSiz: GetSizeMemStream;
  12008. fSetSiz: SetSizeMemStream;
  12009. fRead: ReadMemStream;
  12010. fWrite: WriteMemStream;
  12011. fClose: CloseMemStream;
  12012. fCustom: nil;
  12013. fWait: nil;
  12014. );
  12015. {$ENDIF WIN_GDI}
  12016. {$IFDEF DEBUG_MCK}
  12017. procedure dummy_Log( const s: String );
  12018. var mck_Log: procedure( const s: String ) = dummy_Log;
  12019. {$ENDIF}
  12020. type
  12021. TThemedElement = (
  12022. teButton,
  12023. teClock,
  12024. teComboBox,
  12025. teEdit,
  12026. teExplorerBar,
  12027. teHeader,
  12028. teListView,
  12029. teMenu,
  12030. tePage,
  12031. teProgress,
  12032. teRebar,
  12033. teScrollBar,
  12034. teSpin,
  12035. teStartPanel,
  12036. teStatus,
  12037. teTab,
  12038. teTaskBand,
  12039. teTaskBar,
  12040. teToolBar,
  12041. teToolTip,
  12042. teTrackBar,
  12043. teTrayNotify,
  12044. teTreeview,
  12045. teWindow
  12046. );
  12047. var DrawThemeBackground: function(hTheme: DWORD; hdc: HDC; iPartId, iStateId: Integer;
  12048. const pRect: TRect; pClipRect: PRECT): HRESULT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12049. OpenThemeData: function(hwnd: HWND; pszClassList: LPCWSTR): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12050. ThemeLibrary: THandle;
  12051. IsThemeBackgroundPartiallyTransparent: function(hTheme: DWORD;
  12052. iPartId, iStateId: Integer): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12053. DrawThemeParentBackground: function(hwnd: HWND; hdc: HDC; prc: PRECT): HRESULT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12054. CloseThemeData: function(hTheme: DWORD): HRESULT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12055. DrawThemeText: function(hTheme: DWORD; hdc: HDC; iPartId, iStateId: Integer;
  12056. pszText: LPCWSTR; iCharCount: Integer; dwTextFlags, dwTextFlags2: DWORD;
  12057. const pRect: TRect): HRESULT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12058. IsThemeActive: function: BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12059. IsAppThemed: function: BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12060. GetThemeColor: function(hTheme: DWORD; iPartId, iStateId, iPropId: Integer;
  12061. var pColor: COLORREF): HRESULT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12062. const
  12063. themelib = 'uxtheme';
  12064. type
  12065. PThemedElementDetails = ^TThemedElementDetails;
  12066. TThemedElementDetails = record
  12067. Element: TThemedElement;
  12068. Part,
  12069. State: Integer;
  12070. end;
  12071. TThemedEdit = (
  12072. teEditDontCare,
  12073. teEditRoot,
  12074. teEditTextNormal, teEditTextHot, teEditTextSelected, teEditTextDisabled, teEditTextFocused, teEditTextReadOnly, teEditTextAssist,
  12075. teEditCaret
  12076. );
  12077. //[IMPLEMENTATION]
  12078. implementation
  12079. //[USES-2]
  12080. {uses
  12081. //ShellAPI,
  12082. //commdlg // removing reference to commdlg decreases executable about 0.5 K
  12083. ; //, commctrl;
  12084. // in Delphi3, including of commctrl.pas increases executable
  12085. // onto about 30K. So, all needed definitions are copied here
  12086. // (see commctrl.inc).}
  12087. //[END OF USES-2]
  12088. {$IFDEF _X_}
  12089. {$undef uses_2}
  12090. {$IFNDEF NOT_USE_KOLMATH}
  12091. {$define uses_2}
  12092. {$ENDIF NOT_USE_KOLMATH}
  12093. {$IFDEF uses_2}
  12094. uses {$IFNDEF NOT_USE_KOLMATH} KOLmath
  12095. {$IFNDEF NOT_USE_EXCEPTION} , err
  12096. {$IFDEF REDECLARATION_INSERTED_AUTOMATICALLY}
  12097. , gdk2, pango, gtk2
  12098. {$ENDIF REDECLARATION_INSERTED_AUTOMATICALLY}
  12099. {$ENDIF NOT_USE_EXCEPTION}
  12100. {$ENDIF NOT_USE_KOLMATH};
  12101. {$ENDIF uses_2}
  12102. {$ELSE}
  12103. {$IFDEF USE_GRUSH}
  12104. uses ToGRush;
  12105. {$ELSE}
  12106. {$IFDEF INPACKAGE}
  12107. uses mirror, SysUtils;
  12108. {$ENDIF INPACKAGE}
  12109. {$ENDIF USE_GRUSH}
  12110. {$ENDIF _X_}
  12111. {$IFDEF WIN32}
  12112. {$IFDEF UNICODE_CTRLS}
  12113. {$DEFINE implementation_part} {$I KOL_unicode.inc} {$UNDEF implementation_part}
  12114. {$ENDIF UNICODE_CTRLS}
  12115. {$ENDIF WIN32}
  12116. {$IFDEF DEBUG_MCK}
  12117. procedure dummy_Log( const s: String );
  12118. begin
  12119. //
  12120. end;
  12121. {$ENDIF}
  12122. {$IFDEF WIN}
  12123. {$ifdef win32}
  12124. type
  12125. PSHFileInfoA = ^TSHFileInfoA;
  12126. PSHFileInfoW = ^TSHFileInfoW;
  12127. PSHFileInfo = PSHFileInfoA;
  12128. _SHFILEINFOA = record
  12129. hIcon: HICON; { out: icon }
  12130. iIcon: Integer; { out: icon index }
  12131. dwAttributes: DWORD; { out: SFGAO_ flags }
  12132. szDisplayName: array [0..MAX_PATH-1] of AnsiChar; { out: display name (or path) }
  12133. szTypeName: array [0..79] of AnsiChar; { out: type name }
  12134. end;
  12135. _SHFILEINFOW = record
  12136. hIcon: HICON; { out: icon }
  12137. iIcon: Integer; { out: icon index }
  12138. dwAttributes: DWORD; { out: SFGAO_ flags }
  12139. szDisplayName: array [0..MAX_PATH-1] of WideChar; { out: display name (or path) }
  12140. szTypeName: array [0..79] of WideChar; { out: type name }
  12141. end;
  12142. _SHFILEINFO = {$IFDEF UNICODE_CTRLS} _SHFILEINFOW {$ELSE} _SHFILEINFOA {$ENDIF};
  12143. TSHFileInfoA = _SHFILEINFOA;
  12144. TSHFileInfoW = _SHFILEINFOW;
  12145. TSHFileInfo = {$IFDEF UNICODE_CTRLS} TSHFileInfoW {$ELSE} TSHFileInfoA {$ENDIF};
  12146. SHFILEINFOA = _SHFILEINFOA;
  12147. SHFILEINFOW = _SHFILEINFOW;
  12148. SHFILEINFO = {$IFDEF UNICODE_CTRLS} SHFILEINFOW {$ELSE} SHFILEINFOA {$ENDIF};
  12149. const
  12150. SHGFI_ICON = $000000100; { get icon }
  12151. SHGFI_DISPLAYNAME = $000000200; { get display name }
  12152. SHGFI_TYPENAME = $000000400; { get type name }
  12153. SHGFI_ATTRIBUTES = $000000800; { get attributes }
  12154. SHGFI_ICONLOCATION = $000001000; { get icon location }
  12155. SHGFI_EXETYPE = $000002000; { return exe type }
  12156. SHGFI_SYSICONINDEX = $000004000; { get system icon index }
  12157. SHGFI_LINKOVERLAY = $000008000; { put a link overlay on icon }
  12158. SHGFI_SELECTED = $000010000; { show icon in selected state }
  12159. SHGFI_LARGEICON = $000000000; { get large icon }
  12160. SHGFI_SMALLICON = $000000001; { get small icon }
  12161. SHGFI_OPENICON = $000000002; { get open icon }
  12162. SHGFI_SHELLICONSIZE = $000000004; { get shell size icon }
  12163. SHGFI_PIDL = $000000008; { pszPath is a pidl }
  12164. SHGFI_USEFILEATTRIBUTES = $000000010; { use passed dwFileAttribute }
  12165. function SHGetFileInfoA(pszPath: PAnsiChar; dwFileAttributes: DWORD;
  12166. var psfi: TSHFileInfo; cbFileInfo, uFlags: UINT): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12167. external 'shell32.dll' name 'SHGetFileInfoA';
  12168. {$IFDEF UNICODE_CTRLS}
  12169. function SHGetFileInfoW(pszPath: PWideChar; dwFileAttributes: DWORD;
  12170. var psfi: TSHFileInfo; cbFileInfo, uFlags: UINT): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12171. external 'shell32.dll' name 'SHGetFileInfoW';
  12172. {$ENDIF UNICODE_CTRLS}
  12173. type
  12174. FILEOP_FLAGS = Word;
  12175. PRINTEROP_FLAGS = Word;
  12176. PSHFileOpStructA = ^TSHFileOpStructA;
  12177. PSHFileOpStructW = ^TSHFileOpStructW;
  12178. PSHFileOpStruct = PSHFileOpStructA;
  12179. _SHFILEOPSTRUCTA = {$ifndef wince}packed{$endif} record
  12180. Wnd: HWND;
  12181. wFunc: UINT;
  12182. pFrom: PAnsiChar;
  12183. pTo: PAnsiChar;
  12184. fFlags: FILEOP_FLAGS;
  12185. fAnyOperationsAborted: BOOL;
  12186. hNameMappings: Pointer;
  12187. lpszProgressTitle: PAnsiChar; { only used if FOF_SIMPLEPROGRESS }
  12188. end;
  12189. _SHFILEOPSTRUCTW = {$ifndef wince}packed{$endif} record
  12190. Wnd: HWND;
  12191. wFunc: UINT;
  12192. pFrom: PWideChar;
  12193. pTo: PWideChar;
  12194. fFlags: FILEOP_FLAGS;
  12195. fAnyOperationsAborted: BOOL;
  12196. hNameMappings: Pointer;
  12197. lpszProgressTitle: PWideChar; { only used if FOF_SIMPLEPROGRESS }
  12198. end;
  12199. _SHFILEOPSTRUCT = _SHFILEOPSTRUCTA;
  12200. TSHFileOpStructA = _SHFILEOPSTRUCTA;
  12201. TSHFileOpStructW = _SHFILEOPSTRUCTW;
  12202. TSHFileOpStruct = TSHFileOpStructA;
  12203. SHFILEOPSTRUCTA = _SHFILEOPSTRUCTA;
  12204. SHFILEOPSTRUCTW = _SHFILEOPSTRUCTW;
  12205. SHFILEOPSTRUCT = SHFILEOPSTRUCTA;
  12206. const
  12207. FO_MOVE = $0001;
  12208. FO_COPY = $0002;
  12209. FO_DELETE = $0003;
  12210. FO_RENAME = $0004;
  12211. FOF_MULTIDESTFILES = $0001;
  12212. FOF_CONFIRMMOUSE = $0002;
  12213. FOF_SILENT = $0004; { don't create progress/report }
  12214. FOF_RENAMEONCOLLISION = $0008;
  12215. FOF_NOCONFIRMATION = $0010; { Don't prompt the user. }
  12216. FOF_WANTMAPPINGHANDLE = $0020; { Fill in SHFILEOPSTRUCT.hNameMappings
  12217. Must be freed using SHFreeNameMappings }
  12218. FOF_ALLOWUNDO = $0040;
  12219. FOF_FILESONLY = $0080; { on *.*, do only files }
  12220. FOF_SIMPLEPROGRESS = $0100; { means don't show names of files }
  12221. FOF_NOCONFIRMMKDIR = $0200; { don't confirm making any needed dirs }
  12222. FOF_NOERRORUI = $0400; { don't put up error UI }
  12223. function SHFileOperationW(const lpFileOp: TSHFileOpStructW): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12224. external 'shell32.dll' name 'SHFileOperationW';
  12225. function SHFileOperationA(const lpFileOp: TSHFileOpStructA): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12226. external 'shell32.dll' name 'SHFileOperationA';
  12227. type
  12228. PNotifyIconDataA = ^TNotifyIconDataA;
  12229. PNotifyIconDataW = ^TNotifyIconDataW;
  12230. PNotifyIconData = PNotifyIconDataA;
  12231. _NOTIFYICONDATAA = record
  12232. cbSize: DWORD;
  12233. Wnd: HWND;
  12234. uID: UINT;
  12235. uFlags: UINT;
  12236. uCallbackMessage: UINT;
  12237. hIcon: HICON;
  12238. szTip: array [0..63] of AnsiChar;
  12239. end;
  12240. _NOTIFYICONDATAW = record
  12241. cbSize: DWORD;
  12242. Wnd: HWND;
  12243. uID: UINT;
  12244. uFlags: UINT;
  12245. uCallbackMessage: UINT;
  12246. hIcon: HICON;
  12247. szTip: array [0..63] of WideChar;
  12248. end;
  12249. _NOTIFYICONDATA = _NOTIFYICONDATAA;
  12250. TNotifyIconDataA = _NOTIFYICONDATAA;
  12251. TNotifyIconDataW = _NOTIFYICONDATAW;
  12252. TNotifyIconData = TNotifyIconDataA;
  12253. NOTIFYICONDATAA = _NOTIFYICONDATAA;
  12254. NOTIFYICONDATAW = _NOTIFYICONDATAW;
  12255. NOTIFYICONDATA = NOTIFYICONDATAA;
  12256. const
  12257. NIM_ADD = $00000000;
  12258. NIM_MODIFY = $00000001;
  12259. NIM_DELETE = $00000002;
  12260. NIF_MESSAGE = $00000001;
  12261. NIF_ICON = $00000002;
  12262. NIF_TIP = $00000004;
  12263. {$IFDEF UNICODE_CTRLS}
  12264. function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconDataW): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12265. external 'shell32.dll' name 'Shell_NotifyIconW';
  12266. {$ELSE}
  12267. function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12268. external 'shell32.dll' name 'Shell_NotifyIconA';
  12269. {$ENDIF UNICODE_CTRLS}
  12270. {$IFDEF UNICODE_CTRLS}
  12271. function ExtractIcon(hInst: HINST; lpszExeFileName: PKOLChar;
  12272. nIconIndex: UINT): HICON; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12273. external 'shell32.dll' name 'ExtractIconW';
  12274. {$ELSE}
  12275. function ExtractIcon(hInst: HINST; lpszExeFileName: PKOLChar;
  12276. nIconIndex: UINT): HICON; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12277. external 'shell32.dll' name 'ExtractIconA';
  12278. {$ENDIF UNICODE_CTRLS}
  12279. {$endif win32}
  12280. {$ENDIF WIN}
  12281. {$IFDEF WIN_GDI}
  12282. {$ifdef win32}
  12283. type
  12284. HDROP = Longint;
  12285. function DragQueryPoint(Drop: HDROP; var Point: TPoint): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12286. external 'shell32.dll' name 'DragQueryPoint';
  12287. {$IFDEF UNICODE_CTRLS}
  12288. function DragQueryFile(Drop: HDROP; FileIndex: UINT; FileName: PWideChar; cb: UINT): UINT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12289. external 'shell32.dll' name 'DragQueryFileW';
  12290. {$ELSE}
  12291. function DragQueryFile(Drop: HDROP; FileIndex: UINT; FileName: PChar; cb: UINT): UINT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12292. external 'shell32.dll' name 'DragQueryFileA';
  12293. {$ENDIF UNICODE_CTRLS}
  12294. procedure DragFinish(Drop: HDROP); {$ifdef wince}cdecl{$else}stdcall{$endif};
  12295. external 'shell32.dll' name 'DragFinish';
  12296. procedure DragAcceptFiles(Wnd: HWND; Accept: BOOL); {$ifdef wince}cdecl{$else}stdcall{$endif};
  12297. external 'shell32.dll' name 'DragAcceptFiles';
  12298. const
  12299. OFN_READONLY = $00000001;
  12300. OFN_OVERWRITEPROMPT = $00000002;
  12301. OFN_HIDEREADONLY = $00000004;
  12302. OFN_NOCHANGEDIR = $00000008;
  12303. OFN_SHOWHELP = $00000010;
  12304. OFN_ENABLEHOOK = $00000020;
  12305. OFN_ENABLETEMPLATE = $00000040;
  12306. OFN_ENABLETEMPLATEHANDLE = $00000080;
  12307. OFN_NOVALIDATE = $00000100;
  12308. OFN_ALLOWMULTISELECT = $00000200;
  12309. OFN_EXTENSIONDIFFERENT = $00000400;
  12310. OFN_PATHMUSTEXIST = $00000800;
  12311. OFN_FILEMUSTEXIST = $00001000;
  12312. OFN_CREATEPROMPT = $00002000;
  12313. OFN_SHAREAWARE = $00004000;
  12314. OFN_NOREADONLYRETURN = $00008000;
  12315. OFN_NOTESTFILECREATE = $00010000;
  12316. OFN_NONETWORKBUTTON = $00020000;
  12317. OFN_NOLONGNAMES = $00040000;
  12318. OFN_EXPLORER = $00080000;
  12319. OFN_NODEREFERENCELINKS = $00100000;
  12320. OFN_LONGNAMES = $00200000;
  12321. OFN_ENABLEINCLUDENOTIFY = $00400000;
  12322. OFN_ENABLESIZING = $00800000;
  12323. OFN_DONTADDTORECENT = $02000000;
  12324. OFN_FORCESHOWHIDDEN = $10000000; // Show All files including System and hidden files
  12325. OFN_EX_NOPLACESBAR = $00000001;
  12326. OFN_SHAREFALLTHROUGH = 2;
  12327. OFN_SHARENOWARN = 1;
  12328. OFN_SHAREWARN = 0;
  12329. type
  12330. POpenFilename = ^TOpenFilename;
  12331. tagOFN = {$ifndef wince}packed{$endif} record
  12332. lStructSize: DWORD;
  12333. hWndOwner: HWND;
  12334. hInstance: HINST;
  12335. lpstrFilter: PKOLChar;
  12336. lpstrCustomFilter: PKOLChar;
  12337. nMaxCustFilter: DWORD;
  12338. nFilterIndex: DWORD;
  12339. lpstrFile: PKOLChar;
  12340. nMaxFile: DWORD;
  12341. lpstrFileTitle: PKOLChar;
  12342. nMaxFileTitle: DWORD;
  12343. lpstrInitialDir: PKOLChar;
  12344. lpstrTitle: PKOLChar;
  12345. Flags: DWORD;
  12346. nFileOffset: Word;
  12347. nFileExtension: Word;
  12348. lpstrDefExt: PKOLChar;
  12349. lCustData: LPARAM;
  12350. lpfnHook: function(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): UINT {$ifdef wince}cdecl{$else}stdcall{$endif};
  12351. lpTemplateName: PKOLChar;
  12352. {$IFDEF OpenSaveDialog_Extended}
  12353. //---------- added from Windows2000:
  12354. pvReserved: Pointer;
  12355. dwReserved: DWORD;
  12356. FlagsEx: DWORD;
  12357. {$ENDIF}
  12358. end;
  12359. TOpenFilename = tagOFN;
  12360. OPENFILENAME = tagOFN;
  12361. {$IFDEF UNICODE_CTRLS}
  12362. function GetOpenFileName(var OpenFile: TOpenFilename): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12363. external 'comdlg32.dll' name 'GetOpenFileNameW';
  12364. function GetSaveFileName(var OpenFile: TOpenFilename): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12365. external 'comdlg32.dll' name 'GetSaveFileNameW';
  12366. {$ELSE}
  12367. function GetOpenFileName(var OpenFile: TOpenFilename): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12368. external 'comdlg32.dll' name 'GetOpenFileNameA';
  12369. function GetSaveFileName(var OpenFile: TOpenFilename): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12370. external 'comdlg32.dll' name 'GetSaveFileNameA';
  12371. {$ENDIF UNICODE_CTRLS}
  12372. type
  12373. PChooseColorA = ^TChooseColorA;
  12374. PChooseColorW = ^TChooseColorW;
  12375. PChooseColor = PChooseColorA;
  12376. tagCHOOSECOLORA = {$ifndef wince}packed{$endif} record
  12377. lStructSize: DWORD;
  12378. hWndOwner: HWND;
  12379. hInstance: HWND;
  12380. rgbResult: COLORREF;
  12381. lpCustColors: ^COLORREF;
  12382. Flags: DWORD;
  12383. lCustData: LPARAM;
  12384. lpfnHook: function(Wnd: HWND; Message: UINT; wParam: WPARAM; lParam: LPARAM): UINT {$ifdef wince}cdecl{$else}stdcall{$endif};
  12385. lpTemplateName: PAnsiChar;
  12386. end;
  12387. tagCHOOSECOLORW = {$ifndef wince}packed{$endif} record
  12388. lStructSize: DWORD;
  12389. hWndOwner: HWND;
  12390. hInstance: HWND;
  12391. rgbResult: COLORREF;
  12392. lpCustColors: ^COLORREF;
  12393. Flags: DWORD;
  12394. lCustData: LPARAM;
  12395. lpfnHook: function(Wnd: HWND; Message: UINT; wParam: WPARAM; lParam: LPARAM): UINT {$ifdef wince}cdecl{$else}stdcall{$endif};
  12396. lpTemplateName: PWideChar;
  12397. end;
  12398. tagCHOOSECOLOR = tagCHOOSECOLORA;
  12399. TChooseColorA = tagCHOOSECOLORA;
  12400. TChooseColorW = tagCHOOSECOLORW;
  12401. TChooseColor = TChooseColorA;
  12402. const
  12403. CC_RGBINIT = $00000001;
  12404. CC_FULLOPEN = $00000002;
  12405. CC_PREVENTFULLOPEN = $00000004;
  12406. CC_SHOWHELP = $00000008;
  12407. CC_ENABLEHOOK = $00000010;
  12408. CC_ENABLETEMPLATE = $00000020;
  12409. CC_ENABLETEMPLATEHANDLE = $00000040;
  12410. CC_SOLIDCOLOR = $00000080;
  12411. CC_ANYCOLOR = $00000100;
  12412. function ChooseColor(var CC: TChooseColor): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12413. external 'comdlg32.dll' name 'ChooseColorA';
  12414. {$endif win32}
  12415. {$IFDEF GDI}
  12416. //[procedure Chk_BitBlt_ShowError]
  12417. procedure Chk_BitBlt_ShowError;
  12418. var Rslt: Integer;
  12419. begin
  12420. Rslt := GetLastError;
  12421. ShowMessage( 'BitBlt ERROR: ' + Int2Str( Rslt )
  12422. + ' ' + SysErrorMessage( Rslt ) );
  12423. end;
  12424. //[END Chk_BitBlt_ShowError]
  12425. //[procedure Chk_BitBlt]
  12426. {$ifdef wince}
  12427. procedure Chk_BitBlt;
  12428. begin
  12429. end;
  12430. {$else}
  12431. procedure Chk_BitBlt;
  12432. var Rslt: Integer;
  12433. begin
  12434. asm
  12435. MOV Rslt, EAX
  12436. end;
  12437. if Rslt = 0 then
  12438. begin
  12439. Chk_BitBlt_ShowError;
  12440. asm
  12441. int 3;
  12442. end;
  12443. end;
  12444. end;
  12445. {$endif wince}
  12446. //[END Chk_BitBlt]
  12447. {$ENDIF GDI}
  12448. {-}
  12449. {$ifdef _D2}
  12450. //[PROCEDURE Assert]
  12451. procedure Assert( Cond: Boolean; const Msg: String );
  12452. begin
  12453. if not Cond then
  12454. begin
  12455. AssertErrorProc( Msg, '', 0 );
  12456. //MsgOK( Msg );
  12457. asm
  12458. int 3;
  12459. end;
  12460. end;
  12461. end;
  12462. //[API CreateDIBSection]
  12463. function CreateDIBSection(DC: HDC; const p2: TBitmapInfo; p3: UINT;
  12464. var p4: Pointer; p5: THandle; p6: DWORD): HBITMAP; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12465. external gdi32 name 'CreateDIBSection';
  12466. //[PROCEDURE _LStrFromPCharLen]
  12467. procedure _LStrFromPCharLen(var Dest: AnsiString; Source: PAnsiChar; Length: Integer);
  12468. asm
  12469. { -> EAX pointer to dest }
  12470. { EDX source }
  12471. { ECX length }
  12472. PUSH EBX
  12473. PUSH ESI
  12474. PUSH EDI
  12475. MOV EBX,EAX
  12476. MOV ESI,EDX
  12477. MOV EDI,ECX
  12478. { allocate new string }
  12479. MOV EAX,EDI
  12480. CALL System.@NewAnsiString
  12481. MOV ECX,EDI
  12482. MOV EDI,EAX
  12483. TEST ESI,ESI
  12484. JE @@noMove
  12485. MOV EDX,EAX
  12486. MOV EAX,ESI
  12487. CALL Move
  12488. { assign the result to dest }
  12489. @@noMove:
  12490. MOV EAX,EBX
  12491. CALL System.@LStrClr
  12492. MOV [EBX],EDI
  12493. POP EDI
  12494. POP ESI
  12495. POP EBX
  12496. end;
  12497. {$endif}
  12498. {+}
  12499. {$ifdef win32}
  12500. //[API InitCommonControls]
  12501. procedure InitCommonControls; external cctrl name 'InitCommonControls';
  12502. type
  12503. TInitCommonControlsEx = {$ifndef wince}packed{$endif} record
  12504. dwSize: DWORD;
  12505. dwICC: DWORD;
  12506. end;
  12507. PInitCommonControlsEx = ^TInitCommonControlsEx;
  12508. var ComCtl32_Module: HModule;
  12509. //[procedure DoInitCommonControls]
  12510. procedure DoInitCommonControls( dwICC: DWORD );
  12511. var Proc: procedure( ICC: PInitCommonControlsEx ); {$ifdef wince}cdecl{$else}stdcall{$endif};
  12512. ICC: TInitCommonControlsEx;
  12513. begin
  12514. InitCommonControls;
  12515. if ComCtl32_Module = 0 then
  12516. ComCtl32_Module := LoadLibrary( 'comctl32' );
  12517. @ Proc := GetProcAddress( ComCtl32_Module, 'InitCommonControlsEx' );
  12518. if Assigned( Proc ) then
  12519. begin
  12520. ICC.dwSize := Sizeof( ICC );
  12521. ICC.dwICC := dwICC;
  12522. Proc( @ ICC );
  12523. end;
  12524. end;
  12525. {$else}
  12526. procedure DoInitCommonControls( dwICC: DWORD );
  12527. var
  12528. ICC: TInitCommonControlsEx;
  12529. begin
  12530. ICC.dwSize := Sizeof( ICC );
  12531. ICC.dwICC := dwICC;
  12532. InitCommonControlsEx(@ICC);
  12533. end;
  12534. {$endif win32}
  12535. //[END DoInitCommonControls]
  12536. const size_TRect = 16; // used often in assembler versions of code
  12537. {-}
  12538. {$IFDEF ASM_VERSION}
  12539. const
  12540. EmptyString: String = '';
  12541. //[PROCEDURE EAX2PChar]
  12542. procedure EAX2PChar;
  12543. asm
  12544. TEST EAX, EAX
  12545. JNZ @@exit
  12546. MOV EAX, offset[EmptyString]
  12547. @@exit:
  12548. end;
  12549. //[PROCEDURE EDX2PChar]
  12550. procedure EDX2PChar;
  12551. asm
  12552. TEST EDX, EDX
  12553. JNZ @@exit
  12554. MOV EDX, offset[EmptyString]
  12555. @@exit:
  12556. end;
  12557. //[PROCEDURE ECX2PChar]
  12558. procedure ECX2PChar;
  12559. asm
  12560. JECXZ @@convert
  12561. RET
  12562. @@convert:
  12563. MOV ECX, offset[EmptyString]
  12564. @@exit:
  12565. end;
  12566. //[PROCEDURE RemoveStr]
  12567. procedure RemoveStr;
  12568. asm
  12569. { <- [ESP+4] = string to remove
  12570. -> ESP := ESP + 4
  12571. EAX = 0
  12572. }
  12573. POP EAX
  12574. XCHG EAX, [ESP]
  12575. PUSH EAX
  12576. MOV EAX, ESP
  12577. CALL System.@LStrClr
  12578. POP EAX
  12579. end;
  12580. {$ELSE ASM_VERSION}
  12581. {$ENDIF ASM_VERSION}
  12582. {+}
  12583. const PossibleColorBits : array[1..7] of Byte = ( 1, 4, 8, 16, 24, 32, 0 );
  12584. function FindFilter( const Filter: KOLString): KOLString; forward;
  12585. function WriteExMemoryStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD; forward;
  12586. procedure CreateComboboxWnd( Combo: PControl ); forward;
  12587. procedure ComboboxDropDown( Sender: PObj ); forward;
  12588. function WndProcParentResize(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12589. function WndProcResize(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12590. {$ifndef wince}
  12591. function WndProcJustOneNotify( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean; forward;
  12592. {$endif wince}
  12593. function WndProcJustOne( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean; forward;
  12594. function WndProcTreeView( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12595. function CompareAnsiStrListItems( const Sender : Pointer; const e1, e2 : DWORD ) : Integer; forward;
  12596. function CompareStrListItems( const Sender : Pointer; const e1, e2 : DWORD ) : Integer; forward;
  12597. function CompareIntegers( const Sender : Pointer; const e1, e2 : DWORD ) : Integer; forward;
  12598. procedure SwapIntegers( const Sender : Pointer; const e1, e2 : DWORD ); forward;
  12599. function CompareDwords( const Sender : Pointer; const e1, e2 : DWORD ) : Integer; forward;
  12600. procedure ApplyImageLists2Control( Sender: PControl ); forward;
  12601. procedure ApplyImageLists2ListView( Sender: PControl ); forward;
  12602. {$ifdef win32}
  12603. function OpenDirCallBack( Wnd: HWnd; Msg: DWORD; lParam, lpData: LParam ): Integer;
  12604. {$ifdef wince}cdecl{$else}stdcall{$endif}; forward;
  12605. function OpenDirSelChangeCallBack( Wnd: HWnd; Msg: DWORD; lParam, lpData: LParam ):
  12606. Integer; {$ifdef wince}cdecl{$else}stdcall{$endif}; forward;
  12607. {$endif win32}
  12608. function WndProcShowModal( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12609. function TimerProc( Wnd : HWnd; Msg : Integer; T : PTimer; CurrentTime : DWord ): Integer;
  12610. {$ifdef wince}cdecl{$else}stdcall{$endif}; forward;
  12611. function PrepareBitmapHeader( W, H, BitsPerPixel: Integer ): PBitmapInfo; forward;
  12612. procedure PreparePF16bit( DIBHeader: PBitmapInfo ); forward;
  12613. procedure _RotateBitmapMono( var DstBmp: PBitmap; SrcBmp: PBitmap ); forward;
  12614. procedure _RotateBitmap4bit( var DstBmp: PBitmap; SrcBmp: PBitmap ); forward;
  12615. procedure _RotateBitmap8bit( var DstBmp: PBitmap; SrcBmp: PBitmap ); forward;
  12616. procedure _RotateBitmap16bit( var DstBmp: PBitmap; SrcBmp: PBitmap ); forward;
  12617. procedure _RotateBitmap2432bit( var DstBmp: PBitmap; SrcBmp: PBitmap ); forward;
  12618. procedure _RotateBitmapRight( SrcBmp: PBitmap ); forward;
  12619. procedure _SetDIBPixels1bit( Bmp: PBitmap; X, Y: Integer; Value: TColor ); forward;
  12620. procedure _SetDIBPixelsPalIdx( Bmp: PBitmap; X, Y: Integer; Value: TColor ); forward;
  12621. procedure _SetDIBPixels16bit( Bmp: PBitmap; X, Y: Integer; Value: TColor ); forward;
  12622. procedure _SetDIBPixelsTrueColor( Bmp: PBitmap; X, Y: Integer; Value: TColor ); forward;
  12623. procedure FillBmpWithBkColor( Bmp: PBitmap; DC2: HDC; oldWidth, oldHeight: Integer ); forward;
  12624. procedure DetachBitmapFromCanvas( Sender: PBitmap ); forward;
  12625. function ColorBits( ColorsCount : Integer ) : Integer; forward;
  12626. procedure AlignChildrenProc(Sender: PObj); forward;
  12627. function WndProcUpdate( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12628. function CollectTabControls( Form: PControl ): PList; forward;
  12629. {$IFNDEF NOT_USE_RICHEDIT}
  12630. function WndProc_RE_LinkNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12631. {$ENDIF NOT_USE_RICHEDIT}
  12632. function WndProc_DrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  12633. : Boolean; forward;
  12634. function WndProcTabControl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  12635. forward;
  12636. function WndProcSplitter( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  12637. forward;
  12638. function Tabulate2ControlEx( Self_: PControl; Key: DWORD; checkOnly: Boolean ): Boolean;
  12639. forward;
  12640. procedure Tabulate2Next( Form: PControl; Dir: Integer ); forward;
  12641. function Tabulate2Control( Self_: PControl; Key: DWORD; checkOnly: Boolean ): Boolean;
  12642. forward;
  12643. {$IFDEF GRAPHCTL_XPSTYLES}
  12644. {$I visual_xp_styles.inc}
  12645. {$ENDIF}
  12646. {$ifdef wince}
  12647. var
  12648. _CePlatform: byte = 255;
  12649. function CePlatform: TCePlatform;
  12650. var
  12651. buf: array[0..50] of WideChar;
  12652. begin
  12653. if _CePlatform = $FF then begin
  12654. Result := cpWinCE;
  12655. if SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(buf), @buf, 0) then begin
  12656. if WStrCmp(@buf, 'PocketPC') = 0 then
  12657. Result := cpPocketPC
  12658. else
  12659. if WStrCmp(@buf, 'SmartPhone') = 0 then
  12660. Result := cpSmartphone;
  12661. end
  12662. else
  12663. if GetLastError = ERROR_ACCESS_DENIED then
  12664. Result := cpSmartphone;
  12665. _CePlatform:=byte(Result);
  12666. end
  12667. else
  12668. Result:=TCePlatform(_CePlatform);
  12669. end;
  12670. function WndProcSIPAware(Sender: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  12671. begin
  12672. Result:=False;
  12673. case Msg.message of
  12674. WM_ACTIVATE:
  12675. begin
  12676. if PSHACTIVATEINFO(Sender.fCustomData).bits < 0 then begin
  12677. SHSipPreference(Msg.hwnd, SIPSTATE(PSHACTIVATEINFO(Sender.fCustomData).bits + 10));
  12678. PSHACTIVATEINFO(Sender.fCustomData).bits:=0;
  12679. end;
  12680. SHHandleWMActivate(Msg.hwnd, Msg.wParam, Msg.lParam, Sender.fCustomData, SHA_INPUTDIALOG);
  12681. end;
  12682. WM_SETTINGCHANGE:
  12683. SHHandleWMSettingChange(Msg.hwnd, Msg.wParam, Msg.lParam, Sender.fCustomData);
  12684. end;
  12685. end;
  12686. procedure CeFormSIPAware(Form: PControl; ShowSIP: boolean);
  12687. procedure CreateSIPPref(C: PControl);
  12688. var
  12689. i: integer;
  12690. begin
  12691. for i:=0 to C.ChildCount - 1 do
  12692. CreateSIPPref(C.Children[i]);
  12693. if C.ChildCount > 0 then
  12694. CreateWindowEx(0, 'SIPPREF', '', WS_CHILD , -10, -10, 5, 5, C.Handle, 0, 0, 0);
  12695. end;
  12696. begin
  12697. GetMem(Form.fCustomData, SizeOf(SHACTIVATEINFO));
  12698. FillChar(Form.fCustomData^, SizeOf(SHACTIVATEINFO), 0);
  12699. with PSHACTIVATEINFO(Form.fCustomData)^ do begin
  12700. cbSize:=SizeOf(SHACTIVATEINFO);
  12701. if ShowSIP then
  12702. bits:=integer(SIP_UP) - 10
  12703. else
  12704. bits:=integer(SIP_FORCEDOWN) - 10;
  12705. end;
  12706. Form.AttachProc(WndProcSIPAware);
  12707. SHInitExtraControls;
  12708. Form.CreateChildWindows;
  12709. CreateSIPPref(Form);
  12710. end;
  12711. function InsertMenuItem(Menu: HMENU; uItem: UINT; fByPosition: BOOL; const MII: TMenuItemInfo): BOOL;
  12712. var
  12713. id, Flags: UINT;
  12714. begin
  12715. if MII.hSubMenu <> 0 then begin
  12716. Flags:=MF_POPUP;
  12717. id:=MII.hSubMenu;
  12718. end
  12719. else begin
  12720. id:=MII.wID;
  12721. Flags:=MII.fType and not MFT_RADIOCHECK;
  12722. if MII.fType and MFT_SEPARATOR = 0 then
  12723. Flags:=Flags or MII.fState;
  12724. end;
  12725. if fByPosition then
  12726. Flags:=Flags or MF_BYPOSITION;
  12727. Result:=InsertMenu(Menu, uItem, Flags and not MF_DISABLED, id, MII.dwTypeData);
  12728. if (MII.fType and MFT_RADIOCHECK <> 0) and (MII.fState and MFS_CHECKED <> 0) then
  12729. CheckMenuRadioItem(Menu, MII.wID, MII.wID, MII.wID, MF_BYCOMMAND);
  12730. end;
  12731. var
  12732. CeSetMenuProc: procedure (Wnd: HWND; Menu: PMenu) = nil;
  12733. procedure CeSetMenu(Wnd: HWND; Menu: PMenu);
  12734. begin
  12735. if Assigned(CeSetMenuProc) then
  12736. CeSetMenuProc(Wnd, Menu);
  12737. end;
  12738. procedure CeSetMenuHandler(Wnd: HWND; Menu: PMenu);
  12739. var
  12740. mbi: SHMENUBARINFO;
  12741. tb: TBButton;
  12742. tbbi : TBBUTTONINFO;
  12743. i, j: integer;
  12744. st: byte;
  12745. R, BR: TRect;
  12746. begin
  12747. if (Menu <> nil) and (CePlatform = cpSmartphone) then
  12748. Menu.SaveState;
  12749. GetWindowRect(Wnd, BR);
  12750. mbi.hwndMB:=SHFindMenuBar(Wnd);
  12751. if (mbi.hwndMB <> 0) and (CePlatform = cpSmartphone) then begin
  12752. DestroyWindow(mbi.hwndMB);
  12753. mbi.hwndMB:=0;
  12754. end;
  12755. if mbi.hwndMB = 0 then begin
  12756. FillChar(mbi, SizeOf(mbi), 0);
  12757. with mbi do begin
  12758. cbSize:=SizeOf(mbi);
  12759. hwndParent:=Wnd;
  12760. nToolBarId:=20000;
  12761. hInstRes:=HINSTANCE;
  12762. if CePlatform = cpSmartphone then
  12763. if Menu <> nil then begin
  12764. i:=0;
  12765. for j:=0 to Menu.FItems.Count - 1 do
  12766. with PMenu(Menu.FItems.Items[j])^ do
  12767. if Visible then begin
  12768. Inc(i);
  12769. if (i = 1) and (SubMenu <> 0) then
  12770. Inc(nToolBarId)
  12771. else
  12772. if i = 2 then begin
  12773. if SubMenu <> 0 then
  12774. Inc(nToolBarId, 2);
  12775. break;
  12776. end;
  12777. end;
  12778. end;
  12779. end;
  12780. if not SHCreateMenuBar(@mbi) then
  12781. exit;
  12782. end;
  12783. while SendMessage(mbi.hwndMB, TB_DELETEBUTTON, 0, 0) <> 0 do ;
  12784. if Menu <> nil then begin
  12785. i:=0;
  12786. for j:=0 to Menu.FItems.Count - 1 do
  12787. with PMenu(Menu.FItems.Items[j])^ do
  12788. if Visible then begin
  12789. if FSavedState and MFS_DISABLED = 0 then
  12790. st:=TBSTATE_ENABLED
  12791. else
  12792. st:=0;
  12793. if FSavedState and MFS_CHECKED <> 0 then
  12794. st:=st or TBSTATE_CHECKED;
  12795. if CePlatform = cpSmartphone then begin
  12796. if i = 2 then
  12797. break; // smartphones have maximum 2 top level menu items.
  12798. tbbi.cbSize := sizeof(tbbi);
  12799. tbbi.pszText := PKOLChar(Caption);
  12800. tbbi.idCommand := FID;
  12801. tbbi.dwMask := TBIF_TEXT or TBIF_COMMAND or TBIF_STATE;
  12802. tbbi.fsState:=st;
  12803. SendMessage(mbi.hwndMB, TB_SETBUTTONINFO, i + 1, LPARAM(@tbbi));
  12804. if FHandle <> 0 then begin
  12805. tbbi.dwMask := TBIF_LPARAM;
  12806. SendMessage (mbi.hwndMB, TB_GETBUTTONINFO, FID, LPARAM(@tbbi));
  12807. DestroyMenu(FHandle);
  12808. FHandle:=HMENU(tbbi.lParam);
  12809. ReCreate;
  12810. end;
  12811. end
  12812. else begin
  12813. FillChar(tb, SizeOf(tb), 0);
  12814. tb.iBitmap:=I_IMAGENONE;
  12815. tb.idCommand:=fID;
  12816. tb.iString:=longint(PKOLChar(Caption));
  12817. tb.fsState:=st;
  12818. if SubMenu <> 0 then
  12819. tb.fsStyle:=TBSTYLE_DROPDOWN or $0080 or TBSTYLE_AUTOSIZE
  12820. else
  12821. tb.fsStyle:=TBSTYLE_BUTTON or TBSTYLE_AUTOSIZE;
  12822. tb.dwData:=SubMenu;
  12823. SendMessage(mbi.hwndMB, TB_INSERTBUTTON, i, LPARAM(@tb));
  12824. end;
  12825. Inc(i);
  12826. end;
  12827. if (CePlatform = cpSmartphone) and (i = 1) then begin
  12828. tbbi.dwMask := TBIF_STATE;
  12829. tbbi.fsState:=0;
  12830. SendMessage(mbi.hwndMB, TB_SETBUTTONINFO, 2, LPARAM(@tbbi));
  12831. end;
  12832. end;
  12833. GetWindowRect(mbi.hwndMB, R);
  12834. if BR.Bottom > R.Top then
  12835. SetWindowPos(wnd, 0, 0, 0, BR.Right - BR.Left, R.Top - BR.Top, SWP_NOZORDER or SWP_NOREPOSITION or SWP_NOMOVE);
  12836. end;
  12837. {$endif wince}
  12838. {$IFDEF SNAPMOUSE2DFLTBTN}
  12839. var FoundMsgBoxWnd: HWnd;
  12840. function EnumProcSnapMouse2DfltBtn( W: HWnd; lParam: Integer ): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  12841. var ClassBuf: array[ 0..31 ] of KOLChar;
  12842. begin
  12843. GetClassName( W, ClassBuf, Sizeof( ClassBuf ) div Sizeof( KOLChar ) );
  12844. Result := TRUE;
  12845. if ClassBuf = '#32770' then
  12846. begin
  12847. FoundMsgBoxWnd := W;
  12848. Result := FALSE;
  12849. end;
  12850. end;
  12851. function WndProcSnapMouse2DfltBtn( Sender: PControl; var M: TMsg; var Rslt: Integer ): Boolean;
  12852. var W: HWnd;
  12853. R: TRect;
  12854. P: TPoint;
  12855. SnapMouse: Integer;
  12856. begin
  12857. SnapMouse := 0;
  12858. if SystemParametersInfo( SPI_GETSNAPTODEFBUTTON, 0, @ SnapMouse, 0 ) then
  12859. if SnapMouse <> 0 then
  12860. begin
  12861. FoundMsgBoxWnd := 0;
  12862. EnumThreadWindows( GetCurrentThreadID, @ EnumProcSnapMouse2DfltBtn, 0 );
  12863. if FoundMsgBoxWnd <> 0 then
  12864. begin
  12865. W := GetWindow( FoundMsgBoxWnd, GW_CHILD );
  12866. while W <> 0 do
  12867. begin
  12868. if GetWindowLong( W, GWL_STYLE ) and BS_DEFPUSHBUTTON <> 0 then
  12869. begin
  12870. GetWindowRect( W, R );
  12871. P.X := (R.Left + R.Right) div 2;
  12872. P.Y := (R.Top + R.Bottom) div 2;
  12873. SetCursorPos( P.X, P.Y );
  12874. end;
  12875. W := GetWindow( W, GW_HWNDNEXT );
  12876. end;
  12877. Applet.DetachProc( WndProcSnapMouse2DfltBtn );
  12878. end;
  12879. end;
  12880. Result := FALSE;
  12881. end;
  12882. {$ENDIF SNAPMOUSE2DFLTBTN}
  12883. {$IFDEF GDI}
  12884. //[function MsgBox]
  12885. {$IFDEF ASM_VERSION}
  12886. {$ELSE ASM_VERSION} //Pascal
  12887. function MsgBox( const S: KOLString; Flags: DWORD ): DWORD;
  12888. var Title: PKOLChar;
  12889. begin
  12890. Title := nil;
  12891. if assigned( Applet ) then
  12892. begin
  12893. Title := PKOLChar( Applet.fCaption );
  12894. end;
  12895. {$IFDEF SNAPMOUSE2DFLTBTN}
  12896. if Assigned( Applet ) then
  12897. begin
  12898. Applet.AttachProc( WndProcSnapMouse2DfltBtn );
  12899. Applet.Postmsg( 0, 0, 0 );
  12900. end;
  12901. {$ENDIF}
  12902. Result := MessageBox( 0, PKOLChar( S ), Title, Flags );
  12903. {$IFDEF SNAPMOUSE2DFLTBTN}
  12904. if Assigned( Applet ) then
  12905. Applet.DetachProc( WndProcSnapMouse2DfltBtn );
  12906. {$ENDIF}
  12907. end;
  12908. //[END MsgBox]
  12909. {$ENDIF ASM_VERSION}
  12910. //[PROCEDURE MsgOK]
  12911. procedure MsgOK( const S: KOLString );
  12912. begin
  12913. MsgBox( S, MB_OK );
  12914. end;
  12915. //[function ShowMsg]
  12916. {$IFDEF ASM_UNICODE}
  12917. function ShowMsg( const S: KOLString; Flags: DWORD ): DWORD;
  12918. asm
  12919. push edx // Flags
  12920. mov ecx, [Applet]
  12921. {$IFDEF SNAPMOUSE2DFLTBTN}
  12922. jecxz @@0
  12923. pushad
  12924. xchg eax, ecx
  12925. mov edx, offset[WndProcSnapMouse2DfltBtn]
  12926. call TControl.AttachProc
  12927. popad
  12928. @@0:
  12929. {$ENDIF}
  12930. mov edx, 0
  12931. jecxz @@1
  12932. mov edx, [ecx].TControl.fHandle
  12933. mov ecx, [ecx].TControl.fCaption
  12934. @@1: push ecx // Title
  12935. push eax // S
  12936. push edx // Wnd
  12937. call MessageBox
  12938. {$IFDEF SNAPMOUSE2DFLTBTN}
  12939. mov ecx, [Applet]
  12940. jecxz @@2
  12941. pushad
  12942. xchg eax, ecx
  12943. mov edx, offset[WndProcSnapMouse2DfltBtn]
  12944. call TControl.DetachProc
  12945. popad
  12946. @@2:
  12947. {$ENDIF}
  12948. end;
  12949. {$ELSE PASCAL}
  12950. function ShowMsg( const S: KOLString; Flags: DWORD ): DWORD;
  12951. var Title: PKOLChar;
  12952. Wnd: HWnd;
  12953. begin
  12954. {$IFDEF SNAPMOUSE2DFLTBTN}
  12955. if Assigned( Applet ) then
  12956. Applet.AttachProc( WndProcSnapMouse2DfltBtn );
  12957. {$ENDIF}
  12958. Title := nil;
  12959. Wnd := 0;
  12960. if assigned( Applet ) then
  12961. begin
  12962. Title := PKOLChar( Applet.fCaption );
  12963. //{$IFNDEF SNAPMOUSE2DFLTBTN}
  12964. Wnd := Applet.Handle;
  12965. //{$ENDIF}
  12966. end;
  12967. Result := MessageBox( Wnd, PKOLChar( S ), Title, Flags );
  12968. {$IFDEF SNAPMOUSE2DFLTBTN}
  12969. if Assigned( Applet ) then
  12970. Applet.DetachProc( WndProcSnapMouse2DfltBtn );
  12971. {$ENDIF}
  12972. end;
  12973. {$ENDIF ASM_VERSION}
  12974. //[END ShowMsg]
  12975. //[procedure ShowMessage]
  12976. procedure ShowMessage( const S: KOLString );
  12977. begin
  12978. ShowMsg( S, MB_OK or MB_SETFOREGROUND or MB_DEFBUTTON1 );
  12979. end;
  12980. //[END ShowMessage]
  12981. {$ENDIF GDI}
  12982. {$IFDEF WIN_GDI}
  12983. //[procedure SpeakerBeep]
  12984. procedure SpeakerBeep( Freq: Word; Duration: DWORD );
  12985. begin
  12986. {$ifdef win32}
  12987. if WinVer >= wvNT then
  12988. Windows.Beep( Freq, Duration )
  12989. else
  12990. begin
  12991. if Freq < 18 then Exit;
  12992. Freq := 1193181 div Freq;
  12993. if Freq = 0 then Exit;
  12994. asm
  12995. mov al,0b6H
  12996. out 43H,al
  12997. mov ax,Freq
  12998. //xchg al, ah
  12999. out 42h,al
  13000. xchg al, ah
  13001. out 42h,al
  13002. in al,61H
  13003. or al,03H
  13004. out 61H,al
  13005. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF} ;
  13006. Sleep(Duration);
  13007. asm
  13008. in al,61H
  13009. and al,0fcH
  13010. out 61H,al
  13011. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF} ;
  13012. end;
  13013. {$endif win32}
  13014. end;
  13015. //[END SpeakerBeep]
  13016. {$ENDIF WIN_GDI}
  13017. {++}(*
  13018. //[API FormatMessage]
  13019. function FormatMessage; external kernel32 name 'FormatMessageA';
  13020. *){--}
  13021. //[FUNCTION SysErrorMessage]
  13022. function SysErrorMessage(ErrorCode: Integer): KOLString;
  13023. var
  13024. Len: Integer;
  13025. Buffer: array[0..255] of KOLChar;
  13026. begin
  13027. Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
  13028. FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode, 0, Buffer,
  13029. SizeOf(Buffer), nil);
  13030. while (Len > 0) and ((Buffer[Len - 1] >= #0) and (Buffer[Len - 1] <= ' ')) do Dec(Len);
  13031. SetString(Result, Buffer, Len);
  13032. end;
  13033. //[END SysErrorMessage]
  13034. {$ENDIF WIN_GDI}
  13035. //[function GetShiftState]
  13036. function GetShiftState: DWORD;
  13037. {$IFDEF WIN}
  13038. const Buttons: array[0..6] of Byte = ( VK_SHIFT, VK_CONTROL, VK_MENU, VK_LBUTTON,
  13039. VK_RBUTTON, VK_MBUTTON, VK_CAPITAL );
  13040. Flags: array[0..6] of Byte = ( MK_SHIFT, MK_CONTROL, MK_ALT, MK_LBUTTON,
  13041. MK_RBUTTON, MK_MBUTTON, MK_LOCK );
  13042. var i, mask: Integer;
  13043. {$ENDIF WIN} //todo: for Linux / GTK ?
  13044. begin
  13045. Result := 0;
  13046. {$IFDEF WIN}
  13047. mask := 1;
  13048. for i := High( Buttons ) downto 0 do
  13049. begin
  13050. if GetKeyState( Buttons[ i ] ) and mask <> 0 then
  13051. Result := Result or Flags[ i ];
  13052. mask := $8000;
  13053. end;
  13054. {$ENDIF WIN}
  13055. end;
  13056. //[END GetShiftState]
  13057. //[function MakeMethod]
  13058. function MakeMethod( Data, Code: Pointer ): TMethod;
  13059. begin
  13060. Result.Data := Data;
  13061. Result.Code := Code;
  13062. end;
  13063. //[END MakeMethod]
  13064. //[FUNCTION MakeRect]
  13065. {$IFDEF ASM_VERSION}
  13066. {$ELSE ASM_VERSION} //Pascal
  13067. function MakeRect( Left, Top, Right, Bottom: Integer ): TRect; {$ifdef wince}cdecl{$else}stdcall{$endif};
  13068. begin
  13069. Result.Left := Left;
  13070. Result.Top := Top;
  13071. Result.Right:= Right;
  13072. Result.Bottom := Bottom;
  13073. end;
  13074. {$ENDIF ASM_VERSION}
  13075. //[END MakeRect]
  13076. //[FUNCTION RectsEqual]
  13077. {$IFDEF ASM_VERSION}
  13078. {$ELSE ASM_VERSION} //Pascal
  13079. function RectsEqual( const R1, R2: TRect ): Boolean;
  13080. begin
  13081. Result := CompareMem( @R1, @R2, Sizeof( TRect ) );
  13082. end;
  13083. {$ENDIF ASM_VERSION}
  13084. //[END RectsEqual]
  13085. //[function RectsIntersected]
  13086. function RectsIntersected( const R1, R2: TRect ): Boolean;
  13087. begin
  13088. Result := ((R1.Left <= R2.Left) and (R1.Right > R2.Left ) or
  13089. (R1.Left <= R2.Right) and (R1.Right >= R2.Right) or
  13090. (R1.Left >= R2.Left) and (R1.Right <= R2.Right))
  13091. and
  13092. ((R1.Top <= R2.Top) and (R1.Bottom > R2.Top) or
  13093. (R1.Top <= R2.Bottom) and (R1.Bottom >= R2.Bottom) or
  13094. (R1.Top >= R2.Top) and (R1.Bottom <= R2.Bottom)) ;
  13095. end;
  13096. //[END RectsIntersected]
  13097. //[FUNCTION PointInRect]
  13098. {$IFDEF ASM_VERSION}
  13099. {$ELSE ASM_VERSION} //Pascal
  13100. function PointInRect( const P: TPoint; const R: TRect ): Boolean;
  13101. begin
  13102. Result := (P.x >= R.Left) and (P.x < R.Right)
  13103. and (P.y >= R.Top) and (P.y < R.Bottom);
  13104. end;
  13105. {$ENDIF ASM_VERSION}
  13106. //[END PointInRect]
  13107. //[FUNCTION OffsetPoint]
  13108. {$IFDEF ASM_VERSION}
  13109. function OffsetPoint( const T: TPoint; dX, dY: Integer ): TPoint;
  13110. asm
  13111. ADD EDX, [EAX].TPoint.X
  13112. ADD ECX, [EAX].TPoint.Y
  13113. MOV EAX, [Result]
  13114. MOV [EAX].TPoint.X, EDX
  13115. MOV [EAX].TPoint.Y, ECX
  13116. end;
  13117. {$ELSE ASM_VERSION} // Pascal
  13118. function OffsetPoint( const T: TPoint; dX, dY: Integer ): TPoint;
  13119. begin
  13120. Result := MakePoint( T.X + dX, T.Y + dY );
  13121. end;
  13122. {$ENDIF ASM_VERSION}
  13123. //[FUNCTION OffsetSmallPoint]
  13124. {$IFDEF ASM_VERSION}
  13125. function OffsetSmallPoint( const T: TSmallPoint; dX, dY: SmallInt ): TSmallPoint;
  13126. asm
  13127. SHL EDX, 16
  13128. SHLD ECX, EDX, 16
  13129. CALL @@1
  13130. @@1:
  13131. ROL EAX, 16
  13132. ROL ECX, 16
  13133. ADD AX, CX
  13134. end;
  13135. {$ELSE ASM_VERSION} // Pascal
  13136. function OffsetSmallPoint( const T: TSmallPoint; dX, dY: SmallInt ): TSmallPoint;
  13137. begin
  13138. Result.x := T.x + dX;
  13139. Result.y := T.y + dY;
  13140. end;
  13141. {$ENDIF ASM_VERSION}
  13142. {$IFDEF ASM_VERSION}
  13143. function Point2SmallPoint( const T: TPoint ): TSmallPoint;
  13144. asm
  13145. XCHG EDX, EAX
  13146. MOV EAX, [EDX].TPoint.Y-2
  13147. MOV AX, word ptr [EDX].TPoint.X
  13148. end;
  13149. {$ELSE ASM_VERSION} // Pascal
  13150. function Point2SmallPoint( const T: TPoint ): TSmallPoint;
  13151. begin
  13152. Result.x := T.X;
  13153. Result.y := T.Y;
  13154. end;
  13155. {$ENDIF ASM_VERSION}
  13156. {$IFDEF ASM_VERSION}
  13157. function SmallPoint2Point( const T: TSmallPoint ): TPoint;
  13158. asm
  13159. MOVSX ECX, AX
  13160. MOV [EDX].TPoint.X, ECX
  13161. SAR EAX, 16
  13162. MOV [EDX].TPoint.Y, EAX
  13163. end;
  13164. {$ELSE ASM_VERSION} //Pascal
  13165. function SmallPoint2Point( const T: TSmallPoint ): TPoint;
  13166. begin
  13167. Result := MakePoint( T.x, T.y );
  13168. end;
  13169. {$ENDIF ASM_VERSION}
  13170. //[FUNCTION MakePoint]
  13171. {$IFDEF ASM_VERSION}
  13172. {$ELSE ASM_VERSION} //Pascal
  13173. function MakePoint( X, Y: Integer ): TPoint;
  13174. begin
  13175. Result.x := X;
  13176. Result.y := Y;
  13177. end;
  13178. {$ENDIF ASM_VERSION}
  13179. //[END MakePoint]
  13180. {$IFDEF ASM_VERSION}
  13181. function MakeSmallPoint( X, Y: Integer ): TSmallPoint;
  13182. asm
  13183. SHL EAX, 16
  13184. SHRD EAX, EDX, 16
  13185. end;
  13186. {$ELSE ASM_VERSION} // Pascal
  13187. function MakeSmallPoint( X, Y: Integer ): TSmallPoint;
  13188. begin
  13189. Result.x := X;
  13190. Result.y := Y;
  13191. end;
  13192. {$ENDIF ASM_VERSION}
  13193. //[FUNCTION MakeFlags]
  13194. {$IFDEF ASM_VERSION}
  13195. {$ELSE ASM_VERSION} //Pascal
  13196. function MakeFlags( FlgSet: PDWORD; FlgArray: array of Integer): Integer;
  13197. var I : Integer;
  13198. Mask : DWORD;
  13199. begin
  13200. Result := 0;
  13201. Mask := FlgSet^;
  13202. for I := 0 to High( FlgArray ) do
  13203. begin
  13204. if (FlgArray[ I ] < 0) and not LongBool( Mask and 1 ) then
  13205. Result := Result or not FlgArray[ I ]
  13206. else
  13207. if (FlgArray[ I ] >= 0) and LongBool( Mask and 1 ) then
  13208. Result := Result or FlgArray[ I ];
  13209. Mask := Mask shr 1;
  13210. end;
  13211. end;
  13212. {$ENDIF ASM_VERSION}
  13213. //[END MakeFlags]
  13214. function MakeDateTimeRange( D1, D2: TDateTime ): TDateTimeRange;
  13215. begin
  13216. Result.FromDate := D1;
  13217. Result.ToDate := D2;
  13218. end;
  13219. //[procedure Swap]
  13220. {$IFDEF ASM_VERSION}
  13221. procedure Swap( var X, Y: Integer );
  13222. asm
  13223. MOV ECX, [EDX]
  13224. XCHG ECX, [EAX]
  13225. MOV [EDX], ECX
  13226. end;
  13227. {$ELSE ASM_VERSION} //Pascal
  13228. procedure Swap( var X, Y: Integer );
  13229. var Tmp: Integer;
  13230. begin
  13231. Tmp := X;
  13232. X := Y;
  13233. Y := Tmp;
  13234. end;
  13235. {$ENDIF ASM_VERSION}
  13236. //[END Swap]
  13237. //[function Min]
  13238. {$IFDEF ASM_VERSION}
  13239. function Min( X, Y: Integer ): Integer;
  13240. asm
  13241. {$IFDEF F_P}
  13242. MOV EAX, [X]
  13243. MOV EDX, [Y]
  13244. {$ENDIF F_P}
  13245. {$IFDEF USE_CMOV}
  13246. CMP EAX, EDX
  13247. CMOVG EAX, EDX
  13248. {$ELSE}
  13249. CMP EAX, EDX
  13250. JLE @@exit
  13251. MOV EAX, EDX
  13252. @@exit:
  13253. {$ENDIF}
  13254. end {$IFDEF F_P} [ 'EAX', 'EDX' ] {$ENDIF};
  13255. {$ELSE ASM_VERSION} //Pascal
  13256. function Min( X, Y: Integer ): Integer;
  13257. begin
  13258. if X < Y then
  13259. Result:=X
  13260. else
  13261. Result:=Y;
  13262. end;
  13263. {$ENDIF ASM_VERSION}
  13264. //[END Min]
  13265. //[function Max]
  13266. {$IFDEF ASM_VERSION}
  13267. function Max( X, Y: Integer ): Integer;
  13268. asm
  13269. {$IFDEF F_P}
  13270. MOV EAX, [X]
  13271. MOV EDX, [Y]
  13272. {$ENDIF F_P}
  13273. {$IFDEF USE_CMOV}
  13274. CMP EAX, EDX
  13275. CMOVL EAX, EDX
  13276. {$ELSE}
  13277. CMP EAX, EDX
  13278. JGE @@exit
  13279. MOV EAX, EDX
  13280. @@exit:
  13281. {$ENDIF}
  13282. end {$IFDEF F_P} [ 'EAX', 'EDX' ] {$ENDIF};
  13283. {$ELSE ASM_VERSION} //Pascal
  13284. function Max( X, Y: Integer ): Integer;
  13285. begin
  13286. if X > Y then
  13287. Result:=X
  13288. else
  13289. Result:=Y;
  13290. end;
  13291. {$ENDIF ASM_VERSION}
  13292. //[END Max]
  13293. {$IFDEF REDEFINE_ABS}
  13294. //[function Abs]
  13295. function Abs( X: Integer ): Integer;
  13296. asm
  13297. {$IFDEF F_P}
  13298. MOV EAX, [X]
  13299. {$ENDIF F_P}
  13300. cdq
  13301. xor eax, edx
  13302. sub eax, edx
  13303. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF};
  13304. //[END Abs]
  13305. {$ENDIF}
  13306. //[function Sgn]
  13307. {$IFDEF ASM_VERSION}
  13308. function Sgn( X: Integer ): Integer;
  13309. asm
  13310. CMP EAX, 0
  13311. {$IFDEF USE_CMOV}
  13312. MOV EDX, -1
  13313. CMOVL EAX, EDX
  13314. MOV EDX, 1
  13315. CMOVG EAX, EDX
  13316. {$ELSE}
  13317. JZ @@exit
  13318. MOV EAX, 1
  13319. JG @@exit
  13320. MOV EAX, -1
  13321. @@exit:
  13322. {$ENDIF}
  13323. end;
  13324. {$ELSE ASM_VERSION} //Pascal
  13325. function Sgn( X: Integer ): Integer;
  13326. begin
  13327. if X > 0 then
  13328. Result:=1
  13329. else
  13330. Result:=-1;
  13331. end;
  13332. {$ENDIF ASM_VERSION}
  13333. //[END Sgn]
  13334. //[function iSqrt]
  13335. function iSQRT( X: Integer ): Integer;
  13336. {$IFDEF _D4orHigher}
  13337. // new version is more efficient but code is not compatible with older compilers
  13338. var I, N: Int64;
  13339. begin
  13340. Result := 0;
  13341. while Result < X do
  13342. begin
  13343. I := 1;
  13344. while I > 0 do
  13345. begin
  13346. N := (Result + I) * (Result + I);
  13347. if N > X then
  13348. begin
  13349. I := I shr 1;
  13350. break;
  13351. end
  13352. else
  13353. if N = X then
  13354. begin
  13355. Result := Result + I;
  13356. Exit;
  13357. end;
  13358. I := I * 2;
  13359. end;
  13360. if I <= 0 then Exit;
  13361. Result := Result + I;
  13362. end;
  13363. end;
  13364. {$ELSE _D3 or below or FPC1}
  13365. var m, y, b: DWORD;
  13366. begin
  13367. m := $40000000;
  13368. y := 0;
  13369. while m <> 0 do // 16 times
  13370. begin
  13371. b := y or m;
  13372. y := y shr 1;
  13373. if x >= b then
  13374. begin
  13375. x := x - b;
  13376. y := y or m;
  13377. end;
  13378. m := m shr 2;
  13379. end;
  13380. Result := y;
  13381. end;
  13382. {$ENDIF}
  13383. //[END iSqrt]
  13384. function iCbrt( X: DWORD ): Integer;
  13385. var s: Integer;
  13386. y, b: DWORD;
  13387. begin
  13388. s := 30;
  13389. y := 0;
  13390. while s >= 0 do // 11 times
  13391. begin
  13392. y := 2 * y;
  13393. b := (3 * y * (y+1) + 1) shl s;
  13394. s := s - 3;
  13395. if x >= b then
  13396. begin
  13397. x := x - b;
  13398. y := y + 1;
  13399. end;
  13400. end;
  13401. Result := y;
  13402. end;
  13403. {$IFDEF WIN_GDI}
  13404. {$IFDEF ASM_DC}
  13405. //[PROCEDURE StartDC]
  13406. procedure StartDC;
  13407. asm
  13408. { <- EBX : PBitmap
  13409. -> EAX = dc
  13410. [ESP+8] = var dc
  13411. [ESP+4] = var SaveBmp
  13412. }
  13413. PUSH 0
  13414. CALL CreateCompatibleDC
  13415. POP EDX
  13416. PUSH EAX
  13417. PUSH EDX
  13418. MOV EAX, EBX
  13419. CALL [EBX].TBitmap.fDetachCanvas
  13420. MOV EAX, EBX
  13421. CALL TBitmap.GetHandle
  13422. PUSH EAX
  13423. PUSH dword ptr [ESP+8]
  13424. CALL SelectObject
  13425. POP EDX
  13426. PUSH EAX
  13427. PUSH EDX
  13428. MOV EAX, [ESP+8]
  13429. end;
  13430. //[END StartDC]
  13431. //[procedure FinishDC]
  13432. procedure FinishDC;
  13433. asm
  13434. POP ECX
  13435. POP EAX
  13436. POP EDX
  13437. PUSH ECX
  13438. PUSH EDX
  13439. PUSH EAX
  13440. PUSH EDX
  13441. CALL SelectObject
  13442. CALL DeleteDC
  13443. end;
  13444. //[END FinishDC]
  13445. {$ENDIF ASM_DC}
  13446. //[function EnumDynHandlers FORWARD DECLARATION]
  13447. function EnumDynHandlers( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  13448. forward;
  13449. {$ENDIF WIN_GDI}
  13450. //[procedure DummyObjProc]
  13451. procedure DummyObjProc( Sender: PObj );
  13452. begin
  13453. end;
  13454. //[procedure DummyObjProcParam]
  13455. procedure DummyObjProcParam( Sender: PObj; Param: Pointer );
  13456. begin
  13457. end;
  13458. //[procedure DummyPaintProc]
  13459. procedure DummyPaintProc( Sender: PControl; DC: HDC );
  13460. begin
  13461. end;
  13462. {$IFDEF WIN}
  13463. {$ENDIF WIN}
  13464. {-}
  13465. { _TObj }
  13466. //[procedure Free_And_Nil]
  13467. procedure Free_And_Nil( var Obj );
  13468. var Obj1: PObj;
  13469. begin
  13470. Obj1 := PObj( Obj );
  13471. Pointer( Obj ) := nil;
  13472. Obj1.Free;
  13473. end;
  13474. //[procedure _TObj.Init]
  13475. procedure _TObj.Init;
  13476. begin
  13477. {$IFDEF _D2orD3}
  13478. FillChar( Pointer( Integer(@Self) + 4 )^, Sizeof( Self ) - 4, 0 );
  13479. {$ENDIF}
  13480. end;
  13481. //[function _TObj.VmtAddr]
  13482. function _TObj.VmtAddr: Pointer;
  13483. asm
  13484. {$ifdef cpuarm}
  13485. ldr r0,[r0]
  13486. {$else}
  13487. MOV EAX, [EAX]
  13488. {$endif cpuarm}
  13489. end;
  13490. { TObj }
  13491. class function TObj.AncestorOfObject(Obj: Pointer): Boolean;
  13492. asm
  13493. {$ifdef cpuarm}
  13494. mov r0,#0
  13495. {$else}
  13496. MOV ECX, [EAX]
  13497. MOV EAX, EDX
  13498. JMP @@loop1
  13499. @@loop:
  13500. MOV EAX,[EAX]
  13501. @@loop1:
  13502. TEST EAX,EAX
  13503. JE @@exit
  13504. CMP EAX,ECX
  13505. JNE @@loop
  13506. @@success:
  13507. MOV AL,1
  13508. @@exit:
  13509. {$endif cpuarm}
  13510. end;
  13511. {+}
  13512. {$IFDEF ASM_VERSION}
  13513. {$ELSE ASM_VERSION} //Pascal
  13514. constructor TObj.Create;
  13515. begin
  13516. Init;
  13517. {++}(* inherited; *){--}
  13518. end;
  13519. {$ENDIF ASM_VERSION}
  13520. {$IFDEF OLD_REFCOUNT}
  13521. //[procedure TObj.DoDestroy]
  13522. {$IFDEF ASM_VERSION}
  13523. {$ELSE ASM_VERSION} //Pascal
  13524. procedure TObj.DoDestroy;
  13525. begin
  13526. {$IFDEF OLD_REFCOUNT}
  13527. if fRefCount > 0 then
  13528. begin
  13529. if not LongBool( fRefCount and 1) then
  13530. Dec( fRefCount, 2 );
  13531. RefDec;
  13532. end
  13533. else
  13534. Self.Destroy;
  13535. if fRefCount <> 0 then
  13536. begin
  13537. if not LongBool( fRefCount and 1) then
  13538. Dec( fRefCount );
  13539. end
  13540. else
  13541. Self.Destroy;
  13542. {$ELSE}
  13543. if fRefCount > 0 then
  13544. RefDec
  13545. else
  13546. Self.Destroy;
  13547. {$ENDIF}
  13548. end;
  13549. {$ENDIF ASM_VERSION}
  13550. {$ENDIF OLD_REFCOUNT}
  13551. //[procedure TObj.RefDec]
  13552. {$IFDEF ASM_VERSION}
  13553. {$ELSE ASM_VERSION} //Pascal
  13554. function TObj.RefDec: Integer;
  13555. begin
  13556. Result := 0; // stop Delphi alerting the Warning
  13557. if @ Self = nil then Exit;
  13558. Dec( fRefCount, 2 );
  13559. {$IFDEF OLD_REFCOUNT}
  13560. if (fRefCount < 0) and LongBool(fRefCount and 1) then
  13561. {$ifdef FPC}
  13562. Dispose(PObj(@Self),Destroy);
  13563. {$else}
  13564. Destroy;
  13565. {$endif FPC}
  13566. {$ELSE}
  13567. if fRefCount < 0 then
  13568. {$ifdef FPC}
  13569. Dispose(PObj(@Self),Destroy);
  13570. {$else}
  13571. Destroy;
  13572. {$endif FPC}
  13573. {$ENDIF}
  13574. end;
  13575. {$ENDIF ASM_VERSION}
  13576. //[procedure TObj.RefInc]
  13577. procedure TObj.RefInc;
  13578. begin
  13579. Inc( fRefCount, 2 );
  13580. end;
  13581. {-}
  13582. //[function TObj.VmtAddr]
  13583. function TObj.VmtAddr: Pointer;
  13584. asm
  13585. {$ifdef cpuarm}
  13586. ldr r0,[r0,#-4]
  13587. {$else}
  13588. MOV EAX, [EAX - 4]
  13589. {$endif cpuarm}
  13590. end;
  13591. //[function TObj.InstanceSize]
  13592. function TObj.InstanceSize: Integer;
  13593. asm
  13594. {$ifdef cpuarm}
  13595. ldr r0,[r0]
  13596. ldr r0,[r0,#-4]
  13597. {$else}
  13598. MOV EAX, [EAX]
  13599. MOV EAX,[EAX-4]
  13600. {$endif cpuarm}
  13601. end;
  13602. {+}
  13603. {$IFDEF OLD_FREE}
  13604. //[procedure TObj.Free]
  13605. {$IFDEF ASM_VERSION}
  13606. {$ELSE ASM_VERSION}
  13607. procedure TObj.Free;
  13608. begin
  13609. //if @ Self <> nil then
  13610. RefDec;
  13611. end;
  13612. {$ENDIF ASM_VERSION}
  13613. {$ENDIF OLD_FREE}
  13614. {$UNDEF ASM_LOCAL}
  13615. {$IFDEF ASM_VERSION} {$DEFINE ASM_LOCAL} {$ENDIF}
  13616. {$IFDEF CRASH_DEBUG} {$UNDEF ASM_LOCAL} {$ENDIF}
  13617. {$IFDEF ASM_DEBUG} {$DEFINE ASM_LOCAL} {$ENDIF}
  13618. {$IFDEF ASM_LOCAL}
  13619. {$ELSE ASM_VERSION} //Pascal
  13620. destructor TObj.Destroy;
  13621. begin
  13622. Final;
  13623. {$IFDEF DEBUG_ENDSESSION}
  13624. if EndSession_Initiated then
  13625. LogFileOutput( GetStartDir + 'es_debug.txt',
  13626. 'FINALLED: ' + Int2Hex( DWORD( @ Self )
  13627. {$IFDEF USE_NAMES}
  13628. + ' (name:' + FName + ')'
  13629. {$ENDIF}
  13630. , 8 ) );
  13631. {$ENDIF}
  13632. {$IFDEF USE_NAMES}
  13633. fName := '';
  13634. if fNamedObjList <> nil then Free_And_Nil(fNamedObjList);
  13635. {$ENDIF}
  13636. {-}
  13637. //Dispose( @Self );
  13638. {$IFDEF CRASH_DEBUG}
  13639. FillChar( Pointer( Integer(@Self) + 4 )^, Sizeof( Self ) - 4, #$DD );
  13640. {$ENDIF}
  13641. {$ifndef FPC}
  13642. FreeMem( @ Self );
  13643. {$endif FPC}
  13644. {+} {++}(*
  13645. inherited; *){--}
  13646. end;
  13647. {$ENDIF ASM_VERSION}
  13648. {++}(*
  13649. //[procedure TObj.Init]
  13650. procedure TObj.Init;
  13651. begin
  13652. end;
  13653. *){--}
  13654. //[procedure TObj.Final]
  13655. {$IFDEF ASM_VERSION}
  13656. procedure TObj.Final;
  13657. asm //cmd //opd
  13658. PUSH EBX
  13659. XCHG EBX, EAX
  13660. XOR ECX, ECX
  13661. XCHG ECX, [EBX].fOnDestroy.TMethod.Code
  13662. JECXZ @@freeloop
  13663. MOV EDX, EBX
  13664. MOV EAX, [EDX].fOnDestroy.TMethod.Data
  13665. CALL ECX
  13666. @@freeloop:
  13667. MOV ECX, [EBX].fAutoFree
  13668. JECXZ @@eloop
  13669. MOV EDX, [ECX].TList.fItems
  13670. MOV ECX, [ECX].TList.fCount
  13671. JECXZ @@eloop
  13672. MOV EAX, [EDX+ECX*4-4]
  13673. MOV EDX, [EDX+ECX*4-8]
  13674. PUSH EAX
  13675. PUSH EDX
  13676. MOV EAX, [EBX].fAutoFree
  13677. LEA EDX, [ECX-2]
  13678. XOR ECX, ECX
  13679. MOV CL, 2
  13680. CALL TList.DeleteRange
  13681. POP EDX
  13682. POP EAX
  13683. CALL EDX
  13684. JMP @@freeloop
  13685. @@eloop:
  13686. XOR EAX, EAX
  13687. XCHG [EBX].fAutoFree, EAX
  13688. CALL TObj.RefDec
  13689. @@exit:
  13690. POP EBX
  13691. end;
  13692. {$ELSE ASM_VERSION} //Pascal
  13693. procedure TObj.Final;
  13694. var N: Integer;
  13695. ProcMethod: TMethod;
  13696. {$IFDEF _D2orD3}
  13697. Proc: TObjectMethod;
  13698. {$ELSE}
  13699. Proc: TObjectMethod Absolute ProcMethod;
  13700. {$ENDIF}
  13701. begin
  13702. if Assigned( fOnDestroy ) then
  13703. begin
  13704. fOnDestroy( @Self );
  13705. fOnDestroy := nil;
  13706. end;
  13707. while (fAutoFree <> nil) and (fAutoFree.fCount > 0) do
  13708. begin
  13709. N := fAutoFree.fCount - 2;
  13710. ProcMethod.Code := fAutoFree.fItems[ N ];
  13711. ProcMethod.Data := fAutoFree.fItems[ N + 1 ];
  13712. fAutoFree.DeleteRange( N, 2 );
  13713. {-}
  13714. {$IFDEF _D2orD3}
  13715. Proc := TObjectMethod( ProcMethod );
  13716. {$ENDIF}
  13717. Proc;
  13718. {+}{++}(*
  13719. asm
  13720. MOV EAX, [ProcMethod.Data]
  13721. {$IFDEF F_P}
  13722. PUSH EAX
  13723. {$ENDIF F_P}
  13724. MOV ECX, [ProcMethod.Code]
  13725. CALL ECX
  13726. end {$IFDEF F_P}[ 'EAX', 'EDX', 'ECX' ]{$ENDIF};
  13727. *){--}
  13728. end;
  13729. fAutoFree.Free;
  13730. fAutoFree := nil;
  13731. end;
  13732. {$ENDIF ASM_VERSION}
  13733. //[procedure TObj.Add2AutoFree]
  13734. {$IFDEF ASM_VERSION}
  13735. {$ELSE ASM_VERSION} //Pascal
  13736. procedure TObj.Add2AutoFree(Obj: PObj);
  13737. begin
  13738. if fAutoFree = nil then
  13739. fAutoFree := NewList;
  13740. fAutoFree.Insert( 0, Obj );
  13741. fAutoFree.Insert( 0, Pointer( @TObj.RefDec ) );
  13742. end;
  13743. {$ENDIF ASM_VERSION}
  13744. //[procedure TObj.Add2AutoFreeEx]
  13745. {$IFDEF ASM_VERSION}
  13746. {$ELSE ASM_VERSION} //Pascal
  13747. procedure TObj.Add2AutoFreeEx( Proc: TObjectMethod );
  13748. {$IFDEF F_P}
  13749. var Ptr1, Ptr2: Pointer;
  13750. {$ENDIF F_P}
  13751. begin
  13752. if fAutoFree = nil then
  13753. fAutoFree := NewList;
  13754. {$IFDEF F_P}
  13755. asm
  13756. MOV EAX, [Proc]
  13757. MOV [Ptr1], EAX
  13758. MOV EAX, [Proc+4]
  13759. MOV [Ptr2], EAX
  13760. end [ 'EAX' ];
  13761. fAutoFree.Insert( 0, Ptr2 );
  13762. fAutoFree.Insert( 0, Ptr1 );
  13763. {$ELSE DELPHI}
  13764. fAutoFree.Insert( 0, Pointer( TMethod( Proc ).Data ) );
  13765. fAutoFree.Insert( 0, Pointer( TMethod( Proc ).Code ) );
  13766. {$ENDIF}
  13767. end;
  13768. {$ENDIF ASM_VERSION}
  13769. //[procedure TObj.RemoveFromAutoFree]
  13770. {$IFDEF ASM_VERSION}
  13771. {$ELSE ASM_VERSION}
  13772. procedure TObj.RemoveFromAutoFree(Obj: PObj);
  13773. var i: Integer;
  13774. begin
  13775. if fAutoFree <> nil then
  13776. begin
  13777. i := fAutoFree.IndexOf( Obj );
  13778. if i >= 0 then
  13779. begin
  13780. fAutoFree.DeleteRange( i and not 1, 2 );
  13781. if fAutoFree.Count = 0 then
  13782. Free_And_Nil( fAutoFree );
  13783. end;
  13784. end;
  13785. end;
  13786. {$ENDIF ASM_VERSION}
  13787. procedure TObj.RemoveFromAutoFreeEx(Proc: TObjectMethod);
  13788. var i: Integer;
  13789. begin
  13790. if fAutoFree <> nil then
  13791. begin
  13792. for i := 0 to fAutoFree.Count-2 do
  13793. if (fAutoFree.Items[ i ] = TMethod( Proc ).Data) and
  13794. (fAutoFree.Items[ i+1 ] = TMethod( Proc ).Code) then
  13795. begin
  13796. fAutoFree.Delete( i );
  13797. fAutoFree.Delete( i );
  13798. break;
  13799. end;
  13800. end;
  13801. end;
  13802. {$IFDEF USE_NAMES}
  13803. procedure TObj.SetName( NewOwnerObj: PObj; const NewName: String );
  13804. {$IFDEF UNIQUE_NAMES}
  13805. var i: Integer;
  13806. {$ENDIF}
  13807. begin
  13808. if (FOwnerObj <> nil) then
  13809. if FOwnerObj <> NewOwnerObj then
  13810. begin
  13811. FOwnerObj.fNamedObjList.Remove( @ Self );
  13812. end;
  13813. FOwnerObj := NewOwnerObj;
  13814. if NewOwnerObj = nil then
  13815. begin
  13816. if NewName = '' then
  13817. begin
  13818. fName := '';
  13819. Exit;
  13820. end;
  13821. // çäåñü òîò ñëó÷àé, êîãäà â ïðèëîæåíèè áåç Applet'à óñòàíàâëèâàåòñÿ
  13822. // èìÿ äëÿ ãëàâíîé ôîðìû (íàâåðíîå)
  13823. FOwnerObj := @ Self; // âëàäåëüöåì ñïèñêà èìåíîâàííûõ îáúåêòîâ ñòàíîâèòñÿ
  13824. // ñàì îáúåêò. Äëÿ âûøåîçíà÷åííîãî ñëó÷àÿ - ãëàâíàÿ ôîðìà äåðæèò ñåáÿ è
  13825. // äðóãèå ôîðìû.
  13826. end;
  13827. if FOwnerObj.fNamedObjList = nil then
  13828. FOwnerObj.fNamedObjList := NewList;
  13829. {$IFDEF UNIQUE_NAMES}
  13830. for i := 0 to FOwnerObj.fNamedObjList.Count-1 do
  13831. begin
  13832. if PObj( FOwnerObj.fNamedObjList.Items[ i ] ).FName = NewName then
  13833. begin
  13834. NewName := '';
  13835. break;
  13836. end;
  13837. end;
  13838. {$ENDIF}
  13839. FName := NewName;
  13840. if FName = '' then
  13841. FOwnerObj.fNamedObjList.Remove( @ Self )
  13842. else
  13843. if FOwnerObj.fNamedObjList.IndexOf( @ Self ) < 0 then
  13844. FOwnerObj.fNamedObjList.Add( @ Self );
  13845. end;
  13846. function TObj.FindObj(const ObjName: string): PObj;
  13847. var i: Integer;
  13848. Obj: PObj;
  13849. begin
  13850. if fNamedObjList <> nil then
  13851. for i := 0 to fNamedObjList.Count-1 do
  13852. begin
  13853. Obj := fNamedObjList.Items[ i ];
  13854. if ObjName = Obj.FName then
  13855. begin
  13856. Result := Obj; Exit;
  13857. end;
  13858. end;
  13859. Result := nil;
  13860. end;
  13861. {$ENDIF}
  13862. { TList }
  13863. {$IFDEF ASM_VERSION}
  13864. {$DEFINE ASM_TLIST}
  13865. {$IFDEF TLIST_FAST}
  13866. {$UNDEF ASM_TLIST}
  13867. {$ENDIF}
  13868. {$ENDIF}
  13869. {$IFDEF USE_CONSTRUCTORS}
  13870. procedure TList.Init;
  13871. begin
  13872. {$IFDEF _D2orD3}
  13873. inherited;
  13874. {$ENDIF}
  13875. fAddBy := 4;
  13876. {$IFDEF TLIST_FAST}
  13877. {$IFNDEF DFLT_TLIST_NOUSE_BLOCKS} // for debug only
  13878. fUseBlocks := TRUE;
  13879. {$ENDIF}
  13880. {$ENDIF}
  13881. end;
  13882. //[function NewList]
  13883. function NewList: PList;
  13884. begin
  13885. New( Result, Create );
  13886. //Result.fAddBy := 4;
  13887. end;
  13888. //[END NewList]
  13889. {$ELSE not_USE_CONSTRUCTORS}
  13890. //[function NewList]
  13891. function NewList: PList;
  13892. begin
  13893. {-}
  13894. New( Result, Create );
  13895. {+} {++}(* Result := PList.Create; *){--}
  13896. Result.fAddBy := 4;
  13897. {$IFDEF TLIST_FAST}
  13898. {$IFNDEF DFLT_TLIST_NOUSE_BLOCKS} // for debug only
  13899. Result.fUseBlocks := TRUE;
  13900. {$ENDIF}
  13901. {$ENDIF}
  13902. end;
  13903. //[END NewList]
  13904. {$ENDIF USE_CONSTRUCTORS}
  13905. //[procedure TList.Init]
  13906. {$IFDEF _D4orHigher}
  13907. function NewListInit( const AItems: array of Pointer ): PList;
  13908. var i: Integer;
  13909. begin
  13910. Result := NewList;
  13911. Result.Capacity := Length( AItems );
  13912. for i := 0 to High( AItems ) do
  13913. Result.Add( AItems[ i ] );
  13914. end;
  13915. {$ENDIF}
  13916. //[procedure HelpFastIncNum2Els]
  13917. {$IFDEF ASM_VERSION}
  13918. procedure HelpFastIncNum2Els( DataArray: Pointer; Value, Count: Integer );
  13919. asm
  13920. PUSH ESI
  13921. PUSH EDI
  13922. {$IFDEF F_P}
  13923. MOV ESI, [DataArray]
  13924. MOV EDX, [Value]
  13925. MOV ECX, [Count]
  13926. {$ELSE DELPHI}
  13927. MOV ESI, EAX
  13928. {$ENDIF F_P/DELPHI}
  13929. MOV EDI, ESI
  13930. CLD
  13931. @@1:
  13932. LODSD
  13933. ADD EAX, EDX
  13934. STOSD
  13935. LOOP @@1
  13936. POP EDI
  13937. POP ESI
  13938. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  13939. {$ELSE ASM_VERSION} //Pascal
  13940. procedure HelpFastIncNum2Els( DataArray: Pointer; Value, Count: Integer );
  13941. begin
  13942. while Count > 0 do begin
  13943. Inc(PInteger(DataArray)^, Value);
  13944. Inc(PInteger(DataArray));
  13945. Dec(Count);
  13946. end;
  13947. end;
  13948. {$ENDIF ASM_VERSION}
  13949. //[END HelpFastIncNum2Els]
  13950. //[procedure FastIncNum2Elements]
  13951. procedure FastIncNum2Elements( List: TList; FromIdx, Count, Value: Integer );
  13952. begin
  13953. HelpFastIncNum2Els( @List.fItems[ FromIdx ], Value, Count );
  13954. end;
  13955. {$IFDEF ASM_VERSION}
  13956. {$ELSE ASM_VERSION} //Pascal
  13957. destructor TList.Destroy;
  13958. begin
  13959. Clear;
  13960. inherited;
  13961. end;
  13962. {$ENDIF ASM_VERSION}
  13963. //[procedure TList.Release]
  13964. {$IFDEF ASM_TLIST}
  13965. {$ELSE ASM_VERSION} //Pascal
  13966. procedure TList.Release;
  13967. var I: Integer;
  13968. {$IFDEF TLIST_FAST}
  13969. BlockStart: PDWORD;
  13970. j, CountCurrent: Integer;
  13971. {$ENDIF}
  13972. begin
  13973. if @ Self = nil then Exit;
  13974. {$IFDEF TLIST_FAST}
  13975. if fUseBlocks and Assigned( fBlockList ) then
  13976. begin
  13977. for i := 0 to fBlockList.Count div 2 - 1 do
  13978. begin
  13979. BlockStart := fBlockList.fItems[ i*2 ];
  13980. CountCurrent := Integer( fBlockList.fItems[ i*2+1 ] );
  13981. for j := 0 to CountCurrent-1 do
  13982. begin
  13983. if BlockStart^ <> 0 then
  13984. FreeMem( Pointer( BlockStart^ ) );
  13985. inc( BlockStart );
  13986. end;
  13987. end;
  13988. end
  13989. else
  13990. {$ENDIF}
  13991. for I := 0 to fCount - 1 do
  13992. if fItems[ I ] <> nil then
  13993. FreeMem( fItems[ I ] );
  13994. Free;
  13995. end;
  13996. {$ENDIF ASM_VERSION}
  13997. //[procedure TList.ReleaseObjects]
  13998. procedure TList.ReleaseObjects;
  13999. var I: Integer;
  14000. {$IFDEF TLIST_FAST}
  14001. BlockStart: PDWORD;
  14002. j, CountCurrent: Integer;
  14003. {$ENDIF}
  14004. begin
  14005. if @ Self = nil then Exit;
  14006. {$IFDEF TLIST_FAST}
  14007. if fUseBlocks and Assigned( fBlockList ) then
  14008. begin
  14009. for i := 0 to fBlockList.Count div 2 - 1 do
  14010. begin
  14011. BlockStart := fBlockList.fItems[ i*2 ];
  14012. CountCurrent := Integer( fBlockList.fItems[ i*2+1 ] );
  14013. for j := 0 to CountCurrent-1 do
  14014. begin
  14015. if BlockStart^ <> 0 then
  14016. PObj( Pointer( BlockStart^ ) ).Free;
  14017. inc( BlockStart );
  14018. end;
  14019. end;
  14020. end
  14021. else
  14022. {$ENDIF}
  14023. for I := fCount-1 downto 0 do
  14024. PObj( fItems[ I ] ).Free;
  14025. Free;
  14026. end;
  14027. //[procedure TList.SetCapacity]
  14028. {$IFDEF ASM_VERSION}
  14029. {$ELSE ASM_VERSION} //Pascal
  14030. //var NewItems: PPointerList;
  14031. procedure TList.SetCapacity( Value: Integer );
  14032. begin
  14033. {$IFDEF TLIST_FAST}
  14034. if fUseBlocks and (Assigned( fBlockList ) or (Value > 256)) then
  14035. begin
  14036. fCapacity := Value;
  14037. end
  14038. else
  14039. {$ENDIF}
  14040. begin
  14041. if Value < Count then
  14042. Value := Count;
  14043. if Value = fCapacity then Exit;
  14044. ReallocMem( fItems, Value * Sizeof( Pointer ) );
  14045. fCapacity := Value;
  14046. end;
  14047. end;
  14048. {$ENDIF ASM_VERSION}
  14049. //[procedure TList.Clear]
  14050. {$IFDEF ASM_VERSION}
  14051. {$ELSE ASM_VERSION} //Pascal
  14052. procedure TList.Clear;
  14053. {$IFDEF TLIST_FAST}
  14054. var i: Integer;
  14055. {$ENDIF}
  14056. begin
  14057. if fItems <> nil then
  14058. FreeMem( fItems );
  14059. fItems := nil;
  14060. fCount := 0;
  14061. fCapacity := 0;
  14062. {$IFDEF TLIST_FAST}
  14063. if fBlockList <> nil then
  14064. for i := 0 to fBlockList.Count div 2 - 1 do
  14065. FreeMem(fBlockList.Items[ i*2 ]);
  14066. Free_And_Nil( fBlockList );
  14067. fLastKnownBlockIdx := 0;
  14068. fLastKnownCountBefore := 0;
  14069. {$ENDIF}
  14070. end;
  14071. {$ENDIF ASM_VERSION}
  14072. //[procedure TList.SetAddBy]
  14073. procedure TList.SetAddBy(Value: Integer);
  14074. begin
  14075. if Value < 1 then Value := 1;
  14076. fAddBy := Value;
  14077. end;
  14078. //[procedure TList.Add]
  14079. {$IFDEF ASM_VERSION}
  14080. {$ELSE ASM_VERSION} //Pascal
  14081. procedure TList.Add( Value: Pointer );
  14082. {$IFDEF TLIST_FAST}
  14083. var LastBlockCount: Integer;
  14084. LastBlockStart: Pointer;
  14085. {$ENDIF}
  14086. begin
  14087. {$IFDEF TLIST_FAST}
  14088. if fUseBlocks and ((fCount >= 256) or Assigned( fBlockList )) then
  14089. begin
  14090. if fBlockList = nil then
  14091. begin
  14092. fBlockList := NewList;
  14093. fBlockList.fUseBlocks := FALSE;
  14094. fBlockList.Add( fItems );
  14095. fBlockList.Add( Pointer( fCount ) );
  14096. fItems := nil;
  14097. end;
  14098. if fBlockList.fCount = 0 then
  14099. begin
  14100. fBlockList.Add( nil );
  14101. fBlockList.Add( nil );
  14102. LastBlockCount := 0;
  14103. end
  14104. else
  14105. begin
  14106. LastBlockCount := Integer( fBlockList.fItems[ fBlockList.fCount-1 ] );
  14107. if LastBlockCount >= 256 then
  14108. begin
  14109. fBlockList.Add( nil );
  14110. fBlockList.Add( nil );
  14111. LastBlockCount := 0;
  14112. end;
  14113. end;
  14114. LastBlockStart := fBlockList.Items[ fBlockList.fCount-2 ];
  14115. if LastBlockStart = nil then
  14116. begin
  14117. GetMem( LastBlockStart, 256 * Sizeof( Pointer ) );
  14118. fBlockList.Items[ fBlockList.fCount-2 ] := LastBlockStart;
  14119. end;
  14120. fBlockList.Items[ fBlockList.fCount-1 ] := Pointer( LastBlockCount+1 );
  14121. PDWORD( Integer(LastBlockStart) + Sizeof(Pointer)*LastBlockCount )^ :=
  14122. DWORD( Value );
  14123. end
  14124. else
  14125. {$ENDIF}
  14126. begin
  14127. if fCapacity <= fCount then
  14128. begin
  14129. if fAddBy <= 0 then
  14130. Capacity := fCount + Min( 1000, fCount div 4 + 1 )
  14131. else
  14132. Capacity := fCount + fAddBy;
  14133. end;
  14134. fItems[ fCount ] := Value;
  14135. end;
  14136. Inc( fCount );
  14137. end;
  14138. {$ENDIF ASM_VERSION}
  14139. {$IFDEF _D4orHigher}
  14140. procedure TList.AddItems(const AItems: array of Pointer);
  14141. var i: Integer;
  14142. begin
  14143. Capacity := Count + Length( AItems );
  14144. for i := 0 to High( AItems ) do
  14145. Add( AItems[ i ] );
  14146. end;
  14147. {$ENDIF}
  14148. //[procedure TList.Delete]
  14149. procedure TList.Delete( Idx: Integer );
  14150. begin
  14151. DeleteRange( Idx, 1 );
  14152. end;
  14153. //[procedure TList.DeleteRange]
  14154. {$IFDEF ASM_TLIST}
  14155. {$ELSE ASM_VERSION} //Pascal
  14156. procedure TList.DeleteRange(Idx, Len: Integer);
  14157. {$IFDEF TLIST_FAST}
  14158. var i, DelFromBlock: Integer;
  14159. CountBefore, CountCurrent: Integer;
  14160. BlockStart: Pointer;
  14161. {$ENDIF}
  14162. begin
  14163. if Len <= 0 then Exit;
  14164. if Idx >= Count then Exit;
  14165. Assert( (Idx >= 0), 'TList.DeleteRange: index out of bounds' );
  14166. if DWORD( Idx + Len ) > DWORD( Count ) then
  14167. Len := Count - Idx;
  14168. {$IFDEF TLIST_FAST}
  14169. if fUseBlocks and Assigned( fBlockList ) then
  14170. begin
  14171. CountBefore := 0;
  14172. i := 0;
  14173. if (fLastKnownBlockIdx > 0) and
  14174. (Idx >= fLastKnownCountBefore) then
  14175. begin
  14176. i := fLastKnownBlockIdx;
  14177. CountBefore := fLastKnownCountBefore;
  14178. end;
  14179. while i < fBlockList.fCount div 2 do
  14180. begin
  14181. BlockStart := fBlockList.fItems[ i * 2 ];
  14182. CountCurrent := Integer( fBlockList.fItems[ i * 2 + 1 ] );
  14183. if (Idx >= CountBefore) and (Idx < CountBefore + CountCurrent) then
  14184. begin
  14185. DelFromBlock := CountBefore + CountCurrent - Idx;
  14186. if DelFromBlock > Len then
  14187. DelFromBlock := Len;
  14188. if DelFromBlock < CountCurrent then
  14189. begin
  14190. move( Pointer( Integer( BlockStart ) + (Idx - CountBefore + DelFromBlock) * Sizeof( Pointer ) )^,
  14191. Pointer( Integer( BlockStart ) + (Idx - CountBefore) * Sizeof( Pointer ) )^,
  14192. (CountCurrent - (Idx - CountBefore) - DelFromBlock) * Sizeof( Pointer ) );
  14193. dec( CountCurrent, DelFromBlock );
  14194. fBlockList.fItems[ i * 2 + 1 ] := Pointer( CountCurrent );
  14195. dec( fCount, DelFromBlock );
  14196. dec( Len, DelFromBlock );
  14197. if Len <= 0 then Exit;
  14198. end
  14199. else
  14200. begin // delete entire block
  14201. FreeMem( BlockStart );
  14202. fBlockList.DeleteRange( i * 2, 2 );
  14203. dec( fCount, CountCurrent );
  14204. dec( Len, CountCurrent );
  14205. if Len <= 0 then Exit;
  14206. CountCurrent := 0;
  14207. dec( i );
  14208. end;
  14209. end;
  14210. inc( i );
  14211. inc( CountBefore, CountCurrent );
  14212. end;
  14213. end
  14214. else
  14215. {$ENDIF}
  14216. begin
  14217. Move( fItems[ Idx + Len ], fItems[ Idx ], Sizeof( Pointer ) * (Count - Idx - Len) );
  14218. Dec( fCount, Len );
  14219. end;
  14220. end;
  14221. {$ENDIF ASM_VERSION}
  14222. //[procedure TList.Remove]
  14223. procedure TList.Remove(Value: Pointer);
  14224. var I: Integer;
  14225. begin
  14226. I := IndexOf( Value );
  14227. if I >= 0 then
  14228. Delete( I );
  14229. end;
  14230. function TList.ItemAddress(Idx: Integer): Pointer;
  14231. {$IFDEF TLIST_FAST}
  14232. var i: Integer;
  14233. BlockStart: Pointer;
  14234. CountBefore, CountCurrent: Integer;
  14235. {$ENDIF}
  14236. begin
  14237. {$IFDEF TLIST_FAST}
  14238. if fUseBlocks and Assigned( fBlockList ) then
  14239. begin
  14240. CountBefore := 0;
  14241. i := 0;
  14242. if (fLastKnownBlockIdx > 0) and
  14243. (Idx >= fLastKnownCountBefore) then
  14244. begin
  14245. CountBefore := fLastKnownCountBefore;
  14246. i := fLastKnownBlockIdx;
  14247. end;
  14248. CountCurrent := CountBefore + Integer( fBlockList.fItems[ i*2+1 ] );
  14249. if Idx - CountCurrent > fCount - CountCurrent then
  14250. begin // ïîèñê â îáðàòíîì íàïðàâëåíèè ìîæåò îêàçàòüñÿ áûñòðåå
  14251. CountBefore := fCount;
  14252. i := fBlockList.fCount div 2 - 1;
  14253. while TRUE do
  14254. begin
  14255. BlockStart := fBlockList.fItems[ i * 2 ];
  14256. CountCurrent := Integer( fBlockList.fItems[ i * 2 + 1 ] );
  14257. if (CountBefore - CountCurrent <= Idx) and (Idx < CountBefore) then
  14258. begin
  14259. Result := Pointer( Integer( BlockStart ) +
  14260. (Idx - (CountBefore - CountCurrent))*Sizeof( Pointer ) );
  14261. Exit;
  14262. end;
  14263. dec( CountBefore, CountCurrent );
  14264. dec( i );
  14265. end;
  14266. end;
  14267. while TRUE { i < fBlockList.Count div 2 } do
  14268. begin
  14269. BlockStart := fBlockList.fItems[ i * 2 ];
  14270. CountCurrent := Integer( fBlockList.fItems[ i * 2 + 1 ] );
  14271. if (CountBefore <= Idx) and (Idx < CountBefore + CountCurrent) then
  14272. begin
  14273. Result := Pointer( Integer( BlockStart ) + (Idx - CountBefore) * Sizeof( Pointer ) );
  14274. Exit;
  14275. end;
  14276. inc( CountBefore, CountCurrent );
  14277. inc( i );
  14278. end;
  14279. end
  14280. else
  14281. {$ENDIF}
  14282. Result := Pointer( cardinal( fItems ) + cardinal(Idx) * Sizeof( Pointer ) );
  14283. end;
  14284. //[procedure TList.Put]
  14285. {$IFDEF ASM_VERSION}
  14286. procedure TList.Put( Idx: Integer; Value: Pointer );
  14287. asm
  14288. TEST EDX, EDX
  14289. JL @@exit
  14290. CMP EDX, [EAX].fCount
  14291. JGE @@exit
  14292. PUSH ESI
  14293. MOV ESI, ECX
  14294. {$IFDEF TLIST_FAST}
  14295. CMP [EAX].fUseBlocks, 0
  14296. JZ @@old
  14297. MOV ECX, [EAX].fBlockList
  14298. JECXZ @@old
  14299. PUSH EBX
  14300. PUSH ESI
  14301. PUSH EDI
  14302. PUSH EBP
  14303. XCHG EBX, EAX // EBX == @Self
  14304. XOR ECX, ECX // CountBefore := 0;
  14305. XOR EAX, EAX // i := 0;
  14306. CMP [EBX].fLastKnownBlockIdx, 0
  14307. JLE @@1
  14308. CMP EDX, [EBX].fLastKnownCountBefore
  14309. JL @@1
  14310. MOV ECX, [EBX].fLastKnownCountBefore
  14311. MOV EAX, [EBX].fLastKnownBlockIdx
  14312. @@1:
  14313. MOV ESI, [EBX].fBlockList
  14314. MOV ESI, [ESI].fItems
  14315. MOV EDI, [ESI+EAX*8] // EDI = BlockStart
  14316. MOV ESI, [ESI+EAX*8+4] // ESI = CountCurrent
  14317. CMP ECX, EDX
  14318. JG @@next
  14319. LEA EBP, [ECX+ESI]
  14320. CMP EDX, EBP
  14321. JGE @@next
  14322. MOV [EBX].fLastKnownBlockIdx, EAX
  14323. MOV [EBX].fLastKnownCountBefore, ECX
  14324. SUB EDX, ECX
  14325. LEA EAX, [EDI+EDX*4]
  14326. POP EBP
  14327. POP EDI
  14328. POP ESI
  14329. POP EBX
  14330. MOV [EAX], ESI
  14331. POP ESI
  14332. RET
  14333. @@next:
  14334. ADD ECX, ESI
  14335. INC EAX
  14336. JMP @@1
  14337. @@old:
  14338. {$ENDIF}
  14339. MOV EAX, [EAX].fItems
  14340. MOV [EAX+EDX*4], ESI
  14341. POP ESI
  14342. @@exit:
  14343. end;
  14344. {$ELSE not ASM_VERSION}
  14345. procedure TList.Put( Idx: Integer; Value: Pointer );
  14346. {$IFDEF TLIST_FAST}
  14347. var i: Integer;
  14348. BlockStart: Pointer;
  14349. CountBefore, CountCurrent: Integer;
  14350. {$ENDIF}
  14351. begin
  14352. if Idx < 0 then Exit;
  14353. if Idx >= Count then Exit;
  14354. {$IFDEF TLIST_FAST}
  14355. if fUseBlocks and Assigned( fBlockList ) then
  14356. begin
  14357. CountBefore := 0;
  14358. i := 0;
  14359. if (fLastKnownBlockIdx > 0) and
  14360. (Idx >= fLastKnownCountBefore) then
  14361. begin
  14362. i := fLastKnownBlockIdx;
  14363. CountBefore := fLastKnownCountBefore;
  14364. end;
  14365. while i < fBlockList.fCount div 2 do
  14366. begin
  14367. BlockStart := fBlockList.fItems[ i * 2 ];
  14368. CountCurrent := Integer( fBlockList.fItems[ i * 2 + 1 ] );
  14369. if (CountBefore <= Idx) and (Idx < CountBefore + CountCurrent) then
  14370. begin
  14371. fLastKnownBlockIdx := i;
  14372. fLastKnownCountBefore := CountBefore;
  14373. PDWORD( Integer( BlockStart ) + (Idx - CountBefore) * Sizeof( Pointer ) )^ :=
  14374. DWORD( Value );
  14375. Exit;
  14376. end;
  14377. inc( CountBefore, CountCurrent );
  14378. inc( i );
  14379. end;
  14380. end
  14381. else
  14382. {$ENDIF}
  14383. fItems[ Idx ] := Value;
  14384. end;
  14385. {$ENDIF ASM_VERSION}
  14386. //[function TList.Get]
  14387. {$IFDEF ASM_VERSION}
  14388. function TList.Get( Idx: Integer ): Pointer;
  14389. asm
  14390. TEST EDX, EDX
  14391. JL @@ret_nil
  14392. CMP EDX, [EAX].fCount
  14393. JGE @@ret_nil
  14394. {$IFDEF TLIST_FAST}
  14395. CMP [EAX].fUseBlocks, 0
  14396. JZ @@old
  14397. MOV ECX, [EAX].fBlockList
  14398. JECXZ @@old
  14399. PUSH EBX
  14400. PUSH ESI
  14401. PUSH EDI
  14402. PUSH EBP
  14403. XCHG EBX, EAX // EBX == @Self
  14404. XOR ECX, ECX // CountBefore := 0;
  14405. XOR EAX, EAX // i := 0;
  14406. CMP [EBX].fLastKnownBlockIdx, 0
  14407. JLE @@1
  14408. CMP EDX, [EBX].fLastKnownCountBefore
  14409. JL @@1
  14410. MOV ECX, [EBX].fLastKnownCountBefore
  14411. MOV EAX, [EBX].fLastKnownBlockIdx
  14412. @@1:
  14413. MOV ESI, [EBX].fBlockList
  14414. MOV ESI, [ESI].fItems
  14415. MOV EDI, [ESI+EAX*8] // EDI = BlockStart
  14416. MOV ESI, [ESI+EAX*8+4] // ESI = CountCurrent
  14417. CMP ECX, EDX
  14418. JG @@next
  14419. LEA EBP, [ECX+ESI]
  14420. CMP EDX, EBP
  14421. JGE @@next
  14422. MOV [EBX].fLastKnownBlockIdx, EAX
  14423. MOV [EBX].fLastKnownCountBefore, ECX
  14424. SUB EDX, ECX
  14425. MOV EAX, [EDI+EDX*4]
  14426. POP EBP
  14427. POP EDI
  14428. POP ESI
  14429. POP EBX
  14430. RET
  14431. @@next:
  14432. ADD ECX, ESI
  14433. INC EAX
  14434. JMP @@1
  14435. @@old:
  14436. {$ENDIF}
  14437. MOV EAX, [EAX].fItems
  14438. MOV EAX, [EAX+EDX*4]
  14439. RET
  14440. @@ret_nil:
  14441. XOR EAX, EAX
  14442. end;
  14443. {$ELSE not ASM_VERSION}
  14444. function TList.Get( Idx: Integer ): Pointer;
  14445. {$IFDEF TLIST_FAST}
  14446. var i: Integer;
  14447. BlockStart: Pointer;
  14448. CountBefore, CountCurrent: Integer;
  14449. {$ENDIF}
  14450. begin
  14451. Result := nil;
  14452. if Idx < 0 then Exit;
  14453. if Idx >= fCount then Exit;
  14454. {$IFDEF TLIST_FAST}
  14455. if fUseBlocks and Assigned( fBlockList ) then
  14456. begin
  14457. CountBefore := 0;
  14458. i := 0;
  14459. if (fLastKnownBlockIdx > 0) and
  14460. (Idx >= fLastKnownCountBefore) then
  14461. begin
  14462. i := fLastKnownBlockIdx;
  14463. CountBefore := fLastKnownCountBefore;
  14464. end;
  14465. while {i < fBlockList.fCount div 2} TRUE do
  14466. begin
  14467. BlockStart := fBlockList.fItems[ i * 2 ];
  14468. CountCurrent := Integer( fBlockList.fItems[ i * 2 + 1 ] );
  14469. if (CountBefore <= Idx) and (Idx < CountBefore + CountCurrent) then
  14470. begin
  14471. fLastKnownBlockIdx := i;
  14472. fLastKnownCountBefore := CountBefore;
  14473. Result := Pointer( PDWORD( Integer( BlockStart ) + (Idx - CountBefore) * Sizeof( Pointer ) )^ );
  14474. Exit;
  14475. end;
  14476. inc( CountBefore, CountCurrent );
  14477. inc( i );
  14478. end;
  14479. end
  14480. else
  14481. {$ENDIF}
  14482. Result := fItems[ Idx ];
  14483. end;
  14484. {$ENDIF ASM_VERSION}
  14485. //[function TList.IndexOf]
  14486. {$IFDEF ASM_TLIST}
  14487. {$ELSE ASM_VERSION} //Pascal
  14488. function TList.IndexOf( Value: Pointer ): Integer;
  14489. var I: Integer;
  14490. {$IFDEF TLIST_FAST}
  14491. BlockStart: PDWORD;
  14492. j: Integer;
  14493. CountBefore, CountCurrent: Integer;
  14494. {$ENDIF}
  14495. begin
  14496. {$IFDEF DEBUG}
  14497. TRY
  14498. {$ENDIF}
  14499. Result := -1;
  14500. {$IFDEF TLIST_FAST}
  14501. if fUseBlocks and Assigned( fBlockList ) then
  14502. begin
  14503. CountBefore := 0;
  14504. for I := 0 to fBlockList.fCount div 2 - 1 do
  14505. begin
  14506. BlockStart := fBlockList.fItems[ I * 2 ];
  14507. CountCurrent := Integer( fBlockList.fItems[ I * 2 + 1 ] );
  14508. for j := 0 to CountCurrent-1 do
  14509. begin
  14510. if BlockStart^ = DWORD( Value ) then
  14511. begin
  14512. Result := CountBefore + j;
  14513. Exit;
  14514. end;
  14515. inc( BlockStart );
  14516. end;
  14517. inc( CountBefore, CountCurrent );
  14518. end;
  14519. end
  14520. else
  14521. {$ENDIF}
  14522. begin
  14523. for I := 0 to fCount - 1 do
  14524. begin
  14525. if fItems[ I ] = Value then
  14526. begin
  14527. Result := I;
  14528. break;
  14529. end;
  14530. end;
  14531. end;
  14532. {$IFDEF DEBUG}
  14533. EXCEPT
  14534. asm
  14535. nop
  14536. end;
  14537. END;
  14538. {$ENDIF}
  14539. end;
  14540. {$ENDIF ASM_VERSION}
  14541. //[procedure TList.Insert]
  14542. {$IFDEF ASM_TLIST}
  14543. {$ELSE ASM_VERSION} //Pascal
  14544. procedure TList.Insert(Idx: Integer; Value: Pointer);
  14545. {$IFDEF TLIST_FAST}
  14546. var i: Integer;
  14547. CountBefore, CountCurrent: Integer;
  14548. BlockStart, NewBlock: Pointer;
  14549. {$ENDIF}
  14550. begin
  14551. Assert( (Idx >= 0) and (Idx <= FCount+1), 'List index out of bounds' );
  14552. {$IFDEF TLIST_FAST}
  14553. if fUseBlocks and (Assigned( fBlockList ) or (fCount >= 256)) then
  14554. begin
  14555. if not Assigned( fBlockList ) then
  14556. begin
  14557. fBlockList := NewList;
  14558. fBlockList.fUseBlocks := FALSE;
  14559. fBlockList.Add( fItems );
  14560. fBlockList.Add( Pointer( fCount ) );
  14561. fItems := nil;
  14562. end;
  14563. if fBlockList.fCount = 0 then
  14564. begin
  14565. GetMem( NewBlock, 256 * Sizeof( Pointer ) );
  14566. fBlockList.Add( NewBlock );
  14567. fBlockList.Add( nil );
  14568. end;
  14569. CountBefore := 0;
  14570. i := 0;
  14571. if (fLastKnownBlockIdx > 0) and
  14572. (Idx >= fLastKnownCountBefore) then
  14573. begin
  14574. i := fLastKnownBlockIdx;
  14575. CountBefore := fLastKnownCountBefore;
  14576. end;
  14577. while TRUE {i < fBlockList.fCount div 2} do
  14578. begin
  14579. CountCurrent := Integer( fBlockList.Items[ i * 2 + 1 ] );
  14580. if (Idx >= CountBefore) and
  14581. ((Idx < CountBefore + CountCurrent) or
  14582. (Idx = CountBefore + CountCurrent) and
  14583. (CountCurrent < 256)) then // insert in block i
  14584. begin
  14585. BlockStart := fBlockList.fItems[ i * 2 ];
  14586. if BlockStart = nil then
  14587. begin
  14588. GetMem( BlockStart, 256 * Sizeof( Pointer ) );
  14589. fBlockList.fItems[ i * 2 ] := BlockStart;
  14590. end;
  14591. Idx := Idx - CountBefore;
  14592. if CountCurrent < 256 then
  14593. begin
  14594. if Idx < CountCurrent then
  14595. Move( Pointer( Integer( BlockStart ) + Idx * Sizeof( Pointer ) )^,
  14596. Pointer( Integer( BlockStart ) + (Idx+1) * Sizeof( Pointer ) )^,
  14597. (CountCurrent - Idx) * Sizeof( Pointer ) );
  14598. PDWORD( Integer( BlockStart ) + Idx * Sizeof( Pointer ) )^ :=
  14599. DWORD( Value );
  14600. fBlockList.fItems[ i * 2 + 1 ] := Pointer( CountCurrent + 1 );
  14601. end
  14602. else // new block is created since current block is full 256 items
  14603. begin
  14604. GetMem( NewBlock, 256 * Sizeof( Pointer ) );
  14605. fBlockList.Insert( (i+1)*2, Pointer( 256-Idx ) );
  14606. fBlockList.Insert( (i+1)*2, NewBlock );
  14607. move( Pointer( Integer( BlockStart ) + Idx * Sizeof( Pointer ) )^,
  14608. NewBlock^, (256 - Idx) * Sizeof( Pointer ) );
  14609. PDWORD( Integer( BlockStart ) + Idx * Sizeof( Pointer ) )^ :=
  14610. DWORD( Value );
  14611. fBlockList.fItems[ i * 2 + 1 ] := Pointer( Idx + 1 );
  14612. end;
  14613. fLastKnownBlockIdx := i;
  14614. fLastKnownCountBefore := CountBefore;
  14615. inc( fCount );
  14616. Exit;
  14617. end;
  14618. inc( CountBefore, CountCurrent );
  14619. inc( i );
  14620. if i >= fBlockList.fCount div 2 then
  14621. begin
  14622. fBlockList.Add( nil );
  14623. fBlockList.Add( nil );
  14624. end;
  14625. end;
  14626. end
  14627. else
  14628. {$ENDIF}
  14629. begin
  14630. Add( nil );
  14631. if fCount > Idx then
  14632. Move( FItems[ Idx ], FItems[ Idx + 1 ], (fCount - Idx - 1) * Sizeof( Pointer ) );
  14633. FItems[ Idx ] := Value;
  14634. end;
  14635. end;
  14636. {$ENDIF ASM_VERSION}
  14637. //[procedure TList.MoveItem]
  14638. {$IFDEF ASM_VERSION}
  14639. {$ELSE ASM_VERSION} //Pascal
  14640. procedure TList.MoveItem(OldIdx, NewIdx: Integer);
  14641. var Item: Pointer;
  14642. begin
  14643. if OldIdx = NewIdx then Exit;
  14644. if NewIdx >= Count then Exit;
  14645. Item := Items[ OldIdx ];
  14646. Delete( OldIdx );
  14647. Insert( NewIdx, Item );
  14648. end;
  14649. {$ENDIF ASM_VERSION}
  14650. //[function TList.Last]
  14651. {$IFDEF ASM_VERSION}
  14652. {$ELSE ASM_VERSION} //Pascal
  14653. function TList.Last: Pointer;
  14654. begin
  14655. if Count = 0 then
  14656. Result := nil
  14657. else
  14658. Result := Items[ Count-1 ];
  14659. end;
  14660. {$ENDIF ASM_VERSION}
  14661. //[procedure TList.Swap]
  14662. {$IFDEF ASM_TLIST}
  14663. {$ELSE ASM_VERSION} //Pascal
  14664. procedure TList.Swap(Idx1, Idx2: Integer);
  14665. var Tmp: DWORD;
  14666. AItem1, AItem2: PDWORD;
  14667. begin
  14668. {$IFDEF TLIST_FAST}
  14669. AItem1 := ItemAddress( Idx1 );
  14670. AItem2 := ItemAddress( Idx2 );
  14671. {$ELSE}
  14672. AItem1 := Pointer( cardinal( fItems ) + cardinal(Idx1) * Sizeof( Pointer ) );
  14673. AItem2 := Pointer( cardinal( fItems ) + cardinal(Idx2) * Sizeof( Pointer ) );
  14674. {$ENDIF}
  14675. Tmp := AItem1^;
  14676. AItem1^ := AItem2^;
  14677. AItem2^ := Tmp;
  14678. end;
  14679. {$ENDIF ASM_VERSION}
  14680. //[procedure TList.SetCount]
  14681. procedure TList.SetCount(const Value: Integer);
  14682. begin
  14683. if Value >= Count then exit;
  14684. fCount := Value;
  14685. end;
  14686. //[procedure TList.Assign]
  14687. procedure TList.Assign(SrcList: PList);
  14688. {$IFDEF TLIST_FAST}
  14689. var i, CountCurrent: Integer;
  14690. SrcBlock, DstBlock: Pointer;
  14691. {$ENDIF}
  14692. begin
  14693. Clear;
  14694. if SrcList.fCount > 0 then
  14695. begin
  14696. {$IFDEF TLIST_FAST}
  14697. if SrcList.fUseBlocks and Assigned( SrcList.fBlockList ) then
  14698. begin
  14699. fBlockList := NewList;
  14700. fBlockList.Assign( SrcList.fBlockList );
  14701. for i := 0 to fBlockList.Count div 2 - 1 do
  14702. begin
  14703. SrcBlock := SrcList.fBlockList.fItems[ i*2 ];
  14704. CountCurrent := Integer( fBlockList.fItems[ i*2+1 ] );
  14705. GetMem( DstBlock, 256 * Sizeof( Pointer ) );
  14706. fBlockList.fItems[ i*2 ] := DstBlock;
  14707. move( SrcBlock^, DstBlock^, CountCurrent );
  14708. end;
  14709. end
  14710. else
  14711. {$ENDIF}
  14712. begin
  14713. Capacity := SrcList.fCount;
  14714. Move( SrcList.FItems[ 0 ], FItems[ 0 ], Sizeof( Pointer ) * SrcList.fCount );
  14715. end;
  14716. end;
  14717. fCount := SrcList.fCount;
  14718. end;
  14719. {$IFDEF WIN_GDI}
  14720. { -- Window procedure -- }
  14721. function CallCtlWndProc_1( Ctl: PControl; var Msg: TMsg ): Integer;
  14722. begin
  14723. Result := Ctl.WndProc( Msg );
  14724. end;
  14725. (*
  14726. function WndFunc_asm( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  14727. : Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  14728. const size_TMsg = sizeof( TMsg );
  14729. asm
  14730. ADD ESP, -size_TMsg
  14731. MOV EDX, ESP
  14732. PUSH ESI
  14733. PUSH EDI
  14734. MOV EDI, EDX
  14735. LEA ESI, [W]
  14736. MOVSD
  14737. MOVSD
  14738. MOVSD
  14739. MOVSD
  14740. MOV EDI, EDX
  14741. MOV EAX, [EDI]
  14742. TEST EAX, EAX
  14743. JZ @@self_is_nil
  14744. MOV ECX, [CreatingWindow]
  14745. JECXZ @@get_self_prop
  14746. MOV [ECX].TControl.fHandle, EAX
  14747. PUSH ECX
  14748. PUSH ECX
  14749. {$IFDEF USE_PROP}
  14750. PUSH Offset[ID_SELF]
  14751. PUSH EAX
  14752. CALL SetProp
  14753. {$ELSE}
  14754. PUSH GWL_USERDATA
  14755. PUSH EAX
  14756. CALL SetWindowLong
  14757. {$ENDIF}
  14758. XOR EAX, EAX
  14759. MOV [CreatingWindow], EAX
  14760. POP EAX // EAX = self_
  14761. JMP @@self_got
  14762. @@get_self_prop:
  14763. {$IFDEF USE_PROP}
  14764. PUSH Offset[ID_SELF]
  14765. PUSH EAX
  14766. CALL GetProp
  14767. {$ELSE}
  14768. PUSH GWL_USERDATA
  14769. PUSH EAX
  14770. CALL GetWindowLong
  14771. {$ENDIF}
  14772. TEST EAX, EAX
  14773. JNZ @@self_got
  14774. @@self_is_nil:
  14775. OR EAX, [ Applet ]
  14776. JNZ @@self_got
  14777. POP EDI
  14778. POP ESI
  14779. MOV ESP, EBP
  14780. POP EBP
  14781. JMP DefWindowProc
  14782. @@self_got:
  14783. MOV ESI, EAX
  14784. INC [ESI].TControl.fNestedMsgHandling
  14785. MOV EDX, EDI
  14786. CALL CallCtlWndProc_1
  14787. DEC [ESI].TControl.fNestedMsgHandling
  14788. JG @@1
  14789. CMP [ESI].TControl.fBeginDestroying, 0
  14790. JZ @@1
  14791. CMP [ESI].TObj.fRefCount, 0
  14792. JNZ @@1
  14793. CMP ESI, [Applet]
  14794. JZ @@1
  14795. XCHG EAX, ESI
  14796. CALL TObj.RefDec
  14797. XCHG ESI, EAX
  14798. @@1:
  14799. POP EDI
  14800. POP ESI
  14801. MOV ESP, EBP
  14802. end;
  14803. *)
  14804. {$UNDEF ASM_LOCAL}
  14805. {$IFDEF ASM_noVERSION}
  14806. {$IFNDEF _D2orD3}
  14807. {$DEFINE ASM_LOCAL}
  14808. {$ENDIF}
  14809. {$ENDIF}
  14810. {$IFDEF ASM_LOCAL} //!!//!!
  14811. //[FUNCTION CallCtlWndProc]
  14812. function CallCtlWndProc( Ctl: PControl; var Msg: TMsg ): Integer;
  14813. begin
  14814. Result := Ctl.WndProc( Msg );
  14815. end;
  14816. //[END CallCtlWndProc]
  14817. //[function WndFunc]
  14818. function WndFunc( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  14819. : Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  14820. const size_TMsg = sizeof( TMsg );
  14821. asm
  14822. ADD ESP, -size_TMsg
  14823. MOV EDX, ESP
  14824. PUSH ESI
  14825. PUSH EDI
  14826. MOV EDI, EDX
  14827. LEA ESI, [W]
  14828. MOVSD
  14829. MOVSD
  14830. MOVSD
  14831. MOVSD
  14832. MOV EDI, EDX
  14833. MOV EAX, [EDI]
  14834. TEST EAX, EAX
  14835. JZ @@self_is_nil
  14836. MOV ECX, [CreatingWindow]
  14837. JECXZ @@get_self_prop
  14838. MOV [ECX].TControl.fHandle, EAX
  14839. PUSH ECX
  14840. PUSH ECX
  14841. {$IFDEF USE_PROP}
  14842. PUSH Offset[ID_SELF]
  14843. PUSH EAX
  14844. CALL SetProp
  14845. {$ELSE}
  14846. PUSH GWL_USERDATA
  14847. PUSH EAX
  14848. CALL SetWindowLong
  14849. {$ENDIF}
  14850. XOR EAX, EAX
  14851. MOV [CreatingWindow], EAX
  14852. POP EAX // EAX = self_
  14853. JMP @@self_got
  14854. @@get_self_prop:
  14855. {$IFDEF USE_PROP}
  14856. PUSH Offset[ID_SELF]
  14857. PUSH EAX
  14858. CALL GetProp
  14859. {$ELSE}
  14860. PUSH GWL_USERDATA
  14861. PUSH EAX
  14862. CALL GetWindowLong
  14863. {$ENDIF}
  14864. TEST EAX, EAX
  14865. JNZ @@self_got
  14866. @@self_is_nil:
  14867. OR EAX, [ Applet ]
  14868. JNZ @@self_got
  14869. POP EDI
  14870. POP ESI
  14871. MOV ESP, EBP
  14872. POP EBP
  14873. JMP DefWindowProc
  14874. @@self_got:
  14875. MOV ESI, EAX
  14876. INC [ESI].TControl.fNestedMsgHandling
  14877. MOV EDX, EDI
  14878. CALL CallCtlWndProc
  14879. DEC [ESI].TControl.fNestedMsgHandling
  14880. JA @@1
  14881. CMP [ESI].TControl.fBeginDestroying, 0
  14882. JZ @@1
  14883. CMP [ESI].TObj.fRefCount, 0
  14884. JNZ @@1
  14885. CMP ESI, [Applet]
  14886. JZ @@1
  14887. XCHG EAX, ESI
  14888. CALL TObj.Free
  14889. XCHG ESI, EAX
  14890. @@1:
  14891. POP EDI
  14892. POP ESI
  14893. MOV ESP, EBP
  14894. end;
  14895. {$ELSE ASM_VERSION} //Pascal
  14896. function WndFunc( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  14897. : Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  14898. var M: TMsg;
  14899. self_: PControl;
  14900. begin
  14901. {if (Msg >= $BD33) and (Msg <= $BD33) then
  14902. begin
  14903. Result := WndFunc_asm( W, Msg, wParam, lParam );
  14904. Exit;
  14905. end;}
  14906. {$IFDEF INPACKAGE}
  14907. Log( '->WndFunc ' + Int2Hex( Msg, 4 ) + ' (' + Int2Str( Msg ) + ')' );
  14908. TRY
  14909. {$ENDIF INPACKAGE}
  14910. M.hwnd := W;
  14911. M.message := Msg;
  14912. M.wParam := wParam;
  14913. M.lParam := lParam;
  14914. {$IFDEF DEBUG_ENDSESSION}
  14915. if EndSession_Initiated then
  14916. begin
  14917. LogFileOutput( GetStartDir + 'es_debug.txt',
  14918. 'HWND:' + Int2Str( W ) + ' MSG:$' + Int2Hex( Msg, 4 ) +
  14919. ' WParam: ' + Int2Str( wParam ) + '($' + Int2Hex( wParam, 8 ) + ')' +
  14920. ' LParam: ' + Int2Str( lParam ) + '($' + Int2Hex( lParam, 8 ) + ')' );
  14921. end;
  14922. {$ENDIF}
  14923. self_ := nil;
  14924. if W <> 0 then
  14925. begin
  14926. if CreatingWindow <> nil then
  14927. begin
  14928. {$IFDEF INPACKAGE}
  14929. Log( '//// CreatingWindow <> nil' );
  14930. {$ENDIF INPACKAGE}
  14931. {$IFDEF DEBUG_CREATEWINDOW}
  14932. LogFileOutput( GetStartDir + 'Session.log',
  14933. 'WndFunc: Creating window = ' + Int2Hex( Integer( CreatingWindow ), 4 ) +
  14934. ' hwnd=' + Int2Str( M.hwnd ) +
  14935. ' message=' + Int2Hex( M.message, 4 ) +
  14936. ' wParam=' + Int2Str( M.wParam ) + '=$' + Int2Hex( M.wParam, 4 ) +
  14937. ' lParam=' + Int2Str( M.lParam ) + '=$' + Int2Hex( M.lParam, 4 )
  14938. );
  14939. {$ENDIF DEBUG_CREATEWINDOW}
  14940. self_ := CreatingWindow;
  14941. CreatingWindow.fHandle := W;
  14942. {$IFDEF USE_PROP}
  14943. {$IFDEF INPACKAGE}
  14944. Log( '//// SetProp' );
  14945. {$ENDIF INPACKAGE}
  14946. SetProp( W, ID_SELF, THandle( CreatingWindow ) );
  14947. {$ELSE}
  14948. SetWindowLong( W, GWL_USERDATA, Integer( CreatingWindow ) );
  14949. {$ENDIF}
  14950. CreatingWindow := nil;
  14951. end
  14952. else
  14953. {$IFDEF USE_PROP}
  14954. self_ := Pointer( GetProp( W, ID_SELF ) );
  14955. {$ELSE}
  14956. self_ := Pointer( GetWindowLong( W, GWL_USERDATA ) );
  14957. {$ENDIF}
  14958. end;
  14959. if self_ <> nil then
  14960. begin
  14961. {$IFDEF INPACKAGE}
  14962. Log( '//// self_ <> nil, calling self_.WndProc' );
  14963. {$ENDIF INPACKAGE}
  14964. inc( self_.fNestedMsgHandling );
  14965. Result := self_.WndProc( M );
  14966. dec( self_.fNestedMsgHandling );
  14967. if (self_.RefCount = 0) and (self_.fNestedMsgHandling <= 0) and
  14968. self_.fBeginDestroying and (self_ <> Applet) then
  14969. self_.Free;
  14970. end
  14971. else
  14972. if Assigned( Applet ) then
  14973. Result := Applet.WndProc( M )
  14974. else
  14975. Result := DefWindowProc( W, Msg, wParam, lParam );
  14976. {$IFDEF DEBUG_ENDSESSION}
  14977. if EndSession_Initiated then
  14978. begin
  14979. LogFileOutput( GetStartDir + 'es_debug.txt',
  14980. 'HWND:' + Int2Str( W ) + ' MSG:$' + Int2Hex( Msg, 4 ) +
  14981. ' Result: ' + Int2Str( Result ) + '($' + Int2Hex( Result, 8 ) + ')' );
  14982. end;
  14983. {$ENDIF}
  14984. {$IFDEF INPACKAGE}
  14985. LogOK;
  14986. FINALLY
  14987. Log( '<-WndFunc' );
  14988. END;
  14989. {$ENDIF INPACKAGE}
  14990. end;
  14991. //[END WndFunc]
  14992. {$ENDIF ASM_VERSION}
  14993. {$IFDEF USE_OnIdle}
  14994. var
  14995. IdleHandlers: PList;
  14996. ProcessIdle: procedure ( Sender: PObj ) = DummyObjProc;
  14997. //[procedure ProcessIdleProc]
  14998. procedure ProcessIdleProc( Sender: PObj );
  14999. var
  15000. i: integer;
  15001. m: TMethod;
  15002. begin
  15003. if AppletTerminated then exit; // YS +
  15004. i := 0;
  15005. with IdleHandlers{-}^{+} do
  15006. while i < Count do begin
  15007. m.Code:=Items[i];
  15008. Inc(i);
  15009. m.Data:=Items[i];
  15010. Inc(i);
  15011. TOnEvent(m)(Sender);
  15012. end;
  15013. end;
  15014. //[function FindIdleHandler]
  15015. function FindIdleHandler( const OnIdle: TOnEvent ): integer;
  15016. var
  15017. i: integer;
  15018. begin
  15019. i := 0;
  15020. if not AppletTerminated then //+ {Maxim Pushkar}
  15021. with TMethod(OnIdle), IdleHandlers{-}^{+} do
  15022. while i < Count do begin
  15023. if (Items[i] = Code) and (Items[i + 1] = Data) then
  15024. begin
  15025. Result := i;
  15026. exit;
  15027. end;
  15028. Inc(i, 2);
  15029. end;
  15030. Result := -1;
  15031. end;
  15032. //[END FindIdleHandler]
  15033. //[procedure RegisterIdleHandler]
  15034. procedure RegisterIdleHandler( const OnIdle: TOnEvent );
  15035. begin
  15036. if AppletTerminated then exit;
  15037. if IdleHandlers = nil then begin
  15038. IdleHandlers := NewList;
  15039. if Applet <> nil then
  15040. Applet.Add2AutoFree(IdleHandlers);
  15041. end;
  15042. with TMethod(OnIdle) do
  15043. begin
  15044. IdleHandlers.Add(Code);
  15045. IdleHandlers.Add(Data);
  15046. end;
  15047. ProcessIdle := @ProcessIdleProc;
  15048. end;
  15049. //[procedure UnRegisterIdleHandler]
  15050. procedure UnRegisterIdleHandler( const OnIdle: TOnEvent );
  15051. var
  15052. i: integer;
  15053. begin
  15054. i := FindIdleHandler(OnIdle);
  15055. if i <> -1 then
  15056. with IdleHandlers{-}^{+} do
  15057. begin
  15058. Delete(i);
  15059. Delete(i);
  15060. end;
  15061. end;
  15062. {$ENDIF USE_OnIdle}
  15063. {$IFDEF GDI}
  15064. //[procedure TerminateExecution]
  15065. {$IFDEF ASM_noVERSION}
  15066. procedure TerminateExecution( var AppletWnd: PControl );
  15067. asm
  15068. PUSH EBX
  15069. PUSH ESI
  15070. MOV BX, $0100
  15071. XCHG BX, word ptr [AppletRunning]
  15072. XOR ECX, ECX
  15073. XCHG ECX, [Applet]
  15074. JECXZ @@exit
  15075. PUSH EAX
  15076. XCHG EAX, ECX
  15077. MOV ESI, EAX
  15078. CALL TObj.RefInc
  15079. TEST BH, BH
  15080. JE @@closed
  15081. MOV EAX, ESI
  15082. CALL TControl.ProcessMessages
  15083. PUSH 0
  15084. PUSH 0
  15085. PUSH WM_CLOSE
  15086. PUSH ESI
  15087. CALL TControl.Perform
  15088. @@closed:
  15089. POP EAX
  15090. XOR ECX, ECX
  15091. MOV dword ptr [EAX], ECX
  15092. MOV EAX, ESI
  15093. CALL TObj.Free
  15094. XCHG EAX, ESI
  15095. CALL TObj.RefDec
  15096. @@exit:
  15097. POP ESI
  15098. POP EBX
  15099. end;
  15100. {$ELSE ASM_VERSION}
  15101. procedure TerminateExecution( var AppletWnd: PControl );
  15102. var App: PControl;
  15103. Appalreadyterminated: Boolean;
  15104. begin
  15105. Appalreadyterminated := AppletTerminated;
  15106. AppletTerminated := TRUE;
  15107. AppletRunning := FALSE;
  15108. App := Applet;
  15109. Applet := nil;
  15110. if (App <> nil) {and (App.RefCount >= 0)} then
  15111. begin
  15112. App.RefInc;
  15113. if not Appalreadyterminated then
  15114. begin
  15115. App.ProcessMessages;
  15116. App.Perform( WM_CLOSE, 0, 0 );
  15117. end;
  15118. AppletWnd := nil;
  15119. App.Free;
  15120. App.RefDec;
  15121. end;
  15122. end;
  15123. {$ENDIF ASM_VERSION}
  15124. //[PROCEDURE CallTControlCreateWindow]
  15125. procedure CallTControlCreateWindow( Ctl: PControl );
  15126. begin
  15127. {$IFDEF SAFE_CODE}
  15128. TRY
  15129. if Ctl = nil then Exit;
  15130. Ctl.CreateWindow;
  15131. EXCEPT
  15132. asm
  15133. nop
  15134. end;
  15135. END;
  15136. {$ELSE}
  15137. Ctl.CreateWindow;
  15138. {$ENDIF}
  15139. end;
  15140. //[END CallTControlCreateWindow]
  15141. {$ENDIF GDI}
  15142. {$ENDIF WIN_GDI}
  15143. {$IFDEF GDI}
  15144. //[PROCEDURE Run]
  15145. {$IFDEF ASM_VERSION}
  15146. {$ELSE ASM_VERSION} //Pascal
  15147. procedure Run( var AppletWnd: PControl );
  15148. {$IFDEF PSEUDO_THREADS}
  15149. var n: Integer;
  15150. i: Integer;
  15151. T: PThread;
  15152. u: DWORD;
  15153. M: TMsg;
  15154. {$ENDIF}
  15155. begin
  15156. AppletRunning := True;
  15157. Applet := AppletWnd;
  15158. AppletWnd.CreateWindow; //virtual!!!
  15159. while not AppletTerminated do
  15160. begin
  15161. {$ifdef wince}
  15162. AppletWnd.WaitAndProcessMessages;
  15163. {$else}
  15164. {$IFDEF PSEUDO_THREADS}
  15165. if Assigned( MainThread ) then
  15166. begin
  15167. while not PeekMessage( M, 0, 0, 0, pm_noremove ) do
  15168. begin
  15169. u := GetTickCount;
  15170. n := 0;
  15171. for i := 1 to MainThread.AllThreads.Count-1 do
  15172. begin
  15173. T := MainThread.AllThreads.Items[ i ];
  15174. if not T.Suspended and not T.Terminated and (T.DoNotWakeUntil < u) then
  15175. begin
  15176. inc( n );
  15177. break;
  15178. end;
  15179. end;
  15180. if n = 0 then WaitMessage
  15181. else MainThread.NextThread;
  15182. end;
  15183. end
  15184. else
  15185. WaitMessage;
  15186. {$ELSE}
  15187. WaitMessage;
  15188. {$ENDIF}
  15189. AppletWnd.ProcessMessages;
  15190. {$endif wince}
  15191. {$IFDEF USE_OnIdle}
  15192. ProcessIdle( AppletWnd );
  15193. {$ENDIF}
  15194. end;
  15195. if AppletWnd <> nil then
  15196. TerminateExecution( AppletWnd );
  15197. end;
  15198. //[END Run]
  15199. {$ENDIF ASM_VERSION}
  15200. {$ENDIF GDI}
  15201. {$IFDEF _X_}
  15202. {$IFDEF GTK}
  15203. procedure Run( var AppletWnd: PControl );
  15204. begin
  15205. AppletRunning := True;
  15206. Applet := AppletWnd;
  15207. AppletWnd.VisualizyWindow; // for GTK, show all windows having Visible = TRUE, recursively
  15208. gtk_main( );
  15209. if AppletWnd <> nil then
  15210. //TerminateExecution( AppletWnd );
  15211. Free_And_Nil( AppletWnd );
  15212. end;
  15213. {$ENDIF GTK}
  15214. {$ENDIF _X_}
  15215. {$IFDEF WIN_GDI}
  15216. {$IFDEF GDI}
  15217. //[procedure AppletMinimize]
  15218. procedure AppletMinimize;
  15219. begin
  15220. if Applet = nil then Exit;
  15221. Applet.Perform( WM_SYSCOMMAND, SC_MINIMIZE, 0 );
  15222. end;
  15223. //[procedure AppletHide]
  15224. procedure AppletHide;
  15225. begin
  15226. if Applet = nil then Exit;
  15227. AppletMinimize;
  15228. Applet.Hide;
  15229. end;
  15230. //[procedure AppletRestore]
  15231. procedure AppletRestore;
  15232. begin
  15233. if Applet = nil then Exit;
  15234. Applet.Show;
  15235. Applet.Perform( WM_SYSCOMMAND, SC_RESTORE, 0 );
  15236. end;
  15237. //[function ScreenWidth]
  15238. function ScreenWidth: Integer;
  15239. begin
  15240. Result := GetSystemMetrics( SM_CXSCREEN );
  15241. end;
  15242. //[END ScreenWidth]
  15243. //[function ScreenHeight]
  15244. function ScreenHeight: Integer;
  15245. begin
  15246. Result := GetSystemMetrics( SM_CYSCREEN );
  15247. end;
  15248. //[END ScreenHeight]
  15249. {$ENDIF GDI}
  15250. //[WndProcXXX FORWARD DECLARATIONS]
  15251. {$IFDEF ASM_VERSION}
  15252. function WndProcAppAsm( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15253. {$ELSE}
  15254. function WndProcAppPas( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15255. {$ENDIF ASM_VERSION}
  15256. function WndProcForm( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15257. function WndProcPaint( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15258. function WndProcGradient( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15259. function WndProcGradientEx( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15260. function WndProcLabelEffect( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15261. function WndProcNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15262. function WndProcCommonNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  15263. var fGlobalProcKeybd: function( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean =
  15264. WndProcDummy;
  15265. //[END OF WndProcXXX FORWARD DECLARATIONS]
  15266. { -- Graphics support -- }
  15267. {$ENDIF WIN_GDI}
  15268. //[function _NewGraphicTool]
  15269. function _NewGraphicTool: PGraphicTool;
  15270. begin
  15271. {-}
  15272. New( Result, Create );
  15273. {+}
  15274. {++}(*Result := PGraphicTool.Create;*){--}
  15275. end;
  15276. //[END _NewGraphicTool]
  15277. {$IFDEF WIN_GDI}
  15278. //[FUNCTION SimpleGetCtlBrushHandle]
  15279. {$IFDEF ASM_VERSION}
  15280. {$ELSE ASM_VERSION PAS_VERSION}
  15281. function SimpleGetCtlBrushHandle( Sender: PControl ): HBrush;
  15282. begin
  15283. if (Sender.fParent <> nil) and (Sender.fColor = Sender.fParent.fColor) then
  15284. Result := SimpleGetCtlBrushHandle( Sender.fParent )
  15285. else
  15286. begin
  15287. {$IFDEF GDI}
  15288. if (Sender.fTmpBrush <> 0) and
  15289. (Color2RGB( Sender.fColor ) <> Sender.fTmpBrushColorRGB) then
  15290. begin
  15291. DeleteObject( Sender.fTmpBrush );
  15292. Sender.fTmpBrush := 0;
  15293. end;
  15294. if Sender.fTmpBrush = 0 then
  15295. begin
  15296. Sender.fTmpBrushColorRGB := Color2RGB( Sender.fColor );
  15297. Sender.fTmpBrush := CreateSolidBrush( Sender.fTmpBrushColorRGB );
  15298. end;
  15299. Result := Sender.fTmpBrush;
  15300. {$ELSE} Result := 0;
  15301. {$ENDIF GDI}
  15302. end;
  15303. end;
  15304. {$ENDIF ASM_VERSION}
  15305. //[END SimpleGetCtlBrushHandle]
  15306. //[function NormalGetCtlBrushHandle]
  15307. function NormalGetCtlBrushHandle( Sender: PControl ): HBrush;
  15308. begin
  15309. {$IFDEF GDI}
  15310. if (Sender.fParent <> nil) and (Sender.fParent.fColor <> Sender.fColor) then
  15311. Sender.Brush.fParentGDITool := Sender.fParent.Brush;
  15312. Result := Sender.Brush.Handle;
  15313. {$ELSE} Result := 0;
  15314. {$ENDIF GDI}
  15315. end;
  15316. //[END NormalGetCtlBrushHandle]
  15317. {++}(*
  15318. //[API CreateFontIndirect]
  15319. function CreateFontIndirect(const p1: TLogFont): HFONT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  15320. external gdi32 name 'CreateFontIndirectA';
  15321. *){--}
  15322. //[MakeXXXHandle FORWARD DECLARATIONS]
  15323. function MakeFontHandle( Self_: PGraphicTool ): THandle; forward;
  15324. function MakeBrushHandle( Self_: PGraphicTool ): THandle; forward;
  15325. function MakePenHandle( Self_: PGraphicTool ): THandle; forward;
  15326. function MakeGeometricPenHandle( Self_: PGraphicTool ): THandle; forward;
  15327. //[END OF MakeXXXHandle FORWARD DECLARATIONS]
  15328. {$ENDIF WIN_GDI}
  15329. //[FUNCTION NewBrush]
  15330. {$IFDEF ASM_VERSION}
  15331. {$ELSE ASM_VERSION} //Pascal
  15332. function NewBrush: PGraphicTool;
  15333. begin
  15334. {$IFDEF GDI}
  15335. Global_GetCtlBrushHandle := NormalGetCtlBrushHandle;
  15336. {$ENDIF GDI}
  15337. Result := _NewGraphicTool;
  15338. with Result {-}^{+} do
  15339. begin
  15340. fNewProc := @ NewBrush;
  15341. fType := gttBrush;
  15342. {$IFDEF GDI}
  15343. fMakeHandleProc := @ MakeBrushHandle;
  15344. {$ENDIF GDI}
  15345. Result.fData.Color := {$ifdef wince}clWindow{$else}clBtnFace{$endif};
  15346. Result.fData.Brush.Style := bsSolid;
  15347. end;
  15348. end;
  15349. {$ENDIF ASM_VERSION}
  15350. //[END NewBrush]
  15351. //[FUNCTION NewPen]
  15352. {$IFDEF ASM_VERSION}
  15353. {$ELSE ASM_VERSION} //Pascal
  15354. function NewPen: PGraphicTool;
  15355. begin
  15356. Result := _NewGraphicTool;
  15357. with Result{-}^{+} do
  15358. begin
  15359. fNewProc := @ NewPen;
  15360. fType := gttPen;
  15361. {$IFDEF GDI}
  15362. fMakeHandleProc := @ MakePenHandle;
  15363. {$ENDIF GDI}
  15364. fData.Pen.Mode := pmCopy;
  15365. end;
  15366. end;
  15367. {$ENDIF ASM_VERSION}
  15368. //[END NewPen]
  15369. var ApplyFont2Wnd_Proc: procedure( _Self: PControl ) = nil;
  15370. procedure DoApplyFont2Wnd( _Self: PControl ); forward;
  15371. const size_FontData = sizeof( Integer {fFontHeight} ) + sizeof( Integer {fFontWidth} ) +
  15372. sizeof( TFontPitch ) + sizeof( TFontStyle ) +
  15373. sizeof( Integer {fFontOrientation} ) +
  15374. sizeof( Integer {fFontWeight} ) + sizeof( TFontCharset ) +
  15375. sizeof( TFontQuality );
  15376. //[FUNCTION NewFont]
  15377. {$IFDEF ASM_VERSION}
  15378. {$ELSE ASM_VERSION} //Pascal
  15379. function NewFont: PGraphicTool;
  15380. begin
  15381. ApplyFont2Wnd_Proc := @ DoApplyFont2Wnd;
  15382. Result := _NewGraphicTool;
  15383. with Result {-}^{+} do
  15384. begin
  15385. fNewProc := @ NewFont;
  15386. fType := gttFont;
  15387. {$IFDEF GDI}
  15388. fMakeHandleProc := @ MakeFontHandle;
  15389. fData.Color := DefFontColor;
  15390. Move( DefFont, fData.Font, Sizeof( TGDIFont ) );
  15391. {$ENDIF GDI}
  15392. {$IFDEF GTK}
  15393. fData.Font.Weight := 400;
  15394. {$ENDIF GTK}
  15395. end;
  15396. end;
  15397. {$ENDIF ASM_VERSION}
  15398. //[END NewFont]
  15399. //[function Color2RGB]
  15400. {$IFDEF ASM_VERSION}
  15401. {$ELSE ASM_VERSION}
  15402. function Color2RGB( Color: TColor ): TColor;
  15403. begin
  15404. if Color < 0 then
  15405. Result := GetSysColor(Color and $7FFFFFFF) else
  15406. Result := Color;
  15407. end;
  15408. {$ENDIF ASM_VERSION}
  15409. //[END Color2RGB]
  15410. function RGB2BGR( Color: TColor ): TColor;
  15411. begin
  15412. Result := ((Color shr 16) or (Color shl 16) or Color and $00FF00)
  15413. and $FFFFFF;
  15414. end;
  15415. //[function ColorsMix]
  15416. {$IFDEF ASM_VERSION}
  15417. function ColorsMix( Color1, Color2: TColor ): TColor;
  15418. asm
  15419. PUSH EDX
  15420. CALL Color2Rgb
  15421. XCHG EAX, [ESP]
  15422. CALL Color2Rgb
  15423. POP EDX
  15424. AND EAX, 0FEFEFEh
  15425. AND EDX, 0FEFEFEh
  15426. SHR EAX, 1
  15427. SHR EDX, 1
  15428. ADD EAX, EDX
  15429. end;
  15430. {$ELSE ASM_VERSION} //Pascal
  15431. function ColorsMix( Color1, Color2: TColor ): TColor;
  15432. begin
  15433. Result := ((Color2RGB( Color1 ) and $FEFEFE) shr 1) +
  15434. ((Color2RGB( Color2 ) and $FEFEFE) shr 1);
  15435. end;
  15436. {$ENDIF ASM_VERSION}
  15437. //[END ColorsMix]
  15438. {$IFDEF WIN_GDI}
  15439. //[FUNCTION Color2RGBQuad]
  15440. {$IFDEF ASM_VERSION}
  15441. {$ELSE ASM_VERSION} //Pascal
  15442. function Color2RGBQuad( Color: TColor ): TRGBQuad;
  15443. var C: Integer;
  15444. begin
  15445. C := Color2RGB( Color );
  15446. C := ((C shr 16) and $FF)
  15447. or ((C shl 16) and $FF0000)
  15448. or (C and $FF00);
  15449. Result := TRGBQuad( C );
  15450. end;
  15451. {$ENDIF ASM_VERSION}
  15452. //[END Color2RGBQuad]
  15453. //[FUNCTION Color2Color16]
  15454. {$IFDEF ASM_VERSION}
  15455. {$ELSE ASM_VERSION}
  15456. function Color2Color16( Color: TColor ): WORD;
  15457. begin
  15458. Color := Color2RGB( Color );
  15459. Result := (Color shr 19) and $1F or
  15460. (Color shr 5) and $7E0 or
  15461. (Color shl 8) and $F800;
  15462. end;
  15463. {$ENDIF ASM_VERSION}
  15464. //[END Color2Color16]
  15465. //[FUNCTION Color2Color15]
  15466. function Color2Color15( Color: TColor ): WORD;
  15467. begin
  15468. Color := Color2RGB( Color );
  15469. Result := (Color shr 19) and $1F or
  15470. (Color shr 6) and $3E0 or
  15471. (Color shl 7) and $7C00;
  15472. end;
  15473. //[END Color2Color15]
  15474. {$ENDIF WIN_GDI}
  15475. { TGraphicTool }
  15476. //[function TGraphicTool.Assign]
  15477. {$IFDEF ASM_VERSION}
  15478. {$ELSE ASM_VERSION}
  15479. function TGraphicTool.Assign(Value: PGraphicTool): PGraphicTool;
  15480. var _Self: PGraphicTool;
  15481. begin
  15482. Result := nil;
  15483. if Value = nil then
  15484. begin
  15485. {$IFDEF OLD_REFCOUNT}
  15486. if @Self <> nil then
  15487. DoDestroy;
  15488. {$ELSE}
  15489. Free;
  15490. {$ENDIF}
  15491. Exit;
  15492. end;
  15493. _Self := @Self;
  15494. if _Self = nil then
  15495. _Self := Value.fNewProc();
  15496. Result := _Self;
  15497. if _Self = Value then Exit; // to avoid infinite loop when assigning to itself
  15498. {$IFDEF GDI}
  15499. if _Self.fHandle <> 0 then
  15500. if Value.fHandle = _Self.fHandle then Exit;
  15501. {$ENDIF GDI}
  15502. _Self.Changed; // to destroy handle if allocated and release it from the canvas (if any uses it)
  15503. Assert( Value.fType = _Self.fType, 'Attempt to assign to different GDI tool type' );
  15504. Move( Value.fData, _Self.fData, Sizeof( fData ) );
  15505. _Self.Changed; // to inform owner control, that its tool (font, brush) changed
  15506. end;
  15507. {$ENDIF ASM_VERSION}
  15508. {$IFDEF WIN_GDI}
  15509. //[procedure TGraphicTool.AssignHandle]
  15510. procedure TGraphicTool.AssignHandle(NewHandle: Integer);
  15511. begin
  15512. if fHandle <> 0 then //
  15513. DeleteObject( fHandle ); //
  15514. fHandle := NewHandle;
  15515. GetObject( fHandle, Sizeof( TGDIFont ), @ fData.Font );
  15516. Changed;
  15517. end;
  15518. {$ENDIF WIN_GDI}
  15519. //[procedure TGraphicTool.Changed]
  15520. {$IFDEF ASM_VERSION}
  15521. {$ELSE ASM_VERSION} //Pascal
  15522. procedure TGraphicTool.Changed;
  15523. {$IFDEF GDI} var H: THandle; {$ENDIF GDI}
  15524. begin
  15525. {$IFDEF GDI}
  15526. H := 0;
  15527. if fHandle <> 0 then
  15528. begin
  15529. H := fHandle;
  15530. fHandle := 0;
  15531. end;
  15532. ////////////////////////////////
  15533. if Assigned( fOnChange ) then
  15534. fOnChange( @Self );
  15535. ////////////////////////////////
  15536. if H <> 0 then
  15537. begin
  15538. DeleteObject( H );
  15539. {$IFDEF DEBUG_GDIOBJECTS}
  15540. case fType of
  15541. gttBrush: Dec( BrushCount );
  15542. gttFont: Dec( FontCount );
  15543. gttPen: Dec( PenCount );
  15544. end;
  15545. {$ENDIF}
  15546. end;
  15547. {$ENDIF GDI}
  15548. {$IFDEF GTK}
  15549. if Assigned( fPangoFontDesc ) then
  15550. begin
  15551. pango_font_description_free( fPangoFontDesc );
  15552. fPangoFontDesc := nil;
  15553. end;
  15554. if Assigned( fOnChange ) then
  15555. fOnChange( @Self );
  15556. {$ENDIF GTK}
  15557. end;
  15558. {$ENDIF ASM_VERSION}
  15559. //[destructor TGraphicTool.Destroy]
  15560. {$IFDEF ASM_VERSION}
  15561. {$ELSE ASM_VERSION} //Pascal
  15562. destructor TGraphicTool.Destroy;
  15563. begin
  15564. {$IFDEF GDI}
  15565. case fType of
  15566. gttBrush: if fData.Brush.Bitmap <> 0 then
  15567. DeleteObject( fData.Brush.Bitmap );
  15568. gttPen: if fData.Pen.BrushBitmap <> 0 then
  15569. DeleteObject( fData.Pen.BrushBitmap )
  15570. end;
  15571. if fHandle <> 0 then
  15572. begin
  15573. DeleteObject( fHandle );
  15574. {$IFDEF DEBUG_GDIOBJECTS}
  15575. case fType of
  15576. gttPen: Dec( PenCount );
  15577. gttBrush: Dec( BrushCount );
  15578. gttFont: Dec( FontCount );
  15579. end;
  15580. {$ENDIF}
  15581. //fHandle := 0; Why to do this? It is now destroying!
  15582. end;
  15583. {$ENDIF GDI}
  15584. inherited;
  15585. end;
  15586. {$ENDIF ASM_VERSION}
  15587. {$IFDEF WIN_GDI}
  15588. //[function TGraphicTool.HandleAllocated]
  15589. function TGraphicTool.HandleAllocated: Boolean;
  15590. begin
  15591. Result := fHandle <> 0;
  15592. end;
  15593. //[function TGraphicTool.ReleaseHandle]
  15594. {$IFDEF ASM_VERSION}
  15595. {$ELSE ASM_VERSION PAS_VERSION}
  15596. function TGraphicTool.ReleaseHandle: Integer;
  15597. begin
  15598. Changed;
  15599. Result := fHandle;
  15600. fHandle := 0;
  15601. end;
  15602. {$ENDIF ASM_VERSION}
  15603. {$ENDIF WIN_GDI}
  15604. //[procedure TGraphicTool.SetInt]
  15605. {$IFDEF ASM_VERSION}
  15606. {$ELSE ASM_VERSION} //Pascal
  15607. procedure TGraphicTool.SetInt( const Index: Integer; Value: Integer );
  15608. var Where: PInteger;
  15609. begin
  15610. Where := Pointer( cardinal( @ fData ) + cardinal(Index) );
  15611. if {$ifdef wince}unaligned{$endif}(Where^) = Value then Exit;
  15612. {$ifdef wince}unaligned({$endif}Where^{$ifdef wince}){$endif} := Value;
  15613. Changed;
  15614. end;
  15615. {$ENDIF ASM_VERSION}
  15616. //[function TGraphicTool.GetInt]
  15617. function TGraphicTool.GetInt(const Index: Integer): Integer;
  15618. var Where: PInteger;
  15619. begin
  15620. Where := Pointer( cardinal( @ fData ) + cardinal(Index) );
  15621. Result := Where^;
  15622. end;
  15623. {$IFDEF WIN_GDI}
  15624. {$ENDIF WIN_GDI}
  15625. //[procedure TGraphicTool.SetColor]
  15626. procedure TGraphicTool.SetColor( Value: TColor );
  15627. begin
  15628. SetInt( go_Color, Value );
  15629. fColorRGB := Color2RGB( Value );
  15630. end;
  15631. {$IFDEF WIN_GDI}
  15632. //[function TGraphicTool.IsFontTrueType]
  15633. {$IFDEF ASM_VERSION}
  15634. {$ELSE ASM_VERSION} //Pascal
  15635. {$ifdef wince}
  15636. function TGraphicTool.IsFontTrueType: Boolean;
  15637. begin
  15638. Result:=True;
  15639. end;
  15640. {$else}
  15641. function TGraphicTool.IsFontTrueType: Boolean;
  15642. var OldFont: HFont;
  15643. DC: HDC;
  15644. begin
  15645. Result := False;
  15646. if GetHandle = 0 then Exit;
  15647. DC := GetDC( 0 );
  15648. OldFont := SelectObject( DC, fHandle );
  15649. if GetFontData( DC, 0, 0, nil, 0 ) <> GDI_ERROR then
  15650. Result := True;
  15651. SelectObject( DC, OldFont );
  15652. ReleaseDC( 0, DC );
  15653. end;
  15654. {$endif wince}
  15655. {$ENDIF ASM_VERSION}
  15656. //[function TGraphicTool.GetBrushBitmap]
  15657. function TGraphicTool.GetBrushBitmap: HBitmap;
  15658. begin
  15659. Result := fData.Brush.Bitmap; // for BCB only
  15660. end;
  15661. //[procedure TGraphicTool.SetBrushBitmap]
  15662. procedure TGraphicTool.SetBrushBitmap(const Value: HBitmap);
  15663. begin
  15664. if fData.Brush.Bitmap = Value then Exit;
  15665. if fData.Brush.Bitmap <> 0 then
  15666. begin
  15667. Changed; // !!!
  15668. DeleteObject( fData.Brush.Bitmap );
  15669. end;
  15670. fData.Brush.Bitmap := Value;
  15671. Changed;
  15672. end;
  15673. //[function TGraphicTool.GetBrushStyle]
  15674. function TGraphicTool.GetBrushStyle: TBrushStyle;
  15675. begin
  15676. Result := fData.Brush.Style; // for BCB only
  15677. end;
  15678. {$ENDIF WIN_GDI}
  15679. //[procedure TGraphicTool.SetBrushStyle]
  15680. procedure TGraphicTool.SetBrushStyle(const Value: TBrushStyle);
  15681. begin
  15682. if fData.Brush.Style = Value then Exit;
  15683. fData.Brush.Style := Value;
  15684. Changed;
  15685. end;
  15686. {$IFDEF WIN_GDI}
  15687. //[function TGraphicTool.GetFontCharset]
  15688. function TGraphicTool.GetFontCharset: TFontCharset;
  15689. begin
  15690. Result := fData.Font.CharSet; // for BCB only
  15691. end;
  15692. //[procedure TGraphicTool.SetFontCharset]
  15693. procedure TGraphicTool.SetFontCharset(const Value: TFontCharset);
  15694. begin
  15695. if fData.Font.Charset = Value then Exit;
  15696. fData.Font.Charset := Value;
  15697. Changed;
  15698. end;
  15699. //[function TGraphicTool.GetFontQuality]
  15700. function TGraphicTool.GetFontQuality: TFontQuality;
  15701. begin
  15702. Result := fData.Font.Quality; // for BCB only
  15703. end;
  15704. //[procedure TGraphicTool.SetFontQuality]
  15705. procedure TGraphicTool.SetFontQuality(const Value: TFontQuality);
  15706. begin
  15707. if fData.Font.Quality = Value then Exit;
  15708. fData.Font.Quality := Value;
  15709. Changed;
  15710. end;
  15711. {$ENDIF WIN_GDI}
  15712. //[function TGraphicTool.GetFontName]
  15713. function TGraphicTool.GetFontName: KOLString;
  15714. begin
  15715. Result := fData.Font.Name;
  15716. {$IFDEF GTK}
  15717. if Result = '' then
  15718. Result := 'Sans Serif';
  15719. {$ENDIF GTK}
  15720. end;
  15721. //[procedure TGraphicTool.SetFontName]
  15722. procedure TGraphicTool.SetFontName(const Value: KOLString);
  15723. begin
  15724. if fData.Font.Name = Value then Exit;
  15725. FillChar( fData.Font.Name[ 0 ], LF_FACESIZE, #0 );
  15726. {$IFDEF UNICODE_CTRLS} WStrLCopy {$ELSE} StrLCopy {$ENDIF}
  15727. ( fData.Font.Name, PKOLChar( Value ), LF_FACESIZE );
  15728. Changed;
  15729. end;
  15730. {$IFDEF WIN_GDI}
  15731. //[procedure TextAreaEx]
  15732. {$IFDEF ASM_VERSION}
  15733. {$ELSE ASM_VERSION} //Pascal
  15734. procedure TextAreaEx( Sender: PCanvas; var Sz : TSize; var Pt : TPoint );
  15735. var Orient : Integer;
  15736. Pts : array[ 1..4 ] of TPoint;
  15737. MinX, MinY, I : Integer;
  15738. A : Double;
  15739. begin
  15740. if not Sender.Font.IsFontTrueType then Exit;
  15741. Orient := Sender.Font.FontOrientation;
  15742. Pt.x := 0; Pt.y := 0;
  15743. if Orient = 0 then
  15744. Exit;
  15745. A := Orient / 1800.0 * PI;
  15746. Pts[ 1 ] := Pt;
  15747. Pts[ 2 ].x := Round( Sz.cx * cos( A ) );
  15748. Pts[ 2 ].y := - Round( Sz.cx * sin( A ) );
  15749. Pts[ 4 ].x := - Round( Sz.cy * cos( A + PI / 2 ) );
  15750. Pts[ 4 ].y := Round( Sz.cy * sin( A + PI / 2 ) );
  15751. Pts[ 3 ].x := Pts[ 2 ].x + Pts[ 4 ].x;
  15752. Pts[ 3 ].y := Pts[ 2 ].y + Pts[ 4 ].y;
  15753. MinX := 0; MinY := 0;
  15754. for I := 2 to 4 do
  15755. begin
  15756. if Pts[ I ].x < MinX then
  15757. MinX := Pts[ I ].x;
  15758. if Pts[ I ].y < MinY then
  15759. MinY := Pts[ I ].y;
  15760. end;
  15761. Sz.cx := 0;
  15762. Sz.cy := 0;
  15763. for I := 1 to 4 do
  15764. begin
  15765. Pts[ I ].x := Pts[ I ].x - MinX;
  15766. Pts[ I ].y := Pts[ I ].y - MinY;
  15767. if Pts[ I ].x > Sz.cx then
  15768. Sz.cx := Pts[ I ].x;
  15769. if Pts[ I ].y > Sz.cy then
  15770. Sz.cy := Pts[ I ].y;
  15771. end;
  15772. Pt := Pts[ 1 ];
  15773. end;
  15774. {$ENDIF ASM_VERSION}
  15775. //[function TGraphicTool.GetFontOrientation]
  15776. function TGraphicTool.GetFontOrientation: Integer;
  15777. begin
  15778. Result := fData.Font.Orientation; // for BCB only
  15779. end;
  15780. //[procedure TGraphicTool.SetFontOrientation]
  15781. {$IFDEF ASM_VERSION}
  15782. {$ELSE ASM_VERSION} //Pascal
  15783. procedure TGraphicTool.SetFontOrientation(Value: Integer);
  15784. begin
  15785. GlobalGraphics_UseFontOrient := True;
  15786. GlobalCanvas_OnTextArea := TextAreaEx;
  15787. Value := Value mod 3600; // -3599..+3599
  15788. SetInt( go_FontOrientation, Value );
  15789. SetInt( go_FontEscapement, Value );
  15790. end;
  15791. {$ENDIF ASM_VERSION}
  15792. //[function TGraphicTool.GetFontPitch]
  15793. function TGraphicTool.GetFontPitch: TFontPitch;
  15794. begin
  15795. Result := fData.Font.Pitch; // for BCB only
  15796. end;
  15797. //[procedure TGraphicTool.SetFontPitch]
  15798. procedure TGraphicTool.SetFontPitch(const Value: TFontPitch);
  15799. begin
  15800. if fData.Font.Pitch = Value then Exit;
  15801. fData.Font.Pitch := Value;
  15802. Changed;
  15803. end;
  15804. {$ENDIF WIN_GDI}
  15805. //[function TGraphicTool.GetFontStyle]
  15806. {$IFDEF ASM_VERSION}
  15807. {$ELSE ASM_VERSION} //Pascal
  15808. function TGraphicTool.GetFontStyle: TFontStyle;
  15809. type PFontStyle = ^TFontStyle;
  15810. begin
  15811. Result := [ ];
  15812. if fData.Font.Weight >= 700 then Result := [ fsBold ];
  15813. if fData.Font.Italic then Result := Result + [ fsItalic ];
  15814. if fData.Font.Underline then Result := Result + [ fsUnderline ];
  15815. if fData.Font.StrikeOut then Result := Result + [ fsStrikeOut ];
  15816. end;
  15817. {$ENDIF ASM_VERSION}
  15818. //[procedure TGraphicTool.SetFontStyle]
  15819. {$IFDEF ASM_VERSION}
  15820. {$ELSE ASM_VERSION} //Pascal
  15821. procedure TGraphicTool.SetFontStyle(const Value: TFontStyle);
  15822. begin
  15823. if FontStyle = Value then Exit;
  15824. if fsBold in Value then
  15825. begin
  15826. if fData.Font.Weight < 700 then
  15827. fData.Font.Weight := 700;
  15828. end
  15829. else
  15830. begin
  15831. if fData.Font.Weight >= 700 then
  15832. fData.Font.Weight := 0;
  15833. end;
  15834. fData.Font.Italic := fsItalic in Value;
  15835. fData.Font.Underline := fsUnderline in Value;
  15836. fData.Font.StrikeOut := fsStrikeOut in Value;
  15837. Changed;
  15838. end;
  15839. {$ENDIF ASM_VERSION}
  15840. {$IFDEF WIN_GDI}
  15841. //[function TGraphicTool.GetPenMode]
  15842. function TGraphicTool.GetPenMode: TPenMode;
  15843. begin
  15844. Result := fData.Pen.Mode; // for BCB only
  15845. end;
  15846. //[procedure TGraphicTool.SetPenMode]
  15847. procedure TGraphicTool.SetPenMode(const Value: TPenMode);
  15848. begin
  15849. if fData.Pen.Mode = Value then Exit;
  15850. fData.Pen.Mode := Value;
  15851. Changed;
  15852. end;
  15853. //[function TGraphicTool.GetPenStyle]
  15854. function TGraphicTool.GetPenStyle: TPenStyle;
  15855. begin
  15856. Result := fData.Pen.Style; // for BCB only
  15857. end;
  15858. //[procedure TGraphicTool.SetPenStyle]
  15859. procedure TGraphicTool.SetPenStyle(const Value: TPenStyle);
  15860. begin
  15861. if fData.Pen.Style = Value then Exit;
  15862. fData.Pen.Style := Value;
  15863. Changed;
  15864. end;
  15865. //[function TGraphicTool.GetHandle]
  15866. {$IFDEF ASM_VERSION}
  15867. {$ELSE ASM_VERSION} //Pascal
  15868. function TGraphicTool.GetHandle: THandle;
  15869. begin
  15870. Result := fHandle;
  15871. if Result <> 0 then
  15872. begin
  15873. if Color2RGB( fData.Color ) <> fColorRGB then
  15874. begin
  15875. DeleteObject( ReleaseHandle );
  15876. Result := 0;
  15877. end;
  15878. end;
  15879. if Result = 0 then
  15880. begin
  15881. if Assigned( fParentGDITool ) then
  15882. begin
  15883. if CompareMem( @ fData, @ fParentGDITool.fData, Sizeof( fData ) ) then
  15884. begin
  15885. Result := fParentGDITool.Handle;
  15886. Exit;
  15887. end;
  15888. end;
  15889. fColorRGB := Color2RGB( fData.Color );
  15890. fMakeHandleProc( @Self );
  15891. Result := fHandle;
  15892. end;
  15893. end;
  15894. {$ENDIF ASM_VERSION}
  15895. //[FUNCTION MakeBrushHandle]
  15896. {$IFDEF ASM_VERSION}
  15897. {$ELSE ASM_VERSION} //Pascal
  15898. function MakeBrushHandle( Self_: PGraphicTool ): THandle;
  15899. {$ifndef wince}
  15900. var
  15901. LogBrush: TLogBrush;
  15902. {$endif wince}
  15903. begin
  15904. if Self_.fHandle = 0 then
  15905. begin
  15906. {$ifdef wince}
  15907. Self_.fHandle := CreateSolidBrush(Color2RGB( Self_.fData.Color ));
  15908. {$else}
  15909. LogBrush.lbColor := Color2RGB( Self_.fData.Color );
  15910. if Self_.fData.Brush.Bitmap <> 0 then
  15911. begin
  15912. LogBrush.lbStyle := BS_PATTERN;
  15913. LogBrush.lbHatch := Self_.fData.Brush.Bitmap;
  15914. end
  15915. else
  15916. begin
  15917. LogBrush.lbHatch := 0;
  15918. case Self_.fData.Brush.Style of
  15919. bsSolid: LogBrush.lbStyle := BS_SOLID;
  15920. bsClear: LogBrush.lbStyle := BS_NULL;
  15921. else
  15922. LogBrush.lbStyle := BS_HATCHED;
  15923. LogBrush.lbHatch := Ord( Self_.fData.Brush.Style ) - Ord( bsHorizontal );
  15924. LogBrush.lbColor := Color2RGB( Self_.fData.Brush.LineColor );
  15925. end;
  15926. end;
  15927. Self_.fHandle := CreateBrushIndirect(LogBrush);
  15928. {$endif wince}
  15929. {$IFDEF DEBUG_GDIOBJECTS}
  15930. if Self_.fHandle <> 0 then
  15931. Inc( BrushCount )
  15932. else
  15933. ShowMessage( 'Could not create brush, error ' + Int2Str( GetLastError ) +
  15934. ': ' + SysErrorMessage( GetLastError ) );
  15935. {$ENDIF}
  15936. end;
  15937. Result := Self_.fHandle;
  15938. end;
  15939. {$ENDIF ASM_VERSION}
  15940. //[END MakeBrushHandle]
  15941. {$UNDEF ASM_LOCAL}
  15942. {$IFNDEF UNICODE_CTRLS}
  15943. {$IFDEF ASM_VERSION}
  15944. {$IFNDEF AUTO_REPLACE_CLEARTYPE}
  15945. {$DEFINE ASM_LOCAL}
  15946. {$ENDIF AUTO_REPLACE_CLEARTYPE}
  15947. {$ENDIF ASM_VERSION}
  15948. {$ENDIF}
  15949. //[FUNCTION MakeFontHandle]
  15950. {$IFDEF ASM_LOCAL}
  15951. {$ELSE ASM_VERSION} //Pascal
  15952. function MakeFontHandle( Self_: PGraphicTool ): THandle;
  15953. {$IFDEF AUTO_REPLACE_CLEARTYPE}
  15954. var LF: TLogFont;
  15955. {$ENDIF}
  15956. begin
  15957. with Self_{-}^{+} do
  15958. begin
  15959. if fHandle = 0 then
  15960. begin
  15961. {$IFDEF AUTO_REPLACE_CLEARTYPE}
  15962. Move( fData.Font, LF, Sizeof( LF ) );
  15963. if WinVer < wvXP then
  15964. begin
  15965. if LF.lfQuality > ANTIALIASED_QUALITY then
  15966. LF.lfQuality := ANTIALIASED_QUALITY;
  15967. end;
  15968. fHandle := CreateFontIndirect( LF );
  15969. {$ELSE}
  15970. fHandle := CreateFontIndirect( PLogFont( @ fData.Font )^ );
  15971. {$ENDIF}
  15972. {$IFDEF DEBUG_GDIOBJECTS}
  15973. Inc( FontCount );
  15974. {$ENDIF}
  15975. end;
  15976. Result := fHandle;
  15977. end;
  15978. end;
  15979. {$ENDIF ASM_VERSION}
  15980. //[END MakeFontHandle]
  15981. //[FUNCTION MakePenHandle]
  15982. {$IFDEF ASM_VERSION}
  15983. {$ELSE ASM_VERSION} //Pascal
  15984. function MakePenHandle( Self_: PGraphicTool ): THandle;
  15985. var
  15986. LogPen: TLogPen;
  15987. begin
  15988. with Self_{-}^{+} do
  15989. begin
  15990. //GlobalGraphics_OnObjectCreating( @Self );
  15991. if fHandle = 0 then
  15992. with LogPen do
  15993. begin
  15994. lopnStyle := Byte( fData.Pen.Style );
  15995. lopnWidth.X := fData.Pen.Width;
  15996. lopnColor := Color2RGB( fData.Color );
  15997. fHandle := CreatePenIndirect( LogPen );
  15998. {$IFDEF DEBUG_GDIOBJECTS}
  15999. Inc( PenCount );
  16000. {$ENDIF}
  16001. end;
  16002. //GlobalGraphics_OnObjectCreated( @Self );
  16003. Result := fHandle;
  16004. end;
  16005. end;
  16006. {$ENDIF ASM_VERSION}
  16007. //[END MakePenHandle]
  16008. //+
  16009. //[function GetGeometricPen]
  16010. function TGraphicTool.GetGeometricPen: Boolean;
  16011. begin
  16012. Result := fData.Pen.Geometric; // for BCB only
  16013. end;
  16014. //[procedure TGraphicTool.SetGeometricPen]
  16015. procedure TGraphicTool.SetGeometricPen(const Value: Boolean);
  16016. begin
  16017. if fData.Pen.Geometric = Value then Exit;
  16018. fData.Pen.Geometric := Value;
  16019. fMakeHandleProc := MakeGeometricPenHandle;
  16020. Changed;
  16021. end;
  16022. //[function TGraphicTool.GetPenEndCap]
  16023. function TGraphicTool.GetPenEndCap: TPenEndCap;
  16024. begin
  16025. Result := fData.Pen.EndCap; // for BCB only
  16026. end;
  16027. //[procedure TGraphicTool.SetPenEndCap]
  16028. procedure TGraphicTool.SetPenEndCap(const Value: TPenEndCap);
  16029. begin
  16030. if fData.Pen.EndCap = Value then Exit;
  16031. fData.Pen.EndCap := Value;
  16032. Changed;
  16033. end;
  16034. //[function TGraphicTool.GetPenJoin]
  16035. function TGraphicTool.GetPenJoin: TPenJoin;
  16036. begin
  16037. Result := fData.Pen.Join; // for BCB only
  16038. end;
  16039. //[procedure TGraphicTool.SetPenJoin]
  16040. procedure TGraphicTool.SetPenJoin(const Value: TPenJoin);
  16041. begin
  16042. if fData.Pen.Join = Value then Exit;
  16043. fData.Pen.Join := Value;
  16044. Changed;
  16045. end;
  16046. //[FUNCTION MakeGeometricPenHandle]
  16047. {$IFDEF ASM_VERSION}
  16048. {$ELSE ASM_VERSION} //Pascal
  16049. function MakeGeometricPenHandle( Self_: PGraphicTool ): THandle;
  16050. {$ifndef wince}
  16051. const
  16052. PenEndCapStyles: array[ TPenEndCap ] of Word =
  16053. (PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT);
  16054. PenJoinStyles: array[ TPenJoin ] of Word =
  16055. (PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER );
  16056. var
  16057. LogBrush: TLogBrush;
  16058. {$endif wince}
  16059. begin
  16060. if Self_.fHandle = 0 then
  16061. {$ifdef wince}
  16062. Self_.fHandle := CreatePen(Byte( Self_.fData.Pen.Style ), Self_.fData.Pen.Width, Color2RGB( Self_.fData.Color ));
  16063. {$else}
  16064. with Self_{-}^{+}, LogBrush do
  16065. begin
  16066. lbColor := Color2RGB( fData.Color );
  16067. lbHatch := 0;
  16068. if fData.Pen.BrushBitmap <> 0 then
  16069. begin
  16070. lbStyle := BS_PATTERN;
  16071. lbHatch := fData.Pen.BrushBitmap;
  16072. end
  16073. else
  16074. case fData.Pen.BrushStyle of
  16075. bsSolid: lbStyle := BS_SOLID;
  16076. bsClear: lbStyle := BS_NULL;
  16077. else begin
  16078. lbStyle := BS_HATCHED;
  16079. case fData.Pen.BrushStyle of
  16080. bsHorizontal: lbHatch := HS_HORIZONTAL;
  16081. bsVertical: lbHatch := HS_VERTICAL;
  16082. bsFDiagonal: lbHatch := HS_FDIAGONAL;
  16083. bsBDiagonal: lbHatch := HS_BDIAGONAL;
  16084. bsCross: lbHatch := HS_CROSS;
  16085. bsDiagCross: lbHatch := HS_DIAGCROSS;
  16086. end;
  16087. end;
  16088. end;
  16089. Self_.fHandle := ExtCreatePen( PS_GEOMETRIC or Byte( Self_.fData.Pen.Style ) or
  16090. PenEndCapStyles[ Self_.fData.Pen.EndCap ] or
  16091. PenJoinStyles[ Self_.fData.Pen.Join ],
  16092. Self_.fData.Pen.Width, LogBrush, 0, nil );
  16093. {Assert( Self_.fHandle <> 0, 'Error ' + Int2Str( GetLastError ) +
  16094. ': ' + SysErrorMessage( GetLastError ) );}
  16095. end;
  16096. {$endif wince}
  16097. {$IFDEF DEBUG_GDIOBJECTS}
  16098. Inc( PenCount );
  16099. {$ENDIF}
  16100. Result := Self_.fHandle;
  16101. end;
  16102. {$ENDIF ASM_VERSION}
  16103. //[END MakeGeometricPenHandle]
  16104. {$ENDIF WIN_GDI}
  16105. //[function TGraphicTool.GetFontWeight]
  16106. function TGraphicTool.GetFontWeight: Integer;
  16107. begin
  16108. Result := fData.Font.Weight; // for BCB only
  16109. end;
  16110. //[procedure TGraphicTool.SetFontWeight]
  16111. procedure TGraphicTool.SetFontWeight(const Value: Integer);
  16112. begin
  16113. if fData.Font.Weight = Value then Exit;
  16114. fData.Font.Weight := Value;
  16115. Changed;
  16116. end;
  16117. {$IFDEF WIN_GDI}
  16118. //[procedure TGraphicTool.SetLogFontStruct]
  16119. procedure TGraphicTool.SetLogFontStruct(const Value: TLogFont);
  16120. begin
  16121. if CompareMem(@fData.Font, @Value, SizeOf(TLogFont)) then Exit;
  16122. Move(Value, fData.Font, SizeOF(TLogFont));
  16123. Changed;
  16124. end;
  16125. //[function TGraphicTool.GetLogFontStruct]
  16126. function TGraphicTool.GetLogFontStruct: TLogFont;
  16127. begin
  16128. Move(fData.Font, Result, SizeOf(TLogFont));
  16129. end;
  16130. {$ENDIF WIN_GDI}
  16131. {$IFDEF _X_}
  16132. {$IFDEF GTK}
  16133. function TGraphicTool.GetPangoFontDesc: PPangoFontDescription;
  16134. var s: String;
  16135. i: Integer;
  16136. function IfThen( cond: Boolean; const s: String ): String;
  16137. begin
  16138. Result := '';
  16139. if cond then Result := s;
  16140. end;
  16141. {const Weights: array[0..9] of String = ( 'Ultralight',
  16142. 'Ultralight', 'Ultralight',
  16143. 'Light', 'Normal', 'Normal', 'Normal',
  16144. 'Bold', 'Ultrabold', 'Heavy' );}
  16145. begin
  16146. if not Assigned( fPangoFontDesc ) then
  16147. begin
  16148. s := FontName; { + ' ' +
  16149. IfThen( FontWeight <> 400, Weights[ FontWeight div 100 ] + ' ' ) +
  16150. IfThen( fsItalic in FontStyle, 'Italic ' ) +
  16151. Int2Str( FontHeight )};
  16152. fPangoFontDesc := pango_font_description_from_string( PChar( s ) );
  16153. i := FontHeight;
  16154. if i > 0 then
  16155. pango_font_description_set_absolute_size( fPangoFontDesc, i * PANGO_SCALE );
  16156. //i := pango_font_description_get_size( fPangoFontDesc );
  16157. i := PANGO_STYLE_NORMAL;
  16158. if fsItalic in FontStyle then i := PANGO_STYLE_ITALIC;
  16159. pango_font_description_set_style( fPangoFontDesc, i );
  16160. pango_font_description_set_weight( fPangoFontDesc, FontWeight );
  16161. end;
  16162. Result := fPangoFontDesc;
  16163. end;
  16164. function Color2GDKColor( Color: TColor ): TGdkColor;
  16165. begin
  16166. Color := Color2RGB( Color );
  16167. Result.pixel := 0;
  16168. Result.red := (Color and $FF) shl 8;
  16169. Result.green := Color and $FF00;
  16170. Result.blue := (Color shr 8) and $FF00;
  16171. end;
  16172. {$ENDIF GTK}
  16173. {$ENDIF _X_}
  16174. {$IFDEF WIN_GDI}
  16175. { TCanvas }
  16176. type
  16177. TStock = {$ifndef wince}packed{$endif} Record
  16178. StockPen: HPEN;
  16179. StockBrush: HBRUSH;
  16180. StockFont: HFONT;
  16181. end;
  16182. var
  16183. Stock: TStock;
  16184. //[destructor TCanvas.Destroy]
  16185. destructor TCanvas.Destroy;
  16186. begin
  16187. Handle := 0;
  16188. fPen.Free;
  16189. fBrush.Free;
  16190. fFont.Free;
  16191. inherited;
  16192. end;
  16193. //[function TCanvas.Assign]
  16194. {$IFDEF ASM_VERSION}
  16195. {$ELSE ASM_VERSION} //Pascal
  16196. function TCanvas.Assign(SrcCanvas: PCanvas): Boolean;
  16197. begin
  16198. fFont := fFont.Assign( SrcCanvas.fFont );
  16199. fBrush := fBrush.Assign( SrcCanvas.fBrush );
  16200. fPen := fPen.Assign( SrcCanvas.fPen );
  16201. AssignChangeEvents;
  16202. Result := (fFont <> nil) or (fBrush <> nil) or (fPen <> nil);
  16203. if (SrcCanvas.PenPos.x <> PenPos.x) or (SrcCanvas.PenPos.y <> PenPos.y) then
  16204. begin
  16205. Result := True;
  16206. PenPos := SrcCanvas.PenPos;
  16207. end;
  16208. if SrcCanvas.ModeCopy <> ModeCopy then
  16209. begin
  16210. Result := True;
  16211. ModeCopy := SrcCanvas.ModeCopy;
  16212. end;
  16213. end;
  16214. {$ENDIF ASM_VERSION}
  16215. //[procedure TCanvas.CreateBrush]
  16216. {$IFDEF ASM_VERSION}
  16217. {$ELSE ASM_VERSION} //Pascal
  16218. procedure TCanvas.CreateBrush;
  16219. begin
  16220. if assigned( fBrush ) then
  16221. begin
  16222. SelectObject( GetHandle, fBrush.Handle );
  16223. AssignChangeEvents;
  16224. if fBrush.fData.Brush.Style = bsSolid then
  16225. begin
  16226. SetBkColor( fHandle, Color2RGB( fBrush.fData.Color ) );
  16227. SetBkMode( fHandle, OPAQUE );
  16228. end
  16229. else
  16230. begin
  16231. { Win95 doesn't draw brush hatches if bkcolor = brush color }
  16232. { Since bkmode is transparent, nothing should use bkcolor anyway }
  16233. SetBkColor( fHandle, not Color2RGB( fBrush.fData.Color ) );
  16234. SetBkMode( fHandle, TRANSPARENT );
  16235. end;
  16236. end
  16237. else
  16238. if Assigned( fOwnerControl ) then
  16239. begin
  16240. SetBkColor( GetHandle, Color2RGB( PControl( fOwnerControl ).fColor ) );
  16241. SetBkMode( fHandle, OPAQUE );
  16242. end;
  16243. end;
  16244. {$ENDIF ASM_VERSION}
  16245. //[procedure TCanvas.CreateFont]
  16246. {$IFDEF ASM_VERSION}
  16247. {$ELSE ASM_VERSION} //Pascal
  16248. procedure TCanvas.CreateFont;
  16249. begin
  16250. if assigned( fFont ) then
  16251. begin
  16252. SelectObject( GetHandle, fFont.Handle );
  16253. SetTextColor( fHandle, Color2RGB( fFont.fData.Color ) );
  16254. AssignChangeEvents;
  16255. end
  16256. else
  16257. if Assigned( fOwnerControl ) then
  16258. begin
  16259. SetTextColor( fHandle, Color2RGB( PControl( fOwnerControl ).fTextColor ) );
  16260. end;
  16261. end;
  16262. {$ENDIF ASM_VERSION}
  16263. //[procedure TCanvas.CreatePen]
  16264. {$IFDEF ASM_VERSION}
  16265. {$ELSE ASM_VERSION} //Pascal
  16266. procedure TCanvas.CreatePen;
  16267. begin
  16268. if assigned( fPen ) then
  16269. begin
  16270. SelectObject( GetHandle, fPen.Handle );
  16271. SetROP2( fHandle, Ord( fPen.fData.Pen.Mode ) + 1 );
  16272. AssignChangeEvents;
  16273. end;
  16274. end;
  16275. {$ENDIF ASM_VERSION}
  16276. //[function TCanvas.GetPixels]
  16277. function TCanvas.GetPixels(X, Y: Integer): TColor;
  16278. begin
  16279. RequiredState( HandleValid );
  16280. Result := Windows.GetPixel(FHandle, X, Y);
  16281. end;
  16282. //[procedure TCanvas.SetPixels]
  16283. procedure TCanvas.SetPixels(X, Y: Integer; const Value: TColor);
  16284. begin
  16285. Changing;
  16286. RequiredState( HandleValid );
  16287. Windows.SetPixel(FHandle, X, Y, Color2RGB( Value ));
  16288. end;
  16289. {$ENDIF WIN_GDI}
  16290. {$IFDEF _X_}
  16291. {$IFDEF GTK}
  16292. procedure TCanvas.SaveState;
  16293. begin
  16294. gdk_gc_get_values( fHandle, @ fSavedState );
  16295. end;
  16296. procedure TCanvas.RestoreState;
  16297. var mask: DWORD;
  16298. begin
  16299. mask := $1FFFF;
  16300. if fSavedState.font = nil then mask := mask and not GDK_GC_FONT;
  16301. if fSavedState.stipple = nil then mask := mask and not GDK_GC_STIPPLE;
  16302. gdk_gc_set_values( fHandle, @ fSavedState, mask );
  16303. DeselectHandles;
  16304. end;
  16305. {$ENDIF GTK}
  16306. {$ENDIF _X_}
  16307. //[procedure TCanvas.DeselectHandles]
  16308. {$IFDEF GDI}
  16309. {$IFDEF ASM_VERSION}
  16310. {$ELSE ASM_VERSION} //Pascal
  16311. procedure TCanvas.DeselectHandles;
  16312. begin
  16313. if (fHandle <> 0) and
  16314. LongBool(fState and (PenValid or BrushValid or FontValid)) then
  16315. with Stock do
  16316. begin
  16317. if StockPen = 0 then
  16318. begin
  16319. StockPen := GetStockObject(BLACK_PEN);
  16320. StockBrush := GetStockObject(HOLLOW_BRUSH);
  16321. StockFont := GetStockObject(SYSTEM_FONT);
  16322. end;
  16323. SelectObject( fHandle, StockPen );
  16324. SelectObject( fHandle, StockBrush );
  16325. SelectObject( fHandle, StockFont );
  16326. fState := fState and not( PenValid or BrushValid or FontValid );
  16327. end;
  16328. end;
  16329. {$ENDIF ASM_VERSION}
  16330. {$ENDIF GDI}
  16331. {$IFDEF _X_}
  16332. {$IFDEF GTK}
  16333. procedure TCanvas.DeselectHandles;
  16334. begin
  16335. {$IFDEF GDI}
  16336. Free_And_Nil( fBrush );
  16337. Free_And_Nil( fPen );
  16338. Free_And_Nil( fFont );
  16339. {$ENDIF GDI}
  16340. if Assigned( fFont ) and Assigned( fFont.fPangoFontDesc ) then
  16341. begin
  16342. pango_font_description_free( fFont.fPangoFontDesc );
  16343. fFont.fPangoFontDesc := nil;
  16344. end;
  16345. fState := fState and not( PenValid or BrushValid or FontValid );
  16346. end;
  16347. {$ENDIF GTK}
  16348. {$ENDIF _X_}
  16349. {$IFDEF WIN_GDI}
  16350. //[function TCanvas.RequiredState]
  16351. {$IFDEF ASM_VERSION}
  16352. {$ELSE ASM_VERSION} //Pascal
  16353. function TCanvas.RequiredState(ReqState: DWORD): HDC; {$ifdef wince}cdecl{$else}stdcall{$endif};
  16354. var
  16355. NeededState: Byte;
  16356. begin
  16357. if Boolean(ReqState and ChangingCanvas) then
  16358. Changing;
  16359. ReqState := ReqState and 15;
  16360. NeededState := Byte( ReqState ) and not fState;
  16361. Result := 0;
  16362. if Boolean(ReqState and HandleValid) then
  16363. begin
  16364. if GetHandle = 0 then Exit; // Important!
  16365. end;
  16366. if NeededState <> 0 then
  16367. begin
  16368. if Boolean( NeededState and FontValid ) then
  16369. CreateFont;
  16370. if Boolean( NeededState and PenValid ) then
  16371. begin
  16372. CreatePen;
  16373. if assigned( fPen ) then
  16374. if fPen.fData.Pen.Style in [psDash, psDot, psDashDot, psDashDotDot] then
  16375. NeededState := NeededState or BrushValid;
  16376. end;
  16377. if Boolean( NeededState and BrushValid ) then
  16378. CreateBrush;
  16379. fState := fState or NeededState;
  16380. end;
  16381. Result := fHandle;
  16382. end;
  16383. {$ENDIF ASM_VERSION}
  16384. {$ENDIF WIN_GDI}
  16385. (*function TCanvas.RequiredState(ReqState: DWORD): HDC; {$ifdef wince}cdecl{$else}stdcall{$endif}; //todo:
  16386. var NeededState: Byte;
  16387. //var c: TGdkColor;
  16388. begin
  16389. {if Boolean(ReqState and ChangingCanvas) then
  16390. Changing;}
  16391. ReqState := ReqState and (BrushValid or FontValid or PenValid);
  16392. NeededState := Byte( ReqState ) and not fState;
  16393. //Result := nil;
  16394. { if Boolean(ReqState and HandleValid) then
  16395. begin
  16396. if GetHandle = 0 then Exit; // Important!
  16397. end;}
  16398. if NeededState <> 0 then
  16399. begin
  16400. if Boolean( NeededState and PenValid ) then
  16401. begin
  16402. //CreatePen;
  16403. if not assigned( fPen ) then
  16404. fPen := NewPen;
  16405. if fPen.fData.Pen.Style in [psDash, psDot, psDashDot, psDashDotDot] then
  16406. NeededState := NeededState or BrushValid;
  16407. end;
  16408. if Boolean( NeededState and BrushValid ) then
  16409. begin
  16410. //CreateBrush;
  16411. if not Assigned( fBrush ) then
  16412. fBrush := NewBrush;
  16413. //c := Color2GDKColor( fBrush.Color );
  16414. //gdk_gc_set_rgb_fg_color( fHandle, @ c );
  16415. //todo: what with BrushBitmap and BrushStyle ?
  16416. end;
  16417. if Boolean( NeededState and FontValid ) then
  16418. begin
  16419. //CreateFont;
  16420. if not Assigned( fFont ) then
  16421. fFont := NewFont;
  16422. end;
  16423. fState := fState or NeededState;
  16424. end;
  16425. Result := fHandle;
  16426. end;*)
  16427. {$IFDEF _X_}
  16428. {$IFDEF GTK}
  16429. procedure TCanvas.ForeBack(fg_color, bk_color: TColor); // install colors just before drawing
  16430. begin
  16431. fg_color := RGB2BGR( Color2RGB( fg_color ) );
  16432. bk_color := RGB2BGR( Color2RGB( bk_color ) );
  16433. gdk_rgb_gc_set_foreground( fHandle, fg_color );
  16434. gdk_rgb_gc_set_background( fHandle, bk_color );
  16435. end;
  16436. {$ENDIF GTK}
  16437. {$ENDIF _X_}
  16438. {$IFDEF WIN_GDI}
  16439. //[procedure TCanvas.SetHandle]
  16440. {$IFDEF ASM_VERSION}
  16441. {$ELSE ASM_VERSION} //Pascal
  16442. procedure TCanvas.SetHandle(Value: HDC);
  16443. {$IFDEF F_P}
  16444. var Ptr1: Pointer;
  16445. {$ENDIF F_P}
  16446. begin
  16447. if fHandle = Value then Exit;
  16448. if fHandle <> 0 then
  16449. begin
  16450. DeselectHandles;
  16451. {$IFDEF GDI}
  16452. if not( assigned(fOwnerControl) and
  16453. (PControl(fOwnerControl).fPaintDC = fHandle) ) then
  16454. begin
  16455. {$IFDEF F_P}
  16456. Ptr1 := Self;
  16457. asm
  16458. MOV EAX, [Ptr1]
  16459. MOV EAX, [EAX].TCanvas.fOnGetHandle
  16460. MOV [Ptr1], EAX
  16461. end [ 'EAX' ];
  16462. if Ptr1 = @ TControl.DC2Canvas then
  16463. {$ELSE DELPHI}
  16464. //////////////////// SLAG
  16465. if TMethod(fOnGetHandle).Code =
  16466. @TControl.Dc2Canvas then
  16467. {$ENDIF F_P/DELPHI}
  16468. ReleaseDC(PControl(fOwnerControl).Handle, fHandle )
  16469. else
  16470. DeleteDC( fHandle );
  16471. ////////////////////
  16472. end;
  16473. {$ENDIF GDI}
  16474. fHandle := 0;
  16475. fIsPaintDC := False;
  16476. fState := fState and not HandleValid;
  16477. end;
  16478. if Value <> 0 then
  16479. begin
  16480. fState := fState or HandleValid;
  16481. fHandle := Value;
  16482. SetPenPos( fPenPos );
  16483. end;
  16484. end;
  16485. {$ENDIF ASM_VERSION}
  16486. {$ENDIF WIN_GDI}
  16487. //[procedure TCanvas.SetPenPos]
  16488. {$IFDEF ASM_VERSION}
  16489. {$ELSE ASM_VERSION} //Pascal
  16490. procedure TCanvas.SetPenPos(const Value: TPoint);
  16491. begin
  16492. fPenPos := Value;
  16493. {$IFDEF GDI}
  16494. MoveTo( Value.x, Value.y );
  16495. {$ENDIF GDI}
  16496. end;
  16497. {$ENDIF ASM_VERSION}
  16498. {$IFDEF WIN_GDI}
  16499. //[procedure TCanvas.Changing]
  16500. {$IFDEF ASM_VERSION}
  16501. {$ELSE ASM_VERSION} //Pascal
  16502. procedure TCanvas.Changing;
  16503. begin
  16504. if Assigned( fOnChange ) then
  16505. fOnChange( @Self );
  16506. end;
  16507. {$ENDIF ASM_VERSION}
  16508. {$ENDIF WIN_GDI}
  16509. //[procedure TCanvas.Arc]
  16510. {$IFDEF GDI}
  16511. {$IFDEF ASM_VERSION}
  16512. {$ELSE ASM_VERSION} //Pascal
  16513. procedure TCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); {$ifdef wince}cdecl{$else}stdcall{$endif};
  16514. begin
  16515. RequiredState( HandleValid or PenValid or ChangingCanvas );
  16516. {$ifndef wince}
  16517. Windows.Arc(FHandle, X1, Y1, X2, Y2, X3, Y3, X4, Y4);
  16518. {$endif wince}
  16519. end;
  16520. {$ENDIF ASM_VERSION}
  16521. {$ENDIF GDI}
  16522. {$IFDEF _X_}
  16523. {$IFDEF GTK}
  16524. procedure TCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); {$ifdef wince}cdecl{$else}stdcall{$endif};
  16525. var C: TPoint;
  16526. angle1, angle2: Integer;
  16527. A1, A2: Double;
  16528. begin
  16529. ////RequiredState( {HandleValid or} PenValid or ChangingCanvas );
  16530. C := MakePoint( (X1 + X2) div 2, (Y1 + Y2) div 2 );
  16531. {$IFDEF NOT_USE_EXCEPTION}
  16532. A1 := ArcTan2( Y3-C.Y, X3-C.X );
  16533. A2 := ArcTan2( Y4-C.Y, X4-C.X );
  16534. {$ELSE USE_EXCEPTION}
  16535. TRY
  16536. A1 := ArcTan2( Y3-C.Y, X3-C.X );
  16537. EXCEPT
  16538. A1 := 0;
  16539. END;
  16540. TRY
  16541. A2 := ArcTan2( Y4-C.Y, X4-C.X );
  16542. EXCEPT
  16543. A2 := 0;
  16544. END;
  16545. {$ENDIF NOT_USE_EXCEPTION}
  16546. angle1 := -Round(A1 * 180 * 64 / PI);
  16547. angle2 := -Round(A2 * 180 * 64 / PI);
  16548. if Brush.BrushStyle <> bsClear then
  16549. begin
  16550. ForeBack( Brush.Color, Brush.Color );
  16551. gdk_draw_arc( fDrawable, fHandle, 1, X1, Y1, X2-X1, Y2-Y1, angle1, angle2 );
  16552. end;
  16553. ForeBack( Pen.Color, Brush.Color );
  16554. gdk_draw_arc( fDrawable, fHandle, 0, X1, Y1, X2-X1, Y2-Y1, angle1, angle2 );
  16555. end;
  16556. {$ENDIF GTK}
  16557. {$ENDIF _X_}
  16558. {$IFDEF WIN_GDI}
  16559. //[procedure TCanvas.Chord]
  16560. {$IFDEF ASM_VERSION}
  16561. {$ELSE ASM_VERSION} //Pascal
  16562. procedure TCanvas.Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); {$ifdef wince}cdecl{$else}stdcall{$endif};
  16563. begin
  16564. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  16565. {$ifndef wince}
  16566. Windows.Chord(FHandle, X1, Y1, X2, Y2, X3, Y3, X4, Y4);
  16567. {$endif wince}
  16568. end;
  16569. {$ENDIF ASM_VERSION}
  16570. //[procedure TCanvas.CopyRect]
  16571. {$IFDEF ASM_VERSION}
  16572. {$ELSE ASM_VERSION} //Pascal
  16573. procedure TCanvas.CopyRect(const DstRect: TRect; SrcCanvas: PCanvas;
  16574. const SrcRect: TRect);
  16575. begin
  16576. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  16577. SrcCanvas.RequiredState( HandleValid or BrushValid );
  16578. StretchBlt( fHandle, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left,
  16579. DstRect.Bottom - DstRect.Top, SrcCanvas.Handle, SrcRect.Left, SrcRect.Top,
  16580. SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top, ModeCopy);
  16581. end;
  16582. {$ENDIF ASM_VERSION}
  16583. //[procedure TCanvas.DrawFocusRect]
  16584. {$IFDEF ASM_VERSION}
  16585. {$ELSE ASM_VERSION} //Pascal
  16586. procedure TCanvas.DrawFocusRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  16587. begin
  16588. RequiredState( HandleValid or BrushValid or FontValid or ChangingCanvas );
  16589. Windows.DrawFocusRect(FHandle, Rect);
  16590. end;
  16591. {$ENDIF ASM_VERSION}
  16592. //[procedure TCanvas.Ellipse]
  16593. {$IFDEF ASM_VERSION}
  16594. {$ELSE ASM_VERSION} //Pascal
  16595. procedure TCanvas.Ellipse(X1, Y1, X2, Y2: Integer);
  16596. begin
  16597. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  16598. Windows.Ellipse(FHandle, X1, Y1, X2, Y2);
  16599. end;
  16600. {$ENDIF ASM_VERSION}
  16601. {$ENDIF WIN_GDI}
  16602. //[procedure TCanvas.FillRect]
  16603. {$IFDEF GDI}
  16604. {$IFDEF ASM_VERSION}
  16605. {$ELSE ASM_VERSION} //Pascal
  16606. procedure TCanvas.FillRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  16607. var Br: HBrush;
  16608. begin
  16609. RequiredState( HandleValid or BrushValid or ChangingCanvas );
  16610. if assigned( fBrush ) then
  16611. begin
  16612. Windows.FillRect(fHandle, Rect, fBrush.Handle);
  16613. end
  16614. else
  16615. if assigned( fOwnerControl ) then
  16616. begin
  16617. {$IFDEF GDI}
  16618. if assigned( PControl( fOwnerControl ).fBrush ) then
  16619. Windows.FillRect( fHandle, Rect, PControl( fOwnerControl ).fBrush.Handle )
  16620. else
  16621. begin
  16622. Br := CreateSolidBrush( Color2RGB(PControl(fOwnerControl).fColor) );
  16623. Windows.FillRect(fHandle, Rect, Br );
  16624. DeleteObject( Br );
  16625. end;
  16626. {$ENDIF GDI}
  16627. end
  16628. else
  16629. begin
  16630. Windows.FillRect(fHandle, Rect, HBrush(COLOR_WINDOW + 1) );
  16631. end;
  16632. end;
  16633. {$ENDIF ASM_VERSION}
  16634. {$ENDIF GDI}
  16635. {$IFDEF _X_}
  16636. {$IFDEF GTK}
  16637. procedure TCanvas.FillRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  16638. begin
  16639. if (fBrush <> nil) and (fBrush.BrushStyle = bsClear) then Exit;
  16640. ////RequiredState( {HandleValid or} BrushValid or ChangingCanvas );
  16641. ForeBack( Brush.Color, Brush.Color );
  16642. gdk_draw_rectangle( fDrawable, fHandle, 1, Rect.Left, Rect.Top,
  16643. Rect.Right-Rect.Left, Rect.Bottom-Rect.Top );
  16644. end;
  16645. {$ENDIF GTK}
  16646. {$ENDIF _X_}
  16647. {$IFDEF WIN_GDI}
  16648. //[procedure TCanvas.FillRgn]
  16649. {$IFDEF ASM_VERSION}
  16650. {$ELSE ASM_VERSION} //Pascal
  16651. procedure TCanvas.FillRgn(const Rgn: HRgn);
  16652. var Br : HBrush;
  16653. begin
  16654. RequiredState( HandleValid or BrushValid or ChangingCanvas );
  16655. if assigned( fBrush ) then
  16656. Windows.FillRgn(FHandle, Rgn, fBrush.Handle )
  16657. else
  16658. if assigned( fOwnerControl ) then
  16659. begin
  16660. {$IFDEF GDI}
  16661. if Assigned( PControl( fOwnerControl ).fBrush ) then
  16662. Windows.FillRgn( FHandle, Rgn, PControl( fOwnerControl ).fBrush.Handle )
  16663. else
  16664. begin
  16665. Br := CreateSolidBrush( Color2RGB(PControl(fOwnerControl).fColor) );
  16666. Windows.FillRgn( fHandle, Rgn, Br );
  16667. DeleteObject( Br );
  16668. end;
  16669. {$ENDIF GDI}
  16670. end
  16671. else
  16672. begin
  16673. Br := CreateSolidBrush( DWORD(clWindow) );
  16674. Windows.FillRgn( fHandle, Rgn, Br );
  16675. DeleteObject( Br );
  16676. end;
  16677. end;
  16678. {$ENDIF ASM_VERSION}
  16679. //[procedure TCanvas.FloodFill]
  16680. {$IFDEF ASM_VERSION}
  16681. {$ELSE ASM_VERSION} //Pascal
  16682. procedure TCanvas.FloodFill(X, Y: Integer; Color: TColor;
  16683. FillStyle: TFillStyle);
  16684. {$ifndef wince}
  16685. const
  16686. FillStyles: array[TFillStyle] of Word =
  16687. (FLOODFILLSURFACE, FLOODFILLBORDER);
  16688. {$endif wince}
  16689. begin
  16690. RequiredState( HandleValid or BrushValid or ChangingCanvas );
  16691. {$ifndef wince}
  16692. Windows.ExtFloodFill(FHandle, X, Y, Color, FillStyles[FillStyle]);
  16693. {$endif wince}
  16694. end;
  16695. {$ENDIF ASM_VERSION}
  16696. {$ifdef wince}
  16697. procedure CeFrameRect(DC: HDC; const Rect: TRect; Color: TColor);
  16698. var
  16699. OldBrush, OldPen : HGDIOBJ;
  16700. begin
  16701. OldBrush:=SelectObject(DC, GetStockObject(NULL_BRUSH));
  16702. OldPen:=SelectObject(DC, Windows.CreatePen(PS_SOLID, 1, Color2RGB(Color)));
  16703. with Rect do
  16704. Windows.Rectangle(DC, Left, Top, Right, Bottom);
  16705. DeleteObject( SelectObject(DC, OldPen) );
  16706. SelectObject(DC, OldBrush);
  16707. end;
  16708. {$endif wince}
  16709. //[procedure TCanvas.FrameRect]
  16710. {$IFDEF ASM_VERSION}
  16711. {$ELSE ASM_VERSION} //Pascal
  16712. procedure TCanvas.FrameRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  16713. var {$ifdef win32}SolidBr : HBrush;{$endif}
  16714. col : TColor;
  16715. begin
  16716. RequiredState( HandleValid or ChangingCanvas );
  16717. if assigned( fBrush ) then
  16718. col := fBrush.fData.Color
  16719. else
  16720. if assigned( fOwnerControl ) then
  16721. col := PControl(fOwnerControl).fColor
  16722. else
  16723. col := clWhite;
  16724. {$ifdef wince}
  16725. CeFrameRect(FHandle, Rect, col);
  16726. {$else}
  16727. SolidBr := CreateSolidBrush( Color2RGB(col) );
  16728. Windows.FrameRect(FHandle, Rect, SolidBr);
  16729. DeleteObject( SolidBr );
  16730. {$endif wince}
  16731. end;
  16732. {$ENDIF ASM_VERSION}
  16733. {$ENDIF WIN_GDI}
  16734. //[procedure TCanvas.LineTo]
  16735. {$IFDEF GDI}
  16736. {$IFDEF ASM_VERSION}
  16737. {$ELSE ASM_VERSION} //Pascal
  16738. procedure TCanvas.LineTo(X, Y: Integer);
  16739. begin
  16740. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  16741. Windows.LineTo( fHandle, X, Y );
  16742. end;
  16743. {$ENDIF ASM_VERSION}
  16744. {$ENDIF GDI}
  16745. {$IFDEF _X_}
  16746. {$IFDEF GTK}
  16747. procedure TCanvas.LineTo(X, Y: Integer);
  16748. begin
  16749. //RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  16750. ////RequiredState( PenValid or BrushValid or ChangingCanvas );
  16751. ForeBack( Pen.Color, Brush.Color );
  16752. gdk_draw_line( fDrawable, fHandle, fPenPos.X, fPenPos.Y, X, Y );
  16753. fPenPos := MakePoint( X, Y );
  16754. end;
  16755. {$ENDIF GTK}
  16756. {$ENDIF _X_}
  16757. //[procedure TCanvas.MoveTo]
  16758. {$IFDEF GDI}
  16759. {$IFDEF ASM_VERSION}
  16760. {$ELSE ASM_VERSION} //Pascal
  16761. procedure TCanvas.MoveTo(X, Y: Integer);
  16762. begin
  16763. RequiredState( HandleValid );
  16764. Windows.MoveToEx( fHandle, X, Y, nil );
  16765. end;
  16766. {$ENDIF ASM_VERSION}
  16767. {$ENDIF GDI}
  16768. {$IFDEF _X_}
  16769. {$IFDEF GTK}
  16770. procedure TCanvas.MoveTo(X, Y: Integer);
  16771. begin
  16772. fPenPos := MakePoint( X, Y );
  16773. end;
  16774. {$ENDIF GTK}
  16775. {$ENDIF _X_}
  16776. //[procedure TCanvas.ObjectChanged]
  16777. procedure TCanvas.ObjectChanged(Sender: PGraphicTool);
  16778. begin
  16779. DeselectHandles;
  16780. end;
  16781. {$IFDEF WIN_GDI}
  16782. //[procedure TCanvas.Pie]
  16783. {$IFDEF ASM_VERSION}
  16784. {$ELSE ASM_VERSION} //Pascal
  16785. procedure TCanvas.Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); {$ifdef wince}cdecl{$else}stdcall{$endif};
  16786. begin
  16787. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  16788. {$ifndef wince}
  16789. Windows.Pie( fHandle, X1, Y1, X2, Y2, X3, Y3, X4, Y4);
  16790. {$endif wince}
  16791. end;
  16792. {$ENDIF ASM_VERSION}
  16793. {++}(*
  16794. {$IFDEF F_P}
  16795. //[Windows API FUNCTIONS ADDITIONAL DECLARATIONS FOR Free Pascal]
  16796. function Windows_Polygon; external gdi32 name 'Polygon';
  16797. function Windows_Polyline; external gdi32 name 'Polyline';
  16798. function FillRect; external user32 name 'FillRect';
  16799. function OffsetRect; external user32 name 'OffsetRect';
  16800. function CreateAcceleratorTable; external user32 name 'CreateAcceleratorTableA';
  16801. function TrackPopupMenu; external user32 name 'TrackPopupMenu';
  16802. function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL;
  16803. const NewState: TTokenPrivileges; BufferLength: DWORD;
  16804. var PreviousState: TTokenPrivileges; var ReturnLength: DWORD): BOOL; external advapi32 name 'AdjustTokenPrivileges';
  16805. function InflateRect; external user32 name 'InflateRect';
  16806. {$IFDEF F_P105ORBELOW}
  16807. function InvalidateRect; external user32 name 'InvalidateRect';
  16808. function ValidateRect; external user32 name 'ValidateRect';
  16809. {$ENDIF F_P105ORBELOW}
  16810. //[END OF Windows API FUNCTIONS ADDITIONAL DECLARATIONS FOR Free Pascal]
  16811. {$ENDIF}
  16812. *){--}
  16813. //[procedure TCanvas.Polygon]
  16814. {$IFDEF ASM_VERSION}
  16815. {$ELSE ASM_VERSION} //Pascal
  16816. procedure TCanvas.Polygon(const Points: array of TPoint);
  16817. type
  16818. PPoints = ^TPoints;
  16819. TPoints = array[0..0] of TPoint;
  16820. begin
  16821. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  16822. {$IFDEF F_P} Windows_Polygon
  16823. {$ELSE DELPHI} Windows.Polygon
  16824. {$ENDIF}( fHandle, PPoints(@Points)^, High(Points) + 1);
  16825. end;
  16826. {$ENDIF ASM_VERSION}
  16827. //[procedure TCanvas.Polyline]
  16828. {$IFDEF ASM_VERSION}
  16829. {$ELSE ASM_VERSION} //Pascal
  16830. procedure TCanvas.Polyline(const Points: array of TPoint);
  16831. type
  16832. PPoints = ^TPoints;
  16833. TPoints = array[0..0] of TPoint;
  16834. begin
  16835. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  16836. {$IFDEF F_P}Windows_Polyline
  16837. {$ELSE DELPHI}Windows.Polyline
  16838. {$ENDIF}( fHandle, PPoints(@Points)^, High(Points) + 1);
  16839. end;
  16840. {$ENDIF ASM_VERSION}
  16841. //[procedure TCanvas.Rectangle]
  16842. {$IFDEF ASM_VERSION}
  16843. {$ELSE ASM_VERSION} //Pascal
  16844. procedure TCanvas.Rectangle(X1, Y1, X2, Y2: Integer);
  16845. begin
  16846. RequiredState( HandleValid or BrushValid or PenValid or ChangingCanvas );
  16847. Windows.Rectangle( fHandle, X1, Y1, X2, Y2);
  16848. end;
  16849. {$ENDIF ASM_VERSION}
  16850. //[procedure TCanvas.RoundRect]
  16851. {$IFDEF ASM_VERSION}
  16852. {$ELSE ASM_VERSION} //Pascal
  16853. procedure TCanvas.RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
  16854. begin
  16855. RequiredState( HandleValid or BrushValid or PenValid or ChangingCanvas );
  16856. Windows.RoundRect( fHandle, X1, Y1, X2, Y2, X3, Y3);
  16857. end;
  16858. {$ENDIF ASM_VERSION}
  16859. {$ENDIF WIN_GDI}
  16860. //[procedure TCanvas.TextArea]
  16861. {$IFDEF ASM_VERSION}
  16862. {$ELSE ASM_VERSION} //Pascal
  16863. procedure TCanvas.TextArea(const Text: KOLString; var Sz: TSize;
  16864. var P0: TPoint);
  16865. begin
  16866. Sz := TextExtent( Text );
  16867. P0.x := 0; P0.y := 0;
  16868. if Assigned( GlobalCanvas_OnTextArea ) then
  16869. GlobalCanvas_OnTextArea( @Self, Sz, P0 );
  16870. end;
  16871. {$ENDIF ASM_VERSION}
  16872. //[function TCanvas.TextExtent]
  16873. {$IFDEF GDI}
  16874. {$IFDEF ASM_VERSION}
  16875. {$ELSE ASM_VERSION} //Pascal
  16876. function TCanvas.TextExtent(const Text: KOLString): TSize;
  16877. var DC : HDC;
  16878. ClearHandle : Boolean;
  16879. begin
  16880. ClearHandle := False;
  16881. RequiredState( HandleValid or FontValid );
  16882. DC := fHandle;
  16883. if DC = 0 then
  16884. begin
  16885. DC := CreateCompatibleDC( 0 );
  16886. ClearHandle := True;
  16887. SetHandle( DC );
  16888. If Not fIsPaintDC then
  16889. ClearHandle := True; //************ // Added By Gerasimov
  16890. end;
  16891. RequiredState( HandleValid or FontValid );
  16892. {Windows.}GetTextExtentPoint32( fHandle, PKOLChar(Text), Length(Text), Result);
  16893. {$ifdef wince}
  16894. Inc(Result.cx);
  16895. {$endif wince}
  16896. if ClearHandle then
  16897. SetHandle( 0 );
  16898. { DC must be freed here automatically (never leaks):
  16899. if Canvas created on base of existing DC, no memDC created,
  16900. if Canvas has fHandle:HDC = 0, it is not fIsPaintDC always. }
  16901. end;
  16902. {$ENDIF ASM_VERSION}
  16903. {$ENDIF GDI}
  16904. {$IFDEF _X_}
  16905. {$IFDEF GTK}
  16906. function TCanvas.TextExtent(const Text: KOLString): TSize;
  16907. var layout: PPangoLayout;
  16908. context: PPangoContext;
  16909. begin
  16910. //RequiredState( HandleValid or FontValid );
  16911. if fOwnerControl <> nil then
  16912. begin
  16913. context := nil;
  16914. layout := gtk_widget_create_pango_layout(
  16915. PControl( fOwnerControl ).fEventboxHandle, nil );
  16916. end
  16917. else
  16918. begin //todo: seems not working in such way... What to do for memory bitmap?
  16919. context := pango_context_new;
  16920. //layout := gtk_widget_create_pango_layout( fHandle, PChar( Text ) );
  16921. layout := pango_layout_new( context );
  16922. end;
  16923. pango_layout_set_font_description( layout, Font.FontHandle );
  16924. pango_layout_set_text( layout, PChar( Text ), Length( Text ) );
  16925. pango_layout_get_size( layout, @ Result.cx, @ Result.cy );
  16926. g_object_unref( layout );
  16927. if context <> nil then g_object_unref( context );
  16928. end;
  16929. {$ENDIF GTK}
  16930. {$ENDIF _X_}
  16931. //[function TCanvas.TextHeight]
  16932. function TCanvas.TextHeight(const Text: KOLString): Integer;
  16933. begin
  16934. Result := TextExtent(Text).cY;
  16935. end;
  16936. //[procedure TCanvas.TextOut]
  16937. {$IFDEF GDI}
  16938. {$IFDEF ASM_VERSION}
  16939. {$ELSE ASM_VERSION} //Pascal
  16940. procedure TCanvas.TextOut(X, Y: Integer; const Text: KOLString); {$ifdef wince}cdecl{$else}stdcall{$endif};
  16941. {$ifdef wince}
  16942. var Options: Integer;
  16943. {$endif wince}
  16944. begin
  16945. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  16946. {$ifdef wince}
  16947. Options := 0;
  16948. if GetBkMode(FHandle) = OPAQUE then Options := ETO_OPAQUE;
  16949. Windows.ExtTextOut(FHandle, X, Y, Options, nil, PKOLChar(Text), Length(Text), nil);
  16950. {$else}
  16951. Windows.TextOut(FHandle, X, Y, PChar(Text), Length(Text));
  16952. {$endif wince}
  16953. //MoveTo(X + TextWidth(Text), Y); -- by suggestion of Alexey (Lecha2002)
  16954. end;
  16955. {$ENDIF ASM_VERSION}
  16956. {$ENDIF GDI}
  16957. {$IFDEF _X_}
  16958. {$IFDEF GTK}
  16959. procedure TCanvas.TextOut(X, Y: Integer; const Text: KOLString); {$ifdef wince}cdecl{$else}stdcall{$endif};
  16960. var Options: Integer;
  16961. begin
  16962. Options := 0;
  16963. if Brush.BrushStyle <> bsClear then Options := ETO_OPAQUE;
  16964. ExtTextOut( X, Y, Options, MakeRect( 0,0,0,0 ), Text, [ ] );
  16965. end;
  16966. (*var context: PPangoContext;
  16967. layout: PPangoLayout;
  16968. w, h: Integer;
  16969. begin
  16970. RequiredState( {HandleValid or} FontValid or BrushValid or ChangingCanvas );
  16971. if fOwnerControl <> nil then
  16972. begin
  16973. context := nil;
  16974. layout := gtk_widget_create_pango_layout(
  16975. PControl( fOwnerControl ).fEventboxHandle, nil );
  16976. end
  16977. else
  16978. begin //todo: seems not working in such way... What to do for memory bitmap?
  16979. context := pango_context_new;
  16980. //layout := gtk_widget_create_pango_layout( fHandle, PChar( Text ) );
  16981. layout := pango_layout_new( context );
  16982. end;
  16983. pango_layout_set_font_description( layout, Font.FontHandle );
  16984. pango_layout_set_text( layout, PChar( Text ), Length( Text ) );
  16985. if Brush.BrushStyle <> bsClear then
  16986. begin
  16987. pango_layout_get_size( layout, @ w, @ h );
  16988. ForeBack( Brush.Color, Brush.Color );
  16989. gdk_draw_rectangle( fDrawable, fHandle, 1, X, Y, w div PANGO_SCALE, h div PANGO_SCALE );
  16990. end;
  16991. ForeBack( Font.Color, Brush.Color );
  16992. gdk_draw_layout( fDrawable, fHandle, X, Y, layout );
  16993. g_object_unref( layout );
  16994. if context <> nil then
  16995. g_object_unref( context );
  16996. end;*)
  16997. {$ENDIF GTK}
  16998. {$ENDIF _X_}
  16999. //[procedure TCanvas.TextRect]
  17000. {$IFDEF GDI}
  17001. {$IFDEF ASM_VERSION}
  17002. {$ELSE ASM_VERSION} //Pascal
  17003. procedure TCanvas.TextRect(const Rect: TRect; X, Y: Integer; const Text: KOLString);
  17004. var
  17005. Options: Integer;
  17006. begin
  17007. //Changing;
  17008. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17009. Options := ETO_CLIPPED;
  17010. if assigned( fBrush ) and (fBrush.fData.Brush.Style <> bsClear)
  17011. or not assigned( fBrush ) then Inc(Options, ETO_OPAQUE);
  17012. Windows.
  17013. {$IFDEF UNICODE_CTRLS}
  17014. ExtTextOutW
  17015. {$ELSE}
  17016. ExtTextOut
  17017. {$ENDIF}
  17018. ( fHandle, X, Y, Options,
  17019. @Rect, PKOLChar(Text),
  17020. Length(Text), nil);
  17021. end;
  17022. {$ENDIF ASM_VERSION}
  17023. {$ENDIF GDI}
  17024. {$IFDEF _X_}
  17025. {$IFDEF GTK}
  17026. procedure TCanvas.TextRect(const Rect: TRect; X, Y: Integer; const Text: string);
  17027. var Options: Integer;
  17028. begin
  17029. Options := ETO_CLIPPED;
  17030. if Brush.BrushStyle <> bsClear then Options := Options or ETO_OPAQUE;
  17031. ExtTextOut( X, Y, Options, Rect, Text, [] );
  17032. end;
  17033. {$ENDIF GTK}
  17034. {$ENDIF _X_}
  17035. //[procedure TCanvas.ExtTextOut]
  17036. {$IFDEF GDI}
  17037. procedure TCanvas.ExtTextOut( X, Y: Integer; Options: DWORD; const Rect: TRect; const Text: KOLString;
  17038. const Spacing: array of Integer );
  17039. begin
  17040. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17041. Windows.
  17042. {$IFDEF UNICODE_CTRLS}
  17043. ExtTextOutW
  17044. {$ELSE}
  17045. ExtTextOut
  17046. {$ENDIF}
  17047. (FHandle, X, Y, Options, @Rect, PKOLChar(Text), Length(Text), @Spacing[ 0 ]);
  17048. end;
  17049. {$ENDIF GDI}
  17050. {$IFDEF _X_}
  17051. {$IFDEF GTK}
  17052. procedure TCanvas.ExtTextOut( X, Y: Integer; Options: DWORD; const Rect: TRect; const Text: KOLString;
  17053. const Spacing: array of Integer );
  17054. var context: PPangoContext;
  17055. layout: PPangoLayout;
  17056. w, h: Integer;
  17057. pixmap: PGdkPixmap;
  17058. begin
  17059. ////RequiredState( {HandleValid or} FontValid or BrushValid or ChangingCanvas );
  17060. w := Rect.Right - Rect.Left;
  17061. h := Rect.Bottom - Rect.Top;
  17062. if fOwnerControl <> nil then
  17063. begin
  17064. context := nil;
  17065. layout := gtk_widget_create_pango_layout(
  17066. PControl( fOwnerControl ).fEventboxHandle, nil );
  17067. end
  17068. else
  17069. begin //todo: seems not working in such way... What to do for memory bitmap?
  17070. context := pango_context_new;
  17071. //layout := gtk_widget_create_pango_layout( fHandle, PChar( Text ) );
  17072. layout := pango_layout_new( context );
  17073. end;
  17074. pango_layout_set_font_description( layout, Font.FontHandle );
  17075. pango_layout_set_text( layout, PChar( Text ), Length( Text ) );
  17076. if Options and ETO_CLIPPED = 0 then
  17077. begin
  17078. pango_layout_get_size( layout, @ w, @ h );
  17079. w := w div PANGO_SCALE;
  17080. h := h div PANGO_SCALE;
  17081. end;
  17082. pixmap := gdk_pixmap_new( PControl( fOwnerControl ).fEventboxHandle.window,
  17083. //todo: use MainForm
  17084. w, h, -1 );
  17085. if Options and ETO_OPAQUE <> 0 then
  17086. begin
  17087. ForeBack( Brush.Color, Brush.Color );
  17088. gdk_draw_rectangle( GDK_DRAWABLE( pixmap ), fHandle, 1, 0, 0, w, h );
  17089. end
  17090. else
  17091. begin
  17092. gdk_draw_drawable( GDK_DRAWABLE( pixmap ), fHandle, fDrawable,
  17093. Rect.Left, Rect.Top, 0, 0, w, h );
  17094. end;
  17095. ForeBack( Font.Color, Brush.Color );
  17096. gdk_draw_layout( GDK_DRAWABLE( pixmap ), fHandle, X, Y, layout );
  17097. g_object_unref( layout );
  17098. gdk_draw_drawable( fDrawable, fHandle, GDK_DRAWABLE( pixmap ),
  17099. 0, 0, Rect.Left, Rect.Top, w, h );
  17100. g_object_unref( pixmap );
  17101. if context <> nil then
  17102. g_object_unref( context );
  17103. end;
  17104. {$ENDIF GTK}
  17105. {$ENDIF _X_}
  17106. {$IFDEF WIN_GDI}
  17107. //[procedure TCanvas.DrawText]
  17108. procedure TCanvas.DrawText(Text:KOLString; var Rect:TRect; Flags:DWord);
  17109. begin
  17110. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17111. Windows.
  17112. {$IFDEF UNICODE_CTRLS}
  17113. DrawTextW
  17114. {$ELSE}
  17115. DrawText
  17116. {$ENDIF}
  17117. (Handle,PKOLChar(Text),Length(Text),Rect,Flags);
  17118. end;
  17119. //[function TCanvas.ClipRect]
  17120. function TCanvas.ClipRect: TRect;
  17121. begin
  17122. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17123. GetClipBox(Handle, Result);
  17124. end;
  17125. {$ENDIF WIN_GDI}
  17126. //[function TCanvas.TextWidth]
  17127. function TCanvas.TextWidth(const Text: KOLString): Integer;
  17128. begin
  17129. Result := TextExtent(Text).cX;
  17130. end;
  17131. //[function TCanvas.GetBrush]
  17132. {$IFDEF GDI}
  17133. {$IFDEF ASM_VERSION}
  17134. {$ELSE ASM_VERSION} //Pascal
  17135. function TCanvas.GetBrush: PGraphicTool;
  17136. begin
  17137. if not assigned( fBrush ) then
  17138. begin
  17139. fBrush := NewBrush;
  17140. if assigned( fOwnerControl ) then
  17141. begin
  17142. fBrush.fData.Color := PControl(fOwnerControl).fColor;
  17143. if assigned( PControl(fOwnerControl).fBrush ) then
  17144. {fBrush := }fBrush.Assign( PControl(fOwnerControl).fBrush );
  17145. // both statements above needed
  17146. end;
  17147. //fBrush.OnChange := ObjectChanged;
  17148. AssignChangeEvents;
  17149. end;
  17150. Result := fBrush;
  17151. end;
  17152. {$ENDIF ASM_VERSION}
  17153. {$ENDIF GDI}
  17154. {$IFDEF _X_}
  17155. {$IFDEF GTK}
  17156. function TCanvas.GetBrush: PGraphicTool;
  17157. begin
  17158. if not assigned( fBrush ) then
  17159. begin
  17160. fBrush := NewBrush;
  17161. if assigned( fOwnerControl ) then
  17162. begin
  17163. fBrush.fData.Color := PControl(fOwnerControl).fColor;
  17164. if assigned( PControl(fOwnerControl).fBrush ) then
  17165. {fBrush := }fBrush.Assign( PControl(fOwnerControl).fBrush );
  17166. // both statements above needed
  17167. end;
  17168. //fBrush.OnChange := ObjectChanged;
  17169. AssignChangeEvents;
  17170. end;
  17171. Result := fBrush;
  17172. end;
  17173. {$ENDIF GTK}
  17174. {$ENDIF _X_}
  17175. //[function TCanvas.GetFont]
  17176. {$IFDEF ASM_VERSION}
  17177. {$ELSE ASM_VERSION} //Pascal
  17178. function TCanvas.GetFont: PGraphicTool;
  17179. begin
  17180. if not assigned( fFont ) then
  17181. begin
  17182. fFont := NewFont;
  17183. if assigned( fOwnerControl ) then
  17184. begin
  17185. fFont.Color := PControl(fOwnerControl).fTextColor;
  17186. if assigned( PControl(fOwnerControl).fFont ) then
  17187. {fFont := }fFont.Assign( PControl(fOwnerControl).fFont );
  17188. end;
  17189. //fFont.OnChange := ObjectChanged;
  17190. AssignChangeEvents;
  17191. end;
  17192. Result := fFont;
  17193. end;
  17194. {$ENDIF ASM_VERSION}
  17195. //[function TCanvas.GetPen]
  17196. {$IFDEF ASM_VERSION}
  17197. {$ELSE ASM_VERSION} //Pascal
  17198. function TCanvas.GetPen: PGraphicTool;
  17199. begin
  17200. if not assigned( fPen ) then
  17201. begin
  17202. fPen := NewPen;
  17203. AssignChangeEvents;
  17204. end;
  17205. Result := fPen;
  17206. end;
  17207. {$ENDIF ASM_VERSION}
  17208. //[function TCanvas.GetHandle]
  17209. {$IFDEF GDI}
  17210. {$IFDEF ASM_VERSION}
  17211. {$ELSE ASM_VERSION} //Pascal
  17212. function TCanvas.GetHandle: HDC;
  17213. begin
  17214. if assigned( fOnGetHandle ) then
  17215. begin
  17216. Result := fOnGetHandle( @Self );
  17217. //fHandle := Result;
  17218. SetHandle( Result );
  17219. end
  17220. else
  17221. Result := fHandle;
  17222. end;
  17223. {$ENDIF ASM_VERSION}
  17224. {$ENDIF GDI}
  17225. {$IFDEF _X_}
  17226. {$IFDEF GTK}
  17227. function TCanvas.GetHandle: HDC;
  17228. begin
  17229. if Assigned( fOnGetHandle ) then
  17230. fHandle := fOnGetHandle( @Self );
  17231. Result := fHandle;
  17232. end;
  17233. {$ENDIF GTK}
  17234. {$ENDIF _X_}
  17235. //[procedure TCanvas.AssignChangeEvents]
  17236. {$IFDEF ASM_VERSION}
  17237. {$ELSE ASM_VERSION} //Pascal
  17238. procedure TCanvas.AssignChangeEvents;
  17239. begin
  17240. if assigned( fBrush ) then
  17241. fBrush.fOnChange := ObjectChanged;
  17242. if assigned( fPen ) then
  17243. fPen.fOnChange := ObjectChanged;
  17244. if assigned( fFont ) then
  17245. fFont.fOnChange := ObjectChanged;
  17246. end;
  17247. {$ENDIF ASM_VERSION}
  17248. {$IFDEF WIN_GDI}
  17249. {$IFNDEF _FPC}
  17250. {$IFNDEF _D2}
  17251. //[procedure TCanvas.WDrawText]
  17252. procedure TCanvas.WDrawText(WText: WideString; var Rect: TRect;
  17253. Flags: DWord);
  17254. begin
  17255. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17256. Windows.DrawTextW(Handle,PWideChar(WText),Length(WText),Rect,Flags);
  17257. end;
  17258. //[procedure TCanvas.WExtTextOut]
  17259. procedure TCanvas.WExtTextOut(X, Y: Integer; Options: DWORD;
  17260. const Rect: TRect; const WText: WideString;
  17261. const Spacing: array of Integer);
  17262. begin
  17263. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17264. Windows.ExtTextOutW(FHandle, X, Y, Options, @Rect, PWideChar(WText), Length(WText), @Spacing[ 0 ]);
  17265. end;
  17266. //[procedure TCanvas.WTextOut]
  17267. procedure TCanvas.WTextOut(X, Y: Integer; const WText: WideString);
  17268. begin
  17269. {$ifdef wince}
  17270. TextOut(X, Y, WText);
  17271. {$else}
  17272. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17273. Windows.TextOutW(FHandle, X, Y, PWideChar(WText), Length(WText));
  17274. MoveTo(X + WTextWidth(WText), Y);
  17275. {$endif wince}
  17276. end;
  17277. //[procedure TCanvas.WTextRect]
  17278. procedure TCanvas.WTextRect(const Rect: TRect; X, Y: Integer;
  17279. const WText: WideString);
  17280. var
  17281. Options: Integer;
  17282. begin
  17283. //Changing;
  17284. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  17285. Options := ETO_CLIPPED;
  17286. if assigned( fBrush ) and (fBrush.fData.Brush.Style <> bsClear)
  17287. or not assigned( fBrush ) then Inc(Options, ETO_OPAQUE);
  17288. Windows.ExtTextOutW( fHandle, X, Y, Options,
  17289. @Rect, PWideChar(WText),
  17290. Length(WText), nil);
  17291. end;
  17292. //[function TCanvas.WTextExtent]
  17293. function TCanvas.WTextExtent(const WText: WideString): TSize;
  17294. var DC : HDC;
  17295. ClearHandle : Boolean;
  17296. begin
  17297. ClearHandle := False;
  17298. RequiredState( HandleValid or FontValid );
  17299. DC := fHandle;
  17300. if DC = 0 then
  17301. begin
  17302. DC := CreateCompatibleDC( 0 );
  17303. ClearHandle := True;
  17304. SetHandle( DC );
  17305. end;
  17306. RequiredState( HandleValid or FontValid );
  17307. {Windows.}GetTextExtentPoint32W( fHandle, PWideChar(WText), Length(WText), Result);
  17308. if ClearHandle then
  17309. SetHandle( 0 );
  17310. end;
  17311. //[function TCanvas.WTextHeight]
  17312. function TCanvas.WTextHeight(const WText: WideString): Integer;
  17313. begin
  17314. Result := WTextExtent( WText ).cy;
  17315. end;
  17316. //[function TCanvas.WTextWidth]
  17317. function TCanvas.WTextWidth(const WText: WideString): Integer;
  17318. begin
  17319. Result := WTextExtent( WText ).cx;
  17320. end;
  17321. {$ENDIF _D2}
  17322. {$ENDIF _FPC}
  17323. {$ENDIF WIN_GDI}
  17324. {-}
  17325. //[function MakeInt64]
  17326. function MakeInt64( Lo, Hi: DWORD ): I64;
  17327. begin
  17328. Result.Lo := Lo;
  17329. Result.Hi := Hi;
  17330. end;
  17331. //[function Int2Int64]
  17332. {$IFDEF cpu86}
  17333. function Int2Int64( X: Integer ): I64;
  17334. asm
  17335. MOV [EDX], EAX
  17336. MOV ECX, EDX
  17337. CDQ
  17338. MOV [ECX+4], EDX
  17339. end;
  17340. {$ELSE cpu86} //Pascal
  17341. function Int2Int64( X: Integer ): I64;
  17342. begin
  17343. Int64(Result):=X;
  17344. end;
  17345. {$ENDIF cpu86}
  17346. //[procedure IncInt64]
  17347. {$IFDEF cpu86}
  17348. procedure IncInt64( var I64: I64; Delta: Integer );
  17349. asm
  17350. ADD [EAX], EDX
  17351. ADC dword ptr [EAX+4], 0
  17352. end;
  17353. {$ELSE cpu86} //Pascal
  17354. procedure IncInt64( var I64: I64; Delta: Integer );
  17355. begin
  17356. Inc(Int64(I64), Delta);
  17357. end;
  17358. {$ENDIF cpu86}
  17359. //[procedure DecInt64]
  17360. {$IFDEF cpu86}
  17361. procedure DecInt64( var I64: I64; Delta: Integer );
  17362. asm
  17363. SUB [EAX], EDX
  17364. SBB dword ptr [EDX], 0
  17365. end;
  17366. {$ELSE cpu86} //Pascal
  17367. procedure DecInt64( var I64: I64; Delta: Integer );
  17368. begin
  17369. Dec(Int64(I64), Delta);
  17370. end;
  17371. {$ENDIF cpu86}
  17372. //[function Add64]
  17373. {$IFDEF cpu86}
  17374. function Add64( const X, Y: I64 ): I64;
  17375. asm
  17376. PUSH ESI
  17377. XCHG ESI, EAX
  17378. LODSD
  17379. ADD EAX, [EDX]
  17380. MOV [ECX], EAX
  17381. LODSD
  17382. ADC EAX, [EDX+4]
  17383. MOV [ECX+4], EAX
  17384. POP ESI
  17385. end;
  17386. {$ELSE cpu86} //Pascal
  17387. function Add64( const X, Y: I64 ): I64;
  17388. begin
  17389. Int64(Result):=Int64(X)+Int64(Y);
  17390. end;
  17391. {$ENDIF cpu86}
  17392. //[function Sub64]
  17393. {$IFDEF cpu86}
  17394. function Sub64( const X, Y: I64 ): I64;
  17395. asm
  17396. PUSH ESI
  17397. XCHG ESI, EAX
  17398. LODSD
  17399. SUB EAX, [EDX]
  17400. MOV [ECX], EAX
  17401. LODSD
  17402. SBB EAX, [EDX+4]
  17403. MOV [ECX+4], EAX
  17404. POP ESI
  17405. end;
  17406. {$ELSE cpu86} //Pascal
  17407. function Sub64( const X, Y: I64 ): I64;
  17408. begin
  17409. Int64(Result):=Int64(X)-Int64(Y);
  17410. end;
  17411. {$ENDIF cpu86}
  17412. //[function Neg64]
  17413. {$IFDEF cpu86}
  17414. function Neg64( const X: I64 ): I64;
  17415. asm
  17416. MOV ECX, [EAX]
  17417. NEG ECX
  17418. MOV [EDX], ECX
  17419. MOV ECX, 0
  17420. SBB ECX, [EAX+4]
  17421. MOV [EDX+4], ECX
  17422. end;
  17423. {$ELSE cpu86} //Pascal
  17424. function Neg64( const X: I64 ): I64;
  17425. begin
  17426. Int64(Result):=-Int64(X);
  17427. end;
  17428. {$ENDIF cpu86}
  17429. {$IFDEF cpu86}
  17430. //[function Mul64EDX]
  17431. function Mul64EDX( const X: I64; M: Integer ): I64;
  17432. asm
  17433. PUSH ESI
  17434. PUSH EDI
  17435. XCHG ESI, EAX
  17436. MOV EDI, ECX
  17437. MOV ECX, EDX
  17438. LODSD
  17439. MUL ECX
  17440. STOSD
  17441. XCHG EDX, ECX
  17442. LODSD
  17443. MUL EDX
  17444. ADD EAX, ECX
  17445. STOSD
  17446. POP EDI
  17447. POP ESI
  17448. end;
  17449. //[FUNCTION Mul64i]
  17450. {$IFDEF ASM_VERSION}
  17451. {$ELSE ASM_VERSION} //Pascal
  17452. function Mul64i( const X: I64; Mul: Integer ): I64;
  17453. var Minus: Boolean;
  17454. begin
  17455. Minus := FALSE;
  17456. if Mul < 0 then
  17457. begin
  17458. Minus := TRUE;
  17459. Mul := -Mul;
  17460. end;
  17461. Result := Mul64EDX( X, Mul );
  17462. if Minus then
  17463. Result := Neg64( Result );
  17464. end;
  17465. {$ENDIF ASM_VERSION}
  17466. {$ELSE cpu86}
  17467. function Mul64i( const X: I64; Mul: Integer ): I64;
  17468. begin
  17469. Int64(Result):=Int64(X)*Mul;
  17470. end;
  17471. {$ENDIF cpu86}
  17472. //[END Mul64i]
  17473. {$IFDEF cpu86}
  17474. //[function Div64EDX]
  17475. function Div64EDX( const X: I64; D: Integer ): I64;
  17476. asm
  17477. PUSH ESI
  17478. PUSH EDI
  17479. XCHG ESI, EAX
  17480. MOV EDI, ECX
  17481. MOV ECX, EDX
  17482. MOV EAX, [ESI+4]
  17483. CDQ
  17484. DIV ECX
  17485. MOV [EDI+4], EAX
  17486. LODSD
  17487. DIV ECX
  17488. STOSD
  17489. POP EDI
  17490. POP ESI
  17491. end;
  17492. //[FUNCTION Div64i]
  17493. {$IFDEF ASM_VERSION}
  17494. {$ELSE ASM_VERSION} //Pascal
  17495. function Div64i( const X: I64; D: Integer ): I64;
  17496. var Minus: Boolean;
  17497. begin
  17498. Minus := FALSE;
  17499. if D < 0 then
  17500. begin
  17501. D := -D;
  17502. Minus := TRUE;
  17503. end;
  17504. Result := X;
  17505. if Sgn64( Result ) < 0 then
  17506. begin
  17507. Result := Neg64( Result );
  17508. Minus := not Minus;
  17509. end;
  17510. Result := Div64EDX( Result, D );
  17511. if Minus then
  17512. Result := Neg64( Result );
  17513. end;
  17514. {$ENDIF ASM_VERSION}
  17515. {$ELSE cpu86}
  17516. function Div64i( const X: I64; D: Integer ): I64;
  17517. begin
  17518. Int64(Result):=Int64(X) div D;
  17519. end;
  17520. {$ENDIF cpu86}
  17521. //[END Div64i]
  17522. //[function Mod64i]
  17523. function Mod64i( const X: I64; D: Integer ): Integer;
  17524. begin
  17525. Result := Sub64( X, Mul64i( Div64i( X, D ), D ) ).Lo;
  17526. end;
  17527. //[function Sgn64]
  17528. {$IFDEF cpu86}
  17529. function Sgn64( const X: I64 ): Integer;
  17530. asm
  17531. XOR EDX, EDX
  17532. CMP [EAX+4], EDX
  17533. XCHG EAX, EDX
  17534. JG @@ret_1
  17535. JL @@ret_neg
  17536. CMP [EDX], EAX
  17537. JZ @@exit
  17538. @@ret_1:
  17539. INC EAX
  17540. RET
  17541. @@ret_neg:
  17542. DEC EAX
  17543. @@exit:
  17544. end;
  17545. {$ELSE cpu86}
  17546. function Sgn64( const X: I64 ): Integer;
  17547. begin
  17548. if Int64(X) > 0 then
  17549. Result:=1
  17550. else
  17551. Result:=-1;
  17552. end;
  17553. {$ENDIF cpu86}
  17554. //[function Cmp64]
  17555. function Cmp64( const X, Y: I64 ): Integer;
  17556. begin
  17557. Result := Sgn64( Sub64( X, Y ) );
  17558. end;
  17559. //[function Int64_2Str]
  17560. function Int64_2Str( X: I64 ): String;
  17561. var M: Boolean;
  17562. Y: Integer;
  17563. Buf: array[ 0..31 ] of Char;
  17564. I: Integer;
  17565. begin
  17566. M := FALSE;
  17567. case Sgn64( X ) of
  17568. -1: begin M := TRUE; X := Neg64( X ); end;
  17569. 0: begin Result := '0'; Exit; end;
  17570. end;
  17571. I := 31;
  17572. Buf[ 31 ] := #0;
  17573. while Sgn64( X ) > 0 do
  17574. begin
  17575. Dec( I );
  17576. Y := Mod64i( X, 10 );
  17577. Buf[ I ] := Char( Y + Integer( '0' ) );
  17578. X := Div64i( X, 10 );
  17579. end;
  17580. if M then
  17581. begin
  17582. Dec( I );
  17583. Buf[ I ] := '-';
  17584. end;
  17585. Result := PChar( @Buf[ I ] );
  17586. end;
  17587. function Int64_2Hex( X: I64; MinDigits: Integer ): String;
  17588. begin
  17589. if (MinDigits <= 8) and (X.Hi <> 0) then
  17590. Result := Int2Hex( X.Hi, 1 ) + Int2Hex( X.Lo, 8 )
  17591. else if X.Hi <> 0 then
  17592. Result := Int2Hex( X.Hi, MinDigits - 8 ) + Int2Hex( X.Lo, 8 )
  17593. else
  17594. Result := Int2Hex( X.Lo, MinDigits );
  17595. end;
  17596. //[function Str2Int64]
  17597. function Str2Int64( const S: String ): I64;
  17598. var I: Integer;
  17599. M: Boolean;
  17600. begin
  17601. Result.Lo := 0;
  17602. Result.Hi := 0;
  17603. I := 1;
  17604. if S = '' then Exit;
  17605. M := FALSE;
  17606. if S[ 1 ] = '-' then
  17607. begin
  17608. M := TRUE;
  17609. Inc( I );
  17610. end
  17611. else
  17612. if S[ 1 ] = '+' then
  17613. Inc( I );
  17614. while I <= Length( S ) do
  17615. begin
  17616. if not( S[ I ] in [ '0'..'9' ] ) then
  17617. break;
  17618. Result := Mul64i( Result, 10 );
  17619. IncInt64( Result, Integer( S[ I ] ) - Integer( '0' ) );
  17620. Inc( I );
  17621. end;
  17622. if M then
  17623. Result := Neg64( Result );
  17624. end;
  17625. //[function Int64_2Double]
  17626. {$IFDEF cpu86}
  17627. function Int64_2Double( const X: I64 ): Double;
  17628. asm
  17629. FILD qword ptr [EAX]
  17630. FSTP @Result
  17631. end;
  17632. {$ELSE cpu86}
  17633. function Int64_2Double( const X: I64 ): Double;
  17634. begin
  17635. Result:=Int64(X);
  17636. end;
  17637. {$ENDIF cpu86}
  17638. //[function Double2Int64]
  17639. {$IFDEF cpu86}
  17640. function Double2Int64( D: Double ): I64;
  17641. asm
  17642. FLD D
  17643. FISTP qword ptr [EAX]
  17644. end;
  17645. {$ELSE cpu86}
  17646. function Double2Int64( D: Double ): I64;
  17647. begin
  17648. Int64(Result):=Trunc(D);
  17649. end;
  17650. {$ENDIF cpu86}
  17651. {+}
  17652. function IsNan(const AValue: Double): Boolean;
  17653. {$IFDEF _D2orD3}
  17654. type PI64 = ^I64;
  17655. {$ENDIF}
  17656. begin
  17657. {-}
  17658. Result := (PI64(@AValue).Hi and $7FF00000 = $7FF00000) and
  17659. ((PI64(@AValue).Hi and $000FFFFF <> 0) or (PI64(@AValue).Lo <> 0));
  17660. {+}{++}(*Result := AValue = NAN;*){--}
  17661. end;
  17662. function IsInfinity(const AValue: Double): Boolean;
  17663. {$IFDEF _D2orD3}
  17664. type PI64 = ^I64;
  17665. {$ENDIF}
  17666. begin
  17667. {-}
  17668. Result := (PI64(@AValue).Hi and $7FF00000 = $7FF00000) and
  17669. (PI64(@AValue).Hi and $000FFFFF = $00000000);
  17670. {+}{++}(*Result := AValue = Infinite;*){--}
  17671. end;
  17672. //[function IntPower]
  17673. function IntPower(Base: Extended; Exponent: Integer): Extended;
  17674. {$IFNDEF cpu86}
  17675. begin
  17676. {if Exponent = 0 then
  17677. begin
  17678. Result := 1.0;
  17679. Exit;
  17680. end;
  17681. if Exponent < 0 then
  17682. begin
  17683. Exponent := -Exponent;
  17684. Base := 1.0 / Base;
  17685. end;
  17686. Result := Base;
  17687. REPEAT
  17688. Result := Result * Base;
  17689. Dec( Exponent );
  17690. UNTIL Exponent <= 0;}
  17691. Result := 1.0;
  17692. if Exponent = 0 then exit;
  17693. if Exponent < 0 then begin
  17694. Exponent := -Exponent;
  17695. Base := 1.0 / Base;
  17696. end;
  17697. REPEAT
  17698. Result := Result * Base;
  17699. Dec( Exponent );
  17700. UNTIL Exponent=0;
  17701. end;
  17702. {$ELSE cpu86}
  17703. // This version of code by Galkov:
  17704. // Changes in comparison to Delphi standard:
  17705. // no Overflow exception if Exponent is very big negative value
  17706. // (just 0 in result in such case).
  17707. asm
  17708. fld1 { Result := 1 }
  17709. test eax,eax // check Exponent for 0, return 0 ** 0 = 1
  17710. jz @@3 // (though Mathematics says that this is not so...)
  17711. fld Base
  17712. jg @@2
  17713. fdivr ST,ST(1) { Base := 1 / Base }
  17714. neg eax
  17715. jmp @@2
  17716. @@1: fmul ST,ST { X := Base * Base }
  17717. @@2: shr eax,1
  17718. jnc @@1
  17719. fmul ST(1),ST { Result := Result * X }
  17720. jnz @@1
  17721. fstp st { pop X from FPU stack }
  17722. @@3: fwait
  17723. end;
  17724. {$ENDIF cpu86}
  17725. //[function Str2Double]
  17726. function Str2Double( const S: String ): Double;
  17727. var I: Integer;
  17728. M, Pt: Boolean;
  17729. D: Double;
  17730. Ex: Integer;
  17731. begin
  17732. Result := 0.0;
  17733. if S = '' then Exit;
  17734. M := FALSE;
  17735. I := 1;
  17736. if S[ 1 ] = '-' then
  17737. begin
  17738. M := TRUE;
  17739. Inc( I );
  17740. end;
  17741. Pt := FALSE;
  17742. D := 1.0;
  17743. while I <= Length( S ) do
  17744. begin
  17745. case S[ I ] of
  17746. '.': if not Pt then Pt := TRUE else break;
  17747. '0'..'9': if not Pt then
  17748. Result := Result * 10.0 + Integer( S[ I ] ) - Integer( '0' )
  17749. else
  17750. begin
  17751. D := D * 0.1;
  17752. Result := Result + (Integer( S[ I ] ) - Integer( '0' )) * D;
  17753. end;
  17754. 'e', 'E': begin
  17755. Ex := Str2Int( CopyEnd( S, I + 1 ) );
  17756. Result := Result * IntPower( 10.0, Ex );
  17757. break;
  17758. end;
  17759. end;
  17760. Inc( I );
  17761. end;
  17762. if M then
  17763. Result := -Result;
  17764. end;
  17765. function Str2Extended( const S: String ): Extended;
  17766. var I: Integer;
  17767. M, Pt: Boolean;
  17768. D: Extended;
  17769. Ex: Integer;
  17770. begin
  17771. Result := 0.0;
  17772. if S = '' then Exit;
  17773. M := FALSE;
  17774. I := 1;
  17775. if S[ 1 ] = '-' then
  17776. begin
  17777. M := TRUE;
  17778. Inc( I );
  17779. end;
  17780. Pt := FALSE;
  17781. D := 1.0;
  17782. while I <= Length( S ) do
  17783. begin
  17784. case S[ I ] of
  17785. '.': if not Pt then Pt := TRUE else break;
  17786. '0'..'9': if not Pt then
  17787. Result := Result * 10.0 + Integer( S[ I ] ) - Integer( '0' )
  17788. else
  17789. begin
  17790. D := D * 0.1;
  17791. Result := Result + (Integer( S[ I ] ) - Integer( '0' )) * D;
  17792. end;
  17793. 'e', 'E': begin
  17794. Ex := Str2Int( CopyEnd( S, I + 1 ) );
  17795. Result := Result * IntPower( 10.0, Ex );
  17796. break;
  17797. end;
  17798. end;
  17799. Inc( I );
  17800. end;
  17801. if M then
  17802. Result := -Result;
  17803. end;
  17804. //[function TruncD]
  17805. function TruncD( D: Double ): Double;
  17806. {$ifdef cpu86}
  17807. asm
  17808. FLD D
  17809. PUSH ECX
  17810. FNSTCW [ESP]
  17811. POP ECX
  17812. PUSH ECX
  17813. OR byte ptr [ESP+1], $0C
  17814. FLDCW [ESP]
  17815. PUSH ECX
  17816. FRNDINT
  17817. FSTP @Result
  17818. FLDCW [ESP]
  17819. POP ECX
  17820. POP ECX
  17821. end;
  17822. {$else cpu86}
  17823. begin
  17824. Result := Trunc( D );
  17825. end;
  17826. {$endif cpu86}
  17827. function IfThenElseBool( t, e: Boolean; Cond: Boolean ): Boolean;
  17828. begin
  17829. if cond then Result := t else Result := e;
  17830. end;
  17831. function IfThenElseInt( t, e: Integer; Cond: Boolean ): Integer;
  17832. begin
  17833. if cond then Result := t else Result := e;
  17834. end;
  17835. function IfThenElseStr( const t, e: String; Cond: Boolean ): String;
  17836. begin
  17837. if cond then Result := t else Result := e;
  17838. end;
  17839. {$IFDEF _D5orHigher}
  17840. function IfThenElse( t, e: Boolean; Cond: Boolean ): Boolean; overload;
  17841. begin
  17842. if cond then Result := t else Result := e;
  17843. end;
  17844. function IfThenElse( t, e: Integer; Cond: Boolean ): Integer; overload;
  17845. begin
  17846. if cond then Result := t else Result := e;
  17847. end;
  17848. function IfThenElse( t, e: String; Cond: Boolean ): String; overload;
  17849. begin
  17850. if cond then Result := t else Result := e;
  17851. end;
  17852. function IfThenElse( t, e: Double; Cond: Boolean ): Double; overload;
  17853. begin
  17854. if cond then Result := t else Result := e;
  17855. end;
  17856. {$ENDIF}
  17857. // Precision 15
  17858. //[function Extended2Str]
  17859. function Extended2Str( E: Extended ): String;
  17860. function UnpackFromBuf( const Buf: array of Byte; N: Integer ): String;
  17861. var I, J, K, L: Integer;
  17862. begin
  17863. SetLength( Result, 16 );
  17864. J := 1;
  17865. for I := 7 downto 0 do
  17866. begin
  17867. K := Buf[ I ] shr 4;
  17868. Result[ J ] := Char( Ord('0') + K );
  17869. Inc( J );
  17870. K := Buf[ I ] and $F;
  17871. Result[ J ] := Char( Ord('0') + K );
  17872. Inc( J );
  17873. end;
  17874. Assert( Result[ 1 ] = '0', 'error!' );
  17875. Delete( Result, 1, 1 );
  17876. if N <= 0 then
  17877. begin
  17878. while N < 0 do
  17879. begin
  17880. Result := '0' + Result;
  17881. Inc( N );
  17882. end;
  17883. Result := '0.' + Result;
  17884. end
  17885. else
  17886. if N < Length( Result ) then
  17887. begin
  17888. Result := Copy( Result, 1, N ) + '.' + CopyEnd( Result, N + 1 );
  17889. end
  17890. else
  17891. begin
  17892. while N > Length( Result ) do
  17893. begin
  17894. Result := Result + '0';
  17895. end;
  17896. Exit;
  17897. end;
  17898. L := Length( Result );
  17899. while L > 1 do
  17900. begin
  17901. if not (Result[ L ] in ['0','.']) then break;
  17902. Dec( L );
  17903. if Result[ L + 1 ] = '.' then break;
  17904. end;
  17905. if L < Length( Result ) then Delete( Result, L + 1, MaxInt );
  17906. end;
  17907. var
  17908. S: Boolean;
  17909. var F: Extended;
  17910. N: Integer;
  17911. Buf1: array[ 0..9 ] of Byte;
  17912. I10: Integer;
  17913. {$ifndef cpu86}
  17914. procedure e2bcd(e:Extended);
  17915. var
  17916. i:byte;
  17917. begin
  17918. e:=e+0.5;
  17919. for i := 0 to 9 do begin
  17920. e:=Trunc(e)/10;
  17921. Buf1[i]:=Trunc(frac(e)*10);
  17922. e:=Trunc(e)/10;
  17923. Buf1[i]:=(Trunc((frac(e)*10)) shl 4) or Buf1[i];
  17924. end;
  17925. end;
  17926. {$endif cpu86}
  17927. begin
  17928. Result := '0';
  17929. if E = 0 then Exit;
  17930. S := E < 0;
  17931. if S then E := -E;
  17932. N := 15;
  17933. F := 5E12;
  17934. I10 := 10;
  17935. while E < F do
  17936. begin
  17937. Dec( N );
  17938. E := E * I10;
  17939. end;
  17940. if N = 15 then
  17941. while E >= 1E13 do
  17942. begin
  17943. Inc( N );
  17944. E := E / I10;
  17945. end;
  17946. while TRUE do
  17947. begin
  17948. {$ifdef cpu86}
  17949. asm
  17950. FLD [E]
  17951. FBSTP [Buf1]
  17952. end;
  17953. {$else}
  17954. e2bcd(E);
  17955. {$endif cpu86}
  17956. if Buf1[ 7 ] <> 0 then break;
  17957. E := E * I10;
  17958. Dec( N );
  17959. end;
  17960. Result := UnpackFromBuf( Buf1, N );
  17961. if S then Result := '-' + Result;
  17962. end;
  17963. //[function Double2Str]
  17964. function Double2Str( D: Double ): String;
  17965. begin
  17966. Result := Extended2Str( D );
  17967. end;
  17968. //[function Double2StrEx]
  17969. function Double2StrEx( D: Double ): String;
  17970. var E, E1, E2: Double;
  17971. S: String;
  17972. begin
  17973. Result := Double2Str( D );
  17974. E := Str2Double( Result );
  17975. E1 := E - D;
  17976. if E1 < 0.0 then E1 := -E1;
  17977. if E1 < 1e-307 then Exit;
  17978. while TRUE do
  17979. begin
  17980. E := D - (E - D) * 0.3;
  17981. S := Double2Str( E );
  17982. if S = Result then break;
  17983. E := Str2Double( S );
  17984. E2 := E - D;
  17985. if E2 < 0.0 then E2 := -E2;
  17986. if E2 > E1 * 0.75 then break;
  17987. Result := S;
  17988. if E2 < E1 * 0.1 then break;
  17989. end;
  17990. end;
  17991. //[function GetBits]
  17992. function GetBits( N: DWORD; first, last: Byte ): DWord;
  17993. {$ifndef cpu86}
  17994. begin
  17995. Result := 0;
  17996. if last > 31 then last := 31;
  17997. if first > last then Exit;
  17998. Result := (N and not ($FFFFFFFF shl last)) shr first;
  17999. end;
  18000. {$else}
  18001. asm
  18002. XCHG EAX, EDX // (1) EDX=N, AL=first
  18003. {$IFDEF PARANOIA} DB $3C, 31 {$ELSE} CMP AL, 31 {$ENDIF} // first(AL) > 31 ?
  18004. JBE @@1 // (2) åñëè äà, òî Result := 0;
  18005. @@0:
  18006. XOR EAX, EAX // (2)
  18007. RET // (1)
  18008. @@1:
  18009. XCHG EAX, ECX // (1) AL = last CL = first
  18010. SHR EDX, CL // (2) EDX = N shr first
  18011. SUB AL, CL // (2) AL = last - first
  18012. JL @@0 // (2) åñëè last < first òî Result := 0;
  18013. {$IFDEF PARANOIA} DB $3C, 32 {$ELSE} CMP AL, 32 {$ENDIF} // (2) last - first >= 32 ?
  18014. XCHG ECX, EAX // (1) CL = last - first
  18015. XCHG EAX, EDX // (1) EAX = N shr first
  18016. JAE @@exit // (2) åñëè last - first > 31, òî Result := EAX;
  18017. SBB EDX, EDX // (2) EDX = -1
  18018. DEC EDX // (1) EDX = 1111...10 = -2
  18019. SHL EDX, CL // (2) EDX = 111...100..0 (ãäå n(0)=last-first+1)
  18020. NOT EDX // (2) EDX = ìàñêà 000..0111...1 (ãäå n(1)=last-first+1)
  18021. AND EAX, EDX // (2)
  18022. @@exit:
  18023. // EAX = ðåçóëüòàò, (1 áàéò íà êîìàíäó RET)
  18024. end;
  18025. {$endif cpu86}
  18026. //[function GetBitsL]
  18027. function GetBitsL( N: DWORD; from, len: Byte ): DWord;
  18028. {$ifndef cpu86}
  18029. begin
  18030. Result := GetBits( N, from, from + len - 1 );
  18031. end;
  18032. {$else}
  18033. asm
  18034. ADD CL, DL
  18035. DEC CL
  18036. JMP GetBits
  18037. end;
  18038. {$endif cpu86}
  18039. //[FUNCTION MulDiv]
  18040. {$IFNDEF FPC}
  18041. function MulDiv( A, B, C: Integer ): Integer;
  18042. asm
  18043. IMUL EDX
  18044. IDIV ECX
  18045. end;
  18046. {$ENDIF}
  18047. //[END MulDiv]
  18048. //[FUNCTION Int2Hex]
  18049. {$IFDEF ASM_VERSION}
  18050. {$ELSE ASM_VERSION} //Pascal (mixed)
  18051. function Int2Hex( Value : DWord; Digits : Integer ) : String;
  18052. var Buf: array[ 0..8 ] of Char;
  18053. Dest : PChar;
  18054. function HexDigit( B : Byte ) : Char;
  18055. {$ifdef FPC}
  18056. const
  18057. HexDigitChr: array[ 0..15 ] of Char = ( '0','1','2','3','4','5','6','7',
  18058. '8','9','A','B','C','D','E','F' );
  18059. begin
  18060. Result := HexDigitChr[ B and $F ];
  18061. end;
  18062. {$else Delphi}
  18063. asm
  18064. {$IFDEF PARANOIA} DB $3C,9 {$ELSE} CMP AL,9 {$ENDIF}
  18065. JA @@1
  18066. {$IFDEF PARANOIA} DB $04, $30-$41+$0A {$ELSE} ADD AL,30h-41h+0Ah {$ENDIF}
  18067. @@1:
  18068. {$IFDEF PARANOIA} DB $04, $41-$0A {$ELSE} ADD AL,41h-0Ah {$ENDIF}
  18069. end;
  18070. {$endif FPC}
  18071. begin
  18072. Dest := @Buf[ 8 ];
  18073. Dest^ := #0;
  18074. repeat
  18075. Dec( Dest );
  18076. Dest^ := '0';
  18077. if Value <> 0 then
  18078. begin
  18079. Dest^ := HexDigit( Value and $F );
  18080. Value := Value shr 4;
  18081. end;
  18082. Dec( Digits );
  18083. until (Value = 0) and (Digits <= 0);
  18084. Result := Dest;
  18085. end;
  18086. {$ENDIF ASM_VERSION}
  18087. //[END Int2Hex]
  18088. //[FUNCTION Hex2Int]
  18089. {$IFDEF ASM_VERSION}
  18090. {$ELSE ASM_VERSION} //Pascal
  18091. function Hex2Int( const Value : String) : Integer;
  18092. var I : Integer;
  18093. begin
  18094. Result := 0;
  18095. I := 1;
  18096. if Value = '' then Exit;
  18097. if Value[ 1 ] = '$' then Inc( I );
  18098. while I <= Length( Value ) do
  18099. begin
  18100. if Value[ I ] in [ '0'..'9' ] then
  18101. Result := (Result shl 4) or (Ord(Value[I]) - Ord('0'))
  18102. else
  18103. if Value[ I ] in [ 'A'..'F' ] then
  18104. Result := (Result shl 4) or (Ord(Value[I]) - Ord('A') + 10)
  18105. else
  18106. if Value[ I ] in [ 'a'..'f' ] then
  18107. Result := (Result shl 4) or (Ord(Value[I]) - Ord('a') + 10)
  18108. else
  18109. break;
  18110. Inc( I );
  18111. end;
  18112. end;
  18113. {$ENDIF ASM_VERSION}
  18114. //[END Hex2Int]
  18115. //[FUNCTION Octal2Int]
  18116. function Octal2Int( const Value: String ) : Integer;
  18117. var I: Integer;
  18118. begin
  18119. Result := 0;
  18120. for I := 1 to Length( Value ) do
  18121. begin
  18122. if Value[ I ] in [ '0'..'7' ] then
  18123. Result := Result * 8 + Ord( Value[ I ] ) - Ord( '0' )
  18124. else break;
  18125. end;
  18126. end;
  18127. //[END Octal2Int]
  18128. //[FUNCTION Binary2Int]
  18129. function Binary2Int( const Value: String ) : Integer;
  18130. var I: Integer;
  18131. begin
  18132. Result := 0;
  18133. for I := 1 to Length( Value ) do
  18134. begin
  18135. if Value[ I ] in [ '0'..'1' ] then
  18136. Result := Result * 2 + Ord( Value[ I ] ) - Ord( '0' )
  18137. else break;
  18138. end;
  18139. end;
  18140. //[END Binary2Int]
  18141. //[FUNCTION cHex2Int]
  18142. {$IFDEF ASM_VERSION}
  18143. {$ELSE ASM_VERSION}
  18144. function cHex2Int( const Value : String) : Integer;
  18145. begin
  18146. if StrEq( Copy( Value, 1, 2 ), '0x' ) then
  18147. Result := Hex2Int( CopyEnd( Value, 3 ) )
  18148. else Result := Hex2Int( Value );
  18149. end;
  18150. {$ENDIF ASM_VERSION}
  18151. //[END cHex2Int]
  18152. //[FUNCTION Int2Str]
  18153. {$IFDEF ASM_VERSION}
  18154. {$ELSE ASM_VERSION} //Pascal
  18155. function Int2Str( Value : Integer ) : String;
  18156. var Buf : array[ 0..15 ] of Char;
  18157. Dst : PChar;
  18158. Minus : Boolean;
  18159. D: DWORD;
  18160. begin
  18161. Dst := @Buf[ 15 ];
  18162. Dst^ := #0;
  18163. Minus := False;
  18164. if Value < 0 then
  18165. begin
  18166. Value := -Value;
  18167. Minus := True;
  18168. end;
  18169. D := Value;
  18170. repeat
  18171. Dec( Dst );
  18172. Dst^ := Char( (D mod 10) + Byte( '0' ) );
  18173. D := D div 10;
  18174. until D = 0;
  18175. if Minus then
  18176. begin
  18177. Dec( Dst );
  18178. Dst^ := '-';
  18179. end;
  18180. Result := Dst;
  18181. end;
  18182. {$ENDIF ASM_VERSION}
  18183. //[END Int2Str]
  18184. procedure Int2PChar( s: PChar; Value: Integer );
  18185. var Buf : array[ 0..15 ] of Char;
  18186. Dst : PChar;
  18187. Minus : Boolean;
  18188. D: DWORD;
  18189. begin
  18190. Dst := @Buf[ 15 ];
  18191. Dst^ := #0;
  18192. Minus := False;
  18193. if Value < 0 then
  18194. begin
  18195. Value := -Value;
  18196. Minus := True;
  18197. end;
  18198. D := Value;
  18199. repeat
  18200. Dec( Dst );
  18201. Dst^ := Char( (D mod 10) + Byte( '0' ) );
  18202. D := D div 10;
  18203. until D = 0;
  18204. if Minus then
  18205. begin
  18206. Dec( Dst );
  18207. Dst^ := '-';
  18208. end;
  18209. StrCopy( s, Dst );
  18210. end;
  18211. //[function UInt2Str]
  18212. function UInt2Str( Value: DWORD ): String;
  18213. var Buf : array[ 0..15 ] of Char;
  18214. Dst : PChar;
  18215. D: DWORD;
  18216. begin
  18217. Dst := @Buf[ 15 ];
  18218. Dst^ := #0;
  18219. D := Value;
  18220. repeat
  18221. Dec( Dst );
  18222. Dst^ := Char( (D mod 10) + Byte( '0' ) );
  18223. D := D div 10;
  18224. until D = 0;
  18225. Result := Dst;
  18226. end;
  18227. //[function Int2StrEx]
  18228. function Int2StrEx( Value, MinWidth: Integer ): String;
  18229. begin
  18230. Result := Int2Str( Value );
  18231. while Length( Result ) < MinWidth do
  18232. Result := ' ' + Result;
  18233. end;
  18234. //[function Int2Rome]
  18235. function Int2Rome( Value: Integer ): String;
  18236. const RomeDigs = 'IVXLCDMT';
  18237. function RomeNum( N, FromIdx: Integer ): String;
  18238. begin
  18239. CASE N OF
  18240. 1, 2, 3: Result := StrRepeat( RomeDigs[ FromIdx ], N );
  18241. 4: Result := RomeDigs[ FromIdx ] + RomeDigs[ FromIdx + 1 ];
  18242. 5, 6, 7, 8: Result := RomeDigs[ FromIdx + 1 ] + StrRepeat( RomeDigs[ FromIdx ],
  18243. N - 5 );
  18244. 9: Result := RomeDigs[ FromIdx ] + RomeDigs[ FromIdx + 2 ]
  18245. else Result := '';
  18246. END;
  18247. end;
  18248. var I, J: Integer;
  18249. begin
  18250. Result := '';
  18251. if Value < 1 then Exit;
  18252. if Value > 8999 then Exit;
  18253. // maximum possible is TMMMCMXCIX, i.e. 8999
  18254. J := 1;
  18255. for I := 1 to 3 do
  18256. begin
  18257. Result := RomeNum( Value mod 10, J ) + Result;
  18258. Value := Value div 10;
  18259. if Value = 0 then Exit;
  18260. Inc( J, 2 );
  18261. end;
  18262. end;
  18263. //[FUNCTION Int2Ths]
  18264. {$IFDEF ASM_VERSION}
  18265. {$ELSE ASM_VERSION} //Pascal
  18266. function Int2Ths( I : Integer ) : String;
  18267. var S : String;
  18268. begin
  18269. S := Int2Str( I );
  18270. Result := '';
  18271. while S <> '' do
  18272. begin
  18273. if Result <> '' then
  18274. Result := ThsSeparator + Result;
  18275. Result := CopyTail( S, 3 ) + Result;
  18276. S := Copy( S, 1, Length( S ) - 3 );
  18277. end;
  18278. if Copy( Result, 1, 2 ) = '-' + ThsSeparator then
  18279. Result := '-' + CopyEnd( Result, 3 );
  18280. end;
  18281. {$ENDIF ASM_VERSION}
  18282. //[END Int2Ths]
  18283. //[FUNCTION Int2Digs]
  18284. {$IFDEF ASM_VERSION}
  18285. {$ELSE ASM_VERSION} //Pascal
  18286. function Int2Digs( Value, Digits : Integer ) : String;
  18287. var M : String;
  18288. begin
  18289. Result := Int2Str( Value );
  18290. M := '';
  18291. if Value < 0 then
  18292. begin
  18293. M := '-';
  18294. Result := CopyEnd( Result, 2 );
  18295. end;
  18296. if Digits >= 0 then
  18297. while Length( M + Result ) < Digits do
  18298. Result := '0' + Result
  18299. else
  18300. while Length( Result ) < -Digits do
  18301. Result := '0' + Result;
  18302. Result := M + Result;
  18303. end;
  18304. {$ENDIF ASM_VERSION}
  18305. //[END Int2Digs]
  18306. //[FUNCTION Num2Bytes]
  18307. {$IFDEF ASM_VERSION}
  18308. {$ELSE ASM_VERSION} //Pascal
  18309. function Num2Bytes( Value : Double ) : String;
  18310. const Suffix = 'KMGT';
  18311. var V, I : Integer;
  18312. begin
  18313. Result := '';
  18314. I := 0;
  18315. while (Value >= 1024) and (I < 4) do
  18316. begin
  18317. Inc( I );
  18318. Value := Value / 1024.0;
  18319. end;
  18320. Result := Int2Str( Trunc( Value ) );
  18321. V := Trunc( (Value - Trunc( Value )) * 100 );
  18322. if V <> 0 then
  18323. begin
  18324. if (V mod 10) = 0 then
  18325. V := V div 10;
  18326. Result := Result + ',' + Int2Str( V );
  18327. end;
  18328. if I > 0 then
  18329. Result := Result + Suffix[ I ];
  18330. end;
  18331. {$ENDIF ASM_VERSION}
  18332. //[END Num2Bytes]
  18333. //[FUNCTION S2Int]
  18334. {$IFDEF ASM_VERSION}
  18335. {$ELSE ASM_VERSION} //Pascal
  18336. function S2Int( S: PChar ): Integer;
  18337. var M : Integer;
  18338. begin
  18339. Result := 0;
  18340. if S = '' then Exit;
  18341. M := 1;
  18342. if S^ = '-' then
  18343. begin
  18344. M := -1;
  18345. Inc( S );
  18346. end
  18347. else
  18348. if S^ = '+' then
  18349. Inc( S );
  18350. while S^ in [ '0'..'9' ] do
  18351. begin
  18352. Result := Result * 10 + Integer( S^ ) - Integer( '0' );
  18353. Inc( S );
  18354. end;
  18355. if M < 0 then
  18356. Result := -Result;
  18357. end;
  18358. {$ENDIF ASM_VERSION}
  18359. //[END S2Int]
  18360. //[FUNCTION Str2Int]
  18361. {$IFDEF ASM_VERSION}
  18362. {$ELSE ASM_VERSION} //Pascal
  18363. function Str2Int(const Value : String) : Integer;
  18364. begin
  18365. Result := S2Int( PChar( Value ) );
  18366. end;
  18367. {$ENDIF ASM_VERSION}
  18368. //[END Str2Int]
  18369. //[function StrCopy]
  18370. {$ifdef cpu86}
  18371. function StrCopy( Dest, Source: PChar ): PChar; assembler;
  18372. asm
  18373. {$IFDEF F_P}
  18374. MOV EAX, [Dest]
  18375. MOV EDX, [Source]
  18376. {$ENDIF F_P}
  18377. PUSH EDI
  18378. PUSH ESI
  18379. MOV ESI,EAX
  18380. MOV EDI,EDX
  18381. OR ECX, -1
  18382. XOR AL,AL
  18383. REPNE SCASB
  18384. NOT ECX
  18385. MOV EDI,ESI
  18386. MOV ESI,EDX
  18387. MOV EDX,ECX
  18388. MOV EAX,EDI
  18389. SHR ECX,2
  18390. REP MOVSD
  18391. MOV ECX,EDX
  18392. AND ECX,3
  18393. REP MOVSB
  18394. POP ESI
  18395. POP EDI
  18396. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18397. {$else}
  18398. function StrCopy( Dest, Source: PChar ): PChar;
  18399. var
  18400. counter : SizeInt;
  18401. Begin
  18402. counter := 0;
  18403. while Source[counter] <> #0 do
  18404. begin
  18405. Dest[counter] := char(Source[counter]);
  18406. Inc(counter);
  18407. end;
  18408. Dest[counter] := #0;
  18409. StrCopy := Dest;
  18410. end;
  18411. {$endif cpu86}
  18412. function StrCat( Dest, Source: PChar ): PChar;
  18413. begin
  18414. StrCopy( StrScan( Dest, #0 ), Source );
  18415. Result := Dest;
  18416. end;
  18417. //[function StrScan]
  18418. {$ifdef cpu86}
  18419. function StrScan(Str: PChar; Chr: Char): PChar; assembler;
  18420. asm
  18421. {$IFDEF F_P}
  18422. MOV EAX, [Str]
  18423. MOVZX EDX, [Chr]
  18424. {$ENDIF}
  18425. PUSH EDI
  18426. PUSH EAX
  18427. MOV EDI,Str
  18428. OR ECX, -1
  18429. XOR AL,AL
  18430. REPNE SCASB
  18431. NOT ECX
  18432. POP EDI
  18433. XCHG EAX, EDX
  18434. REPNE SCASB
  18435. XCHG EAX, EDI
  18436. POP EDI
  18437. JE @@1
  18438. XOR EAX, EAX
  18439. RET
  18440. @@1: DEC EAX
  18441. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18442. {$else}
  18443. function StrScan(Str: PChar; Chr: Char): PChar;
  18444. Begin
  18445. repeat
  18446. if Str^ = Chr then begin
  18447. Result := Str;
  18448. exit;
  18449. end;
  18450. Inc(Str);
  18451. until Str^ = #0;
  18452. StrScan := nil;
  18453. end;
  18454. {$endif cpu86}
  18455. //[function StrRScan]
  18456. {$ifdef cpu86}
  18457. function StrRScan(const Str: PChar; Chr: Char): PChar; assembler;
  18458. asm
  18459. {$IFDEF F_P}
  18460. MOV EAX, [Str]
  18461. MOVZX EDX, [Chr]
  18462. {$ENDIF F_P}
  18463. PUSH EDI
  18464. MOV EDI,Str
  18465. MOV ECX,0FFFFFFFFH
  18466. XOR AL,AL
  18467. REPNE SCASB
  18468. NOT ECX
  18469. STD
  18470. DEC EDI
  18471. MOV AL,Chr
  18472. REPNE SCASB
  18473. MOV EAX,0
  18474. JNE @@1
  18475. MOV EAX,EDI
  18476. INC EAX
  18477. @@1: CLD
  18478. POP EDI
  18479. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18480. {$else}
  18481. function StrRScan(const Str: PChar; Chr: Char): PChar;
  18482. Var
  18483. count: longint;
  18484. index: longint;
  18485. Begin
  18486. count := Strlen(Str);
  18487. if Chr = #0 then
  18488. begin
  18489. StrRScan := @(Str[count]);
  18490. exit;
  18491. end;
  18492. Dec(count);
  18493. for index := count downto 0 do
  18494. begin
  18495. if Chr = Str[index] then
  18496. begin
  18497. StrRScan := @(Str[index]);
  18498. exit;
  18499. end;
  18500. end;
  18501. StrRScan := nil;
  18502. end;
  18503. {$endif cpu86}
  18504. //[function StrScanLen]
  18505. {$ifdef cpu86}
  18506. function StrScanLen(Str: PChar; Chr: Char; Len: Integer): PChar; assembler;
  18507. asm
  18508. {$IFDEF F_P}
  18509. MOV EAX, [Str]
  18510. MOVZX EDX, [Chr]
  18511. MOV ECX, [Len]
  18512. {$ENDIF F_P}
  18513. PUSH EDI
  18514. XCHG EDI, EAX
  18515. XCHG EAX, EDX
  18516. REPNE SCASB
  18517. XCHG EAX, EDI
  18518. POP EDI
  18519. { -> EAX => to next character after found or to the end of Str,
  18520. ZF = 0 if character found. }
  18521. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18522. {$else}
  18523. function StrScanLen(Str: PChar; Chr: Char; Len: Integer): PChar;
  18524. Begin
  18525. Result:=Str;
  18526. while Len > 0 do begin
  18527. if Result^ = Chr then begin
  18528. Inc(Result);
  18529. break;
  18530. end;
  18531. Inc(Result);
  18532. Dec(Len);
  18533. end;
  18534. end;
  18535. {$endif cpu86}
  18536. //[FUNCTION TrimLeft]
  18537. {$IFDEF ASM_UNICODE}
  18538. {$ELSE ASM_VERSION} //Pascal
  18539. function TrimLeft(const S: KOLstring): KOLstring;
  18540. var
  18541. I, L: Integer;
  18542. begin
  18543. L := Length(S);
  18544. I := 1;
  18545. while (I <= L) and (S[I] <= ' ') do Inc(I);
  18546. Result := Copy(S, I, Maxint);
  18547. end;
  18548. {$ENDIF ASM_VERSION}
  18549. //[END TrimLeft]
  18550. //[FUNCTION TrimRight]
  18551. {$IFDEF ASM_UNICODE}
  18552. {$ELSE ASM_VERSION} //Pascal
  18553. function TrimRight(const S: KOLstring): KOLstring;
  18554. var
  18555. I: Integer;
  18556. begin
  18557. I := Length(S);
  18558. while (I > 0) and (S[I] <= ' ') do Dec(I);
  18559. Result := Copy(S, 1, I);
  18560. end;
  18561. {$ENDIF ASM_VERSION}
  18562. //[END TrimRight]
  18563. //[FUNCTION Trim]
  18564. {$IFDEF ASM_UNICODE}
  18565. {$ELSE ASM_VERSION} //Pascal
  18566. function Trim( const S : KOLstring): KOLstring;
  18567. begin
  18568. Result := TrimLeft( TrimRight( S ) );
  18569. end;
  18570. {$ENDIF ASM_VERSION}
  18571. //[END Trim]
  18572. //[function RemoveSpaces]
  18573. function RemoveSpaces( const S: String ): String;
  18574. var I: Integer;
  18575. begin
  18576. Result := S;
  18577. for I := Length( S ) downto 1 do
  18578. if S[ I ] <= ' ' then Delete( Result, I, 1 );
  18579. end;
  18580. //[procedure Str2LowerCase]
  18581. {$ifdef cpu86}
  18582. procedure Str2LowerCase( S: PChar );
  18583. asm
  18584. {$IFDEF F_P}
  18585. MOV EAX, [S]
  18586. {$ENDIF}
  18587. XOR ECX, ECX
  18588. @@1:
  18589. MOV CL, byte ptr [EAX]
  18590. JECXZ @@exit
  18591. SUB CL, 'A'
  18592. CMP CL, 'Z'-'A'
  18593. JA @@2
  18594. ADD byte ptr [EAX], 32
  18595. @@2: INC EAX
  18596. JMP @@1
  18597. @@exit:
  18598. end {$IFDEF F_P} [ 'EAX', 'ECX' ] {$ENDIF};
  18599. {$else}
  18600. procedure Str2LowerCase( S: PChar );
  18601. begin
  18602. while S^ <> #0 do begin
  18603. if S^ in [ 'A'..'Z' ] then
  18604. Inc( S^, 32 );
  18605. Inc(S);
  18606. end;
  18607. end;
  18608. {$endif cpu86}
  18609. //[FUNCTION LowerCase]
  18610. {$IFDEF ASM_VERSION}
  18611. {$ELSE ASM_VERSION} //Pascal
  18612. function LowerCase(const S: string): string;
  18613. var I : Integer;
  18614. begin
  18615. Result := S;
  18616. for I := 1 to Length( S ) do
  18617. if Result[ I ] in [ 'A'..'Z' ] then
  18618. Inc( Result[ I ], 32 );
  18619. end;
  18620. {$ENDIF ASM_VERSION}
  18621. //[END LowerCase]
  18622. //[FUNCTION UpperCase]
  18623. {$IFDEF ASM_VERSION}
  18624. {$ELSE ASM_VERSION} //Pascal
  18625. function UpperCase(const S: string): string;
  18626. var I : Integer;
  18627. begin
  18628. Result := S;
  18629. for I := 1 to Length( S ) do
  18630. if Result[ I ] in [ 'a'..'z' ] then
  18631. Dec( Result[ I ], 32 );
  18632. end;
  18633. {$ENDIF ASM_VERSION}
  18634. //[END UpperCase]
  18635. {$IFDEF F_P}
  18636. //[function DummyStrFun]
  18637. function DummyStrFun( const S: String ): String;
  18638. begin
  18639. Result := S;
  18640. end;
  18641. {$ENDIF F_P}
  18642. //[FUNCTION CopyEnd]
  18643. {$IFDEF ASM_UNICODE}
  18644. {$ELSE ASM_VERSION} //Pascal
  18645. function CopyEnd( const S : KOLString; Idx : Integer ) : KOLString;
  18646. begin
  18647. Result := Copy( S, Idx, MaxInt );
  18648. end;
  18649. {$ENDIF ASM_VERSION}
  18650. //[END CopyEnd]
  18651. //[FUNCTION CopyTail]
  18652. {$IFDEF ASM_UNICODE}
  18653. {$ELSE ASM_VERSION} //Pascal
  18654. function CopyTail( const S : KOLString; Len : Integer ) : KOLString;
  18655. var L : Integer;
  18656. begin
  18657. L := Length( S );
  18658. if L < Len then
  18659. Len := L;
  18660. Result := '';
  18661. if Len = 0 then Exit;
  18662. Result := Copy( S, L - Len + 1, Len );
  18663. end;
  18664. {$ENDIF ASM_VERSION}
  18665. //[END CopyTail]
  18666. //[PROCEDURE DeleteTail]
  18667. {$IFDEF ASM_UNICODE}
  18668. {$ELSE ASM_VERSION} //Pascal
  18669. procedure DeleteTail( var S : KOLString; Len : Integer );
  18670. var L : Integer;
  18671. begin
  18672. L := Length( S );
  18673. if Len > L then
  18674. Len := L;
  18675. Delete( S, L - Len + 1, Len );
  18676. end;
  18677. {$ENDIF ASM_VERSION}
  18678. //[END DeleteTail]
  18679. //[FUNCTION IndexOfChar]
  18680. {$IFDEF ASM_VERSION}
  18681. {$ELSE ASM_VERSION} //Pascal
  18682. function IndexOfChar( const S : String; Chr : Char ) : Integer;
  18683. var P, F : PChar;
  18684. begin
  18685. P := PChar( S );
  18686. F := StrScan( P, Chr );
  18687. Result := -1;
  18688. if F = nil then Exit;
  18689. Result := cardinal( F ) - cardinal( P ) + 1;
  18690. end;
  18691. {$ENDIF ASM_VERSION}
  18692. //[END IndexOfChar]
  18693. //[FUNCTION IndexOfCharsMin]
  18694. {$IFDEF ASM_VERSION}
  18695. {$ELSE ASM_VERSION} //Pascal
  18696. function IndexOfCharsMin( const S, Chars : String ) : Integer;
  18697. var I, J : Integer;
  18698. begin
  18699. Result := -1;
  18700. for I := 1 to Length( Chars ) do
  18701. begin
  18702. J := IndexOfChar( S, Chars[ I ] );
  18703. if J > 0 then
  18704. begin
  18705. if (Result < 0) or (J < Result) then
  18706. Result := J;
  18707. end;
  18708. end;
  18709. end;
  18710. {$ENDIF ASM_VERSION}
  18711. //[END IndexOfCharsMin]
  18712. {$IFNDEF _FPC}
  18713. {$IFNDEF _D2}
  18714. //[function IndexOfWideCharsMin]
  18715. function IndexOfWideCharsMin( const S, Chars : WideString ) : Integer;
  18716. var I, J : Integer;
  18717. begin
  18718. Result := -1;
  18719. for I := 1 to Length( Chars ) do
  18720. begin
  18721. J := pos( Chars[ I ], S );
  18722. if J > 0 then
  18723. begin
  18724. if (Result < 0) or (J < Result) then
  18725. Result := J;
  18726. end;
  18727. end;
  18728. end;
  18729. {$ENDIF _D2}
  18730. {$ENDIF _FPC}
  18731. //[FUNCTION IndexOfStr]
  18732. {$IFDEF ASM_VERSION}
  18733. {$ELSE ASM_VERSION} //Pascal
  18734. function IndexOfStr( const S, Sub : String ) : Integer;
  18735. var I : Integer;
  18736. begin
  18737. Result := Length( S );
  18738. if Sub = '' then Exit;
  18739. Result := 0;
  18740. if S = '' then Exit;
  18741. if Length( Sub ) > Length( S ) then Exit;
  18742. Result := 1;
  18743. while Result + Length( Sub ) - 1 <= Length( S ) do
  18744. begin
  18745. I := IndexOfChar( CopyEnd( S, Result ), Sub[ 1 ] );
  18746. if I <= 0 then break;
  18747. Result := Result + I - 1;
  18748. if Result <= 0 then Exit;
  18749. if Copy( S, Result, Length( Sub ) ) = Sub then Exit;
  18750. Inc( Result );
  18751. end;
  18752. Result := -1;
  18753. end;
  18754. {$ENDIF ASM_VERSION}
  18755. //[END IndexOfStr]
  18756. //[FUNCTION Parse]
  18757. {$IFDEF ASM_UNICODE} //???
  18758. function Parse( var S : String; const Separators : String ) : String;
  18759. asm
  18760. PUSH EBX
  18761. PUSH EDI
  18762. MOV EBX, EAX
  18763. PUSH ECX
  18764. MOV EAX, [EBX]
  18765. CALL IndexOfCharsMin
  18766. INC EAX
  18767. JNE @@1
  18768. MOV EAX, [EBX]
  18769. CALL System.@LStrLen
  18770. INC EAX
  18771. INC EAX
  18772. @@1:
  18773. DEC EAX
  18774. MOV EDI, EAX
  18775. MOV ECX, EAX
  18776. DEC ECX
  18777. XOR EDX, EDX
  18778. INC EDX
  18779. MOV EAX, [EBX]
  18780. CALL System.@LStrCopy
  18781. MOV EAX, [EBX]
  18782. MOV EDX, EDI
  18783. INC EDX
  18784. MOV ECX, EBX
  18785. CALL CopyEnd
  18786. POP EDI
  18787. POP EBX
  18788. end;
  18789. {$ELSE ASM_VERSION} //Pascal
  18790. function Parse( var S : KOLString; const Separators : KOLString ) : KOLString;
  18791. var Pos : Integer;
  18792. begin
  18793. Pos := IndexOfCharsMin( S, Separators );
  18794. if Pos <= 0 then
  18795. Pos := Length( S ) + 1;
  18796. Result := S;
  18797. S := Copy( Result, Pos + 1, MaxInt );
  18798. Result := Copy( Result, 1, Pos - 1 );
  18799. end;
  18800. {$ENDIF ASM_VERSION}
  18801. //[END Parse]
  18802. {$IFNDEF _FPC}
  18803. {$IFNDEF _D2}
  18804. //[function WParse]
  18805. function WParse( var S : WideString; const Separators : WideString ) : WideString;
  18806. var Pos : Integer;
  18807. begin
  18808. Pos := IndexOfWideCharsMin( S, Separators );
  18809. if Pos <= 0 then
  18810. Pos := Length( S ) + 1;
  18811. Result := S;
  18812. S := Copy( Result, Pos + 1, MaxInt );
  18813. Result := Copy( Result, 1, Pos - 1 );
  18814. end;
  18815. {$ENDIF _D2}
  18816. {$ENDIF _FPC}
  18817. //[function ParsePascalString]
  18818. function ParsePascalString( var S : String; const Separators : String ) : String;
  18819. var Pos, Idx : Integer;
  18820. Hex, Spc : boolean;
  18821. procedure SkipSpaces;
  18822. begin
  18823. if not Spc then
  18824. while (Length( S ) >= Pos) and (S[ Pos ] = ' ') do
  18825. Inc( Pos );
  18826. end;
  18827. var Buf : String;
  18828. Ou, Val : Integer;
  18829. begin
  18830. Pos := 1;
  18831. Spc := IndexOfChar( Separators, ' ' ) >= 0;
  18832. SkipSpaces;
  18833. if Length( S ) < Pos then
  18834. begin
  18835. Result := S;
  18836. S := '';
  18837. exit;
  18838. end;
  18839. Buf := PChar( S );
  18840. Ou := 1;
  18841. if S[ Pos ] in [ '''', '#' ] then
  18842. begin
  18843. // skip here string constant expression
  18844. while Pos <= Length( S ) do
  18845. begin
  18846. if S[ Pos ] = '''' then
  18847. begin
  18848. Inc( Pos );
  18849. while Pos <= Length( S ) do
  18850. begin
  18851. if S[ Pos ] = '''' then
  18852. if (Pos = Length( S )) or (S[ Pos+1 ] <> '''') then
  18853. begin
  18854. Inc( Pos );
  18855. break;
  18856. end
  18857. else Inc( Pos );
  18858. Buf[ Ou ] := S[ Pos ];
  18859. Inc( Ou );
  18860. Inc( Pos );
  18861. end;
  18862. end
  18863. else
  18864. if S[ Pos ] = '#' then
  18865. begin
  18866. Inc( Pos ); Hex := False; Val := 0;
  18867. if (Pos < Length( S )) and (S[ Pos ] = '$') then
  18868. begin
  18869. Inc( Pos ); Hex := True;
  18870. end;
  18871. Dec( Pos );
  18872. while Pos < Length( S ) do
  18873. begin
  18874. Inc( Pos );
  18875. if (S[ Pos ] in [ '0'..'9' ]) or
  18876. Hex and (S[ Pos ] in [ 'a'..'f', 'A'..'F' ]) then
  18877. begin
  18878. if Hex then
  18879. Val := Val * 16
  18880. else
  18881. Val := Val * 10;
  18882. if S[ Pos ] <= '9' then
  18883. Val := Val + Integer( S[ Pos ] ) - Integer( '0' )
  18884. else
  18885. if S[ Pos ] <= 'F' then
  18886. Val := Val + 10 + Integer( S[ Pos ] ) - Integer( 'A' )
  18887. else
  18888. Val := Val + 10 + Integer( S[ Pos ] ) - Integer( 'a' );
  18889. continue;
  18890. end;
  18891. Inc( Pos ); break;
  18892. end;
  18893. Buf[ Ou ] := Char( Val );
  18894. Inc( Ou );
  18895. end
  18896. else break;
  18897. SkipSpaces;
  18898. if S[ Pos ] <> '+' then break;
  18899. SkipSpaces;
  18900. end;
  18901. end;
  18902. Idx := IndexOfCharsMin( CopyEnd( S, Pos ), Separators );
  18903. if Idx <= 0 then
  18904. begin
  18905. Result := Copy( Buf, 1, Ou - 1 ) + CopyEnd( S, Pos );
  18906. S := '';
  18907. end
  18908. else
  18909. begin
  18910. Result := Copy( Buf, 1, Ou - 1 ) + Copy( S, Pos, Idx - 1 );
  18911. S := CopyEnd( S, Pos + Idx );
  18912. end;
  18913. end;
  18914. //[function String2PascalStrExpr]
  18915. function String2PascalStrExpr( const S : String ) : String;
  18916. var I, Strt : Integer;
  18917. function String2DoubleQuotas( const S : String ) : String;
  18918. var I, J : Integer;
  18919. begin
  18920. if IndexOfChar( S, '''' ) <= 0 then
  18921. Result := S
  18922. else
  18923. begin
  18924. J := 0;
  18925. for I := 1 to Length( S ) do
  18926. if S[ I ] = '''' then Inc( J );
  18927. SetLength( Result, Length( S ) + J );
  18928. J := 1;
  18929. for I := 1 to Length( S ) do
  18930. begin
  18931. Result[ J ] := S[ I ];
  18932. Inc( J );
  18933. if S[ I ] = '''' then
  18934. begin
  18935. Result[ J ] := '''';
  18936. Inc( J );
  18937. end;
  18938. end;
  18939. end;
  18940. end;
  18941. begin
  18942. Result := '';
  18943. if S = '' then
  18944. begin
  18945. Result := '''''';
  18946. exit;
  18947. end;
  18948. Strt := 1;
  18949. for I := 1 to Length( S ) + 1 do
  18950. begin
  18951. if (I > Length( S )) or (S[ I ] < ' ') or (S[ I ] >= #$7F) then
  18952. begin
  18953. if (I > Strt) and (I > 1) then
  18954. begin
  18955. if Result <> '' then
  18956. Result := Result + '+';
  18957. Result := Result + '''' + String2DoubleQuotas( Copy( S, Strt, I - Strt ) ) + '''';
  18958. end;
  18959. if I > Length( S ) then break;
  18960. if Result <> '' then
  18961. Result := Result + '+'
  18962. else
  18963. Result := Result + '''''+';
  18964. Result := Result + '#' + Int2Str( Integer( S[ I ] ) );
  18965. Strt := I + 1;
  18966. end;
  18967. end;
  18968. end;
  18969. //[function CompareMem]
  18970. {$ifdef cpu86}
  18971. function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;
  18972. asm
  18973. {$IFDEF F_P}
  18974. MOV EAX, [P1]
  18975. MOV EDX, [P2]
  18976. MOV ECX, [Length]
  18977. {$ENDIF}
  18978. PUSH ESI
  18979. PUSH EDI
  18980. MOV ESI,P1
  18981. MOV EDI,P2
  18982. MOV EDX,ECX
  18983. XOR EAX,EAX
  18984. AND EDX,3
  18985. SHR ECX,1
  18986. SHR ECX,1
  18987. REPE CMPSD
  18988. JNE @@2
  18989. MOV ECX,EDX
  18990. REPE CMPSB
  18991. JNE @@2
  18992. @@1: INC EAX
  18993. @@2: POP EDI
  18994. POP ESI
  18995. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18996. {$else}
  18997. function CompareMem(P1, P2: Pointer; Length: Integer): Boolean;
  18998. var
  18999. i: Integer;
  19000. begin
  19001. Result:=True;
  19002. I:=0;
  19003. If (P1)<>(P2) then
  19004. While Result and (i<Length) do
  19005. begin
  19006. Result:=PByte(P1)^=PByte(P2)^;
  19007. Inc(I);
  19008. Inc(pchar(P1));
  19009. Inc(pchar(P2));
  19010. end;
  19011. end;
  19012. {$endif cpu86}
  19013. //[FUNCTION AllocMem]
  19014. {$IFDEF ASM_VERSION}
  19015. {$ELSE ASM_VERSION} //Pascal
  19016. function AllocMem( Size : Integer ) : Pointer;
  19017. begin
  19018. Result := nil;
  19019. if Size > 0 then
  19020. begin
  19021. GetMem( Result, Size );
  19022. FillChar( Result^, Size, 0 );
  19023. end;
  19024. end;
  19025. {$ENDIF ASM_VERSION}
  19026. //[END AllocMem]
  19027. //[procedure DisposeMem]
  19028. procedure DisposeMem( var Addr : Pointer );
  19029. begin
  19030. if Addr <> nil then
  19031. FreeMem( Addr );
  19032. Addr := nil;
  19033. end;
  19034. {$IFDEF WIN}
  19035. //[function AnsiUpperCase]
  19036. function AnsiUpperCase(const S: string): string;
  19037. {$ifdef wince}
  19038. begin
  19039. Result:=WAnsiUpperCase(S);
  19040. end;
  19041. {$else}
  19042. var Len: Integer;
  19043. begin
  19044. Len := Length(S);
  19045. SetString(Result, PChar(S), Len);
  19046. if Len > 0 then CharUpperBuffA(Pointer(Result), Len);
  19047. end;
  19048. {$endif wince}
  19049. //[function AnsiLowerCase]
  19050. function AnsiLowerCase(const S: string): string;
  19051. {$ifdef wince}
  19052. begin
  19053. Result:=WAnsiLowerCase(S);
  19054. end;
  19055. {$else}
  19056. var
  19057. Len: Integer;
  19058. begin
  19059. Len := Length(S);
  19060. SetString(Result, PChar(S), Len);
  19061. if Len > 0 then CharLowerBuffA(Pointer(Result), Len);
  19062. end;
  19063. {$endif wince}
  19064. {$ENDIF WIN}
  19065. {$IFNDEF _D2}
  19066. {$IFNDEF _FPC}
  19067. //[function WAnsiUpperCase]
  19068. {$IFDEF WIN}
  19069. function WAnsiUpperCase(const S: WideString): WideString;
  19070. var Len: Integer;
  19071. begin
  19072. Result := S;
  19073. Len := Length(S);
  19074. if Len > 0 then CharUpperBuffW(Pointer(Result), Len);
  19075. end;
  19076. {$ENDIF WIN}
  19077. //[function WAnsiLowerCase]
  19078. {$IFDEF WIN}
  19079. function WAnsiLowerCase(const S: WideString): WideString;
  19080. var Len: Integer;
  19081. begin
  19082. Result := S;
  19083. Len := Length(S);
  19084. if Len > 0 then CharLowerBuffW(Pointer(Result), Len);
  19085. end;
  19086. {$ENDIF WIN}
  19087. {$IFDEF WIN}
  19088. function WStrComp(const S1, S2: WideString): Integer;
  19089. var i: Integer;
  19090. begin
  19091. for i := 1 to min( Length( S1 ), Length( S2 ) ) do
  19092. begin
  19093. Result := Ord( S1[ i ] ) - Ord( S2[ i ] );
  19094. if Result <> 0 then Exit;
  19095. end;
  19096. Result := Length( S1 ) - Length( S2 );
  19097. end;
  19098. function _WStrComp(S1, S2: PWideChar): Integer;
  19099. var Buf0: array[ 0..0 ] of WideChar;
  19100. begin
  19101. Buf0[ 0 ] := #0;
  19102. if S1 = nil then S1 := @ Buf0[ 0 ];
  19103. if S2 = nil then S2 := @ Buf0[ 0 ];
  19104. while TRUE do
  19105. begin
  19106. Result := Ord( S1^ ) - Ord( S2^ );
  19107. if Result <> 0 then Exit;
  19108. if S1^ = #0 then Exit;
  19109. end;
  19110. end;
  19111. function WStrScan(Str: PWideChar; Chr: WideChar): PWideChar;
  19112. begin
  19113. while (Str^ <> Chr) and (Str^ <> #0) do inc( Str );
  19114. Result := Str;
  19115. end;
  19116. function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar;
  19117. begin
  19118. Result := Str;
  19119. while Result^ <> #0 do inc( Result );
  19120. while (DWORD( Result ) >= DWORD( Str )) and
  19121. (Result^ <> Chr) do dec( Result );
  19122. if (DWORD( Result ) < DWORD( Str )) then
  19123. Result := nil;
  19124. end;
  19125. {$ENDIF WIN}
  19126. {$ENDIF _FPC}
  19127. {$ENDIF _D2}
  19128. //[function AnsiCompareStr]
  19129. {$IFDEF WIN}
  19130. function AnsiCompareStr(const S1, S2: KOLString): Integer;
  19131. begin
  19132. Result := CompareString(LOCALE_USER_DEFAULT, 0, PKOLChar(S1), -1, PKOLChar(S2), -1 ) - 2;
  19133. end;
  19134. {$ENDIF WIN}
  19135. //[function _AnsiCompareStr]
  19136. {$IFDEF WIN}
  19137. function _AnsiCompareStr(S1, S2: PKOLChar): Integer;
  19138. begin
  19139. Result := CompareString( LOCALE_USER_DEFAULT, 0, S1, -1,
  19140. S2, -1) - 2;
  19141. end;
  19142. {$ENDIF WIN}
  19143. //[function AnsiCompareStrNoCase]
  19144. {$IFDEF WIN}
  19145. function AnsiCompareStrNoCase(const S1, S2: KOLString): Integer;
  19146. begin
  19147. Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PKOLChar(S1), -1,
  19148. PKOLChar(S2), -1 ) - 2;
  19149. end;
  19150. {$ENDIF WIN}
  19151. //[function _AnsiCompareStrNoCase]
  19152. {$IFDEF WIN}
  19153. function _AnsiCompareStrNoCase(S1, S2: PKOLChar): Integer;
  19154. begin
  19155. Result := CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1, -1,
  19156. S2, -1) - 2;
  19157. end;
  19158. {$ENDIF WIN}
  19159. //[function AnsiCompareText]
  19160. function AnsiCompareText( const S1, S2: String ): Integer;
  19161. begin
  19162. Result := AnsiCompareStrNoCase( S1, S2 );
  19163. end;
  19164. //[function StrLCopy]
  19165. {$IFDEF ASM_VERSION}
  19166. function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
  19167. asm
  19168. {$IFDEF F_P}
  19169. MOV EAX, [Dest]
  19170. MOV EDX, [Source]
  19171. MOV ECX, [MaxLen]
  19172. {$ENDIF F_P}
  19173. PUSH EDI
  19174. PUSH ESI
  19175. PUSH EBX
  19176. MOV ESI,EAX
  19177. MOV EDI,EDX
  19178. MOV EBX,ECX
  19179. XOR AL,AL
  19180. TEST ECX,ECX
  19181. JZ @@1
  19182. REPNE SCASB
  19183. JNE @@1
  19184. INC ECX
  19185. @@1: SUB EBX,ECX
  19186. MOV EDI,ESI
  19187. MOV ESI,EDX
  19188. MOV EDX,EDI
  19189. MOV ECX,EBX
  19190. SHR ECX,2
  19191. REP MOVSD
  19192. MOV ECX,EBX
  19193. AND ECX,3
  19194. REP MOVSB
  19195. STOSB
  19196. MOV EAX,EDX
  19197. POP EBX
  19198. POP ESI
  19199. POP EDI
  19200. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19201. {$ELSE ASM_VERSION} //Pascal
  19202. function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;
  19203. var
  19204. counter: cardinal;
  19205. Begin
  19206. counter := 0;
  19207. { To be compatible with BP, on a null string, put two nulls }
  19208. If Source[0] = #0 then
  19209. Begin
  19210. Dest[0]:=Source[0];
  19211. Inc(counter);
  19212. end;
  19213. while (Source[counter] <> #0) and (counter < MaxLen) do
  19214. Begin
  19215. Dest[counter] := char(Source[counter]);
  19216. Inc(counter);
  19217. end;
  19218. { terminate the string }
  19219. Dest[counter] := #0;
  19220. StrLCopy := Dest;
  19221. end;
  19222. {$ENDIF ASM_VERSION}
  19223. //[FUNCTION StrPCopy]
  19224. {$IFDEF ASM_VERSION}
  19225. {$ELSE ASM_VERSION} //Pascal
  19226. function StrPCopy(Dest: PChar; const Source: string): PChar;
  19227. begin
  19228. Result := StrLCopy(Dest, PChar(Source), Length(Source));
  19229. end;
  19230. {$ENDIF ASM_VERSION}
  19231. //[END StrPCopy]
  19232. //[FUNCTION StrEq]
  19233. {$IFDEF ASM_VERSION}
  19234. {$ELSE ASM_VERSION} //Pascal
  19235. function StrEq( const S1, S2 : String ) : Boolean;
  19236. begin
  19237. Result := (Length( S1 ) = Length( S2 )) and
  19238. (LowerCase( S1 ) = LowerCase( S2 ));
  19239. end;
  19240. {$ENDIF ASM_VERSION}
  19241. //[END StrEq]
  19242. //[FUNCTION AnsiEq]
  19243. {$IFDEF ASM_VERSION}
  19244. {$ELSE ASM_VERSION} //Pascal
  19245. function AnsiEq( const S1, S2 : String ) : Boolean;
  19246. begin
  19247. Result := AnsiCompareStrNoCase( S1, S2 ) = 0;
  19248. end;
  19249. {$ENDIF ASM_VERSION}
  19250. //[END AnsiEq]
  19251. {$IFNDEF _D2}
  19252. {$IFNDEF _FPC}
  19253. //[function WAnsiEq]
  19254. function WAnsiEq( const S1, S2 : WideString ) : Boolean;
  19255. begin
  19256. Result := WAnsiLowerCase( S1 )=WAnsiLowerCase( S2 );
  19257. end;
  19258. {$ENDIF _FPC}
  19259. {$ENDIF _D2}
  19260. //[FUNCTION StrIn]
  19261. {$IFDEF ASM_VERSION}
  19262. {$ELSE ASM_VERSION} //Pascal
  19263. function StrIn(const S: String; const A: array of String): Boolean;
  19264. var I : Integer;
  19265. begin
  19266. for I := Low( A ) to High( A ) do
  19267. if StrEq( S, A[ I ] ) then
  19268. begin
  19269. Result := True;
  19270. Exit;
  19271. end;
  19272. Result := False;
  19273. end;
  19274. {$ENDIF ASM_VERSION}
  19275. //[END StrIn]
  19276. {$IFNDEF _D2}
  19277. {$IFNDEF _FPC}
  19278. //[function WStrIn]
  19279. function WStrIn( const S : WideString; const A : array of WideString ) : Boolean;
  19280. var I : Integer;
  19281. begin
  19282. for I := Low( A ) to High( A ) do
  19283. if WAnsiEq( S, A[ I ] ) then
  19284. begin
  19285. Result := True;
  19286. Exit;
  19287. end;
  19288. Result := False;
  19289. end;
  19290. {$ENDIF _FPC}
  19291. {$ENDIF _D2}
  19292. function CharIn( C: KOLChar; const A: TSetofChar ): Boolean;
  19293. begin
  19294. Result := (DWord( C ) <= 255) and (Char( C ) in A);
  19295. end;
  19296. //[function StrIs]
  19297. function StrIs( const S : String; const A : array of String; var Idx: Integer ) : Boolean;
  19298. var I : Integer;
  19299. begin
  19300. Idx := -1;
  19301. for I := Low( A ) to High( A ) do
  19302. if StrEq( S, A[ I ] ) then
  19303. begin
  19304. Idx := I;
  19305. Result := True;
  19306. Exit;
  19307. end;
  19308. Result := False;
  19309. end;
  19310. //[function IntIn]
  19311. function IntIn( Value: Integer; const List: array of Integer ): Boolean;
  19312. var I: Integer;
  19313. begin
  19314. Result := FALSE;
  19315. for I := 0 to High( List ) do
  19316. begin
  19317. if Value = List[ I ] then
  19318. begin
  19319. Result := TRUE;
  19320. break;
  19321. end;
  19322. end;
  19323. end;
  19324. //[FUNCTION _StrSatisfy]
  19325. {$IFDEF ASM_UNICODE}
  19326. {$ELSE ASM_VERSION} //Pascal
  19327. function _StrSatisfy( S, Mask : PKOLChar ) : Boolean;
  19328. label next_char;
  19329. begin
  19330. next_char:
  19331. Result := True;
  19332. if (S^ = #0) and (Mask^ = #0) then exit;
  19333. if (Mask^ = '*') and (Mask[1] = #0) then exit;
  19334. if S^ = #0 then
  19335. begin
  19336. while Mask^ = '*' do
  19337. Inc( Mask );
  19338. Result := Mask^ = #0;
  19339. exit;
  19340. end;
  19341. Result := False;
  19342. if Mask^ = #0 then exit;
  19343. if Mask^ = '?' then
  19344. begin
  19345. Inc( S ); Inc( Mask ); goto next_char;
  19346. end;
  19347. if Mask^ = '*' then
  19348. begin
  19349. Inc( Mask );
  19350. while S^ <> #0 do
  19351. begin
  19352. Result := _StrSatisfy( S, Mask );
  19353. if Result then exit;
  19354. Inc( S );
  19355. end;
  19356. exit; // (Result = False)
  19357. end;
  19358. Result := S^ = Mask^;
  19359. Inc( S ); Inc( Mask );
  19360. if Result then goto next_char;
  19361. end;
  19362. {$ENDIF ASM_VERSION}
  19363. //[END _StrSatisfy]
  19364. //[FUNCTION StrSatisfy]
  19365. {$IFDEF ASM_UNICODE}
  19366. {$ELSE ASM_VERSION} //Pascal
  19367. function StrSatisfy( const S, Mask: KOLString ): Boolean;
  19368. begin
  19369. Result := _StrSatisfy( PKOLChar( {$IFDEF UNICODE_CTRLS} WAnsiLowerCase
  19370. {$ELSE} AnsiLowerCase {$ENDIF} ( S ) ),
  19371. PKOLChar( {$IFDEF UNICODE_CTRLS} WAnsiLowerCase
  19372. {$ELSE} AnsiLowerCase {$ENDIF} ( Mask ) ) );
  19373. end;
  19374. {$ENDIF ASM_VERSION}
  19375. //[END StrSatisfy]
  19376. //[FUNCTION _2StrSatisfy]
  19377. {$IFDEF ASM_UNICODE}
  19378. {$ELSE ASM_VERSION} // Pascal
  19379. function _2StrSatisfy( S, Mask: PKOLChar ): Boolean;
  19380. begin
  19381. Result := StrSatisfy( S, Mask );
  19382. end;
  19383. {$ENDIF ASM_VERSION}
  19384. //[END _2StrSatisfy]
  19385. //[function StrReplace]
  19386. function StrReplace( var S: String; const From, ReplTo: String ): Boolean;
  19387. var I: Integer;
  19388. begin
  19389. I := pos( From, S );
  19390. if I > 0 then
  19391. begin
  19392. S := Copy( S, 1, I - 1 ) + ReplTo + CopyEnd( S, I + Length( From ) );
  19393. Result := TRUE;
  19394. end
  19395. else Result := FALSE;
  19396. end;
  19397. function KOLStrReplace( var S: KOLString; const From, ReplTo: KOLString ): Boolean;
  19398. var I: Integer;
  19399. begin
  19400. I := pos( From, S );
  19401. if I > 0 then
  19402. begin
  19403. S := Copy( S, 1, I - 1 ) + ReplTo + CopyEnd( S, I + Length( From ) );
  19404. Result := TRUE;
  19405. end
  19406. else Result := FALSE;
  19407. end;
  19408. {-}
  19409. {$IFDEF _FPC}
  19410. //[procedure SetLengthW]
  19411. procedure SetLengthW( var W: WideString; NewLength: Integer );
  19412. begin
  19413. while Length( W ) < NewLength do
  19414. W := W + ' ' + W;
  19415. if Length( W ) > NewLength then
  19416. Delete( W, NewLength + 1, Length( W ) - NewLength );
  19417. end;
  19418. //[function CopyW]
  19419. function CopyW( const W: WideString; From, Count: Integer ): WideString;
  19420. begin
  19421. Result := '';
  19422. if Count <= 0 then Exit;
  19423. SetLengthW( Result, Count );
  19424. Move( W[ From ], Result[ 1 ], Count * Sizeof( WideChar ) );
  19425. end;
  19426. //[function posW]
  19427. function posW( const S1, S2: String ): Integer;
  19428. var I, L1: Integer;
  19429. begin
  19430. L1 := Length( S1 );
  19431. for I := 1 to Length( S2 )-L1+1 do
  19432. begin
  19433. if Copy( S2, I, L1 ) = S1 then
  19434. begin
  19435. Result := I;
  19436. Exit;
  19437. end;
  19438. end;
  19439. Result := 0;
  19440. end;
  19441. {$ENDIF _FPC}
  19442. {$IFNDEF _FPC}
  19443. {$IFNDEF _D2}
  19444. //[function WStrReplace]
  19445. function WStrReplace( var S: WideString; const From, ReplTo: WideString ): Boolean;
  19446. var I: Integer;
  19447. begin
  19448. I := pos( From, S );
  19449. if I > 0 then
  19450. begin
  19451. S := Copy( S, 1, I - 1 ) + ReplTo + Copy( S, I + Length( From ), MaxInt );
  19452. Result := TRUE;
  19453. end
  19454. else Result := FALSE;
  19455. end;
  19456. //[function WStrRepeat]
  19457. function WStrRepeat( const S: WideString; Count: Integer ): WideString;
  19458. var I, L: Integer;
  19459. begin
  19460. L := Length( S );
  19461. SetLength( Result, L * Count );
  19462. for I := 0 to Count-1 do
  19463. Move( S[ 1 ], Result[ 1 + I * L ], L * Sizeof( WideChar ) );
  19464. end;
  19465. {$ENDIF _D2}
  19466. {$ENDIF _FPC}
  19467. {+}
  19468. //[function StrRepeat]
  19469. function StrRepeat( const S: String; Count: Integer ): String;
  19470. var I, L: Integer;
  19471. begin
  19472. L := Length( S );
  19473. SetLength( Result, L * Count );
  19474. for I := 0 to Count-1 do
  19475. Move( S[ 1 ], Result[ 1 + I * L ], L );
  19476. end;
  19477. //[PROCEDURE NormalizeUnixText]
  19478. {$IFDEF ASM_VERSION}
  19479. {$ELSE ASM_VERSION} //Pascal
  19480. procedure NormalizeUnixText( var S: String );
  19481. var I: Integer;
  19482. begin
  19483. if S <> '' then
  19484. begin
  19485. if S[ 1 ] = #10 then
  19486. S[ 1 ] := #13;
  19487. for I := 2 to Length(S) do
  19488. if (S[I]=#10) and (S[I-1]<>#13) then
  19489. S[I] := #13;
  19490. end;
  19491. end;
  19492. {$ENDIF ASM_VERSION}
  19493. //[END NormalizeUnixText]
  19494. var Koi8_to_Ansi: array[ Char ] of Char;
  19495. procedure Koi8ToAnsi( s: PChar );
  19496. const KOI8_Rus: array[ #$C0..#$FF ] of Char = (
  19497. #254,
  19498. #224, #225, #246, #228, #229, #244, #227, #245, #232, #233, #234, #235, #235, #237, #238, #239,
  19499. #255, #240, #241, #242, #243, #230, #226, #252, #251, #231, #248, #253, #249, #247, #250,
  19500. #222,
  19501. #192, #193, #214, #196, #197, #212, #195, #213, #200, #201, #202, #203, #204, #205, #206, #207,
  19502. #223, #208, #209, #210, #211, #198, #194, #220, #219, #199, #216, #221, #217, #215, #218
  19503. );
  19504. var c: Char;
  19505. begin
  19506. if Koi8_to_Ansi[ #0 ] = #0 then
  19507. begin
  19508. for c := #1 to #255 do
  19509. begin
  19510. Koi8_to_Ansi[ c ] := c;
  19511. if (c >= #$C0) and (c <= #$FF) then
  19512. Koi8_to_Ansi[ c ] := KOI8_Rus[ c ];
  19513. end;
  19514. Koi8_to_Ansi[ #0 ] := #1;
  19515. end;
  19516. while s^ <> #0 do
  19517. begin
  19518. s^ := Koi8_to_Ansi[ s^ ];
  19519. inc( s );
  19520. end;
  19521. end;
  19522. //[function StrComp]
  19523. {$IFDEF ASM_VERSION}
  19524. function StrComp(const Str1, Str2: PChar): Integer; assembler;
  19525. asm
  19526. {$IFDEF F_P}
  19527. MOV EAX, [Str1]
  19528. MOV EDX, [Str2]
  19529. {$ENDIF F_P}
  19530. PUSH EDI
  19531. PUSH ESI
  19532. MOV EDI,EDX
  19533. XCHG ESI,EAX
  19534. OR ECX, -1
  19535. XOR EAX,EAX
  19536. REPNE SCASB
  19537. NOT ECX
  19538. MOV EDI,EDX
  19539. XOR EDX,EDX
  19540. REPE CMPSB
  19541. MOV AL,[ESI-1]
  19542. MOV DL,[EDI-1]
  19543. SUB EAX,EDX
  19544. POP ESI
  19545. POP EDI
  19546. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19547. {$ELSE ASM_VERSION} //Pascal
  19548. function StrComp(const Str1, Str2 : PChar): Integer;
  19549. var
  19550. counter: Integer;
  19551. Begin
  19552. counter := 0;
  19553. While str1[counter] = str2[counter] do
  19554. Begin
  19555. if (str2[counter] = #0) or (str1[counter] = #0) then
  19556. break;
  19557. Inc(counter);
  19558. end;
  19559. StrComp := ord(str1[counter]) - ord(str2[counter]);
  19560. end;
  19561. {$ENDIF ASM_VERSION}
  19562. {$IFDEF ASM_VERSION}
  19563. function StrComp_NoCase(const Str1, Str2: PChar): Integer;
  19564. asm
  19565. {$IFDEF F_P}
  19566. MOV EAX, [Str1]
  19567. MOV EDX, [Str2]
  19568. {$ENDIF F_P}
  19569. PUSH EDI
  19570. PUSH ESI
  19571. MOV EDI,EDX
  19572. XCHG ESI,EAX
  19573. OR ECX, -1
  19574. XOR EAX,EAX
  19575. REPNE SCASB
  19576. NOT ECX
  19577. MOV EDI,EDX
  19578. @@0:
  19579. XOR EDX,EDX
  19580. REPE CMPSB
  19581. MOV AL,[ESI-1]
  19582. MOV AH, AL
  19583. SUB AH, 'a'
  19584. CMP AH, 25
  19585. JA @@1
  19586. SUB AL, $20
  19587. @@1:
  19588. MOV DL,[EDI-1]
  19589. MOV AH, DL
  19590. SUB AH, 'a'
  19591. CMP AH, 25
  19592. JA @@2
  19593. SUB DL, $20
  19594. @@2:
  19595. MOV AH, 0
  19596. SUB EAX,EDX
  19597. JNZ @@exit
  19598. CMP DL, 0
  19599. JNZ @@0
  19600. @@exit:
  19601. POP ESI
  19602. POP EDI
  19603. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19604. {$ELSE ASM_VERSION} //Pascal
  19605. function StrComp_NoCase(const Str1, Str2: PChar): Integer;
  19606. var
  19607. counter: Integer;
  19608. Begin
  19609. counter := 0;
  19610. While UpCase(str1[counter]) = UpCase(str2[counter]) do
  19611. Begin
  19612. if (str2[counter] = #0) or (str1[counter] = #0) then
  19613. break;
  19614. Inc(counter);
  19615. end;
  19616. Result := ord(UpCase(str1[counter])) - ord(UpCase(str2[counter]));
  19617. end;
  19618. {$ENDIF ASM_VERSION}
  19619. //[function StrLComp_NoCase]
  19620. {$IFDEF ASM_VERSION}
  19621. function StrLComp_NoCase(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  19622. asm
  19623. {$IFDEF F_P}
  19624. MOV EAX, [Str1]
  19625. MOV EDX, [Str2]
  19626. MOV ECX, [MaxLen]
  19627. {$ENDIF F_P}
  19628. PUSH EDI
  19629. PUSH ESI
  19630. PUSH EBX
  19631. MOV EDI,EDX
  19632. MOV ESI,EAX
  19633. MOV EBX,ECX
  19634. XOR EAX,EAX
  19635. OR ECX,ECX
  19636. JE @@exit
  19637. REPNE SCASB
  19638. SUB EBX,ECX
  19639. MOV ECX,EBX
  19640. MOV EDI,EDX
  19641. @@0:
  19642. XOR EDX,EDX
  19643. REPE CMPSB
  19644. MOV AL,[ESI-1]
  19645. MOV AH, AL
  19646. SUB AH, 'a'
  19647. CMP AH, 25
  19648. JA @@1
  19649. SUB AL, $20
  19650. @@1:
  19651. MOV DL,[EDI-1]
  19652. MOV AH, DL
  19653. SUB AH, 'a'
  19654. CMP AH, 25
  19655. JA @@2
  19656. SUB DL, $20
  19657. @@2:
  19658. MOV AH, 0
  19659. SUB EAX,EDX
  19660. JECXZ @@exit
  19661. JZ @@0
  19662. @@exit:
  19663. POP EBX
  19664. POP ESI
  19665. POP EDI
  19666. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19667. {$ELSE ASM_VERSION} //Pascal
  19668. function StrLComp_NoCase(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  19669. var
  19670. counter: cardinal;
  19671. c1, c2: char;
  19672. Begin
  19673. counter := 0;
  19674. if MaxLen = 0 then
  19675. begin
  19676. Result := 0;
  19677. exit;
  19678. end;
  19679. Repeat
  19680. c1 := UpCase(str1[counter]);
  19681. c2 := UpCase(str2[counter]);
  19682. if (c1 = #0) or (c2 = #0) then break;
  19683. Inc(counter);
  19684. Until (c1 <> c2) or (counter >= MaxLen);
  19685. Result := ord(c1) - ord(c2);
  19686. end;
  19687. {$ENDIF ASM_VERSION}
  19688. //[function StrLComp]
  19689. {$IFDEF ASM_VERSION}
  19690. function StrLComp(const Str1, Str2: PChar; MaxLen: Cardinal): Integer; assembler;
  19691. asm
  19692. {$IFDEF F_P}
  19693. MOV EAX, [Str1]
  19694. MOV EDX, [Str2]
  19695. MOV ECX, [MaxLen]
  19696. {$ENDIF F_P}
  19697. PUSH EDI
  19698. PUSH ESI
  19699. PUSH EBX
  19700. MOV EDI,EDX
  19701. MOV ESI,EAX
  19702. MOV EBX,ECX
  19703. XOR EAX,EAX
  19704. OR ECX,ECX
  19705. JE @@1
  19706. REPNE SCASB
  19707. SUB EBX,ECX
  19708. MOV ECX,EBX
  19709. MOV EDI,EDX
  19710. XOR EDX,EDX
  19711. REPE CMPSB
  19712. MOV AL,[ESI-1]
  19713. MOV DL,[EDI-1]
  19714. SUB EAX,EDX
  19715. @@1: POP EBX
  19716. POP ESI
  19717. POP EDI
  19718. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19719. {$ELSE ASM_VERSION} //Pascal
  19720. function StrLComp(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  19721. var
  19722. counter: cardinal;
  19723. c1, c2: char;
  19724. Begin
  19725. counter := 0;
  19726. if MaxLen = 0 then
  19727. begin
  19728. StrLComp := 0;
  19729. exit;
  19730. end;
  19731. Repeat
  19732. c1 := str1[counter];
  19733. c2 := str2[counter];
  19734. if (c1 = #0) or (c2 = #0) then break;
  19735. Inc(counter);
  19736. Until (c1 <> c2) or (counter >= MaxLen);
  19737. StrLComp := ord(c1) - ord(c2);
  19738. end;
  19739. {$ENDIF ASM_VERSION}
  19740. //[function StrLen]
  19741. {$IFDEF ASM_VERSION}
  19742. function StrLen(const Str: PChar): Cardinal; assembler;
  19743. asm
  19744. {$IFDEF F_P}
  19745. MOV EAX, [Str]
  19746. {$ENDIF F_P}
  19747. XCHG EAX, EDI
  19748. XCHG EDX, EAX
  19749. OR ECX, -1
  19750. XOR EAX, EAX
  19751. CMP EAX, EDI
  19752. JE @@exit0
  19753. REPNE SCASB
  19754. DEC EAX
  19755. DEC EAX
  19756. SUB EAX,ECX
  19757. @@exit0:
  19758. MOV EDI,EDX
  19759. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19760. {$ELSE ASM_VERSION} //Pascal
  19761. function StrLen(const Str: PChar): Cardinal;
  19762. var i : Cardinal;
  19763. begin
  19764. i:=0;
  19765. while Str[i]<>#0 do inc(i);
  19766. Result:=i;
  19767. end;
  19768. {$ENDIF ASM_VERSION}
  19769. //[FUNCTION __DelimiterLast]
  19770. {$IFDEF ASM_UNICODE}
  19771. {$ELSE ASM_VERSION} //Pascal
  19772. function __DelimiterLast( Str, Delimiters: PKOLChar ): PKOLChar;
  19773. var
  19774. P, F : PKOLChar;
  19775. begin
  19776. P := Str;
  19777. Result := P + {$IFDEF UNICODE_CTRLS} WStrLen {$ELSE} StrLen {$ENDIF}( Str );
  19778. while Delimiters^ <> #0 do
  19779. begin
  19780. F := {$IFDEF UNICODE_CTRLS} WStrRScan {$ELSE} StrRScan {$ENDIF}
  19781. ( P, Delimiters^ );
  19782. if F <> nil then
  19783. if (Result^ = #0) or (cardinal(F) > cardinal(Result)) then
  19784. Result := F;
  19785. Inc( Delimiters );
  19786. end;
  19787. end;
  19788. {$ENDIF ASM_VERSION}
  19789. //[END __DelimiterLast]
  19790. {$IFDEF _D3orHigher}
  19791. function W__DelimiterLast( Str, Delimiters: PWideChar ): PWideChar;
  19792. var
  19793. P, F : PWideChar;
  19794. begin
  19795. P := Str;
  19796. Result := P + WStrLen( Str );
  19797. while Delimiters^ <> #0 do
  19798. begin
  19799. F := WStrRScan( P, Delimiters^ );
  19800. if F <> nil then
  19801. if (Result^ = #0) or (cardinal(F) > cardinal(Result)) then
  19802. Result := F;
  19803. Inc( Delimiters );
  19804. end;
  19805. end;
  19806. {$ENDIF _D3orHigher}
  19807. //[function SkipSpaces]
  19808. function SkipSpaces( P: PKOLChar ): PKOLChar;
  19809. begin
  19810. while True do
  19811. begin
  19812. while (P[0] <> #0) and (P[0] <= ' ') do Inc(P);
  19813. if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break;
  19814. end;
  19815. Result := P;
  19816. end;
  19817. //[function SkipParam]
  19818. function SkipParam(P: PKOLChar): PKOLChar;
  19819. begin
  19820. P := SkipSpaces( P );
  19821. while P[0] > ' ' do
  19822. if P[0] = '"' then
  19823. begin
  19824. Inc(P);
  19825. while (P[0] <> #0) and (P[0] <> '"') do
  19826. Inc(P);
  19827. if P[0] <> #0 then Inc(P);
  19828. end
  19829. else
  19830. Inc(P);
  19831. Result := P;
  19832. end;
  19833. {$IFDEF WIN}
  19834. //[FUNCTION ParamStr]
  19835. function ParamStr( Idx: Integer ): KOLString;
  19836. var
  19837. P, P1: PKOLChar;
  19838. Buffer: array[ 0..260 ] of KOLChar;
  19839. begin
  19840. if Idx = 0 then
  19841. SetString( Result, Buffer, GetModuleFileName( 0, Buffer, Sizeof( Buffer ) ) )
  19842. else
  19843. begin
  19844. P := GetCommandLine;
  19845. {$ifdef wince}
  19846. Dec(Idx);
  19847. {$endif}
  19848. repeat
  19849. P := SkipSpaces( P );
  19850. P1 := P;
  19851. P := SkipParam(P);
  19852. if Idx = 0 then Break;
  19853. Dec(Idx);
  19854. until (Idx < 0) or (P = P1);
  19855. Result := Copy( P1, 1, P - P1 );
  19856. if Length( Result ) >= 2 then
  19857. if (Result[ 1 ] = '"') and (Result[ Length( Result ) ] = '"') then
  19858. Result := Copy( Result, 2, Length( Result ) - 2 );
  19859. end;
  19860. end;
  19861. //[END ParamStr]
  19862. //[FUNCTION ParamCount]
  19863. function ParamCount: Integer;
  19864. var
  19865. S: string;
  19866. begin
  19867. Result := 0;
  19868. while True do
  19869. begin
  19870. S := ParamStr(Result + 1);
  19871. if S = '' then Break;
  19872. Inc(Result);
  19873. end;
  19874. end;
  19875. //[END ParamCount]
  19876. {$ENDIF WIN}
  19877. //[FUNCTION DelimiterLast]
  19878. {$IFDEF ASM_UNICODE}
  19879. {$ELSE ASM_VERSION} //Pascal
  19880. function DelimiterLast( const Str, Delimiters: KOLString ): Integer;
  19881. var PStr: PKOLChar;
  19882. begin
  19883. PStr := PKOLChar( Str );
  19884. Result := cardinal( __DelimiterLast( PStr, PKOLChar( Delimiters ) ) )
  19885. - cardinal( PStr )
  19886. + {$IFDEF UNICODE_CTRLS} 2 {$ELSE} 1 {$ENDIF}; // {Viman}
  19887. {$IFDEF UNICODE_CTRLS} Result := Result div SizeOf( WideChar ) {$ENDIF};
  19888. end;
  19889. {$ENDIF ASM_VERSION}
  19890. //[END DelimiterLast]
  19891. // Thanks to Marco Bobba - Marisa Bo for this code
  19892. //[function StrIsStartingFrom]
  19893. {$IFDEF ASM_UNICODE}
  19894. function StrIsStartingFrom( Str, Pattern: PKOLChar ): Boolean;
  19895. asm
  19896. {$IFDEF F_P}
  19897. MOV EAX, [Str]
  19898. MOV EDX, [Pattern]
  19899. {$ENDIF F_P}
  19900. XOR ECX, ECX
  19901. @@1:
  19902. MOV CL, [EDX] // pattern[ i ]
  19903. INC EDX
  19904. MOV CH, [EAX] // str[ i ]
  19905. INC EAX
  19906. JECXZ @@2 // str = pattern; CL = #0, CH = #0
  19907. CMP CL, CH
  19908. JE @@1
  19909. @@2:
  19910. TEST CL, CL
  19911. SETZ AL
  19912. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19913. {$ELSE}
  19914. function StrIsStartingFrom( Str, Pattern: PKOLChar ): Boolean;
  19915. begin
  19916. Result := FALSE;
  19917. while Pattern^ <> #0 do
  19918. begin
  19919. if Str^ <> Pattern^ then Exit;
  19920. inc( Str );
  19921. inc( Pattern );
  19922. end;
  19923. Result := TRUE;
  19924. end;
  19925. {$ENDIF ASM_UNICODE}
  19926. {$IFDEF ASM_VERSION}
  19927. function StrIsStartingFromNoCase( Str, Pattern: PChar ): Boolean;
  19928. asm
  19929. {$IFDEF F_P}
  19930. MOV EAX, [Str]
  19931. MOV EDX, [Pattern]
  19932. {$ENDIF F_P}
  19933. XOR ECX, ECX
  19934. @@1:
  19935. MOV CL, [EDX] // pattern[ i ]
  19936. INC EDX
  19937. MOV CH, [EAX] // str[ i ]
  19938. INC EAX
  19939. JECXZ @@2 // str = pattern; CL = #0, CH = #0
  19940. CMP CL, 'a'
  19941. JB @@cl_ok
  19942. CMP CL, 'z'
  19943. JA @@cl_ok
  19944. SUB CL, 32
  19945. @@cl_ok:
  19946. CMP CH, 'a'
  19947. JB @@ch_ok
  19948. CMP CH, 'z'
  19949. JA @@ch_ok
  19950. SUB CH, 32
  19951. @@ch_ok:
  19952. CMP CL, CH
  19953. JE @@1
  19954. @@2:
  19955. TEST CL, CL
  19956. SETZ AL
  19957. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  19958. {$ELSE ASM_VERSION} //Pascal
  19959. function StrIsStartingFromNoCase( Str, Pattern: PChar ): Boolean;
  19960. begin
  19961. Result := FALSE;
  19962. while Pattern^ <> #0 do
  19963. begin
  19964. if UpCase(Str^) <> UpCase(Pattern^) then Exit;
  19965. inc( Str );
  19966. inc( Pattern );
  19967. end;
  19968. Result := TRUE;
  19969. end;
  19970. {$ENDIF ASM_VERSION}
  19971. {$IFDEF WIN}
  19972. {$IFNDEF _FPC}
  19973. //[FUNCTION Format]
  19974. {$IFDEF ASM_UNICODE}
  19975. {$ELSE ASM_VERSION} //Pascal
  19976. function Format( const fmt: KOLString; params: array of const ): KOLString;
  19977. var Buffer: array[ 0..2047 ] of KOLChar;
  19978. ElsArray, El: ^pointer;
  19979. I : Integer;
  19980. begin
  19981. ElsArray := nil;
  19982. if High( params ) >= 0 then
  19983. GetMem( ElsArray, (High( params ) + 1) * sizeof( Pointer ) );
  19984. El := ElsArray;
  19985. for I := 0 to High( params ) do
  19986. begin
  19987. El^ := params[ I ].VPointer;
  19988. Inc( El );
  19989. end;
  19990. wvsprintf( @Buffer[0], PKOLChar( fmt ), PChar( ElsArray ) );
  19991. Result := Buffer;
  19992. if ElsArray <> nil then
  19993. FreeMem( ElsArray );
  19994. end;
  19995. {$ENDIF ASM_VERSION}
  19996. //[END Format]
  19997. {$ENDIF WIN}
  19998. //[function LStrFromPWCharLen]
  19999. function LStrFromPWCharLen(Source: PWideChar; Length: Integer): String;
  20000. var
  20001. DestLen: Integer;
  20002. Buffer: array[0..2047] of Char;
  20003. begin
  20004. if Length <= 0 then
  20005. begin
  20006. Result := '';
  20007. Exit;
  20008. end;
  20009. if Length < SizeOf(Buffer) div 2 then
  20010. begin
  20011. DestLen := WideCharToMultiByte(0, 0, Source, Length,
  20012. Buffer, SizeOf(Buffer), nil, nil);
  20013. if DestLen > 0 then
  20014. begin
  20015. Result := Buffer;
  20016. Exit;
  20017. end;
  20018. end;
  20019. DestLen := WideCharToMultiByte(0, 0, Source, Length, nil, 0, nil, nil);
  20020. // _LStrFromPCharLen(Dest, nil, DestLen);
  20021. SetLength( Result, DestLen );
  20022. WideCharToMultiByte(0, 0, Source, Length, Pointer(Result), DestLen, nil, nil);
  20023. end;
  20024. //[function LStrFromPWChar]
  20025. {$IFDEF ASM_VERSION}
  20026. function LStrFromPWChar(Source: PWideChar): String;
  20027. {* from Delphi5 - because D2 does not contain it. }
  20028. asm
  20029. PUSH EDX
  20030. XOR EDX,EDX
  20031. TEST EAX,EAX
  20032. JE @@5
  20033. PUSH EAX
  20034. @@0: CMP DX,[EAX+0]
  20035. JE @@4
  20036. CMP DX,[EAX+2]
  20037. JE @@3
  20038. CMP DX,[EAX+4]
  20039. JE @@2
  20040. CMP DX,[EAX+6]
  20041. JE @@1
  20042. ADD EAX,8
  20043. JMP @@0
  20044. @@1: ADD EAX,2
  20045. @@2: ADD EAX,2
  20046. @@3: ADD EAX,2
  20047. @@4: XCHG EDX,EAX
  20048. POP EAX
  20049. SUB EDX,EAX
  20050. SHR EDX,1
  20051. @@5: POP ECX
  20052. JMP LStrFromPWCharLen
  20053. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  20054. {$ELSE ASM_VERSION}
  20055. function LStrFromPWChar(Source: PWideChar): String;
  20056. begin
  20057. Result:=Source;
  20058. end;
  20059. {$ENDIF ASM_VERSION}
  20060. {$ENDIF _FPC}
  20061. /////////////////////////////////////////////////////////////////////////
  20062. //
  20063. //
  20064. // F I L E S
  20065. //
  20066. //
  20067. /////////////////////////////////////////////////////////////////////////
  20068. //[FILES]
  20069. {
  20070. This part of the unit modified by Tim Slusher and Vladimir Kladov.
  20071. }
  20072. {* Set of utility methods to work with files
  20073. and reqistry.
  20074. When programming KOL, which is Windows API-oriented, You should
  20075. avoid alien (for Windows) embedded Pascal files handling, and
  20076. use API-calls which implemented very well. This set of functions
  20077. is intended to make this easier.
  20078. Also TDirList object implementation present here and some registry
  20079. access functions, which allow to make code more elegant.
  20080. }
  20081. {$UNDEF ASM_LOCAL}
  20082. {$IFDEF ASM_VERSION}
  20083. {$DEFINE ASM_LOCAL}
  20084. {$ENDIF ASM_VERSION}
  20085. //[FUNCTION FileCreate]
  20086. {$IFDEF WIN}
  20087. {$IFDEF ASM_VERSION}
  20088. {$ELSE ASM_VERSION} //Pascal
  20089. function FileCreate(const FileName: KOLString; OpenFlags: DWord): THandle;
  20090. var Attr: DWORD;
  20091. begin
  20092. Attr := (OpenFlags shr 16) and $1FFF;
  20093. if Attr = 0 then Attr := FILE_ATTRIBUTE_NORMAL;
  20094. Result := CreateFile( PKOLChar(FileName), OpenFlags and $F0000000,
  20095. OpenFlags and $F, nil, (OpenFlags shr 8) and $F,
  20096. Attr, 0 );
  20097. end;
  20098. {$ENDIF ASM_VERSION}
  20099. {$ENDIF WIN}
  20100. //[END FileCreate]
  20101. {$IFDEF _D3orHigher}
  20102. function WFileCreate(const FileName: WideString; OpenFlags: DWord): THandle;
  20103. var Attr: DWORD;
  20104. begin
  20105. Attr := (OpenFlags shr 16) and $1FFF;
  20106. if Attr = 0 then Attr := FILE_ATTRIBUTE_NORMAL;
  20107. Result := CreateFileW( PWideChar(FileName), OpenFlags and $F0000000,
  20108. OpenFlags and $F, nil, (OpenFlags shr 8) and $F,
  20109. Attr, 0 );
  20110. end;
  20111. {$ENDIF _D3orHigher}
  20112. //[FUNCTION FileClose]
  20113. {$IFDEF WIN}
  20114. {$IFDEF ASM_VERSION}
  20115. {$ELSE ASM_VERSION} //Pascal
  20116. function FileClose(Handle: THandle): boolean;
  20117. begin
  20118. Result := CloseHandle(Handle);
  20119. end;
  20120. {$ENDIF ASM_VERSION}
  20121. {$ENDIF WIN}
  20122. //[END FileClose]
  20123. {$UNDEF ASM_LOCAL}
  20124. {$IFDEF ASM_UNICODE}
  20125. {$DEFINE ASM_LOCAL}
  20126. {$ENDIF}
  20127. {$IFDEF FILE_EXISTS_EX}
  20128. {$UNDEF ASM_LOCAL}
  20129. {$ENDIF}
  20130. //[FUNCTION FileExists]
  20131. {$IFDEF WIN}
  20132. {$IFDEF ASM_LOCAL}
  20133. {$ELSE ASM_VERSION} //Pascal
  20134. function FileExists( const FileName : KOLString ) : Boolean;
  20135. {$IFDEF FILE_EXISTS_EX}
  20136. var FD: TFindFileData;
  20137. //F: DWORD;
  20138. LFT: TFileTime;
  20139. Hi, Lo: Word;
  20140. {$ELSE}
  20141. var Code: Integer;
  20142. {$ENDIF}
  20143. begin
  20144. {$IFDEF FILE_EXISTS_EX}
  20145. Result := FALSE;
  20146. if not Find_First( Filename, FD ) then Exit;
  20147. Find_Close( FD );
  20148. if FD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then Exit;
  20149. FileTimeToLocalFileTime( FD.ftLastWriteTime, LFT );
  20150. if FileTimeToDosDateTime( LFT, Hi, Lo ) then Result := TRUE;
  20151. {$ELSE}
  20152. Code := GetFileAttributes(PKOLChar(FileName));
  20153. Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0);
  20154. {$ENDIF}
  20155. end;
  20156. {$ENDIF ASM_VERSION}
  20157. {$ENDIF WIN}
  20158. //[END FileExists]
  20159. {$IFDEF _D3orHigher}
  20160. function WFileExists( const FileName: WideString ) : Boolean;
  20161. {$IFDEF notimplemented_FILE_EXISTS_EX}
  20162. var FD: TFindFileData;
  20163. //F: DWORD;
  20164. LFT: TFileTime;
  20165. Hi, Lo: Word;
  20166. {$ELSE}
  20167. var Code: Integer;
  20168. {$ENDIF}
  20169. begin
  20170. {$IFDEF notimplemented_FILE_EXISTS_EX}
  20171. Result := FALSE;
  20172. if not WFind_First( Filename, FD ) then Exit;
  20173. WFind_Close( FD );
  20174. if FD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then Exit;
  20175. FileTimeToLocalFileTime( FD.ftLastWriteTime, LFT );
  20176. if FileTimeToDosDateTime( LFT, Hi, Lo ) then Result := TRUE;
  20177. {$ELSE}
  20178. Code := GetFileAttributesW(PWideChar(FileName));
  20179. Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0);
  20180. {$ENDIF}
  20181. end;
  20182. {$ENDIF _D3orHigher}
  20183. //[FUNCTION FileSeek]
  20184. {$IFDEF WIN}
  20185. {$IFDEF ASM_VERSION}
  20186. {$ELSE ASM_VERSION} //Pascal
  20187. function FileSeek(Handle: THandle; MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  20188. begin
  20189. Result := SetFilePointer(Handle, MoveTo, nil, Ord( MoveMethod ) );
  20190. end;
  20191. {$ENDIF ASM_VERSION}
  20192. {$ENDIF WIN}
  20193. //[END FileSeek]
  20194. {$IFDEF _D4orHigher}
  20195. {$IFDEF WIN}
  20196. function FileFarSeek(Handle: THandle; MoveTo: Int64; MoveMethod: TMoveMethod): DWord;
  20197. begin
  20198. Result := SetFilePointer(Handle, MoveTo, nil, Ord( MoveMethod ) );
  20199. end;
  20200. {$ENDIF WIN}
  20201. {$ENDIF _D4orHigher}
  20202. //[FUNCTION FileRead]
  20203. {$IFDEF WIN}
  20204. {$IFDEF ASM_VERSION}
  20205. {$ELSE ASM_VERSION} //Pascal
  20206. function FileRead(Handle: THandle; var Buffer; Count: DWord): DWord;
  20207. begin
  20208. if not ReadFile(Handle, Buffer, Count, Result, nil) then
  20209. Result := 0;
  20210. end;
  20211. {$ENDIF ASM_VERSION}
  20212. {$ENDIF WIN}
  20213. //[END FileRead]
  20214. //[FUNCTION File2Str]
  20215. {$IFDEF ASM_VERSION}
  20216. {$ELSE ASM_VERSION} //Pascal
  20217. function File2Str(Handle: THandle): String;
  20218. var Pos, Size: DWORD;
  20219. begin
  20220. Result := '';
  20221. if Handle = 0 then Exit;
  20222. Pos := FileSeek( Handle, 0, spCurrent );
  20223. Size := GetFileSize( Handle, nil );
  20224. SetString( Result, nil, Size - Pos + 1 );
  20225. FileRead( Handle, Result[ 1 ], Size - Pos );
  20226. Result[ Size - Pos + 1 ] := #0;
  20227. end;
  20228. {$ENDIF ASM_VERSION}
  20229. //[END File2Str]
  20230. {$IFNDEF _D2}
  20231. function File2WStr(Handle: THandle): WideString;
  20232. var Pos, Size: DWORD;
  20233. begin
  20234. Result := '';
  20235. if Handle = 0 then Exit;
  20236. Pos := FileSeek( Handle, 0, spCurrent );
  20237. Size := GetFileSize( Handle, nil );
  20238. SetString( Result, nil, (Size - Pos + 1)*Sizeof( WideChar ) );
  20239. FileRead( Handle, Result[ 1 ], Size - Pos );
  20240. Result[ Size - Pos + 1 ] := #0;
  20241. end;
  20242. {$ENDIF _D2}
  20243. //[FUNCTION FileWrite]
  20244. {$IFDEF WIN}
  20245. {$IFDEF ASM_VERSION}
  20246. {$ELSE ASM_VERSION} //Pascal
  20247. function FileWrite(Handle: THandle; const Buffer; Count: DWord): DWord;
  20248. begin
  20249. if not WriteFile(Handle, Buffer, Count, Result, nil) then
  20250. Result := 0;
  20251. end;
  20252. {$ENDIF ASM_VERSION}
  20253. {$ENDIF WIN}
  20254. //[END FileWrite]
  20255. //[FUNCTION FileEOF]
  20256. {$IFDEF ASM_VERSION}
  20257. {$ELSE ASM_VERSION} //Pascal
  20258. function FileEOF( Handle: THandle ) : Boolean;
  20259. var Siz, Pos : DWord;
  20260. begin
  20261. Siz := GetFileSize( Handle, nil );
  20262. Pos := FileSeek( Handle, 0, spCurrent );
  20263. Result := Pos >= Siz;
  20264. end;
  20265. {$ENDIF ASM_VERSION}
  20266. //[END FileEOF]
  20267. //[FUNCTION FileFullPath]
  20268. {$IFDEF WIN}
  20269. {$IFDEF ASM_noVERSION_UNICODE}
  20270. function FileFullPath( const FileName: String ) : String;
  20271. const
  20272. BkSlash: String = '\';
  20273. szTShFileInfo = sizeof( TShFileInfo );
  20274. asm
  20275. PUSH EBX
  20276. PUSH ESI
  20277. MOV EBX, EDX
  20278. PUSH EAX
  20279. XCHG EAX, EDX
  20280. CALL System.@LStrClr
  20281. POP EDX
  20282. PUSH 0
  20283. MOV EAX, ESP
  20284. CALL System.@LStrAsg
  20285. MOV ESI, ESP
  20286. @@loo: CMP dword ptr [ESI], 0
  20287. JZ @@fin
  20288. MOV EAX, ESI
  20289. MOV EDX, [BkSlash]
  20290. PUSH 0
  20291. MOV ECX, ESP
  20292. CALL Parse
  20293. CMP dword ptr [EBX], 0
  20294. JE @@1
  20295. MOV EAX, EBX
  20296. MOV EDX, [BkSlash]
  20297. CALL System.@LStrCat
  20298. JMP @@2
  20299. @@1:
  20300. POP EAX
  20301. PUSH EAX
  20302. CALL System.@LStrLen
  20303. CMP EAX, 2
  20304. JNE @@2
  20305. POP EAX
  20306. PUSH EAX
  20307. CMP byte ptr [EAX+1], ':'
  20308. JNE @@2
  20309. MOV EAX, EBX
  20310. POP EDX
  20311. PUSH EDX
  20312. CALL System.@LStrAsg
  20313. JMP @@3
  20314. @@2:
  20315. PUSH 0
  20316. MOV EAX, ESP
  20317. MOV EDX, [EBX]
  20318. CALL System.@LStrAsg
  20319. MOV EAX, ESP
  20320. MOV EDX, [ESP+4]
  20321. CALL System.@LStrCat
  20322. POP EAX
  20323. PUSH EAX
  20324. SUB ESP, szTShFileInfo
  20325. MOV EDX, ESP
  20326. PUSH SHGFI_DISPLAYNAME
  20327. PUSH szTShFileInfo
  20328. PUSH EDX
  20329. PUSH 0
  20330. PUSH EAX
  20331. CALL ShGetFileInfo
  20332. LEA EDX, [ESP].TShFileInfo.szDisplayName
  20333. CMP byte ptr [EDX], 0
  20334. JE @@clr_stk
  20335. LEA EAX, [ESP+szTShFileInfo+4]
  20336. CALL System.@LStrFromPChar
  20337. @@clr_stk:
  20338. ADD ESP, szTShFileInfo
  20339. CALL RemoveStr
  20340. POP EDX
  20341. PUSH EDX
  20342. MOV EAX, EBX
  20343. CALL System.@LStrCat
  20344. @@3: CALL RemoveStr
  20345. JMP @@loo
  20346. @@fin: CALL RemoveStr
  20347. POP ESI
  20348. POP EBX
  20349. end;
  20350. {$ELSE ASM_VERSION} //Pascal
  20351. function FileFullPath( const FileName: KOLString ) : KOLString;
  20352. var SFI: TShFileInfo;
  20353. Src, S: KOLString;
  20354. begin
  20355. Result := '';
  20356. Src := FileName;
  20357. while Src <> '' do
  20358. begin
  20359. S := Parse( Src, '\' );
  20360. if Result <> '' then
  20361. Result := Result + '\';
  20362. if (Result = '') and (Length( S ) = 2) and (S[ 2 ] = ':') then
  20363. Result := S
  20364. else
  20365. begin
  20366. {$IFDEF UNICODE_CTRLS} ShGetFileInfoW {$ELSE} ShGetFileInfoA {$ENDIF}
  20367. ( PKOLChar( Result + S ), 0, SFI, Sizeof( SFI ), SHGFI_DISPLAYNAME );
  20368. if SFI.szDisplayName[ 0 ] <> #0 then
  20369. S := SFI.szDisplayName;
  20370. Result := Result + S;
  20371. end;
  20372. end;
  20373. if ExtractFileExt( Result ) = '' then
  20374. // case when flag 'Hide extensions for registered file types' is set on
  20375. // in the Explorer:
  20376. Result := Result + ExtractFileExt( FileName );
  20377. end;
  20378. {$ENDIF ASM_VERSION}
  20379. {$ENDIF WIN}
  20380. //[END FileFullPath]
  20381. {$IFDEF WIN}
  20382. //[function FileShortPath]
  20383. function FileShortPath( const FileName: KOLString ): KOLString;
  20384. {$ifdef wince}
  20385. begin
  20386. Result:=FileName;
  20387. end;
  20388. {$else wince}
  20389. var Buf: array[ 0..MAX_PATH ] of KOLChar;
  20390. begin
  20391. GetShortPathName( PKOLChar( FileName ), Buf, Sizeof( Buf ) );
  20392. Result := Buf;
  20393. end;
  20394. {$endif wince}
  20395. //[function FileIconSystemIdx]
  20396. function FileIconSystemIdx( const Path: KOLString ): Integer;
  20397. var SFI: TShFileInfo;
  20398. begin
  20399. SFI.iIcon := 0; // Bartov
  20400. {$IFDEF UNICODE_CTRLS} ShGetFileInfoW {$ELSE} ShGetFileInfoA {$ENDIF}
  20401. ( PKOLChar( Path ), 0, SFI, sizeof( SFI ), SHGFI_SMALLICON or SHGFI_SYSICONINDEX );
  20402. Result := SFI.iIcon;
  20403. end;
  20404. //[function FileIconSysIdxOffline]
  20405. function FileIconSysIdxOffline( const Path: KOLString ): Integer;
  20406. var SFI: TShFileInfo;
  20407. begin
  20408. SFI.iIcon := 0; // Bartov
  20409. {$IFDEF UNICODE_CTRLS} ShGetFileInfoW {$ELSE} ShGetFileInfoA {$ENDIF}
  20410. ( PKOLChar( Path ), FILE_ATTRIBUTE_NORMAL, SFI, sizeof( SFI ),
  20411. SHGFI_SMALLICON or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES );
  20412. Result := SFI.iIcon;
  20413. end;
  20414. {$ENDIF WIN}
  20415. //[procedure LogFileOutput]
  20416. procedure LogFileOutput( const filepath, str: String );
  20417. var F: THandle;
  20418. Tmp: String;
  20419. begin
  20420. F := FileCreate( filepath, ofOpenWrite or ofOpenAlways or ofShareDenyWrite );
  20421. if F = INVALID_HANDLE_VALUE then Exit;
  20422. FileSeek( F, 0, spEnd );
  20423. Tmp := str + {$IFDEF LIN} #10 {$ELSE} #13#10 {$ENDIF};
  20424. FileWrite( F, PChar( Tmp )^, Length( Tmp ) );
  20425. FileClose( F );
  20426. end;
  20427. //[function StrLoadFromFile]
  20428. function StrLoadFromFile( const Filename: KOLString ): String;
  20429. var F: THandle;
  20430. begin
  20431. {$IFDEF WIN32}
  20432. if StrEq( Filename, 'CON' ) then
  20433. Result := File2Str(GetStdHandle(STD_INPUT_HANDLE))
  20434. else
  20435. {$ENDIF WIN32}
  20436. begin
  20437. Result := '';
  20438. F := FileCreate( Filename, ofOpenRead or ofOpenExisting or ofShareDenyWrite );
  20439. if F = INVALID_HANDLE_VALUE then Exit;
  20440. Result := File2Str( F );
  20441. FileClose( F ); {Dark Knight}
  20442. end;
  20443. end;
  20444. //[function StrSaveToFile]
  20445. function StrSaveToFile( const Filename: KOLString; const Str: String ): Boolean;
  20446. begin
  20447. Result := Mem2File( PKOLChar( Filename ), PChar( Str ), Length( Str ) )
  20448. = Length( Str );
  20449. end;
  20450. {$IFNDEF _D2}
  20451. function WStrLoadFromFile( const Filename: KOLString ): WideString;
  20452. var F: THandle;
  20453. begin
  20454. {$IFDEF WIN32}
  20455. if StrEq( Filename, 'CON' ) then
  20456. Result := File2WStr(GetStdHandle(STD_INPUT_HANDLE))
  20457. else
  20458. {$ENDIF WIN32}
  20459. begin
  20460. Result := '';
  20461. F := FileCreate( Filename, ofOpenRead or ofOpenExisting or ofShareDenyWrite );
  20462. if F = INVALID_HANDLE_VALUE then Exit;
  20463. Result := File2Str( F );
  20464. FileClose( F ); {Dark Knight}
  20465. end;
  20466. end;
  20467. function WStrSaveToFile( const Filename: KOLString; const Str: WideString ): Boolean;
  20468. begin
  20469. Result := Mem2File( PKOLChar( Filename ), PWideChar( Str ), Length( Str ) )
  20470. = Length( Str );
  20471. end;
  20472. {$ENDIF _D2}
  20473. //[function Mem2File]
  20474. function Mem2File( Filename: PKOLChar; Mem: Pointer; Len: Integer ): Integer;
  20475. var F: THandle;
  20476. begin
  20477. Result := 0;
  20478. F := FileCreate( Filename, ofOpenWrite or ofCreateAlways );
  20479. if F = INVALID_HANDLE_VALUE then Exit;
  20480. Result := FileWrite( F, Mem^, Len );
  20481. FileClose( F );
  20482. end;
  20483. //[function File2Mem]
  20484. function File2Mem( Filename: PKOLChar; Mem: Pointer; MaxLen: Integer ): Integer;
  20485. var F: THandle;
  20486. begin
  20487. Result := 0;
  20488. F := FileCreate( Filename, ofOpenRead or ofOpenExisting or ofShareDenyWrite );
  20489. if F = INVALID_HANDLE_VALUE then Exit;
  20490. Result := FileRead( F, Mem^, MaxLen );
  20491. FileClose( F );
  20492. end;
  20493. {$IFDEF WIN}
  20494. function Find_First( const FilePathName: KOLString; var F: TFindFileData ): Boolean;
  20495. begin
  20496. F.FindHandle := FindFirstFile( PKOLChar( FilePathName ),
  20497. {$IFDEF UNICODE_CTRLS} PWin32FindDataW {$ELSE} PWin32FindData {$ENDIF}
  20498. ( @ F )^ );
  20499. Result := F.FindHandle <> INVALID_HANDLE_VALUE;
  20500. end;
  20501. function Find_Next( var F: TFindFileData ): Boolean;
  20502. begin
  20503. Result := FindNextFile( F.FindHandle,
  20504. {$IFDEF UNICODE_CTRLS} PWin32FindDataW {$ELSE} PWin32FindData {$ENDIF}
  20505. ( @ F )^ );
  20506. end;
  20507. procedure Find_Close( var F: TFindFileData );
  20508. begin
  20509. Windows.FindClose( F.FindHandle );
  20510. end;
  20511. {$ENDIF WIN}
  20512. //[FUNCTION FileSize]
  20513. {$IFDEF WIN}
  20514. function FileSize( const Path: KOLString ) : {$IFDEF _D2orD3} Integer {$ELSE} Int64 {$ENDIF};
  20515. var FD : TFindFileData;
  20516. begin
  20517. Result := 0;
  20518. if not Find_First( Path, FD ) then exit;
  20519. {$IFDEF _D2orD3}
  20520. Result := FD.nFileSizeLow;
  20521. {$ELSE}
  20522. I64( Result ).Lo := FD.nFileSizeLow;
  20523. I64( Result ).Hi := FD.nFileSizeHigh;
  20524. {$ENDIF}
  20525. Find_Close( FD );
  20526. end;
  20527. {$ENDIF WIN}
  20528. //[END FileSize]
  20529. //[procedure FileTime]
  20530. procedure FileTime( const Path: KOLString;
  20531. CreateTime, LastAccessTime, LastModifyTime: PFileTime );
  20532. var FD : TFindFileData;
  20533. begin
  20534. if not Find_First( Path, FD ) then exit;
  20535. if CreateTime <> nil then
  20536. CreateTime^ := FD.ftCreationTime;
  20537. if LastAccessTime <> nil then
  20538. LastAccessTime^ := FD.ftLastAccessTime;
  20539. if LastModifyTime <> nil then
  20540. LastModifyTime^ := FD.ftLastWriteTime;
  20541. Find_Close( FD );
  20542. end;
  20543. //[function GetUniqueFilename]
  20544. function GetUniqueFilename( PathName: KOLstring ) : KOLString;
  20545. var Path, Nam, Ext : KOLString;
  20546. I, J, K : Integer;
  20547. begin
  20548. Result := PathName;
  20549. Path := ExtractFilePath( PathName );
  20550. if not DirectoryExists( Path ) then Exit;
  20551. Nam := ExtractFileNameWOext( PathName );
  20552. if Nam = '' then
  20553. begin
  20554. Path := ExcludeTrailingPathDelimiter( Path );
  20555. PathName := Path;
  20556. Result := Path;
  20557. end;
  20558. Nam := ExtractFileNameWOext( PathName );
  20559. Ext := ExtractFileExt( PathName );
  20560. I := Length( Nam );
  20561. for J := I downto 1 do
  20562. if not ((Nam[ J ] >= '0') and (Nam[ J ] <= '9')) then
  20563. begin
  20564. I := J;
  20565. break;
  20566. end;
  20567. K := Str2Int( CopyEnd( Nam, I + 1 ) );
  20568. while FileExists( Result ) do
  20569. begin
  20570. Inc( K );
  20571. Result := Path + Copy( Nam, 1, I ) + Int2Str( K ) + Ext;
  20572. end;
  20573. end;
  20574. {$IFDEF WIN}
  20575. //[FUNCTION CompareSystemTime]
  20576. {$IFDEF ASM_VERSION}
  20577. {$ELSE ASM_VERSION} //Pascal
  20578. function CompareSystemTime(const D1, D2 : TSystemTime) : Integer;
  20579. var R: Integer;
  20580. procedure CompareFields(const F1, F2 : Integer);
  20581. begin
  20582. if R <> 0 then Exit;
  20583. if F1 = F2 then Exit;
  20584. if F1 < F2 then
  20585. R := -1
  20586. else
  20587. R := 1;
  20588. end;
  20589. begin
  20590. R := 0;
  20591. CompareFields( D1.wYear, D2.wYear );
  20592. CompareFields( D1.wMonth, D2.wMonth );
  20593. CompareFields( D1.wDay, D2.wDay );
  20594. CompareFields( D1.wHour, D2.wHour );
  20595. CompareFields( D1.wMinute, D2.wMinute );
  20596. CompareFields( D1.wSecond, D2.wSecond );
  20597. CompareFields( D1.wMilliseconds, D2.wMilliseconds );
  20598. Result := R;
  20599. end;
  20600. {$ENDIF ASM_VERSION}
  20601. //[END CompareSystemTime]
  20602. //[function FileTimeCompare]
  20603. function FileTimeCompare( const FT1, FT2 : TFileTime ) : Integer;
  20604. var ST1, ST2 : TSystemTime;
  20605. begin
  20606. FileTimeToSystemTime( FT1, ST1 );
  20607. FileTimeToSystemTime( FT2, ST2 );
  20608. Result := CompareSystemTime( ST1, ST2 );
  20609. end;
  20610. {$ENDIF WIN}
  20611. {$IFDEF WIN}
  20612. //[FUNCTION DirectoryExists]
  20613. {$IFDEF ASM_VERSION}
  20614. {$ELSE ASM_VERSION} //Pascal
  20615. function DirectoryExists(const Name: KOLString): Boolean;
  20616. var
  20617. Code: Integer;
  20618. {$ifndef wince}
  20619. e: DWORD;
  20620. {$endif wince}
  20621. begin
  20622. {$ifndef wince}
  20623. e := SetErrorMode( SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS );
  20624. {$endif wince}
  20625. Code := GetFileAttributes(PKOLChar(Name));
  20626. Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
  20627. {$ifndef wince}
  20628. SetErrorMode( e );
  20629. {$endif wince}
  20630. end;
  20631. {$ENDIF ASM_VERSION}
  20632. //[END DirectoryExists]
  20633. function DiskPresent( const DrivePath: KOLString ): Boolean;
  20634. {$ifndef wince}
  20635. var e: DWORD;
  20636. restore: Boolean;
  20637. {$endif wince}
  20638. begin
  20639. {$ifndef wince}
  20640. e := 0;
  20641. Restore := FALSE;
  20642. if (Copy( DrivePath, 1, 2 ) = '\\') then
  20643. else
  20644. CASE GetDriveType( PKOLChar( DrivePath ) ) OF
  20645. DRIVE_REMOVABLE, DRIVE_CDROM, DRIVE_RAMDISK:
  20646. begin
  20647. e := SetErrorMode( SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS );
  20648. Restore := TRUE;
  20649. end;
  20650. END;
  20651. {$endif wince}
  20652. Result := DirectoryExists( DrivePath );
  20653. {$ifndef wince}
  20654. if Restore then
  20655. SetErrorMode( e );
  20656. {$endif wince}
  20657. end;
  20658. {$IFDEF _D3orHigher}
  20659. function WDirectoryExists(const Name: WideString): Boolean;
  20660. var
  20661. Code: Integer;
  20662. begin
  20663. Code := GetFileAttributesW(PWideChar(Name));
  20664. Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
  20665. end;
  20666. {$ENDIF _D3orHigher}
  20667. {$ENDIF WIN}
  20668. //[function CheckDirectoryContent]
  20669. function CheckDirectoryContent( const Name: KOLString; SubDirsOnly: Boolean; const Mask: String ): Boolean;
  20670. var FD: TFindFileData;
  20671. begin
  20672. if not DirectoryExists( Name ) then
  20673. Result := TRUE
  20674. else
  20675. begin
  20676. if not Find_First( IncludeTrailingPathDelimiter( Name ) + Mask, FD ) then
  20677. Result := TRUE
  20678. else
  20679. begin
  20680. Result := TRUE;
  20681. repeat
  20682. if not {$IFDEF UNICODE_CTRLS}WStrIn{$ELSE}StrIn{$ENDIF}( FD.cFileName, ['.','..'] ) then
  20683. begin
  20684. if SubDirsOnly and LongBool(FD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)
  20685. or not SubDirsOnly then
  20686. begin
  20687. Result := FALSE;
  20688. break;
  20689. end;
  20690. end;
  20691. until not Find_Next( FD );
  20692. Find_Close( FD );
  20693. end;
  20694. end;
  20695. end;
  20696. //[function DirectoryEmpty]
  20697. function DirectoryEmpty(const Name: KOLString): Boolean;
  20698. begin
  20699. Result := CheckDirectoryContent( Name, FALSE, '*.*' );
  20700. end;
  20701. //[function DirectoryHasSubdirs]
  20702. function DirectoryHasSubdirs( const Path: KOLString ): Boolean;
  20703. begin
  20704. Result := not CheckDirectoryContent( Path, TRUE, '*.*' );
  20705. end;
  20706. //[FUNCTION GetStartDir]
  20707. {$IFDEF ASM_UNICODE}
  20708. {$ELSE ASM_VERSION} //Pascal
  20709. {$IFDEF WIN}
  20710. {$UNDEF LINUX_USE_HOME_STARTFDIR}
  20711. {$ENDIF}
  20712. function GetStartDir : KOLString;
  20713. {$IFNDEF LINUX_USE_HOME_STARTFDIR}
  20714. var Buffer:array[0..MAX_PATH] of KOLChar;
  20715. I : Integer;
  20716. {$ENDIF}
  20717. begin
  20718. {$IFDEF LINUX_USE_HOME_STARTFDIR}
  20719. Result := getenv( 'HOME' );
  20720. {$ELSE}
  20721. I := GetModuleFileName( 0, Buffer, MAX_PATH );
  20722. for I := I downto 0 do
  20723. if Buffer[ I ] = {$IFDEF LIN} '/' {$ELSE} '\' {$ENDIF} then
  20724. begin
  20725. Buffer[ I + 1 ] := #0;
  20726. break;
  20727. end;
  20728. Result := Buffer;
  20729. {$ENDIF}
  20730. end;
  20731. {$ENDIF ASM_VERSION}
  20732. //[END GetStartDir]
  20733. //[FUNCTION ExePath]
  20734. function ExePath: KOLString;
  20735. var Buffer: array[ 0..MAX_PATH+1 ] of KOLChar;
  20736. begin
  20737. Buffer[ MAX_PATH+1 ] := #0;
  20738. GetModuleFileName( hInstance, Buffer, MAX_PATH+1 );
  20739. Result := Buffer;
  20740. end;
  20741. {-}
  20742. //[function DirectorySize]
  20743. function DirectorySize( const Path: KOLString ): I64;
  20744. var DirList: PDirList;
  20745. I: Integer;
  20746. begin
  20747. Result := MakeInt64( 0, 0 );
  20748. DirList := NewDirList( Path, {$IFDEF LIN} '*' {$ELSE} '*.*' {$ENDIF}, 0 );
  20749. for I := 0 to DirList.Count-1 do
  20750. begin
  20751. if LongBool( DirList.Items[ I ].dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY ) then
  20752. Result := Add64( Result, DirectorySize( DirList.Path + DirList.Names[ I ] ) )
  20753. else
  20754. Result := Add64( Result, MakeInt64( DirList.Items[ I ].nFileSizeLow,
  20755. DirList.Items[ I ].nFileSizeHigh ) );
  20756. end;
  20757. DirList.Free;
  20758. end;
  20759. {+}
  20760. {$IFDEF WIN} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  20761. //[function GetFileList]
  20762. function GetFileList(const dir: string): PStrList;
  20763. var
  20764. Srch: TFindFileData;
  20765. succ: boolean;
  20766. begin
  20767. result := nil;
  20768. succ := Find_First(dir, Srch);
  20769. while succ do begin
  20770. if (not (Srch.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY > 0))then begin
  20771. if Result = nil then begin
  20772. Result := NewStrList;
  20773. end;
  20774. Result.Add(Srch.cFileName);
  20775. end;
  20776. succ := Find_Next(Srch);
  20777. end;
  20778. Find_Close(Srch);
  20779. end;
  20780. {$ENDIF WIN}
  20781. //[function ExcludeTrailingChar]
  20782. function ExcludeTrailingChar( const S: KOLString; C: KOLChar ): KOLString;
  20783. begin
  20784. Result := S;
  20785. if Result <> '' then
  20786. if Result[ Length( Result ) ] = C then
  20787. Delete( Result, Length( Result ), 1 );
  20788. end;
  20789. //[function IncludeTrailingChar]
  20790. {$IFDEF ASM_UNICODE}
  20791. function IncludeTrailingChar( const S: KOLString; C: KOLChar ): KOLString;
  20792. asm
  20793. push edx
  20794. push ecx
  20795. xchg ecx, eax
  20796. xchg edx, ecx
  20797. call System.@LStrAsg
  20798. pop eax
  20799. pop edx
  20800. mov ecx, [eax]
  20801. jecxz @@1
  20802. add ecx, [ecx-4]
  20803. dec ecx
  20804. cmp byte ptr [ecx], dl
  20805. jz @@exit
  20806. @@1:
  20807. push eax
  20808. push 0
  20809. mov eax, esp
  20810. call System.@LStrFromChar
  20811. mov edx, [esp]
  20812. mov eax, [esp+4]
  20813. call System.@LStrCat
  20814. call RemoveStr
  20815. pop eax
  20816. @@exit:
  20817. end;
  20818. {$ELSE PASCAL}
  20819. function IncludeTrailingChar( const S: KOLString; C: KOLChar ): KOLString;
  20820. begin
  20821. Result := S;
  20822. if (Result = '') or (Result[ Length( Result ) ] <> C) then
  20823. Result := Result + C;
  20824. end;
  20825. {$ENDIF ASM_VERSION}
  20826. //---------------------------------------------------------
  20827. // Following functions/procedures are created by Edward Aretino:
  20828. // IncludeTrailingPathDelimiter, ExcludeTrailingPathDelimiter,
  20829. // ForceDirectories, CreateDir, ChangeFileExt
  20830. //---------------------------------------------------------
  20831. //[function IncludeTrailingPathDelimiter]
  20832. function IncludeTrailingPathDelimiter(const S: KOLstring): KOLstring;
  20833. begin
  20834. Result := IncludeTrailingChar( S, {$IFDEF UNIX} '/' {$ELSE} '\' {$ENDIF} );
  20835. end;
  20836. //[function ExcludeTrailingPathDelimiter]
  20837. function ExcludeTrailingPathDelimiter(const S: KOLstring): KOLstring;
  20838. begin
  20839. Result := ExcludeTrailingChar( S, {$IFDEF UNIX} '/' {$ELSE} '\' {$ENDIF} );
  20840. end;
  20841. function ExtractFileDrive( const Path: KOLString ) : KOLString;
  20842. var i, j: Integer;
  20843. begin
  20844. Result := Path;
  20845. if Result = '' then Exit;
  20846. if pos( ':', Result ) > 1 then
  20847. Result := Parse( Result, ':' ) + ':\'
  20848. else
  20849. if Length( Result ) > 2 then
  20850. begin
  20851. j := 0;
  20852. for i := 3 to Length( Result ) do
  20853. if Result[ i ] = '\' then
  20854. begin
  20855. inc( j );
  20856. if j = 2 then
  20857. begin
  20858. Result := Copy( Result, 1, i );
  20859. break;
  20860. end;
  20861. end;
  20862. Result := IncludeTrailingPathDelimiter( Result );
  20863. end
  20864. else
  20865. if Length( Result ) = 1 then
  20866. Result := Result + ':\';
  20867. end;
  20868. //[FUNCTION ExtractFilePath]
  20869. {$IFDEF ASM_LStrFromPCharLen} // LStrFromPCharLen - there are no in D2
  20870. function ExtractFilePath( const Path : String ) : String;
  20871. asm
  20872. PUSH EDX
  20873. MOV EDX, [DirDelimiters]
  20874. CALL EAX2PChar
  20875. PUSH EAX
  20876. CALL __DelimiterLast
  20877. XCHG EDX, EAX
  20878. XOR ECX, ECX
  20879. POP EAX
  20880. CMP byte ptr [EDX], CL
  20881. JZ @@ret_0
  20882. SUB EDX, EAX
  20883. INC EDX
  20884. XCHG EDX, EAX
  20885. XCHG ECX, EAX
  20886. @@ret_0:
  20887. POP EAX
  20888. CALL System.@LStrFromPCharLen
  20889. end;
  20890. {$ELSE} //Pascal
  20891. function ExtractFilePath( const Path : KOLString ) : KOLString;
  20892. //var I : Integer;
  20893. var P, P0: PKOLChar;
  20894. begin
  20895. P0 := PKOLChar( Path );
  20896. P := __DelimiterLast( P0, ':\/' );
  20897. if P^ = #0 then
  20898. Result := ''
  20899. else
  20900. Result := Copy( Path, 1, P - P0 + 1 );
  20901. end;
  20902. {$ENDIF ASM_VERSION}
  20903. {$IFDEF _D3orHigher}
  20904. function WExtractFilePath( const Path: WideString ) : WideString;
  20905. var P, P0: PWideChar;
  20906. begin
  20907. P0 := PWideChar( Path );
  20908. P := W__DelimiterLast( P0, ':\/' );
  20909. if P^ = #0 then
  20910. Result := ''
  20911. else
  20912. Result := Copy( Path, 1, P - P0 + 1 );
  20913. end;
  20914. {$ENDIF}
  20915. {$IFDEF ASM_VERSION}
  20916. {$IFNDEF _D2}
  20917. {$DEFINE ASM_LStrFromPCharLen}
  20918. {$ENDIF}
  20919. {$ENDIF ASM_VERSION}
  20920. {$IFDEF ASM_LStrFromPCharLen}
  20921. {$DEFINE ASM_DIRDelimiters}
  20922. {$ENDIF}
  20923. {$IFDEF ASM_VERSION}
  20924. {$DEFINE ASM_DIRDelimiters}
  20925. {$ENDIF ASM_VERSION}
  20926. {$IFDEF ASM_DIRDelimiters}
  20927. const
  20928. DirDelimiters: PChar = ':\/';
  20929. {$ENDIF}
  20930. function IsNetworkPath( const Path: KOLString ): Boolean;
  20931. begin
  20932. Result := (Length( Path ) >= 2) and (Path[1] = '\') and (Path[2] = '\');
  20933. end;
  20934. //[FUNCTION ExtractFileName]
  20935. {$IFDEF ASM_UNICODE}
  20936. {$ELSE ASM_VERSION} //Pascal
  20937. function ExtractFileName( const Path : KOLString ) : KOLString;
  20938. var P: PKOLChar;
  20939. begin
  20940. P := __DelimiterLast( PKOLChar( Path ), ':\/' );
  20941. if P^ = #0 then
  20942. Result := Path
  20943. else
  20944. Result := P + 1;
  20945. end;
  20946. {$ENDIF ASM_VERSION}
  20947. //[END ExtractFileName]
  20948. //[function ExtractFileNameWOext]
  20949. {$IFDEF ASM_UNICODE}
  20950. function ExtractFileNameWOext( const Path : KOLString ) : KOLString;
  20951. asm
  20952. push ebx
  20953. push edx
  20954. push eax
  20955. call ExtractFileName
  20956. pop edx // Path - íå íóæåí áîëüøå
  20957. mov eax, [esp] // eax = Result = ExtractFileName(Path)
  20958. mov eax, [eax]
  20959. push 0
  20960. mov edx, esp
  20961. call ExtractFileExt
  20962. mov eax, [esp]
  20963. call System.@LStrLen
  20964. xchg ebx, eax // ebx = Length(ExtractFileExt(Result))
  20965. call RemoveStr // ExtractFileExt - áîëüøå íå íóæåí
  20966. mov eax, [esp]
  20967. mov eax, [eax]
  20968. call System.@LStrLen // eax = Length(Result)
  20969. sub eax, ebx
  20970. xchg ecx, eax
  20971. xor edx, edx
  20972. inc edx
  20973. mov eax, [esp]
  20974. mov eax, [eax]
  20975. call System.@LStrCopy
  20976. pop ebx
  20977. end;
  20978. {$ELSE PASCAL}
  20979. function ExtractFileNameWOext( const Path : KOLString ) : KOLString;
  20980. begin
  20981. Result := ExtractFileName( Path );
  20982. Result := Copy( Result, 1, Length( Result ) - Length( ExtractFileExt( Result ) ) );
  20983. end;
  20984. {$ENDIF ASM_VERSION}
  20985. {$IFDEF ASM_UNICODE}
  20986. const
  20987. ExtDelimeters: PChar = '.';
  20988. //[function ExtractFileExt]
  20989. function ExtractFileExt( const Path : KOLString ) : KOLString;
  20990. asm
  20991. PUSH EDX
  20992. MOV EDX, [ExtDelimeters]
  20993. CALL EAX2PChar
  20994. CALL __DelimiterLast
  20995. @@1: XCHG EDX, EAX
  20996. POP EAX
  20997. CALL System.@LStrFromPChar
  20998. end;
  20999. {$ELSE ASM_VERSION} //Pascal
  21000. function ExtractFileExt( const Path : KOLString ) : KOLString;
  21001. var P: PKOLChar;
  21002. begin
  21003. P := __DelimiterLast( PKOLChar( Path ), '.' );
  21004. Result := P;
  21005. end;
  21006. {$ENDIF ASM_VERSION}
  21007. //[END ExtractFilePath]
  21008. //[function ReplaceExt]
  21009. {$IFDEF ASM_UNICODE}
  21010. function ReplaceExt( const Path, NewExt: KOLString ): KOLString;
  21011. asm
  21012. push ecx // result
  21013. push edx // NewExt
  21014. push eax // Path
  21015. push 0
  21016. mov edx, esp
  21017. call ExtractFilePath
  21018. pop eax
  21019. xchg [esp], eax // eax=Path, Path in stack replaced with ExtractFilePath(Path)
  21020. push 0
  21021. mov edx, esp
  21022. call ExtractFileNameWOext
  21023. // now stack conatins: result,NewExt,ExtractFilePath(Path),ExtractFileNameWOext(Path)<-ESP
  21024. mov eax, [esp+12]
  21025. mov edx, esp
  21026. push dword ptr [edx+4] // ExtractFilePath(Path)
  21027. push dword ptr [edx] // ExtractFileNameWOext(Path)
  21028. push dword ptr [edx+8] // NewExt
  21029. mov edx, 3
  21030. call System.@LStrCatN
  21031. call RemoveStr
  21032. call RemoveStr
  21033. pop ecx
  21034. pop ecx
  21035. end;
  21036. {$ELSE PASCAL}
  21037. function ReplaceExt( const Path, NewExt: KOLString ): KOLString;
  21038. begin
  21039. Result := ExtractFilePath( Path ) + ExtractFileNameWOext( Path ) +
  21040. NewExt;
  21041. end;
  21042. {$ENDIF}
  21043. //[function ForceDirectories]
  21044. function ForceDirectories(Dir: KOLString): Boolean;
  21045. begin
  21046. Result := Length(Dir) > 0; {Centronix}
  21047. If not Result then Exit;
  21048. Dir := ExcludeTrailingPathDelimiter(Dir);
  21049. If (Length(Dir) < 3) or DirectoryExists(Dir) or
  21050. (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
  21051. Result := ForceDirectories(ExtractFilePath(Dir)) and CreateDir(Dir);
  21052. end;
  21053. //[function CreateDir]
  21054. function CreateDir(const Dir: KOLString): Boolean;
  21055. begin
  21056. Result := {$IFDEF WIN} {Windows.}CreateDirectory(PKOLChar(Dir), nil)
  21057. {$ELSE LIN} Libc.__mkdir(PChar(Dir), S_IRWXU or S_IRWXG or S_IRWXO) = 0
  21058. {$ENDIF};
  21059. end;
  21060. //[function ChangeFileExt]
  21061. function ChangeFileExt(FileName: KOLString; const Extension: KOLstring): KOLstring;
  21062. var
  21063. FileExt: KOLString;
  21064. begin
  21065. FileExt := ExtractFileExt(FileName);
  21066. DeleteTail(FileName, Length(FileExt));
  21067. Result := FileName+ Extension;
  21068. end;
  21069. //[function ReplaceFileExt]
  21070. function ReplaceFileExt( const Path, NewExt: KOLString ): KOLString;
  21071. begin
  21072. Result := ExtractFilePath( Path ) +
  21073. ExtractFileNameWOext( ExtractFileName( Path ) ) +
  21074. NewExt;
  21075. end;
  21076. {$IFDEF WIN} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  21077. //[function ExtractShortPathName]
  21078. function ExtractShortPathName( const Path: KOLString ): KOLString;
  21079. {$ifdef wince}
  21080. begin
  21081. Result:=Path;
  21082. {$else}
  21083. var
  21084. Buffer: array[0..MAX_PATH - 1] of KOLChar;
  21085. begin
  21086. SetString(Result, Buffer,
  21087. GetShortPathName(PKOLChar(Path), Buffer, SizeOf(Buffer) div Sizeof(KOLChar)));
  21088. {$endif wince}
  21089. end;
  21090. {$IFDEF GDI}
  21091. //[function FilePathShortened]
  21092. function FilePathShortened( const Path: KOLString; MaxLen: Integer ): KOLString;
  21093. begin
  21094. Result := FilePathShortenPixels( Path, 0, MaxLen );
  21095. end;
  21096. //[function PixelsLength]
  21097. function PixelsLength( DC: HDC; const Text: KOLString ): Integer;
  21098. var Sz: TSize;
  21099. begin
  21100. if DC = 0 then
  21101. Result := Length( Text )
  21102. else
  21103. begin
  21104. {Windows.}GetTextExtentPoint32( DC, PKOLChar( Text ), Length( Text ), Sz );
  21105. Result := Sz.cx;
  21106. end;
  21107. end;
  21108. //[function FilePathShortenPixels]
  21109. function FilePathShortenPixels( const Path: KOLString; DC: HDC; MaxPixels: Integer ): KOLString;
  21110. var L0, L1: Integer;
  21111. Prev: KOLString;
  21112. begin
  21113. Result := Path;
  21114. L0 := PixelsLength( DC, Result );
  21115. while L0 > MaxPixels do
  21116. begin
  21117. Prev := Result;
  21118. L1 := pos( '\...\', Result );
  21119. if L1 <= 0 then
  21120. Result := ExcludeTrailingPathDelimiter( ExtractFilePath( Result ) )
  21121. else
  21122. Result := Copy( Result, 1, L1 - 1 );
  21123. if Result <> '' then
  21124. Result := IncludeTrailingPathDelimiter( ExtractFilePath( Result ) ) + '...\' + ExtractFileName( Path );
  21125. if (Result = '') or (Result = Prev) then
  21126. begin
  21127. L1 := Length( ExtractFilePath( Result ) );
  21128. while (PixelsLength( DC, Result ) > MaxPixels) and (L1 > 1) do
  21129. begin
  21130. Dec( L1 );
  21131. Result := Copy( Result, 1, L1 ) + '...\' + ExtractFileName( Result );
  21132. end;
  21133. if PixelsLength( DC, Result ) > MaxPixels then
  21134. begin
  21135. L1 := MaxPixels + 1;
  21136. while ((MaxPixels > 0) and (L1 > 1) or (MaxPixels = 0) and (L1 > 0)) and
  21137. (PixelsLength( DC, Result ) > MaxPixels) do
  21138. begin
  21139. Dec( L1 );
  21140. Result := Copy( ExtractFileName( Path ), 1, L1 ) + '...';
  21141. end;
  21142. end;
  21143. break;
  21144. end;
  21145. L0 := PixelsLength( DC, Result );
  21146. end;
  21147. end;
  21148. {$ENDIF GDI}
  21149. //[procedure CutFirstDirectory]
  21150. procedure CutFirstDirectory(var S: KOLString);
  21151. var
  21152. Root: Boolean;
  21153. P: Integer;
  21154. begin
  21155. if S = '\' then
  21156. S := ''
  21157. else
  21158. begin
  21159. if S[1] = '\' then
  21160. begin
  21161. Root := True;
  21162. Delete(S, 1, 1);
  21163. end
  21164. else
  21165. Root := False;
  21166. if S[1] = '.' then
  21167. Delete(S, 1, 4);
  21168. P := pos('\',S);
  21169. if P <> 0 then
  21170. begin
  21171. Delete(S, 1, P);
  21172. S := '...\' + S;
  21173. end
  21174. else
  21175. S := '';
  21176. if Root then
  21177. S := '\' + S;
  21178. end;
  21179. end;
  21180. {$IFDEF GDI}
  21181. //[function MinimizeName]
  21182. function MinimizeName( const Path: KOLString; DC: HDC; MaxPixels: Integer ): KOLString;
  21183. var
  21184. Drive, Dir, Name: KOLString;
  21185. begin
  21186. Result := Path;
  21187. Dir := ExtractFilePath(Result);
  21188. Name := ExtractFileName(Result);
  21189. if (Length(Dir) >= 2) and (Dir[2] = ':') then
  21190. begin
  21191. Drive := Copy(Dir, 1, 2);
  21192. Delete(Dir, 1, 2);
  21193. end
  21194. else
  21195. Drive := '';
  21196. while ((Dir <> '') or (Drive <> '')) and (PixelsLength(DC, Result) > MaxPixels) do
  21197. begin
  21198. if Dir = '\...\' then
  21199. begin
  21200. Drive := '';
  21201. Dir := '...\';
  21202. end
  21203. else if Dir = '' then
  21204. Drive := ''
  21205. else
  21206. CutFirstDirectory(Dir);
  21207. Result := Drive + Dir + Name;
  21208. end;
  21209. end;
  21210. {$ENDIF GDI}
  21211. //[function GetSystemDir]
  21212. function GetSystemDir: KOLString;
  21213. {$ifdef wince}
  21214. begin
  21215. Result:=GetWindowsDir;
  21216. {$else}
  21217. var Buf: array[ 0..MAX_PATH ] of KOLChar;
  21218. begin
  21219. GetSystemDirectory( @ Buf[ 0 ], MAX_PATH + 1 );
  21220. Result := IncludeTrailingPathDelimiter( PKOLChar( @ Buf[ 0 ] ) );
  21221. {$endif wince}
  21222. end;
  21223. //*
  21224. //[function GetWindowsDir]
  21225. function GetWindowsDir : KOLstring;
  21226. {$ifdef wince}
  21227. var
  21228. wPath : array[0..MAX_PATH] of WideChar;
  21229. begin
  21230. if SHGetSpecialFolderPath(0, wPath, $0024{CSIDL_WINDOWS}, False) then
  21231. Result:=IncludeTrailingPathDelimiter(wPath)
  21232. else
  21233. Result:='';
  21234. {$else}
  21235. var Buf : array[ 0..MAX_PATH ] of KOLChar;
  21236. begin
  21237. GetWindowsDirectory( @Buf[ 0 ], MAX_PATH + 1 );
  21238. Result := IncludeTrailingPathDelimiter( PKOLChar( @ Buf[ 0 ] ) );
  21239. {$endif wince}
  21240. end;
  21241. {$ENDIF WIN} //^^^^^^^^^^^
  21242. //[function GetWorkDir]
  21243. {$IFDEF WIN}
  21244. function GetWorkDir : KOLstring;
  21245. {$ifdef wince}
  21246. begin
  21247. Result:='\';
  21248. {$else}
  21249. var Buf: array[ 0..MAX_PATH ] of Char;
  21250. begin
  21251. GetCurrentDirectory( MAX_PATH + 1, @ Buf[ 0 ] );
  21252. Result := IncludeTrailingPathDelimiter( PKOLChar( @ Buf[ 0 ] ) );
  21253. {$endif wince}
  21254. end;
  21255. {$ENDIF WIN}
  21256. //[function GetTempDir]
  21257. {$IFDEF ASM_UNICODE}
  21258. function GetTempDir : KOLstring;
  21259. asm
  21260. push eax
  21261. sub esp, 264
  21262. push esp
  21263. push 261
  21264. call GetTempPath
  21265. mov edx, esp
  21266. mov eax, [esp+264]
  21267. call System.@LStrFromPChar
  21268. add esp, 264
  21269. pop edx
  21270. mov eax, [edx]
  21271. call IncludeTrailingPathDelimiter
  21272. end;
  21273. {$ELSE PASCAL}
  21274. function GetTempDir : KOLstring;
  21275. {$IFDEF WIN} var Buf : array[ 0..MAX_PATH ] of KOLChar; {$ENDIF WIN}
  21276. begin
  21277. {$IFDEF LIN} Result := '/tmp/'; {$ELSE WIN}
  21278. GetTempPath( MAX_PATH + 1, @Buf[ 0 ] );
  21279. Result := IncludeTrailingPathDelimiter( PKOLChar( @ Buf[ 0 ] ) );
  21280. {$ENDIF WIN}
  21281. end;
  21282. {$ENDIF}
  21283. {$IFDEF WIN}
  21284. //[function CreateTempFile]
  21285. {$IFDEF ASM_UNICODE}
  21286. function CreateTempFile( const DirPath, Prefix: KOLString ): KOLString;
  21287. asm
  21288. push ecx
  21289. call EAX2PCHAR
  21290. call EDX2PCHAR
  21291. sub esp, 264
  21292. push esp
  21293. push 0
  21294. push edx
  21295. push eax
  21296. call GetTempFileName
  21297. mov eax, [esp+264]
  21298. mov edx, esp
  21299. call System.@LStrFromPChar
  21300. add esp, 268
  21301. end;
  21302. {$ELSE PASCAL}
  21303. function CreateTempFile( const DirPath, Prefix: KOLString ): KOLString;
  21304. var Buf: array[ 0..MAX_PATH ] of KOLChar;
  21305. begin
  21306. GetTempFileName( PKOLChar( DirPath ), PKOLChar( Prefix ), 0, Buf );
  21307. Result := Buf;
  21308. end;
  21309. {$ENDIF ASM_VERSION}
  21310. {$ENDIF WIN}
  21311. //[function GetFileListStr]
  21312. function GetFileListStr(FPath{e.g.'c:\tmp\'}, FMask{e.g.'*.*'}: KOLstring): KOLstring;
  21313. {* List of files in string, separating each path from others with FileOpSeparator.
  21314. E.g.: 'c:\tmp\unit1.dcu'#13'c:\tmp\unit1.~pa' (for use with DeleteFile2Recycle())}
  21315. var
  21316. Srch: TFindFileData;
  21317. succ: boolean;
  21318. dir:KOLstring;
  21319. begin
  21320. result := '';
  21321. if (FPath<>'') then FPath := IncludeTrailingPathDelimiter( FPath );
  21322. if (FMask<>'') and (FMask[1]={$IFDEF LIN} '/' {$ELSE} '\' {$ENDIF}) then
  21323. FMask := CopyEnd(FMask,2);
  21324. dir:=FPath+FMask;
  21325. succ := Find_First(dir, Srch);
  21326. while succ do begin
  21327. if (not (Srch.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY > 0))then begin
  21328. if Result<>''then Result:=Result+FileOpSeparator;
  21329. Result:=Result+FPath+Srch.cFileName;
  21330. end;
  21331. succ := Find_Next(Srch);
  21332. end;
  21333. Find_Close(Srch);
  21334. end;
  21335. //[function DeleteFiles]
  21336. function DeleteFiles( const DirPath: KOLString ): Boolean;
  21337. var Files, Name: KOLString;
  21338. begin
  21339. Files := GetFileListStr( ExtractFilePath( DirPath ), ExtractFileName( DirPath ) );
  21340. Result := TRUE;
  21341. while Files <> '' do
  21342. begin
  21343. Name := Parse( Files, FileOpSeparator );
  21344. Result := Result and DeleteFile( PKOLChar( Name ) );
  21345. end;
  21346. end;
  21347. {$IFDEF WIN_GDI} //>>>>>>>>>>>>
  21348. //[function DeleteFile2Recycle]
  21349. function DeleteFile2Recycle( const Filename : KOLString ) : Boolean;
  21350. begin
  21351. Result := DoFileOp( Filename, '', FO_DELETE, FOF_ALLOWUNDO or
  21352. FOF_NOCONFIRMATION or FOF_SIMPLEPROGRESS, 'Deleting...' );
  21353. end;
  21354. //[function CopyMoveFiles]
  21355. function CopyMoveFiles( const FromList, ToList: KOLString; Move: Boolean ): Boolean;
  21356. begin
  21357. Result := DoFileOp(FromList, ToList, FO_COPY - Integer( Move ),
  21358. FOF_ALLOWUNDO, nil); //|\\ FO_COPY = 2, FO_MOVE = 1
  21359. end;
  21360. {-}
  21361. //[function DiskFreeSpace]
  21362. function DiskFreeSpace( const Path: KOLString ): I64;
  21363. var
  21364. FBA, TNB: I64;
  21365. {$ifdef wince}
  21366. begin
  21367. GetDiskFreeSpaceEx( PKOLChar( Path ), @ FBA, @ TNB, @Result )
  21368. {$else}
  21369. type TGetDFSEx = function( Path: PKOLChar; CallerFreeBytes, TotalBytes, FreeBytes: Pointer )
  21370. : Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  21371. var GetDFSEx: TGetDFSEx;
  21372. Kern32: THandle;
  21373. V: TOSVersionInfo;
  21374. Ex: Boolean;
  21375. SpC, BpS, NFC, TNC: DWORD;
  21376. begin
  21377. GetDFSEx := nil;
  21378. V.dwOSVersionInfoSize := Sizeof( V );
  21379. GetVersionEx
  21380. ( POSVersionInfo( @ V )^ ); // bug in Windows.pas !
  21381. Ex := FALSE;
  21382. if V.dwPlatformId = VER_PLATFORM_WIN32_NT then
  21383. begin
  21384. Ex := V.dwMajorVersion >= 4;
  21385. end
  21386. else
  21387. if V.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS then
  21388. begin
  21389. Ex := V.dwMajorVersion > 4;
  21390. if not Ex then
  21391. if V.dwMajorVersion = 4 then
  21392. begin
  21393. Ex := V.dwMinorVersion > 0;
  21394. if not Ex then
  21395. Ex := LoWord( V.dwBuildNumber ) >= $1111;
  21396. end;
  21397. end;
  21398. if Ex then
  21399. begin
  21400. Kern32 := GetModuleHandle( 'kernel32' );
  21401. GetDFSEx := GetProcAddress( Kern32, 'GetDiskFreeSpaceExA' );
  21402. end;
  21403. if Assigned( GetDFSEx ) then
  21404. GetDFSEx( PKOLChar( Path ), @ FBA, @ TNB, @Result )
  21405. else
  21406. begin
  21407. GetDiskFreeSpace( PKOLChar( Path ), SpC, BpS, NFC, TNC );
  21408. Result := Mul64i( MakeInt64( SpC * BpS, 0 ), NFC );
  21409. end;
  21410. {$endif wince}
  21411. end;
  21412. {+}
  21413. //[END FILES]
  21414. //[function DoFileOp]
  21415. function DoFileOp( const FromList, ToList: KOLString; FileOp: UINT; Flags: Word;
  21416. Title: PKOLChar): Boolean;
  21417. var FOS : {$IFDEF UNICODE_CTRLS}TSHFileOpStructW{$ELSE}TSHFileOpStruct{$ENDIF};
  21418. Buf : PKOLChar;
  21419. L : Integer;
  21420. begin
  21421. L := Length( FromList );
  21422. Buf := AllocMem( L+2 );
  21423. Move( FromList[ 1 ], Buf^, L );
  21424. for L := L downto 0 do
  21425. if Buf[ L ] = FileOpSeparator then Buf[ L ] := #0;
  21426. FillChar( FOS, Sizeof( FOS ), #0 );
  21427. if Applet <> nil then
  21428. FOS.Wnd := Applet.Handle;
  21429. FOS.wFunc := FileOp;
  21430. FOS.lpszProgressTitle := Title;
  21431. FOS.pFrom := Buf;
  21432. FOS.pTo := PKOLChar( ToList + #0 );
  21433. FOS.fFlags := Flags;
  21434. FOS.fAnyOperationsAborted := True;
  21435. Result := {$IFDEF UNICODE_CTRLS}SHFileOperationW{$ELSE}SHFileOperationA{$ENDIF}( FOS ) = 0;
  21436. if Result then
  21437. Result := not FOS.fAnyOperationsAborted;
  21438. FreeMem( Buf );
  21439. end;
  21440. {$ENDIF WIN_GDI}
  21441. {$IFDEF WIN}
  21442. //[function DirIconSysIdxOffline]
  21443. function DirIconSysIdxOffline( const Path: KOLString ): Integer;
  21444. var SFI: TShFileInfo;
  21445. begin
  21446. SFI.iIcon := 0; // Bartov
  21447. {$IFDEF UNICODE_CTRLS} ShGetFileInfoW {$ELSE} ShGetFileInfoA {$ENDIF}
  21448. ( PKOLChar( Path ), FILE_ATTRIBUTE_DIRECTORY, SFI, sizeof( SFI ),
  21449. SHGFI_SMALLICON or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES );
  21450. Result := SFI.iIcon;
  21451. end;
  21452. {$ENDIF WIN}
  21453. { TDirList }
  21454. //[function NewDirList]
  21455. function NewDirList( const DirPath, Filter: KOLString; Attr: DWORD ): PDirList;
  21456. begin
  21457. {-}
  21458. New( Result, Create );
  21459. {+}{++}(*Result := PDirList.Create;*){--}
  21460. Result.ScanDirectory( DirPath, Filter, Attr );
  21461. end;
  21462. //[END NewDirList]
  21463. //[function NewDirListEx]
  21464. function NewDirListEx( const DirPath, Filters: KOLString; Attr: DWORD ): PDirList;
  21465. begin
  21466. {-}
  21467. New( Result, Create );
  21468. {+}{++}(*Result := PDirList.Create;*){--}
  21469. Result.ScanDirectoryEx( DirPath, Filters, Attr );
  21470. end;
  21471. //[END NewDirListEx]
  21472. //[procedure TDirList.Clear]
  21473. {$IFDEF ASM_VERSION}
  21474. {$ELSE ASM_VERSION} //Pascal
  21475. procedure TDirList.Clear;
  21476. begin
  21477. if FList <> nil then
  21478. FList.Release;
  21479. FList := nil;
  21480. end;
  21481. {$ENDIF ASM_VERSION}
  21482. //[destructor TDirList.Destroy]
  21483. {$IFDEF ASM_VERSION}
  21484. {$ELSE ASM_VERSION} //Pascal
  21485. destructor TDirList.Destroy;
  21486. begin
  21487. Clear;
  21488. FPath := '';
  21489. inherited;
  21490. end;
  21491. {$ENDIF ASM_VERSION}
  21492. //[FUNCTION FindFilter]
  21493. {$IFDEF ASM_UNICODE}
  21494. {$ELSE ASM_VERSION} //Pascal
  21495. function FindFilter(const Filter: KOLString): KOLString;
  21496. begin
  21497. Result := Filter;
  21498. if Result = '' then Result := '*.*';
  21499. end;
  21500. {$ENDIF ASM_VERSION}
  21501. //[END FindFilter]
  21502. //+
  21503. //[function TDirList.Get]
  21504. function TDirList.Get(Idx: Integer): PFindFileData;
  21505. begin
  21506. Result := FList.fItems[ Idx ];
  21507. end;
  21508. //[function TDirList.GetCount]
  21509. {$IFDEF ASM_VERSION}
  21510. {$ELSE ASM_VERSION} //Pascal
  21511. function TDirList.GetCount: Integer;
  21512. begin
  21513. Result := 0;
  21514. if FList = nil then Exit;
  21515. Result := FList.Count;
  21516. end;
  21517. {$ENDIF ASM_VERSION}
  21518. //[function TDirList.GetNames]
  21519. {$IFDEF ASM_UNICODE}
  21520. {$ELSE ASM_VERSION} //Pascal
  21521. function TDirList.GetNames(Idx: Integer): KOLString;
  21522. begin
  21523. Result := PKOLChar(@PFindFileData(fList.fItems[ Idx ]).cFileName[0]);
  21524. end;
  21525. {$ENDIF ASM_VERSION}
  21526. //[function TDirList.GetIsDirectory]
  21527. function TDirList.GetIsDirectory(Idx: Integer): Boolean;
  21528. begin
  21529. Result := LongBool( Items[ Idx ].dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY );
  21530. end;
  21531. {$IFDEF ASM_noVERSION}
  21532. //[function TDirList.SatisfyFilter]
  21533. function TDirList.SatisfyFilter(FileName: PChar; FileAttr,
  21534. FindAttr: DWord): Boolean;
  21535. asm
  21536. PUSH EBX
  21537. PUSH ESI
  21538. PUSH EDI
  21539. XCHG EBX, EAX // EBX = @ Self
  21540. MOV EAX, [FindAttr]
  21541. MOV EDI, EDX // EDI = FileName
  21542. MOV EDX, EAX
  21543. AND EDX, ECX
  21544. CMP EDX, EAX
  21545. JE @@1
  21546. TEST AL, FILE_ATTRIBUTE_NORMAL
  21547. JZ @@ret_false
  21548. @@1:
  21549. CMP word ptr [EDI], '.'
  21550. JE @@1_1
  21551. CMP word ptr [EDI], '..'
  21552. JNE @@1_1
  21553. CMP byte ptr [EDI+2], 0
  21554. JNE @@1_1
  21555. @@1_0:
  21556. MOV ECX, [FindAttr]
  21557. TEST CL, FILE_ATTRIBUTE_NORMAL
  21558. JZ @@1_1
  21559. CMP ECX, FILE_ATTRIBUTE_NORMAL
  21560. JE @@1_1
  21561. TEST AL, FILE_ATTRIBUTE_DIRECTORY
  21562. JZ @@1_1
  21563. TEST CL, FILE_ATTRIBUTE_DIRECTORY
  21564. JNZ @@ret_true
  21565. @@1_1:
  21566. MOV ECX, [EBX].fFilters
  21567. JECXZ @@ret_false //?
  21568. MOV ESI, [ECX].TStrList.fList
  21569. MOV ESI, [ESI].TList.fItems
  21570. MOV ECX, [ECX].TStrList.fCount
  21571. JECXZ @@ret_false
  21572. @@2:
  21573. LODSD
  21574. TEST EAX, EAX
  21575. JZ @@nx_filter
  21576. PUSHAD
  21577. MOV EDX, [EAX]
  21578. CMP DX, $002E
  21579. JE @@F_d_dd
  21580. AND EDX, $FFFFFF
  21581. CMP EDX, $002E2E
  21582. JE @@F_d_dd
  21583. MOV EDX, [EDI]
  21584. CMP DX, $002E
  21585. JE @@4
  21586. AND EDX, $FFFFFF
  21587. CMP EDX, $002E2E
  21588. JE @@4
  21589. JMP @@chk_anti
  21590. @@F_d_dd:
  21591. MOV EDX, EDI
  21592. PUSH EAX
  21593. CALL StrComp
  21594. TEST EAX, EAX
  21595. POP EAX
  21596. JZ @@popad_ret_true
  21597. @@chk_anti:
  21598. XCHG EDX, EAX // EDX = filter[ i ]
  21599. MOV EAX, EDI // EAX = FileName
  21600. CMP byte ptr [EDX], '^'
  21601. JNE @@3
  21602. INC EDX
  21603. CALL _2StrSatisfy
  21604. TEST AL, AL
  21605. JZ @@4
  21606. POPAD
  21607. JMP @@ret_false
  21608. @@3: CALL _2StrSatisfy
  21609. TEST AL, AL
  21610. JZ @@4
  21611. @@popad_ret_true:
  21612. POPAD
  21613. @@ret_true:
  21614. MOV AL, 1
  21615. JMP @@exit
  21616. @@4: POPAD
  21617. @@nx_filter:
  21618. LOOP @@2
  21619. @@ret_false:
  21620. XOR EAX, EAX
  21621. @@exit:
  21622. POP EDI
  21623. POP ESI
  21624. POP EBX
  21625. end;
  21626. {$ELSE ASM_VERSION} //Pascal
  21627. function TDirList.SatisfyFilter(FileName: PKOLChar; FileAttr,
  21628. FindAttr: DWord): Boolean;
  21629. {$IFDEF F_P}
  21630. const Dot: String = '.';
  21631. {$ENDIF F_P}
  21632. var I: Integer;
  21633. F: PKOLChar;
  21634. HasOnlyNegFilters: Boolean;
  21635. begin
  21636. Result := (((FileAttr and FindAttr) = FindAttr) or
  21637. LongBool(FindAttr and FILE_ATTRIBUTE_NORMAL));
  21638. if not Result then Exit;
  21639. if (FileName <> {$IFDEF UNICODE_CTRLS} WideString( '.' )
  21640. {$ELSE} {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}
  21641. {$ENDIF UNICODE_CTRLS} ) and
  21642. (FileName <> '..') then
  21643. if LongBool( FindAttr and FILE_ATTRIBUTE_NORMAL ) and
  21644. (FindAttr <> FILE_ATTRIBUTE_NORMAL) then
  21645. if LongBool( FindAttr and FILE_ATTRIBUTE_DIRECTORY ) and
  21646. LongBool( FileAttr and FILE_ATTRIBUTE_DIRECTORY ) then Exit;
  21647. HasOnlyNegFilters := TRUE;
  21648. for I := 0 to fFilters.Count - 1 do
  21649. begin
  21650. F := PKOLChar(fFilters.fList.fItems[ I ]);
  21651. if F = '' then continue;
  21652. if (F = {$IFDEF UNICODE_CTRLS} WideString( '.' ) {$ELSE}
  21653. {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}
  21654. {$ENDIF UNICODE_CTRLS} ) or (F = '..') then
  21655. begin
  21656. if FileName = F then
  21657. Exit;
  21658. end
  21659. else
  21660. if (Filename = {$IFDEF UNICODE_CTRLS} WideString( '.' ) {$ELSE}
  21661. {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}
  21662. {$ENDIF UNICODE_CTRLS} ) or (FileName = '..') then
  21663. continue;
  21664. if F[ 0 ] = '^' then
  21665. begin
  21666. if StrSatisfy( FileName, PChar(@F[ 1 ]) ) then
  21667. begin
  21668. Result := False;
  21669. Exit;
  21670. end;
  21671. end
  21672. else
  21673. begin
  21674. HasOnlyNegFilters := FALSE;
  21675. if StrSatisfy( FileName, F ) then
  21676. begin
  21677. Result := True;
  21678. Exit;
  21679. end;
  21680. end;
  21681. end;
  21682. Result := HasOnlyNegFilters and
  21683. (FileName <> {$IFDEF UNICODE_CTRLS} WideString( '.' ) {$ELSE}
  21684. {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}
  21685. {$ENDIF UNICODE_CTRLS} ) and (FileName <> '..');
  21686. end;
  21687. {$ENDIF ASM_VERSION}
  21688. {$IFDEF ASM_nononoVERSION}
  21689. //[procedure TDirList.ScanDirectory]
  21690. procedure TDirList.ScanDirectory(const DirPath, Filter: KOLString;
  21691. Attr: DWord);
  21692. const sz_win32finddata = sizeof(TWin32FindData);
  21693. asm
  21694. PUSH EBX
  21695. PUSH EDI
  21696. MOV EBX, EAX
  21697. PUSHAD
  21698. CALL Clear
  21699. CALL NewList
  21700. MOV [EBX].fList, EAX
  21701. POPAD
  21702. PUSHAD
  21703. LEA EAX, [EBX].fPath
  21704. CALL System.@LStrAsg
  21705. POPAD
  21706. MOV EAX, [EBX].fPath
  21707. TEST EAX, EAX
  21708. JE @@exit
  21709. PUSHAD
  21710. LEA EDX, [EBX].fPath
  21711. MOV EAX, [EDX]
  21712. CALL IncludeTrailingPathDelimiter
  21713. MOV EAX, [EBX].fFilters
  21714. TEST EAX, EAX
  21715. JNZ @@1
  21716. CALL NewStrList
  21717. MOV [EBX].fFilters, EAX
  21718. POPAD
  21719. PUSHAD
  21720. PUSH ECX
  21721. XCHG EAX, ECX
  21722. MOV EDX, offset[@@star_d_star]
  21723. CALL StrComp
  21724. TEST AL, AL
  21725. POP EDX
  21726. JNZ @@asg_Filter
  21727. MOV EDX, offset[@@star]
  21728. @@asg_Filter:
  21729. MOV EAX, [EBX].fFilters
  21730. CALL TStrList.Add
  21731. JMP @@1
  21732. @@star_d_star:
  21733. DB '*.*', 0
  21734. DD -1, 1
  21735. @@star: DB '*', 0
  21736. @@1:
  21737. POPAD
  21738. ADD ESP, -sz_win32finddata
  21739. XOR EDX, EDX
  21740. PUSH EDX
  21741. PUSH EDX
  21742. XCHG EAX, ECX
  21743. MOV EDX, ESP
  21744. CALL FindFilter
  21745. LEA EAX, [ESP+4]
  21746. MOV EDX, [EBX].fPath
  21747. POP ECX
  21748. PUSH ECX
  21749. CALL System.@LStrCat3
  21750. CALL RemoveStr
  21751. POP EAX
  21752. MOV EDX, ESP
  21753. PUSH EAX
  21754. PUSH EDX
  21755. PUSH EAX
  21756. CALL FindFirstFile
  21757. MOV EDI, EAX
  21758. INC EAX
  21759. MOV EAX, ESP
  21760. PUSHFD
  21761. CALL System.@LStrClr
  21762. POPFD
  21763. POP ECX
  21764. JZ @@fin
  21765. @@loop:
  21766. MOV ECX, [ESP].TWin32FindData.dwFileAttributes
  21767. PUSH [Attr]
  21768. LEA EDX, [ESP+4].TWin32FindData.cFileName
  21769. MOV EAX, EBX
  21770. CALL SatisfyFilter
  21771. TEST AL, AL
  21772. JZ @@next
  21773. MOV ECX, [EBX].fOnItem.TMethod.Code
  21774. JECXZ @@accept
  21775. MOV EAX, [EBX].fOnItem.TMethod.Data
  21776. MOV ECX, ESP
  21777. PUSH 1
  21778. MOV EDX, ESP
  21779. PUSH EDX
  21780. MOV EDX, EBX
  21781. CALL dword ptr [EBX].fOnItem.TMethod.Code
  21782. POP ECX
  21783. JECXZ @@next
  21784. LOOP @@fin
  21785. @@accept:
  21786. MOV EAX, sz_win32finddata
  21787. PUSH EAX
  21788. CALL System.@GetMem
  21789. PUSH EAX
  21790. XCHG EDX, EAX
  21791. MOV EAX, [EBX].fList
  21792. CALL TList.Add
  21793. POP EDX
  21794. POP ECX
  21795. MOV EAX, ESP
  21796. CALL System.Move
  21797. @@next:
  21798. PUSH ESP
  21799. PUSH EDI
  21800. CALL FindNextFile
  21801. TEST EAX, EAX
  21802. JNZ @@loop
  21803. PUSH EDI
  21804. CALL FindClose
  21805. @@fin:
  21806. ADD ESP, sz_win32finddata
  21807. @@exit:
  21808. XOR EAX, EAX
  21809. XCHG EAX, [EBX].fFilters
  21810. CALL TObj.Free
  21811. POP EDI
  21812. POP EBX
  21813. end;
  21814. {$ELSE ASM_VERSION} //Pascal
  21815. procedure TDirList.ScanDirectory(const DirPath, Filter: KOLString;
  21816. Attr: DWord);
  21817. var FindData : TFindFileData;
  21818. E : PFindFileData;
  21819. Action: TDirItemAction;
  21820. {$ifndef wince}
  21821. {$IFDEF UNICODE_CTRLS}
  21822. IsUnicode: AnsiString;
  21823. {$ENDIF}
  21824. {$endif wince}
  21825. begin
  21826. Clear;
  21827. FList := NewList;
  21828. FPath := DirPath;
  21829. if FPath = '' then Exit;
  21830. FPath := IncludeTrailingPathDelimiter( FPath );
  21831. if fFilters = nil then
  21832. begin
  21833. fFilters := {$IFDEF UNICODE_CTRLS} NewWStrList {$ELSE} NewStrList {$ENDIF};
  21834. if Filter = '*.*' then
  21835. fFilters.Add( '*' )
  21836. else
  21837. fFilters.Add( Filter );
  21838. end;
  21839. if not Find_First( PKOLChar( FPath + FindFilter( Filter ) ), FindData ) then
  21840. Exit;
  21841. while True do
  21842. begin
  21843. {$ifndef wince}
  21844. {$IFDEF UNICODE_CTRLS} //+MtsVN in 2.58 / 14Apr2007
  21845. IsUnicode := FindData.cFileName;
  21846. if (IsUnicode <> '.') and (IsUnicode <> '..') then
  21847. begin
  21848. if pos('?', IsUnicode) > 0 then
  21849. CopyMemory( @FindData.cFileName, @FindData.cAlternateFileName,
  21850. SizeOf(FindData.cAlternateFileName));
  21851. end;
  21852. {$ENDIF}
  21853. {$endif wince}
  21854. if SatisfyFilter( PKOLChar(@FindData.cFileName[0]),
  21855. FindData.dwFileAttributes, Attr ) then
  21856. begin
  21857. Action := diAccept;
  21858. if Assigned( OnItem ) then
  21859. OnItem( @Self, FindData, Action );
  21860. CASE Action OF
  21861. diSkip: ;
  21862. diAccept:
  21863. begin
  21864. GetMem( E, Sizeof( FindData ) );
  21865. E^ := FindData;
  21866. FList.Add( E );
  21867. end;
  21868. diCancel: break;
  21869. END;
  21870. end;
  21871. if not Find_Next( FindData ) then break;
  21872. end;
  21873. Find_Close( FindData );
  21874. fFilters.Free;
  21875. fFilters := nil;
  21876. end;
  21877. {$ENDIF ASM_VERSION}
  21878. //[procedure TDirList.ScanDirectoryEx]
  21879. {$IFDEF ASM_UNICODE}
  21880. {$ELSE ASM_VERSION} //Pascal
  21881. procedure TDirList.ScanDirectoryEx(const DirPath, Filters: KOLString;
  21882. Attr: DWord);
  21883. var F, FF: KOLString;
  21884. begin
  21885. FF := Filters;
  21886. Free_And_Nil( fFilters );
  21887. fFilters := {$IFDEF UNICODE_CTRLS} NewWStrList {$ELSE} NewStrList {$ENDIF};
  21888. repeat
  21889. F := Trim( Parse( FF, ';' ) );
  21890. if F <> '' then
  21891. fFilters.Add( F );
  21892. until FF = '';
  21893. ScanDirectory( DirPath, '', Attr );
  21894. end;
  21895. {$ENDIF ASM_VERSION}
  21896. type
  21897. PSortDirData = ^TSortDirData;
  21898. TSortDirData = {$ifndef wince}packed{$endif} Record
  21899. FoldersFirst, CaseSensitive : Boolean;
  21900. Rules : array[ 0..11 ] of TSortDirRules;
  21901. Dir : PDirList;
  21902. end;
  21903. //[FUNCTION CompareDirItems]
  21904. {$IFDEF ASM_noVERSION}
  21905. function CompareDirItems( const Data : PSortDirData; const e1, e2 : DWORD ) : Integer;
  21906. asm
  21907. PUSH EBX
  21908. PUSH ESI
  21909. PUSH EDI
  21910. XCHG EBX, EAX
  21911. MOV EAX, [EBX].TSortDirData.Dir
  21912. MOV EAX, [EAX].TDirList.fList
  21913. MOV EAX, [EAX].TList.fItems
  21914. MOV ESI, [EAX+EDX*4]
  21915. MOV EDI, [EAX+ECX*4]
  21916. MOV DL, byte ptr[ESI].TWin32FindData.dwFileAttributes
  21917. MOV DH, byte ptr[EDI].TWin32FindData.dwFileAttributes
  21918. AND DX, 2020h
  21919. XOR EAX, EAX
  21920. CMP DL, DH
  21921. JE @@1
  21922. CMP [EBX].TSortDirData.FoldersFirst, AL
  21923. JE @@1
  21924. OR AL, DL
  21925. JNE @@exit_near
  21926. DEC EAX
  21927. @@exit_near:
  21928. POP EDI
  21929. POP ESI
  21930. POP EBX
  21931. RET
  21932. @@sdrByDateChanged:
  21933. LEA EAX, [ESI].TWin32FindData.ftLastWriteTime
  21934. LEA EDX, [EDI].TWin32FindData.ftLastWriteTime
  21935. JMP @@sdrByDate1
  21936. @@sdrByDateAccessed:
  21937. LEA EAX, [ESI].TWin32FindData.ftLastAccessTime
  21938. LEA EDX, [EDI].TWin32FindData.ftLastAccessTime
  21939. JMP @@sdrByDate1
  21940. @@jmp_table:
  21941. DD offset[@@exit1], offset[@@2], offset[@@2]
  21942. DD offset[@@sdrByName], offset[@@sdrByExt]
  21943. DD offset[@@sdrBySize], offset[@@sdrBySize]
  21944. DD offset[@@sdrByDateCreate], offset[@@sdrByDateChanged]
  21945. DD offset[@@sdrByDateAccessed]
  21946. @@1:
  21947. LEA EDX, [EBX].TSortDirData.Rules
  21948. PUSH EDX
  21949. @@2:
  21950. POP EDX
  21951. XOR EAX, EAX
  21952. MOV AL, [EDX]
  21953. INC EDX
  21954. PUSH EDX
  21955. JMP dword ptr [@@jmp_table+EAX*4]
  21956. @@sdrByDateCreate:
  21957. LEA EAX, [ESI].TWin32FindData.ftCreationTime
  21958. LEA EDX, [EDI].TWin32FindData.ftCreationTime
  21959. @@sdrByDate1:
  21960. PUSH EDX
  21961. PUSH EAX
  21962. CALL CompareFileTime
  21963. TEST EAX, EAX
  21964. JE @@2
  21965. JMP @@exit1
  21966. @@sdrBySize:
  21967. MOV EAX, [ESI].TWin32FindData.nFileSizeHigh
  21968. SUB EAX, [EDI].TWin32FindData.nFileSizeHigh
  21969. JNE @@sdrBySize1
  21970. MOV EAX, [ESI].TWin32FindData.nFileSizeLow
  21971. SUB EAX, [EDI].TWin32FindData.nFileSizeLow
  21972. @@to_2:
  21973. JE @@2
  21974. @@sdrBySize1:
  21975. POP EDX
  21976. DEC EDX
  21977. CMP byte ptr[EDX], sdrBySizeDescending
  21978. JNE @@sdrBySize2
  21979. NEG EAX
  21980. @@sdrBySize2:
  21981. JNE @@exit
  21982. DD -1, 1
  21983. @@point:DB '.',0
  21984. @@sdrByExt:
  21985. LEA EAX, [EDI].TWin32FindData.cFileName
  21986. MOV EDX, offset[@@point]
  21987. PUSH EDX
  21988. CALL __DelimiterLast
  21989. POP EDX
  21990. PUSH EAX
  21991. LEA EAX, [ESI].TWin32FindData.cFileName
  21992. CALL __DelimiterLast
  21993. POP EDX
  21994. JMP @@sdrByName0
  21995. @@sdrByName:
  21996. LEA EAX, [ESI].TWin32FindData.cFileName
  21997. LEA EDX, [EDI].TWin32FindData.cFileName
  21998. @@sdrByName0:
  21999. CMP [EBX].TSortDirData.CaseSensitive, 0
  22000. JNE @@sdrByName1
  22001. CALL _AnsiCompareStrNoCase
  22002. JMP @@sdrByName2
  22003. @@sdrByName1:
  22004. CALL _AnsiCompareStr
  22005. @@sdrByName2:
  22006. TEST EAX, EAX
  22007. JE @@to_2
  22008. //JMP @@exit1
  22009. @@exit1:
  22010. POP EDX
  22011. @@exit:
  22012. POP EDI
  22013. POP ESI
  22014. POP EBX
  22015. end;
  22016. {$ELSE ASM_VERSION} //Pascal
  22017. function CompareDirItems( const Data : PSortDirData; const e1, e2 : DWORD ) : Integer;
  22018. var I : Integer;
  22019. Item1, Item2 : PFindFileData;
  22020. S1, S2 : PKOLChar;
  22021. IsDir1, IsDir2 : Boolean;
  22022. Date1, Date2 : PFileTime;
  22023. begin
  22024. Item1 := Data.Dir.fList.fItems[ e1 ];
  22025. Item2 := Data.Dir.fList.fItems[ e2 ];
  22026. Result := 0;
  22027. IsDir1 := (Item1.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0;
  22028. IsDir2 := (Item2.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0;
  22029. if (IsDir1 <> IsDir2) and Data.FoldersFirst then
  22030. begin
  22031. if IsDir1 then Result := -1 else Result := 1;
  22032. exit;
  22033. end;
  22034. for I := 0 to High(Data.Rules) do
  22035. begin
  22036. case Data.Rules[ I ] of
  22037. sdrByName:
  22038. begin
  22039. S1 := Item1.cFileName;
  22040. S2 := Item2.cFileName;
  22041. if not Data.CaseSensitive then
  22042. Result := {$IFDEF UNICODE_CTRLS}
  22043. WStrComp( AnsiUpperCase( S1 ), AnsiUpperCase( S2 ) )
  22044. {$ELSE} _AnsiCompareStrNoCase( S1, S2 ) {$ENDIF}
  22045. else
  22046. Result := {$IFDEF UNICODE_CTRLS}
  22047. _WStrComp( S1, S2 )
  22048. {$ELSE}
  22049. _AnsiCompareStr( S1, S2 )
  22050. {$ENDIF};
  22051. end;
  22052. sdrByExt:
  22053. begin
  22054. S1 := Item1.cFileName;
  22055. S2 := Item2.cFileName;
  22056. S1 := {$IFDEF UNICODE_CTRLS} @ S1[ DelimiterLast( WideString( S1 ), '.' ) - 1 ]
  22057. {$ELSE} __DelimiterLast( S1, '.' ) {$ENDIF};
  22058. S2 := {$IFDEF UNICODE_CTRLS} @ S2[ DelimiterLast( WideString( S2 ), '.' ) - 1 ]
  22059. {$ELSE} __DelimiterLast( S2, '.' ) {$ENDIF};
  22060. if not Data.CaseSensitive then
  22061. Result := {$IFDEF UNICODE_CTRLS}
  22062. WStrComp( WAnsiUpperCase( S1 ), WAnsiUpperCase( S2 ) )
  22063. {$ELSE} _AnsiCompareStrNoCase( S1, S2 ) {$ENDIF}
  22064. else
  22065. Result := {$IFDEF UNICODE_CTRLS} WStrComp( S1, S2 )
  22066. {$ELSE} _AnsiCompareStr( S1, S2 ) {$ENDIF};
  22067. end;
  22068. sdrBySize, sdrBySizeDescending:
  22069. begin
  22070. if Item1.nFileSizeHigh < Item2.nFileSizeHigh then
  22071. Result := -1
  22072. else
  22073. if Item1.nFileSizeHigh > Item2.nFileSizeHigh then
  22074. Result := 1
  22075. else
  22076. if Item1.nFileSizeLow < Item2.nFileSizeLow then
  22077. Result := -1
  22078. else
  22079. if Item1.nFileSizeLow > Item2.nFileSizeLow then
  22080. Result := 1;
  22081. if Data.Rules[ I ] = sdrBySizeDescending then
  22082. Result := -Result;
  22083. end;
  22084. sdrByDateCreate:
  22085. begin
  22086. Date1 := @Item1.ftCreationTime;
  22087. Date2 := @Item2.ftCreationTime;
  22088. Result := FileTimeCompare( Date1^, Date2^ );
  22089. end;
  22090. sdrByDateChanged:
  22091. begin
  22092. Date1 := @Item1.ftLastWriteTime;
  22093. Date2 := @Item2.ftLastWriteTime;
  22094. Result := FileTimeCompare( Date1^, Date2^ );
  22095. end;
  22096. sdrByDateAccessed:
  22097. begin
  22098. Date1 := @Item1.ftLastAccessTime;
  22099. Date2 := @Item2.ftLastAccessTime;
  22100. Result := FileTimeCompare( Date1^, Date2^ );
  22101. end;
  22102. end; {case}
  22103. if Result <> 0 then break;
  22104. end;
  22105. end;
  22106. {$ENDIF ASM_VERSION}
  22107. //[END CompareDirItems]
  22108. //[PROCEDURE SwapDirItems]
  22109. {$IFDEF ASM_VERSION}
  22110. {$ELSE ASM_VERSION} //Pascal
  22111. procedure SwapDirItems( const Data : PSortDirData; const e1, e2 : DWORD );
  22112. var Tmp : Pointer;
  22113. begin
  22114. Tmp := Data.Dir.FList.fItems[ e1 ];
  22115. Data.Dir.FList.fItems[ e1 ] := Data.Dir.FList.fItems[ e2 ];
  22116. Data.Dir.FList.fItems[ e2 ] := Tmp;
  22117. end;
  22118. {$ENDIF ASM_VERSION}
  22119. //[END SwapDirItems]
  22120. {$IFDEF ASM_VERSION}
  22121. {$ELSE ASM_VERSION} //Pascal
  22122. procedure TDirList.Sort(Rules: array of TSortDirRules);
  22123. var SortDirData : TSortDirData;
  22124. I, J : Integer;
  22125. function RulePresent( Rule : TSortDirRules ) : Boolean;
  22126. var K : Integer;
  22127. begin
  22128. Result := True;
  22129. for K := J - 1 downto 0 do
  22130. if Rule = SortDirData.Rules[ K ] then exit;
  22131. Result := False;
  22132. end;
  22133. procedure AddRule( Rule : TSortDirRules );
  22134. begin
  22135. if J > High( SortDirData.Rules ) then exit;
  22136. if RulePresent( Rule ) then exit;
  22137. SortDirData.Rules[ J ] := Rule;
  22138. Inc( J );
  22139. end;
  22140. begin
  22141. if fList = nil then Exit;
  22142. J := 0;
  22143. for I := 0 to High(Rules) do
  22144. AddRule( Rules[ I ] );
  22145. for I := 0 to High(DefSortDirRules) do
  22146. AddRule( DefSortDirRules[ I ] );
  22147. while J < High( SortDirData.Rules ) do
  22148. begin
  22149. SortDirData.Rules[ J ] := sdrNone;
  22150. Inc( J );
  22151. end;
  22152. SortDirData.Dir := @Self;
  22153. SortDirData.FoldersFirst := RulePresent( sdrFoldersFirst );
  22154. SortDirData.CaseSensitive := RulePresent( sdrCaseSensitive );
  22155. SortData( Pointer( @SortDirData ), fList.fCount, @CompareDirItems, @SwapDirItems );
  22156. end;
  22157. {$ENDIF ASM_VERSION}
  22158. //[function TDirList.FileList]
  22159. function TDirList.FileList(const Separator: KOLString; Dirs,
  22160. FullPaths: Boolean): KOLString;
  22161. var I: Integer;
  22162. begin
  22163. Result := '';
  22164. for I := 0 to Count-1 do
  22165. begin
  22166. if not Dirs and IsDirectory[ I ] then Continue;
  22167. if FullPaths then
  22168. Result := Result + Path;
  22169. Result := Result + Names[ I ] + Separator;
  22170. end;
  22171. end;
  22172. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  22173. ////////////////////////////////////////////////////////////////////////
  22174. // R E G I S T R Y
  22175. ////////////////////////////////////////////////////////////////////////
  22176. {++}(*
  22177. function RegSetValueEx; external advapi32 name 'RegSetValueExA';
  22178. *){--}
  22179. { -- registry -- }
  22180. //[function RegKeyOpenRead]
  22181. function RegKeyOpenRead( Key: HKey; const SubKey: KOLString ): HKey;
  22182. begin
  22183. if RegOpenKeyEx( Key, PKOLChar( SubKey ), 0, KEY_READ, Result ) <> ERROR_SUCCESS then
  22184. Result := 0;
  22185. end;
  22186. //[function RegKeyOpenWrite]
  22187. function RegKeyOpenWrite( Key: HKey; const SubKey: KOLString ): HKey;
  22188. begin
  22189. if RegOpenKeyEx( Key, PKOLChar( SubKey ), 0, KEY_READ or KEY_WRITE, Result ) <> ERROR_SUCCESS then
  22190. Result := 0;
  22191. end;
  22192. //[function RegKeyOpenCreate]
  22193. function RegKeyOpenCreate( Key: HKey; const SubKey: KOLString ): HKey;
  22194. var dwDisp: DWORD;
  22195. begin
  22196. if RegCreateKeyEx( Key, PKOLChar( SubKey ), 0, nil, 0, KEY_ALL_ACCESS, nil, Result,
  22197. @dwDisp ) <> ERROR_SUCCESS then
  22198. Result := 0;
  22199. end;
  22200. //[function RegKeyGetDw]
  22201. function RegKeyGetDw( Key: HKey; const ValueName: KOLString ): DWORD;
  22202. var dwType, dwSize: DWORD;
  22203. begin
  22204. dwSize := sizeof( DWORD );
  22205. Result := 0;
  22206. if (Key = 0) or
  22207. (RegQueryValueEx( Key, PKOLChar( ValueName ), nil, @dwType, PByte( @Result ), @dwSize ) <> ERROR_SUCCESS)
  22208. or (dwType <> REG_DWORD) then Result := 0;
  22209. end;
  22210. //[function RegKeyGetStr]
  22211. function RegKeyGetStr( Key: HKey; const ValueName: KOLString ): KOLString;
  22212. var dwType, dwSize: DWORD;
  22213. Buffer: PKOLChar;
  22214. function Query: Boolean;
  22215. begin
  22216. Result := RegQueryValueEx( Key, PKOLChar( ValueName ), nil, @dwType,
  22217. Pointer( Buffer ), @dwSize ) = ERROR_SUCCESS;
  22218. end;
  22219. begin
  22220. Result := '';
  22221. if Key = 0 then Exit;
  22222. dwSize := 0;
  22223. Buffer := nil;
  22224. if not Query or (dwType <> REG_SZ) then Exit;
  22225. GetMem( Buffer, dwSize * Sizeof( KOLChar ) );
  22226. if Query then
  22227. Result := Buffer;
  22228. FreeMem( Buffer );
  22229. end;
  22230. //[function RegKeyGetStrEx]
  22231. function RegKeyGetStrEx( Key: HKey; const ValueName: KOLString ): KOLString;
  22232. var dwType, dwSize: DWORD;
  22233. Buffer: PKOLChar;
  22234. {$ifdef win32}
  22235. Buffer2: PKOLChar;
  22236. Sz: Integer;
  22237. {$endif win32}
  22238. function Query: Boolean;
  22239. begin
  22240. Result := RegQueryValueEx( Key, PKOLChar( ValueName ), nil, @dwType,
  22241. Pointer( Buffer ), @dwSize ) = ERROR_SUCCESS;
  22242. end;
  22243. begin
  22244. Result := '';
  22245. if Key = 0 then Exit;
  22246. dwSize := 0;
  22247. Buffer := nil;
  22248. if not Query or ((dwType <> REG_SZ) and (dwtype <> REG_EXPAND_SZ)) then Exit;
  22249. GetMem( Buffer, dwSize * Sizeof( KOLChar ) );
  22250. if Query then
  22251. begin
  22252. {$ifdef win32}
  22253. if dwtype = REG_EXPAND_SZ then
  22254. begin
  22255. Sz := ExpandEnvironmentStrings(Buffer,nil,0); // bug in size detection! sometimes we get an additional 2 bytes at the end...
  22256. GetMem(Buffer2,Sz * Sizeof( KOLChar )); //
  22257. ExpandEnvironmentStrings(Buffer, Buffer2, Sz); //
  22258. Result:=Buffer2; //
  22259. FreeMem(Buffer2); //
  22260. end
  22261. else
  22262. {$endif win32}
  22263. Result := Buffer;
  22264. end;
  22265. FreeMem( Buffer );
  22266. end;
  22267. //[function RegKeySetDw]
  22268. function RegKeySetDw( Key: HKey; const ValueName: KOLString; Value: DWORD ): Boolean;
  22269. begin
  22270. Result := (Key <> 0) and (RegSetValueEx( Key, PKOLChar( ValueName ), 0,
  22271. REG_DWORD, @Value, sizeof( DWORD ) ) = ERROR_SUCCESS);
  22272. end;
  22273. //[function RegKeySetStr]
  22274. function RegKeySetStr( Key: HKey; const ValueName: KOLString; const Value: KOLString ): Boolean;
  22275. begin
  22276. Result := (Key <> 0) and (RegSetValueEx( Key, PKOLChar( ValueName ), 0,
  22277. REG_SZ, PKOLChar(Value),
  22278. (Length( Value ) + 1)*Sizeof(KOLChar) ) = ERROR_SUCCESS);
  22279. end;
  22280. //[function RegKeySetStrEx]
  22281. function RegKeySetStrEx( Key: HKey; const ValueName: KOLString; const Value: KOLString;
  22282. expand: boolean): Boolean;
  22283. var dwType: DWORD;
  22284. begin
  22285. dwType := REG_SZ;
  22286. if expand then
  22287. dwType := REG_EXPAND_SZ;
  22288. Result := (Key <> 0) and (RegSetValueEx(Key, PKOLChar(ValueName), 0, dwType,
  22289. PKOLChar(Value), (Length(Value) + 1)*Sizeof(KOLChar)) = ERROR_SUCCESS);
  22290. end;
  22291. //[procedure RegKeyClose]
  22292. procedure RegKeyClose( Key: HKey );
  22293. begin
  22294. if Key <> 0 then
  22295. RegCloseKey( Key );
  22296. end;
  22297. //[function RegKeyDelete]
  22298. function RegKeyDelete( Key: HKey; const SubKey: KOLString ): Boolean;
  22299. begin
  22300. Result := FALSE;
  22301. if Key <> 0 then
  22302. Result := RegDeleteKey( Key, PKOLChar( SubKey ) ) = ERROR_SUCCESS;
  22303. end;
  22304. //[function RegKeyDeleteValue]
  22305. function RegKeyDeleteValue( Key: HKey; const SubKey: KOLString ): Boolean;
  22306. begin
  22307. Result := FALSE;
  22308. if Key <> 0 then
  22309. Result := RegDeleteValue( Key, PKOLChar( SubKey ) ) = ERROR_SUCCESS;
  22310. end;
  22311. //[function RegKeyExists]
  22312. function RegKeyExists( Key: HKey; const SubKey: String ): Boolean;
  22313. var K: Integer;
  22314. begin
  22315. if Key = 0 then
  22316. begin
  22317. Result := FALSE;
  22318. Exit;
  22319. end;
  22320. K := RegKeyOpenRead( Key, SubKey );
  22321. Result := K <> 0;
  22322. if K <> 0 then
  22323. RegKeyClose( K );
  22324. end;
  22325. //[function RegKeyValExists]
  22326. function RegKeyValExists( Key: HKey; const ValueName: KOLString ): Boolean;
  22327. var dwType, dwSize: DWORD;
  22328. begin
  22329. Result := (Key <> 0) and
  22330. (RegQueryValueEx( Key, PKOLChar( ValueName ), nil,
  22331. @dwType, nil, @dwSize ) = ERROR_SUCCESS);
  22332. end;
  22333. //[function RegKeyValueSize]
  22334. function RegKeyValueSize( Key: HKey; const ValueName: KOLString ): Integer;
  22335. begin
  22336. Result := 0;
  22337. if Key = 0 then Exit;
  22338. RegQueryValueEx( Key, PKOLChar( ValueName ), nil, nil, nil, @ DWORD( Result ) );
  22339. end;
  22340. //[function RegKeyGetBinary]
  22341. function RegKeyGetBinary( Key: HKey; const ValueName: KOLString; var Buffer; Count: Integer ): Integer;
  22342. begin
  22343. Result := 0;
  22344. if Key = 0 then Exit;
  22345. Result := Count;
  22346. if RegQueryValueEx( Key, PKOLChar( ValueName ), nil, nil, @ Buffer, @ Result ) <> 0 then
  22347. Result:=0;
  22348. end;
  22349. //[function RegKeySetBinary]
  22350. function RegKeySetBinary( Key: HKey; const ValueName: KOLString; const Buffer; Count: Integer ): Boolean;
  22351. begin
  22352. Result := (Key <> 0) and (RegSetValueEx( Key, PKOLChar( ValueName ), 0,
  22353. REG_BINARY, @ Buffer, Count ) = ERROR_SUCCESS);
  22354. end;
  22355. //[function RegKeyGetDateTime]
  22356. function RegKeyGetDateTime(Key: HKey; const ValueName: KOLString): TDateTime;
  22357. begin
  22358. if RegKeyGetBinary( Key, ValueName, Result, Sizeof( Result ) ) <> Sizeof( Result ) then
  22359. Result:=0;
  22360. end;
  22361. //[function RegKeySetDateTime]
  22362. function RegKeySetDateTime(Key: HKey; const ValueName: KOLString; DateTime: TDateTime): Boolean;
  22363. begin
  22364. Result := RegKeySetBinary( Key, ValueName, DateTime, Sizeof( DateTime ) );
  22365. end;
  22366. {$IFDEF OLD_REGKEYGETSUBKEYS}
  22367. //-----------------------------------------------
  22368. // functions by Valerian Luft <luft@valerian.de>
  22369. //-----------------------------------------------
  22370. //[function RegKeyGetSubKeys]
  22371. function RegKeyGetSubKeys( const Key: HKEY; List: PStrList) : Boolean;
  22372. var
  22373. I, Size, NumSubKeys, MaxSubKeyLen : DWORD;
  22374. KeyName: KOLString;
  22375. begin
  22376. Result := False;
  22377. List.Clear ;
  22378. if RegQueryInfoKey(Key, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil,
  22379. nil, nil) = ERROR_SUCCESS then
  22380. begin
  22381. if NumSubKeys > 0 then begin
  22382. for I := 0 to NumSubKeys-1 do
  22383. begin
  22384. Size := MaxSubKeyLen+1;
  22385. SetLength(KeyName, Size);
  22386. //FillChar(KeyName[1],Size,#0);
  22387. RegEnumKeyEx(Key, I, @KeyName[1], Size, nil, nil, nil, nil);
  22388. SetLength(KeyName, {$ifdef UNICODE_CTRLS}WStrLen{$else}StrLen{$endif}(@KeyName[1]));
  22389. List.Add(KeyName);
  22390. end;
  22391. end;
  22392. Result:= True;
  22393. end;
  22394. end;
  22395. {$ELSE} // new (faster) version by Alex Shyshko (Psychedelic)
  22396. function RegKeyGetSubKeys(const Key: HKEY; List: PStrList) : Boolean;
  22397. var
  22398. i, MaxSubKeyLen, Size: DWORD;
  22399. Buf: PKOLchar;
  22400. begin
  22401. Result:=false;
  22402. List.Clear;
  22403. if RegQueryInfoKey(Key, nil, nil, nil, nil, @MaxSubKeyLen, nil, nil, nil, nil,
  22404. nil, nil) = ERROR_SUCCESS then
  22405. begin
  22406. if MaxSubKeyLen > 0 then
  22407. begin
  22408. Inc(MaxSubKeyLen);
  22409. GetMem(Buf,MaxSubKeyLen*SizeOfKOLChar);
  22410. i:=0;
  22411. while True do begin
  22412. Size:=MaxSubKeyLen;
  22413. if RegEnumKeyEx(Key,i,buf,Size,nil,nil,nil,nil) <> ERROR_SUCCESS then
  22414. break;
  22415. List.Add(Buf);
  22416. inc(i);
  22417. end;
  22418. FreeMem(Buf);
  22419. end; // if MaxSubKeyLen
  22420. Result:=true;
  22421. end; // if RegQueryInfoKey
  22422. end;
  22423. {$ENDIF}
  22424. //[function RegKeyGetValueNames]
  22425. {$IFDEF OLD_REGKEYGETVALUENAMES}
  22426. function RegKeyGetValueNames(const Key: HKEY; List: PStrList): Boolean;
  22427. var
  22428. I, Size, NumSubKeys, NumValueNames, MaxValueNameLen: DWORD;
  22429. ValueName: String;
  22430. begin
  22431. List.Clear ;
  22432. Result:=False;
  22433. if RegQueryInfoKey(Key, nil, nil, nil, @NumSubKeys, nil, nil, @NumValueNames,
  22434. @MaxValueNameLen, nil, nil, nil) = ERROR_SUCCESS then
  22435. begin
  22436. if NumValueNames > 0 then
  22437. for I := 0 to NumValueNames - 1 do begin
  22438. Size := MaxValueNameLen + 1;
  22439. SetLength(ValueName, Size);
  22440. //FillChar(ValueName[1],Size,#0);
  22441. RegEnumValue(Key, I, @ValueName[1], Size, nil, nil, nil, nil);
  22442. SetLength(ValueName, {$ifdef UNICODE_CTRLS}WStrLen{$else}StrLen{$endif}(@ValueName[1]));
  22443. List.Add(ValueName);
  22444. end;
  22445. Result := True;
  22446. end ;
  22447. end;
  22448. {$ELSE} // new (faster) version by Alex Shyshko (Psychedelic)
  22449. function RegKeyGetValueNames(const Key: HKEY; List: PStrList) : Boolean;
  22450. var
  22451. i, MaxValueNameLen, Size: DWORD;
  22452. Buf: PKOLchar;
  22453. begin
  22454. Result:=false;
  22455. List.Clear;
  22456. if RegQueryInfoKey(Key, nil, nil, nil, nil, nil, nil, nil, @MaxValueNameLen, nil,
  22457. nil, nil) = ERROR_SUCCESS then
  22458. begin
  22459. if MaxValueNameLen > 0 then
  22460. begin
  22461. GetMem(Buf,MaxValueNameLen + SizeOf(KOLChar) );
  22462. i:=0;
  22463. Size:=MaxValueNameLen+1;
  22464. while RegEnumValue(Key,i,buf,Size,nil,nil,nil,nil) <> ERROR_NO_MORE_ITEMS do
  22465. begin
  22466. List.Add(Buf);
  22467. Size:=MaxValueNameLen+1;
  22468. inc(i);
  22469. end;
  22470. FreeMem(Buf {,MaxValueNameLen + ... system always knows how long buffer is});
  22471. end; // if MaxValueNameLen
  22472. Result:=true;
  22473. end; // if RegQueryInfoKey
  22474. end;
  22475. {$ENDIF}
  22476. //[function RegKeyGetValueTyp]
  22477. function RegKeyGetValueTyp (const Key:HKEY; const ValueName: KOLString) : DWORD;
  22478. begin
  22479. Result:= Key ;
  22480. if Key <> 0 then
  22481. RegQueryValueEx (Key,@ValueName[1],NIL,@Result,NIL,NIL)
  22482. end;
  22483. //////////////////////////////////////////////////////////////////////
  22484. // D A T E A N D T I M E
  22485. //////////////////////////////////////////////////////////////////////
  22486. { -- date and time utilities -- }
  22487. {* This part of the unit contains date-time routines. It is not a simple compilation
  22488. of Delphi VCL date-time. E.g., TDateTime type is not based on 31-Dec-1899,
  22489. but it is based on 31-Dec-0000 instead, allowing easy manipulating of dates
  22490. at all Christian era, and all other historical era too. }
  22491. //[procedure DivMod]
  22492. procedure DivMod(Dividend: Integer; Divisor: Word;
  22493. var Result, Remainder: Word);
  22494. {$ifdef cpu86}
  22495. asm
  22496. PUSH EBX
  22497. MOV EBX,EDX
  22498. MOV EDX,EAX
  22499. SHR EDX,16
  22500. DIV BX
  22501. MOV EBX,Remainder
  22502. MOV [ECX],AX
  22503. MOV [EBX],DX
  22504. POP EBX
  22505. end;
  22506. {$else}
  22507. begin
  22508. Result := Dividend div Divisor;
  22509. Remainder := Dividend mod Divisor;
  22510. end;
  22511. {$endif cpu86}
  22512. {++}(*
  22513. //[API GetLocalTime, GetSystemTime]
  22514. procedure GetLocalTime; external kernel32 name 'GetLocalTime';
  22515. procedure GetSystemTime; external kernel32 name 'GetSystemTime';
  22516. *){--}
  22517. //*
  22518. //[function Now]
  22519. function Now : TDateTime;
  22520. var SystemTime : TSystemTime;
  22521. begin
  22522. GetLocalTime( SystemTime );
  22523. SystemTime2DateTime( SystemTime, Result );
  22524. end;
  22525. //[function Date]
  22526. function Date: TDateTime;
  22527. begin
  22528. Result := Trunc( Now );
  22529. end;
  22530. //[procedure DecodeDateFully]
  22531. procedure DecodeDateFully( DateTime: TDateTime; var Year, Month, Day, DayOfWeek: WORD );
  22532. var ST: TSystemTime;
  22533. begin
  22534. DateTime2SystemTime( DateTime, ST );
  22535. Year := ST.wYear;
  22536. Month := ST.wMonth;
  22537. Day := ST.wDay;
  22538. DayOfWeek := ST.wDayOfWeek;
  22539. end;
  22540. //[procedure DecodeDate]
  22541. procedure DecodeDate( DateTime: TDateTime; var Year, Month, Day: WORD );
  22542. var Dummy: Word;
  22543. begin
  22544. DecodeDateFully( DateTime, Year, Month, Day, Dummy );
  22545. end;
  22546. //[function EncodeDate]
  22547. function EncodeDate( Year, Month, Day: WORD; var DateTime: TDateTime ): Boolean;
  22548. var ST: TSystemTime;
  22549. begin
  22550. FillChar( ST, Sizeof( ST ), #0 );
  22551. ST.wYear := Year;
  22552. ST.wMonth := Month;
  22553. ST.wDay := Day;
  22554. Result := SystemTime2DateTime( ST, DateTime );
  22555. end;
  22556. //[procedure IncDays]
  22557. procedure IncDays( var SystemTime : TSystemTime; DaysNum : Integer );
  22558. var DateTime : TDateTime;
  22559. begin
  22560. SystemTime2DateTime( SystemTime, DateTime );
  22561. DateTime := DateTime + DaysNum;
  22562. DateTime2SystemTime( DateTime, SystemTime );
  22563. end;
  22564. //*
  22565. //[procedure IncMonths]
  22566. procedure IncMonths( var SystemTime : TSystemTime; MonthsNum : Integer );
  22567. var M : Integer;
  22568. DateTime : TDateTime;
  22569. begin
  22570. M := SystemTime.wMonth + MonthsNum - 1;
  22571. Inc( SystemTime.wYear, M div 12 );
  22572. SystemTime.wMonth := M mod 12 + 1;
  22573. // Normalize wDayOfWeek field:
  22574. SystemTime2DateTime( SystemTime, DateTime );
  22575. DateTime2SystemTime( DateTime, SystemTime );
  22576. end;
  22577. //*
  22578. //[function IsLeapYear]
  22579. function IsLeapYear(Year: Integer): Boolean;
  22580. begin
  22581. Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
  22582. end;
  22583. //*
  22584. //[function SystemTime2DateTime]
  22585. function SystemTime2DateTime(const SystemTime : TSystemTime; var DateTime : TDateTime ) : Boolean;
  22586. var I : Integer;
  22587. _Day : Integer;
  22588. DayTable: PDayTable;
  22589. begin
  22590. Result := False;
  22591. DateTime := 0.0;
  22592. DayTable := @MonthDays[IsLeapYear(SystemTime.wYear)];
  22593. with SystemTime do
  22594. if {(wYear >= 0) !always true! and} (wYear <= 9999) and
  22595. {(wMonth >= 1) and !otherwise can not convert time only!}
  22596. (wMonth <= 12) and
  22597. {(wDay >= 1) and !otherwise can not convert time only!}
  22598. (wDay <= DayTable^[wMonth]) and //
  22599. (wHour < 24) and (wMinute < 60) and (wSecond < 60) and (wMilliSeconds < 1000) then //
  22600. begin
  22601. _Day := wDay;
  22602. for I := 1 to wMonth - 1 do
  22603. Inc(_Day, DayTable^[I]);
  22604. I := wYear - 1;
  22605. //--------------- by Vadim Petrov ------++
  22606. if I<0 then i := 0; //
  22607. //--------------------------------------++
  22608. DateTime := I * 365 + I div 4 - I div 100 + I div 400 + _Day
  22609. + (LongInt(wHour) * 3600000 + LongInt(wMinute) * 60000 + LongInt(wSecond) * 1000 + LongInt(wMilliSeconds)) / MSecsPerDay;
  22610. Result := True;
  22611. end;
  22612. end;
  22613. //*
  22614. //[function DayOfWeek]
  22615. function DayOfWeek(Date: TDateTime): Integer;
  22616. begin
  22617. Result := (Trunc( Date ) + 6) mod 7;
  22618. end;
  22619. //*
  22620. //[function DateTime2SystemTime]
  22621. function DateTime2SystemTime(const DateTime : TDateTime; var SystemTime : TSystemTime ) : Boolean;
  22622. const
  22623. D1 = 365;
  22624. D4 = D1 * 4 + 1;
  22625. D100 = D4 * 25 - 1;
  22626. D400 = D100 * 4 + 1;
  22627. var Days : Integer;
  22628. Y, M, D, I: Word;
  22629. MSec : Integer;
  22630. DayTable: PDayTable;
  22631. MinCount, MSecCount: Word;
  22632. begin
  22633. Days := Trunc( DateTime );
  22634. MSec := Round((DateTime - Days) * MSecsPerDay);
  22635. Result := False;
  22636. with SystemTime do
  22637. if Days > 0 then
  22638. begin
  22639. Dec(Days);
  22640. Y := 1;
  22641. while Days >= D400 do
  22642. begin
  22643. Dec(Days, D400);
  22644. Inc(Y, 400);
  22645. end;
  22646. DivMod(Days, D100, I, D);
  22647. if I = 4 then
  22648. begin
  22649. Dec(I);
  22650. Inc(D, D100);
  22651. end;
  22652. Inc(Y, I * 100);
  22653. DivMod(D, D4, I, D);
  22654. Inc(Y, I * 4);
  22655. DivMod(D, D1, I, D);
  22656. if I = 4 then
  22657. begin
  22658. Dec(I);
  22659. Inc(D, D1);
  22660. end;
  22661. Inc(Y, I);
  22662. DayTable := @MonthDays[IsLeapYear(Y)];
  22663. M := 1;
  22664. while True do
  22665. begin
  22666. I := DayTable^[M];
  22667. if D < I then Break;
  22668. Dec(D, I);
  22669. Inc(M);
  22670. end;
  22671. wYear := Y;
  22672. wMonth := M;
  22673. wDay := D + 1;
  22674. wDayOfWeek := KOL.DayOfWeek( DateTime );
  22675. DivMod(MSec, 60000, MinCount, MSecCount);
  22676. DivMod(MinCount, 60, wHour, wMinute);
  22677. DivMod(MSecCount, 1000, wSecond, wMilliSeconds);
  22678. Result := True;
  22679. end;
  22680. end;
  22681. function DateTime_DiffSysLoc: TDateTime;
  22682. var ST, LT: TSystemTime;
  22683. FT, FT1: TFileTime;
  22684. D1, D2: TDateTime;
  22685. begin
  22686. GetSystemTime( ST );
  22687. SystemTimeToFileTime( ST, FT );
  22688. FileTimeToLocalFileTime( FT, FT1 );
  22689. FileTimeToSystemTime( FT1, LT );
  22690. SystemTime2DateTime( ST, D1 );
  22691. SystemTime2DateTime( LT, D2 );
  22692. Result := D2 - D1;
  22693. end;
  22694. //[function DateTime_System2Local]
  22695. function DateTime_System2Local( DTSys: TDateTime ): TDateTime;
  22696. begin
  22697. Result := DTSys + DateTime_DiffSysLoc;
  22698. end;
  22699. //[function DateTime_Local2System]
  22700. function DateTime_Local2System( DTLoc: TDateTime ): TDateTime;
  22701. begin
  22702. Result := DTLoc - DateTime_DiffSysLoc;
  22703. end;
  22704. function FileTime2DateTime( const ft: TFileTime; var DT: TDateTime ): Boolean;
  22705. var ft1: TFileTime;
  22706. st: TSystemTime;
  22707. begin
  22708. Result := FileTimeToLocalFileTime( ft, ft1 ) and
  22709. FileTimeToSystemTime( ft1, st ) and
  22710. SystemTime2DateTime( st, dt );
  22711. end;
  22712. function DateTime2FileTime( DT: TDateTime; var ft: TFileTime ): Boolean;
  22713. var st: TSystemTime;
  22714. begin
  22715. Result := DateTime2SystemTime( DT, ST ) and
  22716. SystemTimeToFileTime( st, ft ) and
  22717. LocalFileTimeToFileTime( ft, ft );
  22718. end;
  22719. //*
  22720. //[function SystemDate2Str]
  22721. function SystemDate2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  22722. const DfltDateFormat : TDateFormat;
  22723. const DateFormat : PKOLChar ) : KOLString;
  22724. var Buf : PKOLChar;
  22725. Sz : Integer;
  22726. Flags : DWORD;
  22727. begin
  22728. Sz := 100;
  22729. Buf := nil;
  22730. Result := '';
  22731. Flags := 0;
  22732. if DateFormat = nil then
  22733. if DfltDateFormat = dfShortDate then
  22734. Flags := DATE_SHORTDATE
  22735. else
  22736. Flags := DATE_LONGDATE;
  22737. while True do
  22738. begin
  22739. if Buf <> nil then
  22740. FreeMem( Buf );
  22741. GetMem( Buf, Sz * Sizeof( KOLChar ) );
  22742. if Buf = nil then Exit;
  22743. if GetDateFormat( LocaleID, Flags, @SystemTime, DateFormat, Buf, Sz )
  22744. = 0 then
  22745. begin
  22746. if GetLastError = ERROR_INSUFFICIENT_BUFFER then
  22747. Sz := Sz * 2
  22748. else
  22749. break;
  22750. end
  22751. else
  22752. begin
  22753. Result := Buf;
  22754. break;
  22755. end;
  22756. end;
  22757. if Buf <> nil then
  22758. FreeMem( Buf );
  22759. end;
  22760. //*
  22761. //[function SystemTime2Str]
  22762. function SystemTime2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  22763. const Flags : TTimeFormatFlags;
  22764. const TimeFormat : PKOLChar ) : KOLString;
  22765. var Buf : PKOLChar;
  22766. Sz : Integer;
  22767. Flg : DWORD;
  22768. begin
  22769. Sz := 100;
  22770. Buf := nil;
  22771. Result := '';
  22772. Flg := 0;
  22773. if tffNoMinutes in Flags then
  22774. Flg := TIME_NOMINUTESORSECONDS
  22775. else
  22776. if tffNoSeconds in Flags then
  22777. Flg := TIME_NOSECONDS;
  22778. if tffNoMarker in Flags then
  22779. Flg := Flg or TIME_NOTIMEMARKER;
  22780. if tffForce24 in Flags then
  22781. Flg := Flg or TIME_FORCE24HOURFORMAT;
  22782. while True do
  22783. begin
  22784. if Buf <> nil then
  22785. FreeMem( Buf );
  22786. GetMem( Buf, Sz * Sizeof( KOLChar ) );
  22787. if Buf = nil then Exit;
  22788. if GetTimeFormat( LocaleID, Flg, @SystemTime, TimeFormat, Buf, Sz )
  22789. = 0 then
  22790. begin
  22791. if GetLastError = ERROR_INSUFFICIENT_BUFFER then
  22792. Sz := Sz * 2
  22793. else
  22794. break;
  22795. end
  22796. else
  22797. begin
  22798. Result := Buf;
  22799. break;
  22800. end;
  22801. end;
  22802. if Buf <> nil then
  22803. FreeMem( Buf );
  22804. end;
  22805. //[function Date2StrFmt]
  22806. function Date2StrFmt( const Fmt: KOLString; D: TDateTime ): KOLString;
  22807. var ST: TSystemTime;
  22808. lpFmt: PKOLChar;
  22809. begin
  22810. DateTime2SystemTime( D, ST );
  22811. lpFmt := nil;
  22812. if Fmt <> '' then lpFmt := PKOLChar( Fmt );
  22813. Result := SystemDate2Str( ST, LOCALE_USER_DEFAULT, dfShortDate, lpFmt );
  22814. end;
  22815. //[function Time2StrFmt]
  22816. function Time2StrFmt( const Fmt: KOLString; D: TDateTime ): KOLString;
  22817. var ST: TSystemTime;
  22818. lpFmt: PKOLChar;
  22819. begin
  22820. if D < 1 then D := D + 1;
  22821. DateTime2SystemTime( D, ST );
  22822. lpFmt := nil;
  22823. if Fmt <> '' then lpFmt := PKOLChar( Fmt );
  22824. Result := SystemTime2Str( ST, LOCALE_USER_DEFAULT, [], lpFmt );
  22825. end;
  22826. //[function DateTime2StrShort]
  22827. function DateTime2StrShort( D: TDateTime ): String;
  22828. var ST: TSystemTime;
  22829. begin
  22830. //--------- by Vadim Petrov --------++
  22831. if D < 1 then D := D + 1; //
  22832. //----------------------------------++
  22833. DateTime2SystemTime( D, ST );
  22834. Result := SystemDate2Str( ST, LOCALE_USER_DEFAULT {GetUserDefaultLCID}, dfShortDate, nil ) + ' ' +
  22835. SystemTime2Str( ST, LOCALE_USER_DEFAULT {GetUserDefaultLCID}, [], nil );
  22836. end;
  22837. //[function Str2DateTimeFmt]
  22838. function Str2DateTimeFmt( const sFmtStr, sS: KOLString ): TDateTime;
  22839. var h12, hAM: Boolean;
  22840. FmtStr, S: PKOLChar;
  22841. function GetNum( var S: PKOLChar; NChars: Integer ): Integer;
  22842. begin
  22843. Result := 0;
  22844. while (S^ <> #0) and (NChars <> 0) do
  22845. begin
  22846. Dec( NChars );
  22847. {$IFDEF UNICODE_CTRLS}
  22848. if (S^ >= '0') and (S^ <= '9') then
  22849. {$ELSE}
  22850. if S^ in ['0'..'9'] then
  22851. {$ENDIF}
  22852. begin
  22853. Result := Result * 10 + Ord(S^) - Ord('0');
  22854. Inc( S );
  22855. end
  22856. else
  22857. break;
  22858. end;
  22859. end;
  22860. function GetYear( var S: PKOLChar; NChars: Integer ): Integer;
  22861. var STNow: TSystemTime;
  22862. OldDate: Boolean;
  22863. begin
  22864. Result := GetNum( S, NChars );
  22865. GetSystemTime( STNow );
  22866. OldDate := Result < 50;
  22867. Result := Result + STNow.wYear - STNow.wYear mod 100;
  22868. if OldDate then Dec( Result, 100 );
  22869. end;
  22870. function GetMonth( const fmt: KOLString; var S: PKOLChar ): Integer;
  22871. var SD: TSystemTime;
  22872. M: Integer;
  22873. C, MonthStr: KOLString;
  22874. begin
  22875. GetSystemTime( SD );
  22876. for M := 1 to 12 do
  22877. begin
  22878. SD.wMonth := M;
  22879. C := SystemDate2Str( SD, LOCALE_USER_DEFAULT, dfLongDate, PKOLChar( fmt + '/dd/yyyy/' ) );
  22880. MonthStr := Parse( C, '/' );
  22881. if AnsiCompareStrNoCase( MonthStr, Copy( S, 1, Length( MonthStr ) ) ) = 0 then
  22882. begin
  22883. Result := M;
  22884. Inc( S, Length( MonthStr ) );
  22885. Exit;
  22886. end;
  22887. end;
  22888. Result := 1;
  22889. end;
  22890. procedure SkipDayOfWeek( const fmt: KOLString; var S: PKOLChar );
  22891. var SD: TSystemTime;
  22892. Dt: TDateTime;
  22893. D: Integer;
  22894. C, DayWeekStr: KOLString;
  22895. begin
  22896. GetSystemTime( SD );
  22897. SystemTime2DateTime( SD, Dt );
  22898. Dt := Dt - SD.wDayOfWeek;
  22899. for D := 0 to 6 do
  22900. begin
  22901. DateTime2SystemTime( Dt, SD );
  22902. C := SystemDate2Str( SD, LOCALE_USER_DEFAULT, dfLongDate, PKOLChar( fmt + '/MM/yyyy/' ) );
  22903. DayWeekStr := Parse( C, '/' );
  22904. if AnsiCompareStrNoCase( DayWeekStr, Copy( S, 1, Length( DayWeekStr ) ) ) = 0 then
  22905. begin
  22906. Inc( S, Length( DayWeekStr ) );
  22907. Exit;
  22908. end;
  22909. Dt := Dt + 1.0;
  22910. end;
  22911. end;
  22912. procedure GetTimeMark( const fmt: KOLString; var S: PKOLChar );
  22913. var SD: TSystemTime;
  22914. AM: Boolean;
  22915. C, TimeMarkStr: KOLString;
  22916. begin
  22917. GetSystemTime( SD );
  22918. SD.wHour := 0;
  22919. for AM := FALSE to TRUE do
  22920. begin
  22921. C := SystemDate2Str( SD, LOCALE_USER_DEFAULT, dfLongDate, PKOLChar( fmt + '/HH/mm' ) );
  22922. TimeMarkStr := Parse( C, '/' );
  22923. if AnsiCompareStrNoCase( TimeMarkStr, Copy( S, 1, Length( TimeMarkStr ) ) ) = 0 then
  22924. begin
  22925. Inc( S, Length( TimeMarkStr ) );
  22926. hAM := AM;
  22927. Exit;
  22928. end;
  22929. SD.wHour := 13;
  22930. end;
  22931. Result := 1;
  22932. end;
  22933. function FmtIs1( S: PKOLChar ): Boolean;
  22934. begin
  22935. if StrIsStartingFrom( FmtStr, S ) then
  22936. begin
  22937. Inc( FmtStr, {$IFDEF UNICODE_CTRLS} WStrLen {$ELSE} StrLen {$ENDIF}( S ) );
  22938. Result := TRUE;
  22939. end
  22940. else
  22941. Result := FALSE;
  22942. end;
  22943. function FmtIs( S1, S2: PKOLChar ): Boolean;
  22944. begin
  22945. Result := FmtIs1( S1 ) or FmtIs1( S2 );
  22946. end;
  22947. var ST: TSystemTime;
  22948. begin
  22949. FmtStr := PKOLChar( sFmtStr);
  22950. S := PKOLChar( sS );
  22951. FillChar( ST, Sizeof( ST ), #0 );
  22952. h12 := FALSE;
  22953. hAM := FALSE;
  22954. while (FmtStr^ <> #0) and (S^ <> #0) do
  22955. begin
  22956. {$IFDEF UNICODE_CTRLS}
  22957. if ((FmtStr^ >= 'a') and (FmtStr^ <= 'z') or
  22958. (FmtStr^ >= 'A') and (FmtStr^ <= 'Z')) and
  22959. (S^ >= '0') and (S^ <= '9') then
  22960. {$ELSE}
  22961. if (FmtStr^ in ['a'..'z','A'..'Z']) and (S^ in ['0'..'9']) then
  22962. {$ENDIF}
  22963. begin
  22964. if FmtIs1( 'yyyy' ) then ST.wYear := GetNum( S, 4 )
  22965. else if FmtIs1( 'yy' ) then ST.wYear := GetYear( S, 2 )
  22966. else if FmtIs1( 'y' ) then ST.wYear := GetYear( S, -1 )
  22967. else if FmtIs( 'dd', 'd' ) then ST.wDay := GetNum( S, 2 )
  22968. else if FmtIs( 'MM', 'M' ) then ST.wMonth := GetNum( S, 2 )
  22969. else if FmtIs( 'HH', 'H' ) then ST.wHour := GetNum( S, 2 )
  22970. else if FmtIs( 'hh', 'h' ) then begin ST.wHour := GetNum( S, 2 ); h12 := TRUE end
  22971. else if FmtIs( 'mm', 'm' ) then ST.wMinute := GetNum( S, 2 )
  22972. else if FmtIs( 'ss', 's' ) then ST.wSecond := GetNum( S, 2 )
  22973. else break; // + ECM
  22974. end
  22975. else
  22976. {$IFDEF UNICODE_CTRLS}
  22977. if (FmtStr^ = 'M') or (FmtStr^ = 'd') or (FmtStr^ = 'g') then
  22978. {$ELSE}
  22979. if (FmtStr^ in [ 'M', 'd', 'g' ]) then
  22980. {$ENDIF}
  22981. begin
  22982. if FmtIs1( 'MMMM' ) then ST.wMonth := GetMonth( 'MMMM', S )
  22983. else if FmtIs1( 'MMM' ) then ST.wMonth := GetMonth( 'MMM', S )
  22984. else if FmtIs1( 'dddd' ) then SkipDayOfWeek( 'dddd', S )
  22985. else if FmtIs1( 'ddd' ) then SkipDayOfWeek( 'ddd', S )
  22986. else if FmtIs1( 'tt' ) then GetTimeMark( 'tt', S )
  22987. else if FmtIs1( 't' ) then GetTimeMark( 't', S )
  22988. else break; // + ECM
  22989. end
  22990. else
  22991. begin
  22992. if FmtStr^ = S^ then
  22993. Inc( FmtStr );
  22994. Inc( S );
  22995. end;
  22996. end;
  22997. if h12 then
  22998. if hAM then
  22999. Inc( ST.wHour, 12 );
  23000. SystemTime2DateTime( ST, Result );
  23001. end;
  23002. var FmtBuf: PKOLChar;
  23003. DateSeparator : KOLChar = #0; // + ECM
  23004. //[function Str2DateTimeShort]
  23005. function Str2DateTimeShort( const S: String ): TDateTime;
  23006. var FmtStr, FmtStr2: KOLString;
  23007. function EnumDateFmt( lpstrFmt: PKOLChar ): Boolean; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23008. begin
  23009. GetMem( FmtBuf, {$IFDEF UNICODE_CTRLS} WStrLen {$ELSE} StrLen {$ENDIF}
  23010. (( lpstrFmt ) + 1) * Sizeof( KOLChar ) );
  23011. {$IFDEF UNICODE_CTRLS} WStrCopy {$ELSE} StrCopy {$ENDIF}
  23012. ( FmtBuf, lpstrFmt );
  23013. Result := FALSE;
  23014. end;
  23015. begin
  23016. FmtStr := 'dd.MM.yyyy';
  23017. FmtBuf := nil;
  23018. EnumDateFormats( @ EnumDateFmt, LOCALE_USER_DEFAULT, DATE_SHORTDATE );
  23019. if FmtBuf <> nil then
  23020. begin
  23021. FmtStr := FmtBuf;
  23022. FreeMem( FmtBuf );
  23023. end;
  23024. FmtStr2 := 'H:mm:ss';
  23025. FmtBuf := nil;
  23026. EnumTimeFormats( @ EnumDateFmt, LOCALE_USER_DEFAULT, 0 );
  23027. if FmtBuf <> nil then
  23028. begin
  23029. FmtStr2 := FmtBuf;
  23030. FreeMem( FmtBuf );
  23031. end;
  23032. Result := Str2DateTimeFmt( FmtStr + ' ' + FmtStr2, S );
  23033. end;
  23034. // + ECM
  23035. //[function Str2DateTimeShortEx]
  23036. function Str2DateTimeShortEx( const S: KOLString ): TDateTime;
  23037. var St: KOLString;
  23038. Buff: Array[0..1] of KOLChar;
  23039. begin
  23040. if DateSeparator = #0 then
  23041. begin
  23042. if GetLocaleInfo({$ifdef wince}LOCALE_USER_DEFAULT{$else}GetThreadLocale{$endif},LOCALE_SDATE,Buff,2) > 0 then
  23043. DateSeparator := Buff[0];
  23044. end;
  23045. St := S;
  23046. if Pos(KOLString(DateSeparator),S) = 0 then
  23047. St := '0.0.0 '+S;
  23048. Result := Str2DateTimeShort(St);
  23049. end;
  23050. ///////////////////////////////////////////////////////////////////////
  23051. // T H R E A D S
  23052. ///////////////////////////////////////////////////////////////////////
  23053. { -- Thread -- }
  23054. //[function ThreadFunc]
  23055. function ThreadFunc(Thread: PThread): integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23056. begin
  23057. Result := Thread.Execute;
  23058. end;
  23059. {$IFDEF USE_CONSTRUCTORS}
  23060. //[function NewThread]
  23061. function NewThread: PThread;
  23062. begin
  23063. new( Result, ThreadCreate );
  23064. end;
  23065. //[END NewThread]
  23066. {$ELSE not_USE_CONSTRUCTORS}
  23067. //*
  23068. //[function NewThread]
  23069. function NewThread: PThread;
  23070. begin
  23071. {$IFNDEF FPC105ORBELOW}
  23072. IsMultiThread := True;
  23073. {$ENDIF}
  23074. {-}
  23075. New( Result, Create );
  23076. {+}
  23077. {++}(*Result := PThread.Create;*){--}
  23078. Result.FSuspended := True;
  23079. {$IFDEF PSEUDO_THREADS}
  23080. {$ELSE}
  23081. Result.FHandle := CreateThread( nil, // no security
  23082. 0, // the same stack size
  23083. @ThreadFunc, // thread entry point
  23084. Result, // parameter to pass to ThreadFunc
  23085. CREATE_SUSPENDED, // always SUSPENDED
  23086. Result.FThreadID ); // receive thread ID
  23087. {$ENDIF}
  23088. end;
  23089. //[END NewThread]
  23090. {$ENDIF USE_CONSTRUCTORS}
  23091. {$IFDEF USE_CONSTRUCTORS}
  23092. //[function NewThreadEx]
  23093. function NewThreadEx( const Proc: TOnThreadExecute ): PThread;
  23094. begin
  23095. new( Result, ThreadCreateEx( Proc ) );
  23096. end;
  23097. {$ELSE not_USE_CONSTRUCTORS}
  23098. //[FUNCTION NewThreadEx]
  23099. {$IFDEF ASM_!VERSION}
  23100. function NewThreadEx( const Proc: TOnThreadExecute ): PThread;
  23101. asm
  23102. CALL NewThread
  23103. POP EBP
  23104. POP ECX
  23105. POP EDX
  23106. MOV [EAX].TThread.fOnExecute.TMethod.Code, EDX
  23107. POP EDX
  23108. MOV [EAX].TThread.fOnExecute.TMethod.Data, EDX
  23109. PUSH ECX
  23110. PUSH EAX
  23111. CALL TThread.Resume
  23112. POP EAX
  23113. RET
  23114. end;
  23115. {$ELSE ASM_VERSION} //Pascal
  23116. function NewThreadEx( const Proc: TOnThreadExecute ): PThread;
  23117. begin
  23118. Result := NewThread;
  23119. Result.OnExecute := {++}(*{$IFDEF F_P} @ {$ENDIF}*){--}Proc;
  23120. Result.Resume;
  23121. end;
  23122. {$ENDIF ASM_VERSION}
  23123. //[END NewThreadEx]
  23124. {$ENDIF USE_CONSTRUCTORS}
  23125. //[function NewThreadAutoFree]
  23126. function NewThreadAutoFree( const Proc: TOnThreadExecute ): PThread;
  23127. begin
  23128. Result := NewThread;
  23129. Result.OnExecute := {++}(*{$IFDEF F_P} @ {$ENDIF}*){--}Proc;
  23130. Result.F_AutoFree := TRUE;
  23131. if Assigned( Proc ) then
  23132. Result.Resume;
  23133. end;
  23134. { TThread }
  23135. function WndProcCMExec( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  23136. : Boolean;
  23137. var Thread: PThread;
  23138. begin
  23139. Result := FALSE;
  23140. if Msg.message = CM_EXECPROC then
  23141. begin
  23142. //Global_Synchronized( Pointer( Msg.lParam ), Pointer( Msg.wParam ) );
  23143. Thread := PThread( Msg.lParam );
  23144. if Msg.wParam <> 0 then
  23145. Thread.FMethodEx( Thread, Pointer( Msg.wParam ) )
  23146. else
  23147. Thread.FMethod( );
  23148. Rslt := 0;
  23149. end;
  23150. end;
  23151. {$IFDEF PSEUDO_THREADS}
  23152. function timeBeginPeriod(uPeriod: UINT): UINT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23153. external 'winmm.dll' name 'timeBeginPeriod';
  23154. function timeEndPeriod(uPeriod: UINT): UINT; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23155. external 'winmm.dll' name 'timeEndPeriod';
  23156. {$ENDIF}
  23157. procedure TThread.Init;
  23158. begin
  23159. {$IFDEF _D2orD3}
  23160. inherited;
  23161. {$ENDIF}
  23162. if Applet <> nil then
  23163. Applet.AttachProc( WndProcCMExec );
  23164. {$IFDEF PSEUDO_THREADS}
  23165. if (MainThread = nil) and not CreatingMainThread then
  23166. begin // creating main thread
  23167. CreatingMainThread := TRUE;
  23168. new( MainThread, Create );
  23169. CreatingMainThread := FALSE;
  23170. end;
  23171. if CreatingMainThread then
  23172. begin
  23173. MainThread := @ Self;
  23174. {MainThread.}AllThreads := NewList;
  23175. {MainThread.}CurrentThread := MainThread;
  23176. TimeBeginPeriod( 10 );
  23177. end;
  23178. if not CreatingMainThread and (MainThread <> @ Self) then
  23179. begin // creating other threads
  23180. GetMem( StackBottom, PseudoThreadStackSize );
  23181. CurStackPos := Pointer( DWORD( StackBottom ) + PseudoThreadStackSize );
  23182. Stack_Empty := TRUE;
  23183. end;
  23184. MainThread.AllThreads.Add( @ Self );
  23185. {$ENDIF}
  23186. end;
  23187. //[destructor TThread.Destroy]
  23188. {$IFDEF ASM_VERSION}
  23189. {$ELSE ASM_VERSION} //Pascal
  23190. destructor TThread.Destroy;
  23191. begin
  23192. RefInc;
  23193. if not FTerminated then
  23194. begin
  23195. Terminate;
  23196. WaitFor;
  23197. end;
  23198. if (FHandle <> 0) then
  23199. CloseHandle(FHandle);
  23200. {$IFDEF PSEUDO_THREADS}
  23201. if StackBottom <> nil then
  23202. FreeMem( StackBottom );
  23203. if MainThread = @ Self then
  23204. begin
  23205. TimeEndPeriod( 10 );
  23206. AllThreads.Free;
  23207. end
  23208. else
  23209. if MainThread <> nil then
  23210. begin
  23211. MainThread.AllThreads.Remove( @ Self );
  23212. if MainThread.AllThreads.Count <= 1 then
  23213. Free_And_Nil( MainThread );
  23214. end;
  23215. {$ENDIF}
  23216. inherited;
  23217. end;
  23218. {$ENDIF ASM_VERSION}
  23219. //*
  23220. //[function TThread.Execute]
  23221. function TThread.Execute: integer;
  23222. begin
  23223. Result := 0;
  23224. if Assigned( FOnExecute ) then
  23225. Result := FOnExecute( @Self );
  23226. FResult := Result;
  23227. FTerminated := TRUE; // fake thread object (to prevent terminating while freeing)
  23228. if F_AutoFree then
  23229. Free;
  23230. end;
  23231. //*
  23232. //[function TThread.GetPriorityCls]
  23233. function TThread.GetPriorityCls: Integer;
  23234. begin
  23235. {$IFDEF PSEUDO_THREADS}
  23236. Result := FPrtyCls;
  23237. {$ELSE}
  23238. Result := {$ifdef wince} NORMAL_PRIORITY_CLASS {$else} GetPriorityClass(FHandle) {$endif};
  23239. {$ENDIF}
  23240. end;
  23241. //*
  23242. //[function TThread.GetThrdPriority]
  23243. function TThread.GetThrdPriority: Integer;
  23244. begin
  23245. {$IFDEF PSEUDO_THREADS}
  23246. Result := FPriority;
  23247. {$ELSE}
  23248. Result := GetThreadPriority(FHandle);
  23249. {$ENDIF}
  23250. end;
  23251. //*
  23252. //[procedure TThread.Resume]
  23253. procedure TThread.Resume;
  23254. begin
  23255. {$IFDEF PSEUDO_THREADS}
  23256. if MainThread.CurrentThread = @ Self then
  23257. Exit;
  23258. MainThread.SwitchToThread( @ Self );
  23259. {$ELSE}
  23260. FSuspended := False;
  23261. if (ResumeThread(FHandle) > 1) then
  23262. FSuspended := True
  23263. else
  23264. if Assigned(FOnResume) then
  23265. FOnResume(@Self);
  23266. {$ENDIF}
  23267. end;
  23268. //*
  23269. //[procedure TThread.SetPriorityCls]
  23270. procedure TThread.SetPriorityCls(Value: Integer);
  23271. begin
  23272. {$ifdef win32}
  23273. {$IFDEF DEBUG}
  23274. if not SetPriorityClass(GetCurrentProcess, Value) then
  23275. begin
  23276. ShowMessage( SysErrorMessage( GetLastError ) );
  23277. end;
  23278. {$ELSE}
  23279. {$IFDEF PSEUDO_THREADS}
  23280. FPrtyCls := Value;
  23281. {$ELSE}
  23282. SetPriorityClass(GetCurrentProcess, Value);
  23283. {$ENDIF}
  23284. {$ENDIF}
  23285. {$endif win32}
  23286. end;
  23287. //*
  23288. //[procedure TThread.SetThrdPriority]
  23289. procedure TThread.SetThrdPriority(Value: Integer);
  23290. begin
  23291. FPriority := Value;
  23292. {$IFDEF PSEUDO_THREADS}
  23293. {$ELSE}
  23294. SetThreadPriority(FHandle, Value);
  23295. {$ENDIF}
  23296. end;
  23297. //*
  23298. //[procedure TThread.Suspend]
  23299. procedure TThread.Suspend;
  23300. begin
  23301. {$IFDEF PSEUDO_THREADS}
  23302. if MainThread <> @ Self then
  23303. FSuspended := TRUE;
  23304. if MainThread.CurrentThread = @ Self then
  23305. MainThread.NextThread;
  23306. {$ELSE}
  23307. FSuspended := TRUE;
  23308. if Assigned(FOnSuspend) then
  23309. Synchronize( FOnSuspend );
  23310. SuspendThread(FHandle);
  23311. {$ENDIF}
  23312. end;
  23313. {$IFDEF PSEUDO_THREADS}
  23314. procedure FinishThread;
  23315. begin
  23316. MainThread.CurrentThread.fTerminated := TRUE;
  23317. MainThread.CurrentThread.Stack_Empty := TRUE;
  23318. MainThread.NextThread;
  23319. end;
  23320. procedure TThread.SwitchToThread(T: PThread);
  23321. begin
  23322. if (T <> MainThread) and not Assigned( T.OnExecute ) then Exit;
  23323. if Assigned( MainThread.CurrentThread.OnSuspend ) then
  23324. begin
  23325. MainThread.CurrentThread.OnExecute( MainThread.CurrentThread );
  23326. end;
  23327. asm
  23328. mov edx, [T]
  23329. // 1. Suspending current thread
  23330. mov ecx, [MainThread]
  23331. mov eax, [ecx].CurrentThread
  23332. push ebx
  23333. push ebp
  23334. push esi
  23335. push edi
  23336. mov [eax].CurStackPos, esp
  23337. mov [eax].Stack_Empty, 0
  23338. // 2. Switching to another thread
  23339. mov [ecx].CurrentThread, edx
  23340. cmp [edx].Stack_Empty, 0
  23341. jz @@1
  23342. // the first call
  23343. mov [edx].Stack_Empty, 0
  23344. cmp [edx].FSuspended, 0
  23345. jz @@0
  23346. mov [edx].FSuspended, 0
  23347. mov esp, [edx].CurStackPos
  23348. mov ecx, [edx].fOnResume.TMethod.Code
  23349. jecxz @@0
  23350. mov eax, [edx].fOnResume.TMethod.Data
  23351. call ecx // calling OnResume for resuming thread
  23352. @@0:
  23353. mov eax, [edx].fOnExecute.TMethod.Data
  23354. mov ecx, [edx].fOnExecute.TMethod.Code
  23355. push offset [FinishThread] // if thread will be finished it will jump there
  23356. jmp ecx
  23357. @@1:
  23358. // other calls - resuming
  23359. mov esp, [edx].CurStackPos
  23360. pop edi
  23361. pop esi
  23362. pop ebp
  23363. pop ebx
  23364. cmp [edx].FSuspended, 0
  23365. jz @@2
  23366. mov [edx].FSuspended, 0
  23367. mov ecx, [edx].fOnResume.TMethod.Code
  23368. jecxz @@2
  23369. mov eax, [edx].fOnResume.TMethod.Data
  23370. call ecx // calling OnResume for resuming thread
  23371. @@2:
  23372. end;
  23373. // At this point, thread is resumed
  23374. end;
  23375. procedure TThread.NextThread;
  23376. var i: Integer;
  23377. T: PThread;
  23378. C: DWORD;
  23379. begin
  23380. i := MainThread.AllThreads.IndexOf( MainThread.CurrentThread );
  23381. if i >= 0 then
  23382. begin
  23383. C := GetTickCount;
  23384. while TRUE do
  23385. begin
  23386. inc( i );
  23387. if i >= MainThread.AllThreads.Count then i := 0;
  23388. T := MainThread.AllThreads.Items[ i ];
  23389. if (T.DoNotWakeUntil > C) and (T <> MainThread) then continue;
  23390. if (T = MainThread) and (MainThread.CurrentThread = T) then Exit;
  23391. if not T.Terminated and not ((T <> MainThread) and (T.Suspended)) then break;
  23392. end;
  23393. MainThread.SwitchToThread( MainThread.AllThreads.Items[ i ] );
  23394. end;
  23395. end;
  23396. procedure Sleep( n: DWORD );
  23397. begin
  23398. if Assigned( MainThread ) then
  23399. begin
  23400. MainThread.CurrentThread.DoNotWakeUntil := GetTickCount + n;
  23401. MainThread.NextThread;
  23402. end
  23403. else
  23404. if n > 0 then Windows.Sleep( n );
  23405. end;
  23406. function WaitForMultipleObjects( nCount: DWORD;
  23407. lpHandles: PHandle; fWaitAll: BOOL; dwMilliseconds: DWORD ): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23408. var i: Integer;
  23409. w: DWORD;
  23410. Ph: PHandle;
  23411. Limit: DWORD;
  23412. begin
  23413. if dwMilliseconds = INFINITE then
  23414. Limit := INFINITE
  23415. else
  23416. Limit := GetTickCount + dwMilliseconds;
  23417. while TRUE do
  23418. begin
  23419. Ph := lpHandles;
  23420. w := 0;
  23421. for i := 0 to nCount-1 do
  23422. begin
  23423. if Windows.WaitForSingleObject( Ph^, 0 ) = WAIT_OBJECT_0 then
  23424. begin
  23425. inc( w );
  23426. if not fWaitAll then
  23427. begin
  23428. Result := WAIT_OBJECT_0 + i;
  23429. Exit;
  23430. end;
  23431. end;
  23432. inc( Ph );
  23433. end;
  23434. if w = nCount then
  23435. begin
  23436. Result := WAIT_OBJECT_0;
  23437. Exit;
  23438. end;
  23439. if (Limit <> INFINITE) and (GetTickCount > Limit) then
  23440. begin
  23441. Result := WAIT_TIMEOUT;
  23442. Exit;
  23443. end;
  23444. if Assigned( MainThread ) then
  23445. MainThread.NextThread;
  23446. {$IFDEF WAIT_SLEEP}
  23447. Sleep( 10 );
  23448. {$ENDIF}
  23449. end;
  23450. end;
  23451. function WaitForSingleObject( hHandle: THandle; dwMilliseconds: DWORD ): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23452. begin
  23453. Result := WaitForMultipleObjects( 1, @ hHandle, TRUE, dwMilliseconds );
  23454. end;
  23455. {$ENDIF PSEUDO_THREADS}
  23456. //*
  23457. //[procedure TThread.Synchronize]
  23458. procedure TThread.Synchronize(Method: TThreadMethod);
  23459. begin
  23460. {$IFDEF PSEUDO_THREADS}
  23461. Method;
  23462. {$ELSE}
  23463. FMethod := Method;
  23464. if Applet <> nil then
  23465. SendMessage( Applet.fHandle, CM_EXECPROC, 0, Integer( @Self ) );
  23466. {$ENDIF}
  23467. end;
  23468. //[procedure TThread.SynchronizeEx]
  23469. procedure TThread.SynchronizeEx( Method: TThreadMethodEx; Param: Pointer );
  23470. begin
  23471. Assert( Param <> nil, 'Parameter must not be NIL' );
  23472. {$IFDEF PSEUDO_THREADS}
  23473. Method( TMethod( Method ).Data, Param );
  23474. {$ELSE}
  23475. FMethodEx := Method;
  23476. SendMessage( Applet.fHandle, CM_EXECPROC, Integer( Param ), Integer( @Self ) );
  23477. {$ENDIF}
  23478. end;
  23479. //*
  23480. //[procedure TThread.Terminate]
  23481. procedure TThread.Terminate;
  23482. begin
  23483. {$IFDEF PSEUDO_THREADS}
  23484. FTerminated := TRUE;
  23485. if Assigned( MainThread ) then
  23486. if MainThread.CurrentThread = @ Self then
  23487. MainThread.NextThread;
  23488. {$ELSE}
  23489. TerminateThread(FHandle,0);
  23490. FTerminated := True;
  23491. {$ENDIF}
  23492. end;
  23493. //*
  23494. //[function TThread.WaitFor]
  23495. function TThread.WaitFor: Integer;
  23496. begin
  23497. RefInc;
  23498. Result := -1;
  23499. {$IFDEF PSEUDO_THREADS}
  23500. while not Terminated do
  23501. Resume;
  23502. if Terminated then
  23503. Result := FResult;
  23504. {$ELSE}
  23505. if FHandle = 0 then Exit;
  23506. WaitForSingleObject(FHandle, INFINITE);
  23507. GetExitCodeThread(FHandle, DWORD(Result));
  23508. {$ENDIF}
  23509. RefDec;
  23510. end;
  23511. function TThread.WaitForTime(T: DWORD): Integer;
  23512. {$IFDEF PSEUDO_THREADS}
  23513. var LimitTime: DWORD;
  23514. {$ENDIF}
  23515. begin
  23516. {$IFDEF PSEUDO_THREADS}
  23517. LimitTime := GetTickCount + T;
  23518. RefInc;
  23519. while not Terminated and (GetTickCount < LimitTime) do
  23520. Resume;
  23521. Result := -1;
  23522. if Terminated then
  23523. Result := FResult;
  23524. RefDec;
  23525. {$ELSE}
  23526. Result := WAIT_OBJECT_0;
  23527. RefInc;
  23528. if FHandle = 0 then Exit;
  23529. Result := WaitForSingleObject(FHandle, T);
  23530. if Result = WAIT_OBJECT_0 then
  23531. GetExitCodeThread(FHandle, T);
  23532. RefDec;
  23533. {$ENDIF}
  23534. end;
  23535. {$IFDEF _D2}
  23536. {$DEFINE _D2orFPC}
  23537. {$ENDIF}
  23538. {$IFDEF _FPC}
  23539. {$IFNDEF _D2orFPC}
  23540. {$DEFINE _D2orFPC}
  23541. {$ENDIF}
  23542. {$ENDIF}
  23543. function TThread.GetPriorityBoost: Boolean;
  23544. type TGetPriorityBoost = function(hThread: THandle;
  23545. var DisablePriorityBoost: Bool): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23546. var B: Bool;
  23547. GPB: TGetPriorityBoost;
  23548. M: THandle;
  23549. begin
  23550. Result := TRUE;
  23551. if fHandle = 0 then Exit;
  23552. if (WinVer >= WvNT) then // by TK: only evaluate if this is true, regardless of evaluation settings
  23553. begin
  23554. M := GetModuleHandle( 'kernel32' );
  23555. GPB := GetProcAddress( M, 'GetThreadPriorityBoost' );
  23556. if Assigned( GPB ) then
  23557. if GPB( fHandle, B ) then
  23558. Result := B;
  23559. end;
  23560. end;
  23561. procedure TThread.SetPriorityBoost(const Value: Boolean);
  23562. type TSetPriorityBoost = function(hThread: THandle;
  23563. DisablePriorityBoost: Bool): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  23564. var M: THandle;
  23565. SPB: TSetPriorityBoost;
  23566. begin
  23567. if fHandle = 0 then Exit;
  23568. if WinVer >= WvNT then
  23569. begin
  23570. M := GetModuleHandle( 'kernel32' );
  23571. SPB := GetProcAddress( M, 'SetThreadPriorityBoost' );
  23572. if Assigned( SPB ) then
  23573. SPB( fHandle, not Value );
  23574. end;
  23575. end;
  23576. { TStream }
  23577. {* This part of the unit contains implementation of streams for KOL. Please note,
  23578. that both stream types (file stream and memory stream) are incapsulated
  23579. by a single object type TStream. To avoid including unnedeed code,
  23580. use constructing functions NewReadFileStream and NewWriteFileStream
  23581. to work with file streams, which do not require both types of operation. }
  23582. {* To create new type of stream, define your own methods, and in your
  23583. constructing function, pass it to _NewStream function (through
  23584. TStreamMethods record). In a field Custom, You can store a reference to
  23585. your own data of any type (but do not forget to define correct releasing
  23586. of such data in your fClose procedure). }
  23587. //[function TStream.GetPosition]
  23588. function TStream.GetPosition: DWord;
  23589. begin
  23590. Result := Seek( 0, spCurrent );
  23591. end;
  23592. //[procedure TStream.SetPosition]
  23593. procedure TStream.SetPosition(Value: DWord);
  23594. begin
  23595. Seek( Value, spBegin );
  23596. end;
  23597. //[function TStream.GetSize]
  23598. {$IFDEF ASM_VERSION}
  23599. {$ELSE ASM_VERSION} //Pascal
  23600. function TStream.GetSize: DWord;
  23601. begin
  23602. Result := fMethods.fGetSiz( @Self );
  23603. end;
  23604. {$ENDIF ASM_VERSION}
  23605. //[procedure TStream.SetSize]
  23606. {$IFDEF ASM_VERSION}
  23607. {$ELSE ASM_VERSION} //Pascal
  23608. procedure TStream.SetSize(NewSize: DWord);
  23609. begin
  23610. fMethods.fSetSiz( @Self, NewSize );
  23611. end;
  23612. {$ENDIF ASM_VERSION}
  23613. //[function TStream.GetFileStreamHandle]
  23614. function TStream.GetFileStreamHandle: THandle;
  23615. begin
  23616. Result := fData.fHandle;
  23617. end;
  23618. //[function TStream.Read]
  23619. {$IFDEF ASM_VERSION}
  23620. {$ELSE ASM_VERSION} //Pascal
  23621. function TStream.Read(var Buffer; Count: DWord): DWord;
  23622. begin
  23623. Result := fMethods.fRead( @Self, Buffer, Count );
  23624. end;
  23625. {$ENDIF ASM_VERSION}
  23626. //[function TStream.GetCapacity]
  23627. function TStream.GetCapacity: DWORD;
  23628. begin
  23629. Result := fData.fCapacity;
  23630. end;
  23631. //[procedure TStream.SetCapacity]
  23632. procedure TStream.SetCapacity(Value: DWORD);
  23633. var OldSize: DWORD;
  23634. begin
  23635. {$IFDEF OLD_STREAM_CAPACITY}
  23636. if fData.fCapacity >= Value then Exit;
  23637. OldSize := Size;
  23638. Size := Value;
  23639. Size := OldSize;
  23640. {$ELSE}
  23641. if Value < fData.fSize then Value := fData.fSize;
  23642. if Value > fData.fCapacity then
  23643. begin
  23644. OldSize := Size;
  23645. Size := Value;
  23646. Size := OldSize;
  23647. end
  23648. else
  23649. if fMemory <> nil then
  23650. begin
  23651. {$IFDEF _D4orHigher}
  23652. fMemory := ReallocMemory( fMemory, Value );
  23653. {$ELSE}
  23654. ReallocMem( fMemory, Value );
  23655. {$ENDIF}
  23656. fData.fCapacity := Value;
  23657. end;
  23658. {$ENDIF}
  23659. end;
  23660. //[function TStream.Busy]
  23661. function TStream.Busy: Boolean;
  23662. begin
  23663. Result := Assigned( fData.fThread );
  23664. end;
  23665. //[function TStream.DoAsyncRead]
  23666. function TStream.DoAsyncRead( Sender: PThread ): Integer;
  23667. begin
  23668. Read( Pointer( fParam1 )^, fParam2 );
  23669. fData.fThread := nil;
  23670. Result := 0;
  23671. end;
  23672. //[procedure TStream.ReadAsync]
  23673. procedure TStream.ReadAsync(var Buffer; Count: DWord);
  23674. begin
  23675. if Busy then Wait;
  23676. fData.fThread := NewThreadAutoFree( nil );
  23677. fData.fThread.OnExecute := DoAsyncRead;
  23678. fParam1 := DWORD( @ Buffer );
  23679. fParam2 := Count;
  23680. fData.fThread.Resume;
  23681. end;
  23682. //[function TStream.DoAsyncSeek]
  23683. function TStream.DoAsyncSeek( Sender: PThread ): Integer;
  23684. begin
  23685. Seek( fParam1, TMoveMethod( fParam2 ) );
  23686. fData.fThread := nil;
  23687. Result := 0;
  23688. end;
  23689. //[procedure TStream.SeekAsync]
  23690. procedure TStream.SeekAsync(MoveTo: Integer; MoveMethod: TMoveMethod);
  23691. begin
  23692. if Busy then Wait;
  23693. fData.fThread := NewThreadAutoFree( nil );
  23694. fData.fThread.OnExecute := DoAsyncSeek;
  23695. fParam1 := MoveTo;
  23696. fParam2 := Ord( MoveMethod );
  23697. fData.fThread.Resume;
  23698. end;
  23699. //[function TStream.DoAsyncWrite]
  23700. function TStream.DoAsyncWrite( Sender: PThread ): Integer;
  23701. begin
  23702. Write( Pointer( fParam1 )^, fParam2 );
  23703. fData.fThread := nil;
  23704. Result := 0;
  23705. end;
  23706. //[procedure TStream.WriteAsync]
  23707. procedure TStream.WriteAsync(var Buffer; Count: DWord);
  23708. begin
  23709. if Busy then Wait;
  23710. fData.fThread := NewThreadAutoFree( nil );
  23711. fData.fThread.OnExecute := DoAsyncWrite;
  23712. fParam1 := DWORD( @ Buffer );
  23713. fParam2 := Count;
  23714. fData.fThread.Resume;
  23715. end;
  23716. //[procedure TStream.Wait]
  23717. procedure TStream.Wait;
  23718. begin
  23719. if not Assigned( fData.fThread ) then Exit;
  23720. if Assigned( fMethods.fWait ) then
  23721. fMethods.fWait( @Self )
  23722. else
  23723. fData.fThread.WaitFor;
  23724. end;
  23725. //[function TStream.Write]
  23726. {$IFDEF ASM_VERSION}
  23727. {$ELSE ASM_VERSION} //Pascal
  23728. function TStream.Write(var Buffer; Count: DWord): DWord;
  23729. begin
  23730. Result := fMethods.fWrite( @Self, Buffer, Count );
  23731. end;
  23732. {$ENDIF ASM_VERSION}
  23733. //[function TStream.WriteVal]
  23734. function TStream.WriteVal(Value, Count: DWORD): DWORD;
  23735. begin
  23736. Result := Write( Value, Count );
  23737. end;
  23738. //[function TStream.WriteStr]
  23739. function TStream.WriteStr(S: String): DWORD;
  23740. begin
  23741. if S <> '' then
  23742. Result := fMethods.fWrite( @Self, S[1], Length( S ) )
  23743. else
  23744. Result := 0;
  23745. end;
  23746. //[function TStream.ReadStrZ]
  23747. function TStream.ReadStrZ: String;
  23748. var C: Char;
  23749. begin
  23750. Result := '';
  23751. REPEAT
  23752. C := #0;
  23753. Read( C, 1 );
  23754. if C <> #0 then Result := Result + C;
  23755. UNTIL C = #0;
  23756. end;
  23757. {$IFDEF _D3orHigher}
  23758. function TStream.ReadWStrZ: WideString;
  23759. var C: WideChar;
  23760. begin
  23761. Result := '';
  23762. REPEAT
  23763. C := #0;
  23764. Read( C, 2 );
  23765. if C <> #0 then
  23766. Result := Result +
  23767. {$IFDEF _D3}
  23768. WideString( C )
  23769. {$ELSE}
  23770. C
  23771. {$ENDIF};
  23772. UNTIL C = #0;
  23773. end;
  23774. {$ENDIF _D3orHigher}
  23775. //[function TStream.ReadStr]
  23776. function TStream.ReadStr: String;
  23777. var C: Char;
  23778. begin
  23779. Result := '';
  23780. REPEAT
  23781. C := #0;
  23782. Read( C, 1 );
  23783. if C <> #0 then
  23784. begin
  23785. if C = #13 then
  23786. begin
  23787. C := #0;
  23788. Read( C, 1 );
  23789. if C <> #10 then Position := Position - 1;
  23790. C := #13;
  23791. end
  23792. else
  23793. if C = #10 then
  23794. C := #13;
  23795. if C <> #13 then
  23796. Result := Result + C;
  23797. end;
  23798. UNTIL C in [ #13, #0 ];
  23799. end;
  23800. //[function TStream.ReadStrLen]
  23801. function TStream.ReadStrLen(Len: Integer): String;
  23802. var i: Integer;
  23803. begin
  23804. SetLength( Result, Len );
  23805. i := Read( Result[1], Len );
  23806. SetLength( Result, i );
  23807. end;
  23808. //[function TStream.WriteStrZ]
  23809. function TStream.WriteStrZ(S: String): DWORD;
  23810. var C: Char;
  23811. begin
  23812. if S = '' then
  23813. begin
  23814. C := #0;
  23815. Result := Write( C, 1 );
  23816. end
  23817. else
  23818. Result := Write( S[ 1 ], Length( S ) + 1 );
  23819. end;
  23820. {$IFDEF _D3orHigher}
  23821. function TStream.WriteWStrZ(S: WideString): DWORD;
  23822. var C: WideChar;
  23823. begin
  23824. if S = '' then
  23825. begin
  23826. C := #0;
  23827. Result := Write( C, 2 );
  23828. end
  23829. else
  23830. Result := Write( S[ 1 ], (Length( S ) + 1) * 2 );
  23831. end;
  23832. {$ENDIF _D3orHigher}
  23833. //[function TStream.WriteStrEx]
  23834. function TStream.WriteStrEx(S: String): DWord;
  23835. var L: DWORD;
  23836. begin
  23837. L := length(s);
  23838. result:=fmethods.fwrite(@self,L,Sizeof(DWORD));
  23839. if result = Sizeof(DWORD) then
  23840. Inc( result, fmethods.fwrite(@self,s[1],L) );
  23841. end;
  23842. //[function TStream.ReadStrExVar]
  23843. function TStream.ReadStrExVar(var S: String): DWord;
  23844. begin
  23845. fmethods.fread(@self,result,Sizeof(DWORD));
  23846. setlength(s,result);
  23847. if result<>0 then result:=fmethods.fread(@self,s[1],result);
  23848. end;
  23849. //[function TStream.ReadStrEx]
  23850. function TStream.ReadStrEx: String;
  23851. begin
  23852. readstrexvar(result);
  23853. end;
  23854. //[function TStream.WriteStrPas]
  23855. function TStream.WriteStrPas( S: String ): DWORD;
  23856. var L: Integer;
  23857. begin
  23858. Result := 0;
  23859. L := Length( S );
  23860. if L > 255 then L := 255;
  23861. if Write( L, 1 ) < 1 then Exit;
  23862. Result := 1;
  23863. if L > 0 then
  23864. Result := Write( S[ 1 ], L ) + 1;
  23865. end;
  23866. //[function TStream.ReadStrPas]
  23867. function TStream.ReadStrPas: String;
  23868. var L: Byte;
  23869. begin
  23870. Result := '';
  23871. if Read( L, 1 ) < 1 then Exit;
  23872. SetLength( Result, L );
  23873. L := Read( Result[ 1 ], L );
  23874. Result := Copy( Result, 1, L );
  23875. end;
  23876. //[function TStream.Seek]
  23877. {$IFDEF ASM_VERSION}
  23878. {$ELSE ASM_VERSION} //Pascal
  23879. function TStream.Seek(MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  23880. begin
  23881. Result := fMethods.fSeek( @Self, MoveTo, MoveMethod );
  23882. end;
  23883. {$ENDIF ASM_VERSION}
  23884. //[destructor TStream.Destroy]
  23885. {$IFDEF ASM_VERSION}
  23886. {$ELSE ASM_VERSION} //Pascal
  23887. destructor TStream.Destroy;
  23888. begin
  23889. fMethods.fClose( @Self );
  23890. fData.fThread.Free;
  23891. inherited;
  23892. end;
  23893. {$ENDIF ASM_VERSION}
  23894. procedure TStream.SaveToFile(const Filename: KOLString; Start, CountSave: DWORD);
  23895. var F: PStream;
  23896. SavePos: DWORD;
  23897. begin
  23898. F := NewWriteFileStream( Filename );
  23899. SavePos := Position;
  23900. Position := Start;
  23901. Stream2Stream( F, @ Self, CountSave );
  23902. Position := SavePos;
  23903. F.Free;
  23904. end;
  23905. //+-
  23906. //[function _NewStream]
  23907. function _NewStream( const StreamMethods: TStreamMethods ): PStream;
  23908. begin
  23909. {-}
  23910. New( Result, Create );
  23911. {+}{++}(*Result := PStream.Create;*){--}
  23912. Move( StreamMethods, Result.fMethods, Sizeof( TStreamMethods ) );
  23913. Result.fPMethods := @Result.fMethods;
  23914. end;
  23915. //+
  23916. //[function SeekFileStream]
  23917. function SeekFileStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  23918. begin
  23919. Result := FileSeek( Strm.fData.fHandle, MoveTo, MoveFrom );
  23920. {$IFDEF FILESTREAM_POSITION}
  23921. Strm.fData.fPosition := Result;
  23922. {$ENDIF}
  23923. end;
  23924. //+
  23925. //[function GetSizeFileStream]
  23926. function GetSizeFileStream( Strm: PStream ): DWORD;
  23927. begin
  23928. Result := GetFileSize( Strm.fData.fHandle, nil );
  23929. if Result = DWORD( -1 ) then Result := 0;
  23930. end;
  23931. //[procedure DummySetSize]
  23932. procedure DummySetSize( Strm: PStream; Value: DWORD );
  23933. begin
  23934. end;
  23935. //[procedure DummyStreamProc]
  23936. procedure DummyStreamProc(Strm: PStream);
  23937. begin
  23938. end;
  23939. //[function DummyReadWrite]
  23940. function DummyReadWrite( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  23941. {$ifdef cpu86}
  23942. asm
  23943. XOR EAX, EAX
  23944. {$else}
  23945. begin
  23946. Result:=0;
  23947. {$endif cpu86}
  23948. end;
  23949. //[function ReadFileStream]
  23950. function ReadFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  23951. begin
  23952. Result := FileRead( Strm.fData.fHandle, Buffer, Count );
  23953. {$IFDEF FILESTREAM_POSITION}
  23954. inc( Strm.fData.fPosition, Result );
  23955. {$ENDIF}
  23956. end;
  23957. //[function WriteFileStream]
  23958. function WriteFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  23959. begin
  23960. Result := FileWrite( Strm.fData.fHandle, Buffer, Count );
  23961. {$IFDEF FILESTREAM_POSITION}
  23962. inc( Strm.fData.fPosition, Result );
  23963. {$ENDIF}
  23964. end;
  23965. //[FUNCTION WriteFileStreamEOF]
  23966. {$IFDEF ASM_VERSION}
  23967. {$ELSE ASM_VERSION} //Pascal
  23968. function WriteFileStreamEOF( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  23969. begin
  23970. Result := WriteFileStream( Strm, Buffer, Count );
  23971. SetEndOfFile( Strm.fData.fHandle );
  23972. end;
  23973. {$ENDIF ASM_VERSION}
  23974. //[END WriteFileStreamEOF]
  23975. //[procedure CloseFileStream]
  23976. procedure CloseFileStream( Strm: PStream );
  23977. begin
  23978. FileClose( Strm.fData.fHandle );
  23979. end;
  23980. //[FUNCTION SeekMemStream]
  23981. {$IFDEF ASM_VERSION}
  23982. {$ELSE ASM_VERSION} //Pascal
  23983. function SeekMemStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  23984. var NewPos: DWORD;
  23985. begin
  23986. case MoveFrom of
  23987. spBegin: NewPos := MoveTo;
  23988. spCurrent: NewPos := Strm.fData.fPosition + DWORD( MoveTo );
  23989. else //spEnd:
  23990. NewPos := Strm.fData.fSize + DWORD( MoveTo );
  23991. end;
  23992. if NewPos > Strm.fData.fSize then
  23993. Strm.SetSize( NewPos );
  23994. Strm.fData.fPosition := NewPos;
  23995. Result := NewPos;
  23996. end;
  23997. {$ENDIF ASM_VERSION}
  23998. //[END SeekMemStream]
  23999. //[function GetSizeMemStream]
  24000. function GetSizeMemStream( Strm: PStream ): DWORD;
  24001. begin
  24002. Result := Strm.fData.fSize;
  24003. end;
  24004. //[PROCEDURE SetSizeMemStream]
  24005. {$IFDEF ASM_VERSION}
  24006. {$ELSE ASM_VERSION} //Pascal
  24007. procedure SetSizeMemStream( Strm: PStream; NewSize: DWORD );
  24008. var S: PStream;
  24009. NewCapacity: DWORD;
  24010. begin
  24011. S := Strm;
  24012. if S.fData.fCapacity < NewSize then
  24013. begin
  24014. {$IFDEF OLD_MEMSTREAMS_SETSIZE}
  24015. NewCapacity := (NewSize or CapacityMask) + 1;
  24016. {$ELSE}
  24017. NewCapacity := NewSize;
  24018. {$ENDIF}
  24019. if S.fMemory = nil then
  24020. begin
  24021. if NewSize <> 0 then
  24022. GetMem( S.fMemory, NewCapacity );
  24023. end
  24024. else
  24025. ReallocMem( S.fMemory, NewCapacity );
  24026. S.fData.fCapacity := NewCapacity;
  24027. end
  24028. else
  24029. if NewSize = 0 then
  24030. begin
  24031. FreeMem( S.fMemory );
  24032. S.fMemory := nil;
  24033. S.fData.fCapacity := 0;
  24034. end;
  24035. S.fData.fSize := NewSize;
  24036. if S.fData.fPosition > S.fData.fSize then
  24037. S.fData.fPosition := S.fData.fSize;
  24038. end;
  24039. {$ENDIF ASM_VERSION}
  24040. //[END SetSizeMemStream]
  24041. //[FUNCTION ReadMemStream]
  24042. {$IFDEF ASM_VERSION}
  24043. {$ELSE ASM_VERSION} //Pascal
  24044. function ReadMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  24045. var S: PStream;
  24046. begin
  24047. S := Strm;
  24048. if Count + S.fData.fPosition > S.fData.fSize then
  24049. Count := S.fData.fSize - S.fData.fPosition;
  24050. Result := Count;
  24051. Move( Pointer( DWORD(S.fMemory) + S.fData.fPosition )^, Buffer, Result );
  24052. Inc( S.fData.fPosition, Result );
  24053. end;
  24054. {$ENDIF ASM_VERSION}
  24055. //[END ReadMemStream]
  24056. //[FUNCTION WriteMemStream]
  24057. {$IFDEF ASM_VERSION}
  24058. {$ELSE ASM_VERSION} //Pascal
  24059. function WriteMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  24060. var S: PStream;
  24061. begin
  24062. S := Strm;
  24063. if Count + S.fData.fPosition > S.fData.fSize then
  24064. S.SetSize( S.fData.fPosition + Count );
  24065. Result := Count;
  24066. Move( Buffer, Pointer( DWORD(S.fMemory) + S.fData.fPosition )^, Result );
  24067. Inc( S.fData.fPosition, Result );
  24068. end;
  24069. {$ENDIF ASM_VERSION}
  24070. //[END WriteMemStream]
  24071. //[PROCEDURE CloseMemStream]
  24072. {$IFDEF ASM_VERSION}
  24073. {$ELSE ASM_VERSION} //Pascal
  24074. procedure CloseMemStream( Strm: PStream );
  24075. var S: PStream;
  24076. begin
  24077. S := Strm;
  24078. if S.fMemory <> nil then
  24079. FreeMem( S.fMemory );
  24080. end;
  24081. {$ENDIF ASM_VERSION}
  24082. //[END CloseMemStream]
  24083. procedure DummyCloseStream( Strm: PStream );
  24084. begin
  24085. // nothing here
  24086. end;
  24087. // by Roman Vorobets:
  24088. //[procedure SetSizeFileStream]
  24089. procedure SetSizeFileStream( Strm: PStream; NewSize: DWORD );
  24090. var
  24091. P: DWORD;
  24092. begin
  24093. P:=Strm.Position;
  24094. Strm.Position:=NewSize;
  24095. SetEndOfFile(Strm.Handle);
  24096. if P < NewSize then
  24097. Strm.Position:=P;
  24098. end;
  24099. //[function NewFileStream]
  24100. function NewFileStream( const FileName: KOLString; Options: DWORD ): PStream;
  24101. begin
  24102. Result := _NewStream( BaseFileMethods );
  24103. Result.fMethods.fRead := ReadFileStreamProc;
  24104. Result.fMethods.fWrite := WriteFileStream; // not WriteStreamEOF, Lëåêñåé +óâàëîâ
  24105. Result.fMethods.fSetSiz := SetSizeFileStream;
  24106. Result.fData.fHandle := FileCreate( FileName, Options );
  24107. end;
  24108. //[FUNCTION NewReadFileStream]
  24109. {$IFDEF ASM_VERSION}
  24110. {$ELSE ASM_VERSION} //Pascal
  24111. function NewReadFileStream( const FileName: KOLString ): PStream;
  24112. begin
  24113. Result := _NewStream( BaseFileMethods );
  24114. Result.fMethods.fRead := ReadFileStreamProc;
  24115. Result.fData.fHandle := FileCreate( FileName,
  24116. ofOpenRead or ofShareDenyWrite or ofOpenExisting );
  24117. end;
  24118. {$ENDIF ASM_VERSION}
  24119. //[END NewReadFileStream]
  24120. function NewExFileStream( F: HFile ): PStream;
  24121. begin
  24122. Result := _NewStream( BaseFileMethods );
  24123. Result.fMethods.fRead := ReadFileStreamProc;
  24124. Result.fMethods.fWrite := WriteFileStream;
  24125. Result.fData.fHandle := F;
  24126. Result.fMethods.fClose := DummyCloseStream;
  24127. end;
  24128. {$IFDEF _D3orHigher}
  24129. function NewReadFileStreamW( const FileName: WideString ): PStream;
  24130. begin
  24131. Result := _NewStream( BaseFileMethods );
  24132. Result.fMethods.fRead := ReadFileStreamProc;
  24133. Result.fData.fHandle := WFileCreate( FileName,
  24134. ofOpenRead or ofShareDenyWrite or ofOpenExisting );
  24135. end;
  24136. {$ENDIF _D3orHigher}
  24137. //[FUNCTION NewWriteFileStream]
  24138. {$IFDEF ASM_VERSION}
  24139. {$ELSE ASM_VERSION} //Pascal
  24140. function NewWriteFileStream( const FileName: KOLString ): PStream;
  24141. begin
  24142. Result := _NewStream( BaseFileMethods );
  24143. Result.fMethods.fWrite := WriteFileStreamEOF;
  24144. Result.fMethods.fSetSiz := SetSizeFileStream;
  24145. Result.fData.fHandle := FileCreate( FileName,
  24146. ofOpenWrite or ofCreateAlways or ofShareDenyWrite );
  24147. end;
  24148. {$ENDIF ASM_VERSION}
  24149. //[END NewWriteFileStream]
  24150. {$IFDEF _D3orHigher}
  24151. function NewWriteFileStreamW( const FileName: WideString ): PStream;
  24152. begin
  24153. Result := _NewStream( BaseFileMethods );
  24154. Result.fMethods.fWrite := WriteFileStreamEOF;
  24155. Result.fMethods.fSetSiz := SetSizeFileStream;
  24156. Result.fData.fHandle := WFileCreate( FileName,
  24157. ofOpenWrite or ofCreateAlways or ofShareDenyWrite );
  24158. end;
  24159. {$ENDIF _D3orHigher}
  24160. //[FUNCTION NewReadWriteFileStream]
  24161. {$IFDEF ASM_noVERSION}
  24162. function NewReadWriteFileStream( const FileName: String ): PStream;
  24163. asm
  24164. PUSH EBX
  24165. XCHG EBX, EAX
  24166. MOV EAX, offset[BaseFileMethods]
  24167. CALL _NewStream
  24168. MOV EDX, [ReadFileStreamProc]
  24169. MOV [EAX].TStream.fMethods.fRead, EDX
  24170. MOV [EAX].TStream.fMethods.fWrite, offset[WriteFileStream]
  24171. MOV [EAX].TStream.fMethods.fSetSiz, offset[SetSizeFileStream]
  24172. XCHG EBX, EAX
  24173. PUSH EAX
  24174. CALL FileExists
  24175. MOV EDX, ofOpenReadWrite or ofCreateAlways or ofShareDenyWrite
  24176. ADD DH, AL // $200 (ofCreateAlways) -> $300 (ofCreateExisting)
  24177. POP EAX
  24178. CALL FileCreate
  24179. MOV [EBX].TStream.fData.fHandle, EAX
  24180. XCHG EAX, EBX
  24181. POP EBX
  24182. end;
  24183. {$ELSE ASM_VERSION} //Pascal
  24184. function NewReadWriteFileStream( const FileName: KOLString ): PStream;
  24185. var Creation: DWORD;
  24186. begin
  24187. Result := _NewStream( BaseFileMethods );
  24188. Result.fMethods.fRead := ReadFileStreamProc;
  24189. Result.fMethods.fWrite := WriteFileStream;
  24190. Result.fMethods.fSetSiz := SetSizeFileStream;
  24191. Creation := ofCreateAlways;
  24192. if FileExists( FileName ) then Creation := ofOpenExisting;
  24193. Result.fData.fHandle := FileCreate( FileName,
  24194. ofOpenReadWrite or Creation or ofShareDenyWrite );
  24195. end;
  24196. {$ENDIF ASM_VERSION}
  24197. //[END NewReadWriteFileStream]
  24198. {$IFDEF _D3orHigher}
  24199. function NewReadWriteFileStreamW( const FileName: WideString ): PStream;
  24200. var Creation: DWORD;
  24201. begin
  24202. Result := _NewStream( BaseFileMethods );
  24203. Result.fMethods.fRead := ReadFileStreamProc;
  24204. Result.fMethods.fWrite := WriteFileStream;
  24205. Result.fMethods.fSetSiz := SetSizeFileStream;
  24206. Creation := ofCreateAlways;
  24207. if WFileExists( FileName ) then Creation := ofOpenExisting;
  24208. Result.fData.fHandle := WFileCreate( FileName,
  24209. ofOpenReadWrite or Creation or ofShareDenyWrite );
  24210. end;
  24211. {$ENDIF _D3orHigher}
  24212. //[function NewMemoryStream]
  24213. function NewMemoryStream: PStream;
  24214. begin
  24215. Result := _NewStream( MemoryMethods );
  24216. end;
  24217. //[FUNCTION WriteExMemoryStream]
  24218. {$IFDEF ASM_VERSION}
  24219. {$ELSE ASM_VERSION}
  24220. function WriteExMemoryStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  24221. var S: PStream;
  24222. begin
  24223. S := Strm;
  24224. if Count + S.fData.fPosition > S.fData.fSize then
  24225. Count := S.fData.fSize - S.fData.fPosition;
  24226. Result := Count;
  24227. Move( Buffer, Pointer( DWORD(S.fMemory) + S.fData.fPosition )^, Result );
  24228. Inc( S.fData.fPosition, Result );
  24229. end;
  24230. {$ENDIF ASM_VERSION}
  24231. //[END WriteExMemoryStream]
  24232. //[procedure DummyClose_ExMemStream]
  24233. procedure DummyClose_ExMemStream( Strm: PStream );
  24234. begin
  24235. // nothing to do - ignore call (memory is not released by any way)
  24236. end;
  24237. //[function NewExMemoryStream]
  24238. function NewExMemoryStream( ExistingMem: Pointer; Size: DWORD ): PStream;
  24239. begin
  24240. Result := NewMemoryStream;
  24241. Result.fMemory := ExistingMem;
  24242. Result.fData.fCapacity := Size;
  24243. Result.fData.fSize := Size;
  24244. Result.fMethods.fWrite := WriteExMemoryStream;
  24245. Result.fMethods.fSetSiz := DummySetSize;
  24246. Result.fMethods.fClose := DummyClose_ExMemStream;
  24247. end;
  24248. //*
  24249. //[function Stream2Stream]
  24250. function Stream2Stream( Dst, Src: PStream; Count: DWORD ): DWORD;
  24251. var Buf: Pointer;
  24252. begin
  24253. if Src.fMemory <> nil then
  24254. begin
  24255. if Src.fData.fPosition + Count > Src.fData.fSize then
  24256. Count := Src.fData.fSize - Src.fData.fPosition;
  24257. Result := Dst.Write( Pointer(DWORD(Src.fMemory)+Src.fData.fPosition)^,
  24258. Count );
  24259. Inc( Src.fData.fPosition, Result );
  24260. end
  24261. else
  24262. if Dst.fMemory <> nil then
  24263. begin
  24264. if Dst.fData.fPosition + Count > Dst.fData.fSize then
  24265. Dst.SetSize( Dst.fData.fPosition + Count );
  24266. Result := Src.Read( Pointer( DWORD( Dst.fMemory ) + Dst.fData.fPosition )^,
  24267. Count );
  24268. Inc( Dst.fData.fPosition, Result );
  24269. end
  24270. else
  24271. begin
  24272. GetMem( Buf, Count );
  24273. Count := Src.Read( Buf^, Count );
  24274. Result := Dst.Write( Buf^, Count );
  24275. FreeMem( Buf );
  24276. end;
  24277. end;
  24278. //[function Stream2StreamEx]
  24279. function Stream2StreamEx( Dst, Src: PStream; Count: DWORD ): DWORD;
  24280. begin
  24281. Result := Stream2StreamExBufSz( Dst, Src, Count, 65536 );
  24282. end;
  24283. //[function Stream2StreamExBufSz]
  24284. function Stream2StreamExBufSz( Dst, Src: PStream; Count, BufSz: DWORD ): DWORD;
  24285. var
  24286. buf:pointer;
  24287. rd, wr:dword;
  24288. begin
  24289. if count=0 then result:=0 else
  24290. begin
  24291. result:=0;
  24292. BufSz := Min( BufSz, Count );
  24293. if BufSz = 0 then BufSz := Count;
  24294. getmem(buf,BufSz);
  24295. repeat
  24296. if count<BufSz then rd:=count else rd:=BufSz;
  24297. rd:=src.read(buf^,rd);
  24298. wr := dst.write(buf^,rd);
  24299. inc(result,wr);
  24300. dec(Count, rd);
  24301. until (rd<>BufSz) or (Count=0);
  24302. freemem(buf);
  24303. end;
  24304. end;
  24305. //[FUNCTION Resource2Stream]
  24306. {$IFDEF ASM_UNICODE}
  24307. {$ELSE ASM_VERSION} //Pascal
  24308. function Resource2Stream( DestStrm : PStream; Inst : HInst;
  24309. ResName : PKOLChar; ResType : PKOLChar ): Integer;
  24310. var R : HRSRC;
  24311. G : HGlobal;
  24312. P : PChar;
  24313. Sz : DWORD;
  24314. E : Integer;
  24315. begin
  24316. Result := 0;
  24317. R := FindResource( Inst, ResName, ResType );
  24318. if R <> 0 then
  24319. begin
  24320. Sz := SizeofResource( Inst, R );
  24321. G := LoadResource( Inst, R );
  24322. if G <> 0 then
  24323. begin
  24324. P := GlobalLock( G );
  24325. if P = nil then
  24326. begin
  24327. E := GetLastError;
  24328. if E = ERROR_INVALID_HANDLE then
  24329. P := Pointer( G )
  24330. else
  24331. Exit;
  24332. end;
  24333. Result := DestStrm.Write( P^, Sz );
  24334. if P <> Pointer( G ) then
  24335. GlobalUnlock( G );
  24336. //FreeResource( G );
  24337. { from Win32.hlp: "You do not need to call the FreeResource
  24338. function to free a resource loaded by using the LoadResource
  24339. function." }
  24340. end;
  24341. end;
  24342. end;
  24343. {$ENDIF ASM_VERSION}
  24344. //[END Resource2Stream]
  24345. ///////////////////////////////////////////////////////////////////////////
  24346. // I N I - F I L E S
  24347. ///////////////////////////////////////////////////////////////////////////
  24348. {$ifdef wince}
  24349. {$define read_implementation}
  24350. {$I KOLCE_IniFile.inc}
  24351. {$undef read_implementation}
  24352. {$else}
  24353. { TIniFile }
  24354. //[destructor TIniFile.Destroy]
  24355. {$IFDEF ASM_VERSION}
  24356. {$ELSE ASM_VERSION} //Pascal
  24357. destructor TIniFile.Destroy;
  24358. begin
  24359. fFileName := '';
  24360. fSection := '';
  24361. inherited;
  24362. end;
  24363. {$ENDIF ASM_VERSION}
  24364. {$IFNDEF _D5orHigher}
  24365. // Place here correct definition for WritePrivateProfileStruct
  24366. // and GetPrivateProfileStruct (a bug in Delphi2, Delphi3 and Delphi4)
  24367. //[API WritePrivateProfileStruct]
  24368. function WritePrivateProfileStruct(lpszSection, lpszKey: PChar;
  24369. lpStruct: Pointer; uSizeStruct: UINT; szFile: PChar): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  24370. external kernel32 name 'WritePrivateProfileStructA';
  24371. //[API GetPrivateProfileStruct]
  24372. function GetPrivateProfileStruct(lpszSection, lpszKey: PAnsiChar;
  24373. lpStruct: Pointer; uSizeStruct: UINT; szFile: PAnsiChar): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  24374. external kernel32 name 'GetPrivateProfileStructA';
  24375. // + by Slava A. Gavrik:
  24376. ////////////////////////////////////////////////////////////////////////////
  24377. //[function WritePrivateProfileSection]
  24378. function WritePrivateProfileSection(lpAppName, lpString,
  24379. lpFileName: PChar): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  24380. external kernel32 name 'WritePrivateProfileSectionA';
  24381. //[function GetPrivateProfileSection]
  24382. function GetPrivateProfileSection(lpAppName: PChar; lpReturnedString: PChar;
  24383. nSize: DWORD; lpFileName: PChar): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  24384. external kernel32 name 'GetPrivateProfileSectionA';
  24385. //[function GetPrivateProfileSectionNames]
  24386. function GetPrivateProfileSectionNames(lpszReturnBuffer: PChar; nSize:
  24387. DWORD;
  24388. lpFileName: PChar): DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  24389. external kernel32 name 'GetPrivateProfileSectionNamesA';
  24390. ////////////////////////////////////////////////////////////////////////////
  24391. {$ENDIF}
  24392. //[procedure TIniFile.ClearAll]
  24393. procedure TIniFile.ClearAll;
  24394. begin
  24395. WritePrivateProfileString( nil, nil, nil,
  24396. PKOLChar( fFileName ) );
  24397. end;
  24398. //[procedure TIniFile.ClearKey]
  24399. procedure TIniFile.ClearKey(const Key: KOLString);
  24400. begin
  24401. WritePrivateProfileString( PKOLChar( fSection ), PKOLChar( Key ), nil,
  24402. PKOLChar( fFileName ) );
  24403. end;
  24404. //[procedure TIniFile.ClearSection]
  24405. procedure TIniFile.ClearSection;
  24406. begin
  24407. WritePrivateProfileString( PKOLChar( fSection ), nil, nil,
  24408. PKOLChar( fFileName ) );
  24409. end;
  24410. //[function TIniFile.ValueBoolean]
  24411. function TIniFile.ValueBoolean(const Key: KOLString; Value: Boolean): Boolean;
  24412. begin
  24413. if fMode = ifmRead then
  24414. Result := GetPrivateProfileInt( PKOLChar( fSection ), PKOLChar( Key ),
  24415. Integer( Value ), PKOLChar( fFileName ) ) <> 0
  24416. else
  24417. begin
  24418. WritePrivateProfileString( PKOLChar( fSection ), PKOLChar( Key ),
  24419. PKOLChar( KOLString( Int2Str( Integer( Value ) ) ) ),
  24420. PKOLChar( fFileName ) );
  24421. Result := Value;
  24422. end;
  24423. end;
  24424. //[function TIniFile.ValueData]
  24425. function TIniFile.ValueData(const Key: KOLString; Value: Pointer;
  24426. Count: Integer): Boolean;
  24427. begin
  24428. if fMode = ifmRead then
  24429. Result := GetPrivateProfileStruct( PKOLChar( fSection ), PKOLChar( Key ),
  24430. Value, Count, PKOLChar( fFileName ) )
  24431. else
  24432. Result := WritePrivateProfileStruct( PKOLChar( fSection ), PKOLChar( Key ),
  24433. Value, Count, PKOLChar( fFileName ) );
  24434. end;
  24435. //[function TIniFile.ValueInteger]
  24436. function TIniFile.ValueInteger(const Key: KOLString; Value: Integer): Integer;
  24437. begin
  24438. if fMode = ifmRead then
  24439. Result := GetPrivateProfileInt( PKOLChar( fSection ), PKOLChar( Key ),
  24440. Integer( Value ), PKOLChar( fFileName ) )
  24441. else
  24442. begin
  24443. Result := Value;
  24444. WritePrivateProfileString( PKOLChar( fSection ), PKOLChar( Key ),
  24445. PKOLChar( KOLString( Int2Str( Value ) ) ), PKOLChar( fFileName ) );
  24446. end;
  24447. end;
  24448. //[function TIniFile.ValueString]
  24449. function TIniFile.ValueString(const Key, Value: KOLString): KOLString;
  24450. var
  24451. Buffer: array[0..4095] of KOLChar;
  24452. begin
  24453. if fMode = ifmRead then
  24454. begin
  24455. Buffer[ 0 ] := #0;
  24456. if GetPrivateProfileString(PKOLChar(fSection),
  24457. PKOLChar(Key), PKOLChar(Value), Buffer, SizeOf(Buffer) div Sizeof(KOLChar),
  24458. PKOLChar(fFileName)) <> 0 then
  24459. Result := Buffer
  24460. else
  24461. Result := ''; // Ïî ïðè÷èíå òîãî, ÷òî FPC âûäàåò îøèáêó ïðè îòñóòñòâèè Key â INI-ôàéëå // MTsv DN
  24462. end
  24463. else
  24464. begin
  24465. Result := Value;
  24466. WritePrivateProfileString( PKOLChar( fSection ), PKOLChar( Key ),
  24467. PKOLChar( Value ), PKOLChar( fFileName ) );
  24468. end;
  24469. end;
  24470. //[function OpenIniFile]
  24471. function OpenIniFile( const FileName: KOLString ): PIniFile;
  24472. begin
  24473. {-}
  24474. New( Result, Create );
  24475. {+}{++}(*Result := PIniFile.Create;*){--}
  24476. Result.fFileName := FileName;
  24477. end;
  24478. /////////////////////////////////////////////////// GetSectionNames, SectionData
  24479. // - by Vyacheslav A. Gavrik :
  24480. const
  24481. IniBufferSize = 32767;
  24482. IniBufferStrSize = IniBufferSize+4; /// äëÿ ìàõèíàöèé :)
  24483. //[procedure _FillStrList]
  24484. {$IFDEF ASM_UNICODE}
  24485. {$ELSE ASM_VERSION} //Pascal
  24486. //[procedure TIniFile.GetSectionNames]
  24487. {$IFDEF UNICODE_CTRLS}
  24488. procedure TIniFile.GetSectionNames(Names:PWStrList);
  24489. {$ELSE}
  24490. procedure TIniFile.GetSectionNames(Names:PStrList);
  24491. {$ENDIF}
  24492. var
  24493. i:integer;
  24494. Pc:PKOLChar;
  24495. PcEnd:PKOLChar;
  24496. Buffer:Pointer;
  24497. begin
  24498. GetMem(Buffer,IniBufferSize * Sizeof( KOLChar ));
  24499. Pc:=Buffer;
  24500. i := GetPrivateProfileSectionNames(Buffer, IniBufferSize, PKOLChar(fFileName));
  24501. PcEnd:=Pc+i;
  24502. repeat
  24503. Names.Add(Pc);
  24504. Pc:=PC+Length(PC)+1;
  24505. until PC>=PcEnd;
  24506. FreeMem(Buffer);
  24507. end;
  24508. //[procedure TIniFile.SectionData]
  24509. procedure TIniFile.SectionData(Names: {$IFDEF UNICODE_CTRLS} PWStrList {$ELSE} PStrList {$ENDIF});
  24510. var
  24511. i:integer;
  24512. Pc:PKOLChar;
  24513. PcEnd:PKOLChar;
  24514. Buffer:Pointer;
  24515. begin
  24516. GetMem(Buffer,IniBufferSize * Sizeof(KOLChar));
  24517. Pc:=Buffer;
  24518. if fMode = ifmRead then
  24519. begin
  24520. i:=GetPrivateProfileSection(PKOLChar(fSection), Buffer, IniBufferSize, PKOLChar(fFileName));
  24521. PcEnd:=Pc+i;
  24522. while PC < PcEnd do // Chg by ECM from REPEAT-UNTIL: i=0 (empty section) => Names.Count=1
  24523. begin
  24524. Names.Add(Pc);
  24525. Pc:=PC+Length(PC)+1;
  24526. end;
  24527. end else
  24528. begin
  24529. for i:= 0 to Names.Count-1 do
  24530. begin
  24531. {$IFDEF UNICODE_CTRLS} WStrCopy {$ELSE} StrCopy {$ENDIF}
  24532. (Pc,Names.ItemPtrs[i]);
  24533. Pc:=PC+Length(PC)+1;
  24534. end;
  24535. Pc[0]:=#0;
  24536. ClearSection;
  24537. WritePrivateProfileSection(PKOLChar(fSection), Buffer, PKOLChar(fFileName));
  24538. end;
  24539. FreeMem(Buffer);
  24540. end;
  24541. {$ENDIF ASM_VERSION}
  24542. {$endif wince}
  24543. /////////////////////////////////////////////////////////////////////////
  24544. // M E N U
  24545. /////////////////////////////////////////////////////////////////////////
  24546. { -- Menu implementation -- }
  24547. //[FUNCTION MakeAccelerator]
  24548. {$IFDEF ASM_VERSION}
  24549. {$ELSE ASM_VERSION} //Pascal
  24550. function MakeAccelerator( fVirt: Byte; Key: Word ): TMenuAccelerator;
  24551. begin
  24552. Result.fVirt := fVirt;
  24553. Result.Key := Key;
  24554. end;
  24555. {$ENDIF ASM_VERSION}
  24556. //[END MakeAccelerator]
  24557. //[FUNCTION GetAcceleratorText]
  24558. {$ifdef wince}
  24559. function GetAcceleratorText( const Accelerator: TMenuAccelerator ): KOLstring;
  24560. begin
  24561. Result:='';
  24562. end;
  24563. {$else}
  24564. function GetAcceleratorText( const Accelerator: TMenuAccelerator ): KOLstring;
  24565. var
  24566. KeyName: array[0..255] of KOLChar;
  24567. procedure AddKeyName( Code: Integer );
  24568. begin
  24569. Code := MapVirtualKey(Code, 0);
  24570. if Code = 0 then exit;
  24571. if GetKeyNameText(Code shl 16, KeyName, 256) > 0 then begin
  24572. if Result <> '' then
  24573. Result := Result + '+';
  24574. Result := Result + KeyName;
  24575. end;
  24576. end;
  24577. begin
  24578. Result := '';
  24579. with Accelerator do begin
  24580. if fVirt and FCONTROL <> 0 then
  24581. AddKeyName(VK_CONTROL);
  24582. if fVirt and FSHIFT <> 0 then
  24583. AddKeyName(VK_SHIFT);
  24584. if fVirt and FALT <> 0 then
  24585. AddKeyName(VK_ALT);
  24586. if fVirt and $20 <> 0 then
  24587. AddKeyName(VK_LWIN);
  24588. if fVirt and $40 <> 0 then
  24589. AddKeyName(VK_RWIN);
  24590. AddKeyName(Key);
  24591. end;
  24592. end;
  24593. {$endif wince}
  24594. //[END GetAcceleratorText]
  24595. const
  24596. MIDATA_CHECKITEM = $40000000;
  24597. MIDATA_RADIOITEM = $80000000;
  24598. //[function WndProcMenu]
  24599. {$IFNDEF NEW_MENU_ACCELL}
  24600. function WndProcMenu( Sender: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  24601. var M, M1: PMenu;
  24602. Idx: Integer;
  24603. Id: Integer;
  24604. begin
  24605. Result := False;
  24606. if Msg.message = WM_COMMAND then
  24607. begin
  24608. if {$ifdef wince}(LOWORD( Msg.wParam ) <> 0){$else}(Msg.lParam = 0){$endif} and (HIWORD( Msg.wParam ) <= 1) then
  24609. begin
  24610. M := PMenu( Sender.fMenuObj );
  24611. while (M = nil) and (Sender.Parent <> nil) do
  24612. begin
  24613. Sender := Sender.Parent;
  24614. M := PMenu( Sender.fMenuObj );
  24615. end;
  24616. while M <> nil do
  24617. begin
  24618. Id := LoWord( Msg.wParam );
  24619. M1 := M.Items[ Id ];
  24620. if M1 <> nil then
  24621. begin
  24622. Result := True;
  24623. Rslt := 0;
  24624. Idx := M.IndexOf( M1 );
  24625. M.fByAccel := HiWord( Msg.wParam ) <> 0;
  24626. if M1.FRadioGroup <> 0 then
  24627. M1.RadioCheckItem
  24628. else
  24629. if M1.FIsCheckItem then
  24630. M1.Checked := not M1.Checked;
  24631. if Assigned(M1.FOnMenuItem) then
  24632. M1.FOnMenuItem( M, Idx )
  24633. else if Assigned( M.FOnMenuItem ) then
  24634. M.FOnMenuItem( M, Idx );
  24635. break;
  24636. end;
  24637. M := M.fNextMenu;
  24638. end;
  24639. end;
  24640. end;
  24641. end;
  24642. {$ELSE}
  24643. function WndProcMenu( Sender: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  24644. function ProcessMenuItem(M: PMenu; Id: Integer): Boolean;
  24645. var
  24646. M1: PMenu;
  24647. Idx: Integer;
  24648. begin
  24649. M1 := M.Items[ Id ];
  24650. Result := (M1 <> nil);
  24651. if Result then
  24652. begin
  24653. Idx := M.IndexOf( M1 );
  24654. M.fByAccel := HiWord( Msg.wParam ) <> 0;
  24655. if M1.FRadioGroup <> 0 then
  24656. M1.RadioCheckItem
  24657. else
  24658. if M1.FIsCheckItem then
  24659. M1.Checked := not M1.Checked;
  24660. if Assigned(M1.FOnMenuItem) then begin
  24661. {$IFDEF USE_MENU_CURCTL} // fixed
  24662. M.fCurCtl := Sender; // fixed
  24663. {$ENDIF} // fixed
  24664. M1.FOnMenuItem( M, Idx )
  24665. end
  24666. else if Assigned( M.FOnMenuItem ) then
  24667. M.FOnMenuItem( M, Idx );
  24668. end;
  24669. end;
  24670. var
  24671. M: PMenu;
  24672. Id: Integer;
  24673. begin
  24674. Result := False;
  24675. if Msg.message = WM_COMMAND then
  24676. if {$ifdef win32}(Msg.lParam = 0) and {$endif} (HIWORD( Msg.wParam ) <= 1) then begin
  24677. Id := LoWord(Msg.wParam);
  24678. M := PMenu(Sender.fAutoPopupMenu);
  24679. if (M <> nil) and ProcessMenuItem(M, Id) then begin
  24680. Result := True;
  24681. Rslt := 0;
  24682. end
  24683. else begin
  24684. M := PMenu(Sender.fMenuObj);
  24685. while M <> nil do begin
  24686. if ProcessMenuItem(M, Id) then begin
  24687. Result := True;
  24688. Rslt := 0;
  24689. Break;
  24690. end;
  24691. M := M.fNextMenu;
  24692. end;
  24693. end;
  24694. end;
  24695. end;
  24696. {$ENDIF}
  24697. {$ENDIF WIN_GDI}
  24698. //[function NewMenu]
  24699. {$IFDEF GDI}
  24700. function NewMenu( AParent : PControl; MaxCmdReserve : DWORD;
  24701. const Template : array of PKOLChar; aOnMenuItem: TOnMenuItem ): PMenu;
  24702. var M: PMenu;
  24703. {$IFDEF INITIALFORMSIZE_FIXMENU}
  24704. R: TRect;
  24705. {$ENDIF}
  24706. begin
  24707. {-}
  24708. New( Result, Create );
  24709. {+}{++}(*Result := PMenu.Create;*){--}
  24710. Result.FVisible := TRUE;
  24711. Result.FPopupFlags := TPM_LEFTALIGN or TPM_LEFTBUTTON;
  24712. Result.FItems := NewList;
  24713. Result.FOnMenuItem := aOnMenuItem;
  24714. if (High(Template)>=0) and (Template[0] <> nil) then
  24715. begin
  24716. {$ifdef win32}
  24717. if (AParent <> nil) and (AParent.fMenuObj = nil) and not AParent.fIsControl then
  24718. Result.FHandle := CreateMenu
  24719. else
  24720. {$endif win32}
  24721. Result.FHandle := CreatePopupMenu;
  24722. Result.FillMenuItems( Result.FHandle, 0, Template );
  24723. end;
  24724. if assigned( AParent ) then
  24725. begin
  24726. Result.FControl := AParent;
  24727. if AParent.fMenuObj <> nil then
  24728. begin
  24729. // add popup menu to the end of menu chain
  24730. M := PMenu( AParent.fMenuObj );
  24731. while M.fNextMenu <> nil do
  24732. M := M.fNextMenu;
  24733. M.fNextMenu := Result;
  24734. end
  24735. else
  24736. begin
  24737. if not AParent.fIsControl then
  24738. begin
  24739. {$IFDEF INITIALFORMSIZE_FIXMENU}
  24740. R := AParent.ClientRect;
  24741. {$ENDIF}
  24742. {$ifdef wince}
  24743. CeSetMenuProc:=@CeSetMenuHandler;
  24744. AParent.fMenu:=Result.FHandle;
  24745. if AParent.fHandle <> 0 then begin
  24746. DestroyWindow(SHFindMenuBar(AParent.fHandle));
  24747. CeSetMenu(AParent.fHandle, Result);
  24748. end;
  24749. {$else}
  24750. AParent.Menu := Result.FHandle;
  24751. {$endif wince}
  24752. {$IFDEF INITIALFORMSIZE_FIXMENU}
  24753. AParent.SetClientSize( R.Right, R.Bottom );
  24754. {$ENDIF}
  24755. end;
  24756. AParent.fMenuObj := Result;
  24757. AParent.AttachProc( WndProcMenu );
  24758. {$IFDEF USE_AUTOFREE4CONTROLS}
  24759. AParent.Add2AutoFree( Result );
  24760. {$ENDIF}
  24761. end;
  24762. end;
  24763. end;
  24764. {$ENDIF GDI}
  24765. {$IFDEF _X_}
  24766. {$IFDEF GTK}
  24767. //--- some code from samples - may be useful to see "how to"
  24768. Function AddSeparatorToMenu( Menu : PGtkMenu ) : PgtkMenuItem ;
  24769. begin
  24770. Result := PGtkMenuitem( gtk_menu_item_new ) ;
  24771. gtk_menu_append( GTK_WIDGET( Menu ), PGtkWidget( Result ) ) ;
  24772. gtk_widget_show( PGtkWidget ( Result ) ) ;
  24773. end;
  24774. Function AddItemToMenu( Menu : PGtkMenu;
  24775. ShortCuts : PGtkAccelGroup;
  24776. const Caption : AnsiString;
  24777. const ShortCut : AnsiString;
  24778. CallBack : TGtkSignalFunc;
  24779. CallBackdata : Pointer ) : PGtkMenuItem;
  24780. Var
  24781. Key, Modifiers : DWORD;
  24782. //LocalAccelGroup : PGtkAccelGroup; -- not used since gtk_menu_ensure_uline_accel_group not defined anywhere...
  24783. TheLabel : PGtkLabel;
  24784. begin
  24785. Result := PGtkMenuItem ( gtk_menu_item_new_with_label( '' ) ) ;
  24786. TheLabel := GTK_LABEL(GTK_BIN( Result )^.child ) ;
  24787. Key:= gtk_label_parse_uline( TheLabel , Pchar ( Caption ) ) ;
  24788. //----------------
  24789. {If Key<>0 then // gtk_menu_ensure_uline_accel_group -- not defined anywhere...
  24790. begin
  24791. LocalAccelGroup := gtk_menu_ensure_uline_accel_group( Menu );
  24792. gtk_widget_add_accelerator( PGtkWidget ( Result ), 'activateitem',
  24793. LocalAccelGroup , Key ,
  24794. 0 , TGtkAccelFlags ( 0 ) ) ;
  24795. end;}
  24796. //-----------------
  24797. gtk_menu_append( GTK_WIDGET( Menu ), PGtkWidget( Result ) ) ;
  24798. //-----------------
  24799. If ( ShortCut<>'' ) and ( ShortCuts<> Nil ) then
  24800. begin
  24801. gtk_accelerator_parse ( pchar( ShortCut ) , @key , @modifiers ) ;
  24802. gtk_widget_add_accelerator ( PGtkWidget ( Result ) , ' activateitem' ,
  24803. ShortCuts, Key, modifiers, GTK_ACCEL_VISIBLE );
  24804. end;
  24805. //------------------
  24806. If Assigned( CallBack ) then
  24807. begin
  24808. gtk_signal_connect( PGtkObject ( Result ) , 'activate' ,
  24809. CallBack , CallBackdata ) ;
  24810. gtk_widget_show( PgtkWidget ( Result ) ) ;
  24811. end ;
  24812. end;
  24813. Function AddMenuToMenuBar( MenuBar : PGtkMenuBar;
  24814. ShortCuts : PGtkAccelGroup;
  24815. Caption : AnsiString;
  24816. CallBack : TGtkSignalFunc;
  24817. CallBackdata : Pointer;
  24818. AlignRight : Boolean;
  24819. Var MenuItem : PgtkMenuItem ) : PGtkMenu;
  24820. Var Key : DWORD;
  24821. TheLabel : PGtkLabel;
  24822. begin
  24823. MenuItem := PGtkMenuItem( gtk_menu_item_new_with_label( '' ) ) ;
  24824. If AlignRight Then
  24825. gtk_menu_item_right_justify( MenuItem );
  24826. TheLabel := GTK_LABEL( GTK_BIN( MenuItem )^ .child ) ;
  24827. Key := gtk_label_parse_uline( TheLabel, Pchar ( Caption ) ) ;
  24828. If Key<>0 then
  24829. gtk_widget_add_accelerator( PGtkWidget( MenuItem ), 'activateitem',
  24830. Shortcuts, Key, GDK_MOD1_MASK, GTK_ACCEL_LOCKED );
  24831. Result := PGtkMenu( gtk_menu_new );
  24832. If Assigned( CallBack ) then
  24833. gtk_signal_connect( PGtkObject ( Result ), 'activate',
  24834. CallBack, CallBackdata ) ;
  24835. gtk_widget_show( PgtkWidget ( MenuItem ) ) ;
  24836. gtk_menu_item_set_submenu( MenuItem, PGtkWidget( Result ) ) ;
  24837. gtk_menu_bar_append( GTK_WIDGET( MenuBar ), PgtkWidget( MenuItem ) ) ;
  24838. end;
  24839. function NewMenu( AParent : PControl; MaxCmdReserve : DWORD;
  24840. const Template : array of PKOLChar; aOnMenuItem: TOnMenuItem ): PMenu;
  24841. procedure CreateMenuItems( ParentMenu: PMenu; var i: Integer );
  24842. var Item, PrevItem: PMenu;
  24843. s: String;
  24844. j: Integer;
  24845. begin
  24846. PrevItem := nil;
  24847. while i <= High( Template )-1 do
  24848. begin
  24849. inc( i );
  24850. s := Template[ i ];
  24851. if s = '' then break; // end of template
  24852. if s = ')' then
  24853. begin
  24854. inc( i ); break; // end of submenu
  24855. end;
  24856. new( Item, Create );
  24857. Item.FCaption := s;
  24858. Item.FVisible := TRUE;
  24859. Item.FParentMenu := ParentMenu;
  24860. if ParentMenu.FItems = nil then
  24861. ParentMenu.FItems := NewList;
  24862. ParentMenu.FItems.Add( Item );
  24863. if (s <> '') and (s[ 1 ] in [ '+', '-' ]) then
  24864. begin
  24865. Item.fIsCheckItem := TRUE;
  24866. Item.fChecked := S[ 1 ] = '+';
  24867. s := CopyEnd( s, 2 );
  24868. if (s <> '') and (s[ 1 ] = '!') then
  24869. begin
  24870. if PrevItem <> nil then
  24871. begin
  24872. if PrevItem.fRadioGroup <> 0 then
  24873. Item.fRadioGroup := PrevItem.fRadioGroup;
  24874. end
  24875. else inc( Item.fRadioGroup );
  24876. s := CopyEnd( s, 2 );
  24877. end;
  24878. end;
  24879. if s = '-' then
  24880. Item.fIsSeparator := TRUE
  24881. else
  24882. begin
  24883. // extract mnemonic
  24884. for j := Length( s )-1 downto 1 do
  24885. begin
  24886. if (s[ j ] = '&') and (s[ j+1 ] <> '&') then // mnemonic
  24887. begin
  24888. Item.fMnemonics := Item.fMnemonics + s[ j+1 ];
  24889. Delete( s, j, 1 );//? <U>m</U> ?
  24890. end;
  24891. end;
  24892. end;
  24893. //---------------------------- now call gtk for create item's widget
  24894. if Item.FIsSeparator then
  24895. Item.fGtkMenuItem := gtk_menu_item_new
  24896. else
  24897. Item.fGtkMenuItem := gtk_menu_item_new_with_label( PChar( s ) );
  24898. if ParentMenu.fGtkMenuBar <> nil then
  24899. gtk_menu_bar_append(
  24900. ParentMenu.fGtkMenuBar,
  24901. Item.fGtkMenuItem )
  24902. else
  24903. gtk_menu_shell_append(
  24904. GTK_MENU_SHELL( ParentMenu.fGtkMenuShell ),
  24905. Item.fGtkMenuItem );
  24906. if s = '(' then
  24907. begin
  24908. inc( i );
  24909. if PrevItem <> nil then
  24910. begin
  24911. PrevItem.fGtkMenuShell := gtk_menu_new;
  24912. gtk_menu_item_set_submenu(
  24913. GTK_MENU_ITEM( PrevItem.fGtkMenuItem ),
  24914. PrevItem.fGtkMenuShell );
  24915. CreateMenuItems( PrevItem, i );
  24916. end;
  24917. end;
  24918. PrevItem := Item;
  24919. end;
  24920. end;
  24921. var i: Integer;
  24922. begin
  24923. new( Result, Create );
  24924. i := -1;
  24925. if AParent.fMenuObj = nil then
  24926. begin // ñîçäàåòñÿ ãëàâíîå ìåíþ ñ ëèíåéêîé ìåíþ (íàâåðõó ôîðìû? ëþáîãî êîíòðîëà?)
  24927. AParent.fMenuObj := Result;
  24928. Result.fGtkMenuBar := gtk_menu_bar_new;
  24929. //AParent.fMenuBar := Result.fGtkMenuBar;
  24930. gtk_container_add( GTK_CONTAINER( AParent.fClient ), Result.fGtkMenuBar );
  24931. gtk_widget_show( Result.fGtkMenuBar );
  24932. end
  24933. else
  24934. begin
  24935. PMenu( AParent.fMenuObj ).fNextMenu := Result;
  24936. Result.fGtkMenuShell := gtk_menu_new;
  24937. end;
  24938. CreateMenuItems( Result, i );
  24939. end;
  24940. {$ENDIF GTK}
  24941. {$ENDIF _X_}
  24942. //[END NewMenu]
  24943. //[function NewMenuEx]
  24944. function NewMenuEx( AParent : PControl; FirstCmd : Integer;
  24945. const Template : array of PKOLChar; aOnMenuItems: array of TOnMenuItem ): PMenu;
  24946. begin
  24947. Result := NewMenu( AParent, FirstCmd, Template, nil );
  24948. {$IFDEF GDI}
  24949. Result.AssignEvents( 0, aOnMenuItems );
  24950. {$ENDIF GDI}
  24951. end;
  24952. //[END NewMenuEx]
  24953. {$IFDEF WIN_GDI}
  24954. { TMenu }
  24955. const
  24956. Breaks: array[ TMenuBreak ] of DWORD = ( 0, MFT_MENUBREAK, MFT_MENUBARBREAK );
  24957. { + by AK - Andrzej Kubaszek }
  24958. //[function MenuStructSize]
  24959. function MenuStructSize: Integer;
  24960. begin
  24961. {$ifdef win32}
  24962. Result := 44;
  24963. if not( WinVer in [wv31, wv95, wvNT] ) then
  24964. {$endif win32}
  24965. Result := {48=} Sizeof( TMenuItemInfo );
  24966. end;
  24967. {$ENDIF WIN_GDI}
  24968. //[destructor TMenu.Destroy]
  24969. {$IFDEF GDI}
  24970. destructor TMenu.Destroy;
  24971. var Next, Prnt: PMenu;
  24972. begin
  24973. {$IFDEF DEBUG_MENU_DESTROY}
  24974. LogFileOutput( GetStartDir + 'TMenu.Destroy.txt',
  24975. Int2Hex( DWORD( @ Self ), 6 ) + ' ' + Int2Str( RefCount ) );
  24976. {$ENDIF}
  24977. if Count > 0 then
  24978. begin
  24979. FItems.ReleaseObjects;
  24980. FItems := NewList;
  24981. end;
  24982. if FParentMenu <> nil then
  24983. begin
  24984. Prnt := FParentMenu;
  24985. Next := Prnt.RemoveSubMenu( FId );
  24986. Prnt.FItems.Remove( @ Self );
  24987. {$ifdef wince}
  24988. if FParentMenu.FParentMenu = nil then
  24989. RedrawFormMenuBar;
  24990. {$endif wince}
  24991. FParentMenu := nil;
  24992. if Next = nil then
  24993. begin
  24994. {$ifdef cpu86}
  24995. asm
  24996. nop
  24997. end;
  24998. {$endif cpu86}
  24999. Exit;
  25000. end;
  25001. end;
  25002. if (FControl <> nil) and (FControl.fMenu = FHandle) and (FHandle <> 0) then
  25003. begin
  25004. //if FControl.fHandle <> 0 then
  25005. if not FControl.fDestroying then //!!!fix by Galkov
  25006. begin
  25007. {$ifdef wince}
  25008. CeSetMenu( FControl.fHandle, 0 );
  25009. {$else}
  25010. Windows.SetMenu( FControl.fHandle, 0 );
  25011. {$endif}
  25012. // this removes main menu from window, but does not destroy it
  25013. end;
  25014. FControl.fMenu := 0;
  25015. Next := PMenu( FControl.fMenuObj );
  25016. while Next <> nil do
  25017. begin
  25018. if Next.fNextMenu = @Self then
  25019. begin
  25020. Next.fNextMenu := fNextMenu;
  25021. break;
  25022. end;
  25023. Next := Next.fNextMenu;
  25024. end;
  25025. end;
  25026. Next := fNextMenu;
  25027. if FBitmap <> 0 then
  25028. Bitmap := 0;
  25029. if FHandle <> 0 then
  25030. begin
  25031. //if not
  25032. DestroyMenu( FHandle )
  25033. // then LogFileOutput( GetStartDir + 'err.log.txt', SysErrorMessage( GetLastError ) )
  25034. ;
  25035. end;
  25036. FCaption := '';
  25037. FItems.Free;
  25038. Next.Free;
  25039. inherited;
  25040. // all later created (popup) menus (of the same control)
  25041. // are destroyed too
  25042. end;
  25043. {$ENDIF GDI}
  25044. {$IFDEF _X_}
  25045. {$IFDEF GTK}
  25046. destructor TMenu.Destroy;
  25047. //var Next, Prnt: PMenu;
  25048. begin
  25049. {$IFDEF DEBUG_MENU_DESTROY}
  25050. LogFileOutput( GetStartDir + 'TMenu.Destroy.txt',
  25051. Int2Hex( DWORD( @ Self ), 6 ) + ' ' + Int2Str( RefCount ) );
  25052. {$ENDIF}
  25053. //if Count > 0 then
  25054. if Assigned( fItems ) then
  25055. begin
  25056. FItems.ReleaseObjects;
  25057. FItems := NewList;
  25058. end;
  25059. {if FParentMenu <> nil then
  25060. begin
  25061. Prnt := FParentMenu;
  25062. Next := Prnt.RemoveSubMenu( FId );
  25063. FParentMenu := nil;
  25064. Prnt.FItems.Remove( @ Self );
  25065. if Next = nil then Exit;
  25066. end;}
  25067. {if (FControl <> nil) and (FControl.fMenu = FHandle) and (FHandle <> 0) then
  25068. begin
  25069. begin
  25070. Windows.SetMenu( FControl.fHandle, 0 );
  25071. // this removes main menu from window, but does not destroy it
  25072. end;
  25073. FControl.fMenu := 0;
  25074. Next := PMenu( FControl.fMenuObj );
  25075. while Next <> nil do
  25076. begin
  25077. if Next.fNextMenu = @Self then
  25078. begin
  25079. Next.fNextMenu := fNextMenu;
  25080. break;
  25081. end;
  25082. Next := Next.fNextMenu;
  25083. end;
  25084. end;}
  25085. //Next := fNextMenu;
  25086. //if FBitmap <> 0 then Bitmap := 0;
  25087. //if FHandle <> 0 then DestroyMenu( FHandle );
  25088. FCaption := '';
  25089. fMnemonics := '';
  25090. FItems.Free;
  25091. //Next.Free;
  25092. inherited;
  25093. // all later created (popup) menus (of the same control)
  25094. // are destroyed too
  25095. end;
  25096. {$ENDIF GTK}
  25097. {$ENDIF _X_}
  25098. {$IFDEF WIN_GDI}
  25099. //[function TMenu.GetInfo]
  25100. function TMenu.GetInfo( var MII: TMenuItemInfo ): Boolean;
  25101. begin
  25102. MII.cbSize := MenuStructSize;
  25103. Result := GetMenuItemInfo( Parent.FHandle, FId, FALSE,
  25104. {Windows.}PMenuitemInfo( @ MII )^ );
  25105. end;
  25106. //[procedure TMenu.RedrawFormMenuBar]
  25107. procedure TMenu.RedrawFormMenuBar;
  25108. var C: PControl;
  25109. begin
  25110. C := TopParent.FControl;
  25111. if not AppletTerminated then
  25112. if (C <> nil) and not C.IsControl and (Pointer( C.fMenuObj ) = Pointer( TopParent )) and not C.fDestroying then
  25113. {$ifdef wince}
  25114. CeSetMenu( C.FHandle, TopParent );
  25115. {$else}
  25116. DrawMenuBar( C.FHandle );
  25117. {$endif wince}
  25118. end;
  25119. //[function TMenu.SetInfo]
  25120. function TMenu.SetInfo( var MII: TMenuItemInfo ): Boolean;
  25121. var H: THandle;
  25122. begin
  25123. MII.cbSize := MenuStructSize;
  25124. H := FHandle;
  25125. if FParentMenu <> nil then
  25126. H := FParentMenu.FHandle;
  25127. if H = 0 then begin
  25128. Result:=False;
  25129. exit;
  25130. end;
  25131. {$ifdef wince}
  25132. if (FHandle <> 0) and (FParentMenu <> nil) then begin
  25133. FParentMenu.SaveState;
  25134. DestroyMenu(FHandle);
  25135. FParentMenu.ReCreate;
  25136. Result:=True;
  25137. end
  25138. else
  25139. if MII.fMask and MIIM_STATE <> 0 then begin
  25140. EnableMenuItem(H, FId, MII.fState and MFS_DISABLED);
  25141. CheckMenuItem(H, FId, MII.fState and MFS_CHECKED);
  25142. Result:=True;
  25143. end
  25144. else
  25145. {$endif wince}
  25146. // {$IFNDEF UNICODE_CTRLS}
  25147. Result := SetMenuItemInfo( H, FId, FALSE, {Windows.}PMenuitemInfo( @ MII )^ );
  25148. // {$ELSE}
  25149. // Result := SetMenuItemInfoW( H, FId, FALSE, Windows.PMenuitemInfoW( @ MII )^ );
  25150. // {$ENDIF}
  25151. if Result and ((FParentMenu = nil) or (FParentMenu.FParentMenu = nil)) then
  25152. RedrawFormMenuBar;
  25153. end;
  25154. //[function TMenu.SetTypeInfo]
  25155. function TMenu.SetTypeInfo( var MII: TMenuItemInfo ): Boolean;
  25156. begin
  25157. if not FIsSeparator then
  25158. begin
  25159. if FBmpItem = 0 then
  25160. MII.dwTypeData := PKOLChar( FCaption )
  25161. else
  25162. MII.dwTypeData := Pointer( FBmpItem );
  25163. MII.cch := Length( FCaption )*SizeOfKOLChar;
  25164. end;
  25165. Result := SetInfo( MII );
  25166. end;
  25167. //[function TMenu.GetTopParent]
  25168. function TMenu.GetTopParent: PMenu;
  25169. begin
  25170. Result := @ Self;
  25171. while Result.FParentMenu <> nil do
  25172. Result := Result.FParentMenu;
  25173. end;
  25174. //[function TMenu.GetControl]
  25175. function TMenu.GetControl: PControl;
  25176. begin
  25177. Result := TopParent.FControl;
  25178. end;
  25179. //[function TMenu.GetItems]
  25180. function TMenu.GetItems( Id: HMenu ): PMenu;
  25181. function SearchItems( ParentMenu: PMenu; var FromIdx: Integer ): PMenu;
  25182. var I: Integer;
  25183. begin
  25184. Result := ParentMenu;
  25185. if Id = HMenu( FromIdx ) then Exit;
  25186. if (Id >= 4096) and (DWORD( ParentMenu.FId ) = Id) then Exit;
  25187. if ParentMenu.FItems = nil then Exit;
  25188. for I := 0 to ParentMenu.FItems.FCount-1 do
  25189. begin
  25190. Inc( FromIdx );
  25191. Result := SearchItems( ParentMenu.FItems.Items[ I ], FromIdx );
  25192. if Result <> nil then Exit;
  25193. end;
  25194. Result := nil;
  25195. end;
  25196. var I: Integer;
  25197. begin
  25198. I := -1;
  25199. Result := SearchItems( @ Self, I );
  25200. end;
  25201. //[function TMenu.GetCount]
  25202. function TMenu.GetCount: Integer;
  25203. var I: Integer;
  25204. SubM: PMenu;
  25205. begin
  25206. Result := FItems.FCount;
  25207. for I := 0 to Result-1 do
  25208. begin
  25209. SubM := FItems.Items[ I ];
  25210. Result := Result + SubM.Count;
  25211. end;
  25212. end;
  25213. //[function TMenu.IndexOf]
  25214. function TMenu.IndexOf( Item: PMenu ): Integer;
  25215. function SearchMenu( ParentMenu: PMenu; var FromIdx: Integer ): PMenu;
  25216. var I: Integer;
  25217. begin
  25218. Result := ParentMenu;
  25219. if Result = Item then Exit;
  25220. for I := 0 to ParentMenu.FItems.FCount-1 do
  25221. begin
  25222. Inc( FromIdx );
  25223. Result := SearchMenu( ParentMenu.FItems.Items[ I ], FromIdx );
  25224. if Result <> nil then Exit;
  25225. end;
  25226. Result := nil;
  25227. end;
  25228. begin
  25229. Result := -1;
  25230. if SearchMenu( @ Self, Result ) = nil then
  25231. Result := -2;
  25232. end;
  25233. //[function TMenu.GetState]
  25234. function TMenu.GetState( const Index: Integer ): Boolean;
  25235. var MII: TMenuItemInfo;
  25236. begin
  25237. if FVisible then
  25238. begin
  25239. MII.fMask := MIIM_STATE;
  25240. if GetInfo( MII ) then
  25241. FSavedState := MII.fState;
  25242. end;
  25243. Result := LongBool( FSavedState and Index );
  25244. if Index < 0 then
  25245. Result := not Result;
  25246. end;
  25247. //[procedure TMenu.SetState]
  25248. procedure TMenu.SetState( const Index: Integer; Value: Boolean );
  25249. var MII: TMenuItemInfo;
  25250. begin
  25251. GetState( 0 );
  25252. if Value xor (Index < 0) then
  25253. FSavedState := FSavedState or DWORD( Index and $7FFFFFFF )
  25254. else
  25255. FSavedState := FSavedState and not DWORD( Index );
  25256. if FVisible then
  25257. begin
  25258. MII.fMask := MIIM_STATE;
  25259. if GetInfo( MII ) then
  25260. begin
  25261. MII.fState := FSavedState;
  25262. SetInfo( MII );
  25263. end;
  25264. end;
  25265. end;
  25266. //[procedure TMenu.SetData]
  25267. procedure TMenu.SetData( Value: Pointer );
  25268. var MII: TMenuItemInfo;
  25269. begin
  25270. MII.fMask := MIIM_DATA;
  25271. MII.dwItemData := DWORD( Value );
  25272. SetInfo( MII );
  25273. FData := Value;
  25274. end;
  25275. //[procedure TMenu.ClearBitmaps]
  25276. procedure TMenu.ClearBitmaps;
  25277. begin
  25278. if FBitmap <> 0 then
  25279. DeleteObject( FBitmap );
  25280. if FBmpChecked <> 0 then
  25281. DeleteObject( FBmpChecked );
  25282. if FBmpItem <> 0 then
  25283. DeleteObject( FBmpItem );
  25284. end;
  25285. //[procedure TMenu.SetBitmap]
  25286. procedure TMenu.SetBitmap( Value: HBitmap );
  25287. var MII: TMenuItemInfo;
  25288. begin
  25289. if not FClearBitmaps then
  25290. begin
  25291. FClearBitmaps := TRUE;
  25292. Add2AutoFreeEx( ClearBitmaps );
  25293. end;
  25294. if Value = FBitmap then Exit;
  25295. if FBitmap <> 0 then
  25296. DeleteObject( FBitmap ); // seems not necessary.
  25297. FBitmap := Value;
  25298. MII.fMask := MIIM_CHECKMARKS;
  25299. MII.hbmpChecked := FBmpChecked;
  25300. MII.hbmpUnchecked := FBitmap;
  25301. SetInfo( MII );
  25302. end;
  25303. //[procedure TMenu.SetBmpChecked]
  25304. procedure TMenu.SetBmpChecked( Value: HBitmap );
  25305. var MII: TMenuItemInfo;
  25306. begin
  25307. if not FClearBitmaps then
  25308. begin
  25309. FClearBitmaps := TRUE;
  25310. Add2AutoFreeEx( ClearBitmaps );
  25311. end;
  25312. if Value = FBmpChecked then Exit;
  25313. if FBmpChecked <> 0 then
  25314. DeleteObject( FBmpChecked );
  25315. FBmpChecked := Value;
  25316. MII.fMask := MIIM_CHECKMARKS;
  25317. MII.hbmpChecked := FBmpChecked;
  25318. MII.hbmpUnchecked := FBitmap;
  25319. SetInfo( MII );
  25320. end;
  25321. //[procedure TMenu.SetBmpItem]
  25322. procedure TMenu.SetBmpItem( Value: HBitmap );
  25323. var MII: TMenuItemInfo;
  25324. begin
  25325. if not FClearBitmaps then
  25326. begin
  25327. FClearBitmaps := TRUE;
  25328. Add2AutoFreeEx( ClearBitmaps );
  25329. end;
  25330. if Value = FBmpItem then Exit;
  25331. if FBmpItem <> 0 then
  25332. DeleteObject( FBmpItem );
  25333. FBmpItem := Value;
  25334. {$ifdef win32}
  25335. if WinVer >= wv98 then {AK}
  25336. begin {AK}
  25337. MII.fMask := $80 {MIIM_BITMAP} ; {AK}
  25338. MII.hbmpItem:=Value; {AK}
  25339. end {AK}
  25340. else {AK}
  25341. {$endif}
  25342. begin//I haven't possibility to test it in Win95 {AK}
  25343. MII.fType := MFT_BITMAP;
  25344. MII.dwItemData := Value;
  25345. end; {AK}
  25346. SetInfo( MII );
  25347. end;
  25348. //[procedure TMenu.SetAccelerator]
  25349. {$IFNDEF NEW_MENU_ACCELL}
  25350. procedure TMenu.SetAccelerator(const Value: TMenuAccelerator);
  25351. const MaxAccel = 1000;
  25352. type TAccTab = array[0..10000] of TAccel;
  25353. PAccTab = ^TAccTab;
  25354. var AccTab: PAccTab;
  25355. I, N : Integer;
  25356. M, SubM: PMenu;
  25357. C: PControl;
  25358. Main: Boolean;
  25359. begin
  25360. if (FAccelerator.fVirt = Value.fVirt) and (FAccelerator.Key = Value.Key) then Exit;
  25361. FAccelerator := Value;
  25362. C := TopParent.FControl;
  25363. if C = nil then Exit;
  25364. if C.fAccelTable <> 0 then
  25365. DestroyAcceleratorTable( C.fAccelTable );
  25366. C.fAccelTable := 0;
  25367. GetMem( AccTab, sizeof( TAccel ) * MaxAccel );
  25368. N := 0;
  25369. M := PMenu( C.fMenuObj );
  25370. Main := TRUE;
  25371. while M <> nil do
  25372. begin
  25373. if Main or M.Visible then
  25374. begin
  25375. for I := 0 to MaxInt-1 do
  25376. begin
  25377. SubM := M.Items[ I ];
  25378. if SubM = nil then break;
  25379. if SubM.FVisible then
  25380. if (SubM.FAccelerator.Key <> 0) or (SubM.FAccelerator.fVirt <> 0) then
  25381. begin
  25382. AccTab[ N ].fVirt := SubM.FAccelerator.fVirt;
  25383. AccTab[ N ].key := SubM.FAccelerator.Key;
  25384. AccTab[ N ].cmd := WORD( SubM.FId );
  25385. Inc( N );
  25386. if N > MaxAccel then break;
  25387. end;
  25388. end;
  25389. end;
  25390. if N > MaxAccel then break;
  25391. M := M.fNextMenu;
  25392. end;
  25393. if N > 0 then
  25394. begin
  25395. C.fAccelTable := CreateAcceleratorTable( AccTab[ 0 ], N );
  25396. {$IFDEF USE_AUTOFREE4CONTROLS}
  25397. C.Add2AutoFreeEx( C.DoDestroyAccelTable );
  25398. {$ENDIF}
  25399. C := C.ParentForm;
  25400. if C <> nil then
  25401. C.SupportMnemonics;
  25402. end;
  25403. FreeMem( AccTab );
  25404. end;
  25405. {$ELSE NEW_MENU_ACCELL}
  25406. procedure TMenu.SetAccelerator(const Value: TMenuAccelerator);
  25407. var
  25408. C: PControl;
  25409. M: PMenu;
  25410. begin
  25411. if (FAccelerator.fVirt = Value.fVirt) and (FAccelerator.Key = Value.Key) then Exit;
  25412. FAccelerator := Value;
  25413. C := FControl;
  25414. M := @Self;
  25415. while (C = nil) and (M <> nil) do begin
  25416. M := M.Parent;
  25417. if (M <> nil) then
  25418. C := M.FControl;
  25419. end;
  25420. if (C <> nil) then
  25421. C.SupportMnemonics;
  25422. end;
  25423. {$ENDIF NEW_MENU_ACCELL}
  25424. //[procedure TMenu.SetMenuItemCaption]
  25425. procedure TMenu.SetMenuItemCaption( const Value: KOLString );
  25426. var MII: TMenuItemInfo;
  25427. begin
  25428. FCaption := Value;
  25429. if FParentMenu = nil then Exit; {+ecm}
  25430. {$ifdef win32}
  25431. {AK}if not (WinVer in [wv95,wvNT]) then
  25432. {AK} MII.fMask := $40 {MIIM_STRING}
  25433. {AK}else begin
  25434. {$endif win32}
  25435. MII.fMask := MIIM_TYPE;
  25436. MII.fType := MFT_STRING;
  25437. {$ifdef win32}
  25438. {AK}end;
  25439. {$endif win32}
  25440. MII.dwTypeData:=nil;
  25441. MII.cch := 0; // to fix turning radio mark to check mark in NT4
  25442. GetInfo( MII ); //-----------------------------------------------
  25443. MII.dwTypeData := PKOLChar( Value );
  25444. MII.cch := Length( Value )*SizeOfKOLChar;
  25445. SetInfo( MII );
  25446. end;
  25447. //[procedure TMenu.SetMenuBreak]
  25448. procedure TMenu.SetMenuBreak( Value: TMenuBreak );
  25449. var MII: TMenuItemInfo;
  25450. begin
  25451. if FId = 0 then Exit;
  25452. if FMenuBreak = Value then Exit;
  25453. FMenuBreak := Value;
  25454. FillChar( MII, Sizeof( MII ), #0 );
  25455. MII.fMask := MIIM_TYPE;
  25456. MII.dwTypeData := nil;
  25457. if GetInfo( MII ) then
  25458. begin
  25459. MII.fType := MII.fType and not( MFT_MENUBREAK or MFT_MENUBARBREAK ) or
  25460. Breaks[ Value ];
  25461. SetTypeInfo( MII );
  25462. end;
  25463. end;
  25464. //[procedure TMenu.SetVisible]
  25465. procedure TMenu.SetVisible( Value: Boolean );
  25466. var I, MPos: Integer;
  25467. M: PMenu;
  25468. MII: TMenuItemInfo;
  25469. begin
  25470. if Value then
  25471. if FParentMenu <> nil then
  25472. FParentMenu.Visible := TRUE;
  25473. if Value = FVisible then Exit;
  25474. FVisible := Value;
  25475. if (FControl <> nil) and (FControl.fMenuObj = @ Self) then
  25476. begin
  25477. FControl.GetWindowHandle;
  25478. {$ifdef wince}
  25479. if Value then
  25480. CeSetMenu( FControl.fHandle, TopParent )
  25481. else
  25482. CeSetMenu( FControl.fHandle, nil );
  25483. {$else}
  25484. if Value then
  25485. SetMenu( FControl.fHandle, FHandle )
  25486. else
  25487. SetMenu( FControl.fHandle, 0 );
  25488. {$endif wince}
  25489. Exit;
  25490. end;
  25491. if FId = 0 then Exit;
  25492. if FParentMenu = nil then Exit;
  25493. MPos := 0;
  25494. for I := 0 to FParentMenu.FItems.FCount-1 do
  25495. begin
  25496. M := FParentMenu.FItems.Items[ I ];
  25497. if M = @Self then
  25498. break;
  25499. if M.FVisible then
  25500. Inc(MPos);
  25501. end;
  25502. if Value then
  25503. begin // show menu item inserting it again into appropriate position
  25504. FillChar( MII, Sizeof( MII ), #0 );
  25505. MII.cbSize := MenuStructSize;
  25506. MII.fMask := MIIM_CHECKMARKS or MIIM_ID or MIIM_STATE or
  25507. MIIM_TYPE;
  25508. MII.fType := Breaks[ FMenuBreak ];
  25509. MII.fState := FSavedState;
  25510. MII.wID := FId;
  25511. MII.dwItemData := DWORD( FData );
  25512. if not FIsSeparator then
  25513. begin
  25514. MII.fType := MII.fType or MFT_STRING;
  25515. MII.dwTypeData := PKOLChar( FCaption );
  25516. MII.cch := Length( FCaption );
  25517. end
  25518. else
  25519. MII.fType := MII.fType or MFT_SEPARATOR;
  25520. if FRadioGroup <> 0 then
  25521. MII.fType := MII.fType or MFT_RADIOCHECK;
  25522. if FOwnerDraw then
  25523. MII.fType := MII.fType or MFT_OWNERDRAW;
  25524. if FBitmap <> 0 then
  25525. begin
  25526. MII.fMask := MII.fMask or MIIM_CHECKMARKS;
  25527. MII.hbmpUnchecked := FBitmap;
  25528. end;
  25529. if FHandle <> 0 then
  25530. begin
  25531. MII.fMask := MII.fMask or MIIM_SUBMENU;
  25532. MII.hSubMenu := FHandle;
  25533. end;
  25534. InsertMenuItem( FParentMenu.FHandle, MPos, True, PMenuitemInfo( @ MII )^ );
  25535. end
  25536. else
  25537. begin // hide menu item removing it
  25538. GetState( 0 ); // store menu item state in FSavedState to allow
  25539. // changing its state while it is not attached to
  25540. // a menu
  25541. RemoveMenu( FParentMenu.FHandle, MPos, MF_BYPOSITION );
  25542. end;
  25543. if (FControl <> nil) or (FParentMenu <> nil) and (FParentMenu.FControl <> nil) then
  25544. RedrawFormMenuBar;
  25545. end;
  25546. //[procedure TMenu.RadioCheckItem]
  25547. procedure TMenu.RadioCheckItem;
  25548. var I, J: Integer;
  25549. M, First, Last: PMenu;
  25550. begin
  25551. if (FParentMenu <> nil) and (FRadioGroup <> 0) then
  25552. begin
  25553. I := FParentMenu.FItems.IndexOf( @ Self );
  25554. if I >= 0 then
  25555. begin
  25556. First := @ Self;
  25557. Last := @ Self;
  25558. for J := I-1 downto 0 do
  25559. begin
  25560. M := FParentMenu.FItems.Items[ J ];
  25561. if M.FRadioGroup <> FRadioGroup then break;
  25562. if M.FVisible then
  25563. First := M;
  25564. end;
  25565. for J := I+1 to FParentMenu.FItems.FCount-1 do
  25566. begin
  25567. M := FParentMenu.FItems.Items[ J ];
  25568. if M.FRadioGroup <> FRadioGroup then break;
  25569. if M.FVisible then
  25570. Last := M;
  25571. end;
  25572. if First <> Last then
  25573. begin
  25574. CheckMenuRadioItem( FParentMenu.FHandle, First.FId, Last.FId,
  25575. FId, MF_BYCOMMAND {or MF_CHECKED} );
  25576. Exit;
  25577. end;
  25578. end;
  25579. end;
  25580. Checked := TRUE;
  25581. end;
  25582. //[function TMenu.FillMenuItems]
  25583. function TMenu.FillMenuItems(AHandle: HMenu; StartIdx: Integer;
  25584. const Template: array of PKOLChar): Integer;
  25585. var S, S1: PKOLChar;
  25586. I: Integer;
  25587. MII: TMenuItemInfo;
  25588. Item, PrevItem: PMenu;
  25589. begin
  25590. PrevItem := nil;
  25591. I := StartIdx;
  25592. while I <= High( Template ) do
  25593. begin
  25594. S := Template[ I ];
  25595. if (S = nil) or (S^ = #0) then break;
  25596. if String( S ) = {$IFDEF F_P}'' +{$ENDIF} ')' then
  25597. begin
  25598. Inc(I);
  25599. break;
  25600. end;
  25601. {-}
  25602. new( Item, Create );
  25603. {+}{++}(*Item := PMenu.Create;*){--}
  25604. Item.FVisible := TRUE;
  25605. Item.FParentMenu := @ Self;
  25606. Item.FItems := NewList;
  25607. FItems.Add( Item );
  25608. FillChar( MII, Sizeof( MII ), #0 );
  25609. MII.cbSize := MenuStructSize;
  25610. MII.fMask := MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE;
  25611. if String( S ) <> {$IFDEF F_P}'' +{$ENDIF} '-' then
  25612. begin
  25613. if (S^ = {$IFDEF F_P}'' +{$ENDIF} '-') or
  25614. (S^ = {$IFDEF F_P}'' +{$ENDIF} '+') then
  25615. begin
  25616. Item.FIsCheckItem := TRUE;
  25617. {$ifdef win32}
  25618. MII.dwItemData := MIDATA_CHECKITEM;
  25619. {$endif win32}
  25620. if S^ <> {$IFDEF F_P}'' +{$ENDIF} '-' then
  25621. MII.fState := MII.fState or MFS_CHECKED;
  25622. Inc( S );
  25623. if S^ = {$IFDEF F_P}'' +{$ENDIF} '!' then
  25624. begin
  25625. MII.fType := MII.fType or MFT_RADIOCHECK;
  25626. {$ifdef win32}
  25627. MII.dwItemData := MII.dwItemData or MIDATA_RADIOITEM;
  25628. {$endif win32}
  25629. Inc( S );
  25630. if PrevItem <> nil then
  25631. begin
  25632. if PrevItem.FRadioGroup <> 0 then
  25633. Item.FRadioGroup := PrevItem.FRadioGroup;
  25634. end;
  25635. if Item.FRadioGroup = 0 then
  25636. Inc( Item.FRadioGroup );
  25637. if S^ = {$IFDEF F_P}'' +{$ENDIF} '!' then
  25638. begin
  25639. Inc( S );
  25640. Inc( Item.FRadioGroup );
  25641. end;
  25642. end;
  25643. end;
  25644. Item.FCaption := S;
  25645. end
  25646. else
  25647. begin
  25648. Item.FIsSeparator := TRUE;
  25649. MII.fType := MFT_SEPARATOR;
  25650. MII.fState := MFS_GRAYED;
  25651. MII.wID := 0;
  25652. end;
  25653. Item.FId := FDynamicMenuID;
  25654. Inc( FDynamicMenuID );
  25655. MII.wID := Item.FId;
  25656. if I <> High( Template ) then
  25657. begin
  25658. S1 := Template[ I + 1 ];
  25659. if String( S1 ) = {$IFDEF F_P}'' +{$ENDIF} '(' then Item.FHandle := CreatePopupMenu;
  25660. end;
  25661. MII.hSubMenu := Item.FHandle;
  25662. MII.dwTypeData := PKOLChar( S );
  25663. MII.cch := {$IFDEF UNICODE_CTRLS} WStrLen( S ) {$ELSE} StrLen( S ) {$ENDIF};
  25664. InsertMenuItem( AHandle, DWORD(-1), True, PMenuitemInfo( @ MII )^ );
  25665. if Item.FHandle <> 0 then
  25666. I := Item.FillMenuItems( Item.FHandle, I + 2, Template )
  25667. else
  25668. Inc( I );
  25669. PrevItem := Item;
  25670. end;
  25671. Result := I;
  25672. end;
  25673. //[procedure TMenu.AssignEvents]
  25674. procedure TMenu.AssignEvents(StartIdx: Integer;
  25675. const Events: array of TOnMenuItem);
  25676. var I: Integer;
  25677. M: PMenu;
  25678. begin
  25679. for I := 0 to High(Events) do
  25680. begin
  25681. M := Items[ StartIdx ];
  25682. if M = nil then break;
  25683. M.FOnMenuItem := Events[ I ];
  25684. Inc( StartIdx );
  25685. end;
  25686. end;
  25687. //[procedure TMenu.Popup]
  25688. function TMenu.Popup(X, Y: Integer): Integer;
  25689. {$ifdef wince}
  25690. var
  25691. OldFlags: DWORD;
  25692. {$endif wince}
  25693. begin
  25694. {$IFDEF GDI}
  25695. if Assigned( fOnPopup ) then fOnPopup( @Self );
  25696. if not FNotPopup then begin
  25697. {$ifdef wince}
  25698. OldFlags:=Flags;
  25699. Flags:=Flags or $1000;
  25700. {$endif wince}
  25701. Result := Integer( TrackPopupMenu( FHandle, {$ifdef wince} OldFlags {$else} FPopupFlags {$endif},
  25702. X, Y, 0, FControl.Handle, nil ) );
  25703. {$ifdef wince}
  25704. Flags:=OldFlags;
  25705. {$endif wince}
  25706. end
  25707. else Result := 0;
  25708. {$ENDIF GDI}
  25709. end;
  25710. //[procedure TMenu.PopupEx]
  25711. function TMenu.PopupEx( X, Y: Integer ): Integer;
  25712. {$IFDEF GDI}
  25713. var OldBounds: TRect;
  25714. WasVisible: Boolean;
  25715. {$ENDIF GDI}
  25716. begin
  25717. {$IFDEF GDI}
  25718. WasVisible := TRUE;
  25719. if FControl <> nil then
  25720. begin
  25721. OldBounds := FControl.BoundsRect;
  25722. if not FControl.fIsControl then
  25723. begin
  25724. WasVisible := FControl.Visible;
  25725. if not WasVisible then
  25726. FControl.Top := ScreenHeight + 50;
  25727. FControl.Show;
  25728. end;
  25729. end;
  25730. // -- by Martin Larsen: -----------------------
  25731. FControl.ProcessMessage; // specific for Win9x
  25732. Result := Popup( X, Y ); {*ecm}
  25733. if FControl <> nil then
  25734. begin
  25735. if FControl.Top = ScreenHeight + 50 then
  25736. begin
  25737. if not WasVisible then
  25738. FControl.Visible := FALSE;
  25739. FControl.BoundsRect := OldBounds;
  25740. end;
  25741. end;
  25742. {$ENDIF GDI}
  25743. end;
  25744. //[function TMenu.GetItemChecked]
  25745. function TMenu.GetItemChecked( Item : Integer ) : Boolean;
  25746. begin
  25747. Result := Items[ Item ].Checked;
  25748. end;
  25749. //[procedure TMenu.SetItemChecked]
  25750. procedure TMenu.SetItemChecked( Item : Integer; Value : Boolean );
  25751. begin
  25752. Items[ Item ].Checked := Value;
  25753. end;
  25754. //[function TMenu.GetMenuItemHandle]
  25755. function TMenu.GetMenuItemHandle( Idx : Integer ): DWORD;
  25756. begin
  25757. Result := Items[ Idx ].FId;
  25758. end;
  25759. //[procedure TMenu.RadioCheck]
  25760. procedure TMenu.RadioCheck( Idx : Integer );
  25761. begin
  25762. Items[ Idx ].RadioCheckItem;
  25763. end;
  25764. //[function TMenu.GetItemBitmap]
  25765. function TMenu.GetItemBitmap(Idx: Integer): HBitmap;
  25766. begin
  25767. Result := Items[ Idx ].Bitmap;
  25768. end;
  25769. //[procedure TMenu.SetItemBitmap]
  25770. procedure TMenu.SetItemBitmap(Idx: Integer; const Value: HBitmap);
  25771. begin
  25772. Items[ Idx ].Bitmap := Value;
  25773. end;
  25774. //[procedure TMenu.AssignBitmaps]
  25775. procedure TMenu.AssignBitmaps(StartIdx: Integer; Bitmaps: array of HBitmap);
  25776. var I: Integer;
  25777. begin
  25778. for I := 0 to High(Bitmaps) do
  25779. ItemBitmap[ I + StartIdx ] := Bitmaps[ I ];
  25780. end;
  25781. //[function TMenu.GetItemText]
  25782. function TMenu.GetItemText(Idx: Integer): KOLString;
  25783. begin
  25784. Result := Items[ Idx ].FCaption;
  25785. end;
  25786. //[procedure TMenu.SetItemText]
  25787. procedure TMenu.SetItemText(Idx: Integer; const Value: KOLString);
  25788. begin
  25789. Items[ Idx ].Caption := Value;
  25790. end;
  25791. //[function TMenu.GetItemEnabled]
  25792. function TMenu.GetItemEnabled(Idx: Integer): Boolean;
  25793. begin
  25794. Result := Items[ Idx ].Enabled;
  25795. end;
  25796. //[procedure TMenu.SetItemEnabled]
  25797. procedure TMenu.SetItemEnabled(Idx: Integer; const Value: Boolean);
  25798. begin
  25799. Items[ Idx ].Enabled := Value;
  25800. end;
  25801. //[function TMenu.GetItemVisible]
  25802. function TMenu.GetItemVisible(Idx: Integer): Boolean;
  25803. begin
  25804. Result := Items[ Idx ].Visible;
  25805. end;
  25806. //[procedure TMenu.SetItemVisible]
  25807. procedure TMenu.SetItemVisible(Idx: Integer; const Value: Boolean);
  25808. begin
  25809. Items[ Idx ].Visible := Value;
  25810. end;
  25811. //[function TMenu.ParentItem]
  25812. function TMenu.ParentItem( Idx: Integer ): Integer;
  25813. begin
  25814. Result := TopParent.IndexOf( Items[ Idx ].FParentMenu );
  25815. end;
  25816. //[function TMenu.GetItemAccelerator]
  25817. function TMenu.GetItemAccelerator(Idx: Integer): TMenuAccelerator;
  25818. begin
  25819. Result := Items[ Idx ].Accelerator;
  25820. end;
  25821. //[procedure TMenu.SetItemAccelerator]
  25822. procedure TMenu.SetItemAccelerator(Idx: Integer; const Value: TMenuAccelerator);
  25823. begin
  25824. Items[ Idx ].Accelerator := Value;
  25825. end;
  25826. //[function TMenu.GetItemSubMenu]
  25827. function TMenu.GetItemSubMenu( Idx: Integer ): HMenu;
  25828. begin
  25829. Result := Items[ Idx ].SubMenu;
  25830. end;
  25831. {$ifdef wince}
  25832. procedure TMenu.ReCreate;
  25833. var
  25834. MII: TMenuItemInfo;
  25835. i, j: integer;
  25836. begin
  25837. if FHandle = 0 then exit;
  25838. while RemoveMenu(FHandle, 0, MF_BYPOSITION) do ;
  25839. j:=0;
  25840. for i:=0 to FItems.Count - 1 do
  25841. with PMenu(FItems.Items[i])^ do begin
  25842. if FHandle <> 0 then
  25843. DestroyMenu(FHandle);
  25844. if FItems.Count > 0 then
  25845. FHandle:=CreatePopupMenu
  25846. else
  25847. FHandle:=0;
  25848. if Visible then begin
  25849. FillChar( MII, Sizeof( MII ), 0 );
  25850. MII.cbSize := SizeOf(MII);
  25851. MII.fMask := MIIM_CHECKMARKS or MIIM_ID or MIIM_STATE or MIIM_TYPE;
  25852. MII.fType := Breaks[ FMenuBreak ];
  25853. MII.fState := FSavedState;
  25854. MII.wID := FId;
  25855. MII.dwItemData := DWORD( FData );
  25856. if not FIsSeparator then
  25857. begin
  25858. MII.fType := MII.fType or MFT_STRING;
  25859. MII.dwTypeData := PKOLChar( FCaption );
  25860. MII.cch := Length( FCaption );
  25861. end
  25862. else
  25863. MII.fType := MII.fType or MFT_SEPARATOR;
  25864. if FRadioGroup <> 0 then
  25865. MII.fType := MII.fType or MFT_RADIOCHECK;
  25866. if FOwnerDraw then
  25867. MII.fType := MII.fType or MFT_OWNERDRAW;
  25868. if FBitmap <> 0 then
  25869. begin
  25870. MII.fMask := MII.fMask or MIIM_CHECKMARKS;
  25871. MII.hbmpUnchecked := FBitmap;
  25872. end;
  25873. if FHandle <> 0 then
  25874. begin
  25875. MII.fMask := MII.fMask or MIIM_SUBMENU;
  25876. MII.hSubMenu := FHandle;
  25877. end;
  25878. InsertMenuItem( Self.FHandle, j, True, PMenuitemInfo( @ MII )^ );
  25879. Inc(j);
  25880. end;
  25881. if FHandle <> 0 then
  25882. ReCreate;
  25883. end;
  25884. end;
  25885. procedure TMenu.SaveState;
  25886. var
  25887. i: integer;
  25888. begin
  25889. for i:=0 to FItems.Count - 1 do
  25890. with PMenu(FItems.Items[i])^ do begin
  25891. GetState(0);
  25892. if SubMenu <> 0 then
  25893. SaveState;
  25894. end;
  25895. end;
  25896. {$endif wince}
  25897. //[function WndProcHelp FORWARD DECLARATION]
  25898. function WndProcHelp( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  25899. forward;
  25900. {$IFDEF GDI}
  25901. //[procedure TMenu.SetHelpContext]
  25902. procedure TMenu.SetHelpContext( Value: Integer );
  25903. {$ifdef wince}
  25904. begin
  25905. {$else}
  25906. var Form, C: PControl;
  25907. begin
  25908. if TopParent <> @ Self then Exit;
  25909. // Help context can not be associated with individual menu items
  25910. FHelpContext := Value;
  25911. C := FControl;
  25912. if C = nil then Exit;
  25913. Form := C.ParentForm;
  25914. Form.AttachProc( WndProcHelp );
  25915. SetMenuContextHelpID( FHandle, Value );
  25916. {$endif wince}
  25917. end;
  25918. {$ENDIF GDI}
  25919. //[procedure TMenu.SetSubmenu]
  25920. procedure TMenu.SetSubmenu( Value: HMenu );
  25921. var MII: TMenuItemInfo;
  25922. begin
  25923. MII.fMask := MIIM_SUBMENU;
  25924. MII.hSubMenu := Value;
  25925. SetInfo( MII );
  25926. FHandle := Value;
  25927. end;
  25928. //[function WndProcMeasureItem]
  25929. function WndProcMeasureItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  25930. var MIS: PMeasureItemStruct;
  25931. M, SM: PMenu;
  25932. H, I: Integer;
  25933. begin
  25934. Result := FALSE;
  25935. if (Msg.message = WM_MEASUREITEM) and (Msg.wParam = 0) then
  25936. begin
  25937. MIS := Pointer( Msg.lParam );
  25938. if MIS.CtlType = ODT_MENU then
  25939. begin
  25940. M := Pointer( Sender.fMenuObj );
  25941. while M <> nil do
  25942. begin
  25943. SM := M.Items[ MIS.itemID ];
  25944. if SM <> nil then
  25945. begin
  25946. Sender.CallDefWndProc( Msg );
  25947. I := M.IndexOf( SM );
  25948. if Assigned( SM.OnMeasureItem ) then
  25949. M := SM;
  25950. if not Assigned( M.OnMeasureItem ) then
  25951. Exit;
  25952. H := M.OnMeasureItem( M, I );
  25953. if HiWord( H ) <> 0 then
  25954. MIS.itemWidth := HiWord( H );
  25955. if LoWord( H ) <> 0 then
  25956. MIS.itemHeight := LoWord( H );
  25957. Rslt := 1;
  25958. Result := TRUE;
  25959. break;
  25960. end;
  25961. M := M.fNextMenu;
  25962. end;
  25963. end;
  25964. end;
  25965. end;
  25966. //[procedure TMenu.SetOnMeasureItem]
  25967. procedure TMenu.SetOnMeasureItem( const Value: TOnMeasureItem );
  25968. var C: PControl;
  25969. begin
  25970. FOnMeasureItem := Value;
  25971. C := TopParent.FControl;
  25972. if C <> nil then
  25973. C.AttachProc( WndProcMeasureItem );
  25974. end;
  25975. //[function WndProcDrawItem]
  25976. function WndProcDrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  25977. type PDrawAction = ^TDrawAction;
  25978. PDrawState = ^TDrawState;
  25979. var DIS: PDrawItemStruct;
  25980. M, SM: PMenu;
  25981. I: Integer;
  25982. begin
  25983. Result := FALSE;
  25984. if (Msg.message = WM_DRAWITEM) and (Msg.wParam = 0) then
  25985. begin
  25986. DIS := Pointer( Msg.lParam );
  25987. if DIS.CtlType = ODT_MENU then
  25988. begin
  25989. M := Pointer( Sender.fMenuObj );
  25990. while M <> nil do
  25991. begin
  25992. SM := M.Items[ DIS.itemID ];
  25993. if SM <> nil then
  25994. begin
  25995. I := M.IndexOf( SM );
  25996. if Assigned( SM.OnDrawItem ) then
  25997. M := SM;
  25998. if Assigned( M.OnDrawItem ) then
  25999. begin
  26000. if not M.OnDrawItem( M, DIS.hDC, DIS.rcItem, I,
  26001. PDrawAction( @ DIS.itemAction )^,
  26002. PDrawState( @ DIS.itemState )^ ) then Exit;
  26003. end
  26004. else Exit;
  26005. Rslt := 1;
  26006. Result := TRUE;
  26007. break;
  26008. end;
  26009. M := M.fNextMenu;
  26010. end;
  26011. end;
  26012. end;
  26013. end;
  26014. //[procedure TMenu.SetOnDrawItem]
  26015. procedure TMenu.SetOnDrawItem( const Value: TOnDrawItem );
  26016. var C: PControl;
  26017. begin
  26018. FOnDrawItem := Value;
  26019. C := TopParent.FControl;
  26020. if C <> nil then
  26021. C.AttachProc( WndProcDrawItem );
  26022. end;
  26023. //[procedure TMenu.SetOwnerDraw]
  26024. procedure TMenu.SetOwnerDraw( Value: Boolean );
  26025. const Masks: array[ Boolean ] of DWORD = ( 0, $FFFFFFFF );
  26026. var MII: TMenuItemInfo;
  26027. begin
  26028. FOwnerDraw := Value;
  26029. FillChar( MII, Sizeof( MII ), #0 );
  26030. MII.fMask := MIIM_TYPE;
  26031. MII.dwTypeData := nil;
  26032. if GetInfo( MII ) then
  26033. begin
  26034. MII.fType := MII.fType and not MFT_OWNERDRAW or
  26035. (MFT_OWNERDRAW and Masks[ Value ]);
  26036. SetTypeInfo( MII );
  26037. end;
  26038. end;
  26039. //[function TMenu.Insert]
  26040. function TMenu.Insert(InsertBefore: Integer; ACaption: PKOLChar; Event: TOnMenuItem;
  26041. Options: TMenuOptions): PMenu;
  26042. const
  26043. MenuStateFlags: array[TMenuOption] of Integer = (MFS_DEFAULT, MFS_DISABLED, MFS_CHECKED, 0, 0,
  26044. MFS_DISABLED, 0, 0, 0, 0);
  26045. MenuTypeFlags: array[TMenuOption] of Integer = (0, 0, 0, 0, MFT_RADIOCHECK, MFT_SEPARATOR, MFT_BITMAP, 0,
  26046. MFT_MENUBREAK, MFT_MENUBARBREAK);
  26047. var M: PMenu;
  26048. MII: TMenuItemInfo;
  26049. begin
  26050. {-}
  26051. new( Result, Create );
  26052. {+}{++}(*Result := PMenu.Create;*){--}
  26053. Result.FVisible := TRUE;
  26054. Result.FParentMenu := @ Self;
  26055. Result.FItems := NewList;
  26056. Result.FIsSeparator := moSeparator in Options;
  26057. if FHandle = 0 then
  26058. SetSubMenu( CreatePopupMenu );
  26059. M := nil;
  26060. if (InsertBefore >= 0) and (InsertBefore < 4096) then
  26061. begin
  26062. M := Items[ InsertBefore ];
  26063. if M <> nil then
  26064. begin
  26065. InsertBefore := M.FId;
  26066. M.Parent.FItems.Insert( M.Parent.FItems.IndexOf( M ), Result );
  26067. end;
  26068. end;
  26069. if M = nil then
  26070. begin
  26071. InsertBefore := -1;
  26072. FItems.Add( Result );
  26073. end;
  26074. Result.FOnMenuItem := Event;
  26075. FillChar( MII, Sizeof( MII ), #0 );
  26076. MII.cbSize := MenuStructSize;
  26077. MII.fMask := MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE;
  26078. MII.fState := MakeFlags( Pointer( @Options ), MenuStateFlags);
  26079. {$ifdef wince}
  26080. Result.FSavedState:=MII.fState;
  26081. {$endif wince}
  26082. MII.fType := MakeFlags( Pointer( @Options ), MenuTypeFlags);
  26083. Result.FId := FDynamicMenuID;
  26084. Inc( FDynamicMenuID );
  26085. MII.wID := Result.FId;
  26086. if moSubMenu in Options
  26087. then begin
  26088. Result.FHandle := CreatePopupMenu;
  26089. MII.hSubMenu := Result.FHandle;
  26090. end;
  26091. MII.dwTypeData := PKOLChar(ACaption);
  26092. {$IFNDEF UNICODE_CTRLS}
  26093. if not (moBitmap in Options) then MII.cch := StrLen( ACaption );
  26094. {$ELSE}
  26095. if not (moBitmap in Options) then MII.cch := WStrLen( ACaption );
  26096. {$ENDIF}
  26097. InsertMenuItem( FHandle, InsertBefore, InsertBefore = -1,
  26098. PMenuItemInfo( @ MII )^ );
  26099. if moBitmap in Options then
  26100. begin
  26101. Result.BitmapItem := DWORD( ACaption );
  26102. end
  26103. else
  26104. Result.FCaption := ACaption;
  26105. RedrawFormMenuBar;
  26106. end;
  26107. //[function TMenu.AddItem]
  26108. function TMenu.AddItem(ACaption: PKOLChar; Event: TOnMenuItem; Options: TMenuOptions): Integer;
  26109. begin
  26110. Result := InsertItem( -1, ACaption, Event, Options );
  26111. end;
  26112. //[function TMenu.InsertItem]
  26113. function TMenu.InsertItem( InsertBefore: Integer; ACaption: PKOLChar; Event: TOnMenuItem;
  26114. Options: TMenuOptions): Integer;
  26115. begin
  26116. Result := InsertItemEx( InsertBefore, ACaption, Event, Options, FALSE );
  26117. end;
  26118. //[function TMenu.InsertItemEx]
  26119. function TMenu.InsertItemEx(InsertBefore: Integer; ACaption: PKOLChar;
  26120. Event: TOnMenuItem; Options: TMenuOptions; ByPosition: Boolean): Integer;
  26121. var M: PMenu;
  26122. begin
  26123. M := Insert( InsertBefore, ACaption, Event, Options );
  26124. Result := M.FId;
  26125. end;
  26126. //[procedure TMenu.InsertSubMenu]
  26127. procedure TMenu.InsertSubMenu( SubMenuToInsert: PMenu; InsertBefore: Integer );
  26128. var AFlags: DWORD;
  26129. M: PMenu;
  26130. {$ifndef wince}
  26131. MII: TMenuItemInfo;
  26132. {$endif wince}
  26133. begin
  26134. if SubMenuToInsert.FParentMenu <> nil then
  26135. SubMenuToInsert := SubMenuToInsert.FParentMenu.RemoveSubMenu( SubMenuToInsert.FId );
  26136. if SubMenuToInsert = nil then Exit;
  26137. AFlags := MF_BYPOSITION;
  26138. M := nil;
  26139. if (InsertBefore >= 0) and (InsertBefore < 4096) then
  26140. begin
  26141. M := Items[ InsertBefore ];
  26142. if M = nil then
  26143. InsertBefore := -1
  26144. else
  26145. InsertBefore := M.FId;
  26146. end;
  26147. if M = nil then
  26148. begin
  26149. FItems.Add( SubMenuToInsert );
  26150. SubMenuToInsert.FParentMenu := @ Self;
  26151. end
  26152. else
  26153. begin
  26154. M.FParentMenu.FItems.Insert( M.FParentMenu.FItems.IndexOf( M ), SubMenuToInsert );
  26155. SubMenuToInsert.FParentMenu := M.FParentMenu;
  26156. end;
  26157. if InsertBefore > 0 then
  26158. AFlags := MF_BYCOMMAND;
  26159. {$ifdef wince}
  26160. if FHandle <> 0 then
  26161. {$endif wince}
  26162. if SubMenuToInsert.FBmpItem <> 0 then
  26163. InsertMenu( FHandle, InsertBefore, AFlags or MF_BITMAP or MF_POPUP,
  26164. SubMenuToInsert.FHandle, PKOLChar( SubMenuToInsert.FBmpItem ) )
  26165. else
  26166. InsertMenu( FHandle, InsertBefore, AFlags or MF_STRING or MF_POPUP,
  26167. SubMenuToInsert.FHandle, PKOLChar( SubMenuToInsert.Caption ) );
  26168. {$ifndef wince}
  26169. if SubMenuToInsert.FId = 0 then
  26170. begin
  26171. SubMenuToInsert.FId := FDynamicMenuID;
  26172. Inc( FDynamicMenuID );
  26173. MII.cbSize := MenuStructSize;
  26174. MII.fMask := MIIM_ID;
  26175. MII.wID := SubMenuToInsert.FId;
  26176. // {$IFNDEF UNICODE_CTRLS}
  26177. SetMenuItemInfo( SubMenuToInsert.FParentMenu.FHandle,
  26178. SubMenuToInsert.FParentMenu.FItems.IndexOf( SubMenuToInsert ),
  26179. TRUE, {Windows.}PMenuItemInfo( @ MII )^ );
  26180. // {$ELSE}
  26181. // SetMenuItemInfoW( SubMenuToInsert.FParentMenu.FHandle,
  26182. // SubMenuToInsert.FParentMenu.FItems.IndexOf( SubMenuToInsert ),
  26183. // TRUE, Windows.PMenuItemInfoW( @ MII )^ );
  26184. // {$ENDIF}
  26185. end;
  26186. {$endif wince}
  26187. if (FParentMenu = nil) or (FParentMenu.FParentMenu = nil) then
  26188. RedrawFormMenuBar;
  26189. end;
  26190. //[function TMenu.RemoveSubMenu]
  26191. function TMenu.RemoveSubMenu( ItemToRemove: Integer ): PMenu;
  26192. {$IFDEF DEBUG_MENU}var OK: Boolean; {$ENDIF}
  26193. begin
  26194. Result := Items[ ItemToRemove ];
  26195. if Result = nil then Exit;
  26196. {$ifdef wince}
  26197. if Result.FHandle = 0 then
  26198. {$endif wince}
  26199. if Result.FParentMenu <> nil then
  26200. {$IFDEF DEBUG_MENU} OK := {$ENDIF}
  26201. RemoveMenu( Result.FParentMenu.FHandle, Result.FId, MF_BYCOMMAND )
  26202. else
  26203. {$IFDEF DEBUG_MENU} OK := {$ENDIF}
  26204. RemoveMenu( FHandle, Result.FId, MF_BYCOMMAND );
  26205. {$IFDEF DEBUG_MENU}
  26206. if not OK then
  26207. ShowMessage( 'Error removing menu: ' + Int2Str( GetLastError ) + ' - ' +
  26208. SysErrorMessage( GetLastError ) );
  26209. {$ENDIF}
  26210. if Count = 0 then
  26211. begin
  26212. Result.Free;
  26213. Result := nil;
  26214. end;
  26215. {$ifndef wince}
  26216. RedrawFormMenuBar;
  26217. {$endif wince}
  26218. end;
  26219. //[function TMenu.GetItemHelpContext]
  26220. function TMenu.GetItemHelpContext(Idx: Integer): Integer;
  26221. begin
  26222. Result := Items[ Idx ].HelpContext;
  26223. end;
  26224. //[procedure TMenu.SetItemHelpContext]
  26225. procedure TMenu.SetItemHelpContext(Idx: Integer; const Value: Integer);
  26226. begin
  26227. Items[ Idx ].HelpContext := Value;
  26228. end;
  26229. //[procedure ClearText]
  26230. procedure ClearText( Sender: PControl );
  26231. begin
  26232. Sender.Caption := '';
  26233. end;
  26234. //[procedure ClearListbox]
  26235. procedure ClearListbox( Sender: PControl );
  26236. begin
  26237. Sender.Perform( LB_RESETCONTENT, 0, 0 );
  26238. end;
  26239. //[procedure ClearCombobox]
  26240. procedure ClearCombobox( Sender: PControl );
  26241. begin
  26242. Sender.Perform( CB_RESETCONTENT, 0, 0 );
  26243. end;
  26244. //[procedure ClearListView]
  26245. procedure ClearListView( Sender: PControl );
  26246. begin
  26247. Sender.Perform( LVM_DELETEALLITEMS, 0, 0 );
  26248. end;
  26249. //[procedure ClearToolbar]
  26250. procedure ClearToolbar( Sender: PControl );
  26251. begin
  26252. while Sender.TBButtonCount > 0 do
  26253. Sender.TBDeleteButton( Sender.TBIndex2Item( 0 ) );
  26254. Sender.Perform( TB_SETBITMAPSIZE, 0, 0 );
  26255. end;
  26256. {$ENDIF WIN_GDI}
  26257. { -- Constructor of canvas -- }
  26258. //[function NewCanvas]
  26259. function NewCanvas( DC: HDC ): PCanvas;
  26260. begin
  26261. {-}
  26262. New( Result, Create );
  26263. {+}
  26264. {++}(*
  26265. Result := PCanvas.Create;
  26266. *){--}
  26267. {$IFDEF GDI}
  26268. Result.ModeCopy := cmSrcCopy;
  26269. if DC <> 0 then
  26270. begin
  26271. Result.SetHandle( DC );
  26272. //Result.fIsPaintDC := True; // If Canvas will be destroyed, DC will not be deleted
  26273. end;
  26274. {$ENDIF GDI}
  26275. end;
  26276. //[END NewCanvas]
  26277. { -- Contructors of controls -- }
  26278. //[FUNCTION _NewTControl]
  26279. {$IFDEF GDI}
  26280. {$IFDEF ASM_VERSION}
  26281. {$ELSE ASM_VERSION} //Pascal
  26282. function _NewWindowed( AParent: PControl; ControlClassName: PKOLChar; Ctl3D: Boolean ): PControl;
  26283. begin
  26284. {-}
  26285. New( Result, CreateParented( AParent ) );
  26286. //Result.fWindowed := TRUE; // is set in TControl.Init
  26287. {+}{++}(*Result := PControl.CreateParented( AParent );*){--}
  26288. Result.fControlClassName := ControlClassName;
  26289. if AParent <> nil then
  26290. begin
  26291. {$IFDEF WIN_GDI}
  26292. Result.fWndProcResizeFlicks := AParent.fWndProcResizeFlicks;
  26293. {$ENDIF WIN_GDI}
  26294. Result.fGotoControl := AParent.fGotoControl;
  26295. Result.fCtl3Dchild := AParent.fCtl3Dchild;
  26296. if AParent.fCtl3Dchild then
  26297. Result.fCtl3D := Ctl3D
  26298. else
  26299. Result.fCtl3D := False; //
  26300. Result.fMargin := AParent.fMargin;
  26301. Result.fTextColor := AParent.fTextColor;
  26302. {$IFDEF SMALLEST_CODE}
  26303. {$ELSE}
  26304. {$IFDEF WIN_GDI} // for now Font is complicated a bit, implement it later
  26305. Result.fFont := Result.fFont.Assign( AParent.fFont );
  26306. if Result.fFont <> nil then
  26307. begin
  26308. {$IFDEF USE_AUTOFREE4CONTROLS}
  26309. Result.Add2AutoFree( Result.fFont );
  26310. {$ENDIF USE_AUTOFREE4CONTROLS}
  26311. Result.fFont.fParentGDITool := AParent.fFont;
  26312. Result.fFont.fOnChange := Result.FontChanged;
  26313. Result.FontChanged( Result.fFont );
  26314. end;
  26315. {$ENDIF WIN_GDI}
  26316. {$ENDIF SMALLEST_CODE}
  26317. Result.fColor := AParent.fColor;
  26318. {$IFDEF WIN_GDI}
  26319. Result.fBrush := Result.fBrush.Assign( AParent.fBrush );
  26320. if Result.fBrush <> nil then
  26321. begin
  26322. {$IFDEF USE_AUTOFREE4CONTROLS}
  26323. Result.Add2AutoFree( Result.fBrush );
  26324. {$ENDIF USE_AUTOFREE4CONTROLS}
  26325. Result.fBrush.fParentGDITool := AParent.fBrush;
  26326. Result.fBrush.fOnChange := Result.BrushChanged;
  26327. Result.BrushChanged( Result.fBrush );
  26328. end;
  26329. {$ENDIF WIN_GDI}
  26330. end;
  26331. end;
  26332. //[END _NewWindowed]
  26333. {$ENDIF ASM_VERSION}
  26334. {$ENDIF GDI}
  26335. {$IFDEF _X_}
  26336. {$IFDEF GTK}
  26337. var GTK_initialized: Boolean;
  26338. argc: Integer = 0;
  26339. procedure FixedChildSetPos( Ctl, Chld: PControl; x, y: Integer );
  26340. begin
  26341. gtk_fixed_move( GTK_FIXED( Ctl.fClient ), Chld.fEventboxHandle, x, y );
  26342. end;
  26343. procedure LayoutChildSetPos( Ctl, Chld: PControl; x, y: Integer );
  26344. begin
  26345. gtk_layout_move( GTK_LAYOUT( Ctl.fClient ), Chld.fEventboxHandle, x, y );
  26346. end;
  26347. procedure FixedChildPut( Ctl, Chld: PControl; x, y: Integer );
  26348. begin
  26349. gtk_fixed_put( GTK_FIXED( Ctl.fClient ), Chld.fEventboxHandle, x, y );
  26350. end;
  26351. procedure LayoutChildPut( Ctl, Chld: PControl; x, y: Integer );
  26352. begin
  26353. gtk_layout_put( GTK_LAYOUT( Ctl.fClient ), Chld.fEventboxHandle, x, y );
  26354. end;
  26355. function FixedClientArea( Ctl: PControl ): PGtkWidget;
  26356. begin
  26357. if Ctl.fClient = nil then
  26358. begin
  26359. Ctl.fClient := gtk_fixed_new;
  26360. gtk_container_set_border_width(GTK_CONTAINER(Ctl.fHandle), 0);
  26361. gtk_container_add( GTK_CONTAINER( Ctl.fHandle ), Ctl.fClient );
  26362. gtk_container_set_border_width(GTK_CONTAINER(Ctl.fClient), 0);
  26363. gtk_widget_show( Ctl.fClient );
  26364. Ctl.fChildPut := FixedChildPut;
  26365. Ctl.fChildSetPos := FixedChildSetPos;
  26366. end;
  26367. Result := Ctl.fClient;
  26368. end;
  26369. function ClientAreaLayout( Ctl: PControl ): PGtkWidget;
  26370. begin
  26371. if Ctl.fClient = nil then
  26372. begin
  26373. Ctl.fClient := gtk_layout_new( {hadjustment} nil, {vadjustment} nil );
  26374. Ctl.fChildPut := LayoutChildPut;
  26375. Ctl.fChildSetPos := LayoutChildSetPos;
  26376. end;
  26377. Result := Ctl.fClient;
  26378. end;
  26379. function _NewWindowed( AParent: PControl; ControlClassName: PChar;
  26380. widget: PGtkWidget; need_eventbox: Boolean ): PControl;
  26381. //var GVal: TGValue;
  26382. begin
  26383. (*if not GTK_initialized then
  26384. begin
  26385. GTK_initialized := TRUE;
  26386. gtk_init( @ argc, {@ argv} nil );
  26387. end;*)
  26388. {-}
  26389. New( Result, CreateParented( AParent, widget, need_eventbox ) );
  26390. //Result.fWindowed := TRUE; // is set in TControl.Init
  26391. //???//Result.fControlClassName := ControlClassName;
  26392. if AParent <> nil then
  26393. begin
  26394. Result.fGotoControl := AParent.fGotoControl;
  26395. {Result.fCtl3Dchild := AParent.fCtl3Dchild;
  26396. if AParent.fCtl3Dchild then
  26397. Result.fCtl3D := Ctl3D
  26398. else
  26399. Result.fCtl3D := False;}
  26400. Result.fMargin := AParent.fMargin;
  26401. Result.fTextColor := AParent.fTextColor;
  26402. {$IFDEF SMALLEST_CODE}
  26403. {$ELSE}
  26404. {$IFDEF WIN_GDI} // for now Font is complicated a bit, implement it later
  26405. Result.fFont := Result.fFont.Assign( AParent.fFont );
  26406. if Result.fFont <> nil then
  26407. begin
  26408. {$IFDEF USE_AUTOFREE4CONTROLS}
  26409. Result.Add2AutoFree( Result.fFont );
  26410. {$ENDIF USE_AUTOFREE4CONTROLS}
  26411. Result.fFont.fParentGDITool := AParent.fFont;
  26412. Result.fFont.fOnChange := Result.FontChanged;
  26413. Result.FontChanged( Result.fFont );
  26414. end;
  26415. {$ENDIF WIN_GDI}
  26416. {$ENDIF SMALLEST_CODE}
  26417. Result.fColor := AParent.fColor;
  26418. {$IFDEF WIN_GDI}
  26419. Result.fBrush := Result.fBrush.Assign( AParent.fBrush );
  26420. if Result.fBrush <> nil then
  26421. begin
  26422. {$IFDEF USE_AUTOFREE4CONTROLS}
  26423. Result.Add2AutoFree( Result.fBrush );
  26424. {$ENDIF USE_AUTOFREE4CONTROLS}
  26425. Result.fBrush.fParentGDITool := AParent.fBrush;
  26426. Result.fBrush.fOnChange := Result.BrushChanged;
  26427. Result.BrushChanged( Result.fBrush );
  26428. end;
  26429. {$ENDIF WIN_GDI}
  26430. end;
  26431. Result.fGetClientArea := FixedClientArea;
  26432. end;
  26433. {$ENDIF GTK}
  26434. {$ENDIF _X_}
  26435. //===================== Form ========================//
  26436. {$IFDEF USE_CONSTRUCTORS}
  26437. //[function NewForm]
  26438. function NewForm( AParent: PControl; const Caption: String ): PControl;
  26439. begin
  26440. new( Result, CreateForm( AParent, Caption ) );
  26441. end;
  26442. //[END NewForm]
  26443. {$ELSE not_USE_CONSTRUCTORS}
  26444. //[FUNCTION NewForm]
  26445. {$IFDEF GDI}
  26446. {$IFDEF ASM_VERSION}
  26447. {$ELSE ASM_VERSION} //Pascal
  26448. function NewForm( AParent: PControl; const Caption: KOLString ): PControl;
  26449. begin
  26450. Result := _NewWindowed( AParent, 'Form', True );
  26451. {$ifdef wince}
  26452. Result.fStyle:=Result.fStyle and not WS_BORDER;
  26453. if AParent <> nil then
  26454. Result.fStyle:=Result.fStyle or WS_POPUP;
  26455. {$endif wince}
  26456. Result.fClsStyle := Result.fClsStyle or CS_DBLCLKS;
  26457. Result.AttachProc( WndProcForm );
  26458. Result.AttachProc( WndProcDoEraseBkgnd );
  26459. {$IFNDEF SMALLEST_CODE}
  26460. Result.fSizeGrip := TRUE;
  26461. {$ENDIF}
  26462. Result.Caption := Caption;
  26463. Result.fIsForm := TRUE;
  26464. end;
  26465. {$ENDIF ASM_VERSION}
  26466. {$ENDIF GDI}
  26467. {$IFDEF _X_}
  26468. {$IFDEF GTK}
  26469. function getFormCaption(F: PControl): KOLString;
  26470. begin
  26471. F.fCaption := gtk_window_get_title( GTK_WINDOW( F.fHandle ) );
  26472. Result := F.fCaption;
  26473. end;
  26474. procedure setFormCaption(F: PControl; const Value: KOLString);
  26475. begin
  26476. F.fCaption := Value;
  26477. gtk_window_set_title( GTK_WINDOW( F.fCaptionHandle ), PChar( String( Value ) ) );
  26478. end;
  26479. procedure DestroyForm( Widget: PGtkWidget; Sender: PControl ); cdecl;
  26480. var Quit: Boolean;
  26481. begin
  26482. Quit := Sender.IsMainWindow;
  26483. Sender.Free;
  26484. if Quit then
  26485. gtk_main_quit();
  26486. end;
  26487. function NewForm( AParent: PControl; const Caption: KOLString ): PControl;
  26488. {$IFDEF GTK}
  26489. var widget: PGtkWidget;
  26490. {$ENDIF GTK}
  26491. begin
  26492. if not GTK_initialized then
  26493. begin
  26494. GTK_initialized := TRUE;
  26495. gtk_init( @ argc, {@ argv} nil );
  26496. end;
  26497. {$IFDEF GDI}
  26498. Result := _NewWindowed( AParent, 'Form', True );
  26499. {$ELSE _X_}
  26500. {$IFDEF GTK}
  26501. widget := gtk_window_new( GTK_WINDOW_TOPLEVEL );
  26502. Result := _NewWindowed( AParent, 'Form', widget, FALSE );
  26503. {$ENDIF GTK}
  26504. {$ENDIF _X_}
  26505. Result.fGetCaption := getFormCaption;
  26506. Result.fSetCaption := setFormCaption;
  26507. Result.Caption := Caption;
  26508. Result.fIsForm := TRUE;
  26509. gtk_signal_connect( Pointer( Result.fHandle ), 'destroy',
  26510. @ DestroyForm, Result );
  26511. end;
  26512. {$ENDIF GTK}
  26513. {$ENDIF _X_}
  26514. //[END NewForm]
  26515. {$ENDIF USE_CONSTRUCTORS}
  26516. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  26517. //===================== Applet button ========================//
  26518. //[FUNCTION WndProcApp]
  26519. {$IFDEF ASM_VERSION}
  26520. function WndProcAppAsm(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  26521. asm
  26522. CMP word ptr [EDX].TMsg.message, WM_SETFOCUS
  26523. JNZ @@chk_CLOSE
  26524. MOV ECX, [EAX].TControl.FCurrentControl
  26525. JECXZ @@ret_false
  26526. XCHG EAX, ECX
  26527. PUSH EAX
  26528. CALL CallTControlCreateWindow
  26529. TEST AL, AL
  26530. POP EAX
  26531. JZ @@1
  26532. PUSH [EAX].TControl.fHandle
  26533. CALL SetFocus
  26534. @@1: MOV AL, 1
  26535. RET
  26536. @@chk_CLOSE:
  26537. CMP word ptr [EDX].TMsg.message, WM_SYSCOMMAND
  26538. JNZ @@ret_false
  26539. MOV EDX, dword ptr [EDX].TMsg.wParam
  26540. AND DX, $FFF0
  26541. CMP DX, SC_CLOSE
  26542. JNZ @@ret_false
  26543. PUSH ECX
  26544. MOV ECX, [EAX].TControl.fChildren
  26545. JECXZ @@ret_false1
  26546. XCHG EAX, ECX
  26547. MOV ECX, [EAX].TList.fCount
  26548. JECXZ @@ret_false1
  26549. MOV EAX, [EAX].TList.fItems
  26550. MOV ECX, dword ptr [EAX]
  26551. JECXZ @@ret_false1
  26552. XCHG EAX, ECX
  26553. PUSH EAX
  26554. CALL TControl.IsMainWindow
  26555. TEST EAX, EAX
  26556. POP EAX
  26557. JZ @@ret_false1
  26558. CALL TControl.Close
  26559. POP ECX
  26560. XOR EAX, EAX
  26561. MOV dword ptr [ECX], EAX
  26562. INC EAX
  26563. JMP @@exit
  26564. @@ret_false1:
  26565. POP ECX
  26566. @@ret_false:
  26567. XOR EAX, EAX
  26568. @@exit:
  26569. end;
  26570. {$ELSE ASM_VERSION} //Pascal
  26571. function WndProcAppPas(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  26572. begin
  26573. Result := False;
  26574. case Msg.message of
  26575. WM_SETFOCUS:
  26576. {$IFDEF NEW_MODAL}
  26577. if Self_.fModalForm <> nil then
  26578. SetFocus( Self_.fModalForm.fHandle )
  26579. else if ( Self_.FCurrentControl <> nil ) and not
  26580. ( Self_.fCurrentControl.IsForm xor Self_.fIsApplet ) then
  26581. {$ELSE not_NEW_MODAL}
  26582. if Self_.FCurrentControl <> nil then
  26583. {$ENDIF NEW_MODAL}
  26584. begin
  26585. if Self_.FCurrentControl.CreateWindow then
  26586. SetFocus( Self_.FCurrentControl.fHandle );
  26587. Result := True;
  26588. end;
  26589. WM_SYSCOMMAND:
  26590. CASE Msg.wParam and $FFF0 OF
  26591. SC_CLOSE:
  26592. if (Self_.fChildren <> nil) and (Self_.fChildren.fCount > 0) and
  26593. PControl( Self_.fChildren.fItems[ 0 ] ).IsMainWindow then
  26594. begin
  26595. PControl( Self_.fChildren.fItems[ 0 ] ).Close;
  26596. Rslt := 0;
  26597. Result := TRUE;
  26598. end;
  26599. END;
  26600. end;
  26601. end;
  26602. {$ENDIF ASM_VERSION}
  26603. //[END WndProcApp]
  26604. {$IFDEF USE_CONSTRUCTORS}
  26605. {$DEFINE CREATEAPPBUTTON_USED}
  26606. //[function NewApplet]
  26607. function NewApplet( const Caption: String ): PControl;
  26608. begin
  26609. new( Result, CreateApplet( Caption ) );
  26610. end;
  26611. //[END NewApplet]
  26612. {$ELSE not_USE_CONSTRUCTORS}
  26613. //[FUNCTION NewApplet]
  26614. {$IFDEF ASM_VERSION}
  26615. {$ELSE ASM_VERSION} //Pascal
  26616. //[procedure CreateAppButton]
  26617. {$ifdef win32}
  26618. procedure CreateAppButton( App: PControl );
  26619. var M: HMenu;
  26620. begin
  26621. M := GetSystemMenu( App.fHandle, False );
  26622. DeleteMenu( M, SC_MAXIMIZE, MF_BYCOMMAND );
  26623. DeleteMenu( M, SC_MOVE, MF_BYCOMMAND );
  26624. DeleteMenu( M, SC_SIZE, MF_BYCOMMAND );
  26625. EnableMenuItem( M, SC_RESTORE, MF_GRAYED or MF_BYCOMMAND );
  26626. end;
  26627. {$endif win32}
  26628. //[function NewApplet]
  26629. function NewApplet( const Caption: KOLString ): PControl;
  26630. begin
  26631. AppButtonUsed := True;
  26632. Result := _NewWindowed( nil, 'App', True );
  26633. Result.FIsApplet := TRUE;
  26634. {$ifdef wince}
  26635. Result.fStyle := WS_VISIBLE;
  26636. {$else}
  26637. Result.fStyle := DWORD(WS_VISIBLE or WS_SYSMENU or WS_POPUP or WS_MINIMIZEBOX or WS_CAPTION);
  26638. Result.fExStyle := WS_EX_APPWINDOW;
  26639. Result.FCreateWndExt := CreateAppButton;
  26640. {$endif wince}
  26641. {$IFDEF ASM_VERSION}
  26642. Result.AttachProc( WndProcAppAsm );
  26643. {$ELSE}
  26644. Result.AttachProc( WndProcAppPas );
  26645. {$ENDIF}
  26646. Result.Caption := Caption;
  26647. end;
  26648. {$ENDIF ASM_VERSION}
  26649. //[END NewApplet]
  26650. {$ENDIF USE_CONSTRUCTORS}
  26651. {$IFDEF CREATEAPPBUTTON_USED}
  26652. procedure CreateAppButton( App: PControl );
  26653. asm
  26654. {$IFDEF F_P}
  26655. MOV EAX, [App]
  26656. {$ENDIF F_P}
  26657. PUSH ESI
  26658. PUSH 0
  26659. PUSH [EAX].TControl.fHandle
  26660. CALL GetSystemMenu
  26661. MOV ESI, offset[DeleteMenu]
  26662. XCHG ECX, EAX
  26663. MOV EAX, SC_MAXIMIZE
  26664. CDQ
  26665. PUSH EDX
  26666. PUSH EAX
  26667. PUSH ECX
  26668. PUSH EDX
  26669. {$IFDEF PARANOIA} DB $2C, $20 {$ELSE} SUB AL, $20 {$ENDIF} // SC_MOVE
  26670. PUSH EAX
  26671. PUSH ECX
  26672. PUSH EDX
  26673. {$IFDEF PARANOIA} DB $2C, $10 {$ELSE} SUB AL, $10 {$ENDIF} // SC_SIZE
  26674. PUSH EAX
  26675. PUSH ECX
  26676. PUSH 1 // MF_GRAYED or MF_BYCOMMAND
  26677. MOV AX, SC_RESTORE
  26678. PUSH EAX
  26679. PUSH ECX
  26680. CALL EnableMenuItem
  26681. CALL ESI
  26682. CALL ESI
  26683. CALL ESI
  26684. POP ESI
  26685. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  26686. {$ENDIF CREATEAPPBUTTON_USED}
  26687. var CtlIdCount: WORD = $8000;
  26688. {-}
  26689. {$IFNDEF ASM_VERSION}
  26690. //{$DEFINE CREATEPARAMS2_USED}
  26691. {$ENDIF}
  26692. {$IFDEF USE_CONSTRUCTORS}
  26693. //{$DEFINE CREATEPARAMS2_USED}
  26694. {$ENDIF}
  26695. {+}
  26696. {$IFDEF CREATEPARAMS2_USED} // seems not needed more
  26697. //[procedure CreateParams2]
  26698. procedure CreateParams2( Self_: PControl; var Params: TCreateParams);
  26699. begin
  26700. Self_.CreateSubclass( Params, Self_.fControlClassName );
  26701. end;
  26702. {$ENDIF}
  26703. {$ENDIF WIN_GDI}
  26704. //[FUNCTION _NewControl]
  26705. {$IFDEF GDI}
  26706. {$IFDEF ASM_UNICODE}
  26707. {$ELSE ASM_VERSION} //Pascal
  26708. function _NewControl( AParent: PControl; ControlClassName: PKOLChar;
  26709. Style: DWORD; Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  26710. var Form: PControl;
  26711. begin
  26712. Result := _NewWindowed( AParent, ControlClassName, Ctl3D );
  26713. if Actions <> nil then
  26714. Result.fCommandActions := Actions^;
  26715. Result.fIsControl := True;
  26716. Result.fStyle := Style or WS_CLIPSIBLINGS or WS_CLIPCHILDREN;
  26717. Result.fVerticalAlign := vaTop;
  26718. Result.fVisible := (Style and WS_VISIBLE) <> 0;
  26719. Result.fTabstop := (Style and WS_TABSTOP) <> 0;
  26720. if (AParent <> nil) then
  26721. begin
  26722. with Result.fBoundsRect do
  26723. begin
  26724. Left := AParent.fMargin + AParent.fClientLeft;
  26725. Top := AParent.fMargin + AParent.fClientTop;
  26726. Right := Left + 64;
  26727. Bottom := Top + 64;
  26728. end;
  26729. Inc( AParent.ParentForm.fTabOrder );
  26730. Result.fTabOrder := AParent.ParentForm.fTabOrder;
  26731. Result.fCursor := AParent.fCursor;
  26732. end;
  26733. Result.fLookTabKeys := [ tkTab, tkLeftRight, tkUpDown, tkPageUpPageDn ];
  26734. {$ifdef win32}
  26735. if Result.fCtl3D then
  26736. begin
  26737. Result.fStyle := Result.fStyle and not WS_BORDER;
  26738. Result.fExStyle := Result.fExStyle or WS_EX_CLIENTEDGE;
  26739. end;
  26740. {$endif win32}
  26741. if (Style and WS_TABSTOP) <> 0 then
  26742. begin
  26743. Form := Result.ParentForm;
  26744. if Form <> nil then
  26745. if Form.FCurrentControl = nil then
  26746. Form.FCurrentControl := Result;
  26747. end;
  26748. Result.fMenu := CtlIdCount;
  26749. Inc( CtlIdCount );
  26750. Result.AttachProc( WndProcCtrl );
  26751. end;
  26752. {$ENDIF ASM_VERSION}
  26753. {$ENDIF GDI}
  26754. {$IFDEF _X_}
  26755. {$IFDEF GTK}
  26756. function getLabelCaption( L: PControl ): KOLString;
  26757. begin
  26758. L.fCaption := gtk_label_get_text( Pointer( L.fCaptionHandle ) );
  26759. Result := L.fCaption;
  26760. end;
  26761. procedure setLabelCaption( L: PControl; const Value: KOLString );
  26762. begin
  26763. L.fCaption := Value;
  26764. gtk_label_set_text( Pointer( L.fCaptionHandle ), PChar( String( Value ) ) );
  26765. end;
  26766. function _NewControl( AParent: PControl; ControlClassName: PChar;
  26767. Style: DWORD; Ctl3D: Boolean; widget: PGtkWidget; need_eventbox: Boolean ): PControl;
  26768. var Rect: TRect;
  26769. begin
  26770. Result := _NewWindowed( AParent, ControlClassName, widget, need_eventbox );
  26771. Result.fIsControl := True;
  26772. Result.fVerticalAlign := vaTop;
  26773. Result.{todo: remove f}fVisible := (Style and WS_VISIBLE) <> 0;
  26774. Result.fTabstop := (Style and WS_TABSTOP) <> 0;
  26775. if (AParent <> nil) then
  26776. begin
  26777. with Rect do
  26778. begin
  26779. Left := AParent.fMargin + AParent.fClientLeft;
  26780. Top := AParent.fMargin + AParent.fClientTop;
  26781. end;
  26782. Inc( AParent.ParentForm.fTabOrder );
  26783. Result.fTabOrder := AParent.ParentForm.fTabOrder;
  26784. {$IFDEF GDI}
  26785. Result.fCursor := AParent.fCursor;
  26786. {$ENDIF GDI}
  26787. //gtk_container_add( GTK_CONTAINER( AParent.fHandle ), Result.fHandle );
  26788. end;
  26789. {with Rect do
  26790. begin
  26791. Right := Left + 64;
  26792. Bottom := Top + 64;
  26793. end;
  26794. Result.fBoundsRect := Result.BoundsRect;
  26795. Result.BoundsRect := Rect;}
  26796. Result.fLookTabKeys := [ tkTab, tkLeftRight, tkUpDown, tkPageUpPageDn ];
  26797. {$IFDEF GDI}
  26798. if Result.fCtl3D then
  26799. begin
  26800. Result.fStyle := Result.fStyle and not WS_BORDER;
  26801. Result.fExStyle := Result.fExStyle or WS_EX_CLIENTEDGE;
  26802. end;
  26803. if (Style and WS_TABSTOP) <> 0 then
  26804. begin
  26805. Form := Result.ParentForm;
  26806. if Form <> nil then
  26807. if Form.FCurrentControl = nil then
  26808. Form.FCurrentControl := Result;
  26809. end;
  26810. Result.fMenu := CtlIdCount;
  26811. Inc( CtlIdCount );
  26812. Result.AttachProc( WndProcCtrl );
  26813. {$ENDIF GDI}
  26814. end;
  26815. {$ENDIF GTK}
  26816. {$ENDIF _X_}
  26817. //[END _NewControl]
  26818. {$IFDEF WIN_GDI}
  26819. //===================== Button ========================//
  26820. //[function TControl.SetButtonIcon]
  26821. function TControl.SetButtonIcon(aIcon: HIcon): PControl;
  26822. var PrevImg: THandle;
  26823. begin
  26824. Style := Style or BS_ICON;
  26825. fButtonIcon := aIcon;
  26826. PrevImg := Perform( BM_SETIMAGE, IMAGE_ICON, aIcon );
  26827. if PrevImg <> 0 then
  26828. DeleteObject( PrevImg );
  26829. Result := @ Self;
  26830. end;
  26831. //[function TControl.SetButtonBitmap]
  26832. function TControl.SetButtonBitmap(aBmp: HBitmap): PControl;
  26833. var PrevImg: THandle;
  26834. begin
  26835. Style := Style or BS_BITMAP;
  26836. PrevImg := Perform( BM_SETIMAGE, IMAGE_BITMAP, aBmp );
  26837. if PrevImg <> 0 then
  26838. DeleteObject( PrevImg );
  26839. Result := @ Self;
  26840. end;
  26841. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  26842. //[function WndProcBtnReturnClick]
  26843. function WndProcBtnReturnClick( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  26844. begin
  26845. Result := FALSE;
  26846. if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP) or
  26847. (Msg.message = WM_CHAR)) and (Msg.wParam = 13) then
  26848. Msg.wParam := 32;
  26849. end;
  26850. {$ENDIF}
  26851. {$IFNDEF BUTTON_DBLCLICK}
  26852. //[function WndProcBtnDblClkAsClk]
  26853. function WndProcBtnDblClkAsClk( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  26854. begin
  26855. Result := FALSE;
  26856. if Msg.message = WM_LBUTTONDBLCLK then
  26857. Msg.message := WM_LBUTTONDOWN;
  26858. end;
  26859. {$ENDIF}
  26860. {$ifdef wince}
  26861. function WndProcBtnFocus( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  26862. begin
  26863. Result := FALSE;
  26864. case Msg.message of
  26865. WM_SETFOCUS:
  26866. Sender.Style:=Sender.Style or BS_DEFPUSHBUTTON;
  26867. WM_KILLFOCUS:
  26868. Sender.Style:=Sender.Style and not BS_DEFPUSHBUTTON;
  26869. end;
  26870. end;
  26871. {$endif wince}
  26872. //[function AutoMinimizeApplet]
  26873. function AutoMinimizeApplet(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  26874. begin
  26875. if (msg.Message=WM_SYSCOMMAND) and ((msg.wParam and not 15)=SC_MINIMIZE) then begin
  26876. AppletMinimize;
  26877. Result := True;
  26878. end else
  26879. Result := False;
  26880. end;
  26881. {$IFDEF USE_CONSTRUCTORS}
  26882. //[function NewButton]
  26883. function NewButton( AParent: PControl; const Caption: KOLString ): PControl;
  26884. begin
  26885. new( Result, CreateButton( AParent, Caption ) );
  26886. end;
  26887. {$ELSE USE_CONSTRUCTORS}
  26888. {$IFDEF ASM_VERSION}
  26889. const ButtonClass: array[ 0..6 ] of KOLChar = ( 'B','U','T','T','O','N',#0 );
  26890. {$ENDIF ASM_VERSION}
  26891. //[FUNCTION NewButton]
  26892. {$IFDEF ASM_VERSION}
  26893. {$ELSE ASM_VERSION} //Pascal
  26894. function NewButton( AParent: PControl; const Caption: KOLString ): PControl;
  26895. begin
  26896. Result := _NewControl( AParent, 'BUTTON',
  26897. WS_VISIBLE or WS_CHILD or BS_NOTIFY or
  26898. BS_PUSHLIKE or WS_TABSTOP, False, @ButtonActions );
  26899. {$ifdef wince}
  26900. Result.fColor:=clBtnFace;
  26901. if Result.fBrush <> nil then
  26902. Result.fBrush.fData.Color:=Result.fColor;
  26903. {$endif wince}
  26904. {$IFDEF BUTTON_DBLCLICK}
  26905. Result.ClsStyle := Result.ClsStyle - CS_DBLCLKS;
  26906. {$ENDIF}
  26907. Result.fIgnoreDefault := TRUE;
  26908. //Result.fCtl3D := TRUE;
  26909. with Result.fBoundsRect do
  26910. Bottom := Top + 22;
  26911. Result.fTextAlign := taCenter;
  26912. Result.Caption := Caption;
  26913. Result.fIsButton := TRUE;
  26914. {$IFNDEF SMALLEST_CODE}
  26915. {$IFNDEF BUTTON_DBLCLICK}
  26916. Result.AttachProc( WndProcBtnDblClkAsClk );
  26917. {$ENDIF}
  26918. {$ENDIF}
  26919. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  26920. Result.AttachProc( WndProcBtnReturnClick );
  26921. {$ENDIF}
  26922. {$ifdef wince}
  26923. Result.AttachProc(WndProcBtnFocus);
  26924. {$endif wince}
  26925. {$IFDEF GRAPHCTL_XPSTYLES}
  26926. Result.fClassicTransparent := Result.fTransparent;
  26927. Attach_WM_THEMECHANGED(Result);
  26928. XP_Themes_For_BitBtn(Result);
  26929. {$ENDIF}
  26930. end;
  26931. {$ENDIF ASM_VERSION}
  26932. //[END NewButton]
  26933. {$ENDIF USE_CONSTRUCTORS}
  26934. {$ENDIF WIN_GDI}
  26935. {$IFDEF _X_}
  26936. {$IFDEF GTK}
  26937. const
  26938. HorAlignments: array[ TTextAlign ] of Single = ( {taLeft} 0, {taRight} 1, {taCenter} 0.5 );
  26939. VerAlignments: array[ TVerticalAlign ] of Single = ( {vaCenter} 0.5, {vaTop} 0, {vaBottom} 1 );
  26940. procedure ButtonSetTextAlign( Self_: PControl );
  26941. begin
  26942. gtk_button_set_alignment( GTK_BUTTON( Self_.fHandle ), HorAlignments[ Self_.fTextAlign ],
  26943. VerAlignments[ Self_.fVerticalAlign ] );
  26944. end;
  26945. function NewButton( AParent: PControl; const Caption: KOLString ): PControl;
  26946. begin
  26947. Result := _NewControl( AParent, 'BUTTON',
  26948. WS_VISIBLE or WS_CHILD or BS_NOTIFY or
  26949. BS_PUSHLIKE or WS_TABSTOP, False,
  26950. gtk_button_new{_with_label}( {PChar( String( Caption ) )} ), FALSE );
  26951. //Result.Height := 22;
  26952. gtk_container_set_border_width( GTK_CONTAINER( Result.fHandle ), 0 );
  26953. Result.fCaptionHandle := gtk_label_new( PChar( String( Caption ) ) );
  26954. gtk_container_add( GTK_CONTAINER( Result.fHandle ), Result.fCaptionHandle );
  26955. //gtk_container_set_border_width( GTK_CONTAINER( Result.fCaptionHandle ), 0 );
  26956. gtk_widget_show( Result.fCaptionHandle );
  26957. Result.fGetCaption := getLabelCaption;
  26958. Result.fSetCaption := setLabelCaption;
  26959. //Result.fIgnoreDefault := TRUE;
  26960. //Result.fCtl3D := TRUE;
  26961. //with Result.fBoundsRect do
  26962. // Bottom := Top + 22;
  26963. Result.fTextAlign := taCenter;
  26964. Result.fCaption := Caption;
  26965. Result.fIsButton := TRUE;
  26966. Result.fSetTextAlign := ButtonSetTextAlign;
  26967. end;
  26968. {$ENDIF GTK}
  26969. {$ENDIF _X_}
  26970. {$IFDEF WIN_GDI}
  26971. //----------------- BitBtn -----------------------
  26972. //[FUNCTION WndProc_DrawItem]
  26973. {$IFDEF ASM_VERSION}
  26974. {$ELSE ASM_VERSION} //Pascal
  26975. function WndProc_DrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  26976. : Boolean;
  26977. var DI: PDrawItemStruct;
  26978. Control: PControl;
  26979. begin
  26980. Result := FALSE;
  26981. if Msg.message = WM_DRAWITEM then
  26982. begin
  26983. DI := Pointer( Msg.lParam );
  26984. {$IFDEF USE_PROP}
  26985. Control := Pointer( GetProp( DI.hwndItem, ID_SELF ) );
  26986. {$ELSE}
  26987. Control := Pointer( GetWindowLong( DI.hwndItem, GWL_USERDATA ) );
  26988. {$ENDIF}
  26989. if Control <> nil then
  26990. begin
  26991. Rslt := Control.Perform( CN_DRAWITEM, Msg.wParam, Msg.lParam );
  26992. Result := TRUE;
  26993. end;
  26994. end;
  26995. end;
  26996. {$ENDIF ASM_VERSION}
  26997. //[END WndProc_DrawItem]
  26998. //[function ExcludeAmpersands]
  26999. function ExcludeAmpersands( Self_: PControl; const S: String ): String;
  27000. var I: Integer;
  27001. begin
  27002. Result := S;
  27003. if not Self_.FBitBtnDrawMnemonic then Exit;
  27004. for I := Length( Result ) downto 1 do
  27005. begin
  27006. if Result[ I ] = '&' then
  27007. Delete( Result, I, 1 );
  27008. end;
  27009. end;
  27010. //[procedure BitBtnExtDraw]
  27011. procedure BitBtnExtDraw( Self_: PControl; DC: HDC; X, Y: Integer; const R: TRect;
  27012. const CapText, CapTxtOrig: KOLString; Color: TColor );
  27013. var I, J, W, H: Integer;
  27014. Sz: TSize;
  27015. Pen, OldPen: HPen;
  27016. begin
  27017. if not Self_.FBitBtnDrawMnemonic then Exit;
  27018. J := 0;
  27019. for I := 1 to Length( CapTxtOrig ) do
  27020. begin
  27021. if CapTxtOrig[ I ] <> '&' then
  27022. Inc( J )
  27023. else
  27024. begin
  27025. GetTextExtentPoint32( DC, PKOLChar( CapText ), J, Sz );
  27026. W := Sz.cx;
  27027. Windows.GetTextExtentPoint32( DC, '_', 1, Sz );
  27028. H := Sz.cy - 1;
  27029. Windows.GetTextExtentPoint32( DC, @ CapTxtOrig[ I + 1 ], 1, Sz );
  27030. Windows.MoveToEx( DC, X + W, Y + H, nil );
  27031. Pen := CreatePen( PS_SOLID, 0, Color2RGB( Color ) );
  27032. OldPen := SelectObject( DC, Pen );
  27033. Windows.LineTo( DC, X + W + Sz.cx, Y + H );
  27034. SelectObject( DC, OldPen );
  27035. DeleteObject( Pen );
  27036. end;
  27037. end;
  27038. end;
  27039. //[procedure TControl.SetBitBtnDrawMnemonic]
  27040. procedure TControl.SetBitBtnDrawMnemonic(const Value: Boolean);
  27041. begin
  27042. FBitBtnDrawMnemonic := Value;
  27043. FBitBtnGetCaption := ExcludeAmpersands;
  27044. FBitBtnExtDraw := BitBtnExtDraw;
  27045. Invalidate;
  27046. end;
  27047. //[function TControl.GetBitBtnImgIdx]
  27048. function TControl.GetBitBtnImgIdx: Integer;
  27049. begin
  27050. Result := LoWord( fGlyphCount );
  27051. end;
  27052. //[procedure TControl.SetBitBtnImgIdx]
  27053. procedure TControl.SetBitBtnImgIdx(const Value: Integer);
  27054. begin
  27055. if not( bboImageList in fBitBtnOptions ) then Exit;
  27056. fGlyphCount := HiWord( fGlyphCount ) or (Value and $FFFF);
  27057. Invalidate;
  27058. end;
  27059. //[function TControl.GetBitBtnImageList]
  27060. function TControl.GetBitBtnImageList: THandle;
  27061. begin
  27062. Result := 0;
  27063. if bboImageList in fBitBtnOptions then
  27064. Result := fGlyphBitmap;
  27065. end;
  27066. //[procedure TControl.SetBitBtnImageList]
  27067. procedure TControl.SetBitBtnImageList(const Value: THandle);
  27068. begin
  27069. fGlyphBitmap := Value;
  27070. if Value <> 0 then
  27071. begin
  27072. fBitBtnOptions := fBitBtnOptions + [ bboImageList ];
  27073. ImageList_GetIconSize( Value, fGlyphWidth, fGlyphHeight );
  27074. end
  27075. else
  27076. fBitBtnOptions := fBitBtnOptions - [ bboImageList ];
  27077. Invalidate;
  27078. end;
  27079. //[FUNCTION WndProcBitBtn]
  27080. {$IFDEF ASM_noVERSION} // remove &-s from view //+ TextShift & if Y < 0 then Y := 0; // + glyph + TextShift if not glyphOver
  27081. // timer when RepeatInterval set
  27082. function WndProcBitBtn( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  27083. const szBitmapInfo = sizeof(TBitmapInfo);
  27084. asm
  27085. CMP word ptr [EDX].TMsg.message, WM_LBUTTONDBLCLK
  27086. JNZ @@noWM_LBUTTONDBLCLK
  27087. PUSH ECX
  27088. PUSH [EDX].TMsg.wParam
  27089. PUSH [EDX].TMsg.lParam
  27090. PUSH WM_LBUTTONDOWN
  27091. PUSH EAX
  27092. CALL TControl.Perform
  27093. POP ECX
  27094. MOV [ECX], EAX
  27095. MOV AL, 1
  27096. RET
  27097. @@noWM_LBUTTONDBLCLK:
  27098. PUSH EBX
  27099. CMP [EDX].TMsg.message, CN_DRAWITEM
  27100. JNZ @@noCN_DRAWITEM
  27101. PUSH EDI
  27102. PUSH ESI
  27103. XCHG EDI, EAX // EDI = @Self
  27104. MOV dword ptr [ECX], 1
  27105. MOV ESI, [EDX].TMsg.lParam // ESI = DIS
  27106. XOR EBX, EBX // G = 0
  27107. MOV EAX, [ESI].TDrawItemStruct.itemState
  27108. TEST byte ptr [EDI].TControl.fBitBtnOptions, 8 //1 shl Ord(bboFixed)
  27109. JNZ @@fixed_in_options
  27110. {$IFDEF PARANOIA} DB $A8, ODS_SELECTED {$ELSE} TEST AL, ODS_SELECTED {$ENDIF}
  27111. JZ @@not1
  27112. JMP @@1
  27113. @@fixed_in_options:
  27114. TEST byte ptr [EDI].TControl.fChecked, 1
  27115. JZ @@not1
  27116. @@1: INC EBX
  27117. @@not1:
  27118. {$IFDEF PARANOIA} DB $A8, ODS_DISABLED {$ELSE} TEST AL, ODS_DISABLED {$ENDIF}
  27119. JZ @@not2
  27120. MOV BL, 2
  27121. @@not2: TEST EBX, EBX
  27122. JNZ @@not3
  27123. {$IFDEF PARANOIA} DB $A8, ODS_FOCUS {$ELSE} TEST AL, ODS_FOCUS {$ENDIF}
  27124. JZ @@not3
  27125. MOV BL, 3
  27126. @@not3: CMP [EDI].TControl.fMouseInControl, BH
  27127. JZ @@not4
  27128. TEST EBX, EBX
  27129. JZ @@4
  27130. CMP BL, 3
  27131. JNZ @@not4
  27132. @@4: MOV BL, 4
  27133. @@not4: MOV ECX, [EDI].TControl.fOnBitBtnDraw.TMethod.Code
  27134. TEST ECX, ECX
  27135. JZ @@noOnBitBtnDraw
  27136. //JECXZ @@noOnBitBtnDraw
  27137. MOV EAX, [EDI].TControl.fCanvas
  27138. PUSH EAX
  27139. TEST EAX, EAX
  27140. JZ @@noCanvas
  27141. MOV EDX, [ESI].TDrawItemStruct.hDC
  27142. CALL TCanvas.SetHandle
  27143. @@noCanvas:
  27144. MOV EAX, [EDI].TControl.fOnBitBtnDraw.TMethod.Data
  27145. MOV EDX, EDI
  27146. PUSH EBX
  27147. XCHG ECX, EBX
  27148. CALL EBX
  27149. POP EBX
  27150. POP ECX // Canvas
  27151. PUSH EAX
  27152. JECXZ @@noCanvas2
  27153. XCHG EAX, ECX
  27154. XOR EDX, EDX
  27155. CALL TCanvas.SetHandle
  27156. @@noCanvas2:
  27157. POP EAX
  27158. TEST AL, AL
  27159. JNZ @@exit_draw
  27160. @@noOnBitBtnDraw:
  27161. TEST byte ptr [EDI].TControl.fBitBtnOptions, 2 //1 shl Ord(bboNoBorder)
  27162. JNZ @@noborder
  27163. TEST byte ptr [ESI].TDrawItemStruct.itemState, ODS_FOCUS
  27164. JZ @@noDefaultBorder
  27165. PUSH {BLACK_BRUSH} DKGRAY_BRUSH
  27166. CALL GetStockObject
  27167. LEA EDX, [ESI].TDrawItemStruct.rcItem
  27168. OR ECX, -1
  27169. PUSH ECX
  27170. PUSH ECX
  27171. PUSH EDX
  27172. PUSH EAX
  27173. PUSH EDX
  27174. PUSH [ESI].TDrawItemStruct.hDC
  27175. CALL Windows.FrameRect
  27176. CALL InflateRect
  27177. XOR ECX, ECX
  27178. JMP @@noFlat
  27179. @@noDefaultBorder:
  27180. MOVZX ECX, [EDI].TControl.fFlat
  27181. JECXZ @@noFlat
  27182. AND CL, [EDI].TControl.fMouseInControl
  27183. JZ @@noborder
  27184. @@noFlat:
  27185. TEST byte ptr [ESI].TDrawItemStruct.itemState, ODS_SELECTED
  27186. MOV CL, {BDR_SUNKENOUTER or} BDR_SUNKENINNER
  27187. JNZ @@border_sunken
  27188. MOV CL, {BDR_RAISEDOUTER or} BDR_RAISEDINNER
  27189. @@border_sunken:
  27190. LEA EDX, [ESI].TDrawItemStruct.rcItem
  27191. OR EAX, -1
  27192. PUSH EAX
  27193. PUSH EAX
  27194. PUSH EDX
  27195. PUSH BF_ADJUST or BF_RECT
  27196. PUSH ECX
  27197. PUSH EDX
  27198. PUSH [ESI].TDrawItemStruct.hDC
  27199. CALL DrawEdge
  27200. CALL InflateRect
  27201. @@noborder:
  27202. PUSH [ESI].TDrawItemStruct.rcItem.Bottom
  27203. PUSH [ESI].TDrawItemStruct.rcItem.Right
  27204. PUSH [ESI].TDrawItemStruct.rcItem.Top
  27205. PUSH [ESI].TDrawItemStruct.rcItem.Left
  27206. MOV EAX, [EDI].TControl.fGlyphWidth
  27207. MOV EDX, [EDI].TControl.fGlyphHeight
  27208. TEST EAX, EAX
  27209. JLE @@noglyph
  27210. TEST EDX, EDX
  27211. JLE @@noglyph
  27212. PUSH EBP
  27213. MOV EBP, ESP
  27214. PUSH EDX // ImgH -> [EBP-4]
  27215. PUSH EAX // ImgW -> [EBP-8]
  27216. PUSH EDX // OutH -> [EBP-12]
  27217. PUSH EAX // OutW -> [EBP-16]
  27218. MOV EAX, [ESI].TDrawItemStruct.rcItem.Left // X = DIS.rcItem.Left
  27219. MOV EDX, [ESI].TDrawItemStruct.rcItem.Top // Y = DIS.rcItem.Top
  27220. MOV ECX, [ESI].TDrawItemStruct.rcItem.Bottom
  27221. SUB ECX, EDX
  27222. PUSH ECX // H -> [EBP-20]
  27223. MOV ECX, [ESI].TDrawItemStruct.rcItem.Right
  27224. SUB ECX, EAX
  27225. PUSH ECX // W -> [EBP-24]
  27226. MOVZX ECX, [EDI].TControl.fGlyphLayout
  27227. PUSH EBX
  27228. INC ECX
  27229. LOOP @@noGlyphLeft
  27230. MOV EBX, EAX // X
  27231. ADD EBX, [EBP-16] // +OutW
  27232. MOV [EBP+4].TRect.Left, EBX // TxRect.Left = X+OutW
  27233. JMP @@centerY
  27234. @@noGlyphLeft:
  27235. LOOP @@noGlyphTop
  27236. MOV EBX, EDX // Y
  27237. ADD EBX, [EBP-12] // +OutH
  27238. MOV [EBP+4].TRect.Top, EBX // TxRect.Top = Y+OutH
  27239. LOOP @@centerX // always JMP, ECX := -1
  27240. @@noGlyphTop:
  27241. LOOP @@noGlyphRight
  27242. MOV EAX, [ESI].TDrawItemStruct.rcItem.Right
  27243. SUB EAX, [EBP-16] // -OutW -> X
  27244. MOV [EBP+4].TRect.Right, EAX
  27245. @@centerY:
  27246. MOV EBX, [EBP-20] // H
  27247. SUB EBX, [EBP-12] // -OutH
  27248. JLE @@noGlyphRight
  27249. SAR EBX, 1
  27250. ADD EDX, EBX // Y = Y + (H-OutH)/2
  27251. @@noGlyphRight:
  27252. LOOP @@noGlyphBottom
  27253. MOV EDX, [ESI].TDrawItemStruct.rcItem.Bottom
  27254. SUB EDX, [EBP-12] // -OutH -> Y
  27255. MOV [EBP+4].TRect.Bottom, EDX
  27256. LOOP @@centerX // always JMP, ECX := -1
  27257. @@noGlyphBottom:
  27258. LOOP @@noGlyphOver
  27259. @@centerX:
  27260. MOV EBX, [EBP-24] // W
  27261. SUB EBX, [EBP-16] // -OutW
  27262. SHR EBX, 1 // /2
  27263. ADD EAX, EBX // +EAX, X = X + (W-OutW)/2
  27264. JECXZ @@centerY
  27265. @@noGlyphOver:
  27266. MOV ECX, [ESI].TDrawItemStruct.rcItem.Left
  27267. CMP EAX, ECX
  27268. JGE @@ok1
  27269. XCHG EAX, ECX
  27270. @@ok1: CMP EDX, [ESI].TDrawItemStruct.rcItem.Top
  27271. {$IFDEF USE_CMOV}
  27272. CMOVL EDX, [ESI].TDrawItemStruct.rcItem.Top
  27273. {$ELSE}
  27274. JGE @@ok2
  27275. MOV EDX, [ESI].TDrawItemStruct.rcItem.Top
  27276. @@ok2: {$ENDIF}
  27277. MOV ECX, [ESI].TDrawItemStruct.rcItem.Right
  27278. SUB ECX, EAX
  27279. CMP [EBP-16], ECX
  27280. JLE @@ok3
  27281. MOV [EBP-16], ECX // OutW := rcItem.Right - X;
  27282. @@ok3: MOV ECX, [ESI].TDrawItemStruct.rcItem.Bottom
  27283. SUB ECX, EDX
  27284. CMP ECX, [EBP-12]
  27285. JGE @@ok4
  27286. MOV [EBP-12], ECX // OutH := rcItem.Bottom - Y;
  27287. @@ok4:
  27288. POP EBX // EBX = G
  27289. TEST byte ptr [EDI].TControl.fBitBtnOptions, 1 //1 shl Ord(bboImageList)
  27290. JZ @@draw_bitmap
  27291. MOVZX ECX, word ptr [EDI].TControl.fGlyphCount
  27292. CMP word ptr [EDI].TControl.fGlyphCount + 2, BX
  27293. JLE @@no_add_glyphIdx
  27294. ADD ECX, EBX
  27295. @@no_add_glyphIdx:
  27296. XOR EBX, EBX
  27297. PUSH ILD_TRANSPARENT // Flags = 1 (ILD_TRANSPARENT)
  27298. PUSH EBX // Blend = 0
  27299. PUSH -1 // Bk = CLR_NONE
  27300. PUSH EBX // 0
  27301. PUSH EBX // 0
  27302. PUSH EDX
  27303. PUSH EAX
  27304. PUSH [ESI].TDrawItemStruct.hDC
  27305. PUSH ECX
  27306. PUSH [EDI].TControl.fGlyphBitmap
  27307. CMP [EDI].TControl.fTransparent, BL
  27308. JNZ @@imgl_transp
  27309. MOV EAX, [EDI].TControl.fColor
  27310. CALL Color2RGB
  27311. MOV [ESP+32], EAX // Bk = Color2RGB(fColor)
  27312. MOV [ESP+40], EBX // Flags = 0
  27313. @@imgl_transp:
  27314. INC EBX
  27315. CMP word ptr [EDI].TControl.fGlyphCount + 2, BX
  27316. JNZ @@draw_imagelist
  27317. DEC byte ptr [ESP+36+3] // $FF, CLR_DEFAULT = $FF000000
  27318. TEST byte ptr [ESI].TDrawItemStruct.itemState, ODS_FOCUS
  27319. JZ @@draw_imagelist
  27320. OR byte ptr [ESP+40], ILD_BLEND25 // Flags != 2
  27321. @@draw_imagelist:
  27322. CALL ImageList_DrawEx
  27323. JMP @@glyph_drawn
  27324. @@draw_bitmap:
  27325. PUSH EAX // PlaceHold for DC
  27326. PUSH EAX // PlaceHold for OldBmp
  27327. PUSH SRCCOPY
  27328. PUSH dword ptr [EBP-4] // ImgH
  27329. PUSH dword ptr [EBP-8] // ImgW
  27330. PUSH 0
  27331. PUSH EAX // PlaceHold for I
  27332. PUSH EAX // PlaceHold for DC
  27333. PUSH dword ptr [EBP-12] // OutH
  27334. PUSH dword ptr [EBP-16] // OutW
  27335. PUSH EDX // Y
  27336. PUSH EAX // X
  27337. PUSH [ESI].TDrawItemStruct.hDC
  27338. PUSH 0
  27339. CALL CreateCompatibleDC
  27340. MOV [ESP+48], EAX // save DC
  27341. MOV [ESP+20], EAX // place DC
  27342. PUSH [EDI].TControl.fGlyphBitmap
  27343. PUSH EAX
  27344. CALL SelectObject
  27345. MOV [ESP+44], EAX // save OldBitmap
  27346. XOR EAX, EAX
  27347. CMP [EDI].TControl.fGlyphCount, EBX
  27348. JLE @@no_incGlyIdx
  27349. MOV EAX, [EBP-8] // ImgW
  27350. IMUL EBX
  27351. @@no_incGlyIdx:
  27352. MOV [ESP+24], EAX // place I
  27353. CALL StretchBlt
  27354. CALL FinishDC
  27355. @@glyph_drawn:
  27356. MOV ESP, EBP
  27357. POP EBP
  27358. @@noglyph:
  27359. TEST byte ptr[EDI].TControl.fBitBtnOptions, 4 //1 shl Ord(bboNoCaption)
  27360. JNZ @@noCaption
  27361. POP EAX
  27362. PUSH EAX
  27363. MOV EDX, [ESP].TRect.Right
  27364. CMP EDX, EAX
  27365. JLE @@noCaption
  27366. MOV EDX, [ESP].TRect.Bottom
  27367. CMP EDX, [ESP].TRect.Top
  27368. JLE @@noCaption
  27369. XOR EBX, EBX
  27370. PUSH EBX // > CapText
  27371. MOV EDX, ESP
  27372. MOV EAX, EDI
  27373. CALL TControl.GetCaption
  27374. PUSH EBX // > Bk
  27375. PUSH EBX // > Blend
  27376. CMP [EDI].TControl.fTransparent, BL
  27377. MOV BL, ETO_CLIPPED
  27378. JNZ @@drwTxTransparent
  27379. CMP [EDI].TControl.fGlyphLayout, glyphOver
  27380. JNZ @@drwTxOpaque
  27381. @@drwTxTransparent:
  27382. PUSH TRANSPARENT
  27383. PUSH [ESI].TDrawItemStruct.hDC
  27384. CALL SetBkMode
  27385. MOV [ESP+4], EAX // Bk := SetBkMode( DIS.hDC, TRANSPARENT )
  27386. JMP @@drwTx1
  27387. @@drwTxOpaque:
  27388. MOV BL, ETO_CLIPPED or ETO_OPAQUE
  27389. MOV EAX, [EDI].TControl.fColor
  27390. CALL Color2RGB
  27391. PUSH EAX
  27392. PUSH [ESI].TDrawItemStruct.hDC
  27393. CALL SetBkColor
  27394. POP ECX
  27395. PUSH EAX // Blend := SetBkColor(DIS.hDC,fColor)
  27396. @@drwTx1:
  27397. PUSH 0 // > OldFont
  27398. PUSH 0 // > OldTextColor
  27399. PUSH 0 // push <nil>
  27400. MOV EDX, [ESP+20] // CapText
  27401. CALL EDX2PChar
  27402. PUSH dword ptr [EDX-4] // push Length(CapText)
  27403. PUSH EDX // push PChar(CapText)
  27404. LEA EAX, [ESP+32]
  27405. PUSH EAX // push @TxRect
  27406. PUSH EBX // push Flags
  27407. MOV EBX, [ESI].TDrawItemStruct.hDC
  27408. MOV ECX, [EDI].TControl.fFont
  27409. JECXZ @@drwTx_noFont
  27410. XCHG EAX, ECX
  27411. CALL TGraphicTool.GetHandle
  27412. PUSH EAX
  27413. PUSH EBX
  27414. CALL SelectObject
  27415. MOV [ESP+24], EAX // OldFont := SelectObject...
  27416. @@drwTx_noFont:
  27417. MOV EAX, [EDI].TControl.fTextColor
  27418. CALL Color2RGB
  27419. PUSH EAX
  27420. PUSH EBX
  27421. CALL SetTextColor
  27422. MOV [ESP+20], EAX // OldTextColor := SetTextColor...
  27423. PUSH EAX
  27424. PUSH EAX
  27425. PUSH ESP
  27426. MOV ECX, [ESP+48] // ECX = CapText
  27427. XOR EAX, EAX
  27428. JECXZ @@drwTx0
  27429. MOV EAX, [ECX-4] // EAX = Length(CapText)
  27430. @@drwTx0:
  27431. PUSH EAX
  27432. PUSH ECX
  27433. PUSH EBX
  27434. CALL GetTextExtentPoint32
  27435. POP ECX // ECX = TextSz.cx
  27436. POP EDX // EDX = TextSz.cy
  27437. MOV EAX, [ESP+40].TRect.Bottom
  27438. SUB EAX, [ESP+40].TRect.Top
  27439. SUB EAX, EDX
  27440. JGE @@yOk
  27441. XOR EAX, EAX
  27442. @@yOk: SHR EAX, 1
  27443. ADD EAX, [ESP+40].TRect.Top
  27444. PUSH EAX // push Y
  27445. MOV EDX, [ESP+44].TRect.Right
  27446. MOV EAX, [ESP+44].TRect.Left // EAX = TxRect.Left
  27447. SUB EDX, EAX // EDX = W
  27448. PUSH EAX
  27449. CMP [EDI].TControl.fTextAlign, taRight
  27450. JL @@chk_X
  27451. JE @@alignR
  27452. SUB ECX, EDX
  27453. SAR ECX, 1
  27454. JMP @@alignC
  27455. @@alignR:
  27456. ADD EAX, EDX
  27457. @@alignC:
  27458. SUB EAX, ECX
  27459. @@chk_X:POP EDX
  27460. CMP EAX, EDX
  27461. JGE @@xOk
  27462. XCHG EAX, EDX
  27463. @@xOk: PUSH EAX // push X
  27464. PUSH EBX // push hDC
  27465. CALL ExtTextOut
  27466. PUSH EBX
  27467. CALL SetTextColor
  27468. POP ECX
  27469. JECXZ @@noRestoreFont
  27470. PUSH ECX
  27471. PUSH EBX
  27472. CALL SelectObject
  27473. @@noRestoreFont:
  27474. POP ECX // Blend
  27475. JECXZ @@restoreBk
  27476. PUSH ECX
  27477. PUSH EBX
  27478. CALL SetBkColor
  27479. POP ECX
  27480. JMP @@delCaption
  27481. @@restoreBk:
  27482. PUSH EBX
  27483. CALL SetBkMode
  27484. @@delCaption:
  27485. CALL RemoveStr
  27486. @@noCaption:
  27487. ADD ESP, 16
  27488. @@exit_draw:
  27489. POP ESI
  27490. POP EDI
  27491. POP EBX
  27492. MOV AL, 1
  27493. RET
  27494. @@noCN_DRAWITEM:
  27495. CMP word ptr [EDX].TMsg.message, WM_LBUTTONDOWN
  27496. JZ @@doDown
  27497. CMP word ptr [EDX].TMsg.message, WM_KEYDOWN
  27498. JNZ @@noWM_LBUTTONDOWN
  27499. CMP [EDX].TMsg.wParam, 32
  27500. JNZ @@noWM_LBUTTONDOWN
  27501. @@doDown:
  27502. PUSH EDX
  27503. XCHG EBX, EAX
  27504. CALL @@fixed_proc
  27505. MOV ECX, [EBX].TControl.fRepeatInterval
  27506. JECXZ @@exit_LBUTTONDOWN
  27507. POP EDX
  27508. PUSH EDX
  27509. CMP word ptr [EDX].TMsg.message, WM_KEYDOWN
  27510. JZ @@not_SetTimer
  27511. PUSH 0
  27512. PUSH [EBX].TControl.fRepeatInterval
  27513. PUSH 1
  27514. PUSH [EBX].TControl.fHandle
  27515. CALL SetTimer
  27516. @@exit_LBUTTONDOWN:
  27517. @@not_SetTimer:
  27518. POP EDX
  27519. JMP @@invalidate
  27520. @@noWM_LBUTTONDOWN:
  27521. CMP word ptr [EDX].TMsg.message, WM_TIMER
  27522. JNZ @@noWM_TIMER
  27523. XCHG EBX, EAX
  27524. PUSH 0
  27525. PUSH 0
  27526. PUSH BM_GETSTATE
  27527. PUSH EBX
  27528. CALL TControl.Perform
  27529. {$IFDEF PARANOIA} DB $A8, 4 {$ELSE} TEST AL, BST_PUSHED {$ENDIF}
  27530. JNZ @@pushed
  27531. PUSH 1
  27532. PUSH [EBX].TControl.fHandle
  27533. CALL KillTimer
  27534. CALL ReleaseCapture
  27535. JMP @@noWM_TIMER
  27536. @@fixed_proc:
  27537. TEST byte ptr [EBX].TControl.fBitBtnOptions, 8 // bboFixed
  27538. JZ @@not_fixed
  27539. XOR [EBX].TControl.fChecked, 1
  27540. MOV ECX, [EBX].TControl.fOnChange.TMethod.Code
  27541. JECXZ @@not_fixed
  27542. MOV EAX, [EBX].TControl.fOnChange.TMethod.Data
  27543. MOV EDX, EBX
  27544. JMP ECX
  27545. @@pushed:
  27546. CALL @@fixed_proc
  27547. MOV EAX, EBX
  27548. CALL TControl.DoClick
  27549. @@invalidate:
  27550. XCHG EAX, EBX
  27551. CALL TControl.Invalidate
  27552. @@noWM_TIMER:
  27553. XOR EAX, EAX
  27554. POP EBX
  27555. @@not_fixed:
  27556. end;
  27557. {$ELSE ASM_VERSION} //Pascal
  27558. function WndProcBitBtn( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  27559. var DIS: PDrawItemStruct;
  27560. IsDown, IsDefault, IsDisabled: Boolean;
  27561. Flags: Integer;
  27562. X, Y, W, H, ImgW, ImgH, OutW, OutH, I, G, Bk, Blend: Integer;
  27563. TxRect, FocusRect: TRect;
  27564. OldFont: HFont;
  27565. OldTextColor: TColor;
  27566. CapText, CapTxtOrig: KOLString;
  27567. TextSz: TSize;
  27568. DC: HDC;
  27569. OldBmp: HBitmap;
  27570. Handled: Boolean;
  27571. begin
  27572. Result := False;
  27573. if (Msg.message = WM_LBUTTONDBLCLK) then
  27574. begin
  27575. Rslt := Self_.Perform( WM_LBUTTONDOWN, Msg.wParam, Msg.lParam );
  27576. Result := True;
  27577. Exit;
  27578. end;
  27579. if (Msg.message = CN_DRAWITEM) then
  27580. begin
  27581. Result := True;
  27582. Rslt := 1;
  27583. DIS := Pointer( Msg.lParam );
  27584. IsDown := (DIS.itemState and ODS_SELECTED <> 0) or Self_.fChecked;
  27585. IsDefault := DIS.itemState and ODS_FOCUS <> 0;
  27586. IsDisabled := DIS.itemState and ODS_DISABLED <> 0;
  27587. G := 0;
  27588. if IsDown then G := {$IFDEF BITBTN_DISABLEDGLYPH2} 1 {$ELSE} 2 {$ENDIF};
  27589. if IsDisabled then G := {$IFDEF BITBTN_DISABLEDGLYPH2} 2 {$ELSE} 1 {$ENDIF};
  27590. if (G = 0) and IsDefault then G := 3;
  27591. if ((G = 0) or (G = 3)) and Self_.MouseInControl then G := 4;
  27592. if Assigned( Self_.fOnBitBtnDraw ) then
  27593. begin
  27594. if Assigned( Self_.fCanvas ) then
  27595. Self_.fCanvas.SetHandle( DIS.hDC );
  27596. Handled := Self_.fOnBitBtnDraw( Self_, G );
  27597. if Assigned( Self_.fCanvas ) then
  27598. Self_.fCanvas.SetHandle( 0 );
  27599. if Handled then Exit;
  27600. end;
  27601. if not ( bboNoBorder in Self_.fBitBtnOptions ) then
  27602. begin
  27603. if IsDefault and not( bboFocusRect in Self_.fBitBtnOptions ) then
  27604. begin
  27605. {$ifdef wince}
  27606. CeFrameRect( DIS.hDC, DIS.rcItem, clGray );
  27607. {$else}
  27608. Windows.FrameRect( DIS.hDC, DIS.rcItem, GetStockObject( {BLACK_BRUSH} DKGRAY_BRUSH ) );
  27609. {$endif wince}
  27610. InflateRect( DIS.rcItem, -1, -1 );
  27611. end;
  27612. if Self_.fFlat then
  27613. begin
  27614. if IsDown then
  27615. Flags := BDR_RAISEDINNER
  27616. else
  27617. Flags := 0; //EDGE_ETCHED;
  27618. DrawEdge( DIS.hDC, DIS.rcItem, Flags, BF_FLAT or BF_RECT );
  27619. //InflateRect( DIS.rcItem, -1, -1 );
  27620. end;
  27621. if not Self_.fFlat or Self_.fMouseInControl or IsDefault then
  27622. begin
  27623. if IsDown then
  27624. Flags := BDR_SUNKENOUTER or BDR_SUNKENINNER
  27625. else
  27626. Flags := BDR_RAISEDOUTER or BDR_RAISEDINNER;
  27627. DrawEdge( DIS.hDC, DIS.rcItem, Flags, BF_ADJUST or BF_RECT );
  27628. InflateRect( DIS.rcItem, -1, -1 );
  27629. end;
  27630. end;
  27631. TxRect := DIS.rcItem;
  27632. if Self_.fGlyphBitmap <> 0 then
  27633. begin
  27634. ImgW := Self_.fGlyphWidth;
  27635. ImgH := Self_.fGlyphHeight;
  27636. if (ImgW > 0) and (ImgH > 0) then
  27637. begin
  27638. OutW := ImgW;
  27639. OutH := ImgH;
  27640. W := DIS.rcItem.Right - DIS.rcItem.Left;
  27641. H := DIS.rcItem.Bottom - DIS.rcItem.Top;
  27642. X := DIS.rcItem.Left;
  27643. Y := DIS.rcItem.Top;
  27644. if isDown and (Self_.fGlyphLayout <> glyphOver) then
  27645. begin
  27646. Inc( X, Self_.TextShiftX );
  27647. Inc( Y, Self_.TextShiftY );
  27648. end;
  27649. case Self_.fGlyphLayout of
  27650. glyphLeft:
  27651. begin
  27652. Y := Y + (H - OutH) div 2;
  27653. TxRect.Left := X + OutW;
  27654. end;
  27655. glyphTop:
  27656. begin
  27657. X := X + (W - OutW) div 2;
  27658. TxRect.Top := Y + OutH;
  27659. end;
  27660. glyphRight:
  27661. begin
  27662. X := DIS.rcItem.Right - OutW;
  27663. TxRect.Right := X;
  27664. Y := Y + (H - OutH) div 2;
  27665. end;
  27666. glyphBottom:
  27667. begin
  27668. Y := DIS.rcItem.Bottom - OutH;
  27669. TxRect.Bottom := Y;
  27670. X := X + (W - OutW) div 2;
  27671. end;
  27672. glyphOver:
  27673. begin
  27674. X := X + (W - OutW) div 2;
  27675. Y := Y + (H - OutH) div 2;
  27676. end;
  27677. end;
  27678. if X < DIS.rcItem.Left then
  27679. X := DIS.rcItem.Left;
  27680. if Y < DIS.rcItem.Top then
  27681. Y := DIS.rcItem.Top;
  27682. if X + OutW > DIS.rcItem.Right then
  27683. OutW := DIS.rcItem.Right - X;
  27684. if Y + OutH > DIS.rcItem.Bottom then
  27685. OutH := DIS.rcItem.Bottom - Y;
  27686. if bboImageList in Self_.fBitBtnOptions then
  27687. begin
  27688. I := LoWord( Self_.fGlyphCount );
  27689. if (HiWord( Self_.fGlyphCount ) > G) then
  27690. I := I + G;
  27691. Flags := 0; // ILD_NORMAL
  27692. Blend := 0;
  27693. if not Self_.fTransparent then
  27694. Bk := Color2RGB( Self_.fColor )
  27695. else
  27696. begin
  27697. Bk := Integer(CLR_NONE);
  27698. Flags := ILD_TRANSPARENT;
  27699. end;
  27700. if HiWord( Self_.fGlyphCount ) = 1 then
  27701. begin
  27702. Blend := Integer(CLR_DEFAULT);
  27703. if IsDefault then
  27704. Flags := Flags or ILD_BLEND25;
  27705. end;
  27706. ImageList_DrawEx( Self_.fGlyphBitmap, I, DIS.hDC, X, Y, 0, 0,
  27707. Bk, Blend, Flags );
  27708. end
  27709. else
  27710. begin
  27711. DC := CreateCompatibleDC( 0 );
  27712. OldBmp := SelectObject( DC, Self_.fGlyphBitmap );
  27713. I := 0;
  27714. if Self_.fGlyphCount > G then
  27715. I := I + G * ImgW;
  27716. StretchBlt( DIS.hDC, X, Y, OutW, OutH, DC, I, 0, ImgW, ImgH, SRCCOPY );
  27717. SelectObject( DC, OldBmp );
  27718. DeleteDC( DC );
  27719. end;
  27720. end;
  27721. end;
  27722. if not (bboNoCaption in Self_.fBitBtnOptions) then
  27723. if (TxRect.Right > TxRect.Left) and (TxRect.Bottom > TxRect.Top) then
  27724. begin
  27725. CapText := Self_.Caption;
  27726. CapTxtOrig := CapText; /////////////////////////// added 19 Nov 2001
  27727. if Assigned( Self_.FBitBtnGetCaption ) then
  27728. CapText := Self_.FBitBtnGetCaption( Self_, CapText ); ////////////
  27729. Bk := 0;
  27730. Blend := 0;
  27731. Flags := ETO_CLIPPED;
  27732. if Self_.fTransparent or (Self_.fGlyphLayout = glyphOver) then
  27733. Bk := SetBkMode( DIS.hDC, TRANSPARENT )
  27734. else
  27735. begin
  27736. Flags := Flags or ETO_OPAQUE;
  27737. Blend := SetBkColor( DIS.hDC, Color2RGB( Self_.fColor ) );
  27738. end; // Returned previous BkMode is either OPAQUE=1 or TRANSPARENT=2
  27739. OldFont := 0;
  27740. if assigned( Self_.fFont ) then
  27741. OldFont := SelectObject( DIS.hDC, Self_.fFont.Handle );
  27742. OldTextColor := SetTextColor( DIS.hDC, Color2RGB( Self_.fTextColor ) );
  27743. {Windows.}GetTextExtentPoint32( DIS.hDC, PKOLChar( CapText ), Length( CapText ),
  27744. TextSz );
  27745. W := TxRect.Right - TxRect.Left;
  27746. H := TxRect.Bottom - TxRect.Top;
  27747. Y := TxRect.Top + (H - TextSz.cy) div 2;
  27748. case Self_.fTextAlign of
  27749. taLeft: X := TxRect.Left;
  27750. taCenter: X := TxRect.Left + (W - TextSz.cx) div 2;
  27751. else {taRight:} X := TxRect.Right - TextSz.cx;
  27752. end;
  27753. if isDown then
  27754. begin
  27755. Inc( X, Self_.TextShiftX );
  27756. Inc( Y, Self_.TextShiftY );
  27757. end;
  27758. if Y < 0 then
  27759. Y := 0;
  27760. if X < TxRect.Left then
  27761. X := TxRect.Left;
  27762. Windows.
  27763. {$IFDEF UNICODE_CTRLS}
  27764. ExtTextOutW
  27765. {$ELSE}
  27766. ExtTextOut
  27767. {$ENDIF}
  27768. ( DIS.hDC, X, Y, Flags, @TxRect,
  27769. PKOLChar( CapText ), Length( CapText ), nil );
  27770. if bboFocusRect in Self_.fBitBtnOptions then
  27771. if IsDefault then
  27772. begin
  27773. FocusRect := TxRect;
  27774. //InflateRect( FocusRect, 1, 1 );
  27775. Windows.DrawFocusRect( DIS.hDC, FocusRect );
  27776. end;
  27777. if Assigned( Self_.FBitBtnExtDraw ) then // to provide underlying mnemonic characters
  27778. Self_.FBitBtnExtDraw( Self_, DIS.hDC, X, Y, TxRect, CapText, CapTxtOrig,
  27779. OldTextColor ); /////////////////////////////////
  27780. SetTextColor( DIS.hDC, OldTextColor );
  27781. if OldFont <> 0 then
  27782. SelectObject( DIS.hDC, OldFont );
  27783. if Blend = 0 then
  27784. SetBkMode( DIS.hDC, Bk )
  27785. else
  27786. SetBkColor( DIS.hDC, Blend );
  27787. end;
  27788. end;
  27789. if (Msg.message = WM_LBUTTONDOWN) or (Msg.message = WM_KEYDOWN) and (Msg.wParam = 32) then
  27790. begin
  27791. if bboFixed in Self_.fBitBtnOptions then
  27792. begin
  27793. Self_.fChecked := not Self_.fChecked;
  27794. if Assigned( Self_.fOnChange ) then
  27795. Self_.fOnChange( Self_ );
  27796. end;
  27797. if Self_.fRepeatInterval > 0 then
  27798. begin
  27799. if Msg.message <> WM_KEYDOWN then
  27800. SetTimer( Self_.fHandle, 1, 400, nil );
  27801. Self_.Invalidate;
  27802. end;
  27803. end;
  27804. if (Msg.message = WM_LBUTTONUP) or (Msg.message = WM_KEYUP) then
  27805. begin
  27806. if Self_.fRepeatInterval > 0 then
  27807. KillTimer( Self_.fHandle, 1 );
  27808. end;
  27809. if Msg.message = WM_KILLFOCUS then // to repaint when focus lost
  27810. Self_.Invalidate;
  27811. if Msg.message = WM_TIMER then
  27812. begin
  27813. KillTimer( Self_.fHandle, 1 );
  27814. if bboFixed in Self_.fBitBtnOptions then
  27815. begin
  27816. Self_.fChecked := not Self_.fChecked;
  27817. if Assigned( Self_.fOnChange ) then
  27818. Self_.fOnChange( Self_ );
  27819. end;
  27820. Self_.DoClick;
  27821. SetTimer( Self_.fHandle, 1, Self_.fRepeatInterval, nil );
  27822. Self_.Invalidate;
  27823. end;
  27824. end;
  27825. {$ENDIF ASM_VERSION}
  27826. //[END WndProcBitBtn]
  27827. {$IFDEF USE_CONSTRUCTORS}
  27828. //[function NewBitBtn]
  27829. function NewBitBtn( AParent: PControl; const Caption: String;
  27830. Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap;
  27831. GlyphCount: Integer ): PControl;
  27832. begin
  27833. new( Result, CreateBitBtn( AParent, Caption, Options, Layout, GlyphBitmap, GlyphCount ) );
  27834. end;
  27835. //[END NewBitBtn]
  27836. {$ELSE not_USE_CONSTRUCTORS}
  27837. //[FUNCTION NewBitBtn]
  27838. {$IFDEF ASM_VERSION}
  27839. {$ELSE ASM_VERSION} //Pascal
  27840. function NewBitBtn( AParent: PControl; const Caption: KOLString;
  27841. Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap;
  27842. GlyphCount: Integer ): PControl;
  27843. var
  27844. B: TBitmapInfo;
  27845. W, H: Integer;
  27846. f: DWORD;
  27847. begin
  27848. f := WS_VISIBLE or WS_CHILD or BS_OWNERDRAW or WS_TABSTOP or BS_NOTIFY;
  27849. Result := _NewControl( AParent, 'BUTTON', f, False, @ButtonActions );
  27850. Result.fIgnoreDefault := TRUE;
  27851. Result.fIsButton := TRUE;
  27852. Result.fIsBitBtn := TRUE;
  27853. Result.fCommandActions.aAutoSzX := 8;
  27854. Result.fCommandActions.aAutoSzY := 8;
  27855. Result.fBitBtnOptions := Options;
  27856. Result.fGlyphLayout := Layout;
  27857. Result.fGlyphBitmap := GlyphBitmap;
  27858. with Result.fBoundsRect do
  27859. begin
  27860. Bottom := Top + 22;
  27861. W := 0; H := 0;
  27862. if GlyphBitmap <> 0 then
  27863. begin
  27864. if bboImageList in Options then
  27865. ImageList_GetIconSize( GlyphBitmap, W, H )
  27866. else
  27867. begin
  27868. if GetObject( GlyphBitmap, Sizeof(B), @B ) > 0 then
  27869. begin
  27870. W := B.bmiHeader.biWidth;
  27871. H := B.bmiHeader.biHeight;
  27872. if GlyphCount = 0 then
  27873. GlyphCount := W div H;
  27874. if GlyphCount > 1 then
  27875. W := W div GlyphCount;
  27876. end;
  27877. end;
  27878. if W > 0 then
  27879. begin
  27880. if (Caption = '') or (Layout = glyphOver) then
  27881. begin
  27882. Right := Left + W;
  27883. Result.fCommandActions.aAutoSzX := 0;
  27884. end
  27885. else
  27886. if Layout in [ glyphLeft, glyphRight ] then
  27887. begin
  27888. Right := Right + W;
  27889. Inc( Result.fCommandActions.aAutoSzX, W );
  27890. end;
  27891. end;
  27892. if H > 0 then
  27893. begin
  27894. if Layout in [ glyphTop, glyphBottom ] then
  27895. begin
  27896. Bottom := Bottom + H;
  27897. Inc( Result.fCommandActions.aAutoSzY, H );
  27898. end
  27899. else
  27900. begin
  27901. Bottom := Top + H;
  27902. Result.fCommandActions.aAutoSzY := 0;
  27903. end;
  27904. end;
  27905. if not ( bboNoBorder in Options ) then
  27906. begin
  27907. if W > 0 then
  27908. begin
  27909. Inc( Right, 4 );
  27910. if Result.fCommandActions.aAutoSzX > 0 then
  27911. Inc( Result.fCommandActions.aAutoSzX, 4 );
  27912. end;
  27913. if H > 0 then
  27914. begin
  27915. Inc( Bottom, 4 );
  27916. if Result.fCommandActions.aAutoSzY > 0 then
  27917. Inc( Result.fCommandActions.aAutoSzY, 4 );
  27918. end;
  27919. end;
  27920. end;
  27921. Result.fGlyphWidth := W;
  27922. Result.fGlyphHeight := H;
  27923. end;
  27924. Result.fGlyphCount := GlyphCount;
  27925. if AParent <> nil then
  27926. AParent.AttachProc( WndProc_DrawItem );
  27927. Result.AttachProc( WndProcBitBtn );
  27928. Result.fTextAlign := taCenter;
  27929. Result.Caption := Caption;
  27930. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  27931. Result.AttachProc( WndProcBtnReturnClick );
  27932. {$ENDIF}
  27933. {$IFDEF GRAPHCTL_XPSTYLES}
  27934. Result.fClassicTransparent := Result.fTransparent;
  27935. Attach_WM_THEMECHANGED(Result);
  27936. XP_Themes_For_BitBtn(Result);
  27937. {$ENDIF}
  27938. end;
  27939. {$ENDIF ASM_VERSION}
  27940. //[END NewBitBtn]
  27941. {$ENDIF USE_CONSTRUCTORS}
  27942. //===================== Check box ========================//
  27943. {$IFDEF USE_CONSTRUCTORS}
  27944. //[function NewCheckbox]
  27945. function NewCheckbox( AParent: PControl; const Caption: String ): PControl;
  27946. begin
  27947. new( Result, CreateCheckbox( AParent, Caption ) );
  27948. end;
  27949. //[END NewCheckbox]
  27950. {$ELSE not_USE_CONSTRUCTORS}
  27951. //[FUNCTION NewCheckbox]
  27952. {$IFDEF ASM_VERSION}
  27953. {$ELSE ASM_VERSION} //Pascal
  27954. function NewCheckbox( AParent: PControl; const Caption: KOLString ): PControl;
  27955. begin
  27956. Result := NewButton( AParent, Caption );
  27957. {$ifdef wince}
  27958. Result.DetachProc(WndProcBtnFocus);
  27959. {$endif wince}
  27960. Result.fColor:=AParent.fColor;
  27961. if Result.fBrush <> nil then
  27962. Result.fBrush.fData.Color:=Result.fColor;
  27963. with Result.fBoundsRect do
  27964. begin
  27965. Right := Left + 72;
  27966. end;
  27967. Result.fStyle := WS_VISIBLE or WS_CHILD or
  27968. BS_AUTOCHECKBOX or WS_TABSTOP or BS_NOTIFY;
  27969. Result.fCommandActions.aAutoSzX := 24;
  27970. Result.fIgnoreDefault := FALSE;
  27971. {$IFDEF GRAPHCTL_XPSTYLES}
  27972. Result.fClassicTransparent := Result.fTransparent;
  27973. Attach_WM_THEMECHANGED(Result);
  27974. XP_Themes_For_CheckBox(Result);
  27975. {$ENDIF}
  27976. end;
  27977. {$ENDIF ASM_VERSION}
  27978. //[END NewCheckbox]
  27979. {$ENDIF USE_CONSTRUCTORS}
  27980. //[function NewCheckBox3State]
  27981. function NewCheckBox3State( AParent: PControl; const Caption: KOLString ): PControl;
  27982. begin
  27983. Result := NewCheckbox( AParent, Caption );
  27984. Result.fStyle := Result.fStyle and not BS_AUTOCHECKBOX or BS_AUTO3STATE;
  27985. end;
  27986. //===================== Radiobox ========================//
  27987. //[FUNCTION ClickRadio]
  27988. {$IFDEF ASM_VERSION}
  27989. {$ELSE ASM_VERSION} //Pascal
  27990. procedure ClickRadio( Sender:PObj );
  27991. var Self_:PControl;
  27992. begin
  27993. Self_ := PControl( Sender );
  27994. if Self_.FParent <> nil then
  27995. CheckRadioButton( Self_.fParent.fHandle,
  27996. Self_.fParent.fRadio1st,
  27997. Self_.fParent.fRadioLast,
  27998. Self_.fMenu );
  27999. end;
  28000. {$ENDIF ASM_VERSION}
  28001. //[END ClickRadio]
  28002. {$IFDEF USE_CONSTRUCTORS}
  28003. //[function NewRadiobox]
  28004. function NewRadiobox( AParent: PControl; const Caption: String ): PControl;
  28005. begin
  28006. new( Result, CreateRadiobox( AParent, Caption ) );
  28007. end;
  28008. //[END NewRadiobox]
  28009. {$ELSE not_USE_CONSTRUCTORS}
  28010. //[FUNCTION NewRadiobox]
  28011. {$IFDEF ASM_VERSION}
  28012. {$ELSE ASM_VERSION} //Pascal
  28013. function NewRadiobox( AParent: PControl; const Caption: KOLString ): PControl;
  28014. begin
  28015. Result := NewCheckbox( AParent, Caption );
  28016. Result.fStyle := WS_VISIBLE or WS_CHILD or
  28017. BS_RADIOBUTTON or WS_TABSTOP or WS_GROUP or BS_NOTIFY;
  28018. {$ifdef wince}
  28019. Result.DetachProc(WndProcBtnFocus);
  28020. {$endif wince}
  28021. Result.fControlClick := ClickRadio;
  28022. if AParent <> nil then
  28023. begin
  28024. AParent.fRadioLast := Result.fMenu;
  28025. if AParent.fRadio1st = 0 then
  28026. begin
  28027. AParent.fRadio1st := Result.fMenu;
  28028. Result.SetRadioChecked;
  28029. end;
  28030. end;
  28031. {$IFDEF GRAPHCTL_XPSTYLES}
  28032. Result.fClassicTransparent := Result.fTransparent;
  28033. Attach_WM_THEMECHANGED(Result);
  28034. XP_Themes_For_RadioBox(Result);
  28035. {$ENDIF}
  28036. end;
  28037. {$ENDIF ASM_VERSION}
  28038. //[END NewRadiobox]
  28039. {$ENDIF USE_CONSTRUCTORS}
  28040. //===================== Label ========================//
  28041. {$ENDIF WIN_GDI}
  28042. {$IFNDEF USE_CONSTRUCTORS}
  28043. {$IFDEF ASM_VERSION}
  28044. const StaticClass: array[0..6]of Char=('S','T','A','T','I','C',#0);
  28045. {$ENDIF ASM_VERSION}
  28046. {$ENDIF not USE_CONSTRUCTORS}
  28047. {$IFDEF USE_CONSTRUCTORS}
  28048. //[function NewLabel]
  28049. function NewLabel( AParent: PControl; const Caption: String ): PControl;
  28050. begin
  28051. new( Result, CreateLabel( AParent, Caption ) );
  28052. end;
  28053. //[END NewLabel]
  28054. {$ELSE not_USE_CONSTRUCTORS}
  28055. //[FUNCTION NewLabel]
  28056. {$IFDEF GDI}
  28057. {$IFDEF ASM_UNICODE}
  28058. {$ELSE ASM_VERSION} //Pascal
  28059. function NewLabel( AParent: PControl; const Caption: KOLString ): PControl;
  28060. begin
  28061. Result := _NewControl( AParent, 'STATIC', WS_VISIBLE or WS_CHILD or
  28062. SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_NOTIFY,
  28063. False ,@LabelActions );
  28064. Inc( Result.fIsStaticControl );
  28065. Result.fSizeRedraw := True;
  28066. with Result.fBoundsRect do
  28067. Bottom := Top + 22; //Right := Left + 64 {done in _NewControl};
  28068. Result.Caption := Caption;
  28069. {$IFDEF GRAPHCTL_XPSTYLES}
  28070. Result.fClassicTransparent := Result.fTransparent;
  28071. Attach_WM_THEMECHANGED(Result);
  28072. XP_Themes_For_Label(Result);
  28073. {$ENDIF}
  28074. end;
  28075. {$ENDIF ASM_VERSION}
  28076. {$ENDIF GDI}
  28077. {$IFDEF _X_}
  28078. {$IFDEF GTK}
  28079. procedure LabelSetTextAlign( Self_: PControl );
  28080. begin
  28081. gtk_misc_set_alignment( GTK_MISC( Self_.fCaptionHandle ), HorAlignments[ Self_.fTextAlign ],
  28082. VerAlignments[ Self_.fVerticalAlign ] );
  28083. end;
  28084. function NewLabel( AParent: PControl; const Caption: KOLString ): PControl;
  28085. begin
  28086. Result := _NewControl( AParent, 'STATIC', WS_VISIBLE or WS_CHILD or
  28087. SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_NOTIFY,
  28088. False, gtk_label_new( PChar( String( Caption ) ) ),
  28089. TRUE );
  28090. Result.fGetCaption := getLabelCaption;
  28091. Result.fSetCaption := setLabelCaption;
  28092. Inc( Result.fIsStaticControl );
  28093. Result.fSetTextAlign := LabelSetTextAlign;
  28094. Result.fTextAlign := taCenter;
  28095. Result.TextAlign := taLeft;
  28096. end;
  28097. {$ENDIF GTK}
  28098. {$ENDIF _X_}
  28099. {$ENDIF USE_CONSTRUCTORS}
  28100. //[END NewLabel]
  28101. {$IFDEF WIN_GDI}
  28102. //===================== word wrap Label ========================//
  28103. {$IFDEF USE_CONSTRUCTORS}
  28104. //[function NewWordWrapLabel]
  28105. function NewWordWrapLabel( AParent: PControl; const Caption: String ): PControl;
  28106. begin
  28107. new( Result, CreateWordWrapLabel( AParent, Caption ) );
  28108. end;
  28109. //[END NewWordWrapLabel]
  28110. {$ELSE not_USE_CONSTRUCTORS}
  28111. //[FUNCTION NewWordWrapLabel]
  28112. {$IFDEF ASM_VERSION}
  28113. {$ELSE ASM_VERSION} //Pascal
  28114. function NewWordWrapLabel( AParent: PControl; const Caption: KOLString ): PControl;
  28115. begin
  28116. Result := NewLabel( AParent, Caption );
  28117. Result.fWordWrap := TRUE;
  28118. with Result.fBoundsRect do
  28119. begin
  28120. Bottom := Top + 44;
  28121. end;
  28122. Result.fStyle := Result.fStyle and not SS_LEFTNOWORDWRAP;
  28123. end;
  28124. {$ENDIF ASM_VERSION}
  28125. //[END NewWordWrapLabel]
  28126. {$ENDIF USE_CONSTRUCTORS}
  28127. //===================== Label Effect ========================//
  28128. {$IFDEF USE_CONSTRUCTORS}
  28129. function NewLabelEffect( AParent: PControl; const Caption: String; ShadowDeep: Integer ): PControl;
  28130. begin
  28131. new( Result, CreateLabelEffect( AParent, Caption, ShadowDeep ) );
  28132. end;
  28133. {$ELSE not_USE_CONSTRUCTORS}
  28134. //[FUNCTION NewLabelEffect]
  28135. {$IFDEF ASM_VERSION}
  28136. {$ELSE ASM_VERSION} //Pascal
  28137. function NewLabelEffect( AParent: PControl; const Caption: KOLString; ShadowDeep: Integer ): PControl;
  28138. begin
  28139. Result := NewLabel( AParent, '' );
  28140. Dec( Result.fIsStaticControl ); // ñíîâà 0 !
  28141. Result.AttachProc( WndProcLabelEffect );
  28142. Result.Caption := Caption;
  28143. Result.AttachProc( WndProcDoEraseBkgnd );
  28144. Result.fTextAlign := taCenter;
  28145. Result.fTextColor := clWindowText;
  28146. Result.fShadowDeep := ShadowDeep;
  28147. Result.fIgnoreWndCaption := True;
  28148. with Result.fBoundsRect do
  28149. begin
  28150. Bottom := Top + 40;
  28151. end;
  28152. Result.fColor2 := clNone;
  28153. end;
  28154. {$ENDIF ASM_VERSION}
  28155. //[END NewLabelEffect]
  28156. {$ENDIF USE_CONSTRUCTORS}
  28157. //===================== Paint box ========================//
  28158. {$ENDIF WIN_GDI}
  28159. {$IFDEF USE_CONSTRUCTORS}
  28160. //[function NewPaintbox]
  28161. function NewPaintbox( AParent: PControl ): PControl;
  28162. begin
  28163. new( Result, CreatePaintBox( AParent ) );
  28164. end;
  28165. {$ELSE not_USE_CONSTRUCTORS}
  28166. //[FUNCTION NewPaintbox]
  28167. {$IFDEF GDI}
  28168. {$UNDEF ASM_LOCAL}
  28169. {$IFNDEF GRAPHCTL_XPSTYLES}
  28170. {$IFDEF ASM_VERSION}
  28171. {$DEFINE ASM_LOCAL}
  28172. {$ENDIF ASM_VERSION}
  28173. {$ENDIF GRAPHCTL_XPSTYLES}
  28174. {$IFDEF ASM_LOCAL}
  28175. function NewPaintbox( AParent: PControl ): PControl;
  28176. asm
  28177. XOR EDX, EDX
  28178. CALL NewLabel
  28179. ADD [EAX].TControl.fBoundsRect.Bottom, 64-22
  28180. end;
  28181. {$ELSE ASM_LOCAL} //Pascal
  28182. function NewPaintbox( AParent: PControl ): PControl;
  28183. begin
  28184. {$IFDEF GRAPHCTL_XPSTYLES}
  28185. Result := _NewControl( AParent, 'STATIC', WS_VISIBLE or WS_CHILD {or
  28186. SS_LEFTNOWORDWRAP or SS_NOPREFIX }or SS_NOTIFY,
  28187. False , @LabelActions );
  28188. //Inc( Result.fIsStaticControl );
  28189. Result.fSizeRedraw := True;
  28190. //with Result.fBoundsRect do
  28191. // Bottom := Top + 64; //Right := Left + 64 {done in _NewControl};
  28192. Result.fClassicTransparent := Result.fTransparent;
  28193. Result.fControlClassName := 'obj_PAINT';
  28194. {$ELSE}
  28195. Result := NewLabel( AParent, '' );
  28196. with Result.fBoundsRect do
  28197. begin
  28198. Bottom := Top + 64; //Right := Left + 64 {done in NewLabel};
  28199. end;
  28200. {$ENDIF}
  28201. end;
  28202. {$ENDIF ASM_VERSION}
  28203. {$ENDIF GDI}
  28204. {$IFDEF _X_}
  28205. {$IFDEF GTK}
  28206. function NewPaintbox( AParent: PControl ): PControl;
  28207. begin
  28208. Result := NewLabel( AParent, '' );
  28209. Result.Height := 64;
  28210. end;
  28211. {$ENDIF GTK}
  28212. {$ENDIF _X_}
  28213. //[END NewPaintbox]
  28214. {$ENDIF USE_CONSTRUCTORS}
  28215. {$IFDEF WIN_GDI}
  28216. {$IFDEF _D2}
  28217. //[API SetBrushOrgEx]
  28218. function SetBrushOrgEx(DC: HDC; X, Y: Integer; PrevPt: PPoint): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  28219. external gdi32 name 'SetBrushOrgEx';
  28220. {$ENDIF}
  28221. //[FUNCTION WndProcDoEraseBkgnd]
  28222. {$IFDEF ASM_VERSION}
  28223. {$ELSE ASM_VERSION PAS_VERSION}
  28224. function WndProcDoEraseBkgnd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  28225. var DC: HDC;
  28226. R: TRect;
  28227. begin
  28228. Result := FALSE;
  28229. if Msg.message = WM_ERASEBKGND then
  28230. begin
  28231. Self_.CreateChildWindows;
  28232. if Self_.Transparent then Exit;
  28233. DC := Msg.wParam;
  28234. SetBkMode( DC, OPAQUE );
  28235. SetBkColor( DC, Color2RGB( Self_.fColor ) );
  28236. SetBrushOrgEx( DC, 0, 0, nil );
  28237. GetClientRect( Self_.fHandle, R );
  28238. Windows.FillRect( DC, R, Global_GetCtlBrushHandle( Self_ ) );
  28239. Rslt := 1;
  28240. end;
  28241. end;
  28242. {$ENDIF ASM_VERSION}
  28243. //[END WndProcDoEraseBkgnd]
  28244. //[function WndProcImageShow]
  28245. function WndProcImageShow( Sender: PControl; var Msg: TMsg;
  28246. var Rslt: Integer ): Boolean;
  28247. var PaintStruct: TPaintStruct;
  28248. IL: PImageList;
  28249. OldPaintDC: HDC;
  28250. begin
  28251. Result := FALSE;
  28252. if (Msg.message = WM_PAINT) or (Msg.message = WM_PRINT) then
  28253. begin
  28254. OldPaintDC := Sender.fPaintDC;
  28255. Sender.fPaintDC := Msg.wParam;
  28256. if Sender.fPaintDC = 0 then
  28257. Sender.fPaintDC := BeginPaint( Sender.fHandle, PaintStruct );
  28258. IL := Sender.ImageListNormal;
  28259. if IL <> nil then
  28260. begin
  28261. IL.Draw( Sender.fCurIndex, Sender.fPaintDC, Sender.fClientLeft, Sender.fClientTop );
  28262. Result := TRUE;
  28263. end;
  28264. if Msg.wParam = 0 then
  28265. EndPaint( Sender.fHandle, PaintStruct );
  28266. Sender.fPaintDC := OldPaintDC;
  28267. Rslt := 0;
  28268. //Result := True;
  28269. Exit;
  28270. end;
  28271. end;
  28272. //[function NewImageShow]
  28273. function NewImageShow( AParent: PControl; AImgList: PImageList;
  28274. ImgIdx: Integer ): PControl;
  28275. var W, H: Integer;
  28276. begin
  28277. Result := NewLabel( AParent, '' );
  28278. Result.ImageListNormal := AImgList;
  28279. Result.AttachProc( WndProcImageShow );
  28280. Result.AttachProc( WndProcDoEraseBkgnd );
  28281. W := 32; H := 32;
  28282. if AImgList <> nil then
  28283. begin
  28284. W := AImgList.ImgWidth;
  28285. H := AImgList.ImgHeight;
  28286. end;
  28287. with Result.fBoundsRect do
  28288. begin
  28289. Right := Left + W;
  28290. Bottom := Top + H;
  28291. end;
  28292. end;
  28293. //[END NewImageShow]
  28294. //===================== Scrollbar ========================//
  28295. const
  28296. KSB_INITIALIZE = WM_USER + 10000;
  28297. KSB_KEY = $3232;
  28298. //[function WndProcScrollBarParent]
  28299. function WndProcScrollBarParent( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  28300. var
  28301. Bar: PControl;
  28302. SI: TScrollInfo;
  28303. NewPos: Integer;
  28304. AllowChange: Boolean;
  28305. Cmd: Word;
  28306. begin
  28307. Result := False;
  28308. case Msg.message of
  28309. WM_HSCROLL, WM_VSCROLL:
  28310. if (Msg.lParam <> 0) then begin
  28311. {$IFDEF USE_PROP}
  28312. Bar := Pointer(GetProp(Msg.lParam, ID_SELF));
  28313. {$ELSE}
  28314. Bar := Pointer( GetWindowLong( Msg.lParam, GWL_USERDATA ) );
  28315. {$ENDIF}
  28316. if (Bar <> nil) then begin
  28317. FillChar(SI, SizeOf(SI), #0);
  28318. SI.cbSize := SizeOf(SI);
  28319. SI.fMask := SIF_RANGE or SIF_POS or SIF_TRACKPOS or SIF_PAGE;
  28320. Bar.SBGetScrollInfo(SI);
  28321. {Cmd := Msg.wParam and $0000FFFF;
  28322. case Cmd of
  28323. SB_BOTTOM: NewPos := SI.nMax;
  28324. SB_TOP: NewPos := SI.nMin;
  28325. SB_LINEDOWN: NewPos := SI.nPos + 1;
  28326. SB_LINEUP: NewPos := SI.nPos - 1;
  28327. SB_PAGEDOWN: NewPos := SI.nPos + Integer(SI.nPage);
  28328. SB_PAGEUP: NewPos := SI.nPos - Integer(SI.nPage);
  28329. SB_THUMBTRACK: NewPos := SI.nTrackPos;
  28330. else
  28331. Exit;
  28332. end;}
  28333. Cmd := Msg.wParam and $0000FFFF;
  28334. case Cmd of
  28335. SB_BOTTOM: NewPos := SI.nMax;
  28336. SB_TOP: NewPos := SI.nMin;
  28337. SB_LINEDOWN: NewPos := SI.nPos + 1;
  28338. SB_LINEUP: NewPos := SI.nPos - 1;
  28339. SB_PAGEDOWN: NewPos := SI.nPos + Integer(SI.nPage);
  28340. SB_PAGEUP: NewPos := SI.nPos - Integer(SI.nPage);
  28341. {!ecm}
  28342. SB_THUMBPOSITION,SB_THUMBTRACK: NewPos := SI.nTrackPos;
  28343. SB_ENDSCROLL: NewPos := SI.nPos;
  28344. {/!ecm}
  28345. else
  28346. Exit;
  28347. end;
  28348. if (NewPos > SI.nMax - Integer(SI.nPage) + 1) then
  28349. NewPos := SI.nMax - Integer(SI.nPage) + 1;
  28350. if (NewPos < SI.nMin) then
  28351. NewPos := SI.nMin;
  28352. AllowChange := True;
  28353. if Assigned(Bar.OnSBBeforeScroll) then
  28354. Bar.OnSBBeforeScroll(Bar, SI.nPos, NewPos, Cmd, AllowChange);
  28355. if AllowChange then
  28356. SI.nPos := NewPos
  28357. else
  28358. SI.nTrackPos := SI.nPos;
  28359. Bar.fSBPosition := SI.nPos;
  28360. Bar.fSBPosition := Bar.SBSetScrollInfo(SI);
  28361. if AllowChange and Assigned(Bar.OnSBScroll) then
  28362. Bar.OnSBScroll(Bar, Cmd);
  28363. end;
  28364. end;
  28365. end;
  28366. end;
  28367. //[END WndProcScrollBarParent]
  28368. //[function NewScrollBar]
  28369. function NewScrollBar( AParent: PControl; BarSide: TScrollerBar ): PControl;
  28370. const SBS_Directions: array[ TScrollerBar ] of DWORD = ( SBS_HORZ {$ifndef wince} or SBS_BOTTOMALIGN{$endif wince},
  28371. SBS_VERT {$ifndef wince}or SBS_RIGHTALIGN{$endif wince} );
  28372. begin
  28373. Result := _NewCommonControl(
  28374. AParent,
  28375. 'SCROLLBAR',
  28376. WS_VISIBLE or WS_CHILD or SBS_Directions[ BarSide ],
  28377. False,
  28378. nil
  28379. );
  28380. {!ecm}
  28381. Result.GetWindowHandle;
  28382. {/!ecm}
  28383. Result.DetachProc(WndProcCtrl);
  28384. Result.fLookTabKeys := [tkTab];
  28385. //#ecm Result.AttachProc(WndProcScrollBar);
  28386. AParent.AttachProc(WndProcScrollBarParent);
  28387. {$ifdef wince}
  28388. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  28389. {$endif wince}
  28390. end;
  28391. //[END NewScrollBar]
  28392. //===================== Scrollbox ========================//
  28393. //[function WndProcScrollBox]
  28394. function WndProcScrollBox( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  28395. procedure DoScrollChildren;
  28396. var
  28397. OldNotifyProc: pointer;
  28398. begin
  28399. if Assigned( Sender.fScrollChildren ) then
  28400. begin
  28401. OldNotifyProc := @ Sender.fNotifyChild;
  28402. Sender.fNotifyChild := nil;
  28403. Sender.fScrollChildren( Sender );
  28404. Sender.fNotifyChild := OldNotifyProc;
  28405. end;
  28406. end;
  28407. var Bar: DWORD;
  28408. SI: TScrollInfo;
  28409. OldPos: integer;
  28410. begin
  28411. Result := FALSE;
  28412. case Msg.message of
  28413. WM_HSCROLL: Bar := SB_HORZ;
  28414. WM_VSCROLL: Bar := SB_VERT;
  28415. WM_SIZE: begin
  28416. if Assigned( Sender.fNotifyChild ) then
  28417. Sender.fNotifyChild( Sender, nil );
  28418. Exit;
  28419. end;
  28420. WM_SHOWWINDOW:
  28421. begin
  28422. if WordBool(Msg.wParam) then begin
  28423. Sender.fVisible:=False;
  28424. Sender.CreateChildWindows;
  28425. Sender.fVisible:=True;
  28426. if Assigned(Sender.fNotifyChild) then
  28427. Sender.fNotifyChild(Sender, nil);
  28428. end;
  28429. exit;
  28430. end;
  28431. else begin
  28432. Exit;
  28433. end;
  28434. end;
  28435. SI.cbSize := Sizeof( SI );
  28436. SI.fMask := SIF_RANGE or SIF_POS or SIF_PAGE or
  28437. {$IFDEF F_P}$10{$ELSE}SIF_TRACKPOS{$ENDIF};
  28438. {$IFDEF _D2}
  28439. GetScrollInfo( Sender.fHandle, Bar, SI );
  28440. {$ELSE}
  28441. GetScrollInfo( Sender.fHandle, Bar, SI );
  28442. {$ENDIF}
  28443. OldPos:=SI.nPos;
  28444. SI.fMask := SIF_POS;
  28445. case LoWord( Msg.wParam ) of
  28446. SB_BOTTOM: SI.nPos := SI.nMax;
  28447. SB_TOP: SI.nPos := SI.nMin;
  28448. SB_LINEDOWN: Inc( SI.nPos, Sender.FScrollLineDist[ Bar ] );
  28449. SB_LINEUP: Dec( SI.nPos, Sender.FScrollLineDist[ Bar ] );
  28450. SB_PAGEDOWN: Inc( SI.nPos, Max( SI.nPage, 1 ) );
  28451. SB_PAGEUP: Dec( SI.nPos, Max( SI.nPage, 1 ) );
  28452. SB_THUMBTRACK:SI.nPos := SI.nTrackPos;
  28453. end;
  28454. if SI.nPos > SI.nMax - Integer( SI.nPage ) + 1 then
  28455. SI.nPos := SI.nMax - Integer( SI.nPage ) + 1;
  28456. if SI.nPos < SI.nMin then
  28457. SI.nPos := SI.nMin;
  28458. if OldPos = SI.nPos then exit;
  28459. SetScrollInfo( Sender.fHandle, Bar, SI, TRUE );
  28460. DoScrollChildren;
  28461. end;
  28462. //[END WndProcScrollBox]
  28463. //[function NewScrollBox]
  28464. function NewScrollBox( AParent: PControl; EdgeStyle: TEdgeStyle;
  28465. Bars: TScrollerBars ): PControl;
  28466. const Edgestyles: array[ TEdgeStyle ] of DWORD = ( {$ifdef wince}WS_BORDER, WS_BORDER{$else}WS_DLGFRAME, SS_SUNKEN{$endif}, 0, 0 );
  28467. var SBFlag: Integer;
  28468. begin
  28469. SBFlag := EdgeStyles[ EdgeStyle ];
  28470. if sbHorizontal in Bars then
  28471. SBFlag := SBFlag or WS_HSCROLL;
  28472. if sbVertical in Bars then
  28473. SBFlag := SBFlag or WS_VSCROLL;
  28474. Result := _NewControl( AParent, 'ScrollBox', WS_VISIBLE or WS_CHILD or
  28475. SBFlag, EdgeStyle = esLowered, nil );
  28476. Result.AttachProc( WndProcForm ); //!!!
  28477. Result.AttachProc( WndProcScrollBox );
  28478. Result.AttachProc( WndProcDoEraseBkgnd );
  28479. Result.fIsControl := TRUE;
  28480. end;
  28481. //[END NewScrollBox]
  28482. //[function WndProcNotifyParentAboutResize]
  28483. function WndProcNotifyParentAboutResize( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  28484. var P: PControl;
  28485. begin
  28486. if (Msg.message = WM_SIZE) or (Msg.message = WM_MOVE) or (Msg.message = CM_SHOW) then
  28487. begin
  28488. P := Sender.Parent;
  28489. if P <> nil then
  28490. if Assigned( P.fNotifyChild ) then
  28491. P.fNotifyChild( P, nil );
  28492. end
  28493. else
  28494. if (Msg.message = WM_SHOWWINDOW) and (Sender.Parent <> nil) and (Sender.Parent.Visible) then
  28495. PostMessage( Sender.fHandle, CM_SHOW, 0, 0 );
  28496. Result := FALSE;
  28497. end;
  28498. //[procedure CalcMinMaxChildren]
  28499. procedure CalcMinMaxChildren( Self_: PControl; var SzR: TRect );
  28500. var I: Integer;
  28501. C: PControl;
  28502. R: TRect;
  28503. begin
  28504. Szr := MakeRect( 0, 0, 0, 0 );
  28505. for I := 0 to Self_.fChildren.fCount - 1 do
  28506. begin
  28507. C := Self_.fChildren.fItems[ I ];
  28508. if C.ToBeVisible then
  28509. begin
  28510. R := C.BoundsRect;
  28511. if (SzR.Left = SzR.Right) or (R.Left < SzR.Left) or (R.Right > SzR.Right) then
  28512. begin
  28513. if SzR.Left = SzR.Right then
  28514. begin
  28515. SzR.Left := R.Left;
  28516. SzR.Right := R.Right;
  28517. end
  28518. else
  28519. begin
  28520. if R.Left < SzR.Left then SzR.Left := R.Left;
  28521. if R.Right > SzR.Right then SzR.Right := R.Right;
  28522. end;
  28523. end;
  28524. if (SzR.Top = SzR.Bottom) or (R.Top < SzR.Top) or (R.Bottom > SzR.Bottom) then
  28525. begin
  28526. if SzR.Top = SzR.Bottom then
  28527. begin
  28528. SzR.Top := R.Top;
  28529. SzR.Bottom := R.Bottom;
  28530. end
  28531. else
  28532. begin
  28533. if R.Top < SzR.Top then SzR.Top := R.Top;
  28534. if R.Bottom > SzR.Bottom then SzR.Bottom := R.Bottom;
  28535. end;
  28536. end;
  28537. end;
  28538. end;
  28539. Dec( SzR.Left, Self_.Border );
  28540. Inc( SzR.Right, Self_.Border - 1 );
  28541. Dec( SzR.Top, Self_.Border );
  28542. Inc( SzR.Bottom, Self_.Border - 1 );
  28543. end;
  28544. //[procedure NotifyScrollBox]
  28545. procedure NotifyScrollBox( Self_, Child: PControl );
  28546. var SI: TScrollInfo;
  28547. procedure GetSetScrollInfo( SBar: DWORD; WH, R_RightBottom, SzR_LeftTop, SzR_RightBottom: Integer );
  28548. {$IFDEF SBOX_OLDPOS} var OldPos: Double; {$ENDIF}
  28549. begin
  28550. {$IFDEF SBOX_OLDPOS} OldPos := 0; {$ENDIF}
  28551. if not GetScrollInfo( Self_.fHandle, SBar, SI ) then
  28552. begin
  28553. SI.nMin := 0;
  28554. SI.nMax := Max( R_RightBottom - 1, SzR_RightBottom - 1 );
  28555. end
  28556. else
  28557. begin
  28558. {$IFDEF SBOX_OLDPOS}
  28559. if SI.nMax > SI.nMin then
  28560. begin
  28561. OldPos := (SI.nPos - SI.nMin) / (SI.nMax - SI.nMin);
  28562. SI.nMin := 0;
  28563. SI.nMax := Max( R_RightBottom - 1, SzR_RightBottom - 1 );
  28564. if SzR_LeftTop < 0 then
  28565. SI.nMax := Max( R_RightBottom - SzR_LeftTop - 1, WH - 1 );
  28566. end
  28567. else
  28568. begin
  28569. SI.nMin := 0;
  28570. SI.nMax := Max( R_RightBottom - 1, SzR_RightBottom - 1 );
  28571. end;
  28572. {$ENDIF}
  28573. SI.nMin := 0; {!ecm}
  28574. SI.nMax := SzR_RightBottom - SzR_LeftTop; {!ecm}
  28575. end;
  28576. {$IFDEF SBOX_OLDPOS}
  28577. SI.nPos := SI.nMin + Round( (SI.nMax - SI.nMin) * OldPos );
  28578. {$ELSE}
  28579. SI.nPos := - SzR_LeftTop;
  28580. {$ENDIF}
  28581. SI.nPage := R_RightBottom;
  28582. SetScrollInfo( Self_.fHandle, SBar, SI, TRUE );
  28583. end;
  28584. var W, H: Integer;
  28585. SzR: TRect;
  28586. R: TRect;
  28587. begin
  28588. if Assigned( Child ) then
  28589. begin
  28590. Child.AttachProc( WndProcNotifyParentAboutResize );
  28591. Exit;
  28592. end;
  28593. CalcMinMaxChildren( Self_, SzR );
  28594. W := SzR.Right - SzR.Left;
  28595. H := SzR.Bottom - SzR.Top;
  28596. R := Self_.ClientRect;
  28597. if (R.Right = 0) or (R.Bottom = 0) then Exit; // for case when form is minimized
  28598. SI.cbSize := sizeof( SI );
  28599. SI.fMask := SIF_RANGE or SIF_PAGE or SIF_POS;
  28600. SI.cbSize := sizeof( SI );
  28601. SI.fMask := SIF_RANGE or SIF_PAGE or SIF_POS;
  28602. GetSetScrollInfo( SB_HORZ, W, R.Right, SzR.Left, SzR.Right );
  28603. {+ecm}R := Self_.ClientRect;{/+ecm}
  28604. GetSetScrollInfo( SB_VERT, H, R.Bottom, SzR.Top, SzR.Bottom );
  28605. {+ecm} if Assigned( Self_.fScrollChildren ) then Self_.fScrollChildren(Self_); {/+ecm}
  28606. end;
  28607. //[procedure ScrollChildren]
  28608. procedure ScrollChildren( _Self_: PControl );
  28609. var SzR, R: TRect;
  28610. I, Xpos, Ypos: Integer;
  28611. OldNotifyProc: Pointer;
  28612. C: PControl;
  28613. DeltaX, DeltaY: Integer;
  28614. begin
  28615. if not _Self_.Visible then exit;
  28616. CalcMinMaxChildren( _Self_, SzR );
  28617. Xpos := GetScrollPos( _Self_.fHandle, SB_HORZ );
  28618. Ypos := GetScrollPos( _Self_.fHandle, SB_VERT );
  28619. DeltaX := -Xpos - SzR.Left;
  28620. DeltaY := -Ypos - SzR.Top;
  28621. if (DeltaX <> 0) or (DeltaY <> 0) then
  28622. begin
  28623. OldNotifyProc := @ _Self_.fNotifyChild;
  28624. _Self_.fNotifyChild := nil;
  28625. for I := 0 to _Self_.fChildren.fCount - 1 do
  28626. begin
  28627. C := _Self_.fChildren.fItems[ I ];
  28628. R := C.BoundsRect;
  28629. OffsetRect( R, DeltaX, DeltaY );
  28630. C.BoundsRect := R;
  28631. {$ifndef wince}
  28632. C.Invalidate;
  28633. {$endif wince}
  28634. end;
  28635. _Self_.Update;
  28636. _Self_.fNotifyChild := OldNotifyProc;
  28637. (*
  28638. CalcMinMaxChildren( _Self_, R );
  28639. if //(SzR.Left <> R.Left) or (SzR.Top <> R.Top) or
  28640. //(Szr.Right <> R.Right) or (SzR.Bottom <> R.Bottom)
  28641. ((SzR.Right - SzR.Left) <> (R.Right - R.Left)) or
  28642. ((SzR.Bottom - SzR.Top) <> (R.Bottom - R.Top))
  28643. then
  28644. if Assigned( _Self_.fNotifyChild ) then
  28645. _Self_.fNotifyChild( _Self_, nil );
  28646. *)
  28647. end;
  28648. end;
  28649. //[function NewScrollBoxEx]
  28650. function NewScrollBoxEx( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
  28651. begin
  28652. Result := NewScrollBox( AParent, EdgeStyle, [ ] );
  28653. Result.fNotifyChild := NotifyScrollBox;
  28654. Result.fScrollChildren := ScrollChildren;
  28655. Result.FScrollLineDist[ 0 ] := 16;
  28656. Result.FScrollLineDist[ 1 ] := 16;
  28657. end;
  28658. //[function WndProcOnScroll]
  28659. function WndProcOnScroll( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  28660. var Bar: TScrollerBar;
  28661. begin
  28662. Bar := sbHorizontal; //0
  28663. if Msg.message = WM_VSCROLL then
  28664. Bar := sbVertical
  28665. else
  28666. if Msg.message <> WM_HSCROLL then
  28667. begin
  28668. Result := FALSE;
  28669. Exit;
  28670. end;
  28671. if Assigned( Sender.OnScroll ) then
  28672. Sender.OnScroll( Sender, Bar, LoWord( Msg.wParam ), HiWord( Msg.wParam ) );
  28673. Result := FALSE;
  28674. end;
  28675. //[procedure TControl.SetOnScroll]
  28676. procedure TControl.SetOnScroll(const Value: TOnScroll);
  28677. begin
  28678. FOnScroll := Value;
  28679. AttachProc( @ WndProcOnScroll );
  28680. end;
  28681. //===================== Groupbox ========================//
  28682. {$IFDEF USE_CONSTRUCTORS}
  28683. //[function NewGroupbox]
  28684. function NewGroupbox( AParent: PControl; const Caption: String ): PControl;
  28685. begin
  28686. new( Result, CreateGroupbox( AParent, Caption ) );
  28687. end;
  28688. //[END NewGroupbox]
  28689. {$ELSE not_USE_CONSTRUCTORS}
  28690. //[FUNCTION NewGroupbox]
  28691. {$IFDEF ASM_UNICODE}
  28692. {$ELSE ASM_VERSION} //Pascal
  28693. function NewGroupbox( AParent: PControl; const Caption: KOLString ): PControl;
  28694. begin
  28695. Result := _NewControl( AParent, 'BUTTON',
  28696. WS_CHILD
  28697. or WS_CLIPSIBLINGS
  28698. or WS_CLIPCHILDREN
  28699. or WS_VISIBLE
  28700. or BS_GROUPBOX,
  28701. FALSE, @ButtonActions );
  28702. {$ifndef wince}
  28703. Result.fExStyle := Result.fExStyle or WS_EX_CONTROLPARENT;
  28704. {$endif wince}
  28705. Result.Caption := Caption;
  28706. with Result.fBoundsRect do
  28707. begin
  28708. Right := Left + 100;
  28709. Bottom := Top + 100;
  28710. end;
  28711. Result.fClientTop := {$ifdef wince}8{$else}22{$endif};
  28712. Result.fClientBottom := 2;
  28713. Result.fClientLeft := 2;
  28714. Result.fClientRight := 2;
  28715. Result.fTabstop := False;
  28716. Result.fIsGroupBox := TRUE;
  28717. Result.AttachProc( WndProcDoEraseBkgnd );
  28718. {$IFDEF GRAPHCTL_XPSTYLES}
  28719. Result.fClassicTransparent := Result.fTransparent;
  28720. //if AppTheming then
  28721. // Result.Style := Result.Style or BS_OWNERDRAW;
  28722. Attach_WM_THEMECHANGED(Result);
  28723. XP_Themes_For_GroupBox(Result);
  28724. {$ENDIF}
  28725. end;
  28726. {$ENDIF ASM_VERSION}
  28727. //[END NewGroupbox]
  28728. {$ENDIF USE_CONSTRUCTORS}
  28729. //===================== Panel ========================//
  28730. {$IFDEF USE_CONSTRUCTORS}
  28731. //[function NewPanel]
  28732. function NewPanel( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
  28733. begin
  28734. new( Result, CreatePanel( AParent, EdgeStyle ) );
  28735. end;
  28736. //[END NewPanel]
  28737. {$ELSE not_USE_CONSTRUCTORS}
  28738. //[FUNCTION NewPanel]
  28739. {$IFDEF ASM_UNICODE}
  28740. {$ELSE ASM_VERSION} //Pascal
  28741. function NewPanel( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
  28742. {$ifdef win32}
  28743. const Edgestyles: array[ TEdgeStyle ] of DWORD = ( WS_DLGFRAME, SS_SUNKEN, 0, 0 );
  28744. {$endif win32}
  28745. begin
  28746. Result := _NewControl( AParent, 'STATIC', WS_VISIBLE or WS_CHILD or SS_NOTIFY or
  28747. SS_LEFTNOWORDWRAP or SS_NOPREFIX, False, @LabelActions );
  28748. with Result.fBoundsRect do
  28749. begin
  28750. Right := Left + 100;
  28751. Bottom := Top + 100;
  28752. end;
  28753. {$ifdef wince}
  28754. if EdgeStyle in [esRaised, esLowered] then
  28755. Result.fStyle := Result.fStyle or WS_BORDER;
  28756. {$else}
  28757. Result.fStyle := Result.fStyle or Edgestyles[ EdgeStyle ];
  28758. Result.fExStyle := Result.fExStyle or WS_EX_CONTROLPARENT;
  28759. {$endif wince}
  28760. Result.fVerticalAlign := vaTop;
  28761. {$IFDEF GRAPHCTL_XPSTYLES}
  28762. Result.fClassicTransparent := Result.fTransparent;
  28763. if AppTheming then
  28764. Result.fStyle := Result.fStyle and (not Edgestyles[ EdgeStyle ]);
  28765. Result.SetEdgeStyle(EdgeStyle);
  28766. Attach_WM_THEMECHANGED(Result);
  28767. XP_Themes_For_Panel(Result);
  28768. {$ENDIF}
  28769. end;
  28770. {$ENDIF ASM_VERSION}
  28771. //[END NewPanel]
  28772. {$ENDIF USE_CONSTRUCTORS}
  28773. //===================== Splitter ==============================//
  28774. //{$DEFINE USE_ASM_DODRAG}
  28775. {$IFNDEF USE_ASM_DODRAG}
  28776. {$DEFINE USE_PAS_DODRAG}
  28777. {$ENDIF}
  28778. {$IFNDEF ASM_VERSION}
  28779. {$DEFINE USE_PAS_DODRAG}
  28780. {$ENDIF}
  28781. {$IFDEF USE_PAS_DODRAG}
  28782. //[procedure DoDrag]
  28783. procedure DoDrag( Self_: PControl; Cancel: Boolean{$ifdef wince}; MousePos: TPoint{$endif});
  28784. var NewSize1, NewSize2: Integer;
  28785. {$ifndef wince}
  28786. MousePos: TPoint;
  28787. {$endif wince}
  28788. R: TRect;
  28789. Prev: PControl;
  28790. I, M : Integer;
  28791. begin
  28792. if Self_.fDragging then
  28793. begin
  28794. I := Self_.fParent.fChildren.IndexOf( Self_ );
  28795. Prev := Self_;
  28796. if I > 0 then
  28797. Prev := Self_.FParent.fChildren.fItems[ I - 1 ];
  28798. {$ifndef wince}
  28799. if Cancel then
  28800. MousePos := Self_.fSplitStartPos
  28801. else
  28802. GetCursorPos( MousePos );
  28803. {$endif wince}
  28804. M := 1;
  28805. if Self_.FAlign in [ caRight, caBottom ] then
  28806. M := -1;
  28807. if Self_.FAlign in [ caTop, caBottom ] then
  28808. begin
  28809. NewSize1 := (MousePos.y - Self_.fSplitStartPos.y)* M
  28810. + Self_.fSplitStartSize;
  28811. NewSize2 := Self_.fParent.ClientHeight - NewSize1
  28812. - Self_.fBoundsRect.Bottom + Self_.fBoundsRect.Top
  28813. - Self_.fParent.fMargin * 4;
  28814. if Self_.fSecondControl <> nil then
  28815. begin
  28816. NewSize2 := Self_.fSecondControl.fBoundsRect.Bottom
  28817. - Self_.fSecondControl.fBoundsRect.Top;
  28818. if Self_.fSecondControl.FAlign = caClient then
  28819. NewSize2 := Self_.fSplitStartPos2.y
  28820. - (MousePos.y - Self_.fSplitStartPos.y)* M
  28821. - Self_.fParent.fMargin * 4;
  28822. end;
  28823. end
  28824. else
  28825. begin
  28826. NewSize1 := (MousePos.x - Self_.fSplitStartPos.x)* M
  28827. + Self_.fSplitStartSize;
  28828. NewSize2 := Self_.fParent.ClientWidth - NewSize1
  28829. - Self_.fBoundsRect.Right + Self_.fBoundsRect.Left
  28830. - Self_.fParent.fMargin * 4;
  28831. if Self_.fSecondControl <> nil then
  28832. begin
  28833. NewSize2 := Self_.fSecondControl.fBoundsRect.Right
  28834. - Self_.fSecondControl.fBoundsRect.Left;
  28835. if Self_.fSecondControl.FAlign = caClient then
  28836. NewSize2 := Self_.fSplitStartPos2.x
  28837. - (MousePos.x - Self_.fSplitStartPos.x)* M
  28838. - Self_.fParent.Margin * 4;
  28839. end;
  28840. end;
  28841. if (NewSize1 < Self_.fSplitMinSize1) then
  28842. begin
  28843. Dec( NewSize2, Self_.fSplitMinSize1 - NewSize1 );
  28844. NewSize1 := Self_.fSplitMinSize1;
  28845. end;
  28846. if (NewSize2 < Self_.fSplitMinSize2) then
  28847. begin
  28848. Dec( NewSize1, Self_.fSplitMinSize2 - NewSize2 );
  28849. NewSize2 := Self_.fSplitMinSize2;
  28850. end;
  28851. if NewSize1 < Self_.fSplitMinSize1 then Exit;
  28852. if NewSize2 < Self_.fSplitMinSize2 then Exit;
  28853. if assigned( Self_.fOnSplit ) then
  28854. if not Self_.fOnSplit( Self_, NewSize1, NewSize2 ) then Exit;
  28855. R := Prev.BoundsRect;
  28856. case Self_.FAlign of
  28857. caTop: R.Bottom := R.Top + NewSize1;
  28858. caBottom: R.Top := R.Bottom - NewSize1;
  28859. caRight: R.Left := R.Right - NewSize1;
  28860. else R.Right := R.Left + NewSize1;
  28861. end;
  28862. Prev.BoundsRect := R;
  28863. {$IFDEF OLD_ALIGN}
  28864. Global_Align( Self_.fParent );
  28865. {$ELSE NEW_ALIGN}
  28866. Global_Align( Self_ );
  28867. {$ENDIF}
  28868. end;
  28869. end;
  28870. {$ENDIF}
  28871. const
  28872. chkLeft=2;
  28873. chkTop=4;
  28874. chkRight=8;
  28875. chkBott=16;
  28876. {$DEFINE USE!_ASM_DODRAG}
  28877. //[FUNCTION WndProcSplitter]
  28878. {$IFDEF ASM_VERSION}
  28879. {$ELSE ASM_VERSION} //Pascal
  28880. function WndProcSplitter( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  28881. var I: Integer;
  28882. Prev: PControl;
  28883. procedure FinDrag;
  28884. begin
  28885. KillTimer( Self_.fHandle, $7B );
  28886. Self_.fDragging := False;
  28887. ReleaseCapture;
  28888. end;
  28889. {$ifdef wince}
  28890. function GetMouseCursorPos(lParam: DWORD): TPoint;
  28891. begin
  28892. Result:=Self_.Client2Screen(MakePoint(SmallInt(LOWORD(Msg.lParam)), SmallInt(HIWORD(Msg.lParam))));
  28893. end;
  28894. {$endif wince}
  28895. begin
  28896. case Msg.message of
  28897. {$ifndef wince}
  28898. WM_NCHITTEST:
  28899. begin
  28900. Rslt := DefWindowProc( Self_.fHandle, Msg.message, Msg.wParam, Msg.lParam );
  28901. if Rslt > 0 then
  28902. Rslt := HTCLIENT;
  28903. Result := True;
  28904. Exit;
  28905. end;
  28906. {$endif wince}
  28907. WM_MOUSEMOVE:
  28908. begin
  28909. Windows.SetCursor( Self_.fCursor );
  28910. DoDrag( Self_, False {$ifdef wince},GetMouseCursorPos(Msg.lParam){$endif} );
  28911. end;
  28912. WM_LBUTTONDOWN:
  28913. begin
  28914. if Self_.fParent <> nil then
  28915. begin
  28916. I := Self_.fParent.fChildren.IndexOf( Self_ );
  28917. Prev := Self_;
  28918. if I > 0 then
  28919. Prev := Self_.FParent.fChildren.fItems[ I - 1 ];
  28920. if Self_.fAlign in [ caTop, caBottom ] then
  28921. Self_.fSplitStartSize := Prev.Height
  28922. else
  28923. Self_.fSplitStartSize := Prev.Width;
  28924. if Self_.fSecondControl <> nil then
  28925. Self_.fSplitStartPos2 :=
  28926. MakePoint( Self_.fSecondControl.Width, Self_.fSecondControl.Height );
  28927. SetCapture( Self_.fHandle );
  28928. Self_.fDragging := True;
  28929. SetTimer( Self_.fHandle, $7B, 100, nil );
  28930. {$ifdef wince}
  28931. Self_.fSplitStartPos:=GetMouseCursorPos(Msg.lParam);
  28932. {$else}
  28933. GetCursorPos( Self_.fSplitStartPos );
  28934. {$endif wince}
  28935. end;
  28936. end;
  28937. WM_LBUTTONUP:
  28938. begin
  28939. DoDrag( Self_, False {$ifdef wince},GetMouseCursorPos(Msg.lParam){$endif});
  28940. FinDrag;
  28941. end;
  28942. WM_TIMER:
  28943. if Self_.fDragging and (GetAsyncKeyState( VK_ESCAPE ) < 0) then
  28944. begin
  28945. DoDrag( Self_, True {$ifdef wince},Self_.fSplitStartPos{$endif});
  28946. FinDrag;
  28947. end;
  28948. end;
  28949. Result := False;
  28950. end;
  28951. {$ENDIF ASM_VERSION}
  28952. //[END WndProcSplitter]
  28953. //[function NewSplitter]
  28954. function NewSplitter( AParent: PControl; MinSizePrev, MinSizeNext: Integer ): PControl;
  28955. begin
  28956. Result := NewSplitterEx( AParent, MinSizePrev, MinSizeNext, esLowered );
  28957. end;
  28958. //[END NewSplitter]
  28959. {$IFDEF USE_CONSTRUCTORS}
  28960. //[function NewSplitterEx]
  28961. function NewSplitterEx( AParent: PControl; MinSizePrev, MinSizeNext: Integer;
  28962. EdgeStyle: TEdgeStyle ): PControl;
  28963. begin
  28964. new( Result, CreateSplitter( AParent, MinSizePrev, MinSizeNext, EdgeStyle ) );
  28965. end;
  28966. //[END NewSplitterEx]
  28967. {$ELSE not_USE_CONSTRUCTORS}
  28968. //[FUNCTION NewSplitterEx]
  28969. {$IFDEF ASM_VERSION}
  28970. {$ELSE ASM_VERSION} //Pascal
  28971. function NewSplitterEx( AParent: PControl; MinSizePrev, MinSizeNext: Integer;
  28972. EdgeStyle: TEdgeStyle ): PControl;
  28973. var PrevCtrl: PControl;
  28974. Sz0: Integer;
  28975. begin
  28976. Result := NewPanel( AParent, EdgeStyle );
  28977. Result.fSplitMinSize1 := MinSizePrev;
  28978. Result.fSplitMinSize2 := MinSizeNext;
  28979. Result.fIsSplitter := TRUE;
  28980. Sz0 := 4;
  28981. with Result.fBoundsRect do
  28982. begin
  28983. Right := Left + Sz0;
  28984. Bottom := Top + Sz0;
  28985. end;
  28986. if AParent <> nil then
  28987. begin
  28988. if AParent.fChildren.fCount > 1 then
  28989. begin
  28990. PrevCtrl := AParent.fChildren.fItems[ AParent.fChildren.fCount - 2 ];
  28991. case PrevCtrl.FAlign of
  28992. caLeft, caRight:
  28993. begin
  28994. Result.fCursor := LoadCursor( 0, IDC_SIZEWE );
  28995. end;
  28996. caTop, caBottom:
  28997. begin
  28998. Result.fCursor := LoadCursor( 0, IDC_SIZENS );
  28999. end;
  29000. end;
  29001. Result.Align := PrevCtrl.FAlign;
  29002. end;
  29003. end;
  29004. Result.AttachProc( WndProcSplitter );
  29005. {$IFDEF GRAPHCTL_XPSTYLES}
  29006. Result.fClassicTransparent := Result.fTransparent;
  29007. Attach_WM_THEMECHANGED(Result);
  29008. XP_Themes_For_Splitter(Result);
  29009. {$ENDIF}
  29010. end;
  29011. {$ENDIF ASM_VERSION}
  29012. //[END NewSplitterEx]
  29013. {$ENDIF USE_CONSTRUCTORS}
  29014. //===================== MDI client window control =============//
  29015. {$ifdef win32}
  29016. //[procedure DestroyMDIChildren]
  29017. procedure DestroyMDIChildren( Form: PControl );
  29018. var MDIClient: PControl;
  29019. I: Integer;
  29020. Ch: PControl;
  29021. begin
  29022. MDIClient := Form.fMDIClient;
  29023. MDIClient.fMDIDestroying := TRUE;
  29024. if MDIClient = nil then Exit;
  29025. if MDIClient.fMDIChildren <> nil then
  29026. for I := MDIClient.fMDIChildren.Count - 1 downto 0 do
  29027. begin
  29028. Ch := MDIClient.fMDIChildren.fItems[ I ];
  29029. if Ch.fHandle <> 0 then
  29030. MDIClient.Perform( WM_MDIDESTROY, Ch.fHandle, 0 );
  29031. end;
  29032. MDIClient.fMDIChildren.Free;
  29033. MDIClient.fMDIChildren := nil;
  29034. if Form.fMenu <> 0 then
  29035. begin
  29036. MDIClient.Perform( WM_MDISETMENU, 0, 0 );
  29037. MDIClient.Perform( WM_MDIREFRESHMENU, 0, 0 );
  29038. DrawMenuBar( Form.fHandle );
  29039. Form.fMenuObj.Free;
  29040. Form.fMenuObj := nil;
  29041. end;
  29042. Form.fMDIClient := nil;
  29043. MDIClient.Free;
  29044. end;
  29045. //[function ProcMDIAccel]
  29046. function ProcMDIAccel( Applet: PControl; var Msg: TMsg ): Boolean;
  29047. var Form: PControl;
  29048. begin
  29049. Result := FALSE;
  29050. if (Msg.message >= WM_KEYFIRST) and (Msg.message <= WM_KEYLAST) then
  29051. begin
  29052. Form := Applet.ActiveControl;
  29053. if Form <> nil then
  29054. begin
  29055. if Form.IsMDIChild then
  29056. Form := Form.Parent;
  29057. Form := Form.ParentForm;
  29058. if (Form <> nil) and (Form.MDIClient <> nil) then
  29059. Result := TranslateMDISysAccel( Form.MDIClient.fHandle, Msg );
  29060. end;
  29061. end;
  29062. end;
  29063. //[function CallDefFrameProc]
  29064. function CallDefFrameProc( Wnd: HWnd; Msg: Integer; wParam, lParam: Integer ): Integer;
  29065. {$ifdef wince}cdecl{$else}stdcall{$endif};
  29066. var Form: PControl;
  29067. begin
  29068. {$IFDEF USE_PROP}
  29069. Form := Pointer( GetProp( Wnd, ID_SELF ) );
  29070. {$ELSE}
  29071. Form := Pointer( GetWindowLong( Wnd, GWL_USERDATA ) );
  29072. {$ENDIF}
  29073. if Form <> nil then
  29074. Form := Form.ParentForm;
  29075. if (Form <> nil) and (Form.fMDIClient <> nil) then
  29076. Result := DefFrameProc( Wnd, Form.fMDIClient.fHandle, Msg, wParam, lParam )
  29077. else
  29078. Result := DefWindowProc( Wnd, Msg, wParam, lParam );
  29079. end;
  29080. //[function WndFuncMDIClient]
  29081. function WndFuncMDIClient( Wnd: HWnd; Msg, wParam, lParam: Integer ): Integer;
  29082. {$ifdef wince}cdecl{$else}stdcall{$endif};
  29083. var C: PControl;
  29084. M: TMsg;
  29085. begin
  29086. {$IFDEF USE_PROP}
  29087. C := Pointer( GetProp( Wnd, ID_SELF ) );
  29088. {$ELSE}
  29089. C := Pointer( GetWindowLong( Wnd, GWL_USERDATA ) );
  29090. {$ENDIF}
  29091. if C <> nil then
  29092. begin
  29093. M.hwnd := Wnd;
  29094. M.message := Msg;
  29095. M.wParam := wParam;
  29096. M.lParam := lParam;
  29097. Result := C.WndProc( M );
  29098. end
  29099. else
  29100. Result := DefWindowProc( Wnd, Msg, wParam, lParam );
  29101. end;
  29102. //[function ShowMDIClientEdge]
  29103. function ShowMDIClientEdge( MDIClient: PControl ): Boolean;
  29104. var ShowEdge: Boolean;
  29105. I: Integer;
  29106. Ch: PControl;
  29107. ExStyle: Integer;
  29108. begin
  29109. Result := FALSE;
  29110. ShowEdge := TRUE;
  29111. if MDIClient.fMDIChildren.Count > 0 then
  29112. for I := 0 to MDIClient.fMDIChildren.Count-1 do
  29113. begin
  29114. Ch := MDIClient.fMDIChildren.fItems[ I ];
  29115. if IsZoomed( Ch.fHandle ) then
  29116. begin
  29117. ShowEdge := FALSE;
  29118. break;
  29119. end;
  29120. end;
  29121. ExStyle := MDIClient.ExStyle;
  29122. if ShowEdge then
  29123. if ExStyle and WS_EX_CLIENTEDGE = 0 then
  29124. ExStyle := ExStyle or WS_EX_CLIENTEDGE
  29125. else
  29126. Exit
  29127. else if ExStyle and WS_EX_CLIENTEDGE <> 0 then
  29128. ExStyle := ExStyle and not WS_EX_CLIENTEDGE
  29129. else
  29130. Exit;
  29131. MDIClient.ExStyle := ExStyle;
  29132. Result := TRUE;
  29133. end;
  29134. //[function WndProcMDIClient]
  29135. function WndProcMDIClient( MDIClient: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29136. begin
  29137. if not MDIClient.fMDIDestroying then
  29138. case Msg.message of
  29139. $3f:
  29140. begin
  29141. PostMessage( MDIClient.fHandle, CM_MDIClientShowEdge, 0, 0 );
  29142. end;
  29143. CM_MDIClientShowEdge:
  29144. begin
  29145. ShowMDIClientEdge( MDIClient );
  29146. end;
  29147. WM_NCHITTEST: // not necessary though
  29148. begin
  29149. Rslt := DefWindowProc( MDIClient.fHandle, WM_NCHITTEST, Msg.wParam, Msg.lParam );
  29150. if Rslt = HTCLIENT then Rslt := HTTRANSPARENT;
  29151. end;
  29152. WM_WINDOWPOSCHANGING:
  29153. begin
  29154. MDIClient.Perform( WM_SETREDRAW, 0, 0 );
  29155. end;
  29156. WM_WINDOWPOSCHANGED:
  29157. begin
  29158. Global_Align( {$IFDEF OLD_ALIGN}MDIClient.Parent{$ELSE}MDIClient{$ENDIF} );
  29159. MDIClient.Invalidate;
  29160. MDIClient.Parent.Invalidate;
  29161. MDIClient.Perform( WM_SETREDRAW, 1, 0 );
  29162. PostMessage( MDIClient.fHandle, CM_INVALIDATE, 0, 0 );
  29163. end;
  29164. CM_INVALIDATE:
  29165. begin
  29166. MDIClient.InvalidateNC( TRUE );
  29167. MDIClient.InvalidateEx;
  29168. end;
  29169. end;
  29170. Result := FALSE;
  29171. end;
  29172. // function added by Thaddy de Koning to fix MDI behaviour
  29173. //[function WndProcParentNotifyMouseLDown]
  29174. function WndProcParentNotifyMouseLDown( Sender: PControl; var Msg: TMsg;
  29175. var Rslt: Integer ): Boolean;
  29176. begin
  29177. Result := FALSE;
  29178. if (Sender.IsMDIChild) and (Msg.message = WM_PARENTNOTIFY) and
  29179. (LOWORD(msg.wparam)=WM_LBUTTONDOWN) then
  29180. BringWindowToTop( Sender.Handle );
  29181. end;
  29182. //[function NewMDIClient]
  29183. function NewMDIClient( AParent: PControl; WindowMenu: THandle ): PControl;
  29184. var F: PControl;
  29185. CCS: TClientCreateStruct;
  29186. PrntWin: HWnd;
  29187. begin
  29188. F := nil;
  29189. PrntWin := 0;
  29190. if AParent <> nil then
  29191. begin
  29192. F := AParent.ParentForm;
  29193. if F <> nil then
  29194. begin
  29195. F.Add2AutoFreeEx( TObjectMethod( MakeMethod( F, @ DestroyMDIChildren ) ) );
  29196. F.GetWindowHandle; // must be created before MDI client creation
  29197. F.fDefWndProc := @CallDefFrameProc;
  29198. end;
  29199. PrntWin := AParent.GetWindowHandle;
  29200. end;
  29201. Applet.fExMsgProc := ProcMDIAccel;
  29202. Result := _NewControl( AParent, 'MDICLIENT',
  29203. WS_CHILD or WS_CLIPCHILDREN or WS_VSCROLL or WS_HSCROLL or
  29204. WS_VISIBLE or WS_TABSTOP or MDIS_ALLCHILDSTYLES, TRUE, nil );
  29205. Result.fMDIChildren := NewList;
  29206. Result.fExStyle := WS_EX_CLIENTEDGE;
  29207. CCS.hWindowMenu := WindowMenu;
  29208. CCS.idFirstChild := $FF00;
  29209. Result.fHandle := CreateWindowEx( WS_EX_CLIENTEDGE, 'MDICLIENT', nil,
  29210. WS_CHILD or WS_CLIPCHILDREN or WS_VSCROLL or WS_HSCROLL or
  29211. WS_VISIBLE or WS_TABSTOP,
  29212. 0, 0, 0, 0, PrntWin, 0, hInstance, @ CCS );
  29213. Result.fDefWndProc := Pointer( GetWindowLong( Result.fHandle, GWL_WNDPROC ) );
  29214. SetWindowLong( Result.fHandle, GWL_WNDPROC, Integer( @WndFuncMDIClient ) );
  29215. {$IFDEF USE_PROP}
  29216. SetProp( Result.fHandle, ID_SELF, Integer( Result ) );
  29217. {$ELSE}
  29218. SetWindowLong( Result.fHandle, GWL_USERDATA, Integer( Result ) );
  29219. {$ENDIF}
  29220. if F <> nil then
  29221. F.fMDIClient := Result;
  29222. Result.AttachProc( WndProcMDIClient );
  29223. Result.GetWindowHandle;
  29224. Applet.AttachProc( WndProcParentNotifyMouseLDown );
  29225. end;
  29226. //===================== MDI child window object ==============//
  29227. //[function MDIChildFunc]
  29228. function MDIChildFunc( Wnd: HWnd; Msg: DWord; wParam, lParam: Integer ): Integer;
  29229. {$ifdef wince}cdecl{$else}stdcall{$endif};
  29230. var C: PControl;
  29231. M: TMsg;
  29232. begin
  29233. {$IFDEF USE_PROP}
  29234. C := Pointer( GetProp( Wnd, ID_SELF ) );
  29235. {$ELSE}
  29236. C := Pointer( GetWindowLong( Wnd, GWL_USERDATA ) );
  29237. {$ENDIF}
  29238. if C <> nil then
  29239. begin
  29240. M.hwnd := Wnd;
  29241. M.message := Msg;
  29242. M.wParam := wParam;
  29243. M.lParam := lParam;
  29244. Result := C.WndProc( M );
  29245. end
  29246. else
  29247. Result := DefMDIChildProc( Wnd, Msg, wParam, lParam );
  29248. end;
  29249. //[function Pass2DefMDIChildProc]
  29250. function Pass2DefMDIChildProc( Sender_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29251. begin
  29252. Result := FALSE;
  29253. if Sender_ = nil then Exit;
  29254. if Sender_.Parent = nil then Exit;
  29255. if Sender_.Parent.fDestroying then Exit;
  29256. if (Msg.message = WM_SYSCOMMAND) or (Msg.message = WM_CHILDACTIVATE) or
  29257. (Msg.message = WM_SETFOCUS) or (Msg.message = WM_SIZE) or
  29258. (Msg.message = WM_MOVE) or (Msg.message = WM_MENUCHAR) or
  29259. (Msg.message = WM_GETMINMAXINFO) {and IsZoomed( Sender_.fHandle ) and (Msg.hwnd = Sender_.fHandle) -- doesn't work -- } then
  29260. begin
  29261. Rslt := DefMDIChildProc( Msg.hwnd, Msg.message, Msg.lParam, Msg.wParam );
  29262. Result := TRUE;
  29263. end;
  29264. end;
  29265. //[function WndProcMDIChild]
  29266. function WndProcMDIChild( MDIChild: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29267. var ClientWnd: HWnd;
  29268. MDIClient: PControl;
  29269. MDIForm: PControl;
  29270. begin
  29271. Result := FALSE;
  29272. MDIClient := MDIChild.Parent;
  29273. if MDIClient = nil then Exit;
  29274. ClientWnd := MDIClient.fHandle;
  29275. if ClientWnd = 0 then Exit;
  29276. case Msg.message of
  29277. WM_DESTROY:
  29278. begin
  29279. MDIClient.fMDIChildren.Remove( MDIChild );
  29280. MDIForm := MDIClient.ParentForm;
  29281. if MDIForm <> nil then
  29282. if MDIForm.fHandle <> 0 then
  29283. DrawMenuBar( MDIForm.fHandle );
  29284. MDIChild.Free;
  29285. Result := TRUE;
  29286. Exit;
  29287. end;
  29288. end;
  29289. if MDIChild.fNotAvailable then
  29290. begin
  29291. MDIChild.fNotAvailable := FALSE;
  29292. MDIChild.Invalidate;
  29293. end;
  29294. end;
  29295. //[procedure CreateMDIChildExt]
  29296. procedure CreateMDIChildExt( Sender: PControl );
  29297. var F: PControl;
  29298. begin
  29299. F := Sender.Parent;
  29300. if F <> nil then
  29301. F := F.ParentForm;
  29302. if F <> nil then
  29303. DrawMenuBar( F.fHandle );
  29304. end;
  29305. //[function NewMDIChild]
  29306. function NewMDIChild( AParent: PControl; const ACaption: String ): PControl;
  29307. var MDIClient: PControl;
  29308. begin
  29309. Assert( (AParent <> nil) and (AParent.ParentForm <> nil) and
  29310. (AParent.ParentForm.fMDIClient <> nil), 'Error creating MDI child' );
  29311. MDIClient := AParent.ParentForm.fMDIClient;
  29312. Result := NewForm( MDIClient, ACaption );
  29313. Result.fIsMDIChild := TRUE;
  29314. Result.fMenu := CtlIdCount;
  29315. Inc( CtlIdCount );
  29316. MDIClient.fMDIChildren.Add( Result );
  29317. Result.fExStyle := Result.fExStyle or WS_EX_MDICHILD;
  29318. Result.fWndFunc := @ MDIChildFunc;
  29319. Result.fDefWndProc := @DefMDIChildProc;
  29320. Result.fPass2DefProc := Pass2DefMDIChildProc;
  29321. Result.AttachProc( WndProcMDIChild );
  29322. Result.SubClassName := 'MDI_chld';
  29323. Result.fNotAvailable := TRUE;
  29324. Result.fCreateWndExt := CreateMDIChildExt;
  29325. end;
  29326. {$endif win32}
  29327. //===================== Gradient panel ========================//
  29328. {$IFDEF USE_CONSTRUCTORS}
  29329. //[function NewGradientPanel]
  29330. function NewGradientPanel( AParent: PControl; Color1, Color2: TColor ): PControl;
  29331. begin
  29332. new( Result, CreateGradientPanel( AParent, Color1, Color2 ) );
  29333. end;
  29334. //[END NewGradientPanel]
  29335. {$ELSE not_USE_CONSTRUCTORS}
  29336. //[FUNCTION NewGradientPanel]
  29337. {$IFDEF ASM_VERSION}
  29338. {$ELSE ASM_VERSION} //Pascal
  29339. function NewGradientPanel( AParent: PControl; Color1, Color2: TColor ): PControl;
  29340. begin
  29341. Result := NewLabel( AParent, '' );
  29342. Result.AttachProc( WndProcGradient );
  29343. Result.fColor2 := Color2;
  29344. Result.fColor1 := Color1;
  29345. with Result.fBoundsRect do
  29346. begin
  29347. Right := Left + 40;
  29348. Bottom := Top + 40;
  29349. end;
  29350. end;
  29351. {$ENDIF ASM_VERSION}
  29352. //[END NewGradientPanel]
  29353. {$ENDIF USE_CONSTRUCTORS}
  29354. {$IFDEF USE_CONSTRUCTORS}
  29355. //[function NewGradientPanelEx]
  29356. function NewGradientPanelEx( AParent: PControl; Color1, Color2: TColor;
  29357. Style: TGradientStyle; Layout: TGradientLayout ): PControl;
  29358. begin
  29359. new( Result, CreateGradientPanelEx( AParent, Color1, Color2,
  29360. Style, Layout ) );
  29361. end;
  29362. //[END NewGradientPanelEx]
  29363. {$ELSE not_USE_CONSTRUCTORS}
  29364. //[FUNCTION NewGradientPanelEx]
  29365. {$IFDEF ASM_VERSION}
  29366. {$ELSE ASM_VERSION} //Pascal
  29367. function NewGradientPanelEx( AParent: PControl; Color1, Color2: TColor;
  29368. Style: TGradientStyle; Layout: TGradientLayout ): PControl;
  29369. begin
  29370. Result := NewLabel( AParent, '' );
  29371. Result.AttachProc( WndProcGradientEx );
  29372. Result.fColor2 := Color2;
  29373. Result.fColor1 := Color1;
  29374. Result.fGradientStyle := Style;
  29375. Result.fGradientLayout := Layout;
  29376. with Result.fBoundsRect do
  29377. begin
  29378. Right := Left + 40;
  29379. Bottom := Top + 40;
  29380. end;
  29381. end;
  29382. {$ENDIF ASM_VERSION}
  29383. //[END NewGradientPanelEx]
  29384. {$ENDIF USE_CONSTRUCTORS}
  29385. //===================== Edit box ========================//
  29386. const Editflags: array [ TEditOption ] of Integer = (
  29387. not (ES_AUTOHSCROLL or WS_HSCROLL),
  29388. not (es_AutoVScroll or WS_VSCROLL),
  29389. es_Lowercase, es_Multiline,
  29390. es_NoHideSel, es_OemConvert, es_Password, es_Readonly,
  29391. es_UpperCase, es_WantReturn, 0, es_Number );
  29392. {$IFDEF USE_CONSTRUCTORS}
  29393. //[function NewEditbox]
  29394. function NewEditbox( AParent: PControl; Options: TEditOptions ) : PControl;
  29395. begin
  29396. new( Result, CreateEditbox( AParent, Options ) );
  29397. end;
  29398. //[END NewEditbox]
  29399. {$ELSE not_USE_CONSTRUCTORS}
  29400. //[FUNCTION NewEditBox]
  29401. {$IFDEF ASM_VERSION}
  29402. {$ELSE ASM_VERSION} //Pascal
  29403. function NewEditbox( AParent: PControl; Options: TEditOptions ) : PControl;
  29404. var Flags: Integer;
  29405. begin
  29406. Flags := MakeFlags( @Options, EditFlags );
  29407. if not(eoMultiline in Options) then
  29408. Flags := Flags and not(WS_HSCROLL or WS_VSCROLL);
  29409. Result := _NewControl( AParent, 'EDIT', WS_VISIBLE or WS_CHILD or WS_TABSTOP
  29410. or WS_BORDER or Flags, True, @EditActions );
  29411. with Result.fBoundsRect do
  29412. begin
  29413. Right := Left + 100;
  29414. Bottom := Top + 22;
  29415. if eoMultiline in Options then
  29416. begin
  29417. Right := Right + 100;
  29418. Bottom := Top + 200;
  29419. Result.fIgnoreDefault := TRUE;
  29420. end;
  29421. end;
  29422. Result.fLookTabKeys := [ tkTab, tkUpDown, tkPageUpPageDn ];
  29423. if eoMultiline in Options then
  29424. Result.fLookTabKeys := [ tkTab ];
  29425. if eoWantTab in Options then
  29426. Result.fLookTabKeys := Result.fLookTabKeys - [ tkTab ];
  29427. end;
  29428. {$ENDIF ASM_VERSION}
  29429. //[END NewEditBox]
  29430. {$ENDIF USE_CONSTRUCTORS}
  29431. //===================== List box ========================//
  29432. const ListFlags: array[TListOption] of Integer = (
  29433. LBS_DISABLENOScroll, not LBS_ExtendedSel,
  29434. LBS_MultiColumn or WS_HSCROLL,
  29435. LBS_MultiPLESel,
  29436. LBS_NoIntegralHeight, LBS_NoSel, LBS_Sort, LBS_USETabstops,
  29437. not LBS_HASSTRINGS, LBS_NODATA, LBS_OWNERDRAWFIXED,
  29438. LBS_OWNERDRAWVARIABLE, WS_HSCROLL );
  29439. {$IFDEF USE_CONSTRUCTORS}
  29440. //[function NewListbox]
  29441. function NewListbox( AParent: PControl; Options: TListOptions ): PControl;
  29442. begin
  29443. new( Result, CreateListbox( AParent, Options ) );
  29444. end;
  29445. //[END NewListbox]
  29446. {$ELSE not_USE_CONSTRUCTORS}
  29447. //[FUNCTION NewListbox]
  29448. {$IFDEF ASM_UNICODE}
  29449. {$ELSE ASM_VERSION} //Pascal
  29450. function NewListbox( AParent: PControl; Options: TListOptions ): PControl;
  29451. var Flags: Integer;
  29452. begin
  29453. Flags := MakeFlags( @Options, ListFlags );
  29454. Result := _NewControl( AParent, 'LISTBOX', WS_VISIBLE or WS_CHILD or WS_TABSTOP
  29455. or WS_BORDER or WS_VSCROLL
  29456. or LBS_NOTIFY or Flags, True, @ListActions );
  29457. with Result.fBoundsRect do
  29458. begin
  29459. Right := Right + 100;
  29460. Bottom := Top + 200;
  29461. end;
  29462. Result.fColor := clWindow;
  29463. Result.fLookTabKeys := [ tkTab, tkLeftRight ];
  29464. end;
  29465. {$ENDIF ASM_VERSION}
  29466. //[END NewListbox]
  29467. {$ENDIF USE_CONSTRUCTORS}
  29468. //===================== Combo box ========================//
  29469. //[FUNCTION ComboboxDropDown]
  29470. {$IFNDEF USE_DROPDOWNCOUNT}
  29471. {$IFDEF ASM_VERSION}
  29472. {$ELSE ASM_VERSION} //Pascal
  29473. procedure ComboboxDropDown( Sender: PObj );
  29474. var
  29475. CB: PControl;
  29476. IC: Integer;
  29477. begin
  29478. CB := PControl( Sender );
  29479. IC := CB.Count;
  29480. if IC > 8 then IC := 8;
  29481. if IC < 1 then IC := 1;
  29482. {$ifdef wince}
  29483. SetWindowPos( CB.Handle, 0, 0, 0, CB.Width, CB.Height * (IC + 1) + 2,
  29484. SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or
  29485. SWP_SHOWWINDOW);
  29486. {$else}
  29487. SetWindowPos( CB.Handle, 0, 0, 0, CB.Width, CB.Height * (IC + 1) + 2,
  29488. SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE + SWP_NOREDRAW +
  29489. SWP_HIDEWINDOW);
  29490. SetWindowPos( CB.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE
  29491. + SWP_NOZORDER + SWP_NOACTIVATE
  29492. + SWP_NOREDRAW + SWP_SHOWWINDOW);
  29493. {$endif wince}
  29494. if assigned( CB.fOnDropDown ) then
  29495. CB.fOnDropDown( CB );
  29496. end;
  29497. {$ENDIF ASM_VERSION}
  29498. {$ELSE newcode}
  29499. procedure ComboboxDropDown( Sender: PObj );
  29500. var
  29501. CB: PControl;
  29502. Count: Integer;
  29503. DropDownCount: Integer;
  29504. ItemHeight: Integer;
  29505. begin
  29506. CB := PControl(Sender);
  29507. Count := CB.Count;
  29508. DropDownCount := CB.DropDownCount;
  29509. if (Count > DropDownCount) then
  29510. Count := DropDownCount;
  29511. if (Count < 1) then
  29512. Count := 1;
  29513. ItemHeight := CB.Perform(CB_GETITEMHEIGHT, 0, 0);
  29514. {$ifdef wince}
  29515. SetWindowPos(
  29516. CB.Handle, 0, 0, 0, CB.Width, ItemHeight * Count + CB.Height + 2,
  29517. SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or SWP_SHOWWINDOW);
  29518. {$else}
  29519. SetWindowPos(
  29520. CB.Handle, 0, 0, 0, CB.Width, ItemHeight * Count + CB.Height + 2,
  29521. SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOREDRAW or SWP_HIDEWINDOW);
  29522. SetWindowPos(
  29523. CB.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or
  29524. SWP_NOACTIVATE or SWP_NOREDRAW or SWP_SHOWWINDOW);
  29525. {$endif wince}
  29526. if Assigned(CB.fOnDropDown) then
  29527. CB.fOnDropDown(CB);
  29528. end;
  29529. {$ENDIF USE_DROPDOWNCOUNT}
  29530. //[END ComboboxDropDown]
  29531. //[function WndFuncCombo]
  29532. function WndFuncCombo( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  29533. : Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  29534. var Combo, Form: PControl;
  29535. ParentWnd : HWnd;
  29536. MsgStruct: TMsg;
  29537. PrevProc:Pointer; //********************************** Added By M.Gerasimov
  29538. begin
  29539. Combo := nil;
  29540. ParentWnd := GetParent( W );
  29541. if ParentWnd <> 0 then
  29542. {$IFDEF USE_PROP}
  29543. Combo := Pointer( GetProp( ParentWnd, ID_SELF ) );
  29544. {$ELSE}
  29545. Combo := Pointer( GetWindowLong( ParentWnd, GWL_USERDATA ) );
  29546. {$ENDIF}
  29547. if Combo <> nil then
  29548. begin
  29549. MsgStruct.hwnd := Combo.fHandle;
  29550. MsgStruct.message := Msg;
  29551. MsgStruct.wParam := wParam;
  29552. MsgStruct.lParam := lParam;
  29553. Form := Combo.ParentForm;
  29554. if fGlobalProcKeybd( Combo, MsgStruct, Result ) then Exit;
  29555. if W <> Combo.FHandle then
  29556. begin
  29557. if Assigned( Applet ) and Assigned( Applet.OnMessage ) then
  29558. if Applet.OnMessage( MsgStruct, Result ) then Exit;
  29559. if (Applet <> Form) and (Form <> nil) then
  29560. if Assigned( Form.OnMessage ) then
  29561. if Form.OnMessage( MsgStruct, Result ) then Exit;
  29562. end;
  29563. if //(GetFocus = W) and
  29564. (Msg = WM_KEYDOWN) or (Msg = WM_KEYUP) or (Msg = WM_CHAR) then
  29565. begin
  29566. Result := 0;
  29567. if (wParam = VK_TAB) then
  29568. begin
  29569. case Msg of
  29570. WM_KEYDOWN:
  29571. if Assigned( Combo.fGotoControl ) and
  29572. Combo.fGotoControl( Combo, wParam, FALSE ) then Exit;
  29573. else Exit;
  29574. end;
  29575. end
  29576. else
  29577. if (Msg = WM_CHAR) and ((wParam = VK_ESCAPE) or (wParam = VK_RETURN)) then
  29578. begin
  29579. if Combo.Perform( CB_GETDROPPEDSTATE, 0, 0 ) <> 0 then
  29580. begin
  29581. Combo.Perform( CB_SHOWDROPDOWN, 0, 0 );
  29582. if wParam = VK_ESCAPE then
  29583. Combo.Perform( CB_SETCURSEL, Combo.fCurIdxAtDrop, 0 );
  29584. Combo.fWndProcKeybd( Combo, MsgStruct, Result );
  29585. Exit;
  29586. end
  29587. {$IFDEF ESC_CLOSE_DIALOGS}
  29588. //---------------------------------Babenko Alexey--------------------------
  29589. else
  29590. if (wparam = VK_ESCAPE) then
  29591. if (combo.ParentForm.ExStyle and WS_EX_DLGMODALFRAME) <> 0 then begin
  29592. SendMessage(combo.ParentForm.Handle, WM_CLOSE, 0, 0);
  29593. exit;
  29594. end;
  29595. {$ENDIF}
  29596. end;
  29597. Combo.fWndProcKeybd( Combo, MsgStruct, Result );
  29598. end
  29599. else
  29600. if Msg = WM_SETFOCUS then
  29601. begin
  29602. if Form <> nil then Form.fCurrentControl := Combo;
  29603. end;
  29604. MsgStruct.hwnd := W;
  29605. //********************************************************* Added By M.Gerasimov
  29606. PrevProc:=Pointer(GetProp( W, ID_PREVPROC ));
  29607. if PrevProc <> Nil then
  29608. Result := CallWindowProc( PrevProc , W, MsgStruct.message,
  29609. MsgStruct.wParam, MsgStruct.lParam )
  29610. else
  29611. Result:=0;
  29612. //*********************************************************
  29613. end
  29614. else
  29615. Result := DefWindowProc( W, Msg, wParam, lParam );
  29616. end;
  29617. //[PROCEDURE CreateComboboxWnd]
  29618. {$IFDEF ASM_UNICODE}
  29619. {$ELSE ASM_VERSION} //Pascal
  29620. procedure CreateComboboxWnd( Combo: PControl );
  29621. var W : HWND;
  29622. PrevProc: DWORD;
  29623. begin
  29624. W := GetWindow( Combo.fHandle, GW_CHILD );
  29625. {if W <> 0 then
  29626. W := GetWindow( W, GW_HWNDNEXT );}
  29627. while W <> 0 do
  29628. begin
  29629. PrevProc :=
  29630. SetWindowLong( W, GWL_WNDPROC, Longint( @WndFuncCombo ) );
  29631. SetProp( W, ID_PREVPROC, PrevProc ); //
  29632. W := GetWindow( W, GW_HWNDNEXT );
  29633. end;
  29634. end;
  29635. {$ENDIF ASM_VERSION}
  29636. //[END CreateComboboxWnd]
  29637. //[procedure RemoveChldPrevProc]
  29638. procedure RemoveChldPrevProc( fHandle: HWnd );
  29639. var Chld: HWnd;
  29640. begin
  29641. Chld := GetWindow( fHandle, GW_CHILD );
  29642. while Chld <> 0 do
  29643. begin
  29644. if GetProp( Chld, ID_PREVPROC ) <> 0 then
  29645. RemoveProp(Chld, ID_PREVPROC);
  29646. Chld := GetWindow( Chld, GW_HWNDNEXT );
  29647. end;
  29648. end;
  29649. //[function WndProcCombo]
  29650. function WndProcCombo( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29651. begin
  29652. Result := FALSE;
  29653. if (Msg.message >= WM_CTLCOLORMSGBOX) and (Msg.message <= WM_CTLCOLORSTATIC) then
  29654. begin
  29655. Rslt := Sender.Perform( Msg.message + CN_BASE, Msg.wParam, Msg.lParam );
  29656. Result := TRUE;
  29657. end
  29658. else
  29659. if (Msg.message >= CN_CTLCOLORMSGBOX) and (Msg.message <= CN_CTLCOLORSTATIC) then
  29660. begin
  29661. if Sender.fTransparent then
  29662. case Msg.message of
  29663. CN_CTLCOLORLISTBOX:
  29664. begin
  29665. SetBkMode( Msg.wParam, Windows.OPAQUE );
  29666. SetBkColor(Msg.WParam, Color2RGB( Sender.fColor ) );
  29667. Rslt := Global_GetCtlBrushHandle( Sender );
  29668. Result := TRUE;
  29669. end;
  29670. end;
  29671. end
  29672. else
  29673. if Msg.message = CM_COMMAND then
  29674. begin
  29675. case HiWord( Msg.wParam ) of
  29676. CBN_DROPDOWN:
  29677. begin
  29678. Sender.fDropped := True;
  29679. Sender.fCurIdxAtDrop := Sender.CurIndex;
  29680. Sender.fDropDownProc( Sender );
  29681. end;
  29682. CBN_CLOSEUP:
  29683. begin
  29684. Sender.fDropped := False;
  29685. if Assigned( Sender.fOnCloseUp ) then Sender.fOnCloseUp( Sender );
  29686. end;
  29687. CBN_SELCHANGE:
  29688. begin
  29689. PostMessage( Sender.fHandle, CM_COMMAND, CM_CBN_SELCHANGE shl 16, 0 );
  29690. end;
  29691. end;
  29692. end
  29693. else
  29694. if Msg.message = WM_DESTROY then
  29695. RemoveChldPrevProc( Sender.Handle );
  29696. end;
  29697. const ComboFlags: array[ TComboOption ] of Integer = (
  29698. CBS_DROPDOWNLIST, not CBS_AUTOHScroll,
  29699. CBS_DISABLENOSCROLL, CBS_LowerCase, CBS_NoIntegralHeight,
  29700. CBS_OemConvert, CBS_Sort, CBS_UpperCase, {$ifndef wince}
  29701. CBS_OWNERDRAWFIXED, CBS_OWNERDRAWVARIABLE, CBS_SIMPLE {$else} 0,0,0 {$endif wince} );
  29702. {$IFDEF USE_CONSTRUCTORS}
  29703. //[function NewCombobox]
  29704. function NewCombobox( AParent: PControl; Options: TComboOptions ): PControl;
  29705. begin
  29706. new( Result, CreateCombobox( AParent, Options ) );
  29707. end;
  29708. {$ELSE not_USE_CONSTRUCTORS}
  29709. //[FUNCTION NewCombobox]
  29710. {$IFDEF ASM_VERSION}
  29711. {$ELSE ASM_VERSION} //Pascal
  29712. function NewCombobox( AParent: PControl; Options: TComboOptions ): PControl;
  29713. var Flags: Integer;
  29714. begin
  29715. Flags := MakeFlags( @Options, ComboFlags );
  29716. {$ifndef wince}
  29717. if not LongBool( Flags and CBS_SIMPLE ) then
  29718. {$endif wince}
  29719. Flags := Flags or CBS_DROPDOWN;
  29720. Result := _NewControl( AParent, 'COMBOBOX',
  29721. WS_VISIBLE
  29722. or WS_CHILD
  29723. or WS_VSCROLL
  29724. or CBS_HASSTRINGS or WS_TABSTOP
  29725. or Flags
  29726. , True, @ComboActions );
  29727. //Result.fCannotDoubleBuf := TRUE;
  29728. Result.fCreateWndExt := CreateComboboxWnd;
  29729. Result.fDropDownProc := ComboboxDropDown;
  29730. Result.fClsStyle := Result.fClsStyle or CS_DBLCLKS;
  29731. with Result.fBoundsRect do
  29732. begin
  29733. Right := Left + 100;
  29734. Bottom := Top + 22;
  29735. end;
  29736. Result.fLookTabKeys := [ tkTab ];
  29737. if coReadOnly in Options then
  29738. Result.fLookTabKeys := [ tkTab, tkLeftRight ];
  29739. Result.AttachProc( @ WndProcCombo );
  29740. {$IFDEF USE_DROPDOWNCOUNT}
  29741. Result.DropDownCount := 8;
  29742. {$ENDIF}
  29743. end;
  29744. {$ENDIF ASM_VERSION}
  29745. //[END NewCombobox]
  29746. {$ENDIF USE_CONSTRUCTORS}
  29747. //[FUNCTION WndProcResiz]
  29748. {$IFDEF ASM_VERSION}
  29749. {$ELSE ASM_VERSION} //Pascal
  29750. function WndProcResize(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29751. var I: Integer;
  29752. C: PControl;
  29753. begin
  29754. if Msg.message = WM_SIZE then
  29755. begin
  29756. for I:= 0 to Self_.fChildren.fCount - 1 do
  29757. begin
  29758. C := Self_.fChildren.fItems[ I ];
  29759. C.Perform( CM_SIZE, 0, 0 );
  29760. end;
  29761. end;
  29762. Result := False; // don't stop further processing
  29763. end;
  29764. {$ENDIF ASM_VERSION}
  29765. //[END WndProcResiz]
  29766. //[FUNCTION WndProcParentResize]
  29767. {$IFDEF ASM_VERSION}
  29768. {$ELSE ASM_VERSION} //Pascal
  29769. function WndProcParentResize(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29770. begin
  29771. Result := False;
  29772. case Msg.message of
  29773. CM_SIZE:
  29774. begin
  29775. Self_.Perform( WM_SIZE, 0, 0 );
  29776. end;
  29777. end;
  29778. end;
  29779. {$ENDIF ASM_VERSION}
  29780. //[END WndProcParentResize]
  29781. //[procedure InitCommonControlCommonNotify]
  29782. procedure InitCommonControlCommonNotify( Ctrl: PControl );
  29783. var AParent: PControl;
  29784. begin
  29785. Ctrl.fIsCommonControl := True;
  29786. AParent := Ctrl.Parent;
  29787. if AParent <> nil then
  29788. begin
  29789. Ctrl.AttachProc( WndProcCommonNotify );
  29790. AParent.AttachProc( WndProcNotify );
  29791. end;
  29792. end;
  29793. //[procedure InitCommonControlSizeNotify]
  29794. procedure InitCommonControlSizeNotify( Ctrl: PControl );
  29795. var AParent: PControl;
  29796. begin
  29797. AParent := Ctrl.Parent;
  29798. if AParent <> nil then
  29799. begin
  29800. Ctrl.AttachProc( WndProcParentResize );
  29801. AParent.AttachProc( WndProcResize );
  29802. end;
  29803. end;
  29804. //[function _NewCommonControl]
  29805. function _NewCommonControl( AParent: PControl; ClassName: PKOLChar; Style: DWORD;
  29806. Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  29807. begin
  29808. {*************} DoInitCommonControls( ICC_WIN95_CLASSES );
  29809. Result := _NewControl( AParent, ClassName, Style, Ctl3D, Actions );
  29810. InitCommonControlCommonNotify( Result );
  29811. end;
  29812. //==================== Progress bar ======================//
  29813. {$IFDEF USE_CONSTRUCTORS}
  29814. //[function NewProgressbar]
  29815. function NewProgressbar( AParent: PControl ): PControl;
  29816. begin
  29817. new( Result, CreateProgressbar( AParent ) );
  29818. end;
  29819. //[END NewProgressbar]
  29820. {$ELSE not_USE_CONSTRUCTORS}
  29821. //[FUNCTION NewProgressbar]
  29822. {$IFDEF ASM_VERSION}
  29823. {$ELSE ASM_VERSION} //Pascal
  29824. function NewProgressbar( AParent: PControl ): PControl;
  29825. begin
  29826. Result := _NewCommonControl( AParent, PROGRESS_CLASS,
  29827. WS_CHILD or WS_VISIBLE{$ifdef wince} or WS_BORDER{$endif}, True, nil );
  29828. with Result.fBoundsRect do
  29829. begin
  29830. Right := Left + 300;
  29831. Bottom := Top + 20;
  29832. end;
  29833. Result.fMenu := 0;
  29834. Result.fTextColor := clHighlight;
  29835. {$ifdef win32}
  29836. Result.fCommandActions.aSetBkColor := PBM_SETBKCOLOR;
  29837. {$endif win32}
  29838. //Result.fNCDestroyed := TRUE; // do not call DestroyWindow!
  29839. end;
  29840. {$ENDIF ASM_VERSION}
  29841. //[END NewProgressbar]
  29842. {$ENDIF USE_CONSTRUCTORS}
  29843. {$IFDEF USE_CONSTRUCTORS}
  29844. //[function NewProgressbarEx]
  29845. function NewProgressbarEx( AParent: PControl; Options: TProgressbarOptions ): PControl;
  29846. begin
  29847. new( Result, CreateProgressbarEx( AParent, Options ) );
  29848. end;
  29849. //[END NewProgressbarEx]
  29850. {$ELSE not_USE_CONSTRUCTORS}
  29851. //[FUNCTION NewProgressbarEx]
  29852. {$IFDEF ASM_VERSION}
  29853. {$ELSE ASM_VERSION} //Pascal
  29854. function NewProgressbarEx( AParent: PControl; Options: TProgressbarOptions ): PControl;
  29855. const ProgressBarFlags: array[ TProgressbarOption ] of Integer =
  29856. (PBS_VERTICAL, PBS_SMOOTH );
  29857. begin
  29858. Result := NewProgressbar( AParent );
  29859. Result.fStyle := Result.fStyle or DWORD( MakeFlags( @Options, ProgressBarFlags ) );
  29860. end;
  29861. {$ENDIF ASM_VERSION}
  29862. //[END NewProgressbarEx]
  29863. {$ENDIF USE_CONSTRUCTORS}
  29864. //===================== List view ========================//
  29865. //[FUNCTION WndProcNotify]
  29866. {$IFDEF ASM_VERSION}
  29867. {$ELSE ASM_VERSION} //Pascal
  29868. function WndProcNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29869. var NMhdr: PNMHdr;
  29870. Child: PControl;
  29871. begin
  29872. Result := False;
  29873. if Msg.message = WM_NOTIFY then
  29874. begin
  29875. NMhdr := Pointer( Msg.lParam );
  29876. {$IFDEF USE_PROP}
  29877. Child := Pointer( GetProp( NMhdr.hwndFrom, ID_SELF ) );
  29878. {$ELSE}
  29879. Child := Pointer( GetWindowLong( NMhdr.hwndFrom, GWL_USERDATA ) );
  29880. {$ENDIF}
  29881. if Child <> nil then
  29882. begin
  29883. Msg.hwnd := Child.fHandle;
  29884. Result := EnumDynHandlers( Child, Msg, Rslt );
  29885. end;
  29886. end;
  29887. end;
  29888. {$ENDIF ASM_VERSION}
  29889. //[END WndProcNotify]
  29890. //[FUNCTION WndProcCommonNotify]
  29891. {$IFDEF ASM_VERSION}
  29892. {$ELSE ASM_VERSION} //Pascal
  29893. function WndProcCommonNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  29894. var NMhdr: PNMHdr;
  29895. begin
  29896. Result := False;
  29897. if Msg.message = WM_NOTIFY then
  29898. begin
  29899. NMHdr := Pointer( Msg.lParam );
  29900. case LongInt(NMHdr.code) of
  29901. NM_RCLICK,
  29902. NM_CLICK: if assigned( Self_.fOnClick ) then
  29903. begin
  29904. Self_.fRightClick := LongInt(NMHdr.code)=NM_RCLICK;
  29905. Self_.fOnClick( Self_ );
  29906. Result := TRUE;
  29907. end;
  29908. NM_KILLFOCUS: if assigned( Self_.fOnLeave ) then
  29909. Self_.fOnLeave( Self_ );
  29910. NM_RETURN,
  29911. NM_SETFOCUS: if assigned( Self_.fOnEnter ) then
  29912. Self_.fOnEnter( Self_ );
  29913. {$ifdef wince}
  29914. NM_RECOGNIZEGESTURE:
  29915. begin
  29916. Rslt:=1;
  29917. Result:=True;
  29918. end;
  29919. {$endif wince}
  29920. end;
  29921. end;
  29922. end;
  29923. {$ENDIF ASM_VERSION}
  29924. //[END WndProcCommonNotify]
  29925. const ListViewStyles: array[ TListViewStyle ] of DWORD = ( LVS_ICON, LVS_SMALLICON,
  29926. LVS_LIST, LVS_REPORT, LVS_REPORT or LVS_NOCOLUMNHEADER );
  29927. ListViewFlags: array[ TListViewOption ] of Integer = ( LVS_ALIGNLEFT, LVS_AUTOARRANGE,
  29928. $400 {LVS_BUTTON}, LVS_EDITLABELS, LVS_NOLABELWRAP,
  29929. LVS_NOSCROLL, LVS_NOSORTHEADER,
  29930. not LVS_SHOWSELALWAYS, not LVS_SINGLESEL, LVS_SORTASCENDING,
  29931. LVS_SORTDESCENDING, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  29932. LVS_OWNERDATA, LVS_OWNERDRAWFIXED );
  29933. ListViewExFlags: array[ TListViewOption ] of Integer = ( 0, 0,
  29934. 0, 0, 0, 0, 0, 0, 0, 0, 0, LVS_EX_GRIDLINES,
  29935. LVS_EX_SUBITEMIMAGES, LVS_EX_CHECKBOXES, LVS_EX_TRACKSELECT,
  29936. LVS_EX_HEADERDRAGDROP, LVS_EX_FULLROWSELECT, LVS_EX_ONECLICKACTIVATE,
  29937. {$ifdef win32}LVS_EX_TWOCLICKACTIVATE, LVS_EX_FLATSB, LVS_EX_REGIONAL,
  29938. LVS_EX_INFOTIP, LVS_EX_UNDERLINEHOT, LVS_EX_MULTIWORKAREAS,{$else}
  29939. 0, 0, 0, 0, 0, 0,{$endif win32}0, 0 );
  29940. //[FUNCTION ApplyImageLists2Control]
  29941. {$IFDEF ASM_VERSION}
  29942. {$ELSE ASM_VERSION} //Pascal
  29943. procedure ApplyImageLists2Control( Sender: PControl );
  29944. var IL: PImageList;
  29945. begin
  29946. if Sender.fCommandActions.aSetImgList = 0 then Exit;
  29947. IL := Sender.ImageListNormal;
  29948. if IL <> nil then
  29949. Sender.Perform( Sender.fCommandActions.aSetImgList, LVSIL_NORMAL, IL.Handle );
  29950. IL := Sender.ImageListSmall;
  29951. if IL <> nil then
  29952. Sender.Perform( Sender.fCommandActions.aSetImgList, LVSIL_SMALL, IL.Handle );
  29953. IL := Sender.ImageListState;
  29954. if IL <> nil then
  29955. Sender.Perform( Sender.fCommandActions.aSetImgList, LVSIL_STATE, IL.Handle );
  29956. end;
  29957. {$ENDIF ASM_VERSION}
  29958. //[END ApplyImageLists2Control]
  29959. //[FUNCTION ApplyImageLists2ListView]
  29960. {$IFDEF ASM_VERSION}
  29961. {$ELSE ASM_VERSION} //Pascal
  29962. procedure ApplyImageLists2ListView( Sender: PControl );
  29963. var Flags: DWORD;
  29964. begin
  29965. Flags := MakeFlags( @Sender.fLVOptions, ListViewFlags );
  29966. Sender.Style := Sender.Style and not $403F
  29967. or Flags or ListViewStyles[ Sender.fLVStyle ];
  29968. Flags := MakeFlags( @Sender.fLVOptions, ListViewExFlags );
  29969. Sender.Perform( LVM_SETEXTENDEDLISTVIEWSTYLE, $3FFF, Flags );
  29970. ApplyImageLists2Control( Sender );
  29971. end;
  29972. {$ENDIF ASM_VERSION}
  29973. //[END ApplyImageLists2ListView]
  29974. {$IFDEF USE_CONSTRUCTORS}
  29975. //[function NewListView]
  29976. function NewListView( AParent: PControl; Style: TListViewStyle; Options: TListViewOptions;
  29977. ImageListSmall, ImageListNormal, ImageListState: PImageList ): PControl;
  29978. begin
  29979. new( Result, CreateListView( AParent, Style, Options, ImageListSmall,
  29980. ImageListNormal, ImageListState ) );
  29981. end;
  29982. //[END NewListView]
  29983. {$ELSE not_USE_CONSTRUCTORS}
  29984. //[FUNCTION NewListView]
  29985. {$IFDEF ASM_VERSION}
  29986. {$ELSE ASM_VERSION} //Pascal
  29987. function NewListView( AParent: PControl; Style: TListViewStyle; Options: TListViewOptions;
  29988. ImageListSmall, ImageListNormal, ImageListState: PImageList ): PControl;
  29989. begin
  29990. Result := _NewCommonControl( AParent, WC_LISTVIEW,
  29991. ListViewStyles[ Style ] or LVS_SHAREIMAGELISTS or WS_CHILD or WS_VISIBLE
  29992. or WS_TABSTOP or WS_CLIPCHILDREN{$ifdef wince} or WS_BORDER{$endif}
  29993. or DWORD( MakeFlags( @Options, ListViewFlags ) ),
  29994. True, @ListViewActions );
  29995. Result.fLVOptions := Options;
  29996. Result.fLVStyle := Style;
  29997. Result.fCreateWndExt := ApplyImageLists2ListView;
  29998. with Result.fBoundsRect do
  29999. begin
  30000. Right := Left + 200;
  30001. Bottom := Top + 150;
  30002. end;
  30003. Result.ImageListSmall := ImageListSmall;
  30004. Result.ImageListNormal := ImageListNormal;
  30005. Result.ImageListState := ImageListState;
  30006. Result.fLVTextBkColor := clWindow;
  30007. Result.fLookTabKeys := [ tkTab ];
  30008. //Result.fMargin := 0;
  30009. {$ifdef wince}
  30010. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  30011. {$endif wince}
  30012. end;
  30013. {$ENDIF ASM_VERSION}
  30014. //[END NewListView]
  30015. {$ENDIF USE_CONSTRUCTORS}
  30016. //===================== Tree view ========================//
  30017. //[FUNCTION WndProcTreeView]
  30018. {$IFDEF ASM_UNICODE}
  30019. {$ELSE ASM_VERSION} //Pascal
  30020. function WndProcTreeView( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30021. var NM: PNMTreeView;
  30022. DI: PTVDispInfo;
  30023. P: TPoint;
  30024. S: KOL_String;
  30025. begin
  30026. if Msg.message = WM_NOTIFY then
  30027. begin
  30028. NM := Pointer( Msg.lParam );
  30029. case LongInt(NM.hdr.code) of
  30030. NM_RCLICK:
  30031. begin
  30032. GetCursorPos( P );
  30033. P := Self_.Screen2Client( P );
  30034. PostMessage( Self_.fHandle, WM_RBUTTONUP, MK_RBUTTON or GetShiftState,
  30035. (P.x and $FFFF) or (P.y shl 16) );
  30036. end;
  30037. (*{$IFNDEF UNICODE_CTRLS}
  30038. TVN_BEGINDRAGW, TVN_BEGINRDRAGW,
  30039. {$ENDIF}*)
  30040. TVN_BEGINDRAG {$IFDEF TV_DRAG_RBUTTON}, TVN_BEGINRDRAG{$ENDIF}:
  30041. if Assigned( Self_.fOnTVBeginDrag ) then
  30042. Self_.fOnTVBeginDrag( Self_, NM.itemNew.hItem );
  30043. TVN_BEGINLABELEDIT
  30044. (*{$IFNDEF UNICODE_CTRLS}, TVN_BEGINLABELEDITW{$ENDIF}*):
  30045. begin
  30046. if Self_.fDragging
  30047. {$ifdef wince}
  30048. or ((Self_.fAutoPopupMenu <> nil) and LongBool(PMenu(Self_.fAutoPopupMenu).Flags and $1000))
  30049. {$endif wince}
  30050. then
  30051. begin
  30052. Rslt := 1; // do not allow edit while dragging
  30053. Result := TRUE;
  30054. Exit;
  30055. end;
  30056. DI := Pointer( NM );
  30057. if Assigned( Self_.fOnTVBeginEdit ) then
  30058. begin
  30059. Rslt := Integer( not Self_.fOnTVBeginEdit( Self_, DI.item.hItem ) );
  30060. if Rslt = 0 then begin
  30061. Self_.fEditing := TRUE;
  30062. {$ifdef wince}
  30063. SHSipPreference(Self_.ParentForm.fHandle, SIP_UP);
  30064. {$endif wince}
  30065. end;
  30066. Result := TRUE;
  30067. Exit;
  30068. end;
  30069. end;
  30070. TVN_ENDLABELEDIT
  30071. (*{$IFNDEF UNICODE_CTRLS}, TVN_ENDLABELEDITW {$ENDIF}*):
  30072. begin
  30073. {$ifdef wince}
  30074. SHSipPreference(Self_.ParentForm.fHandle, SIP_DOWN);
  30075. {$endif wince}
  30076. DI := Pointer( NM );
  30077. if Assigned( Self_.fOnTVEndEdit ) then
  30078. begin
  30079. S := DI.item.pszText;
  30080. if (DI.item.pszText = nil) then
  30081. begin
  30082. Self_.fEditing := FALSE;
  30083. Result := True;
  30084. Exit;
  30085. end;
  30086. if Self_.fOnTVEndEdit( Self_, DI.item.hItem, S ) then Rslt := 1
  30087. else Rslt := 0;
  30088. //Self_.TVItemText[ DI.item.hItem ] := S; // MTsVN: ×òîáû ìîæíî áûëî ïîäðåäàêòèðîâàòü NewTxt â fOnTVEndEdit
  30089. // VK: ýòî ïðåêðàñíî ìîæíî ñäåëàòü â îáðàáîò÷èêå ïîëüçîâàòåëÿ, åñëè åìó ýòî íóæíî. ß òàê âñåãäà è äåëàë.
  30090. end
  30091. else
  30092. Rslt := 1;
  30093. Self_.fEditing := FALSE;
  30094. Result := True;
  30095. Exit;
  30096. end;
  30097. TVN_ITEMEXPANDING
  30098. (*{$IFNDEF UNICODE_CTRLS}, TVN_ITEMEXPANDINGW {$ENDIF}*):
  30099. begin
  30100. if Assigned( Self_.fOnTVExpanding ) then
  30101. begin
  30102. Rslt := Integer( Self_.fOnTVExpanding( Self_, NM.itemNew.hItem,
  30103. NM.action = TVE_EXPAND ) );
  30104. Result := TRUE;
  30105. Exit;
  30106. end;
  30107. end;
  30108. TVN_ITEMEXPANDED
  30109. (*{$IFNDEF UNICODE_CTRLS}, TVN_ITEMEXPANDEDW {$ENDIF}*):
  30110. if Assigned( Self_.fOnTVExpanded ) then
  30111. Self_.fOnTVExpanded( Self_, NM.itemNew.hItem, NM.action=TVE_EXPAND );
  30112. TVN_SELCHANGING
  30113. (*{$IFNDEF UNICODE_CTRLS}, TVN_SELCHANGINGW {$ENDIF}*):
  30114. begin //------------------ TVN_SELCHANGING by Sergey Shisminzev
  30115. if Assigned( Self_.fOnTVSelChanging ) then
  30116. begin
  30117. Rslt := Integer( not Self_.fOnTVSelChanging( Self_, NM.itemOld.hItem, NM.itemNew.hItem ) );
  30118. Result := TRUE;
  30119. Exit;
  30120. end;
  30121. end; //----------------------------------------
  30122. TVN_SELCHANGED
  30123. (*{$IFNDEF UNICODE_CTRLS}, TVN_SELCHANGEDW {$ENDIF}*):
  30124. Self_.DoSelChange;
  30125. end;
  30126. end;
  30127. Result := False;
  30128. end;
  30129. {$ENDIF ASM_VERSION}
  30130. //[END WndProcTreeView]
  30131. //[function ProcTVDeleteItem]
  30132. function ProcTVDeleteItem( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30133. var NM: PNMTreeView;
  30134. begin
  30135. if Msg.message = WM_NOTIFY then
  30136. begin
  30137. NM := Pointer( Msg.lParam );
  30138. case LongInt(NM.hdr.code) of
  30139. TVN_DELETEITEM:
  30140. if Assigned( Self_.fOnTVDelete ) then
  30141. Self_.fOnTVDelete( Self_, NM.itemOld.hItem );
  30142. end;
  30143. end;
  30144. Result := FALSE;
  30145. end;
  30146. //[procedure ClearTreeView]
  30147. procedure ClearTreeView( TV: PControl );
  30148. begin
  30149. TV.TVDelete( TVI_ROOT );
  30150. end;
  30151. const
  30152. TreeViewFlags: array[ TTreeViewOption ] of Integer = ( not TVS_HASLINES, TVS_LINESATROOT,
  30153. not TVS_HASBUTTONS, TVS_EDITLABELS, not TVS_SHOWSELALWAYS,
  30154. not TVS_DISABLEDRAGDROP,
  30155. {$ifdef win32}TVS_NOTOOLTIPS, TVS_CHECKBOXES, TVS_TRACKSELECT, TVS_SINGLEEXPAND,
  30156. TVS_INFOTIP, TVS_FULLROWSELECT, TVS_NOSCROLL, TVS_NONEVENHEIGHT
  30157. {$else}0, TVS_CHECKBOXES, 0, TVS_SINGLEEXPAND, 0, 0, 0, 0
  30158. {$endif win32});
  30159. {$IFDEF USE_CONSTRUCTORS}
  30160. //[function NewTreeView]
  30161. function NewTreeView( AParent: PControl; Options: TTreeViewOptions;
  30162. ImgListNormal, ImgListState: PImageList ): PControl;
  30163. begin
  30164. new( Result, CreateTreeView( AParent, Options, ImgListNormal, ImgListState ) );
  30165. end;
  30166. {$ELSE not_USE_CONSTRUCTORS}
  30167. //[FUNCTION NewTreeView]
  30168. {$IFDEF ASM_VERSION}
  30169. {$ELSE ASM_VERSION} //Pascal
  30170. function NewTreeView( AParent: PControl; Options: TTreeViewOptions;
  30171. ImgListNormal, ImgListState: PImageList ): PControl;
  30172. var Flags: Integer;
  30173. begin
  30174. Flags := MakeFlags( @Options, TreeViewFlags );
  30175. Result := _NewCommonControl( AParent, WC_TREEVIEW, Flags or WS_VISIBLE or
  30176. WS_CHILD or WS_TABSTOP{$ifdef wince} or WS_BORDER{$endif}, True, @TreeViewActions );
  30177. Result.fCreateWndExt := ApplyImageLists2Control;
  30178. Result.fColor := clWindow;
  30179. Result.AttachProc( WndProcTreeView );
  30180. with Result.fBoundsRect do
  30181. begin
  30182. Right := Left + 150;
  30183. Bottom := Top + 200;
  30184. end;
  30185. Result.ImageListNormal := ImgListNormal;
  30186. Result.ImageListState := ImgListState;
  30187. Result.fLookTabKeys := [ tkTab ];
  30188. {$ifdef wince}
  30189. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  30190. {$endif wince}
  30191. end;
  30192. {$ENDIF ASM_VERSION}
  30193. //[END NewTreeView]
  30194. {$ENDIF USE_CONSTRUCTORS}
  30195. //===================== Tab Control ========================//
  30196. //[FUNCTION WndProcTabControl]
  30197. {$IFDEF ASM_VERSION}
  30198. {$ELSE ASM_VERSION} //Pascal
  30199. function WndProcTabControl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30200. var Hdr: PNMHdr;
  30201. A: Integer;
  30202. R: TRect;
  30203. WasActive: Boolean;
  30204. I: Integer;
  30205. {$IFDEF OLD_ALIGN}
  30206. Page: PControl;
  30207. begin
  30208. case Msg.message of
  30209. WM_NOTIFY:
  30210. begin
  30211. Hdr := Pointer( Msg.lParam );
  30212. case LongInt(Hdr.code) of
  30213. TCN_SELCHANGING:
  30214. Self_.fCurIndex := Self_.GetCurIndex;
  30215. TCN_SELCHANGE:
  30216. begin
  30217. A := {Self_.????}Self_.GetCurIndex;
  30218. WasActive := Self_.fCurIndex = A;
  30219. Self_.fCurIndex := A;
  30220. for I := 0 to Self_.Count - 1 do
  30221. begin
  30222. Page := Self_.Pages[ I ];
  30223. Page.Visible := A = I;
  30224. if A = I then
  30225. Page.BringToFront;
  30226. end;
  30227. if not WasActive then
  30228. if Assigned( Self_.fOnSelChange ) then
  30229. Self_.fOnSelChange( Self_ );
  30230. if Assigned(Self_.fGotoControl) and not Self_.Focused then begin
  30231. Self_.ParentForm.fCurrentControl:=Self_;
  30232. Self_.fGotoControl(Self_, VK_TAB, False);
  30233. end;
  30234. end;
  30235. end;
  30236. end;
  30237. WM_SIZE:
  30238. begin
  30239. R:=Self_.TC_DisplayRect;
  30240. for I := 0 to Self_.Count - 1 do
  30241. begin
  30242. Page := Self_.Pages[ I ];
  30243. Page.BoundsRect := R;
  30244. end;
  30245. {$ELSE NEW_ALIGN}
  30246. begin
  30247. case Msg.message of
  30248. WM_NOTIFY:
  30249. begin
  30250. Hdr := Pointer( Msg.lParam );
  30251. case longint(Hdr.code) of
  30252. TCN_SELCHANGING:
  30253. Self_.fCurIndex := Self_.GetCurIndex;
  30254. TCN_SELCHANGE:
  30255. begin
  30256. A := Self_.GetCurIndex;
  30257. WasActive := Self_.fCurIndex = A;
  30258. if (not WasActive)and(Self_.fCurIndex>=0) then
  30259. Self_.Pages[Self_.fCurIndex].Visible := false;
  30260. Self_.fCurIndex := A;
  30261. Self_.Pages[Self_.fCurIndex].Visible := true;
  30262. Self_.Pages[Self_.fCurIndex].BringToFront;
  30263. if not WasActive then
  30264. if Assigned( Self_.fOnSelChange ) then
  30265. Self_.fOnSelChange( Self_ );
  30266. if Assigned(Self_.fGotoControl) and not Self_.Focused then begin
  30267. Self_.ParentForm.fCurrentControl:=Self_;
  30268. Self_.fGotoControl(Self_, VK_TAB, False);
  30269. end;
  30270. end;
  30271. end;
  30272. end;
  30273. WM_SIZE:
  30274. begin
  30275. GetClientRect( Self_.fHandle, R );
  30276. Self_.fClientRight := R.Right;
  30277. Self_.fClientBottom := R.Bottom;
  30278. Self_.Perform( TCM_ADJUSTRECT, 0, Integer( @R ) );
  30279. Self_.fClientLeft := R.Left;
  30280. Self_.fClientTop := R.Top;
  30281. Dec(Self_.fClientRight,R.Right);
  30282. Dec(Self_.fClientBottom,R.Bottom);
  30283. {$ifdef wince}
  30284. with Self_^ do begin
  30285. Dec(fClientTop, fMargin + 2);
  30286. Dec(fClientLeft, fMargin + 2);
  30287. Dec(fClientRight, fMargin + 2);
  30288. Dec(fClientBottom, fMargin);
  30289. end;
  30290. {$endif wince}
  30291. // This fixes anchoring problems on invisible tabs
  30292. A := Self_.CurIndex;
  30293. R:=Self_.ClientRect;
  30294. for I := 0 to Self_.Count - 1 do
  30295. if I <> A then
  30296. Self_.Pages[ I ].BoundsRect := R;
  30297. {$ENDIF}
  30298. end;
  30299. WM_SHOWWINDOW:
  30300. if WordBool(Msg.wParam) and Self_.Focused then
  30301. PostMessage(Self_.fHandle, WM_KEYDOWN, VK_TAB, 1);
  30302. end;
  30303. Result := False;
  30304. end;
  30305. {$ENDIF ASM_VERSION}
  30306. //[END WndProcTabControl]
  30307. {$IFDEF GRAPHCTL_XPSTYLES}
  30308. {$DEFINE RICHEDIT_XPBORDER}
  30309. {$ENDIF}
  30310. {$IFDEF RICHEDIT_XPBORDER}
  30311. function WndProc_RichEditXPBorder( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30312. var ExStyle: DWORD;
  30313. DrawRect, EmptyRect: TRect;
  30314. DC: HDC;
  30315. Details: TThemedElementDetails;
  30316. begin
  30317. Result := FALSE;
  30318. if Msg.message = WM_NCPAINT then
  30319. begin
  30320. ExStyle := GetWindowLong(Self_.Handle, GWL_EXSTYLE);
  30321. if (ExStyle and WS_EX_CLIENTEDGE) <> 0 then
  30322. begin
  30323. GetWindowRect(Self_.Handle, DrawRect);
  30324. OffsetRect(DrawRect, -DrawRect.Left, -DrawRect.Top);
  30325. DC := GetWindowDC(Self_.Handle);
  30326. //try
  30327. EmptyRect := DrawRect;
  30328. with DrawRect do
  30329. ExcludeClipRect(DC, Left + 2, Top + 2, Right - 2, Bottom - 2);
  30330. //Details := GetElementDetails(teEditTextNormal);
  30331. Details.Element := teEdit;
  30332. Details.Part := 1 {EP_EDITTEXT};
  30333. Details.State := Ord(teEditTextNormal) - Ord(teEditTextNormal) + 1;
  30334. //DrawElement(DC, Details, DrawRect);
  30335. if not Assigned( DrawThemeBackground ) then
  30336. begin
  30337. ThemeLibrary := LoadLibrary(themelib);
  30338. DrawThemeBackground := GetProcAddress(ThemeLibrary, 'DrawThemeBackground');
  30339. OpenThemeData := GetProcAddress(ThemeLibrary, 'OpenThemeData');
  30340. end;
  30341. if Assigned( DrawThemeBackground ) then
  30342. begin
  30343. Result := TRUE;
  30344. Rslt := Self_.CallDefWndProc( Msg );
  30345. with Details do
  30346. DrawThemeBackground(OpenThemeData(0, 'edit'),
  30347. DC, Part, State, DrawRect, nil);
  30348. end;
  30349. //finally
  30350. ReleaseDC(Self_.Handle, DC);
  30351. //end;
  30352. end;
  30353. end;
  30354. end;
  30355. {$ENDIF RICHEDIT_XPBORDER}
  30356. const TabControlFlags: array[ TTabControlOption ] of Integer = ( TCS_BUTTONS,
  30357. TCS_FIXEDWIDTH, not TCS_FOCUSNEVER,
  30358. TCS_FIXEDWIDTH or TCS_FORCEICONLEFT, TCS_FIXEDWIDTH or TCS_FORCELABELLEFT,
  30359. TCS_MULTILINE, TCS_MULTISELECT, TCS_RIGHTJUSTIFY, TCS_SCROLLOPPOSITE,
  30360. TCS_BOTTOM, TCS_VERTICAL, TCS_FLATBUTTONS, TCS_HOTTRACK, 0, TCS_OWNERDRAWFIXED );
  30361. {$IFDEF USE_CONSTRUCTORS}
  30362. //[function NewTabControl]
  30363. function NewTabControl( AParent: PControl; Tabs: array of String; Options: TTabControlOptions;
  30364. ImgList: PImageList; ImgList1stIdx: Integer ): PControl;
  30365. begin
  30366. new( Result, CreateTabControl( AParent, Tabs, Options, ImgList, ImgList1stIdx ) );
  30367. end;
  30368. //[END NewTabControl]
  30369. {$ELSE not_USE_CONSTRUCTORS}
  30370. //[FUNCTION NewTabControl]
  30371. {$IFDEF ASM_UNICODE}
  30372. {$ELSE ASM_VERSION} //Pascal
  30373. function NewTabControl( AParent: PControl; const Tabs: array of KOLString; Options: TTabControlOptions;
  30374. ImgList: PImageList; ImgList1stIdx: Integer ): PControl;
  30375. var I, II : Integer;
  30376. Flags: Integer;
  30377. begin
  30378. Flags := MakeFlags( @Options, TabControlFlags );
  30379. if tcoFocusTabs in Options then
  30380. Flags := Flags or TCS_FOCUSONBUTTONDOWN;
  30381. Result := _NewCommonControl( AParent, WC_TABCONTROL,
  30382. Flags or (WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_VISIBLE or WS_TABSTOP{$ifdef wince} or WS_BORDER or TCS_BOTTOM{$endif}), True,
  30383. @TabControlActions );
  30384. {$ifndef wince}
  30385. if not( tcoBorder in Options ) then
  30386. begin
  30387. Result.fExStyle := Result.fExStyle and not WS_EX_CLIENTEDGE;
  30388. end;
  30389. {$endif wince}
  30390. Result.AttachProc( WndProcTabControl );
  30391. with Result.fBoundsRect do
  30392. begin
  30393. Right := Left + 100;
  30394. Bottom := Top + 100;
  30395. end;
  30396. {$ifdef wince}
  30397. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  30398. {$endif wince}
  30399. if ImgList <> nil then
  30400. Result.Perform( TCM_SETIMAGELIST, 0, ImgList.Handle );
  30401. II := ImgList1stIdx;
  30402. for I := 0 to High( Tabs ) do
  30403. begin
  30404. Result.TC_Insert( I, Tabs[ I ], II );
  30405. Inc( II );
  30406. end;
  30407. Result.fLookTabKeys := [ tkTab, tkUpDown ];
  30408. end;
  30409. {$ENDIF ASM_VERSION}
  30410. //[END NewTabControl]
  30411. {$IFNDEF OLD_ALIGN}
  30412. {$IFDEF ASM_VERSION}
  30413. {$ELSE ASM_VERSION} //Pascal
  30414. //[FUNCTION NewTabEmpty]
  30415. function NewTabEmpty( AParent: PControl; Options: TTabControlOptions;
  30416. ImgList: PImageList ): PControl;
  30417. var Flags: Integer;
  30418. begin
  30419. Flags := MakeFlags( @Options, TabControlFlags );
  30420. if tcoFocusTabs in Options then
  30421. Flags := Flags or (WS_TABSTOP or TCS_FOCUSONBUTTONDOWN);
  30422. Result := _NewCommonControl( AParent, WC_TABCONTROL,
  30423. Flags or (WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_VISIBLE), True,
  30424. @TabControlActions );
  30425. if not( tcoBorder in Options ) then
  30426. Result.fExStyle := Result.fExStyle and not WS_EX_CLIENTEDGE;
  30427. Result.AttachProc( WndProcTabControl );
  30428. with Result.fBoundsRect do begin
  30429. Right := Left + 100;
  30430. Bottom := Top + 100;
  30431. end;
  30432. if ImgList <> nil then
  30433. Result.Perform( TCM_SETIMAGELIST, 0, ImgList.Handle );
  30434. Result.fLookTabKeys := [ tkTab ];
  30435. {$ifdef wince}
  30436. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  30437. {$endif wince}
  30438. end;
  30439. {$ENDIF ASM_VERSION}
  30440. //[END NewTabEmpty]
  30441. {$ENDIF}
  30442. {$ENDIF USE_CONSTRUCTORS}
  30443. //===================== Tool bar ========================//
  30444. //[FUNCTION WndProcToolbarCtr]
  30445. {$IFDEF ASM_noVERSION} //TTN_NEEDTEXTW
  30446. function WndProcToolbarCtrl(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  30447. asm
  30448. CMP word ptr [EDX].TMsg.message, WM_WINDOWPOSCHANGED
  30449. JNE @@chk_CM_COMMAND
  30450. MOV dword ptr [ECX], 0 // Rslt := 0
  30451. MOV ECX, [EAX].TControl.fOnResize.TMethod.Code
  30452. JECXZ @@ret_true
  30453. XCHG EDX, EAX // Sender := Self_
  30454. MOV EAX, [EDX].TControl.fOnResize.TMethod.Data
  30455. CALL ECX // Self_.fOnResize
  30456. XOR EAX, EAX // Result := FALSE
  30457. RET
  30458. @@chk_CM_COMMAND:
  30459. CMP word ptr [EDX].TMsg.message, CM_COMMAND
  30460. JNE @@chk_WM_NOTIFY
  30461. MOVZX ECX, word ptr [EDX].TMsg.wParam
  30462. MOV [EAX].TControl.fCurItem, ECX
  30463. PUSH EAX
  30464. PUSH 0
  30465. PUSH ECX
  30466. PUSH TB_COMMANDTOINDEX
  30467. PUSH EAX
  30468. CALL TControl.Perform
  30469. PUSH EAX
  30470. PUSH VK_RETURN
  30471. CALL GetKeyState
  30472. TEST EAX, EAX
  30473. SETL DL
  30474. POP ECX
  30475. POP EAX
  30476. MOV [EAX].TControl.fCurIndex, ECX
  30477. MOV [EAX].TControl.fRightClick, DL
  30478. @@ret_false:
  30479. XOR EAX, EAX
  30480. RET
  30481. @@chk_WM_NOTIFY:
  30482. CMP word ptr [EDX].TMsg.message, WM_NOTIFY
  30483. JNE @@ret_false
  30484. MOV EDX, [EDX].TMsg.lParam
  30485. MOV ECX, [EDX].TTooltipText.hdr.code
  30486. CMP ECX, TTN_NEEDTEXT
  30487. JNE @@chk_NM_RCLICK
  30488. PUSH EAX
  30489. PUSH EDX
  30490. MOV EDX, [EDX].TTooltipText.hdr.idFrom
  30491. MOV ECX, [EAX].TControl.fTBttCmd
  30492. OR EAX, -1
  30493. JECXZ @@idxReady
  30494. XCHG EAX, ECX
  30495. CALL TList.IndexOf
  30496. @@idxReady: // EAX = -1 or index of button tooltip
  30497. TEST EAX, EAX
  30498. POP EDX
  30499. LEA EDX, [EDX].TTooltipText.szText
  30500. MOV byte ptr [EDX], 0
  30501. POP ECX
  30502. JL @@ret_true
  30503. MOV ECX, [ECX].TControl.fTBttTxt
  30504. MOV ECX, [ECX].TStrList.fList
  30505. MOV ECX, [ECX].TList.fItems
  30506. MOV EAX, [ECX+EAX*4]
  30507. XCHG EAX, EDX
  30508. XOR ECX, ECX
  30509. MOV CL, 79
  30510. CALL StrLCopy
  30511. JMP @@ret_true
  30512. @@chk_NM_RCLICK:
  30513. CMP ECX, NM_RCLICK
  30514. JNE @@chk_NM_CLICK
  30515. OR [EAX].TControl.fRightClick, 1
  30516. MOV ECX, [EDX].TNMMouse.dwItemSpec
  30517. MOV [EAX].TControl.fCurItem, -1
  30518. PUSH EAX
  30519. PUSH 0
  30520. PUSH ECX
  30521. PUSH TB_COMMANDTOINDEX
  30522. PUSH EAX
  30523. CALL TControl.Perform
  30524. POP EDX
  30525. MOV [EDX].TControl.fCurIndex, EAX
  30526. XOR EAX, EAX
  30527. RET
  30528. @@chk_NM_CLICK:
  30529. CMP ECX, NM_CLICK
  30530. JNE @@chk_TBN_DROPDOWN
  30531. MOV [EAX].TControl.fRightClick, 0
  30532. OR [EAX].TControl.fCurItem, -1
  30533. OR [EAX].TControl.fCurIndex, -1
  30534. CMP [EDX].TTBNotify.iItem, -1
  30535. SETNZ AL
  30536. RET
  30537. @@chk_TBN_DROPDOWN:
  30538. CMP ECX, TBN_DROPDOWN
  30539. JNE @@ret_false
  30540. MOV EDX, [EDX].TTBNotify.iItem
  30541. MOV [EAX].TControl.fCurItem, EDX
  30542. PUSH EAX
  30543. CALL TControl.TBItem2Index
  30544. POP EDX
  30545. MOV [EDX].TControl.fCurIndex, EAX
  30546. MOV ECX, [EDX].TControl.fOnDropDown.TMethod.Code
  30547. JECXZ @@ret_z
  30548. MOV EAX, [EDX].TControl.fOnDropDown.TMethod.Data
  30549. CALL ECX
  30550. @@ret_z:
  30551. XOR EAX, EAX
  30552. end;
  30553. {$ELSE ASM_VERSION} //Pascal
  30554. function WndProcToolbarCtrl(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  30555. {$ifdef win32}
  30556. var lpttt: PTooltipText;
  30557. idBtn, Idx: Integer;
  30558. {$endif win32}
  30559. var Notify: PTBNotify;
  30560. Mouse: PNMMouse;
  30561. {$ifdef win32}
  30562. {$IFNDEF _FPC}
  30563. {$IFNDEF _D2}
  30564. var Wstr: WideString;
  30565. {$ENDIF _D2}
  30566. {$ENDIF _FPC}
  30567. {$endif win32}
  30568. begin
  30569. Result := False;
  30570. if Msg.message = WM_WINDOWPOSCHANGED then
  30571. begin
  30572. if Assigned( Self_.fOnResize ) then
  30573. Self_.fOnResize( Self_ );
  30574. //Result := TRUE; // this prevents Align working for child controls of Toolbar !
  30575. Rslt := 0;
  30576. end
  30577. else if Msg.message = CM_COMMAND then
  30578. begin
  30579. Self_.fCurItem := Loword( Msg.wParam );
  30580. Self_.fCurIndex := Self_.Perform( TB_COMMANDTOINDEX, Loword( Msg.wParam ), 0 );
  30581. Self_.fRightClick := GetKeyState( VK_RBUTTON ) < 0;
  30582. end
  30583. else if Msg.message = WM_NOTIFY then
  30584. begin
  30585. {$ifdef win32}
  30586. lpttt := Pointer( Msg.lParam );
  30587. {$endif win32}
  30588. Notify := Pointer( Msg.lParam );
  30589. case LongInt(Notify.hdr.code) of
  30590. {$ifdef win32}
  30591. TTN_NEEDTEXT:
  30592. begin
  30593. Result := True;
  30594. idBtn := lpttt.hdr.idFrom;
  30595. Idx := -1;
  30596. if Self_.fTBttCmd <> nil then
  30597. Idx := Self_.fTBttCmd.IndexOf( Pointer( idBtn ) );
  30598. lpttt.szText[ 0 ] := #0;
  30599. if Idx >= 0 then
  30600. {$IFDEF UNICODE_CTRLS} WStrLCopy {$ELSE} StrLCopy {$ENDIF}
  30601. ( lpttt.szText, Self_.fTBttTxt.fList.fItems[ Idx ], 79 );
  30602. Exit;
  30603. end;
  30604. {$IFNDEF _FPC}
  30605. {$IFNDEF _D2}
  30606. TTN_NEEDTEXTW: // for Windows XP
  30607. begin
  30608. Result := True;
  30609. idBtn := lpttt.hdr.idFrom;
  30610. Idx := -1;
  30611. if Self_.fTBttCmd <> nil then
  30612. Idx := Self_.fTBttCmd.IndexOf( Pointer( idBtn ) );
  30613. FillChar( lpttt.szText[ 0 ], 160, #0 );
  30614. if Idx >= 0 then
  30615. begin
  30616. WStr := Self_.fTBttTxt.Items[ Idx ];
  30617. if WStr <> '' then
  30618. Move( Wstr[ 1 ], lpttt.szText, Min( 158, (Length( WStr ) + 1) * 2 ) );
  30619. end;
  30620. Exit;
  30621. end;
  30622. {$ENDIF _D2}
  30623. {$ENDIF _FPC}
  30624. {$endif win32}
  30625. NM_RCLICK:
  30626. begin
  30627. Mouse := Pointer( Msg.lParam );
  30628. Self_.fCurItem := Mouse.dwItemSpec;
  30629. Self_.fCurIndex := Self_.Perform( TB_COMMANDTOINDEX, Mouse.dwItemSpec, 0 );
  30630. Self_.fRightClick := GetKeyState( VK_RBUTTON ) < 0;
  30631. Self_.fRightClick := True;
  30632. end;
  30633. NM_CLICK:
  30634. begin
  30635. Self_.fCurItem := -1; // return CurItem = -1
  30636. Self_.fCurIndex := -1;
  30637. Self_.fRightClick := False;
  30638. Result := Notify.iItem <> -1; // do not handle - if it will be handled in WM_COMMAND
  30639. Exit;
  30640. end;
  30641. TBN_DROPDOWN:
  30642. begin
  30643. Self_.fCurItem := Notify.iItem;
  30644. Self_.fCurIndex := Self_.TBItem2Index( Self_.fCurItem );
  30645. if assigned( Self_.fOnDropDown ) then
  30646. Self_.fOnDropDown( Self_ );
  30647. end;
  30648. end;
  30649. end;
  30650. end;
  30651. {$ENDIF ASM_VERSION}
  30652. //[END WndProcToolbarCtr]
  30653. const ToolbarAligns: array[ TControlAlign ] of DWORD =
  30654. ( CCS_NOPARENTALIGN {or CCS_NOMOVEY} {or CCS_NORESIZE} or CCS_NODIVIDER, CCS_TOP or CCS_VERT, CCS_TOP, CCS_BOTTOM or CCS_VERT, CCS_BOTTOM,
  30655. CCS_TOP );
  30656. ToolbarOptions: array[ TToolbarOption ] of Integer = ( TBSTYLE_LIST, not TBSTYLE_LIST,
  30657. TBSTYLE_FLAT, TBSTYLE_TRANSPARENT, TBSTYLE_WRAPABLE, CCS_NODIVIDER, 0,
  30658. TBSTYLE_CUSTOMERASE );
  30659. {$IFDEF USE_CONSTRUCTORS}
  30660. //[function NewToolbar]
  30661. function NewToolbar( AParent: PControl; Align: TControlAlign; Options: TToolbarOptions;
  30662. Bitmap: HBitmap; Buttons: array of PChar;
  30663. BtnImgIdxArray: array of Integer ) : PControl;
  30664. begin
  30665. new( Result, CreateToolbar( AParent, Align, Options, Bitmap, Buttons, BtnImgIdxArray ) );
  30666. end;
  30667. //[END NewToolbar]
  30668. {$ELSE not_USE_CONSTRUCTORS}
  30669. //[FUNCTION NewToolbar]
  30670. {$IFDEF ASM_UNICODE}
  30671. {$ELSE ASM_VERSION} //Pascal
  30672. function NewToolbar( AParent: PControl; Align: TControlAlign; Options: TToolbarOptions;
  30673. Bitmap: HBitmap; const Buttons: array of PKOLChar;
  30674. const BtnImgIdxArray: array of Integer ) : PControl;
  30675. var Flags: DWORD;
  30676. begin
  30677. if not( tboTextBottom in Options ) then
  30678. Options := Options + [ tboTextRight ];
  30679. if tboTextRight in Options then
  30680. Options := Options - [ tboTextBottom ];
  30681. Flags := MakeFlags( @Options, ToolbarOptions );
  30682. {$ifdef wince}
  30683. if tbo3DBorder in Options then
  30684. Flags:=Flags or WS_BORDER;
  30685. {$endif}
  30686. DoInitCommonControls( ICC_BAR_CLASSES );
  30687. Result := _NewCommonControl( AParent, TOOLBARCLASSNAME,
  30688. (ToolbarAligns[ Align ] or WS_CHILD or WS_VISIBLE or TBSTYLE_TOOLTIPS
  30689. or Flags and not (TBSTYLE_FLAT or TBSTYLE_TRANSPARENT)), {!ecm}
  30690. tbo3DBorder in Options, nil );
  30691. Result.fCommandActions.aClear := ClearToolbar;
  30692. Result.fCommandActions.aGetCount := TB_BUTTONCOUNT;
  30693. Result.fIsButton := TRUE;
  30694. Result.fIgnoreDefault := TRUE;
  30695. with Result.fBoundsRect do
  30696. begin
  30697. if Align in [ caNone ] then
  30698. begin
  30699. Bottom := Top + 26;
  30700. Right := Left + 1000;
  30701. end
  30702. else
  30703. begin
  30704. Left := 0; Right := 0;
  30705. Top := 0; Bottom := 0;
  30706. end;
  30707. end;
  30708. Result.AttachProc( WndProcToolbarCtrl );
  30709. Result.AttachProc( WndProcDoEraseBkgnd );
  30710. {$ifdef wince}
  30711. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  30712. {$endif wince}
  30713. {$ifdef win32}
  30714. Result.Perform(TB_SETEXTENDEDSTYLE, 0, Result.Perform(TB_GETEXTENDEDSTYLE, 0, 0) or
  30715. TBSTYLE_EX_DRAWDDARROWS);
  30716. {$endif win32}
  30717. Result.Perform( TB_BUTTONSTRUCTSIZE, Sizeof( TTBButton ), 0 );
  30718. Result.Perform( TB_SETINDENT, Result.fMargin, 0 );
  30719. with Result.fBoundsRect do
  30720. begin
  30721. if Align in [ caLeft, caRight ] then
  30722. Right := Left + 24
  30723. else if not (Align in [caNone]) then
  30724. Bottom := Top + 22;
  30725. end;
  30726. if Bitmap <> 0 then
  30727. Result.TBAddBitmap( Bitmap );
  30728. Result.TBAddButtons( Buttons, BtnImgIdxArray );
  30729. Result.Perform( WM_SIZE, 0, 0 );
  30730. Result.Style := Result.Style or Flags; {+ecm}
  30731. Result.fLookTabKeys := [ tkTab ];
  30732. end;
  30733. {$ENDIF ASM_VERSION}
  30734. //[END NewToolbar]
  30735. {$ENDIF USE_CONSTRUCTORS}
  30736. //================== DateTimePicker =====================//
  30737. function WndProcDateTimePickerNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30738. var NMhdr: PNMHdr;
  30739. D: TDateTime;
  30740. AllowChg: Boolean;
  30741. NMDTString: PNMDateTimeString;
  30742. begin
  30743. Result := False;
  30744. if Msg.message = WM_NOTIFY then
  30745. begin
  30746. NMHdr := Pointer( Msg.lParam );
  30747. CASE LongInt(NMHdr.code) OF
  30748. DTN_DROPDOWN: if Assigned( Self_.fOnDropDown ) then
  30749. Self_.fOnDropDown( Self_ );
  30750. DTN_CLOSEUP: if Assigned( Self_.fOnCloseUp ) then
  30751. Self_.fOnCloseUp( Self_ );
  30752. DTN_DATETIMECHANGE:
  30753. if Assigned( Self_.fOnChange ) then
  30754. Self_.fOnChange( Self_ );
  30755. DTN_USERSTRING:
  30756. if Assigned( Self_.fOnDTPUserString ) then
  30757. begin
  30758. NMDTString := Pointer( NMHdr );
  30759. D := Self_.DateTime;
  30760. AllowChg := TRUE;
  30761. Self_.fOnDTPUserString( Self_, NMDTString.pszUserString, D, AllowChg );
  30762. NMDTString.dwFlags := Integer( not AllowChg );
  30763. end;
  30764. END;
  30765. end;
  30766. end;
  30767. const
  30768. DateTimePickerOptions: array[ TDateTimePickerOption ] of Integer = (
  30769. DTS_TIMEFORMAT, DTS_LONGDATEFORMAT, DTS_UPDOWN, DTS_RIGHTALIGN,
  30770. DTS_SHOWNONE, DTS_APPCANPARSE );
  30771. function NewDateTimePicker( AParent: PControl; Options: TDateTimePickerOptions )
  30772. : PControl;
  30773. var Flags: DWORD;
  30774. const
  30775. CS_OFF = {$ifdef win32}CS_OWNDC or CS_CLASSDC or {$endif}CS_PARENTDC or CS_GLOBALCLASS or
  30776. CS_VREDRAW or CS_HREDRAW;
  30777. begin
  30778. DoInitCommonControls( ICC_DATE_CLASSES );
  30779. Flags := MakeFlags( @Options, DateTimePickerOptions );
  30780. Result := _NewCommonControl( AParent, DATETIMEPICK_CLASS,
  30781. (WS_CHILD or WS_VISIBLE or WS_TABSTOP or Flags{$ifdef wince} or WS_BORDER{$endif} {or DTS_APPCANPARSE}),
  30782. TRUE, nil );
  30783. Result.SetSize( 110, 24 );
  30784. Result.AttachProc( WndProcDateTimePickerNotify );
  30785. {$ifdef wince}
  30786. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  30787. {$endif wince}
  30788. end;
  30789. procedure TControl.SetDateTime(Value: TDateTime);
  30790. var ST: TSystemTime;
  30791. begin
  30792. if not IsNAN( Value ) then
  30793. DateTime2SystemTime( Value, ST );
  30794. Perform( DTM_SETSYSTEMTIME, Integer( IsNAN( Value ) ) , Integer( @ ST ) );
  30795. end;
  30796. function TControl.GetDateTime: TDateTime;
  30797. var ST: TSystemTime;
  30798. begin
  30799. if Perform( DTM_GETSYSTEMTIME, 0, Integer( @ ST ) ) = GDT_VALID then
  30800. SystemTime2DateTime( ST, Result )
  30801. else
  30802. Result := NAN;
  30803. end;
  30804. function TControl.Get_SystemTime: TSystemTime;
  30805. begin
  30806. if Perform( DTM_GETSYSTEMTIME, 0, Integer( @ Result ) ) <> GDT_VALID then
  30807. FillChar( Result, Sizeof( Result ), #0 );
  30808. end;
  30809. procedure TControl.Set_SystemTime(const Value: TSystemTime);
  30810. begin
  30811. Perform( DTM_SETSYSTEMTIME, Integer( Value.wYear = 0 ) , Integer( @ Value ) );
  30812. end;
  30813. function TControl.GetDate: TDateTime;
  30814. begin
  30815. Result := DateTime;
  30816. if not IsNAN( Result ) then
  30817. Result := Trunc( DateTime );
  30818. end;
  30819. function TControl.GetTime: TDateTime;
  30820. begin
  30821. Result := DateTime;
  30822. if not IsNAN( Result ) then
  30823. Result := Frac( Result );
  30824. end;
  30825. procedure TControl.SetDate(const Value: TDateTime);
  30826. begin
  30827. if IsNAN( Value ) then
  30828. DateTime := Value
  30829. else
  30830. if not IsNAN( DateTime ) then
  30831. DateTime := Trunc( Value ) + Frac( DateTime )
  30832. else
  30833. DateTime := Trunc( Value );
  30834. end;
  30835. procedure TControl.SetTime(const Value: TDateTime);
  30836. begin
  30837. if IsNAN( Value ) then
  30838. DateTime := Value
  30839. else
  30840. if not IsNAN( DateTime ) then
  30841. DateTime := Trunc( DateTime ) + Frac( Value )
  30842. else
  30843. DateTime := 1.0 + Frac( Value );
  30844. end;
  30845. function TControl.GetDateTimeRange: TDateTimeRange;
  30846. var ST_R: array[ 0..1 ] of TSystemTime;
  30847. begin
  30848. Perform( DTM_GETRANGE, 0, Integer( @ ST_R[ 0 ] ) );
  30849. SystemTime2DateTime( ST_R[ 0 ], Result.FromDate );
  30850. SystemTime2DateTime( ST_R[ 1 ], Result.ToDate );
  30851. end;
  30852. procedure TControl.SetDateTimeRange(Value: TDateTimeRange);
  30853. var ST_R: array[ 0..1 ] of TSystemTime;
  30854. begin
  30855. DateTime2SystemTime( Value.FromDate, ST_R[ 0 ] );
  30856. DateTime2SystemTime( Value.ToDate , ST_R[ 1 ] );
  30857. Perform( DTM_SETRANGE,
  30858. Integer( IsNAN( Value.FromDate ) ) or
  30859. (Integer( IsNAN( Value.ToDate ) ) shl 1),
  30860. Integer( @ ST_R[ 0 ] ) );
  30861. end;
  30862. function TControl.GetDateTimePickerColor( Index: TDateTimePickerColor): TColor;
  30863. begin
  30864. Result := Perform( DTM_GETMCCOLOR, Integer( Index ), 0 );
  30865. end;
  30866. procedure TControl.SetDateTimePickerColor(
  30867. Index: TDateTimePickerColor; Value: TColor);
  30868. begin
  30869. Perform( DTM_SETMCCOLOR, Integer( Index ), Color2RGB( Value ) );
  30870. end;
  30871. procedure TControl.SetDateTimeFormat(const Value: KOLString);
  30872. begin
  30873. Perform( DTM_SETFORMAT, 0, Integer( PKOLChar( Value ) ) );
  30874. end;
  30875. //===================== RichEdit ========================//
  30876. {$IFNDEF NOT_USE_RICHEDIT}
  30877. type PENLink = ^TENLink;
  30878. TENLink = {$ifndef wince}packed{$endif} record
  30879. hdr: TNMHDR;
  30880. msg: DWORD;
  30881. wParam: Integer;
  30882. lParam: Integer;
  30883. chrg: TCHARRANGE;
  30884. end;
  30885. TEXTRANGEA = {$ifndef wince}packed{$endif} record
  30886. chrg: TCharRange;
  30887. lpstrText: PAnsiChar;
  30888. end;
  30889. //[FUNCTION WndProc_RE_LinkNotify]
  30890. {$IFDEF ASM_VERSION}
  30891. {$ELSE ASM_VERSION} //Pascal
  30892. function WndProc_RE_LinkNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30893. var Link: PENLink;
  30894. Range: TextRangeA;
  30895. Buffer: array[ 0..1023 ] of Char;
  30896. begin
  30897. Result := False;
  30898. if (Msg.message = WM_NOTIFY) and (PNMHdr( Msg.lParam ).code = EN_LINK) then
  30899. begin
  30900. Link := Pointer( Msg.lParam );
  30901. Range.chrg := Link.chrg;
  30902. Range.lpstrText := @Buffer[ 0 ];
  30903. Buffer[ 0 ] := #0;
  30904. Self_.Perform( EM_GETTEXTRANGE, 0, Integer( @Range ) );
  30905. if (Buffer[ 1 ] = #0) and (Range.chrg.cpMax - Range.chrg.cpMin > 1) then
  30906. Self_.fREUrl := PWideChar( @ Buffer[ 0 ] )
  30907. else
  30908. Self_.fREUrl := Buffer;
  30909. case Link.msg of
  30910. WM_MOUSEMOVE:
  30911. if assigned( Self_.fOnREOverURL ) then
  30912. Self_.fOnREOverURL( Self_ );
  30913. WM_LBUTTONDOWN, WM_RBUTTONDOWN:
  30914. if assigned( Self_.fOnREUrlClick ) then
  30915. Self_.fOnREUrlClick( Self_ );
  30916. end;
  30917. Rslt := 0;
  30918. Result := TRUE;
  30919. end;
  30920. end;
  30921. {$ENDIF ASM_VERSION}
  30922. //[END WndProc_RE_LinkNotify]
  30923. //[FUNCTION WndProcRichEditNotify]
  30924. {$IFDEF ASM_noVERSION}
  30925. function WndProcRichEditNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30926. const int_IDC_ARROW = integer( IDC_ARROW );
  30927. asm
  30928. CMP word ptr [EDX].TMsg.message, WM_NOTIFY
  30929. JNE @@chk_WM_DESTROY
  30930. MOV EDX, [EDX].TMsg.lParam
  30931. CMP [EDX].TNMHdr.code, EN_SELCHANGE
  30932. JNE @@ret_false
  30933. CALL TControl.DoSelChange
  30934. JMP @@ret_false
  30935. @@chk_WM_DESTROY:
  30936. CMP word ptr [EDX].TMsg.message, WM_DESTROY
  30937. JNZ @@ret_false
  30938. LEA EAX, [EAX].TControl.fREUrl
  30939. CALL @LStrClr
  30940. @@ret_false:
  30941. XOR EAX, EAX
  30942. RET
  30943. end;
  30944. {$ELSE ASM_VERSION} //Pascal
  30945. function WndProcRichEditNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  30946. var NMhdr: PNMHdr;
  30947. begin
  30948. Result := False;
  30949. if Msg.message = WM_NOTIFY then
  30950. begin
  30951. NMHdr := Pointer( Msg.lParam );
  30952. case NMHdr.code of
  30953. EN_SELCHANGE:
  30954. begin
  30955. Self_.DoSelChange;
  30956. if Self_.fTransparent then
  30957. Self_.Invalidate;
  30958. end;
  30959. end;
  30960. end
  30961. else
  30962. if Msg.message = WM_DESTROY then
  30963. begin
  30964. Self_.fREURL := '';
  30965. end;
  30966. end;
  30967. {$ENDIF ASM_VERSION}
  30968. //[END WndProcRichEditNotify]
  30969. const RichEditflags: array [ TEditOption ] of Integer = (
  30970. not (es_AutoHScroll or WS_HSCROLL),
  30971. not (es_AutoVScroll or WS_VSCROLL),
  30972. 0 {es_Lowercase - not supported},
  30973. 0 {es_Multiline - RichEdit always multiline},
  30974. es_NoHideSel,
  30975. 0 {es_OemConvert - not suppoted},
  30976. 0 {es_Password - not supported},
  30977. es_Readonly,
  30978. 0 {es_UpperCase - not supported},
  30979. es_WantReturn, 0, es_Number );
  30980. {$IFDEF USE_CONSTRUCTORS}
  30981. //[function NewRichEdit1]
  30982. function NewRichEdit1( AParent: PControl; Options: TEditOptions ): PControl;
  30983. begin
  30984. new( Result, CreateRichEdit1( AParent, Options ) );
  30985. end;
  30986. //[END NewRichEdit1]
  30987. {$ELSE not_USE_CONSTRUCTORS}
  30988. //[FUNCTION NewRichEdit1]
  30989. {$IFDEF ASM_UNICODE}
  30990. {$ELSE ASM_VERSION} //Pascal
  30991. function NewRichEdit1( AParent: PControl; Options: TEditOptions ): PControl;
  30992. var Flags, I, d, Last, SaveErrMode: Integer;
  30993. label search_richedit;
  30994. begin
  30995. {$IFDEF INPACKAGE}
  30996. Log( '->NewRichEdit1' );
  30997. TRY
  30998. {$ENDIF INPACKAGE}
  30999. if FRichEditModule = 0 then
  31000. begin
  31001. search_richedit:
  31002. I := RichEditIdx;
  31003. Last := High( RichEditLibnames );
  31004. d := 1;
  31005. if RichEditIdx > 0 then
  31006. begin
  31007. I := Last;
  31008. Last := 0;
  31009. d := -1;
  31010. end;
  31011. SaveErrMode := SetErrorMode( SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS );
  31012. while I <> Last + d do
  31013. begin
  31014. FRichEditModule := LoadLibrary( RichEditLibnames[ I ] );
  31015. RichEditClass := RichEditClasses[ I ];
  31016. if FRichEditModule > HINSTANCE_ERROR then break;
  31017. inc( I, d );
  31018. end;
  31019. if FRichEditModule <= HINSTANCE_ERROR then
  31020. FRichEditModule := 0;
  31021. SetErrorMode( SaveErrMode );
  31022. end;
  31023. Flags := MakeFlags( @Options, RichEditFlags );
  31024. {$IFDEF INPACKAGE}
  31025. Log( '//// calling _NewCommonControl' );
  31026. {$ENDIF INPACKAGE}
  31027. Result := _NewCommonControl( AParent, RichEditClass, WS_VISIBLE or WS_CHILD
  31028. or WS_TABSTOP or WS_BORDER or ES_MULTILINE or Flags,
  31029. True, @RichEditActions );
  31030. {$IFDEF INPACKAGE}
  31031. Log( '//// after _NewCommonControl called' );
  31032. {$ENDIF INPACKAGE}
  31033. Result.fIgnoreDefault := TRUE;
  31034. Result.fLookTabKeys := [ tkTab ];
  31035. if eoWantTab in Options then
  31036. Result.fLookTabKeys := [ ];
  31037. Result.AttachProc( WndProcRichEditNotify );
  31038. Result.fDoubleBuffered := False;
  31039. Result.fCannotDoubleBuf := True;
  31040. with Result.fBoundsRect do
  31041. begin
  31042. Right := Right + 100;
  31043. Bottom := Top + 200;
  31044. end;
  31045. {$IFDEF INPACKAGE}
  31046. Log( '//// before Perform' );
  31047. {$ENDIF INPACKAGE}
  31048. Result.Perform( EM_SETEVENTMASK, 0,
  31049. ENM_CHANGE or ENM_SELCHANGE or ENM_REQUESTRESIZE or
  31050. ENM_PROTECTED or $04000000 {ENM_LINK} or ENM_KEYEVENTS );
  31051. {$IFDEF INPACKAGE}
  31052. Log( '//// after Perform' );
  31053. {$ENDIF INPACKAGE}
  31054. Result.fColor := clWindow;
  31055. Result.Perform( EM_SETBKGNDCOLOR, 0, Color2RGB(Result.fColor));
  31056. {$IFDEF RICHEDIT_XPBORDER}
  31057. Result.AttachProc( WndProc_RichEditXPBorder );
  31058. {$ENDIF}
  31059. {$IFDEF INPACKAGE}
  31060. LogOK;
  31061. FINALLY
  31062. Log( '<-NewRichEdit1' );
  31063. END;
  31064. {$ENDIF INPACKAGE}
  31065. end;
  31066. {$ENDIF ASM_VERSION}
  31067. //[END NewRichEdit1]
  31068. {$ENDIF NOT_USE_RICHEDIT}
  31069. {$ENDIF USE_CONSTRUCTORS}
  31070. {$ifdef win32}
  31071. //[API OleInitialize]
  31072. function OleInitialize(pwReserved: Pointer): HResult; {$ifdef wince}cdecl{$else}stdcall{$endif};
  31073. external 'ole32.dll' name 'OleInitialize';
  31074. procedure OleUninitialize; {$ifdef wince}cdecl{$else}stdcall{$endif};
  31075. external 'ole32.dll' name 'OleUninitialize';
  31076. //[FUNCTION OleInit]
  31077. {$IFDEF ASM_VERSION}
  31078. {$ELSE ASM_VERSION} //Pascal
  31079. function OleInit: Boolean;
  31080. begin
  31081. if OleInitCount = 0 then
  31082. begin
  31083. Result := False;
  31084. if OleInitialize( nil ) <> 0 then Exit;
  31085. end;
  31086. Inc( OleInitCount );
  31087. Result := True;
  31088. end;
  31089. {$ENDIF ASM_VERSION}
  31090. //[END OleInit]
  31091. //[PROCEDURE OleUnInit]
  31092. {$IFDEF ASM_VERSION}
  31093. {$ELSE ASM_VERSION} //Pascal
  31094. procedure OleUnInit;
  31095. begin
  31096. if OleInitCount > 0 then
  31097. begin
  31098. Dec( OleInitCount );
  31099. if OleInitCount = 0 then
  31100. OleUninitialize;
  31101. end;
  31102. end;
  31103. {$ENDIF ASM_VERSION}
  31104. //[END OleUnInit]
  31105. //[API SysAllocStringLen]
  31106. function SysAllocStringLen(psz: PWideChar; len: Integer): PWideChar; {$ifdef wince}cdecl{$else}stdcall{$endif};
  31107. external 'oleaut32.dll' name 'SysAllocStringLen';
  31108. procedure SysFreeString( psz: PWideChar ); {$ifdef wince}cdecl{$else}stdcall{$endif};
  31109. external 'oleaut32.dll' name 'SysFreeString';
  31110. {-}
  31111. //[function StringToOleStr]
  31112. function StringToOleStr(const Source: string): PWideChar;
  31113. var
  31114. SourceLen, ResultLen: Integer;
  31115. Buffer: array[0..1023] of WideChar;
  31116. begin
  31117. SourceLen := Length(Source);
  31118. if Length(Source) < SizeOf(Buffer) div 2 then
  31119. Result := SysAllocStringLen(Buffer, MultiByteToWideChar(0, 0,
  31120. PChar(Source), SourceLen, Buffer, SizeOf(Buffer) div 2))
  31121. else
  31122. begin
  31123. ResultLen := MultiByteToWideChar(0, 0,
  31124. Pointer(Source), SourceLen, nil, 0);
  31125. Result := SysAllocStringLen(nil, ResultLen);
  31126. MultiByteToWideChar(0, 0, Pointer(Source), SourceLen,
  31127. Result, ResultLen);
  31128. end;
  31129. end;
  31130. {+}
  31131. {$endif win32}
  31132. {$IFNDEF NOT_USE_RICHEDIT}
  31133. {$IFDEF USE_CONSTRUCTORS}
  31134. //[function NewRichEdit]
  31135. function NewRichEdit( AParent: PControl; Options: TEditOptions ): PControl;
  31136. begin
  31137. new( Result, CreateRichEdit( AParent, Options ) );
  31138. end;
  31139. //[END NewRichEdit]
  31140. {$ELSE not_USE_CONSTRUCTORS}
  31141. //[FUNCTION NewRichEdit]
  31142. {$IFDEF ASM_VERSION}
  31143. const RichEdit50W: array[0..11] of Char = ('R','i','c','h','E','d','i','t','5','0','W',#0 );
  31144. function NewRichEdit( AParent: PControl; Options: TEditOptions ): PControl;
  31145. const deltaChr = 24; // sizeof( TCharFormat2 ) - sizeof( RichEdit.TCharFormat );
  31146. deltaPar = sizeof( TParaFormat2 ) - sizeof( RichEdit.TParaFormat );
  31147. asm
  31148. PUSHAD
  31149. CALL OleInit
  31150. TEST EAX, EAX
  31151. POPAD
  31152. JZ @@new1
  31153. MOV [RichEditIdx], 0
  31154. CALL NewRichEdit1
  31155. MOV byte ptr [EAX].TControl.fCharFmtDeltaSz, deltaChr
  31156. MOV byte ptr [EAX].TControl.fParaFmtDeltaSz, deltaPar
  31157. RET
  31158. @@new1: CALL NewRichEdit1
  31159. end;
  31160. {$ELSE ASM_VERSION} //Pascal
  31161. function NewRichEdit( AParent: PControl; Options: TEditOptions ): PControl;
  31162. begin
  31163. {$ifdef win32}
  31164. {$IFDEF INPACKAGE}
  31165. Log( '->NewRichEdit' );
  31166. TRY
  31167. {$ENDIF INPACKAGE}
  31168. if OleInit then
  31169. begin
  31170. {$IFDEF INPACKAGE}
  31171. Log( '//// OleInit OK: call NewRichEdit1' );
  31172. {$ENDIF INPACKAGE}
  31173. RichEditIdx := 0;
  31174. Result := NewRichEdit1( AParent, Options );
  31175. Result.fCharFmtDeltaSz := 24; //sizeof( TCharFormat2 ) - sizeof( RichEdit.TCharFormat );
  31176. // sizeof( TCharFormat2 ) is calculated incorrectly
  31177. Result.fParaFmtDeltaSz := sizeof( TParaFormat2 ) - sizeof( RichEdit.TParaFormat );
  31178. end
  31179. else
  31180. {$endif win32}
  31181. begin
  31182. {$IFDEF INPACKAGE}
  31183. Log( '//// OleInit failed: call NewRichEdit1' );
  31184. {$ENDIF INPACKAGE}
  31185. Result := NewRichEdit1( AParent, Options );
  31186. end;
  31187. {$IFDEF INPACKAGE}
  31188. LogOK;
  31189. FINALLY
  31190. Log( '<-NewRichEdit' );
  31191. END;
  31192. {$ENDIF INPACKAGE}
  31193. end;
  31194. {$ENDIF ASM_VERSION}
  31195. //[END NewRichEdit]
  31196. {$ENDIF USE_CONSTRUCTORS}
  31197. {$ENDIF NOT_USE_RICHEDIT}
  31198. //=====================================================================//
  31199. {$ENDIF WIN_GDI}
  31200. { TControl }
  31201. //[procedure TControl.Init]
  31202. {$IFDEF ASM_VERSION}
  31203. {$ELSE ASM_VERSION} //Pascal
  31204. procedure TControl.Init;
  31205. begin
  31206. {$IFDEF _D2orD3}
  31207. inherited; // nothing here for Delphi 4 and higher
  31208. {$ENDIF}
  31209. {$IFDEF USE_GRAPHCTLS}
  31210. fDoInvalidate := InvalidateWindowed;
  31211. {$ENDIF}
  31212. {$IFDEF GDI}
  31213. fOnDynHandlers := WndProcDummy;
  31214. fWndProcKeybd := WndProcDummy;
  31215. fWndProcResizeFlicks := WndProcDummy;
  31216. fPass2DefProc := WndProcDummy;
  31217. fWndFunc := @ WndFunc;
  31218. fCommandActions.aClear := ClearText;
  31219. fWindowed := True;
  31220. fControlClick := DummyObjProc;
  31221. fAutoSize := DummyObjProc;
  31222. fColor := {$ifdef wince}clWindow{$else}clBtnFace{$endif};
  31223. fTextColor := clWindowText;
  31224. {$ENDIF GDI}
  31225. fMargin := 2;
  31226. {$IFDEF GDI}
  31227. fCtl3D := True;
  31228. fCtl3Dchild := True;
  31229. fAlphaBlend := 255;
  31230. {$ENDIF GDI}
  31231. fChildren := NewList;
  31232. {$IFDEF GDI}
  31233. {$ifdef win32}
  31234. fClsStyle := CS_OWNDC;
  31235. fExStyle := WS_EX_CONTROLPARENT;
  31236. {$endif win32}
  31237. fStyle := WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_BORDER
  31238. {$ifdef win32} or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or
  31239. WS_THICKFRAME {$endif};
  31240. {$ENDIF GDI}
  31241. fVisible := True;
  31242. fEnabled := True;
  31243. fDynHandlers := NewList;
  31244. end;
  31245. {$ENDIF ASM_VERSION}
  31246. //[PROCEDURE CallTControlInit]
  31247. {$IFDEF GDI}
  31248. {$IFDEF ASM_VERSION}
  31249. {$ELSE ASM_VERSION} //Pascal
  31250. procedure TControl.InitParented( AParent: PControl );
  31251. begin
  31252. Init;
  31253. if AParent <> nil then
  31254. fColor := AParent.fColor;
  31255. Parent := AParent;
  31256. end;
  31257. {$ENDIF ASM_VERSION}
  31258. {$ENDIF GDI}
  31259. {$IFDEF _X_}
  31260. {$IFDEF GTK}
  31261. procedure TControl.InitParented( AParent: PControl; widget: PGtkWidget;
  31262. need_eventbox: Boolean );
  31263. begin
  31264. Init;
  31265. fHandle := widget;
  31266. fCaptionHandle := fHandle;
  31267. fEventboxHandle := fHandle;
  31268. if need_eventbox then
  31269. begin
  31270. fEventboxHandle := gtk_event_box_new();
  31271. gtk_widget_set_events( fEventboxHandle, GDK_ALL_EVENTS_MASK );
  31272. //gtk_container_add( GTK_CONTAINER( AParent.fHandle ), fEventboxHandle );
  31273. gtk_widget_show( fEventboxHandle );
  31274. gtk_container_add( GTK_CONTAINER( fEventboxHandle ), fHandle );
  31275. end;
  31276. g_object_set_data( G_OBJECT( fEventboxHandle ), ID_SELF, @ Self );
  31277. if AParent <> nil then
  31278. fColor := AParent.fColor;
  31279. Parent := AParent;
  31280. end;
  31281. {$ENDIF GTK}
  31282. {$ENDIF _X_}
  31283. {$IFDEF WIN_GDI}
  31284. //[destructor TControl.Destroy]
  31285. {$IFDEF ASM_VERSION}
  31286. {$ELSE ASM_VERSION} //Pascal
  31287. destructor TControl.Destroy;
  31288. var I: Integer;
  31289. F: PControl;
  31290. Ico: HIcon;
  31291. begin
  31292. {$IFDEF USE_CUSTOMEXTENSIONS}
  31293. {$I CUSTOM_TCONTROL_DESTROY.INC}
  31294. {$ENDIF}
  31295. {$IFDEF USE_MHTOOLTIP}
  31296. {$DEFINE destroy}
  31297. {$I KOLMHToolTip.pas}
  31298. {$UNDEF destroy}
  31299. {$ENDIF USE_MHTOOLTIP}
  31300. {$IFDEF DEBUG}
  31301. TRY
  31302. F := ParentForm; // or Applet - for form ???
  31303. EXCEPT
  31304. asm
  31305. nop
  31306. end;
  31307. END;
  31308. {$ELSE}
  31309. F := ParentForm; // or Applet - for form ???
  31310. {$ENDIF}
  31311. if F <> nil then
  31312. if F.FCurrentControl = @Self then
  31313. F.FCurrentControl := nil;
  31314. if FHandle <> 0 then
  31315. ShowWindow( fHandle, SW_HIDE );
  31316. Final;
  31317. {$IFDEF USE_AUTOFREE4CHILDREN}
  31318. {$ELSE}
  31319. DestroyChildren;
  31320. {$ENDIF}
  31321. if not fDestroying then
  31322. begin
  31323. fDestroying := True;
  31324. if fCtlClsNameChg then
  31325. begin
  31326. FreeMem( fControlClassName );
  31327. fCtlClsNameChg := FALSE;
  31328. end;
  31329. {$IFDEF USE_AUTOFREE4CONTROLS}
  31330. {$ELSE}
  31331. fFont.Free;
  31332. fFont := nil;
  31333. fBrush.Free;
  31334. fBrush := nil;
  31335. {$ENDIF}
  31336. fCanvas.Free;
  31337. fCanvas := nil;
  31338. if fHandle <> 0 then
  31339. begin
  31340. {$IFNDEF NEW_MENU_ACCELL}
  31341. {$IFDEF USE_AUTOFREE4CONTROLS}
  31342. {$ELSE}
  31343. if fAccelTable <> 0 then
  31344. begin
  31345. DestroyAcceleratorTable( fAccelTable );
  31346. fAccelTable := 0;
  31347. end;
  31348. {$ENDIF}
  31349. {$ENDIF}
  31350. {$IFDEF USE_AUTOFREE4CONTROLS}
  31351. {$ELSE}
  31352. fMenuObj.Free;
  31353. while fImageList <> nil do
  31354. fImageList.Free;
  31355. {$ENDIF}
  31356. I := fHandle;
  31357. Ico := fIcon;
  31358. if (Ico <> 0) and (Ico <> HIcon(-1)) then
  31359. if not fIconShared then
  31360. DestroyIcon( Ico );
  31361. if IsWindow( I ) then
  31362. begin
  31363. // RemoveProp( I, ID_SELF ); //************** Remarked By M.Gerasimov
  31364. if not fNCDestroyed then
  31365. begin
  31366. {$IFDEF DEBUG_ENDSESSION}
  31367. if EndSession_Initiated then
  31368. LogFileOutput( GetStartDir + 'es_debug.txt',
  31369. 'DESTROYING HWND:' + Int2Str( I ) );
  31370. {$ENDIF}
  31371. //if fIsForm then
  31372. {$IFDEF USE_PROP}
  31373. SetProp( I, ID_SELF, 0 );
  31374. {$ELSE}
  31375. SetWindowLong( I, GWL_USERDATA, 0 );
  31376. {$ENDIF}
  31377. DestroyWindow( I );
  31378. end;
  31379. end;
  31380. fHandle := 0;
  31381. end;
  31382. if fCustomData <> nil then
  31383. FreeMem( fCustomData );
  31384. fCustomData := nil;
  31385. fCustomObj.Free;
  31386. fCustomObj := nil;
  31387. if fTmpBrush <> 0 then
  31388. DeleteObject( fTmpBrush );
  31389. fTmpBrush := 0;
  31390. //if FCaption <> nil then FreeMem( FCaption );
  31391. fCaption := '';
  31392. if fStatusTxt <> nil then
  31393. FreeMem( fStatusTxt );
  31394. if fParent <> nil then
  31395. begin
  31396. fParent.fChildren.Remove( @Self );
  31397. {$IFDEF USE_AUTOFREE4CHILDREN}
  31398. fParent.RemoveFromAutoFree( @ Self );
  31399. {$ENDIF}
  31400. if fParent.fCurrentControl = @Self then
  31401. fParent.fCurrentControl := nil;
  31402. end;
  31403. fChildren.Free;
  31404. {$IFDEF USE_AUTOFREE4CONTROLS}
  31405. {$ELSE}
  31406. fTBttCmd.Free;
  31407. fTBttTxt.Free;
  31408. fTmpFont.Free;
  31409. {$ENDIF}
  31410. fDynHandlers.Free;
  31411. //fREUrl := '';
  31412. inherited;
  31413. end;
  31414. end;
  31415. {$ENDIF ASM_VERSION}
  31416. {$IFDEF USE_MHTOOLTIP}
  31417. {$DEFINE code}
  31418. {$I KOLMHToolTip.pas}
  31419. {$UNDEF code}
  31420. {$ENDIF}
  31421. //[procedure TControl.SetEnabled]
  31422. {$IFDEF ASM_VERSION}
  31423. {$ELSE ASM_VERSION} //Pascal
  31424. procedure TControl.SetEnabled( Value: Boolean );
  31425. begin
  31426. if GetEnabled = Value then Exit;
  31427. fEnabled := Value;
  31428. if Value then
  31429. fStyle := fStyle and not WS_DISABLED
  31430. else
  31431. fStyle := fStyle or WS_DISABLED;
  31432. if fHandle <> 0 then
  31433. EnableWindow( fHandle, fEnabled );
  31434. Invalidate; // necessary for Graphic controls
  31435. end;
  31436. {$ENDIF ASM_VERSION}
  31437. //[function TControl.GetParentWindow]
  31438. {$IFDEF ASM_VERSION}
  31439. {$ELSE ASM_VERSION} //Pascal
  31440. function TControl.GetParentWindow: HWnd;
  31441. begin
  31442. Result := 0;
  31443. if fParent = nil then Exit;
  31444. Result := fParent.GetWindowHandle;
  31445. end;
  31446. {$ENDIF ASM_VERSION}
  31447. {$IFDEF ASM_UNICODE}
  31448. {$ELSE ASM_VERSION} //Pascal
  31449. function TControl.GetWindowHandle: HWnd;
  31450. begin
  31451. {$IFDEF INPACKAGE}
  31452. Log( '->TControl.GetWindowHandle' );
  31453. TRY
  31454. {$ENDIF INPACKAGE}
  31455. if fHandle = 0 then
  31456. begin
  31457. if not fCreateVisible then
  31458. begin
  31459. Set_Visible( False );
  31460. CreateWindow; //virtual!!!
  31461. fCreateHidden := True;
  31462. end
  31463. else
  31464. CreateWindow; //virtual!!!
  31465. end;
  31466. Result := fHandle;
  31467. {$IFDEF INPACKAGE}
  31468. LogOK;
  31469. FINALLY
  31470. Log( '<-TControl.GetWindowHandle' );
  31471. END;
  31472. {$ENDIF INPACKAGE}
  31473. end;
  31474. {$ENDIF ASM_VERSION}
  31475. {-}
  31476. {$IFDEF _D7orHigher}
  31477. // may be it was a good idea to replace CreateWindowEx,
  31478. // but Inprise forget about {$ifdef wince}cdecl{$else}stdcall{$endif}... In result, asm-version became broken.
  31479. //[API CreateWindowEx]
  31480. {$IFNDEF UNICODE_CTRLS}
  31481. function CreateWindowEx(dwExStyle: DWORD; lpClassName: PChar;
  31482. lpWindowName: PChar; dwStyle: DWORD; X, Y, nWidth, nHeight: Integer;
  31483. hWndParent: HWND; hMenu: HMENU; hInstance: HINST; lpParam: Pointer): HWND;
  31484. {$ifdef wince}cdecl{$else}stdcall{$endif}; external user32 name 'CreateWindowExA';
  31485. {$ENDIF}
  31486. {$ENDIF}
  31487. {$IFDEF DEBUG_CREATEWINDOW}
  31488. procedure Debug_CreateWindow1( _Self: PControl );
  31489. begin
  31490. {LogFileOutput( GetStartDir + 'Session.log', 'TControl.CreateWindow, ' +
  31491. ' Self = ' + Int2Str( Integer( _Self ) ) +
  31492. ' Caption = ' + _Self.fCaption +
  31493. ' fChildren = ' + Int2Hex( Integer( _Self.fChildren ), 4 ) +
  31494. ' ChildCount = ' + Int2Str( _Self.ChildCount ) );}
  31495. end;
  31496. procedure Debug_CreateWindow2( _Self: PControl; const Params: TCreateWndParams );
  31497. begin
  31498. LogFileOutput( GetStartDir + 'Session.log',
  31499. ' ExStyle=' + Int2Hex( Params.ExStyle, 4 ) +
  31500. ' WinClassName=' + Params.WinClassName +
  31501. ' Caption=' + Params.Caption +
  31502. ' Style=' + Int2Hex( Params.Style, 4 ) +
  31503. ' X=' + Int2Str( Params.X ) +
  31504. ' Y=' + Int2Str( Params.Y ) +
  31505. ' Width=' + Int2Str( Params.Width ) +
  31506. ' Height=' + Int2Str( Params.Height ) +
  31507. //' WndParent=' + Int2Str( Params.WndParent ) +
  31508. ' Parent=' + Int2Hex( DWORD( _Self.Parent ), 6 ) +
  31509. ' Menu=' + Int2Str( Params.Menu ) +
  31510. ' hInstance=' + Int2Str( Params.WindowClass.hInstance ) +
  31511. ' Param=' + Int2Str( Integer( Params.Param ) ) +
  31512. ' WindowClass.style:' + Int2Str( Params.WindowClass.style ) +
  31513. ' WindowClass.lpfnWndProc:' + Int2Str( DWORD( Pointer( Params.WindowClass.lpfnWndProc ) ) ) +
  31514. ' WindowClass.cbClsExtra:' + Int2Str( DWORD( Params.WindowClass.cbClsExtra ) ) +
  31515. ' WindowClass.cbWndExtra:' + Int2Str( DWORD( Params.WindowClass.cbWndExtra ) ) +
  31516. ' WindowClass.hInstance:' + Int2Str( Params.WindowClass.hInstance ) +
  31517. ' WindowClass.hIcon:' + Int2Str( Params.WindowClass.hIcon ) +
  31518. ' WindowClass.hCursor:' + Int2Str( Params.WindowClass.hCursor ) +
  31519. ' WindowClass.hbrBackground:' + Int2Str( Params.WindowClass.hbrBackground ) +
  31520. ' WindowClass.lpszMenuName:' + Params.WindowClass.lpszMenuName +
  31521. ' WindowClass.lpszClassName:' + Params.WindowClass.lpszClassName
  31522. );
  31523. end;
  31524. {$ENDIF DEBUG_CREATEWINDOW}
  31525. {+}
  31526. //[function TControl.CreateWindow]
  31527. {$IFDEF ASM_UNICODE}
  31528. {$ELSE ASM_VERSION} //Pascal
  31529. function TControl.CreateWindow: Boolean;
  31530. const
  31531. CS_OFF = {$ifdef win32}CS_OWNDC or CS_CLASSDC or {$endif} CS_PARENTDC or CS_GLOBALCLASS;
  31532. CS_ON = 0; //CS_VREDRAW or CS_HREDRAW;
  31533. var TempClass: TWndClass;
  31534. Params: TCreateWndParams;
  31535. ClassRegistered: Boolean;
  31536. {$IFDEF _FPC}
  31537. SClassName: String;
  31538. {$ENDIF ASM_VERSION}
  31539. {$ifdef wince}
  31540. DR: TRect;
  31541. mbi: SHMENUBARINFO;
  31542. {$endif wince}
  31543. begin
  31544. {$IFDEF INPACKAGE}
  31545. Log( '->TControl.CreateWindow' );
  31546. TRY
  31547. {$ENDIF INPACKAGE}
  31548. {$IFDEF DEBUG_CREATEWINDOW}
  31549. Debug_CreateWindow1( @ Self );
  31550. {$ENDIF DEBUG_CREATEWINDOW}
  31551. Result := False;
  31552. if fParent <> nil then
  31553. if fParent.GetWindowHandle = 0 then
  31554. Exit;
  31555. if fHandle <> 0 then
  31556. begin
  31557. if fCreateHidden then
  31558. begin
  31559. CreateChildWindows;
  31560. Set_Visible( True );
  31561. fCreateHidden := False;
  31562. end
  31563. else
  31564. begin
  31565. CreateChildWindows;
  31566. end;
  31567. Result := True;
  31568. {$IFDEF INPACKAGE}
  31569. LogOK;
  31570. {$ENDIF INPACKAGE}
  31571. Exit;
  31572. end;
  31573. {$IFDEF USE_GRAPHCTLS}
  31574. if not fWindowed then Exit;
  31575. {$ENDIF}
  31576. {$IFDEF INPACKAGE}
  31577. Log( '/// Filling Params' );
  31578. {$ENDIF INPACKAGE}
  31579. FillChar( Params, Sizeof( Params ), 0 );
  31580. {$ifndef wince}
  31581. Params.WindowClass.hCursor := LoadCursor( 0, IDC_ARROW );
  31582. {$endif wince}
  31583. Params.WindowClass.hInstance := hInstance;
  31584. Params.WindowClass.lpfnWndProc := fDefWndProc;
  31585. Params.WindowClass.style := fClsStyle;
  31586. {$IFDEF _FPC}
  31587. SClassName := SubClassName;
  31588. StrCopy( Params.WinClsNamBuf, @ SClassName[ 1 ] );
  31589. {$ELSE}
  31590. {$IFNDEF UNICODE_CTRLS}
  31591. StrCopy( Params.WinClsNamBuf, @ SubClassName[ 1 ] );
  31592. {$ELSE}
  31593. WStrCopy(Params.WinClsNamBuf, @SubClassName[1]);
  31594. {$ENDIF}
  31595. {$ENDIF}
  31596. Params.Param := nil;
  31597. Params.Inst := hInstance;
  31598. Params.Menu := fMenu;
  31599. Params.WndParent := GetParentWnd( TRUE );
  31600. Params.Height := fBoundsRect.Bottom - fBoundsRect.Top;
  31601. if Params.Height = 0 then
  31602. Params.Height := CW_UseDefault;
  31603. Params.Width := fBoundsRect.Right - fBoundsRect.Left;
  31604. if Params.Width = 0 then
  31605. Params.Width := CW_UseDefault;
  31606. Params.Y := fBoundsRect.Top;
  31607. Params.X := fBoundsRect.Left;
  31608. if not fIsControl and (fChangedPosSz and 3 = 0) then
  31609. begin
  31610. Params.Y := CW_UseDefault;
  31611. Params.X := CW_UseDefault;
  31612. end;
  31613. {$ifdef wince}
  31614. if fIsForm then begin
  31615. SystemParametersInfo(SPI_GETWORKAREA, 0, @DR, 0);
  31616. if Params.X = Integer(CW_UseDefault) then
  31617. Params.X:=DR.Left;
  31618. if Params.Y = Integer(CW_UseDefault) then
  31619. Params.Y:=DR.Top;
  31620. if Params.Width = Integer(CW_UseDefault) then
  31621. Params.Width:=DR.Right - Params.X;
  31622. if Params.Height = Integer(CW_UseDefault) then
  31623. Params.Height:=ScreenHeight - Params.Y;
  31624. end;
  31625. {$endif wince}
  31626. Params.Style := fStyle;
  31627. Params.Caption := PKOLChar( fCaption );
  31628. Params.WinClassName := @ Params.WinClsNamBuf[ 0 ];
  31629. Params.ExStyle := fExStyle;
  31630. {$IFDEF INPACKAGE}
  31631. Log( '/// Getting class info' );
  31632. {$ENDIF INPACKAGE}
  31633. {$ifndef wince}
  31634. if fControlClassName <> nil then
  31635. begin
  31636. GetClassInfo( Params.Inst,fControlClassName,Params.WindowClass );
  31637. Params.WindowClass.hInstance := Params.Inst;
  31638. Params.WindowClass.style := Params.WindowClass.style and
  31639. not CS_OFF or CS_ON;
  31640. end;
  31641. {$endif wince}
  31642. if (fDefWndProc = nil) {$ifdef wince} and GetClassInfo(Params.Inst,fControlClassName,Params.WindowClass)
  31643. and (ptruint(@Params.WindowClass.lpfnWndProc) and $FFFFFF <> ptruint(@WndFunc)) {$endif}
  31644. then
  31645. fDefWndProc := {$ifdef FPC}@{$endif}Params.WindowClass.lpfnWndProc;
  31646. if Params.WndParent = 0 then
  31647. if Params.Style and WS_CHILD <> 0 then Exit;
  31648. ClassRegistered := GetClassInfo( Params.Inst,Params.WinClassName, TempClass );
  31649. {$IFDEF INPACKAGE}
  31650. Log( '/// Registering window class' );
  31651. {$ENDIF INPACKAGE}
  31652. if not ClassRegistered then
  31653. begin
  31654. Params.WindowClass.lpszClassName := Params.WinClassName;
  31655. Params.WindowClass.lpfnWndProc := @ WndFunc;
  31656. if RegisterClass( Params.WindowClass ) = 0 then Exit;
  31657. end;
  31658. {$IFDEF DEBUG_CREATEWINDOW}
  31659. Debug_CreateWindow2( @ Self, Params );
  31660. {$ENDIF}
  31661. {$ifdef wince}
  31662. if fDefWndProc = nil then
  31663. {$endif wince}
  31664. CreatingWindow := @Self;
  31665. {$IFDEF INPACKAGE}
  31666. Log( '/// Calling CreateWindowEx' );
  31667. {$ENDIF INPACKAGE}
  31668. {$IFNDEF UNICODE_CTRLS}
  31669. fHandle := CreateWindowEx( Params.ExStyle, Params.WinClassName,
  31670. Params.Caption, Params.Style, Params.X, Params.Y,
  31671. Params.Width, Params.Height, Params.WndParent,
  31672. Params.Menu, Params.Inst,
  31673. Params.Param );
  31674. {$ELSE}
  31675. fHandle := CreateWindowExW( Params.ExStyle{ or WS_EX_RTLREADING}, Params.WinClassName,
  31676. Params.Caption, Params.Style, Params.X, Params.Y,
  31677. Params.Width, Params.Height, Params.WndParent,
  31678. Params.Menu, Params.Inst,
  31679. Params.Param );
  31680. {$ENDIF}
  31681. {$IFDEF INPACKAGE}
  31682. Log( '/// CreateWindowEx called' );
  31683. {$ENDIF INPACKAGE}
  31684. {$ifdef wince}
  31685. if fDefWndProc <> nil then
  31686. SetWindowLong(fHandle, GWL_WNDPROC, LongInt(@WndFunc));
  31687. if not fIsControl then
  31688. if fMenuObj <> nil then
  31689. CeSetMenu(fHandle, PMenu(fMenuObj))
  31690. else
  31691. if CePlatform <> cpSmartphone then begin
  31692. FillChar(mbi, SizeOf(mbi), 0);
  31693. with mbi do begin
  31694. cbSize:=SizeOf(mbi);
  31695. hwndParent:=fHandle;
  31696. dwFlags:=SHCMBF_EMPTYBAR;
  31697. end;
  31698. if SHCreateMenuBar(@mbi) then begin
  31699. GetWindowRect(mbi.hwndMB, DR);
  31700. if Params.Y + Params.Height > DR.Top then
  31701. SetWindowPos(fHandle, 0, 0, 0, Params.Width, DR.Top - Params.Y, SWP_NOZORDER or SWP_NOREPOSITION or SWP_NOMOVE);
  31702. end;
  31703. end;
  31704. if fStyle and WS_VISIBLE <> 0 then
  31705. Perform(WM_SHOWWINDOW, 1, 0);
  31706. {$endif wince}
  31707. {$IFDEF DEBUG_CREATEWINDOW}
  31708. if fHandle = 0 then
  31709. begin
  31710. MessageBox(0,
  31711. PKOLChar(SysErrorMessage(GetLastError)),
  31712. 'Error creating window',mb_iconhand);
  31713. Exit;
  31714. end;
  31715. {$ENDIF}
  31716. {$IFDEF INPACKAGE}
  31717. Log( '/// SendMessage WM_UPDATEUISTATE' );
  31718. {$ENDIF INPACKAGE}
  31719. {$ifndef wince}
  31720. SendMessage( fHandle, $0128 {WM_UPDATEUISTATE},
  31721. 2 {UIS_CLEAR} or (1 {UISF_HIDEFOCUS} shl 16),0);
  31722. {$endif wince}
  31723. {$IFDEF USE_PROP}
  31724. if GetProp(FHandle,ID_SELF) = 0 then
  31725. begin
  31726. CreatingWindow := nil;
  31727. SetProp(FHandle, ID_SELF, THandle(@Self));
  31728. end;
  31729. {$ELSE}
  31730. CreatingWindow := nil;
  31731. SetWindowLong( FHandle, GWL_USERDATA, Integer(@Self) );
  31732. {$ENDIF}
  31733. //***
  31734. {$IFDEF INPACKAGE}
  31735. Log( '/// Perform WM_SETICON' );
  31736. {$ENDIF INPACKAGE}
  31737. {$IFDEF SMALLEST_CODE}
  31738. {$ELSE}
  31739. {$ifndef wince}
  31740. if not fIsControl then
  31741. Perform( WM_SETICON, 1 {ICON_BIG}, GetIcon );
  31742. {$endif wince}
  31743. {$ENDIF}
  31744. if Assigned( FCreateWndExt ) then
  31745. FCreateWndExt( @Self );
  31746. {$IFDEF INPACKAGE}
  31747. Log( '/// ApplyFont2Wnd' );
  31748. {$ENDIF INPACKAGE}
  31749. ApplyFont2Wnd;
  31750. {$IFDEF INPACKAGE}
  31751. Log( '/// CreateChildWindows' );
  31752. {$ENDIF INPACKAGE}
  31753. CreateChildWindows;
  31754. {$IFDEF INPACKAGE}
  31755. Log( '/// CreateChildWindows called OK' );
  31756. {$ENDIF INPACKAGE}
  31757. Result := True;
  31758. {$IFDEF INPACKAGE}
  31759. LogOK;
  31760. FINALLY
  31761. Log( '<-TControl.CreateWindow' );
  31762. END;
  31763. {$ENDIF INPACKAGE}
  31764. end;
  31765. {$ENDIF}
  31766. {$ENDIF WIN_GDI}
  31767. {$IFDEF _X_}
  31768. {$IFDEF GTK}
  31769. procedure TControl.VisualizyWindow;
  31770. var i: Integer;
  31771. C: PControl;
  31772. begin
  31773. if fHandle = nil then Exit;
  31774. if not fIsApplet and FVisible then
  31775. begin
  31776. for i := 0 to ChildCount-1 do
  31777. begin
  31778. C := Children[ i ];
  31779. if C.fVisible then
  31780. C.VisualizyWindow;
  31781. end;
  31782. gtk_widget_show( fHandle );
  31783. end;
  31784. end;
  31785. {$ENDIF GTK}
  31786. {$ENDIF _X_}
  31787. {$IFDEF WIN_GDI}
  31788. //-
  31789. //[procedure TControl.CreateSubclass]
  31790. procedure TControl.CreateSubclass(var Params: TCreateParams;
  31791. ControlClassName: PKOLChar);
  31792. const
  31793. CS_OFF = {$ifdef win32}CS_OWNDC or CS_CLASSDC or {$endif} CS_PARENTDC or CS_GLOBALCLASS;
  31794. CS_ON = 0; //CS_VREDRAW or CS_HREDRAW;
  31795. var
  31796. SaveInstance: THandle;
  31797. begin
  31798. if fControlClassName <> nil then
  31799. with Params do
  31800. begin
  31801. SaveInstance := WindowClass.hInstance;
  31802. // {$IFNDEF UNICODE_CTRLS}
  31803. if not GetClassInfo(HInstance, fControlClassName, WindowClass) and
  31804. not GetClassInfo(0, fControlClassName, WindowClass)
  31805. then
  31806. GetClassInfo(WindowClass.hInstance, fControlClassName, WindowClass);
  31807. // {$ELSE}
  31808. // if not GetClassInfoW(HInstance, pWideChar(fControlClassName), WindowClass) and
  31809. // not GetClassInfoW(0, pWidechar(fControlClassName), WindowClass)
  31810. // then
  31811. // GetClassInfoW(WindowClass.hInstance, pWideChar(fControlClassName), WindowClass);
  31812. // {$ENDIF}
  31813. WindowClass.hInstance := SaveInstance;
  31814. WindowClass.style := WindowClass.style and not CS_OFF or CS_ON;
  31815. end;
  31816. end;
  31817. //[FUNCTION WndProcMouse]
  31818. {$IFDEF ASM_VERSION}
  31819. {$ELSE ASM_VERSION} //Pascal
  31820. function WndProcMouse(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  31821. var MouseData: TMouseEventData;
  31822. begin
  31823. Result := False;
  31824. if (Msg.message >= WM_MOUSEFIRST) and (Msg.message <= $20A {WM_MOUSELAST}) then
  31825. with MouseData do
  31826. begin
  31827. Shift := Msg.wParam;
  31828. if GetKeyState( VK_MENU ) < 0 then
  31829. Shift := Shift or MK_ALT;
  31830. X := LoWord( Msg.lParam );
  31831. Y := HiWord( Msg.lParam );
  31832. //Button := TMouseButton(Msg.wParam);
  31833. // not possible: wParam can contain a combination of flags
  31834. // MK_CONTROL, MK_LBUTTON, MK_RBUTTON, MK_MBUTTON, MK_SHIFT, MK_XBUTTON1, MK_XBUTTON2
  31835. // So, Shift must be tested.
  31836. Button := mbNone;
  31837. StopHandling := FALSE;
  31838. Rslt := 0; // needed ?
  31839. case Msg.message of
  31840. WM_LBUTTONDOWN:
  31841. if Assigned( Self_.OnMouseDown ) then
  31842. begin
  31843. Button := mbLeft;
  31844. Self_.OnMouseDown( Self_, MouseData );
  31845. end;
  31846. WM_RBUTTONDOWN:
  31847. if Assigned( Self_.OnMouseDown ) then
  31848. begin
  31849. Button := mbRight;
  31850. Self_.OnMouseDown( Self_, MouseData );
  31851. end;
  31852. WM_MBUTTONDOWN:
  31853. if Assigned( Self_.OnMouseDown ) then
  31854. begin
  31855. Button := mbMiddle;
  31856. Self_.OnMouseDown( Self_, MouseData );
  31857. end;
  31858. WM_LBUTTONUP:
  31859. if Assigned( Self_.OnMouseUp ) then
  31860. begin
  31861. Button := mbLeft;
  31862. Self_.OnMouseUp( Self_, MouseData );
  31863. end;
  31864. WM_RBUTTONUP:
  31865. if Assigned( Self_.OnMouseUp ) then
  31866. begin
  31867. Button := mbRight;
  31868. Self_.OnMouseUp( Self_, MouseData );
  31869. end;
  31870. WM_MBUTTONUP:
  31871. if Assigned( Self_.OnMouseUp ) then
  31872. begin
  31873. Button := mbMiddle;
  31874. Self_.OnMouseUp( Self_, MouseData );
  31875. end;
  31876. WM_MOUSEMOVE:
  31877. if Assigned( Self_.OnMouseMove ) then
  31878. Self_.OnMouseMove( Self_, MouseData );
  31879. WM_LBUTTONDBLCLK:
  31880. if Assigned( Self_.OnMouseDblClk ) then
  31881. begin
  31882. Button := mbLeft;
  31883. Self_.OnMouseDblClk( Self_, MouseData );
  31884. end;
  31885. WM_RBUTTONDBLCLK:
  31886. if Assigned( Self_.OnMouseDblClk ) then
  31887. begin
  31888. Button := mbRight;
  31889. Self_.OnMouseDblClk( Self_, MouseData );
  31890. end;
  31891. WM_MBUTTONDBLCLK:
  31892. if Assigned( Self_.OnMouseDblClk ) then
  31893. begin
  31894. Button := mbMiddle;
  31895. Self_.OnMouseDblClk( Self_, MouseData );
  31896. end;
  31897. $020A {WM_MOUSEWHEEL}:
  31898. if Assigned( Self_.OnMouseWheel ) then
  31899. Self_.OnMouseWheel( Self_, MouseData );
  31900. else
  31901. Exit; //Result := False;
  31902. end;
  31903. Result := StopHandling;
  31904. end;
  31905. end;
  31906. {$ENDIF ASM_VERSION}
  31907. //[END WndProcMous]
  31908. //[FUNCTION WndProcKeybd]
  31909. {$IFDEF ASM_UNICODE}
  31910. {$ELSE ASM_VERSION} //Pascal
  31911. function WndProcKeybd(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  31912. var C : KOLChar;
  31913. begin
  31914. Result := True;
  31915. case Msg.message of
  31916. WM_KEYDOWN, WM_SYSKEYDOWN:
  31917. if assigned( Self_.fOnKeyDown ) then
  31918. Self_.fOnKeyDown( Self_, Msg.wParam, GetShiftState );
  31919. WM_KEYUP, WM_SYSKEYUP:
  31920. if assigned( Self_.fOnKeyUp ) then
  31921. Self_.fOnKeyUp( Self_, Msg.wParam, GetShiftState );
  31922. WM_CHAR, WM_SYSCHAR:
  31923. if assigned( Self_.fOnChar ) then
  31924. begin
  31925. C := KOLChar( Msg.wParam );
  31926. Self_.fOnChar( Self_, C, GetShiftState );
  31927. Msg.wParam := Integer( C );
  31928. end;
  31929. {$IFDEF SUPPORT_ONDEADCHAR}
  31930. WM_DEADCHAR, WM_SYSDEADCHAR:
  31931. if assigned( Self_.fOnDeadChar ) then
  31932. begin
  31933. C := KOLChar( Msg.wParam );
  31934. Self_.fOnDeadChar( Self_, C, GetShiftState );
  31935. Msg.wParam := Integer( C );
  31936. end;
  31937. {$ENDIF SUPPORT_ONDEADCHAR}
  31938. else begin
  31939. Result := False;
  31940. Exit;
  31941. end;
  31942. end;
  31943. if Msg.wParam <> 0 then
  31944. Result := False;
  31945. end;
  31946. {$ENDIF ASM_VERSION}
  31947. //[END WndProcKeybd]
  31948. //[function WndProcDummy]
  31949. function WndProcDummy(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  31950. begin
  31951. Result := False;
  31952. end;
  31953. const
  31954. MM_MCINOTIFY = $3B9;
  31955. function WndProcOnClose( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  31956. : Boolean;
  31957. var Accept: Boolean;
  31958. begin
  31959. Result := FALSE;
  31960. if Msg.message = WM_CLOSE then
  31961. begin
  31962. {$IFDEF NEW_MODAL}
  31963. // version of code by Alexander Pravdin
  31964. begin
  31965. Accept := True;
  31966. if Assigned( Sender.fOnClose ) then begin
  31967. Sender.fOnClose( Sender, Accept );
  31968. if AppletRunning then
  31969. if Accept then
  31970. if Sender.fModal > 0 then begin
  31971. if Sender.ModalResult = 0 then
  31972. Sender.fModalResult := Integer($80000000);
  31973. Msg.message := 0;
  31974. Exit;
  31975. end
  31976. else
  31977. Sender.fOnClose := nil
  31978. else begin
  31979. Rslt := 0;
  31980. Sender.fModalResult := 0;
  31981. Result := TRUE;
  31982. end
  31983. else
  31984. Sender.fOnClose := nil;
  31985. end
  31986. else begin
  31987. if Sender.fModal > 0 then begin
  31988. if Sender.ModalResult = 0 then
  31989. Sender.fModalResult := Integer($80000000);
  31990. Exit;
  31991. end;
  31992. end;
  31993. if Accept then begin
  31994. if Sender.IsMainWindow or ( Applet = Sender ) then
  31995. begin
  31996. {if Assigned( Applet ) and ( Applet <> Sender ) then
  31997. Applet.Perform( WM_CLOSE, 0, 0 );}
  31998. PostQuitMessage( 0 );
  31999. Rslt := 0;
  32000. end
  32001. else
  32002. Exit; // Default;
  32003. end;
  32004. end;
  32005. {$ELSE}
  32006. begin
  32007. Accept := True;
  32008. if Assigned( Sender.fOnClose ) then
  32009. begin
  32010. Sender.fOnClose( Sender, Accept );
  32011. if (not Accept) and (AppletRunning) then
  32012. begin
  32013. Rslt := 0;
  32014. Result := TRUE;
  32015. end
  32016. else //+-+
  32017. Sender.fOnClose := nil;
  32018. end;
  32019. if Accept then
  32020. begin
  32021. if Sender.IsMainWindow or (Applet = Sender) then
  32022. begin
  32023. {if Assigned( Applet ) and (Applet <> Sender) then
  32024. Applet.Perform( WM_CLOSE, 0, 0 );}
  32025. PostQuitMessage( 0 );
  32026. Rslt := 0;
  32027. end
  32028. else
  32029. Exit; //Default;
  32030. end;
  32031. end;
  32032. {$ENDIF}
  32033. end;
  32034. end;
  32035. procedure TControl.SetOnClose(const AOnClose: TOnEventAccept);
  32036. begin
  32037. fOnClose := AOnClose;
  32038. AttachProc( WndProcOnClose );
  32039. end;
  32040. function WndProcFormOnClick( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  32041. begin
  32042. Result := FALSE;
  32043. if (Msg.message = WM_LBUTTONDOWN) or (Msg.message = WM_LBUTTONDBLCLK) or
  32044. (Msg.message = WM_RBUTTONDOWN) or (Msg.message = WM_RBUTTONDBLCLK) or
  32045. (Msg.message = WM_MBUTTONDOWN) or (Msg.message = WM_MBUTTONDBLCLK)
  32046. then
  32047. begin
  32048. Sender.fRightClick := (Msg.message = WM_RBUTTONDOWN) or
  32049. (Msg.message = WM_RBUTTONDBLCLK);
  32050. if Assigned( Sender.fOnClick ) then
  32051. Sender.fOnClick( Sender );
  32052. end;
  32053. end;
  32054. procedure TControl.SetFormOnClick(const AOnClick: TOnEvent);
  32055. begin
  32056. fOnClick := AOnClick;
  32057. AttachProc( WndProcFormOnClick );
  32058. end;
  32059. {$IFDEF ASM_VERSION}//------------------
  32060. {$DEFINE ASM_LOCAL}
  32061. {$IFDEF NEW_MODAL}
  32062. {$UNDEF ASM_LOCAL}
  32063. {$ENDIF}
  32064. {$ELSE}//-------------------------------
  32065. {$IFDEF ASM_LOCAL}
  32066. {$UNDEF ASM_LOCAL}
  32067. {$ENDIF}
  32068. {$ENDIF}//------------------------------
  32069. {$IFDEF USE_GRAPHCTLS}
  32070. {$UNDEF ASM_LOCAL}
  32071. {$ENDIF}
  32072. //[function TControl.WndProc]
  32073. {$IFDEF ASM_LOCAL}
  32074. {$ELSE ASM_LOCAL} //Pascal
  32075. {$IFDEF DEBUG_CREATEWINDOW}
  32076. var DbgCWCount: Integer = 0;
  32077. {$ENDIF DEBUG_CREATEWINDOW}
  32078. function TControl.WndProc( var Msg: TMsg ): Integer;
  32079. var C : PControl;
  32080. F: HWnd;
  32081. PassFun: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  32082. procedure Default;
  32083. begin
  32084. Result := CallDefWndProc( Msg );
  32085. end;
  32086. begin
  32087. {$IFDEF INPACKAGE}
  32088. Log( '->TControl.WndProc' );
  32089. TRY
  32090. {$ENDIF INPACKAGE}
  32091. {$IFDEF DEBUG_CREATEWINDOW}
  32092. Inc( DbgCWCount );
  32093. if DbgCWCount < 10 then
  32094. LogFileOutput( GetStartDir + 'Session.log', 'TControl.WndProc: ' +
  32095. ' Msg.hwnd=' + Int2Str( Msg.hwnd ) +
  32096. ' Msg.message=' + Int2Hex( Msg.message, 2 ) +
  32097. ' Msg.wParam=' + Int2Str( Msg.wParam ) + '=$' + Int2Hex( Msg.wParam, 4 ) +
  32098. ' Msg.lParam=' + Int2Str( Msg.lParam ) + '=$' + Int2Hex( Msg.lParam, 4 ) );
  32099. {$ENDIF DEBUG_CREATEWINDOW}
  32100. if (Msg.hwnd <> 0) and (fHandle = 0)
  32101. {$IFDEF USE_GRAPHCTLS} and fWindowed {$ENDIF} then
  32102. fHandle := Msg.hwnd;
  32103. {$IFDEF DEBUG_MCK} mck_Log( '01' ); {$ENDIF}
  32104. PassFun := fPass2DefProc;
  32105. {$IFDEF DEBUG_MCK} mck_Log( '01' ); {$ENDIF}
  32106. if not (AppletRunning and (Applet <> @Self) and Assigned( Applet ) and
  32107. Assigned( Applet.OnMessage ) and Applet.OnMessage( Msg, Result )) then
  32108. begin {$IFDEF DEBUG_MCK} mck_Log( '02' ); {$ENDIF}
  32109. if not (Assigned( OnMessage ) and OnMessage( Msg, Result )) then
  32110. begin {$IFDEF DEBUG_MCK} mck_Log( '03' ); {$ENDIF}
  32111. if not fOnDynHandlers( @Self, Msg, Result ) then
  32112. begin {$IFDEF DEBUG_MCK} mck_Log( '04' ); {$ENDIF}
  32113. if not fWndProcResizeFlicks( @Self, Msg, Result ) then
  32114. begin {$IFDEF DEBUG_MCK} mck_Log( '05' ); {$ENDIF}
  32115. case Msg.message of
  32116. WM_CLOSE:
  32117. begin // handler by default - simple:
  32118. if (Applet = @ Self) or IsMainWindow then begin
  32119. PostQuitMessage( 0 );
  32120. {$ifdef wince}
  32121. Result:=0;
  32122. exit;
  32123. {$endif wince}
  32124. end;
  32125. Default;
  32126. end;
  32127. {$IFDEF USE_PROP}
  32128. WM_NCDESTROY:
  32129. begin
  32130. RemoveProp( fHandle, ID_SELF ); //********* Added By M.Gerasimov
  32131. end;
  32132. {$ENDIF}
  32133. WM_DESTROY:
  32134. begin
  32135. fBeginDestroying := TRUE;
  32136. Default;
  32137. {$IFDEF INPACKAGE}
  32138. LogOK;
  32139. {$ENDIF INPACKAGE}
  32140. Exit;
  32141. end;
  32142. {$ifdef wince}
  32143. WM_WINDOWPOSCHANGED:
  32144. begin
  32145. Default;
  32146. { In case of subclassing, DefWindowProc must be called on wince
  32147. to generate WM_SIZE and WM_MOVE messages }
  32148. if fDefWndProc <> nil then
  32149. Result:=DefWindowProc(Msg.hwnd, Msg.message, Msg.wParam, Msg.lParam);
  32150. exit;
  32151. end;
  32152. {$endif wince}
  32153. WM_SIZE: begin
  32154. {$IFDEF INPACKAGE}
  32155. Log( 'WM_SIZE >>> Default' );
  32156. {$ENDIF INPACKAGE}
  32157. Default;
  32158. {$IFDEF INPACKAGE}
  32159. Log( '//// Default called' );
  32160. {$ENDIF INPACKAGE}
  32161. fWindowState := TWindowState( Msg.wParam );
  32162. {$IFDEF OLD_ALIGN}
  32163. if not fIsForm then
  32164. Global_Align( fParent );
  32165. {$ENDIF}
  32166. {$IFDEF INPACKAGE}
  32167. Log( '//// Before Global_Align' );
  32168. {$ENDIF INPACKAGE}
  32169. Global_Align( @Self );
  32170. {$IFDEF INPACKAGE}
  32171. LogOK;
  32172. {$ENDIF INPACKAGE}
  32173. Exit;
  32174. end;
  32175. {$ifndef wince}
  32176. WM_SysCommand:
  32177. begin
  32178. if ((Msg.wParam and $FFF0) = SC_MINIMIZE) and
  32179. IsMainWindow and (@Self <> Applet) then
  32180. begin
  32181. PostMessage( Applet.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
  32182. Result := 0;
  32183. end
  32184. else Default;
  32185. end;
  32186. {$endif wince}
  32187. WM_SETFOCUS:
  32188. begin
  32189. if not DoSetFocus then
  32190. begin
  32191. Result := 0;
  32192. end
  32193. else
  32194. begin
  32195. Inc( fClickDisabled );
  32196. Default;
  32197. Dec( fClickDisabled );
  32198. {$IFDEF INPACKAGE}
  32199. LogOK;
  32200. {$ENDIF INPACKAGE}
  32201. Exit;
  32202. end;
  32203. end;
  32204. WM_CTLCOLORMSGBOX..WM_CTLCOLORSTATIC:
  32205. begin
  32206. Result := SendMessage(Msg.LParam, CN_BASE + Msg.message, Msg.WParam, Msg.LParam);
  32207. end;
  32208. WM_COMMAND:
  32209. begin
  32210. {$IFDEF USE_PROP}
  32211. C := Pointer( GetProp( Msg.lParam, ID_SELF ) );
  32212. {$ELSE}
  32213. C := Pointer( GetWindowLong( Msg.lParam, GWL_USERDATA ) );
  32214. {$ENDIF}
  32215. if C <> nil then
  32216. begin
  32217. Result := SendMessage( Msg.lParam, CM_COMMAND, Msg.wParam, Msg.lParam );
  32218. end
  32219. else Default;
  32220. end;
  32221. WM_KEYFIRST..WM_KEYLAST:
  32222. begin
  32223. F := GetFocus;
  32224. if (F <> fFocusHandle) and (F <> fHandle)
  32225. {$IFDEF USE_GRAPHCTLS} and fWindowed {$ENDIF}
  32226. {$IFDEF KEY_PREVIEW}
  32227. and not (fKeyPreviewing (*and
  32228. ((Msg.Message=WM_KEYDOWN) {or (Msg.message = WM_CHAR) )*))
  32229. {$ENDIF}
  32230. then
  32231. begin
  32232. Result := 0;
  32233. // Jump to PassFun here. Prevents beep in case when WM_KEYDOWN
  32234. // called another form and focus is changed, so WM_KEYUP failed
  32235. // to handle.
  32236. end
  32237. else
  32238. begin
  32239. {$IFDEF KEY_PREVIEW}
  32240. fkeypreviewing:=false; //ADDITION JUST FOR CORRECT KEYPREVIEWING
  32241. {$ENDIF}
  32242. if fGlobalProcKeybd( @Self, Msg, Result ) then
  32243. begin
  32244. {$IFDEF INPACKAGE}
  32245. LogOK;
  32246. {$ENDIF INPACKAGE}
  32247. Exit; //??????????????????
  32248. end;
  32249. if fWndProcKeybd( @Self, Msg, Result ) then
  32250. begin
  32251. {$IFDEF INPACKAGE}
  32252. LogOK;
  32253. {$ENDIF INPACKAGE}
  32254. Exit; //???????????????????
  32255. end;
  32256. if ((GetKeystate( VK_CONTROL ) or GetKeyState( VK_MENU )) >= 0) then
  32257. begin
  32258. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  32259. if (Msg.message <> WM_CHAR) // v1.02 Tabulate AND " in EditBox fix
  32260. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  32261. then
  32262. begin
  32263. C := ParentForm;
  32264. if (C <> nil) and Assigned(C.fGotoControl) and
  32265. C.fGotoControl( @Self, Msg.wParam,
  32266. (Msg.message <> WM_KEYDOWN) and
  32267. (Msg.message <> WM_SYSKEYDOWN) ) then
  32268. begin
  32269. Msg.wParam := 0;
  32270. Result := 0;
  32271. end
  32272. else Default;
  32273. end
  32274. //+++++++++++++++++++++++++++++++++++++++++++++//
  32275. else //
  32276. if Msg.wParam = 9 then // prevent system beep //
  32277. begin //
  32278. Msg.wParam := 0; //
  32279. Result := 0; //
  32280. end //
  32281. //+++++++++++++++++++++++++++++++++++++++++++++//
  32282. else Default;
  32283. end
  32284. else Default;
  32285. end;
  32286. end;
  32287. else begin
  32288. {$IFDEF DEBUG_MCK} mck_Log( 'else' ); {$ENDIF}
  32289. Default; //+-+
  32290. {$IFDEF INPACKAGE}
  32291. LogOK;
  32292. {$ENDIF INPACKAGE}
  32293. Exit; //+-+
  32294. end;
  32295. end;
  32296. end;
  32297. end;
  32298. end;
  32299. end;
  32300. {$IFDEF DEBUG_MCK} mck_Log( '06' ); {$ENDIF}
  32301. if not AppletTerminated and not fNCDestroyed then
  32302. begin {$IFDEF DEBUG_MCK} mck_Log( '07' ); {$ENDIF}
  32303. PassFun( @Self, Msg, Result ); //+-+
  32304. {$IFDEF DEBUG_MCK} mck_Log( '08' ); {$ENDIF}
  32305. end;
  32306. {$IFDEF INPACKAGE}
  32307. LogOK;
  32308. FINALLY
  32309. Log( '<-TControl.WndProc' );
  32310. END;
  32311. {$ENDIF INPACKAGE}
  32312. end;
  32313. {$ENDIF ASM_LOCAL}
  32314. //[END TContro]
  32315. {$UNDEF ASM_LOCAL}
  32316. {$ENDIF WIN_GDI}
  32317. //[procedure SetMouseEvent]
  32318. {$IFDEF GDI}
  32319. procedure SetMouseEvent( Self_: PControl );
  32320. begin
  32321. Self_.AttachProc( WndProcMouse );
  32322. end;
  32323. {$ENDIF GDI}
  32324. {$IFDEF _X_}
  32325. {$IFDEF GTK}
  32326. function mouse_events_handler( Obj: PGtkWidget; var Event: TGdkEventAny ): Boolean; cdecl;
  32327. var Sender: PControl;
  32328. M: TMouseEventData;
  32329. procedure PrepareMouseEvent( const Evt: TGdkEventMotion );
  32330. begin
  32331. M.Button := mbNone;
  32332. if Evt.state and GDK_BUTTON1_MASK <> 0 then M.Button := mbLeft
  32333. else
  32334. if Evt.state and GDK_BUTTON2_MASK <> 0 then M.Button := mbRight
  32335. else
  32336. if Evt.state and GDK_BUTTON3_MASK <> 0 then M.Button := mbMiddle;
  32337. M.Shift := 0;
  32338. if Evt.state and GDK_SHIFT_MASK <> 0 then M.Shift := MK_SHIFT;
  32339. if Evt.state and GDK_CONTROL_MASK <> 0 then M.Shift := M.Shift or MK_CONTROL;
  32340. if Evt.state and GDK_LOCK_MASK <> 0 then M.Shift := M.Shift or MK_LOCK;
  32341. if Evt.state and GDK_BUTTON1_MASK <> 0 then M.Shift := M.Shift or MK_LBUTTON;
  32342. if Evt.state and GDK_BUTTON2_MASK <> 0 then M.Shift := M.Shift or MK_RBUTTON;
  32343. if Evt.state and GDK_BUTTON3_MASK <> 0 then M.Shift := M.Shift or MK_MBUTTON;
  32344. if Evt.state and GDK_LOCK_MASK <> 0 then M.Shift := M.Shift or MK_LOCK;
  32345. M.X := Round( Evt.x );
  32346. M.Y := Round( Evt.y );
  32347. end;
  32348. var scrl: PGdkEventScroll;
  32349. z: SmallInt;
  32350. begin
  32351. Result := FALSE;
  32352. //Sender := Pointer( Event.window );
  32353. Sender := g_object_get_data( G_OBJECT( Obj ), ID_SELF );
  32354. CASE Event._type OF
  32355. GDK_MOTION_NOTIFY,
  32356. GDK_BUTTON_PRESS,
  32357. GDK_2BUTTON_PRESS,
  32358. GDK_3BUTTON_PRESS, // òðîéíîé êëèê ìûøè - ñ÷èòàòü êàê äâîéíîé?
  32359. GDK_BUTTON_RELEASE,
  32360. GDK_SCROLL: ;
  32361. else Exit;
  32362. END;
  32363. PrepareMouseEvent( PGdkEventMotion( @ Event )^ );
  32364. CASE Event._type OF
  32365. GDK_MOTION_NOTIFY :
  32366. begin
  32367. if Assigned( Sender.fOnMouseMove ) then
  32368. begin
  32369. Sender.fOnMouseMove( Sender, M );
  32370. Result := TRUE;
  32371. end;
  32372. end;
  32373. GDK_BUTTON_PRESS :
  32374. begin
  32375. if Assigned( Sender.fOnMouseDown ) then
  32376. begin
  32377. Sender.fOnMouseDown( Sender, M );
  32378. Result := TRUE;
  32379. end;
  32380. end;
  32381. GDK_2BUTTON_PRESS,
  32382. GDK_3BUTTON_PRESS :
  32383. begin
  32384. if Assigned( Sender.fOnMouseDblClk ) then
  32385. begin
  32386. Sender.f3ButtonPress := Event._type = GDK_3BUTTON_PRESS;
  32387. Sender.fOnMouseDblClk( Sender, M );
  32388. Result := TRUE;
  32389. end;
  32390. end;
  32391. GDK_BUTTON_RELEASE :
  32392. begin
  32393. if Assigned( Sender.fOnMouseUp ) then
  32394. begin
  32395. Sender.fOnMouseUp( Sender, M );
  32396. Result := TRUE;
  32397. end;
  32398. if Assigned( Sender.fOnClick ) then
  32399. Sender.fOnClick( Sender );
  32400. end;
  32401. GDK_SCROLL :
  32402. begin
  32403. if Assigned( Sender.fOnMouseWheel ) then
  32404. begin
  32405. scrl := @ Event;
  32406. if scrl.direction = GDK_SCROLL_UP then
  32407. z := 120
  32408. else if scrl.direction = GDK_SCROLL_DOWN then
  32409. z := -120 //todo: direction and value?
  32410. else
  32411. z := 0;
  32412. M.Shift := M.Shift or DWord(z shl 16);
  32413. Sender.fOnMouseWheel( Sender, M );
  32414. Result := TRUE;
  32415. end;
  32416. end;
  32417. END;
  32418. end;
  32419. procedure SetMouseEvent( Self_: PControl; event_name: PChar );
  32420. begin
  32421. gtk_signal_connect( GTK_OBJECT( Self_.fEventboxHandle ), event_name,
  32422. @mouse_events_handler, Self_ );
  32423. end;
  32424. {$ENDIF GTK}
  32425. {$ENDIF _X_}
  32426. //[procedure TControl.SetOnMouseDown]
  32427. {$IFDEF GDI}
  32428. procedure TControl.SetOnMouseDown(const Value: TOnMouse);
  32429. begin
  32430. fOnMouseDown := Value;
  32431. SetMouseEvent( @Self );
  32432. end;
  32433. {$ENDIF GDI}
  32434. {$IFDEF _X_}
  32435. {$IFDEF GTK}
  32436. procedure TControl.SetOnMouseDown(const Value: TOnMouse);
  32437. begin
  32438. fOnMouseDown := Value;
  32439. SetMouseEvent( @Self, 'button_press_event' );
  32440. end;
  32441. {$ENDIF GTK}
  32442. {$ENDIF _X_}
  32443. {$IFDEF GDI}
  32444. //[procedure TControl.SetOnMouseMove]
  32445. procedure TControl.SetOnMouseMove(const Value: TOnMouse);
  32446. begin
  32447. fOnMouseMove := Value;
  32448. SetMouseEvent( @Self );
  32449. end;
  32450. {$ENDIF GDI}
  32451. {$IFDEF _X_}
  32452. {$IFDEF GTK}
  32453. procedure TControl.SetOnMouseMove(const Value: TOnMouse);
  32454. begin
  32455. fOnMouseMove := Value;
  32456. SetMouseEvent( @Self, 'motion_notify_event' );
  32457. end;
  32458. {$ENDIF GTK}
  32459. {$ENDIF _X_}
  32460. //[procedure TControl.SetOnMouseUp]
  32461. {$IFDEF GDI}
  32462. procedure TControl.SetOnMouseUp(const Value: TOnMouse);
  32463. begin
  32464. fOnMouseUp := Value;
  32465. SetMouseEvent( @Self );
  32466. end;
  32467. {$ENDIF GDI}
  32468. {$IFDEF _X_}
  32469. {$IFDEF GTK}
  32470. procedure TControl.SetOnMouseUp(const Value: TOnMouse);
  32471. begin
  32472. fOnMouseUp := Value;
  32473. SetMouseEvent( @Self, 'button_release_event' );
  32474. end;
  32475. {$ENDIF GTK}
  32476. {$ENDIF _X_}
  32477. //[procedure TControl.SetOnMouseDblClk]
  32478. {$IFDEF GDI}
  32479. procedure TControl.SetOnMouseDblClk(const Value: TOnMouse);
  32480. begin
  32481. fOnMouseDblClk := Value;
  32482. SetMouseEvent( @Self );
  32483. end;
  32484. {$ENDIF GDI}
  32485. {$IFDEF _X_}
  32486. {$IFDEF GTK}
  32487. procedure TControl.SetOnMouseDblClk(const Value: TOnMouse);
  32488. begin
  32489. fOnMouseDblClk := Value;
  32490. SetMouseEvent( @Self, 'button_press_event' );
  32491. end;
  32492. {$ENDIF GTK}
  32493. {$ENDIF _X_}
  32494. //[procedure TControl.SetOnMouseWheel]
  32495. {$IFDEF GDI}
  32496. procedure TControl.SetOnMouseWheel(const Value: TOnMouse);
  32497. begin
  32498. fOnMouseWheel := Value;
  32499. SetMouseEvent( @Self );
  32500. end;
  32501. {$ENDIF GDI}
  32502. {$IFDEF _X_}
  32503. {$IFDEF GTK}
  32504. procedure TControl.SetOnMouseWheel(const Value: TOnMouse);
  32505. begin
  32506. fOnMouseWheel := Value;
  32507. SetMouseEvent( @Self, 'scroll_event' );
  32508. end;
  32509. {$ENDIF GTK}
  32510. {$ENDIF _X_}
  32511. {$IFDEF WIN_GDI}
  32512. //[procedure TControl.SetClsStyle]
  32513. {$IFDEF ASM_VERSION}
  32514. {$ELSE ASM_VERSION} //Pascal
  32515. procedure TControl.SetClsStyle( Value: DWord );
  32516. begin
  32517. if fClsStyle = Value then Exit;
  32518. fClsStyle := Value;
  32519. if fHandle = 0 then Exit;
  32520. SetClassLong( fHandle, GCL_STYLE, Value );
  32521. end;
  32522. {$ENDIF ASM_VERSION}
  32523. //[procedure TControl.SetStyle]
  32524. {$IFDEF ASM_VERSION}
  32525. {$ELSE ASM_VERSION} //Pascal
  32526. procedure TControl.SetStyle( Value: DWord );
  32527. begin
  32528. if fStyle = Value then Exit;
  32529. fStyle := Value;
  32530. if fHandle = 0 then Exit;
  32531. SetWindowLong( fHandle, GWL_STYLE, Value );
  32532. SetWindowPos( fHandle, 0, 0, 0, 0, 0,
  32533. SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or
  32534. SWP_NOZORDER or SWP_FRAMECHANGED );
  32535. Invalidate;
  32536. end;
  32537. {$ENDIF ASM_VERSION}
  32538. {$IFDEF GRAPHCTL_XPSTYLES}
  32539. procedure TControl.SetEdgeStyle( Value: TEdgeStyle );
  32540. begin
  32541. if fedgeStyle = Value then Exit;
  32542. fedgeStyle := Value;
  32543. if fHandle = 0 then Exit;
  32544. case Value of
  32545. esRaised:
  32546. begin
  32547. Style := Style and (not SS_SUNKEN);
  32548. ExStyle := ExStyle and (not WS_EX_STATICEDGE);
  32549. ExStyle := ExStyle or WS_EX_WINDOWEDGE;
  32550. Style := Style or WS_DLGFRAME;
  32551. end;
  32552. esLowered:
  32553. begin
  32554. Style := Style and (not WS_DLGFRAME);
  32555. ExStyle := ExStyle or WS_EX_WINDOWEDGE;
  32556. ExStyle := ExStyle or WS_EX_STATICEDGE;
  32557. Style := Style or SS_SUNKEN;
  32558. end;
  32559. else
  32560. Style := Style and (not SS_SUNKEN) and (not WS_DLGFRAME);
  32561. ExStyle := ExStyle and (not WS_EX_STATICEDGE) or WS_EX_WINDOWEDGE;
  32562. end;
  32563. Invalidate;
  32564. end;
  32565. {$ENDIF}
  32566. //[procedure TControl.SetExStyle]
  32567. {$IFDEF ASM_VERSION}
  32568. {$ELSE ASM_VERSION} //Pascal
  32569. procedure TControl.SetExStyle( Value: DWord );
  32570. begin
  32571. if fExStyle = Value then Exit;
  32572. fExStyle := Value;
  32573. if fHandle = 0 then Exit;
  32574. SetWindowLong( fHandle, GWL_EXSTYLE, Value );
  32575. SetWindowPos( fHandle, 0, 0, 0, 0, 0,
  32576. SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or
  32577. SWP_NOZORDER or SWP_FRAMECHANGED );
  32578. Invalidate;
  32579. end;
  32580. {$ENDIF ASM_VERSION}
  32581. function WndProcSetCursor( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  32582. var Cur: HCursor;
  32583. begin
  32584. Result := FALSE;
  32585. if Msg.message = WM_SETCURSOR then
  32586. begin
  32587. if (GetCapture = 0) and
  32588. (LOWORD( Msg.lParam ) = HTCLIENT) then
  32589. begin
  32590. if ScreenCursor <> 0 then //YS
  32591. Cur := ScreenCursor //YS
  32592. else //YS
  32593. Cur := Self_.fCursor; //YS
  32594. if Cur <> 0 then //YS
  32595. begin //YS
  32596. Windows.SetCursor( Cur ); //YS
  32597. Rslt := 1; //YS
  32598. Result := TRUE;
  32599. end;
  32600. end;
  32601. end;
  32602. end;
  32603. //[procedure TControl.SetCursor]
  32604. {$IFDEF ASM_VERSION}
  32605. {$ELSE ASM_VERSION} //Pascal
  32606. procedure TControl.SetCursor( Value: HCursor );
  32607. var P: TPoint;
  32608. begin
  32609. AttachProc( WndProcSetCursor );
  32610. if fCursor = Value then Exit;
  32611. fCursor := Value;
  32612. if (fHandle = 0) or (fCursor = 0) then Exit; //YS
  32613. if ScreenCursor <> 0 then Exit;
  32614. GetCursorPos( P );
  32615. P := Screen2Client( P );
  32616. if PointInRect( P, ClientRect ) then
  32617. Windows.SetCursor( Value );
  32618. end;
  32619. {$ENDIF ASM_VERSION}
  32620. //[procedure TControl.CursorLoad]
  32621. procedure TControl.CursorLoad(Inst: Integer; ResName: PKOLChar);
  32622. begin
  32623. Cursor := LoadCursor( Inst, ResName );
  32624. fCursorShared := TRUE;
  32625. end;
  32626. //[procedure TControl.SetIcon]
  32627. {$IFDEF ASM_VERSION}
  32628. {$ELSE ASM_VERSION} //Pascal
  32629. procedure TControl.SetIcon( Value: HIcon );
  32630. var OldIco: HIcon;
  32631. begin
  32632. if fIcon = Value then Exit;
  32633. fIcon := Value;
  32634. if Value = THandle(-1) then
  32635. Value := 0;
  32636. OldIco := Perform( WM_SETICON, 1 {ICON_BIG}, Value );
  32637. if OldIco <> 0 then
  32638. DestroyIcon( OldIco );
  32639. end;
  32640. {$ENDIF ASM_VERSION}
  32641. //[procedure TControl.SetMenu]
  32642. {$IFDEF ASM_VERSION}
  32643. {$ELSE ASM_VERSION} //Pascal
  32644. procedure TControl.SetMenu( Value: HMenu );
  32645. begin
  32646. if fMenu = Value then Exit;
  32647. if fMenuObj <> nil then
  32648. begin
  32649. {$IFDEF USE_AUTOFREE4CONTROLS}
  32650. RemoveFromAutoFree( fMenuObj );
  32651. {$ENDIF}
  32652. Free_And_Nil(fMenuObj);
  32653. end;
  32654. if fMenu <> 0 then
  32655. DestroyMenu( fMenu );
  32656. fMenu := Value;
  32657. if fHandle = 0 then Exit;
  32658. {$ifdef wince}
  32659. if Value = 0 then
  32660. CeSetMenu(fHandle, nil);
  32661. {$else}
  32662. Windows.SetMenu( fHandle, Value );
  32663. {$endif wince}
  32664. end;
  32665. {$ENDIF ASM_VERSION}
  32666. //[procedure CallWinHelp]
  32667. procedure CallWinHelp( Context: Integer; CtxCtl: PControl );
  32668. {$ifdef wince}
  32669. begin
  32670. {$else}
  32671. var Cmd: Integer;
  32672. Form: PControl;
  32673. Popup: Boolean;
  32674. begin
  32675. Cmd := HELP_CONTEXT;
  32676. if CtxCtl <> nil then
  32677. begin
  32678. Form := CtxCtl.ParentForm;
  32679. if Form <> nil then
  32680. if Assigned( Form.OnHelp ) then
  32681. begin
  32682. Popup := FALSE;
  32683. Form.OnHelp( CtxCtl, Context, Popup );
  32684. if Popup then
  32685. Cmd := HELP_CONTEXTPOPUP;
  32686. if CtxCtl = nil then Exit;
  32687. end;
  32688. end
  32689. else
  32690. if Context = 0 then
  32691. Cmd := HELP_CONTENTS;
  32692. WinHelp( Applet.Handle, PKOLChar( Applet.GetHelpPath ), Cmd, Context );
  32693. {$endif wince}
  32694. end;
  32695. var HHCtrl: THandle;
  32696. HtmlHelp: procedure( Wnd: HWnd; Path: PChar; Cmd, Data: Integer ); {$ifdef wince}cdecl{$else}stdcall{$endif};
  32697. //[procedure HtmlHelpCommand]
  32698. procedure HtmlHelpCommand( Wnd: HWnd; const HelpFilePath: String; Cmd, Data: Integer );
  32699. begin
  32700. if HHCtrl = 0 then
  32701. HHCtrl := LoadLibrary( 'HHCTRL.OCX' );
  32702. if HHCtrl = 0 then Exit;
  32703. if not Assigned( HtmlHelp ) then
  32704. HtmlHelp := GetProcAddress( HHCtrl, 'HtmlHelpA' );
  32705. if not Assigned( HtmlHelp ) then Exit;
  32706. HtmlHelp( Wnd, PChar( HelpFilePath ), Cmd, Data );
  32707. end;
  32708. //[procedure CallHtmlHelp]
  32709. procedure CallHtmlHelp( Context: Integer; CtxCtl: PControl );
  32710. var Cmd: Integer;
  32711. Form: PControl;
  32712. Popup: Boolean;
  32713. Ids: array[ 0..2 ] of DWORD;
  32714. begin
  32715. Cmd := $F; // HH_HELP_CONTEXT;
  32716. if CtxCtl <> nil then
  32717. begin
  32718. Form := CtxCtl.ParentForm;
  32719. if Form <> nil then
  32720. if Assigned( Form.OnHelp ) then
  32721. begin
  32722. Popup := FALSE;
  32723. Form.OnHelp( CtxCtl, Context, Popup );
  32724. if Popup then
  32725. begin
  32726. Cmd := $10; //HH_TP_HELPCONTEXTMENU;
  32727. Ids[ 0 ] := CtxCtl.fMenu;
  32728. Ids[ 1 ] := Context;
  32729. Ids[ 2 ] := 0;
  32730. Context := Integer( @ Ids );
  32731. end;
  32732. if CtxCtl = nil then Exit;
  32733. end;
  32734. end
  32735. else
  32736. if Context = 0 then
  32737. Cmd := 1; // HH_DISPLAY_TOC;
  32738. //ShowMessage( Int2Str( Cmd ) + ' ' + Int2Str( Context ) );
  32739. HtmlHelpCommand( {$IFDEF HTMLHELP_NOTOP} 0 {$ELSE} Applet.Handle {$ENDIF},
  32740. HelpFilePath, Cmd, Context );
  32741. end;
  32742. var
  32743. Global_HelpProc: procedure( Context: Integer; CtxCtl: PControl ) = CallWinHelp;
  32744. //[function WndProcHelp]
  32745. function WndProcHelp( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  32746. var HI: PHelpInfo;
  32747. Ctx: Integer;
  32748. Ctl: PControl;
  32749. begin
  32750. Result := FALSE;
  32751. if Msg.message = WM_HELP then
  32752. begin
  32753. Ctx := 0;
  32754. Ctl := nil;
  32755. HI := Pointer( Msg.lParam );
  32756. if HI.iContextType = HELPINFO_WINDOW then
  32757. begin
  32758. {$IFDEF USE_PROP}
  32759. Ctl := Pointer( GetProp( HI.hItemHandle, ID_SELF ) );
  32760. {$ELSE}
  32761. Ctl := Pointer( GetWindowLong( HI.hItemHandle, GWL_USERDATA ) );
  32762. {$ENDIF}
  32763. while Ctl <> nil do
  32764. begin
  32765. Ctx := Ctl.fHelpContext;
  32766. if Ctx <> 0 then break;
  32767. Ctl := Ctl.Parent;
  32768. end;
  32769. end
  32770. else
  32771. {$ifdef win32}Ctx := GetMenuContextHelpID( HI.hItemHandle ){$endif};
  32772. Applet.CallHelp( Ctx, Ctl );
  32773. Rslt := 1;
  32774. Result := TRUE;
  32775. end
  32776. {$IFDEF AUTO_CONTEXT_HELP}
  32777. else
  32778. if (Msg.message = WM_CONTEXTMENU) then
  32779. begin
  32780. {$IFDEF USE_PROP}
  32781. Ctl := Pointer( GetProp( Msg.wParam, ID_SELF ) );
  32782. {$ELSE}
  32783. Ctl := Pointer( GetWindowLong( Msg.wParam, GWL_USERDATA ) );
  32784. {$ENDIF}
  32785. if (Ctl <> nil) and (Ctl.fHelpContext <> 0) then
  32786. begin
  32787. Applet.CallHelp( Ctl.fHelpContext, Ctl );
  32788. Rslt := 1;
  32789. Result := TRUE;
  32790. end;
  32791. end
  32792. {$ENDIF};
  32793. end;
  32794. //[procedure TControl.SetHelpContext]
  32795. procedure TControl.SetHelpContext(Value: Integer);
  32796. var F: PControl;
  32797. begin
  32798. fHelpContext := Value;
  32799. F := ParentForm;
  32800. if F = nil then Exit;
  32801. F.AttachProc( WndProcHelp );
  32802. {$ifdef win32}
  32803. SetWindowContextHelpId( GetWindowHandle, Value );
  32804. {$endif win32}
  32805. end;
  32806. //[function TControl.AssignHelpContext]
  32807. function TControl.AssignHelpContext(Context: Integer): PControl;
  32808. begin
  32809. SetHelpContext( Context );
  32810. Result := @ Self;
  32811. end;
  32812. //[procedure AssignHtmlHelp]
  32813. procedure AssignHtmlHelp( const HtmlHelpPath: KOLString );
  32814. begin
  32815. Assert( (HtmlHelpPath <> '') and (Applet <> nil), 'Error parameters' );
  32816. if HelpFilePath <> '' then
  32817. FreeMem( HelpFilePath );
  32818. GetMem( HelpFilePath, (Length( HtmlHelpPath ) + 1) * Sizeof( KOLChar ) );
  32819. StrCopy( HelpFilePath, @ HtmlHelpPath[ 1 ] );
  32820. Global_HelpProc := CallHtmlHelp;
  32821. Applet.AttachProc( WndProcHelp );
  32822. end;
  32823. //[procedure TControl.CallHelp]
  32824. procedure TControl.CallHelp(Context: Integer; CtxCtl: PControl {; CtlID: Integer} );
  32825. begin
  32826. Global_HelpProc( Context, CtxCtl {, CtlID} );
  32827. end;
  32828. //[function TControl.GetHelpPath]
  32829. function TControl.GetHelpPath: KOLString;
  32830. begin
  32831. Result := HelpFilePath;
  32832. if Result = '' then
  32833. begin
  32834. Result := ParamStr( 0 );
  32835. Result := ReplaceFileExt( Result, '.hlp' );
  32836. end;
  32837. end;
  32838. //[procedure TControl.SetHelpPath]
  32839. procedure TControl.SetHelpPath(const Value: KOLString);
  32840. begin
  32841. Assert( Value <> '', 'Error parameter' );
  32842. if HelpFilePath <> '' then
  32843. FreeMem( HelpFilePath );
  32844. GetMem( HelpFilePath, (Length( Value ) + 1)*Sizeof( KOLChar ) );
  32845. StrCopy( HelpFilePath, @ Value[ 1 ] );
  32846. end;
  32847. {$ENDIF WIN_GDI}
  32848. {$IFDEF ASM_VERSION}
  32849. {$ELSE}
  32850. procedure TControl.DoAutoSize;
  32851. begin
  32852. if Assigned( fAutoSize ) then
  32853. fAutoSize( @Self );
  32854. end;
  32855. {$ENDIF}
  32856. {$IFDEF GDI}
  32857. {$IFDEF ASM_UNICODE}
  32858. //[function TControl.GetCaption]
  32859. function TControl.GetCaption: KOLString;
  32860. asm
  32861. PUSH EBX
  32862. PUSH EDI
  32863. XCHG EBX, EAX
  32864. MOV EDI, EDX
  32865. CMP [EBX].fIgnoreWndCaption, 0
  32866. JNZ @@getFCaption
  32867. MOV ECX, [EBX].fHandle
  32868. JECXZ @@getFCaption
  32869. @@getWndCaption:
  32870. PUSH ECX
  32871. CALL GetWindowTextLength
  32872. PUSH EAX
  32873. XCHG EDX, EAX
  32874. LEA EAX, [EBX].fCaption
  32875. CALL System.@LStrSetLength
  32876. POP ECX
  32877. JECXZ @@getFCaption
  32878. INC ECX
  32879. PUSH ECX
  32880. PUSH [EBX].fCaption
  32881. PUSH [EBX].fHandle
  32882. CALL GetWindowText
  32883. @@getFCaption:
  32884. MOV EDX, [EBX].fCaption
  32885. XCHG EAX, EDI
  32886. {$IFNDEF UNICODE_CTRLS}
  32887. CALL System.@LStrAsg
  32888. {$ELSE}
  32889. CALL System.@WStrFromPChar
  32890. {$ENDIF}
  32891. @@exit:
  32892. POP EDI
  32893. POP EBX
  32894. end;
  32895. {$ELSE ASM_VERSION} //Pascal
  32896. function TControl.GetCaption: KOLString;
  32897. var Sz: Integer;
  32898. begin
  32899. if not fIgnoreWndCaption and (FHandle <> 0) then
  32900. begin
  32901. Sz := GetWindowTextLength( FHandle );
  32902. SetLength( fCaption, Sz );
  32903. if Sz > 0 then
  32904. begin
  32905. {$IFNDEF UNICODE_CTRLS}
  32906. GetWindowText( FHandle, @ fCaption[ 1 ], Sz + 1 );
  32907. {$ELSE}
  32908. GetWindowTextW( FHandle, @ fCaption[ 1 ], Sz + 1 );
  32909. {$ENDIF}
  32910. end;
  32911. end;
  32912. Result := FCaption;
  32913. end;
  32914. {$ENDIF ASM_VERSION}
  32915. {$ENDIF GDI}
  32916. {$IFDEF _X_}
  32917. {$IFDEF GTK}
  32918. function TControl.GetCaption: KOLString;
  32919. begin
  32920. if not fIgnoreWndCaption {and (FHandle <> 0)} then
  32921. FCaption := fGetCaption(@Self);
  32922. Result := FCaption;
  32923. end;
  32924. {$ENDIF GTK}
  32925. {$ENDIF _X_}
  32926. {$IFDEF GDI}
  32927. //[procedure TControl.SetCaption]
  32928. {$IFDEF ASM_VERSION}
  32929. {$ELSE ASM_VERSION} //Pascal
  32930. procedure TControl.SetCaption( const Value: KOLString );
  32931. begin
  32932. fCaption := Value;
  32933. if fHandle <> 0 then
  32934. SendMessage( fHandle, WM_SETTEXT,
  32935. 0, Integer( PKOLChar( Value ) ) );
  32936. if fIsStaticControl <> 1 then
  32937. Invalidate;
  32938. DoAutoSize;
  32939. end;
  32940. {$ENDIF ASM_VERSION}
  32941. {$ENDIF GDI}
  32942. {$IFDEF _X_}
  32943. {$IFDEF GTK}
  32944. procedure TControl.SetCaption( const Value: KOLString );
  32945. begin
  32946. fCaption := Value;
  32947. if Assigned( fSetCaption ) then fSetCaption( @Self, Value );
  32948. DoAutoSize;
  32949. end;
  32950. {$ENDIF GTK}
  32951. {$ENDIF _X_}
  32952. {$IFDEF WIN_GDI}
  32953. //[function TControl.GetVisible]
  32954. {$IFDEF ASM_VERSION}
  32955. {$ELSE ASM_VERSION}
  32956. function TControl.GetVisible: Boolean;
  32957. begin
  32958. if (fHandle <> 0) then
  32959. fVisible := IsWindowVisible( fHandle )
  32960. else
  32961. fVisible := (FStyle and WS_VISIBLE) <> 0;
  32962. Result := fVisible;
  32963. end;
  32964. {$ENDIF ASM_VERSION}
  32965. //[function TControl.Get_Visible]
  32966. {$IFDEF ASM_VERSION}
  32967. {$ELSE ASM_VERSION} // Pascal
  32968. function TControl.Get_Visible: Boolean;
  32969. begin
  32970. if (fHandle <> 0) and not fIsControl then
  32971. fVisible := IsWindowVisible( fHandle );
  32972. Result := fVisible;
  32973. end;
  32974. {$ENDIF ASM_VERSION}
  32975. //[procedure TControl.Set_Visible]
  32976. {$IFDEF ASM_VERSION}
  32977. {$ELSE ASM_VERSION} // Pascal
  32978. procedure TControl.Set_Visible( Value: Boolean );
  32979. {$IFDEF OLD_ALIGN}
  32980. var CmdShow: DWORD;
  32981. begin
  32982. //if Get_Visible <> Value then // commented to allow to set up controls visibility
  32983. begin // on invisible form (Vladimir Piven)
  32984. if Value then
  32985. begin
  32986. fStyle := fStyle or WS_VISIBLE;
  32987. CmdShow := SW_SHOW;
  32988. end
  32989. else
  32990. begin
  32991. fStyle := fStyle and not WS_VISIBLE;
  32992. CmdShow := SW_HIDE;
  32993. end;
  32994. fVisible := Value;
  32995. if fHandle = 0 then Exit;
  32996. {$ifdef wince}
  32997. Perform(WM_SHOWWINDOW, WPARAM(WordBool(Value)), 0);
  32998. {$endif wince}
  32999. ShowWindow( fHandle, CmdShow );
  33000. Global_Align( fParent );
  33001. if Value then
  33002. Global_Align( @Self );
  33003. end;
  33004. if not Value and (fHandle <> 0) then
  33005. fCreateHidden := FALSE; // { +++ }
  33006. {$ELSE NEW_ALIGN}
  33007. begin
  33008. fStyle := fStyle and not WS_VISIBLE;
  33009. if Value then
  33010. fStyle := fStyle or WS_VISIBLE;
  33011. fVisible := Value;
  33012. if fHandle = 0 then Exit;
  33013. {$ifdef wince}
  33014. Perform(WM_SHOWWINDOW, WPARAM(WordBool(Value)), 0);
  33015. {$endif wince}
  33016. if Value then begin
  33017. Global_Align( @Self );
  33018. ShowWindow( fHandle, SW_SHOW );
  33019. end else begin
  33020. fCreateHidden := FALSE; // { +++ }
  33021. ShowWindow( fHandle, SW_HIDE );
  33022. Global_Align( @Self );
  33023. end;
  33024. {$ENDIF}
  33025. end;
  33026. {$ENDIF ASM_VERSION}
  33027. //[procedure TControl.SetVisible]
  33028. procedure TControl.SetVisible( Value: Boolean );
  33029. begin
  33030. fCreateVisible := TRUE;
  33031. Set_Visible( Value );
  33032. end;
  33033. {$ENDIF WIN_GDI}
  33034. //[function TControl.GetBoundsRect]
  33035. {$IFDEF GDI}
  33036. {$IFDEF ASM_VERSION}
  33037. {$ELSE ASM_VERSION} //Pascal
  33038. function TControl.GetBoundsRect: TRect;
  33039. var W: PControl;
  33040. P: TPoint;
  33041. begin
  33042. Result := fBoundsRect;
  33043. if fHandle <> 0 then
  33044. begin
  33045. GetWindowRect( fHandle, Result );
  33046. if fIsControl or fIsMDIChild then
  33047. begin
  33048. W := fParent; // WindowedParent;
  33049. if W <> nil then
  33050. begin
  33051. P.x := 0; P.y := 0;
  33052. P := W.Client2Screen( P );
  33053. OffsetRect( Result, -P.x, -P.y );
  33054. end;
  33055. end;
  33056. {$IFDEF TEST_BOUNDSRECT}
  33057. if not CompareMem( @ fBoundsRect, @ Result, Sizeof( TRect ) ) then
  33058. {$ENDIF}
  33059. fBoundsRect := Result;
  33060. end;
  33061. end;
  33062. {$ENDIF ASM_VERSION}
  33063. {$ENDIF GDI}
  33064. {$IFDEF _X_}
  33065. {$IFDEF GTK}
  33066. function TControl.GetBoundsRect: TRect;
  33067. var R: TRect;
  33068. window: PGtkWindow;
  33069. requisition: TGtkRequisition;
  33070. begin
  33071. //if fHandle <> nil then
  33072. begin
  33073. if fIsControl then
  33074. begin
  33075. R.Left := fBoundsRect.Left;
  33076. R.Top := fBoundsRect.Top;
  33077. gtk_widget_get_size_request( fEventboxHandle, @ R.Right, @ R.Bottom );
  33078. gtk_widget_size_request( fHandle, @ requisition );
  33079. if R.Right < 0 then R.Right := requisition.width;
  33080. if R.Bottom < 0 then R.Bottom := requisition.height;
  33081. end
  33082. else
  33083. begin
  33084. window := GTK_WINDOW( fHandle );
  33085. gtk_window_get_position(window, @ R.Left, @ R.Top);
  33086. gtk_window_get_size(window, @ R.Right, @ R.Bottom);
  33087. end;
  33088. inc( R.Right, R.Left );
  33089. inc( R.Bottom, R.Top );
  33090. fBoundsRect := R;
  33091. end;
  33092. Result := fBoundsRect;
  33093. end;
  33094. {$ENDIF GTK}
  33095. {$ENDIF _X_}
  33096. {$IFDEF GDI}
  33097. //[procedure TControl.SetBoundsRect]
  33098. {$IFDEF ASM_VERSION}
  33099. {$ELSE ASM_VERSION} //Pascal
  33100. procedure TControl.SetBoundsRect( const Value: TRect );
  33101. var Rect: TRect;
  33102. Flags: DWORD;
  33103. cx, cy: integer;
  33104. begin
  33105. Rect := GetBoundsRect;
  33106. if RectsEqual( Value, Rect ) then Exit;
  33107. {$ifdef wince}
  33108. if fIsForm and (fChangedPosSz = 0) then
  33109. Style:=Style or WS_BORDER or WS_CAPTION or WS_SYSMENU;
  33110. fChangedPosSz := fChangedPosSz or $C;
  33111. {$endif wince}
  33112. if Value.Left <> fBoundsRect.Left then fChangedPosSz := fChangedPosSz or 1;
  33113. if Value.Top <> fBoundsRect.Top then fChangedPosSz := fChangedPosSz or 2;
  33114. {$IFDEF USE_GRAPHCTLS}
  33115. if not fWindowed then
  33116. Invalidate;
  33117. {$ENDIF}
  33118. fBoundsRect := Value;
  33119. if fHandle <> 0 then
  33120. with fBoundsRect do begin
  33121. Flags:=SWP_NOZORDER or SWP_NOACTIVATE;
  33122. cx:=Right - Left;
  33123. cy:=Bottom - Top;
  33124. if (Rect.Right - Rect.Left = cx) and (Rect.Bottom - Rect.Top = cy) then
  33125. Flags:=Flags or SWP_NOSIZE
  33126. else
  33127. if (Left = Rect.Left) and (Top = Rect.Top) then
  33128. Flags:=Flags or SWP_NOMOVE;
  33129. SetWindowPos( fHandle, 0, Left, Top, cx, cy, Flags );
  33130. if fSizeRedraw and (Flags and SWP_NOSIZE = 0) then
  33131. Invalidate;
  33132. end;
  33133. end;
  33134. {$ENDIF ASM_VERSION}
  33135. {$ENDIF GDI}
  33136. {$IFDEF _X_}
  33137. {$IFDEF GTK}
  33138. procedure TControl.SetBoundsRect( const Value: TRect );
  33139. var Rect: TRect;
  33140. window: PGtkWindow;
  33141. begin
  33142. Rect := GetBoundsRect;
  33143. if RectsEqual( Value, Rect ) then Exit;
  33144. if Value.Left <> fBoundsRect.Left then fChangedPosSz := fChangedPosSz or 1;
  33145. if Value.Top <> fBoundsRect.Top then fChangedPosSz := fChangedPosSz or 2;
  33146. fBoundsRect := Value;
  33147. Rect := Value;
  33148. if fIsControl then
  33149. begin
  33150. //gtk_widget_set_uposition( fHandle, Rect.Left, Rect.Top );
  33151. if fParent <> nil then
  33152. fParent.fChildSetPos( fParent, @ Self, Rect.Left, Rect.Top );
  33153. if (Rect.Right > Rect.Left) and (Rect.Bottom > Rect.Top) then
  33154. gtk_widget_set_size_request( fEventboxHandle,
  33155. Rect.Right - Rect.Left, Rect.Bottom - Rect.Top );
  33156. end
  33157. else
  33158. begin
  33159. window := GTK_WINDOW( fHandle );
  33160. gtk_window_move( window, Rect.Left, Rect.Top );
  33161. gtk_window_resize( window, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top );
  33162. end;
  33163. //if fSizeRedraw then
  33164. // Invalidate;
  33165. end;
  33166. {$ENDIF GTK}
  33167. {$ENDIF _X_}
  33168. {$IFDEF WIN_GDI}
  33169. const
  33170. WindowStateShowCommands: array[TWindowState] of Byte =
  33171. (SW_SHOWNOACTIVATE, SW_SHOWMINNOACTIVE, SW_SHOWMAXIMIZED);
  33172. //[procedure TControl.SetWindowState]
  33173. {$IFDEF ASM_VERSION}
  33174. {$ELSE ASM_VERSION} //Pascal
  33175. procedure TControl.SetWindowState( Value: TWindowState );
  33176. begin
  33177. if fWindowState <> Value then
  33178. begin
  33179. fWindowState := Value;
  33180. ShowWindow(GetWindowHandle, WindowStateShowCommands[Value]);
  33181. end;
  33182. end;
  33183. {$ENDIF ASM_VERSION}
  33184. //[procedure TControl.Show]
  33185. {$IFDEF ASM_VERSION}
  33186. {$ELSE ASM_VERSION} //Pascal
  33187. procedure TControl.Show;
  33188. begin
  33189. CreateWindow;
  33190. SetVisible( True );
  33191. SetForegroundWindow( Handle );
  33192. DoSetFocus;
  33193. end;
  33194. {$ENDIF ASM_VERSION}
  33195. //[procedure TControl.Hide]
  33196. procedure TControl.Hide;
  33197. begin
  33198. SetVisible( False );
  33199. end;
  33200. //[function TControl.Client2Screen]
  33201. {$IFDEF ASM_VERSION}
  33202. {$ELSE ASM_VERSION} //Pascal
  33203. function TControl.Client2Screen( const P: TPoint ): TPoint;
  33204. begin
  33205. Result := P;
  33206. if fHandle <> 0 then
  33207. Windows.ClientToScreen( fHandle, Result );
  33208. end;
  33209. {$ENDIF ASM_VERSION}
  33210. //[function TControl.Screen2Client]
  33211. {$IFDEF ASM_VERSION}
  33212. {$ELSE ASM_VERSION} //Pascal
  33213. function TControl.Screen2Client( const P: TPoint ): TPoint;
  33214. begin
  33215. Result := P;
  33216. if Handle <> 0 then
  33217. Windows.ScreenToClient( Handle, Result );
  33218. end;
  33219. {$ENDIF ASM_VERSION}
  33220. {$ENDIF WIN_GDI}
  33221. //[function TControl.ClientRect]
  33222. {$IFDEF GDI}
  33223. {$IFDEF ASM_VERSION}
  33224. {$ELSE ASM_VERSION} //Pascal
  33225. function TControl.ClientRect: TRect;
  33226. begin
  33227. Result := fBoundsRect;
  33228. GetWindowHandle;
  33229. if (fHandle <> 0) then
  33230. GetClientRect( fHandle, Result );
  33231. Inc( Result.Top, fClientTop );
  33232. Dec( Result.Bottom, fClientBottom );
  33233. Inc( Result.Left, fClientLeft );
  33234. Dec( Result.Right, fClientRight );
  33235. end;
  33236. {$ENDIF ASM_VERSION}
  33237. {$ENDIF GDI}
  33238. {$IFDEF _X_}
  33239. {$IFDEF GTK}
  33240. function TControl.ClientRect: TRect; //todo: implement exact, now for PaintBox only
  33241. begin
  33242. Result := fBoundsRect;
  33243. OffsetRect( Result, -Result.Left, -Result.Top );
  33244. Inc( Result.Top, fClientTop );
  33245. Dec( Result.Bottom, fClientBottom );
  33246. Inc( Result.Left, fClientLeft );
  33247. Dec( Result.Right, fClientRight );
  33248. end;
  33249. {$ENDIF GTK}
  33250. {$ENDIF _X_}
  33251. //[procedure TControl.Invalidate]
  33252. {$IFDEF GDI}
  33253. {$IFDEF ASM_VERSION}
  33254. {$ELSE PAS_VERSION}
  33255. procedure TControl.Invalidate;
  33256. begin
  33257. {$IFDEF USE_GRAPHCTLS}
  33258. fDoInvalidate;
  33259. {$ELSE}
  33260. if fHandle <> 0 then
  33261. InvalidateRect( fHandle, nil, TRUE );
  33262. {$ENDIF}
  33263. end;
  33264. {$ENDIF ASM_VERSION}
  33265. {$ENDIF GDI}
  33266. {$IFDEF _X_}
  33267. {$IFDEF GTK}
  33268. procedure TControl.Invalidate;
  33269. begin
  33270. gtk_widget_queue_draw_area( fHandle, 0, 0, Width, Height );
  33271. end;
  33272. {$ENDIF GTK}
  33273. {$ENDIF _X_}
  33274. {$IFDEF WIN_GDI}
  33275. {$IFDEF USE_GRAPHCTLS}
  33276. procedure TControl.InvalidateNonWindowed;
  33277. var R: TRect;
  33278. begin
  33279. R := BoundsRect;
  33280. if fParent.fHandle <> 0 then
  33281. InvalidateRect( fParent.fHandle, @ R, TRUE );
  33282. end;
  33283. //[procedure TControl.InvalidateWindowed]
  33284. {$IFDEF ASM_VERSION}
  33285. {$ELSE PAS_VERSION}
  33286. procedure TControl.InvalidateWindowed;
  33287. begin
  33288. if fHandle <> 0 then
  33289. InvalidateRect( fHandle, nil, TRUE );
  33290. end;
  33291. {$ENDIF ASM_VERSION}
  33292. {$ENDIF USE_GRAPHCTLS}
  33293. //[function TControl.GetIcon]
  33294. {$IFDEF ASM_VERSION}
  33295. {$ELSE ASM_VERSION} //Pascal
  33296. function TControl.GetIcon: HIcon;
  33297. begin
  33298. Result := fIcon;
  33299. if Result = THandle( -1 ) then
  33300. begin
  33301. Result := 0;
  33302. Exit;
  33303. end;
  33304. if Result = 0 then
  33305. if (Assigned( Applet )) and
  33306. (@Self <> Applet) then
  33307. begin
  33308. Result := Applet.Icon;
  33309. {$ifdef wince}
  33310. fIconShared := TRUE;
  33311. {$else}
  33312. if Result <> 0 then
  33313. Result := CopyImage( Result, IMAGE_ICON, 0, 0, 0 );
  33314. {$endif}
  33315. end
  33316. else
  33317. begin
  33318. Result := LoadIcon( hInstance,
  33319. {$IFDEF CUSTOM_APPICON}
  33320. {$I CusomAppIconRsrcName_PAS.inc} // create such file with 'your icon rsrc name'
  33321. {$ELSE} 'MAINICON' {$ENDIF} );
  33322. end;
  33323. fIcon := Result;
  33324. end;
  33325. {$ENDIF ASM_VERSION}
  33326. //*
  33327. //[procedure TControl.IconLoad]
  33328. procedure TControl.IconLoad(Inst: Integer; ResName: PKOLChar);
  33329. begin
  33330. Icon := LoadIcon( Inst, ResName );
  33331. fIconShared := TRUE;
  33332. end;
  33333. //[procedure TControl.IconLoadCursor]
  33334. procedure TControl.IconLoadCursor(Inst: Integer; ResName: PKOLChar);
  33335. begin
  33336. Icon := LoadCursor( Inst, ResName );
  33337. fIconShared := TRUE;
  33338. end;
  33339. //[function TControl.CallDefWndProc]
  33340. {$IFDEF ASM_VERSION}
  33341. {$ELSE ASM_VERSION} //Pascal
  33342. function TControl.CallDefWndProc(var Msg: TMsg): Integer;
  33343. begin
  33344. {$IFDEF INPACKAGE}
  33345. Log( '->TControl.CallDefWndProc FHandle = ' + Int2Str( FHandle ) +
  33346. ', Msg.hwd = ' + Int2Str( Msg.hwnd ) );
  33347. TRY
  33348. {$ENDIF INPACKAGE}
  33349. if FDefWndProc <> nil then
  33350. begin
  33351. {$IFDEF INPACKAGE}
  33352. Log( '//// CallWindowProc, FDefWndProc = ' + Int2Hex( DWORD( FDefWndProc ), 6 ) );
  33353. TRY
  33354. TRY
  33355. {$ENDIF INPACKAGE}
  33356. Result := CallWindowProc( FDefWndProc, FHandle, Msg.message, Msg.wParam, Msg.lParam );
  33357. {$IFDEF INPACKAGE}
  33358. EXCEPT on E: Exception do
  33359. Log( '*** Exception in CallWindowProc, msg = ' + E.Message );
  33360. END;
  33361. EXCEPT
  33362. Log( '*** Exception handled' );
  33363. END;
  33364. {$ENDIF INPACKAGE}
  33365. end
  33366. else
  33367. begin
  33368. {$IFDEF INPACKAGE}
  33369. Log( '//// DefWindowProc' );
  33370. {$ENDIF INPACKAGE}
  33371. Result := DefWindowProc( Msg.hwnd, Msg.message, Msg.wParam, Msg.lParam );
  33372. end;
  33373. {$IFDEF INPACKAGE}
  33374. LogOK;
  33375. FINALLY
  33376. Log( '<-TControl.CallDefWndProc' );
  33377. END;
  33378. {$ENDIF INPACKAGE}
  33379. end;
  33380. {$ENDIF ASM_VERSION}
  33381. //[function TControl.GetWindowState]
  33382. {$IFDEF ASM_VERSION}
  33383. {$ELSE ASM_VERSION} //Pascal
  33384. function TControl.GetWindowState: TWindowState;
  33385. begin
  33386. Result := fWindowState;
  33387. {$ifdef win32}
  33388. if Handle <> 0 then
  33389. begin
  33390. if IsIconic( Handle ) then
  33391. Result := wsMinimized
  33392. else
  33393. if IsZoomed( Handle ) then
  33394. Result := wsMaximized
  33395. else
  33396. Result := wsNormal;
  33397. fWindowState := Result;
  33398. end;
  33399. {$endif win32}
  33400. end;
  33401. {$ENDIF ASM_VERSION}
  33402. //[function TControl.DoSetFocus]
  33403. {$IFDEF ASM_VERSION}
  33404. {$ELSE ASM_VERSION} //Pascal
  33405. function TControl.DoSetFocus: Boolean;
  33406. begin
  33407. Result := False;
  33408. if Enabled and (fTabstop or (fStyle and WS_TABSTOP <> 0)) then
  33409. begin
  33410. Inc( fClickDisabled );
  33411. SetFocus( fHandle );
  33412. Dec( fClickDisabled );
  33413. Result := True;
  33414. end;
  33415. end;
  33416. {$ENDIF ASM_VERSION}
  33417. //[function TControl.HandleAllocated]
  33418. function TControl.HandleAllocated: Boolean;
  33419. begin
  33420. Result := FHandle <> 0;
  33421. end;
  33422. //[function TControl.GetEnabled]
  33423. {$IFDEF ASM_VERSION}
  33424. {$ELSE ASM_VERSION} //Pascal
  33425. function TControl.GetEnabled: Boolean;
  33426. begin
  33427. if FHandle = 0 then
  33428. Result := (Style and WS_DISABLED) = 0
  33429. else
  33430. Result := IsWindowEnabled( FHandle );
  33431. end;
  33432. {$ENDIF ASM_VERSION}
  33433. {$ENDIF WIN_GDI}
  33434. //[function TControl.IsMainWindow]
  33435. {$IFDEF ASM_VERSION}
  33436. {$ELSE ASM_VERSION} //Pascal
  33437. function TControl.IsMainWindow: Boolean;
  33438. begin
  33439. if Applet = nil then
  33440. Result := not IsControl
  33441. else if not AppButtonUsed then
  33442. Result := @ Self = Applet
  33443. else
  33444. Result := Applet.Children[ 0 ] = @ Self;
  33445. end;
  33446. {$ENDIF ASM_VERSION}
  33447. {$IFDEF WIN_GDI}
  33448. //[function TControl.get_ClassName]
  33449. {$IFDEF ASM_UNICODE}
  33450. {$ELSE ASM_VERSION} //Pascal
  33451. function TControl.get_ClassName: KOLString;
  33452. begin
  33453. {$ifndef wince}
  33454. if not fCtlClsNameChg then
  33455. Result := 'obj_' + fControlClassName
  33456. else
  33457. {$endif wince}
  33458. Result := fControlClassName;
  33459. end;
  33460. {$ENDIF ASM_VERSION}
  33461. //[procedure TControl.set_ClassName]
  33462. procedure TControl.set_ClassName(const Value: KOLString);
  33463. begin
  33464. if fCtlClsNameChg then
  33465. FreeMem( fControlClassName );
  33466. GetMem( fControlClassName, (Length( Value ) + 1) * Sizeof( KOLChar ) );
  33467. {$IFDEF UNICODE_CTRLS} WStrCopy {$ELSE} StrCopy {$ENDIF}
  33468. ( fControlClassName, @ Value[ 1 ] );
  33469. fCtlClsNameChg := TRUE;
  33470. end;
  33471. //[function WndProcQueryEndSession]
  33472. function WndProcQueryEndSession( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  33473. var Accept: Boolean;
  33474. begin
  33475. Result := FALSE;
  33476. if Msg.message = WM_QUERYENDSESSION then
  33477. begin
  33478. if Assigned( Sender.fOnQueryEndSession ) then
  33479. begin
  33480. Accept := TRUE;
  33481. Sender.fCloseQueryReason := qShutdown;
  33482. if LongBool(Msg.lParam and {ENDSESSION_LOGOFF} DWORD($80000000)) then
  33483. Sender.fCloseQueryReason := qLogoff;
  33484. Sender.fOnQueryEndSession( Sender, Accept );
  33485. Sender.fCloseQueryReason := qClose;
  33486. Rslt := Integer( Accept );
  33487. // Äîáàâèòü. Íóæíî äëÿ òîãî, ÷òîáû îòìåíèëîñü çàâåðøåíèå ñåàíñà,
  33488. // åñëè Accept óñòàíîâëåí â False è ñåàíñ çàâåðøèëñÿ ïðè Accept = True
  33489. // Add (YS). To cancel ending session if Accept=FALSE but allow ending
  33490. // session if Accept=TRUE.
  33491. Result := True; // {YS}: no further processing
  33492. end;
  33493. end;
  33494. end;
  33495. //[procedure TControl.SetOnQueryEndSession]
  33496. procedure TControl.SetOnQueryEndSession(const Value: TOnEventAccept);
  33497. begin
  33498. AttachProc( WndProcQueryEndSession );
  33499. fOnQueryEndSession := Value;
  33500. end;
  33501. //[function WndProcMinMaxRestore]
  33502. function WndProcMinMaxRestore( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  33503. begin
  33504. Result := FALSE;
  33505. if Msg.message = WM_SYSCOMMAND then
  33506. begin
  33507. case Msg.wParam and not 15 of
  33508. SC_MINIMIZE: if Assigned( Sender.fOnMinimize ) then
  33509. Sender.fOnMinimize( Sender );
  33510. SC_MAXIMIZE: if Assigned( Sender.fOnMaximize ) then
  33511. Sender.fOnMaximize( Sender );
  33512. SC_RESTORE: if Assigned( Sender.fOnRestore ) then
  33513. Sender.fOnRestore( Sender );
  33514. end;
  33515. end;
  33516. end;
  33517. //[procedure TControl.SetOnMinMaxRestore]
  33518. procedure TControl.SetOnMinMaxRestore(const Index: Integer;
  33519. const Value: TOnEvent);
  33520. type POnEvent = ^TOnEvent;
  33521. {$IFDEF F_P}
  33522. var Ptr1: Pointer;
  33523. {$ELSE DELPHI}
  33524. var Ev: POnEvent;
  33525. {$ENDIF F_P/DELPHI}
  33526. begin
  33527. AttachProc( WndProcMinMaxRestore );
  33528. {$IFDEF F_P}
  33529. Ptr1 := Self;
  33530. asm
  33531. MOV EAX, [Ptr1]
  33532. LEA EAX, [EAX].TControl.fOnMinimize
  33533. ADD EAX, [Index]
  33534. MOV EDX, [Value]
  33535. MOV [EAX], EDX
  33536. MOV EDX, [Value+4]
  33537. MOV [EAX+4], EDX
  33538. end [ 'EAX', 'EDX' ];
  33539. {$ELSE DELPHI}
  33540. Ev := Pointer( cardinal( @ TMethod( fOnMinimize ).Code ) + cardinal(Index) );
  33541. Ev^ := Value;
  33542. {$ENDIF}
  33543. end;
  33544. procedure TControl.SetOnMinimize(const Value: TOnEvent);
  33545. begin
  33546. SetOnMinMaxRestore( 0, Value );
  33547. end;
  33548. procedure TControl.SetOnMaximize(const Value: TOnEvent);
  33549. begin
  33550. SetOnMinMaxRestore( 8, Value );
  33551. end;
  33552. procedure TControl.SetOnRestore(const Value: TOnEvent);
  33553. begin
  33554. SetOnMinMaxRestore( 16, Value );
  33555. end;
  33556. {$IFDEF F_P}
  33557. //[function TControl.GetOnMinMaxRestore]
  33558. function TControl.GetOnMinMaxRestore(const Index: Integer): TOnEvent;
  33559. begin
  33560. CASE Index OF
  33561. 0: Result := fOnMinimize;
  33562. 8: Result := fOnMaximize;
  33563. 16: Result := fOnRestore;
  33564. END;
  33565. end;
  33566. {$ENDIF F_P}
  33567. {$IFDEF INPACKAGE}
  33568. {$IFDEF ASM_LOCAL}
  33569. {$UNDEF ASM_LOCAL}
  33570. {$ENDIF}
  33571. {$ELSE}
  33572. {$IFDEF ASM_VERSION}
  33573. {$DEFINE ASM_LOCAL}
  33574. {$ENDIF}
  33575. {$ENDIF}
  33576. {$ENDIF WIN_GDI}
  33577. {$IFDEF GDI}
  33578. //[procedure TControl.SetParent]
  33579. {$IFDEF ASM_LOCAL}
  33580. {$ELSE ASM_VERSION} //Pascal
  33581. procedure TControl.SetParent( Value: PControl );
  33582. begin
  33583. if Value = fParent then Exit;
  33584. if fParent <> nil then
  33585. begin
  33586. {$IFDEF USE_GRAPHCTLS}
  33587. Invalidate; // necessary for graphic controls
  33588. {$ENDIF}
  33589. {$IFDEF DEBUG_MCK}
  33590. if Assigned( fParent.fChildren ) then
  33591. begin
  33592. mck_Log( 'remove from old parent children 1st' );
  33593. fParent.fChildren.Remove( @Self );
  33594. mck_Log( 'removed ok' );
  33595. end;
  33596. {$ELSE not DEBUG_MCK}
  33597. fParent.fChildren.Remove( @Self );
  33598. {$IFDEF NOT_USE_AUTOFREE4CONTROLS}
  33599. {$ELSE}
  33600. fParent.RemoveFromAutoFree( @Self );
  33601. {$ENDIF}
  33602. if Assigned( fParent.fNotifyChild ) then
  33603. fParent.fNotifyChild( fParent, nil );
  33604. {$ENDIF not DEBUG_MCK}
  33605. end;
  33606. fParent := Value;
  33607. if fParent <> nil then
  33608. begin
  33609. fParent.fChildren.Add( @Self );
  33610. {$IFDEF USE_AUTOFREE4CHILDREN}
  33611. fParent.Add2AutoFree( @ Self );
  33612. {$ENDIF}
  33613. {$IFNDEF INPACKAGE} //-----------------------------------------------------
  33614. if FHandle <> 0 then
  33615. Windows.SetParent( FHandle, Value.GetWindowHandle );
  33616. {$ENDIF not INPACKAGE} //--------------------------------------------------
  33617. if Assigned( fParent.fNotifyChild ) then
  33618. fParent.fNotifyChild( fParent, @ Self );
  33619. if Assigned( fNotifyChild ) then
  33620. fNotifyChild( fParent, @ Self );
  33621. {$IFDEF USE_GRAPHCTLS}
  33622. Invalidate; // necessary for graphic controls
  33623. {$ENDIF}
  33624. end;
  33625. end;
  33626. {$ENDIF ASM_VERSION}
  33627. {$ENDIF GDI}
  33628. {$IFDEF _X_}
  33629. {$IFDEF GTK}
  33630. procedure TControl.SetParent( Value: PControl );
  33631. begin
  33632. if Value = fParent then Exit;
  33633. if fParent <> nil then
  33634. begin
  33635. fParent.fChildren.Remove( @Self );
  33636. {$IFDEF NOT_USE_AUTOFREE4CONTROLS}
  33637. {$ELSE}
  33638. fParent.RemoveFromAutoFree( @Self );
  33639. {$ENDIF}
  33640. end;
  33641. fParent := Value;
  33642. if fParent <> nil then
  33643. begin
  33644. fParent.fChildren.Add( @Self );
  33645. {$IFDEF USE_AUTOFREE4CHILDREN}
  33646. fParent.Add2AutoFree( @ Self );
  33647. {$ENDIF}
  33648. end;
  33649. fParent.fGetClientArea( fParent );
  33650. fParent.fChildPut( fParent, @ Self, fBoundsRect.Left, fBoundsRect.Top );
  33651. end;
  33652. {$ENDIF GTK}
  33653. {$ENDIF _X_}
  33654. //[function TControl.ChildIndex]
  33655. function TControl.ChildIndex(Child: PControl): Integer;
  33656. begin
  33657. Result := fChildren.IndexOf( Child );
  33658. end;
  33659. //*
  33660. //[procedure TControl.MoveChild]
  33661. procedure TControl.MoveChild(Child: PControl; NewIdx: Integer);
  33662. var I: Integer;
  33663. begin
  33664. I := ChildIndex( Child );
  33665. Assert( I>=0, 'TControl.MoveChild: index out of bounds' );
  33666. fChildren.MoveItem( I, NewIdx );
  33667. end;
  33668. {$IFDEF WIN_GDI}
  33669. //[procedure TControl.EnableChildren]
  33670. procedure TControl.EnableChildren(Enable, Recursive: Boolean);
  33671. var I: Integer;
  33672. C: PControl;
  33673. begin
  33674. for I := 0 to ChildCount-1 do
  33675. begin
  33676. C := Children[ I ];
  33677. C.Enabled := Enable;
  33678. if Recursive then
  33679. C.EnableChildren( Enable, TRUE );
  33680. end;
  33681. end;
  33682. {$ENDIF WIN_GDI}
  33683. //[constructor TControl.CreateParented]
  33684. {$IFDEF GDI}
  33685. {$IFDEF ASM_VERSION}
  33686. {$ELSE ASM_VERSION} //Pascal
  33687. constructor TControl.CreateParented(AParent: PControl);
  33688. begin
  33689. InitParented( AParent ); // because InitParented is virtual, but CreateParented
  33690. end; // can not be virtual (as an _object_ - not a class - constructor)
  33691. {$ENDIF ASM_VERSION}
  33692. {$ENDIF GDI}
  33693. {$IFDEF _X_}
  33694. {$IFDEF GTK}
  33695. constructor TControl.CreateParented(AParent: PControl; widget: PGtkWidget;
  33696. need_eventbox: Boolean);
  33697. begin
  33698. InitParented( AParent, widget, need_eventbox );
  33699. // because InitParented is virtual, but CreateParented
  33700. end; // can not be virtual (as an _object_ - not a class - constructor)
  33701. {$ENDIF GTK}
  33702. {$ENDIF _X_}
  33703. //[function TControl.GetLeft]
  33704. {$IFDEF ASM_VERSION}
  33705. {$ELSE ASM_VERSION} //Pascal
  33706. function TControl.GetLeft: Integer;
  33707. begin
  33708. Result := BoundsRect.Left;
  33709. end;
  33710. {$ENDIF ASM_VERSION}
  33711. //[procedure TControl.SetLeft]
  33712. {$IFDEF ASM_VERSION}
  33713. {$ELSE ASM_VERSION} //Pascal
  33714. procedure TControl.SetLeft( Value: Integer );
  33715. var R: TRect;
  33716. begin
  33717. R := BoundsRect;
  33718. R.Left := Value;
  33719. R.Right := Value + Width;
  33720. SetBoundsRect( R );
  33721. end;
  33722. {$ENDIF ASM_VERSION}
  33723. //[function TControl.GetTop]
  33724. {$IFDEF ASM_VERSION}
  33725. {$ELSE ASM_VERSION} //Pascal
  33726. function TControl.GetTop: Integer;
  33727. begin
  33728. Result := BoundsRect.Top;
  33729. end;
  33730. {$ENDIF ASM_VERSION}
  33731. //[procedure TControl.SetTop]
  33732. {$IFDEF ASM_VERSION}
  33733. {$ELSE ASM_VERSION} //Pascal
  33734. procedure TControl.SetTop( Value: Integer );
  33735. var R: TRect;
  33736. begin
  33737. R := BoundsRect;
  33738. R.Top := Value;
  33739. R.Bottom := Value + Height;
  33740. SetBoundsRect( R );
  33741. end;
  33742. {$ENDIF ASM_VERSION}
  33743. //[function TControl.GetWidth]
  33744. {$IFDEF ASM_VERSION}
  33745. {$ELSE ASM_VERSION} //Pascal
  33746. function TControl.GetWidth: Integer;
  33747. begin
  33748. with BoundsRect do
  33749. Result := Right - Left;
  33750. end;
  33751. {$ENDIF ASM_VERSION}
  33752. //[procedure TControl.SetWidth]
  33753. {$IFDEF ASM_VERSION}
  33754. {$ELSE ASM_VERSION} //Pascal
  33755. procedure TControl.SetWidth( Value: Integer );
  33756. var R: TRect;
  33757. begin
  33758. R := BoundsRect;
  33759. with R do
  33760. Right := Left + Value;
  33761. SetBoundsRect( R );
  33762. end;
  33763. {$ENDIF ASM_VERSION}
  33764. //[function TControl.GetHeight]
  33765. {$IFDEF ASM_VERSION}
  33766. {$ELSE ASM_VERSION} //Pascal
  33767. function TControl.GetHeight: Integer;
  33768. begin
  33769. with BoundsRect do
  33770. Result := Bottom - Top;
  33771. end;
  33772. {$ENDIF ASM_VERSION}
  33773. //[procedure TControl.SetHeight]
  33774. {$IFDEF ASM_VERSION}
  33775. {$ELSE ASM_VERSION} //Pascal
  33776. procedure TControl.SetHeight( Value: Integer );
  33777. var R: TRect;
  33778. begin
  33779. R := BoundsRect;
  33780. with R do
  33781. Bottom := Top + Value;
  33782. SetBoundsRect( R );
  33783. end;
  33784. {$ENDIF ASM_VERSION}
  33785. //[function TControl.GetPosition]
  33786. {$IFDEF ASM_VERSION}
  33787. {$ELSE ASM_VERSION} //Pascal
  33788. function TControl.GetPosition: TPoint;
  33789. begin
  33790. Result.x := BoundsRect.Left;
  33791. Result.y := BoundsRect.Top;
  33792. end;
  33793. {$ENDIF ASM_VERSION}
  33794. //[procedure TControl.Set_Position]
  33795. {$IFDEF ASM_VERSION}
  33796. {$ELSE ASM_VERSION} //Pascal
  33797. procedure TControl.Set_Position( Value: TPoint );
  33798. var R: TRect;
  33799. begin
  33800. R.Top := Value.y;
  33801. R.Left := Value.x;
  33802. R.Right := R.Left + Width;
  33803. R.Bottom := R.Top + Height;
  33804. BoundsRect := R;
  33805. end;
  33806. {$ENDIF ASM_VERSION}
  33807. {$IFDEF WIN_GDI}
  33808. //[function WndProcConstraints]
  33809. function WndProcConstraints( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  33810. var MMI: PMinMaxInfo;
  33811. begin
  33812. Result := FALSE;
  33813. if Msg.message = WM_GETMINMAXINFO then
  33814. begin
  33815. Rslt := Sender.CallDefWndProc( Msg );
  33816. MMI := Pointer( Msg.lParam );
  33817. if Sender.FMaxWidth > 0 then
  33818. begin
  33819. MMI.ptMaxSize.x := Sender.FMaxWidth;
  33820. MMI.ptMaxTrackSize.x := Sender.FMaxWidth;
  33821. end;
  33822. if Sender.FMaxHeight > 0 then
  33823. begin
  33824. MMI.ptMaxSize.y := Sender.FMaxHeight;
  33825. MMI.ptMaxTrackSize.y := Sender.FMaxHeight;
  33826. end;
  33827. MMI.ptMinTrackSize := MakePoint( Sender.FMinWidth, Sender.FMinHeight );
  33828. Rslt := 0;
  33829. Result := TRUE;
  33830. end;
  33831. end;
  33832. {$IFDEF USE_MHTOOLTIP}
  33833. {$DEFINE implementation}
  33834. {$I KOLMHToolTip.pas}
  33835. {$UNDEF implementation}
  33836. {$ENDIF}
  33837. //[procedure TControl.SetConstraint]
  33838. procedure TControl.SetConstraint(const Index, Value: Integer);
  33839. begin
  33840. AttachProc( WndProcConstraints );
  33841. case Index of
  33842. 0: FMinWidth := Value;
  33843. 1: FMinHeight := Value;
  33844. 2: FMaxWidth := Value;
  33845. 3: FMaxHeight := Value;
  33846. end;
  33847. end;
  33848. {$IFDEF F_P}
  33849. //[function TControl.GetConstraint]
  33850. function TControl.GetConstraint(const Index: Integer): Integer;
  33851. begin
  33852. CASE Index OF
  33853. 0: Result := FMinWidth;
  33854. 1: Result := FMinHeight;
  33855. 2: Result := FMaxWidth;
  33856. 3: Result := FMaxHeight;
  33857. END;
  33858. end;
  33859. {$ENDIF F_P}
  33860. //*
  33861. //[function TControl.ControlRect]
  33862. function TControl.ControlRect: TRect;
  33863. var C: PControl;
  33864. R: TRect;
  33865. begin
  33866. Result := BoundsRect;
  33867. C := Parent;
  33868. if C <> nil then
  33869. begin
  33870. if not C.fIsControl then Exit;
  33871. R := C.ControlRect;
  33872. OffsetRect( Result, R.Left, R.Top );
  33873. if C.fChildren <> nil then
  33874. if C.FChildren.IndexOf( @Self ) >= C.MembersCount then
  33875. begin
  33876. R := C.ClientRect;
  33877. Dec( R.Top, C.fClientTop );
  33878. Dec( R.Left, C.fClientLeft );
  33879. OffsetRect( Result, R.Left, R.Top );
  33880. end;
  33881. end;
  33882. end;
  33883. //*
  33884. //[function TControl.ControlAtPos]
  33885. function TControl.ControlAtPos( X, Y: Integer;
  33886. IgnoreDisabled: Boolean ): PControl;
  33887. var I: Integer;
  33888. C: PControl;
  33889. CR, VR: TRect;
  33890. begin
  33891. Result := nil;
  33892. CR := ControlRect;
  33893. if Windowed then
  33894. CR := MakeRect( 0, 0, 0, 0 );
  33895. X := X + CR.Left; // - R.Left;
  33896. Y := Y + CR.Top; // - R.Top;
  33897. for I := ChildCount { + MembersCount } - 1 downto 0 do
  33898. begin
  33899. C := Children[ I ]; //Members[ I ];
  33900. if C.Visible then
  33901. if (not IgnoreDisabled) or IgnoreDisabled and C.Enabled then
  33902. begin
  33903. VR := C.ControlRect;
  33904. if (X >= VR.Left) and (X < VR.Right) and
  33905. (Y >= VR.Top) and (Y < VR.Bottom) then
  33906. begin
  33907. Result := C;
  33908. Exit;
  33909. end;
  33910. end;
  33911. end;
  33912. end;
  33913. {$ENDIF WIN_GDI}
  33914. //[PROCEDURE DefaultPaintBackground]
  33915. {$IFDEF ASM_VERSION}
  33916. {$ELSE ASM_VERSION} //Pascal
  33917. procedure DefaultPaintBackground( Sender: PControl; DC: HDC; Rect: PRect );
  33918. {$IFDEF GDI} var B: HBrush; {$ENDIF GDI}
  33919. begin
  33920. {$IFDEF GDI}
  33921. B := CreateSolidBrush( Color2Rgb( Sender.Color ) );
  33922. Windows.FillRect( DC, Rect^, B );
  33923. DeleteObject( B );
  33924. {$ENDIF GDI}
  33925. end;
  33926. {$ENDIF ASM_VERSION}
  33927. //[END DefaultPaintBackground]
  33928. {$IFDEF WIN_GDI}
  33929. //[procedure TControl.PaintBackground]
  33930. procedure TControl.PaintBackground( DC: HDC; Rect: PRect );
  33931. begin
  33932. Global_OnPaintBkgnd( @Self, DC, Rect );
  33933. end;
  33934. {$ENDIF WIN_GDI}
  33935. //[procedure TControl.SetCtlColor]
  33936. {$IFDEF GDI}
  33937. {$IFDEF ASM_VERSION}
  33938. {$ELSE ASM_VERSION} //Pascal
  33939. procedure TControl.SetCtlColor( Value: TColor );
  33940. begin
  33941. {$IFNDEF INPACKAGE}
  33942. if GetWindowHandle <> 0 then
  33943. {$ELSE}
  33944. if fHandle <> 0 then
  33945. {$ENDIF}
  33946. if fCommandActions.aSetBkColor <> 0 then
  33947. Perform( fCommandActions.aSetBkColor, 0, Color2RGB( Value ) );
  33948. if fColor = Value then Exit;
  33949. fColor := Value;
  33950. if fTmpBrush <> 0 then
  33951. begin
  33952. DeleteObject( fTmpBrush );
  33953. fTmpBrush := 0;
  33954. end;
  33955. if fBrush <> nil then
  33956. fBrush.Color := Value;
  33957. Invalidate;
  33958. end;
  33959. {$ENDIF ASM_VERSION}
  33960. {$ENDIF GDI}
  33961. {$IFDEF _X_}
  33962. {$IFDEF GTK}
  33963. procedure TControl.SetCtlColor( Value: TColor );
  33964. var gcolor: TGdkColor;
  33965. i: Integer;
  33966. begin
  33967. if fColor = Value then Exit;
  33968. fColor := Value;
  33969. //oldfontdesc := PGtkWidget( _Self.fHandle ).style.font_desc;
  33970. gcolor := Color2GdkColor( Value );
  33971. for i := 0 to 4 do
  33972. begin
  33973. gtk_widget_modify_bg( fEventboxHandle, {GTK_STATE_NORMAL} i, @ gcolor );
  33974. gtk_widget_modify_base( fEventboxHandle, {GTK_STATE_NORMAL} i, @ gcolor );
  33975. end;
  33976. //if Assigned( _Self.fFont ) then
  33977. {begin
  33978. _Self.fHandle.style.font_desc :=
  33979. pango_font_description_copy( _Self.fFont.GetPangoFontDesc );
  33980. if oldfontdesc <> nil then
  33981. pango_font_description_free( oldfontdesc );
  33982. end;}
  33983. //Invalidate;
  33984. end;
  33985. {$ENDIF GTK}
  33986. {$ENDIF _X_}
  33987. {$IFDEF WIN_GDI}
  33988. //[function TControl.GetParentWnd]
  33989. {$IFDEF ASM_VERSION}
  33990. {$ELSE ASM_VERSION} //Pascal
  33991. function TControl.GetParentWnd( NeedHandle: Boolean ): HWnd;
  33992. var C: PControl;
  33993. begin
  33994. Result := 0;
  33995. C := fParent; // WindowedParent;
  33996. if C <> nil then
  33997. begin
  33998. if NeedHandle then
  33999. C.GetWindowHandle;
  34000. Result := C.fHandle;
  34001. end;
  34002. end;
  34003. {$ENDIF ASM_VERSION}
  34004. //[procedure TControl.CreateChildWindows]
  34005. {$IFDEF ASM_VERSION}
  34006. {$ELSE ASM_VERSION} //Pascal
  34007. procedure TControl.CreateChildWindows;
  34008. var I: Integer;
  34009. C: PControl;
  34010. begin
  34011. {$IFDEF INPACKAGE}
  34012. Log( '->TControl.CreateChildWindows' );
  34013. TRY
  34014. {$ENDIF INPACKAGE}
  34015. for I := 0 to fChildren.Count - 1 do
  34016. begin
  34017. {$IFDEF INPACKAGE}
  34018. Log( Int2Str( I ) );
  34019. {$ENDIF INPACKAGE}
  34020. C := fChildren.fItems[ I ];
  34021. C.CreateWindow; //virtual!!!
  34022. end;
  34023. {$IFDEF INPACKAGE}
  34024. LogOK;
  34025. FINALLY
  34026. Log( '<-TControl.CreateChildWindows' );
  34027. END;
  34028. {$ENDIF INPACKAGE}
  34029. end;
  34030. {$ENDIF ASM_VERSION}
  34031. {$ENDIF WIN_GDI}
  34032. //[function TControl.GetMembers]
  34033. function TControl.GetMembers(Idx: Integer): PControl;
  34034. begin
  34035. Result := fChildren.Items[ Idx ];
  34036. // Important: .Items but not .fItems - when fChildren.Count=0, nil is returned
  34037. end;
  34038. {$IFDEF WIN_GDI}
  34039. //[procedure TControl.DestroyChildren]
  34040. {$IFDEF ASM_VERSION}
  34041. {$ELSE ASM_VERSION} //Pascal
  34042. procedure TControl.DestroyChildren;
  34043. var I: Integer;
  34044. W: PControl;
  34045. begin
  34046. for I := fChildren.fCount - 1 downto 0 do
  34047. begin
  34048. W := fChildren.fItems[ I ];
  34049. W.Free;
  34050. end;
  34051. fChildren.Clear;
  34052. end;
  34053. {$ENDIF ASM_VERSION}
  34054. {//-
  34055. //[function TControl.WindowedParent]
  34056. function TControl.WindowedParent: PControl;
  34057. begin
  34058. Result := fParent;
  34059. end;}
  34060. //[function TControl.ProcessMessage]
  34061. {$IFDEF ASM_VERSION}
  34062. {$ELSE ASM_VERSION} //Pascal
  34063. function TControl.ProcessMessage: Boolean;
  34064. begin
  34065. Result := InternalProcessMessage(nil);
  34066. end;
  34067. {$ENDIF ASM_VERSION}
  34068. function TControl.InternalProcessMessage(AMsg: PMsg): Boolean;
  34069. var Msg: TMsg;
  34070. begin
  34071. Result := False;
  34072. if AMsg <> nil then
  34073. Msg:=AMsg^
  34074. else
  34075. if not PeekMessage( Msg, 0, 0, 0, PM_REMOVE ) then
  34076. exit;
  34077. Result := Msg.message <> 0;
  34078. if (Msg.message = WM_QUIT) then
  34079. begin
  34080. AppletTerminated := True;
  34081. {$IFDEF PROVIDE_EXITCODE}
  34082. ExitCode := Msg.wParam;
  34083. {$ENDIF PROVIDE_EXITCODE}
  34084. end
  34085. else
  34086. begin
  34087. if not(Assigned( fExMsgProc ) and fExMsgProc( @Self, Msg )) then
  34088. begin
  34089. TranslateMessage( Msg );
  34090. DispatchMessage( Msg );
  34091. {$IFDEF PSEUDO_THREADS}
  34092. if Assigned( MainThread ) then
  34093. MainThread.NextThread;
  34094. {$ENDIF}
  34095. end;
  34096. end;
  34097. end;
  34098. procedure TControl.WaitAndProcessMessages;
  34099. var Msg: TMsg;
  34100. begin
  34101. GetMessage(Msg, 0, 0, 0);
  34102. InternalProcessMessage(@Msg);
  34103. while InternalProcessMessage(nil) do ;
  34104. end;
  34105. //[procedure TControl.ProcessMessages]
  34106. {$IFDEF ASM_VERSION}
  34107. {$ELSE ASM_VERSION} //Pascal
  34108. procedure TControl.ProcessMessages;
  34109. begin
  34110. while ProcessMessage do ;
  34111. end;
  34112. {$ENDIF ASM_VERSION}
  34113. //[procedure TControl.ProcessMessagesEx]
  34114. procedure TControl.ProcessMessagesEx;
  34115. begin
  34116. PostMessage( GetWindowHandle, CM_PROCESS, 0, 0 );
  34117. ProcessMessages;
  34118. end;
  34119. //-
  34120. //[procedure TControl.ProcessPendingMessages]
  34121. procedure TControl.ProcessPendingMessages;
  34122. var Msg: TMsg;
  34123. begin
  34124. if LOWORD( GetQueueStatus( QS_ALLINPUT ) ) <> 0 then
  34125. if PeekMessage( Msg, 0, 0, 0, PM_NOREMOVE {or PM_NOYIELD} )
  34126. or PeekMessage( Msg, HWnd(-1), 0, 0, PM_NOREMOVE {or PM_NOYIELD} )
  34127. then
  34128. Applet.ProcessMessages;
  34129. end;
  34130. //[procedure TControl.ProcessPaintMessages]
  34131. procedure TControl.ProcessPaintMessages;
  34132. var Msg: TMsg;
  34133. begin
  34134. while PeekMessage( Msg, Handle, 15, 15, PM_NOREMOVE ) do
  34135. Applet.ProcessMessage;
  34136. end;
  34137. //[FUNCTION WndProcForm]
  34138. {$IFDEF ASM_VERSION}
  34139. {$ELSE ASM_VERSION} //Pascal
  34140. function WndProcForm(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  34141. {$IFDEF ENDSESSION_HALT}
  34142. var App: PControl;
  34143. {$ENDIF}
  34144. begin
  34145. Result := True;
  34146. with Self_{-}^{+} do
  34147. case Msg.message of
  34148. {$IFDEF ENDSESSION_HALT}
  34149. WM_ENDSESSION:
  34150. begin
  34151. if Msg.wParam <> 0 then
  34152. begin
  34153. Self_.RefDec;
  34154. { Normally, WM_ENDSESSION is sent to a main form, not to Applet.
  34155. Since we do not plan further working after handling this message,
  34156. we decrease RefCount for the form (in was increased in EnumDynHandlers
  34157. to prevent object destroying while its message processing is not
  34158. finished). }
  34159. App := Applet;
  34160. //Rslt := 0; { We will not return any result at all. }
  34161. {$IFDEF DEBUG_ENDSESSION}
  34162. EndSession_Initiated := TRUE;
  34163. LogFileOutput( GetStartDir + 'es_debug.txt',
  34164. 'Self_=' + Int2Hex( DWORD( Self_ ), 8 ) +
  34165. ' Self_.Handle=' + Int2Str( Self_.FHandle ) );
  34166. {$ENDIF}
  34167. AppletTerminated := TRUE;
  34168. AppletRunning := FALSE;
  34169. Applet := nil;
  34170. App.Free; { We provide OnDestroy handlers to be called for any objects here }
  34171. Halt; { Stop further executing. }
  34172. end else Result := FALSE;
  34173. end;
  34174. {$ENDIF ENDSESSION_HALT}
  34175. WM_SETFOCUS:
  34176. begin
  34177. {$IFDEF NEW_MODAL}
  34178. if fModalForm <> nil then
  34179. SetFocus( fModalForm.fHandle )
  34180. else if ( FCurrentControl <> nil ) and not ( fCurrentControl.IsForm xor fIsApplet ) then
  34181. {$ELSE not NEW_MODAL}
  34182. if FCurrentControl <> nil then
  34183. {$ENDIF}
  34184. begin
  34185. if FCurrentControl.CreateWindow then
  34186. SetFocus( FCurrentControl.fHandle );
  34187. end
  34188. else
  34189. Result := False;
  34190. if assigned( Applet ) and (Applet <> Self_) then
  34191. Applet.FCurrentControl := Self_;
  34192. end;
  34193. {$IFDEF SNAPMOUSE2DFLTBTN}
  34194. WM_INITDIALOG:
  34195. begin
  34196. asm
  34197. nop
  34198. end;
  34199. Result := FALSE;
  34200. end;
  34201. {$ENDIF}
  34202. else Result := False;
  34203. end;
  34204. end;
  34205. {$ENDIF ASM_VERSION}
  34206. //[END WndProcForm]
  34207. {$ENDIF WIN_GDI}
  34208. //[FUNCTION GetPrevCtrlBoundsRect]
  34209. {$IFDEF ASM_VERSION}
  34210. {$ELSE ASM_VERSION} //Pascal
  34211. function GetPrevCtrlBoundsRect( P: PControl; var R: TRect ): Boolean;
  34212. var Idx: Integer;
  34213. begin
  34214. Result := False;
  34215. if P.FParent = nil then Exit;
  34216. Idx := P.FParent.ChildIndex( P ) - 1;
  34217. if Idx < 0 then Exit;
  34218. Result := True;
  34219. R := P.FParent.Children[ Idx ].BoundsRect;
  34220. end;
  34221. {$ENDIF ASM_VERSION}
  34222. //[END GetPrevCtrlBoundsRect]
  34223. //[function TControl.PlaceUnder]
  34224. {$IFDEF ASM_VERSION}
  34225. {$ELSE ASM_VERSION} //Pascal
  34226. function TControl.PlaceUnder: PControl;
  34227. var R: TRect;
  34228. begin
  34229. Result := @Self;
  34230. if not GetPrevCtrlBoundsRect( @Self, R ) then Exit;
  34231. Top := R.Bottom + fParent.fMargin;
  34232. Left := R.Left;
  34233. end;
  34234. {$ENDIF ASM_VERSION}
  34235. //[function TControl.PlaceDown]
  34236. {$IFDEF ASM_VERSION}
  34237. {$ELSE ASM_VERSION} //Pascal
  34238. function TControl.PlaceDown: PControl;
  34239. var R: TRect;
  34240. begin
  34241. Result := @Self;
  34242. if not GetPrevCtrlBoundsRect( @Self, R ) then Exit;
  34243. Top := R.Bottom + fParent.fMargin;
  34244. end;
  34245. {$ENDIF ASM_VERSION}
  34246. //[function TControl.PlaceRight]
  34247. {$IFDEF ASM_VERSION}
  34248. {$ELSE ASM_VERSION} //Pascal
  34249. function TControl.PlaceRight: PControl;
  34250. var R: TRect;
  34251. begin
  34252. Result := @Self;
  34253. if not GetPrevCtrlBoundsRect( @Self, R ) then Exit;
  34254. Top := R.Top;
  34255. Left := R.Right + fParent.fMargin;
  34256. end;
  34257. {$ENDIF ASM_VERSION}
  34258. //[function TControl.SetSize]
  34259. {$IFDEF ASM_VERSION}
  34260. {$ELSE ASM_VERSION} //Pascal
  34261. function TControl.SetSize(W, H: Integer): PControl;
  34262. var R: TRect;
  34263. begin
  34264. R := BoundsRect;
  34265. if W > 0 then R.Right := R.Left + W;
  34266. if H > 0 then R.Bottom := R.Top + H;
  34267. SetBoundsRect( R );
  34268. Result := @Self;
  34269. end;
  34270. {$ENDIF ASM_VERSION}
  34271. {$IFDEF WIN_GDI}
  34272. //[function TControl.SetClientSize]
  34273. function TControl.SetClientSize(W, H: Integer): PControl;
  34274. begin
  34275. if W > 0 then ClientWidth := W;
  34276. if H > 0 then ClientHeight := H;
  34277. Result := @Self;
  34278. end;
  34279. //[function TControl.AlignLeft]
  34280. {$IFDEF ASM_VERSION}
  34281. {$ELSE ASM_VERSION} //Pascal
  34282. function TControl.AlignLeft(P: PControl): PControl;
  34283. begin
  34284. Result := @Self;
  34285. Left := P.Left;
  34286. end;
  34287. {$ENDIF ASM_VERSION}
  34288. //[function TControl.AlignTop]
  34289. {$IFDEF ASM_VERSION}
  34290. {$ELSE ASM_VERSION} //Pascal
  34291. function TControl.AlignTop(P: PControl): PControl;
  34292. begin
  34293. Result := @Self;
  34294. Top := P.Top;
  34295. end;
  34296. {$ENDIF ASM_VERSION}
  34297. {$IFDEF KEY_PREVIEW}
  34298. {$DEFINE KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
  34299. {$ENDIF}
  34300. {$IFDEF ESC_CLOSE_DIALOGS}
  34301. {$IFNDEF KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
  34302. {$DEFINE KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
  34303. {$ENDIF}
  34304. {$ENDIF}
  34305. //[FUNCTION WndProcCtrl]
  34306. {$IFDEF ASM_VERSION} // see addition for combobox in pas version
  34307. function WndProcCtrl( Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  34308. asm //cmd //opd
  34309. PUSH EBX
  34310. XCHG EBX, EAX
  34311. PUSH ESI
  34312. PUSH EDI
  34313. MOV EDI, EDX
  34314. MOV EDX, [EDI].TMsg.message
  34315. SUB DX, CN_CTLCOLORMSGBOX
  34316. CMP DX, CN_CTLCOLORSTATIC-CN_CTLCOLORMSGBOX
  34317. JA @@chk_CM_COMMAND
  34318. @@2:
  34319. PUSH ECX
  34320. MOV EAX, [EBX].TControl.fTextColor
  34321. CALL Color2RGB
  34322. XCHG ESI, EAX
  34323. PUSH ESI
  34324. PUSH [EDI].TMsg.wParam
  34325. CALL SetTextColor
  34326. CMP [EBX].TControl.fTransparent, 0
  34327. JZ @@opaque
  34328. PUSH Windows.TRANSPARENT
  34329. PUSH [EDI].TMsg.wParam
  34330. CALL SetBkMode
  34331. PUSH NULL_BRUSH
  34332. CALL GetStockObject
  34333. JMP @@ret_rslt
  34334. @@opaque:
  34335. MOV EAX, [EBX].TControl.fColor
  34336. CALL Color2RGB
  34337. XCHG ESI, EAX
  34338. PUSH OPAQUE
  34339. PUSH [EDI].TMsg.wParam
  34340. CALL SetBkMode
  34341. PUSH ESI
  34342. PUSH [EDI].TMsg.wParam
  34343. CALL SetBkColor
  34344. MOV EAX, EBX
  34345. CALL Global_GetCtlBrushHandle
  34346. @@ret_rslt:
  34347. XCHG ECX, EAX
  34348. @@tmpbrushready:
  34349. POP EAX
  34350. MOV [EAX], ECX
  34351. @@ret_true:
  34352. MOV AL, 1
  34353. JMP @@ret_EAX
  34354. @@chk_CM_COMMAND:
  34355. CMP word ptr [EDI].TMsg.message, CM_COMMAND
  34356. JNE @@chk_WM_SETFOCUS
  34357. PUSH ECX
  34358. MOVZX ECX, word ptr [EDI].TMsg.wParam+2
  34359. CMP CX, [EBX].TControl.fCommandActions.aClick
  34360. JNE @@chk_aEnter
  34361. CMP [EBX].TControl.fClickDisabled, 0
  34362. JG @@calldef
  34363. MOV EAX, EBX
  34364. MOV DL, 1
  34365. CALL TControl.SetFocused
  34366. MOV EAX, EBX
  34367. CALL TControl.DoClick
  34368. JMP @@calldef
  34369. @@chk_aEnter:
  34370. LEA EAX, [EBX].TControl.fOnEnter
  34371. CMP CX, [EBX].TControl.fCommandActions.aEnter
  34372. JE @@goEvent
  34373. LEA EAX, [EBX].TControl.fOnLeave
  34374. CMP CX, [EBX].TControl.fCommandActions.aLeave
  34375. JE @@goEvent
  34376. LEA EAX, [EBX].TControl.fOnChange
  34377. CMP CX, [EBX].TControl.fCommandActions.aChange
  34378. JNE @@chk_aSelChange
  34379. @@goEvent:
  34380. MOV ECX, [EAX].TMethod.Code
  34381. JECXZ @@2calldef
  34382. MOV EAX, [EAX].TMethod.Data
  34383. MOV EDX, EBX
  34384. CALL ECX
  34385. @@2calldef:
  34386. JMP @@calldef
  34387. @@chk_aSelChange:
  34388. CMP CX, [EBX].TControl.fCommandActions.aSelChange
  34389. JNE @@chk_WM_SETFOCUS_1
  34390. MOV EAX, EBX
  34391. CALL TControl.DoSelChange
  34392. @@calldef:
  34393. XCHG EAX, EBX
  34394. MOV EDX, EDI
  34395. CALL TControl.CallDefWndProc
  34396. JMP @@ret_rslt
  34397. @@chk_WM_SETFOCUS_1:
  34398. POP ECX
  34399. @@chk_WM_SETFOCUS:
  34400. XOR EAX, EAX
  34401. CMP word ptr [EDI].TMsg.message, WM_SETFOCUS
  34402. JNE @@chk_WM_KEYDOWN
  34403. MOV [ECX], EAX
  34404. MOV EAX, EBX
  34405. CALL TControl.ParentForm
  34406. TEST EAX, EAX
  34407. JZ @@ret_true
  34408. PUSH EAX
  34409. MOV ECX, [EAX].TControl.FCurrentControl
  34410. JECXZ @@a1
  34411. CMP ECX, EBX
  34412. JZ @@a1
  34413. XCHG EAX, ECX
  34414. MOV ECX, [EAX].TControl.fLeave.TMethod.Code
  34415. JECXZ @@a1
  34416. XCHG EDX, EAX
  34417. MOV EAX, [EDX].TControl.fLeave.TMethod.Data
  34418. CALL ECX
  34419. @@a1: POP EAX
  34420. MOV [EAX].TControl.FCurrentControl, EBX
  34421. XOR EAX, EAX
  34422. PUSH EDX
  34423. @@2ret_EAX:
  34424. POP EDX
  34425. @@chk_WM_KEYDOWN:
  34426. {$IFDEF KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
  34427. CMP word ptr [EDI].TMsg.message, WM_KEYDOWN
  34428. {$IFDEF KEY_PREVIEW}
  34429. JNE @@chk_other_KEYMSGS
  34430. {$ELSE}
  34431. JNE @@ret0
  34432. {$ENDIF}
  34433. {$IFDEF KEY_PREVIEW}
  34434. MOV EAX, EBX
  34435. CALL TControl.ParentForm
  34436. CMP EAX, EBX
  34437. JE @@kp_end
  34438. CMP [EAX].TControl.fKeyPreview, 0
  34439. JZ @@kp_end
  34440. MOV [EAX].TControl.fKeyPreviewing, 1
  34441. INC [EAX].TControl.fKeyPreviewCount
  34442. PUSH EAX
  34443. PUSH [EDI].TMsg.lParam
  34444. PUSH [EDI].TMsg.wParam
  34445. PUSH WM_KEYDOWN
  34446. PUSH EAX
  34447. CALL TControl.Perform
  34448. POP EAX
  34449. DEC [EAX].TControl.fKeyPreviewCount
  34450. @@kp_end:
  34451. {$ENDIF}
  34452. {$IFDEF ESC_CLOSE_DIALOGS}
  34453. MOV EAX, EBX
  34454. CALL TControl.ParentForm
  34455. TEST [EAX].TControl.fExStyle, WS_EX_DLGMODALFRAME
  34456. JZ @@ecd_end
  34457. CMP [EDI].TMsg.wParam, 27
  34458. JNE @@ecd_end
  34459. PUSH 0
  34460. PUSH 0
  34461. PUSH WM_CLOSE
  34462. PUSH EAX
  34463. CALL TControl.Perform
  34464. @@ecd_end:
  34465. {$ENDIF}
  34466. @@ret0:
  34467. XOR EAX, EAX
  34468. {$IFDEF KEY_PREVIEW}
  34469. JMP @@ret_EAX
  34470. @@chk_other_KEYMSGS:
  34471. MOVZX EAX, word ptr [EDI].TMsg.message
  34472. SUB AX, WM_KEYDOWN
  34473. JB @@ret0
  34474. CMP AX, 6
  34475. JA @@ret0
  34476. // all WM_KEYUP=$101, WM_CHAR=$102, WM_DEADCHAR=$103, WM_SYSKEYDOWN=$104,
  34477. // WM_SYSKEYUP=$105, WM_SYSCHAR=$106, WM_SYSDEADCHAR=$107
  34478. MOV EAX, EBX
  34479. CALL TControl.ParentForm
  34480. CMP EAX, EBX
  34481. JE @@ret0
  34482. MOV [EAX].TControl.fKeyPreviewing, 1
  34483. INC [EAX].TControl.fKeyPreviewCount
  34484. PUSH EAX
  34485. PUSH [EDI].TMsg.lParam
  34486. PUSH [EDI].TMsg.wParam
  34487. PUSH [EDI].TMsg.message
  34488. PUSH EAX
  34489. CALL TControl.Perform
  34490. POP EAX
  34491. DEC [EAX].TControl.fKeyPreviewCount
  34492. XOR EAX, EAX
  34493. {$ENDIF KEY_PREVIEW}
  34494. {$ENDIF KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
  34495. @@ret_EAX:
  34496. POP EDI
  34497. POP ESI
  34498. POP EBX
  34499. end;
  34500. {$ELSE ASM_VERSION} //Pascal
  34501. function WndProcCtrl(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  34502. var F: PControl;
  34503. Cmd : DWORD;
  34504. begin
  34505. Result := FALSE;
  34506. with Self_{-}^{+} do
  34507. case Msg.message of
  34508. CN_CTLCOLORMSGBOX..CN_CTLCOLORSTATIC:
  34509. begin
  34510. SetTextColor(Msg.WParam, Color2RGB(fTextColor));
  34511. if fTransparent then
  34512. begin
  34513. SetBkMode( Msg.wParam, Windows.TRANSPARENT );
  34514. Rslt := GetStockObject( NULL_BRUSH );
  34515. end
  34516. else
  34517. begin
  34518. SetBkMode( Msg.wParam, Windows.OPAQUE );
  34519. SetBkColor(Msg.WParam, Color2RGB( fColor ) );
  34520. Rslt := Global_GetCtlBrushHandle( Self_ );
  34521. end;
  34522. Result := TRUE;
  34523. end;
  34524. CM_COMMAND:
  34525. begin
  34526. Result := True;
  34527. Cmd := HiWord( Msg.wParam );
  34528. if Cmd = fCommandActions.aClick then
  34529. begin
  34530. if Integer( fClickDisabled ) <= 0 then
  34531. begin
  34532. Focused := TRUE;
  34533. DoClick;
  34534. end;
  34535. end else
  34536. if Cmd = fCommandActions.aEnter then
  34537. begin
  34538. if Assigned( fOnEnter ) then fOnEnter( Self_ );
  34539. end else
  34540. if Cmd = fCommandActions.aLeave then
  34541. begin
  34542. if Assigned( fOnLeave ) then fOnLeave( Self_ );
  34543. end else
  34544. if Integer(Cmd) = fCommandActions.aChange then
  34545. begin
  34546. if Assigned( fOnChange ) then fOnChange( Self_ );
  34547. end else
  34548. if Integer(Cmd) = fCommandActions.aSelChange then
  34549. begin
  34550. DoSelChange;
  34551. end
  34552. else Result := False;
  34553. if Result then
  34554. Rslt := CallDefWndProc( Msg );
  34555. end;
  34556. WM_SETFOCUS:
  34557. begin
  34558. Rslt := 0;
  34559. Result := TRUE;
  34560. F := ParentForm;
  34561. if F <> nil then
  34562. begin
  34563. if (F.fCurrentControl <> nil) and (F.fCurrentControl <> Self_) and
  34564. Assigned( F.fCurrentControl.fLeave ) then
  34565. F.fCurrentControl.fLeave( F.fCurrentControl );
  34566. F.fCurrentControl := Self_;
  34567. Result := False; // go further handling
  34568. end;
  34569. end;
  34570. {$IFDEF KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
  34571. WM_KEYDOWN:
  34572. begin
  34573. {$IFDEF KEY_PREVIEW}
  34574. //--------------------------------Truf-------------------------------------
  34575. if ParentForm <> Self_ then
  34576. begin
  34577. if ParentForm.KeyPreview then begin
  34578. ParentForm.KeyPreviewing := TRUE;
  34579. inc( ParentForm.FKeyPreviewCount );
  34580. ParentForm.Perform(WM_KEYDOWN,msg.wParam,msg.lParam);
  34581. dec( ParentForm.FKeyPreviewCount );
  34582. end;
  34583. end;
  34584. //--------------------------------Truf-------------------------------------
  34585. {$ENDIF KEY_PREVIEW}
  34586. {$IFDEF ESC_CLOSE_DIALOGS}
  34587. //---------------------------------Babenko Alexey--------------------------
  34588. begin
  34589. if (Self_.ParentForm.fExStyle and WS_EX_DLGMODALFRAME) <> 0 then
  34590. if Msg.wParam = 27 then
  34591. Self_.ParentForm.Perform(WM_CLOSE, 0, 0);
  34592. end;
  34593. //---------------------------------Babenko Alexey--------------------------
  34594. {$ENDIF ESC_CLOSE_DIALOGS}
  34595. end;
  34596. {$IFDEF KEY_PREVIEW}
  34597. WM_SYSKEYDOWN,
  34598. WM_KEYUP, WM_SYSKEYUP,
  34599. WM_CHAR, WM_SYSCHAR:
  34600. if ParentForm <> Self_ then
  34601. begin
  34602. if ParentForm.KeyPreview then
  34603. begin
  34604. ParentForm.KeyPreviewing := TRUE;
  34605. ParentForm.Perform(Msg.message,msg.wParam,msg.lParam);
  34606. end;
  34607. end;
  34608. {$ENDIF KEY_PREVIEW}
  34609. {$ENDIF KEY_PREVIEW_OR_ESC_CLOSE_DIALOGS}
  34610. end;
  34611. end;
  34612. {$ENDIF ASM_VERSION}
  34613. //[END WndProcCtrl]
  34614. {$ifdef win32}
  34615. //[FUNCTION WndProcTransparent]
  34616. {$IFDEF OLD_TRANSPARENT}
  34617. function WndProcTransparent( Sender: PControl; var Msg: TMsg;
  34618. var Rslt: Integer ): Boolean;
  34619. var DC, PDC, BLTDC: HDC;
  34620. Save: integer;
  34621. OLDp: THANDLE;
  34622. L, T: SmallInt;
  34623. TP, ParentClient: TPoint;
  34624. TR, Margins: TRect;
  34625. Wnd: HWND;
  34626. tRgn: HRgn;
  34627. C: PControl;
  34628. begin
  34629. Result := FALSE;
  34630. {$IFDEF STOP_WNDPROCTRANSPARENT_AFTER_APPLETTERMINATED}
  34631. if AppletTerminated or not Sender.ToBeVisible then
  34632. begin
  34633. Exit;
  34634. end;
  34635. {$ENDIF}
  34636. case Msg.message of
  34637. WM_HSCROLL, WM_VSCROLL:
  34638. begin
  34639. Sender.Invalidate;
  34640. exit;
  34641. end;
  34642. WM_SETTEXT:
  34643. begin
  34644. if Sender.fIsStaticControl = 0 then exit;
  34645. Sender.Invalidate;
  34646. Rslt := DefWindowProc
  34647. ( Sender.fHandle, WM_SETTEXT, Msg.wParam, Msg.lParam );
  34648. Result := TRUE;
  34649. exit;
  34650. end;
  34651. WM_NCPAINT:
  34652. begin
  34653. if Sender.fTransparent then
  34654. Result := TRUE;
  34655. exit;
  34656. end;
  34657. end;
  34658. if Sender.fTransparent and (not Sender.fParent.fDoubleBuffered) then
  34659. Sender.fTransparent := FALSE;
  34660. if not (Sender.fTransparent or Sender.fDoubleBuffered) then exit;
  34661. if Sender.fSelfRequirePaint then exit;
  34662. case Msg.message of
  34663. WM_ERASEBKGND:
  34664. begin
  34665. Result := TRUE;
  34666. end;
  34667. WM_PAINT:
  34668. begin
  34669. ValidateRect(Sender.fHandle, nil); //???--brandys???
  34670. if (Sender.fTransparent) and (not Sender.fParentRequirePaint) then begin
  34671. InvalidateRect(Sender.fParent.Handle, nil, FALSE);
  34672. Result := TRUE;
  34673. exit;
  34674. end;
  34675. GetClientRect(Msg.hwnd, Margins);
  34676. OLDp := 0;
  34677. if not Sender.fParentRequirePaint then begin
  34678. Sender.fDblExcludeRgn := CreateRectRgn(0, 0, Margins.Right, Margins.Bottom);
  34679. DC := GetDC(0);
  34680. PDC := CreateCompatibleDC( DC );
  34681. OLDp := SelectObject(PDC,
  34682. CreateCompatibleBitmap(DC, Margins.Right, Margins.Bottom) );
  34683. ReleaseDC(0, DC);
  34684. Sender.fParentCoordX := 0;
  34685. Sender.fParentCoordy := 0;
  34686. end else begin
  34687. PDC := Msg.wParam;
  34688. Sender.fDblExcludeRgn := Sender.fParent.fDblExcludeRgn;
  34689. end;
  34690. Sender.fSelfRequirePaint := TRUE;
  34691. Sender.fPaintDC := PDC;
  34692. if (not Sender.fParentRequirePaint) or Sender.fDoubleBuffered then
  34693. Sender.Perform(WM_ERASEBKGND, PDC, 0);
  34694. Sender.Perform(WM_PAINT, PDC, 0);
  34695. Wnd := GetWindow( Sender.fHandle, GW_CHILD );
  34696. Wnd := GetWindow( Wnd, GW_HWNDLAST);
  34697. while Wnd <> 0 do begin
  34698. if IsWindowVisible(Wnd) then begin
  34699. {$IFDEF USE_PROP}
  34700. C := Pointer( GetProp( Wnd, ID_SELF ) );
  34701. {$ELSE}
  34702. C := Pointer( GetWindowLong( Wnd, GWL_USERDATA ) );
  34703. {$ENDIF}
  34704. with C{-}^{+} do begin
  34705. if (C <> nil) and (fTransparent or fDoubleBuffered) then begin
  34706. Save := SaveDC( PDC );
  34707. fParentRequirePaint := TRUE;
  34708. L := Sender.fParentCoordX + Left;
  34709. T := Sender.fParentCoordY + Top;
  34710. SetWindowOrgEx(PDC, -L, -T, nil);
  34711. SendMessage(Wnd, WM_PRINT, PDC, PRF_NONCLIENT);
  34712. TP.x := 0; TP.Y := 0;
  34713. ClientToScreen(fHandle, TP);
  34714. GetWindowRect(fHandle, TR);
  34715. fParentCoordX := L + TP.X - TR.Left;
  34716. fParentCoordY := T + TP.Y - TR.Top;
  34717. SetWindowOrgEx(PDC, -fParentCoordX, -fParentCoordY, nil);
  34718. GetClientRect(Wnd, TR);
  34719. IntersectClipRect(PDC, 0, 0, TR.Right, TR.Bottom);
  34720. SendMessage(Wnd, WM_PAINT, PDC, 0);
  34721. fParentRequirePaint := FALSE;
  34722. RestoreDC( PDC, Save );
  34723. end else begin
  34724. GetWindowRect(Wnd, TR);
  34725. TP.X := 0; TP.Y := 0;
  34726. ClientToScreen(Sender.fHandle, TP);
  34727. TP.X := TR.Left - TP.X + Sender.fParentCoordX;
  34728. TP.Y := TR.Top - TP.Y + Sender.fParentCoordY;
  34729. TR.Left := TR.Right - TR.Left;
  34730. TR.Top := TR.Bottom - TR.Top;
  34731. tRgn := CreateRectRgn(TP.X, TP.Y, TP.X+TR.Left, TP.Y+TR.Top);
  34732. CombineRgn(Sender.fDblExcludeRgn, Sender.fDblExcludeRgn, tRgn, RGN_DIFF);
  34733. DeleteObject(tRgn);
  34734. end;
  34735. end;
  34736. end;
  34737. Wnd := GetWindow( Wnd, GW_HWNDPREV );
  34738. end;
  34739. Sender.fPaintDC := 0;
  34740. Sender.fSelfRequirePaint := FALSE;
  34741. if not Sender.fParentRequirePaint then begin
  34742. BLTDC := GetWindowDC(Sender.fHandle);
  34743. GetWindowRect( Sender.fHandle, TR );
  34744. ParentClient.x := 0; ParentClient.y := 0;
  34745. ClientToScreen( Sender.fHandle, ParentClient );
  34746. SetWindowOrgEx(BLTDC, TR.Left - ParentClient.x, TR.Top - ParentClient.y, nil);
  34747. OffsetRgn(Sender.fDblExcludeRgn, ParentClient.x - TR.Left, ParentClient.y - TR.Top);
  34748. ExtSelectClipRgn(BLTDC, Sender.fDblExcludeRgn, RGN_AND);
  34749. BitBlt( BLTDC, 0, 0, Margins.Right, Margins.Bottom, PDC, 0, 0, SRCCOPY );
  34750. ReleaseDC(Sender.fHandle, BLTDC);
  34751. DeleteObject(SelectObject( PDC, OLDp ));
  34752. DeleteObject(Sender.fDblExcludeRgn);
  34753. DeleteDC( PDC );
  34754. end;
  34755. //ValidateRect(Sender.fHandle, nil); //???++brandys???//
  34756. Result := TRUE;
  34757. end;
  34758. end;
  34759. end;
  34760. {$ELSE NEW_TRANSPARENT} // by Alexander Karpinsky a.k.a. homm
  34761. function WndProcTransparent( Sender: PControl; var Msg: TMsg;
  34762. var Rslt: Integer ): Boolean;
  34763. function SetRectRgnInderect(tRgn: HRGN; const TR: TRect): BOOL;
  34764. begin
  34765. Result := SetRectRgn(tRgn, TR.Left, TR.Top, TR.Right, TR.Bottom);
  34766. end;
  34767. var
  34768. DC, PDC, BLTDC: HDC;
  34769. Save: integer;
  34770. OLDp: THANDLE;
  34771. L, T: SmallInt;
  34772. TP: TPoint;
  34773. TR, Margins: TRect;
  34774. Wnd: HWND;
  34775. C: PControl;
  34776. ChildRgn: HRGN;
  34777. PS: TPaintStruct;
  34778. begin
  34779. Result := FALSE;
  34780. {$IFDEF STOP_WNDPROCTRANSPARENT_AFTER_APPLETTERMINATED}
  34781. if AppletTerminated or not Sender.ToBeVisible then
  34782. begin
  34783. Exit;
  34784. end;
  34785. {$ENDIF}
  34786. if Sender.fTransparent and (not Sender.fParent.fDoubleBuffered) then
  34787. Sender.fTransparent := FALSE;
  34788. if not (Sender.fTransparent or Sender.fDoubleBuffered) then exit;
  34789. case Msg.message of
  34790. WM_HSCROLL, WM_VSCROLL:
  34791. begin
  34792. Sender.Invalidate;
  34793. exit;
  34794. end;
  34795. WM_SETTEXT:
  34796. begin
  34797. if Sender.fIsStaticControl = 0 then exit;
  34798. Sender.Invalidate;
  34799. Rslt := DefWindowProc ( Sender.fHandle, WM_SETTEXT, Msg.wParam, Msg.lParam );
  34800. Result := TRUE;
  34801. exit;
  34802. end;
  34803. WM_PAINT,
  34804. WM_ERASEBKGND:;
  34805. WM_NCPAINT:
  34806. if not Sender.fTransparent then
  34807. exit;
  34808. else exit;
  34809. end;
  34810. if Sender.fSelfRequirePaint then begin
  34811. exit;
  34812. end;
  34813. Result := TRUE;
  34814. if Sender.fTransparent and (not Sender.fParentRequirePaint) then
  34815. begin
  34816. TR := Sender.BoundsRect;
  34817. InvalidateRect(Sender.fParent.fHandle, @TR, true);
  34818. ValidateRect(Sender.fHandle, nil); //???--brandys???+
  34819. exit;
  34820. end;
  34821. if Msg.message = WM_PAINT then begin
  34822. OLDp := 0;
  34823. if not Sender.fParentRequirePaint then begin
  34824. Sender.fDblExcludeRgn := CreateRectRgn(0, 0, 0, 0);
  34825. if GetUpdateRgn(Sender.fHandle, Sender.fDblExcludeRgn, TRUE) <= NULLREGION then
  34826. begin
  34827. DeleteObject(Sender.fDblExcludeRgn);
  34828. exit;
  34829. end;
  34830. DC := BeginPaint(Sender.fHandle, PS);
  34831. PDC := CreateCompatibleDC( DC );
  34832. GetClientRect(Msg.hwnd, Margins);
  34833. OLDp := SelectObject(PDC, CreateCompatibleBitmap(DC, Margins.Right, Margins.Bottom) );
  34834. Sender.fParentCoordX := 0;
  34835. Sender.fParentCoordy := 0;
  34836. end else begin
  34837. PDC := Msg.wParam;
  34838. Sender.fDblExcludeRgn := Sender.fParent.fDblExcludeRgn;
  34839. end;
  34840. Sender.fSelfRequirePaint := TRUE;
  34841. Sender.fPaintDC := PDC;
  34842. if (not Sender.fParentRequirePaint) or Sender.fDoubleBuffered then
  34843. Sender.Perform(WM_ERASEBKGND, PDC, 0);
  34844. Sender.Perform(WM_PAINT, PDC, 0);
  34845. Wnd := GetWindow( Sender.fHandle, GW_CHILD );
  34846. Wnd := GetWindow( Wnd, GW_HWNDLAST);
  34847. while Wnd <> 0 do begin
  34848. if IsWindowVisible(Wnd) then begin
  34849. ChildRgn := CreateRectRgn(0, 0, 0, 0);
  34850. if GetWindowRgn(WND, ChildRgn) <= NULLREGION then begin
  34851. GetWindowRect(WND, TR);
  34852. TP.X := 0; TP.Y := 0;
  34853. ClientToScreen(Sender.fHandle, TP);
  34854. OffsetRect(TR, -TP.X , -TP.Y);
  34855. SetRectRgnInderect(ChildRgn, TR);
  34856. end;
  34857. OffsetRgn(ChildRgn, Sender.fParentCoordX, Sender.fParentCoordY);
  34858. {$IFDEF USE_PROP}
  34859. C := Pointer( GetProp( Wnd, ID_SELF ) );
  34860. {$ELSE}
  34861. C := Pointer( GetWindowLong( Wnd, GWL_USERDATA ) );
  34862. {$ENDIF}
  34863. if CombineRgn(ChildRgn, ChildRgn, Sender.fDblExcludeRgn, RGN_AND) >= SIMPLEREGION then begin
  34864. with C{-}^{+} do begin
  34865. if (C <> nil) and fTransparent then begin
  34866. Save := SaveDC( PDC );
  34867. fParentRequirePaint := TRUE;
  34868. L := Sender.fParentCoordX + Left;
  34869. T := Sender.fParentCoordY + Top;
  34870. SetWindowOrgEx(PDC, -L, -T, nil);
  34871. SendMessage(Wnd, WM_PRINT, PDC, PRF_NONCLIENT);
  34872. TP.x := 0; TP.Y := 0;
  34873. ClientToScreen(fHandle, TP);
  34874. GetWindowRect(fHandle, TR);
  34875. fParentCoordX := L + TP.X - TR.Left;
  34876. fParentCoordY := T + TP.Y - TR.Top;
  34877. SetWindowOrgEx(PDC, -fParentCoordX, -fParentCoordY, nil);
  34878. GetClientRect(Wnd, TR);
  34879. IntersectClipRect(PDC, 0, 0, TR.Right, TR.Bottom);
  34880. SendMessage(Wnd, WM_PAINT, PDC, 0);
  34881. fParentRequirePaint := FALSE;
  34882. RestoreDC( PDC, Save );
  34883. end else begin
  34884. CombineRgn(Sender.fDblExcludeRgn, Sender.fDblExcludeRgn, ChildRgn, RGN_DIFF);
  34885. end;
  34886. end;
  34887. end; // if Save >= SIMPLEREGION then begin
  34888. DeleteObject(ChildRgn);
  34889. end;
  34890. Wnd := GetWindow( Wnd, GW_HWNDPREV );
  34891. end;
  34892. Sender.fPaintDC := 0;
  34893. Sender.fSelfRequirePaint := FALSE;
  34894. if not Sender.fParentRequirePaint then begin
  34895. BLTDC := GetDCEx(Sender.fHandle, 0, DCX_CACHE or DCX_CLIPSIBLINGS);
  34896. ExtSelectClipRgn(BLTDC, Sender.fDblExcludeRgn, RGN_AND);
  34897. BitBlt(BLTDC, 0, 0, Margins.Right, Margins.Bottom, PDC, 0, 0, SRCCOPY );
  34898. ReleaseDC(Sender.fHandle, BLTDC);
  34899. DeleteObject(SelectObject( PDC, OLDp ));
  34900. DeleteObject(Sender.fDblExcludeRgn);
  34901. DeleteDC( PDC );
  34902. EndPaint(Sender.fHandle, PS);
  34903. end;
  34904. end;
  34905. end;
  34906. {$ENDIF}
  34907. //[END WndProcTransparent]
  34908. {$endif win32}
  34909. //[FUNCTION WndProcPaint]
  34910. {$IFDEF ASM_noVERSION}
  34911. function WndProcPaint( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  34912. const szPaintStruct = sizeof(TPaintStruct);
  34913. asm
  34914. CMP word ptr [EDX].TMsg.message, WM_PRINT
  34915. JE @@print
  34916. CMP word ptr [EDX].TMsg.message, WM_PAINT
  34917. JNE @@ret_false
  34918. @@print:
  34919. CMP word ptr [EAX].TControl.fOnPaint.TMethod.Code+2, 0
  34920. JE @@ret_false
  34921. PUSH EBX
  34922. PUSH ESI
  34923. XCHG EBX, EAX
  34924. MOV ESI, EDX
  34925. XOR EAX, EAX
  34926. PUSH ECX
  34927. PUSH EAX
  34928. PUSH EAX
  34929. PUSH EAX
  34930. PUSH EAX
  34931. CALL CreateRectRgn
  34932. MOV [EBX].TControl.fUpdRgn, EAX
  34933. MOVSX EDX, [EBX].TControl.fEraseUpdRgn
  34934. PUSH EDX
  34935. PUSH EAX
  34936. PUSH [EBX].TControl.fHandle
  34937. CALL GetUpdateRgn
  34938. CMP EAX, 1
  34939. JA @@collectUpdRgn
  34940. XOR EAX, EAX
  34941. XCHG EAX, [EBX].TControl.fUpdRgn
  34942. PUSH EAX
  34943. CALL DeleteObject
  34944. @@collectUpdRgn:
  34945. MOV ECX, [EBX].TControl.fCollectUpdRgn
  34946. JECXZ @@asg_fPaintDC
  34947. XCHG EAX, ECX
  34948. MOV ECX, [EBX].TControl.fUpdRgn
  34949. JECXZ @@asg_fPaintDC
  34950. PUSH RGN_OR
  34951. PUSH ECX
  34952. PUSH EAX
  34953. PUSH EAX
  34954. CALL CombineRgn
  34955. DEC EAX
  34956. JNZ @@invalidateRgn
  34957. ADD ESP, -16
  34958. PUSH ESP
  34959. PUSH [EBX].TControl.fHandle
  34960. CALL Windows.GetClientRect
  34961. PUSH [EBX].TControl.fCollectUpdRgn
  34962. CALL DeleteObject
  34963. CALL CreateRectRgn
  34964. MOV [EBX].TControl.fCollectUpdRgn, EAX
  34965. @@invalidateRgn:
  34966. MOVSX EDX, [EBX].TControl.fEraseUpdRgn
  34967. PUSH EDX
  34968. PUSH [EBX].TControl.fCollectUpdRgn
  34969. PUSH [EBX].TControl.fHandle
  34970. CALL InvalidateRgn
  34971. @@asg_fPaintDC:
  34972. MOV ECX, [ESI].TMsg.wParam
  34973. INC ECX
  34974. LOOP @@storePaintDC
  34975. ADD ESP, -szPaintStruct
  34976. PUSH ESP
  34977. PUSH [EBX].TControl.fHandle
  34978. CALL BeginPaint
  34979. XCHG ECX, EAX
  34980. @@storePaintDC:
  34981. MOV [EBX].TControl.fPaintDC, ECX
  34982. XCHG EAX, ECX
  34983. MOV ECX, [EBX].TControl.fCollectUpdRgn
  34984. JECXZ @@doOnPaint
  34985. PUSH ECX
  34986. PUSH EAX
  34987. CALL SelectClipRgn
  34988. @@doOnPaint:
  34989. MOV ECX, [EBX].TControl.fPaintDC
  34990. MOV EDX, EBX
  34991. MOV EAX, [EBX].TControl.fOnPaint.TMethod.Data
  34992. CALL dword ptr [EBX].TControl.fOnPaint.TMethod.Code
  34993. MOV ECX, [EBX].TControl.fCanvas
  34994. JECXZ @@e_paint
  34995. XCHG EAX, ECX
  34996. XOR EDX, EDX
  34997. CALL TCanvas.SetHandle
  34998. @@e_paint:
  34999. MOV ECX, [ESI].TMsg.wParam
  35000. INC ECX
  35001. LOOP @@zero_fPaintDC
  35002. PUSH ESP
  35003. PUSH [EBX].TControl.fHandle
  35004. CALL EndPaint
  35005. ADD ESP, szPaintStruct
  35006. @@zero_fPaintDC:
  35007. XOR ECX, ECX
  35008. MOV [EBX].TControl.fPaintDC, ECX
  35009. POP EAX
  35010. MOV [EAX], ECX
  35011. XCHG ECX, [EBX].TControl.fUpdRgn
  35012. JECXZ @@exit_True
  35013. PUSH ECX
  35014. CALL DeleteObject
  35015. @@exit_True:
  35016. POP ESI
  35017. POP EBX
  35018. MOV AL, 1
  35019. RET
  35020. @@ret_false:
  35021. XOR EAX, EAX
  35022. end;
  35023. {$ELSE ASM_VERSION} //Pascal
  35024. function WndProcPaint( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  35025. var PaintStruct: TPaintStruct;
  35026. Cplxity: Integer;
  35027. OldPaintDC: HDC;
  35028. begin
  35029. with Self_{-}^{+} do
  35030. case Msg.message of
  35031. //WM_PRINT,
  35032. WM_PAINT: if assigned( fOnPaint ) {or Assigned( fPaintProc )} then
  35033. begin
  35034. fUpdRgn := CreateRectRgn( 0, 0, 0, 0 );
  35035. Cplxity := Integer( GetUpdateRgn( fHandle, fUpdRgn, fEraseUpdRgn ) );
  35036. if (Cplxity = NULLREGION) or (Cplxity = ERROR) then
  35037. begin
  35038. DeleteObject( fUpdRgn );
  35039. fUpdRgn := 0;
  35040. end;
  35041. OldPaintDC := fPaintDC;
  35042. fPaintDC := Msg.wParam;
  35043. if fPaintDC = 0 then
  35044. fPaintDC := BeginPaint( fHandle, PaintStruct );
  35045. //if fUpdRgn <> 0 then added in v2.16
  35046. // SelectClipRgn( fPaintDC, fUpdRgn ); removed in v2.26
  35047. fOnPaint( Self_, fPaintDC );
  35048. if assigned( Self_.fCanvas ) then
  35049. Self_.fCanvas.SetHandle( 0 );
  35050. if Msg.wParam = 0 then
  35051. EndPaint( fHandle, PaintStruct );
  35052. fPaintDC := OldPaintDC;
  35053. Rslt := 0;
  35054. Result := True;
  35055. if fUpdRgn <> 0 then
  35056. DeleteObject( fUpdRgn );
  35057. fUpdRgn := 0;
  35058. Exit;
  35059. end;
  35060. end;
  35061. Result := FALSE;
  35062. end;
  35063. {$ENDIF ASM_VERSION}
  35064. //[END WndProcPaint]
  35065. {$ENDIF WIN_GDI}
  35066. //[procedure TControl.SetOnPaint]
  35067. {$IFDEF GDI}
  35068. procedure TControl.SetOnPaint( const Value: TOnPaint );
  35069. begin
  35070. fOnPaint := Value;
  35071. AttachProc( WndProcPaint );
  35072. end;
  35073. {$ENDIF GDI}
  35074. {$IFDEF _X_}
  35075. {$IFDEF GTK}
  35076. function expose_widget( Widget: PGtkWidget; Event: PGdkEventExpose;
  35077. Sender: PControl ): Boolean; cdecl;
  35078. begin
  35079. if not Assigned( Sender.fOnPaint ) then Result := FALSE
  35080. else
  35081. begin
  35082. Sender.Canvas.SaveState;
  35083. Sender.fOnPaint( Sender, Sender.Canvas.Handle );
  35084. Sender.Canvas.RestoreState;
  35085. Result := TRUE;
  35086. end;
  35087. end;
  35088. procedure TControl.SetOnPaint( const Value: TOnPaint );
  35089. begin
  35090. fOnPaint := Value;
  35091. {$IFNDEF SMALLER_CODE} // it is actually not necessary to disconnect, event
  35092. // still will be fired but fOnPaint is not assigned
  35093. // so FALSE will be returned to GTK.
  35094. if not Assigned( Value ) then
  35095. gtk_signal_disconnect( fHandle, fExposeEvent )
  35096. else
  35097. {$ENDIF}
  35098. fExposeEvent := gtk_signal_connect( GTK_OBJECT( fHandle ), 'expose_event',
  35099. @ expose_widget, @ Self );
  35100. end;
  35101. {$ENDIF GTK}
  35102. {$ENDIF _X_}
  35103. {$IFDEF WIN_GDI}
  35104. //*
  35105. //[function WndProcEraseBkgnd]
  35106. function WndProcEraseBkgnd( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  35107. var PaintStruct: TPaintStruct;
  35108. OldPaintDC: HDC;
  35109. begin
  35110. Result := FALSE;
  35111. if Msg.message = WM_ERASEBKGND then
  35112. begin
  35113. if Assigned( Sender.OnEraseBkgnd ) then
  35114. begin
  35115. OldPaintDC := Sender.fPaintDC;
  35116. Sender.fPaintDC := Msg.wParam;
  35117. if Sender.fPaintDC = 0 then
  35118. Sender.fPaintDC := BeginPaint( Sender.fHandle, PaintStruct );
  35119. Sender.OnEraseBkgnd( Sender, Msg.wParam );
  35120. if Msg.wParam = 0 then
  35121. EndPaint( Sender.fHandle, PaintStruct );
  35122. if Assigned( Sender.fCanvas ) then
  35123. Sender.fCanvas.SetHandle( 0 );
  35124. Sender.fPaintDC := OldPaintDC;
  35125. Rslt := 0;
  35126. Result := TRUE;
  35127. end
  35128. else
  35129. Rslt := 0;
  35130. end;
  35131. end;
  35132. //[procedure TControl.SetOnEraseBkgnd]
  35133. procedure TControl.SetOnEraseBkgnd(const Value: TOnPaint);
  35134. begin
  35135. fOnEraseBkgnd := Value;
  35136. AttachProc( WndProcEraseBkgnd );
  35137. end;
  35138. procedure DummyPaintClear( Self_: PControl; Sender: PControl; DC: HDC );
  35139. begin
  35140. Sender.Canvas.FillRect( Sender.ClientRect );
  35141. end;
  35142. {$IFDEF NEW_GRADIENT}
  35143. function WndProcGradient( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  35144. var PaintStruct: TPaintStruct;
  35145. Bmp: PBitmap;
  35146. CR: TRect;
  35147. I: Integer;
  35148. R, G, B: Integer;
  35149. R1, G1, B1: Integer;
  35150. C: TColor;
  35151. W, H, WH: Integer;
  35152. OldPaintDC: HDC;
  35153. Pattern: PBitmap;
  35154. pdc: HDC;
  35155. pw: integer;
  35156. begin
  35157. case Msg.message of
  35158. WM_PAINT, WM_PRINTCLIENT:
  35159. begin
  35160. result := false;
  35161. CR := Self_.ClientRect;
  35162. case Self_.fGradientStyle of
  35163. gsHorizontal: begin
  35164. W := CR.Right;
  35165. H := 1;
  35166. WH := W;
  35167. pw := 32;
  35168. end;
  35169. gsVertical: begin
  35170. W := 1;
  35171. H := CR.Bottom;
  35172. WH := H;
  35173. pw := 32
  35174. end;
  35175. gsTopToBottom,
  35176. gsBottomToTop: begin
  35177. W := CR.Bottom + CR.Right;
  35178. H := 1;
  35179. WH := W;
  35180. pw := 1 + (CR.Bottom div 16);
  35181. if pw > 6 then
  35182. pw := 6;
  35183. end;
  35184. else exit;
  35185. // <-- impartant if user change GradientStyle to not supported by this object
  35186. end;
  35187. OldPaintDC := Self_.fPaintDC;
  35188. Self_.fPaintDC := Msg.wParam;
  35189. if Self_.fPaintDC = 0 then
  35190. Self_.fPaintDC := BeginPaint( Self_.fHandle, PaintStruct );
  35191. Bmp := NewDIBBitmap( W, H, pf24bit );
  35192. C := Color2RGB( Self_.fColor1 );
  35193. R := C shr 16;
  35194. G := (C shr 8) and $FF;
  35195. B := C and $FF;
  35196. C := Color2RGB( Self_.fColor2 );
  35197. R1 := C shr 16;
  35198. G1 := (C shr 8) and $FF;
  35199. B1 := C and $FF;
  35200. for I := 0 to WH-1 do begin
  35201. C := (( R + (R1 - R) * I div WH ) shl 16) or
  35202. (( G + (G1 - G) * I div WH ) shl 8) or
  35203. ( B + (B1 - B) * I div WH );
  35204. if Self_.fGradientStyle = gsVertical then
  35205. Bmp.DIBPixels[ 0, I ] := C
  35206. else
  35207. Bmp.DIBPixels[ I, 0 ] := C;
  35208. end;
  35209. if Self_.fGradientStyle = gsVertical then
  35210. Pattern := NewBitMap(pw, H)
  35211. else
  35212. Pattern := NewBitMap(W, pw);
  35213. pdc := Pattern.Canvas.Handle;
  35214. SetStretchBltMode( pdc, HALFTONE);
  35215. SetBrushOrgEx( pdc, 0, 0, nil );
  35216. StretchBlt( pdc, 0, 0, Pattern.Width, Pattern.Height, Bmp.Canvas.Handle,
  35217. 0, 0, W, H, SRCCOPY );
  35218. case Self_.fGradientStyle of
  35219. gsHorizontal: for i := 0 to (CR.Bottom div pw) do
  35220. Pattern.Draw(Self_.fPaintDC, 0, i*pw);
  35221. gsVertical: for i := 0 to (CR.Right div pw) do
  35222. Pattern.Draw(Self_.fPaintDC, i*pw, 0);
  35223. gsTopToBottom: for i := 0 to ((CR.Bottom + pw -1) div pw)-1 do
  35224. Pattern.Draw(Self_.fPaintDC, -i*pw, i*pw);
  35225. gsBottomToTop: for i := 0 to ((CR.Bottom + pw -1) div pw)-1 do
  35226. Pattern.Draw(Self_.fPaintDC, -CR.Bottom + i*pw, i*pw);
  35227. end;
  35228. Bmp.Free;
  35229. Pattern.Free;
  35230. if TMethod( Self_.fOnPaint2 ).Code = @ DummyPaintClear then
  35231. Self_.fOnPaint2 := TOnPaint( MakeMethod( nil, @ DummyPaintProc ) );
  35232. if Assigned( Self_.fOnPaint ) then
  35233. Self_.fOnPaint( Self_, Self_.fPaintDC );
  35234. if Msg.wParam = 0 then
  35235. EndPaint( Self_.fHandle, PaintStruct );
  35236. Self_.fPaintDC := OldPaintDC;
  35237. Rslt := 0;
  35238. Result := True;
  35239. Exit;
  35240. end;
  35241. end;
  35242. Result := False;
  35243. end;
  35244. {$ELSE OLD_GRADIENT}
  35245. function WndProcGradient( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  35246. var PaintStruct: TPaintStruct;
  35247. CR: TRect;
  35248. I, R, G, B, R1, G1, B1, W, H, WH: Integer;
  35249. C: TColor;
  35250. {$ifdef win32}
  35251. W9x: Boolean;
  35252. Bmp: PBitmap;
  35253. {$endif win32}
  35254. Br: HBrush;
  35255. OldPaintDC: HDC;
  35256. begin
  35257. case Msg.message of
  35258. WM_PAINT, WM_PRINTCLIENT:
  35259. begin
  35260. OldPaintDC := Self_.fPaintDC;
  35261. Self_.fPaintDC := Msg.wParam;
  35262. if Self_.fPaintDC = 0 then
  35263. Self_.fPaintDC := BeginPaint( Self_.fHandle, PaintStruct );
  35264. CR := Self_.ClientRect;
  35265. {$ifdef win32}
  35266. W9x := WinVer < wvNT;
  35267. Bmp := nil;
  35268. {$endif win32}
  35269. W := 1;
  35270. H := CR.Bottom;
  35271. WH := H;
  35272. if Self_.fGradientStyle = gsHorizontal then
  35273. begin
  35274. W := CR.Right;
  35275. H := 1;
  35276. WH := W;
  35277. end;
  35278. {$ifdef win32}
  35279. if not W9x then
  35280. Bmp := NewDIBBitmap( W, H, pf32bit );
  35281. {$endif win32}
  35282. C := Color2RGB( Self_.fColor1 );
  35283. R := C shr 16;
  35284. G := (C shr 8) and $FF;
  35285. B := C and $FF;
  35286. C := Color2RGB( Self_.fColor2 );
  35287. R1 := C shr 16;
  35288. G1 := (C shr 8) and $FF;
  35289. B1 := C and $FF;
  35290. for I := 0 to WH-1 do
  35291. begin
  35292. C := ((( R + (R1 - R) * I div WH ) and $FF) shl 16) or
  35293. ((( G + (G1 - G) * I div WH ) and $FF) shl 8) or
  35294. ( B + (B1 - B) * I div WH ) and $FF;
  35295. {$ifdef win32}
  35296. if W9x then
  35297. {$endif win32}
  35298. begin
  35299. if Self_.fGradientStyle <> gsHorizontal then
  35300. CR.Bottom := CR.Top + 1
  35301. else
  35302. CR.Right := CR.Left + 1;
  35303. Br := CreateSolidBrush( C );
  35304. Windows.FillRect( Self_.fPaintDC, CR, Br );
  35305. DeleteObject( Br );
  35306. if Self_.fGradientStyle <> gsHorizontal then
  35307. Inc( CR.Top )
  35308. else
  35309. Inc( CR.Left );
  35310. end
  35311. {$ifdef win32}
  35312. else
  35313. begin
  35314. if Self_.fGradientStyle <> gsHorizontal then
  35315. Bmp.DIBPixels[ 0, I ] := C
  35316. else
  35317. Bmp.DIBPixels[ I, 0 ] := C;
  35318. end;
  35319. {$endif win32}
  35320. end;
  35321. {$ifdef win32}
  35322. if not W9x then
  35323. begin
  35324. SetStretchBltMode( Self_.fPaintDC, HALFTONE );
  35325. SetBrushOrgEx( Self_.fPaintDC, 0, 0, nil );
  35326. StretchBlt( Self_.fPaintDC, 0, 0, CR.Right, CR.Bottom, Bmp.Canvas.Handle,
  35327. 0, 0, W, H, SRCCOPY );
  35328. Bmp.Free;
  35329. end;
  35330. {$endif win32}
  35331. if TMethod( Self_.fOnPaint2 ).Code = @ DummyPaintClear then
  35332. Self_.fOnPaint2 := TOnPaint( MakeMethod( nil, @ DummyPaintProc ) );
  35333. if Assigned( Self_.fOnPaint ) then
  35334. Self_.fOnPaint( Self_, Self_.fPaintDC );
  35335. if Msg.wParam = 0 then
  35336. EndPaint( Self_.fHandle, PaintStruct );
  35337. Self_.fPaintDC := OldPaintDC;
  35338. Rslt := 0;
  35339. Result := True;
  35340. Exit;
  35341. end;
  35342. end;
  35343. Result := False;
  35344. end;
  35345. {$ENDIF OLD_GRADIENT}
  35346. //[END WndProcGradient]
  35347. //[function WndProcGradientEx]
  35348. function WndProcGradientEx( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  35349. function Ceil( X: Double ): Integer;
  35350. begin
  35351. Result := Round( X ) {+ 1};
  35352. //if X > 0 then dec( Result ) else inc( Result );
  35353. end;
  35354. const
  35355. SQRT2 = 1.4142135623730950488016887242097;
  35356. var
  35357. RC, R0: TRect;
  35358. C, C2: TColor;
  35359. R1, G1, B1: Integer;
  35360. R2, G2, B2: Integer;
  35361. DX1, DX2, DY1, DY2, DR, DG, DB, K: Double;
  35362. PaintStruct: TPaintStruct;
  35363. I: Integer;
  35364. Br: HBrush;
  35365. Rgn: HRgn;
  35366. {$ifdef win32}
  35367. Poly: array[ 0..3 ] of TPoint;
  35368. {$endif win32}
  35369. OldPaintDC: HDC;
  35370. fX1, fX2, fY1, fY2: Double;
  35371. procedure OffsetF( DX, DY: Double );
  35372. begin
  35373. fX1 := fX1 + DX;
  35374. fX2 := fX2 + DX;
  35375. fY1 := fY1 + DY;
  35376. fY2 := fY2 + DY;
  35377. end;
  35378. begin
  35379. Result := FALSE;
  35380. if (Msg.message <> WM_PAINT) and (Msg.message <> WM_PRINTCLIENT) then Exit;
  35381. if Self_.fGradientStyle in [ gsHorizontal, gsVertical ] then
  35382. begin
  35383. Result := WndProcGradient( Self_, Msg, Rslt );
  35384. Exit;
  35385. end;
  35386. C := Color2RGB( Self_.fColor2 );
  35387. R2 := C and $FF;
  35388. G2 := (C shr 8) and $FF;
  35389. B2 := (C shr 16) and $FF;
  35390. C := Color2RGB( Self_.fColor1 );
  35391. R1 := C and $FF;
  35392. G1 := (C shr 8) and $FF;
  35393. B1 := (C shr 16) and $FF;
  35394. DR := (R2 - R1) / 256;
  35395. DG := (G2 - G1) / 256;
  35396. DB := (B2 - B1) / 256;
  35397. OldPaintDC := Self_.fPaintDC;
  35398. Self_.fPaintDC := Msg.wParam;
  35399. if Self_.fPaintDC = 0 then
  35400. Self_.fPaintDC := BeginPaint( Self_.fHandle, PaintStruct );
  35401. RC := Self_.ClientRect;
  35402. fX1 := 0;
  35403. fY1 := 0;
  35404. case Self_.fGradientStyle of
  35405. gsRombic:
  35406. begin
  35407. fX2 := RC.Right / 128;
  35408. fY2 := RC.Bottom / 128;
  35409. end;
  35410. gsElliptic:
  35411. begin
  35412. fX2 := RC.Right / 256 * SQRT2;
  35413. fY2 := RC.Bottom / 256 * SQRT2;
  35414. end;
  35415. else
  35416. begin
  35417. fX2 := RC.Right / 256;
  35418. fY2 := RC.Bottom / 256;
  35419. end;
  35420. end;
  35421. case Self_.fGradientStyle of
  35422. gsRectangle, gsRombic, gsElliptic:
  35423. begin
  35424. case Self_.FGradientLayout of
  35425. glCenter, glTop, glBottom:
  35426. OffsetF( (RC.Right - fX2) / 2, 0 );
  35427. glTopRight, glBottomRight, glRight:
  35428. OffsetF( RC.Right - fX2 / 2, 0 );
  35429. glTopLeft, glBottomLeft, glLeft:
  35430. OffsetF( -fX2 / 2, 0 );
  35431. end;
  35432. case Self_.FGradientLayout of
  35433. glCenter, glLeft, glRight:
  35434. OffsetF( 0, (RC.Bottom - fY2) / 2 );
  35435. glBottom, glBottomLeft, glBottomRight:
  35436. OffsetF( 0, RC.Bottom - fY2 / 2 );
  35437. glTop, glTopLeft, glTopRight:
  35438. OffsetF( 0, -fY2 / 2 )
  35439. end;
  35440. end;
  35441. end;
  35442. DX1 := -fX1 / 255; //(-RF.Left) / 255;
  35443. DY1 := -fY1 / 255; // (-RF.Top) / 255;
  35444. DX2 := (RC.Right - fX2) / 255; //(RC.Right - RF.Right) / 255;
  35445. DY2 := (RC.Bottom - fY2) / 255;
  35446. case Self_.fGradientStyle of
  35447. gsRombic, gsElliptic:
  35448. begin
  35449. if DX2 < -DX1 then DX2 := -DX1;
  35450. if DY2 < -DY1 then DY2 := -DY1;
  35451. K := 2;
  35452. if Self_.fGradientStyle = gsElliptic then K := SQRT2;
  35453. DX2 := DX2 * K;
  35454. DY2 := DY2 * K;
  35455. DX1 := -DX2;
  35456. DY1 := -DY2;
  35457. end;
  35458. end;
  35459. C2 := C;
  35460. for I := 0 to 255 do
  35461. begin
  35462. if (I < 255) then
  35463. begin
  35464. C2 := TColor( (( Ceil( B1 + DB * (I+1) ) and $FF) shl 16) or
  35465. (( Ceil( G1 + DG * (I+1) ) and $FF) shl 8) or
  35466. Ceil( R1 + DR * (I+1) ) and $FF );
  35467. if (Self_.fGradientStyle in [gsRombic,gsElliptic,gsRectangle]) and
  35468. (C2 = C) then continue;
  35469. end;
  35470. Br := CreateSolidBrush( C );
  35471. R0 := MakeRect( Ceil( fX1 + DX1 * I ),
  35472. Ceil( fY1 + DY1 * I ),
  35473. Ceil( fX2 + DX2 * I ) + 1,
  35474. Ceil( fY2 + DY2 * I ) + 1 );
  35475. Rgn := 0;
  35476. {$ifdef wince}
  35477. Rgn := CreateRectRgnIndirect( R0 );
  35478. {$else}
  35479. case Self_.fGradientStyle of
  35480. gsRectangle:
  35481. Rgn := CreateRectRgnIndirect( R0 );
  35482. gsRombic:
  35483. begin
  35484. Poly[ 0 ].x := R0.Left;
  35485. Poly[ 0 ].y := R0.Top + (R0.Bottom - R0.Top) div 2;
  35486. Poly[ 1 ].x := R0.Left + (R0.Right - R0.Left) div 2;
  35487. Poly[ 1 ].y := R0.Top;
  35488. Poly[ 2 ].x := R0.Right;
  35489. Poly[ 2 ].y := Poly[ 0 ].y;
  35490. Poly[ 3 ].x := Poly[ 1 ].x;
  35491. Poly[ 3 ].y := R0.Bottom;
  35492. Rgn := CreatePolygonRgn( Poly[ 0 ].x, 4, ALTERNATE );
  35493. end;
  35494. gsElliptic:
  35495. Rgn := CreateEllipticRgnIndirect( R0 );
  35496. end;
  35497. {$endif wince}
  35498. if Rgn <> 0 then
  35499. begin
  35500. if Rgn <> NULLREGION then
  35501. begin
  35502. Windows.FillRgn( Self_.fPaintDC, Rgn, Br );
  35503. {$ifdef win32}
  35504. ExtSelectClipRgn( Self_.fPaintDC, Rgn, RGN_DIFF );
  35505. {$endif win32}
  35506. end;
  35507. DeleteObject( Rgn );
  35508. end;
  35509. DeleteObject( Br );
  35510. C := C2;
  35511. end;
  35512. if TMethod( Self_.fOnPaint2 ).Code = @ DummyPaintClear then
  35513. Self_.fOnPaint2 := TOnPaint( MakeMethod( nil, @ DummyPaintProc ) );
  35514. if Assigned( Self_.fOnPaint ) then
  35515. Self_.fOnPaint( Self_, Self_.fPaintDC );
  35516. if Self_.fPaintDC <> HDC( Msg.wParam ) then
  35517. EndPaint( Self_.fHandle, PaintStruct );
  35518. Self_.fPaintDC := OldPaintDC;
  35519. Rslt := 0;
  35520. Result := True;
  35521. end;
  35522. //*
  35523. //[function WndProcLabelEffect]
  35524. function WndProcLabelEffect( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  35525. var
  35526. Sz: TSize;
  35527. P0: TPoint;
  35528. CR: TRect;
  35529. B : Boolean;
  35530. CShadow: TColor;
  35531. Target: PCanvas;
  35532. Txt: KOLString;
  35533. //LCaption: PKOLChar;
  35534. OldPaintDC: HDC;
  35535. procedure doTextOut( shfx, shfy: Integer; col: TColor );
  35536. begin
  35537. SetTextColor( Target.fHandle, col );
  35538. Windows.
  35539. {$IFDEF UNICODE_CTRLS}
  35540. ExtTextOutW
  35541. {$ELSE}
  35542. ExtTextOut
  35543. {$ENDIF}
  35544. ( Target.fHandle, P0.x + shfx, P0.y + shfy,
  35545. ETO_CLIPPED, @CR,
  35546. PKOLChar(Txt), Length(Txt), nil );
  35547. //GDIFlush; // for test only
  35548. end;
  35549. var I, J, Istp : Integer;
  35550. PS: TPaintStruct;
  35551. //DoEndPaint: Boolean;
  35552. begin
  35553. Result := False;
  35554. case Msg.message of
  35555. WM_SETTEXT:
  35556. begin
  35557. Self_.fCaption := PKOLChar( Msg.lParam );
  35558. Result := True;
  35559. Rslt := 1;
  35560. Exit;
  35561. end;
  35562. WM_PRINTCLIENT, WM_PAINT:
  35563. begin
  35564. OldPaintDC := Self_.fPaintDC;
  35565. Self_.fPaintDC := Msg.wParam;
  35566. if Self_.fPaintDC = 0 then
  35567. Self_.fPaintDC := BeginPaint( Self_.fHandle, PS );
  35568. begin
  35569. Target := Self_.Canvas;
  35570. Txt := Self_.fCaption;
  35571. Target.TextArea( Txt, Sz, P0 );
  35572. if Self_.fShadowDeep <> 0 then
  35573. begin
  35574. for B := False to Self_.fCtl3D do
  35575. begin
  35576. Inc( Sz.cx, Abs( Self_.fShadowDeep ) );
  35577. Inc( Sz.cy, Abs( Self_.fShadowDeep ) );
  35578. end;
  35579. end;
  35580. CR := Self_.ClientRect;
  35581. case Self_.fTextAlign of
  35582. taCenter: P0.x := P0.x + (CR.Right - Sz.cx) div 2;
  35583. taRight: P0.x := P0.x + (CR.Right - Sz.cx);
  35584. end;
  35585. case Self_.fVerticalAlign of
  35586. vaCenter: P0.y := P0.y + (CR.Bottom - Sz.cy) div 2;
  35587. vaBottom: P0.y := P0.y + (CR.Bottom - Sz.cy);
  35588. end;
  35589. if Self_.fShadowDeep <> 0 then
  35590. begin
  35591. if Self_.fColor2 = clNone then
  35592. CShadow := ColorsMix(Color2RGB(Self_.fTextColor),Color2RGB(Self_.fColor2))
  35593. else
  35594. CShadow := Color2RGB( Self_.fColor2 );
  35595. if not Self_.fTransparent then
  35596. Target.FillRect( CR ); // GDIFlush; for test only
  35597. //Target.DeselectHandles;
  35598. Target.RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  35599. SetBkMode( Target.fHandle, Windows.TRANSPARENT );
  35600. if Self_.fCtl3D then
  35601. begin
  35602. I := - Self_.fShadowDeep;
  35603. Istp := 1;
  35604. if Self_.ShadowDeep > 0 then Istp := -1;
  35605. repeat
  35606. J := - Self_.fShadowDeep;
  35607. repeat
  35608. if not ( (I=0) and (J=0) ) then
  35609. begin
  35610. if (I * Istp < 0) and (J * Istp < 0) then
  35611. begin
  35612. doTextOut( I, J, CShadow );
  35613. end;
  35614. end;
  35615. J := J - Istp;
  35616. until J = Self_.fShadowDeep - IStp;
  35617. I := I - Istp;
  35618. until I = Self_.fShadowDeep - IStp;
  35619. end
  35620. else
  35621. doTextout( Self_.fShadowDeep, Self_.fShadowdeep, CShadow );
  35622. doTextout( 0, 0, Color2RGB(Self_.fTextColor) );
  35623. end
  35624. else
  35625. begin
  35626. Target.RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  35627. SetBkMode( Target.fHandle, Windows.TRANSPARENT );
  35628. doTextout( 0, 0, Color2RGB(Self_.fTextColor) );
  35629. end;
  35630. end;
  35631. if assigned( Self_.fCanvas ) then
  35632. Self_.fCanvas.SetHandle( 0 );
  35633. if MSg.wParam = 0 then
  35634. EndPaint( Self_.fHandle, PS );
  35635. Self_.fPaintDC := OldPaintDC;
  35636. Rslt := 0;
  35637. Result := True;
  35638. Exit;
  35639. end;
  35640. end;
  35641. end;
  35642. //[procedure TControl.DoClick]
  35643. {$IFDEF ASM_VERSION}
  35644. {$ELSE ASM_VERSION} //Pascal
  35645. procedure TControl.DoClick;
  35646. begin
  35647. fControlClick( @Self );
  35648. if Assigned( fOnClick ) then
  35649. fOnClick( @Self );
  35650. end;
  35651. {$ENDIF ASM_VERSION}
  35652. {$ENDIF WIN_GDI}
  35653. //[function TControl.ParentForm]
  35654. {$IFDEF ASM_VERSION}
  35655. {$ELSE ASM_VERSION} //Pascal
  35656. function TControl.ParentForm: PControl;
  35657. begin
  35658. Result := @Self;
  35659. if Result.fIsControl then
  35660. repeat
  35661. Result := Result.fParent;
  35662. until (Result = nil) or not Result.fIsControl;
  35663. end;
  35664. {$ENDIF ASM_VERSION}
  35665. {$IFDEF WIN_GDI}
  35666. //[procedure TControl.SetProgressColor]
  35667. {$IFDEF ASM_VERSION}
  35668. {$ELSE ASM_VERSION} //Pascal
  35669. procedure TControl.SetProgressColor(const Value: TColor);
  35670. begin
  35671. {$ifdef win32}
  35672. if Perform( PBM_SETBARCOLOR, 0, Color2RGB(Value) ) <> 0 then
  35673. fTextColor := Value;
  35674. {$endif win32}
  35675. end;
  35676. {$ENDIF ASM_VERSION}
  35677. //[procedure TControl.SetShadowDeep]
  35678. procedure TControl.SetShadowDeep(const Value: Integer);
  35679. begin
  35680. fShadowDeep := Value;
  35681. Invalidate;
  35682. end;
  35683. {$ENDIF WIN_GDI}
  35684. //[function TControl.GetFont]
  35685. {$IFDEF ASM_VERSION}
  35686. {$ELSE ASM_VERSION} //Pascal
  35687. function TControl.GetFont: PGraphicTool;
  35688. begin
  35689. if FFont = nil then
  35690. begin
  35691. FFont := NewFont;
  35692. {$IFDEF USE_AUTOFREE4CONTROLS}
  35693. Add2AutoFree( FFont );
  35694. {$ENDIF}
  35695. FFont.fData.Color := fTextColor;
  35696. FFont.OnChange := FontChanged;
  35697. end;
  35698. Result := FFont;
  35699. end;
  35700. {$ENDIF ASM_VERSION}
  35701. {$IFDEF WIN_GDI}
  35702. //[function TControl.GetBrush]
  35703. {$IFDEF ASM_VERSION}
  35704. {$ELSE ASM_VERSION} //Pascal
  35705. function TControl.GetBrush: PGraphicTool;
  35706. begin
  35707. if FBrush = nil then
  35708. begin
  35709. FBrush := NewBrush;
  35710. FBrush.fData.Color := fColor;
  35711. FBrush.OnChange := BrushChanged;
  35712. {$IFDEF USE_AUTOFREE4CONTROLS}
  35713. Add2AutoFree( FBrush );
  35714. {$ENDIF}
  35715. end;
  35716. Result := FBrush;
  35717. end;
  35718. {$ENDIF ASM_VERSION}
  35719. {$ENDIF WIN_GDI}
  35720. //[procedure TControl.FontChanged]
  35721. {$IFDEF ASM_VERSION}
  35722. {$ELSE ASM_VERSION} //Pascal
  35723. procedure TControl.FontChanged(Sender: PGraphicTool);
  35724. begin
  35725. fTextColor := Sender.fData.Color;
  35726. ApplyFont2Wnd;
  35727. Invalidate;
  35728. end;
  35729. {$ENDIF ASM_VERSION}
  35730. {$IFDEF WIN_GDI}
  35731. //[procedure TControl.BrushChanged]
  35732. {$IFDEF ASM_VERSION}
  35733. {$ELSE ASM_VERSION} //Pascal
  35734. procedure TControl.BrushChanged(Sender: PGraphicTool);
  35735. begin
  35736. fColor := Sender.fData.Color;
  35737. if fTmpBrush <> 0 then
  35738. begin
  35739. DeleteObject( fTmpBrush );
  35740. fTmpBrush := 0;
  35741. end;
  35742. if fPaintDC = 0 then
  35743. // only if not in painting already :
  35744. Invalidate;
  35745. end;
  35746. {$ENDIF ASM_VERSION}
  35747. {$ENDIF WIN_GDI}
  35748. {$IFDEF GDI}
  35749. //[procedure DoApplyFont2Wnd]
  35750. {$IFDEF ASM_VERSION}
  35751. {$ELSE ASM_VERSION} //Pascal
  35752. procedure DoApplyFont2Wnd( _Self: PControl );
  35753. begin
  35754. if _Self.fFont <> nil then
  35755. begin
  35756. if _Self.fHandle <> 0 then
  35757. begin
  35758. _Self.fTextColor := _Self.fFont.fData.Color;
  35759. _Self.Perform( WM_SETFONT, _Self.FFont.Handle, 1 );
  35760. end;
  35761. if (_Self.fCanvas <> nil) and (_Self.fCanvas.fFont <> nil) then
  35762. _Self.fCanvas.fFont.Assign(_Self.fFont);
  35763. if Assigned( _Self.fAutoSize ) then
  35764. _Self.fAutoSize( _Self );
  35765. end;
  35766. end;
  35767. {$ENDIF ASM_VERSION}
  35768. {$ENDIF GDI}
  35769. {$IFDEF _X_}
  35770. {$IFDEF GTK}
  35771. procedure DoApplyFont2Wnd( _Self: PControl );
  35772. var oldfontdesc: PPangoFontDescription;
  35773. rcstyle: PGtkRcStyle;
  35774. gcolor: TGdkColor;
  35775. i: Integer;
  35776. begin
  35777. if Assigned( _Self.fFont ) then
  35778. begin
  35779. gcolor := Color2GdkColor( _Self.fFont.Color );
  35780. rcstyle := gtk_widget_get_modifier_style( _Self.fHandle );
  35781. oldfontdesc := rcstyle.font_desc;
  35782. rcstyle.font_desc :=
  35783. pango_font_description_copy( _Self.fFont.GetPangoFontDesc );
  35784. gtk_widget_modify_style( _Self.fHandle, rcstyle );
  35785. if oldfontdesc <> nil then
  35786. pango_font_description_free( oldfontdesc );
  35787. for i := 0 to 4 do
  35788. gtk_widget_modify_fg( _Self.fCaptionHandle, {GTK_STATE_NORMAL} i, @ gcolor );
  35789. end;
  35790. end;
  35791. {$ENDIF GTK}
  35792. {$ENDIF _X_}
  35793. //[procedure TControl.ApplyFont2Wnd]
  35794. procedure TControl.ApplyFont2Wnd;
  35795. begin
  35796. if Assigned( ApplyFont2Wnd_Proc ) then
  35797. ApplyFont2Wnd_Proc( @ Self );
  35798. end;
  35799. {$IFDEF WIN_GDI}
  35800. //[function TControl.ResizeParent]
  35801. {$IFDEF ASM_VERSION}
  35802. {$ELSE ASM_VERSION} //Pascal
  35803. function TControl.ResizeParent: PControl;
  35804. begin
  35805. ResizeParentBottom;
  35806. ResizeParentRight;
  35807. // Once again, to fix Windows (or my???) bug with
  35808. // incorrect calculating of GetClientRect after
  35809. // SetWindowLong( GWL_[EX}STYLE,... )
  35810. Result := ResizeParentBottom;
  35811. end;
  35812. {$ENDIF ASM_VERSION}
  35813. //[function TControl.ResizeParentBottom]
  35814. {$IFDEF ASM_VERSION}
  35815. {$ELSE ASM_VERSION} //Pascal
  35816. function TControl.ResizeParentBottom: PControl;
  35817. var NewCH: Integer;
  35818. begin
  35819. Result := @Self;
  35820. if fParent <> nil then
  35821. begin
  35822. NewCH := BoundsRect.Bottom + fParent.fMargin;
  35823. if (fParent.fChangedPosSz and $20) <> 0 then
  35824. if NewCH <> fParent.ClientHeight then Exit;
  35825. fParent.ClientHeight := NewCH;
  35826. fParent.fChangedPosSz := fParent.fChangedPosSz or $20;
  35827. end;
  35828. end;
  35829. {$ENDIF ASM_VERSION}
  35830. //[function TControl.ResizeParentRight]
  35831. {$IFDEF ASM_VERSION}
  35832. {$ELSE ASM_VERSION} //Pascal
  35833. function TControl.ResizeParentRight: PControl;
  35834. var NewCW: Integer;
  35835. begin
  35836. Result := @Self;
  35837. if fParent <> nil then
  35838. begin
  35839. NewCW := fBoundsRect.Right + fParent.fMargin;
  35840. if (fParent.fChangedPosSz and $10) <> 0 then
  35841. if NewCW < fParent.ClientWidth then Exit;
  35842. fParent.ClientWidth := NewCW;
  35843. fParent.fChangedPosSz := fParent.fChangedPosSz or $10;
  35844. end;
  35845. end;
  35846. {$ENDIF ASM_VERSION}
  35847. //[function TControl.GetClientHeight]
  35848. {$IFDEF ASM_VERSION}
  35849. {$ELSE ASM_VERSION} //Pascal
  35850. function TControl.GetClientHeight: Integer;
  35851. begin
  35852. with ClientRect do
  35853. Result := Bottom - Top;
  35854. end;
  35855. {$ENDIF ASM_VERSION}
  35856. //[function TControl.GetClientWidth]
  35857. {$IFDEF ASM_VERSION}
  35858. {$ELSE ASM_VERSION} //Pascal
  35859. function TControl.GetClientWidth: Integer;
  35860. begin
  35861. with ClientRect do
  35862. Result := Right - Left;
  35863. end;
  35864. {$ENDIF ASM_VERSION}
  35865. //[procedure TControl.SetClientHeight]
  35866. {$IFDEF ASM_VERSION}
  35867. {$ELSE ASM_VERSION} //Pascal
  35868. procedure TControl.SetClientHeight(const Value: Integer);
  35869. var Delta: Integer;
  35870. begin
  35871. Delta := ClientHeight;
  35872. Delta := Height - Delta;
  35873. Height := Value + Delta;
  35874. end;
  35875. {$ENDIF ASM_VERSION}
  35876. //[procedure TControl.SetClientWidth]
  35877. {$IFDEF ASM_VERSION}
  35878. {$ELSE ASM_VERSION} //Pascal
  35879. procedure TControl.SetClientWidth(const Value: Integer);
  35880. var Delta: Integer;
  35881. begin
  35882. Delta := ClientWidth;
  35883. Delta := Width - Delta;
  35884. Width := Value + Delta;
  35885. end;
  35886. {$ENDIF ASM_VERSION}
  35887. //[function TControl.CenterOnParent]
  35888. {$IFDEF ASM_VERSION}
  35889. {$ELSE ASM_VERSION} //Pascal
  35890. function TControl.CenterOnParent: PControl;
  35891. var PCR: TRect;
  35892. begin
  35893. Result := @Self;
  35894. if (fParent = nil) or not fIsControl then
  35895. PCR := MakeRect( 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) )
  35896. else
  35897. PCR := fParent.ClientRect;
  35898. GetWindowHandle;
  35899. Left := (PCR.Right - PCR.Left - Width) div 2;
  35900. Top := (PCR.Bottom - PCR.Top - Height) div 2;
  35901. end;
  35902. {$ENDIF ASM_VERSION}
  35903. //[function TControl.GetHasBorder]
  35904. {$IFDEF ASM_VERSION}
  35905. {$ELSE ASM_VERSION} //Pascal
  35906. function TControl.GetHasBorder: Boolean;
  35907. begin
  35908. UpdateWndStyles;
  35909. Result := LongBool( fStyle and (WS_BORDER or WS_THICKFRAME or WS_DLGFRAME))
  35910. or LongBool( fExStyle and WS_EX_CLIENTEDGE );
  35911. end;
  35912. {$ENDIF ASM_VERSION}
  35913. {$IFDEF ASM_noVERSION} // YS
  35914. //[procedure TControl.SetHasBorder]
  35915. procedure TControl.SetHasBorder(const Value: Boolean);
  35916. const style_mask = WS_BORDER or WS_THICKFRAME or WS_DLGFRAME or WS_CAPTION
  35917. or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU;
  35918. exstyle_mask = not (WS_EX_CONTROLPARENT or WS_EX_DLGMODALFRAME
  35919. or WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE);
  35920. asm
  35921. PUSH EAX
  35922. PUSH EDX
  35923. CALL GetHasBorder
  35924. POP ECX
  35925. CMP AL, CL
  35926. POP EAX
  35927. JZ @@exit
  35928. MOV EDX, [EAX].fStyle
  35929. DEC CL
  35930. MOVZX ECX, [EAX].fIsControl
  35931. JNZ @@1
  35932. OR EDX, WS_THICKFRAME
  35933. INC ECX
  35934. LOOP @@set_style
  35935. OR EDX, style_mask
  35936. JMP @@set_style
  35937. @@1: AND EDX, not style_mask
  35938. INC ECX
  35939. LOOP @@2
  35940. OR EDX, WS_POPUP
  35941. @@2: PUSH EDX
  35942. MOV EDX, [EAX].fExStyle
  35943. AND EDX, exstyle_mask
  35944. PUSH EAX
  35945. CALL SetExStyle
  35946. POP EAX
  35947. POP EDX
  35948. @@set_style:
  35949. TEST [EAX].fTabStop, 1
  35950. JZ @@no_tabstop
  35951. OR DX, WS_TABSTOP
  35952. JMP @@set_style_1
  35953. @@no_tabstop:
  35954. AND DX, not WS_TABSTOP
  35955. @@set_style_1:
  35956. CALL SetStyle
  35957. @@exit:
  35958. end;
  35959. {$ELSE ASM_VERSION} //Pascal
  35960. procedure TControl.SetHasBorder(const Value: Boolean);
  35961. var NewStyle: DWORD;
  35962. begin
  35963. if Value = GetHasBorder then Exit;
  35964. if Value then
  35965. begin
  35966. if not fIsControl then
  35967. Style := fStyle or WS_BORDER or WS_CAPTION or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU
  35968. {$ifdef win32}or WS_THICKFRAME or WS_DLGFRAME{$endif}
  35969. else
  35970. {$ifdef win32}
  35971. if fCtl3D then
  35972. ExStyle := fExStyle or WS_EX_CLIENTEDGE
  35973. else
  35974. {$endif win32}
  35975. Style := fStyle or WS_BORDER;
  35976. end
  35977. else
  35978. begin
  35979. NewStyle := fStyle and not (WS_BORDER or WS_THICKFRAME or WS_DLGFRAME or WS_CAPTION
  35980. or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU);
  35981. {$ifdef win32}
  35982. if not fIsControl then NewStyle := NewStyle or WS_POPUP;
  35983. {$endif win32}
  35984. Style := NewStyle;
  35985. {$ifdef win32}
  35986. ExStyle := fExStyle and not (WS_EX_CONTROLPARENT or WS_EX_DLGMODALFRAME
  35987. or WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE);
  35988. {$endif win32}
  35989. end;
  35990. //+MTsv DN
  35991. if fIsControl then
  35992. if fTabStop then Style := fStyle or WS_TABSTOP
  35993. else Style := fStyle {xor} and not WS_TABSTOP;
  35994. end;
  35995. {$ENDIF ASM_VERSION}
  35996. //[function TControl.GetHasCaption]
  35997. {$IFDEF ASM_VERSION}
  35998. {$ELSE ASM_VERSION} //Pascal
  35999. function TControl.GetHasCaption: Boolean;
  36000. begin
  36001. UpdateWndStyles;
  36002. Result := LongBool( fStyle and (WS_CAPTION xor WS_BORDER));
  36003. end;
  36004. {$ENDIF ASM_VERSION}
  36005. //[procedure TControl.SetHasCaption]
  36006. {$IFDEF ASM_VERSION}
  36007. {$ELSE ASM_VERSION} //Pascal
  36008. procedure TControl.SetHasCaption(const Value: Boolean);
  36009. begin
  36010. if Value = GetHasCaption then Exit;
  36011. if Value then
  36012. begin
  36013. Style := fStyle {$ifdef win32}and not (WS_POPUP or WS_DLGFRAME){$endif} or WS_CAPTION;
  36014. end
  36015. else
  36016. begin
  36017. if fIsControl then
  36018. Style := fStyle and not WS_CAPTION or WS_DLGFRAME
  36019. else
  36020. Style := fStyle and not (WS_CAPTION or WS_SYSMENU xor WS_BORDER){$ifdef win32} or WS_POPUP{$endif};
  36021. {$ifdef win32}
  36022. ExStyle := fExStyle or WS_EX_DLGMODALFRAME;
  36023. {$endif win32}
  36024. end;
  36025. end;
  36026. {$ENDIF ASM_VERSION}
  36027. //[function TControl.GetCanResize]
  36028. {$IFDEF ASM_VERSION}
  36029. {$ELSE ASM_VERSION} //Pascal
  36030. function TControl.GetCanResize: Boolean;
  36031. begin
  36032. //UpdateWndStyles;
  36033. //Result := LongBool( fStyle and WS_THICKFRAME);
  36034. Result := not fPreventResize;
  36035. end;
  36036. {$ENDIF ASM_VERSION}
  36037. //[function WndProcCanResize]
  36038. function WndProcCanResize( Sender: PControl; var M: TMsg; var Rslt: Integer ): Boolean;
  36039. var W, H: Integer;
  36040. P: PMinMaxInfo;
  36041. begin
  36042. if not Sender.CanResize then
  36043. if M.message = WM_GETMINMAXINFO then
  36044. begin
  36045. Rslt := Sender.CallDefWndProc( M );
  36046. W := Sender.FFixWidth;
  36047. H := Sender.FFixHeight;
  36048. P := Pointer( M.lParam );
  36049. P.ptMinTrackSize.x := W;
  36050. P.ptMinTrackSize.y := H;
  36051. P.ptMaxTrackSize := P.ptMinTrackSize;
  36052. Result := True; // stop further processing (prevent resizing)
  36053. Exit;
  36054. end
  36055. else
  36056. {$ifdef win32}
  36057. if M.message = WM_NCHITTEST then
  36058. begin
  36059. Rslt := Sender.CallDefWndProc( M );
  36060. if (Rslt >= 10) and (Rslt <= 17) then
  36061. begin
  36062. {$IFDEF CANRESIZE_THICKFRAME}
  36063. Rslt := {-}HTBORDER{+}{++}(*18{HTBORDER}*){--};
  36064. {$ELSE}
  36065. Rslt := HTNOWHERE;
  36066. {$ENDIF}
  36067. Result := True;
  36068. exit;
  36069. end;
  36070. end
  36071. {$endif win32};
  36072. Result := False; // continue message processing
  36073. end;
  36074. //[procedure TControl.SetCanResize]
  36075. {$IFDEF ASM_VERSION}
  36076. {$ELSE ASM_VERSION} //Pascal
  36077. procedure TControl.SetCanResize( const Value: Boolean );
  36078. begin
  36079. if Value = CanResize then Exit;
  36080. fPreventResize := not Value;
  36081. {$IFDEF CANRESIZE_THICKFRAME}
  36082. if Value then
  36083. Style := Style or WS_THICKFRAME
  36084. else
  36085. Style := Style and not WS_THICKFRAME;
  36086. {$ENDIF}
  36087. GetWindowHandle;
  36088. FFixWidth := Width;
  36089. FFixHeight := Height;
  36090. AttachProc( WndProcCanResize );
  36091. end;
  36092. {$ENDIF ASM_VERSION}
  36093. //[function TControl.GetStayOnTop]
  36094. {$IFDEF ASM_VERSION}
  36095. {$ELSE ASM_VERSION} //Pascal
  36096. function TControl.GetStayOnTop: Boolean;
  36097. begin
  36098. UpdateWndStyles;
  36099. Result := LongBool( fExStyle and WS_EX_TOPMOST);
  36100. end;
  36101. {$ENDIF ASM_VERSION}
  36102. //[procedure TControl.SetStayOnTop]
  36103. {$IFDEF ASM_VERSION}
  36104. {$ELSE ASM_VERSION} //Pascal
  36105. procedure TControl.SetStayOnTop(const Value: Boolean);
  36106. begin
  36107. if Value = GetStayOnTop then Exit;
  36108. if fHandle <> 0 then
  36109. if Value then
  36110. SetWindowPos( fHandle, HWND_TOPMOST, 0,0,0,0,
  36111. SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE )
  36112. else
  36113. SetWindowPos( fHandle, HWND_NOTOPMOST, 0,0,0,0,
  36114. SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE )
  36115. else
  36116. if Value then fExStyle := fExStyle or WS_EX_TOPMOST
  36117. else fExStyle := fExStyle and not WS_EX_TOPMOST;
  36118. end;
  36119. {$ENDIF ASM_VERSION}
  36120. //[function TControl.UpdateWndStyles]
  36121. {$IFDEF ASM_VERSION}
  36122. {$ELSE ASM_VERSION} //Pascal
  36123. function TControl.UpdateWndStyles: PControl;
  36124. begin
  36125. Result := @Self;
  36126. if fHandle = 0 then Exit;
  36127. fStyle := GetWindowLong( fHandle, GWL_STYLE );
  36128. fExStyle := GetWindowLong( fHandle, GWL_EXSTYLE );
  36129. fClsStyle := GetClassLong( fHandle, GCL_STYLE );
  36130. end;
  36131. {$ENDIF ASM_VERSION}
  36132. //[function TControl.GetChecked]
  36133. {$IFDEF ASM_VERSION}
  36134. {$ELSE ASM_VERSION} //Pascal
  36135. function TControl.GetChecked: Boolean;
  36136. begin
  36137. if bboFixed in fBitBtnOptions then
  36138. Result := fChecked
  36139. else
  36140. Result := LongBool( Perform( BM_GETCHECK, 0, 0 ) ) ; //= BST_CHECKED;
  36141. end;
  36142. {$ENDIF ASM_VERSION}
  36143. //[procedure TControl.Set_Checked]
  36144. {$IFDEF ASM_VERSION}
  36145. {$ELSE ASM_VERSION} //Pascal
  36146. procedure TControl.Set_Checked(const Value: Boolean);
  36147. begin
  36148. if bboFixed in fBitBtnOptions then
  36149. begin
  36150. fChecked := Value;
  36151. Invalidate;
  36152. end
  36153. else
  36154. Perform( BM_SETCHECK, Integer( Value ), 0 );
  36155. end;
  36156. {$ENDIF ASM_VERSION}
  36157. //[function TControl.SetChecked]
  36158. function TControl.SetChecked(const Value: Boolean): PControl;
  36159. begin
  36160. Perform( BM_SETCHECK, Integer( Value ), 0 );
  36161. Result := @Self;
  36162. end;
  36163. //[function TControl.SetRadioCheckedOld]
  36164. {$IFDEF ASM_VERSION}
  36165. {$ELSE ASM_VERSION} //Pascal
  36166. function TControl.SetRadioCheckedOld: PControl;
  36167. begin
  36168. Result := @Self;
  36169. if fParent = nil then Exit;
  36170. CheckRadioButton( fParent.GetWindowHandle,
  36171. fParent.fRadio1st,
  36172. fParent.fRadioLast,
  36173. fMenu );
  36174. end;
  36175. {$ENDIF ASM_VERSION}
  36176. //*
  36177. //[function TControl.SetRadioChecked]
  36178. {$IFDEF ASM_VERSION}
  36179. {$ELSE PAS_VERSION}
  36180. function TControl.SetRadioChecked: PControl;
  36181. var WasTabStop: Boolean;
  36182. begin
  36183. WasTabStop := fTabStop;
  36184. fTabStop := FALSE;
  36185. DoClick;
  36186. fTabStop := WasTabStop;
  36187. Result := @Self;
  36188. end;
  36189. {$ENDIF ASM_VERSION}
  36190. //[function TControl.GetCheck3]
  36191. function TControl.GetCheck3: TTriStateCheck;
  36192. begin
  36193. Result := TTriStateCheck(Perform(BM_GETCHECK, 0, 0) and 3);
  36194. end;
  36195. //[procedure TControl.SetCheck3]
  36196. procedure TControl.SetCheck3(value: TTriStateCheck);
  36197. var
  36198. wp: WPARAM;
  36199. begin
  36200. wp := Perform(BM_GETCHECK, 0, 0) and not 3;
  36201. wp := wp or WPARAM(ord(value));
  36202. Perform(BM_SETCHECK, wp, 0);
  36203. end;
  36204. //*
  36205. //[procedure TControl.Click]
  36206. procedure TControl.Click;
  36207. begin
  36208. if (fCommandActions.aClick <> 0) or
  36209. (fCommandActions.aEnter = BN_SETFOCUS) then
  36210. Perform( WM_COMMAND, (fCommandActions.aClick shl 16) or fMenu,
  36211. GetWindowHandle )
  36212. else
  36213. begin
  36214. Perform( WM_LBUTTONDOWN, MK_LBUTTON, 0 );
  36215. Perform( WM_LBUTTONUP, MK_LBUTTON, 0 );
  36216. end;
  36217. end;
  36218. type
  36219. TCharRange = record
  36220. cpMin: Longint;
  36221. cpMax: LongInt;
  36222. end;
  36223. //[function TControl.GetSelStart]
  36224. {$IFDEF ASM_VERSION}
  36225. {$ELSE ASM_VERSION} //Pascal
  36226. function TControl.GetSelStart: Integer;
  36227. //var SR: TCharRange;
  36228. begin
  36229. Result := 0;
  36230. if fCommandActions.aGetSelRange <> 0 then
  36231. //Result := LoWord( Perform( fCommandActions.aGetSelRange, 0, 0 ) )
  36232. Perform( fCommandActions.aGetSelRange, Integer( @ Result ), 0 )
  36233. {else
  36234. if fCommandActions.aExGetSelRange <> 0 then
  36235. begin
  36236. Perform( fCommandActions.aExGetSelRange, 0, Integer( @SR ) );
  36237. Result := SR.cpMin;
  36238. end};
  36239. end;
  36240. {$ENDIF ASM_VERSION}
  36241. //[procedure TControl.SetSelStart]
  36242. procedure TControl.SetSelStart(const Value: Integer);
  36243. begin
  36244. ItemSelected[ Value ] := True;
  36245. end;
  36246. //[function TControl.GetSelLength]
  36247. {$IFDEF ASM_VERSION}
  36248. {$ELSE ASM_VERSION} //Pascal
  36249. function TControl.GetSelLength: Integer;
  36250. var Start, Finish: Integer;
  36251. begin
  36252. Result := 0;
  36253. if fCommandActions.aGetSelCount <> 0 then
  36254. begin
  36255. if fCommandActions.aGetSelCount = EM_GETSEL then
  36256. begin
  36257. Perform( fCommandActions.aGetSelCount, Integer( @ Start ), Integer( @ Finish ) );
  36258. Result := Finish - Start;
  36259. end
  36260. else
  36261. begin
  36262. Result := Perform( fCommandActions.aGetSelCount {and $7FFF}, 0, 0 );
  36263. end;
  36264. end
  36265. {else
  36266. if fCommandActions.aExGetSelRange <> 0 then
  36267. begin
  36268. Perform( fCommandActions.aExGetSelRange, 0, Integer( @SR ) );
  36269. Result := SR.cpMax - SR.cpMin;
  36270. end};
  36271. end;
  36272. {$ENDIF ASM_VERSION}
  36273. //[procedure TControl.SetSelLength]
  36274. {$IFDEF ASM_VERSION}
  36275. {$ELSE ASM_VERSION} //Pascal
  36276. procedure TControl.SetSelLength(const Value: Integer);
  36277. var SR: TCharRange;
  36278. begin
  36279. SR.cpMin := GetSelStart;
  36280. SR.cpMax := SR.cpMin + Value;
  36281. if Value < 0 then
  36282. SR.cpMax := -1;
  36283. if fCommandActions.aSetSelRange <> 0 then
  36284. Perform( fCommandActions.aSetSelRange, SR.cpMin, SR.cpMax )
  36285. else
  36286. if fCommandActions.aExSetSelRange <> 0 then
  36287. Perform( fCommandActions.aExSetSelRange, 0, Integer( @SR ) );
  36288. // Preform( EM_SCROLLCARET, 0, 0 );
  36289. end;
  36290. {$ENDIF ASM_VERSION}
  36291. //[function TControl.GetItems]
  36292. {$IFDEF ASM_UNICODE}
  36293. {$ELSE ASM_VERSION} //Pascal
  36294. function TControl.GetItems(Idx: Integer): KOLString;
  36295. var L, Pos: Integer;
  36296. Buf: PKOLChar;
  36297. begin
  36298. Result := '';
  36299. Pos := Item2Pos( Idx );
  36300. Idx := Pos2Item( Pos );
  36301. if fCommandActions.aGetItemLength <> 0 then
  36302. L := Perform( fCommandActions.aGetItemLength, Pos, 0 )
  36303. else
  36304. Exit;
  36305. if L = 0 then Exit;
  36306. GetMem( Buf, (L + 4) * SizeOf( KOLChar ) );
  36307. PDWORD( Buf )^ := L + 1;
  36308. if fCommandActions.aGetItemText <> 0 then
  36309. Perform( fCommandActions.aGetItemText, Idx, Integer( Buf ) );
  36310. Buf[ L ] := #0;
  36311. Result := Buf;
  36312. FreeMem( Buf );
  36313. end;
  36314. {$ENDIF ASM_VERSION}
  36315. //[procedure TControl.SetItems]
  36316. {$IFDEF ASM_UNICODE}
  36317. {$ELSE ASM_VERSION} //Pascal
  36318. procedure TControl.SetItems(Idx: Integer; const Value: KOLString);
  36319. var Strt, L : DWORD;
  36320. {$IFNDEF NOT_FIX_CURINDEX}
  36321. TmpCurIdx: Integer; // AK - Andrzey Kubasek
  36322. TmpData: DWORD;
  36323. {$ENDIF NOT_FIX_CURINDEX}
  36324. begin
  36325. if fCommandActions.aSetItemText <> 0 then
  36326. begin
  36327. Strt := Item2Pos( Idx );
  36328. L := Item2Pos( Idx + 1 ) - Strt;
  36329. SelStart := Strt;
  36330. SelLength := L;
  36331. Perform( fCommandActions.aSetItemText, 0, Integer( PKOLChar( Value ) ) );
  36332. end
  36333. else
  36334. if fCommandActions.aDeleteItem <> 0 then
  36335. begin
  36336. {$IFNDEF NOT_FIX_CURINDEX}
  36337. TmpCurIdx := CurIndex; // +AK
  36338. TmpData := ItemData[ Idx ];
  36339. {$ENDIF}
  36340. Delete( Idx );
  36341. Insert( Idx, Value );
  36342. {$IFNDEF NOT_FIX_CURINDEX}
  36343. CurIndex := TmpCurIdx; //+AK
  36344. ItemData[ Idx ] := TmpData;
  36345. {$ENDIF}
  36346. end;
  36347. end;
  36348. {$ENDIF ASM_VERSION}
  36349. //[function TControl.GetItemsCount]
  36350. {$IFDEF ASM_VERSION}
  36351. {$ELSE ASM_VERSION} //Pascal
  36352. function TControl.GetItemsCount: Integer;
  36353. begin
  36354. Result := 0;
  36355. {$IFDEF DEBUG}
  36356. try
  36357. {$ENDIF}
  36358. if fCommandActions.aGetCount = 0 then Exit;
  36359. Result := Perform( fCommandActions.aGetCount, 0, 0 );
  36360. {$IFDEF DEBUG}
  36361. except
  36362. asm
  36363. int 3
  36364. end;
  36365. end;
  36366. {$ENDIF}
  36367. end;
  36368. {$ENDIF ASM_VERSION}
  36369. //*
  36370. //[procedure TControl.SetItemsCount]
  36371. procedure TControl.SetItemsCount(const Value: Integer);
  36372. begin
  36373. if fCommandActions.aSetCount = 0 then Exit;
  36374. Perform( fCommandActions.aSetCount, Value, 0 );
  36375. end;
  36376. //[function TControl.Item2Pos]
  36377. {$IFDEF ASM_VERSION}
  36378. {$ELSE ASM_VERSION} //Pascal
  36379. function TControl.Item2Pos(ItemIdx: Integer): DWORD;
  36380. begin
  36381. Result := ItemIdx;
  36382. if fCommandActions.aItem2Pos <> 0 then
  36383. begin
  36384. Result := Perform( fCommandActions.aItem2Pos, ItemIdx, 0 );
  36385. //if Result < 0 then Result := 0;
  36386. end;
  36387. end;
  36388. {$ENDIF ASM_VERSION}
  36389. //[function TControl.Pos2Item]
  36390. {$IFDEF ASM_VERSION}
  36391. {$ELSE ASM_VERSION} //Pascal
  36392. function TControl.Pos2Item(Pos: Integer): DWORD;
  36393. begin
  36394. Result := Pos;
  36395. if fCommandActions.aPos2Item <> 0 then
  36396. Result := Perform( fCommandActions.aPos2Item, Pos, 0 );
  36397. end;
  36398. {$ENDIF ASM_VERSION}
  36399. function TControl.SavePosition: TEditPositions;
  36400. var {$IFNDEF NOT_USE_RICHEDIT}
  36401. p: TPoint;
  36402. {$ENDIF USE_RICHEDIT}
  36403. i: Integer;
  36404. begin
  36405. Result.SelStart := SelStart;
  36406. Result.SelLength := SelLength;
  36407. {$IFNDEF NOT_USE_RICHEDIT}
  36408. if fCannotDoubleBuf { TRUE for rich edit, FALSE for edit } then
  36409. begin
  36410. P.X := 0;
  36411. P.Y := 0;
  36412. i := Perform( EM_CHARFROMPOS, 0, Integer( @ P ) );
  36413. Result.TopLine := Pos2Item( i );
  36414. Result.TopColumn := i - Integer( Item2Pos( Result.TopLine ) );
  36415. {$ifdef win32}
  36416. Perform( EM_GETSCROLLPOS, 0, Integer( @ Result.ScrollPos ) );
  36417. {$else}
  36418. Result.ScrollPos.x:=0;
  36419. Result.ScrollPos.y:=0;
  36420. {$endif win32}
  36421. end
  36422. else
  36423. {$ENDIF USE_RICHEDIT}
  36424. begin
  36425. i := 0;
  36426. i := Perform( EM_CHARFROMPOS, 0, i );
  36427. Result.TopLine := HiWord( i );
  36428. Result.TopColumn := LoWord( i ) - Item2Pos( Result.TopLine );
  36429. Result.ScrollPos.Y := GetScrollPos( Handle, SB_VERT );
  36430. Result.ScrollPos.X := GetScrollPos( Handle, SB_HORZ );
  36431. end;
  36432. Result.RestoreScroll := TRUE;
  36433. end;
  36434. procedure TControl.RestorePosition( const P: TEditPositions );
  36435. var Cur: TEditPositions;
  36436. begin
  36437. SelStart := P.SelStart;
  36438. SelLength := P.SelLength;
  36439. if P.RestoreScroll then
  36440. begin
  36441. Perform( EM_SCROLLCARET, 0, 0 );
  36442. Cur := SavePosition;
  36443. {$IFNDEF NOT_USE_RICHEDIT}
  36444. if fCannotDoubleBuf then
  36445. begin // RichEdit
  36446. if P.TopLine <> Cur.TopLine then
  36447. Perform( EM_LINESCROLL, 0, P.TopLine - Cur.TopLine );
  36448. {$ifdef win32}
  36449. Perform( EM_SETSCROLLPOS, 0, Integer( @ P.ScrollPos ) );
  36450. {$endif win32}
  36451. end
  36452. else // Edit
  36453. {$ENDIF USE_RICHEDIT}
  36454. begin
  36455. if (P.TopLine <> Cur.TopLine) or
  36456. (P.TopColumn <> Cur.TopColumn) then
  36457. Perform( EM_LINESCROLL, P.TopColumn - Cur.TopColumn,
  36458. P.TopLine - Cur.TopLine );
  36459. SetScrollPos( Handle, SB_VERT, P.ScrollPos.Y, TRUE );
  36460. SetScrollPos( Handle, SB_HORZ, P.ScrollPos.X, TRUE );
  36461. end;
  36462. end;
  36463. end;
  36464. procedure TControl.UpdatePosition( var p: TEditPositions; FromPos,
  36465. CountInsertDelChars, CountInsertDelLines: Integer );
  36466. var d: Integer;
  36467. begin
  36468. if (FromPos <= p.SelStart) and (CountInsertDelChars >= 0) or
  36469. (CountInsertDelChars < 0) and
  36470. ((FromPos + Abs( CountInsertDelChars ) <= p.SelStart)
  36471. ) then
  36472. begin
  36473. p.SelStart := p.SelStart + CountInsertDelChars;
  36474. end
  36475. else
  36476. if FromPos >= p.SelStart + p.SelLength then
  36477. begin
  36478. // nothing to do
  36479. end
  36480. else
  36481. if CountInsertDelChars < 0 then // deleting
  36482. begin
  36483. if FromPos - CountInsertDelChars > p.SelStart + p.SelLength then
  36484. CountInsertDelChars := -( p.SelStart + p.SelLength - FromPos );
  36485. if FromPos - CountInsertDelChars >= p.SelStart then
  36486. begin
  36487. d := FromPos - CountInsertDelChars - p.SelStart;
  36488. p.SelLength := p.SelLength - d;
  36489. //inc( CountInsertDelChars, d );
  36490. end;
  36491. inc( p.SelStart, CountInsertDelChars );
  36492. end
  36493. else // inserting
  36494. begin
  36495. if (FromPos > p.SelStart) and (FromPos < p.SelStart + p.SelLength) then
  36496. inc( p.SelLength, CountInsertDelChars )
  36497. else
  36498. if FromPos <= p.SelStart then
  36499. inc( p.SelStart, CountInsertDelChars );
  36500. end;
  36501. p.TopLine := p.TopLine + CountInsertDelLines;
  36502. end;
  36503. //[function WndProcTabChar]
  36504. function WndProcTabChar( Sender: PControl; var M: TMsg; var Rslt: Integer ): Boolean;
  36505. begin
  36506. if M.message = WM_CHAR then
  36507. begin
  36508. if M.wParam = 9 then
  36509. Sender.ReplaceSelection( #9, TRUE );
  36510. end;
  36511. Result := FALSE;
  36512. end;
  36513. //[function TControl.EditTabChar]
  36514. function TControl.EditTabChar: PControl;
  36515. begin
  36516. AttachProc( WndProcTabChar );
  36517. Result := @Self;
  36518. end;
  36519. //[function TControl.Add]
  36520. {$IFDEF ASM_UNICODE}
  36521. {$ELSE ASM_VERSION} //Pascal
  36522. function TControl.Add(const S: KOLString): Integer;
  36523. begin
  36524. if fCommandActions.aAddItem <> 0 then
  36525. begin
  36526. Result := Perform( fCommandActions.aAddItem, 0, Integer( PKOLChar( S ) ) );
  36527. if Count = 1 then
  36528. ItemSelected[ 0 ] := True;
  36529. end
  36530. else
  36531. begin
  36532. if assigned( fCommandActions.aAddText ) then
  36533. fCommandActions.aAddText( @Self, S )
  36534. else
  36535. Text := Text + S;
  36536. Result := 0;
  36537. end;
  36538. end;
  36539. {$ENDIF ASM_VERSION}
  36540. //[procedure TControl.Delete]
  36541. {$IFDEF ASM_VERSION}
  36542. {$ELSE ASM_VERSION} //Pascal
  36543. procedure TControl.Delete(Idx: Integer);
  36544. begin
  36545. if fCommandActions.aDeleteItem <> 0 then
  36546. Perform( fCommandActions.aDeleteItem, Idx, 0 );
  36547. end;
  36548. {$ENDIF ASM_VERSION}
  36549. //[function TControl.Insert]
  36550. {$IFDEF ASM_UNICODE}
  36551. {$ELSE ASM_VERSION} //Pascal
  36552. function TControl.Insert(Idx: Integer; const S: KOLString): Integer;
  36553. begin
  36554. if fCommandActions.aInsertItem <> 0 then
  36555. Result := Perform( fCommandActions.aInsertItem, Idx, Integer( PKOLChar( S ) ) )
  36556. else
  36557. Result := -1;
  36558. end;
  36559. {$ENDIF ASM_VERSION}
  36560. //[function TControl.GetItemSelected]
  36561. {$IFDEF ASM_VERSION}
  36562. {$ELSE ASM_VERSION} //Pascal
  36563. function TControl.GetItemSelected(ItemIdx: Integer): Boolean;
  36564. var SS: Integer;
  36565. begin
  36566. if fCommandActions.aGetSelected <> 0 then
  36567. begin
  36568. SS := Perform( fCommandActions.aGetSelected, ItemIdx, LVIS_SELECTED );
  36569. { Though it is written in docs that for combobox lParam for CB_GETCURSEL
  36570. is not used and _must_ be 0, therefore this code is working for
  36571. combobox too. }
  36572. if fCommandActions.aGetSelected <> CB_GETCURSEL then
  36573. ItemIdx := 1;
  36574. Result := SS = ItemIdx;
  36575. end
  36576. else
  36577. begin
  36578. SS := SelStart;
  36579. Result := (ItemIdx >= SS) and (ItemIdx < SS + SelLength);
  36580. end;
  36581. end;
  36582. {$ENDIF ASM_VERSION}
  36583. //[procedure TControl.SetItemSelected]
  36584. {$IFDEF ASM_VERSION}
  36585. {$ELSE ASM_VERSION} //Pascal
  36586. procedure TControl.SetItemSelected(ItemIdx: Integer; const Value: Boolean);
  36587. var SR: TCharRange;
  36588. begin
  36589. if fCommandActions.aSetSelected <> 0 then
  36590. Perform( fCommandActions.aSetSelected, Integer( Value ), ItemIdx )
  36591. else
  36592. if fCommandActions.aSetCurrent <> 0 then
  36593. Perform( fCommandActions.aSetCurrent, ItemIdx, 0 )
  36594. else
  36595. if fCommandActions.aSetSelRange <> 0 then
  36596. Perform( fCommandActions.aSetSelRange, ItemIdx, ItemIdx )
  36597. else
  36598. if fCommandActions.aExSetSelRange <> 0 then
  36599. begin
  36600. SR.cpMin := ItemIdx;
  36601. SR.cpMax := ItemIdx;
  36602. Perform( fCommandActions.aExSetSelRange, 0, Integer( @SR ) );
  36603. end
  36604. else
  36605. begin // for ImageShow: set the index and invalidate the control
  36606. FCurIndex := ItemIdx;
  36607. Invalidate;
  36608. end;
  36609. end;
  36610. {$ENDIF ASM_VERSION}
  36611. //[procedure TControl.SetCtl3D]
  36612. {$IFDEF ASM_VERSION}
  36613. {$ELSE ASM_VERSION} //Pascal
  36614. procedure TControl.SetCtl3D(const Value: Boolean);
  36615. begin
  36616. fCtl3Dchild := Value;
  36617. //if fCtl3D = Value then Exit;
  36618. fCtl3D := Value;
  36619. {$ifdef win32}
  36620. UpdateWndStyles;
  36621. if Value then
  36622. begin
  36623. Style := fStyle and not WS_BORDER;
  36624. ExStyle := fExStyle or WS_EX_CLIENTEDGE;
  36625. end
  36626. else
  36627. begin
  36628. Style := fStyle or WS_BORDER;
  36629. ExStyle := fExStyle and not WS_EX_CLIENTEDGE;
  36630. end;
  36631. {$endif win32}
  36632. end;
  36633. {$ENDIF ASM_VERSION}
  36634. //[function TControl.Shift]
  36635. {$IFDEF ASM_VERSION}
  36636. {$ELSE ASM_VERSION} //Pascal
  36637. function TControl.Shift(dX, dY: Integer): PControl;
  36638. begin
  36639. Left := fBoundsRect.Left + dX;
  36640. Top := fBoundsRect.Top + dY;
  36641. Result := @Self;
  36642. end;
  36643. {$ENDIF ASM_VERSION}
  36644. //[procedure SetKeyEvent]
  36645. procedure SetKeyEvent( Self_: PControl );
  36646. begin
  36647. Self_.fWndProcKeybd := WndProcKeybd;
  36648. end;
  36649. //[procedure TControl.SetOnChar]
  36650. procedure TControl.SetOnChar(const Value: TOnChar);
  36651. begin
  36652. fOnChar := Value;
  36653. SetKeyEvent( @Self );
  36654. end;
  36655. {$IFDEF SUPPORT_ONDEADCHAR}
  36656. //[procedure TControl.SetOnChar]
  36657. procedure TControl.SetOnDeadChar(const Value: TOnChar);
  36658. begin
  36659. fOnDeadChar := Value;
  36660. SetKeyEvent( @Self );
  36661. end;
  36662. {$ENDIF SUPPORT_ONDEADCHAR}
  36663. //[procedure TControl.SetOnKeyDown]
  36664. procedure TControl.SetOnKeyDown(const Value: TOnKey);
  36665. begin
  36666. fOnKeyDown := Value;
  36667. SetKeyEvent( @Self );
  36668. end;
  36669. //[procedure TControl.SetOnKeyUp]
  36670. procedure TControl.SetOnKeyUp(const Value: TOnKey);
  36671. begin
  36672. fOnKeyUp := Value;
  36673. SetKeyEvent( @Self );
  36674. end;
  36675. //[FUNCTION CollectTabControls]
  36676. {$IFDEF ASM_VERSION}
  36677. {$ELSE ASM_VERSION} //Pascal
  36678. function CollectTabControls( Form: PControl ): PList;
  36679. var R: PList;
  36680. function CollectTab( P: PControl ): Boolean;
  36681. var I, J: Integer;
  36682. C, D: PControl;
  36683. begin
  36684. Result := FALSE;
  36685. for I := 0 to P.fChildren.fCount - 1 do
  36686. begin
  36687. C := P.fChildren.fItems[ I ];
  36688. if C.fTabstop and C.fEnabled and C.ToBeVisible and
  36689. (C.fStyle and WS_TABSTOP <> 0) then
  36690. begin
  36691. D := nil;
  36692. for J := 0 to R.fCount - 1 do
  36693. begin
  36694. D := R.fItems[ J ];
  36695. if D.fTabOrder > C.fTabOrder then
  36696. begin
  36697. Result := TRUE;
  36698. R.Insert( J, C );
  36699. break;
  36700. end
  36701. else
  36702. D := nil;
  36703. end;
  36704. if D = nil then
  36705. begin
  36706. R.Add( C );
  36707. Result := TRUE;
  36708. end;
  36709. end;
  36710. if C.fEnabled then
  36711. begin
  36712. if CollectTab( C ) then
  36713. R.Remove( C );
  36714. end;
  36715. end;
  36716. end;
  36717. {$IFDEF DEBUG_COLLECTTABCONTROLS}
  36718. var SL: PStrList;
  36719. i: Integer;
  36720. C: PControl;
  36721. {$ENDIF}
  36722. begin
  36723. R := NewList;
  36724. CollectTab( Form );
  36725. {$IFDEF DEBUG_COLLECTTABCONTROLS}
  36726. SL := NewStrList;
  36727. for i := 0 to R.Count-1 do
  36728. begin
  36729. C := R.Items[ i ];
  36730. SL.Add( Int2Str( C.fTabOrder ) + ' ' + Int2Str( C.fTag ) + ' ' + C.fCaption );
  36731. end;
  36732. SL.SaveToFile( GetStartDir + 'debug_collecttabcontrols.txt' );
  36733. SL.Free;
  36734. {$ENDIF}
  36735. Result := R;
  36736. end;
  36737. {$ENDIF ASM_VERSION}
  36738. //[END CollectTabControls]
  36739. //[PROCEDURE Tabulate2Next]
  36740. {$IFDEF ASM_VERSION}
  36741. {$ELSE ASM_VERSION} //Pascal
  36742. procedure Tabulate2Next( Form: PControl; Dir: Integer );
  36743. var CL : PList;
  36744. I, J : Integer;
  36745. Ctrl1, Ctrl2, C : PControl;
  36746. begin
  36747. CL := CollectTabControls( Form );
  36748. I := 0;
  36749. C := Form.fCurrentControl;
  36750. if C <> nil then
  36751. I := C.fTabOrder;
  36752. Ctrl2 := nil;
  36753. Ctrl1 := nil;
  36754. for J := 0 to CL.fCount - 1 do
  36755. begin
  36756. C := CL.fItems[ J ];
  36757. if C.fTabOrder = I then continue;
  36758. if (Ctrl1 = nil)
  36759. and ( (Dir >= 0) and (C.fTabOrder > I)
  36760. or (Dir < 0) and (C.fTabOrder < I) )
  36761. or (Dir >= 0)
  36762. and (C.fTabOrder > I) and (C.fTabOrder < Ctrl1.fTabOrder)
  36763. or (Dir < 0)
  36764. and (C.fTabOrder < I) and (C.fTabOrder > Ctrl1.fTabOrder)
  36765. then Ctrl1 := C;
  36766. if (Ctrl2 = nil)
  36767. or (Dir >= 0) and (C.fTabOrder < Ctrl2.fTabOrder)
  36768. or (Dir < 0) and (C.fTabOrder > Ctrl2.fTabOrder)
  36769. then Ctrl2 := C;
  36770. end;
  36771. if Ctrl1 = nil then
  36772. Ctrl1 := Ctrl2;
  36773. if Ctrl1 <> nil then
  36774. begin
  36775. if (Ctrl1.fHandle <> 0) {$IFDEF USE_GRAPHCTLS} or not Ctrl1.fWindowed {$ENDIF} then
  36776. begin
  36777. Inc( Ctrl1.fClickDisabled );
  36778. Ctrl1.Focused := TRUE;
  36779. Dec( Ctrl1.fClickDisabled );
  36780. end;
  36781. Form.fCurrentControl := Ctrl1;
  36782. end;
  36783. CL.Free;
  36784. end;
  36785. {$ENDIF ASM_VERSION}
  36786. //[END Tabulate2Next]
  36787. //[FUNCTION Tabulate2Control]
  36788. {$IFDEF ASM_VERSION}
  36789. {$ELSE ASM_VERSION} //Pascal
  36790. function Tabulate2Control( Self_: PControl; Key: DWORD; checkOnly: Boolean ): Boolean;
  36791. var Form: PControl;
  36792. begin
  36793. Result := False;
  36794. case Key of
  36795. VK_TAB: if not (tkTab in Self_.fLookTabKeys) then exit;
  36796. VK_LEFT, VK_RIGHT: if not (tkLeftRight in Self_.fLookTabKeys) then exit;
  36797. VK_UP, VK_DOWN: if not (tkUpDown in Self_.fLookTabKeys) then exit;
  36798. VK_NEXT, VK_PRIOR: if not (tkPageUpPageDn in Self_.fLookTabKeys) then exit;
  36799. else Exit;
  36800. end;
  36801. Result := True;
  36802. if checkOnly then Exit;
  36803. Form := Self_.ParentForm;
  36804. case Key of
  36805. VK_TAB:
  36806. if GetKeyState( VK_SHIFT ) < 0 then
  36807. Tabulate2Next( Form, -1 )
  36808. else
  36809. Tabulate2Next( Form, 1 );
  36810. VK_RIGHT, VK_DOWN, VK_NEXT: Tabulate2Next( Form, 1 );
  36811. VK_LEFT, VK_UP, VK_PRIOR: Tabulate2Next( Form, -1 );
  36812. end;
  36813. end;
  36814. {$ENDIF ASM_VERSION}
  36815. //[END Tabulate2Control]
  36816. //[FUNCTION Tabulate2ControlEx]
  36817. {$IFDEF ASM_VERSION}
  36818. {$ELSE ASM_VERSION} //Pascal
  36819. function Tabulate2ControlEx( Self_: PControl; Key: DWORD; checkOnly: Boolean ): Boolean;
  36820. label search_tabcontrol;
  36821. var Form: PControl;
  36822. CL : PList;
  36823. I : Integer;
  36824. CurCtrl, Ctrl, Found : PControl;
  36825. MinDist, Dist: Integer;
  36826. R, R1 : TRect;
  36827. begin
  36828. Result := False;
  36829. case Key of
  36830. VK_TAB: if not (tkTab in Self_.fLookTabKeys) then exit;
  36831. VK_LEFT, VK_RIGHT: if not (tkLeftRight in Self_.fLookTabKeys) then exit;
  36832. VK_UP, VK_DOWN: if not (tkUpDown in Self_.fLookTabKeys) then exit;
  36833. VK_NEXT, VK_PRIOR: if not (tkPageUpPageDn in Self_.fLookTabKeys) then exit;
  36834. else exit;
  36835. end;
  36836. Result := True;
  36837. if checkOnly then Exit;
  36838. Form := Self_.ParentForm;
  36839. if Key = VK_TAB then
  36840. if GetKeyState( VK_SHIFT ) < 0 then
  36841. Tabulate2Next( Form, -1 )
  36842. else
  36843. Tabulate2Next( Form, 1 )
  36844. else
  36845. begin
  36846. CL := CollectTabControls( Form );
  36847. I := CL.IndexOf( Form.fCurrentControl );
  36848. Found := nil;
  36849. if I >= 0 then
  36850. begin
  36851. CurCtrl := CL.fItems[ I ];
  36852. GetWindowRect( CurCtrl.Handle, R );
  36853. search_tabcontrol:
  36854. MinDist := MaxInt;
  36855. for I := CL.fCount - 1 downto 0 do
  36856. begin
  36857. Ctrl := CL.fItems[ I ];
  36858. if Ctrl = CurCtrl then continue;
  36859. if not (Ctrl.fEnabled and Ctrl.fTabstop) then continue;
  36860. GetWindowRect( Ctrl.Handle, R1 );
  36861. Dist := MaxInt;
  36862. case Key of
  36863. VK_LEFT:
  36864. begin
  36865. if (R1.Bottom < R.Top)
  36866. or (R1.Top >= R.Bottom)
  36867. or (R1.Left > R.Left) then continue;
  36868. Dist := R.Left - R1.Left;
  36869. end;
  36870. VK_RIGHT:
  36871. begin
  36872. if (R1.Bottom < R.Top)
  36873. or (R1.Top >= R.Bottom)
  36874. or (R1.Left < R.Left) then continue;
  36875. Dist := R1.Left - R.Left;
  36876. end;
  36877. VK_UP, VK_PRIOR:
  36878. begin
  36879. if (R1.Right < R.Left)
  36880. or (R1.Left >= R.Right)
  36881. or (R1.Top > R.Top) then continue;
  36882. Dist := R.Top - R1.Top;
  36883. end;
  36884. VK_DOWN, VK_NEXT:
  36885. begin
  36886. if (R1.Right < R.Left)
  36887. or (R1.Left >= R.Right)
  36888. or (R1.Top < R.Bottom) then continue;
  36889. Dist := R1.Top - R.Top;
  36890. end;
  36891. end;
  36892. if Dist < MinDist then
  36893. begin
  36894. Found := Ctrl;
  36895. MinDist := Dist;
  36896. end;
  36897. end;
  36898. if Found = nil then
  36899. begin
  36900. case Key of
  36901. VK_LEFT:
  36902. begin
  36903. Key := VK_UP; goto search_tabcontrol;
  36904. end;
  36905. VK_RIGHT:
  36906. begin
  36907. Key := VK_DOWN; goto search_tabcontrol;
  36908. end;
  36909. VK_UP, VK_PRIOR:
  36910. Tabulate2Next( Form, -1 );
  36911. VK_DOWN, VK_NEXT:
  36912. Tabulate2Next( Form, 1 );
  36913. end;
  36914. end
  36915. else
  36916. begin
  36917. if Found.fHandle <> 0 then
  36918. begin
  36919. Inc( Found.fClickDisabled );
  36920. SetFocus( Found.fHandle );
  36921. Dec( Found.fClickDisabled );
  36922. end;
  36923. Form.fCurrentControl := Found;
  36924. end;
  36925. end;
  36926. CL.Free;
  36927. end;
  36928. end;
  36929. {$ENDIF ASM_VERSION}
  36930. //[END Tabulate2ControlEx]
  36931. //[function TControl.Tabulate]
  36932. {$IFDEF ASM_VERSION}
  36933. {$ELSE ASM_VERSION} //Pascal
  36934. function TControl.Tabulate: PControl;
  36935. var F : PControl;
  36936. begin
  36937. Result := @Self;
  36938. F := ParentForm;
  36939. if F = nil then Exit;
  36940. F.fGotoControl := Tabulate2Control;
  36941. end;
  36942. {$ENDIF ASM_VERSION}
  36943. //[function TControl.TabulateEx]
  36944. {$IFDEF ASM_VERSION}
  36945. {$ELSE ASM_VERSION} //Pascal
  36946. function TControl.TabulateEx: PControl;
  36947. var F : PControl;
  36948. begin
  36949. Result := @Self;
  36950. F := ParentForm;
  36951. if F = nil then Exit;
  36952. F.fGotoControl := Tabulate2ControlEx;
  36953. end;
  36954. {$ENDIF ASM_VERSION}
  36955. function WndProcMouseTransparent( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  36956. begin
  36957. Result := FALSE;
  36958. if Msg.message = WM_NCHITTEST then
  36959. begin
  36960. Rslt := HTTRANSPARENT;
  36961. Result := TRUE;
  36962. end;
  36963. end;
  36964. function TControl.MouseTransparent: PControl;
  36965. begin
  36966. AttachProc( WndProcMouseTransparent );
  36967. Result := @ Self;
  36968. end;
  36969. //*
  36970. //[procedure TControl.GotoControl]
  36971. procedure TControl.GotoControl(Key: DWORD);
  36972. var Form: PControl;
  36973. begin
  36974. Form := ParentForm;
  36975. if Form <> nil then
  36976. if assigned( Form.fGotoControl ) then
  36977. Form.fGotoControl( Form.fCurrentControl, Key, false );
  36978. end;
  36979. //[function TControl.GetCurIndex]
  36980. {$IFDEF ASM_VERSION}
  36981. {$ELSE ASM_VERSION} //Pascal
  36982. function TControl.GetCurIndex: Integer;
  36983. var I, J: Integer;
  36984. begin
  36985. Result := fCurIndex;
  36986. if fCommandActions.aGetCurrent = 0 then
  36987. Exit;
  36988. I := 0;
  36989. if fCommandActions.aGetCurrent = EM_LINEINDEX then
  36990. Dec( I );
  36991. J := 0;
  36992. if fCommandActions.aGetCurrent = LVM_GETNEXTITEM then
  36993. begin
  36994. J := 2 {LVNI_SELECTED};
  36995. Dec( I );
  36996. end;
  36997. Result := Perform( fCommandActions.aGetCurrent, I, J );
  36998. end;
  36999. {$ENDIF ASM_VERSION}
  37000. //[procedure TControl.SetCurIndex]
  37001. {$IFDEF ASM_VERSION}
  37002. {$ELSE ASM_VERSION} //Pascal
  37003. procedure TControl.SetCurIndex(const Value: Integer);
  37004. var NMHdr: TNMHdr;
  37005. begin
  37006. if fCommandActions.aSetCurrent <> 0 then
  37007. begin
  37008. Perform( fCommandActions.aSetCurrent, Value, 0 );
  37009. if fCommandActions.aSetCurrent = TCM_SETCURSEL then
  37010. begin
  37011. LongInt(NMHdr.code) := TCN_SELCHANGE;
  37012. NMHdr.hwndFrom := fHandle;
  37013. Perform( WM_NOTIFY, 0, Integer( @NMHdr ) );
  37014. end;
  37015. end
  37016. else
  37017. ItemSelected[ Value ] := True;
  37018. end;
  37019. {$ENDIF ASM_VERSION}
  37020. {$ENDIF WIN_GDI}
  37021. {$IFDEF GDI}
  37022. //[function TControl.GetTextAlign]
  37023. {$IFDEF ASM_VERSION}
  37024. {$ELSE ASM_VERSION} //Pascal
  37025. function TControl.GetTextAlign: TTextAlign;
  37026. begin
  37027. UpdateWndStyles;
  37028. if (fStyle and fCommandActions.aTextAlignRight) = fCommandActions.aTextAlignRight then
  37029. Result := taRight
  37030. else
  37031. if (fStyle and fCommandActions.aTextAlignCenter) = fCommandActions.aTextAlignCenter then
  37032. Result := taCenter
  37033. else
  37034. Result := fTextAlign;
  37035. end;
  37036. {$ENDIF ASM_VERSION}
  37037. {$ENDIF GDI}
  37038. {$IFDEF _X_}
  37039. {$IFDEF GTK}
  37040. function TControl.GetTextAlign: TTextAlign;
  37041. begin
  37042. Result := fTextAlign;
  37043. end;
  37044. {$ENDIF GTK}
  37045. {$ENDIF _X_}
  37046. {$IFDEF GDI}
  37047. //[procedure TControl.SetTextAlign]
  37048. {$IFDEF ASM_VERSION}
  37049. {$ELSE ASM_VERSION} //Pascal
  37050. procedure TControl.SetTextAlign(const Value: TTextAlign);
  37051. var NewStyle: DWORD;
  37052. begin
  37053. fTextAlign := Value;
  37054. NewStyle := 0;
  37055. with fCommandActions do
  37056. case Value of
  37057. taLeft: NewStyle := fStyle and not DWORD(aTextAlignCenter or aTextAlignRight)
  37058. or aTextAlignLeft;
  37059. taRight: NewStyle := fStyle and not DWORD(aTextAlignLeft or aTextAlignCenter)
  37060. or aTextAlignRight;
  37061. taCenter: NewStyle := fStyle and not DWORD(aTextAlignLeft or aTextAlignRight)
  37062. or aTextAlignCenter;
  37063. end;
  37064. NewStyle := NewStyle and not DWORD(fCommandActions.aTextAlignMask);
  37065. Style := NewStyle;
  37066. end;
  37067. {$ENDIF ASM_VERSION}
  37068. {$ENDIF GDI}
  37069. {$IFDEF _X_}
  37070. {$IFDEF GTK}
  37071. procedure TControl.SetTextAlign(const Value: TTextAlign);
  37072. begin
  37073. if fTextAlign = Value then Exit;
  37074. fTextAlign := Value;
  37075. if Assigned( fSetTextAlign ) then
  37076. fSetTextAlign( @ Self );
  37077. end;
  37078. {$ENDIF GTK}
  37079. {$ENDIF _X_}
  37080. {$IFDEF GDI}
  37081. //[function TControl.GetVerticalAlign]
  37082. {$IFDEF ASM_VERSION}
  37083. {$ELSE ASM_VERSION} //Pascal
  37084. function TControl.GetVerticalAlign: TVerticalAlign;
  37085. begin
  37086. UpdateWndStyles;
  37087. if (fStyle and (fCommandActions.aVertAlignCenter shl 8)) = (DWORD(fCommandActions.aVertAlignCenter) shl 8) then
  37088. Result := vaCenter
  37089. else
  37090. if (fStyle and (fCommandActions.aVertAlignBottom shl 8)) = (DWORD(fCommandActions.aVertAlignBottom) shl 8) then
  37091. Result := vaBottom
  37092. else
  37093. Result := fVerticalAlign;
  37094. end;
  37095. {$ENDIF ASM_VERSION}
  37096. {$ENDIF GDI}
  37097. {$IFDEF _X_}
  37098. {$IFDEF GTK}
  37099. function TControl.GetVerticalAlign: TVerticalAlign;
  37100. begin
  37101. Result := fVerticalAlign;
  37102. end;
  37103. {$ENDIF GTK}
  37104. {$ENDIF _X_}
  37105. //[procedure TControl.SetVerticalAlign]
  37106. {$IFDEF GDI}
  37107. {$IFDEF ASM_VERSION}
  37108. {$ELSE ASM_VERSION} //Pascal
  37109. procedure TControl.SetVerticalAlign(const Value: TVerticalAlign);
  37110. var NewStyle: DWORD;
  37111. begin
  37112. fVerticalAlign := Value;
  37113. with fCommandActions do
  37114. begin
  37115. NewStyle := fStyle and not DWORD((aVertAlignTop or aVertAlignCenter or aVertAlignBottom) shl 8);
  37116. case Value of
  37117. vaCenter: NewStyle := NewStyle or (aVertAlignCenter shl 8);
  37118. vaTop: NewStyle := NewStyle or (aVertAlignTop shl 8);
  37119. vaBottom: NewStyle := NewStyle or (aVertAlignBottom shl 8);
  37120. end;
  37121. end;
  37122. Style := NewStyle;
  37123. end;
  37124. {$ENDIF ASM_VERSION}
  37125. {$ENDIF GDI}
  37126. {$IFDEF _X_}
  37127. {$IFDEF GTK}
  37128. procedure TControl.SetVerticalAlign(const Value: TVerticalAlign);
  37129. begin
  37130. if fVerticalAlign = Value then Exit;
  37131. fVerticalAlign := Value;
  37132. if Assigned( fSetTextAlign ) then
  37133. fSetTextAlign( @ Self );
  37134. end;
  37135. {$ENDIF GTK}
  37136. {$ENDIF _X_}
  37137. {$IFDEF WIN_GDI}
  37138. //[function TControl.Dc2Canvas]
  37139. {$IFDEF ASM_VERSION}
  37140. {$ELSE ASM_VERSION} //Pascal
  37141. function TControl.Dc2Canvas( Sender: PCanvas ): HDC;
  37142. begin
  37143. if fPaintDC <> 0 then
  37144. begin
  37145. Result := fPaintDC;
  37146. Sender.SetHandle( Result );
  37147. Sender.fIsPaintDC := True;
  37148. end
  37149. else
  37150. begin
  37151. if Sender.fHandle <> 0 then
  37152. Result := Sender.fHandle
  37153. else
  37154. Result := GetDC( GetWindowHandle );
  37155. end;
  37156. end;
  37157. {$ENDIF ASM_VERSION}
  37158. {$ENDIF WIN_GDI}
  37159. //[function TControl.GetCanvas]
  37160. {$IFDEF GDI}
  37161. {$IFDEF ASM_VERSION}
  37162. {$ELSE ASM_VERSION} //Pascal
  37163. function TControl.GetCanvas: PCanvas;
  37164. begin
  37165. if not assigned( fCanvas ) then
  37166. begin
  37167. fCanvas := NewCanvas( 0 );
  37168. fCanvas.OnGetHandle := Dc2Canvas;
  37169. fCanvas.fOwnerControl := @Self;
  37170. if assigned( fFont ) then
  37171. fCanvas.fFont := fCanvas.fFont.Assign( fFont );
  37172. if assigned( fBrush ) then
  37173. fCanvas.fBrush := fCanvas.fBrush.Assign( fBrush );
  37174. end;
  37175. Result := fCanvas;
  37176. end;
  37177. {$ENDIF ASM_VERSION}
  37178. {$ENDIF GDI}
  37179. {$IFDEF _X_}
  37180. {$IFDEF GTK}
  37181. function TControl.ProvideCanvasHandle( Sender: PCanvas ): HDC;
  37182. type PPGdkGC = ^PGdkGC;
  37183. var Array_gc: PPGdkGC;
  37184. begin
  37185. if fInBkPaint then Array_gc := @ fEventboxHandle.style.bg_gc[ 0 ]
  37186. else
  37187. //if fInPaint then
  37188. Array_gc := @ fEventboxHandle.style.fg_gc[ 0 ];
  37189. {CASE fEventboxHandle.state OF
  37190. GTK_STATE_NORMAL : Result := Array_gc[ 0 ];
  37191. GTK_STATE_ACTIVE : Result := Array_gc[ 1 ];
  37192. GTK_STATE_PRELIGHT : Result := Array_gc[ 2 ];
  37193. GTK_STATE_SELECTED : Result := Array_gc[ 3 ];
  37194. GTK_STATE_INSENSITIVE: Result := Array_gc[ 4 ];
  37195. else Result := Array_gc[ 0 ];
  37196. END;}
  37197. CASE fEventboxHandle.state OF
  37198. GTK_STATE_NORMAL,
  37199. GTK_STATE_ACTIVE,
  37200. GTK_STATE_PRELIGHT,
  37201. GTK_STATE_SELECTED,
  37202. GTK_STATE_INSENSITIVE: Result := PPGdkGC( Integer( Array_gc ) + fEventboxHandle.state * sizeof( Pointer ) )^;
  37203. else Result := Array_gc^;
  37204. END;
  37205. end;
  37206. function TControl.GetCanvas: PCanvas;
  37207. begin
  37208. if not assigned( fCanvas ) then
  37209. begin
  37210. fCanvas := NewCanvas( nil {fHandle.style.fg_gc[0]} );
  37211. fCanvas.OnGetHandle := ProvideCanvasHandle;
  37212. fCanvas.fOwnerControl := @Self;
  37213. fCanvas.fDrawable := Pointer( fEventboxHandle.window );
  37214. {if assigned( fFont ) then
  37215. fCanvas.fFont := fCanvas.fFont.Assign( fFont );}
  37216. {if assigned( fBrush ) then
  37217. fCanvas.fBrush := fCanvas.fBrush.Assign( fBrush );}
  37218. end;
  37219. //fCanvas.fHandle := fEventboxHandle.style.fg_gc[ 0 ]; // todo: setup desired context
  37220. fCanvas.GetHandle; // ïîëó÷èì çäåñü òîò êîíòåêñò, êîòîðûé ñîîòâåòñòâóåò
  37221. // òåêóùåìó ñîñòîÿíèþ êîíòðîëà (åñëè ýòî êîíòðîë) è òåêóùåé
  37222. // ñòàäèè ðèñîâàíèÿ
  37223. Result := fCanvas;
  37224. end;
  37225. {$ENDIF GTK}
  37226. {$ENDIF _X_}
  37227. {$IFDEF WIN_GDI}
  37228. //[function TControl.DblBufTopParent]
  37229. function TControl.DblBufTopParent: PControl;
  37230. var Ctl: PControl;
  37231. begin
  37232. Result := nil;
  37233. Ctl := @ Self;
  37234. while Ctl <> nil do
  37235. begin
  37236. if (Ctl.fDoubleBuffered) or (Ctl.fTransparent) then
  37237. Result := Ctl;
  37238. Ctl := Ctl.fParent;
  37239. end;
  37240. end;
  37241. //[procedure TControl.SetDoubleBuffered]
  37242. procedure TControl.SetDoubleBuffered(const Value: Boolean);
  37243. begin
  37244. {$ifdef win32}
  37245. if CannotDoubleBuf then Exit;
  37246. fDoubleBuffered := Value;
  37247. AttachProc(WndProcTransparent);
  37248. {$IFNDEF SMALLEST_CODE}
  37249. Global_AttachProcExtension := @TransparentAttachProcExtension;
  37250. {$ENDIF}
  37251. {$endif win32}
  37252. end;
  37253. //[procedure TControl.SetTransparent]
  37254. {$IFDEF ASM_VERSION}
  37255. {$ELSE ASM_VERSION} //Pascal
  37256. procedure TControl.SetTransparent(const Value: Boolean);
  37257. begin
  37258. {$ifdef win32}
  37259. fTransparent := Value;
  37260. if fParent = nil then Exit;
  37261. {$IFDEF GRAPHCTL_XPSTYLES}
  37262. if not AppTheming then
  37263. fClassicTransparent := Value;
  37264. {$ENDIF}
  37265. if Value then begin
  37266. AttachProc(WndProcTransparent);
  37267. fParent.DoubleBuffered := TRUE;
  37268. end;
  37269. {$endif win32}
  37270. end;
  37271. {$ENDIF ASM_VERSION}
  37272. //[function TControl.SetBorder]
  37273. function TControl.SetBorder( Value: Integer ): PControl;
  37274. begin
  37275. fMargin := Value;
  37276. Result := @ Self;
  37277. end;
  37278. { TTrayIcon }
  37279. var FTrayItems: PList;
  37280. //[FUNCTION WndProcTray]
  37281. {$IFDEF ASM_noVERSION}
  37282. function WndProcTray( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean;
  37283. asm
  37284. PUSH ECX
  37285. MOV ECX, [EDX].TMsg.message
  37286. CMP CX, CM_TRAYICON
  37287. JNE @@1
  37288. MOV ECX, [EDX].TMsg.lParam
  37289. MOV EDX, [EDX].TMsg.wParam
  37290. MOV EAX, [EDX].TTrayIcon.fOnMouse.TMethod.Data
  37291. CMP word ptr [EDX].TTrayIcon.fOnMouse.TMethod.Code+2, 0
  37292. JE @@no_on
  37293. CALL [EDX].TTrayIcon.fOnMouse.TMethod.Code
  37294. @@no_on:
  37295. POP ECX
  37296. XOR EAX, EAX
  37297. MOV [ECX], EAX
  37298. INC EAX
  37299. RET
  37300. @@1:
  37301. SUB ECX, WM_CLOSE
  37302. JNE @@exit_0
  37303. @@2:
  37304. POP ECX
  37305. PUSH EBX
  37306. XCHG EBX, EAX
  37307. MOV EAX, [EBX].TControl.fHandle
  37308. CMP EAX, [EDX].TMsg.hwnd
  37309. JNE @@otherwin
  37310. MOV EDX, [FTrayItems]
  37311. MOV ECX, [EDX].TList.fCount
  37312. MOV EDX, [EDX].TList.fItems
  37313. @@loop:
  37314. MOV EAX, [EDX + ECX*4 - 4]
  37315. CMP [EAX].TTray.FNoAutoDeactivate, 0
  37316. JNZ @@3
  37317. CMP [EAX].TTrayIcon.fControl, EBX
  37318. JNE @@3
  37319. PUSHAD
  37320. XOR EDX, EDX
  37321. CALL TTrayIcon.SetActive
  37322. POPAD
  37323. @@3: LOOP @@loop
  37324. @@otherwin:
  37325. POP EBX
  37326. PUSH ECX
  37327. @@exit_0:
  37328. XOR EAX, EAX
  37329. POP ECX
  37330. end;
  37331. {$ELSE ASM_VERSION} //Pascal
  37332. function WndProcTray( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean;
  37333. var Self_: PTrayIcon;
  37334. I : Integer;
  37335. begin
  37336. Result := False;
  37337. case Msg.message of
  37338. CM_TRAYICON:
  37339. begin
  37340. Self_ := Pointer( Msg.wParam );
  37341. if Assigned( Self_.FOnMouse ) then
  37342. Self_.FOnMouse( @Self_, Msg.lParam );
  37343. Rslt := 0;
  37344. Result := True;
  37345. end;
  37346. WM_CLOSE:
  37347. if Msg.hwnd = Control.fHandle then
  37348. begin
  37349. if FTrayItems <> nil then // ?????????????????
  37350. for I := FTrayItems.Count - 1 downto 0 do
  37351. begin
  37352. Self_ := FTrayItems.Items[ I ];
  37353. if not Self_.FNoAutoDeactivate then
  37354. if Self_.FControl = Control then
  37355. Self_.Active := False;
  37356. end;
  37357. end;
  37358. end;
  37359. end;
  37360. {$ENDIF ASM_VERSION}
  37361. //[END WndProcTray]
  37362. function WndProcTrayIconWnd( Wnd: HWnd; Msg: DWORD; wParam, lParam: Integer ): Integer;
  37363. {$ifdef wince}cdecl{$else}stdcall{$endif};
  37364. var PrevProc: function ( Wnd: HWnd; Msg: DWORD;
  37365. wParam, lParam: Integer ): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  37366. var Tr: PTrayIcon;
  37367. begin
  37368. PrevProc := Pointer( GetProp( Wnd, 'TRAYSAVEPROC' ) );
  37369. if Msg = CM_TRAYICON then
  37370. begin
  37371. Tr := Pointer( wParam );
  37372. if Assigned( Tr.FOnMouse ) then
  37373. Tr.FOnMouse( Tr, lParam );
  37374. Result := 0;
  37375. Exit;
  37376. end
  37377. else
  37378. if Msg = WM_CLOSE then
  37379. begin
  37380. if Assigned( PrevProc ) then
  37381. begin
  37382. SetWindowLong( Wnd, GWL_WNDPROC, Integer( @ PrevProc ) );
  37383. RemoveProp( Wnd, 'TRAYSAVEPROC' );
  37384. PostMessage( Wnd, WM_CLOSE, wParam, lParam );
  37385. Result := 0;
  37386. Exit;
  37387. end;
  37388. end;
  37389. if (Wnd <> 0) and IsWindow( Wnd ) and Assigned( PrevProc ) then
  37390. Result := PrevProc( Wnd, Msg, wParam, lParam )
  37391. else
  37392. Result := DefWindowProc( Wnd, Msg, wParam, lParam );
  37393. end;
  37394. //[PROCEDURE TTrayIcon.AttachProc2Wnd]
  37395. procedure TTrayIcon.AttachProc2Wnd;
  37396. begin
  37397. if FWnd = 0 then Exit;
  37398. if GetProp( FWnd, 'TRAYSAVEPROC' ) <> 0 then Exit; // already attached
  37399. SetProp( FWnd, 'TRAYSAVEPROC', GetWindowLong( FWnd, GWL_WNDPROC ) );
  37400. SetWindowLong( FWnd, GWL_WNDPROC, Integer( @ WndProcTrayIconWnd ) );
  37401. end;
  37402. // [END TTrayIcon.AttachProc2Wnd]
  37403. // [PROCEDURE TTrayIcon.DetachProc2Wnd]
  37404. procedure TTrayIcon.DetachProc2Wnd;
  37405. var OldProc: function ( Wnd: HWnd; Msg: DWORD;
  37406. wParam, lParam: Integer ): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  37407. begin
  37408. if FWnd = 0 then Exit;
  37409. OldProc := Pointer( GetProp( FWnd, 'TRAYSAVEPROC' ) );
  37410. if not Assigned( OldProc ) then Exit; // not attached
  37411. SetWindowLong( FWnd, GWL_WNDPROC, Integer( @ OldProc ) );
  37412. RemoveProp( FWnd, 'TRAYSAVEPROC' );
  37413. end;
  37414. // [END TTrayIcon.DetachProc2Wnd]
  37415. //[FUNCTION NewTrayIcon]
  37416. {$IFDEF ASM_VERSION}
  37417. {$ELSE ASM_VERSION} //Pascal
  37418. function NewTrayIcon( Wnd: PControl; Icon: HIcon ): PTrayIcon;
  37419. begin
  37420. if FTrayItems = nil then
  37421. FTrayItems := NewList;
  37422. {-}
  37423. New( Result, Create );
  37424. {+}{++}(*Result := PTrayIcon.Create;*){--}
  37425. FTrayItems.Add( Result );
  37426. if Wnd <> nil then
  37427. Wnd.AttachProc( WndProcTray );
  37428. Result.FControl := Wnd;
  37429. Result.FIcon := Icon;
  37430. Result.Active := True;
  37431. end;
  37432. {$ENDIF ASM_VERSION}
  37433. //[END NewTrayIcon]
  37434. var fRecreateMsg: DWORD;
  37435. //[FUNCTION WndProcRecreateTrayIcons]
  37436. {$IFDEF ASM_VERSION}
  37437. {$ELSE ASM_VERSION} //Pascal
  37438. function WndProcRecreateTrayIcons( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  37439. var I: Integer;
  37440. TI: PTrayIcon;
  37441. begin
  37442. if Msg.message = fRecreateMsg then
  37443. begin
  37444. for I := 0 to FTrayItems.fCount - 1 do
  37445. begin
  37446. TI := FTrayItems.Items[ I ];
  37447. if TI.fAutoRecreate then
  37448. if TI.fActive then
  37449. begin
  37450. TI.fActive := False;
  37451. TI.Active := True;
  37452. end;
  37453. end;
  37454. end;
  37455. Result := False;
  37456. end;
  37457. {$ENDIF ASM_VERSION}
  37458. //[END WndProcRecreateTrayIcons]
  37459. const
  37460. TaskbarCreatedMsg: array[ 0..14 ] of KOLChar = ('T','a','s','k','b','a','r',
  37461. 'C','r','e','a','t','e','d',#0);
  37462. //[procedure TTrayIcon.SetAutoRecreate]
  37463. {$IFDEF ASM_VERSION}
  37464. {$ELSE ASM_VERSION} //Pascal
  37465. procedure TTrayIcon.SetAutoRecreate(const Value: Boolean);
  37466. begin
  37467. fAutoRecreate := Value;
  37468. FControl.ParentForm.AttachProc( WndProcRecreateTrayIcons );
  37469. fRecreateMsg := RegisterWindowMessage( TaskbarCreatedMsg );
  37470. end;
  37471. {$ENDIF ASM_VERSION}
  37472. //[destructor TTrayIcon.Destroy]
  37473. {$IFDEF ASM_VERSION}
  37474. {$ELSE ASM_VERSION} //Pascal
  37475. destructor TTrayIcon.Destroy;
  37476. begin
  37477. Active := False;
  37478. if fIcon <> 0 then
  37479. DestroyIcon( fIcon );
  37480. FTrayItems.Remove( @ Self );
  37481. if FTrayItems.Count = 0 then
  37482. Free_And_Nil( FTrayItems );
  37483. FTooltip := '';
  37484. inherited;
  37485. end;
  37486. {$ENDIF ASM_VERSION}
  37487. //[procedure TTrayIcon.SetActive]
  37488. {$IFDEF ASM_VERSION}
  37489. {$ELSE ASM_VERSION} //Pascal
  37490. {$ifdef wince}
  37491. const
  37492. NIM_ADD = $00000000;
  37493. NIM_MODIFY = $00000001;
  37494. NIM_DELETE = $00000002;
  37495. NIF_MESSAGE = $00000001;
  37496. NIF_ICON = $00000002;
  37497. NIF_TIP = $00000004;
  37498. {$endif wince}
  37499. procedure TTrayIcon.SetActive(const Value: Boolean);
  37500. begin
  37501. if FActive = Value then Exit;
  37502. if FIcon = 0 then Exit;
  37503. if (Wnd = 0) and ((FControl = nil) or (FControl.GetWindowHandle = 0)) then Exit;
  37504. FActive := Value;
  37505. if Value then
  37506. SetTrayIcon( NIM_ADD )
  37507. else
  37508. SetTrayIcon( NIM_DELETE );
  37509. end;
  37510. {$ENDIF ASM_VERSION}
  37511. //[procedure TTrayIcon.SetIcon]
  37512. {$IFDEF ASM_VERSION}
  37513. {$ELSE ASM_VERSION} //Pascal
  37514. procedure TTrayIcon.SetIcon(const Value: HIcon);
  37515. var Cmd : DWORD;
  37516. begin
  37517. if FIcon = Value then Exit;
  37518. // Previous icon is not destroying. This is normal for
  37519. // icons, loaded from resources using LoadIcon. For icons,
  37520. // created using CreateIconIndirect, You have to call
  37521. // DestroyIcon manually.
  37522. Cmd := NIM_MODIFY;
  37523. if FIcon = 0 then
  37524. Cmd := NIM_ADD;
  37525. FIcon := Value;
  37526. if FActive then
  37527. SetTrayIcon( Cmd );
  37528. end;
  37529. {$ENDIF ASM_VERSION}
  37530. //[procedure TTrayIcon.SetTooltip]
  37531. {$IFDEF ASM_UNICODE}
  37532. {$ELSE ASM_VERSION} //Pascal
  37533. procedure TTrayIcon.SetTooltip(const Value: KOLString);
  37534. begin
  37535. if FTooltip = Value then Exit;
  37536. FTooltip := Value;
  37537. if Active then
  37538. SetTrayIcon( NIM_MODIFY );
  37539. end;
  37540. {$ENDIF ASM_VERSION}
  37541. //[procedure TTrayIcon.SetTrayIcon]
  37542. {$IFDEF ASM_UNICODE}
  37543. {$ELSE ASM_VERSION} //Pascal
  37544. procedure TTrayIcon.SetTrayIcon(const Value: DWORD);
  37545. var NID : {$IFDEF UNICODE_CTRLS} TNotifyIconDataW {$ELSE} TNotifyIconData {$ENDIF};
  37546. L : Integer;
  37547. V : DWORD;
  37548. begin
  37549. V := Value;
  37550. if AppletTerminated then
  37551. V := NIM_DELETE;
  37552. if Wnd <> 0 then
  37553. NID.Wnd := Wnd
  37554. else
  37555. NID.Wnd := FControl.fHandle;
  37556. NID.cbSize := Sizeof( NID );
  37557. NID.uID := DWORD( @Self );
  37558. NID.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
  37559. if V = NIM_DELETE then
  37560. NID.uFlags := 0;
  37561. NID.uCallbackMessage := CM_TRAYICON;
  37562. NID.hIcon := FIcon;
  37563. L := Length( FToolTip );
  37564. if L > 63 then L := 63;
  37565. Move( FTooltip[1], NID.szTip[0], Min( 63, L ) );
  37566. {$ifdef wince}
  37567. NID.szTip[ L ] := 0;
  37568. {$else wince}
  37569. NID.szTip[ L ] := #0;
  37570. {$endif wince}
  37571. Shell_NotifyIcon( V, @NID );
  37572. end;
  37573. {$ENDIF ASM_VERSION}
  37574. { -- JustOne -- }
  37575. var JustOneMutex: THandle;
  37576. //[FUNCTION WndProcJustOne]
  37577. {$IFDEF ASM_VERSION}
  37578. {$ELSE ASM_VERSION} //Pascal
  37579. function WndProcJustOne( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean;
  37580. begin
  37581. Result := False;
  37582. case Msg.message of
  37583. WM_CLOSE{$ifndef wince}, WM_NCDESTROY{$endif}:
  37584. if LongBool( JustOneMutex ) and (Control.Handle = Msg.hwnd) then
  37585. begin
  37586. CloseHandle( JustOneMutex );
  37587. JustOneMutex := 0;
  37588. end;
  37589. end;
  37590. end;
  37591. {$ENDIF ASM_VERSION}
  37592. //[END WndProcJustOne]
  37593. //[FUNCTION JustOne]
  37594. {$IFDEF ASM_noVERSION}
  37595. function JustOne( Wnd: PControl; const Identifier : String ) : Boolean;
  37596. asm
  37597. PUSH EBX
  37598. PUSH ESI
  37599. XOR ESI, ESI
  37600. PUSH EDI
  37601. XCHG EBX, EAX
  37602. CALL EDX2PChar
  37603. PUSH EDX
  37604. PUSH 0
  37605. PUSH 1
  37606. PUSH ESI
  37607. MOV EDI, offset[CreateMutex]
  37608. CALL EDI
  37609. POP EDX
  37610. TEST EAX, EAX
  37611. JZ @@exit //
  37612. PUSH EAX
  37613. PUSH EAX
  37614. PUSH EDX
  37615. PUSH ESI
  37616. PUSH ESI
  37617. CALL EDI
  37618. MOV [JustOneMutex], EAX
  37619. TEST EAX, EAX
  37620. JE @@1 //
  37621. PUSH ESI
  37622. PUSH EAX
  37623. CALL WaitForSingleObject
  37624. SUB EAX, WAIT_TIMEOUT
  37625. JE @@1
  37626. INC ESI
  37627. @@1:
  37628. XCHG EAX, EBX
  37629. MOV EDX, offset[WndProcJustOne]
  37630. CALL TControl.AttachProc
  37631. CALL ReleaseMutex
  37632. CALL CloseHandle
  37633. @@exit:
  37634. XCHG EAX, ESI
  37635. POP EDI
  37636. POP ESI
  37637. POP EBX
  37638. end;
  37639. {$ELSE ASM_VERSION} //Pascal
  37640. function JustOne( Wnd: PControl; const Identifier : KOLString ) : Boolean;
  37641. var CritSecMutex : THandle;
  37642. DW : Longint;
  37643. begin
  37644. Result := False;
  37645. CritSecMutex := CreateMutex( nil, True, nil );
  37646. if CritSecMutex = 0 then Exit;
  37647. {$ifdef UNICODE_CTRLS}
  37648. JustOneMutex := CreateMutexW( nil, False, PKOLChar( Identifier ) );
  37649. {$else}
  37650. JustOneMutex := CreateMutex( nil, False, PChar( Identifier ) );
  37651. {$endif UNICODE_CTRLS}
  37652. if JustOneMutex <> 0 then
  37653. begin
  37654. DW := WaitForSingleObject( JustOneMutex, 0 );
  37655. Result := (DW <> WAIT_TIMEOUT);
  37656. end;
  37657. Wnd.AttachProc( WndProcJustOne );
  37658. CloseHandle( CritSecMutex );
  37659. end;
  37660. {$ENDIF ASM_VERSION}
  37661. //[END JustOne]
  37662. var
  37663. JustOneIdentifier: KOLString;
  37664. FoundOtherWnd: HWND;
  37665. function JustOneEnumWindowsProc( Wnd : HWnd; Identifier: PKOLChar ) : Boolean; {$ifdef wince}cdecl{$else}{$ifdef wince}cdecl{$else}stdcall{$endif}{$endif};
  37666. begin
  37667. Result:=GetProp(Wnd, Identifier) <> 1;
  37668. if not Result then begin
  37669. SetForegroundWindow(Wnd {$ifdef wince} or 1 {$endif});
  37670. JustOneIdentifier:='';
  37671. FoundOtherWnd:=Wnd;
  37672. end;
  37673. end;
  37674. function WndProcJustOneActivate( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean;
  37675. begin
  37676. Result := False;
  37677. if (Msg.message = WM_DESTROY) and (Control.fHandle = Msg.hwnd) then
  37678. RemoveProp(Msg.hwnd, PKOLChar(JustOneIdentifier));
  37679. end;
  37680. function JustOneActivate( Wnd: PControl; const Identifier : KOLString ) : HWND;
  37681. begin
  37682. JustOneIdentifier:=Identifier;
  37683. FoundOtherWnd:=0;
  37684. EnumWindows(@JustOneEnumWindowsProc, DWORD(PKOLChar(Identifier)));
  37685. Result:=FoundOtherWnd;
  37686. if FoundOtherWnd = 0 then begin
  37687. SetProp(Wnd.GetWindowHandle, PKOLChar(Identifier), 1);
  37688. Wnd.AttachProc(WndProcJustOneActivate);
  37689. end;
  37690. end;
  37691. {$ifndef wince}
  37692. { JustOneNotify }
  37693. var
  37694. OnAnotherInstance: TOnAnotherInstance;
  37695. JustOneMsg: DWORD;
  37696. //[FUNCTION WndProcJustOneNotify]
  37697. {$IFDEF ASM_VERSION}
  37698. {$ELSE ASM_VERSION} //Pascal
  37699. function WndProcJustOneNotify( Control: PControl; var Msg: TMsg; var Rslt: Integer ) : Boolean;
  37700. var Buf : array[0..MAX_PATH] of KOLChar;
  37701. begin
  37702. WndProcJustOne( Control, Msg, Rslt );
  37703. Result := False;
  37704. if Msg.message = JustOneMsg then
  37705. begin
  37706. Result := True;
  37707. if assigned( OnAnotherInstance ) then
  37708. begin
  37709. GetWindowText( Msg.lParam, Buf, MAX_PATH );
  37710. OnAnotherInstance( Buf );
  37711. end;
  37712. Rslt := 0;
  37713. end;
  37714. end;
  37715. {$ENDIF ASM_VERSION}
  37716. //[END WndProcJustOneNotify]
  37717. // Redefine here incorrectly declared BroadcastSystemMessage API function.
  37718. // It should not refer to BroadcastSystemMessageA, which is not present in
  37719. // earlier versions of Windows95, but to BroadcastSystemMessage, which is
  37720. // present in all Windows95/98/Me and NT/2K/XP.
  37721. //[API BroadcastSystemMessage]
  37722. function BroadcastSystemMessage(Flags: DWORD; Recipients: PDWORD;
  37723. uiMessage: UINT; wParam: WPARAM; lParam: LPARAM): Longint; {$ifdef wince}cdecl{$else}stdcall{$endif};
  37724. external user32 name 'BroadcastSystemMessage';
  37725. //[FUNCTION JustOneNotify]
  37726. {$IFDEF ASM_UNICODE}
  37727. {$ELSE ASM_VERSION} //Pascal
  37728. function JustOneNotify( Wnd: PControl; const Identifier : KOLString;
  37729. const aOnAnotherInstance: TOnAnotherInstance ) : Boolean;
  37730. var Recipients : DWord;
  37731. OldCap: String;
  37732. begin
  37733. Result := False;
  37734. JustOneMsg := RegisterWindowMessage( PKOLChar( 'Message.' + Identifier ) );
  37735. if JustOneMsg = 0 then Exit;
  37736. Result := JustOne( Wnd, Identifier );
  37737. if not Result then
  37738. begin
  37739. // Send a message to the first instance of applet
  37740. OldCap := Wnd.Caption;
  37741. Wnd.Caption := GetCommandLine;
  37742. if Wnd.GetWindowHandle <> 0 then
  37743. begin
  37744. Recipients := BSM_APPLICATIONS;
  37745. BroadcastSystemMessage( BSF_QUERY or BSF_IGNORECURRENTTASK, @Recipients,
  37746. JustOneMsg, 0, Wnd.fHandle );
  37747. end;
  37748. Wnd.Caption := OldCap;
  37749. end
  37750. else
  37751. begin
  37752. // Store event handler to notify this instance about another
  37753. // instance staring:
  37754. OnAnotherInstance := aOnAnotherInstance;
  37755. Wnd.AttachProc( WndProcJustOneNotify );
  37756. end;
  37757. end;
  37758. {$ENDIF ASM_VERSION}
  37759. //[END JustOneNotify]
  37760. {$endif wince}
  37761. ///////////////////////////////////////// STRING LIST OBJECT /////////////////
  37762. {$ENDIF WIN}
  37763. { TStrList }
  37764. //[function NewStrList]
  37765. function NewStrList: PStrList;
  37766. begin
  37767. {-}
  37768. New( Result, Create );
  37769. {+}
  37770. {++}(*
  37771. Result := PStrList.Create;
  37772. *){--}
  37773. end;
  37774. //[END NewStrList]
  37775. //[destructor TStrList.Destroy]
  37776. {$IFDEF ASM_VERSION}
  37777. {$ELSE ASM_VERSION} //Pascal
  37778. destructor TStrList.Destroy;
  37779. begin
  37780. Clear;
  37781. inherited;
  37782. end;
  37783. {$ENDIF ASM_VERSION}
  37784. //[procedure TStrList.Init]
  37785. procedure TStrList.Init;
  37786. begin
  37787. {$IFDEF _D2orD3}
  37788. inherited;
  37789. {$ENDIF}
  37790. fNameDelim := DefaultNameDelimiter;
  37791. end;
  37792. //[function TStrList.Add]
  37793. {$IFDEF ASM_VERSION}
  37794. {$ELSE ASM_VERSION} //Pascal
  37795. function TStrList.Add(const S: string): integer;
  37796. begin
  37797. Result := fCount;
  37798. Insert( Result, S );
  37799. end;
  37800. {$ENDIF ASM_VERSION}
  37801. //[procedure TStrList.AddStrings]
  37802. {$IFDEF ASM_VERSION}
  37803. {$ELSE ASM_VERSION} //Pascal
  37804. procedure TStrList.AddStrings(Strings: PStrList);
  37805. begin
  37806. SetText( Strings.Text, True );
  37807. end;
  37808. {$ENDIF ASM_VERSION}
  37809. //[procedure TStrList.Assign]
  37810. {$IFDEF ASM_VERSION}
  37811. {$ELSE ASM_VERSION} //Pascal
  37812. procedure TStrList.Assign(Strings: PStrList);
  37813. begin
  37814. Clear;
  37815. AddStrings( Strings );
  37816. end;
  37817. {$ENDIF ASM_VERSION}
  37818. //[procedure TStrList.Clear]
  37819. {$IFDEF ASM_VERSION}
  37820. {$ELSE ASM_VERSION} //Pascal
  37821. procedure TStrList.Clear;
  37822. var I: Integer;
  37823. begin
  37824. if fCount > 0 then
  37825. for I := fList.Count - 1 downto 0 do
  37826. Delete( I );
  37827. fList.Free;
  37828. fList := nil;
  37829. fCount := 0;
  37830. if fTextBuf <> nil then
  37831. begin
  37832. FreeMem( fTextBuf );
  37833. fTextBuf := nil;
  37834. fTextSiz := 0;
  37835. end;
  37836. end;
  37837. {$ENDIF ASM_VERSION}
  37838. //[procedure TStrList.Delete]
  37839. {$IFDEF ASM_VERSION}
  37840. {$ELSE ASM_VERSION} //Pascal
  37841. procedure TStrList.Delete(Idx: integer);
  37842. var P: DWORD;
  37843. El:Pointer;
  37844. begin
  37845. P := DWORD( fList.fItems[ Idx ] );
  37846. if (fTextBuf <> nil) and ( P >= DWORD( fTextBuf )) and
  37847. ( P < DWORD( fTextBuf ) + fTextSiz ) then
  37848. else
  37849. begin
  37850. El := FList.Items[ Idx ];
  37851. FreeMem( El );
  37852. end;
  37853. fList.Delete( Idx );
  37854. Dec( fCount );
  37855. end;
  37856. {$ENDIF ASM_VERSION}
  37857. //[procedure TStrList.DeleteLast]
  37858. procedure TStrList.DeleteLast;
  37859. begin
  37860. Delete( Count-1 );
  37861. end;
  37862. //[function TStrList.Get]
  37863. {$IFDEF ASM_VERSION}
  37864. {$ELSE ASM_VERSION} //Pascal
  37865. function TStrList.Get(Idx: integer): string;
  37866. begin
  37867. if fList <> nil then
  37868. Result := PChar( fList.Items[ Idx ] )
  37869. else Result := '';
  37870. end;
  37871. {$ENDIF ASM_VERSION}
  37872. //[function TStrList.GetPChars]
  37873. {$IFDEF ASM_VERSION}
  37874. {$ELSE ASM_VERSION} //Pascal
  37875. function TStrList.GetPChars(Idx: Integer): PChar;
  37876. begin
  37877. Result := PChar( fList.fItems[ Idx ] );
  37878. end;
  37879. {$ENDIF ASM_VERSION}
  37880. //[function TStrList.GetTextStr]
  37881. {$IFDEF ASM_VERSION}
  37882. {$ELSE ASM_VERSION} //Pascal
  37883. function TStrList.GetTextStr: string;
  37884. var
  37885. I, Len, Size: integer;
  37886. P: PChar;
  37887. begin
  37888. Size := 0;
  37889. for I := 0 to fCount - 1 do
  37890. Inc(Size, StrLen( PChar(fList.fItems[I]) ) +
  37891. {$IFDEF LIN} 1 {$ELSE} 2 {$ENDIF});
  37892. SetString(Result, nil, Size);
  37893. P := Pointer(Result);
  37894. for I := 0 to Count - 1 do
  37895. begin
  37896. Len := StrLen(PChar(fList.fItems[I]));
  37897. if (Len > 0) then
  37898. begin
  37899. System.Move(PChar(fList.fItems[I])^, P^, Len);
  37900. Inc(P, Len);
  37901. end;
  37902. P^ := #13;
  37903. Inc(P);
  37904. {$IFDEF WIN}
  37905. P^ := #10;
  37906. Inc(P);
  37907. {$ENDIF WIN}
  37908. end;
  37909. end;
  37910. {$ENDIF ASM_VERSION}
  37911. //[function TStrList.IndexOf]
  37912. {$IFDEF ASM_VERSION}
  37913. {$ELSE ASM_VERSION} //Pascal
  37914. function TStrList.IndexOf(const S: string): integer;
  37915. begin
  37916. for Result := 0 to fCount - 1 do
  37917. if (S = PChar( fList.Items[Result] )) then Exit;
  37918. Result := -1;
  37919. end;
  37920. {$ENDIF ASM_VERSION}
  37921. //[function TStrList.IndexOf]
  37922. function TStrList.IndexOf_NoCase(const S: string): integer;
  37923. begin
  37924. for Result := 0 to fCount - 1 do
  37925. if AnsiCompareStrNoCase( S, Items[Result] ) = 0 then Exit;
  37926. Result := -1;
  37927. end;
  37928. function TStrList.IndexOfStrL_NoCase( Str: PChar; L: Integer ): integer;
  37929. begin
  37930. for Result := 0 to fCount - 1 do
  37931. if (StrLen( PChar( fList.fItems[ Result ] ) ) = DWORD( L )) and
  37932. (StrLComp_NoCase( Str, PChar( fList.fItems[ Result ] ), L ) = 0) then Exit;
  37933. Result := -1;
  37934. end;
  37935. //[function TStrList.Find]
  37936. function TStrList.Find(const S: String; var Index: Integer): Boolean;
  37937. var
  37938. L, H, I, C: Integer;
  37939. begin
  37940. Result := FALSE;
  37941. L := 0;
  37942. H := FCount - 1;
  37943. while L <= H do
  37944. begin
  37945. I := (L + H) shr 1;
  37946. C := AnsiCompareStr( PChar( fList.Items[ I ] ), S );
  37947. if C < 0 then L := I + 1 else
  37948. begin
  37949. H := I - 1;
  37950. if C = 0 then
  37951. begin
  37952. Result := TRUE;
  37953. L := I;
  37954. end;
  37955. end;
  37956. end;
  37957. Index := L;
  37958. end;
  37959. //[procedure TStrList.Insert]
  37960. {$IFDEF ASM_VERSION}
  37961. {$ELSE ASM_VERSION} //Pascal
  37962. procedure TStrList.Insert(Idx: integer; const S: string);
  37963. var Mem: PChar;
  37964. L: Integer;
  37965. begin
  37966. if fList = nil then
  37967. fList := NewList;
  37968. L := Length( S ) + 1;
  37969. GetMem( Mem, L );
  37970. Mem[0] := #0;
  37971. if L > 1 then
  37972. System.Move( S[1], Mem[0], L );
  37973. fList.Insert( Idx, Mem );
  37974. Inc( fCount );
  37975. end;
  37976. {$ENDIF ASM_VERSION}
  37977. //[procedure TStrList.Move]
  37978. procedure TStrList.Move(CurIndex, NewIndex: integer);
  37979. begin
  37980. fList.MoveItem( CurIndex, NewIndex );
  37981. end;
  37982. //[procedure TStrList.Put]
  37983. {$IFDEF ASM_VERSION}
  37984. {$ELSE ASM_VERSION} //Pascal
  37985. procedure TStrList.Put(Idx: integer; const Value: string);
  37986. begin
  37987. Delete( Idx );
  37988. Insert( Idx, Value );
  37989. end;
  37990. {$ENDIF ASM_VERSION}
  37991. //[procedure TStrList.SetText]
  37992. {$IFDEF ASM_VERSION}
  37993. {$ELSE ASM_VERSION} //Pascal
  37994. //[procedure TStrList.SetText]
  37995. procedure TStrList.SetText(const S: string; Append2List: boolean);
  37996. var
  37997. P, TheLast : PChar;
  37998. L, I : Integer;
  37999. procedure AddTextBuf(Src: PChar; Len: DWORD);
  38000. var OldTextBuf, P: PChar;
  38001. I : Integer;
  38002. begin
  38003. if Src <> nil then
  38004. begin
  38005. OldTextBuf := fTextBuf;
  38006. GetMem( fTextBuf, fTextSiz + Len );
  38007. if fTextSiz <> 0 then
  38008. begin
  38009. System.Move( OldTextBuf^, fTextBuf^, fTextSiz );
  38010. for I := 0 to fCount - 1 do
  38011. begin
  38012. P := fList.fItems[ I ];
  38013. if (DWORD( P ) >= DWORD( OldTextBuf )) and
  38014. (DWORD( P ) < DWORD( OldTextBuf ) + fTextSiz) then
  38015. fList.fItems[ I ] := Pointer( DWORD( P ) - DWORD( OldTextBuf ) + DWORD( fTextBuf ) );
  38016. end;
  38017. FreeMem( OldTextBuf );
  38018. end;
  38019. System.Move( Src^, fTextBuf[ fTextSiz ], Len );
  38020. Inc( fTextSiz, Len );
  38021. end;
  38022. end;
  38023. begin
  38024. if not Append2List then Clear;
  38025. if S = '' then Exit;
  38026. L := fTextSiz;
  38027. AddTextBuf( PChar( S ), Length( S ) + 1 );
  38028. P := PChar( DWORD( fTextBuf ) + DWORD( L ) );
  38029. if fList = nil then
  38030. fList := NewList;
  38031. I := 0;
  38032. TheLast := P + Length( S );
  38033. while P^ <> #0 do
  38034. begin
  38035. Inc( I );
  38036. {$IFDEF WIN}
  38037. P := StrScanLen( P, #13, TheLast - P );
  38038. if P^ = #10 then
  38039. Inc( P );
  38040. {$ELSE LIN}
  38041. P := StrScanLen( P, #10, TheLast - P );
  38042. {$ENDIF}
  38043. end;
  38044. Inc( fCount, I );
  38045. if fList.fCapacity < fCount then
  38046. fList.Capacity := fCount;
  38047. P := PChar( DWORD( fTextBuf ) + DWORD( L ) );
  38048. while P^ <> #0 do
  38049. begin
  38050. fList.Add( P );
  38051. {$IFDEF WIN}
  38052. P := StrScanLen( P, #13, TheLast - P );
  38053. if PChar( P - 1 )^ = #13 then
  38054. PChar( P - 1 )^ := #0;
  38055. if P^ = #10 then Inc(P);
  38056. {$ELSE LIN}
  38057. P := StrScanLen( P, #10, TheLast - P );
  38058. {$ENDIF}
  38059. end;
  38060. end;
  38061. {$ENDIF ASM_VERSION}
  38062. //[procedure TStrList.SetUnixText]
  38063. procedure TStrList.SetUnixText(const S: String; Append2List: Boolean);
  38064. var S1: String;
  38065. begin
  38066. S1 := S;
  38067. NormalizeUnixText( S1 );
  38068. SetText( S1, Append2List );
  38069. end;
  38070. //[procedure TStrList.SetTextStr]
  38071. procedure TStrList.SetTextStr(const Value: string);
  38072. begin
  38073. SetText( Value, False );
  38074. end;
  38075. //[FUNCTION CompareStrListItems]
  38076. {$IFDEF ASM_VERSION}
  38077. {$ELSE ASM_VERSION} //Pascal
  38078. function CompareStrListItems( const Sender : Pointer; const e1, e2 : DWORD ) : Integer;
  38079. var S1, S2 : PChar;
  38080. begin
  38081. S1 := PStrList( Sender ).fList.Items[ e1 ];
  38082. S2 := PStrList( Sender ).fList.Items[ e2 ];
  38083. if PStrList( Sender ).fCaseSensitiveSort then
  38084. Result := StrComp( S1, S2 )
  38085. else
  38086. Result := StrComp( PChar( LowerCase( S1 ) ), PChar( LowerCase( S2 ) ) );
  38087. end;
  38088. {$ENDIF ASM_VERSION}
  38089. //[END CompareStrListItems]
  38090. //[FUNCTION CompareAnsiStrListItems]
  38091. {$IFDEF ASM_VERSION}
  38092. {$ELSE ASM_VERSION} //Pascal
  38093. function CompareAnsiStrListItems( const Sender : Pointer; const e1, e2 : DWORD ) : Integer;
  38094. var S1, S2 : PKOLChar;
  38095. begin
  38096. S1 := PStrList( Sender ).fList.Items[ e1 ];
  38097. S2 := PStrList( Sender ).fList.Items[ e2 ];
  38098. if PStrList( Sender ).fCaseSensitiveSort then
  38099. Result := _AnsiCompareStr( S1, S2 )
  38100. else
  38101. Result := _AnsiCompareStrNoCase( S1, S2 );
  38102. end;
  38103. {$ENDIF ASM_VERSION}
  38104. //[END CompareAnsiStrListItems]
  38105. {$IFNDEF ASM_VERSION}
  38106. //[procedure SwapStrListItems]
  38107. procedure SwapStrListItems( const Sender: Pointer; const e1, e2: DWORD );
  38108. begin
  38109. PStrList( Sender ).Swap( e1, e2 );
  38110. end;
  38111. {$ENDIF}
  38112. //[procedure TStrList.Sort]
  38113. {$IFDEF ASM_VERSION}
  38114. {$ELSE ASM_VERSION} //Pascal
  38115. procedure TStrList.Sort(CaseSensitive: Boolean);
  38116. begin
  38117. fCaseSensitiveSort := CaseSensitive;
  38118. SortData( @Self, fCount, @CompareStrListItems, @SwapStrListItems );
  38119. end;
  38120. {$ENDIF ASM_VERSION}
  38121. //[procedure TStrList.AnsiSort]
  38122. {$IFDEF ASM_VERSION}
  38123. {$ELSE ASM_VERSION} //Pascal
  38124. procedure TStrList.AnsiSort(CaseSensitive: Boolean);
  38125. begin
  38126. fCaseSensitiveSort := CaseSensitive;
  38127. SortData( @Self, fCount, @CompareAnsiStrListItems, @SwapStrListItems );
  38128. end;
  38129. {$ENDIF ASM_VERSION}
  38130. //[procedure TStrList.Swap]
  38131. procedure TStrList.Swap(Idx1, Idx2: Integer);
  38132. begin
  38133. fList.Swap( Idx1, Idx2 );
  38134. end;
  38135. //[function TStrList.Last]
  38136. function TStrList.Last: String;
  38137. begin
  38138. if Count = 0 then
  38139. Result := ''
  38140. else
  38141. Result := Items[ Count - 1 ];
  38142. end;
  38143. //-- code by Dod:
  38144. //[function TStrList.IndexOfName]
  38145. function TStrList.IndexOfName(AName: string): Integer;
  38146. var
  38147. i: Integer;
  38148. L: Integer;
  38149. begin
  38150. Result:=-1;
  38151. // Do not start search if empty string
  38152. L := Length( AName );
  38153. if L > 0 then
  38154. begin
  38155. AName := LowerCase( AName ) + fNameDelim;
  38156. Inc( L );
  38157. for i := 0 to fCount - 1 do
  38158. begin
  38159. // For optimization, check only list entry that begin with same letter as searched name
  38160. if StrLComp( PChar( LowerCase( ItemPtrs[ i ] ) ), PChar( AName ), L ) = 0 then
  38161. begin
  38162. Result:=i;
  38163. exit;
  38164. end;
  38165. end;
  38166. end;
  38167. end;
  38168. //-- code by Dod:
  38169. //[function TStrList.GetValue]
  38170. function TStrList.GetValue(const AName: string): string;
  38171. var
  38172. i: Integer;
  38173. begin
  38174. I := IndexOfName(AName);
  38175. if I >= 0
  38176. then Result := Copy(Items[i], Length(AName) + 2, Length(Items[i])-Length(AName)-1)
  38177. else Result := '';
  38178. end;
  38179. //-- code by Dod:
  38180. //[procedure TStrList.SetValue]
  38181. procedure TStrList.SetValue(const AName, Value: string);
  38182. var
  38183. I: Integer;
  38184. begin
  38185. I := IndexOfName(AName);
  38186. if i=-1
  38187. then Add( AName + fNameDelim + Value )
  38188. else Items[i] := AName + fNameDelim + Value;
  38189. end;
  38190. //[function TStrList.GetLineName]
  38191. function TStrList.GetLineName(Idx: Integer): String;
  38192. var s: KOLString;
  38193. begin
  38194. s := Items[ Idx ];
  38195. Result := Parse( s, fNameDelim );
  38196. end;
  38197. //[procedure TStrList.SetLineName]
  38198. procedure TStrList.SetLineName(Idx: Integer; const NV: String);
  38199. begin
  38200. Items[ Idx ] := NV + fNameDelim + LineValue[ Idx ];
  38201. end;
  38202. //[function TStrList.GetLineValue]
  38203. function TStrList.GetLineValue(Idx: Integer): string;
  38204. var s: KOLString;
  38205. begin
  38206. s := Items[ Idx ];
  38207. Parse( s, fNameDelim );
  38208. Result := s;
  38209. end;
  38210. //[procedure TStrList.SetLineValue]
  38211. procedure TStrList.SetLineValue(Idx: Integer; const Value: string);
  38212. begin
  38213. Items[ Idx ] := LineName[ Idx ] + fNameDelim + Value;
  38214. end;
  38215. function TStrList.Join( const sep: String ): String;
  38216. var
  38217. I, Len, Size: integer;
  38218. P: PChar;
  38219. begin
  38220. Size := 0;
  38221. for I := 0 to Count - 1 do
  38222. Inc(Size, Integer( StrLen( ItemPtrs[I] ) ) + Length(Sep));
  38223. SetString(Result, nil, Size);
  38224. P := @ Result[ 1 ];
  38225. for I := 0 to Count - 1 do
  38226. begin
  38227. Len := StrLen( ItemPtrs[I] );
  38228. if (Len > 0) then
  38229. begin
  38230. System.Move( ItemPtrs[I]^, P^, Len);
  38231. Inc(P, Len);
  38232. end;
  38233. P := StrPCopy(P, Sep);
  38234. inc( P, Length( Sep ) ); // + by Korneev Ivan
  38235. end;
  38236. end;
  38237. {$IFDEF WIN_GDI}
  38238. //[function TStrList.AppendToFile]
  38239. {$IFDEF ASM_UNICODE}
  38240. {$ELSE ASM_VERSION} //Pascal
  38241. function TStrList.AppendToFile(const FileName: KOLstring): Boolean;
  38242. var F: HFile;
  38243. Buf: String;
  38244. L: Integer;
  38245. begin
  38246. F := FileCreate( FileName, ofOpenWrite or ofOpenAlways );
  38247. Result := F <> INVALID_HANDLE_VALUE;
  38248. if Result then
  38249. begin
  38250. FileSeek( F, 0, spEnd );
  38251. Buf := Text;
  38252. L := Length( Buf );
  38253. FileWrite( F, Buf[ 1 ], L );
  38254. FileClose( F );
  38255. end;
  38256. end;
  38257. {$ENDIF ASM_VERSION}
  38258. //[function TStrList.LoadFromFile]
  38259. {$IFDEF ASM_UNICODE}
  38260. {$ELSE ASM_VERSION} //Pascal
  38261. function TStrList.LoadFromFile(const FileName: KOLstring): Boolean;
  38262. var Buf: String;
  38263. F: HFile;
  38264. Sz: Integer;
  38265. begin
  38266. F := FileCreate( FileName, ofOpenRead or ofShareDenyWrite or ofOpenExisting );
  38267. Result := F <> INVALID_HANDLE_VALUE;
  38268. if Result then
  38269. begin
  38270. Sz := GetFileSize( F, nil );
  38271. SetString( Buf, nil, Sz );
  38272. FileRead( F, Buf[1], Sz );
  38273. FileClose( F );
  38274. SetText( Buf, False );
  38275. end;
  38276. end;
  38277. {$ENDIF ASM_VERSION}
  38278. //[procedure TStrList.LoadFromStream]
  38279. {$IFDEF ASM_VERSION}
  38280. {$ELSE ASM_VERSION} //Pascal
  38281. procedure TStrList.LoadFromStream(Stream: PStream; Append2List: boolean);
  38282. var Buf: String;
  38283. Sz: Integer;
  38284. begin
  38285. Sz := Stream.Size - Stream.Position;
  38286. SetString( Buf, nil, Sz );
  38287. Stream.Read( Buf[1], Sz );
  38288. SetText( Buf, Append2List );
  38289. end;
  38290. {$ENDIF ASM_VERSION}
  38291. //[procedure TStrList.MergeFromFile]
  38292. {$IFDEF ASM_VERSION}
  38293. {$ELSE ASM_VERSION} //Pascal
  38294. procedure TStrList.MergeFromFile(const FileName: KOLstring);
  38295. var TmpStream: PStream;
  38296. begin
  38297. TmpStream := NewReadFileStream( FileName );
  38298. LoadFromStream( TmpStream, True );
  38299. TmpStream.Free;
  38300. end;
  38301. {$ENDIF ASM_VERSION}
  38302. //[function TStrList.SaveToFile]
  38303. {$IFDEF ASM_UNICODE}
  38304. {$ELSE ASM_VERSION} //Pascal
  38305. function TStrList.SaveToFile(const FileName: KOLstring): Boolean;
  38306. var F: HFile;
  38307. Buf: String;
  38308. begin
  38309. F := FileCreate( FileName, ofOpenWrite or ofCreateAlways );
  38310. Result := F <> INVALID_HANDLE_VALUE;
  38311. if Result then
  38312. begin
  38313. Buf := Text;
  38314. FileWrite( F, Buf[ 1 ], Length( Buf ) );
  38315. SetEndOfFile( F ); // necessary! - V.K.
  38316. FileClose( F );
  38317. end;
  38318. end;
  38319. {$ENDIF ASM_VERSION}
  38320. //[procedure TStrList.SaveToStream]
  38321. {$IFDEF ASM_VERSION}
  38322. {$ELSE ASM_VERSION} //Pascal
  38323. procedure TStrList.SaveToStream(Stream: PStream);
  38324. var S: string;
  38325. L: Integer;
  38326. begin
  38327. S := GetTextStr;
  38328. L := Length( S );
  38329. if L <> 0 then
  38330. Stream.Write( S[1], L );
  38331. end;
  38332. {$ENDIF ASM_VERSION}
  38333. {$ENDIF WIN_GDI}
  38334. ////////////////////////////////// EXTENDED STRING LIST OBJECT ////////////////
  38335. {-}
  38336. //[procedure WStrCopy]
  38337. {$IFDEF ASM_VERSION}
  38338. procedure WStrCopy( Dest, Src: PWideChar );
  38339. asm
  38340. PUSH EDI
  38341. PUSH ESI
  38342. MOV ESI,EAX
  38343. MOV EDI,EDX
  38344. OR ECX, -1
  38345. XOR EAX, EAX
  38346. REPNE SCASW
  38347. NOT ECX
  38348. MOV EDI,ESI
  38349. MOV ESI,EDX
  38350. REP MOVSW
  38351. POP ESI
  38352. POP EDI
  38353. end;
  38354. {$ELSE ASM_VERSION} //Pascal
  38355. procedure WStrCopy( Dest, Src: PWideChar );
  38356. var
  38357. counter : longint;
  38358. Begin
  38359. counter := 0;
  38360. while Src[counter] <> #0 do
  38361. begin
  38362. Dest[counter] := Src[counter];
  38363. Inc(counter);
  38364. end;
  38365. Dest[counter] := #0;
  38366. end;
  38367. {$ENDIF ASM_VERSION}
  38368. procedure WStrLCopy( Dest, Src: PWideChar; MaxLen: Integer );
  38369. begin
  38370. while MaxLen > 0 do
  38371. begin
  38372. Dest^ := Src^;
  38373. if Src^ = #0 then break;
  38374. inc( Dest );
  38375. inc( Src );
  38376. dec( MaxLen );
  38377. if MaxLen = 0 then
  38378. Dest^ := Src^;
  38379. end;
  38380. end;
  38381. //[function WStrCmp]
  38382. {$IFDEF ASM_VERSION}
  38383. function WStrCmp( W1, W2: PWideChar ): Integer;
  38384. asm
  38385. PUSH ESI
  38386. PUSH EDI
  38387. XCHG ESI, EAX
  38388. MOV EDI, EDX
  38389. XOR EAX, EAX
  38390. @@loop: LODSW
  38391. MOVZX EDX, word ptr [EDI]
  38392. INC EDI
  38393. INC EDI
  38394. CMP EAX, EDX
  38395. JNE @@exit
  38396. TEST EAX, EAX
  38397. JNZ @@loop
  38398. @@exit: SUB EAX, EDX
  38399. POP EDI
  38400. POP ESI
  38401. end;
  38402. {$ELSE ASM_VERSION} //Pascal
  38403. function WStrCmp( W1, W2: PWideChar ): Integer;
  38404. var
  38405. counter: Integer;
  38406. Begin
  38407. counter := 0;
  38408. While W1[counter] = W2[counter] do
  38409. Begin
  38410. if (W2[counter] = #0) or (W1[counter] = #0) then
  38411. break;
  38412. Inc(counter);
  38413. end;
  38414. Result := ord(W1[counter]) - ord(W2[counter]);
  38415. end;
  38416. {$ENDIF ASM_VERSION}
  38417. { TStrListEx }
  38418. //[function NewStrListEx]
  38419. function NewStrListEx: PStrListEx;
  38420. begin
  38421. {-}
  38422. new( Result, Create );
  38423. {+}
  38424. {++}(*
  38425. Result := PStrListEx.Create;
  38426. *){--}
  38427. end;
  38428. //[END NewStrListEx]
  38429. //[destructor TStrListEx.Destroy]
  38430. destructor TStrListEx.Destroy;
  38431. var Obj: PList;
  38432. begin
  38433. Obj := FObjects;
  38434. inherited;
  38435. Obj.Free;
  38436. end;
  38437. //[function TStrListEx.GetObjects]
  38438. function TStrListEx.GetObjects(Idx: Integer): DWORD;
  38439. begin
  38440. Result := 0;
  38441. if FObjects.fCount > Idx then
  38442. Result := DWORD( FObjects.Items[ Idx ] );
  38443. end;
  38444. //[function TStrListEx.GetObjectCount]
  38445. function TStrListEx.GetObjectCount: Integer;
  38446. begin
  38447. Result := FObjects.Count;
  38448. end;
  38449. //[procedure TStrListEx.SetObjects]
  38450. procedure TStrListEx.SetObjects(Idx: Integer; const Value: DWORD);
  38451. begin
  38452. ProvideObjCapacity( Idx + 1 );
  38453. FObjects.Items[ Idx ] := Pointer( Value );
  38454. end;
  38455. //[procedure TStrListEx.Init]
  38456. procedure TStrListEx.Init;
  38457. begin
  38458. inherited;
  38459. FObjects := NewList;
  38460. end;
  38461. //[procedure SwapStrListExItems]
  38462. procedure SwapStrListExItems( const Sender: Pointer; const e1, e2: DWORD );
  38463. begin
  38464. PStrListEx( Sender ).Swap( e1, e2 );
  38465. end;
  38466. //[procedure TStrListEx.AnsiSort]
  38467. procedure TStrListEx.AnsiSort(CaseSensitive: Boolean);
  38468. begin
  38469. fCaseSensitiveSort := CaseSensitive;
  38470. SortData( @Self, fCount, @CompareAnsiStrListItems, @SwapStrListExItems );
  38471. end;
  38472. //[procedure TStrListEx.Sort]
  38473. procedure TStrListEx.Sort(CaseSensitive: Boolean);
  38474. begin
  38475. fCaseSensitiveSort := CaseSensitive;
  38476. SortData( @Self, fCount, @CompareStrListItems, @SwapStrListExItems );
  38477. end;
  38478. //[procedure TStrListEx.Move]
  38479. procedure TStrListEx.Move(CurIndex, NewIndex: integer);
  38480. begin
  38481. // move string
  38482. fList.MoveItem( CurIndex, NewIndex );
  38483. // move object
  38484. if FObjects.fCount >= Min( CurIndex, NewIndex ) then
  38485. begin
  38486. ProvideObjCapacity( max( CurIndex, NewIndex ) + 1 );
  38487. FObjects.MoveItem( CurIndex, NewIndex );
  38488. end;
  38489. end;
  38490. //[procedure TStrListEx.Swap]
  38491. procedure TStrListEx.Swap(Idx1, Idx2: Integer);
  38492. begin
  38493. // swap strings
  38494. fList.Swap( Idx1, Idx2 );
  38495. // swap objects
  38496. if FObjects.fCount >= Min( Idx1, Idx2 ) then
  38497. begin
  38498. ProvideObjCapacity( max( Idx1, Idx2 ) + 1 );
  38499. FObjects.Swap( Idx1, Idx2 );
  38500. end;
  38501. end;
  38502. //[procedure TStrListEx.ProvideObjCapacity]
  38503. procedure TStrListEx.ProvideObjCapacity(NewCap: Integer);
  38504. begin
  38505. if FObjects.FCount < NewCap then
  38506. begin
  38507. FObjects.Capacity := NewCap;
  38508. FillChar( FObjects.FItems[ FObjects.FCount ],
  38509. (FObjects.Capacity - FObjects.Count) * sizeof( Pointer ), #0 );
  38510. FObjects.FCount := NewCap;
  38511. end;
  38512. end;
  38513. //[procedure TStrListEx.AddStrings]
  38514. procedure TStrListEx.AddStrings(Strings: PStrListEx);
  38515. var I: Integer;
  38516. begin
  38517. I := Count;
  38518. if Strings.FObjects.fCount > 0 then
  38519. ProvideObjCapacity( Count );
  38520. inherited AddStrings( Strings );
  38521. if Strings.FObjects.fCount > 0 then
  38522. begin
  38523. ProvideObjCapacity( I + Strings.FObjects.fCount );
  38524. System.Move( Strings.FObjects.FItems[ 0 ],
  38525. FObjects.FItems[ I ],
  38526. Sizeof( Pointer ) * Strings.FObjects.fCount );
  38527. end;
  38528. end;
  38529. //[procedure TStrListEx.Assign]
  38530. procedure TStrListEx.Assign(Strings: PStrListEx);
  38531. begin
  38532. inherited Assign( Strings );
  38533. FObjects.Assign( Strings.FObjects );
  38534. end;
  38535. //[procedure TStrListEx.Clear]
  38536. procedure TStrListEx.Clear;
  38537. begin
  38538. inherited;
  38539. FObjects.Clear;
  38540. end;
  38541. //[procedure TStrListEx.Delete]
  38542. procedure TStrListEx.Delete(Idx: integer);
  38543. begin
  38544. inherited;
  38545. if FObjects.fCount > Idx then // mdw: '>=' -> '>'
  38546. FObjects.Delete( Idx );
  38547. end;
  38548. //[function TStrListEx.LastObj]
  38549. function TStrListEx.LastObj: DWORD;
  38550. begin
  38551. if Count = 0 then
  38552. Result := 0
  38553. else
  38554. Result := Objects[ Count - 1 ];
  38555. end;
  38556. //[function TStrListEx.AddObject]
  38557. function TStrListEx.AddObject(const S: String; Obj: DWORD): Integer;
  38558. begin
  38559. Result := Count;
  38560. InsertObject( Count, S, Obj );
  38561. end;
  38562. //[procedure TStrListEx.InsertObject]
  38563. procedure TStrListEx.InsertObject(Before: Integer; const S: String; Obj: DWORD);
  38564. begin
  38565. Insert( Before, S );
  38566. ProvideObjCapacity( Before );
  38567. FObjects.Insert( Before, Pointer( Obj ) );
  38568. end;
  38569. //[function TStrListEx.IndexOfObj]
  38570. function TStrListEx.IndexOfObj( Obj: Pointer ): Integer;
  38571. begin
  38572. Result := FObjects.IndexOf( Obj );
  38573. end;
  38574. //[function WStrLen]
  38575. {$IFDEF ASM_VERSION}
  38576. function WStrLen( W: PWideChar ): Integer;
  38577. asm
  38578. XCHG EDI, EAX
  38579. XCHG EDX, EAX
  38580. OR ECX, -1
  38581. XOR EAX, EAX
  38582. CMP EAX, EDI
  38583. JE @@exit0
  38584. REPNE SCASW
  38585. DEC EAX
  38586. DEC EAX
  38587. SUB EAX, ECX
  38588. @@exit0:
  38589. MOV EDI, EDX
  38590. end;
  38591. {$ELSE ASM_VERSION} //Pascal
  38592. function WStrLen( W: PWideChar ): Integer;
  38593. var i : Integer;
  38594. begin
  38595. i:=0;
  38596. while W[i]<>#0 do inc(i);
  38597. Result:=i;
  38598. end;
  38599. {$ENDIF ASM_VERSION}
  38600. {$IFDEF _D3orHigher} {$ifdef win32}
  38601. function UTF8_2WideString( const s: AnsiString ): WideString;
  38602. var Buffer: PWideChar;
  38603. L: Integer;
  38604. begin
  38605. L := Length( s ) + 1;
  38606. GetMem( Buffer, L * 2 );
  38607. MultiByteToWideChar( CP_UTF8, 0, PChar( s ), L-1,
  38608. Buffer, L );
  38609. Result := Buffer;
  38610. FreeMem( Buffer );
  38611. end;
  38612. {$endif win32} {$ENDIF _D3orHigher}
  38613. {------------------------------------------------------------------------------)
  38614. | |
  38615. | T W S t r L i s t |
  38616. | |
  38617. (------------------------------------------------------------------------------}
  38618. {$IFDEF WIN_GDI}
  38619. {$IFNDEF _D2}
  38620. //[function NewWStrList]
  38621. function NewWStrList: PWStrList;
  38622. begin
  38623. new( Result, Create );
  38624. end;
  38625. { TWStrList }
  38626. //[function TWStrList.Add]
  38627. function TWStrList.Add(const W: WideString): Integer;
  38628. begin
  38629. Result := Count;
  38630. Insert( Result, W );
  38631. end;
  38632. //[procedure TWStrList.AddWStrings]
  38633. procedure TWStrList.AddWStrings(WL: PWStrList);
  38634. begin
  38635. Text := Text + WL.Text;
  38636. end;
  38637. //[function TWStrList.AppendToFile]
  38638. function TWStrList.AppendToFile(const Filename: KOLString): Boolean;
  38639. var Strm: PStream;
  38640. begin
  38641. Strm := NewReadWriteFileStream( Filename );
  38642. Result := Strm.Handle <> INVALID_HANDLE_VALUE;
  38643. if Result then
  38644. begin
  38645. Strm.Position := Strm.Size;
  38646. SaveToStream( Strm );
  38647. end;
  38648. Strm.Free;
  38649. end;
  38650. //[procedure TWStrList.Assign]
  38651. procedure TWStrList.Assign(WL: PWStrList);
  38652. begin
  38653. Text := WL.Text;
  38654. end;
  38655. //[procedure TWStrList.Clear]
  38656. procedure TWStrList.Clear;
  38657. var I: Integer;
  38658. P: Pointer;
  38659. begin
  38660. for I := 0 to Count-1 do
  38661. begin
  38662. P := fList.Items[ I ];
  38663. if P <> nil then
  38664. if not( (P >= fText) and (P <= fText + fTextBufSz) ) then
  38665. FreeMem( P );
  38666. end;
  38667. if fText <> nil then
  38668. FreeMem( fText );
  38669. fText := nil;
  38670. fTextBufSz := 0;
  38671. fList.Clear;
  38672. end;
  38673. //[procedure TWStrList.Delete]
  38674. procedure TWStrList.Delete(Idx: Integer);
  38675. var P: Pointer;
  38676. begin
  38677. P := fList.Items[ Idx ];
  38678. if P <> nil then
  38679. if not( (P >= fText) and (P <= fText + fTextBufSz) ) then
  38680. FreeMem( P );
  38681. fList.Delete( Idx );
  38682. end;
  38683. //[destructor TWStrList.Destroy]
  38684. destructor TWStrList.Destroy;
  38685. begin
  38686. Clear;
  38687. fList.Free;
  38688. inherited;
  38689. end;
  38690. //[function TWStrList.GetCount]
  38691. function TWStrList.GetCount: Integer;
  38692. begin
  38693. Result := fList.Count;
  38694. end;
  38695. //[function TWStrList.GetItems]
  38696. function TWStrList.GetItems(Idx: Integer): WideString;
  38697. begin
  38698. Result := PWideChar( fList.Items[ Idx ] );
  38699. end;
  38700. //[function TWStrList.GetPtrs]
  38701. function TWStrList.GetPtrs(Idx: Integer): PWideChar;
  38702. begin
  38703. Result := fList.Items[ Idx ];
  38704. end;
  38705. //[function TWStrList.GetText]
  38706. function TWStrList.GetText: WideString;
  38707. const
  38708. EoL: array[ 0..5 ] of Char = ( #13, #0, #10, #0, #0, #0 );
  38709. var L, I: Integer;
  38710. P, Dest: Pointer;
  38711. begin
  38712. L := 0;
  38713. for I := 0 to Count-1 do
  38714. begin
  38715. P := fList.Items[ I ];
  38716. if P <> nil then
  38717. L := L + WStrLen( P ) + 2
  38718. else
  38719. L := L + 2;
  38720. end;
  38721. SetLength( Result, L );
  38722. Dest := PWideChar( Result );
  38723. for I := 0 to Count-1 do
  38724. begin
  38725. P := fList.Items[ I ];
  38726. if P <> nil then
  38727. begin
  38728. WStrCopy( Dest, P );
  38729. Dest := Pointer( cardinal( Dest ) + cardinal(WStrLen( P )) * 2 );
  38730. end;
  38731. WStrCopy( Dest, Pointer( @ EoL[ 0 ] ) );
  38732. Dest := Pointer( cardinal( Dest ) + 4 );
  38733. end;
  38734. end;
  38735. //[procedure TWStrList.Init]
  38736. procedure TWStrList.Init;
  38737. begin
  38738. fList := NewList;
  38739. end;
  38740. //[procedure TWStrList.Insert]
  38741. procedure TWStrList.Insert(Idx: Integer; const W: WideString);
  38742. var P: Pointer;
  38743. begin
  38744. while Idx > Count do // by Misha Shar. a.k.a. kreit
  38745. fList.Add( nil );
  38746. GetMem( P, (Length( W ) + 1) * Sizeof(WideChar) );
  38747. fList.Insert( Idx, P );
  38748. WStrCopy( P, PWideChar( W ) );
  38749. end;
  38750. //[function TWStrList.LoadFromFile]
  38751. function TWStrList.LoadFromFile(const Filename: KOLString): Boolean;
  38752. begin
  38753. Clear;
  38754. Result := MergeFromFile( Filename );
  38755. end;
  38756. //[procedure TWStrList.LoadFromStream]
  38757. procedure TWStrList.LoadFromStream(Strm: PStream);
  38758. begin
  38759. Clear;
  38760. MergeFromStream( Strm );
  38761. end;
  38762. //[function TWStrList.MergeFromFile]
  38763. function TWStrList.MergeFromFile(const Filename: KOLString): Boolean;
  38764. var Strm: PStream;
  38765. begin
  38766. Strm := NewReadFileStream( Filename );
  38767. Result := Strm.Handle <> INVALID_HANDLE_VALUE;
  38768. if Result then
  38769. MergeFromStream( Strm );
  38770. Strm.Free;
  38771. end;
  38772. //[procedure TWStrList.MergeFromStream]
  38773. procedure TWStrList.MergeFromStream(Strm: PStream);
  38774. var Buf: WideString;
  38775. L: Integer;
  38776. begin
  38777. L := Strm.Size - Strm.Position;
  38778. Assert( L mod 1 = 0, 'Wide strings streams must be of even length in bytes.' );
  38779. if L = 0 then Exit;
  38780. SetLength( Buf, L div 2 );
  38781. Strm.Read( Buf[ 1 ], L );
  38782. Text := Text + Buf;
  38783. end;
  38784. //[procedure TWStrList.Move]
  38785. procedure TWStrList.Move(IdxOld, IdxNew: Integer);
  38786. begin
  38787. fList.MoveItem( IdxOld, IdxNew );
  38788. end;
  38789. //[function TWStrList.SaveToFile]
  38790. function TWStrList.SaveToFile(const Filename: KOLString): Boolean;
  38791. var Strm: PStream;
  38792. begin
  38793. Strm := NewWriteFileStream( Filename );
  38794. Result := Strm.Handle <> INVALID_HANDLE_VALUE;
  38795. if Result then
  38796. SaveToStream( Strm );
  38797. Strm.Free;
  38798. end;
  38799. //[procedure TWStrList.SaveToStream]
  38800. procedure TWStrList.SaveToStream(Strm: PStream);
  38801. var Buf, Dest: PWideChar;
  38802. I, L, Sz: Integer;
  38803. P: Pointer;
  38804. begin
  38805. Sz := 0;
  38806. for I := 0 to Count-1 do
  38807. begin
  38808. P := fList.Items[ I ];
  38809. if P <> nil then
  38810. Sz := Sz + WStrLen( P ) * 2 + 4
  38811. else
  38812. Sz := Sz + 4;
  38813. end;
  38814. GetMem( Buf, Sz );
  38815. Dest := Buf;
  38816. for I := 0 to Count-1 do
  38817. begin
  38818. P := fList.Items[ I ];
  38819. if P <> nil then
  38820. begin
  38821. L := WStrLen( P );
  38822. System.Move( P^, Dest^, L * 2 );
  38823. Inc( Dest, L );
  38824. end;
  38825. Dest^ := #13;
  38826. Inc( Dest );
  38827. Dest^ := #10;
  38828. Inc( Dest );
  38829. end;
  38830. Strm.Write( Buf^, Sz );
  38831. FreeMem( Buf );
  38832. end;
  38833. //[procedure TWStrList.SetItems]
  38834. procedure TWStrList.SetItems(Idx: Integer; const Value: WideString);
  38835. var P: Pointer;
  38836. begin
  38837. while Idx > Count-1 do
  38838. fList.Add( nil );
  38839. if WStrLen( ItemPtrs[ Idx ] ) > Length( Value ) then // fixed by kreit
  38840. WStrCopy( ItemPtrs[ Idx ], PWideChar( Value ) )
  38841. else
  38842. begin
  38843. P := fList.Items[ Idx ];
  38844. if P <> nil then
  38845. if not ((P >= fText) and (P <= fText + fTextBufSz)) then
  38846. FreeMem( P );
  38847. GetMem( P, (Length( Value ) + 1) * Sizeof(WideChar) );
  38848. fList.Items[ Idx ] := P;
  38849. WStrCopy( P, PWideChar( Value ) );
  38850. end;
  38851. end;
  38852. //[procedure TWStrList.SetText]
  38853. procedure TWStrList.SetText(const Value: WideString);
  38854. var L, N: Integer;
  38855. P: PWideChar;
  38856. begin
  38857. Clear;
  38858. if Value = '' then Exit;
  38859. L := (Length( Value ) + 1) * Sizeof( WideChar );
  38860. GetMem( fText, L );
  38861. System.Move( Value[ 1 ], fText^, L );
  38862. fTextBufSz := Length( Value );
  38863. N := 0;
  38864. P := fText;
  38865. while Word( P^ ) <> 0 do
  38866. begin
  38867. if (Word( P^ ) = 13) then
  38868. begin
  38869. Inc( N );
  38870. PWord( P )^ := 0;
  38871. if Word( P[ 1 ] ) = 10 then
  38872. Inc( P );
  38873. end
  38874. else
  38875. if (Word( P^ ) = 10) and ((P = fText) or (Word( (P-1)^ ) <> 0)) then
  38876. begin
  38877. Inc( N );
  38878. PWord( P )^ := 0;
  38879. end;
  38880. Inc( P );
  38881. end;
  38882. fList.Capacity := N;
  38883. P := fText;
  38884. while P < fText + fTextBufSz do
  38885. begin
  38886. fList.Add( P );
  38887. while Word( P^ ) <> 0 do Inc( P );
  38888. Inc( P );
  38889. if Word( P^ ) = 10 then Inc( P );
  38890. end;
  38891. end;
  38892. //[function CompareWStrListItems]
  38893. function CompareWStrListItems( const Sender: Pointer; const Idx1, Idx2: DWORD ): Integer;
  38894. var WL: PWStrList;
  38895. begin
  38896. WL := Sender;
  38897. Result := WStrCmp( WL.fList.Items[ Idx1 ], WL.fList.Items[ Idx2 ] );
  38898. end;
  38899. //[function CompareWStrListItems_UpperCase]
  38900. function CompareWStrListItems_UpperCase( const Sender: Pointer; const Idx1, Idx2: DWORD ): Integer;
  38901. var WL: PWStrList;
  38902. L1, L2: Integer;
  38903. begin
  38904. WL := Sender;
  38905. L1 := WStrLen( WL.fList.Items[ Idx1 ] );
  38906. L2 := WStrLen( WL.fList.Items[ Idx2 ] );
  38907. if Length( WL.fTmp1 ) < L1 then
  38908. SetLength( WL.fTmp1, L1 + 1 );
  38909. if Length( WL.fTmp2 ) < L2 then
  38910. SetLength( WL.fTmp2, L2 + 1 );
  38911. if L1 > 0 then
  38912. Move( WL.fList.Items[ Idx1 ]^, WL.fTmp1[ 1 ], (L1 + 1) * 2 )
  38913. else
  38914. WL.fTmp1[ 1 ] := #0;
  38915. if L2 > 0 then
  38916. Move( WL.fList.Items[ Idx2 ]^, WL.fTmp2[ 1 ], (L2 + 1) * 2 )
  38917. else
  38918. WL.fTmp2[ 1 ] := #0;
  38919. CharUpperBuffW( PWideChar( WL.fTmp1 ), L1 );
  38920. CharUpperBuffW( PWideChar( WL.fTmp2 ), L2 );
  38921. Result := WStrCmp( PWideChar( WL.fTmp1 ), PWideChar( WL.fTmp2 ) );
  38922. end;
  38923. //[procedure SwapWStrListItems]
  38924. procedure SwapWStrListItems( const Sender: Pointer; const Idx1, Idx2: DWORD );
  38925. var WL: PWStrList;
  38926. begin
  38927. WL := Sender;
  38928. WL.Swap( Idx1, Idx2 );
  38929. end;
  38930. //[procedure TWStrList.Sort]
  38931. procedure TWStrList.Sort( CaseSensitive: Boolean );
  38932. begin
  38933. if CaseSensitive then
  38934. SortData( @ Self, Count, @CompareWStrListItems, @SwapWStrListItems )
  38935. else
  38936. begin
  38937. SortData( @ Self, Count, @CompareWStrListItems_UpperCase, @SwapWStrListItems );
  38938. fTmp1 := '';
  38939. fTmp2 := '';
  38940. end;
  38941. end;
  38942. //[procedure TWStrList.Swap]
  38943. procedure TWStrList.Swap(Idx1, Idx2: Integer);
  38944. begin
  38945. fList.Swap( Idx1, Idx2 );
  38946. end;
  38947. function TWStrList.IndexOf( const s: WideString ): Integer;
  38948. var i: Integer;
  38949. p: PWideChar;
  38950. begin
  38951. for i := 0 to Count-1 do
  38952. begin
  38953. p := ItemPtrs[ i ];
  38954. if (p <> nil) and
  38955. (WStrCmp( PWideChar( s ), p ) = 0) then
  38956. begin
  38957. Result := i;
  38958. Exit;
  38959. end;
  38960. end;
  38961. Result := -1;
  38962. end;
  38963. //[function NewWStrListEx]
  38964. function NewWStrListEx: PWStrListEx;
  38965. begin
  38966. new( Result, Create );
  38967. end;
  38968. { TWStrListEx }
  38969. //[function TWStrListEx.AddObject]
  38970. function TWStrListEx.AddObject(const S: WideString; Obj: DWORD): Integer;
  38971. begin
  38972. Result := Count;
  38973. InsertObject( Count, S, Obj );
  38974. end;
  38975. //[procedure TWStrListEx.AddWStrings]
  38976. procedure TWStrListEx.AddWStrings(WL: PWStrListEx);
  38977. var I: Integer;
  38978. begin
  38979. I := Count;
  38980. if WL.FObjects.Count > 0 then
  38981. ProvideObjectsCapacity( Count );
  38982. inherited AddWStrings( WL );
  38983. if WL.FObjects.Count > 0 then
  38984. begin
  38985. ProvideObjectsCapacity( I + WL.FObjects.Count );
  38986. System.Move( WL.FObjects.FItems[ 0 ],
  38987. FObjects.FItems[ I ],
  38988. Sizeof( Pointer ) * WL.FObjects.Count );
  38989. end;
  38990. end;
  38991. //[procedure TWStrListEx.Assign]
  38992. procedure TWStrListEx.Assign(WL: PWStrListEx);
  38993. begin
  38994. inherited Assign( WL );
  38995. FObjects.Assign( WL.FObjects );
  38996. end;
  38997. //[procedure TWStrListEx.Clear]
  38998. procedure TWStrListEx.Clear;
  38999. begin
  39000. inherited Clear;
  39001. FObjects.Clear;
  39002. end;
  39003. //[procedure TWStrListEx.Delete]
  39004. procedure TWStrListEx.Delete(Idx: Integer);
  39005. begin
  39006. inherited Delete( Idx );
  39007. if FObjects.FCount >= Idx then
  39008. FObjects.Delete( Idx );
  39009. end;
  39010. //[destructor TWStrListEx.Destroy]
  39011. destructor TWStrListEx.Destroy;
  39012. begin
  39013. fObjects.Free;
  39014. inherited;
  39015. end;
  39016. //[function TWStrListEx.GetObjects]
  39017. function TWStrListEx.GetObjects(Idx: Integer): DWORD;
  39018. begin
  39019. Result := DWORD( fObjects.Items[ Idx ] );
  39020. end;
  39021. //[function TWStrListEx.IndexOfObj]
  39022. function TWStrListEx.IndexOfObj(Obj: Pointer): Integer;
  39023. begin
  39024. Result := FObjects.IndexOf( Obj );
  39025. end;
  39026. //[procedure TWStrListEx.Init]
  39027. procedure TWStrListEx.Init;
  39028. begin
  39029. inherited;
  39030. fObjects := NewList;
  39031. end;
  39032. //[procedure TWStrListEx.InsertObject]
  39033. procedure TWStrListEx.InsertObject(Before: Integer; const S: WideString;
  39034. Obj: DWORD);
  39035. begin
  39036. Insert( Before, S );
  39037. FObjects.Insert( Before, Pointer( Obj ) );
  39038. end;
  39039. //[procedure TWStrListEx.Move]
  39040. procedure TWStrListEx.Move(IdxOld, IdxNew: Integer);
  39041. begin
  39042. fList.MoveItem( IdxOld, IdxNew );
  39043. if FObjects.FCount >= Min( IdxOld, IdxNew ) then
  39044. begin
  39045. ProvideObjectsCapacity( Max( IdxOld, IdxNew ) + 1 );
  39046. FObjects.MoveItem( IdxOld, IdxNew );
  39047. end;
  39048. end;
  39049. //[procedure TWStrListEx.ProvideObjectsCapacity]
  39050. procedure TWStrListEx.ProvideObjectsCapacity(NewCap: Integer);
  39051. begin
  39052. if fObjects.Capacity >= NewCap then Exit;
  39053. fObjects.Capacity := NewCap;
  39054. FillChar( FObjects.FItems[ FObjects.Count ],
  39055. (FObjects.Capacity - FObjects.Count) * Sizeof( Pointer ), #0 );
  39056. FObjects.FCount := NewCap;
  39057. end;
  39058. //[procedure TWStrListEx.SetObjects]
  39059. procedure TWStrListEx.SetObjects(Idx: Integer; const Value: DWORD);
  39060. begin
  39061. ProvideObjectsCapacity( Idx + 1 );
  39062. fObjects.Items[ Idx ] := Pointer( Value );
  39063. end;
  39064. {$ENDIF}
  39065. {$ENDIF WIN_GDI}
  39066. {+}
  39067. //////////////////////////////////////////////////////////////////////////
  39068. // S O R T I N G
  39069. //////////////////////////////////////////////////////////////////////////
  39070. { -- qsort -- }
  39071. //[PROCEDURE SortData]
  39072. {$IFDEF ASM_VERSION} // translated to BASM by Kladov Vladimir
  39073. procedure SortData( const Data: Pointer; const uNElem: Dword;
  39074. const CompareFun: TCompareEvent;
  39075. const SwapProc: TSwapEvent );
  39076. asm
  39077. CMP EDX, 2
  39078. JL @@exit
  39079. PUSH EAX // [EBP-4] = Data
  39080. PUSH ECX // [EBP-8] = CompareFun
  39081. PUSH EBX // EBX = pivotP
  39082. XOR EBX, EBX
  39083. INC EBX // EBX = 1 to pass to qSortHelp as PivotP
  39084. MOV EAX, EDX // EAX = nElem
  39085. CALL @@qSortHelp
  39086. POP EBX
  39087. POP ECX
  39088. POP ECX
  39089. @@exit:
  39090. POP EBP
  39091. RET 4
  39092. @@qSortHelp:
  39093. PUSH EBX // EBX (in) = PivotP
  39094. PUSH ESI // ESI = leftP
  39095. PUSH EDI // EDI = rightP
  39096. @@TailRecursion:
  39097. CMP EAX, 2
  39098. JG @@2
  39099. JNE @@exit_qSortHelp
  39100. LEA ECX, [EBX+1]
  39101. MOV EDX, EBX
  39102. CALL @@Compare
  39103. JLE @@exit_qSortHelp
  39104. @@swp_exit:
  39105. CALL @@Swap
  39106. @@exit_qSortHelp:
  39107. POP EDI
  39108. POP ESI
  39109. POP EBX
  39110. RET
  39111. // ESI = leftP
  39112. // EDI = rightP
  39113. @@2: LEA EDI, [EAX+EBX-1]
  39114. MOV ESI, EAX
  39115. SHR ESI, 1
  39116. ADD ESI, EBX
  39117. MOV ECX, ESI
  39118. MOV EDX, EDI
  39119. CALL @@CompareLeSwap
  39120. MOV EDX, EBX
  39121. CALL @@Compare
  39122. JG @@4
  39123. CALL @@Swap
  39124. JMP @@5
  39125. @@4: MOV ECX, EBX
  39126. MOV EDX, EDI
  39127. CALL @@CompareLeSwap
  39128. @@5:
  39129. CMP EAX, 3
  39130. JNE @@6
  39131. MOV EDX, EBX
  39132. MOV ECX, ESI
  39133. JMP @@swp_exit
  39134. @@6: // classic Horae algorithm
  39135. PUSH EAX // EAX = pivotEnd
  39136. LEA EAX, [EBX+1]
  39137. MOV ESI, EAX
  39138. @@repeat:
  39139. MOV EDX, ESI
  39140. MOV ECX, EBX
  39141. CALL @@Compare
  39142. JG @@while2
  39143. @@while1:
  39144. JNE @@7
  39145. MOV EDX, ESI
  39146. MOV ECX, EAX
  39147. CALL @@Swap
  39148. INC EAX
  39149. @@7:
  39150. CMP ESI, EDI
  39151. JGE @@qBreak
  39152. INC ESI
  39153. JMP @@repeat
  39154. @@while2:
  39155. CMP ESI, EDI
  39156. JGE @@until
  39157. MOV EDX, EBX
  39158. MOV ECX, EDI
  39159. CALL @@Compare
  39160. JGE @@8
  39161. DEC EDI
  39162. JMP @@while2
  39163. @@8:
  39164. MOV EDX, ESI
  39165. MOV ECX, EDI
  39166. PUSHFD
  39167. CALL @@Swap
  39168. POPFD
  39169. JE @@until
  39170. INC ESI
  39171. DEC EDI
  39172. @@until:
  39173. CMP ESI, EDI
  39174. JL @@repeat
  39175. @@qBreak:
  39176. MOV EDX, ESI
  39177. MOV ECX, EBX
  39178. CALL @@Compare
  39179. JG @@9
  39180. INC ESI
  39181. @@9:
  39182. PUSH EBX // EBX = PivotTemp
  39183. PUSH ESI // ESI = leftTemp
  39184. DEC ESI
  39185. @@while3:
  39186. CMP EBX, EAX
  39187. JGE @@while3_break
  39188. CMP ESI, EAX
  39189. JL @@while3_break
  39190. MOV EDX, EBX
  39191. MOV ECX, ESI
  39192. CALL @@Swap
  39193. INC EBX
  39194. DEC ESI
  39195. JMP @@while3
  39196. @@while3_break:
  39197. POP ESI
  39198. POP EBX
  39199. MOV EDX, EAX
  39200. POP EAX // EAX = nElem
  39201. PUSH EDI // EDI = lNum
  39202. MOV EDI, ESI
  39203. SUB EDI, EDX
  39204. ADD EAX, EBX
  39205. SUB EAX, ESI
  39206. PUSH EBX
  39207. PUSH EAX
  39208. CMP EAX, EDI
  39209. JGE @@10
  39210. MOV EBX, ESI
  39211. CALL @@qSortHelp
  39212. POP EAX
  39213. MOV EAX, EDI
  39214. POP EBX
  39215. JMP @@11
  39216. @@10: MOV EAX, EDI
  39217. CALL @@qSortHelp
  39218. POP EAX
  39219. POP EBX
  39220. MOV EBX, ESI
  39221. @@11:
  39222. POP EDI
  39223. JMP @@TailRecursion
  39224. @@Compare:
  39225. PUSH EAX
  39226. PUSH EDX
  39227. PUSH ECX
  39228. MOV EAX, [EBP-4]
  39229. DEC EDX
  39230. DEC ECX
  39231. CALL dword ptr [EBP-8]
  39232. POP ECX
  39233. POP EDX
  39234. TEST EAX, EAX
  39235. POP EAX
  39236. RET
  39237. @@CompareLeSwap:
  39238. CALL @@Compare
  39239. JG @@ret
  39240. @@Swap: PUSH EAX
  39241. PUSH EDX
  39242. PUSH ECX
  39243. MOV EAX, [EBP-4]
  39244. DEC EDX
  39245. DEC ECX
  39246. CALL dword ptr [SwapProc]
  39247. POP ECX
  39248. POP EDX
  39249. TEST EAX, EAX
  39250. POP EAX
  39251. @@ret:
  39252. RET
  39253. end;
  39254. {$ELSE ASM_VERSION} //Pascal
  39255. procedure SortData( const Data: Pointer; const uNElem: Dword;
  39256. const CompareFun: TCompareEvent;
  39257. const SwapProc: TSwapEvent );
  39258. { uNElem - number of elements to sort }
  39259. function Compare( const e1, e2 : DWord ) : Integer;
  39260. begin
  39261. Result := CompareFun( Data, e1 - 1, e2 - 1 );
  39262. end;
  39263. procedure Swap( const e1, e2 : DWord );
  39264. begin
  39265. SwapProc( Data, e1 - 1, e2 - 1 );
  39266. end;
  39267. procedure qSortHelp(pivotP: Dword; nElem: Dword);
  39268. label
  39269. TailRecursion,
  39270. qBreak;
  39271. var
  39272. leftP, rightP, pivotEnd, pivotTemp, leftTemp: Dword;
  39273. lNum: Dword;
  39274. retval: integer;
  39275. begin
  39276. TailRecursion:
  39277. if (nElem <= 2) then
  39278. begin
  39279. if (nElem = 2) then
  39280. begin
  39281. rightP := pivotP +1;
  39282. retval := Compare(pivotP,rightP);
  39283. if (retval > 0) then Swap(pivotP,rightP);
  39284. end;
  39285. exit;
  39286. end;
  39287. rightP := (nElem -1) + pivotP;
  39288. leftP := (nElem shr 1) + pivotP;
  39289. { sort pivot, left, and right elements for "median of 3" }
  39290. retval := Compare(leftP,rightP);
  39291. if (retval > 0) then Swap(leftP, rightP);
  39292. retval := Compare(leftP,pivotP);
  39293. if (retval > 0) then
  39294. Swap(leftP, pivotP)
  39295. else
  39296. begin
  39297. retval := Compare(pivotP,rightP);
  39298. if retval > 0 then Swap(pivotP, rightP);
  39299. end;
  39300. if (nElem = 3) then
  39301. begin
  39302. Swap(pivotP, leftP);
  39303. exit;
  39304. end;
  39305. { now for the classic Horae algorithm }
  39306. pivotEnd := pivotP + 1;
  39307. leftP := pivotEnd;
  39308. repeat
  39309. retval := Compare(leftP, pivotP);
  39310. while (retval <= 0) do
  39311. begin
  39312. if (retval = 0) then
  39313. begin
  39314. Swap(leftP, pivotEnd);
  39315. Inc(pivotEnd);
  39316. end;
  39317. if (leftP < rightP) then
  39318. Inc(leftP)
  39319. else
  39320. goto qBreak;
  39321. retval := Compare(leftP, pivotP);
  39322. end; {while}
  39323. while (leftP < rightP) do
  39324. begin
  39325. retval := Compare(pivotP, rightP);
  39326. if (retval < 0) then
  39327. Dec(rightP)
  39328. else
  39329. begin
  39330. Swap(leftP, rightP);
  39331. if (retval <> 0) then
  39332. begin
  39333. Inc(leftP);
  39334. Dec(rightP);
  39335. end;
  39336. break;
  39337. end;
  39338. end; {while}
  39339. until (leftP >= rightP);
  39340. qBreak:
  39341. retval := Compare(leftP,pivotP);
  39342. if (retval <= 0) then Inc(leftP);
  39343. leftTemp := leftP -1;
  39344. pivotTemp := pivotP;
  39345. while ((pivotTemp < pivotEnd) and (leftTemp >= pivotEnd)) do
  39346. begin
  39347. Swap(pivotTemp, leftTemp);
  39348. Inc(pivotTemp);
  39349. Dec(leftTemp);
  39350. end; {while}
  39351. lNum := (leftP - pivotEnd);
  39352. nElem := ((nElem + pivotP) -leftP);
  39353. if (nElem < lNum) then
  39354. begin
  39355. qSortHelp(leftP, nElem);
  39356. nElem := lNum;
  39357. end
  39358. else
  39359. begin
  39360. qSortHelp(pivotP, lNum);
  39361. pivotP := leftP;
  39362. end;
  39363. goto TailRecursion;
  39364. end; {qSortHelp }
  39365. begin
  39366. if (uNElem < 2) then exit; { nothing to sort }
  39367. qSortHelp(1, uNElem);
  39368. end;
  39369. {$ENDIF ASM_VERSION}
  39370. //[END SortData]
  39371. //[FUNCTION CompareIntegers]
  39372. {$IFDEF ASM_VERSION}
  39373. {$ELSE ASM_VERSION} //Pascal
  39374. function CompareIntegers( const Sender : Pointer; const e1, e2 : DWORD ) : Integer;
  39375. var I1, I2 : Integer;
  39376. begin
  39377. I1 := PInteger( DWORD( Sender ) + e1 * Sizeof( Integer ) )^;
  39378. I2 := PInteger( DWORD( Sender ) + e2 * Sizeof( Integer ) )^;
  39379. Result := 0;
  39380. if I1 < I2 then Result := -1
  39381. else
  39382. if I1 > I2 then Result := 1;
  39383. end;
  39384. {$ENDIF ASM_VERSION}
  39385. //[END CompareIntegers]
  39386. //[FUNCTION CompareDwords]
  39387. {$IFDEF ASM_VERSION}
  39388. {$ELSE ASM_VERSION} //Pascal
  39389. function CompareDwords( const Sender : Pointer; const e1, e2 : DWORD ) : Integer;
  39390. var I1, I2 : DWord;
  39391. begin
  39392. I1 := PDWORD( DWORD( Sender ) + e1 * Sizeof( Integer ) )^;
  39393. I2 := PDWORD( DWORD( Sender ) + e2 * Sizeof( Integer ) )^;
  39394. Result := 0;
  39395. if I1 < I2 then Result := -1
  39396. else
  39397. if I1 > I2 then Result := 1;
  39398. end;
  39399. {$ENDIF ASM_VERSION}
  39400. //[END CompareDwords]
  39401. //[PROCEDURE SwapIntegers]
  39402. {$IFDEF ASM_VERSION}
  39403. {$ELSE ASM_VERSION} //Pascal
  39404. procedure SwapIntegers( const Sender : Pointer; const e1, e2 : DWORD );
  39405. var Tmp : Integer;
  39406. begin
  39407. Tmp := PInteger( DWORD( Sender ) + e1 * SizeOf( Integer ) )^;
  39408. PInteger( DWORD( Sender ) + e1 * Sizeof( Integer ) )^ :=
  39409. PInteger( DWORD( Sender ) + e2 * Sizeof( Integer ) )^;
  39410. PInteger( DWORD( Sender ) + e2 * Sizeof( Integer ) )^ := Tmp;
  39411. end;
  39412. {$ENDIF ASM_VERSION}
  39413. //[END SwapIntegers]
  39414. //[procedure SortIntegerArray]
  39415. procedure SortIntegerArray( var A : array of Integer );
  39416. begin
  39417. SortData( @A[ 0 ], High( A ) - Low( A ) + 1, @CompareIntegers, @SwapIntegers );
  39418. end;
  39419. procedure SwapListItems( const L: Pointer; const e1, e2: DWORD );
  39420. begin
  39421. PList( L ).Swap( e1, e2 );
  39422. end;
  39423. //[procedure SortDwordArray]
  39424. procedure SortDwordArray( var A : array of DWORD );
  39425. begin
  39426. SortData( @A[ 0 ], High( A ) - Low( A ) + 1, @CompareDwords, @SwapIntegers );
  39427. end;
  39428. {$IFDEF WIN_GDI}
  39429. { -- status bar implementation -- }
  39430. //[FUNCTION _NewStatusbar]
  39431. {$IFDEF ASM_VERSION}
  39432. {$ELSE ASM_VERSION} //Pascal
  39433. function _NewStatusbar( AParent: PControl ): PControl;
  39434. var Style: DWORD;
  39435. begin
  39436. Style := WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or 3 or WS_VISIBLE;
  39437. {if AParent.CanResize then
  39438. Style := Style or SBARS_SIZEGRIP;}
  39439. if AParent.fSizeGrip then
  39440. Style := (Style or SBARS_SIZEGRIP) and not 3;
  39441. Result := _NewCommonControl( AParent, STATUSCLASSNAME,
  39442. Style, FALSE, nil );
  39443. with Result.fBoundsRect do
  39444. begin
  39445. Left := 0;
  39446. Right := 0;
  39447. Top := 0;
  39448. Bottom := 0;
  39449. end;
  39450. Result.fAlign := caBottom;
  39451. Result.fNotUseAlign := True;
  39452. {$IFDEF TEST_VERSION}
  39453. Result.fTag := DWORD( PChar( 'Status bar' ) );
  39454. {$ENDIF}
  39455. InitCommonControlSizeNotify( Result );
  39456. {$ifdef wince}
  39457. Result.Perform(CCM_SETVERSION, COMCTL32_VERSION, 0);
  39458. {$endif wince}
  39459. end;
  39460. {$ENDIF ASM_VERSION}
  39461. //[END _NewStatusbar]
  39462. //[procedure TControl.SetStatusText]
  39463. {$IFDEF ASM_VERSION}
  39464. {$ELSE ASM_VERSION} //Pascal
  39465. procedure TControl.SetStatusText(Index: Integer; Value: PKOLChar);
  39466. var ch: Integer;
  39467. R : TRect;
  39468. N, I, L, W : Integer;
  39469. WidthsBuf: array[ 0..254 ] of Integer;
  39470. begin
  39471. if fStatusCtl = nil then
  39472. begin
  39473. ch := GetClientHeight;
  39474. fStatusCtl := _NewStatusBar( @Self );
  39475. fStatusWnd := fStatusCtl.GetWindowHandle;
  39476. fStatusCtl.Perform( SB_SIMPLE, Integer( LongBool( Index = 255 ) ), 0 );
  39477. GetWindowRect( fStatusWnd, R );
  39478. fClientBottom := R.Bottom - R.Top;
  39479. SetClientHeight( ch );
  39480. SendMessage( fStatusWnd, WM_SIZE, 0, 0 );
  39481. end;
  39482. if Index < 255 then
  39483. begin
  39484. N := SendMessage( fStatusWnd, SB_GETPARTS, 0, 0 );
  39485. if N <= Index then
  39486. begin
  39487. W := Width;
  39488. L := W div (Index + 1);
  39489. W := L;
  39490. for I := 0 to Index - 1 do
  39491. begin
  39492. WidthsBuf[ I ] := W;
  39493. Inc( W, L );
  39494. end;
  39495. WidthsBuf[ Index ] := -1;
  39496. SendMessage( fStatusWnd, SB_SETPARTS, Index + 1, Integer( @WidthsBuf[ 0 ] ) );
  39497. end;
  39498. SendMessage( fStatusWnd, SB_SIMPLE, 0, 0 );
  39499. end;
  39500. SendMessage( fStatusWnd,
  39501. {$IFDEF UNICODE_CTRLS} SB_SETTEXTW {$ELSE} SB_SETTEXT {$ENDIF}, Index, Integer( Value ) );
  39502. end;
  39503. {$ENDIF ASM_VERSION}
  39504. //[function TControl.GetStatusText]
  39505. {$IFDEF ASM_VERSION}
  39506. {$ELSE ASM_VERSION} //Pascal
  39507. function TControl.GetStatusText( Index: Integer ): PKOLChar;
  39508. var L, I: Integer;
  39509. Msg: DWORD;
  39510. begin
  39511. Result := nil;
  39512. if fStatusWnd = 0 then Exit;
  39513. if fStatusTxt <> nil then
  39514. FreeMem( fStatusTxt );
  39515. fStatusTxt := nil;
  39516. Msg := SB_GETTEXTLENGTH;
  39517. I := Index;
  39518. if Index = 255 then
  39519. begin
  39520. Msg := WM_GETTEXTLENGTH;
  39521. I := 0;
  39522. end;
  39523. L := SendMessage( fStatusWnd, Msg, I, 0 ) and $FFFF;
  39524. if L > 0 then
  39525. begin
  39526. GetMem( fStatusTxt, (L + 1)*Sizeof(KOLChar) );
  39527. fStatusTxt[ L ] := #0;
  39528. Msg := {$IFDEF UNICODE_CTRLS} SB_GETTEXTW {$ELSE} SB_GETTEXT {$ENDIF};
  39529. if Index = 255 then
  39530. Msg := WM_GETTEXT;
  39531. SendMessage( fStatusWnd, Msg, I, Integer( fStatusTxt ) );
  39532. end;
  39533. Result := fStatusTxt;
  39534. end;
  39535. {$ENDIF ASM_VERSION}
  39536. //[procedure TControl.RemoveStatus]
  39537. {$IFDEF ASM_VERSION}
  39538. {$ELSE ASM_VERSION} //Pascal
  39539. procedure TControl.RemoveStatus;
  39540. var ch: Integer;
  39541. begin
  39542. if fStatusCtl = nil then Exit;
  39543. ch := ClientHeight;
  39544. fStatusWnd := 0;
  39545. fStatusCtl.Free;
  39546. fStatusCtl := nil;
  39547. fClientBottom := 0;
  39548. ClientHeight := ch;
  39549. end;
  39550. {$ENDIF ASM_VERSION}
  39551. //[function TControl.StatusPanelCount]
  39552. {$IFDEF ASM_VERSION}
  39553. {$ELSE ASM_VERSION} //Pascal
  39554. function TControl.StatusPanelCount: Integer;
  39555. begin
  39556. Result := 0;
  39557. if fStatusWnd = 0 then Exit;
  39558. Result := SendMessage( fStatusWnd, SB_GETPARTS, 0, 0 );
  39559. end;
  39560. {$ENDIF ASM_VERSION}
  39561. //[function TControl.GetStatusPanelX]
  39562. {$IFDEF ASM_VERSION}
  39563. {$ELSE ASM_VERSION} //Pascal
  39564. function TControl.GetStatusPanelX(Idx: Integer): Integer;
  39565. var Buf: array[0..254] of Integer;
  39566. N : Integer;
  39567. begin
  39568. Result := 0;
  39569. if fStatusWnd = 0 then Exit;
  39570. N := SendMessage( fStatusWnd, SB_GETPARTS, 255, Integer( @Buf[ 0 ] ) );
  39571. if N <= Idx then Exit;
  39572. Result := Buf[ Idx ];
  39573. end;
  39574. {$ENDIF ASM_VERSION}
  39575. //[procedure TControl.SetStatusPanelX]
  39576. {$IFDEF ASM_VERSION}
  39577. {$ELSE ASM_VERSION} //Pascal
  39578. procedure TControl.SetStatusPanelX(Idx: Integer; const Value: Integer);
  39579. var Buf: array[0..254] of Integer;
  39580. N : Integer;
  39581. begin
  39582. if fStatusWnd = 0 then Exit;
  39583. N := SendMessage( fStatusWnd, SB_GETPARTS, 255, Integer( @Buf[ 0 ] ) );
  39584. if N <= Idx then Exit;
  39585. Buf[ Idx ] := Value;
  39586. SendMessage( fStatusWnd, SB_SETPARTS, N, Integer( @Buf[ 0 ] ) );
  39587. end;
  39588. {$ENDIF ASM_VERSION}
  39589. //[procedure TControl.SetColor1]
  39590. procedure TControl.SetColor1(const Value: TColor);
  39591. begin
  39592. fColor1 := Value;
  39593. Invalidate;
  39594. end;
  39595. //[procedure TControl.SetColor2]
  39596. procedure TControl.SetColor2(const Value: TColor);
  39597. begin
  39598. fColor2 := Value;
  39599. Invalidate;
  39600. end;
  39601. //[procedure TControl.SetGradientLayout]
  39602. procedure TControl.SetGradientLayout(const Value: TGradientLayout);
  39603. begin
  39604. FGradientLayout := Value;
  39605. Invalidate;
  39606. end;
  39607. //[procedure TControl.SetGradientStyle]
  39608. procedure TControl.SetGradientStyle(const Value: TGradientStyle);
  39609. begin
  39610. FGradientStyle := Value;
  39611. Invalidate;
  39612. end;
  39613. { -- Image List -- }
  39614. //*
  39615. {$IFDEF USE_CONSTRUCTORS}
  39616. //[function NewImageList]
  39617. function NewImageList( AOwner: PControl ): PImageList;
  39618. begin
  39619. new( Result, CreateImageList( AOwner ) );
  39620. end;
  39621. //[END NewImageList]
  39622. {$ELSE not_USE_CONSTRUCTORS}
  39623. //[function NewImageList]
  39624. function NewImageList( AOwner: PControl ): PImageList;
  39625. begin
  39626. {*************} DoInitCommonControls( ICC_WIN95_CLASSES );
  39627. {-}
  39628. New( Result, Create );
  39629. {+}
  39630. {++}(*Result := TImageList.Create;*){--}
  39631. Result.FAllocBy := 1;
  39632. Result.FMasked := True;
  39633. Result.fBkColor := clNone;
  39634. //ImageList_SetBkColor( Result.FHandle, CLR_NONE );
  39635. Result.FImgWidth := 32;
  39636. Result.FImgHeight := 32;
  39637. Result.FColors := ilcDefault;
  39638. if AOwner = nil then exit;
  39639. Result.fNext := PImageList( AOwner.fImageList );
  39640. if AOwner.fImageList <> nil then
  39641. PImageList( AOwner.fImageList ).fPrev := Result;
  39642. Result.FControl := AOwner;
  39643. {$IFDEF USE_AUTOFREE4CONTROLS}
  39644. AOwner.Add2AutoFree( Result );
  39645. {$ENDIF}
  39646. AOwner.fImageList := Result;
  39647. end;
  39648. {$ENDIF}
  39649. {$ifdef win32}
  39650. //[API ImageList_XXX]
  39651. function ImageList_Create; {$ifdef wince}cdecl{$else}stdcall{$endif}; external cctrl name 'ImageList_Create';
  39652. function ImageList_Destroy; external cctrl name 'ImageList_Destroy';
  39653. function ImageList_GetImageCount; external cctrl name 'ImageList_GetImageCount';
  39654. function ImageList_SetImageCount; external cctrl name 'ImageList_SetImageCount';
  39655. function ImageList_Add; external cctrl name 'ImageList_Add';
  39656. function ImageList_ReplaceIcon; external cctrl name 'ImageList_ReplaceIcon';
  39657. function ImageList_SetBkColor; external cctrl name 'ImageList_SetBkColor';
  39658. function ImageList_GetBkColor; external cctrl name 'ImageList_GetBkColor';
  39659. function ImageList_SetOverlayImage; external cctrl name 'ImageList_SetOverlayImage';
  39660. function ImageList_Draw; external cctrl name 'ImageList_Draw';
  39661. function ImageList_Replace; external cctrl name 'ImageList_Replace';
  39662. function ImageList_AddMasked; external cctrl name 'ImageList_AddMasked';
  39663. function ImageList_DrawEx; external cctrl name 'ImageList_DrawEx';
  39664. function ImageList_Remove; external cctrl name 'ImageList_Remove';
  39665. function ImageList_GetIcon; external cctrl name 'ImageList_GetIcon';
  39666. {$IFDEF UNICODE_CTRLS}
  39667. function ImageList_LoadImage; external cctrl name 'ImageList_LoadImageW';
  39668. {$ELSE}
  39669. function ImageList_LoadImage; external cctrl name 'ImageList_LoadImageA';
  39670. {$ENDIF}
  39671. function ImageList_BeginDrag; external cctrl name 'ImageList_BeginDrag';
  39672. function ImageList_EndDrag; external cctrl name 'ImageList_EndDrag';
  39673. function ImageList_DragEnter; external cctrl name 'ImageList_DragEnter';
  39674. function ImageList_DragLeave; external cctrl name 'ImageList_DragLeave';
  39675. function ImageList_DragMove; external cctrl name 'ImageList_DragMove';
  39676. function ImageList_SetDragCursorImage; external cctrl name 'ImageList_SetDragCursorImage';
  39677. function ImageList_DragShowNolock; external cctrl name 'ImageList_DragShowNolock';
  39678. function ImageList_GetDragImage; external cctrl name 'ImageList_GetDragImage';
  39679. function ImageList_GetIconSize; external cctrl name 'ImageList_GetIconSize';
  39680. function ImageList_SetIconSize; external cctrl name 'ImageList_SetIconSize';
  39681. function ImageList_GetImageInfo; external cctrl name 'ImageList_GetImageInfo';
  39682. function ImageList_Merge; external cctrl name 'ImageList_Merge';
  39683. //[function ImageList_AddIcon]
  39684. function ImageList_AddIcon(ImageList: HImageList; Icon: HIcon): Integer;
  39685. begin
  39686. Result := ImageList_ReplaceIcon(ImageList, -1, Icon);
  39687. end;
  39688. //[function Index2OverlayMask]
  39689. function Index2OverlayMask(Index: Integer): Integer;
  39690. begin
  39691. Result := Index shl 8;
  39692. end;
  39693. { macros }
  39694. //[procedure ImageList_RemoveAll]
  39695. procedure ImageList_RemoveAll(ImageList: HImageList); {$ifdef wince}cdecl{$else}stdcall{$endif};
  39696. begin
  39697. ImageList_Remove(ImageList, -1);
  39698. end;
  39699. //[function ImageList_ExtractIcon]
  39700. function ImageList_ExtractIcon(Instance: THandle; ImageList: HImageList;
  39701. Image: Integer): HIcon; {$ifdef wince}cdecl{$else}stdcall{$endif};
  39702. begin
  39703. Result := ImageList_GetIcon(ImageList, Image, 0);
  39704. end;
  39705. //[function ImageList_LoadBitmap]
  39706. function ImageList_LoadBitmap(Instance: THandle; Bmp: PKOLChar;
  39707. CX, Grow: Integer; Mask: TColorRef): HImageList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  39708. begin
  39709. Result := ImageList_LoadImage(Instance, Bmp, CX, Grow, Mask, IMAGE_BITMAP, 0);
  39710. end;
  39711. {$endif win32}
  39712. //[procedure FreeBmp]
  39713. procedure FreeBmp( Bmp: HBitmap );
  39714. begin
  39715. DeleteObject( Bmp );
  39716. end;
  39717. //[function LoadBmp]
  39718. function LoadBmp( Instance: Integer; Rsrc: PKOLChar; MasterObj: PObj ): HBitmap;
  39719. begin
  39720. Result := LoadBitmap( Instance, Rsrc );
  39721. MasterObj.Add2AutoFreeEx( TObjectMethod( MakeMethod( Pointer( Result ), @ FreeBmp ) ) );
  39722. end;
  39723. { TImageList }
  39724. //*
  39725. //[function TImageList.Add]
  39726. function TImageList.Add(Bmp, Msk: HBitmap): Integer;
  39727. begin
  39728. Result := -1;
  39729. if not HandleNeeded then Exit;
  39730. Result := ImageList_Add( FHandle, Bmp, Msk );
  39731. end;
  39732. //*
  39733. //[function TImageList.AddIcon]
  39734. function TImageList.AddIcon(Ico: HIcon): Integer;
  39735. {var Bmp : HBitmap;
  39736. DC : HDC;}
  39737. begin
  39738. Result := -1;
  39739. if ImgWidth = 0 then
  39740. ImgWidth := 32;
  39741. if ImgHeight = 0 then
  39742. ImgHeight := 32;
  39743. if not HandleNeeded then Exit;
  39744. Result := ImageList_AddIcon( fHandle, Ico );
  39745. end;
  39746. //*
  39747. //[function TImageList.AddMasked]
  39748. function TImageList.AddMasked(Bmp: HBitmap; Color: TColor): Integer;
  39749. begin
  39750. Result := -1;
  39751. if not HandleNeeded then Exit;
  39752. Result := ImageList_AddMasked( FHandle, Bmp, Color2RGB( Color ) );
  39753. end;
  39754. //+
  39755. //[procedure TImageList.Clear]
  39756. procedure TImageList.Clear;
  39757. begin
  39758. Handle := 0;
  39759. end;
  39760. //*
  39761. //[procedure TImageList.Delete]
  39762. procedure TImageList.Delete(Idx: Integer);
  39763. begin
  39764. if FHandle = 0 then Exit;
  39765. ImageList_Remove( FHandle, Idx );
  39766. end;
  39767. //[destructor TImageList.Destroy]
  39768. {$IFDEF ASM_VERSION}
  39769. {$ELSE ASM_VERSION} //Pascal
  39770. destructor TImageList.Destroy;
  39771. begin
  39772. Clear;
  39773. if fNext <> nil then
  39774. fNext.fPrev := fPrev;
  39775. if fPrev <> nil then
  39776. fPrev.fNext := fNext;
  39777. if fControl <> nil then
  39778. begin
  39779. if PControl( fControl ).fImageList = @Self then
  39780. PControl( fControl ).fImageList := fNext;
  39781. {$IFDEF USE_AUTOFREE4CONTROLS}
  39782. PControl(fControl).RemoveFromAutoFree( @ Self );
  39783. {$ENDIF}
  39784. end;
  39785. inherited;
  39786. end;
  39787. {$ENDIF ASM_VERSION}
  39788. //*
  39789. //[procedure TImageList.Draw]
  39790. procedure TImageList.Draw(Idx: Integer; DC: HDC; X, Y: Integer);
  39791. begin
  39792. if FHandle = 0 then Exit;
  39793. ImageList_Draw( FHandle, Idx, DC, X, Y, GetDrawStyle );
  39794. end;
  39795. //[function TImageList.ExtractIcon]
  39796. function TImageList.ExtractIcon(Idx: Integer): HIcon;
  39797. begin
  39798. Result := ImageList_ExtractIcon( 0, FHandle, Idx );
  39799. end;
  39800. //[function TImageList.ExtractIconEx]
  39801. function TImageList.ExtractIconEx(Idx: Integer): HIcon;
  39802. begin
  39803. Result := ImageList_GetIcon( FHandle, Idx, GetDrawStyle );
  39804. end;
  39805. //*
  39806. //[function TImageList.GetBitmap]
  39807. function TImageList.GetBitmap: HBitmap;
  39808. var II : TImageInfo;
  39809. begin
  39810. Result := 0;
  39811. if FHandle = 0 then Exit;
  39812. if ImageList_GetImageInfo( FHandle, 0, II ) then
  39813. Result := II.hbmImage;
  39814. end;
  39815. //*
  39816. //[function TImageList.GetBkColor]
  39817. function TImageList.GetBkColor: TColor;
  39818. begin
  39819. Result := fBkColor;
  39820. if FHandle = 0 then Exit;
  39821. Result := ImageList_GetBkColor( FHandle );
  39822. end;
  39823. //*
  39824. //[function TImageList.GetCount]
  39825. function TImageList.GetCount: Integer;
  39826. begin
  39827. Result := 0;
  39828. if FHandle <> 0 then
  39829. Result := ImageList_GetImageCount( FHandle );
  39830. end;
  39831. //*
  39832. //[function TImageList.GetDrawStyle]
  39833. function TImageList.GetDrawStyle: DWord;
  39834. begin
  39835. Result := 0;
  39836. if dsBlend25 in DrawingStyle then
  39837. Result := Result or ILD_BLEND25;
  39838. if dsBlend50 in DrawingStyle then
  39839. Result := Result or ILD_BLEND50;
  39840. if dsTransparent in DrawingStyle then
  39841. Result := Result or ILD_TRANSPARENT
  39842. else
  39843. if dsMask in DrawingStyle then
  39844. Result := Result or ILD_MASK
  39845. {else
  39846. Result := Result or ILD_NORMAL}; // ILD_NORMAL = 0
  39847. end;
  39848. //[function TImageList.GetHandle]
  39849. {$IFDEF ASM_VERSION}
  39850. {$ELSE ASM_VERSION} //Pascal
  39851. function TImageList.GetHandle: THandle;
  39852. begin
  39853. HandleNeeded;
  39854. Result := FHandle;
  39855. end;
  39856. {$ENDIF ASM_VERSION}
  39857. //*
  39858. //[function TImageList.GetMask]
  39859. function TImageList.GetMask: HBitmap;
  39860. var II : TImageInfo;
  39861. begin
  39862. Result := 0;
  39863. if FHandle = 0 then Exit;
  39864. if ImageList_GetImageInfo( FHandle, 0, II ) then
  39865. Result := II.hbmMask;
  39866. end;
  39867. {$IFDEF ASM_noVERSION}
  39868. //[function TImageList.HandleNeeded]
  39869. function TImageList.HandleNeeded: Boolean;
  39870. const ColorFlags : array[ TImageListColors ] of Byte = ( ILC_COLOR,
  39871. ILC_COLOR4, ILC_COLOR8, ILC_COLOR16, ILC_COLOR24,
  39872. ILC_COLOR32, ILC_COLORDDB );
  39873. asm
  39874. MOV ECX, [EAX].FHandle
  39875. JECXZ @@make_handle
  39876. MOV AL, 1
  39877. RET
  39878. @@make_handle:
  39879. MOV ECX, [EAX].fImgWidth
  39880. JECXZ @@ret_ECX
  39881. MOV EDX, ECX
  39882. MOV ECX, [EAX].fImgHeight
  39883. JECXZ @@ret_ECX
  39884. PUSH EBX
  39885. XCHG EBX, EAX
  39886. PUSH [EBX].FAllocBy
  39887. PUSH 0
  39888. MOVZX EAX, [EBX].FColors
  39889. MOVZX EAX, byte ptr [ColorFlags+EAX]
  39890. CMP [EBX].FMasked, 0
  39891. JZ @@flags_ready
  39892. {$IFDEF PARANOIA} DB $0C, $01 {$ELSE} OR AL, 1 {$ENDIF}
  39893. @@flags_ready:
  39894. PUSH EAX
  39895. PUSH ECX
  39896. PUSH EDX
  39897. CALL ImageList_Create
  39898. MOV [EBX].FHandle, EAX
  39899. XCHG ECX, EAX
  39900. POP EBX
  39901. @@ret_ECX:
  39902. TEST ECX, ECX
  39903. SETNZ AL
  39904. end;
  39905. {$ELSE ASM_VERSION} //Pascal
  39906. function TImageList.HandleNeeded: Boolean;
  39907. const ColorFlags : array[ TImageListColors ] of Byte = ( ILC_COLOR,
  39908. {$ifndef wince}
  39909. ILC_COLOR4, ILC_COLOR8, ILC_COLOR16, ILC_COLOR24, ILC_COLOR32,
  39910. {$else}
  39911. ILC_COLOR, ILC_COLOR, ILC_COLOR, ILC_COLOR, ILC_COLOR,
  39912. {$endif wince}
  39913. ILC_COLORDDB, 0 );
  39914. var Flags : DWord;
  39915. begin
  39916. Result := True;
  39917. if FHandle <> 0 then Exit;
  39918. Result := False;
  39919. if ImgWidth = 0 then Exit;
  39920. if ImgHeight = 0 then Exit;
  39921. Flags := ColorFlags[ FColors ];
  39922. if Masked then
  39923. Flags := Flags or ILC_MASK;
  39924. FHandle := ImageList_Create( ImgWidth, ImgHeight, Flags, 0, FAllocBy );
  39925. if fBkColor <> clNone then
  39926. SetBkColor( fBkColor );
  39927. Result := FHandle <> 0;
  39928. end;
  39929. {$ENDIF ASM_VERSION}
  39930. //*
  39931. //[function TImageList.ImgRect]
  39932. function TImageList.ImgRect(Idx: Integer): TRect;
  39933. var II : TImageInfo;
  39934. begin
  39935. Result := MakeRect( 0, 0, 0, 0 );
  39936. if FHandle = 0 then Exit;
  39937. if ImageList_GetImageInfo( FHandle, Idx, II ) then
  39938. Result := II.rcImage;
  39939. end;
  39940. {$IFDEF ASM_noVERSION_UNICODE}
  39941. //[function TImageList.LoadBitmap]
  39942. function TImageList.LoadBitmap(ResourceName: PChar;
  39943. TranspColor: TColor): Boolean;
  39944. asm
  39945. PUSH EBX
  39946. XCHG EBX, EAX
  39947. XCHG EAX, ECX //TranspColor
  39948. PUSH EDX
  39949. CMP EAX, clNone
  39950. JNE @@2rgb
  39951. OR EAX, -1
  39952. JMP @@tranColorReady
  39953. @@2rgb:
  39954. CALL Color2RGB
  39955. @@tranColorReady:
  39956. POP EDX
  39957. PUSH EAX
  39958. PUSH [EBX].fAllocBy
  39959. PUSH [EBX].fImgWidth
  39960. PUSH EDX
  39961. PUSH [hInstance]
  39962. CALL ImageList_LoadBitmap
  39963. TEST EAX, EAX
  39964. JZ @@exit
  39965. XCHG EDX, EAX
  39966. XCHG EAX, EBX
  39967. CALL SetHandle
  39968. MOV AL, 1
  39969. @@exit: POP EBX
  39970. end;
  39971. {$ELSE ASM_VERSION} //Pascal
  39972. function TImageList.LoadBitmap(ResourceName: PKOLChar;
  39973. TranspColor: TColor): Boolean;
  39974. var NewHandle : THandle;
  39975. TranColr: TColor;
  39976. begin
  39977. TranColr := TranspColor;
  39978. if TranColr = clNone then TranColr := TColor( CLR_NONE )
  39979. else TranColr := Color2RGB( TranColr );
  39980. NewHandle := ImageList_LoadBitmap( hInstance, pointer(ResourceName),
  39981. ImgWidth, AllocBy, TranColr );
  39982. //ImageList_GetIconSize( NewHandle, fImgWidth, fImgHeight );
  39983. Result := NewHandle <> 0;
  39984. if Result then
  39985. Handle := NewHandle;
  39986. ImageList_GetIconSize( fHandle, FImgWidth, FImgHeight );
  39987. end;
  39988. {$ENDIF ASM_VERSION}
  39989. //*
  39990. //[function TImageList.LoadFromFile]
  39991. function TImageList.LoadFromFile(FileName: PKOLChar; TranspColor: TColor;
  39992. ImgType: TImageType): Boolean;
  39993. const ImgTypes:array[ TImageType ] of DWord = ( IMAGE_BITMAP, IMAGE_ICON, IMAGE_CURSOR );
  39994. var NewHandle : THandle;
  39995. TranspFlag : DWord;
  39996. begin
  39997. TranspFlag := 0;
  39998. if TranspColor <> clNone then
  39999. TranspFlag := LR_LOADTRANSPARENT;
  40000. NewHandle := ImageList_LoadImage( hInstance, pointer(FileName), ImgWidth, AllocBy,
  40001. Color2RGB( TranspColor ), ImgTypes[ ImgType ],
  40002. LR_LOADFROMFILE or TranspFlag );
  40003. Result := NewHandle <> 0;
  40004. if Result then
  40005. Handle := NewHandle;
  40006. end;
  40007. //*
  40008. //[function TImageList.LoadSystemIcons]
  40009. function TImageList.LoadSystemIcons(SmallIcons: Boolean): Boolean;
  40010. var NewHandle : THandle;
  40011. FileInfo : TSHFileInfo;
  40012. Flags : DWord;
  40013. begin
  40014. {$ifdef win32}OleInit;{$endif}
  40015. Flags := SHGFI_SYSICONINDEX;
  40016. if SmallIcons then
  40017. Flags := Flags or SHGFI_SMALLICON;
  40018. NewHandle := {$IFDEF UNICODE_CTRLS} SHGetFileInfoW {$ELSE} SHGetFileInfoA {$ENDIF}
  40019. ( '', 0, FileInfo, Sizeof( FileInfo ), Flags );
  40020. Result := NewHandle <> 0;
  40021. if Result then
  40022. begin
  40023. Handle := NewHandle;
  40024. FShareImages := True;
  40025. end;
  40026. end;
  40027. //*
  40028. //[function TImageList.Merge]
  40029. function TImageList.Merge(Idx: Integer; ImgList2: PImageList; Idx2, X,
  40030. Y: Integer): PImageList;
  40031. var L : THandle;
  40032. begin
  40033. Result := nil;
  40034. //if FHandle = 0 then Exit;
  40035. L := ImageList_Merge( FHandle, Idx, ImgList2.Handle, Idx2, X, Y );
  40036. if L <> 0 then
  40037. begin
  40038. Result := NewImageList( fControl );
  40039. Result.Handle := L;
  40040. end;
  40041. end;
  40042. //*
  40043. //[function TImageList.Replace]
  40044. function TImageList.Replace(Idx: Integer; Bmp, Msk: HBitmap): Boolean;
  40045. begin
  40046. Result := False;
  40047. if FHandle = 0 then Exit;
  40048. Result := ImageList_Replace( FHandle, Idx, Bmp, Msk );
  40049. end;
  40050. //*
  40051. //[function TImageList.ReplaceIcon]
  40052. function TImageList.ReplaceIcon(Idx: Integer; Ico: HIcon): Boolean;
  40053. begin
  40054. Result := False;
  40055. if FHandle = 0 then Exit;
  40056. Result := ImageList_ReplaceIcon( FHandle, Idx, Ico ) >= 0;
  40057. end;
  40058. //*
  40059. //[procedure TImageList.SetAllocBy]
  40060. procedure TImageList.SetAllocBy(const Value: Integer);
  40061. begin
  40062. if FHandle <> 0 then Exit;
  40063. // AllocBy can be changed only before adding images
  40064. // and creating image list handle
  40065. FAllocBy := Value;
  40066. end;
  40067. //*
  40068. //[procedure TImageList.SetBkColor]
  40069. procedure TImageList.SetBkColor(const Value: TColor);
  40070. begin
  40071. fBkColor := Value;
  40072. if fHandle <> 0 then
  40073. ImageList_SetBkColor( FHandle, Color2RGB( Value ) );
  40074. end;
  40075. //*
  40076. //[procedure TImageList.SetColors]
  40077. procedure TImageList.SetColors(const Value: TImageListColors);
  40078. begin
  40079. if FHandle <> 0 then Exit;
  40080. FColors := Value;
  40081. end;
  40082. //[procedure TImageList.SetHandle]
  40083. {$IFDEF ASM_VERSION}
  40084. {$ELSE ASM_VERSION} //Pascal
  40085. procedure TImageList.SetHandle(const Value: THandle);
  40086. begin
  40087. if FHandle = Value then Exit;
  40088. if (FHandle <> 0) and not FShareImages then
  40089. ImageList_Destroy( FHandle );
  40090. FHandle := Value;
  40091. if FHandle <> 0 then
  40092. ImageList_GetIconSize( FHandle, FImgWidth, FImgHeight )
  40093. else
  40094. begin
  40095. FImgWidth := 0;
  40096. FImgHeight := 0;
  40097. end;
  40098. //FBkColor := ImageList_GetBkColor( FHandle );
  40099. end;
  40100. {$ENDIF ASM_VERSION}
  40101. //[procedure TImageList.SetImgHeight]
  40102. procedure TImageList.SetImgHeight(const Value: Integer);
  40103. begin
  40104. if FHandle <> 0 then Exit;
  40105. FImgHeight := Value;
  40106. end;
  40107. //[procedure TImageList.SetImgWidth]
  40108. procedure TImageList.SetImgWidth(const Value: Integer);
  40109. begin
  40110. if FHandle <> 0 then Exit;
  40111. FImgWidth := Value;
  40112. end;
  40113. //[procedure TImageList.SetMasked]
  40114. procedure TImageList.SetMasked(const Value: Boolean);
  40115. begin
  40116. if FHandle <> 0 then Exit;
  40117. FMasked := Value;
  40118. end;
  40119. //*
  40120. //[function TImageList.GetOverlay]
  40121. function TImageList.GetOverlay(Idx: TImgLOVrlayIdx): Integer;
  40122. begin
  40123. Result := fOverlay[ Idx ];
  40124. end;
  40125. //[procedure TImageList.SetOverlay]
  40126. procedure TImageList.SetOverlay(Idx: TImgLOVrlayIdx; const Value: Integer);
  40127. begin
  40128. if ImageList_SetOverlayImage( fHandle, Value, Idx ) then
  40129. fOverlay[ Idx ] := Value;
  40130. end;
  40131. //[procedure TImageList.StretchDraw]
  40132. procedure TImageList.StretchDraw(Idx: Integer; DC: HDC; const Rect: TRect);
  40133. begin
  40134. if FHandle = 0 then Exit;
  40135. ImageList_DrawEx( FHandle, Idx, DC, Rect.Left, Rect.Top,
  40136. Rect.Right- Rect.Left, Rect.Bottom-Rect.Top,
  40137. BkColor, BlendColor, GetDrawStyle );
  40138. end;
  40139. //*
  40140. //[function GetImgListSize]
  40141. function GetImgListSize( Sender: PControl; Size: Integer ): PImageList;
  40142. begin
  40143. if Size > 16 then
  40144. Result := Sender.fCtlImageListNormal
  40145. else
  40146. Result := Sender.fCtlImageListSml;
  40147. if Result <> nil then
  40148. begin
  40149. if Result.fImgWidth = 0 then
  40150. Result.ImgWidth := Size;
  40151. if Result.fImgHeight = 0 then
  40152. Result.ImgHeight := Size;
  40153. //if (Result.FImgWidth <> Size) or (Result.FImgHeight <> Size) then
  40154. // Result := nil;
  40155. end;
  40156. if Result = nil then
  40157. begin
  40158. Result := Sender.fImageList;
  40159. while Result <> nil do
  40160. begin
  40161. if (Result.FImgWidth = Size) and (Result.FImgHeight = Size) then
  40162. break;
  40163. Result := Result.fNext;
  40164. end;
  40165. end;
  40166. end;
  40167. //*
  40168. //[function TControl.GetImgListIdx]
  40169. function TControl.GetImgListIdx(const Index: Integer): PImageList;
  40170. begin
  40171. if Index <> 0 then
  40172. Result := GetImgListSize( @Self, Index )
  40173. else
  40174. begin
  40175. Result := fCtlImgListState;
  40176. if Result = nil then
  40177. begin
  40178. Result := fImageList;
  40179. while Result <> nil do
  40180. begin
  40181. if (Result <> GetImgListIdx( 16 )) and (Result <> GetImgListIdx( 32 )) then
  40182. break;
  40183. Result := Result.fNext;
  40184. end;
  40185. end;
  40186. end;
  40187. end;
  40188. //*
  40189. //[procedure TControl.SetImgListIdx]
  40190. procedure TControl.SetImgListIdx(const Index: Integer;
  40191. const Value: PImageList);
  40192. begin
  40193. if Value <> nil then
  40194. begin
  40195. if Index <> 0 then
  40196. if (Value.ImgWidth = 0) or (Value.ImgHeight = 0) then
  40197. begin
  40198. Value.ImgWidth := Index;
  40199. Value.ImgHeight := Index;
  40200. end;
  40201. end;
  40202. case Index of
  40203. 32: fCtlImageListNormal := Value;
  40204. 16: fCtlImageListSml := Value;
  40205. else fCtlImgListState := Value;
  40206. end;
  40207. ApplyImageLists2Control( @Self );
  40208. end;
  40209. { -- list view -- }
  40210. //[function WndProcEndLabelEdit]
  40211. function WndProcEndLabelEdit( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  40212. var NMhdr: PNMHdr;
  40213. LVDisp: PLVDispInfo;
  40214. Flag: Boolean;
  40215. begin
  40216. Result := False;
  40217. if Msg.message = WM_NOTIFY then
  40218. begin
  40219. NMHdr := Pointer( Msg.lParam );
  40220. case LongInt(NMHdr.code) of
  40221. LVN_ENDLABELEDIT:
  40222. begin
  40223. LVDisp := Pointer( Msg.lParam );
  40224. Result := True;
  40225. if LVDisp.item.pszText = nil then Exit;
  40226. Rslt := 1;
  40227. if assigned( Self_.fOnEndEditLVItem ) then
  40228. begin
  40229. Flag := Self_.fOnEndEditLVItem( Self_, LVDisp.item.iItem,
  40230. LVDisp.item.iSubItem, LVDisp.item.pszText );
  40231. if Flag then Rslt := 1
  40232. else Rslt := 0;
  40233. end;
  40234. end;
  40235. end;
  40236. end;
  40237. end;
  40238. //[procedure TControl.SetOnEndEditLVItem]
  40239. procedure TControl.SetOnEndEditLVItem(const Value: TOnEditLVItem);
  40240. begin
  40241. fOnEndEditLVITem := Value;
  40242. AttachProc( WndProcEndLabelEdit );
  40243. end;
  40244. //*
  40245. //[procedure TControl.LVColAdd]
  40246. procedure TControl.LVColAdd(const aText: KOLString; aalign: TTextAlign;
  40247. aWidth: Integer);
  40248. begin
  40249. LVColInsert( fLVColCount, aText, aalign, aWidth );// 21.10.2001
  40250. end;
  40251. //****************** changed by Mike Gerasimov
  40252. //[procedure TControl.LVColInsert]
  40253. procedure TControl.LVColInsert(ColIdx: Integer; const aText: KOLString;
  40254. aAlign: TTextAlign; aWidth: Integer);
  40255. var LVColData: TLVColumn;
  40256. begin
  40257. LVColData.mask := LVCF_FMT or LVCF_TEXT;
  40258. if ImageListSmall <> nil then
  40259. LVColData.mask := LVColData.mask; // or LVCF_IMAGE ;
  40260. LVColData.iImage := -1;
  40261. LVColData.fmt := Ord( aAlign );
  40262. if aWidth < 0 then
  40263. begin
  40264. aWidth := -aWidth;
  40265. LVColData.fmt := LVColData.fmt or LVCFMT_BITMAP_ON_RIGHT;
  40266. end;
  40267. LVColData.cx := aWidth;
  40268. if aWidth > 0 then
  40269. LVColData.mask := LVColData.mask or LVCF_WIDTH;
  40270. LVColData.pszText := PKOL_Char( aText );
  40271. if Perform( LVM_INSERTCOLUMN, ColIdx, Integer( @LVColData ) ) >= 0 then
  40272. Inc( fLVColCount );
  40273. end;
  40274. //[function TControl.GetLVColText]
  40275. function TControl.GetLVColText(Idx: Integer): KOLString;
  40276. var Buf: array[ 0..4095 ] of KOLChar;
  40277. LC: TLVColumn;
  40278. begin
  40279. LC.mask := LVCF_TEXT;
  40280. LC.pszText := @ Buf[ 0 ];
  40281. LC.cchTextMax := 4096;
  40282. Buf[ 0 ] := #0;
  40283. Perform( LVM_GETCOLUMN, Idx, Integer( @ LC ) );
  40284. Result := Buf;
  40285. end;
  40286. //[procedure TControl.SetLVColText]
  40287. procedure TControl.SetLVColText(Idx: Integer; const Value: KOLString);
  40288. var LC: TLVColumn;
  40289. begin
  40290. FillChar( LC, Sizeof( LC ), #0 ); {Alexey (Lecha2002)}
  40291. LC.mask := LVCF_TEXT;
  40292. LC.pszText := '';
  40293. if Value <> '' then
  40294. LC.pszText := @ Value[ 1 ];
  40295. Perform( LVM_SETCOLUMN, Idx, Integer( @ LC ) );
  40296. end;
  40297. //[function TControl.GetLVColalign]
  40298. function TControl.GetLVColalign(Idx: Integer): TTextAlign;
  40299. const Formats: array[ 0..2 ] of TTextAlign = ( taLeft, taRight, taCenter );
  40300. var LC: TLVColumn;
  40301. begin
  40302. FillChar( LC, Sizeof( LC ), #0 ); {Alexey (Lecha2002)}
  40303. LC.mask := LVCF_FMT;
  40304. Perform( LVM_GETCOLUMN, Idx, Integer( @ LC ) );
  40305. Result := Formats[ LC.fmt and LVCFMT_JUSTIFYMASK ];
  40306. end;
  40307. //[procedure TControl.SetLVColalign]
  40308. procedure TControl.SetLVColalign(Idx: Integer; const Value: TTextAlign);
  40309. const FormatFlags: array[ TTextAlign ] of BYTE = ( LVCFMT_LEFT, LVCFMT_RIGHT,
  40310. LVCFMT_CENTER );
  40311. var LC: TLVColumn;
  40312. begin
  40313. FillChar( LC, Sizeof( LC ), #0 ); {Alexey (Lecha2002)}
  40314. LC.mask := LVCF_FMT;
  40315. Perform( LVM_GETCOLUMN, Idx, Integer( @ LC ) );
  40316. LC.fmt := LC.fmt and not LVCFMT_JUSTIFYMASK or FormatFlags[ Value ];
  40317. Perform( LVM_SETCOLUMN, Idx, Integer( @ LC ) );
  40318. end;
  40319. //[function TControl.GetLVColEx]
  40320. function TControl.GetLVColEx(Idx: Integer; const Index: Integer): Integer;
  40321. var LC: TLVColumn;
  40322. begin
  40323. FillChar( LC, Sizeof( LC ), #0 ); {Alexey (Lecha2002)}
  40324. LC.mask := LoWord( Index );
  40325. Perform( LVM_GETCOLUMN, Idx, Integer( @ LC ) );
  40326. Result := PDWORD( cardinal( @ LC ) + HiWord( Index ) )^;
  40327. end;
  40328. //********************** changed by Mike Gerasimov
  40329. //[procedure TControl.SetLVColEx]
  40330. procedure TControl.SetLVColEx(Idx: Integer; const Index: Integer;
  40331. const Value: Integer);
  40332. var LC: TLVColumn;
  40333. begin
  40334. FillChar(LC,SizeOf(LC),#0); // Added Line
  40335. LC.mask := LoWord( Index );
  40336. {$ifdef win32}
  40337. if HiWord( Index ) = 24 then // Added Line
  40338. begin // Added Line
  40339. LC.mask := LC.mask or LVCF_FMT; // Added Line
  40340. if Value <>-1 then // Added Line
  40341. LC.fmt := LC.fmt or LVCFMT_IMAGE or LVCFMT_COL_HAS_IMAGES // Added Line
  40342. else LC.mask := LC.mask and not LVCF_IMAGE; // + by non
  40343. end;
  40344. {$endif win32}
  40345. if (value<>-1)or(HiWord( Index )<>24) then // + by non
  40346. PDWORD( cardinal( @ LC ) + HiWord( Index ) )^ := Value;
  40347. Perform( LVM_SETCOLUMN, Idx, Integer( @ LC ) );
  40348. end;
  40349. //*
  40350. //[function TControl.LVAdd]
  40351. function TControl.LVAdd(const aText: KOLString; ImgIdx: Integer;
  40352. State: TListViewItemState; StateImgIdx, OverlayImgIdx: Integer;
  40353. Data: DWORD): Integer;
  40354. begin
  40355. Result := LVInsert( MaxInt {Count}, aText, ImgIdx, State, StateImgIdx, OverlayImgIdx, Data );
  40356. end;
  40357. //*
  40358. //[function TControl.LVInsert]
  40359. function TControl.LVInsert(Idx: Integer; const aText: KOLString;
  40360. ImgIdx: Integer; State: TListViewItemState; StateImgIdx, OverlayImgIdx: Integer;
  40361. Data: DWORD): Integer;
  40362. const
  40363. LVM_REDRAWITEMS = LVM_FIRST + 21;
  40364. var LVI: TLVItem;
  40365. begin
  40366. LVI.mask := LVIF_TEXT or LVIF_IMAGE or LVIF_PARAM or LVIF_STATE;
  40367. LVI.iItem := Idx;
  40368. LVI.iSubItem := 0;
  40369. LVI.state := 0;
  40370. if lvisBlend in State then
  40371. LVI.state := LVIS_CUT;
  40372. if lvisHighlight in State then
  40373. LVI.state := LVI.state or LVIS_DROPHILITED;
  40374. if lvisFocus in State then
  40375. LVI.state := LVI.state or LVIS_FOCUSED;
  40376. if lvisSelect in State then
  40377. LVI.state := LVI.state or LVIS_SELECTED;
  40378. LVI.stateMask := $FFFF;
  40379. if StateImgIdx <> 0 then
  40380. LVI.state := LVI.state or ((cardinal(StateImgIdx) and $F) shl 12);
  40381. if OverlayImgIdx <> 0 then
  40382. LVI.state := LVI.state or ((cardinal(OverlayImgIdx) and $F) shl 8);
  40383. LVI.pszText := PKOL_Char( aText );
  40384. LVI.iImage := ImgIdx;
  40385. LVI.lParam := Data;
  40386. Result := Perform( LVM_INSERTITEM, 0, Integer( @LVI ) );
  40387. //Perform( LVM_REDRAWITEMS, Idx, Idx );
  40388. end;
  40389. //*
  40390. //[procedure TControl.LVSetItem]
  40391. procedure TControl.LVSetItem(Idx, Col: Integer; const aText: KOLString;
  40392. ImgIdx: Integer; State: TListViewItemState; StateImgIdx,
  40393. OverlayImgIdx: Integer; Data: DWORD);
  40394. var LVI: TLVItem;
  40395. I: Integer;
  40396. begin
  40397. if Col = 0 then
  40398. LVI.mask := LVIF_TEXT or LVIF_STATE or LVIF_PARAM
  40399. else
  40400. LVI.mask := LVIF_TEXT;
  40401. if ImgIdx <> I_SKIP then
  40402. LVI.mask := LVI.mask or LVIF_IMAGE;
  40403. if ImgIdx < I_SKIP then
  40404. LVI.mask := LVIF_TEXT;
  40405. LVI.iItem := Idx;
  40406. LVI.iSubItem := Col;
  40407. LVI.state := 0;
  40408. if lvisBlend in State then
  40409. LVI.state := LVIS_CUT;
  40410. if lvisHighlight in State then
  40411. LVI.state := LVI.state or LVIS_DROPHILITED;
  40412. if lvisFocus in State then
  40413. LVI.state := LVI.state or LVIS_FOCUSED;
  40414. if lvisSelect in State then
  40415. LVI.state := LVI.state or LVIS_SELECTED;
  40416. LVI.stateMask := $FFFF;
  40417. if StateImgIdx <> 0 then
  40418. LVI.state := LVI.state or ((cardinal(StateImgIdx) and $F) shl 12);
  40419. if StateImgIdx < 0 {= I_SKIP} then
  40420. LVI.stateMask := $F0FF;
  40421. if OverlayImgIdx <> 0 then
  40422. LVI.state := LVI.state or ((cardinal(OverlayImgIdx) and $F) shl 8);
  40423. if OverlayImgIdx < 0 {=I_SKIP} then
  40424. LVI.stateMask := LVI.stateMask and $FFF;
  40425. LVI.pszText := PKOL_Char( aText );
  40426. LVI.iImage := ImgIdx;
  40427. LVI.lParam := Data;
  40428. I := Perform( LVM_SETITEM, 0, Integer( @LVI ) );
  40429. if (I = 0) and (Col = 0) then
  40430. Assert( False, 'Can not set item ' );
  40431. end;
  40432. //*
  40433. //[procedure LVGetItem]
  40434. procedure LVGetItem( Sender: PControl; Idx, Col: Integer; var LVI: TLVItem;
  40435. TextBuf: PKOL_Char; TextBufSize: Integer );
  40436. begin
  40437. LVI.mask := LVIF_STATE or LVIF_PARAM or LVIF_IMAGE;
  40438. if Col > 0 then
  40439. if not (lvoSubItemImages in Sender.fLVOptions) then
  40440. LVI.mask := LVIF_STATE or LVIF_PARAM;
  40441. LVI.iItem := Idx;
  40442. LVI.iSubItem := Col;
  40443. LVI.pszText := TextBuf;
  40444. LVI.cchTextMax := TextBufSize;
  40445. if TextBufSize <> 0 then
  40446. LVI.mask := LVI.mask or LVIF_TEXT;
  40447. Sender.Perform( LVM_GETITEM, 0, Integer( @LVI ) );
  40448. end;
  40449. //[function TControl.LVGetItemImgIdx]
  40450. function TControl.LVGetItemImgIdx(Idx: Integer): Integer;
  40451. var LVI: TLVItem;
  40452. begin
  40453. LVI.iImage := -1;//= Result if image is not assigned {Andrzej Kubaszek}
  40454. LVGetItem( @Self, Idx, 0, LVI, nil, 0 );
  40455. Result := LVI.iImage;
  40456. end;
  40457. //[procedure TControl.LVSetItemImgIdx]
  40458. procedure TControl.LVSetItemImgIdx(Idx: Integer; const Value: Integer);
  40459. var LVI: TLVItem;
  40460. begin
  40461. LVGetItem( @Self, Idx, 0, LVI, nil, 0 );
  40462. LVI.iImage := Value;
  40463. Perform( LVM_SETITEM, 0, Integer( @LVI ) );
  40464. end;
  40465. //[function TControl.LVGetItemText]
  40466. function TControl.LVGetItemText(Idx, Col: Integer): KOLString;
  40467. var LVI: TLVItem;
  40468. TextBuf: PKOL_Char;
  40469. BufSize: Integer;
  40470. begin
  40471. BufSize := 0;
  40472. TextBuf := nil;
  40473. repeat
  40474. if TextBuf <> nil then
  40475. FreeMem( TextBuf );
  40476. BufSize := BufSize * 2 + 100; // to vary in asm version
  40477. GetMem( TextBuf, BufSize * Sizeof( KOLChar ) );
  40478. TextBuf[ 0 ] := #0;
  40479. LVGetItem( @Self, Idx, Col, LVI, TextBuf, BufSize );
  40480. until Integer({$IFDEF UNICODE_CTRLS} WStrLen {$ELSE} StrLen {$ENDIF}
  40481. ( PKOLChar( TextBuf ) )) < BufSize - 1;
  40482. Result := TextBuf;
  40483. FreeMem( TextBuf );
  40484. end;
  40485. //*
  40486. //[procedure TControl.LVSetItemText]
  40487. procedure TControl.LVSetItemText(Idx, Col: Integer; const Value: KOLString);
  40488. var LVI: TLVItem;
  40489. begin
  40490. LVI.iSubItem := Col;
  40491. LVI.pszText := PKOL_Char( Value );
  40492. Perform( LVM_SETITEMTEXT, Idx, Integer( @LVI ) );
  40493. end;
  40494. //[procedure TControl.LVColDelete]
  40495. procedure TControl.LVColDelete(ColIdx: Integer);
  40496. begin
  40497. Perform( LVM_DELETECOLUMN, ColIdx, 0 );
  40498. if fLVColCount > 0 then
  40499. Dec( fLVColCount );
  40500. end;
  40501. //[procedure TControl.SetLVOptions]
  40502. procedure TControl.SetLVOptions(const Value: TListViewOptions);
  40503. begin
  40504. if fLVOptions = Value then Exit;
  40505. fLVOptions := Value;
  40506. ApplyImageLists2ListView( @Self );
  40507. PostMessage( fHandle, WM_SIZE, 0, 0 ); // to restore scrollers (otherwise its are lost)
  40508. end;
  40509. //[procedure TControl.SetLVStyle]
  40510. procedure TControl.SetLVStyle(const Value: TListViewStyle);
  40511. begin
  40512. if fLVStyle = Value then Exit;
  40513. fLVStyle := Value;
  40514. ApplyImageLists2ListView( @Self );
  40515. end;
  40516. //[function TControl.Perform]
  40517. {$IFDEF ASM_VERSION}
  40518. {$ELSE ASM_VERSION} //Pascal
  40519. function TControl.Perform(msgcode: DWORD; wParam, lParam: Integer): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  40520. begin
  40521. {$IFDEF INPACKAGE}
  40522. Log( '->TControl.Perform' );
  40523. TRY
  40524. {$ENDIF INPACKAGE}
  40525. Result := SendMessage( GetWindowHandle, msgcode, wParam, lParam );
  40526. {$IFDEF INPACKAGE}
  40527. LogOK;
  40528. FINALLY
  40529. Log( '<-TControl.Perform' );
  40530. END;
  40531. {$ENDIF INPACKAGE}
  40532. end;
  40533. {$ENDIF ASM_VERSION}
  40534. //[function TControl.Postmsg]
  40535. {$IFDEF ASM_VERSION}
  40536. {$ELSE ASM_VERSION} //Pascal
  40537. function TControl.Postmsg(msgcode: DWORD; wParam, lParam: Integer): Boolean; {$ifdef wince}cdecl{$else}stdcall{$endif};
  40538. begin
  40539. Result := PostMessage( GetWindowHandle, msgcode, wParam, lParam );
  40540. end;
  40541. {$ENDIF ASM_VERSION}
  40542. {$ENDIF WIN_GDI}
  40543. //[function TControl.GetChildCount]
  40544. {$IFDEF ASM_VERSION}
  40545. {$ELSE ASM_VERSION} //Pascal
  40546. function TControl.GetChildCount: Integer;
  40547. begin
  40548. Result := fChildren.fCount;
  40549. end;
  40550. {$ENDIF ASM_VERSION}
  40551. {$IFDEF WIN_GDI}
  40552. //[procedure TControl.LVDelete]
  40553. procedure TControl.LVDelete(Idx: Integer);
  40554. begin
  40555. Perform( LVM_DELETEITEM, Idx, 0 );
  40556. end;
  40557. //[procedure TControl.LVEditItemLabel]
  40558. procedure TControl.LVEditItemLabel(Idx: Integer);
  40559. begin
  40560. Perform( LVM_EDITLABEL, Idx, 0 );
  40561. end;
  40562. //*
  40563. //[function TControl.LVItemRect]
  40564. function TControl.LVItemRect(Idx: Integer; Part: TGetLVItemPart): TRect;
  40565. const Parts: array[ TGetLVItemPart ] of Byte = (
  40566. LVIR_BOUNDS, LVIR_ICON, LVIR_LABEL, LVIR_SELECTBOUNDS );
  40567. begin
  40568. Result := MakeRect( Parts[ Part ], 0, 0, 0 );
  40569. if Perform( LVM_GETITEMRECT, Idx, Integer( @Result ) ) = 0 then
  40570. begin
  40571. //ShowMessage( SysErrorMessage( GetLastError ) );
  40572. Result := MakeRect( 0, 0, 0, 0 );
  40573. end;
  40574. end;
  40575. //[function TControl.LVSubItemRect]
  40576. function TControl.LVSubItemRect(Idx, ColIdx: Integer): TRect;
  40577. var Hdr: HWnd;
  40578. R, R1: TRect;
  40579. ClassNameBuf: array[ 0..31 ] of KOLChar;
  40580. HdItem: THDItem;
  40581. begin
  40582. Result.Top := ColIdx; // + 1; error in MSDN ?
  40583. Result.Left := LVIR_BOUNDS;
  40584. if Perform( LVM_GETSUBITEMRECT, Idx, Integer( @Result ) ) <> 0 then
  40585. Exit;
  40586. Result := MakeRect( 0, 0, 0, 0 );
  40587. if ColIdx > 0 then R := LVSubItemRect( Idx, ColIdx - 1 )
  40588. else R := LVItemRect( Idx, lvipBounds );
  40589. if (R.Left = 0) and (R.Right = 0) and
  40590. (R.Top = 0) and (R.Bottom = 0) then Exit;
  40591. Hdr := GetWindow( GetWindowHandle, GW_CHILD );
  40592. if Hdr <> 0 then
  40593. begin
  40594. if GetClassName( Hdr, ClassNameBuf, 32 ) > 0 then
  40595. if ClassNameBuf = 'SysHeader32' then
  40596. begin
  40597. if ColIdx > 0 then R.Left := R.Right
  40598. else R.Left := 0;
  40599. R1.Top := 0; R1.Left := 0;
  40600. Windows.ClientToScreen( Hdr,{$IFDEF FPC} PPoint( @ R1.Left )^ {$ELSE} R1.TopLeft {$ENDIF} );
  40601. Windows.ScreenToClient( fHandle, {$IFDEF FPC} PPoint( @ R1.Left )^ {$ELSE} R1.TopLeft {$ENDIF} );
  40602. R1 := R;
  40603. HdItem.Mask := HDI_WIDTH;
  40604. if SendMessage( Hdr, HDM_GETITEM, ColIdx, Integer( @HdItem ) ) = 0 then Exit;
  40605. R1.Right := R1.Left + HdItem.cxy;
  40606. Result := R1;
  40607. end;
  40608. end;
  40609. end;
  40610. //*
  40611. //[function TControl.LVGetItemPos]
  40612. function TControl.LVGetItemPos(Idx: Integer): TPoint;
  40613. begin
  40614. Perform( LVM_GETITEMPOSITION, Idx, Integer( @Result ) );
  40615. end;
  40616. //*
  40617. //[procedure TControl.LVSetItemPos]
  40618. procedure TControl.LVSetItemPos(Idx: Integer; const Value: TPoint);
  40619. begin
  40620. Perform( LVM_SETITEMPOSITION32, Idx, Integer( @Value ) );
  40621. end;
  40622. //*
  40623. //[function TControl.LVItemAtPos]
  40624. function TControl.LVItemAtPos(X, Y: Integer): Integer;
  40625. var Dummy: TWherePosLVItem;
  40626. begin
  40627. Result := LVItemAtPosEx( X, Y, Dummy );
  40628. end;
  40629. //*
  40630. //[function TControl.LVItemAtPosEx]
  40631. function TControl.LVItemAtPosEx(X, Y: Integer;
  40632. var Where: TWherePosLVItem): Integer;
  40633. var HTI: TLVHitTestInfo;
  40634. begin
  40635. HTI.pt.x := X;
  40636. HTI.pt.y := Y;
  40637. Perform( LVM_HITTEST, 0, Integer( @HTI ) );
  40638. Result := HTI.iItem;
  40639. Where := lvwpOnColumn;
  40640. if HTI.flags = LVHT_ONITEMICON then
  40641. Where := lvwpOnIcon
  40642. else
  40643. if HTI.flags = LVHT_ONITEMLABEL then
  40644. Where := lvwpOnLabel
  40645. else
  40646. if HTI.flags = LVHT_ONITEMSTATEICON then
  40647. Where := lvwpOnStateIcon
  40648. else
  40649. if HTI.flags = LVHT_ONITEM then
  40650. Where := lvwpOnItem;
  40651. end;
  40652. //[procedure TControl.LVMakeVisible]
  40653. procedure TControl.LVMakeVisible(Item: Integer; PartiallyOK: Boolean);
  40654. begin
  40655. if Item < 0 then Exit;
  40656. Perform( LVM_ENSUREVISIBLE, Item, Integer( PartiallyOK ) );
  40657. end;
  40658. //*
  40659. //[procedure TControl.LVSetColorByIdx]
  40660. procedure TControl.LVSetColorByIdx(const Index: Integer;
  40661. const Value: TColor);
  40662. var MsgCode: Integer;
  40663. ColorValue: TColor;
  40664. begin
  40665. MsgCode := Index + 1;
  40666. case MsgCode of
  40667. LVM_SETTEXTCOLOR: fTextColor := Value;
  40668. LVM_SETTEXTBKCOLOR: fLVTextBkColor := Value;
  40669. LVM_SETBKCOLOR: fColor := Value;
  40670. end;
  40671. ColorValue := Color2RGB( Value );
  40672. Perform( MsgCode, 0, ColorValue );
  40673. end;
  40674. {$IFDEF F_P}
  40675. //[function TControl.LVGetColorByIdx]
  40676. function TControl.LVGetColorByIdx(const Index: Integer): TColor;
  40677. begin
  40678. CASE Index OF
  40679. LVM_SETTEXTCOLOR: Result := fTextColor;
  40680. LVM_SETTEXTBKCOLOR: Result := fLVTextBkColor;
  40681. LVM_SETBKCOLOR: Result := fColor;
  40682. END;
  40683. end;
  40684. {$ENDIF F_P}
  40685. //*
  40686. //[function TControl.GetIntVal]
  40687. function TControl.GetIntVal(const Index: Integer): Integer;
  40688. begin
  40689. Result := GetItemVal( 0, Index );
  40690. end;
  40691. //*
  40692. //[procedure TControl.SetIntVal]
  40693. procedure TControl.SetIntVal(const Index, Value: Integer);
  40694. begin
  40695. SetItemVal( Value, Index, 0 );
  40696. end;
  40697. //*
  40698. //[function TControl.GetItemVal]
  40699. function TControl.GetItemVal(Item: Integer; const Index: Integer): Integer;
  40700. begin
  40701. Result := Perform( LoWord(Index), Item, 0 );
  40702. end;
  40703. //[procedure TControl.SetItemVal]
  40704. {$IFDEF ASM_VERSION}
  40705. {$ELSE ASM_VERSION} //Pascal
  40706. procedure TControl.SetItemVal(Item: Integer; const Index: Integer; const Value: Integer);
  40707. var MsgCode: Integer;
  40708. begin
  40709. MsgCode := HiWord( Index );
  40710. if MsgCode = 0 then
  40711. MsgCode := Index + 1;
  40712. Perform( MsgCode and $7FFF, Item, Value );
  40713. if (MsgCode and $8000) <> 0 then
  40714. Invalidate;
  40715. end;
  40716. {$ENDIF ASM_VERSION}
  40717. //[procedure TControl.GetSBMinMax]
  40718. function TControl.GetSBMinMax: TPoint;
  40719. {$IFDEF _D2}
  40720. var X, Y: Integer;
  40721. {$ENDIF}
  40722. begin
  40723. if (Handle <> 0) then begin
  40724. {$IFDEF _D2}
  40725. GetScrollRange(Handle, SB_CTL, X, Y);
  40726. Result.X := X;
  40727. Result.Y := Y;
  40728. {$ELSE}
  40729. GetScrollRange(Handle, SB_CTL, Result.X, Result.Y);
  40730. {$ENDIF}
  40731. Dec(Result.Y, SBPageSize - 1);
  40732. end
  40733. else
  40734. Result := fSBMinMax;
  40735. end;
  40736. //[procedure TControl.GetSBPageSize]
  40737. function TControl.GetSBPageSize: Integer;
  40738. var
  40739. SI: TScrollInfo;
  40740. begin
  40741. FillChar(SI, SizeOf(SI), #0);
  40742. SI.cbSize := SizeOf(SI);
  40743. SI.fMask := SIF_PAGE;
  40744. SBGetScrollInfo(SI);
  40745. Result := SI.nPage;
  40746. end;
  40747. //[procedure TControl.GetSBPosition]
  40748. function TControl.GetSBPosition: Integer;
  40749. begin
  40750. Result := GetScrollPos(Handle, SB_CTL);
  40751. end;
  40752. //[procedure TControl.SetSBMax]
  40753. procedure TControl.SetSBMax(Value: Longint);
  40754. var
  40755. P: TPoint;
  40756. begin
  40757. fSBMinMax.Y := Value;
  40758. if (Handle <> 0) then begin
  40759. P := SBMinMax;
  40760. P.Y := Value;
  40761. SBMinMax := P;
  40762. end;
  40763. end;
  40764. //[procedure TControl.SetSBMin]
  40765. procedure TControl.SetSBMin(Value: Longint);
  40766. var
  40767. P: TPoint;
  40768. begin
  40769. fSBMinMax.X := Value;
  40770. if (Handle <> 0) then begin
  40771. P := SBMinMax;
  40772. P.X := Value;
  40773. SBMinMax := P;
  40774. end;
  40775. end;
  40776. //[procedure TControl.SetSBPageSize]
  40777. procedure TControl.SetSBPageSize(Value: Integer);
  40778. var
  40779. SI: TScrollInfo;
  40780. begin
  40781. fSBPageSize := Value;
  40782. if (Handle <> 0) then begin
  40783. FillChar(SI, SizeOf(SI), #0);
  40784. SI.cbSize := SizeOf(SI);
  40785. SI.fMask := SIF_PAGE or SIF_RANGE;
  40786. SBGetScrollInfo(SI);
  40787. if (SI.nMax = 0) and (SI.nMin = 0) then
  40788. SI.nMax := 1;
  40789. SI.nMax := SI.nMax - Integer(SI.nPage) + Value;
  40790. SI.nPage := Value;
  40791. SBSetScrollInfo(SI);
  40792. end;
  40793. end;
  40794. //[procedure TControl.SetSBPosition]
  40795. procedure TControl.SetSBPosition(Value: Integer);
  40796. begin
  40797. fSBPosition := Value;
  40798. if (Handle <> 0) then
  40799. SetScrollPos(Handle, SB_CTL, Value, True);
  40800. end;
  40801. //[procedure TControl.SetSBMinMax]
  40802. procedure TControl.SetSBMinMax(const Value: TPoint);
  40803. begin
  40804. GetSBMinMax;
  40805. if (Handle <> 0) then
  40806. SetScrollRange(Handle, SB_CTL, Value.X, Value.Y + SBPageSize - 1, True)
  40807. else
  40808. fSBMinMax := Value;
  40809. end;
  40810. //[procedure TControl.SBSetScrollInfo]
  40811. function TControl.SBSetScrollInfo(const SI: TScrollInfo): Integer;
  40812. begin
  40813. Result := SetScrollInfo(Handle, SB_CTL, SI, True)
  40814. end;
  40815. //[procedure TControl.SBGetScrollInfo]
  40816. function TControl.SBGetScrollInfo(var SI: TScrollInfo): Boolean;
  40817. begin
  40818. Result := Cardinal(GetScrollInfo(Handle, SB_CTL, SI)) <> 0;
  40819. end;
  40820. { -- OpenSaveDialog -- }
  40821. //*
  40822. //[function NewOpenSaveDialog]
  40823. function NewOpenSaveDialog( const Title, StrtDir: KOLString;
  40824. Options: TOpenSaveOptions ): POpenSaveDialog;
  40825. begin
  40826. {-}
  40827. New( Result, Create );
  40828. {+}{++}(*Result := POpenSaveDialog.Create;*){--}
  40829. Result.FOptions := Options;
  40830. if Options = [] then
  40831. Result.FOptions := DefOpenSaveDlgOptions;
  40832. Result.fOpenDialog := True;
  40833. Result.FTitle := Title;
  40834. Result.FInitialDir := StrtDir;
  40835. end;
  40836. //[END NewOpenSaveDialog]
  40837. { TOpenSaveDialog }
  40838. //[destructor TOpenSaveDialog.Destroy]
  40839. {$IFDEF ASM_VERSION}
  40840. {$ELSE ASM_VERSION} //Pascal
  40841. destructor TOpenSaveDialog.Destroy;
  40842. begin
  40843. FFilter := '';
  40844. FInitialDir := '';
  40845. FDefExtension := '';
  40846. FFileName := '';
  40847. FTitle := '';
  40848. {$IFDEF OpenSaveDialog_Extended}
  40849. TemplateName := '';
  40850. {$ENDIF}
  40851. inherited;
  40852. end;
  40853. {$ENDIF ASM_VERSION}
  40854. //[function TOpenSaveDialog.Execute]
  40855. {$IFDEF ASM_UNICODE}
  40856. {$ELSE ASM_VERSION} //Pascal
  40857. function TOpenSaveDialog.Execute: Boolean;
  40858. const OpenSaveFlags: array[ TOpenSaveOption ] of Integer = (
  40859. OFN_CREATEPROMPT,
  40860. OFN_EXTENSIONDIFFERENT,
  40861. OFN_FILEMUSTEXIST,
  40862. OFN_HIDEREADONLY,
  40863. OFN_NOCHANGEDIR,
  40864. OFN_NODEREFERENCELINKS,
  40865. OFN_ALLOWMULTISELECT,
  40866. OFN_NONETWORKBUTTON,
  40867. OFN_NOREADONLYRETURN,
  40868. OFN_OVERWRITEPROMPT,
  40869. OFN_PATHMUSTEXIST,
  40870. OFN_READONLY,
  40871. OFN_NOVALIDATE
  40872. //{$IFDEF OpenSaveDialog_Extended}
  40873. ,
  40874. OFN_ENABLETEMPLATE,
  40875. OFN_ENABLEHOOK
  40876. //{$ENDIF}
  40877. );
  40878. var
  40879. Ofn : TOpenFilename;
  40880. Fltr : KOLString;
  40881. TempFilename : KOLString;
  40882. Function MakeFilter(s : string) : String;
  40883. {
  40884. format of filter for API call is following:
  40885. 'text files'#0'*.txt'#0
  40886. 'bitmap files'#0'*.bmp'#0#0
  40887. }
  40888. var Str: PChar;
  40889. begin
  40890. Result := s;
  40891. if Result='' then
  40892. exit;
  40893. Result:=Result+#0; {Delphi string always end on #0 is this is #0#0}
  40894. Str := PChar( Result );
  40895. while Str^ <> #0 do
  40896. begin
  40897. if Str^ = '|' then
  40898. Str^ := #0;
  40899. Inc( Str );
  40900. end;
  40901. end;
  40902. var m: Integer;
  40903. begin
  40904. Fillchar( ofn, sizeof( ofn ), 0 );
  40905. {$ifdef wince}
  40906. ofn.lStructSize := Sizeof( ofn );
  40907. {$else}
  40908. {$IFDEF OpenSaveDialog_Extended}
  40909. if (WinVer <= wvNT) and (WinVer <> wvME) then
  40910. ofn.lStructSize := 76
  40911. else
  40912. begin
  40913. ofn.lStructSize := Sizeof( ofn );
  40914. ofn.FlagsEx := Integer( NoPlaceBar );
  40915. end;
  40916. {$ELSE}
  40917. ofn.lStructSize:= 76; //to provide correct work in Win9x
  40918. {$ENDIF}
  40919. {$endif wince}
  40920. if fWnd <> 0 then
  40921. ofn.hWndOwner := fWnd
  40922. else
  40923. if assigned(applet) then
  40924. ofn.hwndOwner:=applet.Handle;
  40925. ofn.hInstance:=HInstance;
  40926. Fltr:=MakeFilter(FFilter);
  40927. if Fltr <> '' then
  40928. ofn.lpstrFilter := PKOLchar(Fltr);
  40929. ofn.nFilterIndex := FFilterIndex;
  40930. if OSAllowMultiSelect in FOptions then
  40931. ofn.nMaxFile := High(word)-14 // by V.K. (exchanged condition)
  40932. else
  40933. ofn.nMaxFile := MAX_PATH+2;
  40934. SetLength( TempFileName, ofn.nMaxFile );
  40935. FillChar( TempFileName[ 1 ], ofn.nMaxFile * sizeof( KOLChar ), 0 );
  40936. m := Min( ofn.nMaxFile, Length(fFileName) );
  40937. {$IFDEF UNICODE_CTRLS}
  40938. ofn.lpstrFile := PKOLchar( TempFileName );
  40939. WStrLCopy(PWideChar(TempFileName), PWideChar(fFileName), m );
  40940. {$ELSE}
  40941. ofn.lpstrFile := StrLCopy(PKOLChar(TempFileName), PKOLchar(fFileName), m );
  40942. {$ENDIF}
  40943. ofn.lpstrInitialDir:=PKOLChar(FInitialDir);
  40944. ofn.lpstrTitle := PKOLChar(FTitle);
  40945. ofn.Flags := MakeFlags( @FOptions, OpenSaveFlags )
  40946. or OFN_EXPLORER or OFN_LONGNAMES{$ifdef win32} or OFN_ENABLESIZING{$endif};
  40947. ofn.lpstrDefExt := PKOLChar(FDefExtension);
  40948. ofn.lCustData := integer(@self);
  40949. {$ifdef win32}
  40950. {$IFDEF OpenSaveDialog_Extended}
  40951. ofn.lpTemplateName := PKOLChar( TemplateName );
  40952. ofn.lpfnHook := HookProc;
  40953. {$ELSE}
  40954. ofn.lpTemplateName := nil;
  40955. ofn.lpfnHook := nil;
  40956. {$ENDIF}
  40957. {$endif win32}
  40958. if fOpenDialog then
  40959. result := GetOpenFileName(POpenFileName( @ofn )^)
  40960. else
  40961. result := GetSaveFileName(POpenFileName( @ofn )^);
  40962. if result then begin
  40963. fFilterIndex := ofn.nFilterIndex; // by Vadim
  40964. fOpenReadOnly := OFN_READONLY and ofn.Flags <> 0; // by ECM (in my redaction)
  40965. if OSAllowMultiSelect in foptions then begin
  40966. FFileName := copy(TempFileName, 1, pos(#0#0, tempfilename)-1);
  40967. while pos(#0, ffilename) > 0 do begin
  40968. FFilename[pos(#0, ffilename)]:=#13;
  40969. end;
  40970. end else
  40971. FFileName := copy(tempFileName, 1, pos(#0, TempFilename)
  40972. -1 // by X.Y.B.
  40973. );
  40974. end else
  40975. FFilename:='';
  40976. end;
  40977. {$ENDIF ASM_VERSION}
  40978. {$ifdef wince}
  40979. {$define read_implementation}
  40980. {$I KOLCEOpenDir.inc}
  40981. {$undef read_implementation}
  40982. {$else}
  40983. { -- OpenDirDialog -- }
  40984. //*
  40985. //[function NewOpenDirDialog]
  40986. function NewOpenDirDialog( const Title: KOLString; Options: TOpenDirOptions ):
  40987. POpenDirDialog;
  40988. begin
  40989. {-}
  40990. New( Result, Create );
  40991. {+}{++}(*Result := POpenDirDialog.Create;*){--}
  40992. Result.FOptions := [ odOnlySystemDirs ];
  40993. if Options <> [] then
  40994. Result.FOptions := Options;
  40995. Result.FTitle := Title;
  40996. end;
  40997. //[END NewOpenDirDialog]
  40998. { TOpenDirDialog }
  40999. //[destructor TOpenDirDialog.Destroy]
  41000. {$IFDEF ASM_VERSION}
  41001. {$ELSE ASM_VERSION} //Pascal
  41002. destructor TOpenDirDialog.Destroy;
  41003. begin
  41004. FTitle := '';
  41005. FInitialPath := '';
  41006. FStatusText := '';
  41007. inherited;
  41008. end;
  41009. {$ENDIF ASM_VERSION}
  41010. {$ifdef win32}
  41011. type
  41012. PSHItemID = ^TSHItemID;
  41013. TSHItemID = {$ifndef wince}packed{$endif} record
  41014. cb: Word; { Size of the ID (including cb itself) }
  41015. abID: array[0..0] of Byte; { The item ID (variable length) }
  41016. end;
  41017. PItemIDList = ^TItemIDList;
  41018. TItemIDList = record
  41019. mkid: TSHItemID;
  41020. end;
  41021. PBrowseInfo = ^TBrowseInfo;
  41022. TBrowseInfoA = record
  41023. hwndOwner: HWND;
  41024. pidlRoot: PItemIDList;
  41025. pszDisplayName: PChar; { Return display name of item selected. }
  41026. lpszTitle: PChar; { text to go in the banner over the tree. }
  41027. ulFlags: UINT; { Flags that control the return stuff }
  41028. lpfn: Pointer; //TFNBFFCallBack;
  41029. lParam: LPARAM; { extra info that's passed back in callbacks }
  41030. iImage: Integer; { output var: where to return the Image index. }
  41031. end;
  41032. TBrowseInfoW = record
  41033. hwndOwner: HWND;
  41034. pidlRoot: PItemIDList;
  41035. pszDisplayName: PWideChar; { Return display name of item selected. }
  41036. lpszTitle: PWideChar; { text to go in the banner over the tree. }
  41037. ulFlags: UINT; { Flags that control the return stuff }
  41038. lpfn: Pointer; //TFNBFFCallBack;
  41039. lParam: LPARAM; { extra info that's passed back in callbacks }
  41040. iImage: Integer; { output var: where to return the Image index. }
  41041. end;
  41042. TBrowseInfo = {$IFDEF UNICODE_CTRLS} TBrowseInfoW {$ELSE} TBrowseInfoA {$ENDIF};
  41043. //[API SHXXXXXXXXXX]
  41044. function SHBrowseForFolderA(var lpbi: TBrowseInfoA): PItemIDList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  41045. external 'shell32.dll' name 'SHBrowseForFolderA';
  41046. {$IFDEF UNICODE_CTRLS}
  41047. function SHBrowseForFolderW(var lpbi: TBrowseInfoW): PItemIDList; {$ifdef wince}cdecl{$else}stdcall{$endif};
  41048. external 'shell32.dll' name 'SHBrowseForFolderW';
  41049. {$ENDIF UNICODE_CTRLS}
  41050. function SHGetPathFromIDListA(pidl: PItemIDList; pszPath: PChar): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  41051. external 'shell32.dll' name 'SHGetPathFromIDListA';
  41052. {$IFDEF UNICODE_CTRLS}
  41053. function SHGetPathFromIDListW(pidl: PItemIDList; pszPath: PKOLChar): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  41054. external 'shell32.dll' name 'SHGetPathFromIDListW';
  41055. {$ENDIF UNICODE_CTRLS}
  41056. procedure CoTaskMemFree(pv: Pointer); {$ifdef wince}cdecl{$else}stdcall{$endif}; external 'ole32.dll'
  41057. name 'CoTaskMemFree';
  41058. const
  41059. BIF_RETURNONLYFSDIRS = $0001; { For finding a folder to start document searching }
  41060. BIF_DONTGOBELOWDOMAIN = $0002; { For starting the Find Computer }
  41061. BIF_STATUSTEXT = $0004;
  41062. BIF_RETURNFSANCESTORS = $0008;
  41063. BIF_EDITBOX = $0010;
  41064. BIF_VALIDATE = $0020; { insist on valid result (or CANCEL) }
  41065. BIF_NEWDIALOGSTYLE = $0040; { Use the new dialog layout with the ability to resize }
  41066. { Caller needs to call OleInitialize() before using this API (c) JVCL }
  41067. BIF_BROWSEFORCOMPUTER = $1000; { Browsing for Computers. }
  41068. BIF_BROWSEFORPRINTER = $2000; { Browsing for Printers }
  41069. BIF_BROWSEINCLUDEFILES = $4000; { Browsing for Everything }
  41070. BFFM_INITIALIZED = 1;
  41071. BFFM_SELCHANGED = 2;
  41072. BFFM_SETSTATUSTEXT = WM_USER + 100;
  41073. BFFM_ENABLEOK = WM_USER + 101;
  41074. BFFM_SETSELECTION = WM_USER + 102;
  41075. {$endif win32}
  41076. {$IFDEF ASM_UNICODE} // WndOwner
  41077. //[function TOpenDirDialog.Execute]
  41078. function TOpenDirDialog.Execute: Boolean;
  41079. asm
  41080. PUSH EBX
  41081. XCHG EBX, EAX
  41082. XOR ECX, ECX
  41083. PUSH ECX // prepare iImage = 0
  41084. PUSH EBX // prepare lParam = @Self
  41085. PUSH [EBX].FCallBack // prepare lpfn = FCallBack
  41086. LEA EAX, [EBX].FOptions
  41087. MOV EDX, Offset[@@FlagsArray]
  41088. MOV CL, 8
  41089. CALL MakeFlags
  41090. PUSH EAX // prepare ulFlags = Options
  41091. PUSH [EBX].FTitle // prepare lpszTitle
  41092. LEA EAX, [EBX].FBuf
  41093. PUSH EAX // prepare pszDisplayName
  41094. PUSH 0 // prepare pidlRoot
  41095. MOV ECX, [EBX].fWnd
  41096. INC ECX
  41097. LOOP @@1
  41098. MOV ECX, Applet
  41099. JECXZ @@1
  41100. MOV ECX, [ECX].TControl.fHandle
  41101. @@1: PUSH ECX // prepare hwndOwner
  41102. PUSH ESP
  41103. CALL SHBrowseForFolderA
  41104. ADD ESP, 32
  41105. TEST EAX, EAX
  41106. JZ @@exit
  41107. PUSH EAX
  41108. LEA EDX, [EBX].FBuf
  41109. PUSH EDX
  41110. PUSH EAX
  41111. CALL SHGetPathFromIDListA
  41112. CALL CoTaskMemFree
  41113. MOV AL, 1
  41114. JMP @@fin
  41115. @@FlagsArray:
  41116. DD BIF_BROWSEFORCOMPUTER, BIF_BROWSEFORPRINTER, BIF_DONTGOBELOWDOMAIN
  41117. DD BIF_RETURNFSANCESTORS, BIF_RETURNONLYFSDIRS, BIF_STATUSTEXT
  41118. DD BIF_BROWSEINCLUDEFILES, BIF_EDITBOX, BIF_NEWDIALOGSTYLE
  41119. @@exit: XOR EAX, EAX
  41120. @@fin:
  41121. POP EBX
  41122. end;
  41123. {$ELSE ASM_VERSION} //Pascal
  41124. function TOpenDirDialog.Execute: Boolean;
  41125. const FlagsArray: array[ TOpenDirOption ] of Integer =
  41126. ( BIF_BROWSEFORCOMPUTER, BIF_BROWSEFORPRINTER, BIF_DONTGOBELOWDOMAIN,
  41127. BIF_RETURNFSANCESTORS, BIF_RETURNONLYFSDIRS, BIF_STATUSTEXT,
  41128. BIF_BROWSEINCLUDEFILES, BIF_EDITBOX, BIF_NEWDIALOGSTYLE );
  41129. var BI : TBrowseInfo;
  41130. Browse : PItemIdList;
  41131. begin
  41132. Result := False;
  41133. if WndOwner <> 0 then
  41134. BI.hwndOwner := WndOwner
  41135. else
  41136. if assigned( Applet ) then
  41137. BI.hwndOwner := Applet.Handle
  41138. else
  41139. BI.hwndOwner := 0;
  41140. BI.pidlRoot := nil;
  41141. BI.pszDisplayName := @FBuf[ 0 ];
  41142. BI.lpszTitle := PKOLChar( Title );
  41143. BI.ulFlags := MakeFlags( @FOptions, FlagsArray );
  41144. BI.lpfn := FCallBack;
  41145. BI.lParam := Integer( @Self );
  41146. Browse := {$IFDEF UNICODE_CTRLS} SHBrowseForFolderW {$ELSE} SHBrowseForFolderA {$ENDIF}
  41147. ( BI );
  41148. if Browse <> nil then
  41149. begin
  41150. {$IFDEF UNICODE_CTRLS}SHGetPathFromIDListW{$ELSE} SHGetPathFromIDListA{$ENDIF}( Browse, @FBuf[ 0 ] );
  41151. CoTaskMemFree( Browse );
  41152. Result := True;
  41153. end;
  41154. end;
  41155. {$ENDIF ASM_VERSION}
  41156. //[function TOpenDirDialog.GetInitialPath]
  41157. function TOpenDirDialog.GetInitialPath: KOLString;
  41158. begin
  41159. Result := IncludeTrailingPathDelimiter( fInitialPath );
  41160. end;
  41161. //[function TOpenDirDialog.GetPath]
  41162. function TOpenDirDialog.GetPath: KOLString;
  41163. begin
  41164. Result := FBuf;
  41165. end;
  41166. //[FUNCTION OpenDirSelChangeCallBack]
  41167. {$IFDEF ASM_UNICODE}
  41168. {$ELSE ASM_VERSION} //Pascal
  41169. function OpenDirSelChangeCallBack( Wnd: HWnd; Msg: DWORD; lParam, lpData: LParam ):
  41170. Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  41171. var _Self_: POpenDirDialog;
  41172. EnableOK: Integer;
  41173. begin
  41174. _Self_ := Pointer( lpData );
  41175. if assigned( _Self_.FOnSelChanged ) then
  41176. begin
  41177. {$IFDEF UNICODE_CTRLS} SHGetPathFromIDListW {$ELSE} SHGetPathFromIDListA {$ENDIF}( PItemIDList( lParam ), @ _Self_.FBuf[ 0 ] );
  41178. EnableOK := 0;
  41179. _Self_.FOnSelChanged( _Self_, _Self_.FBuf, EnableOK,
  41180. KOL_String( KOLString( _Self_.FStatusText ) ) );
  41181. SendMessage( Wnd, BFFM_ENABLEOK, 0, EnableOK );
  41182. if _Self_.FStatusText <> '' then
  41183. SendMessage( Wnd, BFFM_SETSTATUSTEXT, 0, Integer( PKOLChar( _Self_.FStatusText ) ) );
  41184. end;
  41185. Result := 0;
  41186. end;
  41187. {$ENDIF ASM_VERSION}
  41188. //[END OpenDirSelChangeCallBack]
  41189. {$IFDEF ASM_LOCAL} {$UNDEF ASM_LOCAL} {$ENDIF}
  41190. {$IFNDEF NEW_OPEN_DIR_STYLE_EX}
  41191. {$IFDEF ASM_VERSION} {$DEFINE ASM_LOCAL} {$ENDIF}
  41192. {$ENDIF}
  41193. //[FUNCTION OpenDirCallBack]
  41194. {$IFDEF ASM_LOCAL}
  41195. {$ELSE ASM_VERSION} //Pascal
  41196. function OpenDirCallBack( Wnd: HWnd; Msg: DWORD; lParam, lpData: LParam ): Integer;
  41197. {$ifdef wince}cdecl{$else}stdcall{$endif};
  41198. {$IFDEF NEW_OPEN_DIR_STYLE_EX}
  41199. const
  41200. Shel: array[ 0..3 ] of Char = 'SHBr';
  41201. {$ENDIF}
  41202. var Self_ : POpenDirDialog;
  41203. {$IFDEF NEW_OPEN_DIR_STYLE_EX}
  41204. WList: HWnd;
  41205. ClassBuf: array[ 0..127 ] of KOLChar;
  41206. {$ENDIF}
  41207. begin
  41208. Self_ := Pointer( lpData );
  41209. Self_.FDialogWnd := Wnd;
  41210. if Msg = BFFM_INITIALIZED then
  41211. begin
  41212. if assigned( Self_.FCenterProc ) then
  41213. Self_.FCenterProc( Wnd );
  41214. if Self_.FInitialPath <> '' then
  41215. begin
  41216. {$IFDEF NEW_OPEN_DIR_STYLE_EX}
  41217. WList := GetWindow( Wnd, GW_CHILD );
  41218. while WList <> 0 do
  41219. begin
  41220. WList := GetWindow( WList, GW_HWNDNEXT );
  41221. GetClassName( WList, @ ClassBuf[ 0 ], Sizeof( ClassBuf ) );
  41222. if PDWord( @ ClassBuf[ 0 ] )^ = DWORD( Shel ) then
  41223. begin
  41224. PostMessage( Wnd, WM_NEXTDLGCTL, WList, 1 );
  41225. break;
  41226. end;
  41227. end;
  41228. PostMessage( Wnd, BFFM_SETSELECTION, 1, Integer( PChar(
  41229. ExtractFilePath( Self_.FInitialPath ) ) ) );
  41230. PostMessage( WND, WM_KEYDOWN, VK_ADD, 0 );
  41231. PostMessage( WND, WM_KEYUP, VK_ADD, 0 );
  41232. PostMessage( Wnd, BFFM_SETSELECTION, 1, Integer( PKOLChar( Self_.FInitialPath ) ) );
  41233. {$ELSE}
  41234. SendMessage( Wnd, BFFM_SETSELECTION, 1, Integer( PKOLChar( Self_.FInitialPath ) ) );
  41235. {$ENDIF}
  41236. SendMessage( Wnd, BFFM_ENABLEOK, 0, 1 );
  41237. end;
  41238. end
  41239. else
  41240. if Msg = BFFM_SELCHANGED then
  41241. begin
  41242. if assigned( Self_.FDoSelChanged ) then
  41243. Self_.FDoSelChanged( Wnd, Msg, lParam, lpData )
  41244. else
  41245. SendMessage( Wnd, BFFM_ENABLEOK, 0, 1 );
  41246. end;
  41247. Result := 0;
  41248. end;
  41249. {$ENDIF ASM_VERSION}
  41250. //[END OpenDirCallBack]
  41251. //[PROCEDURE OpenDirDlgCenter]
  41252. {$IFDEF ASM_VERSION}
  41253. {$ELSE ASM_VERSION} //Pascal
  41254. procedure OpenDirDlgCenter( Wnd: HWnd );
  41255. var R: TRect;
  41256. W, H: Integer;
  41257. begin
  41258. GetWindowRect( Wnd, R );
  41259. W := R.Right - R.Left;
  41260. H := R.Bottom - R.Top;
  41261. R.Left := (GetSystemMetrics( SM_CXSCREEN ) - W) div 2;
  41262. R.Top := (GetSystemMetrics( SM_CYSCREEN ) - H) div 2;
  41263. MoveWindow( Wnd, R.Left, R.Top, W, H, True );
  41264. end;
  41265. {$ENDIF ASM_VERSION}
  41266. //[END OpenDirDlgCenter]
  41267. //[procedure TOpenDirDialog.SetCenterOnScreen]
  41268. {$IFDEF ASM_VERSION}
  41269. {$ELSE ASM_VERSION} //Pascal
  41270. procedure TOpenDirDialog.SetCenterOnScreen(const Value: Boolean);
  41271. var P: procedure( Wnd: HWnd );
  41272. begin
  41273. FCenterOnScreen := Value;
  41274. P := nil;
  41275. if Value then
  41276. P := @OpenDirDlgCenter;
  41277. FCenterProc := P;
  41278. end;
  41279. {$ENDIF ASM_VERSION}
  41280. //[procedure TOpenDirDialog.SetInitialPath]
  41281. procedure TOpenDirDialog.SetInitialPath(const Value: KOLString);
  41282. begin
  41283. FCallBack := @OpenDirCallBack;
  41284. FInitialPath := ExcludeTrailingPathDelimiter( Value );
  41285. if (FInitialPath <> '') and
  41286. (FInitialPath[ Length( FInitialPath ) ] = ':') then
  41287. FInitialPath := IncludeTrailingPathDelimiter( Value );
  41288. end;
  41289. //[procedure TOpenDirDialog.SetOnSelChanged]
  41290. procedure TOpenDirDialog.SetOnSelChanged(const Value: TOnODSelChange);
  41291. begin
  41292. FOnSelChanged := Value;
  41293. FCallBack := @OpenDirCallBack;
  41294. FDoSelChanged := @OpenDirSelChangeCallBack;
  41295. end;
  41296. {$endif wince}
  41297. type
  41298. PByteArray =^TByteArray;
  41299. TByteArray = array[Word]of Byte;
  41300. //[function CreateMappedBitmapEx]
  41301. function CreateMappedBitmapEx(Instance: THandle; BmpRsrcName: PKOLChar; Flags:
  41302. Cardinal; ColorMap: PColorMap; NumMaps: Integer): HBitmap;
  41303. var tmcl: Cardinal;
  41304. {$ifndef wince}
  41305. bi: TBITMAPINFO;
  41306. DC: Cardinal;
  41307. {$endif}
  41308. Bits: PByteArray;
  41309. i, j, k, CO, bps: Integer;
  41310. tm: array [1..4] of byte absolute tmcl;
  41311. bm: Windows.TBITMAP;
  41312. CM: PColorMap;
  41313. {$ifdef wince}
  41314. tbmp, tbmp2: PBitmap;
  41315. {$else}
  41316. DW: HWnd;
  41317. {$endif wince}
  41318. begin
  41319. Result := LoadBitmap( Instance, BmpRsrcName );
  41320. if Result = 0 then
  41321. begin
  41322. {$IFDEF DEBUG}
  41323. ShowMessage( 'Can not load bitmap ' + BmpRsrcName + ', error ' +
  41324. Int2Str( GetLastError ) + ': ' + SysErrorMessage( GetLastError ) );
  41325. {$ENDIF}
  41326. Exit;
  41327. end;
  41328. FillChar( bm, SizeOf(bm), #0 );
  41329. GetObject( Result, SizeOf( bm ), @bm );
  41330. {$ifdef wince}
  41331. tbmp:=NewDIBBitmap(bm.bmWidth, bm.bmHeight, pf24bit);
  41332. tbmp2:=NewBitmap(0, 0);
  41333. tbmp2.Handle:=Result;
  41334. tbmp2.Draw(tbmp.Canvas.Handle, 0, 0);
  41335. tbmp.RemoveCanvas;
  41336. Bits:=tbmp.DIBBits;
  41337. bps := CalcScanLineSize( @tbmp.DibHeader.bmiHeader );
  41338. CM:=ColorMap;
  41339. for k := 1 to NumMaps do begin
  41340. tbmp2.Pixels[0, 0]:=Color2RGB(CM.{$ifdef wince}from{$else}cFrom{$endif});
  41341. CM.{$ifdef wince}from{$else}cFrom{$endif}:=tbmp2.Pixels[0, 0];
  41342. CM.{$ifdef wince}_to{$else}cTo{$endif}:=Color2RGB(CM.{$ifdef wince}_to{$else}cTo{$endif});
  41343. Inc(CM);
  41344. end;
  41345. tbmp2.Free;
  41346. {$else}
  41347. FillChar( bi, SizeOf( bi ), #0 );
  41348. bi.bmiHeader.biSize := SizeOf( bi.bmiHeader );
  41349. bi.bmiHeader.biWidth := bm.bmWidth;
  41350. bi.bmiHeader.biHeight := -bm.bmHeight;
  41351. bi.bmiHeader.biPlanes := 1;
  41352. bi.bmiHeader.biBitCount := 24;
  41353. // BitCout - always 24 for easy algorythm
  41354. bi.bmiHeader.biCompression:=BI_RGB;
  41355. bps := CalcScanLineSize( @bi.bmiHeader );
  41356. GetMem( Bits, bps * bm.bmHeight );
  41357. DW := GetDesktopWindow;
  41358. DC := GetDC(DW);
  41359. GetDIBits( DC, Result, 0, bm.bmHeight, @Bits[0], bi, DIB_RGB_COLORS );
  41360. DeleteObject( Result );
  41361. {$endif wince}
  41362. for i := 0 to bm.bmHeight - 1 do begin
  41363. for j := 0 to bm.bmWidth - 1 do begin
  41364. CO := bps * i + 3 * j;
  41365. for k := 0 to NumMaps - 1 do begin
  41366. CM := Pointer( cardinal( ColorMap ) + SizeOf( TColorMap ) * cardinal(k) );
  41367. if RGB( Bits[CO+2], Bits[CO+1], Bits[CO] ) = CM.{$ifdef wince}from{$else}cFrom{$endif} then
  41368. begin
  41369. tmcl := CM.{$ifdef wince}_to{$else}cTo{$endif};
  41370. tm[4]:=tm[1];
  41371. tm[1]:=tm[3];
  41372. tm[3]:=tm[4];
  41373. Move( tmcl, Bits[CO], 3);
  41374. end;
  41375. end;
  41376. end;
  41377. end;
  41378. {$ifdef wince}
  41379. Result:=tbmp.ReleaseHandle;
  41380. tbmp.Free;
  41381. {$else}
  41382. Result := CreateDIBitmap( DC, bi.bmiHeader, CBM_INIT, @Bits[0], bi,
  41383. DIB_RGB_COLORS );
  41384. ReleaseDC( DW, DC );
  41385. FreeMem( Bits );
  41386. {$endif wince}
  41387. end;
  41388. {$ifdef wince}
  41389. function CreateMappedBitmap(Instance: THandle; Bitmap: Integer;
  41390. Flags: UINT; ColorMap: PColorMap; NumMaps: Integer): HBitmap; {$ifdef wince}cdecl{$else}stdcall{$endif};
  41391. begin
  41392. Result:=CreateMappedBitmapEx(Instance, PKOLChar(Bitmap), Flags, ColorMap, NumMaps);
  41393. end;
  41394. {$else}
  41395. //[API CreateMappedBitmap]
  41396. function CreateMappedBitmap(Instance: THandle; Bitmap: Integer;
  41397. Flags: UINT; ColorMap: PColorMap; NumMaps: Integer): HBitmap; {$ifdef wince}cdecl{$else}stdcall{$endif};
  41398. external cctrl name 'CreateMappedBitmap';
  41399. {$endif wince}
  41400. //*
  41401. //[function LoadMappedBitmap]
  41402. function LoadMappedBitmap( hInst: THandle; BmpResID: Integer; const Map: array of TColor )
  41403. : HBitmap;
  41404. var Map2Pass: Pointer;
  41405. begin
  41406. Map2Pass := nil;
  41407. if High( Map ) > 0 then
  41408. Map2Pass := PColorMap( @Map[ 0 ] );
  41409. Result := CreateMappedBitmap( hInst, BmpResID, 0, Map2Pass, (High( Map ) + 1) div 2 );
  41410. end;
  41411. //[function LoadMappedBitmapEx]
  41412. function LoadMappedBitmapEx( MasterObj: PObj; hInst: THandle; BmpResName: PKOLChar; const Map: array of TColor )
  41413. : HBitmap;
  41414. var Map2Pass: Pointer;
  41415. begin
  41416. Map2Pass := nil;
  41417. if High( Map ) > 0 then
  41418. Map2Pass := PColorMap( @Map[ 0 ] );
  41419. Result := CreateMappedBitmapEx( hInst, BmpResName, 0, Map2Pass, (High( Map ) + 1) div 2 );
  41420. if MasterObj <> nil then
  41421. MasterObj.Add2AutoFreeEx( TObjectMethod( MakeMethod( Pointer( Result ), @ FreeBmp ) ) );
  41422. end;
  41423. { -- Toolbar -- }
  41424. {$IFDEF ASM_noVERSION} // width
  41425. //[procedure TControl.TBAddBitmap]
  41426. procedure TControl.TBAddBitmap(Bitmap: HBitmap);
  41427. const szBI = sizeof(TBitmapInfo);
  41428. asm
  41429. TEST EDX, EDX
  41430. JZ @@exit
  41431. JGE @@1
  41432. CMP EDX, -6
  41433. JL @@1
  41434. NEG EDX
  41435. DEC EDX
  41436. PUSH EDX
  41437. PUSH -1
  41438. XOR EDX, EDX
  41439. JMP @@2
  41440. @@1: PUSH EDX // AB.hInst = Bitmap
  41441. PUSH 0 // AB.nID = 0
  41442. PUSH EAX // > @Self
  41443. ADD ESP, -szBI
  41444. PUSH ESP
  41445. PUSH szBI
  41446. PUSH EDX
  41447. CALL GetObject
  41448. TEST EAX, EAX
  41449. JG @@11
  41450. ADD ESP, szBI
  41451. JMP @@exit
  41452. @@11: MOV EAX, [ESP].TBitmapInfo.bmiHeader.biWidth
  41453. MOV ECX, [ESP].TBitmapInfo.bmiHeader.biHeight
  41454. TEST ECX, ECX
  41455. JGE @@12
  41456. NEG ECX
  41457. @@12: ADD ESP, szBI
  41458. CDQ // EDX = 0
  41459. DIV ECX // EAX = N
  41460. XCHG EAX, [ESP] // > N
  41461. PUSH EAX // > @Self
  41462. MOV EDX, ECX
  41463. SHL EDX, 16
  41464. OR ECX, EDX
  41465. CDQ
  41466. PUSH EDX
  41467. PUSH EDX
  41468. PUSH TB_AUTOSIZE
  41469. PUSH EAX
  41470. PUSH ECX
  41471. PUSH EDX
  41472. PUSH TB_SETBITMAPSIZE
  41473. PUSH EAX
  41474. CALL Perform
  41475. CALL Perform
  41476. POP EAX
  41477. POP EDX
  41478. @@2: PUSH ESP
  41479. PUSH EDX
  41480. PUSH TB_ADDBITMAP
  41481. PUSH EAX
  41482. CALL Perform
  41483. POP ECX
  41484. POP ECX
  41485. @@exit:
  41486. end;
  41487. {$ELSE ASM_VERSION} //Pascal
  41488. procedure TControl.TBAddBitmap(Bitmap: HBitmap);
  41489. //const NstdBitmaps: array[ 0..5 ] of DWORD = ( 15, 15, 0, 0, 13, 13 );
  41490. var BI: TBitmapInfo;
  41491. AB: TTBAddBitmap;
  41492. N, W: Integer;
  41493. begin
  41494. if Bitmap = 0 then Exit;
  41495. if (Integer( Bitmap ) >= -10) and (Integer( Bitmap ) <= -1) then
  41496. begin
  41497. AB.hInst := THandle(-1);
  41498. AB.nID := -Integer(Bitmap) - 1;
  41499. N := 0; //NstdBitmaps[ AB.nID ]; // (this value is ignored)
  41500. end
  41501. else
  41502. if GetObject( Bitmap, sizeof( TBitmapInfo ), @BI ) > 0 then
  41503. begin
  41504. AB.hInst := 0;
  41505. AB.nID := Bitmap;
  41506. W := fTBBtnImgWidth;
  41507. if W = 0 then
  41508. W := Abs( BI.bmiHeader.biHeight );
  41509. N := BI.bmiHeader.biWidth div W;
  41510. Perform( TB_SETBITMAPSIZE, 0, MAKELONG( W, Abs(BI.bmiHeader.biHeight )) );
  41511. Perform( TB_AUTOSIZE, 0, 0 );
  41512. end
  41513. else Exit;
  41514. Perform( TB_ADDBITMAP, N, Integer( @AB ) );
  41515. end;
  41516. {$ENDIF ASM_VERSION}
  41517. //[function TControl.TBAddInsButtons]
  41518. {$IFDEF ASM_UNICODE}
  41519. {$ELSE ASM_VERSION} //Pascal
  41520. function TControl.TBAddInsButtons(Idx: Integer; const Buttons: array of PKOLChar;
  41521. const BtnImgIdxArray: array of Integer): Integer;
  41522. function AddInsButtons: Integer;
  41523. type TTBBtnArray = array[ 0..100000 ] of TTBButton;
  41524. PTBBtnArray = ^TTBBtnArray;
  41525. var AB: PTBBtnArray;
  41526. I, N, nBmp: Integer;
  41527. PAB: PTBButton;
  41528. Str: PKOLChar;
  41529. begin
  41530. Result := -1;
  41531. AB := nil;
  41532. if High( Buttons ) >= 0 then
  41533. GetMem( AB, Sizeof( TTBButton ) * (High(Buttons) + 1) );
  41534. N := 0;
  41535. PAB := @AB[ 0 ];
  41536. nBmp := -2;
  41537. if High(BtnImgIdxArray) >= 0 then
  41538. nBmp := BtnImgIdxArray[ 0 ] - 1;
  41539. for I:= 0 to High( Buttons ) do
  41540. begin
  41541. if Buttons[ I ] = nil then break;
  41542. if {$IFDEF UNICODE_CTRLS} WStrComp {$ELSE} StrComp {$ENDIF}
  41543. ( Buttons[ I ], {$IFDEF F_P}''+{$ENDIF} '-' ) = 0 then
  41544. begin
  41545. PAB.iBitmap := -1;
  41546. //PAB.idCommand := 0;
  41547. PAB.fsState := 0;
  41548. PAB.fsStyle := TBSTYLE_SEP;
  41549. PAB.iString := -1;
  41550. end
  41551. else
  41552. begin
  41553. Str := Buttons[ I ];
  41554. Inc( nBmp );
  41555. PAB.iBitmap := nBmp;
  41556. if nBmp < 0 then
  41557. Dec( nBmp );
  41558. if High( BtnImgIdxArray ) >= N then
  41559. PAB.iBitmap := BtnImgIdxArray[ N ];
  41560. PAB.fsState := TBSTATE_ENABLED;
  41561. PAB.fsStyle := TBSTYLE_BUTTON or TBSTYLE_AUTOSIZE;
  41562. if Str^ = '^' then
  41563. begin
  41564. PAB.fsStyle := TBSTYLE_DROPDOWN or TBSTYLE_AUTOSIZE;
  41565. Inc( Str );
  41566. end;
  41567. if CharIn( Str^, [ '-', '+' ] ) then
  41568. begin
  41569. PAB.fsStyle := PAB.fsStyle or TBSTYLE_CHECK;
  41570. if Str^ = '+' then
  41571. PAB.fsState := PAB.fsState or TBSTATE_CHECKED;
  41572. Inc( Str );
  41573. if Str^ = '!' then
  41574. begin
  41575. PAB.fsStyle := PAB.fsStyle or TBSTYLE_GROUP;
  41576. Inc( Str );
  41577. end;
  41578. end;
  41579. {$IFDEF TOOLBAR_DOT_NOAUTOSIZE_BUTTON}
  41580. if Str^ = '.' then
  41581. begin
  41582. PAB.fsStyle := PAB.fsStyle and not TBSTYLE_AUTOSIZE;
  41583. inc( Str );
  41584. end;
  41585. {$ENDIF TOOLBAR_DOT_NOAUTOSIZE_BUTTON}
  41586. if (Str = KOLString( {$IFDEF F_P}''+{$ENDIF} KOLChar( ' ' ) )) or (Str^ = #0) then
  41587. PAB.iString := -1
  41588. //Perform( TB_ADDSTRING, 0, Integer( PChar( '' + #0 ) ) )
  41589. // an experiment: is it possible to remove space right to image
  41590. // without setting tboTextBottom option (non compatible with FixFlatXP)
  41591. // answer: seems not possible.
  41592. else
  41593. PAB.iString :=
  41594. Perform( TB_ADDSTRING, 0, Integer( PKOLChar( KOLString( '' + Str + #0 ) ) ) );
  41595. end;
  41596. PAB.idCommand := ToolbarsIDcmd;
  41597. if Result < 0 then Result := PAB.idCommand;
  41598. Inc( ToolbarsIDcmd );
  41599. PAB.dwData := Integer( @Self );
  41600. Inc( N );
  41601. Inc( PAB );
  41602. end;
  41603. if N > 0 then
  41604. begin
  41605. if Idx < 0 then
  41606. Perform( TB_ADDBUTTONS, N, Integer( @AB[ 0 ] ) )
  41607. else
  41608. Perform( TB_INSERTBUTTON, Idx, Integer( @AB[ 0 ] ) );
  41609. end;
  41610. if AB <> nil then
  41611. FreeMem( AB );
  41612. end;
  41613. begin
  41614. if High( Buttons ) < 0 then
  41615. Result := -1
  41616. else
  41617. Result := AddInsButtons;
  41618. end;
  41619. {$ENDIF ASM_VERSION}
  41620. //[function TControl.TBAddButtons]
  41621. {$IFDEF ASM_VERSION}
  41622. {$ELSE ASM_VERSION} //Pascal
  41623. function TControl.TBAddButtons(const Buttons: array of PKOLChar;
  41624. const BtnImgIdxArray: array of Integer): Integer;
  41625. begin
  41626. Result := TBAddInsButtons( -1, Buttons, BtnImgIdxArray );
  41627. end;
  41628. {$ENDIF ASM_VERSION}
  41629. //*
  41630. //[function TControl.TBInsertButtons]
  41631. function TControl.TBInsertButtons(BeforeIdx: Integer;
  41632. Buttons: array of PKOLChar; BtnImgIdxArray: array of Integer): Integer;
  41633. var I, J, K: Integer;
  41634. begin
  41635. J := -1;
  41636. Result := -1;
  41637. for I := 0 to High( Buttons ) do
  41638. begin
  41639. if I <= High( BtnImgIdxArray ) then
  41640. J := BtnImgIdxArray[ I ]
  41641. else
  41642. if J >= 0 then Inc( J );
  41643. K := TBAddInsButtons( BeforeIdx, [ Buttons[ I ], '' ], [ J ] );
  41644. if Result < 0 then Result := K;
  41645. end;
  41646. end;
  41647. //[function GetTBBtnGoodID]
  41648. function GetTBBtnGoodID( Toolbar: PControl; BtnIDorIdx: Integer ): Integer;
  41649. // change by Alexander Pravdin (to fix toolbar with separator first):
  41650. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  41651. var Btn1st, i: Integer; btn: TTBButton;
  41652. begin
  41653. Result := BtnIDorIdx;
  41654. Btn1st := 0;
  41655. for i := 0 to Toolbar.TBButtonCount - 1 do begin
  41656. Toolbar.Perform( TB_GETBUTTON, i, Integer( @btn ) );
  41657. if btn.fsStyle <> TBSTYLE_SEP then begin
  41658. Btn1st := i;
  41659. Break;
  41660. end;
  41661. end;
  41662. if Result < Toolbar.TBIndex2Item( Btn1st ) then
  41663. Result := Toolbar.TBIndex2Item( Result );
  41664. end;
  41665. type
  41666. TTBButtonEvent = {$ifndef wince}packed{$endif} Record
  41667. BtnID: DWORD;
  41668. Event: TOnToolbarButtonClick;
  41669. end;
  41670. PTBButtonEvent = ^TTBButtonEvent;
  41671. //[procedure TControl.TBFreeTBevents]
  41672. procedure TControl.TBFreeTBevents;
  41673. begin
  41674. //if fTBevents <> nil then
  41675. begin
  41676. fTBevents.Release;
  41677. //fTBevents := nil;
  41678. end;
  41679. end;
  41680. //[function WndProcToolbarButtonsClicks]
  41681. function WndProcToolbarButtonsClicks( TB: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  41682. var I: Integer;
  41683. Event: PTBButtonEvent;
  41684. begin
  41685. Result := FALSE;
  41686. if Msg.message = CM_COMMAND then
  41687. begin
  41688. for I := TB.fTBevents.fCount-1 downto 0 do
  41689. begin
  41690. Event := TB.fTBevents.fItems[ I ];
  41691. if Integer( Event.BtnID ) = LoWord( Msg.wParam ) then
  41692. begin
  41693. if Assigned( Event.Event ) then
  41694. begin
  41695. TB.RefInc;
  41696. Rslt := DefWindowProc( Msg.hwnd, Msg.message, Msg.wParam, Msg.lParam );
  41697. Event.Event( TB, Event.BtnID );
  41698. TB.RefDec;
  41699. Result := TRUE;
  41700. Exit;
  41701. end;
  41702. break;
  41703. end;
  41704. end;
  41705. end;
  41706. end;
  41707. //[procedure TControl.TBAssignEvents]
  41708. procedure TControl.TBAssignEvents(BtnID: Integer;
  41709. Events: array of TOnToolbarButtonClick);
  41710. var I: Integer;
  41711. EventRec: PTBButtonEvent;
  41712. begin
  41713. if fTBevents = nil then
  41714. begin
  41715. fTBevents := NewList;
  41716. Add2AutoFreeEx( TBFreeTBevents );
  41717. AttachProc( WndProcToolbarButtonsClicks );
  41718. end;
  41719. BtnID := GetTBBtnGoodID( @Self, BtnID );
  41720. for I := 0 to High( Events ) do
  41721. begin
  41722. GetMem( EventRec, Sizeof( TTBButtonEvent ) );
  41723. fTBevents.Add( EventRec );
  41724. EventRec.Event := Events[ I ];
  41725. EventRec.BtnID := BtnID;
  41726. Inc( BtnID );
  41727. end;
  41728. end;
  41729. //[procedure TControl.TBResetImgIdx]
  41730. procedure TControl.TBResetImgIdx( BtnID, BtnCount: Integer );
  41731. begin
  41732. while BtnCount > 0 do
  41733. begin
  41734. TBButtonImage[ BtnID ] := -2;
  41735. Inc( BtnID );
  41736. Dec( BtnCount );
  41737. end;
  41738. end;
  41739. //*
  41740. //[function TControl.TBGetButtonVisible]
  41741. function TControl.TBGetButtonVisible(BtnID: Integer): Boolean;
  41742. begin
  41743. Result := Perform( TB_ISBUTTONHIDDEN, GetTBBtnGoodID( @ Self, BtnID ), 0 ) = 0;
  41744. end;
  41745. //*
  41746. //[function TControl.TBItem2Index]
  41747. function TControl.TBItem2Index(BtnID: Integer): Integer;
  41748. begin
  41749. Result := Perform( TB_COMMANDTOINDEX, BtnID, 0 );
  41750. end;
  41751. //*
  41752. //[procedure TControl.TBSetButtonVisible]
  41753. procedure TControl.TBSetButtonVisible(BtnID: Integer;
  41754. const Value: Boolean);
  41755. begin
  41756. BtnID := GetTBBtnGoodID( @Self, BtnID );
  41757. Perform( TB_HIDEBUTTON, BtnID, Integer( not Value ) );
  41758. end;
  41759. //[function TControl.TBGetBtnStt]
  41760. {$IFDEF ASM_VERSION}
  41761. {$ELSE ASM_VERSION} //Pascal
  41762. function TControl.TBGetBtnStt(BtnID: Integer; const Index: Integer): Boolean;
  41763. begin
  41764. BtnID := GetTBBtnGoodID( @Self, BtnID );
  41765. Result := Perform( Index + 8, BtnID, 0 ) <> 0;
  41766. end;
  41767. {$ENDIF ASM_VERSION}
  41768. //+
  41769. //[procedure TControl.TBSetBtnStt]
  41770. procedure TControl.TBSetBtnStt(BtnID: Integer; const Index: Integer; const Value: Boolean);
  41771. begin
  41772. BtnID := GetTBBtnGoodID( @Self, BtnID );
  41773. Perform( Index, BtnID, Integer( Value ) );
  41774. end;
  41775. //[function TControl.TBIndex2Item]
  41776. {$IFDEF ASM_VERSION}
  41777. {$ELSE ASM_VERSION} //Pascal
  41778. function TControl.TBIndex2Item(Idx: Integer): Integer;
  41779. var ButtonInfo: TTBButton;
  41780. begin
  41781. Result := -1;
  41782. if Perform( TB_GETBUTTON, Idx, Integer( @ButtonInfo ) ) <> 0 then
  41783. Result := ButtonInfo.idCommand;
  41784. end;
  41785. {$ENDIF ASM_VERSION}
  41786. //[procedure TControl.TBConvertIdxArray2ID]
  41787. procedure TControl.TBConvertIdxArray2ID(const IdxVars: array of PDWORD);
  41788. var i: Integer;
  41789. begin
  41790. for i := 0 to High( IdxVars ) do
  41791. IdxVars[ i ]^ := TBIndex2Item( IdxVars[ I ]^ );
  41792. end;
  41793. //[function TControl.TBGetButtonText]
  41794. {$IFDEF ASM_UNICODE}
  41795. {$ELSE ASM_VERSION} //Pascal
  41796. function TControl.TBGetButtonText( BtnID: Integer ): KOLString;
  41797. var Buffer: array[ 0..1023 ] of KOLChar;
  41798. begin
  41799. BtnID := GetTBBtnGoodID( @Self, BtnID );
  41800. if Perform( TB_GETBUTTONTEXT, BtnID, Integer( @Buffer[ 0 ] ) ) > 0 then
  41801. Result := Buffer
  41802. else
  41803. Result := '';
  41804. end;
  41805. {$ENDIF ASM_VERSION}
  41806. //*
  41807. //[function TControl.TBGetButtonRect]
  41808. function TControl.TBGetButtonRect(BtnID: Integer): TRect;
  41809. begin
  41810. BtnID := GetTBBtnGoodID( @Self, BtnID );
  41811. Perform( TB_GETITEMRECT, TBItem2Index( BtnID ), Integer( @Result ) );
  41812. end;
  41813. function ToolbarButtonRect( Toolbar: PControl; BtnID: Integer ): TRect;
  41814. begin
  41815. Result := Toolbar.TBGetButtonRect(BtnID);
  41816. end;
  41817. //*
  41818. //[function TControl.TBGetRows]
  41819. function TControl.TBGetRows: Integer;
  41820. begin
  41821. Result := 1;
  41822. UpdateWndStyles;
  41823. if (TBSTYLE_WRAPABLE and fStyle) <> 0 then
  41824. Result := Perform( TB_GETROWS, 0, 0 );
  41825. end;
  41826. //*
  41827. //[procedure TControl.TBSetRows]
  41828. procedure TControl.TBSetRows(const Value: Integer);
  41829. begin
  41830. Perform( TB_SETROWS, Value, 0 );
  41831. end;
  41832. //[function TControl.TBMoveBtn]
  41833. function TControl.TBMoveBtn(FromIdx, ToIdx: Integer): Boolean;
  41834. var btn: TTBButton;
  41835. begin
  41836. Perform(TB_GETBUTTON,FromIdx,integer(@btn));
  41837. Result := Perform(TB_DELETEBUTTON,FromIdx,0) <> 0;
  41838. if Result then
  41839. Perform(TB_INSERTBUTTON,ToIdx,integer(@btn));
  41840. end;
  41841. //[procedure TControl.TBSetTooltips]
  41842. {$IFDEF ASM_UNICODE}
  41843. {$ELSE ASM_VERSION} //Pascal
  41844. procedure TControl.TBSetTooltips(BtnID1st: Integer;
  41845. const Tooltips: array of PKOLChar);
  41846. var I, J: Integer;
  41847. begin
  41848. if not assigned( fTBttTxt ) then
  41849. begin
  41850. {$ifndef wince}
  41851. fTBttCmd := NewList;
  41852. {$endif wince}
  41853. fTBttTxt := {$IFDEF UNICODE_CTRLS} NewWStrList {$ELSE} NewStrList {$ENDIF};
  41854. {$IFDEF USE_AUTOFREE4CONTROLS}
  41855. {$ifndef wince}
  41856. Add2AutoFree( fTBttCmd );
  41857. {$endif wince}
  41858. Add2AutoFree( fTBttTxt );
  41859. {$ENDIF}
  41860. end;
  41861. {$ifdef wince}
  41862. j:=TBItem2Index(BtnID1st);
  41863. BtnID1st:=-1;
  41864. for i:=0 to j do
  41865. if not TBButtonSeparator(i) then
  41866. Inc(BtnID1st);
  41867. for i:=fTBttTxt.Count - 1 to BtnID1st - 1 do
  41868. fTBttTxt.Add('');
  41869. for I:=0 to High( Tooltips ) do begin
  41870. if BtnID1st < fTBttTxt.Count then
  41871. fTBttTxt.Items[BtnID1st]:=Tooltips[ I ]
  41872. else
  41873. fTBttTxt.Add( Tooltips[ I ] );
  41874. Inc(BtnID1st);
  41875. end;
  41876. Perform(TB_SETTOOLTIPS, fTBttTxt.Count, LPARAM(fTBttTxt.fList.fItems));
  41877. {$else}
  41878. for I:= 0 to High( Tooltips ) do
  41879. begin
  41880. J := fTBttCmd.IndexOf( Pointer( BtnID1st ) );
  41881. if J < 0 then
  41882. begin
  41883. fTBttCmd.Add( Pointer( BtnID1st ) );
  41884. fTBttTxt.Add( Tooltips[ I ] );
  41885. end
  41886. else
  41887. fTBttTxt.Items[ J ] := Tooltips[ I ];
  41888. Inc( BtnID1st );
  41889. end;
  41890. {$endif wince}
  41891. end;
  41892. {$ENDIF ASM_VERSION}
  41893. procedure ToolbarSetTooltips( Toolbar: PControl; BtnID1st: Integer;
  41894. const Tooltips: array of PKOLChar );
  41895. begin
  41896. Toolbar.TBSetTooltips( BtnID1st, Tooltips );
  41897. end;
  41898. function ToolbarButtonEnabled( Toolbar: PControl; BtnID: Integer ): Boolean;
  41899. begin
  41900. Result := Toolbar.TBButtonEnabled[ BtnID ];
  41901. end;
  41902. procedure EnableToolbarButton( Toolbar: PControl; BtnID: Integer; Enable: Boolean );
  41903. begin
  41904. Toolbar.TBButtonEnabled[ BtnID ] := Enable;
  41905. end;
  41906. function ToolbarButtonVisible( Toolbar: PControl; BtnID: Integer ): Boolean;
  41907. begin
  41908. Result := Toolbar.TBButtonVisible[ BtnID ];
  41909. end;
  41910. procedure ShowHideToolbarButton( Toolbar: PControl; BtnID: Integer; Show: Boolean );
  41911. begin
  41912. Toolbar.TBButtonVisible[ BtnID ] := Show;
  41913. end;
  41914. function ToolbarButtonChecked( Toolbar: PControl; BtnID: Integer): Boolean;
  41915. begin
  41916. Result := Toolbar.TBButtonChecked[ BtnID ];
  41917. end;
  41918. procedure ToolbarButtonSetChecked( Toolbar: PControl; BtnID: Integer; Checked: Boolean );
  41919. begin
  41920. Toolbar.TBButtonChecked[ BtnID ] := Checked;
  41921. end;
  41922. //[function TControl.TBButtonAtPos]
  41923. {$IFDEF ASM_VERSION}
  41924. {$ELSE ASM_VERSION} //Pascal
  41925. function TControl.TBButtonAtPos(X, Y: Integer): Integer;
  41926. var I: Integer;
  41927. begin
  41928. I := TBBtnIdxAtPos( X, Y );
  41929. if I >= 0 then
  41930. I := TBIndex2Item( I );
  41931. Result := I;
  41932. end;
  41933. {$ENDIF ASM_VERSION}
  41934. //[function TControl.TBBtnIdxAtPos]
  41935. {$IFDEF ASM_VERSION}
  41936. {$ELSE ASM_VERSION} //Pascal
  41937. function TControl.TBBtnIdxAtPos(X, Y: Integer): Integer;
  41938. var I: Integer;
  41939. R: TRect;
  41940. P: TPoint;
  41941. begin
  41942. P := MakePoint( X, Y );
  41943. for I := TBButtonCount - 1 downto 0 do
  41944. begin
  41945. Perform( TB_GETITEMRECT, I, Integer( @R ) );
  41946. if PointInRect( P, R ) then
  41947. begin
  41948. Result := I;
  41949. Exit;
  41950. end;
  41951. end;
  41952. Result := -1;
  41953. end;
  41954. {$ENDIF ASM_VERSION}
  41955. //[function TControl.TBButtonSeparator]
  41956. function TControl.TBButtonSeparator(BtnID: Integer): Boolean;
  41957. var B: TTBButton;
  41958. begin
  41959. Perform( TB_GETBUTTON, TBItem2Index( GetTBBtnGoodID( @Self, BtnID )), Integer( @B ) ) ;
  41960. Result := B.fsStyle = TBSTYLE_SEP;
  41961. end;
  41962. //*
  41963. //[procedure TControl.TBDeleteButton]
  41964. procedure TControl.TBDeleteButton(BtnID: Integer);
  41965. begin
  41966. BtnID := GetTBBtnGoodID( @Self, BtnID );
  41967. Perform( TB_DELETEBUTTON, TBItem2Index( BtnID ), 0 );
  41968. end;
  41969. //*
  41970. //[procedure TControl.TBDeleteBtnByIdx]
  41971. procedure TControl.TBDeleteBtnByIdx(Idx: Integer);
  41972. begin
  41973. Perform( TB_DELETEBUTTON, Idx, 0 );
  41974. end;
  41975. //*
  41976. //[procedure TControl.Clear]
  41977. procedure TControl.Clear;
  41978. begin
  41979. fCommandActions.aClear( @Self );
  41980. end;
  41981. {$IFDEF ASM_noVERSION}
  41982. //[function TControl.TBGetBtnImgIdx]
  41983. function TControl.TBGetBtnImgIdx(BtnID: Integer): Integer;
  41984. const szTBButton = sizeof( TTBButton );
  41985. asm
  41986. ADD ESP, -szTBButton
  41987. PUSH ESP
  41988. PUSH EAX
  41989. CALL TBItem2Index
  41990. POP EDX
  41991. PUSH EAX
  41992. PUSH TB_GETBUTTON
  41993. PUSH EDX
  41994. CALL Perform
  41995. POP EAX
  41996. ADD ESP, szTBButton-4
  41997. end;
  41998. {$ELSE ASM_VERSION} //Pascal
  41999. function TControl.TBGetBtnImgIdx(BtnID: Integer): Integer;
  42000. var B: TTBButton;
  42001. begin
  42002. Perform( TB_GETBUTTON, TBItem2Index( GetTBBtnGoodID( @Self, BtnID ) ), Integer( @B ) );
  42003. Result := B.iBitmap;
  42004. end;
  42005. {$ENDIF ASM_VERSION}
  42006. //*
  42007. //[procedure TControl.TBSetBtnImgIdx]
  42008. procedure TControl.TBSetBtnImgIdx(BtnID: Integer; const Value: Integer);
  42009. begin
  42010. Perform( TB_CHANGEBITMAP, GetTBBtnGoodID( @Self, BtnID ), Value );
  42011. end;
  42012. //[procedure TControl.TBSetButtonText]
  42013. {$IFDEF ASM_VERSION}
  42014. {$ELSE ASM_VERSION} //Pascal
  42015. procedure TControl.TBSetButtonText(BtnID: Integer; const Value: KOLString);
  42016. var BI: TTBButtonInfo;
  42017. begin
  42018. BtnID := GetTBBtnGoodID( @Self, BtnID );
  42019. BI.cbSize := Sizeof( BI );
  42020. BI.dwMask := TBIF_TEXT;
  42021. BI.pszText := PKOLChar( Value );
  42022. Perform( TB_SETBUTTONINFO, BtnID, Integer( @BI ) );
  42023. end;
  42024. {$ENDIF ASM_VERSION}
  42025. //[function TControl.TBGetBtnWidth]
  42026. {$IFDEF ASM_VERSION}
  42027. {$ELSE ASM_VERSION} //Pascal
  42028. function TControl.TBGetBtnWidth(BtnID: Integer): Integer;
  42029. var R: TRect;
  42030. begin
  42031. R := TBButtonRect[ BtnID ];
  42032. Result := R.Right - R.Left;
  42033. end;
  42034. {$ENDIF ASM_VERSION}
  42035. //[procedure TControl.TBSetBtnWidth]
  42036. {$IFDEF ASM_VERSION}
  42037. {$ELSE ASM_VERSION} //Pascal
  42038. procedure TControl.TBSetBtnWidth(BtnID: Integer; const Value: Integer);
  42039. var BI: TTBButtonInfo;
  42040. begin
  42041. BI.cbSize := Sizeof( BI );
  42042. BI.dwMask := TBIF_SIZE or TBIF_STYLE;
  42043. BtnID := GetTBBtnGoodID( @Self, BtnID );
  42044. Perform( TB_GETBUTTONINFO, BtnID, Integer( @BI ) );
  42045. BI.cx := Value;
  42046. BI.fsStyle := BI.fsStyle and not TBSTYLE_AUTOSIZE;
  42047. Perform( TB_SETBUTTONINFO, BtnID, Integer( @BI ) );
  42048. end;
  42049. {$ENDIF ASM_VERSION}
  42050. //[procedure TControl.TBSetBtMinMaxWidth]
  42051. procedure TControl.TBSetBtMinMaxWidth(const Idx: Integer; const Value: Integer);
  42052. begin
  42053. case Idx of
  42054. 0: FTBBtMinWidth := Value;
  42055. 1: FTBBtMaxWidth := Value;
  42056. end;
  42057. Perform( TB_SETBUTTONWIDTH, 0, FTBBtMaxWidth or (FTBBtMinWidth shl 16) );
  42058. end;
  42059. {$IFDEF F_P}
  42060. //[function TControl.TBGetBtMinMaxWidth]
  42061. function TControl.TBGetBtMinMaxWidth(const Idx: Integer): Integer;
  42062. begin
  42063. CASE Idx OF
  42064. 0: Result := FTBBtMinWidth;
  42065. 1: Result := FTBBtMaxWidth;
  42066. END;
  42067. end;
  42068. {$ENDIF F_P}
  42069. {$ifndef wince}
  42070. function WndProcTBCustomDraw( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  42071. var CD: PNMTBCustomDraw;
  42072. Br: HBrush;
  42073. begin
  42074. Result := FALSE;
  42075. if Msg.message = WM_NOTIFY then
  42076. begin
  42077. CD := Pointer( Msg.lParam );
  42078. if longint(CD.nmcd.hdr.code) = NM_CUSTOMDRAW then
  42079. begin
  42080. if Assigned( Sender.OnTBCustomDraw ) then
  42081. Rslt := Sender.OnTBCustomDraw( Sender, CD^ )
  42082. else
  42083. begin
  42084. if Assigned( Sender.fBrush ) then
  42085. Windows.FillRect( CD.nmcd.hdc, Sender.ClientRect, Sender.fBrush.Handle )
  42086. else
  42087. begin
  42088. Br := CreateSolidBrush( Color2RGB( Sender.Color ) );
  42089. Windows.FillRect( CD.nmcd.hdc, Sender.ClientRect, Br );
  42090. DeleteObject( Br );
  42091. end;
  42092. Rslt := CDRF_SKIPDEFAULT;
  42093. end;
  42094. end;
  42095. end;
  42096. end;
  42097. procedure TControl.SetOnTBCustomDraw( const Value: TOnTBCustomDraw );
  42098. begin
  42099. fOnTBCustomDraw := Value;
  42100. AttachProc( WndProcTBCustomDraw );
  42101. end;
  42102. {$endif wince}
  42103. //[procedure TControl.SetDroppedDown]
  42104. procedure TControl.SetDroppedDown(const Value: Boolean);
  42105. begin
  42106. //fDropped := Value;
  42107. Perform( CB_SHOWDROPDOWN, Integer( Value ), 0 );
  42108. end;
  42109. //[procedure TControl.AddDirList]
  42110. {$IFDEF ASM_VERSION}
  42111. {$ELSE ASM_VERSION} //Pascal
  42112. procedure TControl.AddDirList(const Filemask: KOLString; Attrs: DWORD);
  42113. begin
  42114. if fCommandActions.aDir <> 0 then
  42115. Perform( fCommandActions.aDir, Attrs, Integer( PKOLChar( Filemask ) ) );
  42116. end;
  42117. {$ENDIF ASM_VERSION}
  42118. //[FUNCTION WndProcShowModal]
  42119. {$IFDEF ASM_noVERSION}
  42120. {$ELSE ASM_VERSION} //Pascal
  42121. function WndProcShowModal( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  42122. //var Accept: Boolean; // {Alexander Pravdin, AP}
  42123. begin
  42124. if Msg.message = WM_CLOSE then
  42125. begin
  42126. if Self_.ModalResult = 0 then { (Sergey Shishmintzev) }
  42127. Self_.ModalResult := -1;
  42128. Rslt := 0;
  42129. Result := True; // Do not process !
  42130. end
  42131. else
  42132. {$ifdef wince}
  42133. if Msg.message = WM_COMMAND then begin
  42134. if (HIWORD(Msg.wParam) = 4096) or (HWND(Msg.lParam) = Msg.hwnd) then begin
  42135. if Self_.fDefaultBtnCtl <> nil then
  42136. if Self_.fDefaultBtnCtl.Enabled then
  42137. Self_.fDefaultBtnCtl.Click
  42138. else
  42139. Self_.ModalResult:=IDCANCEL
  42140. else
  42141. Self_.ModalResult:=IDOK;
  42142. Rslt := 0;
  42143. Result := True;
  42144. end
  42145. else begin
  42146. Rslt := 1;
  42147. Result := False;
  42148. end;
  42149. end
  42150. else
  42151. {$endif wince}
  42152. Result := False;
  42153. end;
  42154. {$ENDIF ASM_VERSION}
  42155. //[END WndProcShowModal]
  42156. //[function WndProcFixModal]
  42157. // by TR"]F
  42158. function WndProcFixModal( Self_: PControl; var Msg: TMsg; var Rslt:
  42159. Integer ): Boolean;
  42160. const HTERROR = $FFFE;
  42161. LBtnDown = $201;
  42162. LBtnUp = $202;
  42163. RBtnDown = $204;
  42164. RBtnUp = $205;
  42165. WeelDown = $207;
  42166. WeelUp = $208;
  42167. {$IFDEF MODAL_ACTIVATE_FIX}
  42168. var i: Integer;
  42169. C: PControl;
  42170. {$ENDIF MODAL_ACTIVATE_FIX}
  42171. begin
  42172. Result := false;
  42173. if (Msg.message = WM_SETCURSOR) then
  42174. if (LoWord(Msg.lParam) = HTERROR) then
  42175. if (HiWord(Msg.lParam) >= LBtnDown) and
  42176. (HiWord(Msg.lParam) <= RBtnUp) then
  42177. begin
  42178. if Applet.fModalForm <> nil then
  42179. SetForegroundWindow(Applet.fModalForm.Handle);
  42180. Rslt := 1;
  42181. Result := TRUE;
  42182. end;
  42183. {$IFDEF MODAL_ACTIVATE_FIX}
  42184. if (Msg.message = WM_ACTIVATEAPP) then
  42185. begin
  42186. if not Applet.fActivating then
  42187. begin
  42188. Applet.fActivating := TRUE;
  42189. if Msg.wParam <> 0 then
  42190. begin
  42191. for i := Applet.ChildCount-1 downto 0 do
  42192. begin
  42193. C := Applet.Children[ i ];
  42194. if C.Visible and not C.Enabled then
  42195. SetForegroundWindow( C.Handle );
  42196. end;
  42197. SetForegroundWindow( Applet.fModalForm.Handle );
  42198. end;
  42199. Applet.fActivating := FALSE;
  42200. end;
  42201. end;
  42202. {$ENDIF MODAL_ACTIVATE_FIX}
  42203. end;
  42204. //[END WndProcFixModal]
  42205. {$IFDEF ASM_noVERSION}
  42206. //[function TControl.ShowModal]
  42207. function TControl.ShowModal: Integer;
  42208. asm
  42209. MOV ECX, [EAX].fParent
  42210. JECXZ @@show
  42211. MOVZX ECX, [EAX].fIsControl
  42212. JECXZ @@show_modal
  42213. @@show:
  42214. CALL Show
  42215. XOR EAX, EAX
  42216. RET
  42217. @@show_modal:
  42218. PUSHAD
  42219. MOV EBX, EAX
  42220. MOV EDI, [Applet]
  42221. XOR EBP, EBP // CurCtl = nil
  42222. MOV EAX, [EDI].fCurrentControl
  42223. CMP [EDI].TControl.FIsApplet, 0
  42224. {$IFDEF USE_CMOV}
  42225. CMOVZ EAX, EDI
  42226. {$ELSE}
  42227. JNZ @@curctrl_save
  42228. MOV EAX, EDI
  42229. @@curctrl_save:
  42230. {$ENDIF}
  42231. PUSH EAX
  42232. MOV EDX, offset[WndProcShowModal]
  42233. PUSH EDX
  42234. MOV EAX, EBX
  42235. CALL TControl.AttachProc
  42236. XOR EDX, EDX
  42237. MOV [EBX].fModalResult, EDX
  42238. CALL NewList
  42239. XCHG EAX, EBP
  42240. XOR ECX, ECX
  42241. INC ECX
  42242. MOV ESI, EDI
  42243. CMP [EDI].TControl.FIsApplet, 0
  42244. JZ @@isapplet
  42245. MOV EBP, [EDI].fCurrentControl // CurCtl = Applet.fCurrentControl
  42246. MOV ESI, [EDI].fChildren
  42247. MOV ECX, [ESI].TList.fCount
  42248. MOV ESI, [ESI].TList.fItems
  42249. @@1loo: LODSD
  42250. @@isapplet:
  42251. PUSH ECX
  42252. CMP EAX, EBX
  42253. JE @@1nx
  42254. PUSH EAX
  42255. CALL GetEnabled
  42256. TEST AL, AL
  42257. POP EAX
  42258. JZ @@1nx
  42259. PUSH EAX
  42260. MOV DL, 0
  42261. CALL SetEnabled
  42262. POP EDX
  42263. MOV EAX, EBP
  42264. CALL TList.Add
  42265. @@1nx: POP ECX
  42266. LOOP @@1loo
  42267. INC [EBX].fModal
  42268. MOV EAX, [Applet]
  42269. MOV [EAX].fModalForm, EBX
  42270. MOV EAX, EBX
  42271. CALL Show
  42272. @@msgloo:
  42273. MOVZX ECX, [AppletTerminated]
  42274. OR ECX, [EBX].fModalResult
  42275. JNZ @@e_msgloo
  42276. CALL WaitMessage
  42277. MOV EAX, EDI
  42278. CALL ProcessMessages
  42279. {$IFDEF USE_OnIdle}
  42280. MOV EAX, EBX
  42281. CALL [ProcessIdle]
  42282. {$ENDIF}
  42283. JMP @@msgloo
  42284. @@e_msgloo:
  42285. POP EDX
  42286. MOV EAX, EBX
  42287. CALL TControl.DetachProc
  42288. DEC [EBX].fModal
  42289. MOV EAX, [Applet]
  42290. XOR ECX, ECX
  42291. MOV [EAX].fModalForm, ECX
  42292. MOV ECX, [EBP].TList.fCount
  42293. JECXZ @@2end
  42294. MOV ESI, [EBP].TList.fItems
  42295. @@2loo: LODSD
  42296. PUSH ECX
  42297. MOV DL, 1
  42298. CALL TControl.SetEnabled
  42299. POP ECX
  42300. LOOP @@2loo
  42301. @@2end:
  42302. MOV EAX, EBP
  42303. CALL TObj.Free
  42304. POP ECX
  42305. JECXZ @@exit
  42306. PUSH 0
  42307. PUSH WA_ACTIVE
  42308. PUSH WM_ACTIVATE
  42309. PUSH [ECX].fHandle
  42310. CALL PostMessage
  42311. TEST EBP, EBP // CurCtl = nil ?
  42312. JZ @@exit
  42313. MOV EAX, EBP
  42314. MOV DL, 1
  42315. CALL TControl.SetFocused
  42316. @@exit:
  42317. POPAD
  42318. MOV EAX, [EAX].fModalResult
  42319. end;
  42320. {$ELSE ASM_VERSION} //Pascal
  42321. {$IFDEF USE_SHOWMODALPARENTED_ALWAYS}
  42322. function TControl.ShowModal: Integer;
  42323. begin
  42324. Result := ShowModalParented(Applet);
  42325. end;
  42326. {$ELSE not USE_SHOWMODALPARENTED_ALWAYS}
  42327. function TControl.ShowModal: Integer;
  42328. var FL: PList;
  42329. var CurForm: PControl;
  42330. I: Integer;
  42331. F: PControl;
  42332. CurCtl: PControl; // { Alexander Pravdin }
  42333. begin
  42334. Result := 0;
  42335. if (fIsControl) or (fParent = nil) then
  42336. begin
  42337. Show;
  42338. Exit;
  42339. end;
  42340. {$ifdef wince}
  42341. SHDoneButton(GetWindowHandle, SHDB_SHOW);
  42342. Style:=Style and not WS_SYSMENU;
  42343. {$endif wince}
  42344. AttachProc( WndProcShowModal );
  42345. CurForm := Applet.fCurrentControl;
  42346. FL := NewList;
  42347. CurCtl := nil; // { Alexander Pravdin }
  42348. if Applet.IsApplet then
  42349. begin
  42350. for I := 0 to Applet.ChildCount - 1 do
  42351. begin
  42352. F := Applet.fChildren.Items[ I ];
  42353. if F <> @Self then
  42354. if F.Enabled then
  42355. begin
  42356. FL.Add( F );
  42357. F.Enabled := FALSE;
  42358. {$IFNDEF NOT_FIX_MODAL}
  42359. Inc( F.fFixingModal );
  42360. F.AttachProc(WndProcFixModal); {**************}
  42361. {$ENDIF}
  42362. end;
  42363. end
  42364. end
  42365. else
  42366. begin
  42367. CurForm := Applet;
  42368. if Applet.Enabled then
  42369. begin
  42370. FL.Add( Applet );
  42371. CurCtl := Applet.fCurrentControl; { Alexander Pravdin }
  42372. Applet.Enabled := FALSE;
  42373. {$IFNDEF NOT_FIX_MODAL}
  42374. Inc( Applet.fFixingModal );
  42375. Applet.AttachProc(WndProcFixModal); {**************}
  42376. {$ENDIF}
  42377. end;
  42378. end;
  42379. Inc( fModal );
  42380. Applet.fModalForm := @ Self;
  42381. Enabled := TRUE;
  42382. Show;
  42383. ModalResult := 0;
  42384. while not AppletTerminated and (ModalResult = 0) do
  42385. begin
  42386. Applet.WaitAndProcessMessages;
  42387. {$IFDEF USE_OnIdle}
  42388. ProcessIdle( @Self );
  42389. {$ENDIF}
  42390. end;
  42391. Dec( fModal );
  42392. Applet.fModalForm := nil;
  42393. DetachProc( WndProcShowModal );
  42394. for I := 0 to FL.Count - 1 do
  42395. begin
  42396. F := FL.Items[ I ];
  42397. {$IFNDEF NOT_FIX_MODAL}
  42398. Dec( F.fFixingModal );
  42399. if F.fFixingModal <= 0 then
  42400. F.DetachProc(WndProcFixModal); {**************}
  42401. {$ENDIF}
  42402. F.Enabled := TRUE;
  42403. end;
  42404. FL.Free;
  42405. if CurForm <> nil then
  42406. PostMessage( CurForm.Handle, WM_ACTIVATE, WA_ACTIVE, 0 );
  42407. if CurCtl <> nil then CurCtl.SetFocused( TRUE ); { Alexander Pravdin }
  42408. Result := ModalResult;
  42409. {$ifdef wince}
  42410. Applet.ProcessMessages;
  42411. {$endif wince}
  42412. end;
  42413. {$ENDIF USE_SHOWMODALPARENTED_ALWAYS}
  42414. {$ENDIF ASM_VERSION}
  42415. //[function TControl.ShowModalParented]
  42416. {$IFNDEF NEW_MODAL}
  42417. function TControl.ShowModalParented( const AParent: PControl ): Integer;
  42418. begin
  42419. Result := 0;
  42420. end;
  42421. {$ELSE NEW_MODAL defined}
  42422. function TControl.ShowModalParented( const AParent: PControl ): Integer;
  42423. var
  42424. FL: PList;
  42425. OldMF, F: PControl;
  42426. I: Integer;
  42427. begin
  42428. Result := 0;
  42429. if ( AParent = nil ) then Exit;
  42430. Inc( fModal );
  42431. FL := NewList;
  42432. OldMF := AParent.fModalForm;
  42433. AParent.fModalForm := @Self;
  42434. if AParent.fIsApplet or ( AParent.IsMainWindow and AParent.fIsForm ) then
  42435. begin
  42436. for I := 0 to AParent.ChildCount - 1 do
  42437. begin
  42438. F := AParent.fChildren.Items[ I ];
  42439. if ( F <> @Self ) and F.fIsForm and F.fEnabled and F.fVisible then
  42440. begin
  42441. FL.Add( F );
  42442. F.Enabled := FALSE;
  42443. {$IFNDEF NOT_FIX_MODAL}
  42444. F.AttachProc(WndProcFixModal); {**************}
  42445. {$ENDIF}
  42446. end;
  42447. end;
  42448. end;
  42449. if AParent.fIsForm and AParent.Enabled then
  42450. begin
  42451. FL.Add( AParent );
  42452. AParent.Enabled := FALSE;
  42453. end;
  42454. ModalResult := 0;
  42455. Show;
  42456. while not AppletTerminated and ( ModalResult = 0 ) do
  42457. begin
  42458. AParent.WaitAndProcessMessages;
  42459. {$IFDEF USE_OnIdle}
  42460. ProcessIdle( @Self );
  42461. {$ENDIF}
  42462. end;
  42463. AParent.fModalForm := OldMF;
  42464. Dec( fModal );
  42465. for I := 0 to FL.Count - 1 do
  42466. begin
  42467. F := PControl( FL.Items[ I ] );
  42468. F.Enabled := True;
  42469. {$IFNDEF NOT_FIX_MODAL}
  42470. F.DetachProc(WndProcFixModal); {**************}
  42471. {$ENDIF}
  42472. end;
  42473. FL.Free;
  42474. Hide;
  42475. Result := ModalResult;
  42476. end;
  42477. {$ENDIF NEW_MODAL}
  42478. //[function DisableWindows]
  42479. function DisableWindows( W: hwnd; LPARAM: Integer ): Bool; {$ifdef wince}cdecl{$else}stdcall{$endif};
  42480. var FL: PList;
  42481. Buf: array[ 0..127 ] of Char;
  42482. begin
  42483. FL := Pointer( LPARAM );
  42484. if IsWindowEnabled( W ) and (W <> FL.Tag) then
  42485. begin
  42486. GetClassName( W, @ Buf[ 0 ], Sizeof( Buf ) );
  42487. if Buf <> 'ComboLBox' then
  42488. begin
  42489. FL.Add( Pointer( W ) );
  42490. EnableWindow( W, FALSE );
  42491. end;
  42492. end;
  42493. Result := TRUE;
  42494. end;
  42495. //[function TControl.ShowModalEx]
  42496. function TControl.ShowModalEx: Integer;
  42497. {$ifdef wince}
  42498. begin
  42499. Result:=ShowModal;
  42500. {$else}
  42501. var FL: PList;
  42502. var CurForm: PControl;
  42503. I: Integer;
  42504. W: HWnd;
  42505. CurCtl: PControl; { Alexander Pravdin }
  42506. begin
  42507. Result := 0;
  42508. if (fIsControl) or (fParent = nil) then
  42509. begin
  42510. Show;
  42511. Exit;
  42512. end;
  42513. AttachProc( WndProcShowModal );
  42514. CurForm := Applet.fCurrentControl;
  42515. FL := NewList;
  42516. FL.Tag := fHandle;
  42517. // ++++ { Alexander Pravdin }
  42518. if not Applet.fIsApplet then CurCtl := Applet.fCurrentControl
  42519. else CurCtl := nil;
  42520. // ----
  42521. CreateWindow;
  42522. EnumThreadWindows( GetCurrentThreadID, @ DisableWindows, Integer( FL ) );
  42523. Enabled := TRUE;
  42524. Inc( fModal );
  42525. Applet.fModalForm := @ Self;
  42526. Show;
  42527. ModalResult := 0;
  42528. while not AppletTerminated and (ModalResult = 0) do
  42529. begin
  42530. Applet.WaitAndProcessMessages;
  42531. {$IFDEF USE_OnIdle}
  42532. ProcessIdle( @Self );
  42533. {$ENDIF}
  42534. end;
  42535. Dec( fModal );
  42536. Applet.fModalForm := @ Self;
  42537. DetachProc( WndProcShowModal );
  42538. for I := 0 to FL.Count - 1 do
  42539. begin
  42540. W := THandle( FL.Items[ I ] );
  42541. EnableWindow( W, TRUE );
  42542. end;
  42543. FL.Free;
  42544. if CurForm <> nil then
  42545. PostMessage( CurForm.Handle, WM_ACTIVATE, WA_ACTIVE, 0 );
  42546. if CurCtl <> nil then CurCtl.SetFocused( True ); { Alexander Pravdin }
  42547. Result := ModalResult;
  42548. {$endif wince}
  42549. end;
  42550. //[function TControl.GetModal]
  42551. function TControl.GetModal: Boolean;
  42552. begin
  42553. Result := fModal > 0;
  42554. end;
  42555. {$IFDEF USE_SETMODALRESULT}
  42556. //[procedure TControl.SetModalResult]
  42557. procedure TControl.SetModalResult( const Value: Integer );
  42558. begin
  42559. //if fModal <= 0 then Exit;
  42560. fModalResult := Value;
  42561. if Value <> 0 then
  42562. PostMessage( GetWindowHandle, 0, 0, 0 );
  42563. end;
  42564. {$ENDIF}
  42565. {$IFNDEF NEW_MENU_ACCELL}
  42566. procedure TControl.DoDestroyAccelTable;
  42567. begin
  42568. if fAccelTable <> 0 then
  42569. begin
  42570. DestroyAcceleratorTable( fAccelTable );
  42571. fAccelTable := 0;
  42572. end;
  42573. end;
  42574. {$ENDIF}
  42575. {$ENDIF WIN_GDI} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  42576. {$IFDEF _X_}
  42577. {$IFDEF GTK}
  42578. function control_clicked( Obj: PGtkWidget; Sender: PControl ): Boolean; cdecl;
  42579. begin
  42580. if Assigned( Sender.fOnClick ) then
  42581. Sender.fOnClick( Sender );
  42582. Result := FALSE;
  42583. end;
  42584. procedure TControl.SetOnClick( const Value: TOnEvent );
  42585. begin
  42586. fOnClick := Value;
  42587. if fEventboxHandle = fHandle then
  42588. begin
  42589. {$IFNDEF SMALLER_CODE}
  42590. if not Assigned( Value ) then
  42591. gtk_signal_disconnect( GTK_OBJECT( fEventboxHandle ), fClickedEvent )
  42592. else
  42593. {$ENDIF SMALLEST_CODE}
  42594. fClickedEvent := gtk_signal_connect( GTK_OBJECT( fEventboxHandle ), 'clicked',
  42595. @ control_clicked, @ Self )
  42596. end
  42597. else
  42598. SetMouseEvent( @ Self, 'button_release_event' );
  42599. end;
  42600. {$ENDIF GTK}
  42601. {$ENDIF _X_}
  42602. //////////////////////////////////////////////////////////////////
  42603. // T I M E R
  42604. //////////////////////////////////////////////////////////////////
  42605. var {$IFDEF WIN} TimerOwnerWnd: PControl; {$ENDIF} // in Linux, timer not need in a window
  42606. TimerCount: Integer = 0;
  42607. { -- Constructor of timer -- }
  42608. //[function NewTimer]
  42609. function NewTimer( Interval: Integer ): PTimer;
  42610. begin
  42611. {-}
  42612. New( Result, Create );
  42613. {+}{++}(*Result := PTimer.Create;*){--}
  42614. if Interval <= 0 then Interval := 1000;
  42615. Result.fInterval := Interval;
  42616. Inc( TimerCount );
  42617. end;
  42618. //[END NewTimer]
  42619. { -- Timer procedure -- }
  42620. {$IFDEF WIN}
  42621. //[FUNCTION TimerProc]
  42622. {$IFDEF ASM_VERSION}
  42623. {$ELSE ASM_VERSION} //Pascal
  42624. function TimerProc( Wnd : HWnd; Msg : Integer; T : PTimer; CurrentTime : DWord ): Integer;
  42625. {$ifdef wince}cdecl{$else}stdcall{$endif};
  42626. begin
  42627. {$IFDEF STOPTIMER_AFTER_APPLETTERMINATED}
  42628. if not AppletTerminated then
  42629. {$ENDIF}
  42630. if Assigned( T.fOnTimer ) then
  42631. T.fOnTimer( T );
  42632. Result := 0;
  42633. end;
  42634. {$ENDIF ASM_VERSION}
  42635. //[END TimerProc]
  42636. {$ENDIF WIN}
  42637. { TTimer }
  42638. //[destructor TTimer.Destroy]
  42639. {$IFDEF ASM_VERSION}
  42640. {$ELSE ASM_VERSION} //Pascal
  42641. destructor TTimer.Destroy;
  42642. begin
  42643. Enabled := False;
  42644. inherited;
  42645. Dec( TimerCount );
  42646. {$IFDEF WIN}
  42647. if TimerCount = 0 then
  42648. begin
  42649. TimerOwnerWnd.Free;
  42650. TimerOwnerWnd := nil;
  42651. end;
  42652. {$ENDIF WIN}
  42653. end;
  42654. {$ENDIF ASM_VERSION}
  42655. //[procedure TTimer.SetEnabled]
  42656. {$IFDEF WIN_GDI}
  42657. {$IFDEF ASM_VERSION}
  42658. {$ELSE ASM_VERSION} //Pascal
  42659. procedure TTimer.SetEnabled(const Value: Boolean);
  42660. var WasEnabled: Boolean;
  42661. begin
  42662. WasEnabled := fEnabled;
  42663. fEnabled := Value;
  42664. if WasEnabled = Value then Exit;
  42665. {$IFDEF TIMER_APPLETWND}
  42666. if Applet = nil then Exit;
  42667. {$ENDIF}
  42668. if Value then
  42669. begin
  42670. {$IFDEF TIMER_APPLETWND}
  42671. fHandle := SetTimer( Applet.GetWindowHandle, Integer( @Self ),
  42672. fInterval, @TimerProc );
  42673. {$ELSE}
  42674. if TimerOwnerWnd = nil then
  42675. begin
  42676. TimerOwnerWnd := _NewWindowed( nil, {$ifdef wince}'TWND'{$else}''{$endif}, TRUE );
  42677. TimerOwnerWnd.fStyle := 0;
  42678. TimerOwnerWnd.fIsControl := TRUE;
  42679. end;
  42680. fHandle := SetTimer( TimerOwnerWnd.GetWindowHandle, Integer( @Self ),
  42681. fInterval, @TimerProc );
  42682. {$ENDIF}
  42683. end
  42684. else
  42685. begin
  42686. if fHandle <> 0 then
  42687. begin
  42688. KillTimer( {$IFDEF TIMER_APPLETWND} Applet.fHandle
  42689. {$ELSE} TimerOwnerWnd.fHandle {$ENDIF}, fHandle );
  42690. fHandle := 0;
  42691. end;
  42692. end;
  42693. end;
  42694. {$ENDIF ASM_VERSION}
  42695. {$ENDIF WIN_GDI}
  42696. {$IFDEF _X_}
  42697. {$IFDEF GTK}
  42698. function TimerGTKTick( Sender: Pointer ): LONGBOOL; cdecl;
  42699. begin
  42700. if not PTimer( Sender ).fEnabled then Result := FALSE
  42701. else
  42702. begin
  42703. if Assigned( PTimer( Sender ).fOnTimer ) then
  42704. Ptimer( Sender ).fOnTimer( Sender );
  42705. Result := PTimer( Sender ).fEnabled;
  42706. end;
  42707. if Result then
  42708. PTimer( Sender ).RefDec;
  42709. end;
  42710. procedure TTimer.SetEnabled(const Value: Boolean);
  42711. begin
  42712. if FEnabled = Value then Exit;
  42713. fEnabled := Value;
  42714. if Value then
  42715. begin
  42716. RefInc;
  42717. fHandle := gtk_timeout_add( fInterval, TimerGTKTick, @ Self );
  42718. end
  42719. else
  42720. begin
  42721. if AppletTerminated then
  42722. begin
  42723. gtk_timeout_remove( fHandle );
  42724. RefDec;
  42725. end;
  42726. end;
  42727. end;
  42728. {$ELSE not GTK}
  42729. var fActiveTimerList: PTimer;
  42730. fClockPerSecond: Integer;
  42731. fAlarmHandling: Boolean;
  42732. procedure SetAlarm; forward;
  42733. procedure AlarmHandler(SigNum: Integer); cdecl;
  42734. var T, NT: PTimer;
  42735. c: Integer;
  42736. count_handled: Integer;
  42737. begin
  42738. c := clock;
  42739. fAlarmHandling := TRUE; // to prevent SetAlarm working while timers are handling
  42740. TRY
  42741. //--- 1. Clear fTimerHandled flag for all active timers
  42742. T := fActiveTimerList;
  42743. while T <> nil do
  42744. begin
  42745. T.fTimerHandled := FALSE;
  42746. T := T.fNext;
  42747. end;
  42748. //--- 2. Handle all expired timers
  42749. count_handled := 0;
  42750. while not AppletTerminated do // until all timers expired are handled or
  42751. begin // until the application is terminated
  42752. //--- 2.A. Search a timer which was expired before all others
  42753. T := fActiveTimerList;
  42754. NT := nil;
  42755. while T <> nil do
  42756. begin
  42757. if not T.fTimerHandled and (
  42758. (NT = nil) or ((T.fExpireNext - c) < (NT.fExpireNext - c))
  42759. ) then
  42760. NT := T;
  42761. T := T.fNext;
  42762. end;
  42763. if NT = nil then break; // there are no more timers expired
  42764. if (count_handled > 0) and
  42765. ((NT.fExpireNext - c > 0) or (NT.fExpireNext < 0) and (c > 0)) then break;
  42766. //--- 2.B. Handle found timer (NT)
  42767. inc( count_handled ); // count handled timer to ensure that at least 1 timer
  42768. // was handled in result of alarm call
  42769. {$IFDEF SUPPORT_LONG_TIMER}
  42770. NT.fExpireTotal := NT.fExpireTotal - (c - NT.fTimeStart);
  42771. if NT.fExpireTotal > 30 * 60 * fClockPerSecond then
  42772. NT.fExpireNext := c + 30 * 60 * fClockPerSecond
  42773. else
  42774. NT.fExpireNext := c + NT.fExpireTotal;
  42775. {$ELSE not SUPPORT_LONG_TIMER}
  42776. NT.fExpireNext := // next time to expire this timer
  42777. NT.fExpireNext + fClockPerSecond * NT.fInterval;
  42778. {$ENDIF SUPPORT_LONG_TIMER}
  42779. NT.fTimerHandled := TRUE; // do not handle that timer again in that loop
  42780. {$IFDEF SUPPORT_LONG_TIMER}
  42781. if NT.fExpireTotal <= 0 then
  42782. {$ENDIF SUPPORT_LONG_TIMER}
  42783. begin
  42784. if NT.fMultimedia and not NT.fPeriodic then
  42785. NT.Enabled := FALSE; // one-shot timer, disable it now
  42786. //--------------------------------------------------------------
  42787. //todo: for not a multimedia timer, post a signal to a window
  42788. // to synchronize timer handling with the main thread!
  42789. // (but not for fMultimedia timers)
  42790. //--------------------------------------------------------------
  42791. if Assigned( NT.fOnTimer ) then
  42792. NT.fOnTimer( NT ); // in result of this action, timer NT or any other active
  42793. // timer can be disabled and dropped from fActiveTimerList and any amount of
  42794. // previously disbled timers can be added
  42795. end;
  42796. end;
  42797. FINALLY
  42798. fAlarmHandling := FALSE;
  42799. END;
  42800. // 3. finally, install the next alarm to the nearest expirating timer if any
  42801. SetAlarm;
  42802. end;
  42803. procedure SetAlarm;
  42804. var i: Integer;
  42805. T, NT: PTimer;
  42806. TV: itimerval;
  42807. c: clock_t;
  42808. begin
  42809. if AppletTerminated then Exit; // if the application is terminated we do not install alarms
  42810. if fAlarmHandling then Exit; // while alarm is handling do not reinstall alarms
  42811. c := clock;
  42812. T := fActiveTimerList;
  42813. NT := T;
  42814. while T <> nil do
  42815. begin
  42816. if (T.fExpireNext - c) < (NT.fExpireNext - c) then
  42817. NT := T;
  42818. T := T.fNext;
  42819. end;
  42820. if NT = nil then Exit;
  42821. i := (NT.fExpireNext - c) * 1000 div fClockPerSecond;
  42822. if i < 0 then i := 10; // 10 milliseconds as minimum time to alarm
  42823. TV.it_interval.tv_sec := 0; // set interval to alarm once
  42824. TV.it_interval.tv_usec := 0;
  42825. TV.it_value.tv_sec := i div 1000; // set time to alarm next time
  42826. TV.it_value.tv_usec := (i mod 1000) * 1000;
  42827. signal( SIGALRM, AlarmHandler );
  42828. setitimer( ITIMER_REAL, TV, nil );
  42829. end;
  42830. procedure TTimer.SetEnabled(const Value: Boolean);
  42831. begin
  42832. if FEnabled = Value then Exit;
  42833. fEnabled := Value;
  42834. if Value then
  42835. begin
  42836. if fClockPerSecond = 0 then
  42837. fClockPerSecond := CLK_TCK;
  42838. fExpireTotal := Int64( fClockPerSecond ) * fInterval;
  42839. {$IFDEF SUPPORT_LONG_TIMER}
  42840. if fExpireTotal > 30 * 60 * fClockPerSecond then
  42841. fExpireNext := clock + 30 * 60 * fClockPerSecond
  42842. else
  42843. fExpireNext := clock + fExpireTotal;
  42844. {$ELSE}
  42845. fExpireNext := clock + fExpireTotal;
  42846. {$ENDIF SUPPORT_LONG_TIMER}
  42847. if fActiveTimerList <> nil then
  42848. begin
  42849. fNext := fActiveTimerList;
  42850. fActiveTimerList.fPrev := @ Self;
  42851. end;
  42852. fActiveTimerList := @ Self;
  42853. end
  42854. else
  42855. begin
  42856. if fPrev <> nil then
  42857. fPrev.fNext := fNext;
  42858. if fNext <> nil then
  42859. fNext.fPrev := fPrev;
  42860. if fActiveTimerList = @ Self then
  42861. fActiveTimerList := fNext;
  42862. fPrev := nil;
  42863. fNext := nil;
  42864. end;
  42865. if fActiveTimerList <> nil then
  42866. begin // set alarm to the nearest expiring timer
  42867. SetAlarm;
  42868. end;
  42869. end;
  42870. {$ENDIF not GTK}
  42871. {$ENDIF _X_}
  42872. procedure TTimer.SetInterval(const Value: Integer);
  42873. var WasEnabled : Boolean;
  42874. begin
  42875. if fInterval = Value then Exit;
  42876. fInterval := Value;
  42877. WasEnabled := Enabled;
  42878. Enabled := False;
  42879. Enabled := WasEnabled {$IFDEF STOPTIMER_AFTER_APPLETTERMINATED}
  42880. and not AppletTerminated
  42881. {$ENDIF};
  42882. end;
  42883. {$IFDEF WIN}
  42884. {$ifdef win32}
  42885. { TMMTimer }
  42886. { ------------ declarations moved here from MMSystem -------------------- }
  42887. const
  42888. TIME_ONESHOT = 0; { program timer for single event }
  42889. TIME_PERIODIC = 1; { program for continuous periodic event }
  42890. TIME_CALLBACK_FUNCTION = $0000; { callback is function }
  42891. TIME_CALLBACK_EVENT_SET = $0010; { callback is event - use SetEvent }
  42892. TIME_CALLBACK_EVENT_PULSE = $0020; { callback is event - use PulseEvent }
  42893. type
  42894. TFNTimeCallBack = procedure(uTimerID, uMessage: UINT;
  42895. dwUser, dw1, dw2: DWORD) {$ifdef wince}cdecl{$else}stdcall{$endif};
  42896. //[API timeSetEvent]
  42897. function timeSetEvent(uDelay, uResolution: UINT;
  42898. lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): THandle; {$ifdef wince}cdecl{$else}stdcall{$endif};
  42899. external 'winmm.dll' name 'timeSetEvent';
  42900. function timeKillEvent(uTimerID: UINT): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  42901. external 'winmm.dll' name 'timeKillEvent';
  42902. { ----------------------------------------------------------------------- }
  42903. //[procedure MMTimerCallback]
  42904. procedure MMTimerCallback(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD);
  42905. {$ifdef wince}cdecl{$else}stdcall{$endif};
  42906. var MMTimer: PMMTimer;
  42907. begin
  42908. MMTimer := Pointer( dwUser );
  42909. if Assigned( MMTimer.FOnTimer ) then
  42910. MMTimer.fOnTimer( MMTimer );
  42911. end;
  42912. //[function NewMMTimer]
  42913. function NewMMTimer( Interval: Integer ): PMMTimer;
  42914. begin
  42915. {-}
  42916. New( Result, Create );
  42917. {+} {++}(* Result := PMMTimer.Create; *){--}
  42918. Result.fInterval := Interval;
  42919. Result.FPeriodic := TRUE;
  42920. end;
  42921. //[END NewMMTimer]
  42922. //[destructor TMMTimer.Destroy]
  42923. destructor TMMTimer.Destroy;
  42924. begin
  42925. Enabled := FALSE;
  42926. Inc( TimerCount );
  42927. inherited;
  42928. end;
  42929. //[procedure TMMTimer.SetEnabled]
  42930. procedure TMMTimer.SetEnabled(const Value: Boolean);
  42931. begin
  42932. if Value xor (fHandle <> 0) then
  42933. begin
  42934. if fHandle = 0 then
  42935. fHandle := timeSetEvent( Interval, Resolution, MMTimerCallback, DWORD( @ Self ),
  42936. Integer( Periodic ) or TIME_CALLBACK_FUNCTION )
  42937. else
  42938. begin
  42939. timeKillEvent( fHandle );
  42940. fHandle := 0;
  42941. end;
  42942. end;
  42943. fEnabled := Value;
  42944. end;
  42945. {$endif win32}
  42946. {$ENDIF WIN}
  42947. {$IFDEF LIN}
  42948. function NewMMTimer( Interval: Integer ): PTimer;
  42949. begin
  42950. Result := NewTimer( Interval );
  42951. {$IFNDEF GTK}
  42952. {$IFNDEF QT}
  42953. Result.fMultimedia := TRUE;
  42954. Result.fPeriodic := TRUE;
  42955. Result.fResolution := 1;
  42956. {$ENDIF QT}
  42957. {$ENDIF GTK}
  42958. end;
  42959. {$ENDIF LIN}
  42960. {$IFDEF WIN_GDI} //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  42961. ////////////////////////////////////////////////////////////////////////
  42962. // t B I T M A P
  42963. ///////////////////////////////////////////////////////////////////////
  42964. { -- bitmap -- }
  42965. //[FUNCTION PrepareBitmapHeader]
  42966. {$IFDEF ASM_VERSION}
  42967. {$ELSE ASM_VERSION} //Pascal
  42968. function PrepareBitmapHeader( W, H, BitsPerPixel: Integer ): PBitmapInfo;
  42969. begin
  42970. Assert( W > 0, 'Width must be >0' );
  42971. Assert( H > 0, 'Height must be >0' );
  42972. Result := AllocMem( 256*Sizeof(TRGBQuad)+Sizeof(TBitmapInfoHeader) );
  42973. Assert( Result <> nil, 'No memory' );
  42974. Result.bmiHeader.biSize := Sizeof( TBitmapInfoHeader );
  42975. Result.bmiHeader.biWidth := W;
  42976. Result.bmiHeader.biHeight := H; // may be, -H ?
  42977. Result.bmiHeader.biPlanes := 1;
  42978. Result.bmiHeader.biBitCount := BitsPerPixel;
  42979. end;
  42980. {$ENDIF ASM_VERSION}
  42981. //[END PrepareBitmapHeader]
  42982. const
  42983. BitsPerPixel_By_PixelFormat: array[ TPixelFormat ] of Byte =
  42984. ( 0, 1, 4, 8, 16, 16, 24, 32, 0 );
  42985. //[FUNCTION Bits2PixelFormat]
  42986. {$IFDEF ASM_VERSION}
  42987. {$ELSE ASM_VERSION} //Pascal
  42988. function Bits2PixelFormat( BitsPerPixel: Integer ): TPixelFormat;
  42989. var I: TPixelFormat;
  42990. begin
  42991. for I := High(I) downto Low(I) do
  42992. if BitsPerPixel = BitsPerPixel_By_PixelFormat[ I ] then
  42993. begin
  42994. Result := I;
  42995. Exit;
  42996. end;
  42997. Result := pfDevice;
  42998. end;
  42999. {$ENDIF ASM_VERSION}
  43000. //[END Bits2PixelFormat]
  43001. //[procedure DummyDetachCanvas]
  43002. procedure DummyDetachCanvas( Sender: PBitmap );
  43003. begin
  43004. end;
  43005. //[FUNCTION NewBitmap]
  43006. {$IFDEF ASM_VERSION}
  43007. {$ELSE ASM_VERSION} //Pascal
  43008. function NewBitmap( W, H: Integer ): PBitmap;
  43009. var DC: HDC;
  43010. begin
  43011. {-}
  43012. New( Result, Create );
  43013. {+}{++}(*Result := PBitmap.Create;*){--}
  43014. Result.fHandleType := bmDDB;
  43015. Result.fDetachCanvas := DummyDetachCanvas;
  43016. Result.fWidth := W;
  43017. Result.fHeight := H;
  43018. if (W <> 0) and (H <> 0) then
  43019. begin
  43020. DC := GetDC( 0 );
  43021. Result.fHandle := CreateCompatibleBitmap( DC, W, H );
  43022. Assert( Result.fHandle <> 0, 'Can not create bitmap handle' );
  43023. ReleaseDC( 0, DC );
  43024. end;
  43025. end;
  43026. {$ENDIF ASM_VERSION}
  43027. //[END NewBitmap]
  43028. const InitColors: array[ 0..17 ] of DWORD = ( $F800, $7E0, $1F, 0, $800000, $8000,
  43029. $808000, $80, $800080, $8080, $808080, $C0C0C0, $FF0000, $FF00, $FFFF00, $FF,
  43030. $FF00FF, $FFFF );
  43031. //[PROCEDURE PreparePF16bit]
  43032. {$IFDEF ASM_VERSION}
  43033. {$ELSE ASM_VERSION} //Pascal
  43034. procedure PreparePF16bit( DIBHeader: PBitmapInfo );
  43035. begin
  43036. DIBHeader.bmiHeader.biCompression := BI_BITFIELDS;
  43037. Move( InitColors[ 0 ], DIBHeader.bmiColors[ 0 ], 19*Sizeof(TRGBQUAD) );
  43038. end;
  43039. {$ENDIF ASM_VERSION}
  43040. //[END PreparePF16bit]
  43041. //[FUNCTION NewDIBBitmap]
  43042. {$IFDEF ASM_VERSION}
  43043. {$ELSE ASM_VERSION} //Pascal
  43044. function NewDIBBitmap( W, H: Integer; PixelFormat: TPixelFormat ): PBitmap;
  43045. const BitsPerPixel: array[ TPixelFormat ] of Byte = ( 0, 1, 4, 8, 16, 16, 24, 32, 0 );
  43046. var BitsPixel: Integer;
  43047. begin
  43048. {-}
  43049. New( Result, Create );
  43050. {+}{++}(*Result := PBitmap.Create;*){--}
  43051. Result.fDetachCanvas := DummyDetachCanvas;
  43052. Result.fWidth := W;
  43053. Result.fHeight := H;
  43054. if (W <> 0) and (H <> 0) then
  43055. begin
  43056. BitsPixel := BitsPerPixel[ PixelFormat ];
  43057. if BitsPixel = 0 then
  43058. begin
  43059. Result.fNewPixelFormat := DefaultPixelFormat;
  43060. BitsPixel := BitsPerPixel[DefaultPixelFormat];
  43061. end
  43062. else
  43063. Result.fNewPixelFormat := PixelFormat;
  43064. ASSERT( Result.fNewPixelFormat in [ pf1bit..pf32bit ], 'Strange pixel format' );
  43065. Result.fDIBHeader := PrepareBitmapHeader( W, H, BitsPixel );
  43066. if PixelFormat = pf16bit then
  43067. begin
  43068. PreparePF16bit( Result.fDIBHeader );
  43069. end;
  43070. Result.fDIBSize := Result.ScanLineSize * H;
  43071. Result.fDIBBits :=
  43072. Pointer( GlobalAlloc( GMEM_FIXED or GMEM_ZEROINIT, Result.fDIBSize + 16 ) );
  43073. ASSERT( Result.fDIBBits <> nil, 'No memory' );
  43074. end;
  43075. end;
  43076. {$ENDIF ASM_VERSION}
  43077. //[END NewDIBBitmap]
  43078. { TBitmap }
  43079. //[procedure TBitmap.ClearData]
  43080. {$IFDEF ASM_VERSION}
  43081. {$ELSE ASM_VERSION} //Pascal
  43082. procedure TBitmap.ClearData;
  43083. begin
  43084. fDetachCanvas( @Self );
  43085. if fHandle <> 0 then
  43086. begin
  43087. DeleteObject( fHandle );
  43088. fHandle := 0;
  43089. fDIBBits := nil;
  43090. end;
  43091. if fDIBBits <> nil then
  43092. begin
  43093. GlobalFree( THandle( fDIBBits ) );
  43094. fDIBBits := nil;
  43095. end;
  43096. if fDIBHeader <> nil then
  43097. begin
  43098. FreeMem( fDIBHeader );
  43099. fDIBHeader := nil;
  43100. end;
  43101. fScanLineSize := 0;
  43102. fGetDIBPixels := nil;
  43103. fSetDIBPixels := nil;
  43104. ClearTransImage;
  43105. end;
  43106. {$ENDIF ASM_VERSION}
  43107. //[procedure TBitmap.Clear]
  43108. {$IFDEF ASM_VERSION}
  43109. {$ELSE ASM_VERSION} //Pascal
  43110. procedure TBitmap.Clear;
  43111. begin
  43112. RemoveCanvas;
  43113. ClearData;
  43114. fWidth := 0;
  43115. fHeight := 0;
  43116. fDIBAutoFree := FALSE;
  43117. end;
  43118. {$ENDIF ASM_VERSION}
  43119. //[function TBitmap.GetBoundsRect]
  43120. function TBitmap.GetBoundsRect: TRect;
  43121. begin
  43122. Result := MakeRect( 0, 0, Width, Height );
  43123. end;
  43124. //[destructor TBitmap.Destroy]
  43125. {$IFDEF ASM_VERSION}
  43126. {$ELSE ASM_VERSION} //Pascal
  43127. destructor TBitmap.Destroy;
  43128. begin
  43129. Clear;
  43130. inherited;
  43131. end;
  43132. {$ENDIF ASM_VERSION}
  43133. //[function TBitmap.BitsPerPixel]
  43134. function TBitmap.BitsPerPixel: Integer;
  43135. var B: tagBitmap;
  43136. begin
  43137. CASE PixelFormat OF
  43138. pf1bit: Result := 1;
  43139. pf4bit: Result := 4;
  43140. pf8bit: Result := 8;
  43141. pf15bit: Result := 15;
  43142. pf16bit: Result := 16;
  43143. pf24bit: Result := 24;
  43144. pf32bit: Result := 32;
  43145. else begin
  43146. Result := 0;
  43147. if fHandle <> 0 then
  43148. if GetObject( fHandle, Sizeof( B ), @B ) > 0 then
  43149. Result := B.bmBitsPixel * B.bmPlanes;
  43150. end;
  43151. END;
  43152. end;
  43153. //[procedure TBitmap.Draw]
  43154. {$IFDEF ASM_VERSION}
  43155. {$ELSE ASM_VERSION} //Pascal
  43156. procedure TBitmap.Draw(DC: HDC; X, Y: Integer);
  43157. var
  43158. DCfrom, DC0: HDC;
  43159. oldBmp: HBitmap;
  43160. oldHeight: Integer;
  43161. B: tagBitmap;
  43162. label
  43163. TRYAgain;
  43164. begin
  43165. TRYAgain:
  43166. if Empty then Exit;
  43167. if fHandle <> 0 then
  43168. begin
  43169. fDetachCanvas( @Self );
  43170. oldHeight := fHeight;
  43171. if GetObject( fHandle, sizeof( B ), @B ) <> 0 then
  43172. oldHeight := B.bmHeight;
  43173. ASSERT( oldHeight > 0, 'oldHeight must be > 0' );
  43174. DC0 := GetDC( 0 );
  43175. DCfrom := CreateCompatibleDC( DC0 );
  43176. ReleaseDC( 0, DC0 );
  43177. oldBmp := SelectObject( DCfrom, fHandle );
  43178. ASSERT( oldBmp <> 0, 'Can not select bitmap to DC' );
  43179. BitBlt( DC, X, Y, fWidth, oldHeight, DCfrom, 0, 0, SRCCOPY );
  43180. {$IFDEF CHK_BITBLT} Chk_BitBlt; {$ENDIF}
  43181. SelectObject( DCfrom, oldBmp );
  43182. DeleteDC( DCfrom );
  43183. end
  43184. else
  43185. if fDIBBits <> nil then
  43186. begin
  43187. oldHeight := Abs(fDIBHeader.bmiHeader.biHeight);
  43188. ASSERT( oldHeight > 0, 'oldHeight must be > 0' );
  43189. ASSERT( fWidth > 0, 'Width must be > 0' );
  43190. if StretchDIBits( DC, X, Y, fWidth, oldHeight, 0, 0, fWidth, oldHeight,
  43191. fDIBBits, fDIBHeader^, DIB_RGB_COLORS, SRCCOPY ) = 0 then
  43192. begin
  43193. if GetHandle <> 0 then
  43194. goto TRYAgain;
  43195. end;
  43196. end;
  43197. end;
  43198. {$ENDIF ASM_VERSION}
  43199. //[procedure TBitmap.StretchDraw]
  43200. {$IFDEF ASM_VERSION}
  43201. {$ELSE ASM_VERSION} //Pascal
  43202. procedure TBitmap.StretchDraw(DC: HDC; const Rect: TRect);
  43203. var DCfrom: HDC;
  43204. oldBmp: HBitmap;
  43205. label DrawHandle;
  43206. begin
  43207. if Empty then Exit;
  43208. DrawHandle:
  43209. if fHandle <> 0 then
  43210. begin
  43211. fDetachCanvas( @Self );
  43212. DCfrom := CreateCompatibleDC( 0 );
  43213. oldBmp := SelectObject( DCfrom, fHandle );
  43214. ASSERT( oldBmp <> 0, 'Can not select bitmap to DC' );
  43215. StretchBlt( DC, Rect.Left, Rect.Top, Rect.Right - Rect.Left,
  43216. Rect.Bottom - Rect.Top, DCfrom, 0, 0, fWidth, fHeight,
  43217. SRCCOPY );
  43218. SelectObject( DCfrom, oldBmp );
  43219. DeleteDC( DCfrom );
  43220. end
  43221. else
  43222. if fDIBBits <> nil then
  43223. begin
  43224. if StretchDIBits( DC, Rect.Left, Rect.Top, Rect.Right - Rect.Left,
  43225. Rect.Bottom - Rect.Top, 0, 0, fWidth, fHeight,
  43226. fDIBBits, fDIBHeader^, DIB_RGB_COLORS, SRCCOPY )<=0 then
  43227. begin
  43228. if GetHandle <> 0 then
  43229. goto DrawHandle;
  43230. end;
  43231. end;
  43232. end;
  43233. {$ENDIF ASM_VERSION}
  43234. //[procedure TBitmap.DrawMasked]
  43235. procedure TBitmap.DrawMasked(DC: HDC; X, Y: Integer; Mask: HBitmap);
  43236. begin
  43237. StretchDrawMasked( DC, MakeRect( X, Y, X + fWidth, Y + fHeight ), Mask );
  43238. end;
  43239. //[procedure TBitmap.DrawTransparent]
  43240. {$IFDEF ASM_VERSION}
  43241. {$ELSE ASM_VERSION} //Pascal
  43242. procedure TBitmap.DrawTransparent(DC: HDC; X, Y: Integer; TranspColor: TColor);
  43243. begin
  43244. if TranspColor = clNone then
  43245. Draw( DC, X, Y )
  43246. else
  43247. StretchDrawTransparent( DC, MakeRect( X, Y, X + fWidth, Y + fHeight ),
  43248. TranspColor );
  43249. end;
  43250. {$ENDIF ASM_VERSION}
  43251. //[procedure TBitmap.StretchDrawTransparent]
  43252. {$IFDEF ASM_VERSION}
  43253. {$ELSE ASM_VERSION} //Pascal
  43254. {$ifdef wince}
  43255. function TransparentImage(hdcDest : HDC;DstX : LONG;DstY : LONG;DstCx : LONG;DstCy : LONG;hSrc : HANDLE;SrcX : LONG;SrcY : LONG;SrcCx : LONG;SrcCy : LONG;TransparentColor : COLORREF): WINBOOL; cdecl; external KernelDLL name 'TransparentImage';
  43256. {$endif wince}
  43257. procedure TBitmap.StretchDrawTransparent(DC: HDC; const Rect: TRect; TranspColor: TColor);
  43258. begin
  43259. if TranspColor = clNone then
  43260. StretchDraw( DC, Rect )
  43261. else
  43262. begin
  43263. if GetHandle = 0 then Exit;
  43264. TranspColor := Color2RGB( TranspColor );
  43265. {$ifdef wince}
  43266. TransparentImage(DC, Rect.Left, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top, fHandle, 0, 0, Width, Height, TranspColor);
  43267. {$else}
  43268. if (fTransMaskBmp = nil) or (fTransColor <> TranspColor) then
  43269. begin
  43270. if fTransMaskBmp = nil then
  43271. fTransMaskBmp := NewBitmap( 0, 0 {fWidth, fHeight} );
  43272. fTransColor := TranspColor;
  43273. // Create here mask bitmap:
  43274. fTransMaskBmp.Assign( @Self );
  43275. fTransMaskBmp.Convert2Mask( TranspColor );
  43276. end;
  43277. StretchDrawMasked( DC, Rect, fTransMaskBmp.Handle );
  43278. {$endif wince}
  43279. end;
  43280. end;
  43281. {$ENDIF ASM_VERSION}
  43282. {$IFDEF DEBUG_DRAWTRANSPARENT}
  43283. procedure DebugDrawTransparent( DC: HDC; X, Y, W, H: Integer; PF: TPixelFormat;
  43284. const Note: String );
  43285. const PixelFormatAsStr: array[ TPixelFormat ] of String = ( 'pfDevice', 'pf1bit',
  43286. 'pf4bit', 'pf8bit', 'pf15bit', 'pf16bit', 'pf24bit', 'pf32bit', 'pfCustom' );
  43287. var Bmp: PBitmap;
  43288. begin
  43289. Bmp := NewDibBitmap( W, H, pf32bit );
  43290. BitBlt( Bmp.Canvas.Handle, 0, 0, W, H, DC, X, Y, SrcCopy );
  43291. Bmp.SaveToFile( GetStartDir + PixelFormatAsStr[ PF ] + Note );
  43292. Bmp.Free;
  43293. end;
  43294. {$ENDIF DEBUG_DRAWTRANSPARENT}
  43295. const
  43296. ROP_DstCopy = $00AA0029;
  43297. //[procedure TBitmap.StretchDrawMasked]
  43298. {$IFDEF ASM_VERSION}
  43299. {$ELSE ASM_VERSION} //Pascal
  43300. procedure TBitmap.StretchDrawMasked(DC: HDC; const Rect: TRect; Mask: HBitmap);
  43301. var
  43302. DCfrom, MemDC, MaskDC: HDC;
  43303. MemBmp: HBITMAP;
  43304. //Save4From,
  43305. Save4Mem, Save4Mask: THandle;
  43306. crText, crBack: TColorRef;
  43307. {$IFDEF FIX_TRANSPBMPPALETTE}
  43308. FixBmp: PBitmap;
  43309. {$ENDIF FIX_TRANSPBMPPALETTE}
  43310. begin
  43311. {$IFDEF FIX_TRANSPBMPPALETTE}
  43312. if PixelFormat in [ pf4bit, pf8bit ] then
  43313. begin
  43314. FixBmp := NewBitmap( 0, 0 );
  43315. FixBmp.Assign( @ Self );
  43316. FixBmp.PixelFormat := pf32bit;
  43317. FixBmp.StretchDrawMasked( DC, Rect, Mask );
  43318. FixBmp.Free;
  43319. Exit;
  43320. end;
  43321. {$ENDIF FIX_TRANSPBMPPALETTE}
  43322. if GetHandle = 0 then Exit;
  43323. //fDetachCanvas( @Self );
  43324. //DCfrom := CreateCompatibleDC( 0 );
  43325. DCFrom := Canvas.Handle;
  43326. //Save4From := SelectObject( DCfrom, fHandle );
  43327. //ASSERT( Save4From <> 0, 'Can not select source bitmap to DC' );
  43328. MaskDC := CreateCompatibleDC( 0 );
  43329. Save4Mask := SelectObject( MaskDC, Mask );
  43330. ASSERT( Save4Mask <> 0, 'Can not select mask bitmap to DC' );
  43331. MemDC := CreateCompatibleDC( 0 );
  43332. MemBmp := CreateCompatibleBitmap( DCfrom, fWidth, fHeight );
  43333. Save4Mem := SelectObject( MemDC, MemBmp );
  43334. ASSERT( Save4Mem <> 0, 'Can not select memory bitmap to DC' );
  43335. StretchBlt( MemDC, 0, 0, fWidth, fHeight, MaskDC, 0, 0, fWidth, fHeight, SrcCopy);
  43336. {$IFDEF DEBUG_DRAWTRANSPARENT}
  43337. DebugDrawTransparent( MemDC, 0, 0, fWidth, fWidth, PixelFormat, '1SrcCopy.bmp' );
  43338. {$ENDIF}
  43339. StretchBlt( MemDC, 0, 0, fWidth, fHeight, DCfrom, 0, 0, fWidth, fHeight, SrcErase);
  43340. {$IFDEF DEBUG_DRAWTRANSPARENT}
  43341. DebugDrawTransparent( MemDC, 0, 0, fWidth, fWidth, PixelFormat, '2SrcErase.bmp' );
  43342. {$ENDIF}
  43343. crText := SetTextColor(DC, $0);
  43344. crBack := Windows.SetBkColor(DC, $FFFFFF);
  43345. StretchBlt( DC, Rect.Left, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top,
  43346. MaskDC, 0, 0, fWidth, fHeight, SrcAnd);
  43347. {$IFDEF DEBUG_DRAWTRANSPARENT}
  43348. DebugDrawTransparent( DC, Rect.Left, Rect.Top, fWidth, fHeight, PixelFormat, '3SrcAnd.bmp' );
  43349. {$ENDIF}
  43350. StretchBlt( DC, Rect.Left, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top,
  43351. MemDC, 0, 0, fWidth, fHeight, SrcInvert);
  43352. {$IFDEF DEBUG_DRAWTRANSPARENT}
  43353. DebugDrawTransparent( DC, Rect.Left, Rect.Top, fWidth, fHeight, PixelFormat, '4SrcInvert.bmp' );
  43354. {$ENDIF}
  43355. Windows.SetBkColor( DC, crBack);
  43356. SetTextColor( DC, crText);
  43357. //if Save4Mem <> 0 then
  43358. // SelectObject( MemDC, Save4Mem );
  43359. DeleteObject(MemBmp);
  43360. DeleteDC(MemDC);
  43361. //SelectObject( DCfrom, Save4From );
  43362. //DeleteDC( DCfrom );
  43363. SelectObject( MaskDC, Save4Mask );
  43364. DeleteDC( MaskDC );
  43365. end;
  43366. {$ENDIF ASM_VERSION}
  43367. //[procedure ApplyBitmapBkColor2Canvas]
  43368. procedure ApplyBitmapBkColor2Canvas( Sender: PBitmap );
  43369. begin
  43370. if Sender.fCanvas = nil then Exit;
  43371. Sender.fCanvas.Brush.Color := Sender.BkColor;
  43372. end;
  43373. //[PROCEDURE DetachBitmapFromCanvas]
  43374. {$IFDEF ASM_VERSION}
  43375. {$ELSE ASM_VERSION} //Pascal
  43376. procedure DetachBitmapFromCanvas( Sender: PBitmap );
  43377. begin
  43378. if Sender.fCanvasAttached = 0 then Exit;
  43379. SelectObject( Sender.fCanvas.fHandle, Sender.fCanvasAttached );
  43380. Sender.fCanvasAttached := 0;
  43381. end;
  43382. {$ENDIF ASM_VERSION}
  43383. //[END DetachBitmapFromCanvas]
  43384. //[function TBitmap.GetCanvas]
  43385. {$IFDEF ASM_VERSION}
  43386. {$ELSE ASM_VERSION} //Pascal
  43387. function TBitmap.GetCanvas: PCanvas;
  43388. var DC: HDC;
  43389. begin
  43390. Result := nil;
  43391. if Empty then Exit;
  43392. if GetHandle = 0 then Exit;
  43393. if fCanvas = nil then
  43394. begin
  43395. fApplyBkColor2Canvas := ApplyBitmapBkColor2Canvas;
  43396. DC := CreateCompatibleDC( 0 );
  43397. fCanvas := NewCanvas( DC );
  43398. fCanvas.fIsPaintDC := FALSE;
  43399. fCanvas.OnChange := CanvasChanged;
  43400. if fBkColor <> 0 then
  43401. fCanvas.Brush.Color := fBkColor;
  43402. end;
  43403. Result := fCanvas;
  43404. if fCanvas.fHandle = 0 then
  43405. begin
  43406. DC := CreateCompatibleDC( 0 );
  43407. fCanvas.Handle := DC;
  43408. fCanvasAttached := 0;
  43409. end;
  43410. if fCanvasAttached = 0 then
  43411. begin
  43412. fCanvasAttached := SelectObject( fCanvas.Handle, fHandle );
  43413. ASSERT( fCanvasAttached <> 0, 'Can not select bitmap to DC of Canvas' );
  43414. end;
  43415. fDetachCanvas := DetachBitmapFromCanvas;
  43416. end;
  43417. {$ENDIF ASM_VERSION}
  43418. //[function TBitmap.GetEmpty]
  43419. {$IFDEF ASM_VERSION}
  43420. {$ELSE ASM_VERSION} //Pascal
  43421. function TBitmap.GetEmpty: Boolean;
  43422. begin
  43423. Result := (fWidth = 0) or (fHeight = 0);
  43424. ASSERT( (fWidth >= 0) and (fHeight >= 0), 'Bitmap dimensions can be negative' );
  43425. end;
  43426. {$ENDIF ASM_VERSION}
  43427. {$IFDEF ASM_noVERSION}
  43428. //[function TBitmap.GetHandle]
  43429. function TBitmap.GetHandle: HBitmap;
  43430. asm
  43431. PUSH EBX
  43432. MOV EBX, EAX
  43433. CALL GetEmpty
  43434. JZ @@exit
  43435. MOV EAX, EBX
  43436. CALL [EAX].fDetachCanvas
  43437. MOV ECX, [EBX].fHandle
  43438. INC ECX
  43439. LOOP @@exit
  43440. MOV ECX, [EBX].fDIBBits
  43441. JECXZ @@exit
  43442. PUSH ECX
  43443. PUSH 0
  43444. CALL GetDC
  43445. PUSH EAX
  43446. PUSH 0
  43447. PUSH 0
  43448. LEA EDX, [EBX].fDIBBits
  43449. PUSH EDX
  43450. PUSH DIB_RGB_COLORS
  43451. PUSH [EBX].fDIBHeader
  43452. PUSH EAX
  43453. CALL CreateDIBSection
  43454. MOV [EBX].fHandle, EAX
  43455. PUSH 0
  43456. CALL ReleaseDC
  43457. POP EAX
  43458. PUSH EAX
  43459. MOV EDX, [EBX].fDIBBits
  43460. MOV ECX, [EBX].fDIBSize
  43461. CALL System.Move
  43462. POP EAX
  43463. CMP [EBX].fDIBAutoFree, 0
  43464. JNZ @@freed
  43465. PUSH EAX
  43466. CALL GlobalFree
  43467. @@freed:MOV [EBX].fDIBAutoFree, 1
  43468. XOR EAX, EAX
  43469. MOV [EBX].fGetDIBPixels, EAX
  43470. MOV [EBX].fSetDIBPixels, EAX
  43471. @@exit: MOV EAX, [EBX].fHandle
  43472. POP EBX
  43473. end;
  43474. {$ELSE ASM_VERSION} //Pascal
  43475. function TBitmap.GetHandle: HBitmap;
  43476. var OldBits: Pointer;
  43477. DC0: HDC;
  43478. begin
  43479. Result := 0;
  43480. if Empty then Exit;
  43481. fDetachCanvas( @ Self );
  43482. if fHandle = 0 then
  43483. begin
  43484. if fDIBBits <> nil then
  43485. begin
  43486. OldBits := fDIBBits;
  43487. DC0 := GetDC( 0 );
  43488. fDIBBits := nil;
  43489. fHandle := CreateDIBSection( DC0, fDIBHeader^, DIB_RGB_COLORS,
  43490. fDIBBits, 0, 0 );
  43491. {$IFDEF DEBUG}
  43492. if fHandle = 0 then
  43493. ShowMessage( 'Can not create DIB section, error: ' + Int2Str( GetLastError ) +
  43494. ', ' + SysErrorMessage( GetLastError ) );
  43495. {$ELSE}
  43496. ASSERT( fHandle <> 0, 'Can not create DIB section, error: ' + Int2Str( GetLastError ) +
  43497. ', ' + SysErrorMessage( GetLastError ) );
  43498. {$ENDIF}
  43499. ReleaseDC( 0, DC0 );
  43500. if fHandle <> 0 then
  43501. begin
  43502. Move( OldBits^, fDIBBits^, fDIBSize );
  43503. if not fDIBAutoFree then
  43504. GlobalFree( THandle( OldBits ) );
  43505. fDIBAutoFree := TRUE;
  43506. fGetDIBPixels := nil;
  43507. fSetDIBPixels := nil;
  43508. end
  43509. else
  43510. fDIBBits := OldBits;
  43511. end;
  43512. end;
  43513. Result := fHandle;
  43514. end;
  43515. {$ENDIF ASM_VERSION}
  43516. //[function TBitmap.GetHandleAllocated]
  43517. function TBitmap.GetHandleAllocated: Boolean;
  43518. begin
  43519. Result := fHandle <> 0;
  43520. end;
  43521. //[procedure TBitmap.LoadFromFile]
  43522. {$IFDEF ASM_VERSION}
  43523. {$ELSE ASM_VERSION} //Pascal
  43524. procedure TBitmap.LoadFromFile(const Filename: KOLString);
  43525. var Strm: PStream;
  43526. begin
  43527. Strm := NewReadFileStream( Filename );
  43528. LoadFromStream( Strm );
  43529. Strm.Free;
  43530. end;
  43531. {$ENDIF ASM_VERSION}
  43532. //[procedure TBitmap.LoadFromResourceID]
  43533. procedure TBitmap.LoadFromResourceID(Inst: DWORD; ResID: Integer);
  43534. begin
  43535. LoadFromResourceName( Inst, MAKEINTRESOURCE( ResID ) );
  43536. end;
  43537. //[procedure TBitmap.LoadFromResourceName]
  43538. {$IFDEF ASM_UNICODE}
  43539. {$ELSE ASM_VERSION} //Pascal
  43540. procedure TBitmap.LoadFromResourceName(Inst: DWORD; ResName: PKOLChar);
  43541. var ResHandle: HBitmap;
  43542. {$ifndef wince}
  43543. Flg: DWORD;
  43544. {$endif wince}
  43545. begin
  43546. Clear;
  43547. {$ifndef wince}
  43548. Flg := 0;
  43549. if fHandleType = bmDIB then
  43550. Flg := LR_CREATEDIBSECTION;
  43551. {$endif wince}
  43552. ResHandle := LoadImage( Inst, ResName, IMAGE_BITMAP, 0, 0, {$ifdef wince} 0 {$else} LR_DEFAULTSIZE or Flg {$endif} );
  43553. if ResHandle = 0 then Exit;
  43554. Handle := ResHandle;
  43555. end;
  43556. {$ENDIF ASM_VERSION}
  43557. {$IFDEF F_P}
  43558. type
  43559. TBITMAPFILEHEADER = packed record
  43560. bfType: Word;
  43561. bfSize: DWORD;
  43562. bfReserved1: Word;
  43563. bfReserved2: Word;
  43564. bfOffBits: DWORD;
  43565. end;
  43566. {$ENDIF}
  43567. {$IFDEF ASM_noVERSION} // error + 16Colors->swap(Gray,Silver) + Core
  43568. //[procedure TBitmap.LoadFromStream]
  43569. procedure TBitmap.LoadFromStream(Strm: PStream);
  43570. type tBFH = TBitmapFileHeader;
  43571. tBIH = TBitmapInfoHeader;
  43572. const szBIH = Sizeof( tBIH );
  43573. szBFH = Sizeof( tBFH );
  43574. asm
  43575. PUSH EBX
  43576. PUSH ESI
  43577. MOV EBX, EAX
  43578. PUSH EDX
  43579. CALL Clear
  43580. POP ESI
  43581. MOV EAX, ESI
  43582. CALL TStream.GetPosition
  43583. PUSH EAX // [EBP+4] = Strm.Pos (starting pos)
  43584. PUSH EBP
  43585. MOV EBP, ESP
  43586. ADD ESP, -(szBIH + szBFH)
  43587. // reading bitmap
  43588. XOR ECX, ECX
  43589. MOV [EBX].fHandleType, CL
  43590. MOV CL, szBFH
  43591. MOV EDX, ESP
  43592. PUSH ECX
  43593. MOV EAX, ESI
  43594. CALL TStream.Read
  43595. POP ECX
  43596. SUB ECX, EAX
  43597. JNZ @@eread1
  43598. CMP [ESP].tBFH.bfType, $4D42
  43599. JE @@1
  43600. MOV EDX, [EBP+4]
  43601. MOV EAX, ESI
  43602. CALL TStream.Seek
  43603. XOR EAX, EAX
  43604. XOR EDX, EDX
  43605. JMP @@2
  43606. @@1:
  43607. MOV EDX, [ESP].tBFH.bfSize
  43608. MOV EAX, [ESP].tBFH.bfOffBits
  43609. @@2:
  43610. PUSH EDX // Push Size
  43611. PUSH EAX // Push Off
  43612. XOR ECX, ECX
  43613. MOV CL, szBIH
  43614. LEA EDX, [EBP-szBIH]
  43615. MOV EAX, ESI
  43616. PUSH ECX
  43617. CALL TStream.Read // read BIH
  43618. POP ECX
  43619. @@eread1:
  43620. XOR ECX, EAX
  43621. JNZ @@eread
  43622. MOVZX EAX, [EBP-szBIH].tBIH.biBitCount
  43623. MOVZX EDX, [EBP-szBIH].tBIH.biPlanes
  43624. MUL EDX
  43625. CALL Bits2PixelFormat
  43626. {$IFDEF PARANOIA} DB $3C, pf15bit {$ELSE} CMP AL, pf15bit {$ENDIF}
  43627. JNZ @@no15bit
  43628. CMP [EBP-szBIH].tBIH.biCompression, 0
  43629. JZ @@no15bit
  43630. INC AL // AL = pf16bit
  43631. @@no15bit:
  43632. MOV [EBX].fNewPixelFormat, AL
  43633. MOV EAX, szBIH + 1024
  43634. CALL System.@GetMem
  43635. MOV [EBX].fDIBHeader, EAX
  43636. XCHG EDX, EAX
  43637. LEA EAX, [EBP-szBIH]
  43638. XOR ECX, ECX
  43639. MOV CL, szBIH
  43640. CALL System.Move
  43641. MOV EAX, [EBP-szBIH].tBIH.biWidth
  43642. MOV [EBX].fWidth, EAX
  43643. MOV EAX, [EBP-szBIH].tBIH.biHeight
  43644. TEST EAX, EAX
  43645. JGE @@20
  43646. NEG EAX
  43647. @@20: MOV [EBX].fHeight, EAX
  43648. MOV EAX, EBX
  43649. CALL GetScanLineSize
  43650. MOV EDX, [EBX].fHeight
  43651. MUL EDX
  43652. MOV [EBX].fDIBSize, EAX
  43653. PUSH EAX
  43654. PUSH GMEM_FIXED or GMEM_ZEROINIT
  43655. CALL GlobalAlloc
  43656. MOV [EBX].fDIBBits, EAX
  43657. MOVZX EAX, [EBP-szBIH].tBIH.biBitCount
  43658. {$IFDEF PARANOIA} DB $3C, 8 {$ELSE} CMP AL, 8 {$ENDIF}
  43659. JA @@3
  43660. MOV AL, 4
  43661. MOVZX ECX, [EBP-szBIH].tBIH.biBitCount
  43662. SAL EAX, CL
  43663. XCHG ECX, EAX
  43664. @@3:
  43665. CMP [EBX].TBitmap.fNewPixelFormat, pf16bit
  43666. JNE @@30
  43667. XOR ECX, ECX
  43668. MOV CL, 12 // ColorCount = 12
  43669. @@30:
  43670. POP EAX // EAX = off
  43671. TEST EAX, EAX
  43672. JLE @@4
  43673. SUB EAX, szBFH + szBIH
  43674. CMP EAX, ECX
  43675. JZ @@4
  43676. XCHG ECX, EAX
  43677. @@4:
  43678. JECXZ @@5
  43679. PUSH ECX
  43680. MOV EDX, [EBX].fDIBHeader
  43681. ADD EDX, szBIH
  43682. MOV EAX, ESI
  43683. CALL TStream.Read
  43684. POP ECX
  43685. XOR EAX, ECX
  43686. JNZ @@eread
  43687. @@5:
  43688. MOV ECX, [EBX].fDIBSize
  43689. @@7:
  43690. PUSH ECX
  43691. MOV EAX, ESI
  43692. CALL TStream.GetPosition
  43693. PUSH EAX
  43694. MOV EAX, ESI
  43695. CALL TStream.GetSize
  43696. POP EDX
  43697. SUB EAX, EDX
  43698. POP ECX // Size = fDIBSize
  43699. CMP EAX, ECX // Strm.Size - Strm.Position > Size ?
  43700. JL @@8
  43701. XCHG ECX, EAX
  43702. @@8: // ++++++++++++++ 26-Oct-2003 VK see comment in Pascal
  43703. MOV EAX, [EBX].fDIBSize
  43704. CMP ECX, EAX
  43705. JGE @@9
  43706. SUB EAX, ECX
  43707. PUSH EAX
  43708. MOV EAX, ESI
  43709. PUSH ECX
  43710. CALL TStream.GetPosition
  43711. POP ECX
  43712. POP EDX
  43713. CMP EDX, EAX
  43714. JG @@9
  43715. MOV EAX, ESI
  43716. NEG EDX
  43717. XOR ECX, ECX
  43718. INC ECX
  43719. CALL TStream.Seek
  43720. MOV ECX, [EBX].fDIBSize
  43721. @@9: // ++++++++++++++
  43722. PUSH ECX
  43723. MOV EDX, [EBX].fDIBBits
  43724. MOV EAX, ESI
  43725. CALL TStream.Read
  43726. POP ECX
  43727. XOR EAX, ECX
  43728. POP EAX // Strm.Size - Position
  43729. POP ECX // fDIBSize
  43730. // end of reading bitmap
  43731. @@eread:
  43732. MOV ESP, EBP
  43733. POP EBP
  43734. POP EDX
  43735. JZ @@exit
  43736. // not success:
  43737. XCHG EAX, ESI
  43738. XOR ECX, ECX // ECX = spBegin
  43739. CALL TStream.Seek
  43740. XCHG EAX, EBX
  43741. CALL Clear
  43742. @@exit: POP ESI
  43743. POP EBX
  43744. end;
  43745. {$ELSE ASM_VERSION} //Pascal
  43746. procedure TBitmap.LoadFromStream(Strm: PStream);
  43747. type
  43748. TColorsArray = array[ 0..15 ] of TColor;
  43749. PColorsArray = ^TColorsArray;
  43750. PColor = ^TColor;
  43751. var Pos : DWORD;
  43752. BFH : TBitmapFileHeader;
  43753. function ReadBitmap : Boolean;
  43754. var Size, Size1: Integer;
  43755. BCH: TBitmapCoreHeader;
  43756. RGBSize: DWORD;
  43757. C: PColor;
  43758. Off, HdSz, ColorCount: DWORD;
  43759. //BFHValid: Boolean;
  43760. begin
  43761. fHandleType := bmDIB;
  43762. Result := False;
  43763. //BFHValid := FALSE;
  43764. if Strm.Read( BFH, Sizeof( BFH ) ) <> Sizeof( BFH ) then Exit;
  43765. Off := 0; Size := 0;
  43766. if BFH.bfType <> $4D42 then
  43767. Strm.Seek( Pos, spBegin )
  43768. else
  43769. begin
  43770. //BFHValid := TRUE;
  43771. Off := BFH.bfOffBits - Sizeof( BFH );
  43772. Size := BFH.bfSize; // don't matter, just <> 0 is good
  43773. end;
  43774. RGBSize := 4;
  43775. HdSz := Sizeof( TBitmapInfoHeader );
  43776. fDIBHeader := AllocMem( 256*sizeof(TRGBQuad) + HdSz );
  43777. if Strm.Read( fDIBHeader.bmiHeader.biSize, Sizeof( DWORD ) ) <> Sizeof( DWORD ) then
  43778. Exit;
  43779. if fDIBHeader.bmiHeader.biSize = HdSz then
  43780. begin
  43781. if Strm.Read( fDIBHeader.bmiHeader.biWidth, HdSz - Sizeof( DWORD ) ) <>
  43782. HdSz - Sizeof( DWORD ) then
  43783. Exit;
  43784. end
  43785. else
  43786. if fDIBHeader.bmiHeader.biSize = Sizeof( TBitmapCoreHeader ) then
  43787. begin
  43788. RGBSize := 3;
  43789. HdSz := Sizeof( TBitmapCoreHeader );
  43790. if Strm.Read( BCH.bcWidth, HdSz - Sizeof( DWORD ) ) <>
  43791. HdSz - Sizeof( DWORD ) then
  43792. Exit;
  43793. fDIBHeader.bmiHeader.biSize := Sizeof( TBitmapInfoHeader );
  43794. fDIBHeader.bmiHeader.biWidth := BCH.bcWidth;
  43795. fDIBHeader.bmiHeader.biHeight := BCH.bcHeight;
  43796. fDIBHeader.bmiHeader.biPlanes := BCH.bcPlanes;
  43797. fDIBHeader.bmiHeader.biBitCount := BCH.bcBitCount;
  43798. end
  43799. else Exit;
  43800. fNewPixelFormat := Bits2PixelFormat( fDIBHeader.bmiHeader.biBitCount
  43801. * fDIBHeader.bmiHeader.biPlanes );
  43802. if (fNewPixelFormat = pf15bit) and (fDIBHeader.bmiHeader.biCompression <> BI_RGB) then
  43803. begin
  43804. ASSERT( fDIBHeader.bmiHeader.biCompression = BI_BITFIELDS, 'Unsupported bitmap format' );
  43805. end;
  43806. fWidth := fDIBHeader.bmiHeader.biWidth;
  43807. ASSERT( fWidth > 0, 'Bitmap width must be > 0' );
  43808. fHeight := Abs(fDIBHeader.bmiHeader.biHeight);
  43809. ASSERT( fHeight > 0, 'Bitmap height must be > 0' );
  43810. fDIBSize := ScanLineSize * fHeight;
  43811. fDIBBits :=
  43812. Pointer( GlobalAlloc( GMEM_FIXED or GMEM_ZEROINIT, fDIBSize ) );
  43813. ASSERT( fDIBBits <> nil, 'No memory' );
  43814. ColorCount := 0;
  43815. if fDIBHeader.bmiHeader.biBitCount <= 8 then
  43816. begin
  43817. if fDIBHeader.bmiHeader.biClrUsed > 0 then
  43818. ColorCount := fDIBHeader.bmiHeader.biClrUsed * Sizeof( TRGBQuad )
  43819. else
  43820. ColorCount := (1 shl fDIBHeader.bmiHeader.biBitCount) * Sizeof( TRGBQuad )
  43821. end
  43822. else if (fNewPixelFormat in [ pf16bit ]) or
  43823. (fDIBHeader.bmiHeader.biCompression = BI_BITFIELDS) then
  43824. ColorCount := 12;
  43825. if Off > 0 then
  43826. begin
  43827. Off := Off - HdSz;
  43828. if (Off <> ColorCount) then
  43829. if not(fNewPixelFormat in [pf15bit,pf16bit])
  43830. or (Off = 0) //+++ to fix loading 15- and 16-bit bmps with mask omitted
  43831. then
  43832. ColorCount := Min( 1024, Off );
  43833. end;
  43834. if ColorCount <> 0 then
  43835. begin
  43836. if Off >= ColorCount then
  43837. Off := Off - ColorCount;
  43838. if RGBSize = 4 then
  43839. begin
  43840. if Strm.Read( fDIBheader.bmiColors[ 0 ], ColorCount )
  43841. <> DWORD( ColorCount ) then Exit;
  43842. end
  43843. else
  43844. begin
  43845. C := @ fDIBHeader.bmiColors[ 0 ];
  43846. while ColorCount > 0 do
  43847. begin
  43848. if Strm.Read( C^, RGBSize ) <> RGBSize then Exit;
  43849. Dec( ColorCount, RGBSize );
  43850. Inc( C );
  43851. end;
  43852. end;
  43853. end;
  43854. if Off > 0 then
  43855. Strm.Seek( Off, spCurrent );
  43856. if (Size = 0) or (Strm.Size <= 0) then
  43857. Size := fDIBSize
  43858. else
  43859. Size := Min( fDIBSize, Strm.Size - Strm.Position );
  43860. Size1 := Min( Size, fDIBSize );
  43861. if (Size1 < fDIBSize)
  43862. and (DWORD( fDIBSize - Size1 ) <= Strm.Position) then
  43863. begin
  43864. Strm.Seek( Size1 - fDIBSize, spCurrent );
  43865. Size1 := fDIBSize;
  43866. end;
  43867. //if BFHValid and (Integer( Strm.Size - BFH.bfOffBits - Pos ) >= Integer( Size )) then
  43868. //if Strm.Position - Pos <= BFH.bfOffbits then
  43869. // Strm.Position := Pos + BFH.bfOffbits;
  43870. if Size1 > fDIBSize then Size1 := fDIBSize;
  43871. // +++++++++++++++++++ to fix some "incorrect" bitmaps while loading
  43872. if Strm.Read( fDIBBits^, Size1 ) <> DWORD( Size1 ) then Exit;
  43873. if Size > Size1 then
  43874. Strm.Seek( Size - Size1, spCurrent );
  43875. Result := True;
  43876. end;
  43877. begin
  43878. Clear;
  43879. Pos := Strm.Position;
  43880. if not ReadBitmap then
  43881. begin
  43882. Strm.Seek( Pos, spBegin );
  43883. Clear;
  43884. end;
  43885. end;
  43886. {$ENDIF ASM_VERSION}
  43887. ////////////////// bitmap RLE-decoding and loading - by Vyacheslav A. Gavrik
  43888. //[procedure DecodeRLE4]
  43889. // by Vyacheslav A. Gavrik
  43890. procedure DecodeRLE4(Bmp:PBitmap;Data:Pointer; MaxSize: DWORD);
  43891. procedure OddMove(Src,Dst:PByte;Size:Integer);
  43892. begin
  43893. if Size=0 then Exit;
  43894. repeat
  43895. Dst^:=(Dst^ and $F0)or(Src^ shr 4);
  43896. Inc(Dst);
  43897. Dst^:=(Dst^ and $0F)or(Src^ shl 4);
  43898. Inc(Src);
  43899. Dec(Size);
  43900. until Size=0;
  43901. end;
  43902. procedure OddFill(Mem:PByte;Size,Value:Integer);
  43903. begin
  43904. Value:=(Value shr 4)or(Value shl 4);
  43905. Mem^:=(Mem^ and $F0)or(Value and $0F);
  43906. Inc(Mem);
  43907. if Size>1 then FillChar(Mem^,Size,Char( Value ))
  43908. else Mem^:=(Mem^ and $0F)or(Value and $F0);
  43909. end;
  43910. var
  43911. pb: PByte;
  43912. x,y,z,i: Integer;
  43913. begin
  43914. pb:=Data; x:=0; y:=0;
  43915. if Bmp.fScanLineSize = 0 then
  43916. Bmp.ScanLineSize;
  43917. while (y<Bmp.Height) and (DWORD(pb) - DWORD(Data) < MaxSize) do
  43918. begin
  43919. if pb^=0 then
  43920. begin
  43921. Inc(pb);
  43922. z:=pb^;
  43923. case pb^ of
  43924. 0: begin
  43925. Inc(y);
  43926. x:=0;
  43927. end;
  43928. 1: Break;
  43929. 2: begin
  43930. Inc(pb); Inc(x,pb^);
  43931. Inc(pb); Inc(y,pb^);
  43932. end;
  43933. else
  43934. begin
  43935. Inc(pb);
  43936. i:=(z+1)shr 1;
  43937. if i and 1 = 1 then Inc( i );
  43938. if x + z <= bmp.Width then
  43939. if x and 1 =1 then
  43940. OddMove(pb,@PByteArray(cardinal( Bmp.fDIBBits ) + cardinal(Bmp.fScanLineSize * y))[x shr 1],(z+1)shr 1)
  43941. else
  43942. Move(pb^,PByteArray(cardinal( Bmp.fDIBBits ) + cardinal(Bmp.fScanLineSize * y))[x shr 1],(z+1)shr 1);
  43943. Inc(pb,i-1);
  43944. Inc(x,z);
  43945. end;
  43946. end;
  43947. end else
  43948. begin
  43949. z:=pb^;
  43950. Inc(pb);
  43951. if x + z <= Bmp.Width then
  43952. if x and 1 = 1 then
  43953. OddFill(@PByteArray(cardinal( Bmp.fDIBBits ) + cardinal(Bmp.fScanLineSize * y))[x shr 1],(z+1) shr 1,pb^)
  43954. else
  43955. FillChar( PByteArray(cardinal( Bmp.fDIBBits ) + cardinal(Bmp.fScanLineSize * y))[x shr 1],
  43956. (z+1) shr 1, Char( pb^ ));
  43957. Inc(x,z);
  43958. end;
  43959. Inc(pb);
  43960. end;
  43961. end;
  43962. //[procedure DecodeRLE8]
  43963. // by Vyacheslav A. Gavrik
  43964. procedure DecodeRLE8(Bmp:PBitmap;Data:Pointer; MaxSize: DWORD);
  43965. var
  43966. pb: PByte;
  43967. x,y,z,i: Integer;
  43968. begin
  43969. pb:=Data; y:=0; x:=0;
  43970. if Bmp.fScanLineSize = 0 then
  43971. Bmp.ScanLineSize;
  43972. while (y<Bmp.Height) and (DWORD(pb) - DWORD(Data) < MaxSize) do
  43973. begin
  43974. if pb^=0 then
  43975. begin
  43976. Inc(pb);
  43977. case pb^ of
  43978. 0: begin
  43979. Inc(y);
  43980. x:=0;
  43981. end;
  43982. 1: Break;
  43983. 2: begin
  43984. Inc(pb); Inc(x,pb^);
  43985. Inc(pb); Inc(y,pb^);
  43986. end;
  43987. else
  43988. begin
  43989. i:=pb^;
  43990. z:=(i+1)and(not 1);
  43991. Inc(pb);
  43992. Move(pb^,PByteArray(cardinal( Bmp.fDIBBits ) + cardinal(Bmp.fScanLineSize * y))[x],i);
  43993. Inc(pb,z-1);
  43994. Inc(x,i);
  43995. end;
  43996. end;
  43997. end else
  43998. begin
  43999. i:=pb^; Inc(pb);
  44000. if x + i <= Bmp.Width then
  44001. FillChar( PByteArray(cardinal( Bmp.fDIBBits ) + cardinal(Bmp.fScanLineSize * y))[x],
  44002. i, Char( pb^ ));
  44003. Inc(x,i);
  44004. end;
  44005. Inc(pb);
  44006. end;
  44007. end;
  44008. //[function TBitmap.LoadFromFileEx]
  44009. function TBitmap.LoadFromFileEx(const Filename: KOLString): Boolean; // by Vyacheslav A. Gavrik
  44010. var Strm: PStream;
  44011. begin
  44012. Strm := NewReadFileStream( Filename );
  44013. Result := LoadFromStreamEx(Strm);
  44014. Strm.Free;
  44015. end;
  44016. //[function TBitmap.LoadFromStreamEx]
  44017. function TBitmap.LoadFromStreamEx(Strm: PStream): Boolean; // by Vyacheslav A. Gavrik
  44018. var Pos : DWORD;
  44019. i: Integer;
  44020. function ReadBitmap : Boolean;
  44021. var Off, Size, ColorCount: Integer;
  44022. BFH : TBitmapFileHeader;
  44023. BCH: TBITMAPCOREHEADER;
  44024. BFHValid: Boolean;
  44025. Buffer: Pointer;
  44026. L: DWORD;
  44027. ColorTriples: Boolean;
  44028. PColr: PDWORD;
  44029. FinalPos: DWORD;
  44030. ZI: DWORD;
  44031. begin
  44032. fHandleType := bmDIB;
  44033. Result := False;
  44034. BFHValid := FALSE;
  44035. if Strm.Read( BFH, Sizeof( BFH ) ) <> Sizeof( BFH ) then Exit;
  44036. Off := 0; Size := 0;
  44037. ColorTriples := FALSE;
  44038. if BFH.bfType <> $4D42 then
  44039. begin
  44040. Strm.Seek( Pos, spBegin );
  44041. BFH.bfOffBits := 0;
  44042. BFH.bfSize := 0;
  44043. end
  44044. else
  44045. begin
  44046. BFHValid := TRUE;
  44047. Off := BFH.bfOffBits;
  44048. Size := BFH.bfSize;
  44049. end;
  44050. fDIBHeader := AllocMem( 256*sizeof(TRGBQuad) + sizeof(TBitmapInfoHeader) );
  44051. if Strm.Read( fDIBHeader.bmiHeader.biSize, Sizeof( fDIBHeader.bmiHeader.biSize ) ) <>
  44052. Sizeof( fDIBHeader.bmiHeader.biSize ) then Exit;
  44053. if (fDIBHeader.bmiHeader.biSize <> Sizeof( TBITMAPCOREHEADER )) and
  44054. (fDIBHeader.bmiHeader.biSize <> Sizeof( TBitmapInfoHeader )) then Exit;
  44055. L := fDIBHeader.bmiHeader.biSize - Sizeof( fDIBHeader.bmiHeader.biSize );
  44056. if (fDIBHeader.bmiHeader.biSize = Sizeof( TBITMAPCOREHEADER )) then
  44057. begin
  44058. if Strm.Read( BCH.bcWidth, L ) <> L then Exit;
  44059. fDIBHeader.bmiHeader.biSize := Sizeof( TBitmapInfoHeader );
  44060. fDIBHeader.bmiHeader.biWidth := BCH.bcWidth;
  44061. fDIBHeader.bmiHeader.biHeight := BCH.bcHeight;
  44062. fDIBHeader.bmiHeader.biPlanes := BCH.bcPlanes;
  44063. fDIBHeader.bmiHeader.biBitCount := BCH.bcBitCount;
  44064. ColorTriples := TRUE;
  44065. end
  44066. else
  44067. begin
  44068. if Strm.Read( fDIBHeader.bmiHeader.biWidth, L) <> L then
  44069. Exit;
  44070. end;
  44071. fNewPixelFormat := Bits2PixelFormat( fDIBHeader.bmiHeader.biBitCount
  44072. * fDIBHeader.bmiHeader.biPlanes );
  44073. //if fNewPixelFormat = pf15bit then fNewPixelFormat := pf16bit;
  44074. fWidth := fDIBHeader.bmiHeader.biWidth;
  44075. ASSERT( fWidth > 0, 'Bitmap width must be > 0' );
  44076. fHeight := Abs(fDIBHeader.bmiHeader.biHeight);
  44077. ASSERT( fHeight > 0, 'Bitmap height must be > 0' );
  44078. fDIBSize := ScanLineSize * fHeight;
  44079. ZI := 0;
  44080. if (fDIBHeader.bmiHeader.biCompression = BI_RLE8) or
  44081. (fDIBHeader.bmiHeader.biCompression = BI_RLE4) then
  44082. ZI := GMEM_ZEROINIT;
  44083. fDIBBits := Pointer( GlobalAlloc( GMEM_FIXED or ZI, fDIBSize + 4 ) );
  44084. ASSERT( fDIBBits <> nil, 'No memory' );
  44085. ASSERT( (fDIBHeader.bmiHeader.biCompression and
  44086. (BI_RLE8 or BI_RLE4 or BI_RLE8 or BI_BITFIELDS) <> 0) or
  44087. (fDIBHeader.bmiHeader.biCompression = BI_RGB),
  44088. 'Unknown compression algorithm');
  44089. ColorCount := 0;
  44090. if fDIBHeader.bmiHeader.biBitCount <= 8 then
  44091. begin
  44092. if fDIBHeader.bmiHeader.biClrUsed > 0 then
  44093. ColorCount := fDIBHeader.bmiHeader.biClrUsed * Sizeof( TRGBQuad )
  44094. else
  44095. ColorCount := (1 shl fDIBHeader.bmiHeader.biBitCount) * Sizeof( TRGBQuad )
  44096. end
  44097. else if (fNewPixelFormat in [ pf15bit, pf16bit ]) or
  44098. (fDIBHeader.bmiHeader.biCompression = BI_BITFIELDS) then
  44099. begin
  44100. if (Strm.Size = 0) or (Strm.Size - Strm.Position - DWORD( Size ) >= 12) then
  44101. ColorCount := 12;
  44102. end;
  44103. if ColorTriples then
  44104. ColorCount := ColorCount div 4 * 3;
  44105. if Off > 0 then
  44106. begin
  44107. Off := Off - SizeOf( TBitmapFileHeader ) - Sizeof( TBitmapInfoHeader );
  44108. if (Off <> ColorCount) and (fNewPixelFormat <= pf8bit) then
  44109. if ColorTriples then
  44110. ColorCount := min( Off, 3 * 256 )
  44111. else
  44112. ColorCount := min( Off, 4 * 256 );
  44113. end;
  44114. if (fNewPixelFormat in [ pf15bit, pf16bit ]) then
  44115. if (fDIBHeader.bmiHeader.biCompression = BI_BITFIELDS) then
  44116. begin
  44117. PDWORD( DWORD( @ fDIBHeader.bmiColors[ 0 ] ) + 8 )^ := ( $00001F );
  44118. PDWORD( DWORD( @ fDIBHeader.bmiColors[ 0 ] ) + 4 )^ := ( $0007E0 );
  44119. TColor( fDIBHeader.bmiColors[ 0 ] ) := ( $00F800 );
  44120. end
  44121. else
  44122. begin
  44123. ColorCount := 0;
  44124. end;
  44125. if ColorCount <> 0 then
  44126. if ColorTriples then
  44127. begin
  44128. PColr := @ fDIBheader.bmiColors[ 0 ];
  44129. while ColorCount >= 3 do
  44130. begin
  44131. if strm.Read( PColr^, 3 ) <> 3 then Exit;
  44132. Inc( PColr );
  44133. Dec( ColorCount, 3 );
  44134. end;
  44135. end
  44136. else
  44137. begin
  44138. if (Integer( Strm.Size - Strm.Position ) > fDIBSize) or
  44139. (fDIBHeader.bmiHeader.biCompression = BI_RLE8) or
  44140. (fDIBHeader.bmiHeader.biCompression = BI_RLE4) then
  44141. begin
  44142. if Strm.Read( fDIBheader.bmiColors[ 0 ], ColorCount )
  44143. <> DWORD( ColorCount ) then Exit;
  44144. if Off - ColorCount > 0 then
  44145. Strm.Position := Integer( Strm.Position ) + Off - ColorCount;
  44146. end;
  44147. end;
  44148. if not BFHValid then
  44149. Size := fDIBSize
  44150. else
  44151. if (fDIBHeader.bmiHeader.biCompression = BI_RLE8) or
  44152. (fDIBHeader.bmiHeader.biCompression = BI_RLE4) then
  44153. begin
  44154. //if BFHValid then //-- already TRUE here
  44155. Size := BFH.bfSize - BFH.bfOffBits;
  44156. end
  44157. else
  44158. begin
  44159. if (Strm.Size = 0) or
  44160. (Integer( Strm.Size - BFH.bfOffBits - Pos ) > Integer(Size)) then
  44161. Size := fDIBSize
  44162. else
  44163. Size := Strm.Size - BFH.bfOffBits - DWORD( Pos );
  44164. if Size > fDIBSize then Size := fDIBSize
  44165. else if (Size < fDIBSize) and (fDIBheader.bmiHeader.biClrUsed <> 0) then
  44166. begin
  44167. BFHValid := FALSE;
  44168. Strm.Position := Strm.Position + fDIBheader.bmiHeader.biClrUsed * 4;
  44169. Size := Strm.Size - Strm.Position;
  44170. end;
  44171. end;
  44172. if (fDIBHeader.bmiHeader.biCompression = BI_RGB) or
  44173. (fDIBHeader.bmiHeader.biCompression = BI_BITFIELDS) then
  44174. begin
  44175. if BFHValid and
  44176. ( (Strm.Size > 0) and
  44177. (Integer( Strm.Size - BFH.bfOffBits - Pos) > Integer(Size))
  44178. or
  44179. (Strm.Size = 0) and
  44180. (Off > 0)
  44181. ) then
  44182. if Integer( Strm.Position - Pos ) <= Integer( BFH.bfOffbits ) then
  44183. Strm.Position := Pos + BFH.bfOffbits;
  44184. i := Strm.Read( fDIBBits^, Size );
  44185. if i <> Size then
  44186. begin
  44187. //Exit;
  44188. {$IFDEF FILL_BROKEN_BITMAP}
  44189. FillChar( Pointer( Integer( fDIBBits ) + i )^,
  44190. Size - i, #0 );
  44191. {$ENDIF FILL_BROKEN_BITMAP}
  44192. end;
  44193. end
  44194. else
  44195. begin
  44196. if (Integer( fDIBHeader.bmiHeader.biSizeImage ) > 0) and
  44197. (Integer( fDIBHeader.bmiHeader.biSizeImage ) < Size) then
  44198. Size := Integer( fDIBHeader.bmiHeader.biSizeImage ); // - ColorCount;
  44199. // it is possible that bitmap "compressed" with RLE has size
  44200. // greater then non-compressed one:
  44201. FinalPos := Strm.Position + DWORD( Size );
  44202. //Size := Size * 3;
  44203. L := Strm.Size - Strm.Position;
  44204. if L > DWORD( Size ) then
  44205. L := Size;
  44206. Buffer := AllocMem( Size * 3 );
  44207. if Strm.Read(Buffer^,L) <> DWORD( L ) then ; //Exit;
  44208. if fDIBHeader.bmiHeader.biCompression=BI_RLE8 then
  44209. DecodeRLE8(@Self,Buffer,Size * 3)
  44210. else
  44211. DecodeRLE4(@Self,Buffer,Size * 3);
  44212. Strm.Position := FinalPos;
  44213. fDIBHeader.bmiHeader.biCompression := BI_RGB;
  44214. FreeMem(Buffer);
  44215. end;
  44216. Result := True;
  44217. end;
  44218. begin
  44219. Clear;
  44220. Pos := Strm.Position;
  44221. result := ReadBitmap;
  44222. if not result then
  44223. begin
  44224. Strm.Seek( Pos, spBegin );
  44225. Clear;
  44226. end;
  44227. end;
  44228. ///////////////////////////
  44229. //[function TBitmap.ReleaseHandle]
  44230. {$IFDEF ASM_VERSION}
  44231. {$ELSE ASM_VERSION} //Pascal
  44232. function TBitmap.ReleaseHandle: HBitmap;
  44233. var OldBits: Pointer;
  44234. begin
  44235. HandleType := bmDIB;
  44236. Result := GetHandle;
  44237. if Result = 0 then Exit; // only when bitmap is empty
  44238. if fDIBAutoFree then
  44239. begin
  44240. OldBits := fDIBBits;
  44241. fDIBBits := Pointer( GlobalAlloc( GMEM_FIXED {or GMEM_ZEROINIT}, fDIBSize ) );
  44242. Move( OldBits^, fDIBBits^, fDIBSize );
  44243. fDIBAutoFree := FALSE;
  44244. end;
  44245. fHandle := 0;
  44246. end;
  44247. {$ENDIF ASM_VERSION}
  44248. //[procedure TBitmap.SaveToFile]
  44249. {$IFDEF ASM_VERSION}
  44250. {$ELSE ASM_VERSION} //Pascal
  44251. procedure TBitmap.SaveToFile(const Filename: KOLString);
  44252. var Strm: PStream;
  44253. begin
  44254. if Empty then Exit;
  44255. Strm := NewWritefileStream( Filename );
  44256. SaveToStream( Strm );
  44257. Strm.Free;
  44258. end;
  44259. {$ENDIF ASM_VERSION}
  44260. //[procedure TBitmap.SaveToStream]
  44261. {$IFDEF ASM_VERSION}
  44262. {$ELSE ASM_VERSION} //Pascal
  44263. procedure TBitmap.SaveToStream(Strm: PStream);
  44264. var BFH : TBitmapFileHeader;
  44265. Pos : Integer;
  44266. function WriteBitmap : Boolean;
  44267. var ColorsSize, BitsSize, Size : Integer;
  44268. begin
  44269. Result := False;
  44270. if Empty then Exit;
  44271. HandleType := bmDIB; // convert to DIB if DDB
  44272. FillChar( BFH, Sizeof( BFH ), 0 );
  44273. ColorsSize := 0;
  44274. with fDIBHeader.bmiHeader do
  44275. if biBitCount <= 8 then
  44276. ColorsSize := (1 shl biBitCount) * Sizeof( TRGBQuad );
  44277. BFH.bfOffBits := Sizeof( BFH ) + Sizeof( TBitmapInfoHeader ) + ColorsSize;
  44278. BitsSize := fDIBSize; //ScanLineSize * fHeight;
  44279. BFH.bfSize := BFH.bfOffBits + DWord( BitsSize );
  44280. BFH.bfType := $4D42; // 'BM';
  44281. if fDIBHeader.bmiHeader.biCompression <> 0 then
  44282. begin
  44283. ColorsSize := 12 + 16*sizeof(TRGBQuad);
  44284. Inc( BFH.bfOffBits, ColorsSize );
  44285. end;
  44286. if Strm.Write( BFH, Sizeof( BFH ) ) <> Sizeof( BFH ) then Exit;
  44287. Size := Sizeof( TBitmapInfoHeader ) + ColorsSize;
  44288. if Strm.Write( fDIBHeader^, Size ) <> DWORD(Size) then Exit;
  44289. if Strm.Write( fDIBBits^, BitsSize ) <> DWord( BitsSize ) then Exit;
  44290. Result := True;
  44291. end;
  44292. begin
  44293. Pos := Strm.Position;
  44294. if not WriteBitmap then
  44295. Strm.Seek( Pos, spBegin );
  44296. end;
  44297. {$ENDIF ASM_VERSION}
  44298. //[procedure TBitmap.SetHandle]
  44299. {$IFDEF ASM_VERSION}
  44300. {$ELSE ASM_VERSION} //Pascal
  44301. procedure TBitmap.SetHandle(const Value: HBitmap);
  44302. var B: tagBitmap;
  44303. Dib: TDIBSection;
  44304. begin
  44305. Clear;
  44306. if Value = 0 then Exit;
  44307. if (WinVer >= wvNT) and
  44308. (GetObject( Value, Sizeof( Dib ), @ Dib ) = Sizeof( Dib )) then
  44309. begin
  44310. fHandle := Value;
  44311. fHandleType := bmDIB;
  44312. fDIBHeader := PrepareBitmapHeader( Dib.dsBm.bmWidth, Dib.dsBm.bmHeight,
  44313. Dib.dsBm.bmBitsPixel );
  44314. Move( Dib.dsBitfields, fDIBHeader.bmiColors, 3 * 4 );
  44315. fWidth := Dib.dsBm.bmWidth;
  44316. fHeight := Dib.dsBm.bmHeight;
  44317. fDIBBits := Dib.dsBm.bmBits;
  44318. fDIBSize := Dib.dsBmih.biSizeImage;
  44319. fDIBAutoFree := true;
  44320. {$ifdef wince}
  44321. if fDIBBits = nil then
  44322. HandleType:=bmDDB;
  44323. {$endif wince}
  44324. end
  44325. else
  44326. begin
  44327. if GetObject( Value, Sizeof( B ), @B ) = 0 then Exit;
  44328. fHandle := Value;
  44329. fWidth := B.bmWidth;
  44330. fHeight := B.bmHeight;
  44331. fHandleType := bmDDB;
  44332. end;
  44333. end;
  44334. {$ENDIF ASM_VERSION}
  44335. //[procedure TBitmap.SetWidth]
  44336. procedure TBitmap.SetWidth(const Value: Integer);
  44337. begin
  44338. if fWidth = Value then Exit;
  44339. fWidth := Value;
  44340. FormatChanged;
  44341. end;
  44342. //[procedure TBitmap.SetHeight]
  44343. {$IFDEF ASM_VERSION}
  44344. {$ELSE ASM_VERSION} //Pascal
  44345. procedure TBitmap.SetHeight(const Value: Integer);
  44346. begin
  44347. if fHeight = Value then Exit;
  44348. HandleType := bmDDB;
  44349. // Not too good, but provides correct changing of height
  44350. // preserving previous image
  44351. fHeight := Value;
  44352. FormatChanged;
  44353. end;
  44354. {$ENDIF ASM_VERSION}
  44355. //[procedure TBitmap.SetPixelFormat]
  44356. {$IFDEF ASM_VERSION}
  44357. {$ELSE ASM_VERSION} //Pascal
  44358. procedure TBitmap.SetPixelFormat(Value: TPixelFormat);
  44359. begin
  44360. if PixelFormat = Value then Exit;
  44361. if Empty then Exit;
  44362. if Value = pfDevice then
  44363. HandleType := bmDDB
  44364. else
  44365. begin
  44366. fNewPixelFormat := Value;
  44367. fHandleType := bmDIB;
  44368. FormatChanged;
  44369. end;
  44370. end;
  44371. {$ENDIF ASM_VERSION}
  44372. //[FUNCTION CalcScanLineSize]
  44373. {$IFDEF ASM_VERSION}
  44374. {$ELSE ASM_VERSION} //Pascal
  44375. function CalcScanLineSize( Header: PBitmapInfoHeader ): Integer;
  44376. begin
  44377. Result := ((Header.biBitCount * Header.biWidth + 31) shr 3) and $FFFFFFFC;
  44378. end;
  44379. {$ENDIF ASM_VERSION}
  44380. //[END CalcScanLineSize]
  44381. //[PROCEDURE FillBmpWithBkColor]
  44382. {$IFDEF ASM_VERSION}
  44383. {$ELSE ASM_VERSION} //Pascal
  44384. procedure FillBmpWithBkColor( Bmp: PBitmap; DC2: HDC; oldWidth, oldHeight: Integer );
  44385. var oldBmp: HBitmap;
  44386. R: TRect;
  44387. Br: HBrush;
  44388. begin
  44389. with Bmp{-}^{+} do
  44390. if Color2RGB( fBkColor ) <> 0 then
  44391. if (oldWidth < fWidth) or (oldHeight < fHeight) then
  44392. if GetHandle <> 0 then
  44393. begin
  44394. oldBmp := SelectObject( DC2, fHandle );
  44395. ASSERT( oldBmp <> 0, 'Can not select bitmap to DC' );
  44396. Br := CreateSolidBrush( Color2RGB( fBkColor ) );
  44397. R := MakeRect( oldWidth, oldHeight, fWidth, fHeight );
  44398. if oldWidth = fWidth then
  44399. R.Left := 0;
  44400. if oldHeight = fHeight then
  44401. R.Top := 0;
  44402. Windows.FillRect( DC2, R, Br );
  44403. DeleteObject( Br );
  44404. SelectObject( DC2, oldBmp );
  44405. end;
  44406. end;
  44407. {$ENDIF ASM_VERSION}
  44408. //[END FillBmpWithBkColor]
  44409. const BitCounts: array[ TPixelFormat ] of Byte = ( 0, 1, 4, 8, 16, 16, 24, 32, 0 );
  44410. //[procedure TBitmap.FormatChanged]
  44411. {$IFDEF ASM_VERSION}
  44412. {$ELSE ASM_VERSION} //Pascal
  44413. procedure TBitmap.FormatChanged;
  44414. // This method is used whenever Width, Height, PixelFormat or HandleType
  44415. // properties are changed.
  44416. // Old image will be drawn here to a new one (excluding cases when
  44417. // old width or height was 0, and / or new width or height is 0).
  44418. // To avoid inserting this code into executable, try not to change
  44419. // properties Width / Height of bitmat after it is created using
  44420. // NewBitmap( W, H ) function or after it is loaded from file, stream
  44421. // or resource.
  44422. var B: tagBitmap;
  44423. oldBmp, NewHandle: HBitmap;
  44424. DC0, DC2: HDC;
  44425. oldHeight, oldWidth: Integer;
  44426. Br: HBrush;
  44427. NewHeader: PBitmapInfo;
  44428. NewBits: Pointer;
  44429. sizeBits, bitsPixel: Integer;
  44430. NewDIBAutoFree: Boolean;
  44431. {$ifndef wince}
  44432. N: Integer;
  44433. Hndl: THandle;
  44434. {$endif wince}
  44435. begin
  44436. if Empty then Exit;
  44437. {$ifndef wince}
  44438. NewDIBAutoFree := FALSE;
  44439. {$endif wince}
  44440. fDetachCanvas( @Self );
  44441. fScanLineSize := 0;
  44442. fGetDIBPixels := nil;
  44443. fSetDIBPixels := nil;
  44444. oldWidth := fWidth;
  44445. oldHeight := fHeight;
  44446. if fDIBBits <> nil then
  44447. begin
  44448. oldWidth := fDIBHeader.bmiHeader.biWidth;
  44449. oldHeight := Abs(fDIBHeader.bmiHeader.biHeight);
  44450. end
  44451. else
  44452. if fHandle <> 0 then
  44453. begin
  44454. if GetObject( fHandle, Sizeof( B ), @ B ) <> 0 then
  44455. begin
  44456. oldWidth := B.bmWidth;
  44457. oldHeight := B.bmHeight;
  44458. end;
  44459. end;
  44460. DC2 := CreateCompatibleDC( 0 );
  44461. if fHandleType = bmDDB then
  44462. begin
  44463. // New HandleType is bmDDB: old bitmap can be copied using Draw method
  44464. DC0 := GetDC( 0 );
  44465. NewHandle := CreateCompatibleBitmap( DC0, fWidth, fHeight );
  44466. ASSERT( NewHandle <> 0, 'Can not create DDB' );
  44467. ReleaseDC( 0, DC0 );
  44468. oldBmp := SelectObject( DC2, NewHandle );
  44469. ASSERT( oldBmp <> 0, 'Can not select bitmap to DC' );
  44470. Br := CreateSolidBrush( Color2RGB( fBkColor ) );
  44471. FillRect( DC2, MakeRect( 0, 0, fWidth, fHeight ), Br );
  44472. DeleteObject( Br );
  44473. {$ifdef win32}
  44474. if fDIBBits <> nil then
  44475. begin
  44476. SelectObject( DC2, oldBmp );
  44477. SetDIBits( DC2, NewHandle, 0, fHeight, fDIBBits, fDIBHeader^, DIB_RGB_COLORS );
  44478. end
  44479. else
  44480. {$endif win32}
  44481. begin
  44482. Draw( DC2, 0, 0 );
  44483. SelectObject( DC2, oldBmp );
  44484. end;
  44485. ClearData; // Image is cleared but fWidth and fHeight are preserved
  44486. fHandle := NewHandle;
  44487. end
  44488. else
  44489. begin
  44490. // New format is DIB. GetDIBits applied to transform old data to new one.
  44491. if fNewPixelFormat = pfDevice then
  44492. bitsPixel := GetDeviceCaps( DC2, Windows.BITSPIXEL )*GetDeviceCaps( DC2, PLANES )
  44493. else
  44494. bitsPixel := BitCounts[ fNewPixelFormat ];
  44495. if bitsPixel = 0 then
  44496. bitsPixel := BitCounts[DefaultPixelFormat];
  44497. NewHandle := 0;
  44498. NewHeader := PrepareBitmapHeader( fWidth, fHeight, bitsPixel );
  44499. if bitsPixel = 16 then
  44500. PreparePF16bit( NewHeader );
  44501. sizeBits := CalcScanLineSize( @NewHeader.bmiHeader ) * fHeight;
  44502. {$ifndef wince}
  44503. NewBits := Pointer( GlobalAlloc( GMEM_FIXED, sizeBits ) );
  44504. ASSERT( NewBits <> nil, 'No memory' );
  44505. Hndl := GetHandle;
  44506. if Hndl = 0 then Exit;
  44507. N :=
  44508. GetDIBits( DC2, Hndl, 0, Min( fHeight, oldHeight ),
  44509. NewBits, NewHeader^, DIB_RGB_COLORS );
  44510. if N <> Min( fHeight, oldHeight ) then
  44511. begin
  44512. GlobalFree( DWORD( NewBits ) );
  44513. {$endif wince}
  44514. NewBits := nil;
  44515. NewHandle := CreateDIBSection( DC2, NewHeader^, DIB_RGB_COLORS, NewBits, 0, 0 );
  44516. NewDIBAutoFree := TRUE;
  44517. ASSERT( NewHandle <> 0, 'Can not create DIB secion for pf16bit bitmap' );
  44518. oldBmp := SelectObject( DC2, NewHandle );
  44519. ASSERT( oldBmp <> 0, 'Can not select pf16bit to DC' );
  44520. Draw( DC2, 0, 0 );
  44521. SelectObject( DC2, oldBmp );
  44522. {$ifndef wince}
  44523. end;
  44524. {$endif wince}
  44525. ClearData;
  44526. fDIBSize := sizeBits;
  44527. fDIBBits := NewBits;
  44528. fDIBHeader := NewHeader;
  44529. fHandle := NewHandle;
  44530. fDIBAutoFree := NewDIBAutoFree;
  44531. end;
  44532. if Assigned( fFillWithBkColor ) then
  44533. fFillWithBkColor( @Self, DC2, oldWidth, oldHeight );
  44534. DeleteDC( DC2 );
  44535. end;
  44536. {$ENDIF ASM_VERSION}
  44537. //[function TBitmap.GetScanLine]
  44538. {$IFDEF ASM_VERSION}
  44539. {$ELSE ASM_VERSION} //Pascal
  44540. function TBitmap.GetScanLine(Y: Integer): Pointer;
  44541. begin
  44542. ASSERT( (Y >= 0) {and (Y < fHeight)}, 'ScanLine index out of bounds' );
  44543. ASSERT( fDIBBits <> nil, 'No bits available' );
  44544. Result := nil;
  44545. if fDIBHeader = nil then Exit;
  44546. if fDIBHeader.bmiHeader.biHeight > 0 then
  44547. Y := fHeight - 1 - Y;
  44548. if fScanLineSize = 0 then
  44549. ScanLineSize;
  44550. Result := Pointer( cardinal( fDIBBits ) + cardinal(fScanLineSize * Y) );
  44551. end;
  44552. {$ENDIF ASM_VERSION}
  44553. //[function TBitmap.GetScanLineSize]
  44554. {$IFDEF ASM_VERSION}
  44555. {$ELSE ASM_VERSION} //Pascal
  44556. function TBitmap.GetScanLineSize: Integer;
  44557. begin
  44558. Result := 0;
  44559. if fDIBHeader = nil then Exit;
  44560. FScanLineSize := CalcScanLineSize( @fDIBHeader.bmiHeader );
  44561. Result := FScanLineSize;
  44562. end;
  44563. {$ENDIF ASM_VERSION}
  44564. //[procedure TBitmap.CanvasChanged]
  44565. {$IFDEF ASM_VERSION}
  44566. {$ELSE ASM_VERSION} //Pascal
  44567. procedure TBitmap.CanvasChanged( Sender : PObj );
  44568. begin
  44569. fBkColor := PCanvas( Sender ).Brush.Color;
  44570. ClearTransImage;
  44571. end;
  44572. {$ENDIF ASM_VERSION}
  44573. //[procedure TBitmap.Dormant]
  44574. {$IFDEF ASM_VERSION}
  44575. {$ELSE ASM_VERSION} //Pascal
  44576. procedure TBitmap.Dormant;
  44577. begin
  44578. RemoveCanvas;
  44579. if fHandle <> 0 then
  44580. DeleteObject( ReleaseHandle );
  44581. end;
  44582. {$ENDIF ASM_VERSION}
  44583. //[procedure TBitmap.SetBkColor]
  44584. {$IFDEF ASM_VERSION}
  44585. {$ELSE ASM_VERSION} //Pascal
  44586. procedure TBitmap.SetBkColor(const Value: TColor);
  44587. begin
  44588. if fBkColor = Value then Exit;
  44589. fBkColor := Value;
  44590. fFillWithBkColor := FillBmpWithBkColor;
  44591. if Assigned( fApplyBkColor2Canvas ) then
  44592. fApplyBkColor2Canvas( @Self );
  44593. end;
  44594. {$ENDIF ASM_VERSION}
  44595. //[function TBitmap.Assign]
  44596. {$IFDEF ASM_VERSION}
  44597. {$ELSE ASM_VERSION} //Pascal
  44598. function TBitmap.Assign(SrcBmp: PBitmap): Boolean;
  44599. {$ifdef wince}
  44600. var
  44601. DC: HDC;
  44602. OldBmp: HBITMAP;
  44603. {$endif wince}
  44604. begin
  44605. Clear;
  44606. Result := False;
  44607. if SrcBmp = nil then Exit;
  44608. if SrcBmp.Empty then Exit;
  44609. fWidth := SrcBmp.fWidth;
  44610. fHeight := SrcBmp.fHeight;
  44611. fHandleType := SrcBmp.fHandleType;
  44612. if SrcBmp.fHandleType = bmDDB then
  44613. begin
  44614. {$ifdef wince}
  44615. DC := GetDC( 0 );
  44616. fHandle := CreateCompatibleBitmap( DC, fWidth, fHeight );
  44617. ReleaseDC( 0, DC );
  44618. DC:=CreateCompatibleDC(0);
  44619. OldBmp:=SelectObject(DC, fHandle);
  44620. SrcBmp.Draw(DC, 0, 0);
  44621. SelectObject(DC, OldBmp);
  44622. DeleteDC(DC);
  44623. {$else}
  44624. fHandle := CopyImage( SrcBmp.fHandle, IMAGE_BITMAP, 0, 0, 0 {LR_COPYRETURNORG} );
  44625. ASSERT( fHandle <> 0, 'Can not copy bitmap image' );
  44626. {$endif wince}
  44627. Result := fHandle <> 0;
  44628. if not Result then Clear;
  44629. end
  44630. else
  44631. begin
  44632. GetMem( fDIBHeader, Sizeof(TBitmapInfoHeader) + 256*sizeof(TRGBQuad) );
  44633. ASSERT( fDIBHeader <> nil, 'No memory' );
  44634. Move( SrcBmp.fDIBHeader^, fDIBHeader^, Sizeof(TBitmapInfoHeader) + 256*sizeof(TRGBQuad) );
  44635. fDIBSize := SrcBmp.fDIBSize;
  44636. fDIBBits := Pointer( GlobalAlloc( GMEM_FIXED {or GMEM_ZEROINIT}, fDIBSize ) );
  44637. ASSERT( fDIBBits <> nil, 'No memory' );
  44638. Move( SrcBmp.fDIBBits^, fDIBBits^, fDIBSize );
  44639. Result := True;
  44640. end;
  44641. end;
  44642. {$ENDIF ASM_VERSION}
  44643. //[procedure TBitmap.RemoveCanvas]
  44644. {$IFDEF ASM_VERSION}
  44645. {$ELSE ASM_VERSION} //Pascal
  44646. procedure TBitmap.RemoveCanvas;
  44647. begin
  44648. fDetachCanvas( @Self );
  44649. fCanvas.Free;
  44650. fCanvas := nil;
  44651. end;
  44652. {$ENDIF ASM_VERSION}
  44653. //[function TBitmap.DIBPalNearestEntry]
  44654. {$IFDEF ASM_VERSION}
  44655. {$ELSE ASM_VERSION} //Pascal
  44656. function TBitmap.DIBPalNearestEntry(Color: TColor): Integer;
  44657. var I, Diff, D: Integer;
  44658. C : Integer;
  44659. begin
  44660. Color := TColor( Color2RGBQuad( Color ) );
  44661. Result := 0;
  44662. Diff := MaxInt;
  44663. for I := 0 to DIBPalEntryCount - 1 do
  44664. begin
  44665. C := Color xor PInteger( cardinal( @fDIBHeader.bmiColors[ 0 ] )
  44666. + cardinal(I * Sizeof( TRGBQuad )) )^;
  44667. D := TRGBQuad( C ).rgbBlue + TRGBQuad( C ).rgbGreen + TRGBQuad( C ).rgbRed;
  44668. if D < Diff then
  44669. begin
  44670. Diff := D;
  44671. Result := I;
  44672. end;
  44673. end;
  44674. end;
  44675. {$ENDIF ASM_VERSION}
  44676. //[function TBitmap.GetDIBPalEntries]
  44677. {$IFDEF ASM_VERSION}
  44678. {$ELSE ASM_VERSION} //Pascal
  44679. function TBitmap.GetDIBPalEntries(Idx: Integer): TColor;
  44680. begin
  44681. Result := TColor(-1);
  44682. if fDIBBits = nil then Exit;
  44683. ASSERT( PixelFormat in [pf1bit..pf8bit], 'Format has no DIB palette entries available' );
  44684. ASSERT( (Idx >= 0) and (Idx < (1 shl fDIBHeader.bmiHeader.biBitCount)),
  44685. 'DIB palette index out of bounds' );
  44686. Result := PDWORD( cardinal( @fDIBHeader.bmiColors[ 0 ] )
  44687. + cardinal(Idx * Sizeof( TRGBQuad ) ))^;
  44688. end;
  44689. {$ENDIF ASM_VERSION}
  44690. //[function TBitmap.GetDIBPalEntryCount]
  44691. {$IFDEF ASM_VERSION}
  44692. {$ELSE ASM_VERSION} //Pascal
  44693. function TBitmap.GetDIBPalEntryCount: Integer;
  44694. begin
  44695. Result := 0;
  44696. if Empty then Exit;
  44697. case PixelFormat of
  44698. pf1bit: Result := 2;
  44699. pf4bit: Result := 16;
  44700. pf8bit: Result := 256;
  44701. else;
  44702. end;
  44703. end;
  44704. {$ENDIF ASM_VERSION}
  44705. //[procedure TBitmap.SetDIBPalEntries]
  44706. procedure TBitmap.SetDIBPalEntries(Idx: Integer; const Value: TColor);
  44707. begin
  44708. if fDIBBits = nil then Exit;
  44709. Dormant;
  44710. PDWORD( cardinal( @fDIBHeader.bmiColors[ 0 ] )
  44711. + cardinal(Idx * Sizeof( TRGBQuad )) )^ := Color2RGB( Value );
  44712. end;
  44713. //[procedure TBitmap.SetHandleType]
  44714. procedure TBitmap.SetHandleType(const Value: TBitmapHandleType);
  44715. begin
  44716. if fHandleType = Value then Exit;
  44717. fHandleType := Value;
  44718. FormatChanged;
  44719. end;
  44720. //[function TBitmap.GetPixelFormat]
  44721. function TBitmap.GetPixelFormat: TPixelFormat;
  44722. begin
  44723. if (HandleType = bmDDB) or (fDIBBits = nil) then
  44724. Result := pfDevice
  44725. else
  44726. begin
  44727. Result := Bits2PixelFormat( fDIBHeader.bmiHeader.biBitCount );
  44728. if fDIBHeader.bmiHeader.biCompression <> 0 then
  44729. begin
  44730. Assert( fDIBHeader.bmiHeader.biCompression = BI_BITFIELDS, 'Unsupported bitmap format' );
  44731. if (TColor( fDIBHeader.bmiColors[ 0 ] ) = $F800) and
  44732. (PInteger( DWORD(@ fDIBHeader.bmiColors[ 0 ])+4 )^ = $7E0) and
  44733. (PInteger( DWORD(@ fDIBHeader.bmiColors[ 0 ])+8 )^ = $1F) then
  44734. Result := pf16bit
  44735. else
  44736. if (TColor( fDIBHeader.bmiColors[ 0 ] ) = $7C00) and
  44737. (PInteger( DWORD(@ fDIBHeader.bmiColors[ 0 ])+4 )^ = $3E0) and
  44738. (PInteger( DWORD(@ fDIBHeader.bmiColors[ 0 ])+8 )^ = $1F) then
  44739. Result := pf15bit
  44740. else
  44741. Result := pfCustom;
  44742. end;
  44743. end;
  44744. end;
  44745. //[procedure TBitmap.ClearTransImage]
  44746. {$IFDEF ASM_VERSION}
  44747. {$ELSE ASM_VERSION} //Pascal
  44748. procedure TBitmap.ClearTransImage;
  44749. begin
  44750. fTransColor := clNone;
  44751. fTransMaskBmp.Free;
  44752. fTransMaskBmp := nil;
  44753. end;
  44754. {$ENDIF ASM_VERSION}
  44755. //[procedure TBitmap.Convert2Mask]
  44756. {$IFDEF ASM_VERSION}
  44757. {$ELSE ASM_VERSION} //Pascal
  44758. {$IFDEF USE_OLDCONVERT2MASK}
  44759. procedure TBitmap.Convert2Mask(TranspColor: TColor);
  44760. var MonoHandle: HBitmap;
  44761. SaveMono, SaveFrom: THandle;
  44762. MonoDC, {DC0,} DCfrom: HDC;
  44763. SaveBkColor: TColorRef;
  44764. begin
  44765. if GetHandle = 0 then Exit;
  44766. fDetachCanvas( @Self );
  44767. ///DC0 := GetDC( 0 );
  44768. MonoHandle := CreateBitmap( fWidth, fHeight, 1, 1, nil );
  44769. ASSERT( MonoHandle <> 0, 'Can not create monochrome bitmap' );
  44770. MonoDC := CreateCompatibleDC( 0 );
  44771. SaveMono := SelectObject( MonoDC, MonoHandle );
  44772. ASSERT( SaveMono <> 0, 'Can not select bitmap to DC' );
  44773. DCfrom := CreateCompatibleDC( 0 );
  44774. SaveFrom := SelectObject( DCfrom, fHandle );
  44775. ASSERT( SaveFrom <> 0, 'Can not select source bitmap to DC' );
  44776. TranspColor := Color2RGB( TranspColor );
  44777. SaveBkColor := Windows.SetBkColor( DCfrom, TranspColor );
  44778. BitBlt( MonoDC, 0, 0, fWidth, fHeight, DCfrom, 0, 0, SRCCOPY );
  44779. {$IFDEF CHK_BITBLT} Chk_BitBlt; {$ENDIF}
  44780. Windows.SetBkColor( DCfrom, SaveBkColor );
  44781. SelectObject( DCfrom, SaveFrom );
  44782. DeleteDC( DCfrom );
  44783. SelectObject( MonoDC, SaveMono );
  44784. DeleteDC( MonoDC );
  44785. ///ReleaseDC( 0, DC0 );
  44786. ClearData;
  44787. fHandle := MonoHandle;
  44788. fHandleType := bmDDB;
  44789. end;
  44790. {$ELSE NOT USE_OLDCONVERT2MASK} //Pascal
  44791. procedure TBitmap.Convert2Mask(TranspColor: TColor);
  44792. var Y, X, i: Integer;
  44793. Src, Dst: PByte;
  44794. W: Word;
  44795. TmpMsk: PBitmap;
  44796. B, C: Byte;
  44797. TranspColor32: TColor;
  44798. begin
  44799. HandleType := bmDIB;
  44800. if PixelFormat < pf4bit then
  44801. PixelFormat := pf4bit;
  44802. if PixelFormat > pf32bit then
  44803. PixelFormat := pf32bit;
  44804. TranspColor := Color2RGB( TranspColor ) and $FFFFFF;
  44805. TranspColor32 := TColor( Color2RGBQuad( TranspColor ) );
  44806. TmpMsk := NewDIBBitmap( fWidth, fHeight, pf1bit );
  44807. TmpMsk.DIBPalEntries[ 1 ] := $FFFFFF;
  44808. for Y := 0 to fHeight-1 do
  44809. begin
  44810. Src := ScanLine[ Y ];
  44811. Dst := TmpMsk.ScanLine[ Y ];
  44812. B := 0; C := 8;
  44813. CASE PixelFormat OF
  44814. pf4bit:
  44815. begin
  44816. W := 16;
  44817. for i := 0 to 15 do
  44818. if DIBPalEntries[ i ] = TranspColor32 then
  44819. begin
  44820. W := i; break;
  44821. end;
  44822. for X := 0 to (fWidth div 2)-1 do
  44823. begin
  44824. B := B shl 1;
  44825. if Src^ shr 4 = W then inc( B );
  44826. B := B shl 1;
  44827. if Src^ and $0F = W then inc( B );
  44828. Inc( Src );
  44829. Dec( C, 2 );
  44830. if C = 0 then
  44831. begin
  44832. Dst^ := B;
  44833. Inc( Dst );
  44834. C := 8;
  44835. end;
  44836. end;
  44837. end;
  44838. pf8bit:
  44839. begin
  44840. W := 256;
  44841. for i := 0 to 255 do
  44842. if DIBPalEntries[ i ] = TranspColor32 then
  44843. begin
  44844. W := i; break;
  44845. end;
  44846. for X := 0 to fWidth-1 do
  44847. begin
  44848. B := B shl 1;
  44849. if Src^ = W then inc( B );
  44850. Inc( Src );
  44851. Dec( C );
  44852. if C = 0 then
  44853. begin
  44854. Dst^ := B;
  44855. Inc( Dst );
  44856. C := 8;
  44857. end;
  44858. end;
  44859. end;
  44860. pf15bit:
  44861. begin
  44862. W := Color2Color15( TranspColor );
  44863. for X := 0 to fWidth-1 do
  44864. begin
  44865. B := B shl 1;
  44866. if PWord( Src )^ = W then inc( B );
  44867. Inc( Src, 2 );
  44868. Dec( C );
  44869. if C = 0 then
  44870. begin
  44871. Dst^ := B;
  44872. Inc( Dst );
  44873. C := 8;
  44874. end;
  44875. end;
  44876. end;
  44877. pf16bit:
  44878. begin
  44879. W := Color2Color16( TranspColor );
  44880. for X := 0 to fWidth-1 do
  44881. begin
  44882. B := B shl 1;
  44883. if PWord( Src )^ = W then inc( B );
  44884. Inc( Src, 2 );
  44885. Dec( C );
  44886. if C = 0 then
  44887. begin
  44888. Dst^ := B;
  44889. Inc( Dst );
  44890. C := 8;
  44891. end;
  44892. end;
  44893. end;
  44894. pf24bit:
  44895. begin
  44896. for X := 0 to fWidth-1 do
  44897. begin
  44898. B := B shl 1;
  44899. if PInteger( Src )^ and $FFFFFF = TranspColor32 then inc( B );
  44900. Inc( Src, 3 );
  44901. Dec( C );
  44902. if C = 0 then
  44903. begin
  44904. Dst^ := B;
  44905. Inc( Dst );
  44906. C := 8;
  44907. end;
  44908. end;
  44909. end;
  44910. pf32bit:
  44911. begin
  44912. for X := 0 to fWidth-1 do
  44913. begin
  44914. B := B shl 1;
  44915. if PInteger( Src )^ and $FFFFFF = TranspColor32 then inc( B );
  44916. Inc( Src, 4 );
  44917. Dec( C );
  44918. if C = 0 then
  44919. begin
  44920. Dst^ := B;
  44921. Inc( Dst );
  44922. C := 8;
  44923. end;
  44924. end;
  44925. end;
  44926. END;
  44927. if (C > 0) and (C < 8) then
  44928. begin
  44929. while C > 0 do
  44930. begin
  44931. B := B shl 1;
  44932. dec( C );
  44933. end;
  44934. Dst^ := B;
  44935. end;
  44936. end;
  44937. Assign( TmpMsk );
  44938. TmpMsk.Free;
  44939. end;
  44940. {$ENDIF USE_OLDCONVERT2MASK} //Pascal
  44941. {$ENDIF ASM_VERSION}
  44942. //[procedure TBitmap.Invert]
  44943. procedure TBitmap.Invert;
  44944. var R: TRect;
  44945. begin
  44946. //BitBlt( Canvas.Handle, 0, 0, Width, Height, Canvas.Handle, 0, 0, DSTINVERT )
  44947. R := BoundsRect;
  44948. InvertRect(Canvas.Handle, R);
  44949. end;
  44950. //[procedure TBitmap.DIBDrawRect]
  44951. procedure TBitmap.DIBDrawRect( DC: HDC; X, Y: Integer; const R: TRect );
  44952. begin
  44953. if fDIBBits = nil then Exit;
  44954. StretchDIBits( DC, X, Y, R.Right - R.Left, R.Bottom - R.Top,
  44955. R.Left, fHeight - R.Bottom, R.Right - R.Left, R.Bottom - R.Top,
  44956. fDIBBits, fDIBHeader^, DIB_RGB_COLORS, SRCCOPY );
  44957. end;
  44958. //[PROCEDURE _RotateBitmapMono]
  44959. {$IFDEF ASM_VERSION}
  44960. {$ELSE ASM_VERSION} //Pascal
  44961. procedure _RotateBitmapMono( var DstBmp: PBitmap; SrcBmp: PBitmap );
  44962. var X, Y, Z, Shf, Wbytes, BytesPerDstLine: Integer;
  44963. Src, Dst, Dst1: PByte;
  44964. Tmp: Byte;
  44965. begin
  44966. DstBmp := NewDIBBitmap( SrcBmp.fHeight, (SrcBmp.fWidth + 7) and not 7, pf1bit );
  44967. Move( SrcBmp.fDIBHeader.bmiColors[ 0 ], DstBmp.fDIBHeader.bmiColors[ 0 ], 2 * Sizeof( TRGBQuad ) );
  44968. // Calculate ones:
  44969. Dst := DstBmp.ScanLine[ 0 ];
  44970. BytesPerDstLine := cardinal( DstBmp.ScanLine[ 1 ]) - cardinal( Dst );
  44971. Wbytes := (SrcBmp.fWidth + 7) shr 3;
  44972. Inc( Dst, (DstBmp.fWidth - 1) shr 3 );
  44973. Shf := (DstBmp.fWidth - 1) and 7;
  44974. // Rotating bits:
  44975. for Y := 0 to SrcBmp.fHeight - 1 do
  44976. begin
  44977. Src := SrcBmp.ScanLine[ Y ];
  44978. Dst1 := Dst;
  44979. for X := Wbytes downto 1 do
  44980. begin
  44981. Tmp := Src^;
  44982. Inc( Src );
  44983. for Z := 8 downto 1 do
  44984. begin
  44985. Dst1^ := Dst1^ or ( (Tmp and $80) shr Shf );
  44986. Tmp := Tmp shl 1;
  44987. Inc( Dst1, BytesPerDstLine );
  44988. end;
  44989. end;
  44990. Dec( Shf );
  44991. if Shf < 0 then
  44992. begin
  44993. Shf := 7;
  44994. Dec( Dst );
  44995. end;
  44996. end;
  44997. end;
  44998. {$ENDIF ASM_VERSION}
  44999. //[END _RotateBitmapMono]
  45000. //[PROCEDURE _RotateBitmap4bit]
  45001. {$IFDEF ASM_VERSION}
  45002. {$ELSE ASM_VERSION} //Pascal
  45003. procedure _RotateBitmap4bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
  45004. var X, Y, Shf, Wbytes, BytesPerDstLine: Integer;
  45005. Src, Dst, Dst1: PByte;
  45006. Tmp: Byte;
  45007. begin
  45008. DstBmp := NewDIBBitmap( SrcBmp.fHeight, (SrcBmp.fWidth + 1) and not 1, pf4bit );
  45009. Move( SrcBmp.fDIBHeader.bmiColors[ 0 ], DstBmp.fDIBHeader.bmiColors[ 0 ], 16 * Sizeof( TRGBQuad ) );
  45010. // Calculate ones:
  45011. Dst := DstBmp.ScanLine[ 0 ];
  45012. BytesPerDstLine := cardinal( DstBmp.ScanLine[ 1 ]) - cardinal( Dst );
  45013. Wbytes := (SrcBmp.fWidth + 1) shr 1;
  45014. Inc( Dst, (DstBmp.fWidth - 1) shr 1 );
  45015. Shf := ((DstBmp.fWidth - 1) and 1) shl 2;
  45016. // Rotating bits:
  45017. for Y := 0 to SrcBmp.fHeight - 1 do
  45018. begin
  45019. Src := SrcBmp.ScanLine[ Y ];
  45020. Dst1 := Dst;
  45021. for X := Wbytes downto 1 do
  45022. begin
  45023. Tmp := Src^;
  45024. Inc( Src );
  45025. Dst1^ := Dst1^ or ( (Tmp and $F0) shr Shf );
  45026. Inc( Dst1, BytesPerDstLine );
  45027. Dst1^ := Dst1^ or ( ((Tmp shl 4) and $F0) shr Shf );
  45028. Inc( Dst1, BytesPerDstLine );
  45029. end;
  45030. Dec( Shf, 4 );
  45031. if Shf < 0 then
  45032. begin
  45033. Shf := 4;
  45034. Dec( Dst );
  45035. end;
  45036. end;
  45037. end;
  45038. {$ENDIF ASM_VERSION}
  45039. //[END _RotateBitmap4bit]
  45040. //[PROCEDURE _RotateBitmap8bit]
  45041. {$IFDEF ASM_VERSION}
  45042. {$ELSE ASM_VERSION} //Pascal
  45043. procedure _RotateBitmap8bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
  45044. var X, Y, Wbytes, BytesPerDstLine: Integer;
  45045. Src, Dst, Dst1: PByte;
  45046. Tmp: Byte;
  45047. begin
  45048. DstBmp := NewDIBBitmap( SrcBmp.fHeight, SrcBmp.fWidth, SrcBmp.PixelFormat );
  45049. Move( SrcBmp.fDIBHeader.bmiColors[ 0 ], DstBmp.fDIBHeader.bmiColors[ 0 ], 256 * Sizeof( TRGBQuad ) );
  45050. // Calculate ones:
  45051. Wbytes := SrcBmp.fWidth;
  45052. Dst := DstBmp.ScanLine[ 0 ];
  45053. BytesPerDstLine := cardinal( DstBmp.ScanLine[ 1 ]) - cardinal( Dst );
  45054. Inc( Dst, DstBmp.fWidth - 1 );
  45055. // Rotating bits:
  45056. for Y := 0 to SrcBmp.fHeight - 1 do
  45057. begin
  45058. Src := SrcBmp.ScanLine[ Y ];
  45059. Dst1 := Dst;
  45060. for X := Wbytes downto 1 do
  45061. begin
  45062. Tmp := Src^;
  45063. Inc( Src );
  45064. Dst1^ := Tmp;
  45065. Inc( Dst1, BytesPerDstLine );
  45066. end;
  45067. Dec( Dst );
  45068. end;
  45069. end;
  45070. {$ENDIF ASM_VERSION}
  45071. //[END _RotateBitmap8bit]
  45072. //[PROCEDURE _RotateBitmap16bit]
  45073. {$IFDEF ASM_VERSION}
  45074. {$ELSE ASM_VERSION} //Pascal
  45075. procedure _RotateBitmap16bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
  45076. var X, Y, Wwords, BytesPerDstLine: Integer;
  45077. Src, Dst, Dst1: PWord;
  45078. Tmp: Word;
  45079. begin
  45080. DstBmp := NewDIBBitmap( SrcBmp.fHeight, SrcBmp.fWidth, SrcBmp.PixelFormat );
  45081. Wwords := SrcBmp.fWidth;
  45082. Dst := DstBmp.ScanLine[ 0 ];
  45083. BytesPerDstLine := cardinal( DstBmp.ScanLine[ 1 ]) - cardinal( Dst );
  45084. Inc( Dst, DstBmp.fWidth - 1 );
  45085. // Rotating bits:
  45086. for Y := 0 to SrcBmp.fHeight - 1 do
  45087. begin
  45088. Src := SrcBmp.ScanLine[ Y ];
  45089. Dst1 := Dst;
  45090. for X := Wwords downto 1 do
  45091. begin
  45092. Tmp := Src^;
  45093. Inc( Src );
  45094. Dst1^ := Tmp;
  45095. Inc( PByte(Dst1), BytesPerDstLine );
  45096. end;
  45097. Dec( Dst );
  45098. end;
  45099. end;
  45100. {$ENDIF ASM_VERSION}
  45101. //[END _RotateBitmap16bit]
  45102. //[PROCEDURE _RotateBitmap2432bit]
  45103. {$IFDEF ASM_VERSION}
  45104. {$ELSE ASM_VERSION} //Pascal
  45105. procedure _RotateBitmap2432bit( var DstBmp: PBitmap; SrcBmp: PBitmap );
  45106. var X, Y, Wwords, BytesPerDstLine, IncW: Integer;
  45107. Src, Dst, Dst1: PDWord;
  45108. Tmp: DWord;
  45109. begin
  45110. DstBmp := NewDIBBitmap( SrcBmp.fHeight, SrcBmp.fWidth, SrcBmp.PixelFormat );
  45111. // Calculate ones:
  45112. IncW := 4;
  45113. if DstBmp.PixelFormat = pf24bit then
  45114. IncW := 3;
  45115. Wwords := SrcBmp.fWidth;
  45116. Dst := DstBmp.ScanLine[ 0 ];
  45117. BytesPerDstLine := cardinal( DstBmp.ScanLine[ 1 ]) - cardinal( Dst );
  45118. Inc( PByte(Dst), (DstBmp.fWidth - 1) * IncW );
  45119. // Rotating bits:
  45120. for Y := 0 to SrcBmp.fHeight - 1 do
  45121. begin
  45122. Src := SrcBmp.ScanLine[ Y ];
  45123. Dst1 := Dst;
  45124. for X := Wwords downto 1 do
  45125. begin
  45126. Tmp := Src^ and $FFFFFF;
  45127. Inc( PByte(Src), IncW );
  45128. Dst1^ := Dst1^ or Tmp;
  45129. Inc( PByte(Dst1), BytesPerDstLine );
  45130. end;
  45131. Dec( PByte(Dst), IncW );
  45132. end;
  45133. end;
  45134. {$ENDIF ASM_VERSION}
  45135. //[END _RotateBitmap2432bit]
  45136. type
  45137. TRotateBmpRefs = {$ifndef wince}packed{$endif} record
  45138. proc_RotateBitmapMono: procedure( var Dst: PBitmap; Src: PBitmap );
  45139. proc_RotateBitmap4bit: procedure( var Dst: PBitmap; Src: PBitmap );
  45140. proc_RotateBitmap8bit: procedure( var Dst: PBitmap; Src: PBitmap );
  45141. proc_RotateBitmap16bit: procedure( var Dst: PBitmap; Src: PBitmap );
  45142. proc_RotateBitmap2432bit: procedure( var Dst: PBitmap; Src: PBitmap );
  45143. end;
  45144. var
  45145. RotateProcs: TRotateBmpRefs;
  45146. //[PROCEDURE _RotateBitmapRight]
  45147. {$IFDEF ASM_VERSION}
  45148. {$ELSE ASM_VERSION} //Pascal
  45149. procedure _RotateBitmapRight( SrcBmp: PBitmap );
  45150. var DstBmp: PBitmap;
  45151. RotateProc: procedure( var DstBmp: PBitmap; SrcBmp: PBitmap );
  45152. begin
  45153. if SrcBmp.fHandleType <> bmDIB then Exit;
  45154. case SrcBmp.PixelFormat of
  45155. pf1bit: RotateProc := RotateProcs.proc_RotateBitmapMono;
  45156. pf4bit: RotateProc := RotateProcs.proc_RotateBitmap4bit;
  45157. pf8bit: RotateProc := RotateProcs.proc_RotateBitmap8bit;
  45158. pf15bit, pf16bit: RotateProc := RotateProcs.proc_RotateBitmap16bit;
  45159. else RotateProc := RotateProcs.proc_RotateBitmap2432bit;
  45160. end;
  45161. if not Assigned( RotateProc ) then Exit;
  45162. RotateProc( DstBmp, SrcBmp );
  45163. if DstBmp.fHeight > SrcBmp.fWidth then
  45164. begin
  45165. DstBmp.fDIBSize := DstBmp.fScanLineSize * SrcBmp.fWidth;
  45166. if DstBmp.fDIBHeader.bmiHeader.biHeight > 0 then
  45167. Move( DstBmp.ScanLine[ SrcBmp.fWidth - 1 ]^, DstBmp.ScanLine[ DstBmp.fHeight - 1 ]^,
  45168. DstBmp.fDIBSize );
  45169. DstBmp.fHeight := SrcBmp.fWidth;
  45170. DstBmp.fDIBHeader.bmiHeader.biHeight := DstBmp.fHeight;
  45171. end;
  45172. SrcBmp.ClearData;
  45173. SrcBmp.fDIBHeader := DstBmp.fDIBHeader;
  45174. DstBmp.fDIBHeader := nil;
  45175. SrcBmp.fDIBBits := DstBmp.fDIBBits;
  45176. DstBmp.fDIBBits := nil;
  45177. SrcBmp.fDIBAutoFree := DstBmp.fDIBAutoFree;
  45178. SrcBmp.fDIBSize := DstBmp.fDIBSize;
  45179. SrcBmp.fWidth := DstBmp.fWidth;
  45180. SrcBmp.fHeight := DstBmp.fHeight;
  45181. DstBmp.Free;
  45182. end;
  45183. {$ENDIF ASM_VERSION}
  45184. //[END _RotateBitmapRight]
  45185. //[procedure TBitmap.RotateRight]
  45186. procedure TBitmap.RotateRight;
  45187. const AllRotators: TRotateBmpRefs = (
  45188. proc_RotateBitmapMono: _RotateBitmapMono;
  45189. proc_RotateBitmap4bit: _RotateBitmap4bit;
  45190. proc_RotateBitmap8bit: _RotateBitmap8bit;
  45191. proc_RotateBitmap16bit: _RotateBitmap16bit;
  45192. proc_RotateBitmap2432bit: _RotateBitmap2432bit );
  45193. begin
  45194. RotateProcs := AllRotators;
  45195. _RotateBitmapRight( @Self );
  45196. end;
  45197. //[procedure _RotateBitmapLeft]
  45198. procedure _RotateBitmapLeft( Src: PBitmap );
  45199. begin
  45200. _RotateBitmapRight( Src );
  45201. _RotateBitmapRight( Src );
  45202. _RotateBitmapRight( Src );
  45203. end;
  45204. //[procedure TBitmap.RotateLeft]
  45205. procedure TBitmap.RotateLeft;
  45206. begin
  45207. RotateRight;
  45208. _RotateBitmapRight( @Self );
  45209. _RotateBitmapRight( @Self );
  45210. end;
  45211. //[procedure TBitmap.RotateLeftMono]
  45212. procedure TBitmap.RotateLeftMono;
  45213. begin
  45214. if PixelFormat <> pf1bit then Exit;
  45215. RotateProcs.proc_RotateBitmapMono := _RotateBitmapMono;
  45216. _RotateBitmapRight( @Self );
  45217. end;
  45218. //[procedure TBitmap.RotateRightMono]
  45219. procedure TBitmap.RotateRightMono;
  45220. begin
  45221. if PixelFormat <> pf1bit then Exit;
  45222. RotateProcs.proc_RotateBitmapMono := _RotateBitmapMono;
  45223. _RotateBitmapLeft( @Self );
  45224. end;
  45225. //[procedure TBitmap.RotateLeft16bit]
  45226. procedure TBitmap.RotateLeft16bit;
  45227. begin
  45228. if PixelFormat <> pf16bit then Exit;
  45229. RotateProcs.proc_RotateBitmap16bit := _RotateBitmap16bit;
  45230. _RotateBitmapLeft( @Self );
  45231. end;
  45232. //[procedure TBitmap.RotateLeft4bit]
  45233. procedure TBitmap.RotateLeft4bit;
  45234. begin
  45235. if PixelFormat <> pf4bit then Exit;
  45236. RotateProcs.proc_RotateBitmap4bit := _RotateBitmap4bit;
  45237. _RotateBitmapLeft( @Self );
  45238. end;
  45239. //[procedure TBitmap.RotateLeft8bit]
  45240. procedure TBitmap.RotateLeft8bit;
  45241. begin
  45242. if PixelFormat <> pf8bit then Exit;
  45243. RotateProcs.proc_RotateBitmap8bit := _RotateBitmap8bit;
  45244. _RotateBitmapLeft( @Self );
  45245. end;
  45246. //[procedure TBitmap.RotateLeftTrueColor]
  45247. procedure TBitmap.RotateLeftTrueColor;
  45248. begin
  45249. if not (PixelFormat in [ pf24bit, pf32bit ]) then Exit;
  45250. RotateProcs.proc_RotateBitmap2432bit := _RotateBitmap2432bit;
  45251. _RotateBitmapLeft( @Self );
  45252. end;
  45253. //[procedure TBitmap.RotateRight16bit]
  45254. procedure TBitmap.RotateRight16bit;
  45255. begin
  45256. if PixelFormat <> pf16bit then Exit;
  45257. RotateProcs.proc_RotateBitmap16bit := _RotateBitmap16bit;
  45258. _RotateBitmapRight( @Self );
  45259. end;
  45260. //[procedure TBitmap.RotateRight4bit]
  45261. procedure TBitmap.RotateRight4bit;
  45262. begin
  45263. if PixelFormat <> pf4bit then Exit;
  45264. RotateProcs.proc_RotateBitmap4bit := _RotateBitmap4bit;
  45265. _RotateBitmapRight( @Self );
  45266. end;
  45267. //[procedure TBitmap.RotateRight8bit]
  45268. procedure TBitmap.RotateRight8bit;
  45269. begin
  45270. if PixelFormat <> pf8bit then Exit;
  45271. RotateProcs.proc_RotateBitmap8bit := _RotateBitmap8bit;
  45272. _RotateBitmapRight( @Self );
  45273. end;
  45274. //[procedure TBitmap.RotateRightTrueColor]
  45275. procedure TBitmap.RotateRightTrueColor;
  45276. begin
  45277. if not (PixelFormat in [ pf24bit, pf32bit ]) then Exit;
  45278. RotateProcs.proc_RotateBitmap2432bit := _RotateBitmap2432bit;
  45279. _RotateBitmapRight( @Self );
  45280. end;
  45281. //[function TBitmap.GetPixels]
  45282. {$IFDEF ASM_VERSION}
  45283. {$ELSE ASM_VERSION} //Pascal
  45284. function TBitmap.GetPixels(X, Y: Integer): TColor;
  45285. var DC: HDC;
  45286. Save: THandle;
  45287. begin
  45288. Result := clNone;
  45289. //if GetHandle = 0 then Exit;
  45290. if Empty then Exit;
  45291. fDetachCanvas( @Self );
  45292. DC := CreateCompatibleDC( 0 );
  45293. Save := SelectObject( DC, GetHandle );
  45294. ASSERT( Save <> 0, 'Can not select bitmap to DC' );
  45295. Result := Windows.GetPixel( DC, X, Y );
  45296. SelectObject( DC, Save );
  45297. DeleteDC( DC );
  45298. end;
  45299. {$ENDIF ASM_VERSION}
  45300. //[procedure TBitmap.SetPixels]
  45301. {$IFDEF ASM_VERSION}
  45302. {$ELSE ASM_VERSION} //Pascal
  45303. procedure TBitmap.SetPixels(X, Y: Integer; const Value: TColor);
  45304. var DC: HDC;
  45305. Save: THandle;
  45306. begin
  45307. //if GetHandle = 0 then Exit;
  45308. if Empty then Exit;
  45309. fDetachCanvas( @Self );
  45310. DC := CreateCompatibleDC( 0 );
  45311. Save := SelectObject( DC, GetHandle );
  45312. ASSERT( Save <> 0, 'Can not select bitmap to DC' );
  45313. Windows.SetPixel( DC, X, Y, Color2RGB( Value ) );
  45314. SelectObject( DC, Save );
  45315. DeleteDC( DC );
  45316. end;
  45317. {$ENDIF ASM_VERSION}
  45318. //[FUNCTION _GetDIBPixelsPalIdx]
  45319. {$IFDEF ASM_VERSION}
  45320. {$ELSE ASM_VERSION} //Pascal
  45321. function _GetDIBPixelsPalIdx( Bmp: PBitmap; X, Y: Integer ): TColor;
  45322. var Pixel: Byte;
  45323. begin
  45324. Pixel := PByte( cardinal(Bmp.fScanLine0) + cardinal(Y * Bmp.fScanLineDelta
  45325. + (X div (Bmp.fPixelsPerByteMask + 1))) )^;
  45326. Pixel := ( Pixel shr ( (Bmp.fPixelsPerByteMask - (X and Bmp.fPixelsPerByteMask))
  45327. * Bmp.fDIBHeader.bmiHeader.biBitCount ) )
  45328. and Bmp.fPixelMask;
  45329. Result := TColor( Color2RGBQuad( TColor( PRGBQuad( DWORD(@Bmp.fDIBHeader.bmiColors[ 0 ])
  45330. + DWORD(Pixel) * Sizeof( TRGBQuad ) )^ ) ) );
  45331. end;
  45332. {$ENDIF ASM_VERSION}
  45333. //[END _GetDIBPixelsPalIdx]
  45334. //[FUNCTION _GetDIBPixels16bit]
  45335. {$IFDEF ASM_VERSION}
  45336. {$ELSE ASM_VERSION} //Pascal
  45337. function _GetDIBPixels16bit( Bmp: PBitmap; X, Y: Integer ): TColor;
  45338. var Pixel: Word;
  45339. begin
  45340. Pixel := PWord( cardinal(Bmp.fScanLine0) + cardinal(Y * Bmp.fScanLineDelta + X * 2) )^;
  45341. if Bmp.fPixelMask = 15 then
  45342. Result := (Pixel shr 7) and $F8 or (Pixel shl 6) and $F800
  45343. or (Pixel shl 19) and $F80000
  45344. else
  45345. Result := (Pixel shr 8) and $F8 or (Pixel shl 5) and $FC00
  45346. or (Pixel shl 19) and $F80000;
  45347. end;
  45348. {$ENDIF ASM_VERSION}
  45349. //[END _GetDIBPixels16bit]
  45350. //[FUNCTION _GetDIBPixelsTrueColor]
  45351. {$IFDEF ASM_VERSION}
  45352. {$ELSE ASM_VERSION} //Pascal
  45353. function _GetDIBPixelsTrueColor( Bmp: PBitmap; X, Y: Integer ): TColor;
  45354. var Pixel: DWORD;
  45355. begin
  45356. Pixel := PDWORD( cardinal(Bmp.fScanLine0) + cardinal(Y * Bmp.fScanLineDelta +
  45357. X * Bmp.fBytesPerPixel) )^ and $FFFFFF;
  45358. Result := TColor( Color2RGBQuad( TColor( Pixel ) ) );
  45359. end;
  45360. {$ENDIF ASM_VERSION}
  45361. //[END _GetDIBPixelsTrueColor]
  45362. //[function TBitmap.GetDIBPixels]
  45363. {$IFDEF ASM_VERSION}
  45364. {$ELSE ASM_VERSION} //Pascal
  45365. function TBitmap.GetDIBPixels(X, Y: Integer): TColor;
  45366. begin
  45367. if not Assigned( fGetDIBPixels ) then
  45368. begin
  45369. if fHandleType = bmDIB then
  45370. begin
  45371. fScanLine0 := ScanLine[ 0 ];
  45372. fScanLineDelta := cardinal(ScanLine[ 1 ]) - cardinal(fScanLine0);
  45373. case PixelFormat of
  45374. pf1bit:
  45375. begin
  45376. fPixelMask := $01;
  45377. fPixelsPerByteMask := 7;
  45378. fGetDIBPixels := _GetDIBPixelsPalIdx;
  45379. end;
  45380. pf4bit:
  45381. begin
  45382. fPixelMask := $0F;
  45383. fPixelsPerByteMask := 1;
  45384. fGetDIBPixels := _GetDIBPixelsPalIdx;
  45385. end;
  45386. pf8bit:
  45387. begin
  45388. fPixelMask := $FF;
  45389. fPixelsPerByteMask := 0;
  45390. fGetDIBPixels := _GetDIBPixelsPalIdx;
  45391. end;
  45392. pf15bit:
  45393. begin
  45394. fPixelMask := 15;
  45395. fGetDIBPixels := _GetDIBPixels16bit;
  45396. end;
  45397. pf16bit:
  45398. begin
  45399. fPixelMask := 16;
  45400. fGetDIBPixels := _GetDIBPixels16bit;
  45401. end;
  45402. pf24bit:
  45403. begin
  45404. fPixelsPerByteMask := 0;
  45405. fBytesPerPixel := 3;
  45406. fGetDIBPixels := _GetDIBPixelsTrueColor;
  45407. end;
  45408. pf32bit:
  45409. begin
  45410. fPixelsPerByteMask := 1;
  45411. fBytesPerPixel := 4;
  45412. fGetDIBPixels := _GetDIBPixelsTrueColor;
  45413. end;
  45414. else;
  45415. end;
  45416. end;
  45417. if not Assigned( fGetDIBPixels ) then
  45418. begin
  45419. Result := Pixels[ X, Y ];
  45420. Exit;
  45421. end;
  45422. end;
  45423. Result := fGetDIBPixels( @Self, X, Y );
  45424. end;
  45425. {$ENDIF ASM_VERSION}
  45426. //[PROCEDURE _SetDIBPixels1bit]
  45427. {$IFDEF ASM_VERSION}
  45428. {$ELSE ASM_VERSION} //Pascal
  45429. procedure _SetDIBPixels1bit( Bmp: PBitmap; X, Y: Integer; Value: TColor );
  45430. var Pixel: Byte;
  45431. Pos: PByte;
  45432. Shf: Integer;
  45433. begin
  45434. Value := Color2RGB( Value );
  45435. if ((Value shr 16) and $FF) + ((Value shr 8) and $FF) + (Value and $FF)
  45436. < 255 * 3 div 2 then Pixel := 0 else Pixel := $80;
  45437. Pos := PByte( cardinal(Bmp.fScanLine0) + cardinal(Y * Bmp.fScanLineDelta + X div 8) );
  45438. Shf := X and 7;
  45439. Pos^ := Pos^ and ($FF7F shr Shf) or (Pixel shr Shf);
  45440. end;
  45441. {$ENDIF ASM_VERSION}
  45442. //[END _SetDIBPixels1bit]
  45443. //[PROCEDURE _SetDIBPixelsPalIdx]
  45444. {$IFDEF ASM_VERSION}
  45445. {$ELSE ASM_VERSION} //Pascal
  45446. procedure _SetDIBPixelsPalIdx( Bmp: PBitmap; X, Y: Integer; Value: TColor );
  45447. var Pixel: Byte;
  45448. Pos: PByte;
  45449. Shf: Integer;
  45450. begin
  45451. Pixel := Bmp.DIBPalNearestEntry( Value );
  45452. Pos := PByte( cardinal(Bmp.fScanLine0) + cardinal(Y * Bmp.fScanLineDelta
  45453. + X div (Bmp.fPixelsPerByteMask + 1)) );
  45454. Shf := (Bmp.fPixelsPerByteMask - (X and Bmp.fPixelsPerByteMask))
  45455. * Bmp.fDIBHeader.bmiHeader.biBitCount;
  45456. Pos^ := Pos^ and not (Bmp.fPixelMask shl Shf) or (Pixel shl Shf);
  45457. end;
  45458. {$ENDIF ASM_VERSION}
  45459. //[END _SetDIBPixelsPalIdx]
  45460. //[PROCEDURE _SetDIBPixels16bit]
  45461. {$IFDEF ASM_VERSION}
  45462. {$ELSE ASM_VERSION} //Pascal
  45463. procedure _SetDIBPixels16bit( Bmp: PBitmap; X, Y: Integer; Value: TColor );
  45464. var RGB16: Word;
  45465. Pos: PWord;
  45466. begin
  45467. Value := Color2RGB( Value );
  45468. if Bmp.fPixelMask = 15 then
  45469. RGB16 := (Value shr 19) and $001F or (Value shr 6) and $03E0
  45470. or (Value shl 7) and $7C00
  45471. else
  45472. RGB16 := (Value shr 19) and $001F or (Value shr 5) and $07E0
  45473. or (Value shl 8) and $F800;
  45474. Pos := PWord( cardinal(Bmp.fScanLine0) + cardinal(Y * Bmp.fScanLineDelta + X * 2) );
  45475. Pos^ := RGB16;
  45476. end;
  45477. {$ENDIF ASM_VERSION}
  45478. //[END _SetDIBPixels16bit]
  45479. //[PROCEDURE _SetDIBPixelsTrueColor]
  45480. {$IFDEF ASM_VERSION}
  45481. {$ELSE ASM_VERSION} //Pascal
  45482. procedure _SetDIBPixelsTrueColor( Bmp: PBitmap; X, Y: Integer; Value: TColor );
  45483. var RGB: TRGBQuad;
  45484. Pos: PDWord;
  45485. begin
  45486. RGB := Color2RGBQuad( Value );
  45487. Pos := PDWORD( cardinal(Bmp.fScanLine0) + cardinal(Y * Bmp.fScanLineDelta
  45488. + X * Bmp.fBytesPerPixel) );
  45489. Pos^ := Pos^ and $FF000000 or DWORD(RGB);
  45490. end;
  45491. {$ENDIF ASM_VERSION}
  45492. //[END _SetDIBPixelsTrueColor]
  45493. //[procedure TBitmap.SetDIBPixels]
  45494. {$IFDEF ASM_VERSION}
  45495. {$ELSE ASM_VERSION} //Pascal
  45496. procedure TBitmap.SetDIBPixels(X, Y: Integer; const Value: TColor);
  45497. begin
  45498. if not Assigned( fSetDIBPixels ) then
  45499. begin
  45500. if fHandleType = bmDIB then
  45501. begin
  45502. fScanLine0 := ScanLine[ 0 ];
  45503. fScanLineDelta := cardinal(ScanLine[ 1 ]) - cardinal(fScanLine0);
  45504. case PixelFormat of
  45505. pf1bit:
  45506. begin
  45507. //fPixelMask := $01;
  45508. //fPixelsPerByteMask := 7;
  45509. fSetDIBPixels := _SetDIBPixels1bit;
  45510. end;
  45511. pf4bit:
  45512. begin
  45513. fPixelMask := $0F;
  45514. fPixelsPerByteMask := 1;
  45515. fSetDIBPixels := _SetDIBPixelsPalIdx;
  45516. end;
  45517. pf8bit:
  45518. begin
  45519. fPixelMask := $FF;
  45520. fPixelsPerByteMask := 0;
  45521. fSetDIBPixels := _SetDIBPixelsPalIdx;
  45522. end;
  45523. pf15bit:
  45524. begin
  45525. fPixelMask := 15;
  45526. fSetDIBPixels := _SetDIBPixels16bit;
  45527. end;
  45528. pf16bit:
  45529. begin
  45530. fPixelMask := 16;
  45531. fSetDIBPixels := _SetDIBPixels16bit;
  45532. end;
  45533. pf24bit:
  45534. begin
  45535. fPixelsPerByteMask := 0;
  45536. fBytesPerPixel := 3;
  45537. fSetDIBPixels := _SetDIBPixelsTrueColor;
  45538. end;
  45539. pf32bit:
  45540. begin
  45541. fPixelsPerByteMask := 1;
  45542. fBytesPerPixel := 4;
  45543. fSetDIBPixels := _SetDIBPixelsTrueColor;
  45544. end;
  45545. else;
  45546. end;
  45547. end;
  45548. if not Assigned( fSetDIBPixels ) then
  45549. begin
  45550. Pixels[ X, Y ] := Value;
  45551. Exit;
  45552. end;
  45553. end;
  45554. fSetDIBPixels( @Self, X, Y, Value );
  45555. end;
  45556. {$ENDIF ASM_VERSION}
  45557. //[procedure TBitmap.FlipVertical]
  45558. {$IFDEF ASM_VERSION}
  45559. {$ELSE ASM_VERSION} //Pascal
  45560. procedure TBitmap.FlipVertical;
  45561. var DC: HDC;
  45562. Save: THandle;
  45563. TmpScan: PByte;
  45564. Y: Integer;
  45565. begin
  45566. if fHandle <> 0 then
  45567. begin
  45568. fDetachCanvas( @Self );
  45569. DC := CreateCompatibleDC( 0 );
  45570. Save := SelectObject( DC, fHandle );
  45571. StretchBlt( DC, 0, fHeight - 1, fWidth, -fHeight, DC, 0, 0, fWidth, fHeight, SRCCOPY );
  45572. SelectObject( DC, Save );
  45573. DeleteDC( DC );
  45574. end
  45575. else
  45576. if fDIBBits <> nil then
  45577. begin
  45578. GetMem( TmpScan, ScanLineSize );
  45579. for Y := 0 to fHeight div 2 do
  45580. begin
  45581. Move( ScanLine[ Y ]^, TmpScan^, fScanLineSize );
  45582. Move( ScanLine[ fHeight - Y - 1 ]^, ScanLine[ Y ]^, fScanLineSize );
  45583. Move( TmpScan^, ScanLine[ fHeight - Y - 1 ]^, fScanLineSize );
  45584. end;
  45585. end;
  45586. end;
  45587. {$ENDIF ASM_VERSION}
  45588. //[procedure TBitmap.FlipHorizontal]
  45589. {$IFDEF ASM_VERSION}
  45590. {$ELSE ASM_VERSION} //Pascal
  45591. procedure TBitmap.FlipHorizontal;
  45592. var DC: HDC;
  45593. Save: THandle;
  45594. begin
  45595. if GetHandle <> 0 then
  45596. begin
  45597. fDetachCanvas( @Self );
  45598. DC := CreateCompatibleDC( 0 );
  45599. Save := SelectObject( DC, fHandle );
  45600. StretchBlt( DC, fWidth - 1, 0, -fWidth, fHeight, DC, 0, 0, fWidth, fHeight, SRCCOPY );
  45601. SelectObject( DC, Save );
  45602. DeleteDC( DC );
  45603. end;
  45604. end;
  45605. {$ENDIF ASM_VERSION}
  45606. //[procedure TBitmap.CopyRect]
  45607. {$IFDEF ASM_VERSION}
  45608. procedure TBitmap.CopyRect(const DstRect: TRect; SrcBmp: PBitmap;
  45609. const SrcRect: TRect);
  45610. asm
  45611. PUSHAD
  45612. MOV EBX, EAX
  45613. MOV ESI, ECX
  45614. MOV EDI, EDX
  45615. CALL GetHandle
  45616. TEST EAX, EAX
  45617. JZ @@exit
  45618. MOV EAX, ESI
  45619. CALL GetHandle
  45620. TEST EAX, EAX
  45621. JZ @@exit
  45622. CALL StartDC
  45623. XCHG EBX, ESI
  45624. CMP EBX, ESI
  45625. JNZ @@diff1
  45626. PUSH EAX
  45627. PUSH 0
  45628. JMP @@nodiff1
  45629. @@diff1:
  45630. CALL StartDC
  45631. @@nodiff1:
  45632. PUSH SrcCopy // ->
  45633. MOV EBP, [SrcRect]
  45634. MOV EAX, [EBP].TRect.Bottom
  45635. MOV EDX, [EBP].TRect.Top
  45636. SUB EAX, EDX
  45637. PUSH EAX // ->
  45638. MOV EAX, [EBP].TRect.Right
  45639. MOV ECX, [EBP].TRect.Left
  45640. SUB EAX, ECX
  45641. PUSH EAX // ->
  45642. PUSH EDX // ->
  45643. PUSH ECX // ->
  45644. PUSH dword ptr [ESP+24] // -> DCsrc
  45645. MOV EAX, [EDI].TRect.Bottom
  45646. MOV EDX, [EDI].TRect.Top
  45647. SUB EAX, EDX
  45648. PUSH EAX // ->
  45649. MOV EAX, [EDI].TRect.Right
  45650. MOV ECX, [EDI].TRect.Left
  45651. SUB EAX, ECX
  45652. PUSH EAX // ->
  45653. PUSH EDX // ->
  45654. PUSH ECX // ->
  45655. PUSH dword ptr [ESP+13*4] // -> DCdst
  45656. CALL StretchBlt
  45657. CMP EBX, ESI
  45658. JNE @@diff2
  45659. POP ECX
  45660. POP ECX
  45661. JMP @@nodiff2
  45662. @@diff2:
  45663. CALL FinishDC
  45664. @@nodiff2:
  45665. CALL FinishDC
  45666. @@exit:
  45667. POPAD
  45668. end;
  45669. {$ELSE ASM_VERSION} //Pascal
  45670. procedure TBitmap.CopyRect(const DstRect: TRect; SrcBmp: PBitmap;
  45671. const SrcRect: TRect);
  45672. var DCsrc, DCdst: HDC;
  45673. SaveSrc, SaveDst: THandle;
  45674. begin
  45675. if (GetHandle = 0) or (SrcBmp.GetHandle = 0) then Exit;
  45676. fDetachCanvas( @Self );
  45677. SrcBmp.fDetachCanvas( SrcBmp );
  45678. DCsrc := CreateCompatibleDC( 0 );
  45679. SaveSrc := SelectObject( DCsrc, SrcBmp.fHandle );
  45680. DCdst := DCsrc;
  45681. SaveDst := 0;
  45682. if SrcBmp <> @Self then
  45683. begin
  45684. DCdst := CreateCompatibleDC( 0 );
  45685. SaveDst := SelectObject( DCdst, fHandle );
  45686. end;
  45687. StretchBlt( DCdst, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left,
  45688. DstRect.Bottom - DstRect.Top, DCsrc, SrcRect.Left, SrcRect.Top,
  45689. SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top,
  45690. SRCCOPY );
  45691. if SrcBmp <> @Self then
  45692. begin
  45693. SelectObject( DCdst, SaveDst );
  45694. DeleteDC( DCdst );
  45695. end;
  45696. SelectObject( DCsrc, SaveSrc );
  45697. DeleteDC( DCsrc );
  45698. end;
  45699. {$ENDIF ASM_VERSION}
  45700. //[function TBitmap.CopyToClipboard]
  45701. function TBitmap.CopyToClipboard: Boolean;
  45702. var DibMem: PChar;
  45703. HdrSize: Integer;
  45704. Gbl: HGlobal;
  45705. //Mem: PStream;
  45706. //Sz: Integer;
  45707. //Pt: Pointer;
  45708. Restore_Compression: Integer;
  45709. begin
  45710. Result := FALSE;
  45711. if Applet = nil then Exit;
  45712. if not OpenClipboard( Applet.GetWindowHandle ) then
  45713. Exit;
  45714. if EmptyClipboard then
  45715. begin
  45716. HandleType := bmDIB;
  45717. HdrSize := sizeof( TBitmapInfoHeader );
  45718. Restore_Compression := -1;
  45719. TRY
  45720. if fDIBHeader.bmiHeader.biBitCount <= 8 then
  45721. Inc( HdrSize,
  45722. (1 shl fDIBHeader.bmiHeader.biBitCount) * Sizeof( TRGBQuad ) )
  45723. else
  45724. begin
  45725. if fDIBHeader.bmiHeader.biCompression = BI_RGB then
  45726. begin
  45727. CASE fDIBHeader.bmiHeader.biBitCount OF
  45728. {24,} 32:
  45729. begin
  45730. Restore_Compression := fDIBHeader.bmiHeader.biCompression;
  45731. fDIBHeader.bmiHeader.biCompression := BI_BITFIELDS;
  45732. PDWORD( @ fDIBHeader.bmiColors[ 0 ] )^ := $FF0000;
  45733. PDWORD( cardinal( @ fDIBHeader.bmiColors[ 0 ] ) + 4 )^ := $FF00;
  45734. PDWORD( cardinal( @ fDIBHeader.bmiColors[ 0 ] ) + 8 )^ := $FF;
  45735. Inc( HdrSize, 12 );
  45736. end;
  45737. END;
  45738. end;
  45739. end;
  45740. Gbl := GlobalAlloc( GMEM_MOVEABLE, HdrSize + fDIBSize );
  45741. DibMem := GlobalLock( Gbl );
  45742. if DibMem <> nil then
  45743. begin
  45744. Move( fDIBHeader^, DibMem^, HdrSize );
  45745. Move( fDIBBits^, Pointer( cardinal( DibMem ) + cardinal(HdrSize) )^, fDIBSize );
  45746. if not GlobalUnlock( Gbl ) and (GetLastError = NO_ERROR) then
  45747. begin
  45748. Result := SetClipboardData( CF_DIB, Gbl ) <> 0;
  45749. end;
  45750. end;
  45751. FINALLY
  45752. if Restore_Compression >= 0 then
  45753. fDIBHeader.bmiHeader.biCompression := Restore_Compression;
  45754. END;
  45755. end;
  45756. CloseClipboard;
  45757. end;
  45758. //[function TBitmap.PasteFromClipboard]
  45759. function TBitmap.PasteFromClipboard: Boolean;
  45760. var Gbl: HGlobal;
  45761. //DIBPtr: PChar;
  45762. Size {, HdrSize}: Integer;
  45763. Mem: PChar;
  45764. Strm: PStream;
  45765. begin
  45766. Result := FALSE;
  45767. if Applet = nil then Exit;
  45768. if not OpenClipboard( Applet.GetWindowHandle ) then Exit;
  45769. TRY
  45770. if IsClipboardFormatAvailable( CF_DIB ) then
  45771. begin
  45772. Gbl := GetClipboardData( CF_DIB );
  45773. if Gbl <> 0 then
  45774. begin
  45775. Size := GlobalSize( Gbl );
  45776. Mem := GlobalLock( Gbl );
  45777. TRY
  45778. if (Size > 0) and (Mem <> nil) then
  45779. begin
  45780. Strm := NewMemoryStream;
  45781. Strm.Write( Mem^, Size );
  45782. Strm.Position := 0;
  45783. LoadFromStreamEx( Strm );
  45784. ////Strm.SaveToFile( GetStartDir + 'test_paste.bmp', 0, Strm.Size );
  45785. Strm.Free;
  45786. Result := not Empty;
  45787. end;
  45788. FINALLY
  45789. GlobalUnlock( Gbl );
  45790. END;
  45791. end;
  45792. end;
  45793. FINALLY
  45794. CloseClipboard;
  45795. END;
  45796. end;
  45797. ///////////////////////////////////////////////////////////////////////
  45798. // I C O N
  45799. ///////////////////////////////////////////////////////////////////////
  45800. { -- icon -- }
  45801. //[function NewIcon]
  45802. function NewIcon: PIcon;
  45803. begin
  45804. {-}
  45805. New( Result, Create );
  45806. {+}{++}(*Result := TIcon.Create;*){--}
  45807. {$IFDEF ICON_DIFF_WH}
  45808. Result.FWidth := 32;
  45809. Result.FHeight := 32;
  45810. {$ELSE}
  45811. Result.FSize := 32;
  45812. {$ENDIF}
  45813. end;
  45814. { TIcon }
  45815. //[PROCEDURE asmIconEmpty]
  45816. {$IFDEF ASM_VERSION}
  45817. {$ENDIF ASM_VERSION}
  45818. //[END asmIconEmpty]
  45819. //[procedure TIcon.Clear]
  45820. {$IFDEF ASM_VERSION}
  45821. {$ELSE ASM_VERSION} //Pascal
  45822. procedure TIcon.Clear;
  45823. begin
  45824. if fHandle <> 0 then
  45825. begin
  45826. if not FShareIcon then
  45827. DestroyIcon( fHandle );
  45828. fHandle := 0;
  45829. end;
  45830. fShareIcon := False;
  45831. end;
  45832. {$ENDIF ASM_VERSION}
  45833. {$IFDEF ASM_LOCAL}
  45834. {$UNDEF ASM_LOCAL}
  45835. {$ENDIF}
  45836. {$IFNDEF ICON_DIFF_WH}
  45837. {$IFDEF ASM_VERSION} {$DEFINE ASM_LOCAL} {$ENDIF}
  45838. {$ENDIF}
  45839. //[function TIcon.Convert2Bitmap]
  45840. {$IFDEF ASM_LOCAL}
  45841. {$ELSE ASM_VERSION} //Pascal
  45842. function TIcon.Convert2Bitmap(TranColor: TColor): HBitmap;
  45843. var DC0, DC2: HDC;
  45844. Save: THandle;
  45845. Br: HBrush;
  45846. begin
  45847. Result := 0;
  45848. if Empty then Exit;
  45849. DC0 := GetDC( 0 );
  45850. DC2 := CreateCompatibleDC( DC0 );
  45851. {$IFDEF ICON_DIFF_WH}
  45852. Result := CreateCompatibleBitmap( DC0, fWidth, fHeight );
  45853. {$ELSE}
  45854. Result := CreateCompatibleBitmap( DC0, fSize, fSize );
  45855. {$ENDIF}
  45856. Save := SelectObject( DC2, Result );
  45857. Br := CreateSolidBrush( Color2RGB( TranColor ) );
  45858. {$IFDEF ICON_DIFF_WH}
  45859. FillRect( DC2, MakeRect( 0, 0, fWidth, fHeight ), Br );
  45860. {$ELSE}
  45861. FillRect( DC2, MakeRect( 0, 0, fSize, fSize ), Br );
  45862. {$ENDIF}
  45863. DeleteObject( Br );
  45864. Draw( DC2, 0, 0 );
  45865. SelectObject( DC2, Save );
  45866. DeleteDC( DC2 );
  45867. ReleaseDC( 0, DC0 );
  45868. end;
  45869. {$ENDIF ASM_VERSION}
  45870. //[destructor TIcon.Destroy]
  45871. {$IFDEF ASM_VERSION}
  45872. {$ELSE ASM_VERSION} //Pascal
  45873. destructor TIcon.Destroy;
  45874. begin
  45875. Clear;
  45876. inherited;
  45877. end;
  45878. {$ENDIF ASM_VERSION}
  45879. //[procedure TIcon.Draw]
  45880. {$IFDEF ASM_VERSION}
  45881. {$ELSE ASM_VERSION} //Pascal
  45882. procedure TIcon.Draw(DC: HDC; X, Y: Integer);
  45883. begin
  45884. if Empty then Exit;
  45885. {$IFDEF ICON_DIFF_WH}
  45886. DrawIconEx( DC, X, Y, fHandle, fWidth, fHeight, 0, 0, DI_NORMAL );
  45887. {$ELSE}
  45888. DrawIconEx( DC, X, Y, fHandle, fSize, fSize, 0, 0, DI_NORMAL );
  45889. {$ENDIF}
  45890. end;
  45891. {$ENDIF ASM_VERSION}
  45892. //[procedure TIcon.StretchDraw]
  45893. {$IFDEF ASM_VERSION}
  45894. {$ELSE ASM_VERSION} //Pascal
  45895. procedure TIcon.StretchDraw(DC: HDC; Dest: TRect);
  45896. begin
  45897. if Empty then Exit;
  45898. DrawIconEx( DC, Dest.Left, Dest.Top, FHandle, Dest.Right - Dest.Left,
  45899. Dest.Bottom - Dest.Top, 0, 0, DI_NORMAL );
  45900. end;
  45901. {$ENDIF ASM_VERSION}
  45902. //[function TIcon.GetEmpty]
  45903. function TIcon.GetEmpty: Boolean;
  45904. begin
  45905. Result := (fHandle = 0)
  45906. {$IFDEF ICONLOAD_PRESERVEBMPS}
  45907. and ((ImgBmp = nil) or ImgBmp.Empty)
  45908. {$ENDIF ICONLOAD_PRESERVEBMPS}
  45909. ;
  45910. end;
  45911. //*
  45912. //[function TIcon.GetHotSpot]
  45913. function TIcon.GetHotSpot: TPoint;
  45914. {$ifdef win32}
  45915. var II : TIconInfo;
  45916. {$endif win32}
  45917. begin
  45918. Result := MakePoint( 0, 0 );
  45919. {$ifdef win32}
  45920. if FHandle = 0 then Exit;
  45921. GetIconInfo( FHandle, II );
  45922. Result.x := II.xHotspot;
  45923. Result.y := II.yHotspot;
  45924. if II.hbmMask <> 0 then
  45925. DeleteObject( II.hbmMask );
  45926. if II.hbmColor <> 0 then
  45927. DeleteObject( II.hbmColor );
  45928. {$endif win32}
  45929. end;
  45930. //*
  45931. //[procedure TIcon.LoadFromFile]
  45932. procedure TIcon.LoadFromFile(const FileName: KOLString);
  45933. var Strm : PStream;
  45934. begin
  45935. Strm := NewReadFileStream( Filename );
  45936. LoadFromStream( Strm );
  45937. Strm.Free;
  45938. end;
  45939. //*
  45940. //[procedure TIcon.LoadFromStream]
  45941. procedure TIcon.LoadFromStream(Strm: PStream);
  45942. var DesiredSize : Integer;
  45943. Pos : DWord;
  45944. Mem : PStream;
  45945. {$IFNDEF ICONLOAD_PRESERVEBMPS}
  45946. ImgBmp, MskBmp : PBitmap;
  45947. {$ENDIF ICONLOAD_PRESERVEBMPS}
  45948. TmpBmp: PBitmap;
  45949. function ReadIcon : Boolean;
  45950. var IH : TIconHeader;
  45951. IDI, FoundIDI : TIconDirEntry;
  45952. I, J, SumSz, FoundSz, D : Integer;
  45953. II : TIconInfo;
  45954. BIH : TBitmapInfoheader;
  45955. SzImg: DWORD;
  45956. begin
  45957. Result := False;
  45958. if Strm.Read( IH, Sizeof( IH ) ) <> Sizeof( IH ) then Exit;
  45959. if (IH.idReserved = Sizeof( TBitmapInfoHeader )) then
  45960. begin
  45961. Strm.Position := Strm.Position - Sizeof( IH );
  45962. {$IFDEF ICON_DIFF_WH} fWidth := 0;
  45963. fHeight := 0;
  45964. {$ELSE} fSize := 0;
  45965. {$ENDIF}
  45966. SumSz := 0;
  45967. end
  45968. else
  45969. if (IH.idReserved = 0) and ((IH.idType = 1) or (IH.idType = 2)) and
  45970. (IH.idCount >= 1) then
  45971. begin
  45972. if (IH.idReserved <> 0) or ((IH.idType <> 1) and (IH.idType <> 2)) or
  45973. (IH.idCount < 1) or (IH.idCount >= 1024) then Exit;
  45974. SumSz := Sizeof( IH );
  45975. FoundSz := 1000000;
  45976. for I := 1 to IH.idCount do
  45977. begin
  45978. if Strm.Read( IDI, Sizeof( IDI ) ) <> Sizeof( IDI ) then Exit;
  45979. Inc( SumSz, IDI.dwBytesInRes + Sizeof( IDI ) );
  45980. D := IDI.bWidth - DesiredSize;
  45981. if D < 0 then D := -D;
  45982. if D < FoundSz then
  45983. begin
  45984. FoundSz := D;
  45985. FoundIDI := IDI;
  45986. end;
  45987. end;
  45988. if FoundSz = 1000000 then Exit;
  45989. Strm.Position := Integer( Pos ) + FoundIDI.dwImageOffset;
  45990. {$IFDEF ICON_DIFF_WH} fWidth := FoundIDI.bWidth;
  45991. fHeight := FoundIDI.bHeight;
  45992. {$ELSE} fSize := FoundIDI.bWidth;
  45993. {$ENDIF}
  45994. end
  45995. else Exit;
  45996. if Strm.Read( BIH, Sizeof( BIH ) ) <> Sizeof( BIH ) then Exit;
  45997. {$IFDEF ICON_DIFF_WH}
  45998. fWidth := BIH.biWidth;
  45999. BIH.biHeight := BIH.biHeight div 2; // fSize;
  46000. fHeight := BIH.biHeight;
  46001. {$ELSE}
  46002. fSize := BIH.biWidth;
  46003. BIH.biHeight := BIH.biHeight div 2; // fSize;
  46004. {$ENDIF}
  46005. Mem := NewMemoryStream;
  46006. if (FoundIDI.bColorCount >= 2) or (FoundIDI.bReserved = 1) or
  46007. (FoundIDI.bColorCount = 0) then
  46008. begin
  46009. I := 0;
  46010. SzImg := ((BIH.biBitCount * BIH.biWidth + 31) div 32) * 4 * BIH.biHeight;
  46011. if (BIH.biSizeImage > 0) and (SzImg > BIH.biSizeImage) then
  46012. SzImg := BIH.biSizeImage;
  46013. if BIH.biBitCount <= 8 then
  46014. begin
  46015. I := (1 shl BIH.biBitCount) * Sizeof( TRGBQuad );
  46016. end;
  46017. Mem.Write( BIH, Sizeof( BIH ) );
  46018. if I > 0 then
  46019. begin
  46020. if Stream2Stream( Mem, Strm, I ) <> DWORD(I) then Exit;
  46021. end
  46022. else
  46023. if BIH.biBitCount = 16 then
  46024. begin
  46025. for I := 0 to 2 do
  46026. begin
  46027. J := InitColors[ I ];
  46028. Mem.Write( J, 4 );
  46029. end;
  46030. end;
  46031. I := Stream2Stream( Mem, Strm, SzImg );
  46032. if I <> Integer( SzImg ) then Exit;
  46033. {$IFDEF ICON_DIFF_WH}
  46034. ImgBmp := NewBitmap( fWidth, fHeight );
  46035. {$ELSE}
  46036. ImgBmp := NewBitmap( fSize, fSize );
  46037. {$ENDIF}
  46038. {$IFDEF ICONLOAD_PRESERVEBMPS}
  46039. Add2AutoFree( ImgBmp );
  46040. {$ENDIF ICONLOAD_PRESERVEBMPS}
  46041. Mem.Seek( 0, spBegin );
  46042. {$IFDEF LOADEX}
  46043. ImgBmp.LoadFromStreamEx( Mem );
  46044. {$ELSE}
  46045. ImgBmp.LoadFromStream( Mem );
  46046. {$ENDIF}
  46047. if ImgBmp.Empty then Exit;
  46048. end
  46049. else
  46050. begin
  46051. Mem.Write( BIH, Sizeof( BIH ) );
  46052. end;
  46053. BIH.biBitCount := 1;
  46054. BIH.biPlanes := 1;
  46055. BIH.biClrUsed := 0;
  46056. Mem.Seek( 0, spBegin );
  46057. BIH.biSizeImage := ((BIH.biWidth + 31) div 32) * 4 * BIH.biHeight;
  46058. Mem.Write( BIH, Sizeof( BIH ) );
  46059. I := 0;
  46060. Mem.Write( I, Sizeof( I ) );
  46061. I := $FFFFFF;
  46062. Mem.Write( I, Sizeof( I ) );
  46063. I := BIH.biSizeImage;
  46064. J := Stream2Stream( Mem, Strm, I );
  46065. while J < I do
  46066. begin
  46067. D := 0;
  46068. Mem.Write( D, 4 );
  46069. Inc( J, 4 );
  46070. end;
  46071. {$IFDEF ICON_DIFF_WH}
  46072. MskBmp := NewBitmap( fWidth, fHeight );
  46073. {$ELSE}
  46074. MskBmp := NewBitmap( fSize, fSize );
  46075. {$ENDIF}
  46076. {$IFDEF ICONLOAD_PRESERVEBMPS}
  46077. Add2AutoFree( MskBmp );
  46078. {$ENDIF ICONLOAD_PRESERVEBMPS}
  46079. Mem.Seek( 0, spBegin );
  46080. {$IFDEF LOADEX}
  46081. MskBmp.LoadFromStreamEx( Mem );
  46082. {$ELSE}
  46083. MskBmp.LoadFromStream( Mem );
  46084. {$ENDIF}
  46085. {$IFDEF ICONLOAD_PRESERVEBMPS}
  46086. Result := TRUE;
  46087. if not Only_Bmp then
  46088. {$ENDIF ICONLOAD_PRESERVEBMPS}
  46089. begin
  46090. II.fIcon := True;
  46091. II.xHotspot := 0;
  46092. II.yHotspot := 0;
  46093. II.hbmMask := 0;
  46094. if Assigned( MskBmp ) and not MskBmp.Empty then
  46095. II.hbmMask := MskBmp.Handle;
  46096. II.hbmColor := 0;
  46097. if ImgBmp <> nil then
  46098. II.hbmColor := ImgBmp.Handle;
  46099. fHandle := CreateIconIndirect( II );
  46100. if SumSz > 0 then
  46101. Strm.Seek( Integer( Pos ) + SumSz, spBegin );
  46102. Result := fHandle <> 0;
  46103. end;
  46104. end;
  46105. begin
  46106. DesiredSize := Size;
  46107. if DesiredSize = 0 then
  46108. DesiredSize := GetSystemMetrics( SM_CXICON );
  46109. Clear;
  46110. Pos := Strm.Position;
  46111. Mem := nil;
  46112. {$IFDEF ICONLOAD_PRESERVEBMPS}
  46113. if ImgBmp <> nil then
  46114. begin
  46115. RemoveFromAutoFree( ImgBmp );
  46116. RemoveFromAutoFree( MskBmp );
  46117. Free_And_Nil( ImgBmp );
  46118. Free_And_Nil( MskBmp );
  46119. end;
  46120. {$ELSE}
  46121. ImgBmp := nil;
  46122. MskBmp := nil;
  46123. {$ENDIF ICONLOAD_PRESERVEBMPS}
  46124. TmpBmp := nil;
  46125. if not ReadIcon then
  46126. begin
  46127. Clear;
  46128. Strm.Seek( Pos, spBegin );
  46129. end;
  46130. Mem.Free;
  46131. {$IFNDEF ICONLOAD_PRESERVEBMPS}
  46132. ImgBmp.Free;
  46133. MskBmp.Free;
  46134. {$ENDIF ICONLOAD_PRESERVEBMPS}
  46135. TmpBmp.Free;
  46136. end;
  46137. {$ifdef win32}
  46138. //[procedure TIcon.SaveToFile]
  46139. {$IFDEF ASM_VERSION}
  46140. {$ELSE ASM_VERSION} //Pascal
  46141. procedure TIcon.SaveToFile(const FileName: KOLString);
  46142. begin
  46143. SaveIcons2File( [ @Self ], FileName );
  46144. end;
  46145. {$ENDIF ASM_VERSION}
  46146. //[procedure TIcon.SaveToStream]
  46147. {$IFDEF ASM_VERSION}
  46148. {$ELSE ASM_VERSION} //Pascal
  46149. procedure TIcon.SaveToStream(Strm: PStream);
  46150. begin
  46151. SaveIcons2Stream( [ @Self ], Strm );
  46152. end;
  46153. {$ENDIF ASM_VERSION}
  46154. {$endif win32}
  46155. {$IFDEF ASM_noVERSION}
  46156. //[procedure TIcon.SetHandle]
  46157. procedure TIcon.SetHandle(const Value: HIcon);
  46158. const szII = sizeof( TIconInfo );
  46159. szBIH = sizeof(TBitmapInfoHeader);
  46160. asm //cmd //opd
  46161. CMP EDX, [EAX].fHandle
  46162. JE @@exit
  46163. PUSHAD
  46164. PUSH EDX
  46165. MOV EBX, EAX
  46166. CALL Clear
  46167. POP ECX
  46168. MOV [EBX].fHandle, ECX
  46169. JECXZ @@fin
  46170. ADD ESP, -szBIH
  46171. PUSH ESP
  46172. PUSH ECX
  46173. CALL GetIconInfo
  46174. MOV ESI, [ESP].TIconInfo.hbmMask
  46175. MOV EDI, [ESP].TIconInfo.hbmColor
  46176. PUSH ESP
  46177. PUSH szBIH
  46178. PUSH ESI
  46179. CALL GetObject
  46180. POP EAX
  46181. POP [EBX].fSize
  46182. ADD ESP, szBIH-8
  46183. TEST ESI, ESI
  46184. JZ @@1
  46185. PUSH ESI
  46186. CALL DeleteObject
  46187. @@1: TEST EDI, EDI
  46188. JZ @@fin
  46189. PUSH EDI
  46190. CALL DeleteObject
  46191. @@fin: POPAD
  46192. @@exit:
  46193. end;
  46194. {$ELSE ASM_VERSION} //Pascal
  46195. procedure TIcon.SetHandle(const Value: HIcon);
  46196. {$ifdef win32}
  46197. var II : TIconInfo;
  46198. B: TagBitmap;
  46199. {$endif win32}
  46200. begin
  46201. if FHandle = Value then Exit;
  46202. Clear;
  46203. FHandle := Value;
  46204. if Value <> 0 then
  46205. begin
  46206. {$ifdef wince}
  46207. {$IFDEF ICON_DIFF_WH}
  46208. fWidth := 32;
  46209. fHeight := 32;
  46210. {$ELSE}
  46211. fSize := 32;
  46212. {$ENDIF}
  46213. {$else}
  46214. GetIconInfo( FHandle, II );
  46215. GetObject( II.hbmMask, Sizeof( B ), @B );
  46216. {$IFDEF ICON_DIFF_WH}
  46217. fWidth := B.bmWidth;
  46218. fHeight := B.bmHeight;
  46219. {$ELSE}
  46220. fSize := B.bmWidth;
  46221. {$ENDIF}
  46222. if II.hbmMask <> 0 then
  46223. DeleteObject( II.hbmMask );
  46224. if II.hbmColor <> 0 then
  46225. DeleteObject( II.hbmColor );
  46226. {$endif wince}
  46227. end;
  46228. end;
  46229. {$ENDIF ASM_VERSION}
  46230. //*
  46231. //[procedure TIcon.SetSize]
  46232. procedure TIcon.SetSize(const Value: Integer);
  46233. begin
  46234. {$IFDEF ICON_DIFF_WH}
  46235. if (fWidth = Value) and (fHeight = Value) then Exit;
  46236. {$ELSE}
  46237. if FSize = Value then Exit;
  46238. {$ENDIF}
  46239. Clear;
  46240. {$IFDEF ICON_DIFF_WH}
  46241. fWidth := Value;
  46242. fHeight := Value;
  46243. {$ELSE}
  46244. FSize := Value;
  46245. {$ENDIF}
  46246. end;
  46247. {$IFDEF ICON_DIFF_WH}
  46248. function TIcon.GetIconSize: Integer;
  46249. begin
  46250. Result := Max( fWidth, fHeight );
  46251. end;
  46252. {$ENDIF}
  46253. //[FUNCTION ColorBits]
  46254. {$IFDEF ASM_VERSION}
  46255. {$ELSE ASM_VERSION} //Pascal
  46256. function ColorBits( ColorsCount : Integer ) : Integer;
  46257. var I : Integer;
  46258. begin
  46259. for I := 1 to 6 do
  46260. begin
  46261. Result := PossibleColorBits[ I ];
  46262. if (1 shl Result) >= ColorsCount then break;
  46263. end;
  46264. end;
  46265. {$ENDIF ASM_VERSION}
  46266. //[END ColorBits]
  46267. {$ifdef win32}
  46268. //[function SaveIcons2StreamEx]
  46269. function SaveIcons2StreamEx( const BmpHandles: array of HBitmap; Strm: PStream ): Boolean;
  46270. var I, Off : Integer;
  46271. IDI : TIconDirEntry;
  46272. BIH : TBitmapInfoHeader;
  46273. B: TagBitmap;
  46274. function RGBArraySize : Integer;
  46275. begin
  46276. Result := 0;
  46277. if (IDI.bColorCount >= 2) or (IDI.bReserved = 1) then
  46278. Result := (IDI.bColorCount + (IDI.bReserved shl 8)) * Sizeof( TRGBQuad );
  46279. end;
  46280. function ColorDataSize( W, H: Integer ) : Integer;
  46281. var N: Integer;
  46282. begin
  46283. if (IDI.bColorCount >= 2) or (IDI.bReserved = 1) then
  46284. N := (ColorBits( IDI.bColorCount + (IDI.bReserved shl 8) ) )
  46285. else
  46286. begin
  46287. N := IDI.wBitCount;
  46288. end;
  46289. Result := ((N * W + 31) div 32) * 4
  46290. * H;
  46291. end;
  46292. function MaskDataSize( W, H: Integer ) : Integer;
  46293. begin
  46294. Result := ((W + 31) div 32) * 4 * H;
  46295. end;
  46296. var BColor, BMask: HBitmap;
  46297. W, H: Integer;
  46298. ImgBmp, MskBmp: PBitmap;
  46299. IH : TIconHeader;
  46300. Colors : PList;
  46301. begin
  46302. Assert( (High(BmpHandles) >= 0) and (High(BmpHandles) and 1 <> 0),
  46303. 'Incorrect parameters count in call to SaveIcons2StreamEx' );
  46304. Result := False;
  46305. IH.idReserved := 0;
  46306. IH.idType := 1;
  46307. IH.idCount := (High( BmpHandles )+1) div 2;
  46308. if Strm.Write( IH, Sizeof( IH ) ) <> Sizeof( IH ) then Exit;
  46309. Off := Sizeof( IH ) + IH.idCount * Sizeof( IDI );
  46310. Colors := NewList;
  46311. ImgBmp := NewBitmap( 0, 0 );
  46312. MskBmp := NewBitmap( 0, 0 );
  46313. TRY
  46314. for I := 0 to High( BmpHandles ) div 2 do
  46315. begin
  46316. BColor := BmpHandles[ I * 2 ];
  46317. BMask := BmpHandles[ I * 2 + 1 ];
  46318. if (BColor = 0) and (BMask = 0) then break;
  46319. Assert( BMask <> 0, 'Mask bitmap not provided for saving icons in SaveIcons2StreamEx' );
  46320. GetObject( BMask, Sizeof( B ), @ B );
  46321. W := B.bmWidth;
  46322. H := B.bmHeight;
  46323. if BColor <> 0 then
  46324. begin
  46325. GetObject( BColor, Sizeof( B ), @B );
  46326. Assert( (B.bmWidth = W) and (B.bmHeight = H),
  46327. 'Mask bitmap size must much color bitmap size in SaveIcons2StreamEx' );
  46328. end;
  46329. FillChar( IDI, Sizeof( IDI ), #0 );
  46330. IDI.bWidth := W;
  46331. IDI.bHeight := H;
  46332. if BColor = 0 then
  46333. IDI.bColorCount := 2
  46334. else
  46335. begin
  46336. ImgBmp.Handle := CopyImage( BColor, IMAGE_BITMAP, W, H,
  46337. LR_CREATEDIBSECTION );
  46338. FillChar( BIH, Sizeof( BIH ), #0 );
  46339. BIH.biSize := Sizeof( BIH );
  46340. GetObject( ImgBmp.Handle, Sizeof( B ), @B );
  46341. if (B.bmPlanes = 1) and (B.bmBitsPixel >= 15) then
  46342. begin
  46343. IDI.bColorCount := 0;
  46344. IDI.bReserved := 0;
  46345. IDI.wBitCount := B.bmBitsPixel;
  46346. end
  46347. else
  46348. if B.bmPlanes * (1 shl B.bmBitsPixel) < 16 then
  46349. begin
  46350. ImgBmp.PixelFormat := pf1bit;
  46351. IDI.bColorCount := 2;
  46352. end
  46353. else
  46354. if B.bmPlanes * (1 shl B.bmBitsPixel) < 256 then
  46355. begin
  46356. ImgBmp.PixelFormat := pf4bit;
  46357. IDI.bColorCount := 16;
  46358. end
  46359. else
  46360. begin
  46361. ImgBmp.PixelFormat := pf8bit;
  46362. IDI.bColorCount := 0;
  46363. IDI.bReserved := 1;
  46364. end;
  46365. end;
  46366. Colors.Add( Pointer(IDI.bColorCount + (IDI.bReserved shl 8)) );
  46367. IDI.dwBytesInRes := Sizeof( BIH ) + RGBArraySize +
  46368. ColorDataSize( W, H ) + MaskDataSize( W, H );
  46369. IDI.dwImageOffset := Off;
  46370. if Strm.Write( IDI, Sizeof( IDI ) ) <> Sizeof( IDI ) then Exit;
  46371. Inc( Off, IDI.dwBytesInRes );
  46372. end;
  46373. for I := 0 to High( BmpHandles ) div 2 do
  46374. begin
  46375. BColor := BmpHandles[ I * 2 ];
  46376. BMask := BmpHandles[ I * 2 + 1 ];
  46377. if (BColor = 0) and (BMask = 0) then break;
  46378. GetObject( BMask, Sizeof( B ), @ B );
  46379. W := B.bmWidth;
  46380. H := B.bmHeight;
  46381. FillChar( BIH, Sizeof( BIH ), #0 );
  46382. BIH.biSize := Sizeof( BIH );
  46383. BIH.biWidth := W;
  46384. BIH.biHeight := H;
  46385. if BColor <> 0 then
  46386. BIH.biHeight := W * 2;
  46387. BIH.biPlanes := 1;
  46388. PWord( @ IDI.bColorCount )^ := DWord( Colors.Items[ I ] );
  46389. if IDI.wBitCount = 0 then
  46390. IDI.wBitCount := ColorBits( PWord( @ IDI.bColorCount )^ );
  46391. BIH.biBitCount := IDI.wBitCount;
  46392. BIH.biSizeImage := Sizeof( BIH ) + ColorDataSize( W, H ) + MaskDataSize( W, H );
  46393. if Strm.Write( BIH, Sizeof( BIH ) ) <> Sizeof( BIH ) then Exit;
  46394. if BColor <> 0 then
  46395. begin
  46396. ImgBmp.Handle := CopyImage( BColor, IMAGE_BITMAP, W, H, 0 );
  46397. case BIH.biBitCount of
  46398. 1 : ImgBmp.PixelFormat := pf1bit;
  46399. 4 : ImgBmp.PixelFormat := pf4bit;
  46400. 8 : ImgBmp.PixelFormat := pf8bit;
  46401. 16: ImgBmp.PixelFormat := pf16bit;
  46402. 24: ImgBmp.PixelFormat := pf24bit;
  46403. 32: ImgBmp.PixelFormat := pf32bit;
  46404. end;
  46405. end
  46406. else
  46407. begin
  46408. ImgBmp.Handle := CopyImage( BMask, IMAGE_BITMAP, W, H, 0 );
  46409. ImgBmp.PixelFormat := pf1bit;
  46410. end;
  46411. if ImgBmp.FDIBBits <> nil then
  46412. begin
  46413. if Strm.Write( Pointer(cardinal(ImgBmp.FDIBHeader) + Sizeof(TBitmapInfoHeader))^,
  46414. PWord( @ IDI.bColorCount )^ * Sizeof( TRGBQuad ) ) <>
  46415. DWORD(PWord( @ IDI.bColorCount )^ * Sizeof( TRGBQuad )) then Exit;
  46416. if Strm.Write( ImgBmp.FDIBBits^, ColorDataSize( W, H ) ) <>
  46417. DWord( ColorDataSize( W, H ) ) then Exit;
  46418. end;
  46419. MskBmp.Handle := CopyImage( BMask, IMAGE_BITMAP, W, H, 0 );
  46420. MskBmp.PixelFormat := pf1bit;
  46421. if Strm.Write( MskBmp.FDIBBits^, MaskDataSize( W, H ) ) <>
  46422. DWord( MaskDataSize( W, H ) ) then Exit;
  46423. end;
  46424. FINALLY
  46425. Colors.Free;
  46426. ImgBmp.Free;
  46427. MskBmp.Free;
  46428. END;
  46429. Result := True;
  46430. end;
  46431. {$IFDEF FPC}
  46432. {$DEFINE _D3orFPC}
  46433. {$ENDIF}
  46434. {$IFDEF _D2orD3}
  46435. {$DEFINE _D3orFPC}
  46436. {$ENDIF}
  46437. //[procedure SaveIcons2Stream]
  46438. procedure SaveIcons2Stream( const Icons : array of PIcon; Strm : PStream );
  46439. var I, J, Pos : Integer;
  46440. {$IFDEF _D3orFPC}
  46441. Bitmaps: array[ 0..63 ] of HBitmap;
  46442. {$ELSE DELPHI}
  46443. Bitmaps: array of HBitmap;
  46444. {$ENDIF FPC/DELPHI}
  46445. II: TIconInfo;
  46446. Bmp: HBitmap;
  46447. begin
  46448. for I := 0 to High( Icons ) do
  46449. begin
  46450. if Icons[ I ].Handle = 0 then Exit;
  46451. for J := I + 1 to High( Icons ) do
  46452. if Icons[ I ].Size = Icons[ J ].Size then Exit;
  46453. end;
  46454. Pos := Strm.Position;
  46455. {$IFDEF _D3orFPC}
  46456. for I := 0 to High( Bitmaps ) do
  46457. Bitmaps[ I ] := 0;
  46458. {$ELSE DELPHI}
  46459. SetLength( Bitmaps, Length( Icons ) * 2 );
  46460. {$ENDIF FPC/DELPHI}
  46461. for I := 0 to High( Icons ) do
  46462. begin
  46463. GetIconInfo( Icons[ I ].Handle, II );
  46464. Bitmaps[ I * 2 ] := II.hbmColor;
  46465. Bitmaps[ I * 2 + 1 ] := II.hbmMask;
  46466. end;
  46467. if not SaveIcons2StreamEx( Bitmaps, Strm ) then
  46468. Strm.Seek( Pos, spBegin );
  46469. for I := 0 to High( Bitmaps ) do
  46470. begin
  46471. Bmp := Bitmaps[ I ];
  46472. if Bmp <> 0 then
  46473. DeleteObject( Bmp );
  46474. end;
  46475. end;
  46476. //[procedure SaveIcons2File]
  46477. procedure SaveIcons2File( const Icons : array of PIcon; const FileName : KOLString );
  46478. var Strm: PStream;
  46479. begin
  46480. Strm := NewWriteFileStream( FileName );
  46481. SaveIcons2Stream( Icons, Strm );
  46482. Strm.Free;
  46483. end;
  46484. {$endif win32}
  46485. //[procedure TIcon.LoadFromExecutable]
  46486. procedure TIcon.LoadFromExecutable(const FileName: KOLString; IconIdx: Integer);
  46487. var I: Integer;
  46488. begin
  46489. Clear;
  46490. {$ifdef wince}
  46491. if ExtractIconEx(PKOLChar( FileName ), IconIdx, @I, nil, 1) > 0 then
  46492. {$else}
  46493. I := ExtractIcon( hInstance, PKOLChar( FileName ), IconIdx );
  46494. if I > 1 then
  46495. {$endif wince}
  46496. Handle := I;
  46497. end;
  46498. //[function GetFileIconCount]
  46499. function GetFileIconCount( const FileName: KOLString ): Integer;
  46500. begin
  46501. {$ifdef wince}
  46502. Result := ExtractIconEx(PKOLChar( FileName ), -1, nil, nil, 0);
  46503. {$else}
  46504. Result := ExtractIcon( hInstance, PKOLChar( FileName ), DWORD(-1) );
  46505. {$endif wince}
  46506. end;
  46507. //[procedure TIcon.LoadFromResourceID]
  46508. procedure TIcon.LoadFromResourceID(Inst, ResID, DesiredSize: Integer);
  46509. begin
  46510. LoadFromResourceName( Inst, MAKEINTRESOURCE( ResID ), DesiredSize );
  46511. end;
  46512. //[procedure TIcon.LoadFromResourceName]
  46513. procedure TIcon.LoadFromResourceName(Inst: Integer; ResName: PKOLChar; DesiredSize: Integer);
  46514. begin
  46515. Handle := LoadImage( Inst, ResName, IMAGE_ICON, DesiredSize, DesiredSize, {$ifdef wince} 0 {$else} $8000 {LR_SHARED} {$endif} );
  46516. {$ifdef wince}
  46517. {$IFDEF ICON_DIFF_WH}
  46518. fWidth := DesiredSize;
  46519. fHeight := DesiredSize;
  46520. {$ELSE}
  46521. fSize := DesiredSize;
  46522. {$ENDIF}
  46523. {$endif wince}
  46524. if fHandle <> 0 then FShareIcon := True;
  46525. end;
  46526. //[function LoadImgIcon]
  46527. function LoadImgIcon( RsrcName: PKOLChar; Size: Integer ): HIcon;
  46528. begin
  46529. Result := LoadImage( hInstance, RsrcName, IMAGE_ICON, Size, Size, {$ifdef wince} 0 {$else} $8000 {LR_SHARED} {$endif} );
  46530. end;
  46531. //*
  46532. //[procedure AlignChildrenProc]
  46533. {$IFDEF OLD_ALIGN}
  46534. procedure AlignChildrenProc( Sender: PObj );
  46535. type
  46536. TAligns = set of TControlAlign;
  46537. var P: PControl;
  46538. CR: TRect;
  46539. procedure DoAlign( Allowed: TAligns );
  46540. var I: Integer;
  46541. C: PControl;
  46542. R, R1: TRect;
  46543. W, H: Integer;
  46544. ChgPos, ChgSiz: Boolean;
  46545. begin
  46546. for I := 0 to P.fChildren.fCount - 1 do
  46547. begin
  46548. C := P.fChildren.fItems[ I ];
  46549. if not C.ToBeVisible then continue;
  46550. // important: not fVisible, and even not Visible, but ToBeVisible!
  46551. if C.fNotUseAlign then continue;
  46552. if C.FAlign in Allowed then
  46553. begin
  46554. R := C.BoundsRect;
  46555. R1 := R;
  46556. W := R.Right - R.Left;
  46557. H := R.Bottom - R.Top;
  46558. case C.FAlign of
  46559. caTop:
  46560. begin
  46561. OffsetRect( R, 0, -R.Top + CR.Top + P.Margin );
  46562. Inc( CR.Top, H + P.Margin );
  46563. R.Left := CR.Left + P.Margin;
  46564. R.Right := CR.Right - P.Margin;
  46565. end;
  46566. caBottom:
  46567. begin
  46568. OffsetRect( R, 0, -R.Bottom + CR.Bottom - P.Margin );
  46569. Dec( CR.Bottom, H + P.Margin );
  46570. R.Left := CR.Left + P.Margin;
  46571. R.Right := CR.Right - P.Margin;
  46572. end;
  46573. caLeft:
  46574. begin
  46575. OffsetRect( R, -R.Left + CR.Left + P.Margin, 0 );
  46576. Inc( CR.Left, W + P.Margin );
  46577. R.Top := CR.Top + P.Margin;
  46578. R.Bottom := CR.Bottom - P.Margin;
  46579. end;
  46580. caRight:
  46581. begin
  46582. OffsetRect( R, -R.Right + CR.Right - P.Margin, 0 );
  46583. Dec( CR.Right, W + P.Margin );
  46584. R.Top := CR.Top + P.Margin;
  46585. R.Bottom := CR.Bottom - P.Margin;
  46586. end;
  46587. caClient:
  46588. begin
  46589. R := CR;
  46590. InflateRect( R, -P.Margin, -P.Margin );
  46591. end;
  46592. end;
  46593. if R.Right < R.Left then R.Right := R.Left;
  46594. if R.Bottom < R.Top then R.Bottom := R.Top;
  46595. ChgPos := (R.Left <> R1.Left) or (R.Top <> R1.Top);
  46596. ChgSiz := (R.Right - R.Left <> W) or (R.Bottom - R.Top <> H);
  46597. if ChgPos or ChgSiz then
  46598. begin
  46599. C.BoundsRect := R;
  46600. if ChgSiz then
  46601. AlignChildrenProc( C );
  46602. end;
  46603. end;
  46604. end;
  46605. end;
  46606. begin
  46607. P := Pointer( Sender );
  46608. if P = nil then Exit; // Called for form - ignore.
  46609. CR := P.ClientRect;
  46610. if CR.Right <= CR.Left then Exit;
  46611. DoAlign( [ caTop, caBottom ] );
  46612. DoAlign( [ caLeft, caRight ] );
  46613. DoAlign( [ caClient ] );
  46614. end;
  46615. {$ELSE NEW_ALIGN}
  46616. procedure AlignChildrenProc_(P:PControl);
  46617. type TAligns = set of TControlAlign;
  46618. var CR: TRect;
  46619. procedure DoAlign( Allowed: TAligns );
  46620. var I, W, H: Integer;
  46621. C: PControl;
  46622. R, R1: TRect;
  46623. ChgPos, ChgSiz: Boolean;
  46624. begin
  46625. for I := 0 to P.fChildren.fCount - 1 do begin
  46626. C := P.fChildren.fItems[ I ];
  46627. with C{-}^{+} do begin
  46628. if not (fVisible or fCreateHidden)
  46629. or not (fAlign in Allowed)
  46630. or (oaAligning in fAligning) then continue;
  46631. if not fNotUseAlign and (fAlign <> caNone) then begin
  46632. R := BoundsRect;
  46633. R1 := R;
  46634. W := R.Right - R.Left;
  46635. H := R.Bottom - R.Top;
  46636. case FAlign of
  46637. caTop:
  46638. begin
  46639. OffsetRect( R, 0, -R.Top + CR.Top + P.Margin );
  46640. Inc( CR.Top, H + P.Margin );
  46641. R.Left := CR.Left + P.Margin;
  46642. R.Right := CR.Right - P.Margin;
  46643. end;
  46644. caBottom:
  46645. begin
  46646. OffsetRect( R, 0, -R.Bottom + CR.Bottom - P.Margin );
  46647. Dec( CR.Bottom, H + P.Margin );
  46648. R.Left := CR.Left + P.Margin;
  46649. R.Right := CR.Right - P.Margin;
  46650. end;
  46651. caLeft:
  46652. begin
  46653. OffsetRect( R, -R.Left + CR.Left + P.Margin, 0 );
  46654. Inc( CR.Left, W + P.Margin );
  46655. R.Top := CR.Top + P.Margin;
  46656. R.Bottom := CR.Bottom - P.Margin;
  46657. end;
  46658. caRight:
  46659. begin
  46660. OffsetRect( R, -R.Right + CR.Right - P.Margin, 0 );
  46661. Dec( CR.Right, W + P.Margin );
  46662. R.Top := CR.Top + P.Margin;
  46663. R.Bottom := CR.Bottom - P.Margin;
  46664. end;
  46665. caClient:
  46666. begin
  46667. R := CR;
  46668. InflateRect( R, -P.Margin, -P.Margin );
  46669. end;
  46670. end;
  46671. if R.Right < R.Left then R.Right := R.Left;
  46672. if R.Bottom < R.Top then R.Bottom := R.Top;
  46673. ChgPos := (R.Left <> R1.Left) or (R.Top <> R1.Top);
  46674. ChgSiz := (R.Right - R.Left <> W) or (R.Bottom - R.Top <> H);
  46675. if ChgPos or ChgSiz then begin
  46676. include(fAligning,oaFromSelf);
  46677. BoundsRect := R;
  46678. exclude(fAligning,oaFromSelf);
  46679. end;
  46680. if ChgSiz then
  46681. include(fAligning,oaWaitAlign);
  46682. end;
  46683. if oaWaitAlign in fAligning then AlignChildrenProc_(C);
  46684. end;
  46685. end;
  46686. end;
  46687. begin
  46688. if oaAligning in P.fAligning then exit;
  46689. exclude(P.fAligning,oaWaitAlign);
  46690. if P.ChildCount = 0 then exit;
  46691. include(P.fAligning,oaAligning);
  46692. CR := P.ClientRect;
  46693. DoAlign( [ caTop, caBottom ] );
  46694. DoAlign( [ caLeft, caRight ] );
  46695. DoAlign( [ caClient,caNone ] );
  46696. exclude(P.fAligning,oaAligning);
  46697. end;
  46698. {$IFDEF ASM_VERSION}
  46699. {$ELSE PAS_VERSION} // Pascal
  46700. procedure AlignChildrenProc(Sender: PObj);
  46701. function ToBeAlign( S: PControl ):boolean;
  46702. begin
  46703. Result := (S.fVisible or S.fCreateHidden)
  46704. and (S.isForm or (S.fParent=nil) or ToBeAlign(S.fParent));
  46705. if not Result then include(S.fAligning,oaWaitAlign);
  46706. end;
  46707. var
  46708. S: PControl;
  46709. begin
  46710. if Sender = nil then Exit;
  46711. S := Pointer( Sender );
  46712. if oaFromSelf in S.fAligning then exit;
  46713. if not (S.fNotUseAlign or (S.fAlign = caNone)) and (S.fParent <> nil) and not S.isForm then begin
  46714. include(S.fAligning, oaWaitAlign);
  46715. S := S.Parent;
  46716. end;
  46717. if ToBeAlign(S) then
  46718. AlignChildrenProc_(S);
  46719. end;
  46720. {$ENDIF ASM_VERSION}
  46721. {$ENDIF OLD_ALIGN}
  46722. //*
  46723. //[procedure TControl.Set_Align]
  46724. procedure TControl.Set_Align(const Value: TControlAlign);
  46725. begin
  46726. Global_Align := AlignChildrenProc;
  46727. if fNotUseAlign then Exit;
  46728. if FAlign = Value then Exit;
  46729. FAlign := Value;
  46730. {$IFDEF OLD_ALIGN}
  46731. AlignChildrenProc( Parent );
  46732. {$ELSE NEW_ALIGN}
  46733. AlignChildrenProc(@Self);
  46734. {$ENDIF}
  46735. end;
  46736. //*
  46737. //[function TControl.SetAlign]
  46738. function TControl.SetAlign(AAlign: TControlAlign): PControl;
  46739. begin
  46740. Set_Align( AAlign );
  46741. Result := @Self;
  46742. end;
  46743. //*
  46744. //[function WndProcPreventResizeFlicks]
  46745. function WndProcPreventResizeFlicks( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  46746. type TRectsArray = array[0..2] of TRect;
  46747. PRectsArray = ^TRectsArray;
  46748. TChange = ( ChgL, ChgT, ChgR, ChgB );
  46749. TChanges = Set of TChange;
  46750. var Rects : PRectsArray;
  46751. Changes : Set of TChange;
  46752. Resizing : Boolean;
  46753. X, Y, DX, DY : Integer;
  46754. EntireRect, Src, Dst : TRect;
  46755. function GetClientAfter : TRect;
  46756. var R : TRect;
  46757. begin
  46758. R := Rects[ 2 ];
  46759. OffsetRect( R, Rects[ 0 ].Left - Rects[ 1 ].Left,
  46760. Rects[ 0 ].Top - Rects[ 1 ].Top );
  46761. if Rects[ 0 ].Right - Rects[ 0 ].Left <> Rects[ 1 ].Right - Rects[ 1 ].Left then
  46762. R.Right := R.Left + (R.Right - R.Left)
  46763. + (Rects[ 0 ].Right - Rects[ 0 ].Left)
  46764. - (Rects[ 1 ].Right - Rects[ 1 ].Left);
  46765. if Rects[ 0 ].Bottom - Rects[ 0 ].Top <> Rects[ 1 ].Bottom - Rects[ 1 ].Top then
  46766. R.Bottom := R.Top + (R.Bottom - R.Top)
  46767. + (Rects[ 0 ].Bottom - Rects[ 0 ].Top)
  46768. - (Rects[ 1 ].Bottom - Rects[ 1 ].Top);
  46769. Result := R;
  46770. end;
  46771. procedure DoResize( F : PControl; Changes : TChanges );
  46772. procedure CollectClipRgn( V : PControl; Changes : TChanges );
  46773. var C : PControl;
  46774. I : Integer;
  46775. begin
  46776. for I := 0 to V.FChildren.FCount - 1 do
  46777. begin
  46778. C := V.FChildren.FItems[ I ];
  46779. if not C.Visible then Continue;
  46780. if C.fNotUseAlign then
  46781. begin
  46782. C.Update;
  46783. end;
  46784. end;
  46785. end; // of CollectClipRgn
  46786. begin // DoResize
  46787. CollectClipRgn( F, Changes );
  46788. end; // of DoResize
  46789. var PR: PRect;
  46790. R: TRect;
  46791. begin // Procedure WndProcResizeFlicks
  46792. Result := False;
  46793. case Msg.message of
  46794. WM_NCCALCSIZE:
  46795. if Msg.wParam <> 0 then
  46796. begin
  46797. Rects := Pointer( Msg.lParam );
  46798. Changes := [];
  46799. if Rects[ 0 ].Left <> Rects[ 1 ].Left then
  46800. Changes := Changes + [ ChgL ];
  46801. if Rects[ 0 ].Top <> Rects[ 1 ].Top then
  46802. Changes := Changes + [ ChgT ];
  46803. if Rects[ 0 ].Right <> Rects[ 1 ].Right then
  46804. Changes := Changes + [ ChgR ];
  46805. if Rects[ 0 ].Bottom <> Rects[ 1 ].Bottom then
  46806. Changes := Changes + [ ChgB ];
  46807. Resizing := Changes * [ ChgL, ChgT ] <> [ ];
  46808. if Resizing and not Sender.fNotUseAlign then
  46809. begin
  46810. EntireRect := GetClientAfter;
  46811. OffsetRect( EntireRect, -EntireRect.Left, -EntireRect.Top );
  46812. if EntireRect.Right - EntireRect.Left < Rects[ 2 ].Right - Rects[ 2 ].Left then
  46813. EntireRect.Right := Rects[ 2 ].Right - Rects[ 2 ].Left;
  46814. if EntireRect.Bottom - EntireRect.Top < Rects[ 2 ].Bottom - Rects[ 2 ].Top then
  46815. EntireRect.Bottom := Rects[ 2 ].Bottom - Rects[ 2 ].Top;
  46816. X := Min( Rects[ 0 ].Left, Rects[ 1 ].Left ) + Rects[ 2 ].Left - Rects[ 1 ].Left;
  46817. Y := Min( Rects[ 0 ].Top, Rects[ 1 ].Top ) + Rects[ 2 ].Top - Rects[ 2 ].Top;
  46818. OffsetRect( EntireRect, X, Y );
  46819. DX := 0; DY := 0;
  46820. if ChgL in Changes then
  46821. DX := Rects[ 0 ].Left - Rects[ 1 ].Left;
  46822. if ChgR in Changes then
  46823. DX := Rects[ 0 ].Right - Rects[ 1 ].Right;
  46824. if ChgT in Changes then
  46825. DY := Rects[ 0 ].Top - Rects[ 1 ].Top;
  46826. if ChgB in Changes then
  46827. DY := Rects[ 0 ].Bottom - Rects[ 1 ].Bottom;
  46828. DoResize( Sender, Changes );
  46829. Rslt := 0;
  46830. if (Changes = [ChgL]) then
  46831. begin
  46832. Rslt := WVR_VALIDRECTS;
  46833. Src := Rects[ 2 ];
  46834. Dst := GetClientAfter;
  46835. Src.Right := Src.Left - DX;
  46836. Dst.Right := Dst.Left - DX;
  46837. Rects[ 1 ] := Src;
  46838. Rects[ 2 ] := Dst;
  46839. end
  46840. else
  46841. if (Changes = [ChgR]) then
  46842. begin
  46843. Rslt := WVR_VALIDRECTS;
  46844. Src := Rects[ 2 ];
  46845. Dst := GetClientAfter;
  46846. Src.Left := Src.Right - DX;
  46847. Dst.Left := Dst.Right - DX;
  46848. Rects[ 1 ] := Src;
  46849. Rects[ 2 ] := Dst;
  46850. end
  46851. else
  46852. if (Changes = [ChgT]) then
  46853. begin
  46854. Rslt := WVR_VALIDRECTS;
  46855. Src := Rects[ 2 ];
  46856. Dst := GetClientAfter;
  46857. Src.Bottom := Src.Top - DY;
  46858. Dst.Bottom := Dst.Top - DY;
  46859. Rects[ 1 ] := Src;
  46860. Rects[ 2 ] := Dst;
  46861. end
  46862. else
  46863. if Changes = [ChgL,ChgT] then
  46864. begin
  46865. Rslt := WVR_VALIDRECTS;
  46866. Src := Rects[ 2 ];
  46867. Dst := GetClientAfter;
  46868. Src.Left := Src.Right - DX;
  46869. Dst.Left := Dst.Right - DX;
  46870. Src.Bottom := Src.Top - DY;
  46871. Dst.Bottom := Dst.Top - DY;
  46872. Rects[ 1 ] := Src;
  46873. Rects[ 2 ] := Dst;
  46874. end;
  46875. PostMessage( Sender.fHandle, CM_UPDATE, 0, 0 );
  46876. end;
  46877. end;
  46878. CM_UPDATE:
  46879. begin
  46880. if Sender.fNotUpdate then
  46881. begin
  46882. Sender.fNotUpdate := False;
  46883. Sender.Invalidate;
  46884. end;
  46885. Sender.Update;
  46886. end;
  46887. WM_SIZING:
  46888. begin
  46889. if (Msg.wParam = WMSZ_TOPLEFT) or (Msg.wParam = WMSZ_BOTTOMLEFT) or (Msg.wParam = WMSZ_TOPRIGHT) then
  46890. begin
  46891. PR := Pointer( Msg.lParam );
  46892. GetWindowRect( Sender.fHandle, R );
  46893. PostMessage( Sender.fHandle, CM_SIZEPOS, LoWord( PR.Left) or (PR.Top shl 16),
  46894. LoWord( PR.Right - PR.Left ) or ( (PR.Bottom - PR.Top) shl 16) );
  46895. if Msg.wParam = WMSZ_TOPLEFT then
  46896. if Abs( R.Top - PR.Top ) < Abs( R.Left - PR.Left ) then
  46897. PR.Top := R.Top
  46898. else
  46899. PR.Left := R.Left
  46900. else
  46901. if Msg.wParam = WMSZ_BOTTOMLEFT then
  46902. if Abs( R.Bottom - PR.Bottom ) < Abs( R.Left - PR.Left ) then
  46903. PR.Bottom := R.Bottom
  46904. else
  46905. PR.Left := R.Left
  46906. else // WMSZ_TOPRIGHT
  46907. if Abs( R.Top - PR.Top ) < Abs( R.Right - PR.Right ) then
  46908. PR.Top := R.Top
  46909. else
  46910. PR.Right := R.Right;
  46911. Sender.fNotUpdate := True;
  46912. Rslt := 1;
  46913. Result := TRUE;
  46914. end;
  46915. end;
  46916. CM_SIZEPOS:
  46917. begin
  46918. Sender.fNotUpdate := False;
  46919. SetWindowPos( Sender.fHandle, 0, SmallInt( LoWord( Msg.wParam ) ),
  46920. SmallInt( HiWord( Msg.wParam ) ), SmallInt( LoWord( Msg.lParam ) ),
  46921. SmallInt( HiWord( Msg.lParam ) ), SWP_NOZORDER or SWP_NOACTIVATE );
  46922. end;
  46923. WM_PAINT:
  46924. begin
  46925. if Sender.fNotUpdate then
  46926. begin
  46927. Rslt := 0;
  46928. Result := True;
  46929. end;
  46930. end;
  46931. WM_ERASEBKGND:
  46932. begin
  46933. if Sender.fNotUpdate then
  46934. begin
  46935. Rslt := 1;
  46936. Result := True;
  46937. end;
  46938. end;
  46939. end;
  46940. end;
  46941. //*
  46942. //[function TControl.PreventResizeFlicks]
  46943. function TControl.PreventResizeFlicks: PControl;
  46944. begin
  46945. fWndProcResizeFlicks := WndProcPreventResizeFlicks;
  46946. Result := @Self;
  46947. end;
  46948. //*
  46949. //[procedure TControl.Update]
  46950. procedure TControl.Update;
  46951. var I: Integer;
  46952. C: PControl;
  46953. begin
  46954. if fUpdateCount > 0 then
  46955. Exit;
  46956. if fNotUpdate then Exit;
  46957. if fHandle = 0 then Exit;
  46958. UpdateWindow( fHandle );
  46959. for I := 0 to fChildren.fCount - 1 do
  46960. begin
  46961. C := fChildren.fItems[ I ];
  46962. C.Update;
  46963. end;
  46964. end;
  46965. //[FUNCTION WndProcUpdate]
  46966. {$IFDEF ASM_VERSION}
  46967. {$ELSE ASM_VERSION} //Pascal
  46968. function WndProcUpdate( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  46969. begin
  46970. if Sender.fUpdateCount <> 0 then
  46971. begin
  46972. case Msg.message of
  46973. WM_PAINT:
  46974. begin
  46975. ValidateRect( Sender.Handle, nil );
  46976. Rslt := 0;
  46977. end;
  46978. WM_ERASEBKGND: Rslt := 1;
  46979. else begin
  46980. Result := FALSE;
  46981. Exit;
  46982. end;
  46983. end;
  46984. Result := TRUE;
  46985. end
  46986. else Result := FALSE;
  46987. end;
  46988. {$ENDIF ASM_VERSION}
  46989. //[END WndProcUpdate]
  46990. //[procedure TControl.BeginUpdate]
  46991. procedure TControl.BeginUpdate;
  46992. begin
  46993. Inc( fUpdateCount );
  46994. AttachProc( @WndProcUpdate );
  46995. end;
  46996. //[procedure TControl.EndUpdate]
  46997. procedure TControl.EndUpdate;
  46998. begin
  46999. Dec( fUpdateCount );
  47000. if fUpdateCount <= 0 then
  47001. begin
  47002. Invalidate;
  47003. //Update;
  47004. end;
  47005. end;
  47006. //*
  47007. //[function TControl.GetSelection]
  47008. function TControl.GetSelection: KOLString;
  47009. var L: Integer;
  47010. begin
  47011. if fCommandActions.aGetSelection <> 0 then
  47012. begin
  47013. L := SelLength;
  47014. SetString( Result, nil, L + 1 );
  47015. Perform( fCommandActions.aGetSelection, 0, Integer( @Result[ 1 ] ) );
  47016. end
  47017. else
  47018. Result := Copy( Text, SelStart + 1, SelLength );
  47019. end;
  47020. //*
  47021. //[procedure TControl.SetSelection]
  47022. procedure TControl.SetSelection(const Value: KOLString);
  47023. begin
  47024. ReplaceSelection( Value, True );
  47025. end;
  47026. //*
  47027. //[procedure TControl.ReplaceSelection]
  47028. procedure TControl.ReplaceSelection(const Value: KOLString; aCanUndo: Boolean);
  47029. begin
  47030. if fCommandActions.aReplaceSel <> 0 then
  47031. begin
  47032. Perform( fCommandActions.aReplaceSel, Integer( aCanUndo ), Integer( PKOLchar( Value ) ) );
  47033. end;
  47034. end;
  47035. //[procedure TControl.DeleteLines]
  47036. procedure TControl.DeleteLines(FromLine, ToLine: Integer);
  47037. var I1, I2: DWORD;
  47038. SStart, SLength: DWORD;
  47039. begin
  47040. if FromLine > ToLine then Exit;
  47041. Assert( FromLine >= 0, 'Incorrect line index' );
  47042. I1 := Item2Pos( FromLine );
  47043. I2 := Item2Pos( ToLine+1 ) - I1;
  47044. SStart := SelStart;
  47045. SLength := SelLength;
  47046. SelStart := I1;
  47047. {if ToLine >= Count-1 then
  47048. I2 := MaxInt;}
  47049. SelLength := I2;
  47050. ReplaceSelection( '', TRUE );
  47051. if SStart >= I2 then
  47052. begin
  47053. SStart := SStart - (I2 - I1);
  47054. end
  47055. else
  47056. if SStart >= I1 then
  47057. begin
  47058. SLength := SLength - (I2 - SStart);
  47059. SStart := I1;
  47060. end
  47061. else
  47062. if SStart + SLength >= I2 then
  47063. begin
  47064. SLength := SLength - (I2 - I1);
  47065. end
  47066. else
  47067. if SStart + SLength >= I1 then
  47068. begin
  47069. SLength := I1 - SLength;
  47070. end;
  47071. SelStart := SStart;
  47072. SelLength := Max( 0, SLength );
  47073. end;
  47074. //*
  47075. //[procedure TControl.SetTabOrder]
  47076. procedure TControl.SetTabOrder(const Value: Integer);
  47077. var CL: PList;
  47078. I : Integer;
  47079. C: PControl;
  47080. begin
  47081. if Value = fTabOrder then Exit;
  47082. CL := CollectTabControls( ParentForm );
  47083. for I := 0 to CL.fCount - 1 do
  47084. begin
  47085. C := CL.fItems[ I ];
  47086. if C.fTabOrder >= Value then
  47087. Inc( C.fTabOrder );
  47088. end;
  47089. fTabOrder := Value;
  47090. CL.Free;
  47091. end;
  47092. //*
  47093. //[function TControl.GetFocused]
  47094. function TControl.GetFocused: Boolean;
  47095. begin
  47096. if fIsControl then
  47097. Result := ParentForm.fCurrentControl = @Self
  47098. else
  47099. Result := GetForegroundWindow = fHandle;
  47100. end;
  47101. //*
  47102. //[procedure TControl.SetFocused]
  47103. procedure TControl.SetFocused(const Value: Boolean);
  47104. var PF: PControl;
  47105. begin
  47106. if not Value or not fTabStop then Exit;
  47107. if fIsControl then
  47108. begin
  47109. PF := ParentForm;
  47110. if Assigned( PF.fCurrentControl ) and (PF.fCurrentControl <> @ Self) then
  47111. if Assigned( PF.fCurrentControl.fLeave ) then
  47112. PF.fCurrentControl.fLeave( PF.fCurrentControl )
  47113. else
  47114. Windows.SetFocus( 0 );
  47115. PF.fCurrentControl := @Self;
  47116. if Assigned( fSetFocus ) then
  47117. fSetFocus
  47118. else
  47119. SetFocus( GetWindowHandle );
  47120. end
  47121. else
  47122. SetForegroundWindow( GetWindowHandle );
  47123. end;
  47124. {$IFNDEF NOT_USE_RICHEDIT}
  47125. type
  47126. PCharFormat = ^TCharFormat;
  47127. //////////////////////////////////////////////////////////////////////
  47128. // R I C H E D I T
  47129. //////////////////////////////////////////////////////////////////////
  47130. { -- rich edit -- }
  47131. //*
  47132. //[function TControl.REGetFont]
  47133. function TControl.REGetFont: PGraphicTool;
  47134. var CF: PCharFormat;
  47135. FS: TFontStyle;
  47136. begin
  47137. CF := @fRECharFormatRec;
  47138. FillChar( CF^, Sizeof( CF^ ), #0 );
  47139. {$IFDEF UNICODE_CTRLS}
  47140. CF.cbSize := Sizeof( CF^ );
  47141. {$ELSE}
  47142. CF.cbSize := sizeof( RichEdit.TCharFormat ) + fCharFmtDeltaSz;
  47143. {$ENDIF}
  47144. if fTmpFont = nil then
  47145. begin
  47146. fTmpFont := NewFont;
  47147. {$IFDEF USE_AUTOFREE4CONTROLS}
  47148. Add2AutoFree( fTmpFont );
  47149. {$ENDIF}
  47150. end;
  47151. Result := fTmpFont;
  47152. Result.OnChange := nil;
  47153. Perform( EM_GETCHARFORMAT, 1, Integer( CF ) );
  47154. Result.FontHeight := CF.yHeight;
  47155. FS := [ ];
  47156. if LongBool(CF.dwEffects and CFE_BOLD) then
  47157. FS := [ fsBold ];
  47158. if LongBool(CF.dwEffects and CFE_ITALIC) then
  47159. FS := FS + [ fsItalic ];
  47160. if LongBool(CF.dwEffects and CFE_STRIKEOUT) then
  47161. FS := FS + [ fsStrikeOut ];
  47162. if LongBool(CF.dwEffects and CFE_UNDERLINE) then
  47163. FS := FS + [ fsUnderline ];
  47164. Result.FontStyle := FS;
  47165. if not LongBool(CF.dwEffects and CFE_AUTOCOLOR) then
  47166. Result.Color := CF.crTextColor;
  47167. Result.FontPitch := TFontPitch( CF.bPitchAndFamily and 3 );
  47168. Result.FontCharset := CF.bCharSet;
  47169. Result.FontName := CF.szFaceName;
  47170. Result.OnChange := RESetFont;
  47171. end;
  47172. const RichAreas: array[ TRichFmtArea ] of Integer = ( SCF_SELECTION,
  47173. SCF_WORD, 4 {SCF_ALL} );
  47174. //*
  47175. //[procedure TControl.RESetFontEx]
  47176. procedure TControl.RESetFontEx(const Index: Integer);
  47177. var CF: PCharFormat;
  47178. FS: TFontStyle;
  47179. begin
  47180. CF := @fRECharFormatRec;
  47181. FillChar( CF^, {82} sizeof( CF^ ), #0 );
  47182. {$IFDEF UNICODE_CTRLS}
  47183. CF.cbSize := Sizeof( CF^ );
  47184. {$ELSE}
  47185. CF.cbSize := 60 { sizeof( TCharFormat ) } + fCharFmtDeltaSz;
  47186. {$ENDIF}
  47187. CF.dwMask := CFM_BOLD or CFM_COLOR or CFM_FACE or CFM_ITALIC
  47188. or CFM_SIZE or CFM_STRIKEOUT or CFM_UNDERLINE;
  47189. CF.yHeight := fTmpFont.FontHeight;
  47190. FS := fTmpFont.FontStyle;
  47191. if fsBold in FS then CF.dwEffects := CFE_BOLD;
  47192. if fsItalic in FS then CF.dwEffects := CF.dwEffects or CFE_ITALIC;
  47193. if fsStrikeOut in FS then CF.dwEffects := CF.dwEffects or CFE_STRIKEOUT;
  47194. if fsUnderline in FS then CF.dwEffects := CF.dwEffects or CFE_UNDERLINE;
  47195. CF.crTextColor := Color2RGB(fTmpFont.Color);
  47196. CF.bCharSet := fTmpFont.FontCharset;
  47197. CF.bPitchAndFamily := Ord( fTmpFont.FontPitch );
  47198. {$IFDEF UNICODE_CTRLS} WStrLCopy {$ELSE} StrLCopy {$ENDIF}
  47199. ( CF.szFaceName, PKOLChar( fTmpFont.FontName ), 31 );
  47200. Perform( EM_SETCHARFORMAT, RichAreas[ fRECharArea ], Integer( CF ) );
  47201. end;
  47202. //*
  47203. //[procedure TControl.RESetFont]
  47204. procedure TControl.RESetFont(Value: PGraphicTool);
  47205. var H: Integer;
  47206. begin
  47207. if Value <> fTmpFont then
  47208. REGetFont;
  47209. H := fTmpFont.fData.Font.Height;
  47210. fTmpFont := fTmpFont.Assign( Value );
  47211. if fTmpFont.fData.Font.Height = 0 then
  47212. fTmpFont.fData.Font.Height := H;
  47213. RESetFontEx( Integer( CFM_BOLD or CFM_COLOR or CFM_FACE or CFM_ITALIC
  47214. or CFM_SIZE or CFM_STRIKEOUT or CFM_UNDERLINE ) );
  47215. end;
  47216. //*
  47217. //[function TControl.REGetFontMask]
  47218. function TControl.REGetFontMask( const Index: Integer ): Boolean;
  47219. begin
  47220. REGetFont;
  47221. Result := LongBool( fRECharFormatRec.dwMask and Index );
  47222. end;
  47223. //*
  47224. //[function TControl.REGetFontEffects]
  47225. function TControl.REGetFontEffects(const Index: Integer): Boolean;
  47226. begin
  47227. REGetFont;
  47228. Result := LongBool( fRECharFormatRec.dwEffects and Index );
  47229. end;
  47230. //*
  47231. //[procedure TControl.RESetFontEffect]
  47232. procedure TControl.RESetFontEffect(const Index: Integer;
  47233. const Value: Boolean);
  47234. var CF: PCharFormat;
  47235. begin
  47236. ReGetFont;
  47237. CF := @fRECharFormatRec;
  47238. CF.dwEffects := $FFFFFFFF and Index;
  47239. if not Value then CF.dwEffects := 0;
  47240. CF.dwMask := Index;
  47241. Perform( EM_SETCHARFORMAT, RichAreas[ fRECharArea ], Integer( CF ) );
  47242. end;
  47243. //*
  47244. //[function TControl.REGetFontAttr]
  47245. function TControl.REGetFontAttr(const Index: Integer): Integer;
  47246. var CF: PDWORD;
  47247. Mask: DWORD;
  47248. begin
  47249. REGetFont;
  47250. CF := Pointer( cardinal( @fRECharFormatRec ) + (HiWord(Index) and $7E) );
  47251. Mask := $FFFFFFFF;
  47252. if LongBool( HiWord(Index) and $1 ) then
  47253. Mask := $FF;
  47254. Result := CF^ and Mask;
  47255. end;
  47256. //*
  47257. //[procedure TControl.RESetFontAttr]
  47258. procedure TControl.RESetFontAttr(const Index, Value: Integer);
  47259. var CF: PDWORD;
  47260. Mask: DWORD;
  47261. begin
  47262. REGetFont;
  47263. CF := Pointer( cardinal( @fRECharFormatRec ) + (HiWord(Index) and $7E) );
  47264. Mask := 0;
  47265. if LongBool( HiWord(Index) and $1 ) then
  47266. Mask := $FFFFFF00;
  47267. CF^ := CF^ and Mask or DWORD(Value);
  47268. fRECharFormatRec.dwMask := Index and $FF81FFFF;
  47269. if LongBool( fRECharFormatRec.dwMask and (CFM_COLOR or CFM_BACKCOLOR) ) then
  47270. fRECharFormatRec.dwEffects := fRECharFormatRec.dwEffects and
  47271. not (CFE_AUTOCOLOR or CFE_AUTOBACKCOLOR);
  47272. Perform( EM_SETCHARFORMAT, RichAreas[ fRECharArea ], Integer( @fRECharFormatRec ) );
  47273. end;
  47274. //[procedure TControl.RESetFontAttr1]
  47275. procedure TControl.RESetFontAttr1(const Index, Value: Integer);
  47276. begin
  47277. RESetFontAttr( Index, Color2RGB( Value ) );
  47278. end;
  47279. //*
  47280. //[function TControl.REGetFontSizeValid]
  47281. function TControl.REGetFontSizeValid: Boolean;
  47282. begin
  47283. Result := REGetFontMask( Integer( CFM_SIZE ) );
  47284. end;
  47285. //*
  47286. //[function TControl.REGetFontName]
  47287. function TControl.REGetFontName: KOLString;
  47288. begin
  47289. ReGetFont;
  47290. Result := fRECharFormatRec.szFaceName;
  47291. end;
  47292. //*
  47293. //[procedure TControl.RESetFontName]
  47294. procedure TControl.RESetFontName(const Value: KOLString);
  47295. begin
  47296. ReGetFont;
  47297. {$IFDEF UNICODE_CTRLS} WStrLCopy {$ELSE} StrLCopy {$ENDIF}
  47298. ( fRECharFormatRec.szFaceName, PKOLChar( Value ), Sizeof( fRECharFormatRec.szFaceName ) - 1 );
  47299. fRECharFormatRec.dwMask := CFM_FACE;
  47300. Perform( EM_SETCHARFORMAT, RichAreas[ fRECharArea ], Integer( @fRECharFormatRec ) );
  47301. end;
  47302. //*
  47303. //[function TControl.REGetCharformat]
  47304. function TControl.REGetCharformat: TCharFormat;
  47305. begin
  47306. REGetFont;
  47307. Result := fRECharFormatRec;
  47308. end;
  47309. //*
  47310. //[procedure TControl.RESetCharFormat]
  47311. procedure TControl.RESetCharFormat(const Value: TCharFormat);
  47312. begin
  47313. Perform( EM_SETCHARFORMAT, RichAreas[ fRECharArea ], Integer( @Value ) );
  47314. end;
  47315. //*
  47316. //[function REOut2Stream]
  47317. function REOut2Stream( Sender: PControl; Buf: PByte; Sz: DWORD; pSz: PInteger )
  47318. :DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  47319. begin
  47320. if Sz + Sender.fREStream.Position > Sender.fREStream.Size then
  47321. Sender.fREStream.Size := Sender.fREStream.Size + DWORD( {Min(} Sz {, 8192 )} );
  47322. pSz^ := Sender.fREStream.Write( Buf^, Sz );
  47323. if Assigned( Sender.fOnProgress ) then
  47324. Sender.fOnProgress( Sender );
  47325. Result := 0;
  47326. end;
  47327. const TextTypes: array[ TRETextFormat ] of WORD = ( SF_RTF, SF_TEXT,
  47328. SF_RTF or SFF_PLAINRTF, SF_RTFNOOBJS, SF_RTFNOOBJS or SFF_PLAINRTF,
  47329. SF_TEXTIZED, {SF_UNICODE} $0010, $0010 or SF_TEXT );
  47330. //*
  47331. //[function TControl.RE_SaveToStream]
  47332. function TControl.RE_SaveToStream(Stream: PStream; Format: TRETextFormat;
  47333. SelectionOnly: Boolean): Boolean;
  47334. var ES: TEditStream;
  47335. SelFlag: Integer;
  47336. begin
  47337. fREStream := Stream;
  47338. ES.dwCookie := Integer( @Self );
  47339. ES.dwError := 0;
  47340. ES.pfnCallback := @REOut2Stream;
  47341. SelFlag := 0;
  47342. if SelectionOnly then
  47343. SelFlag := SFF_SELECTION;
  47344. Perform( EM_STREAMOUT, TextTypes[ Format ] or SelFlag, Integer( @ES ) );
  47345. fREStream := nil;
  47346. fREError := ES.dwError;
  47347. Result := fREError = 0;
  47348. end;
  47349. //[procedure RE_AddText]
  47350. procedure RE_AddText( Self_: PControl; const S: String );
  47351. begin
  47352. Self_.SelStart := Self_.TextSize;
  47353. Self_.RE_Text[ reText, True ] := S;
  47354. end;
  47355. //*
  47356. //[function TControl.REReadText]
  47357. function TControl.REReadText(Format: TRETextFormat;
  47358. SelectionOnly: Boolean): KOLString;
  47359. var B0: Integer;
  47360. MS: PStream;
  47361. begin
  47362. fCommandActions.aAddText := RE_AddText;
  47363. MS := NewMemoryStream;
  47364. RE_SaveToStream( MS, Format, SelectionOnly );
  47365. B0 := 0;
  47366. MS.Write( B0, Sizeof( KOLChar ) );
  47367. if not (Format in [reUnicode,reTextUnicode]) then
  47368. Result := PChar( MS.fMemory ) // must be PChar, not PKOLChar!
  47369. else
  47370. Result := PKOLChar( MS.fMemory );
  47371. MS.Free;
  47372. end;
  47373. //*
  47374. //[function REInFromStream]
  47375. function REInFromStream( Sender: PControl; Buf: PByte; Sz: DWORD; pSz: PInteger )
  47376. :DWORD; {$ifdef wince}cdecl{$else}stdcall{$endif};
  47377. begin
  47378. {$IFDEF _D3} if Sender.fREStrLoadLen >= 0 then {$ENDIF}
  47379. if Sz > Sender.fREStrLoadLen then
  47380. Sz := Sender.fREStrLoadLen;
  47381. pSz^ := Sender.fREStream.Read( Buf^, Sz );
  47382. Dec( Sender.fREStrLoadLen, pSz^ );
  47383. if Assigned( Sender.fOnProgress ) then
  47384. Sender.fOnProgress( Sender );
  47385. Result := 0;
  47386. end;
  47387. //*
  47388. //[function TControl.RE_LoadFromStream]
  47389. function TControl.RE_LoadFromStream(Stream: PStream; Length: Integer;
  47390. Format: TRETextFormat; SelectionOnly: Boolean): Boolean;
  47391. var ES: TEditStream;
  47392. SelFlag: Integer;
  47393. begin
  47394. fREStream := Stream;
  47395. fREStrLoadLen := DWORD( Length );
  47396. ES.dwCookie := Integer( @Self );
  47397. ES.dwError := 0;
  47398. ES.pfnCallback := @REInFromStream;
  47399. SelFlag := 0;
  47400. if SelectionOnly then
  47401. SelFlag := SFF_SELECTION;
  47402. Perform( EM_STREAMIN, TextTypes[ Format ] or SelFlag, Integer( @ES ) );
  47403. fREStream := nil;
  47404. fREError := ES.dwError;
  47405. Result := fREError = 0;
  47406. end;
  47407. //*
  47408. //[procedure TControl.REWriteText]
  47409. procedure TControl.REWriteText(Format: TRETextFormat;
  47410. SelectionOnly: Boolean; const Value: KOLString);
  47411. var MS: PStream;
  47412. s: String; // not KOLString!
  47413. begin
  47414. fCommandActions.aAddText := RE_AddText;
  47415. if not (Format in [reUnicode,reTextUnicode]) then
  47416. begin
  47417. s := Value;
  47418. MS := NewExMemoryStream( @ s[ 1 ], Length( s ) );
  47419. end
  47420. else
  47421. MS := NewExMemoryStream( @ Value[ 1 ], Length( Value ) * Sizeof( KOLChar ) );
  47422. RE_LoadFromStream( MS, MS.fData.fSize, Format, SelectionOnly );
  47423. MS.Free;
  47424. end;
  47425. //*
  47426. //[function TControl.RE_LoadFromFile]
  47427. function TControl.RE_LoadFromFile(const Filename: KOLString;
  47428. Format: TRETextFormat; SelectionOnly: Boolean): Boolean;
  47429. var Strm: PStream;
  47430. begin
  47431. Strm := NewReadFileStream( Filename );
  47432. Result := RE_LoadFromStream( Strm, -1, Format, SelectionOnly );
  47433. Strm.Free;
  47434. end;
  47435. //*
  47436. //[function TControl.RE_SaveToFile]
  47437. function TControl.RE_SaveToFile(const Filename: KOLString;
  47438. Format: TRETextFormat; SelectionOnly: Boolean): Boolean;
  47439. var Strm: PStream;
  47440. begin
  47441. Strm := NewWriteFileStream( Filename );
  47442. Result := RE_SaveToStream( Strm, Format, SelectionOnly );
  47443. Strm.Free;
  47444. end;
  47445. //*
  47446. //[function TControl.REGetParaFmt]
  47447. function TControl.REGetParaFmt: TParaFormat;
  47448. begin
  47449. FillChar( Result, sizeof( TParaFormat2 ), #0 );
  47450. Result.cbSize := sizeof( RichEdit.TParaFormat ) + fParaFmtDeltaSz;
  47451. Perform( EM_GETPARAFORMAT, 0, Integer( @Result ) );
  47452. end;
  47453. //*
  47454. //[procedure TControl.RESetParaFmt]
  47455. procedure TControl.RESetParaFmt(const Value: TParaFormat);
  47456. begin
  47457. //Value.cbSize := szTParaFmtRec;
  47458. Perform( EM_SETPARAFORMAT, 0, Integer( @Value ) );
  47459. end;
  47460. //*
  47461. //[function TControl.REGetNumbering]
  47462. function TControl.REGetNumbering: Boolean;
  47463. begin
  47464. Result := LongBool( ReGetParaAttr( 9 shl 16 ) );
  47465. end;
  47466. //*
  47467. //[function TControl.REGetParaAttr]
  47468. function TControl.REGetParaAttr( const Index: Integer ): Integer;
  47469. var pDw : PDWORD;
  47470. begin
  47471. fREParaFmtRec := REGetParaFmt;
  47472. pDw := Pointer( cardinal( @fREParaFmtRec ) + ( HiWord( Index ) and $7E ) );
  47473. Result := pDw^;
  47474. if LongBool( HiWord( Index ) and 1 ) then
  47475. Result := Result and $FFFF;
  47476. end;
  47477. //*
  47478. //[function TControl.REGetParaAttrValid]
  47479. function TControl.REGetParaAttrValid( const Index: Integer ): Boolean;
  47480. begin
  47481. Result := LongBool( ReGetParaAttr( 4 shl 16 ) and Index );
  47482. end;
  47483. //*
  47484. //[function TControl.REGetTabCount]
  47485. function TControl.REGetTabCount: Integer;
  47486. begin
  47487. Result := ReGetParaAttr( 27 shl 16 );
  47488. end;
  47489. //*
  47490. //[function TControl.REGetTabs]
  47491. function TControl.REGetTabs(Idx: Integer): Integer;
  47492. begin
  47493. Result := ReGetParaAttr( (28 + 4 * Idx) shl 16 );
  47494. end;
  47495. //*
  47496. //[function TControl.REGetTextAlign]
  47497. function TControl.REGetTextAlign: TRichTextAlign;
  47498. begin
  47499. Result := TRichTextAlign( ReGetParaAttr( 25 shl 16 ) - 1 );
  47500. end;
  47501. //*
  47502. //[procedure TControl.RESetNumbering]
  47503. procedure TControl.RESetNumbering(const Value: Boolean);
  47504. begin
  47505. RESetParaAttr( (9 shl 16) or PFM_NUMBERING, Integer( Value ) );
  47506. end;
  47507. //*
  47508. //[procedure TControl.RESetParaAttr]
  47509. procedure TControl.RESetParaAttr(const Index, Value: Integer);
  47510. var pDw: PDWORD;
  47511. Mask: Integer;
  47512. begin
  47513. REGetParaAttr( 0 );
  47514. pDw := Pointer( cardinal( @fREParaFmtRec ) + ( HiWord( Index ) and $7E ) );
  47515. Mask := 0;
  47516. if LongBool( HiWord( Index ) and 1 ) then
  47517. Mask := Integer( $FFFF0000 );
  47518. pDw^ := pDw^ and Mask or DWORD(Value);
  47519. fREParaFmtRec.dwMask := Index and $8000FFFF;
  47520. RESetParaFmt( fREParaFmtRec );
  47521. end;
  47522. //*
  47523. //[procedure TControl.RESetTabCount]
  47524. procedure TControl.RESetTabCount(const Value: Integer);
  47525. begin
  47526. REGetParaAttr( 0 );
  47527. RESetParaAttr( (27 shl 16) or PFM_TABSTOPS, Value );
  47528. end;
  47529. //*
  47530. //[procedure TControl.RESetTabs]
  47531. procedure TControl.RESetTabs(Idx: Integer; const Value: Integer);
  47532. begin
  47533. REGetParaAttr( 0 );
  47534. RESetParaAttr( (28 + 4 * Idx) or PFM_TABSTOPS, Value );
  47535. end;
  47536. //*
  47537. //[procedure TControl.RESetTextAlign]
  47538. procedure TControl.RESetTextAlign(const Value: TRichTextAlign);
  47539. begin
  47540. RESetParaAttr( (25 shl 16) or PFM_ALIGNMENT, Ord( Value ) + 1 );
  47541. end;
  47542. //*
  47543. //[function TControl.REGetStartIndentValid]
  47544. function TControl.REGetStartIndentValid: Boolean;
  47545. begin
  47546. Result := REGetParaAttrValid( Integer( PFM_STARTINDENT ) );
  47547. end;
  47548. //*
  47549. //[procedure TControl.RE_HideSelection]
  47550. procedure TControl.RE_HideSelection(aHide: Boolean);
  47551. begin
  47552. Perform( EM_HIDESELECTION, Integer( aHide ), 1 );
  47553. end;
  47554. //*
  47555. //[function TControl.RE_SearchText]
  47556. function TControl.RE_SearchText(const Value: KOLString; MatchCase,
  47557. WholeWord, ScanForward: Boolean; SearchFrom, SearchTo: Integer): Integer;
  47558. var Flags: Integer;
  47559. FT: {$IFDEF UNICODE_CTRLS} TFindTextW {$ELSE}
  47560. {$IFDEF _D2} TFindText {$ELSE} TFindTextA {$ENDIF} {$ENDIF};
  47561. begin
  47562. Flags := Integer( ScanForward );
  47563. if WholeWord then Flags := Flags or FT_WHOLEWORD;
  47564. if MatchCase then Flags := Flags or FT_MATCHCASE;
  47565. FT.chrg.cpMin := SearchFrom;
  47566. FT.chrg.cpMax := SearchTo;
  47567. FT.lpstrText := PKOLChar( Value );
  47568. Result := Perform( EM_FINDTEXT, Flags, Integer( @FT ) );
  47569. end;
  47570. {$IFNDEF _FPC}
  47571. {$IFNDEF _D2} //------- WideString not supported in D2
  47572. //[function TControl.RE_WSearchText]
  47573. function TControl.RE_WSearchText(const Value: WideString; MatchCase,
  47574. WholeWord, ScanForward: Boolean; SearchFrom, SearchTo: Integer): Integer;
  47575. var Flags: Integer;
  47576. FT: TFindTextW;
  47577. begin
  47578. Flags := Integer( ScanForward );
  47579. if WholeWord then Flags := Flags or FT_WHOLEWORD;
  47580. if MatchCase then Flags := Flags or FT_MATCHCASE;
  47581. FT.chrg.cpMin := SearchFrom;
  47582. FT.chrg.cpMax := SearchTo;
  47583. FT.lpstrText := PWideChar( Value );
  47584. Result := Perform( WM_USER+123 {EM_FINDTEXTW}, Flags, Integer( @FT ) );
  47585. end;
  47586. {$ENDIF}{$ENDIF}
  47587. {$ENDIF NOT_USE_RICHEDIT}
  47588. //*
  47589. //[function TControl.CanUndo]
  47590. function TControl.CanUndo: Boolean;
  47591. begin
  47592. Result := LongBool( Perform( EM_CANUNDO, 0, 0 ) );
  47593. end;
  47594. //*
  47595. //[procedure TControl.EmptyUndoBuffer]
  47596. procedure TControl.EmptyUndoBuffer;
  47597. begin
  47598. Perform( EM_EMPTYUNDOBUFFER, 0, 0 );
  47599. end;
  47600. //*
  47601. //[function TControl.Undo]
  47602. function TControl.Undo: Boolean;
  47603. begin
  47604. Result := LongBool( Perform( EM_UNDO, 0, 0 ) );
  47605. end;
  47606. //*
  47607. //[function TControl.GetMaxTextSize]
  47608. function TControl.GetMaxTextSize: DWORD;
  47609. begin
  47610. Result := Perform( EM_GETLIMITTEXT, 0, 0 );
  47611. end;
  47612. //*
  47613. //[procedure TControl.SetMaxTextSize]
  47614. procedure TControl.SetMaxTextSize(const Value: DWORD);
  47615. var V1, V2: Integer;
  47616. begin
  47617. if fCommandActions.aSetLimit <> 0 then
  47618. begin
  47619. V1 := 0; V2 := Value;
  47620. if fCommandActions.aSetLimit = EM_SETLIMITTEXT then
  47621. begin
  47622. V1 := Value; V2 := 0;
  47623. end;
  47624. Perform( fCommandActions.aSetLimit, V1, V2 );
  47625. end;
  47626. end;
  47627. {$IFNDEF NOT_USE_RICHEDIT}
  47628. //*
  47629. //[function TControl.RE_Redo]
  47630. function TControl.RE_Redo: Boolean;
  47631. begin
  47632. Result := LongBool( Perform( EM_REDO, 0, 0 ) );
  47633. end;
  47634. //*
  47635. //[function TControl.REGetAutoURLDetect]
  47636. function TControl.REGetAutoURLDetect: Boolean;
  47637. begin
  47638. Result := LongBool( Perform( EM_GETAUTOURLDETECT, 0, 0 ) );
  47639. end;
  47640. //*
  47641. //[procedure TControl.RESetAutoURLDetect]
  47642. procedure TControl.RESetAutoURLDetect(const Value: Boolean);
  47643. begin
  47644. AttachProc( WndProc_RE_LinkNotify );
  47645. Perform( EM_AUTOURLDETECT, Integer( Value ), 0 );
  47646. end;
  47647. procedure TControl.RESetZoom( const Value: TSmallPoint );
  47648. begin
  47649. Perform( EM_SETZOOM, Value.x, Value.y );
  47650. end;
  47651. function TControl.REGetZoom: TSmallPoint;
  47652. var P: TPoint;
  47653. begin
  47654. Perform( EM_GETZOOM, Integer( @ P.X ), Integer( @ P.Y ) );
  47655. Result := Point2SmallPoint( P );
  47656. end;
  47657. //*
  47658. //[function WndProc_REFmt]
  47659. function WndProc_REFmt( _Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  47660. var Mask: Integer;
  47661. Shft, Alt, Ctrl, Flg: Boolean;
  47662. Delta: Integer;
  47663. TA: TRichTextAlign;
  47664. ChgTA: Boolean;
  47665. US: TRichUnderline;
  47666. NS: TRichNumbering;
  47667. NB: TRichNumBrackets;
  47668. Side: TBorderEdge;
  47669. Param: DWORD;
  47670. begin
  47671. Result := False;
  47672. if Msg.message = WM_CHAR then
  47673. if _Self_.FSupressTab then
  47674. begin
  47675. _Self_.FSupressTab := FALSE;
  47676. if Msg.wParam = 9 then
  47677. begin
  47678. Result := TRUE;
  47679. Exit;
  47680. end;
  47681. end;
  47682. if (Msg.message = WM_KEYDOWN) or (Msg.message = WM_SYSKEYDOWN) then
  47683. begin
  47684. Ctrl := GetKeyState( VK_CONTROL ) < 0;
  47685. Alt := GetKeyState( VK_MENU ) < 0;
  47686. Param := Msg.wParam;
  47687. if Ctrl or
  47688. Alt and IntIn(Param, [ VK_ADD, VK_SUBTRACT, Integer( '-' ), Integer( '=' ),
  47689. Integer( '+' ), 189 {-}, 187 {+} ]) then
  47690. begin
  47691. Shft := GetKeyState( VK_SHIFT ) < 0;
  47692. Rslt := 0;
  47693. Result := True;
  47694. Mask := 0;
  47695. ChgTA := False; TA := raLeft;
  47696. case Param of
  47697. Integer('Z'):
  47698. begin
  47699. if Shft then
  47700. begin
  47701. _Self_.RE_Redo;
  47702. Exit;
  47703. end;
  47704. Result := False;
  47705. end;
  47706. Integer('L'): begin ChgTA := True; TA := raLeft; end;
  47707. Integer('R'): begin ChgTA := True; TA := raRight; end;
  47708. Integer('E'): begin ChgTA := True; TA := raCenter; end;
  47709. Integer('J'): begin ChgTA := True; TA := raJustify; end;
  47710. Integer('N'): begin
  47711. if Shft then
  47712. begin
  47713. NS := _Self_.RE_NumStyle;
  47714. NB := _Self_.RE_NumBrackets;
  47715. if NS = rnBullets then
  47716. begin
  47717. _Self_.RE_NumStyle := rnNone;
  47718. Exit;
  47719. end;
  47720. if NS = rnNone then
  47721. begin
  47722. _Self_.RE_NumStyle := rnBullets;
  47723. //NB := rnbPlain;
  47724. Exit;
  47725. end
  47726. else
  47727. if Ord( NB ) = 0 then
  47728. NB := High(NB) else
  47729. NB := Pred(NB);
  47730. _Self_.RE_NumBrackets := NB;
  47731. end
  47732. else
  47733. begin
  47734. NS := _Self_.RE_NumStyle;
  47735. if Ord( NS ) = 0 then
  47736. begin
  47737. NS := rnURoman; //rnULetter; //High( NS );
  47738. { because rnLRoman, rnURoman, rnNoNumber are not shown
  47739. in RichEdit. }
  47740. _Self_.RE_NumBrackets := rnbPeriod;
  47741. end else
  47742. NS := Pred(NS);
  47743. _Self_.RE_NumStyle := NS;
  47744. if NS in [ rnLRoman, rnURoman, rnArabic ] then
  47745. _Self_.RE_NumStart := 1;
  47746. end;
  47747. Exit;
  47748. end;
  47749. Integer('W'): begin
  47750. Delta := _Self_.RE_BorderWidth[ beLeft ] + 4;
  47751. if Shft then Delta := -1;
  47752. for Side := Low(Side) to High(Side) do
  47753. begin
  47754. if Delta < 0 then
  47755. _Self_.RE_BorderStyle[ Side ] := _Self_.RE_BorderStyle[ Side ] + 1
  47756. else
  47757. begin
  47758. _Self_.RE_BorderWidth[ Side ] := Delta;
  47759. _Self_.RE_BorderSpace[ Side ] := Delta;
  47760. end;
  47761. end;
  47762. Exit;
  47763. end;
  47764. (* TABLES STUFF -- to try, uncomment it and press CTRL+T in RichEdit.
  47765. (and uncomment declaration for Tmp above).
  47766. Not finished, and seems no way to figure it out - even RichEdit20.dll
  47767. (i.e. Rich Edit v3.0) can not display tables properly formatted. :(((
  47768. Integer('T'): begin
  47769. if _Self_.RE_Table then
  47770. begin
  47771. //MsgOK( 'table' );
  47772. end;
  47773. Tmp := _Self_.REReadText( reRTF, True );
  47774. if StrIsStartingFrom( PChar(Tmp), '{\rtf' )
  47775. and (CopyTail( Tmp, 3 ) = '}'#$D#$A) then
  47776. begin
  47777. //Tmp := Copy( Tmp, 1, Length(Tmp) - 3 );
  47778. _Self_.RE_Text[ reRTF, True ] := '{\rtf1' + //Copy( Tmp, 1, 6 ) +
  47779. '\trowd' +
  47780. //'\lytcalctblwd' +
  47781. //'\oldlinewrap' +
  47782. //'\alntblind' +
  47783. //'\trgaph108' +
  47784. '\trleft-108' +
  47785. {'\trbrdrt\brdrs\brdrw10' +
  47786. '\trbrdrl\brdrs\brdrw10' +
  47787. '\trbrdrb\brdrs\brdrw10' +
  47788. '\trbrdrr\brdrs\brdrw10' +
  47789. '\trbrdrh\brdrs\brdrw10' +
  47790. '\trbrdrv\brdrs\brdrw10' +}
  47791. //'\clvertalt' +
  47792. {'\clbrdrt\brdrs\brdrw10' +
  47793. '\clbrdrl\brdrs\brdrw10' +
  47794. '\clbrdrb\brdrs\brdrw10' +
  47795. '\clbrdrr\brdrs\brdrw10' +}
  47796. //'\cltxlrtb' +
  47797. '\cellx1414' +
  47798. //'\pard' +
  47799. //'\plain' +
  47800. //'\widctlpar' +
  47801. '\trautofit1' +
  47802. '\intbl' +
  47803. //'\adjustright' +
  47804. //'\fs20\lang1049' +
  47805. //'\cgrid' +
  47806. '\trrh0' +
  47807. '{\clFitText{{\box\brdrs\brdrw20\brsp20}'+
  47808. '\par}\cell\row}' +
  47809. //'\pard\widctlpar' +
  47810. //'\intbl'+
  47811. //'\adjustright'+
  47812. //'{\row}' +
  47813. '\pard\widctlpar' +
  47814. '}'#$D#$A;
  47815. _Self_.Perform( WM_KEYDOWN, VK_UP, 0 );
  47816. _Self_.Perform( WM_KEYUP, VK_UP, 0 );
  47817. end;
  47818. Exit;
  47819. end;
  47820. *)
  47821. Integer('B'): Mask := CFM_BOLD;
  47822. Integer('I'):
  47823. begin
  47824. Mask := CFM_ITALIC;
  47825. _Self_.FSupressTab := TRUE;
  47826. end;
  47827. Integer('U'):
  47828. begin
  47829. if Shft then
  47830. begin
  47831. US := _Self_.RE_FmtUnderlineStyle;
  47832. if Ord(US) = 0 then US := High(TRichUnderLine)
  47833. else US := Pred( US );
  47834. _Self_.RE_FmtUnderlineStyle := US;
  47835. Exit;
  47836. end;
  47837. Mask := CFM_UNDERLINE;
  47838. end;
  47839. Integer('O'): Mask := CFM_STRIKEOUT;
  47840. VK_SUBTRACT, VK_ADD, Integer( '+' ), 187, Integer( '-' ), 189:
  47841. ;
  47842. else
  47843. begin
  47844. Result := False;
  47845. Msg.wParam := Param;
  47846. end;
  47847. end;
  47848. if not Result then Exit;
  47849. if ChgTA then
  47850. begin
  47851. if Shft then Result := False
  47852. else _Self_.RE_TextAlign := TA;
  47853. Exit;
  47854. end;
  47855. _Self_.REGetFont;
  47856. if Mask > 0 then
  47857. begin
  47858. if Shft then Result := False
  47859. else begin
  47860. Flg := _Self_.REGetFontEffects( Mask );
  47861. if not Flg then
  47862. _Self_.fRECharFormatRec.dwEffects := _Self_.fRECharFormatRec.dwEffects and not Mask;
  47863. _Self_.fRECharFormatRec.dwEffects := _Self_.fRECharFormatRec.dwEffects xor DWORD(Mask);
  47864. end;
  47865. end
  47866. else
  47867. if IntIn( Param, [ VK_ADD, VK_SUBTRACT, Integer( '+' ),
  47868. Integer( '-' ), 189, 187 ] ) then
  47869. begin
  47870. if (Param = VK_SUBTRACT) or (Param = DWORD( '-' )) or (Param = 189) then
  47871. Delta := -1
  47872. else
  47873. Delta := 1;
  47874. if Alt and Ctrl then
  47875. begin
  47876. Mask := Integer( CFM_SIZE ) or Integer( CFM_OFFSET );
  47877. Delta := 0;
  47878. _Self_.fRECharFormatRec.yOffset := 0;
  47879. _Self_.fRECharFormatRec.yHeight := 200;
  47880. end
  47881. else
  47882. if Alt then Mask := Integer( CFM_SIZE )
  47883. else Mask := Integer( CFM_OFFSET );
  47884. Inc( _Self_.fRECharFormatRec.yOffset, Delta * _Self_.fRECharFormatRec.yHeight div 3 );
  47885. Inc( _Self_.fRECharFormatRec.yHeight, Delta * _Self_.fRECharFormatRec.yHeight div 8 );
  47886. Flg := LongBool( _Self_.fRECharFormatRec.dwMask and Mask );
  47887. if not Flg then
  47888. _Self_.fRECharFormatRec.yOffset := 0;
  47889. end;
  47890. _Self_.fRECharFormatRec.dwMask := Mask;
  47891. if _Self_.SelLength = 0 then
  47892. _Self_.SelLength := 1;
  47893. _Self_.Perform( EM_SETCHARFORMAT, SCF_SELECTION { RichAreas[ _Self_.fRECharArea ] }, Integer( @_Self_.fRECharFormatRec ) );
  47894. end;
  47895. end;
  47896. end;
  47897. //*
  47898. //[function TControl.RE_FmtStandard]
  47899. function TControl.RE_FmtStandard: PControl;
  47900. begin
  47901. AttachProc( WndProc_REFmt );
  47902. Result := @Self;
  47903. end;
  47904. procedure TControl.RE_CancelFmtStandard;
  47905. begin
  47906. DetachProc( WndProc_REFmt );
  47907. end;
  47908. {$ENDIF NOT_USE_RICHEDIT}
  47909. //[FUNCTION EnumDynHandlers]
  47910. {$IFDEF ASM_VERSION}
  47911. {$ELSE ASM_VERSION} //Pascal
  47912. function EnumDynHandlers( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  47913. var I: Integer;
  47914. Proc: TWindowFunc;
  47915. begin
  47916. Result := False;
  47917. if Self_.fRefCount < 0 then Exit;
  47918. if (Self_.fDynHandlers = nil) or (Self_.fDynHandlers.fCount = 0) then Exit;
  47919. Self_.RefInc; // Prevent destroying Self_
  47920. for I := Self_.fDynHandlers.fCount div 2 - 1 downto 0 do
  47921. begin
  47922. Proc := Self_.fDynHandlers.fItems[ I * 2 ];
  47923. {$IFNDEF SMALLEST_CODE}
  47924. {$IFNDEF ENUM_DYN_HANDLERS_AFTER_RUN}
  47925. if not AppletTerminated or (Self_.fDynHandlers.fItems[ I * 2 + 1 ] <> nil) then
  47926. {$ENDIF}
  47927. {$ENDIF}
  47928. if Proc( Self_, Msg, Rslt ) then
  47929. begin
  47930. Result := True;
  47931. break;
  47932. end;
  47933. end;
  47934. {$IFDEF DEBUG_ENDSESSION}
  47935. if EndSession_Initiated then
  47936. begin
  47937. LogFileOutput( GetStartDir + 'es_debug.txt',
  47938. 'ENUM_DYN_HANDLERS: Self_:' + Int2Hex( DWORD( Self_ ), 8 ) );
  47939. LogFileOutput( GetStartDir + 'es_debug.txt',
  47940. 'ENUM_DYN_HANDLERS: Self_.fRefCount:' + Int2Str( Self_.fRefCount ) );
  47941. end;
  47942. {$ENDIF}
  47943. if LongBool(Self_.fRefCount and 1) then
  47944. Result := True; // If Self_ will be destroyed now, stop further processing
  47945. Self_.RefDec; // Destroy Self_, if Free was called for it while processing attached procedures
  47946. end;
  47947. {$ENDIF ASM_VERSION}
  47948. //[END EnumDynHandlers]
  47949. {$ifdef win32}
  47950. procedure TransparentAttachProcExtension ( DynHandlers: PList );
  47951. var i: integer;
  47952. begin
  47953. I := DynHandlers.IndexOf( @WndProcTransparent );
  47954. if I >=0 then begin
  47955. DynHandlers.Delete( I );
  47956. DynHandlers.Delete( I );
  47957. DynHandlers.Add( @WndProcTransparent );
  47958. DynHandlers.Add( nil );
  47959. end;
  47960. end;
  47961. {$endif win32}
  47962. procedure DummyAttachProcExtension ( DynHandlers: PList );
  47963. begin
  47964. end;
  47965. //[procedure TControl.AttachProcEx]
  47966. {$IFDEF ASM_VERSION}
  47967. {$ELSE ASM_VERSION} //Pascal
  47968. procedure TControl.AttachProcEx( Proc: TWindowFunc; ExecuteAfterAppletTerminated: Boolean );
  47969. begin
  47970. //if fDynHandlers = nil then
  47971. // fDynHandlers := NewList;
  47972. if not IsProcAttached( Proc ) then
  47973. begin
  47974. fDynHandlers.Add( @Proc );
  47975. fDynHandlers.Add( Pointer( Integer( ExecuteAfterAppletTerminated ) ) );
  47976. end;
  47977. {$IFNDEF SMALLEST_CODE}
  47978. Global_AttachProcExtension(fDynHandlers);
  47979. {$ENDIF}
  47980. fOnDynHandlers := EnumDynHandlers;
  47981. end;
  47982. {$ENDIF ASM_VERSION}
  47983. //[procedure TControl.AttachProc]
  47984. procedure TControl.AttachProc(Proc: TWindowFunc);
  47985. begin
  47986. AttachProcEx( Proc, FALSE );
  47987. end;
  47988. //*
  47989. //[procedure TControl.DetachProc]
  47990. procedure TControl.DetachProc(Proc: TWindowFunc);
  47991. var I: Integer;
  47992. begin
  47993. if fDynHandlers = nil then Exit;
  47994. I := fDynHandlers.IndexOf( @Proc );
  47995. if I >=0 then
  47996. begin
  47997. fDynHandlers.Delete( I );
  47998. fDynHandlers.Delete( I );
  47999. end;
  48000. end;
  48001. //[function TControl.IsProcAttached]
  48002. {$IFDEF ASM_VERSION}
  48003. {$ELSE ASM_VERSION} //Pascal
  48004. function TControl.IsProcAttached(Proc: TWindowFunc): Boolean;
  48005. var I: Integer;
  48006. begin
  48007. //Result := False;
  48008. //if fDynHandlers = nil then Exit;
  48009. I := fDynHandlers.IndexOf( @Proc );
  48010. Result := I >=0;
  48011. end;
  48012. {$ENDIF ASM_VERSION}
  48013. //[function WndProcAutoPopupMenu]
  48014. function WndProcAutoPopupMenu( Control: PControl; var Msg: TMsg; var MsgRslt: Integer ): Boolean;
  48015. function GetMenuPoint: TPoint;
  48016. var
  48017. R: TRect;
  48018. I, M: Integer;
  48019. begin
  48020. R:=Control.ClientRect;
  48021. Result.x:=(R.Left + R.Right) div 2;
  48022. Result.y:=R.Bottom;
  48023. I := Control.CurIndex;
  48024. M := Control.fCommandActions.aItem2XY;
  48025. if (I >= 0) and (M <> 0) then begin
  48026. CASE M OF
  48027. EM_POSFROMCHAR:
  48028. begin
  48029. I := Control.SelStart + Control.SelLength;
  48030. I := Control.Perform( M, I, 1 );
  48031. Result.X := SmallInt( LoWord( I ) );
  48032. Result.Y := SmallInt( HiWord( I ) );
  48033. end;
  48034. LB_GETITEMRECT, LVM_GETITEMRECT, TCM_GETITEMRECT:
  48035. begin
  48036. R.Left := LVIR_BOUNDS;
  48037. Control.Perform( M, I, Integer( @ R ) );
  48038. R.Left:=Max(R.Left, 0);
  48039. R.Right:=Min(R.Right, ScreenWidth);
  48040. Result.X := (R.Left + R.Right) div 2;
  48041. Result.Y := R.Bottom;
  48042. end;
  48043. TVM_GETITEMRECT:
  48044. begin
  48045. I := Control.TVSelected;
  48046. R.Left := I;
  48047. Control.Perform( M, 1, Integer( @ R ) );
  48048. Result.X := (R.Left + R.Right) div 2;
  48049. Result.Y := R.Bottom;
  48050. end;
  48051. END;
  48052. R := Control.ClientRect;
  48053. if Result.X < R.Left then Result.X := R.Left;
  48054. if Result.X > R.Right then Result.X := R.Right;
  48055. if Result.Y < R.Top then Result.Y := R.Top;
  48056. if Result.Y > R.Bottom then Result.Y := R.Bottom;
  48057. end;
  48058. end;
  48059. var P: TPoint;
  48060. {$ifdef wince}
  48061. shrg: SHRGINFO;
  48062. {$endif wince}
  48063. begin
  48064. {$ifdef wince}
  48065. if (Control.fAutoPopupMenu <> nil) and ((Msg.message = WM_LBUTTONDOWN) or (Msg.message = WM_KEYDOWN)) then begin
  48066. if Msg.message = WM_KEYDOWN then
  48067. P:=GetMenuPoint
  48068. else begin
  48069. P.X := SmallInt( LoWord( Msg.lParam ) );
  48070. P.Y := SmallInt( HiWord( Msg.lParam ) );
  48071. end;
  48072. with shrg do begin
  48073. cbSize:=SizeOf(shrg);
  48074. hwndClient:=Control.Handle;
  48075. ptDown.x:=P.X;
  48076. ptDown.y:=P.Y;
  48077. dwFlags:=SHRG_RETURNCMD;
  48078. end;
  48079. if (SHRecognizeGesture(shrg) = GN_CONTEXTMENU) and (Msg.message = WM_KEYDOWN) then begin
  48080. MsgRslt:=0;
  48081. Result:=True;
  48082. end
  48083. else
  48084. Result:=False;
  48085. end
  48086. else
  48087. {$endif wince}
  48088. if (Msg.message = WM_CONTEXTMENU) and
  48089. (Control.fAutoPopupMenu <> nil) then
  48090. begin
  48091. {$IFDEF USE_MENU_CURCTL}
  48092. PMenu( Control.fAutoPopupMenu ).fCurCtl := Control;
  48093. {$ENDIF USE_MENU_CURCTL}
  48094. if (Msg.lParam = -1) then
  48095. P:=Control.Client2Screen(GetMenuPoint)
  48096. else begin
  48097. P.X := SmallInt( LoWord( Msg.lParam ) );
  48098. P.Y := SmallInt( HiWord( Msg.lParam ) );
  48099. end;
  48100. PMenu( Control.fAutoPopupMenu ).Popup( P.X, P.Y );
  48101. Result := TRUE;
  48102. end
  48103. else
  48104. Result := FALSE;
  48105. end;
  48106. //[procedure TControl.SetAutoPopupMenu]
  48107. procedure TControl.SetAutoPopupMenu(PopupMenu: PObj);
  48108. { new version - by Alexander Pravdin. Allows to attach a submenu (e.g. of the
  48109. main menu) as a popup menu to a control, to avoid duplicating menu object,
  48110. if it is the same already as desired. }
  48111. var pm: PMenu;
  48112. begin
  48113. if PopupMenu <> nil then
  48114. {$IFDEF USE_MENU_CURCTL}
  48115. begin
  48116. pm := PMenu( PopupMenu );
  48117. if ( pm.FParentMenu <> nil ) then
  48118. begin
  48119. while pm.FControl = nil do
  48120. pm := pm.FParentMenu;
  48121. PMenu( PopupMenu ).FControl := pm.FControl;
  48122. end
  48123. else
  48124. if pm.FControl = nil then
  48125. PMenu( PopupMenu ).FControl := @Self;
  48126. AttachProc(WndProcAutoPopupMenu);
  48127. AttachProc(WndProcMenu)
  48128. end
  48129. else begin
  48130. DetachProc(WndProcAutoPopupMenu);
  48131. DetachProc(WndProcMenu);
  48132. end;
  48133. {$ELSE}
  48134. begin
  48135. pm := PMenu( PopupMenu );
  48136. while pm.FControl = nil do pm := pm.Parent;
  48137. PMenu( PopupMenu ).FControl := pm.FControl;
  48138. end;
  48139. {$ENDIF}
  48140. fAutoPopupMenu := PopupMenu;
  48141. {$IFNDEF USE_MENU_CURCTL}
  48142. AttachProc( WndProcAutoPopupMenu );
  48143. {$ENDIF}
  48144. end;
  48145. {$ifdef win32}
  48146. //[function SearchAnsiMnemonics]
  48147. function SearchAnsiMnemonics( const S: KOLString ): KOLString;
  48148. var I: Integer;
  48149. Sh: ShortInt;
  48150. begin
  48151. Result := S;
  48152. for I := 1 to Length( Result ) do
  48153. begin
  48154. Sh := VkKeyScanEx( Result[ I ], MnemonicsLocale );
  48155. if Sh <> -1 then
  48156. Result[ I ] := KOLChar( Sh );
  48157. end;
  48158. end;
  48159. //[procedure SupportAnsiMnemonics]
  48160. procedure SupportAnsiMnemonics( LocaleID: Integer );
  48161. begin
  48162. MnemonicsLocale := LocaleID;
  48163. SearchMnemonics := SearchAnsiMnemonics;
  48164. end;
  48165. //[function WndProcMnemonics]
  48166. function WndProcMnemonics( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48167. var Form: PControl;
  48168. function HandleMnemonic( Prnt: PControl ): Boolean;
  48169. var C: PControl;
  48170. XY: Integer;
  48171. procedure DoPressMnemonic;
  48172. begin
  48173. if Msg.message = WM_SYSKEYDOWN then
  48174. begin
  48175. Form.FPressedMnemonic := Msg.wParam;
  48176. C.Perform( WM_LBUTTONDOWN, MK_LBUTTON, XY );
  48177. end
  48178. else
  48179. begin
  48180. Form.FPressedMnemonic := 0;
  48181. C.Perform( WM_LBUTTONUP, MK_LBUTTON, XY );
  48182. end;
  48183. end;
  48184. var I, J: Integer;
  48185. R: TRect;
  48186. begin
  48187. for I := 0 to Prnt.ChildCount-1 do
  48188. begin
  48189. C := Prnt.Children[ I ];
  48190. if not C.Visible then continue; // {YS} Do not process hidden controls
  48191. if C.IsButton then
  48192. if C.Enabled then
  48193. begin
  48194. if C.fCommandActions.aGetCount = TB_BUTTONCOUNT then
  48195. for J := 0 to C.Count-1 do
  48196. begin
  48197. if C.TBButtonEnabled[ J ] then
  48198. if pos( '&' + Char( Msg.wParam ), SearchMnemonics( C.TBButtonText[ J ] ) ) > 0 then
  48199. begin
  48200. C.fCurIndex := J;
  48201. C.fCurItem := C.TBIndex2Item( J );
  48202. R := C.TBButtonRect[ J ];
  48203. XY := R.Left or (R.Top shl 16);
  48204. DoPressMnemonic;
  48205. Result := TRUE;
  48206. Exit;
  48207. end;
  48208. end;
  48209. if pos( '&' + Char( Msg.wParam ), SearchMnemonics( C.Caption ) ) > 0 then
  48210. begin
  48211. XY := 0;
  48212. DoPressMnemonic;
  48213. Result := TRUE;
  48214. Exit;
  48215. end;
  48216. end;
  48217. if HandleMnemonic( C ) then
  48218. begin
  48219. Result := TRUE;
  48220. Exit;
  48221. end;
  48222. end;
  48223. Result := FALSE;
  48224. end;
  48225. {$IFDEF NEW_MENU_ACCELL}
  48226. function FindByCtlRef(C: PControl; Accell: TMenuAccelerator): Boolean;
  48227. function FindInMenu(M: PMenu): PMenu;
  48228. var
  48229. I: Integer;
  48230. SM: PMenu;
  48231. begin
  48232. for I := 0 to M.FItems.Count - 1 do begin
  48233. Result := M.FItems.Items[I];
  48234. if (Cardinal(Result.Accelerator) = Cardinal(Accell)) and Result.Enabled then
  48235. Exit;
  48236. end;
  48237. Result := nil;
  48238. for I := 0 to M.FItems.Count - 1 do begin
  48239. SM := PMenu(M.FItems.Items[I]);
  48240. if (SM.FItems.Count > 0) then
  48241. Result := FindInMenu(SM);
  48242. if (Result <> nil) then
  48243. Break;
  48244. end;
  48245. end;
  48246. function FindInMenu2(M: PMenu): Boolean;
  48247. var
  48248. MI: PMenu;
  48249. begin
  48250. if (M <> nil) then begin
  48251. MI := FindInMenu(M);
  48252. if (MI <> nil) then begin
  48253. //M.FControl.Perform(WM_COMMAND, MI.FId, 0);
  48254. C.Perform(WM_COMMAND, MI.FId, 0); // fixed
  48255. Result := True;
  48256. Exit;
  48257. end;
  48258. end;
  48259. Result := False;
  48260. end;
  48261. var
  48262. Parent: PControl;
  48263. begin
  48264. Result := False;
  48265. if not FindInMenu2(PMenu(C.fAutoPopupMenu)) then
  48266. if not FindInMenu2(PMenu(C.fMenuObj)) then begin
  48267. Parent := C.Parent;
  48268. if (Parent <> nil) then
  48269. Result := FindByCtlRef(Parent, Accell);
  48270. end;
  48271. end;
  48272. var
  48273. Ac: TMenuAccelerator;
  48274. {$ENDIF}
  48275. begin
  48276. Result := FALSE;
  48277. if (Msg.message >= WM_KEYFIRST) and (Msg.message <= WM_KEYLAST) then
  48278. begin
  48279. {$IFDEF NEW_MENU_ACCELL}
  48280. Ac := MakeAccelerator(FVIRTKEY or GetShiftState, Msg.wParam);
  48281. Result := FindByCtlRef(Sender, Ac);
  48282. {$ELSE}
  48283. if (Sender.fAccelTable <> 0)
  48284. {$IFDEF KEY_PREVIEW}
  48285. and (Sender.FKeyPreviewCount = 0)
  48286. {$ENDIF}
  48287. then
  48288. Result := LongBool( TranslateAccelerator( Sender.fHandle, Sender.fAccelTable, Msg ) );
  48289. if not Result then
  48290. begin
  48291. if Sender.fCurrentControl <> nil then
  48292. if Sender.fCurrentControl.fAccelTable <> 0 then
  48293. Result := LongBool( TranslateAccelerator( Sender.fCurrentControl.fHandle,
  48294. Sender.fCurrentControl.fAccelTable, Msg ) );
  48295. end;
  48296. if not Result then
  48297. begin
  48298. Form := Sender.ParentForm;
  48299. if (Form <> nil) and (Form <> Sender)
  48300. {$IFDEF KEY_PREVIEW}
  48301. and (Form.FKeyPreviewCount = 0)
  48302. {$ENDIF KEY_PREVIEW}
  48303. then
  48304. if Form.fAccelTable <> 0 then
  48305. Result := LongBool( TranslateAccelerator( Form.fHandle,
  48306. Form.fAccelTable, Msg ) );
  48307. end;
  48308. {$ENDIF}
  48309. end;
  48310. if Result then Exit;
  48311. if (Msg.message = WM_SYSKEYUP) or
  48312. (Msg.message = WM_SYSKEYDOWN) and (GetKeyState( VK_MENU ) < 0) then
  48313. begin
  48314. Rslt := 0;
  48315. Form := Sender.ParentForm;
  48316. if Form <> nil then
  48317. begin
  48318. if Char( Msg.wParam ) in [ 'A'..'Z', '0'..'9' ] then
  48319. begin
  48320. if HandleMnemonic( Form ) then
  48321. begin
  48322. Result := TRUE;
  48323. Exit;
  48324. end;
  48325. end;
  48326. end;
  48327. end
  48328. else
  48329. if Msg.message = WM_KEYUP then
  48330. begin
  48331. Rslt := 0;
  48332. Form := Sender.ParentForm;
  48333. if Form <> nil then
  48334. begin
  48335. if Msg.wParam = VK_MENU then
  48336. begin
  48337. if Form.FPressedMnemonic <> 0 then
  48338. Form.FPressedMnemonic := Form.FPressedMnemonic or $80000000;
  48339. end
  48340. else
  48341. if Char( Msg.wParam ) in [ 'A'..'Z', '0'..'9' ] then
  48342. begin
  48343. if HandleMnemonic( Form ) then
  48344. begin
  48345. Result := TRUE;
  48346. Exit;
  48347. end;
  48348. end;
  48349. end;
  48350. end;
  48351. Result := FALSE;
  48352. end;
  48353. {$endif win32}
  48354. //[function TControl.SupportMnemonics]
  48355. function TControl.SupportMnemonics: PControl;
  48356. begin
  48357. {$ifdef win32}
  48358. fGlobalProcKeybd := WndProcMnemonics;
  48359. {$endif win32}
  48360. Result := @Self;
  48361. end;
  48362. //*
  48363. //[procedure TControl.SelectAll]
  48364. procedure TControl.SelectAll;
  48365. begin
  48366. SelStart := 0;
  48367. SelLength := -1; // this can be not working for some controls... //*//*
  48368. end;
  48369. {$IFNDEF NOT_USE_RICHEDIT}
  48370. //*
  48371. //[API RevokeDragDrop]
  48372. function RevokeDragDrop(wnd: HWnd): HResult; {$ifdef wince}cdecl{$else}stdcall{$endif};
  48373. external 'ole32.dll' name 'RevokeDragDrop';
  48374. //*
  48375. //[function TControl.RE_NoOLEDragDrop]
  48376. function TControl.RE_NoOLEDragDrop: PControl;
  48377. begin
  48378. RevokeDragDrop( Handle );
  48379. Result := @Self;
  48380. end;
  48381. {$ENDIF NOT_USE_RICHEDIT}
  48382. //*
  48383. //[function WndProcOnResize]
  48384. function WndProcOnResize( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48385. begin
  48386. if Msg.message = WM_SIZE then
  48387. begin
  48388. if Assigned( Self_.fOnResize ) then
  48389. Self_.fOnResize( Self_ );
  48390. end;
  48391. Result := False;
  48392. end;
  48393. //*
  48394. //[procedure TControl.SetOnResize]
  48395. procedure TControl.SetOnResize(const Value: TOnEvent);
  48396. begin
  48397. FOnResize := Value;
  48398. AttachProc( WndProcOnResize );
  48399. end;
  48400. //[function WndProcMove]
  48401. function WndProcMove( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48402. begin
  48403. if Msg.message = WM_MOVE then
  48404. begin
  48405. if Assigned( Self_.FOnMove ) then
  48406. Self_.FOnMove( Self_ );
  48407. end;
  48408. Result := False;
  48409. end;
  48410. //[procedure TControl.SetOnMove]
  48411. procedure TControl.SetOnMove(const Value: TOnEvent);
  48412. begin
  48413. FOnMove := Value;
  48414. AttachProc( WndProcMove );
  48415. end;
  48416. //[function WndProcMove]
  48417. function WndProcMoving( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48418. begin
  48419. Result := False;
  48420. if Msg.message = WM_MOVING then
  48421. begin
  48422. if Assigned( Self_.FOnMoving ) then
  48423. Self_.FOnMoving( Self_, Pointer( Msg.lParam ) );
  48424. Rslt := 1;
  48425. Result := TRUE;
  48426. end;
  48427. end;
  48428. procedure TControl.SetOnMoving(const Value: TOnEventMoving);
  48429. begin
  48430. FOnMoving := Value;
  48431. AttachProc( WndProcMoving );
  48432. end;
  48433. {$IFNDEF NOT_USE_RICHEDIT}
  48434. //[function WndProc_REBottomless]
  48435. function WndProc_REBottomless( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48436. begin
  48437. if Msg.message = WM_SIZE then
  48438. Self_.Perform( EM_REQUESTRESIZE, 0, 0 );
  48439. Result := False;
  48440. end;
  48441. //*
  48442. //[function TControl.RE_Bottomless]
  48443. function TControl.RE_Bottomless: PControl;
  48444. begin
  48445. AttachProc( WndProc_REBottomless );
  48446. Result := @Self;
  48447. end;
  48448. //*
  48449. //[procedure TControl.RE_Append]
  48450. procedure TControl.RE_Append(const S: KOLString; ACanUndo: Boolean);
  48451. begin
  48452. SelStart := TextSize;
  48453. if S <> '' then
  48454. begin
  48455. ReplaceSelection( S, ACanUndo );
  48456. SelStart := TextSize;
  48457. end;
  48458. end;
  48459. //*
  48460. //[procedure TControl.RE_InsertRTF]
  48461. procedure TControl.RE_InsertRTF(const S: KOLString);
  48462. var MS: PStream;
  48463. begin
  48464. MS := NewMemoryStream;
  48465. MS.Size := (Length( S ) + 1) * Sizeof(KOLChar);
  48466. Move( S[ 1 ], MS.Memory^, ( Length( S ) + 1 ) * Sizeof( KOLChar ) );
  48467. RE_LoadFromStream( MS, Length( S ), reRTF, TRUE );
  48468. MS.Free;
  48469. end;
  48470. {$ENDIF NOT_USE_RICHEDIT}
  48471. //*
  48472. //[procedure TControl.DoSelChange]
  48473. procedure TControl.DoSelChange;
  48474. begin
  48475. if Assigned( fOnSelChange ) then fOnSelChange( @Self )
  48476. else
  48477. if Assigned( fOnChange ) then fOnChange( @Self );
  48478. end;
  48479. //*
  48480. //[function TControl.GetTextSize]
  48481. function TControl.GetTextSize: Integer;
  48482. begin
  48483. Result := 0;
  48484. if fHandle <> 0 then
  48485. Result := GetWindowTextLength( fHandle );
  48486. end;
  48487. {$IFNDEF NOT_USE_RICHEDIT}
  48488. //*
  48489. //[function TControl.REGetUnderlineEx]
  48490. function TControl.REGetUnderlineEx: TRichUnderline;
  48491. begin
  48492. Result := TRichUnderline( REGetFontAttr( ((81
  48493. {$IFDEF UNICODE_CTRLS} + 32 {$ENDIF})
  48494. shl 16) or CFM_UNDERLINETYPE ) - 1 );
  48495. end;
  48496. //*
  48497. //[procedure TControl.RESetUnderlineEx]
  48498. procedure TControl.RESetUnderlineEx(const Value: TRichUnderline);
  48499. begin
  48500. RESetFontAttr( ((81
  48501. {$IFDEF UNICODE_CTRLS} + 32 {$ENDIF})
  48502. shl 16) or CFM_UNDERLINETYPE, Ord( Value ) + 1 );
  48503. RESetFontEffect( CFM_UNDERLINE, True );
  48504. end;
  48505. //*
  48506. //[function TControl.REGetTextSize]
  48507. function TControl.REGetTextSize(Units: TRichTextSize): Integer;
  48508. const TextLengthFlags: array[ TRichTextSizes ] of Integer =
  48509. ( not GTL_UseCRLF, not GTL_Precise, GTL_Close, GTL_NUMBytes );
  48510. var GTL: TGetTextLengthEx;
  48511. begin
  48512. GTL.flags := MakeFlags( @Units, TextLengthFlags );
  48513. if not(rtsBytes in Units) then
  48514. GTL.flags := GTL.flags or GTL_NUMCHARS;
  48515. GTL.codepage := CP_ACP;
  48516. Result := Perform( EM_GETTEXTLENGTHEX, Integer( @GTL ), 0 );
  48517. end;
  48518. //[function TControl.RE_TextSizePrecise]
  48519. function TControl.RE_TextSizePrecise: Integer;
  48520. var gtlex : TGetTextLengthEx;
  48521. begin
  48522. gtlex.flags := GTL_PRECISE;
  48523. gtlex.codepage := CP_ACP;
  48524. Result := Perform(EM_GETTEXTLENGTHEX,WPARAM(@gtlex), 0 );
  48525. end;
  48526. //*
  48527. //[function TControl.REGetNumStyle]
  48528. function TControl.REGetNumStyle: TRichNumbering;
  48529. begin
  48530. Result := TRichNumbering( ReGetParaAttr( 9 shl 16 ) );
  48531. end;
  48532. //*
  48533. //[procedure TControl.RESetNumStyle]
  48534. procedure TControl.RESetNumStyle(const Value: TRichNumbering);
  48535. begin
  48536. RESetParaAttr( (9 shl 16) or PFM_NUMBERING, Ord( Value ) );
  48537. end;
  48538. //*
  48539. //[function TControl.REGetNumBrackets]
  48540. function TControl.REGetNumBrackets: TRichNumBrackets;
  48541. begin
  48542. REGetParaAttr( 0 );
  48543. Result := TRichNumBrackets( (fREParaFmtRec.wNumberingStyle shr 8) {and 3} );
  48544. end;
  48545. //*
  48546. //[procedure TControl.RESetNumBrackets]
  48547. procedure TControl.RESetNumBrackets(const Value: TRichNumBrackets);
  48548. begin
  48549. REGetParaAttr( 0 );
  48550. fREParaFmtRec.wNumberingStyle := fREParaFmtRec.wNumberingStyle and $F8FF
  48551. or Word( Ord( Value ) shl 8 );
  48552. fREParaFmtRec.dwMask := PFM_NUMBERINGSTYLE;
  48553. RE_ParaFmt := fREParaFmtRec;
  48554. end;
  48555. //*
  48556. //[function TControl.REGetNumTab]
  48557. function TControl.REGetNumTab: Integer;
  48558. begin
  48559. REGetParaAttr( 0 );
  48560. Result := fREParaFmtRec.wNumberingTab;
  48561. end;
  48562. //*
  48563. //[procedure TControl.RESetNumTab]
  48564. procedure TControl.RESetNumTab(const Value: Integer);
  48565. begin
  48566. REGetParaAttr( 0 );
  48567. fREParaFmtRec.wNumberingTab := Value;
  48568. fREParaFmtRec.dwMask := PFM_NUMBERINGTAB;
  48569. RE_ParaFmt := fREParaFmtRec;
  48570. end;
  48571. //*
  48572. //[function TControl.REGetNumStart]
  48573. function TControl.REGetNumStart: Integer;
  48574. begin
  48575. REGetParaAttr( 0 );
  48576. Result := fREParaFmtRec.wNumberingStart;
  48577. end;
  48578. //*
  48579. //[procedure TControl.RESetNumStart]
  48580. procedure TControl.RESetNumStart(const Value: Integer);
  48581. begin
  48582. REGetParaAttr( 0 );
  48583. fREParaFmtRec.wNumberingStart := Value;
  48584. fREParaFmtRec.dwMask := PFM_NUMBERINGSTART;
  48585. RE_ParaFmt := fREParaFmtRec;
  48586. end;
  48587. //*
  48588. //[function TControl.REGetSpacing]
  48589. function TControl.REGetSpacing( const Index: Integer ): Integer;
  48590. begin
  48591. REGetParaAttr( 0 );
  48592. Result := PInteger( cardinal(@fREParaFmtRec.dySpaceBefore) + cardinal(Index and $F) )^;
  48593. end;
  48594. //*
  48595. //[procedure TControl.RESetSpacing]
  48596. procedure TControl.RESetSpacing(const Index, Value: Integer);
  48597. begin
  48598. REGetParaAttr( 0 );
  48599. PInteger( cardinal(@fREParaFmtRec.dySpaceBefore) + cardinal(Index and $F) )^ := Value;
  48600. fREParaFmtRec.dwMask := Index and not $F;
  48601. RE_ParaFmt := fREParaFmtRec;
  48602. end;
  48603. //*
  48604. //[function TControl.REGetSpacingRule]
  48605. function TControl.REGetSpacingRule: Integer;
  48606. begin
  48607. REGetParaAttr( 0 );
  48608. Result := fREParaFmtRec.bLineSpacingRule;
  48609. end;
  48610. //*
  48611. //[procedure TControl.RESetSpacingRule]
  48612. procedure TControl.RESetSpacingRule(const Value: Integer);
  48613. begin
  48614. REGetParaAttr( 0 );
  48615. fREParaFmtRec.bLineSpacingRule := Value;
  48616. fREParaFmtRec.dwMask := PFM_LINESPACING;
  48617. RE_ParaFmt := fREParaFmtRec;
  48618. end;
  48619. //*
  48620. //[function TControl.REGetLevel]
  48621. function TControl.REGetLevel: Integer;
  48622. begin
  48623. REGetParaAttr( 0 );
  48624. Result := fREParaFmtRec.bCRC;
  48625. end;
  48626. //*
  48627. //[function TControl.REGetBorder]
  48628. function TControl.REGetBorder(Side: TBorderEdge; const Index: Integer): Integer;
  48629. begin
  48630. REGetParaAttr( 0 );
  48631. Result := PWORD( cardinal(@fREParaFmtRec.wBorderSpace) + cardinal(Index) )^ shr (Ord(Side) * 4);
  48632. end;
  48633. //*
  48634. //[procedure TControl.RESetBorder]
  48635. procedure TControl.RESetBorder(Side: TBorderEdge; const Index: Integer;
  48636. const Value: Integer);
  48637. var Mask: Word;
  48638. pW : PWord;
  48639. begin
  48640. REGetParaAttr( 0 );
  48641. pw := PWORD( cardinal(@fREParaFmtRec.wBorderSpace) + cardinal(Index) );
  48642. Mask := $F shl (Ord(Side) * 4);
  48643. pw^ := pw^ and not Mask or (Value shl (4 * Ord(Side)) );
  48644. fREParaFmtRec.dwMask := PFM_BORDER;
  48645. RE_ParaFmt := fREParaFmtRec;
  48646. end;
  48647. //*
  48648. //[function TControl.REGetParaEffect]
  48649. function TControl.REGetParaEffect(const Index: Integer): Boolean;
  48650. begin
  48651. Result := LongBool( HiWord( REGetParaAttr( 8 shl 16 ) ) and Index );
  48652. end;
  48653. //*
  48654. //[procedure TControl.RESetParaEffect]
  48655. procedure TControl.RESetParaEffect(const Index: Integer;
  48656. const Value: Boolean);
  48657. var Idx: Integer;
  48658. begin
  48659. REGetParaAttr( 0 );
  48660. fREParaFmtRec.wReserved := Index;
  48661. Idx := Index;
  48662. //if Idx >= $4000 then Idx := $4000;
  48663. fREParaFmtRec.dwMask := Idx shl 16;
  48664. RE_ParaFmt := fREParaFmtRec;
  48665. end;
  48666. //*
  48667. //[function WndProc_REMonitorIns]
  48668. function WndProc_REMonitorIns( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48669. begin
  48670. Result := False;
  48671. if (Msg.message = WM_KEYDOWN) and (Msg.wParam = VK_INSERT) and
  48672. ((GetKeyState(VK_CONTROL) or GetKeyState(VK_SHIFT) or GetKeyState(VK_MENU)) >= 0) then
  48673. begin
  48674. if not Self_.fReOvrDisable then
  48675. Self_.fREOvr := not Self_.fREOvr
  48676. else
  48677. Result := True;
  48678. if assigned( Self_.fOnREInsModeChg ) then
  48679. Self_.fOnREInsModeChg( Self_ );
  48680. end;
  48681. end;
  48682. //*
  48683. //[function TControl.REGetOverwite]
  48684. function TControl.REGetOverwite: Boolean;
  48685. begin
  48686. AttachProc( WndProc_REMonitorIns );
  48687. Result := fREOvr;
  48688. end;
  48689. //*
  48690. //[procedure TControl.RESetOverwrite]
  48691. procedure TControl.RESetOverwrite(const Value: Boolean);
  48692. begin
  48693. if REGetOverwite = Value then // do not replace with fREOvr here!
  48694. Exit; // calling REGetOverwite installs monitor WndProc_REMonitorIns.
  48695. Perform( WM_KEYDOWN, VK_INSERT, 0 );
  48696. Perform( WM_KEYUP, VK_INSERT, 0 );
  48697. end;
  48698. //*
  48699. //[procedure TControl.RESetOvrDisable]
  48700. procedure TControl.RESetOvrDisable(const Value: Boolean);
  48701. begin
  48702. REGetOverwite;
  48703. fReOvrDisable := Value;
  48704. end;
  48705. //*
  48706. //[function WndProc_RichEdTransp_ParentPaint]
  48707. function WndProc_RichEdTransp_ParentPaint( Self_:PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48708. var I: Integer;
  48709. C: PControl;
  48710. begin
  48711. if (Msg.message = WM_PAINT) and (Msg.wParam = 0) then
  48712. begin
  48713. for I := 0 to Self_.fChildren.fCount - 1 do
  48714. begin
  48715. C := Self_.fChildren.fItems[ I ];
  48716. if C.fIsCommonControl then
  48717. begin
  48718. Inc( C.fUpdCount );
  48719. PostMessage( C.fHandle, CM_NCUPDATE, C.fUpdCount, WM_PAINT );
  48720. InvalidateRect( C.fHandle, nil, False );
  48721. end;
  48722. end;
  48723. end;
  48724. Result := False;
  48725. end;
  48726. //*
  48727. //[function WndProc_RichEdTransp_Update]
  48728. function WndProc_RichEdTransp_Update( Self_:PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48729. var Rgn, Rgn1: HRgn;
  48730. R, CR: TRect;
  48731. Pt: TPoint;
  48732. VW, HH, VH, HW: Integer;
  48733. begin
  48734. if Self_.fRETransparent then
  48735. case Msg.message of
  48736. WM_CHAR, WM_KILLFOCUS, WM_SETFOCUS, WM_KEYDOWN:
  48737. begin
  48738. PostMessage( Self_.fHandle, CM_INVALIDATE, 0, 0 );
  48739. end;
  48740. WM_PAINT:
  48741. if Msg.wParam = 0 then
  48742. begin
  48743. Inc( Self_.fUpdCount );
  48744. PostMessage( Self_.fHandle, CM_NCUPDATE, Self_.fUpdCount, Msg.message );
  48745. end;
  48746. WM_SIZE:
  48747. begin
  48748. Inc( Self_.fUpdCount );
  48749. PostMessage( Self_.fHandle, CM_NCUPDATE, Self_.fUpdCount, Msg.message );
  48750. PostMessage( Self_.fHandle, CM_INVALIDATE, 0, 0 );
  48751. end;
  48752. WM_ERASEBKGND:
  48753. if Msg.wParam = 0 then
  48754. begin
  48755. Inc( Self_.fUpdCount );
  48756. PostMessage( Self_.fHandle, CM_NCUPDATE, Self_.fUpdCount, Msg.message );
  48757. end;
  48758. WM_HSCROLL, WM_VSCROLL:
  48759. begin
  48760. Self_.fREScrolling := LoWord( Msg.wParam ) <> SB_ENDSCROLL;
  48761. Inc( Self_.fUpdCount );
  48762. PostMessage( Self_.fHandle, CM_NCUPDATE, Self_.fUpdCount, Msg.message );
  48763. if Self_.fREScrolling then
  48764. Self_.Invalidate;
  48765. end;
  48766. CM_INVALIDATE:
  48767. begin
  48768. //Self_.Update;
  48769. Self_.Parent.Invalidate;
  48770. Self_.Invalidate;
  48771. //Inc( Self_.fUpdCount );
  48772. //PostMessage( Self_.fHandle, CM_NCUPDATE, Self_.fUpdCount, Msg.message );
  48773. end;
  48774. CM_NCUPDATE:
  48775. if Msg.wParam = Self_.fUpdCount then
  48776. begin
  48777. //if Msg.lParam = WM_PAINT then
  48778. // UpdateWindow( Self_.fHandle );
  48779. GetWindowRect( Self_.fHandle, R );
  48780. Windows.GetClientRect( Self_.fHandle, CR );
  48781. Pt.x := 0; Pt.y := 0;
  48782. Pt := Self_.Client2Screen( Pt );
  48783. OffsetRect( CR, Pt.x, Pt.y );
  48784. Rgn := CreateRectRgn( R.Left, R.Top, R.Right, R.Bottom );
  48785. if Self_.fREScrolling then
  48786. begin
  48787. VW := GetSystemMetrics( SM_CXVSCROLL );
  48788. HH := GetSystemMetrics( SM_CYHSCROLL );
  48789. VH := GetSystemMetrics( SM_CYVSCROLL );
  48790. HW := GetSystemMetrics( SM_CXHSCROLL );
  48791. if CR.Right + VW <= R.Right then
  48792. begin
  48793. Rgn1 := CreateRectRgn( CR.Right, CR.Top + VH, CR.Right + VW, CR.Bottom - VH );
  48794. CombineRgn( Rgn, Rgn, Rgn1, RGN_DIFF );
  48795. DeleteObject( Rgn1 );
  48796. end;
  48797. if CR.Bottom + HH <= R.Bottom then
  48798. begin
  48799. Rgn1 := CreateRectRgn( CR.Left + HW, CR.Bottom, CR.Right - HW, CR.Bottom + HH );
  48800. CombineRgn( Rgn, Rgn, Rgn1, RGN_DIFF );
  48801. DeleteObject( Rgn1 );
  48802. end;
  48803. end;
  48804. Self_.Perform( WM_NCPAINT, Rgn, 0 );
  48805. DeleteObject( Rgn ); // Unremarked By M.Gerasimov
  48806. end;
  48807. end;
  48808. Result := False;
  48809. end;
  48810. //*
  48811. //[function TControl.REGetTransparent]
  48812. function TControl.REGetTransparent: Boolean;
  48813. begin
  48814. Result := Longbool(ExStyle and WS_EX_TRANSPARENT);
  48815. end;
  48816. //*
  48817. //[procedure TControl.RESetTransparent]
  48818. procedure TControl.RESetTransparent(const Value: Boolean);
  48819. begin
  48820. if Value then
  48821. ExStyle := ExStyle or WS_EX_TRANSPARENT
  48822. else
  48823. ExStyle := ExStyle and not WS_EX_TRANSPARENT;
  48824. fRETransparent := Value;
  48825. fParent.AttachProc( WndProc_RichEdTransp_ParentPaint );
  48826. AttachProc( WndProc_RichEdTransp_Update );
  48827. fTransparent := Value;
  48828. end;
  48829. //*
  48830. //[procedure TControl.RESetOnURL]
  48831. procedure TControl.RESetOnURL(const Index: Integer; const Value: TOnEvent);
  48832. begin
  48833. if Index = 0 then
  48834. fOnREOverURL := Value
  48835. else
  48836. fOnREURLClick := Value;
  48837. RE_AutoURLDetect := assigned(fOnREOverURL) or assigned(fOnREURLClick);
  48838. end;
  48839. //[procedure TControl.SetOnRE_URLClick]
  48840. procedure TControl.SetOnRE_URLClick(const Value: TOnEvent);
  48841. begin
  48842. RESetOnURL( 1, Value );
  48843. end;
  48844. procedure TControl.SetOnRE_OverURL(const Value: TOnEvent);
  48845. begin
  48846. RESetOnURL( 0, Value );
  48847. end;
  48848. {$IFDEF F_P}
  48849. //[function TControl.REGetOnURL]
  48850. function TControl.REGetOnURL(const Index: Integer): TOnEvent;
  48851. begin
  48852. CASE Index OF
  48853. 0: Result := fOnREOverURL;
  48854. else Result := fOnREURLClick;
  48855. END;
  48856. end;
  48857. {$ENDIF F_P}
  48858. //*
  48859. //[function TControl.REGetLangOptions]
  48860. function TControl.REGetLangOptions(const Index: Integer): Boolean;
  48861. begin
  48862. Result := LongBool( Perform( EM_GETLANGOPTIONS, 0, 0 ) and Index);
  48863. end;
  48864. //*
  48865. //[procedure TControl.RESetLangOptions]
  48866. procedure TControl.RESetLangOptions(const Index: Integer;
  48867. const Value: Boolean);
  48868. var Mask: Integer;
  48869. begin
  48870. Mask := -1;
  48871. if not Value then Inc( Mask );
  48872. Perform( EM_SETLANGOPTIONS, 0, Perform( EM_GETLANGOPTIONS, 0, 0 ) and
  48873. not Index or (Mask and Index) );
  48874. end;
  48875. {$ENDIF NOT_USE_RICHEDIT}
  48876. {$ifdef win32}
  48877. //[function DoTrackMouseEvent]
  48878. function DoTrackMouseEvent(lpEventTrack: PTrackMouseEvent): BOOL;
  48879. var FunTrack: function(lpEventTrack: PTrackMouseEvent): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  48880. ComCtlModule: THandle;
  48881. begin
  48882. Result := FALSE;
  48883. ComCtlModule := GetModuleHandle( cctrl );
  48884. if ComCtlModule = 0 then Exit;
  48885. FunTrack := GetProcAddress( ComCtlModule, '_TrackMouseEvent' );
  48886. if not Assigned( FunTrack ) then Exit;
  48887. Result := FunTrack( lpEventTrack );
  48888. end;
  48889. //*
  48890. //[function WndProcMouseEnterLeave]
  48891. function WndProcMouseEnterLeave( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48892. var P: TPoint;
  48893. MouseWasInControl: Boolean;
  48894. Yes: Boolean;
  48895. Track: TTrackMouseEvent;
  48896. begin
  48897. case Msg.message of
  48898. WM_MOUSEFIRST..WM_MOUSELAST:
  48899. begin
  48900. MouseWasInControl := Self_.MouseInControl;
  48901. if Assigned( Self_.fOnTestMouseOver ) then
  48902. Yes := Self_.fOnTestMouseOver( Self_ )
  48903. else
  48904. begin
  48905. GetCursorPos( P );
  48906. P := Self_.Screen2Client( P );
  48907. Yes := PointInRect( P, Self_.ClientRect );
  48908. end;
  48909. if MouseWasInControl <> Yes then
  48910. begin
  48911. //???
  48912. Self_.Invalidate;
  48913. if Yes then
  48914. begin
  48915. Self_.fMouseInControl := TRUE;
  48916. if Assigned( Self_.fOnMouseEnter ) then
  48917. Self_.fOnMouseEnter( Self_ );
  48918. Track.cbSize := Sizeof( Track );
  48919. Track.dwFlags := TME_LEAVE;
  48920. Track.hwndTrack := Self_.Handle;
  48921. //Track.dwHoverTime := 0;
  48922. DoTrackMouseEvent( @ Track );
  48923. //???
  48924. Self_.Invalidate;
  48925. end
  48926. else
  48927. begin
  48928. Self_.fMouseInControl := FALSE;
  48929. Track.cbSize := Sizeof( Track );
  48930. Track.dwFlags := TME_LEAVE or TME_CANCEL;
  48931. Track.hwndTrack := Self_.Handle;
  48932. //Track.dwHoverTime := 0;
  48933. DoTrackMouseEvent( @ Track );
  48934. if Assigned( Self_.fOnMouseLeave ) then
  48935. Self_.fOnMouseLeave( Self_ );
  48936. //???
  48937. Self_.Invalidate; //Erase( FALSE );
  48938. end;
  48939. end;
  48940. end;
  48941. WM_MOUSELEAVE:
  48942. begin
  48943. if Self_.fMouseInControl then
  48944. begin
  48945. Self_.fMouseInControl := FALSE;
  48946. {$IFDEF GRAPHCTL_HOTTRACK}
  48947. if Assigned( Self_.fMouseLeaveProc ) then
  48948. Self_.fMouseLeaveProc( Self_ );
  48949. {$ENDIF}
  48950. if Assigned( Self_.fOnMouseLeave ) then
  48951. Self_.fOnMouseLeave( Self_ );
  48952. //???
  48953. Self_.Invalidate; //Erase( FALSE );
  48954. end;
  48955. end;
  48956. end;
  48957. Result := False;
  48958. end;
  48959. {$endif win32}
  48960. //[procedure ProvideMouseEnterLeave]
  48961. procedure ProvideMouseEnterLeave( Self_: PControl );
  48962. begin
  48963. {$ifdef win32}
  48964. InitCommonControls;
  48965. Self_.AttachProc( WndProcMouseEnterLeave );
  48966. //???Self_.InvalidateErase( FALSE );
  48967. {$endif win32}
  48968. end;
  48969. //[procedure TControl.SetFlat]
  48970. procedure TControl.SetFlat(const Value: Boolean);
  48971. begin
  48972. //if fFlat = Value then Exit;
  48973. fFlat := Value;
  48974. fMouseInControl := FALSE;
  48975. ProvideMouseEnterLeave( @Self );
  48976. Invalidate;
  48977. end;
  48978. //[procedure TControl.SetOnMouseEnter]
  48979. procedure TControl.SetOnMouseEnter(const Value: TOnEvent);
  48980. begin
  48981. fOnMouseEnter := Value;
  48982. ProvideMouseEnterLeave( @Self );
  48983. end;
  48984. //[procedure TControl.SetOnMouseLeave]
  48985. procedure TControl.SetOnMouseLeave(const Value: TOnEvent);
  48986. begin
  48987. fOnMouseLeave := Value;
  48988. ProvideMouseEnterLeave( @Self );
  48989. end;
  48990. //[procedure TControl.SetOnTestMouseOver]
  48991. procedure TControl.SetOnTestMouseOver(const Value: TOnTestMouseOver);
  48992. begin
  48993. fOnTestMouseOver := Value;
  48994. ProvideMouseEnterLeave( @Self );
  48995. end;
  48996. //[function WndProcEdTransparent]
  48997. function WndProcEdTransparent( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  48998. begin
  48999. if (Msg.message = WM_KEYDOWN) or
  49000. (Msg.message = WM_MOUSEMOVE) and (GetKeyState( VK_LBUTTON ) < 0) or
  49001. (Msg.message = WM_LBUTTONUP) or (Msg.message = WM_LBUTTONDOWN) then
  49002. Self_.Invalidate;
  49003. Result := False; // continue handling of a message anyway
  49004. end;
  49005. //[procedure TControl.EdSetTransparent]
  49006. procedure TControl.EdSetTransparent(const Value: Boolean);
  49007. begin
  49008. Transparent := Value;
  49009. AttachProc( WndProcEdTransparent );
  49010. end;
  49011. //[function WndProcSpeedButton]
  49012. var LastHWnd: HWnd; // + Don
  49013. function WndProcSpeedButton( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  49014. begin
  49015. Result := False;
  49016. if Msg.message = WM_SETFOCUS then
  49017. begin
  49018. Result := TRUE;
  49019. Rslt := 0;
  49020. LastHWnd := Msg.wParam; // + don
  49021. end
  49022. else // + Don
  49023. if (Msg.message = WM_CAPTURECHANGED) and
  49024. (Msg.lParam = 0) and
  49025. (LastHwnd <> 0) then
  49026. begin
  49027. SetFocus(LastHwnd);
  49028. LastHwnd := 0;
  49029. end;
  49030. end;
  49031. //[function TControl.LikeSpeedButton]
  49032. function TControl.LikeSpeedButton: PControl;
  49033. //type TProcObj = procedure of object;
  49034. var Form: PControl;
  49035. begin
  49036. AttachProc( WndProcSpeedButton );
  49037. //fSetFocus := TProcObj( MakeMethod( nil, @ DummyObjProc ) );
  49038. fTabstop := False;
  49039. Style := Style and not WS_TABSTOP;
  49040. Form := ParentForm;
  49041. if Form <> nil then
  49042. if Form.fCurrentControl = @Self then
  49043. begin
  49044. Form.GotoControl( VK_TAB );
  49045. if Form.fCurrentControl = @Self then
  49046. Form.fCurrentControl := nil;
  49047. end;
  49048. Result := @Self;
  49049. end;
  49050. { -- Unicode -- }
  49051. //[function TControl.SetUnicode]
  49052. function TControl.SetUnicode(Unicode: Boolean): PControl;
  49053. begin
  49054. {$ifdef win32}
  49055. Perform( CCM_SETUNICODEFORMAT, Integer( Unicode ), 0 );
  49056. {$endif win32}
  49057. Result := @ Self;
  49058. end;
  49059. { -- TabControl -- }
  49060. //[function TControl.GetPages]
  49061. function TControl.GetPages(Idx: Integer): PControl;
  49062. var Item: TTCItem;
  49063. begin
  49064. Item.mask := TCIF_PARAM;
  49065. if Perform( TCM_GETITEM, Idx, Integer( @Item ) ) = 0 then
  49066. Result := nil
  49067. else
  49068. Result := Pointer( Item.lParam );
  49069. end;
  49070. //[function TControl.TCGetItemText]
  49071. function TControl.TCGetItemText(Idx: Integer): KOLString;
  49072. var TI: TTCItem;
  49073. Buffer: array[ 0..1023 ] of KOLChar;
  49074. begin
  49075. TI.mask := TCIF_TEXT;
  49076. TI.pszText := @Buffer[ 0 ];
  49077. TI.cchTextMax := sizeof( Buffer );
  49078. Buffer[ 0 ] := #0;
  49079. Perform( TCM_GETITEM, Idx, Integer( @TI ) );
  49080. Result := PKOLChar( @ Buffer[ 0 ] );
  49081. end;
  49082. //[procedure TControl.TCSetItemText]
  49083. procedure TControl.TCSetItemText(Idx: Integer; const Value: KOLString);
  49084. var TI: TTCItem;
  49085. begin
  49086. TI.mask := TCIF_TEXT;
  49087. TI.pszText := PKOLChar( Value );
  49088. Perform( TCM_SETITEM, Idx, Integer( @TI ) );
  49089. end;
  49090. //[function TControl.TCGetItemImgIDx]
  49091. function TControl.TCGetItemImgIDx(Idx: Integer): Integer;
  49092. var TI: TTCItem;
  49093. begin
  49094. TI.mask := TCIF_IMAGE;
  49095. if Perform( TCM_GETITEM, Idx, Integer( @TI ) ) = 0 then
  49096. Result := -1
  49097. else
  49098. Result := TI.iImage;
  49099. end;
  49100. //[procedure TControl.TCSetItemImgIdx]
  49101. procedure TControl.TCSetItemImgIdx(Idx: Integer; const Value: Integer);
  49102. var TI: TTCItem;
  49103. begin
  49104. TI.mask := TCIF_IMAGE;
  49105. TI.iImage := Value;
  49106. Perform( TCM_SETITEM, Idx, Integer( @TI ) );
  49107. end;
  49108. //[function TControl.TCGetItemRect]
  49109. function TControl.TCGetItemRect(Idx: Integer): TRect;
  49110. begin
  49111. if Perform( TCM_GETITEMRECT, Idx, Integer( @Result ) ) = 0 then
  49112. begin
  49113. Result.Left := 0;
  49114. Result.Right := 0;
  49115. Result.Top := 0;
  49116. Result.Bottom := 0;
  49117. end;
  49118. end;
  49119. //[procedure TControl.TC_SetPadding]
  49120. procedure TControl.TC_SetPadding(cx, cy: Integer);
  49121. begin
  49122. Perform( TCM_SETPADDING, 0, cx or (cy shl 16) );
  49123. end;
  49124. //[function TControl.TC_TabAtPos]
  49125. function TControl.TC_TabAtPos(x, y: Integer): Integer;
  49126. type TTCHittestInfo = {$ifndef wince}packed{$endif} record
  49127. Pt: TPoint;
  49128. Fl: DWORD;
  49129. end;
  49130. var HTI: TTCHitTestInfo;
  49131. begin
  49132. HTI.Pt.x := x;
  49133. HTI.Pt.y := y;
  49134. Result := Perform( TCM_HITTEST, 0, Integer( @HTI ) );
  49135. end;
  49136. //[function TControl.TC_DisplayRect]
  49137. function TControl.TC_DisplayRect: TRect;
  49138. begin
  49139. Windows.GetClientRect( fHandle, Result );
  49140. Perform( TCM_ADJUSTRECT, 0, Integer( @Result ) );
  49141. {$ifdef wince}
  49142. Dec(Result.Top, 2);
  49143. Dec(Result.Left, 2);
  49144. Inc(Result.Right, 2);
  49145. {$endif wince}
  49146. end;
  49147. //[function TControl.TC_IndexOf]
  49148. function TControl.TC_IndexOf(const S: KOLString): Integer;
  49149. begin
  49150. Result := TC_SearchFor( S, -1, FALSE );
  49151. end;
  49152. //[function TControl.TC_SearchFor]
  49153. function TControl.TC_SearchFor(const S: KOLString; StartAfter: Integer;
  49154. Partial: Boolean): Integer;
  49155. var I: Integer;
  49156. begin
  49157. Result := -1;
  49158. for I := StartAfter+1 to Count-1 do
  49159. begin
  49160. if Partial and ( Copy( TC_Items[ I ], 1, Length( S ) ) = S ) or
  49161. ( TC_Items[ I ] = S ) then
  49162. begin
  49163. Result := I;
  49164. break;
  49165. end;
  49166. end;
  49167. end;
  49168. //[function TControl.TC_Insert]
  49169. function TControl.TC_Insert(Idx: Integer; const TabText: KOLString;
  49170. TabImgIdx: Integer): PControl;
  49171. var TI: TTCItem;
  49172. begin
  49173. Result := NewPanel( @Self, esNone );
  49174. {$IFDEF OLD_ALIGN}
  49175. Result.FAlign := caClient; //+ Galkov
  49176. Result.fNotUseAlign := True;
  49177. Result.fVisibleWoParent := TRUE;
  49178. {$ELSE NEW_ALIGN}
  49179. Result.Align := caClient; //+ Galkov
  49180. {$ENDIF}
  49181. Result.Visible := CurIndex<0;
  49182. TI.mask := TCIF_TEXT or TCIF_IMAGE or TCIF_PARAM;
  49183. TI.iImage := TabImgIdx;
  49184. TI.pszText := PKOLChar( TabText );
  49185. TI.lParam := Integer( Result );
  49186. Perform( TCM_INSERTITEM, Idx, Integer( @TI ) );
  49187. {$IFDEF OLD_ALIGN}
  49188. Result.BoundsRect := TC_DisplayRect;//+ Galkov
  49189. {$ENDIF}
  49190. Perform(WM_SIZE,0,0); //May be changes of margins for TabControl
  49191. {$IFDEF GRAPHCTL_XPSTYLES}
  49192. Result.fClassicTransparent := Result.fTransparent;
  49193. Attach_WM_THEMECHANGED(Result);
  49194. XP_Themes_For_TabPanel(Result);
  49195. {$ENDIF}
  49196. end;
  49197. //[procedure TControl.TC_Delete]
  49198. procedure TControl.TC_Delete(Idx: Integer);
  49199. var Page: PControl;
  49200. begin
  49201. Page := TC_Pages[ Idx ];
  49202. if Page = nil then Exit;
  49203. Perform( TCM_DELETEITEM, Idx, 0 );
  49204. Page.Free;
  49205. Perform(WM_SIZE,0,0); //May be changes of margins for TabControl
  49206. end;
  49207. {$IFNDEF OLD_ALIGN}
  49208. //[procedure TControl.TC_InsertControl
  49209. procedure TControl.TC_InsertControl( Idx: Integer; const TabText: KOLString;
  49210. TabImgIdx: Integer; Page: PControl);
  49211. var TI: TTCItem;
  49212. begin
  49213. Page.Visible := CurIndex<0;
  49214. TI.mask := TCIF_TEXT or TCIF_IMAGE or TCIF_PARAM;
  49215. TI.iImage := TabImgIdx;
  49216. TI.pszText := PKOLChar( TabText );
  49217. TI.lParam := Integer( Page );
  49218. Perform( TCM_INSERTITEM, Idx, Integer( @TI ) );
  49219. Perform(WM_SIZE,0,0); //May be changes of margins for TabControl
  49220. end;
  49221. //[function TControl.TC_Remove]
  49222. function TControl.TC_Remove( Idx: Integer ):PControl;
  49223. begin
  49224. Result := TC_Pages[ Idx ];
  49225. if Result = nil then Exit;
  49226. Perform( TCM_DELETEITEM, Idx, 0 );
  49227. Perform(WM_SIZE,0,0); //May be changes of margins for TabControl
  49228. end;
  49229. {$ENDIF}
  49230. { -- TreeView -- }
  49231. //[function TControl.TVGetItemIdx]
  49232. function TControl.TVGetItemIdx(const Index: Integer): THandle;
  49233. begin
  49234. Result := Perform( TVM_GETNEXTITEM, Index, 0 );
  49235. end;
  49236. //[procedure TControl.TVSetItemIdx]
  49237. procedure TControl.TVSetItemIdx(const Index: Integer;
  49238. const Value: THandle);
  49239. begin
  49240. Perform( TVM_SELECTITEM, Index, Value );
  49241. end;
  49242. //[function TControl.TVGetItemNext]
  49243. function TControl.TVGetItemNext(Item: THandle; const Index: Integer): THandle;
  49244. begin
  49245. Result := Perform( TVM_GETNEXTITEM, Index, Item );
  49246. end;
  49247. //[function TControl.TVGetItemRect]
  49248. function TControl.TVGetItemRect(Item: THandle; TextOnly: Boolean): TRect;
  49249. begin
  49250. Result.Left := Item;
  49251. if Perform( TVM_GETITEMRECT, Integer( TextOnly ), Integer( @Result ) ) = 0 then
  49252. begin
  49253. Result.Left := 0;
  49254. Result.Right := 0;
  49255. Result.Top := 0;
  49256. Result.Bottom := 0;
  49257. end;
  49258. end;
  49259. //[function TControl.TVGetItemVisible]
  49260. function TControl.TVGetItemVisible(Item: THandle): Boolean;
  49261. var R: TRect;
  49262. begin
  49263. R := TVItemRect[ Item, False ];
  49264. Result := R.Bottom > R.Top;
  49265. end;
  49266. //[procedure TControl.TVSetItemVisible]
  49267. procedure TControl.TVSetItemVisible(Item: THandle; const Value: Boolean);
  49268. begin
  49269. if Value then
  49270. Perform( TVM_ENSUREVISIBLE, 0, Item );
  49271. end;
  49272. //[function TControl.TVGetItemStateFlg]
  49273. function TControl.TVGetItemStateFlg(Item: THandle; const Index: Integer): Boolean;
  49274. var TVI: TTVItem;
  49275. begin
  49276. TVI.mask := TVIF_HANDLE or TVIF_STATE;
  49277. TVI.hItem := Item;
  49278. TVI.stateMask := Index;
  49279. Result := False;
  49280. if Perform( TVM_GETITEM, 0, Integer( @TVI ) ) <> 0 then
  49281. Result := (TVI.state and Index) <> 0;
  49282. end;
  49283. //[procedure TControl.TVSetItemStateFlg]
  49284. procedure TControl.TVSetItemStateFlg(Item: THandle; const Index: Integer;
  49285. const Value: Boolean);
  49286. var TVI: TTVItem;
  49287. begin
  49288. TVI.mask := TVIF_HANDLE or TVIF_STATE;
  49289. TVI.hItem := Item;
  49290. TVI.stateMask := Index;
  49291. TVI.state := $FFFFFFFF and Index;
  49292. if not Value then
  49293. TVI.state := 0;
  49294. Perform( TVM_SETITEM, 0, Integer( @TVI ) );
  49295. end;
  49296. //[function TControl.TVGetItemImage]
  49297. function TControl.TVGetItemImage(Item: THandle; const Index: Integer): Integer;
  49298. var TVI: TTVItem;
  49299. begin
  49300. TVI.mask := TVIF_HANDLE or Loword( Index );
  49301. TVI.hItem := Item;
  49302. if Hiword( Index ) <> 0 then
  49303. begin
  49304. TVI.mask := TVIF_STATE or TVIF_HANDLE;
  49305. TVI.stateMask := Loword( Index );
  49306. end;
  49307. Result := -1;
  49308. if Perform( TVM_GETITEM, 0, Integer( @TVI ) ) <> 0 then
  49309. begin
  49310. if Hiword( Index ) <> 0 then
  49311. Result := (TVI.state shr Hiword( Index )) and $F
  49312. else
  49313. if Loword( Index ) = TVIF_IMAGE then
  49314. Result := TVI.iImage
  49315. else
  49316. Result := TVI.iSelectedImage;
  49317. end;
  49318. end;
  49319. //[procedure TControl.TVSetItemImage]
  49320. procedure TControl.TVSetItemImage(Item: THandle; const Index: Integer;
  49321. const Value: Integer);
  49322. var TVI: TTVItem;
  49323. begin
  49324. TVI.mask := TVIF_HANDLE or Loword( Index );
  49325. TVI.hItem := Item;
  49326. TVI.iImage := Value;
  49327. TVI.iSelectedImage := Value;
  49328. if Hiword( Index ) <> 0 then
  49329. begin
  49330. TVI.mask := TVIF_STATE or TVIF_HANDLE;
  49331. TVI.stateMask := Loword( Index );
  49332. TVI.state := Value shl Hiword( Index );
  49333. end;
  49334. Perform( TVM_SETITEM, 0, Integer( @TVI ) );
  49335. end;
  49336. //[function TControl.TVGetItemText]
  49337. function TControl.TVGetItemText(Item: THandle): KOLString;
  49338. var TVI: TTVItem;
  49339. Buffer: array[ 0..4095 ] of KOLChar;
  49340. begin
  49341. TVI.mask := TVIF_HANDLE or TVIF_TEXT;
  49342. TVI.hItem := Item;
  49343. TVI.pszText := @Buffer[ 0 ];
  49344. Buffer[ 0 ] := #0;
  49345. TVI.cchTextMax := Sizeof( Buffer ) {$IFDEF UNICODE_CTRLS} div Sizeof( KOLChar ) {$ENDIF};
  49346. Perform( TVM_GETITEM, 0, Integer( @TVI ) );
  49347. Result := PKOLChar( @ Buffer[ 0 ] );
  49348. end;
  49349. //[procedure TControl.TVSetItemText]
  49350. procedure TControl.TVSetItemText(Item: THandle; const Value: KOLString);
  49351. var TVI: TTVItem;
  49352. begin
  49353. TVI.mask := TVIF_HANDLE or TVIF_TEXT;
  49354. TVI.hItem := Item;
  49355. TVI.pszText := PKOLChar( Value );
  49356. Perform( TVM_SETITEM, 0, Integer( @TVI ) );
  49357. end;
  49358. //[function TControl.TVItemPath]
  49359. function TControl.TVItemPath(Item: THandle; Delimiter: KOLChar): KOLString;
  49360. begin
  49361. if Item = 0 then
  49362. Item := TVSelected;
  49363. Result := '';
  49364. while Item <> 0 do
  49365. begin
  49366. if Result <> '' then
  49367. Result := Delimiter + Result;
  49368. Result := TVItemText[ Item ] + Result;
  49369. Item := TVItemParent[ Item ];
  49370. end;
  49371. end;
  49372. //[function TControl.TV_GetItemHasChildren]
  49373. function TControl.TV_GetItemHasChildren(Item: THandle): Boolean;
  49374. var TVI: TTVItem;
  49375. begin
  49376. TVI.mask := TVIF_HANDLE or TVIF_CHILDREN;
  49377. TVI.hItem := Item;
  49378. Perform( TVM_GETITEM, 0, Integer( @TVI ) );
  49379. Result := TVI.cChildren = 1;
  49380. end;
  49381. //[procedure TControl.TV_GetItemChildCount]
  49382. function TControl.TV_GetItemChildCount(Item: THandle): Integer;
  49383. var Node: THandle;
  49384. begin
  49385. Result := 0;
  49386. Node := TVItemChild[ Item ];
  49387. while Node <> 0 do
  49388. begin
  49389. Inc( Result );
  49390. Node := TVItemNext[ Node ];
  49391. end;
  49392. end;
  49393. //[procedure TControl.TV_SetItemHasChildren]
  49394. procedure TControl.TV_SetItemHasChildren(Item: THandle;
  49395. const Value: Boolean);
  49396. var TVI: TTVItem;
  49397. begin
  49398. TVI.mask := TVIF_HANDLE or TVIF_CHILDREN;
  49399. TVI.hItem := Item;
  49400. TVI.cChildren := 1 and Integer( Value );
  49401. Perform( TVM_SETITEM, 0, Integer( @TVI ) );
  49402. end;
  49403. //[function TControl.TVItemAtPos]
  49404. function TControl.TVItemAtPos(x, y: Integer; var Where: DWORD): THandle;
  49405. var HTI: TTVHitTestInfo;
  49406. begin
  49407. HTI.pt.x := x;
  49408. HTI.pt.y := y;
  49409. Result := Perform( TVM_HITTEST, 0, Integer( @HTI ) );
  49410. Where := HTI.{$ifdef wince}flags{$else}fl{$endif};
  49411. end;
  49412. type
  49413. TTVInsertStruct = {$ifndef wince}packed{$endif} Record
  49414. hParent: THandle;
  49415. hAfter : THandle;
  49416. item: TTVItem;
  49417. end;
  49418. {$ifdef win32}
  49419. TTVInsertStructEx = {$ifndef wince}packed{$endif} Record
  49420. hParent: THandle;
  49421. hAfter : THandle;
  49422. item: TTVItemEx;
  49423. end;
  49424. {$endif win32}
  49425. //[function TControl.TVInsert]
  49426. function TControl.TVInsert(nParent, nAfter: THandle;
  49427. const Txt: KOLString): THandle;
  49428. var TVIns: TTVInsertStruct;
  49429. begin
  49430. TVIns.hParent := nParent;
  49431. TVIns.hAfter := nAfter;
  49432. TVIns.item.mask := TVIF_TEXT;
  49433. TVIns.item.pszText := PKOLChar( Txt );
  49434. Result := Perform( TVM_INSERTITEM, 0, Integer( @TVIns ) );
  49435. Invalidate;
  49436. end;
  49437. //[procedure TControl.TVExpand]
  49438. procedure TControl.TVExpand(Item: THandle; Flags: DWORD);
  49439. begin
  49440. Perform( TVM_EXPAND, Flags, Item );
  49441. end;
  49442. //[procedure TControl.TVSort]
  49443. procedure TControl.TVSort( N: THandle );
  49444. var a: Cardinal;
  49445. b: Boolean;
  49446. begin
  49447. b := N = 0;
  49448. if b then
  49449. begin
  49450. N := TVRoot;
  49451. end;
  49452. while N <> 0 do
  49453. begin
  49454. a := TVItemChild[N];
  49455. if a > 0 then
  49456. TVSort(a);
  49457. Perform(TVM_SORTCHILDREN, 0, N);
  49458. N := TVItemNext[N];
  49459. end;
  49460. if b then //moved by Tr"]f
  49461. Perform(TVM_SORTCHILDREN, 0, 0); //+ by YS
  49462. end;
  49463. //[procedure TControl.TVDelete]
  49464. procedure TControl.TVDelete(Item: THandle);
  49465. begin
  49466. Perform( TVM_DELETEITEM, 0, Item );
  49467. Invalidate;
  49468. end;
  49469. //[function TControl.TVGetItemData]
  49470. function TControl.TVGetItemData(Item: THandle): Pointer;
  49471. var TVI: TTVItem;
  49472. begin
  49473. TVI.mask := TVIF_HANDLE or TVIF_PARAM;
  49474. TVI.hItem := Item;
  49475. Result := nil;
  49476. if Perform( TVM_GETITEM, 0, Integer( @TVI ) ) <> 0 then
  49477. Result := Pointer( TVI.lParam );
  49478. end;
  49479. //[procedure TControl.TVSetItemData]
  49480. procedure TControl.TVSetItemData(Item: THandle; const Value: Pointer);
  49481. var TVI: TTVItem;
  49482. begin
  49483. TVI.mask := TVIF_HANDLE or TVIF_PARAM;
  49484. TVI.hItem := Item;
  49485. TVI.lParam := Integer( Value );
  49486. Perform( TVM_SETITEM, 0, Integer( @TVI ) );
  49487. end;
  49488. //[procedure TControl.TVEditItem]
  49489. procedure TControl.TVEditItem(Item: THandle);
  49490. begin
  49491. Perform( TVM_EDITLABEL, 0, Item );
  49492. end;
  49493. //[procedure TControl.TVStopEdit]
  49494. procedure TControl.TVStopEdit(Cancel: Boolean);
  49495. begin
  49496. Perform( TVM_ENDEDITLABELNOW, Integer( Cancel ), 0 );
  49497. end;
  49498. //[function WndProcTVRightClickSelect]
  49499. function WndProcTVRightClickSelect( Sender: PControl; var Msg: TMsg; var R: Integer ): Boolean;
  49500. var I: Integer;
  49501. Where: DWORD;
  49502. begin
  49503. if Msg.message = WM_RBUTTONDOWN then
  49504. begin
  49505. I := Sender.TVItemAtPos( SmallInt( Msg.lParam and $FFFF ),
  49506. SmallInt( Msg.lParam shr 16 ), Where );
  49507. if I <> 0 then
  49508. Sender.TVSelected := I;
  49509. end;
  49510. Result := FALSE;
  49511. end;
  49512. //[procedure TControl.SetTVRightClickSelect]
  49513. procedure TControl.SetTVRightClickSelect(const Value: Boolean);
  49514. begin
  49515. fTVRightClickSelect := Value;
  49516. if Value then
  49517. AttachProc( @WndProcTVRightClickSelect );
  49518. end;
  49519. //[procedure TControl.SetOnTVDelete]
  49520. procedure TControl.SetOnTVDelete( const Value: TOnTVDelete );
  49521. begin
  49522. fOnTVDelete := Value;
  49523. if fParent <> nil then
  49524. begin
  49525. fParent.Add2AutoFreeEx( Clear );
  49526. fParent.DetachProc( WndProcNotify );
  49527. fParent.AttachProcEx( WndProcNotify, TRUE );
  49528. end;
  49529. AttachProcEx( ProcTVDeleteItem, TRUE );
  49530. end;
  49531. //[function ClipboardHasText]
  49532. function ClipboardHasText: Boolean;
  49533. begin
  49534. Result := false;
  49535. if OpenClipboard( 0 ) then
  49536. begin
  49537. if IsClipboardFormatAvailable( CF_TEXT ) then
  49538. Result := TRUE;
  49539. CloseClipboard;
  49540. end;
  49541. end;
  49542. //[function Clipboard2Text]
  49543. {$ifdef wince}
  49544. function Clipboard2Text: String;
  49545. begin
  49546. Result:=Clipboard2WText;
  49547. end;
  49548. {$else}
  49549. function Clipboard2Text: String;
  49550. var gbl: THandle;
  49551. str: PChar;
  49552. begin
  49553. Result := '';
  49554. if OpenClipboard( 0 ) then
  49555. begin
  49556. if IsClipboardFormatAvailable( CF_TEXT ) then
  49557. begin
  49558. gbl := GetClipboardData( CF_TEXT );
  49559. if gbl <> 0 then
  49560. begin
  49561. str := GlobalLock( gbl );
  49562. if str <> nil then
  49563. begin
  49564. Result := str;
  49565. GlobalUnlock( gbl );
  49566. end;
  49567. end;
  49568. end;
  49569. CloseClipboard;
  49570. end;
  49571. end;
  49572. {$endif wince}
  49573. {-}
  49574. {$IFNDEF _D2}
  49575. //[function Clipboard2WText]
  49576. function Clipboard2WText: WideString;
  49577. var gbl: THandle;
  49578. str: PWideChar;
  49579. begin
  49580. Result := '';
  49581. if OpenClipboard( 0 ) then
  49582. begin
  49583. if IsClipboardFormatAvailable( CF_UNICODETEXT ) then
  49584. begin
  49585. gbl := GetClipboardData( CF_UNICODETEXT );
  49586. if gbl <> 0 then
  49587. begin
  49588. str := GlobalLock( gbl );
  49589. if str <> nil then
  49590. begin
  49591. Result := str;
  49592. GlobalUnlock( gbl );
  49593. end;
  49594. end;
  49595. end;
  49596. CloseClipboard;
  49597. end;
  49598. end;
  49599. {$ENDIF}
  49600. {+}
  49601. //[function Text2Clipboard]
  49602. {$ifdef wince}
  49603. function Text2Clipboard( const S: String ): Boolean;
  49604. begin
  49605. Result:=WText2Clipboard(S);
  49606. end;
  49607. {$else}
  49608. function Text2Clipboard( const S: String ): Boolean;
  49609. var gbl: THandle;
  49610. str: PChar;
  49611. begin
  49612. Result := False;
  49613. if not OpenClipboard( 0 ) then Exit;
  49614. EmptyClipboard;
  49615. if S <> '' then
  49616. begin
  49617. gbl := GlobalAlloc( GMEM_MOVEABLE, Length( S ) + 1 );
  49618. if gbl <> 0 then
  49619. begin
  49620. str := GlobalLock( gbl );
  49621. Move( S[ 1 ], str^, Length( S ) + 1 );
  49622. GlobalUnlock( gbl );
  49623. Result := SetClipboardData( CF_TEXT, gbl ) <> 0;
  49624. end;
  49625. end
  49626. else
  49627. Result := True;
  49628. CloseClipboard;
  49629. end;
  49630. {$endif wince}
  49631. {-}
  49632. {$IFNDEF _D2}
  49633. //[function WText2Clipboard]
  49634. function WText2Clipboard( const WS: WideString ): Boolean;
  49635. var gbl: THandle;
  49636. str: PChar;
  49637. begin
  49638. Result := False;
  49639. if not OpenClipboard( 0 ) then Exit;
  49640. EmptyClipboard;
  49641. if WS <> '' then
  49642. begin
  49643. gbl := GlobalAlloc( GMEM_MOVEABLE, (Length( WS ) + 1) * 2 );
  49644. if gbl <> 0 then
  49645. begin
  49646. str := GlobalLock( gbl );
  49647. Move( WS[ 1 ], str^, (Length( WS ) + 1) * 2 );
  49648. GlobalUnlock( gbl );
  49649. Result := SetClipboardData( CF_UNICODETEXT, gbl ) <> 0;
  49650. end;
  49651. end
  49652. else
  49653. Result := True;
  49654. CloseClipboard;
  49655. end;
  49656. {$ENDIF}
  49657. {+}
  49658. //[function TControl.Size]
  49659. function TControl.Size(W, H: Integer): PControl;
  49660. var C, P: PControl;
  49661. dW, dH: Integer;
  49662. begin
  49663. C := @Self;
  49664. while True do
  49665. begin
  49666. dW := 0; dH := 0;
  49667. P := C.FParent;
  49668. if C.ToBeVisible {or C.fCreateHidden or (P <> nil) and (P.fVisible)} then
  49669. begin
  49670. if C.fAlign in [caLeft, caRight, caClient] then
  49671. begin
  49672. if H > 0 then
  49673. begin
  49674. dH := H - C.Height; H := 0;
  49675. end;
  49676. end;
  49677. if C.fAlign in [caTop, caBottom, caClient] then
  49678. begin
  49679. if W > 0 then
  49680. begin
  49681. dW := W - C.Width; W := 0;
  49682. end;
  49683. end;
  49684. end;
  49685. if (W > 0) or (H > 0) then
  49686. begin
  49687. C.SetSize( W, H );
  49688. if (P <> nil) // {Ralf Junker}
  49689. and not P.IsApplet then
  49690. C.ResizeParent;
  49691. end;
  49692. if (dW = 0) and (dH = 0) then break;
  49693. C := P; //C.FParent;
  49694. if C = nil then break;
  49695. //if not C.fIsControl then break;
  49696. if C.IsApplet then break;
  49697. W := C.Width + dW;
  49698. H := C.Height + dH;
  49699. end;
  49700. Result := @Self;
  49701. end;
  49702. {$ENDIF WIN_GDI}
  49703. //[procedure AutoSzProc]
  49704. {$IFDEF GDI}
  49705. procedure AutoSzProc( Self_: PObj );
  49706. var DeltaX, DeltaY: Integer;
  49707. SZ: TSize; PT: TPoint;
  49708. Txt: KOLString;
  49709. Chg: Boolean;
  49710. R: TRect;
  49711. Flags: DWORD;
  49712. {+ecm}
  49713. OldFont: HFONT;
  49714. CtlHavingFont: PControl;
  49715. {/+ecm}
  49716. OldNotUseAlign: boolean;
  49717. begin
  49718. Txt := PControl( Self_ ).fCaption;
  49719. SZ.cx := 0;
  49720. SZ.cy := 0;
  49721. if Txt <> '' then
  49722. begin
  49723. if not PControl( Self_ ).HandleAllocated then begin
  49724. PControl( Self_ ).fAutoSize:=DummyObjProc;
  49725. PControl( Self_ ).GetWindowHandle; // this line must be here.
  49726. //-- otherwise, when handle is not yet allocated,
  49727. // it is requested in TCanvas.GetHandle, and in result
  49728. // of unpredictable recursion some memory can be currupted.
  49729. PControl( Self_ ).fAutoSize:=AutoSzProc;
  49730. end;
  49731. if Assigned( PControl( Self_ ).fFont ) then
  49732. if PControl( Self_ ).fFont.fData.Font.Italic then
  49733. Txt := Txt + ' ';
  49734. if PControl( Self_ ).fWordWrap and (PControl( Self_ ).fAlign <> caClient) then
  49735. begin
  49736. R := PControl( Self_ ).ClientRect;
  49737. Dec(R.Right, PControl( Self_ ).fCommandActions.aAutoSzX);
  49738. if R.Right < R.Left then
  49739. R.Right:=R.Left + 1;
  49740. Flags := DT_CALCRECT or DT_EXPANDTABS or DT_WORDBREAK;
  49741. CASE PControl( Self_ ).fTextAlign OF
  49742. taCenter: Flags := Flags or DT_CENTER;
  49743. taRight : Flags := Flags or DT_RIGHT;
  49744. END;
  49745. {-ecm}
  49746. // CASE Self_.fVerticalAlign OF
  49747. // vaCenter: Flags := Flags or DT_VCENTER;
  49748. // vaBottom: Flags := Flags or DT_BOTTOM;
  49749. // END;
  49750. {/-ecm}
  49751. {+ecm}
  49752. CtlHavingFont := PControl( Self_ );
  49753. while (CtlHavingFont <> nil) and not Assigned( CtlHavingFont.FFont ) do
  49754. CtlHavingFont := CtlHavingFont.Parent;
  49755. OldFont := 0;
  49756. if Assigned( CtlHavingFont ) then
  49757. OldFont := SelectObject( PControl( Self_ ).Canvas.Handle, CtlHavingFont.Font.Handle );
  49758. {/+ecm}
  49759. // DrawText return the height of the text !
  49760. SZ.cy := DrawText( PControl( Self_ ).Canvas.Handle, PKOLChar( Txt ), Length( Txt ), R, Flags );
  49761. {+ecm}
  49762. if Assigned( CtlHavingFont ) then
  49763. SelectObject(PControl( Self_ ).Canvas.fHandle,OldFont);
  49764. {/+ecm}
  49765. SZ.cx := R.Right - R.Left;
  49766. {$ifdef wince}
  49767. Inc(SZ.cx);
  49768. {$endif wince}
  49769. //SZ.cy := R.Bottom - R.Top;
  49770. end
  49771. else
  49772. PControl( Self_ ).Canvas.TextArea( Txt, SZ, PT );
  49773. end;
  49774. Chg := FALSE;
  49775. OldNotUseAlign:=PControl( Self_ ).fNotUseAlign;
  49776. PControl( Self_ ).fNotUseAlign:=True;
  49777. if PControl( Self_ ).FAlign in [ caNone, caLeft, caRight ] then
  49778. begin
  49779. DeltaX := PControl( Self_ ).fCommandActions.aAutoSzX;
  49780. if PControl( Self_ ).Width <> SZ.cx + DeltaX then
  49781. begin
  49782. PControl( Self_ ).Width := SZ.cx + DeltaX;
  49783. Chg := TRUE;
  49784. end;
  49785. if PControl( Self_ ).fMinWidth > PControl( Self_ ).Width then
  49786. begin
  49787. PControl( Self_ ).Width := PControl( Self_ ).fMinWidth;
  49788. Chg := TRUE;
  49789. end;
  49790. end;
  49791. if PControl( Self_ ).FAlign in [ caNone, caTop, caBottom ] then
  49792. begin
  49793. DeltaY := PControl( Self_ ).fCommandActions.aAutoSzY;
  49794. if PControl( Self_ ).Height <> SZ.cy + DeltaY then
  49795. begin
  49796. PControl( Self_ ).Height := SZ.cy + DeltaY;
  49797. Chg := TRUE;
  49798. end;
  49799. if PControl( Self_ ).FMinHeight > PControl( Self_ ).Height then
  49800. begin
  49801. PControl( Self_ ).Height := PControl( Self_ ).FMinHeight;
  49802. Chg := TRUE;
  49803. end;
  49804. end;
  49805. PControl( Self_ ).fNotUseAlign:=OldNotUseAlign;
  49806. if Chg then
  49807. begin
  49808. {$IFDEF OLD_ALIGN}
  49809. if PControl( Self_ ).fParent <> nil then
  49810. Global_Align( PControl( Self_ ).fParent );
  49811. {$ENDIF}
  49812. Global_Align( Self_ );
  49813. end;
  49814. end;
  49815. {$ENDIF GDI}
  49816. {$IFDEF _X_}
  49817. {$IFDEF GTK}
  49818. procedure AutoSzProc( Self_: PObj );
  49819. var SZ: TSize;
  49820. //Txt: KOLString;
  49821. Chg: Boolean;
  49822. req_captn, req_evbox: TGtkRequisition;
  49823. begin
  49824. //Txt := PControl( Self_ ).fCaption;
  49825. SZ.cx := 0;
  49826. SZ.cy := 0;
  49827. //if Txt <> '' then
  49828. begin
  49829. {if Assigned( PControl( Self_ ).fFont ) then
  49830. if PControl( Self_ ).fFont.fData.Font.Italic then
  49831. Txt := Txt + ' ';}
  49832. gtk_widget_size_request( PControl( Self_ ).fCaptionHandle, @ req_captn );
  49833. //gtk_widget_get_size_request( PControl( Self_ ).fCaptionHandle, @ Sz.cx, @ Sz.cy );
  49834. //gtk_widget_size_request( PControl( Self_ ).fEventboxHandle, @ requisition2 );
  49835. {if Sz.cx < 0 then Sz.cx := PControl( Self_ ).Width;
  49836. if Sz.cy < 0 then Sz.cy := PControl( Self_ ).Height;
  49837. Sz.cx := max( requisition2.width, requisition1.width + requisition2.width - Sz.cx );
  49838. Sz.cy := max( requisition2.height, requisition1.height + requisition2.height - Sz.cy );}
  49839. if (PControl( Self_ ).fDeltaX = 0) and
  49840. (PControl( Self_ ).fDeltaY = 0) then
  49841. begin
  49842. gtk_widget_size_request( PControl( Self_ ).fEventboxHandle, @ req_evbox );
  49843. PControl( Self_ ).fDeltaX := Max( 0, req_evbox.width - req_captn.width );
  49844. PControl( Self_ ).fDeltaY := Max( 0, req_evbox.height - req_captn.height );
  49845. end;
  49846. Sz.cx := req_captn.width + PControl( Self_ ).fDeltaX;
  49847. Sz.cy := req_captn.height + PControl( Self_ ).fDeltaY;
  49848. //gtk_widget_get_size_request( PControl( Self_ ).fHandle, @ Sz.cx, @ Sz.cy );
  49849. end;
  49850. Chg := FALSE;
  49851. if PControl( Self_ ).FAlign in [ caNone, caLeft, caRight ] then
  49852. begin
  49853. //DeltaX := PControl( Self_ ).fCommandActions.aAutoSzX;
  49854. if PControl( Self_ ).Width <> SZ.cx {+ DeltaX} then
  49855. begin
  49856. PControl( Self_ ).Width := SZ.cx {+ DeltaX};
  49857. Chg := TRUE;
  49858. end;
  49859. if PControl( Self_ ).fMinWidth > PControl( Self_ ).Width then
  49860. begin
  49861. PControl( Self_ ).Width := PControl( Self_ ).fMinWidth;
  49862. Chg := TRUE;
  49863. end;
  49864. end;
  49865. if PControl( Self_ ).FAlign in [ caNone, caTop, caBottom ] then
  49866. begin
  49867. //DeltaY := PControl( Self_ ).fCommandActions.aAutoSzY;
  49868. if PControl( Self_ ).Height <> SZ.cy {+ DeltaY} then
  49869. begin
  49870. PControl( Self_ ).Height := SZ.cy {+ DeltaY};
  49871. Chg := TRUE;
  49872. end;
  49873. if PControl( Self_ ).FMinHeight > PControl( Self_ ).Height then
  49874. begin
  49875. PControl( Self_ ).Height := PControl( Self_ ).FMinHeight;
  49876. Chg := TRUE;
  49877. end;
  49878. end;
  49879. if Chg then
  49880. begin
  49881. {$IFDEF OLD_ALIGN}
  49882. if PControl( Self_ ).fParent <> nil then
  49883. Global_Align( PControl( Self_ ).fParent );
  49884. {$ENDIF}
  49885. Global_Align( Self_ );
  49886. end;
  49887. end;
  49888. {$ENDIF GTK}
  49889. {$ENDIF _X_}
  49890. //[function TControl.AutoSize]
  49891. function TControl.AutoSize(AutoSzOn: Boolean): PControl;
  49892. begin
  49893. if AutoSzOn then
  49894. begin
  49895. fAutoSize := AutoSzProc;
  49896. DoAutoSize;
  49897. end
  49898. else
  49899. fAutoSize := DummyObjProc;
  49900. Result := @Self;
  49901. end;
  49902. {$IFDEF WIN_GDI}
  49903. //[function TControl.IsAutoSize]
  49904. function TControl.IsAutoSize: Boolean;
  49905. begin
  49906. Result := Assigned( fAutoSize );
  49907. end;
  49908. //*
  49909. //[function TControl.GetToBeVisible]
  49910. function TControl.GetToBeVisible: Boolean;
  49911. begin
  49912. Result := fVisible or fCreateHidden or fVisibleWoParent;
  49913. if fIsControl then
  49914. if Parent <> nil then
  49915. begin
  49916. if fVisibleWoParent then
  49917. Result := fVisible
  49918. else
  49919. begin
  49920. Parent.Visible; // needed to provide correct fVisible for a form!
  49921. Result := Result and Parent.ToBeVisible;
  49922. end;
  49923. end;
  49924. end;
  49925. ///////////////////////////////////////////////////////////////////////
  49926. // W I N D O W S
  49927. ///////////////////////////////////////////////////////////////////////
  49928. { -- Set of window-related utility functions. -- }
  49929. type
  49930. PGUIThreadInfo = ^TGUIThreadInfo;
  49931. tagGUITHREADINFO = {$ifndef wince}packed{$endif} record
  49932. cbSize: DWORD;
  49933. flags: DWORD;
  49934. hwndActive: HWND;
  49935. hwndFocus: HWND;
  49936. hwndCapture: HWND;
  49937. hwndMenuOwner: HWND;
  49938. hwndMoveSize: HWND;
  49939. hwndCaret: HWND;
  49940. rcCaret: TRect;
  49941. end;
  49942. TGUIThreadInfo = tagGUITHREADINFO;
  49943. const
  49944. GUI_CARETBLINKING = $00000001;
  49945. GUI_INMOVESIZE = $00000002;
  49946. GUI_INMENUMODE = $00000004;
  49947. GUI_SYSTEMMENUMODE = $00000008;
  49948. GUI_POPUPMENUMODE = $00000010;
  49949. type TGUIThreadInfo_Proc = function( ThreadID: THandle; var GTI: TGUIThreadInfo )
  49950. : Boolean; {$ifdef wince}cdecl{$else}stdcall{$endif};
  49951. var Proc_GetGUIThreadInfo: TGuiThreadInfo_Proc;
  49952. //[function GetWindowChild]
  49953. function GetWindowChild( Wnd: HWnd; Kind: TWindowChildKind ): HWnd;
  49954. var GTI: TGuiThreadInfo;
  49955. ThreadID: THandle;
  49956. Module: THandle;
  49957. begin
  49958. if not Assigned( Proc_GetGUIThreadInfo ) then
  49959. begin
  49960. Module := GetModuleHandle( 'User32' );
  49961. Proc_GetGUIThreadInfo := GetProcAddress( Module, 'GetGUIThreadInfoA' );
  49962. if not Assigned( Proc_GetGUIThreadInfo ) then
  49963. Proc_GetGUIThreadInfo := Pointer( -1 );
  49964. end;
  49965. Result := Wnd;
  49966. if @Proc_GetGUIThreadInfo = Pointer( -1 ) then
  49967. Exit;
  49968. Result := 0;
  49969. if Wnd = 0 then
  49970. ThreadID := GetCurrentThreadID
  49971. else
  49972. ThreadID := GetWindowThreadProcessID( Wnd, nil );
  49973. if ThreadID = 0 then Exit;
  49974. GTI.cbSize := Sizeof( GTI );
  49975. if Proc_GetGUIThreadInfo( ThreadId, GTI ) then
  49976. begin
  49977. case Kind of
  49978. wcActive: Result := GTI.hwndActive;
  49979. wcFocus: Result := GTI.hwndFocus;
  49980. wcCapture: Result := GTI.hwndCapture;
  49981. wcMenuOwner: Result := GTI.hwndMenuOwner;
  49982. wcMoveSize: Result := GTI.hwndMoveSize;
  49983. wcCaret: Result := GTI.hwndCaret;
  49984. end;
  49985. end;
  49986. end;
  49987. {$ifdef win32}
  49988. //[function GetFocusedChild]
  49989. function GetFocusedChild( Wnd: HWnd ): HWnd;
  49990. var Tr1, Tr2: THandle;
  49991. begin
  49992. Result := 0;
  49993. Tr1 := GetCurrentThreadId;
  49994. Tr2 := GetWindowThreadProcessId( Wnd, nil );
  49995. if Tr1 = Tr2 then
  49996. Result := GetFocus
  49997. else
  49998. if AttachThreadInput( Tr2, Tr1, True ) then
  49999. begin
  50000. Result := GetFocus;
  50001. AttachThreadInput( Tr2, Tr1, False );
  50002. end;
  50003. end;
  50004. //[function WaitFocusedWndChild]
  50005. function WaitFocusedWndChild( Wnd: HWnd ): HWnd;
  50006. var T1, T2: Integer;
  50007. W: HWnd;
  50008. begin
  50009. Sleep( 50 );
  50010. T1 := GetTickCount;
  50011. while True do
  50012. begin
  50013. W := GetTopWindow( Wnd );
  50014. if W = 0 then W := Wnd;
  50015. W := GetFocusedChild( W );
  50016. if W <> 0 then
  50017. begin
  50018. Wnd := W;
  50019. break;
  50020. end;
  50021. T2 := GetTickCount;
  50022. if Abs( T1 - T2 ) > 100 then break;
  50023. end;
  50024. Result := Wnd;
  50025. end;
  50026. //[function Stroke2Window]
  50027. function Stroke2Window( Wnd: HWnd; const S: String ): Boolean;
  50028. var P: PChar;
  50029. begin
  50030. Result := False;
  50031. //Wnd := GetTopWindow( Wnd );
  50032. Wnd := WaitFocusedWndChild( Wnd );
  50033. if Wnd = 0 then Exit;
  50034. P := PChar( S );
  50035. while P^ <> #0 do
  50036. begin
  50037. PostMessage( Wnd, WM_CHAR, Integer( P^ ), 1 );
  50038. Inc( P );
  50039. end;
  50040. Result := True;
  50041. end;
  50042. //[function Stroke2WindowEx]
  50043. function Stroke2WindowEx( Wnd: HWnd; const S: String; Wait: Boolean ): Boolean;
  50044. var P: PChar;
  50045. EndChar: Char;
  50046. MsgDn, MsgUp, SCA: Integer;
  50047. function Compare( Pattern: PChar ): Boolean;
  50048. var Pos: PChar;
  50049. C1, C2: Char;
  50050. begin
  50051. Pos := P;
  50052. while Pattern^ <> #0 do
  50053. begin
  50054. C1 := Pattern^;
  50055. C2 := Pos^;
  50056. if C1 in [ 'a'..'z' ] then
  50057. C1 := Char( Ord( C1 ) - $20 );
  50058. if C2 in [ 'a'..'z' ] then
  50059. C2 := Char( Ord( C2 ) - $20 );
  50060. if C1 <> C2 then
  50061. begin
  50062. Result := False;
  50063. Exit;
  50064. end;
  50065. Inc( Pos );
  50066. Inc( Pattern );
  50067. end;
  50068. while Pos^ = ' ' do Inc( Pos );
  50069. P := Pos;
  50070. Result := True;
  50071. end;
  50072. procedure Send( Msg, KeyCode: Integer );
  50073. var lParam: Integer;
  50074. begin
  50075. Wnd := WaitFocusedWndChild( Wnd );
  50076. if Wnd = 0 then Exit;
  50077. lParam := 1;
  50078. if longBool( SCA and 4 ) then
  50079. lParam := $20000001;
  50080. if Msg = MsgUp then
  50081. lParam := lParam or Integer($D0000000);
  50082. PostMessage( Wnd, Msg, KeyCode, lParam );
  50083. Applet.ProcessMessages;
  50084. if Wait then
  50085. Sleep( 50 );
  50086. end;
  50087. function CompareSend( Pattern: PChar; Value2Send: Integer ): Boolean;
  50088. begin
  50089. if Compare( Pattern ) then
  50090. begin
  50091. Send( MsgDn, Value2Send );
  50092. Send( MsgUp, Value2Send );
  50093. Result := True;
  50094. end
  50095. else
  50096. Result := False;
  50097. end;
  50098. function ParseKeys( EndChar: Char ): PChar;
  50099. var FN: Integer;
  50100. begin
  50101. SCA := 0;
  50102. while not (P^ in [ #0, EndChar ]) do
  50103. begin
  50104. if Compare( 'Shift' ) then SCA := SCA or 1
  50105. else
  50106. if Compare( 'Ctrl' ) then SCA := SCA or 2
  50107. else
  50108. if Compare( 'Alt' ) then SCA := SCA or 4
  50109. else
  50110. break;
  50111. end;
  50112. MsgDn := WM_KEYDOWN;
  50113. MsgUp := WM_KEYUP;
  50114. if LongBool( SCA and 4 ) then
  50115. begin
  50116. MsgDn := WM_SYSKEYDOWN;
  50117. MsgUp := WM_SYSKEYUP;
  50118. keybd_event( VK_MENU, 0, 0, 0 );
  50119. Send( WM_SYSKEYDOWN, VK_MENU );
  50120. end;
  50121. if LongBool( SCA and 2 ) then
  50122. begin
  50123. keybd_event( VK_CONTROL, 0, 0, 0 );
  50124. Send( WM_KEYDOWN, VK_CONTROL );
  50125. end;
  50126. if Longbool( SCA and 1 ) then
  50127. begin
  50128. keybd_event( VK_SHIFT, 0, 0, 0 );
  50129. Send( WM_KEYDOWN, VK_SHIFT );
  50130. end;
  50131. while not (P^ in [ #0, EndChar ]) do
  50132. begin
  50133. if (P^ = 'F') and (P[ 1 ] in [ '1'..'9' ]) then
  50134. begin
  50135. Inc( P );
  50136. FN := Ord( P^ ) - Ord( '0' );
  50137. if (FN = 1) and (P[ 1 ] in [ '0'..'2' ]) then
  50138. begin
  50139. Inc( P );
  50140. FN := 10 + Ord( P^ ) - Ord( '0' );
  50141. end;
  50142. repeat Inc( P ) until P^ <> ' ';
  50143. FN := FN + $6F;
  50144. Send( MsgDn, FN );
  50145. Send( MsgUp, FN );
  50146. end
  50147. else
  50148. if Compare( 'Numpad' ) then
  50149. begin
  50150. if P^ in [ '0'..'9' ] then
  50151. begin
  50152. FN := Ord( P^ ) - Ord( '0' ) + $60;
  50153. repeat Inc( P^ ) until P^ <> ' ';
  50154. Send( MsgDn, FN );
  50155. Send( MsgUp, FN );
  50156. end;
  50157. end
  50158. else
  50159. if not (CompareSend( 'Add', $6B ) or
  50160. CompareSend( 'Gray+', $6B ) or
  50161. CompareSend( 'Apps', $5D ) or
  50162. CompareSend( 'BackSpace', $08 ) or
  50163. CompareSend( 'BkSp', $08 ) or
  50164. CompareSend( 'BS', $08 ) or
  50165. CompareSend( 'Break', $13 ) or
  50166. CompareSend( 'CapsLock', $14 ) or
  50167. CompareSend( 'Clear', $0C ) or
  50168. CompareSend( 'Decimal', $6E ) or
  50169. CompareSend( 'Del', $2E ) or
  50170. CompareSend( 'Delete', $2E ) or
  50171. CompareSend( 'Divide', $6F ) or
  50172. CompareSend( 'Gray/', $6F ) or
  50173. CompareSend( 'Down', $28 ) or
  50174. CompareSend( 'End', $23 ) or
  50175. CompareSend( 'Enter', $0D ) or
  50176. CompareSend( 'Return', $0D ) or
  50177. CompareSend( 'CR', $0D ) or
  50178. CompareSend( 'Esc', $1B ) or
  50179. CompareSend( 'Escape', $1B ) or
  50180. CompareSend( 'Help', $2F ) or
  50181. CompareSend( 'Home', $24 ) or
  50182. CompareSend( 'Ins', $2D ) or
  50183. CompareSend( 'Insert', $2D ) or
  50184. CompareSend( 'Left', $25 ) or
  50185. CompareSend( 'LWin', $5B ) or
  50186. CompareSend( 'Multiply', $6A ) or
  50187. CompareSend( 'Gray*', $6A ) or
  50188. CompareSend( 'NumLock', $90 ) or
  50189. CompareSend( 'PgDn', $22 ) or
  50190. CompareSend( 'PgUp', $21 ) or
  50191. CompareSend( 'PrintScrn', $2C ) or
  50192. CompareSend( 'Right', $27 ) or
  50193. CompareSend( 'RWin', $5C ) or
  50194. CompareSend( 'Separator', $6C ) or
  50195. CompareSend( 'ScrollLock', $91 ) or
  50196. CompareSend( 'Subtract', $6D ) or
  50197. CompareSend( 'Tab', $09 ) or
  50198. CompareSend( 'Gray-', $6D ) or
  50199. CompareSend( 'Up', $26 )) then break;
  50200. end;
  50201. while not (P^ in [ #0, EndChar ]) do
  50202. begin
  50203. if P^ in [ 'A'..'Z', '0'..'9' ] then
  50204. begin
  50205. Send( MsgDn, Integer( P^ ) );
  50206. Send( MsgUp, Integer( P^ ) );
  50207. end
  50208. else
  50209. if P^ in [ #1..#255 ] then
  50210. Stroke2Window( Wnd, '' + P^ );
  50211. repeat Inc( P ) until (P^ <> ' ');
  50212. end;
  50213. if P^ = EndChar then
  50214. Inc( P );
  50215. if Longbool( SCA and 1 ) then
  50216. begin
  50217. Send( WM_KEYUP, VK_SHIFT );
  50218. keybd_event( VK_SHIFT, 0, KEYEVENTF_KEYUP, 0 );
  50219. end;
  50220. if LongBool( SCA and 2 ) then
  50221. begin
  50222. Send( WM_KEYUP, VK_CONTROL );
  50223. keybd_event( VK_CONTROL, 0, KEYEVENTF_KEYUP, 0 );
  50224. end;
  50225. if LongBool( SCA and 4 ) then
  50226. begin
  50227. Send( WM_SYSKEYUP, VK_MENU );
  50228. keybd_event( VK_MENU, 0, KEYEVENTF_KEYUP, 0 );
  50229. end;
  50230. Result := P;
  50231. end;
  50232. begin
  50233. Result := False;
  50234. Wnd := GetTopWindow( Wnd );
  50235. Wnd := GetFocusedChild( Wnd );
  50236. if Wnd = 0 then Exit;
  50237. P := PChar( S );
  50238. while P^ <> #0 do
  50239. begin
  50240. if not (P^ in [ '[', '{' ]) then
  50241. begin
  50242. Stroke2Window( Wnd, '' + P^ );
  50243. Inc( P );
  50244. end
  50245. else
  50246. begin
  50247. if P^ = '[' then
  50248. EndChar := ']'
  50249. else
  50250. EndChar := '}';
  50251. Inc( P );
  50252. P := ParseKeys( EndChar );
  50253. end;
  50254. end;
  50255. Result := True;
  50256. end;
  50257. {$endif win32}
  50258. type
  50259. PHWnd = ^HWnd;
  50260. TFindWndRec = {$ifndef wince}packed{$endif} Record
  50261. ThreadID : DWord;
  50262. WndFound : HWnd;
  50263. end;
  50264. PFindWndRec = ^TFindWndRec;
  50265. //[function EnumWindowsProc]
  50266. function EnumWindowsProc( Wnd : HWnd; Find : PFindWndRec ) : Boolean;
  50267. {$ifdef wince}cdecl{$else}stdcall{$endif};
  50268. var Id : DWord;
  50269. begin
  50270. Result := True;
  50271. Id := GetWindowThreadProcessId( Wnd, @Id );
  50272. if Id = Find.ThreadID then
  50273. begin
  50274. Find.WndFound := Wnd;
  50275. Result := False;
  50276. end;
  50277. end;
  50278. //[function FindWindowByThreadID]
  50279. function FindWindowByThreadID( ThreadID : DWORD ) : HWnd;
  50280. var Find : TFindWndRec;
  50281. begin
  50282. Find.ThreadID := ThreadID;
  50283. Find.WndFound := 0;
  50284. EnumWindows( @EnumWindowsProc, Integer( @Find ) );
  50285. Result := Find.WndFound;
  50286. end;
  50287. //[function DesktopPixelFormat]
  50288. function DesktopPixelFormat: TPixelFormat;
  50289. var DC: HDC;
  50290. Nbits_per_pixel, Nplanes: Integer;
  50291. begin
  50292. DC := GetDC( 0 );
  50293. Nbits_per_pixel := GetDeviceCaps( DC, BITSPIXEL );
  50294. Nplanes := GetDeviceCaps( DC, PLANES );
  50295. ReleaseDC( 0, DC );
  50296. CASE Nplanes * Nbits_per_pixel OF
  50297. 1: Result := pf1bit;
  50298. 4: Result := pf4bit;
  50299. 8: Result := pf8bit;
  50300. 16: Result := pf16bit;
  50301. 24, 32: Result := pf32bit;
  50302. else Result := pfDevice;
  50303. END;
  50304. end;
  50305. //[function GetDesktopRect]
  50306. function GetDesktopRect : TRect;
  50307. {$ifdef win32}
  50308. var W1, W2 : HWnd;
  50309. {$endif win32}
  50310. begin
  50311. Result := MakeRect( 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) );
  50312. {$ifdef win32}
  50313. W2 := findwindow(nil,'Program Manager');
  50314. W1 := findwindowex(W2,0,'SHELLDLL_DefView',nil);
  50315. if W1 = 0 then Exit;
  50316. GetWindowRect( W1, Result );
  50317. {$endif win32}
  50318. end;
  50319. //[function GetWorkArea]
  50320. function GetWorkArea: TRect;
  50321. begin
  50322. SystemParametersInfo( SPI_GETWORKAREA, 0, @ Result, 0 );
  50323. end;
  50324. //[function ExecuteWait]
  50325. function ExecuteWait( const AppPath, CmdLine, DfltDirectory: KOLString;
  50326. Show: DWORD; TimeOut: DWORD; ProcID: PDWORD ): Boolean;
  50327. var Flags: DWORD;
  50328. Startup: TStartupInfo;
  50329. ProcInf: TProcessInformation;
  50330. DfltDir, pAppPath: PKOLChar;
  50331. Cmd: KOLString;
  50332. begin
  50333. Result := FALSE;
  50334. {$ifdef wince}
  50335. Flags := 0;
  50336. {$else}
  50337. Flags := CREATE_NEW_CONSOLE;
  50338. if Show = SW_HIDE then
  50339. Flags := Flags or {$IFDEF F_P}$08000000{$ELSE}CREATE_NO_WINDOW{$ENDIF};
  50340. {$endif wince}
  50341. FillChar( Startup, SizeOf( Startup ), #0 );
  50342. Startup.cb := Sizeof( Startup );
  50343. Startup.wShowWindow := Show;
  50344. Startup.dwFlags := STARTF_USESHOWWINDOW;
  50345. if ProcID <> nil then
  50346. ProcID^ := 0;
  50347. DfltDir := nil;
  50348. if DfltDirectory <> '' then
  50349. DfltDir := PKOLChar( DfltDirectory );
  50350. if AppPath <> '' then
  50351. pAppPath:=PKOLChar(AppPath)
  50352. else
  50353. pAppPath:=nil;
  50354. Cmd:=CmdLine; // CmdLine parameter must not be const
  50355. if CreateProcess( pAppPath, PKOLChar(Cmd), nil,
  50356. nil, FALSE, Flags, nil, DfltDir, Startup,
  50357. ProcInf ) then
  50358. begin
  50359. if WaitForSingleObject( ProcInf.hProcess, TimeOut ) = WAIT_OBJECT_0 then
  50360. begin
  50361. CloseHandle( ProcInf.hProcess );
  50362. Result := TRUE;
  50363. end
  50364. else
  50365. begin
  50366. if ProcID <> nil then
  50367. ProcID^ := ProcInf.hProcess;
  50368. end;
  50369. CloseHandle( ProcInf.hThread );
  50370. end;
  50371. end;
  50372. {$ifdef win32}
  50373. //[function ExecuteIORedirect]
  50374. function ExecuteIORedirect( const AppPath, CmdLine, DfltDirectory: KOLString;
  50375. Show: DWORD; ProcID: PDWORD; InPipe, OutPipeWr, OutPipeRd: PHandle ): Boolean;
  50376. var Flags: DWORD;
  50377. Startup: TStartupInfo;
  50378. ProcInf: TProcessInformation;
  50379. DfltDir: PKOLChar;
  50380. SecurityAttributes: TSecurityAttributes;
  50381. SaveStdOut, SaveStdIn: THandle;
  50382. ChildStdOutRd, ChildStdOutWr: THandle;
  50383. ChildStdInRd, ChildStdInWr: THandle;
  50384. ChildStdOutRdDup: THandle;
  50385. ChildStdInWrDup: THandle;
  50386. procedure Do_CloseHandle( var Handle: THandle );
  50387. begin
  50388. if Handle <> 0 then
  50389. begin
  50390. CloseHandle( Handle );
  50391. Handle := 0;
  50392. end;
  50393. end;
  50394. procedure Close_Handles;
  50395. begin
  50396. Do_CloseHandle( ChildStdOutRd );
  50397. Do_CloseHandle( ChildStdOutWr );
  50398. Do_CloseHandle( ChildStdInRd );
  50399. Do_CloseHandle( ChildStdInWr );
  50400. end;
  50401. function RedirectInputOutput: Boolean;
  50402. begin
  50403. Result := FALSE;
  50404. if (OutPipeRd <> nil) or (OutPipeWr <> nil) then
  50405. begin
  50406. // redirect output
  50407. SaveStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
  50408. if not CreatePipe( ChildStdOutRd, ChildStdOutWr, @ SecurityAttributes, 0 ) then
  50409. Exit;
  50410. if not SetStdHandle( STD_OUTPUT_HANDLE, ChildStdOutWr ) then
  50411. Exit;
  50412. if not DuplicateHandle( GetCurrentProcess, ChildStdOutRd,
  50413. GetCurrentProcess, @ ChildStdOutRdDup, 0, FALSE,
  50414. 2 {DUPLICATE_SAME_ACCESS} ) then
  50415. Exit;
  50416. Do_CloseHandle( ChildStdOutRd );
  50417. if OutPipeRd <> nil then
  50418. OutPipeRd^ := ChildStdOutRdDup;
  50419. if OutPipeWr <> nil then
  50420. OutPipeWr^ := ChildStdOutWr;
  50421. end;
  50422. if InPipe <> nil then
  50423. begin
  50424. // redirect input
  50425. SaveStdIn := GetStdHandle(STD_INPUT_HANDLE);
  50426. if not CreatePipe( ChildStdInRd, ChildStdInWr, @ SecurityAttributes, 0 ) then
  50427. Exit;
  50428. if not SetStdHandle( STD_INPUT_HANDLE, ChildStdInRd ) then
  50429. Exit;
  50430. if not DuplicateHandle( GetCurrentProcess, ChildStdInWr,
  50431. GetCurrentProcess, @ ChildStdInWrDup, 0, FALSE,
  50432. 2 {DUPLICATE_SAME_ACCESS} ) then
  50433. Exit;
  50434. Do_CloseHandle( ChildStdInWr );
  50435. if InPipe <> nil then
  50436. InPipe^ := ChildStdInWrDup;
  50437. Do_CloseHandle( ChildStdInRd );
  50438. end;
  50439. Result := TRUE;
  50440. end;
  50441. procedure Restore_Saved_StdInOut;
  50442. begin
  50443. SetStdHandle( STD_OUTPUT_HANDLE, SaveStdOut );
  50444. SetStdHandle( STD_INPUT_HANDLE, SaveStdIn );
  50445. end;
  50446. begin
  50447. Result := FALSE;
  50448. Flags := 0;
  50449. if Show = SW_HIDE then
  50450. Flags := Flags or {$IFDEF F_P}$08000000{$ELSE}CREATE_NO_WINDOW{$ENDIF};
  50451. FillChar( Startup, SizeOf( Startup ), #0 );
  50452. Startup.cb := Sizeof( Startup );
  50453. if ProcID <> nil then
  50454. ProcID^ := 0;
  50455. DfltDir := nil;
  50456. SecurityAttributes.nLength := Sizeof( SecurityAttributes );
  50457. SecurityAttributes.lpSecurityDescriptor := nil;
  50458. SecurityAttributes.bInheritHandle := TRUE;
  50459. SaveStdOut := 0;
  50460. SaveStdIn := 0;
  50461. ChildStdOutRd := 0;
  50462. ChildStdOutWr := 0;
  50463. ChildStdInRd := 0;
  50464. ChildStdInWr := 0;
  50465. if not RedirectInputOutput then
  50466. begin
  50467. Close_Handles;
  50468. Exit;
  50469. end;;
  50470. if DfltDirectory <> '' then
  50471. DfltDir := PKOLChar( DfltDirectory );
  50472. if CreateProcess( nil, PKOLChar( '"' + AppPath + '" ' + CmdLine ),
  50473. nil, nil, TRUE, Flags, nil, DfltDir, Startup,
  50474. ProcInf ) then
  50475. begin
  50476. if ProcID <> nil then
  50477. ProcID^ := ProcInf.hProcess
  50478. else
  50479. CloseHandle( ProcInf.hProcess );
  50480. CloseHandle( ProcInf.hThread );
  50481. Restore_Saved_StdInOut;
  50482. Result := TRUE;
  50483. end
  50484. else
  50485. begin
  50486. Restore_Saved_StdInOut;
  50487. Close_Handles;
  50488. Exit;
  50489. end;
  50490. end;
  50491. //[function ExecuteConsoleAppIORedirect]
  50492. function ExecuteConsoleAppIORedirect( const AppPath, CmdLine, DfltDirectory: String;
  50493. Show: DWORD; const InStr: String; var OutStr: String; WaitTimeout: DWORD ): Boolean;
  50494. var PipeIn, PipeOutRd, PipeOutWr: THandle;
  50495. ProcID: DWORD;
  50496. BytesCount: DWORD;
  50497. Buffer: array[ 0..4096 ] of Char;
  50498. BufStr: String;
  50499. PPipeIn: PHandle;
  50500. begin
  50501. Result := FALSE;
  50502. PPipeIn := @ PipeIn;
  50503. if InStr = '' then
  50504. PPipeIn := nil;
  50505. PipeOutRd := 0;
  50506. PipeOutWr := 0;
  50507. if not ExecuteIORedirect( AppPath, CmdLine, DfltDirectory, Show, @ ProcID,
  50508. PPipeIn, @ PipeOutWr, @ PipeOutRd ) then Exit;
  50509. if PPipeIn <> nil then
  50510. begin
  50511. if InStr <> '' then
  50512. WriteFile( PipeIn, InStr[ 1 ], Length( InStr ), BytesCount, nil );
  50513. CloseHandle( PipeIn );
  50514. end;
  50515. OutStr := '';
  50516. if WaitForSingleObject( ProcID, WaitTimeOut ) = WAIT_OBJECT_0 then
  50517. begin
  50518. CloseHandle( ProcID );
  50519. CloseHandle( PipeOutWr );
  50520. while ReadFile( PipeOutRd, Buffer, Sizeof( Buffer ), BytesCount, nil ) do
  50521. begin
  50522. SetLength( BufStr, BytesCount );
  50523. Move( Buffer[ 0 ], BufStr[ 1 ], BytesCount );
  50524. OutStr := OutStr + BufStr;
  50525. end;
  50526. end
  50527. else
  50528. CloseHandle( PipeOutWr );
  50529. CloseHandle( PipeOutRd );
  50530. Result := TRUE;
  50531. end;
  50532. {$IFDEF _D2}
  50533. //[API OpenProcessToken]
  50534. function OpenProcessToken(ProcessHandle: THandle; DesiredAccess: DWORD;
  50535. var TokenHandle: THandle): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  50536. external advapi32 name 'OpenProcessToken';
  50537. {$ENDIF}
  50538. //[function WindowsShutdown]
  50539. function WindowsShutdown( const Machine : KOLString; Force, Reboot : Boolean ) : Boolean;
  50540. var
  50541. hToken: THandle;
  50542. tkp, tkp_prev: TTokenPrivileges;
  50543. dwRetLen :DWORD;
  50544. Flags: Integer;
  50545. begin
  50546. Result := False;
  50547. if Integer( GetVersion ) < 0 then // Windows95/98/Me
  50548. begin
  50549. if Machine <> '' then Exit;
  50550. Flags := EWX_SHUTDOWN;
  50551. if Reboot then
  50552. Flags := Flags or EWX_REBOOT;
  50553. if Force then
  50554. Flags := Flags or EWX_FORCE;
  50555. Result := ExitWindowsEx( Flags, 0 );
  50556. Exit;
  50557. end;
  50558. OpenProcessToken(GetCurrentProcess(),
  50559. TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
  50560. hToken);
  50561. if not LookupPrivilegeValue(PKOLChar(Machine), 'SeShutdownPrivilege',
  50562. tkp.Privileges[0].Luid) then Exit;
  50563. tkp_prev:=tkp;
  50564. tkp.PrivilegeCount:=1;
  50565. tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
  50566. AdjustTokenPrivileges(hToken, FALSE, tkp, sizeof(tkp), tkp_prev,
  50567. dwRetLen);
  50568. if not LookupPrivilegeValue(PKOLChar(Machine),
  50569. 'SeRemoteShutdownPrivilege',
  50570. tkp.Privileges[0].Luid)
  50571. then
  50572. Exit;
  50573. tkp.PrivilegeCount:=1;
  50574. tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
  50575. AdjustTokenPrivileges(hToken, FALSE, tkp, sizeof(tkp), tkp_prev,
  50576. dwRetLen);
  50577. Result := InitiateSystemShutdown(PKOLChar(Machine),nil, 0, Force, Reboot);
  50578. end;
  50579. var SaveWinVer: Byte = $FF;
  50580. //[function WinVer]
  50581. {$IFDEF ASM_VERSION}
  50582. {$ELSE ASM_VERSION}
  50583. function WinVer : TWindowsVersion;
  50584. var MajorVersion, MinorVersion: Byte;
  50585. dwVersion: Integer;
  50586. begin
  50587. if SaveWinVer <> $FF then Result := TWindowsVersion( SaveWinVer )
  50588. else
  50589. begin
  50590. dwVersion := GetVersion;
  50591. MajorVersion := LoByte( dwVersion );
  50592. MinorVersion := HiByte( LoWord( dwVersion ) );
  50593. if dwVersion >= 0 then
  50594. begin
  50595. Result := wvNT;
  50596. if MajorVersion >= 6 then
  50597. Result := wvVista
  50598. else begin
  50599. if MajorVersion >= 5 then
  50600. if MinorVersion >= 1 then
  50601. begin
  50602. Result := wvXP;
  50603. if MinorVersion >= 2 then
  50604. Result := wvServer2003;
  50605. end
  50606. else Result := wvY2K;
  50607. end;
  50608. end
  50609. else
  50610. begin
  50611. Result := wv95;
  50612. if (MajorVersion > 4) or
  50613. (MajorVersion = 4) and (MinorVersion >= 10) then
  50614. begin
  50615. Result := wv98;
  50616. if (MajorVersion = 4) and (MinorVersion >= $5A) then
  50617. Result := wvME;
  50618. end
  50619. else
  50620. if MajorVersion <= 3 then
  50621. Result := wv31;
  50622. end;
  50623. SaveWinVer := Ord( Result );
  50624. end;
  50625. end;
  50626. {$ENDIF ASM_VERSION}
  50627. {$else}
  50628. function WinVer : TWindowsVersion;
  50629. begin
  50630. Result:=wvCE;
  50631. end;
  50632. {$endif win32}
  50633. //[function IsWinVer]
  50634. function IsWinVer( Ver : TWindowsVersions ) : Boolean;
  50635. {* Returns True if Windows version is in given range of values. }
  50636. begin
  50637. Result := WinVer in Ver;
  50638. end;
  50639. //[procedure TControl.SetAlphaBlend]
  50640. procedure TControl.SetAlphaBlend(const Value: Integer);
  50641. const
  50642. LWA_COLORKEY=$00000001;
  50643. LWA_ALPHA=$00000002;
  50644. ULW_COLORKEY=$00000001;
  50645. ULW_ALPHA=$00000002;
  50646. ULW_OPAQUE=$00000004;
  50647. WS_EX_LAYERED=$00080000;
  50648. type
  50649. TSetLayeredWindowAttributes=
  50650. function( hwnd: Integer; crKey: TColor; bAlpha: Byte; dwFlags: DWORD )
  50651. : Boolean; {$ifdef wince}cdecl{$else}stdcall{$endif};
  50652. var
  50653. SetLayeredWindowAttributes: TSetLayeredWindowAttributes;
  50654. User32: THandle;
  50655. dw: DWORD;
  50656. begin
  50657. if Value = fAlphaBlend then Exit;
  50658. fAlphaBlend := Value;
  50659. User32 := GetModuleHandle( 'User32' );
  50660. SetLayeredWindowAttributes := GetProcAddress( User32,
  50661. 'SetLayeredWindowAttributes' );
  50662. if Assigned( SetLayeredWindowAttributes ) then
  50663. begin
  50664. dw := GetWindowLong( GetWindowHandle, GWL_EXSTYLE );
  50665. if Byte( Value ) < 255 then
  50666. begin
  50667. SetWindowLong( fHandle, GWL_EXSTYLE, dw or WS_EX_LAYERED );
  50668. SetLayeredWindowAttributes( fHandle, 0, Value and $FF, LWA_ALPHA);
  50669. end
  50670. else
  50671. SetWindowLong( fHandle, GWL_EXSTYLE, dw and not WS_EX_LAYERED );
  50672. end;
  50673. end;
  50674. {$ENDIF WIN_GDI}
  50675. //[function TControl.SetPosition]
  50676. function TControl.SetPosition( X, Y: Integer ): PControl;
  50677. begin
  50678. Left := X;
  50679. Top := Y;
  50680. Result := @Self;
  50681. end;
  50682. {$IFDEF WIN_GDI}
  50683. //[function NewColorDialog]
  50684. function NewColorDialog( FullOpen: TColorCustomOption ): PColorDialog;
  50685. var I: Integer;
  50686. begin
  50687. {-}
  50688. New( Result, Create );
  50689. {+}{++}(*Result := PColorDialog.Create;*){--}
  50690. Result.ColorCustomOption := FullOpen;
  50691. for I := 1 to 16 do
  50692. Result.CustomColors[ I ] := clWhite;
  50693. end;
  50694. //[END NewColorDialog]
  50695. { TColorDialog }
  50696. //[function TColorDialog.Execute]
  50697. function TColorDialog.Execute: Boolean;
  50698. var CD: TChooseColor;
  50699. begin
  50700. CD.lStructSize := Sizeof( CD );
  50701. CD.hWndOwner := OwnerWindow;
  50702. //CD.hInstance := 0;
  50703. CD.rgbResult := Color2RGB( Color );
  50704. CD.lpCustColors := @CustomColors[ 1 ];
  50705. CD.Flags := CC_RGBINIT;
  50706. case ColorCustomOption of
  50707. ccoFullOpen: CD.Flags := CD.Flags or CC_FULLOPEN;
  50708. ccoPreventFullOpen: CD.Flags := CD.Flags or CC_PREVENTFULLOPEN;
  50709. end;
  50710. Result := ChooseColor( {$ifdef wince}@{$endif}CD );
  50711. if Result then
  50712. Color := CD.rgbResult;
  50713. end;
  50714. //[procedure TControl.SetMaxProgress]
  50715. procedure TControl.SetMaxProgress(const Index, Value: Integer);
  50716. begin
  50717. // ignore index, and set Value via PBM_SETRANGE32: ()
  50718. Perform( PBM_SETRANGE32, 0, Value );
  50719. end;
  50720. //[procedure TControl.SetDroppedWidth]
  50721. procedure TControl.SetDroppedWidth(const Value: Integer);
  50722. begin
  50723. FDroppedWidth := Value;
  50724. Perform( CB_SETDROPPEDWIDTH, Value, 0 );
  50725. end;
  50726. //[function TControl.LVGetItemState]
  50727. function TControl.LVGetItemState(Idx: Integer): TListViewItemState;
  50728. type
  50729. PListViewItemState = ^TListViewItemState;
  50730. var I: integer;
  50731. begin
  50732. I := Perform( LVM_GETITEMSTATE, Idx,
  50733. LVIS_CUT or LVIS_DROPHILITED or LVIS_FOCUSED or LVIS_SELECTED );
  50734. Result := PListViewItemState( @ I )^;
  50735. end;
  50736. //[procedure TControl.LVSetItemState]
  50737. procedure TControl.LVSetItemState(Idx: Integer; const Value: TListViewItemState);
  50738. var Data: TLVItem;
  50739. begin
  50740. Data.stateMask := LVIS_FOCUSED or LVIS_SELECTED or LVIS_CUT or LVIS_DROPHILITED;
  50741. Data.state := PByte( @ Value )^;
  50742. Perform( LVM_SETITEMSTATE, Idx, Integer( @Data ) );
  50743. end;
  50744. //[procedure TControl.LVSelectAll]
  50745. procedure TControl.LVSelectAll;
  50746. begin
  50747. LVSetItemState( -1, [ lvisSelect ] );
  50748. end;
  50749. //[function TControl.LVItemInsert]
  50750. function TControl.LVItemInsert(Idx: Integer; const aText: KOLString): Integer;
  50751. var LVI: TLVItem;
  50752. begin
  50753. LVI.mask := LVIF_TEXT;
  50754. LVI.iItem := Idx;
  50755. LVI.iSubItem := 0;
  50756. LVI.pszText := PKOL_Char( aText );
  50757. Result := Perform( LVM_INSERTITEM, 0, Integer( @LVI ) );
  50758. end;
  50759. //[function TControl.LVItemAdd]
  50760. function TControl.LVItemAdd(const aText: KOLString): Integer;
  50761. begin
  50762. Result := LVItemInsert( Count, aText );
  50763. end;
  50764. //[function TControl.LVGetSttImgIdx]
  50765. function TControl.LVGetSttImgIdx(Idx: Integer): Integer;
  50766. begin
  50767. Result := Perform( LVM_GETITEMSTATE, Idx, LVIS_STATEIMAGEMASK ) shr 12;
  50768. end;
  50769. //[procedure TControl.LVSetSttImgIdx]
  50770. procedure TControl.LVSetSttImgIdx(Idx: Integer; const Value: Integer);
  50771. var LVI: TLVItem;
  50772. begin
  50773. LVI.stateMask := LVIS_STATEIMAGEMASK;
  50774. LVI.state := Value shl 12;
  50775. Perform( LVM_SETITEMSTATE, Idx, Integer( @LVI ) );
  50776. end;
  50777. //[function TControl.LVGetOvlImgIdx]
  50778. function TControl.LVGetOvlImgIdx(Idx: Integer): Integer;
  50779. begin
  50780. Result := Perform( LVM_GETITEMSTATE, Idx, LVIS_OVERLAYMASK ) shr 8;
  50781. end;
  50782. //[procedure TControl.LVSetOvlImgIdx]
  50783. procedure TControl.LVSetOvlImgIdx(Idx: Integer; const Value: Integer);
  50784. var LVI: TLVItem;
  50785. begin
  50786. LVI.stateMask := LVIS_OVERLAYMASK;
  50787. LVI.state := Value shl 8;
  50788. Perform( LVM_SETITEMSTATE, Idx, Integer( @LVI ) );
  50789. end;
  50790. //[function TControl.LVGetItemData]
  50791. function TControl.LVGetItemData(Idx: Integer): DWORD;
  50792. var LVI: TLVItem;
  50793. begin
  50794. LVI.mask := LVIF_PARAM;
  50795. LVI.iItem := Idx;
  50796. LVI.iSubItem := 0;
  50797. Perform( LVM_GETITEM, 0, Integer( @LVI ) );
  50798. Result := LVI.lParam;
  50799. end;
  50800. //[procedure TControl.LVSetItemData]
  50801. procedure TControl.LVSetItemData(Idx: Integer; const Value: DWORD);
  50802. var LVI: TLVItem;
  50803. begin
  50804. LVI.mask := LVIF_PARAM;
  50805. LVI.iItem := Idx;
  50806. LVI.iSubItem := 0;
  50807. LVI.lParam := Value;
  50808. Perform( LVM_SETITEM, 0, Integer( @LVI ) );
  50809. end;
  50810. //[function TControl.LVGetItemIndent]
  50811. function TControl.LVGetItemIndent(Idx: Integer): Integer;
  50812. var LI: TLVItem;
  50813. begin
  50814. LI.mask := LVIF_INDENT;
  50815. LI.iItem := Idx;
  50816. LI.iSubItem := 0;
  50817. Perform( LVM_GETITEM, 0, Integer( @LI ) );
  50818. Result := LI.iIndent;
  50819. end;
  50820. //[procedure TControl.LVSetItemIndent]
  50821. procedure TControl.LVSetItemIndent(Idx: Integer; const Value: Integer);
  50822. var LI: TLVItem;
  50823. begin
  50824. LI.mask := LVIF_INDENT;
  50825. LI.iItem := Idx;
  50826. LI.iSubItem := 0;
  50827. LI.iIndent := Value;
  50828. Perform( LVM_SETITEM, 0, Integer( @LI ) );
  50829. end;
  50830. type
  50831. TNMLISTVIEW = {$ifndef wince}packed{$endif} Record
  50832. hdr: TNMHDR;
  50833. iItem: Integer;
  50834. iSubItem: Integer;
  50835. uNewState: Integer;
  50836. uOldState: Integer;
  50837. uChanged: Integer;
  50838. ptAction: Integer;
  50839. lParam: DWORD;
  50840. end;
  50841. PNMLISTVIEW = ^TNMLISTVIEW;
  50842. //[function WndProc_LVDeleteItem]
  50843. function WndProc_LVDeleteItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  50844. : Boolean;
  50845. var Hdr: PNMHDR;
  50846. LV: PNMListView;
  50847. begin
  50848. Result := FALSE;
  50849. if Msg.message = WM_NOTIFY then
  50850. begin
  50851. Hdr := Pointer(Msg.lParam);
  50852. if Hdr.hwndFrom = Sender.Handle then
  50853. begin
  50854. LV := Pointer( Hdr );
  50855. if LongInt(Hdr.code) = LVN_DELETEITEM then
  50856. begin
  50857. if Assigned( Sender.OnDeleteLVItem ) then
  50858. Sender.OnDeleteLVItem( Sender, LV.iItem );
  50859. Result := TRUE;
  50860. end
  50861. else
  50862. if LongInt(Hdr.code) = LVN_DELETEALLITEMS then
  50863. begin
  50864. if Assigned( Sender.OnDeleteAllLVItems ) then
  50865. begin
  50866. Sender.OnDeleteAllLVItems( Sender );
  50867. Rslt := 0;
  50868. if Assigned( Sender.OnDeleteLVItem ) then
  50869. Rslt := 1;
  50870. end;
  50871. Result := TRUE;
  50872. end;
  50873. end;
  50874. end;
  50875. end;
  50876. //[procedure TControl.SetOnDeleteAllLVItems]
  50877. procedure TControl.SetOnDeleteAllLVItems(const Value: TOnEvent);
  50878. begin
  50879. fOnDeleteAllLVItems := Value;
  50880. AttachProc( @WndProc_LVDeleteItem );
  50881. end;
  50882. //[procedure TControl.SetOnDeleteLVItem]
  50883. procedure TControl.SetOnDeleteLVItem(const Value: TOnDeleteLVItem);
  50884. begin
  50885. fOnDeleteLVItem := Value;
  50886. AttachProc( @WndProc_LVDeleteItem );
  50887. end;
  50888. //[function WndProc_LVData]
  50889. function WndProc_LVData( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  50890. : Boolean;
  50891. var Hdr: PNMHDR;
  50892. DI: PLVDispInfo;
  50893. Store: Boolean;
  50894. Txt: KOL_String;
  50895. LV: PControl;
  50896. begin
  50897. Result := FALSE;
  50898. if Msg.message = WM_NOTIFY then
  50899. begin
  50900. Hdr := Pointer(Msg.lParam);
  50901. if Hdr.hwndFrom = Sender.Handle then
  50902. begin
  50903. if (LongInt(Hdr.code) = LVN_GETDISPINFO)
  50904. {$IFDEF UNICODE_CTRLS}
  50905. or (LongInt(Hdr.code) = LVN_GETDISPINFOW)
  50906. {$ENDIF UNICODE_CTRLS}
  50907. then
  50908. begin
  50909. DI := Pointer( Hdr );
  50910. LV := Sender;
  50911. if LV <> nil then
  50912. begin
  50913. DI.item.iImage := -1;
  50914. DI.item.state := 0;
  50915. Store := FALSE;
  50916. if Assigned( LV.OnLVData ) and (DI.item.iItem >= 0) then
  50917. begin
  50918. LV.OnLVData( LV, DI.item.iItem, DI.item.iSubItem, Txt,
  50919. DI.item.iImage, DWORD( DI.item.state ), Store );
  50920. if LongBool(DI.item.mask and LVIF_TEXT) then begin
  50921. LV.fCaption := Txt;
  50922. DI.item.pszText := PKOL_Char( PKOLChar( LV.fCaption ) );
  50923. end;
  50924. DI.item.stateMask := 0;
  50925. if DI.item.state and LVIS_STATEIMAGEMASK <> 0 then
  50926. DI.item.stateMask := LVIS_STATEIMAGEMASK;
  50927. if DI.item.state and LVIS_OVERLAYMASK <> 0 then
  50928. DI.item.stateMask := DI.item.stateMask or LVIS_OVERLAYMASK;
  50929. if DI.item.state and $7F <> 0 then
  50930. DI.item.stateMask := DI.item.stateMask or $7F;
  50931. if Store then
  50932. DI.item.mask := DI.item.mask or LVIF_DI_SETITEM;
  50933. end;
  50934. Result := TRUE;
  50935. end;
  50936. end;
  50937. end;
  50938. end;
  50939. end;
  50940. //[procedure TControl.SetOnLVData]
  50941. procedure TControl.SetOnLVData(const Value: TOnLVData);
  50942. begin
  50943. fOnLVData := Value;
  50944. AttachProc( @WndProc_LVData );
  50945. Perform( LVM_SETCALLBACKMASK, LVIS_OVERLAYMASK or LVIS_STATEIMAGEMASK, 0 );
  50946. end;
  50947. {$IFDEF ENABLE_DEPRECATED}
  50948. {$DEFINE implementation} {$I KOL_deprecated.inc} {$UNDEF implementation}
  50949. {$ENDIF DISABLE_DEPRECATED}
  50950. //[function WndProc_LVCustomDraw]
  50951. function WndProc_LVCustomDraw( Sender: PControl; var Msg: TMsg;
  50952. var Rslt: Integer ): Boolean;
  50953. var NMCustDraw: PNMLVCustomDraw;
  50954. NMHdr: PNMHdr;
  50955. ItemIdx, SubItemIdx: Integer;
  50956. S: TListViewItemState;
  50957. ItemState: TDrawState;
  50958. begin
  50959. Result := FALSE;
  50960. if Msg.message = WM_NOTIFY then
  50961. begin
  50962. NMHdr := Pointer( Msg.lParam );
  50963. if (LongInt(NMHdr.code) = NM_CUSTOMDRAW) and Assigned( Sender.fOnLVCustomDraw ) then
  50964. begin
  50965. NMCustDraw := Pointer( Msg.lParam );
  50966. ItemIdx := -1;
  50967. SubItemIdx := -1;
  50968. if LongBool( NMCustDraw.nmcd.dwDrawStage and CDDS_ITEM ) then
  50969. ItemIdx := NMCustDraw.nmcd.dwItemSpec;
  50970. if LongBool( NMCustDraw.nmcd.dwDrawStage and CDDS_SUBITEM ) then
  50971. SubItemIdx := NMCustDraw.iSubItem;
  50972. ItemState := [ ];
  50973. if ItemIdx >= 0 then
  50974. begin
  50975. S := Sender.LVItemState[ ItemIdx ];
  50976. if lvisFocus in S then
  50977. ItemState := ItemState + [ odsFocused ];
  50978. if lvisSelect in S then
  50979. ItemState := ItemState + [ odsSelected ];
  50980. if lvisBlend in S then
  50981. ItemState := ItemState + [ odsGrayed ];
  50982. if lvisHighlight in S then
  50983. ItemState := ItemState + [ odsMarked ];
  50984. end;
  50985. Sender.Canvas;
  50986. Rslt := Sender.FOnLVCustomDraw( Sender, {Sender.fPaintDC} NMCustDraw.nmcd.hdc,
  50987. NMCustDraw.nmcd.dwDrawStage, ItemIdx, SubItemIdx, NMCustDraw.nmcd.rc,
  50988. ItemState, TColor( NMCustDraw.clrText ), TColor( NMCustDraw.clrTextBk ) );
  50989. Result := TRUE;
  50990. end;
  50991. end;
  50992. end;
  50993. //[procedure TControl.SetOnLVCustomDraw]
  50994. procedure TControl.SetOnLVCustomDraw(const Value: TOnLVCustomDraw);
  50995. begin
  50996. fOnLVCustomDraw := Value;
  50997. AttachProc( @WndProc_LVCustomDraw );
  50998. end;
  50999. //[function CompareLVItems]
  51000. function CompareLVItems( Idx1, Idx2: Integer; ListView: PControl ): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  51001. begin
  51002. if Assigned( ListView.fOnCompareLVItems ) then
  51003. Result := ListView.fOnCompareLVItems( ListView, Idx1, Idx2 )
  51004. else
  51005. Result := 0;
  51006. end;
  51007. //[procedure TControl.LVSort]
  51008. procedure TControl.LVSort;
  51009. begin
  51010. {$ifdef wince}
  51011. MsgOk('TControl.LVSort must be fixed!');
  51012. Halt(6); // FIXME
  51013. {$else}
  51014. Perform( LVM_SORTITEMSEX, Integer(@Self), Integer(@CompareLVItems) );
  51015. {$endif wince}
  51016. end;
  51017. //[function CompareLVItemsData]
  51018. function CompareLVItemsData( D1, D2: DWORD; ListView: PControl ): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  51019. begin
  51020. if Assigned( ListView.fOnCompareLVItems ) then
  51021. Result := ListView.fOnCompareLVItems( ListView, D1, D2 )
  51022. else
  51023. Result := 0;
  51024. end;
  51025. //[procedure TControl.LVSortData]
  51026. procedure TControl.LVSortData;
  51027. begin
  51028. Perform( LVM_SORTITEMS, Integer( @Self ), Integer( @CompareLVItemsData ) );
  51029. end;
  51030. //[function WndProc_LVColumnClick]
  51031. function WndProc_LVColumnClick( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  51032. : Boolean;
  51033. var Hdr: PNMHDR;
  51034. LV: PNMListView;
  51035. begin
  51036. Result := FALSE;
  51037. if Msg.message = WM_NOTIFY then
  51038. begin
  51039. Hdr := Pointer(Msg.lParam);
  51040. if Hdr.hwndFrom = Sender.Handle then
  51041. begin
  51042. LV := Pointer( Hdr );
  51043. if LongInt(Hdr.code) = LVN_COLUMNCLICK then
  51044. begin
  51045. if Assigned( Sender.OnColumnClick ) then
  51046. Sender.OnColumnClick( Sender, LV.iSubItem );
  51047. Result := TRUE;
  51048. end;
  51049. end;
  51050. end;
  51051. end;
  51052. //[procedure TControl.SetOnColumnClick]
  51053. procedure TControl.SetOnColumnClick(const Value: TOnLVColumnClick);
  51054. begin
  51055. fOnColumnClick := Value;
  51056. AttachProc( @WndProc_LVColumnClick );
  51057. end;
  51058. //[function WndProc_LVStateChange]
  51059. function WndProc_LVStateChange( Sender: PControl; var Msg: TMsg; var R: Integer ): Boolean;
  51060. var NMOD: PNMLVODStateChange;
  51061. NMLV: PNMLISTVIEW;
  51062. begin
  51063. if Msg.message = WM_NOTIFY then
  51064. begin
  51065. NMOD := Pointer( Msg.lParam );
  51066. NMLV := Pointer( Msg.lParam );
  51067. if LongInt(NMOD.hdr.code) = LVN_ODSTATECHANGED then
  51068. begin
  51069. if Assigned( Sender.OnLVStateChange ) then
  51070. Sender.OnLVStateChange( Sender, NMOD.iFrom, NMOD.iTo,
  51071. NMOD.uOldState, NMOD.uNewState );
  51072. end
  51073. else
  51074. if LongInt(NMLV.hdr.code) = LVN_ITEMCHANGED then
  51075. begin
  51076. if Assigned( Sender.OnLVStateChange ) then
  51077. Sender.OnLVStateChange( Sender, NMLV.iItem, NMLV.iItem,
  51078. NMLV.uOldState, NMLV.uNewState );
  51079. end;
  51080. end;
  51081. Result := FALSE;
  51082. end;
  51083. //[procedure TControl.SetOnLVStateChange]
  51084. procedure TControl.SetOnLVStateChange(const Value: TOnLVStateChange);
  51085. begin
  51086. FOnLVStateChange := Value;
  51087. AttachProc( WndProc_LVStateChange );
  51088. end;
  51089. //[function CompareLVColumns]
  51090. function CompareLVColumns( Idx1, Idx2: Integer; Sender: PControl ): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  51091. var S1, S2: String;
  51092. begin
  51093. //--- changed by Mike Gerasimov:
  51094. S1 := Sender.LVItems[ Idx1, Sender.fColumn ];
  51095. S2 := Sender.LVItems[ Idx2, Sender.fColumn ];
  51096. If lvoSortAscending in Sender.fLVOptions Then
  51097. Result := AnsiCompareStrNoCase( S1, S2 )
  51098. Else
  51099. If lvoSortDescending in Sender.fLVOptions Then
  51100. Result := AnsiCompareStrNoCase( S2, S1 )
  51101. Else
  51102. Result:=0;
  51103. end;
  51104. //[procedure TControl.LVSortColumn]
  51105. procedure TControl.LVSortColumn(Idx: Integer);
  51106. begin
  51107. fColumn := Idx;
  51108. {$ifdef wince}
  51109. MsgOk('TControl.LVSortColumn must be fixed!');
  51110. Halt(6); // FIXME
  51111. {$else}
  51112. Perform( LVM_SORTITEMSEX, Integer(@Self), Integer(@CompareLVColumns) );
  51113. {$endif wince}
  51114. end;
  51115. //[function TControl.LVIndexOf]
  51116. function TControl.LVIndexOf(const S: KOLString): Integer;
  51117. begin
  51118. Result := LVSearchFor( S, -1, FALSE );
  51119. end;
  51120. //[function TControl.LVSearchFor]
  51121. function TControl.LVSearchFor(const S: KOLString; StartAfter: Integer;
  51122. Partial: Boolean): Integer;
  51123. var f: TLVFindInfo;
  51124. begin
  51125. f.lParam := 0;
  51126. f.flags := LVFI_STRING;
  51127. if Partial then
  51128. f.flags := LVFI_STRING or LVFI_PARTIAL;
  51129. f.psz := @s[1];
  51130. result := Perform(LVM_FINDITEM,StartAfter,integer(@f));
  51131. end;
  51132. function WndProcLVMeasureItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  51133. var
  51134. pMI: PMeasureItemStruct;
  51135. P: PControl;
  51136. H: Integer;
  51137. wId: DWORD;
  51138. i: Integer;
  51139. begin
  51140. Result := FALSE;
  51141. if Msg.message = WM_MEASUREITEM then begin
  51142. pMI := Pointer(Msg.lParam);
  51143. with pMI^ do begin
  51144. for i:=0 to Sender.ChildCount-1 do begin
  51145. P := Sender.Children[i];
  51146. if P <> nil then begin
  51147. wId := GetWindowLong(P.Handle,GWL_ID);
  51148. if CtlID = wId then begin
  51149. H := P.fLVItemHeight;
  51150. if H > 0 then begin
  51151. itemHeight := H;
  51152. Rslt:=1;
  51153. Result := TRUE;
  51154. end;
  51155. break;
  51156. end;
  51157. end;
  51158. end;
  51159. end;
  51160. end;
  51161. end;
  51162. function TControl.SetLVItemHeight(Value: Integer): PControl;
  51163. begin
  51164. Set_LVItemHeight( Value );
  51165. Result := @ Self;
  51166. end;
  51167. procedure TControl.Set_LVItemHeight(Value: Integer);
  51168. begin
  51169. if fLVItemHeight <> Value then begin
  51170. if fLVItemHeight = 0 then
  51171. Parent.AttachProc(WndProcLVMeasureItem);
  51172. fLVItemHeight := Value;
  51173. end;
  51174. end;
  51175. //[function TControl.IndexOf]
  51176. function TControl.IndexOf(const S: KOLString): Integer;
  51177. begin
  51178. Result := SearchFor( S, -1, FALSE );
  51179. end;
  51180. //[function TControl.SearchFor]
  51181. function TControl.SearchFor(const S: KOLString; StartAfter: Integer;
  51182. Partial: Boolean): Integer;
  51183. var Cmd: Integer;
  51184. I: Integer;
  51185. begin
  51186. Cmd := fCommandActions.aFindItem;
  51187. if Partial then
  51188. Cmd := fCommandActions.aFindPartial;
  51189. if Cmd <> 0 then
  51190. Result := Perform( Cmd, StartAfter, Integer( PKOLChar( S ) ) )
  51191. else
  51192. begin
  51193. Result := -1;
  51194. for I := StartAfter+1 to Count-1 do
  51195. begin
  51196. if Partial and ( Copy( Items[ I ], 1, Length( S ) ) = S ) or
  51197. ( Items[ I ] = S ) then
  51198. begin
  51199. Result := I;
  51200. break;
  51201. end;
  51202. end;
  51203. end;
  51204. end;
  51205. //[function TControl.DefaultBtnProc]
  51206. function TControl.DefaultBtnProc(var Msg: TMsg;
  51207. var Rslt: Integer): Boolean;
  51208. var Btn: PControl;
  51209. F: PControl;
  51210. begin
  51211. if Assigned( fOldOnMessage ) then
  51212. begin
  51213. Result := fOldOnMessage( Msg, Rslt );
  51214. if Result then Exit;
  51215. end;
  51216. Result := FALSE;
  51217. if AppletTerminated then Exit;
  51218. F := Applet;
  51219. if not F.fIsForm then
  51220. begin
  51221. F := F.fCurrentControl;
  51222. if F = nil then Exit;
  51223. end;
  51224. Btn := nil;
  51225. if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
  51226. ((Msg.wParam = VK_RETURN) or (Msg.wParam = VK_ESCAPE)) then
  51227. begin
  51228. if (Msg.wParam = VK_RETURN) and
  51229. (F.fDefaultBtnCtl <> nil) and
  51230. F.fDefaultBtnCtl.ToBeVisible and
  51231. F.fDefaultBtnCtl.Enabled and
  51232. ((F.fCurrentControl=nil) or (not F.fCurrentControl.fCancelBtn and
  51233. not F.fCurrentControl.fIgnoreDefault)
  51234. or (F.fCurrentControl = F.fDefaultBtnCtl)
  51235. ) then
  51236. Btn := F.fDefaultBtnCtl
  51237. else
  51238. if (Msg.wParam = VK_ESCAPE) and
  51239. (F.fCancelBtnCtl <> nil) and
  51240. F.fCancelBtnCtl.ToBeVisible and
  51241. F.fCancelBtnCtl.Enabled then
  51242. Btn := F.fCancelBtnCtl
  51243. else
  51244. if (Msg.wParam = VK_RETURN) and
  51245. (F.fAllBtnReturnClick or fAllBtnReturnClick) and
  51246. (F.ActiveControl <> nil) and
  51247. (F.ActiveControl.ToBeVisible) and
  51248. (F.ActiveControl.IsButton) and
  51249. (F.ActiveControl.Count = 0) then
  51250. Btn := F.ActiveControl;
  51251. if Btn <> nil then
  51252. begin
  51253. if Msg.message = WM_KEYDOWN then
  51254. begin
  51255. {$IFDEF CLICK_DEFAULT_CANCEL_BTN_DIRECTLY}
  51256. //Btn.Click;
  51257. if Assigned( Btn.OnClick ) then
  51258. Btn.OnClick( Btn );
  51259. {$ELSE}
  51260. Btn.Focused := TRUE;
  51261. {$ENDIF}
  51262. end;
  51263. {$IFDEF CLICK_DEFAULT_CANCEL_BTN_DIRECTLY}
  51264. {$ELSE}
  51265. Btn.Perform( Msg.message, DWORD( ' ' ), Msg.lParam );
  51266. {$ENDIF}
  51267. Msg.wParam := 0;
  51268. Result := TRUE;
  51269. Rslt := 0;
  51270. Exit;
  51271. end
  51272. end;
  51273. Result := FALSE;
  51274. end;
  51275. //[procedure TControl.SetDefaultBtn]
  51276. procedure TControl.SetDefaultBtn(const Index: Integer;
  51277. const Value: Boolean);
  51278. var F, C: PControl;
  51279. begin
  51280. if Index = 13 then
  51281. begin
  51282. fDefaultBtn := Value;
  51283. {$IFDEF DEFAULT_CANCEL_BTN_EXCLUSIVE}
  51284. fCancelBtn := FALSE;
  51285. {$ENDIF}
  51286. end
  51287. else
  51288. if Index = 27 then
  51289. begin
  51290. fCancelBtn := Value;
  51291. {$IFDEF DEFAULT_CANCEL_BTN_EXCLUSIVE}
  51292. fDefaultBtn := FALSE;
  51293. {$ENDIF}
  51294. end;
  51295. if Applet = nil then Exit;
  51296. F := ParentForm;
  51297. if F <> nil then
  51298. begin
  51299. if Value then
  51300. begin
  51301. if @ Applet.fOnMessage <> @ TControl.DefaultBtnProc then
  51302. Applet.fOldOnMessage := Applet.fOnMessage; // fixed by YS
  51303. Applet.fOnMessage := Applet.DefaultBtnProc;
  51304. end
  51305. else
  51306. begin
  51307. Applet.fOnMessage := Applet.fOldOnMessage;
  51308. Applet.fOldOnMessage := nil;
  51309. end;
  51310. C := nil;
  51311. if Value then C := @ Self;
  51312. if Index = 13 then
  51313. begin
  51314. F.fDefaultBtnCtl := C;
  51315. {$ifndef wince}
  51316. {$IFDEF NO_DEFAULT_BUTTON_BOLD}
  51317. {$ELSE}
  51318. if Value then
  51319. Style := Style or BS_DEFPUSHBUTTON
  51320. else
  51321. Style := Style and not BS_DEFPUSHBUTTON;
  51322. {$ENDIF}
  51323. {$endif wince}
  51324. end
  51325. else
  51326. if Index = 27 then
  51327. F.fCancelBtnCtl := C;
  51328. end;
  51329. end;
  51330. {$IFDEF F_P}
  51331. //[function TControl.GetDefaultBtn]
  51332. function TControl.GetDefaultBtn(const Index: Integer): Boolean;
  51333. begin
  51334. CASE Index OF
  51335. 13: Result := fDefaultBtn;
  51336. 27: Result := fCancelBtn;
  51337. END;
  51338. end;
  51339. {$ENDIF F_P}
  51340. //[function TControl.AllBtnReturnClick]
  51341. function TControl.AllBtnReturnClick: PControl;
  51342. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  51343. begin
  51344. // nothing: already implemented in WndProcBtnReturnClick
  51345. Result := @ Self;
  51346. end;
  51347. {$ELSE}
  51348. var F: PControl;
  51349. begin
  51350. SetDefaultBtn( 0, TRUE );
  51351. F := ParentForm;
  51352. if F <> nil then
  51353. F.fAllBtnReturnClick := TRUE;
  51354. Result := @ Self;
  51355. end;
  51356. {$ENDIF}
  51357. //[function WndProc_CNDrawItem]
  51358. function WndProc_CNDrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  51359. : Boolean;
  51360. type PDrawAction = ^TDrawAction;
  51361. PDrawState = ^TDrawState;
  51362. var DI: PDrawItemStruct;
  51363. begin
  51364. Result := FALSE;
  51365. if Msg.message = CN_DRAWITEM then
  51366. begin
  51367. DI := Pointer( Msg.lParam );
  51368. if Assigned( Sender.OnDrawItem ) then
  51369. begin
  51370. if Sender.OnDrawItem( Sender, DI.hDC, DI.rcItem, DI.itemID,
  51371. PDrawAction( @ DI.itemAction )^,
  51372. PDrawState( @ DI.itemState )^ )
  51373. then Rslt := 1
  51374. else Rslt := 0;
  51375. Result := TRUE;
  51376. end
  51377. else Rslt := 0;
  51378. end;
  51379. end;
  51380. //[procedure TControl.SetOnDrawItem]
  51381. procedure TControl.SetOnDrawItem(const Value: TOnDrawItem);
  51382. begin
  51383. fOnDrawItem := Value;
  51384. if Parent <> nil then
  51385. Parent.AttachProc( @WndProc_DrawItem );
  51386. AttachProc( @WndProc_CNDrawItem );
  51387. end;
  51388. //[function WndProc_MeasureItem]
  51389. function WndProc_MeasureItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  51390. : Boolean;
  51391. var MI: PMeasureItemStruct;
  51392. Control: PControl;
  51393. I: Integer;
  51394. begin
  51395. Result := FALSE;
  51396. if Msg.message = WM_MEASUREITEM then
  51397. begin
  51398. MI := Pointer( Msg.lParam );
  51399. for I := 0 to Sender.ChildCount - 1 do
  51400. begin
  51401. Control := Sender.Children[ I ];
  51402. if Control.Menu = MI.CtlID then
  51403. begin
  51404. if Assigned( Control.OnMeasureItem ) then
  51405. begin
  51406. MI.itemHeight := Control.OnMeasureItem( Control, MI.itemID );
  51407. if MI.itemHeight > 0 then
  51408. begin
  51409. Rslt := 1;
  51410. Result := TRUE;
  51411. end;
  51412. end;
  51413. break;
  51414. end;
  51415. end;
  51416. end;
  51417. end;
  51418. //[procedure TControl.SetOnMeasureItem]
  51419. procedure TControl.SetOnMeasureItem(const Value: TOnMeasureItem);
  51420. begin
  51421. fOnMeasureItem := Value;
  51422. if Parent <> nil then
  51423. Parent.AttachProc( @WndProc_MeasureItem );
  51424. end;
  51425. //[function TControl.GetItemData]
  51426. function TControl.GetItemData(Idx: Integer): DWORD;
  51427. begin
  51428. Result := 0;
  51429. if fCommandActions.aGetItemData <> 0 then
  51430. Result := Perform( fCommandActions.aGetItemData, Idx, 0 );
  51431. end;
  51432. //[procedure TControl.SetItemData]
  51433. procedure TControl.SetItemData(Idx: Integer; const Value: DWORD);
  51434. begin
  51435. if fCommandActions.aSetItemData <> 0 then
  51436. Perform( fCommandActions.aSetItemData, Idx, Value );
  51437. end;
  51438. //[function TControl.GetLVCurItem]
  51439. function TControl.GetLVCurItem: Integer;
  51440. begin
  51441. Result := Perform( LVM_GETNEXTITEM, -1, LVNI_SELECTED );
  51442. end;
  51443. //[procedure TControl.SetLVCurItem]
  51444. procedure TControl.SetLVCurItem(const Value: Integer);
  51445. begin
  51446. if (lvoMultiselect in LVOptions) or (Value <> LVCurItem ) then
  51447. LVItemState[ -1 ] := [ ];
  51448. if Value >= 0 then
  51449. LVItemState[ Value ] := [ lvisSelect, lvisFocus ];
  51450. end;
  51451. //[function TControl.LVNextItem]
  51452. function TControl.LVNextItem(IdxPrev: Integer; Attrs: DWORD): Integer;
  51453. begin
  51454. Result := Perform( LVM_GETNEXTITEM, IdxPrev, Attrs );
  51455. end;
  51456. //[function TControl.LVNextSelected]
  51457. function TControl.LVNextSelected(IdxPrev: Integer): Integer;
  51458. begin
  51459. Result := Perform( LVM_GETNEXTITEM, IdxPrev, LVNI_SELECTED );
  51460. end;
  51461. //[function TControl.GetLVFocusItem]
  51462. function TControl.GetLVFocusItem: Integer;
  51463. begin
  51464. Result := Perform( LVM_GETNEXTITEM, -1, LVNI_FOCUSED );
  51465. end;
  51466. //[procedure TControl.Close]
  51467. procedure TControl.Close;
  51468. begin
  51469. PostMessage( Handle, WM_CLOSE, 0, 0 );
  51470. end;
  51471. //[function WndProcMinimize]
  51472. function WndProcMinimize( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  51473. var Wnd: PControl;
  51474. begin
  51475. Result := FALSE;
  51476. if (Msg.message = WM_SYSCOMMAND) and ((Msg.wParam and $FFF0) = SC_MINIMIZE)then
  51477. begin
  51478. if Applet <> nil then
  51479. begin
  51480. Wnd := Applet.FMinimizeWnd;
  51481. if Wnd <> nil then
  51482. SetWindowPos( Applet.Handle, 0, Wnd.Left, Wnd.Top, Wnd.Width, 0,
  51483. SWP_NOZORDER or SWP_NOREDRAW);
  51484. end;
  51485. end;
  51486. end;
  51487. function WndProcRestore( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  51488. begin
  51489. Result := FALSE;
  51490. CASE Msg.message OF
  51491. WM_SHOWWINDOW:
  51492. begin
  51493. case Msg.lParam of
  51494. SW_PARENTCLOSING:
  51495. begin
  51496. {$ifdef win32}
  51497. if IsIconic( Self_.fHandle ) then
  51498. Self_.fShowAction := SW_SHOWMINNOACTIVE
  51499. else
  51500. if IsZoomed( Self_.fHandle ) then
  51501. Self_.fShowAction := SW_SHOWMAXIMIZED
  51502. else
  51503. Self_.fShowAction := SW_SHOWNOACTIVATE;
  51504. {$endif win32}
  51505. end;
  51506. SW_PARENTOPENING:
  51507. begin
  51508. if Self_.fShowAction <> 0 then
  51509. begin
  51510. ShowWindow( Self_.fHandle, Self_.fShowAction );
  51511. Self_.fShowAction := 0;
  51512. end;
  51513. Rslt := 0;
  51514. end;
  51515. end;
  51516. end;
  51517. END;
  51518. end;
  51519. //[procedure TControl.MinimizeNormalAnimated]
  51520. procedure TControl.MinimizeNormalAnimated;
  51521. var App: PControl;
  51522. begin
  51523. App := Applet;
  51524. if App = nil then
  51525. App := @Self;
  51526. App.FMinimizeWnd := @Self;
  51527. App.AttachProc( @WndProcMinimize );
  51528. AttachProc( @WndProcRestore );
  51529. end;
  51530. //[procedure TCotrol.RestoreNormalMaximized]
  51531. procedure TControl.RestoreNormalMaximized;
  51532. begin
  51533. AttachProc( @WndProcRestore );
  51534. end;
  51535. {$ifndef wince}
  51536. //[function WndProcDropFiles]
  51537. function WndProcDropFiles( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  51538. var hDrop: THandle;
  51539. Pt: TPoint;
  51540. FList: KOLString;
  51541. I, N: Integer;
  51542. Buf: array[ 0..MAX_PATH ] of KOLChar;
  51543. begin
  51544. if Msg.message = WM_DROPFILES then
  51545. if Assigned( Sender.FOnDropFiles ) then
  51546. begin
  51547. hDrop := Msg.wParam;
  51548. DragQueryPoint( hDrop, Pt );
  51549. N := DragQueryFile( hDrop, $FFFFffff, nil, 0 );
  51550. FList := '';
  51551. for I := 0 to N-1 do
  51552. begin
  51553. if FList <> '' then
  51554. FList := FList + #13;
  51555. DragQueryFile( hDrop, I, Buf, Sizeof( Buf ) );
  51556. FList := FList + Buf;
  51557. end;
  51558. DragFinish( hDrop );
  51559. Sender.FOnDropFiles( Sender, FList, Pt );
  51560. Rslt := 0;
  51561. Result := TRUE;
  51562. Exit;
  51563. end;
  51564. Result := FALSE;
  51565. end;
  51566. {$endif wince}
  51567. //[procedure TControl.SetOnDropFiles]
  51568. procedure TControl.SetOnDropFiles(const Value: TOnDropFiles);
  51569. begin
  51570. FOnDropFiles := Value;
  51571. {$ifndef wince}
  51572. AttachProc( @WndProcDropFiles );
  51573. DragAcceptFiles( GetWindowHandle, Assigned( Value ) );
  51574. {$endif wince}
  51575. end;
  51576. //[function WndProcShowHide]
  51577. function WndProcShowHide( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  51578. var IsVisible: Boolean;
  51579. begin
  51580. if Msg.message = WM_SHOWWINDOW then
  51581. if Msg.hwnd = Sender.Handle then
  51582. begin
  51583. IsVisible := IsWindowVisible( Sender.Handle );
  51584. if LongBool( Msg.wParam ) then
  51585. begin
  51586. Sender.fVisible := TRUE;
  51587. if not IsVisible then
  51588. if Assigned( Sender.FOnShow ) then
  51589. Sender.FOnShow( Sender );
  51590. end
  51591. else
  51592. begin
  51593. Sender.fVisible := FALSE;
  51594. if IsVisible then
  51595. if Assigned( Sender.FOnHide ) then
  51596. Sender.FOnHide( Sender );
  51597. end;
  51598. end;
  51599. Result := FALSE;
  51600. end;
  51601. //[procedure TControl.SetOnHide]
  51602. procedure TControl.SetOnHide(const Value: TOnEvent);
  51603. begin
  51604. FOnHide := Value;
  51605. AttachProc( WndProcShowHide );
  51606. end;
  51607. //[procedure TControl.SetOnShow]
  51608. procedure TControl.SetOnShow(const Value: TOnEvent);
  51609. begin
  51610. FOnShow := Value;
  51611. AttachProc( WndProcShowHide );
  51612. end;
  51613. //[function TControl.BringToFront]
  51614. function TControl.BringToFront: PControl;
  51615. begin
  51616. SetWindowPos( GetWindowHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or
  51617. SWP_NOACTIVATE or SWP_NOOWNERZORDER or SWP_SHOWWINDOW );
  51618. Result := @Self;
  51619. end;
  51620. //[function TControl.SendToBack]
  51621. function TControl.SendToBack: PControl;
  51622. begin
  51623. SetWindowPos( GetWindowHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or
  51624. SWP_NOACTIVATE or SWP_NOOWNERZORDER );
  51625. Result := @Self;
  51626. end;
  51627. //[procedure TControl.DragStart]
  51628. procedure TControl.DragStart;
  51629. begin
  51630. PostMessage( GetWindowHandle, WM_SYSCOMMAND, $F012, 0 );
  51631. end;
  51632. //[function WndProcDragWindow]
  51633. function WndProcDragWindow( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  51634. var P: TPoint;
  51635. begin
  51636. if Msg.message = WM_MOUSEMOVE then
  51637. begin
  51638. if Sender.FDragging then
  51639. begin
  51640. GetCursorPos( P );
  51641. P.x := P.x - Sender.fMouseStartPos.x + Sender.fDragStartPos.x;
  51642. P.y := P.y - Sender.fMouseStartPos.y + Sender.fDragStartPos.y;
  51643. Sender.Position := P;
  51644. end;
  51645. end;
  51646. Result := FALSE;
  51647. end;
  51648. //[procedure TControl.DragStartEx]
  51649. procedure TControl.DragStartEx;
  51650. var StartBounds: TRect;
  51651. begin
  51652. {$IFNDEF SMALLEST_CODE}
  51653. if fDragging then Exit;
  51654. {$ENDIF}
  51655. GetCursorPos( fMouseStartPos );
  51656. StartBounds := BoundsRect;
  51657. fDragStartPos.x := StartBounds.Left;
  51658. fDragStartPos.y := StartBounds.Top;
  51659. SetCapture( GetWindowHandle );
  51660. fDragging := TRUE;
  51661. AttachProc( WndProcDragWindow );
  51662. end;
  51663. //[procedure TControl.DragStopEx]
  51664. procedure TControl.DragStopEx;
  51665. begin
  51666. if FDragging then
  51667. begin
  51668. ReleaseCapture;
  51669. FDragging := FALSE;
  51670. end;
  51671. end;
  51672. //[function CallDragCallBack]
  51673. function CallDragCallBack( Sender: PControl; var Stop: Boolean ): Boolean;
  51674. var P: TPoint;
  51675. Shape, ShapeWas: Integer;
  51676. begin
  51677. Sender.AttachProc( WndProcSetCursor );
  51678. GetCursorPos( P );
  51679. Shape := LoadCursor( 0, IDC_HAND );
  51680. ShapeWas := Shape;
  51681. Result := Sender.fDragCallback( Sender, P.x, P.y, Shape, Stop );
  51682. if not Stop then
  51683. begin
  51684. if not Result then
  51685. if Shape = ShapeWas then
  51686. Shape := LoadCursor( 0, IDC_NO );
  51687. ScreenCursor := Shape;
  51688. end
  51689. else
  51690. begin
  51691. ScreenCursor := 0;
  51692. Shape := Sender.fCursor;
  51693. end;
  51694. Windows.SetCursor( Shape );
  51695. end;
  51696. //[function WndProcDrag]
  51697. function WndProcDrag( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  51698. var Stop: Boolean;
  51699. begin
  51700. if Sender.fDragging then
  51701. begin
  51702. Stop := FALSE;
  51703. case Msg.message of
  51704. WM_MOUSEMOVE:
  51705. CallDragCallBack( Sender, Stop );
  51706. WM_LBUTTONUP, WM_RBUTTONUP:
  51707. begin
  51708. Stop := TRUE;
  51709. CallDragCallBack( Sender, Stop );
  51710. end;
  51711. else
  51712. begin
  51713. Result := FALSE;
  51714. Exit;
  51715. end;
  51716. end;
  51717. if Stop then
  51718. begin
  51719. ReleaseCapture;
  51720. Sender.fDragging := FALSE;
  51721. end
  51722. else
  51723. begin
  51724. Result := TRUE;
  51725. exit;
  51726. end;
  51727. end;
  51728. Result := FALSE;
  51729. end;
  51730. //[procedure TControl.DragItem]
  51731. procedure TControl.DragItem(OnDrag: TOnDrag);
  51732. begin
  51733. fDragCallback := OnDrag;
  51734. fDragging := TRUE;
  51735. SetCapture( GetWindowHandle );
  51736. AttachProc( WndProcDrag );
  51737. end;
  51738. {-}
  51739. {$IFDEF USE_CONSTRUCTORS} //****************************************************//
  51740. //
  51741. //[constructor TControl.CreateWindowed]
  51742. constructor TControl.CreateWindowed(AParent: PControl; AClassName: PKOLChar; //
  51743. ACtl3D: Boolean); //
  51744. begin //
  51745. CreateParented( AParent ); //
  51746. fOnDynHandlers := WndProcDummy; //
  51747. fWndProcKeybd := WndProcDummy; //
  51748. fWndProcResizeFlicks := WndProcDummy; //
  51749. fCommandActions.aClear := ClearText; //
  51750. //fWindowed := True; // is set in TControl.Init
  51751. fControlClassName := AClassName; //
  51752. //
  51753. fControlClick := DummyObjProc; //
  51754. //
  51755. fColor := clBtnFace; //
  51756. fTextColor := clWindowText; //
  51757. fMargin := 2; //
  51758. fCtl3D := True; //
  51759. fCtl3Dchild := True; //
  51760. if AParent <> nil then //
  51761. begin //
  51762. fWndProcResizeFlicks := AParent.fWndProcResizeFlicks; //
  51763. fGotoControl := AParent.fGotoControl; //
  51764. fDoubleBuffered := AParent.fDoubleBuffered; //
  51765. fTransparent := AParent.fTransparent; //
  51766. fCtl3Dchild := AParent.fCtl3Dchild; //
  51767. if AParent.fCtl3Dchild then //
  51768. fCtl3D := ACtl3D //
  51769. else //
  51770. fCtl3D := False; //
  51771. fMargin := AParent.fMargin; //
  51772. with fBoundsRect do //
  51773. begin //
  51774. Left := AParent.fMargin + AParent.fClientLeft; //
  51775. Top := AParent.fMargin + AParent.fClientTop; //
  51776. Right := Left + 64; //
  51777. Bottom := Top + 64; //
  51778. end; //
  51779. fTextColor := AParent.fTextColor; //
  51780. fFont := fFont.Assign( AParent.fFont ); //
  51781. if fFont <> nil then //
  51782. begin //
  51783. fFont.fOnChange := FontChanged; //
  51784. FontChanged( fFont ); //
  51785. end; //
  51786. fColor := AParent.fColor; //
  51787. fBrush := fBrush.Assign( AParent.fBrush ); //
  51788. if fBrush <> nil then //
  51789. begin //
  51790. fBrush.fOnChange := BrushChanged; //
  51791. BrushChanged( fBrush ); //
  51792. end; //
  51793. end; //
  51794. end; //
  51795. //
  51796. //[constructor TControl.CreateApplet]
  51797. constructor TControl.CreateApplet(const ACaption: String); //
  51798. begin //
  51799. AppButtonUsed := True; //
  51800. CreateWindowed( nil, 'App', TRUE ); //
  51801. FIsApplet := TRUE; //
  51802. fStyle := WS_VISIBLE or WS_SYSMENU or WS_POPUP or WS_MINIMIZEBOX //
  51803. or WS_CAPTION; //
  51804. fExStyle := WS_EX_APPWINDOW; //
  51805. FCreateWndExt := CreateAppButton; //
  51806. AttachProc( WndProcApp ); //
  51807. Caption := ACaption; //
  51808. end; //
  51809. //
  51810. //[constructor TControl.CreateForm]
  51811. constructor TControl.CreateForm(AParent: PControl; const ACaption: String); //
  51812. begin //
  51813. CreateWindowed( AParent, 'Form', TRUE ); //
  51814. AttachProc( WndProcForm ); //
  51815. AttachProc( WndProcDoEraseBkgnd ); //
  51816. Caption := ACaption; //
  51817. end; //
  51818. //
  51819. //[constructor TControl.CreateControl]
  51820. constructor TControl.CreateControl(AParent: PControl; AClassName: PChar; //
  51821. AStyle: DWORD; ACtl3D: Boolean; Actions: PCommandActions); //
  51822. var Form: PControl; //
  51823. begin //
  51824. CreateWindowed( AParent, AClassName, ACtl3D ); //
  51825. if Actions <> nil then //
  51826. fCommandActions := Actions^; //
  51827. fIsControl := True; //
  51828. fStyle := AStyle or WS_CLIPSIBLINGS or WS_CLIPCHILDREN; //
  51829. fVisible := (Style and WS_VISIBLE) <> 0; //
  51830. fTabstop := (Style and WS_TABSTOP) <> 0; //
  51831. if (AParent <> nil) then //
  51832. begin //
  51833. Inc( AParent.ParentForm.fTabOrder ); //
  51834. fTabOrder := AParent.ParentForm.fTabOrder; //
  51835. end; //
  51836. fLookTabKeys := [ tkTab, tkLeftRight, tkUpDown, tkPageUpPageDn ]; //
  51837. if fCtl3D then //
  51838. begin //
  51839. fStyle := fStyle and not WS_BORDER; //
  51840. fExStyle := fExStyle or WS_EX_CLIENTEDGE; //
  51841. end; //
  51842. if (Style and WS_TABSTOP) <> 0 then //
  51843. begin //
  51844. Form := ParentForm; //
  51845. if Form <> nil then //
  51846. if Form.FCurrentControl = nil then //
  51847. Form.FCurrentControl := @Self; //
  51848. end; //
  51849. //fCreateParamsExt := CreateParams2; //
  51850. fMenu := CtlIdCount; //
  51851. Inc( CtlIdCount ); //
  51852. AttachProc( WndProcCtrl ); //
  51853. end; //
  51854. //
  51855. //[constructor TControl.CreateButton]
  51856. constructor TControl.CreateButton(AParent: PControl; //
  51857. const ACaption: String); //
  51858. begin //
  51859. CreateControl( AParent, 'BUTTON', //
  51860. WS_VISIBLE or WS_CHILD or //
  51861. BS_PUSHLIKE or WS_TABSTOP, False, @ButtonActions ); //
  51862. with fBoundsRect do //
  51863. Bottom := Top + 22; //
  51864. fTextAlign := taCenter; //
  51865. Caption := ACaption; //
  51866. end; //
  51867. //
  51868. //[constructor TControl.CreateBitBtn]
  51869. constructor TControl.CreateBitBtn(AParent: PControl; //
  51870. const ACaption: String; AOptions: TBitBtnOptions; ALayout: TGlyphLayout; //
  51871. AGlyphBitmap: HBitmap; AGlyphCount: Integer); //
  51872. var //
  51873. B: TBitmapInfo; //
  51874. W, H: Integer; //
  51875. begin //
  51876. CreateControl( AParent, 'BUTTON', WS_VISIBLE or WS_CHILD or //
  51877. WS_TABSTOP or BS_OWNERDRAW, False, @ButtonActions ); //
  51878. fBitBtnOptions := AOptions; //
  51879. fGlyphLayout := ALayout; //
  51880. fGlyphBitmap := AGlyphBitmap; //
  51881. with fBoundsRect do //
  51882. begin //
  51883. Bottom := Top + 22; //
  51884. W := 0; H := 0; //
  51885. if AGlyphBitmap <> 0 then //
  51886. begin //
  51887. if bboImageList in AOptions then //
  51888. ImageList_GetIconSize( AGlyphBitmap, W, H ) //
  51889. else //
  51890. begin //
  51891. if GetObject( AGlyphBitmap, Sizeof(B), @B ) > 0 then //
  51892. begin //
  51893. W := B.bmiHeader.biWidth; //
  51894. H := B.bmiHeader.biHeight; //
  51895. if AGlyphCount = 0 then //
  51896. AGlyphCount := W div H; //
  51897. if AGlyphCount > 1 then //
  51898. W := W div AGlyphCount; //
  51899. end; //
  51900. end; //
  51901. if W > 0 then //
  51902. if ACaption = '' then //
  51903. Right := Left + W //
  51904. else //
  51905. Right := Right + W; //
  51906. if H > 0 then //
  51907. Bottom := Top + H; //
  51908. if not ( bboNoBorder in AOptions ) then //
  51909. begin //
  51910. if W > 0 then //
  51911. Inc( Right, 2 ); //
  51912. if H > 0 then //
  51913. Inc( Bottom, 2 ); //
  51914. end; //
  51915. end; //
  51916. fGlyphWidth := W; //
  51917. fGlyphHeight := H; //
  51918. end; //
  51919. fGlyphCount := AGlyphCount; //
  51920. if AParent <> nil then //
  51921. AParent.AttachProc( WndProc_DrawItem ); //
  51922. AttachProc( WndProcBitBtn ); //
  51923. fTextAlign := taCenter; //
  51924. Caption := ACaption; //
  51925. end; //
  51926. //
  51927. //[constructor TControl.CreateLabel]
  51928. constructor TControl.CreateLabel(AParent: PControl; //
  51929. const ACaption: String); //
  51930. begin //
  51931. CreateControl( AParent, 'STATIC', WS_VISIBLE or WS_CHILD or //
  51932. SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_NOTIFY, //
  51933. False, @LabelActions ); //
  51934. fIsStaticControl := 1; //
  51935. fSizeRedraw := True; //
  51936. fBoundsRect.Bottom := fBoundsRect.Top + 22; //
  51937. Caption := ACaption; //
  51938. end; //
  51939. //
  51940. //[constructor TControl.CreateWordWrapLabel]
  51941. constructor TControl.CreateWordWrapLabel(AParent: PControl; //
  51942. const ACaption: String); //
  51943. begin //
  51944. CreateLabel( AParent, ACaption ); //
  51945. fBoundsRect.Bottom := fBoundsRect.Top + 44; //
  51946. fStyle := fStyle and not SS_LEFTNOWORDWRAP; //
  51947. end; //
  51948. //
  51949. //[constructor TControl.CreateLabelEffect]
  51950. constructor TControl.CreateLabelEffect(AParent: PControl; ACaption: String; //
  51951. AShadowDeep: Integer); //
  51952. begin //
  51953. CreateLabel( AParent, ACaption ); //
  51954. fIsStaticControl := 0; //
  51955. AttachProc( WndProcLabelEffect ); //
  51956. fTextAlign := taCenter; //
  51957. fTextColor := clBtnShadow; //
  51958. fShadowDeep := AShadowDeep; //
  51959. fIgnoreWndCaption := True; //
  51960. with fBoundsRect do //
  51961. begin //
  51962. Bottom := Top + 40; //
  51963. end; //
  51964. end; //
  51965. //
  51966. //[constructor TControl.CreatePaintBox]
  51967. constructor TControl.CreatePaintBox(AParent: PControl); //
  51968. begin //
  51969. CreateLabel( AParent, '' ); //
  51970. with fBoundsRect do //
  51971. begin //
  51972. Right := Left + 40; //
  51973. Bottom := Top + 40; //
  51974. end; //
  51975. end; //
  51976. //
  51977. {$IFDEF ASM_VERSION} //
  51978. //[constructor TControl.CreateGradientPanel]
  51979. constructor TControl.CreateGradientPanel(AParent: PControl; AColor1, //
  51980. AColor2: TColor); //
  51981. asm //cmd //opd //
  51982. XOR EDX, EDX //
  51983. PUSH EDX //
  51984. CALL CreateLabel //
  51985. MOV ECX, AColor1 //
  51986. MOV [EAX].fColor1, ECX //
  51987. MOV ECX, AColor2 //
  51988. MOV [EAX].fColor2, ECX //
  51989. MOV EDX, [EAX].fBoundsRect.Left //
  51990. ADD EDX, 40 //
  51991. MOV [EAX].fBoundsRect.Right, EDX //
  51992. MOV EDX, [EAX].fBoundsRect.Top //
  51993. ADD EDX, 40 //
  51994. MOV [EAX].fBoundsRect.Bottom, EDX //
  51995. PUSH EAX //
  51996. MOV EDX, offset[ WndProcGradient ] //
  51997. CALL AttachProc //
  51998. POP EAX //
  51999. end; //
  52000. {$ELSE ASM_VERSION} //Pascal //
  52001. constructor TControl.CreateGradientPanel(AParent: PControl; AColor1, //
  52002. AColor2: TColor); //
  52003. begin //
  52004. CreateLabel( AParent, '' ); //
  52005. AttachProc( WndProcGradient ); //
  52006. fColor2 := AColor2; //
  52007. fColor1 := AColor1; //
  52008. with fBoundsRect do //
  52009. begin //
  52010. Right := Left + 40; //
  52011. Bottom := Top + 40; //
  52012. end; //
  52013. end; //
  52014. {$ENDIF ASM_VERSION} //
  52015. //
  52016. //[constructor TControl.CreateGradientPanelEx]
  52017. constructor TControl.CreateGradientPanelEx(AParent: PControl; AColor1, //
  52018. AColor2: TColor; AStyle: TGradientStyle; ALayout: TGradientLayout); //
  52019. begin //
  52020. CreateLabel( AParent, '' ); //
  52021. AttachProc( WndProcGradientEx ); //
  52022. fColor2 := AColor2; //
  52023. fColor1 := AColor1; //
  52024. fGradientStyle := AStyle; //
  52025. fGradientLayout := ALayout; //
  52026. with fBoundsRect do //
  52027. begin //
  52028. Right := Left + 40; //
  52029. Bottom := Top + 40; //
  52030. end; //
  52031. end; //
  52032. //
  52033. //[constructor TControl.CreateGroupbox]
  52034. constructor TControl.CreateGroupbox(AParent: PControl; //
  52035. const ACaption: String); //
  52036. begin //
  52037. CreateButton( AParent, ACaption ); //
  52038. with fBoundsRect do //
  52039. begin //
  52040. Right := Left + 100; //
  52041. Bottom := Top + 100; //
  52042. end; //
  52043. fStyle := WS_VISIBLE or WS_CHILD or BS_GROUPBOX or WS_TABSTOP; //
  52044. fClientTop := 22; //
  52045. fClientLeft := 2; //
  52046. fClientBottom := 2; //
  52047. fClientRight := 2; //
  52048. fTabstop := False; //
  52049. end; //
  52050. //
  52051. //[constructor TControl.CreateCheckbox]
  52052. constructor TControl.CreateCheckbox(AParent: PControl; //
  52053. const ACaption: String); //
  52054. begin //
  52055. CreateButton( AParent, ACaption ); //
  52056. with fBoundsRect do //
  52057. begin //
  52058. Right := Left + 72; //
  52059. end; //
  52060. fStyle := WS_VISIBLE or WS_CHILD or //
  52061. BS_AUTOCHECKBOX or WS_TABSTOP; //
  52062. end; //
  52063. //
  52064. //[constructor TControl.CreateRadiobox]
  52065. constructor TControl.CreateRadiobox(AParent: PControl; //
  52066. const ACaption: String); //
  52067. begin //
  52068. CreateCheckbox( AParent, ACaption ); //
  52069. fStyle := WS_VISIBLE or WS_CHILD or //
  52070. BS_RADIOBUTTON or WS_TABSTOP or WS_GROUP; //
  52071. fControlClick := ClickRadio; //
  52072. if AParent <> nil then //
  52073. begin //
  52074. AParent.fRadioLast := fMenu; //
  52075. if AParent.fRadio1st = 0 then //
  52076. begin //
  52077. AParent.fRadio1st := fMenu; //
  52078. SetRadioChecked; //
  52079. end; //
  52080. end; //
  52081. end; //
  52082. //
  52083. //[constructor TControl.CreateEditbox]
  52084. constructor TControl.CreateEditbox(AParent: PControl; //
  52085. AOptions: TEditOptions); //
  52086. var Flags: Integer; //
  52087. begin //
  52088. Flags := MakeFlags( @AOptions, EditFlags ); //
  52089. if not(eoMultiline in AOptions) then //
  52090. Flags := Flags and not(WS_HSCROLL or WS_VSCROLL); //
  52091. CreateControl( AParent, 'EDIT', WS_VISIBLE or WS_CHILD or WS_TABSTOP //
  52092. or WS_BORDER or Flags, True, @EditActions ); //
  52093. //YS fCursor := LoadCursor( 0, IDC_IBEAM ); // //YS
  52094. with fBoundsRect do //
  52095. begin //
  52096. Right := Left + 100; //
  52097. Bottom := Top + 22; //
  52098. if eoMultiline in AOptions then //
  52099. begin //
  52100. Right := Right + 100; //
  52101. Bottom := Top + 200; //
  52102. end; //
  52103. end; //
  52104. fColor := clWindow; //
  52105. fLookTabKeys := [ tkTab, tkUpDown, tkPageUpPageDn ]; //
  52106. if eoMultiline in AOptions then //
  52107. fLookTabKeys := [ tkTab ]; //
  52108. if eoWantTab in AOptions then //
  52109. fLookTabKeys := fLookTabKeys - [ tkTab ]; //
  52110. end; //
  52111. //
  52112. //[constructor TControl.CreatePanel]
  52113. constructor TControl.CreatePanel(AParent: PControl; AStyle: TEdgeStyle); //
  52114. const Edgestyles: array[ TEdgeStyle ] of DWORD = ( WS_DLGFRAME, SS_SUNKEN, 0 ); //
  52115. begin //
  52116. CreateControl( AParent, 'STATIC', WS_VISIBLE or WS_CHILD or //
  52117. SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_NOTIFY, False, //
  52118. @LabelActions ); //
  52119. with fBoundsRect do //
  52120. begin //
  52121. Right := Left + 100; //
  52122. Bottom := Top + 100; //
  52123. end; //
  52124. Style := Style or Edgestyles[ AStyle ]; //
  52125. ExStyle := ExStyle or WS_EX_CONTROLPARENT; //
  52126. end; //
  52127. //
  52128. //[constructor TControl.CreateSplitter]
  52129. constructor TControl.CreateSplitter(AParent: PControl; AMinSizePrev, //
  52130. AMinSizeNext: Integer; EdgeStyle: TEdgeStyle); //
  52131. var PrevCtrl: PControl; //
  52132. Sz0: Integer; //
  52133. begin //
  52134. CreatePanel( AParent, EdgeStyle ); //
  52135. fSplitMinSize1 := AMinSizePrev; //
  52136. fSplitMinSize2 := AMinSizeNext; //
  52137. Sz0 := 4; //
  52138. with fBoundsRect do //
  52139. begin //
  52140. Right := Left + Sz0; //
  52141. Bottom := Top + Sz0; //
  52142. end; //
  52143. if AParent <> nil then //
  52144. begin //
  52145. if AParent.fChildren.fCount > 1 then //
  52146. begin //
  52147. PrevCtrl := AParent.fChildren.fItems[ AParent.fChildren.fCount - 2 ]; //
  52148. case PrevCtrl.FAlign of //
  52149. caLeft, caRight: //
  52150. begin //
  52151. fCursor := LoadCursor( 0, IDC_SIZEWE ); //
  52152. end; //
  52153. caTop, caBottom: //
  52154. begin //
  52155. fCursor := LoadCursor( 0, IDC_SIZENS ); //
  52156. end; //
  52157. end; //
  52158. Align := PrevCtrl.FAlign; //
  52159. end; //
  52160. end; //
  52161. AttachProc( WndProcSplitter ); //
  52162. end; //
  52163. //
  52164. //[constructor TControl.CreateListbox]
  52165. constructor TControl.CreateListbox(AParent: PControl; //
  52166. AOptions: TListOptions); //
  52167. var Flags: Integer; //
  52168. begin //
  52169. Flags := MakeFlags( @AOptions, ListFlags ); //
  52170. CreateControl( AParent, 'LISTBOX', WS_VISIBLE or WS_CHILD or WS_TABSTOP //
  52171. or WS_BORDER or WS_VSCROLL //
  52172. or LBS_NOTIFY or Flags, True, @ListActions ); //
  52173. with fBoundsRect do //
  52174. begin //
  52175. Right := Right + 100; //
  52176. Bottom := Top + 200; //
  52177. end; //
  52178. fColor := clWindow; //
  52179. fLookTabKeys := [ tkTab, tkLeftRight ]; //
  52180. end; //
  52181. //
  52182. //[constructor TControl.CreateCombobox]
  52183. constructor TControl.CreateCombobox(AParent: PControl; //
  52184. AOptions: TComboOptions); //
  52185. var Flags: Integer; //
  52186. begin //
  52187. Flags := MakeFlags( @AOptions, ComboFlags ); //
  52188. CreateControl( AParent, 'COMBOBOX', //
  52189. WS_VISIBLE or WS_CHILD or WS_VSCROLL or //
  52190. CBS_DROPDOWN or CBS_HASSTRINGS or WS_TABSTOP or Flags, //
  52191. True, @ComboActions ); //
  52192. fCreateWndExt := CreateComboboxWnd; //
  52193. fDropDownProc := ComboboxDropDown; //
  52194. fClsStyle := fClsStyle or CS_DBLCLKS; //
  52195. with fBoundsRect do //
  52196. begin //
  52197. Right := Left + 100; //
  52198. Bottom := Top + 22; //
  52199. end; //
  52200. fColor := clWindow; //
  52201. fLookTabKeys := [ tkTab ]; //
  52202. if coReadOnly in AOptions then //
  52203. fLookTabKeys := [ tkTab, tkLeftRight ]; //
  52204. end; //
  52205. //
  52206. //[constructor TControl.CreateCommonControl]
  52207. constructor TControl.CreateCommonControl(AParent: PControl; //
  52208. AClassName: PChar; AStyle: DWORD; ACtl3D: Boolean; //
  52209. Actions: PCommandActions); //
  52210. begin //
  52211. {*************} DoInitCommonControls( ICC_WIN95_CLASSES ); //
  52212. CreateControl( AParent, AClassName, AStyle, ACtl3D, Actions ); //
  52213. fIsCommonControl := True; //
  52214. if AParent <> nil then //
  52215. begin //
  52216. AttachProc( WndProcParentResize ); //
  52217. AParent.AttachProc( WndProcResize ); //
  52218. AttachProc( WndProcCommonNotify ); //
  52219. AParent.AttachProc( WndProcNotify ); //
  52220. end; //
  52221. end; //
  52222. //
  52223. //[constructor TControl.CreateRichEdit1]
  52224. constructor TControl.CreateRichEdit1(AParent: PControl; //
  52225. AOptions: TEditOptions); //
  52226. var Flags, I: Integer; //
  52227. begin //
  52228. if FRichEditModule = 0 then //
  52229. begin //
  52230. for I := 0 to High( RichEditLibnames ) do //
  52231. begin //
  52232. FRichEditModule := LoadLibrary( RichEditLibnames[ I ] ); //
  52233. if FRichEditModule > HINSTANCE_ERROR then break; //
  52234. RichEditClass := RichEditClasses[ I ]; //
  52235. end; //
  52236. if FRichEditModule <= HINSTANCE_ERROR then //
  52237. FRichEditModule := 0; //
  52238. end; //
  52239. Flags := MakeFlags( @AOptions, RichEditFlags ); //
  52240. CreateCommonControl( AParent, RichEditClass, WS_VISIBLE or WS_CHILD //
  52241. or WS_TABSTOP or WS_BORDER or ES_MULTILINE or Flags, //
  52242. True, @RichEditActions ); //
  52243. //
  52244. AttachProc( WndProcRichEditNotify ); //
  52245. fDoubleBuffered := False; //
  52246. fCannotDoubleBuf := True; //
  52247. with fBoundsRect do //
  52248. begin //
  52249. Right := Right + 100; //
  52250. Bottom := Top + 200; //
  52251. end; //
  52252. fColor := clWindow; //
  52253. fLookTabKeys := [ tkTab ]; //
  52254. if eoWantTab in AOptions then //
  52255. fLookTabKeys := [ ]; //
  52256. Perform( EM_SETEVENTMASK, 0, //
  52257. ENM_CHANGE or ENM_SELCHANGE or ENM_REQUESTRESIZE or //
  52258. ENM_PROTECTED or $04000000 {ENM_LINK} ); //
  52259. Perform( EM_SETBKGNDCOLOR, 0, Color2RGB(fColor)); //
  52260. end; //
  52261. //
  52262. //
  52263. //[constructor TControl.CreateRichEdit]
  52264. constructor TControl.CreateRichEdit(AParent: PControl; //
  52265. AOptions: TEditOptions); //
  52266. var OldRichEditClass, OldRichEditLib: PChar; //
  52267. begin //
  52268. if OleInit then //
  52269. begin //
  52270. OldRichEditClass := RichEditClass; //
  52271. OldRichEditLib := RichEditLib; //
  52272. CreateRichEdit1( AParent, AOptions ); //
  52273. fCharFmtDeltaSz := 24; //
  52274. fParaFmtDeltaSz := sizeof( TParaFormat2 ) - sizeof( RichEdit.TParaFormat ); //
  52275. RichEditClass := OldRichEditClass; //
  52276. RichEditLib := OldRichEditLib; //
  52277. end //
  52278. else //
  52279. CreateRichEdit1( AParent, AOptions ); //
  52280. end; //
  52281. //
  52282. //[constructor TControl.CreateProgressbar]
  52283. constructor TControl.CreateProgressbar(AParent: PControl); //
  52284. const ProgressBarFlags: array[ TProgressbarOption ] of Integer = //
  52285. (PBS_VERTICAL, PBS_SMOOTH ); //
  52286. begin //
  52287. CreateCommonControl( AParent, PROGRESS_CLASS, //
  52288. WS_CHILD or WS_VISIBLE, True, nil ); //
  52289. with fBoundsRect do //
  52290. begin //
  52291. Right := Left + 300; //
  52292. Bottom := Top + 20; //
  52293. end; //
  52294. fMenu := 0; //
  52295. fTextColor := clHighlight; //
  52296. end; //
  52297. //
  52298. //[constructor TControl.CreateProgressbarEx]
  52299. constructor TControl.CreateProgressbarEx(AParent: PControl; //
  52300. AOptions: TProgressbarOptions); //
  52301. const ProgressBarFlags: array[ TProgressbarOption ] of Integer = //
  52302. (PBS_VERTICAL, PBS_SMOOTH ); //
  52303. begin //
  52304. CreateProgressbar( AParent ); //
  52305. fStyle := fStyle or DWORD( MakeFlags( @AOptions, ProgressBarFlags ) ); //
  52306. end; //
  52307. //
  52308. //[constructor TControl.CreateListView]
  52309. constructor TControl.CreateListView(AParent: PControl; //
  52310. AStyle: TListViewStyle; AOptions: TListViewOptions; AImageListSmall, //
  52311. AImageListNormal, AImageListState: PImageList); //
  52312. begin //
  52313. CreateCommonControl( AParent, WC_LISTVIEW, ListViewStyles[ AStyle ] or //
  52314. LVS_SHAREIMAGELISTS or WS_CHILD or WS_VISIBLE or WS_TABSTOP, //
  52315. True, @ListViewActions ); //
  52316. fLVOptions := AOptions; //
  52317. fLVStyle := AStyle; //
  52318. fCreateWndExt := ApplyImageLists2ListView; //
  52319. with fBoundsRect do //
  52320. begin //
  52321. Right := Left + 200; //
  52322. Bottom := Top + 150; //
  52323. end; //
  52324. ImageListSmall := AImageListSmall; //
  52325. ImageListNormal := AImageListNormal; //
  52326. ImageListState := AImageListState; //
  52327. fLVTextBkColor := clWindow; //
  52328. fLookTabKeys := [ tkTab ]; //
  52329. end; //
  52330. //
  52331. //[constructor TControl.CreateTreeView]
  52332. constructor TControl.CreateTreeView(AParent: PControl; //
  52333. AOptions: TTreeViewOptions; AImgListNormal, AImgListState: PImageList); //
  52334. var Flags: Integer; //
  52335. begin //
  52336. Flags := MakeFlags( @AOptions, TreeViewFlags ); //
  52337. CreateCommonControl( AParent, WC_TREEVIEW, Flags or WS_VISIBLE or //
  52338. WS_CHILD or WS_TABSTOP, True, @TreeViewActions ); //
  52339. fCreateWndExt := ApplyImageLists2Control; //
  52340. fColor := clWindow; //
  52341. AttachProc( WndProcTreeView ); //
  52342. with fBoundsRect do //
  52343. begin //
  52344. Right := Left + 150; //
  52345. Bottom := Top + 200; //
  52346. end; //
  52347. ImageListNormal := AImgListNormal; //
  52348. ImageListState := AImgListState; //
  52349. fLookTabKeys := [ tkTab ]; //
  52350. end; //
  52351. //
  52352. //[constructor TControl.CreateTabControl]
  52353. constructor TControl.CreateTabControl(AParent: PControl; ATabs: array of String;//
  52354. AOptions: TTabControlOptions; //
  52355. AImgList: PImageList; AImgList1stIdx: Integer); //
  52356. var I, II : Integer; //
  52357. Flags: Integer; //
  52358. begin //
  52359. Flags := MakeFlags( @AOptions, TabControlFlags ); //
  52360. if tcoFocusTabs in AOptions then //
  52361. Flags := Flags or (WS_TABSTOP or TCS_FOCUSONBUTTONDOWN); //
  52362. CreateCommonControl( AParent, WC_TABCONTROL, //
  52363. Flags or (WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or //
  52364. WS_VISIBLE), True, @TabControlActions ); //
  52365. if not( tcoBorder in AOptions ) then //
  52366. fExStyle := fExStyle and not WS_EX_CLIENTEDGE; //
  52367. AttachProc( WndProcTabControl ); //
  52368. with fBoundsRect do //
  52369. begin //
  52370. Right := Left + 100; //
  52371. Bottom := Top + 100; //
  52372. end; //
  52373. if AImgList <> nil then //
  52374. Perform( TCM_SETIMAGELIST, 0, AImgList.Handle ); //
  52375. II := AImgList1stIdx; //
  52376. for I := 0 to High( ATabs ) do //
  52377. begin //
  52378. TC_Insert( I, ATabs[ I ], II ); //
  52379. Inc( II ); //
  52380. end; //
  52381. fLookTabKeys := [ tkTab ]; //
  52382. end; //
  52383. //
  52384. //[constructor TControl.CreateToolbar]
  52385. constructor TControl.CreateToolbar(AParent: PControl; //
  52386. AAlign: TControlAlign; AOptions: TToolbarOptions; ABitmap: HBitmap; //
  52387. AButtons: array of PChar; ABtnImgIdxArray: array of Integer); //
  52388. var Flags: DWORD; //
  52389. begin //
  52390. if not( tboTextBottom in AOptions ) then //
  52391. AOptions := AOptions + [ tboTextRight ]; //
  52392. if tboTextRight in AOptions then //
  52393. AOptions := AOptions - [ tboTextBottom ]; //
  52394. Flags := MakeFlags( @AOptions, ToolbarOptions ); //
  52395. CreateCommonControl( AParent, TOOLBARCLASSNAME, ToolbarAligns[ Align ] or //
  52396. WS_CHILD or WS_VISIBLE {or WS_TABSTOP} //
  52397. or TBSTYLE_TOOLTIPS or Flags, //
  52398. (not (Align in [caNone])) and //
  52399. not (tboNoDivider in AOptions), nil ); //
  52400. fCommandActions.aClear := ClearToolbar; //
  52401. fCommandActions.aGetCount := TB_BUTTONCOUNT; //
  52402. with fBoundsRect do //
  52403. begin //
  52404. if AAlign in [ caNone ] then //
  52405. begin //
  52406. Bottom := Top + 26; //
  52407. Right := Left + 1000; //
  52408. end //
  52409. else //
  52410. begin //
  52411. Left := 0; Right := 0; //
  52412. Top := 0; Bottom := 0; //
  52413. end; //
  52414. end; //
  52415. Perform(TB_SETEXTENDEDSTYLE, 0, Perform(TB_GETEXTENDEDSTYLE, 0, 0) or //
  52416. TBSTYLE_EX_DRAWDDARROWS); //
  52417. //
  52418. AttachProc( WndProcToolbarCtrl ); //
  52419. Perform( TB_BUTTONSTRUCTSIZE, Sizeof( TTBButton ), 0 ); //
  52420. Perform( TB_SETINDENT, fMargin, 0 ); //
  52421. with fBoundsRect do //
  52422. begin //
  52423. if AAlign in [ caLeft, caRight ] then //
  52424. Right := Left + 24 //
  52425. else if not (AAlign in [caNone]) then //
  52426. Bottom := Top + 22; //
  52427. end; //
  52428. if ABitmap <> 0 then //
  52429. TBAddBitmap( ABitmap ); //
  52430. TBAddButtons( AButtons, ABtnImgIdxArray ); //
  52431. Perform( WM_SIZE, 0, 0 ); //
  52432. end; //
  52433. //
  52434. //[constructor TImageList.CreateImageList]
  52435. constructor TImageList.CreateImageList(POwner: Pointer); //
  52436. var AOwner: PControl; //
  52437. begin //
  52438. {*************} DoInitCommonControls( ICC_WIN95_CLASSES ); //
  52439. Create; //
  52440. FAllocBy := 1; //
  52441. FMasked := True; //
  52442. if POwner = nil then exit; //
  52443. FBkColor := TColor( CLR_NONE );
  52444. //ImageList_SetBkColor( FHandle, CLR_NONE );
  52445. //
  52446. AOwner := POwner; //
  52447. FControl := AOwner; //
  52448. fNext := PImageList( AOwner.fImageList ); //
  52449. if AOwner.fImageList <> nil then //
  52450. PImageList( AOwner.fImageList ).fPrev := @Self; //
  52451. AOwner.fImageList := @Self; //
  52452. end; //
  52453. //
  52454. //[constructor TThread.ThreadCreate]
  52455. constructor TThread.ThreadCreate; //
  52456. begin //
  52457. IsMultiThread := True; //
  52458. Create; //
  52459. FSuspended := True; //
  52460. FHandle := CreateThread( nil, // no security //
  52461. 0, // the same stack size //
  52462. @ThreadFunc, // thread entry point //
  52463. @Self, // parameter to pass to ThreadFunc //
  52464. CREATE_SUSPENDED, // always SUSPENDED //
  52465. FThreadID ); // receive thread ID //
  52466. end; //
  52467. //
  52468. //[constructor TThread.ThreadCreateEx]
  52469. constructor TThread.ThreadCreateEx( const Proc: TOnThreadExecute ); //
  52470. begin //
  52471. ThreadCreate; //
  52472. OnExecute := Proc; //
  52473. Resume; //
  52474. end; //
  52475. //
  52476. {$ENDIF USE_CONSTRUCTORS} //****************************************************//
  52477. {+}
  52478. //[procedure InvalidateExW]
  52479. procedure InvalidateExW( Wnd: HWnd );
  52480. begin
  52481. InvalidateRect( Wnd, nil, TRUE );
  52482. Wnd := GetWindow( Wnd, GW_CHILD );
  52483. while Wnd <> 0 do
  52484. begin
  52485. InvalidateExW( Wnd );
  52486. Wnd := GetWindow( Wnd, GW_HWNDNEXT );
  52487. end;
  52488. end;
  52489. //[procedure TControl.InvalidateEx]
  52490. procedure TControl.InvalidateEx;
  52491. begin
  52492. if fHandle = 0 then Exit;
  52493. InvalidateExW( fHandle );
  52494. end;
  52495. //[procedure InvalidateNCW]
  52496. procedure InvalidateNCW( Wnd: HWnd; Recursive: Boolean );
  52497. begin
  52498. SendMessage( Wnd, WM_NCPAINT, 1, 0 );
  52499. if not Recursive then Exit;
  52500. Wnd := GetWindow( Wnd, GW_CHILD );
  52501. while Wnd <> 0 do
  52502. begin
  52503. InvalidateNCW( Wnd, Recursive );
  52504. Wnd := GetWindow( Wnd, GW_HWNDNEXT );
  52505. end;
  52506. end;
  52507. //[procedure TControl.InvalidateNC]
  52508. procedure TControl.InvalidateNC(Recursive: Boolean);
  52509. begin
  52510. if fHandle = 0 then Exit;
  52511. InvalidateNCW( fHandle, Recursive );
  52512. end;
  52513. //[procedure TControl.SetClientMargin]
  52514. procedure TControl.SetClientMargin(const Index, Value: Integer);
  52515. begin
  52516. case Index of
  52517. 1: fClientTop := Value;
  52518. 2: fClientBottom := Value;
  52519. 3: fClientLeft := Value;
  52520. 4: fClientRight := Value;
  52521. end;
  52522. {$IFNDEF OLD_ALIGN}include(fAligning,oaFromSelf);{$ENDIF}//???
  52523. Global_Align( @Self );
  52524. end;
  52525. {$IFDEF F_P}
  52526. //[function TControl.GetClientMargin]
  52527. function TControl.GetClientMargin(const Index: Integer): Integer;
  52528. begin
  52529. CASE Index OF
  52530. 1: Result := fClientTop;
  52531. 2: Result := fClientBottom;
  52532. 3: Result := fClientLeft;
  52533. 4: Result := fClientRight;
  52534. END;
  52535. end;
  52536. {$ENDIF F_P}
  52537. {------------------------------------------------------------------------------}
  52538. { G R A P H C O N T R O L S }
  52539. {------------------------------------------------------------------------------}
  52540. type TGrayTextData = {$ifndef wince}packed{$endif} record
  52541. Ctl: PControl;
  52542. W, H: Integer;
  52543. Flags: DWORD;
  52544. end;
  52545. PGrayTextData = ^TGrayTextData;
  52546. function DrawTextGrayed( DC: HDC; lData, wData, cX, cY: Integer ): BOOL; {$ifdef wince}cdecl{$else}stdcall{$endif};
  52547. var GDT: PGrayTextData;
  52548. R: TRect;
  52549. begin
  52550. GDT := Pointer( lData );
  52551. R := MakeRect( 0, 0, cX, cY );
  52552. DrawFormattedText( GDT.Ctl, DC, R, GDT.Flags or $80000000 );
  52553. Result := TRUE;
  52554. end;
  52555. procedure DrawFormattedText( Ctl: PControl; DC: HDC; var R: TRect; Flags: DWORD {EditCtl: Boolean} );
  52556. var Fmt: DWORD;
  52557. OldFont: Integer;
  52558. OldBrush: Integer;
  52559. OldBk: Integer;
  52560. ParentHavingFont: PControl;
  52561. {$ifdef win32}
  52562. GTD: TGrayTextData;
  52563. {$endif win32}
  52564. dX, dY: Integer;
  52565. R1: TRect;
  52566. begin
  52567. Fmt := DT_EXPANDTABS or Flags and $7FFFFFFF;
  52568. if Ctl.WordWrap then
  52569. Fmt := Fmt or DT_WORDBREAK;
  52570. if Flags and DT_EDITCONTROL <> 0 then
  52571. Inc( R.Left, 4 );
  52572. ParentHavingFont := Ctl;
  52573. while (ParentHavingFont <> nil) and not Assigned( ParentHavingFont.FFont )
  52574. and not ParentHavingFont.IsForm do
  52575. ParentHavingFont := ParentHavingFont.Parent;
  52576. OldFont := 0;
  52577. if Assigned( ParentHavingFont ) then
  52578. begin
  52579. OldFont := SelectObject( DC, ParentHavingFont.Font.Handle );
  52580. SetTextColor( DC, ParentHavingFont.Font.FColorRGB );
  52581. end;
  52582. R1 := R;
  52583. Windows.{$IFDEF UNICODE_CTRLS}DrawTextW{$ELSE}DrawTextA{$ENDIF}( DC, PKOLChar( Ctl.Caption ), Length( Ctl.Caption ), R,
  52584. Fmt or DT_CALCRECT );
  52585. CASE Ctl.fTextAlign OF
  52586. taCenter:
  52587. dX := (R1.Right - R1.Left - (R.Right - R.Left)) div 2;
  52588. taRight:
  52589. dX := R1.Right - R.Right;
  52590. else
  52591. dX := 0;
  52592. END;
  52593. CASE Ctl.fVerticalAlign OF
  52594. vaCenter:
  52595. dY := (R1.Bottom - R1.Top - (R.Bottom - R.Top)) div 2;
  52596. vaBottom:
  52597. dY := R1.Bottom - R.Bottom;
  52598. else
  52599. dY := 0;
  52600. END;
  52601. OffsetRect( R, dX, dY );
  52602. if Ctl.fEnabled or (Flags and $80000000 <> 0) then
  52603. begin
  52604. OldBk := SetBkMode( DC, TRANSPARENT );
  52605. OldBrush := SelectObject( DC, GetStockObject( NULL_BRUSH ) );
  52606. Windows.{$IFDEF UNICODE_CTRLS}DrawTextW{$ELSE}DrawTextA{$ENDIF}( DC, PKOLChar( Ctl.Caption ), Length( Ctl.Caption ), R, Fmt );
  52607. SelectObject( DC, OldBrush );
  52608. SetBkMode( DC, OldBk );
  52609. end
  52610. else
  52611. begin
  52612. {$ifdef wince}
  52613. MsgOk('DrawFormattedText must be fixed!');
  52614. Halt(4); // FIXME
  52615. {$else}
  52616. GTD.Ctl := Ctl;
  52617. GTD.W := R.Right - R.Left;
  52618. GTD.H := R.Bottom - R.Top;
  52619. GTD.Flags := Flags;
  52620. Windows.DrawState( DC, GetStockObject( NULL_BRUSH ), @ DrawTextGrayed,
  52621. Integer( @ GTD ), Length( Ctl.fCaption ), R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
  52622. DST_COMPLEX or DSS_DISABLED );
  52623. {$endif wince}
  52624. end;
  52625. if Assigned( ParentHavingFont ) then
  52626. SelectObject( DC, OldFont );
  52627. end;
  52628. {$IFDEF USE_GRAPHCTLS}
  52629. {$IFDEF GRAPHCTL_XPSTYLES}
  52630. type TOpenThemeDataProc = function( Wnd: HWnd; pszClassList: PWideChar ): THandle;
  52631. {$ifdef wince}cdecl{$else}stdcall{$endif};
  52632. TDrawThemeBackground = function( Theme: THandle; DC: HDC; iPartId: Integer;
  52633. iStateId: Integer; Rect, ClipRect: PRect ): Integer;
  52634. {$ifdef wince}cdecl{$else}stdcall{$endif};
  52635. TGetThemeBackgroundContentRect = function( Theme: THandle; DC: HDC;
  52636. iPartId, iStateId: Integer; Rect, ContentRect: PRect ):
  52637. Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  52638. TDrawThemeText = function( Theme: THandle; DC: HDC; iPartId, iStateId: Integer;
  52639. pszText: PWideChar; iCharCount: Integer;
  52640. dwTextFlags, dwTextFlags2: DWORD; Rect: PRect ): Integer;
  52641. {$ifdef wince}cdecl{$else}stdcall{$endif};
  52642. TCloseThemeData = function( Theme: THandle ): Integer; {$ifdef wince}cdecl{$else}stdcall{$endif};
  52643. var fOpenThemeDataProc: TOpenThemeDataProc;
  52644. fDrawthemeBackground: TDrawThemeBackground;
  52645. fGetThemeBackgroundcontentRect: TGetThemeBackgroundContentRect;
  52646. fDrawThemeText: TDrawThemeText;
  52647. fCloseThemeData: TCloseThemeData;
  52648. uxtheme_lib: THandle;
  52649. function OpenThemeDataProc: TOpenThemeDataProc;
  52650. begin
  52651. Result := nil;
  52652. if Integer(uxtheme_lib) = -1 then Exit;
  52653. if uxtheme_lib = 0 then
  52654. uxtheme_lib := LoadLibrary( 'uxtheme' );
  52655. if uxtheme_lib = 0 then
  52656. begin
  52657. uxtheme_lib := DWORD( -1 );
  52658. Exit;
  52659. end;
  52660. fOpenThemeDataProc := GetProcAddress( uxtheme_lib, 'OpenThemeData' );
  52661. fDrawthemeBackground := GetProcAddress( uxtheme_lib, 'DrawThemeBackground' );
  52662. fGetThemeBackgroundcontentRect := GetProcAddress( uxtheme_lib, 'GetThemeBackgroundContentRect' );
  52663. fDrawThemeText := GetProcAddress( uxtheme_lib, 'DrawThemeText' );
  52664. fCloseThemeData := GetProcAddress( uxtheme_lib, 'CloseThemeData' );
  52665. if not Assigned( fOpenThemeDataProc ) or
  52666. not Assigned( fDrawThemeBackground ) or
  52667. not Assigned( fGetThemeBackgroundcontentRect ) or
  52668. not Assigned( fDrawThemeText ) or
  52669. not Assigned( fCloseThemeData ) then
  52670. begin
  52671. FreeLibrary( uxtheme_lib );
  52672. uxtheme_lib := DWORD( -1 );
  52673. fOpenThemeDataProc := nil;
  52674. fDrawThemeBackground := nil;
  52675. fGetThemeBackgroundcontentRect := nil;
  52676. fDrawThemeText := nil;
  52677. fCloseThemeData := nil;
  52678. end;
  52679. Result := fOpenThemeDataProc;
  52680. end;
  52681. procedure DrawFormattedTextXP( Theme: THandle; Ctl: PControl; DC: HDC;
  52682. var R: TRect; CtlType, CtlStates, Flags1, Flags2: Integer );
  52683. var OldFont: Integer;
  52684. OldBrush: Integer;
  52685. ParentHavingFont: PControl;
  52686. begin
  52687. ParentHavingFont := Ctl;
  52688. while (ParentHavingFont <> nil) and not Assigned( ParentHavingFont.FFont )
  52689. and not ParentHavingFont.IsForm do
  52690. ParentHavingFont := ParentHavingFont.Parent;
  52691. OldFont := 0;
  52692. if Assigned( ParentHavingFont ) then
  52693. OldFont := SelectObject( DC, ParentHavingFont.Font.Handle );
  52694. OldBrush := SelectObject( DC, GetStockObject( NULL_BRUSH ) );
  52695. fDrawThemeText( Theme, DC, CtlType, CtlStates, @ WideString( Ctl.fCaption )[ 1 ],
  52696. Length( Ctl.fCaption ), Flags1, Flags2, @ R );
  52697. SelectObject( DC, OldBrush );
  52698. if Assigned( ParentHavingFont ) then
  52699. SelectObject( DC, OldFont );
  52700. end;
  52701. {$ENDIF}
  52702. procedure PaintGraphicChildren( Self_, Sender: PControl; DC: HDC );
  52703. var i, sav: Integer;
  52704. C: PControl;
  52705. R: TRect;
  52706. rgn: HRgn;
  52707. begin
  52708. for i := Self_.ChildCount-1 downto 0 do
  52709. begin
  52710. C := Self_.Children[ i ];
  52711. if not C.Visible then continue;
  52712. R := C.BoundsRect;
  52713. if (C.Handle = 0) and not C.fWindowed and
  52714. Assigned( C.fPaintProc ) then
  52715. begin
  52716. sav := SaveDC( DC );
  52717. rgn := CreateRectRgnIndirect( R );
  52718. ExtSelectClipRgn( DC, rgn, RGN_AND );
  52719. SelectClipRgn( DC, rgn );
  52720. DeleteObject( rgn );
  52721. Free_And_Nil( C.fCanvas );
  52722. C.fCanvas := Self_.Canvas;
  52723. Self_.Canvas.Brush.Assign( Self_.Brush );
  52724. Self_.Canvas.Font.Assign( Self_.Font ); // íå ïðèñâàèâàåòñÿ?
  52725. Self_.fCanvas.DeselectHandles; // íå ïîìîãàåò???
  52726. if Assigned( C.OnPrepaint ) then
  52727. C.OnPrePaint( C, DC );
  52728. if Assigned( C.OnPaint ) then
  52729. C.OnPaint( C, DC )
  52730. else
  52731. C.fPaintProc( DC );
  52732. if Assigned( C.OnPostPaint ) then
  52733. C.OnPostPaint( C, DC );
  52734. C.fCanvas := nil;
  52735. Self_.Canvas.Brush.Assign( Self_.Brush );
  52736. Self_.Canvas.Font.Assign( Self_.Font );
  52737. RestoreDC( DC, sav );
  52738. ExcludeClipRect( DC, R.Left, R.Top, R.Right, R.Bottom );
  52739. end;
  52740. end;
  52741. if Self_.fIsGroupBox then
  52742. begin
  52743. Self_.fErasingBkgnd := TRUE;
  52744. R := Self_.BoundsRect;
  52745. OffsetRect( R, -R.Left, -R.Top );
  52746. Self_.Canvas.FillRect( R );
  52747. Self_.GroupBoxPaint( DC );
  52748. Self_.fErasingBkgnd := FALSE;
  52749. end
  52750. else
  52751. if Assigned( Self_.fOnPaint2 ) then
  52752. Self_.fOnPaint2( Self_, DC )
  52753. else
  52754. Self_.Canvas.FillRect( Self_.ClientRect );
  52755. end;
  52756. function WndProc_ParentOfGraphicCtl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  52757. var WasOnPaint: TOnPaint;
  52758. i: Integer;
  52759. C: PControl;
  52760. Pt: TPoint;
  52761. PF: PControl;
  52762. save_Paint2: TOnPaint;
  52763. begin
  52764. Result := FALSE;
  52765. if (Msg.message = WM_PAINT) {or (Msg.message = WM_PRINT)} then
  52766. begin
  52767. //if not Result then
  52768. begin
  52769. WasOnPaint := Self_.fOnPaint;
  52770. Self_.fOnPaint2 := Self_.fOnPaint;
  52771. Self_.fPaintMsg := Msg;
  52772. TMethod( Self_.fOnPaint ) := MakeMethod( Self_, @ PaintGraphicChildren );
  52773. save_Paint2 := Self_.fOnPaint2;
  52774. if not Assigned( Self_.fOnPaint2 ) then
  52775. Self_.fOnPaint2 := TOnPaint( MakeMethod( nil, @ DummyPaintClear ) );
  52776. i := Self_.fDynHandlers.fCount;
  52777. Self_.fDynHandlers.fCount := Self_.fDynHandlers.IndexOf( @ WndProc_ParentOfGraphicCtl );
  52778. Result := EnumDynHandlers( Self_, Msg, Rslt );
  52779. Self_.fDynHandlers.fCount := i;
  52780. //Self_.fOnPaint2 := save_Paint2;
  52781. if not Result then
  52782. {Result :=} WndProcPaint( Self_, Msg, Rslt );
  52783. Self_.fOnPaint := WasOnPaint;
  52784. end;
  52785. Result := TRUE;
  52786. end
  52787. else
  52788. if (Msg.message >= WM_MOUSEFIRST) and (Msg.message <= WM_MOUSELAST) then
  52789. begin
  52790. Pt.X := SmallInt( LoWord( Msg.lParam ) );
  52791. Pt.Y := SmallInt( HiWord( Msg.lParam ) );
  52792. for i := 0 to Self_.ChildCount-1 do
  52793. begin
  52794. if (i = 0) and (Self_.fPushedBtn <> nil) then
  52795. C := Self_.fPushedBtn
  52796. else
  52797. C := Self_.Children[ i ];
  52798. if (C = Self_.fPushedBtn) OR
  52799. C.fVisible and C.fEnabled and PtInRect( C.BoundsRect, Pt ) then
  52800. begin
  52801. if not C.fWindowed and
  52802. (C.fCursor <> 0) and (C.fCursor <> Self_.fCursor) and
  52803. (ScreenCursor = 0) then
  52804. begin
  52805. if Self_.fSaveCursor = 0 then
  52806. begin
  52807. Self_.fSaveCursor := Self_.fCursor;
  52808. if Self_.fCursor = 0 then
  52809. Self_.fSaveCursor := LoadCursor( 0, IDC_ARROW );
  52810. end;
  52811. Self_.Cursor := C.fCursor;
  52812. Windows.SetCursor( C.fCursor );
  52813. end;
  52814. {$IFDEF GRAPHCTL_HOTTRACK}
  52815. if not C.fWindowed and (Applet.fHotCtl <> C) then
  52816. begin
  52817. if Applet.fHotCtl <> nil then
  52818. begin
  52819. Applet.fHotCtl.fHot := FALSE;
  52820. if not Applet.fHotCtl.fWindowed then
  52821. begin
  52822. Applet.fHotCtl.Invalidate;
  52823. if Assigned( Applet.fHotCtl.OnMouseLeave ) then
  52824. Applet.fHotCtl.OnMouseLeave( Applet.fHotCtl );
  52825. end;
  52826. Applet.fHotCtl.RefDec;
  52827. end;
  52828. C.RefInc;
  52829. Applet.fHotCtl := C;
  52830. C.fHot := TRUE;
  52831. C.Invalidate;
  52832. Self_.fMouseLeaveProc := Self_.MouseLeaveFromParentOfGraphCtl;
  52833. ProvideMouseEnterLeave( Self_ );
  52834. if Assigned( C.OnMouseEnter ) then
  52835. C.OnMouseEnter( C );
  52836. end;
  52837. {$ENDIF GRAPHCTL_HOTTRACK}
  52838. if C.fWindowed then
  52839. begin
  52840. Msg.hwnd := C.fHandle;
  52841. Pt := Self_.Client2Screen( Pt );
  52842. Pt := C.Screen2Client( Pt );
  52843. Msg.lParam := Pt.Y shl 16 or (Pt.X and $FFFF);
  52844. end;
  52845. Rslt := C.WndProc( Msg );
  52846. if not C.fWindowed then
  52847. if Assigned( C.fGraphCtlMouseEvent ) then
  52848. C.fGraphCtlMouseEvent( Msg )
  52849. else
  52850. if (Msg.message = WM_LBUTTONDOWN) or
  52851. (Msg.message = WM_RBUTTONDOWN) or
  52852. (Msg.message = WM_MBUTTONDOWN) then
  52853. C.DoClick;
  52854. Result := TRUE;
  52855. Exit;
  52856. end;
  52857. end;
  52858. {$IFDEF GRAPHCTL_HOTTRACK}
  52859. Self_.MouseLeaveFromParentOfGraphCtl( Self_ );
  52860. {$ENDIF GRAPHCTL_HOTTRACK}
  52861. if Self_.fIsGroupBox and (
  52862. (Msg.message = WM_LBUTTONDOWN) or
  52863. (Msg.message = WM_LBUTTONDBLCLK) or
  52864. (Msg.message = WM_LBUTTONUP)
  52865. ) then
  52866. begin
  52867. Self_.Invalidate;
  52868. end;
  52869. if Self_.fSaveCursor <> 0 then
  52870. begin
  52871. Self_.Cursor := Self_.fSaveCursor;
  52872. Self_.fSaveCursor := 0;
  52873. if ScreenCursor = 0 then
  52874. Windows.SetCursor( Self_.fCursor );
  52875. end;
  52876. end
  52877. else
  52878. if (Msg.message >= WM_KEYFIRST) and (Msg.message <= WM_KEYLAST) then
  52879. begin
  52880. if Self_.IsControl then
  52881. PF := Self_.ParentForm
  52882. else
  52883. PF := Self_;
  52884. if (PF.fCurrentControl <> nil) and not PF.fCurrentControl.fWindowed then
  52885. begin
  52886. if Assigned( PF.fCurrentControl.fKeyboardProcess ) and
  52887. PF.fCurrentControl.fKeyboardProcess( Msg, Rslt ) then
  52888. else
  52889. Rslt := PF.fCurrentControl.WndProc( Msg );
  52890. Result := TRUE;
  52891. end
  52892. else
  52893. begin
  52894. if Self_.fIsGroupBox and (Msg.wParam = WORD( ' ' )) and
  52895. (
  52896. (Msg.message = WM_KEYDOWN) or
  52897. (Msg.message = WM_SYSKEYDOWN) or
  52898. (Msg.message = WM_KEYUP) or
  52899. (Msg.message = WM_SYSKEYUP) or
  52900. (Msg.message = WM_CHAR) or
  52901. (Msg.message = WM_SYSCHAR)
  52902. ) then
  52903. begin
  52904. Self_.Invalidate;
  52905. end;
  52906. end;
  52907. end
  52908. else
  52909. if Msg.message = CM_QUIT then
  52910. begin
  52911. C := Pointer( Msg.wParam );
  52912. C.Free;
  52913. end
  52914. else
  52915. if Msg.message = CM_FOCUSGRAPHCTL then
  52916. begin
  52917. C := Pointer( Msg.wParam );
  52918. PF := C.ParentForm;
  52919. if (PF.fCurrentControl <> nil) and (PF.fCurrentControl <> C) then
  52920. begin
  52921. PF.fCurrentControl.fFocused := FALSE;
  52922. PF.fCurrentControl.Invalidate;
  52923. end;
  52924. PF.fCurrentControl := C;
  52925. C.Parent.fCurrentControl := C;
  52926. C.Parent.fFocusHandle := C.Parent.fHandle;
  52927. C.fFocused := TRUE;
  52928. if Assigned( C.fOnEnter ) then
  52929. C.fOnEnter( C );
  52930. C.Invalidate;
  52931. C.fLeave := C.LeaveGraphButton;
  52932. C.RefDec;
  52933. end;
  52934. end;
  52935. function WndProc_FormHavingGraphCtl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  52936. var Msg2: TMsg;
  52937. begin
  52938. Result := FALSE;
  52939. if Msg.message = WM_ACTIVATE then
  52940. begin
  52941. if Self_.fCurrentControl <> nil then
  52942. Self_.fCurrentControl.Invalidate;
  52943. end
  52944. else
  52945. if (Msg.message >= WM_KEYFIRST) and (Msg.message <= WM_KEYLAST) then
  52946. begin
  52947. if (Self_.fCurrentControl <> nil) and not Self_.fCurrentControl.fWindowed then
  52948. begin
  52949. if (Msg.message = WM_KEYDOWN) and ((Msg.wParam = 32) or (Msg.wParam = 13)) then
  52950. begin
  52951. if not PeekMessage( Msg2, Msg.hwnd, WM_CHAR, WM_CHAR, pm_noRemove ) or
  52952. (Msg2.wParam <> Msg.wParam) then
  52953. Msg.message := WM_CHAR;
  52954. end
  52955. else
  52956. if (Msg.message = WM_SYSKEYDOWN) and ((Msg.wParam = 32) or (Msg.wParam = 13)) then
  52957. begin
  52958. if not PeekMessage( Msg2, Msg.hwnd, WM_SYSCHAR, WM_SYSCHAR, pm_noRemove ) or
  52959. (Msg2.wParam <> Msg.wParam) then
  52960. Msg.message := WM_SYSCHAR;
  52961. end;
  52962. if Assigned( Self_.fCurrentControl.fKeyboardProcess ) and
  52963. Self_.fCurrentControl.fKeyboardProcess( Msg, Rslt ) then
  52964. else
  52965. Rslt := Self_.fCurrentControl.WndProc( Msg );
  52966. Result := TRUE;
  52967. end;
  52968. end;
  52969. end;
  52970. {$IFDEF GRAPHCTL_HOTTRACK}
  52971. procedure TControl.MouseLeaveFromParentOfGraphCtl(Sender: PObj);
  52972. var C: PControl;
  52973. Pt: TPoint;
  52974. begin
  52975. if AppletTerminated then Exit;
  52976. GetCursorPos( Pt );
  52977. Pt := Screen2Client( Pt );
  52978. if (Applet.fHotCtl <> nil) and (fChildren.IndexOf( Applet.fHotCtl ) >= 0) then
  52979. begin
  52980. C := Applet.fHotCtl;
  52981. if PtInRect( C.BoundsRect, Pt ) then Exit;
  52982. Applet.fHotCtl := nil;
  52983. C.fHot := FALSE;
  52984. if not C.fWindowed then
  52985. C.Invalidate;
  52986. if Assigned( C.OnMouseLeave ) then
  52987. C.OnMouseLeave( C );
  52988. C.RefDec;
  52989. end;
  52990. end;
  52991. {$ENDIF GRAPHCTL_HOTTRACK}
  52992. procedure NotifyGraphCtlAboutNewParent(Prnt, Chld: PControl);
  52993. begin
  52994. if (Chld <> nil) and (Prnt <> nil) then
  52995. begin
  52996. Prnt.AttachProc( WndProc_ParentOfGraphicCtl );
  52997. {if not Prnt.IsProcAttached( WndProc_ParentOfGraphicCtl ) then
  52998. begin
  52999. Prnt.fDynHandlers.Insert( 0, nil );
  53000. Prnt.fDynHandlers.Insert( 0, @ WndProc_ParentOfGraphicCtl );
  53001. end;}
  53002. end;
  53003. end;
  53004. function _NewGraphCtl( AParent: PControl; ATabStop: Boolean ): PControl;
  53005. begin
  53006. {-}
  53007. new( Result, Create );
  53008. {+}{++}(*Result := PControl.CreateParented( AParent );*){--}
  53009. Result.fDoInvalidate := Result.InvalidateNonWindowed;
  53010. Result.fWindowed := FALSE;
  53011. Result.fVisible := TRUE;
  53012. Result.fCreateVisible := TRUE;
  53013. Result.fIsControl := TRUE;
  53014. Result.fMenu := CtlIdCount;
  53015. Inc( CtlIdCount );
  53016. Result.fBitBtnOptions := [ bboFixed ]; // to return Checked = fChecked w/o window handle
  53017. Result.fIgnoreWndCaption := TRUE;
  53018. Result.fNotifyChild := @ NotifyGraphCtlAboutNewParent;
  53019. Result.fSizeRedraw := TRUE;
  53020. Result.fTabstop := ATabStop;
  53021. if ATabStop then
  53022. Result.fLookTabKeys := [ tkTab, tkLeftRight, tkUpDown, tkPageUpPageDn ];
  53023. if AParent <> nil then
  53024. begin
  53025. Result.Parent := AParent;
  53026. Result.Border := AParent.Border;
  53027. //if not AParent.IsProcAttached( WndProc_ParentOfGraphicCtl ) then
  53028. begin
  53029. AParent.AttachProc( WndProc_ParentOfGraphicCtl );
  53030. //AParent.fDynHandlers.Insert( 0, nil );
  53031. //AParent.fDynHandlers.Insert( 0, @ WndProc_ParentOfGraphicCtl );
  53032. end;
  53033. if ATabStop then
  53034. begin
  53035. Inc( AParent.ParentForm.fTabOrder );
  53036. Result.fTabOrder := AParent.ParentForm.fTabOrder;
  53037. end;
  53038. if AParent.IsControl then
  53039. AParent.ParentForm.AttachProc( WndProc_FormHavingGraphCtl );
  53040. if AParent.fIsGroupBox then
  53041. begin
  53042. AParent.Style := AParent.Style and
  53043. not BS_GROUPBOX; // otherwise the groupbox is flickering A LOT!
  53044. AParent.Parent.AttachProc( WndProc_ParentOfGraphicCtl );
  53045. end;
  53046. Result.fFont := Result.fFont.Assign( AParent.fFont );
  53047. if Result.fFont <> nil then
  53048. begin
  53049. Result.fFont.fParentGDITool := AParent.fFont;
  53050. Result.fFont.fOnChange := Result.FontChanged;
  53051. Result.FontChanged( Result.fFont );
  53052. end;
  53053. end;
  53054. Result.fBoundsRect.Right := Result.fBoundsRect.Left + 64;
  53055. Result.fBoundsRect.Bottom := Result.fBoundsRect.Top + 22;
  53056. {$IFDEF GRAPHCTL_XPSTYLES}
  53057. if WinVer < wvXP then
  53058. DoNotDrawGraphCtlsUsingXPStyles := TRUE;
  53059. {$ENDIF}
  53060. end;
  53061. function NewGraphLabel( AParent: PControl; const ACaption: String ): PControl;
  53062. begin
  53063. {$IFDEF INPACKAGE}
  53064. Result := NewLabel( AParent, ACaption );
  53065. {$ELSE}
  53066. Result := _NewGraphCtl( AParent, FALSE );
  53067. Result.fCommandActions := LabelActions;
  53068. Result.fPaintProc := Result.GraphicLabelPaint;
  53069. Result.Caption := ACaption;
  53070. {$ENDIF}
  53071. end;
  53072. function NewWordWrapGraphLabel( AParent: PControl; const ACaption: KOLString ): PControl;
  53073. begin
  53074. {$IFDEF INPACKAGE}
  53075. Result := NewWordWrapLabel( AParent, ACaption );
  53076. {$ELSE}
  53077. Result := NewGraphLabel( AParent, ACaption );
  53078. Result.fWordWrap := TRUE;
  53079. {$ENDIF}
  53080. end;
  53081. function NewGraphPaintBox( AParent: PControl ): PControl;
  53082. begin
  53083. {$IFDEF INPACKAGE}
  53084. Result := NewPaintbox( AParent );
  53085. {$ELSE}
  53086. Result := NewGraphLabel( AParent, '' );
  53087. {$ENDIF}
  53088. end;
  53089. procedure ClickGraphCheck(Sender: PObj);
  53090. var Ctl: PControl;
  53091. begin
  53092. Ctl := Pointer( Sender );
  53093. if not Ctl.Enabled then Exit;
  53094. Ctl.Focused := TRUE;
  53095. if Assigned( Ctl.OnEnter ) then
  53096. Ctl.OnEnter( Ctl );
  53097. Ctl.fChecked := not Ctl.fChecked;
  53098. Ctl.Invalidate;
  53099. if Assigned( Ctl.OnClick ) then
  53100. Ctl.OnClick( Ctl );
  53101. end;
  53102. function NewGraphCheckBox( AParent: PControl; const ACaption: KOLString ): PControl;
  53103. begin
  53104. {$IFDEF INPACKAGE}
  53105. Result := NewCheckbox( AParent, ACaption );
  53106. {$ELSE}
  53107. Result := NewGraphButton( AParent, ACaption );
  53108. Result.TextAlign := taLeft;
  53109. Result.fCommandActions.aAutoSzX := GetSystemMetrics( SM_CXMENUCHECK ) + 4;
  53110. Result.fPaintProc := Result.GraphicCheckBoxPaint;
  53111. Result.fGraphCtlMouseEvent := Result.GraphicCheckBoxMouse;
  53112. Result.fControlClick := @ ClickGraphCheck;
  53113. {$ENDIF}
  53114. end;
  53115. procedure ClickGraphRadio(Sender: PObj);
  53116. var Ctl, C: PControl;
  53117. i: Integer;
  53118. begin
  53119. Ctl := Pointer( Sender );
  53120. if not Ctl.Enabled then Exit;
  53121. Ctl.Focused := TRUE;
  53122. Ctl.Checked := TRUE;
  53123. if Ctl.Parent <> nil then
  53124. for i := 0 to Ctl.Parent.ChildCount-1 do
  53125. begin
  53126. C := Ctl.Parent.Children[ i ];
  53127. if (C <> Ctl) and (@ C.fControlClick = @ ClickGraphRadio) then
  53128. C.Checked := FALSE;
  53129. end;
  53130. end;
  53131. function NewGraphRadioBox( AParent: PControl; const ACaption: KOLString ): PControl;
  53132. begin
  53133. {$IFDEF INPACKAGE}
  53134. Result := NewRadiobox( AParent, ACaption );
  53135. if (@ ClickGraphRadio) <> nil then;
  53136. {$ELSE}
  53137. Result := NewGraphButton( AParent, ACaption );
  53138. Result.TextAlign := taLeft;
  53139. Result.fCommandActions.aAutoSzX := GetSystemMetrics( SM_CXMENUCHECK ) + 4;
  53140. Result.fPaintProc := Result.GraphicRadioBoxPaint;
  53141. Result.fControlClick := @ ClickGraphRadio;
  53142. if AParent <> nil then
  53143. begin
  53144. AParent.fRadioLast := Result.fMenu;
  53145. if AParent.fRadio1st = 0 then
  53146. begin
  53147. AParent.fRadio1st := Result.fMenu;
  53148. Result.SetRadioChecked;
  53149. end;
  53150. end;
  53151. {$ENDIF}
  53152. end;
  53153. function NewGraphButton( AParent: PControl; const ACaption: KOLString ): PControl;
  53154. begin
  53155. {$IFDEF INPACKAGE}
  53156. Result := NewButton( AParent, ACaption );
  53157. {$ELSE}
  53158. Result := _NewGraphCtl( AParent, TRUE );
  53159. Result.fCommandActions := ButtonActions;
  53160. Result.fPaintProc := Result.GraphicButtonPaint;
  53161. Result.Caption := ACaption;
  53162. Result.TextAlign := taCenter;
  53163. Result.VerticalAlign := vaCenter;
  53164. Result.fGraphCtlMouseEvent := Result.GraphicButtonMouse;
  53165. Result.fSetFocus := Result.GraphButtonSetFocus;
  53166. Result.fKeyboardProcess := Result.GraphButtonKeyboardProcess;
  53167. {$ENDIF}
  53168. end;
  53169. function NewGraphEditbox( AParent: PControl; Options: TEditOptions ): PControl;
  53170. begin
  53171. {$IFDEF INPACKAGE}
  53172. Result := NewEditbox( AParent, Options );
  53173. {$ELSE}
  53174. Result := _NewGraphCtl( AParent, TRUE );
  53175. Result.fCommandActions := EditActions;
  53176. Result.fPaintProc := Result.GraphicEditPaint;
  53177. Result.fEditOptions := Options;
  53178. Result.VerticalAlign := vaCenter;
  53179. Result.fColor := clWindow;
  53180. Result.fGraphCtlMouseEvent := Result.GraphicEditMouse;
  53181. Result.fSetFocus := Result.GraphEditBoxSetFocus;
  53182. Result.fLookTabKeys := [ tkTab, tkUpDown, tkPageUpPageDn ];
  53183. Result.fLeave := Result.LeaveGraphEdit;
  53184. {$ENDIF}
  53185. end;
  53186. { TGraphicControl }
  53187. function TControl.DoGraphCtlPrepaint: TRect;
  53188. begin
  53189. Result := ClientRect;
  53190. if not Assigned( OnPrepaint ) and not Transparent then
  53191. begin
  53192. if Assigned( fBrush ) then
  53193. Canvas.Brush.Assign( fBrush )
  53194. else
  53195. Canvas.Brush.Color := Color;
  53196. Canvas.FillRect( Result );
  53197. end;
  53198. end;
  53199. procedure TControl.GraphicLabelPaint(DC: HDC);
  53200. var R: TRect;
  53201. begin
  53202. R := DoGraphCtlPrepaint;
  53203. if Text <> '' then
  53204. DrawFormattedText( @ Self, DC, R, 0 );
  53205. //SaveImg( Canvas, R, 'bm09.bmp' );
  53206. //sv1 := FALSE;
  53207. end;
  53208. procedure TControl.GraphicCheckBoxPaint(DC: HDC);
  53209. var R, R1: TRect;
  53210. Flag: DWORD;
  53211. W, H: Integer;
  53212. {$IFDEF GRAPHCTL_XPSTYLES}
  53213. Theme: THandle;
  53214. {$ENDIF}
  53215. begin
  53216. R := DoGraphCtlPrepaint;
  53217. {
  53218. R := ClientRect;
  53219. if not Assigned( OnPrepaint ) and not Transparent then
  53220. begin
  53221. if Assigned( fBrush ) then
  53222. Canvas.Brush.Assign( fBrush )
  53223. else
  53224. Canvas.Brush.Color := Color;
  53225. Canvas.FillRect( R );
  53226. end;
  53227. }
  53228. {$IFDEF GRAPHCTL_XPSTYLES}
  53229. OpenThemeDataProc;
  53230. Theme := 0;
  53231. if Assigned( fOpenThemeDataProc ) and not DoNotDrawGraphCtlsUsingXPStyles then
  53232. Theme := fOpenThemeDataProc( 0, 'Button' );
  53233. if Theme <> 0 then
  53234. begin
  53235. W := GetSystemMetrics( SM_CXMENUCHECK );
  53236. H := GetSystemMetrics( SM_CYMENUCHECK );
  53237. R1 := R;
  53238. R1.Right := R1.Left + W;
  53239. if fWordWrap then
  53240. R1.Top := R1.Top + Border
  53241. else
  53242. R1.Top := R1.Top + (R1.Bottom - R1.Top - H) div 2;
  53243. R1.Bottom := R1.Top + H;
  53244. Flag := 1; {CBS_UNCHECKEDNORMAL}
  53245. if not Enabled then
  53246. Flag := 4 {CBS_UNCHECKEDDISABLED}
  53247. else
  53248. if fHot then
  53249. Flag := 2; {CBS_UNCHECKEDHOT}
  53250. if fChecked then
  53251. Inc( Flag, 4 );
  53252. fDrawThemeBackground( Theme, DC, 3 {BP_CHECKBOX}, Flag, @R1, @R );
  53253. R.Left := R1.Left + W + Border;
  53254. if fCaption <> '' then
  53255. begin
  53256. DrawFormattedText( @ Self, DC, R, DT_CALCRECT );
  53257. if fWordWrap then
  53258. begin
  53259. DrawFormattedText( @ Self, DC, R, 0 );
  53260. GraphCtlDrawFocusRect( DC, R );
  53261. end
  53262. else
  53263. begin
  53264. GraphCtlDrawFocusRect( DC, R );
  53265. DrawFormattedTextXP( Theme, @ Self, DC, R, 3 {BP_CHECKBOX}, Flag, 0, 0 );
  53266. end;
  53267. end;
  53268. fCloseThemeData( Theme );
  53269. end
  53270. else
  53271. {$ENDIF}
  53272. begin
  53273. W := GetSystemMetrics( SM_CXMENUCHECK );
  53274. H := GetSystemMetrics( SM_CYMENUCHECK );
  53275. R1 := R;
  53276. R1.Right := R1.Left + W;
  53277. if fWordWrap then
  53278. R1.Top := R1.Top + Border
  53279. else
  53280. R1.Top := R1.Top + (R1.Bottom - R1.Top - H) div 2;
  53281. R1.Bottom := R1.Top + H;
  53282. //if not Transparent then
  53283. begin
  53284. Flag := 0;
  53285. if fChecked then
  53286. Flag := DFCS_CHECKED;
  53287. DrawFrameControl( DC, R1, DFC_BUTTON, DFCS_BUTTONCHECK or
  53288. $800 {DFCS_TRANSPARENT} or Flag );
  53289. end;
  53290. R.Left := R1.Left + W + Border;
  53291. DrawFormattedText( @ Self, DC, R, 0 );
  53292. GraphCtlDrawFocusRect( DC, R );
  53293. end;
  53294. end;
  53295. procedure TControl.GraphicCheckBoxMouse(var Msg: TMsg);
  53296. begin
  53297. if (Msg.message = WM_LBUTTONDOWN) or (Msg.message = WM_LBUTTONDBLCLK) then
  53298. ClickGraphCheck( @ Self );
  53299. end;
  53300. procedure TControl.GraphicRadioBoxPaint(DC: HDC);
  53301. var R, R1: TRect;
  53302. Flag: DWORD;
  53303. W, H: Integer;
  53304. {$IFDEF GRAPHCTL_XPSTYLES}
  53305. Theme: THandle;
  53306. {$ENDIF}
  53307. begin
  53308. R := DoGraphCtlPrepaint;
  53309. {R := ClientRect;
  53310. if not Assigned( OnPrepaint ) and not Transparent then
  53311. Canvas.FillRect( R );}
  53312. {$IFDEF GRAPHCTL_XPSTYLES}
  53313. OpenThemeDataProc;
  53314. Theme := 0;
  53315. if Assigned( fOpenThemeDataProc ) and not DoNotDrawGraphCtlsUsingXPStyles then
  53316. Theme := fOpenThemeDataProc( 0, 'Button' );
  53317. if Theme <> 0 then
  53318. begin
  53319. W := GetSystemMetrics( SM_CXMENUCHECK );
  53320. H := GetSystemMetrics( SM_CYMENUCHECK );
  53321. R1 := R;
  53322. R1.Right := R1.Left + W;
  53323. if fWordWrap then
  53324. R1.Top := R1.Top + Border
  53325. else
  53326. R1.Top := R1.Top + (R1.Bottom - R1.Top - H) div 2;
  53327. R1.Bottom := R1.Top + H;
  53328. Flag := 1; {CBS_UNCHECKEDNORMAL}
  53329. if not Enabled then
  53330. Flag := 4 {CBS_UNCHECKEDDISABLED}
  53331. else
  53332. if fHot then
  53333. Flag := 2; {CBS_UNCHECKEDHOT}
  53334. if fChecked then
  53335. Inc( Flag, 4 );
  53336. fDrawThemeBackground( Theme, DC, 2 {BP_RADIOBOX}, Flag, @R1, @R );
  53337. R.Left := R1.Left + W + Border;
  53338. if fCaption <> '' then
  53339. begin
  53340. DrawFormattedText( @ Self, DC, R, DT_CALCRECT );
  53341. if fWordWrap then
  53342. begin
  53343. DrawFormattedText( @ Self, DC, R, 0 );
  53344. GraphCtlDrawFocusRect( DC, R );
  53345. end
  53346. else
  53347. begin
  53348. GraphCtlDrawFocusRect( DC, R );
  53349. DrawFormattedTextXP( Theme, @ Self, DC, R, 2 {BP_RADIOBOX}, Flag, 0, 0 );
  53350. end;
  53351. end;
  53352. fCloseThemeData( Theme );
  53353. end
  53354. else
  53355. {$ENDIF}
  53356. begin
  53357. W := GetSystemMetrics( SM_CXMENUCHECK );
  53358. H := GetSystemMetrics( SM_CYMENUCHECK );
  53359. R1 := R;
  53360. R1.Right := R1.Left + W;
  53361. if fWordWrap then
  53362. R1.Top := R1.Top + Border
  53363. else
  53364. R1.Top := R1.Top + (R1.Bottom - R1.Top - H) div 2;
  53365. R1.Bottom := R1.Top + H;
  53366. //if not Transparent then
  53367. begin
  53368. Flag := 0;
  53369. if fChecked then
  53370. Flag := DFCS_CHECKED;
  53371. DrawFrameControl( DC, R1, DFC_BUTTON, DFCS_BUTTONRADIO
  53372. or $800 {DFCS_TRANSPARENT} {or DFCS_ADJUSTRECT} or Flag );
  53373. end;
  53374. R.Left := R1.Right + 2;
  53375. DrawFormattedText( @ Self, DC, R, 0 );
  53376. GraphCtlDrawFocusRect( DC, R );
  53377. end;
  53378. end;
  53379. procedure TControl.GraphicButtonPaint(DC: HDC);
  53380. var R: TRect;
  53381. Flag: DWORD;
  53382. {$IFDEF GRAPHCTL_XPSTYLES}
  53383. Flag1: DWORD;
  53384. Theme: THandle;
  53385. {$ENDIF}
  53386. II: TIconInfo;
  53387. BI: TagBitmap;
  53388. Y: Integer;
  53389. R1: TRect;
  53390. begin
  53391. R := DoGraphCtlPrepaint;
  53392. {$IFDEF GRAPHCTL_XPSTYLES}
  53393. OpenThemeDataProc;
  53394. Theme := 0;
  53395. if Assigned( fOpenThemeDataProc ) and not DoNotDrawGraphCtlsUsingXPStyles then
  53396. Theme := fOpenThemeDataProc( 0, 'Button' );
  53397. if Theme <> 0 then
  53398. begin
  53399. Flag := 1; {PBS_UNCHECKEDNORMAL}
  53400. if not Enabled then
  53401. Flag := 4 {PBS_UNCHECKEDDISABLED}
  53402. else
  53403. if fPushed then
  53404. Flag := 3 {PBS_UNCHECKEDPRESSED}
  53405. else
  53406. if fHot then
  53407. Flag := 2; {PBS_UNCHECKEDHOT}
  53408. if fChecked then
  53409. Inc( Flag, 4 );
  53410. fDrawThemeBackground( Theme, DC, 1 {BP_PUSHBUTTON}, Flag, @R, @R );
  53411. fGetThemeBackgroundContentRect( Theme, DC, 1 {BS_PUSHBUTTON}, Flag, @R, @R1 );
  53412. GraphCtlDrawFocusRect( DC, R1 );
  53413. if (fButtonIcon <> 0) and GetIconInfo( fButtonIcon, II ) then
  53414. begin
  53415. if GetObject( II.hbmColor, Sizeof( BI ), @ BI ) <> 0 then
  53416. begin
  53417. CASE fVerticalAlign OF
  53418. vaTop:
  53419. Y := R.Top + Border;
  53420. vaBottom:
  53421. Y := R.Bottom - Border - BI.bmHeight;
  53422. else //vaCenter:
  53423. Y := R.Top + (R.Bottom - R.Top - BI.bmHeight) div 2;
  53424. END;
  53425. DrawIcon( DC, R.Left + Border, Y, fButtonIcon );
  53426. Inc( R1.Left, BI.bmWidth + Border * 2 );
  53427. end;
  53428. DeleteObject( II.hbmColor );
  53429. if II.hbmMask <> 0 then
  53430. DeleteObject( II.hbmMask );
  53431. end;
  53432. if fCaption <> '' then
  53433. begin
  53434. Flag1 := DT_SINGLELINE;
  53435. if WordWrap then
  53436. Flag1 := DT_WORDBREAK;
  53437. DrawFormattedText( @ Self, DC, R1, DT_CALCRECT );
  53438. DrawFormattedTextXP( Theme, @ Self, DC, R1, 1 {BP_PUSHBUTTON}, Flag,
  53439. Flag1, 0 );
  53440. end;
  53441. fCloseThemeData( Theme );
  53442. end
  53443. else
  53444. {$ENDIF}
  53445. begin
  53446. Flag := 0;
  53447. if fChecked then
  53448. Flag := DFCS_CHECKED
  53449. else
  53450. if fPushed then
  53451. Flag := DFCS_PUSHED;
  53452. if fFlat then
  53453. Flag := Flag or DFCS_FLAT;
  53454. DrawFrameControl( DC, R, DFC_BUTTON, DFCS_BUTTONPUSH or
  53455. $800 {DFCS_TRANSPARENT} or DFCS_ADJUSTRECT or Flag );
  53456. //{$IFNDEF GRAPHCTL_XPSTYLES}
  53457. R1 := R;
  53458. //{$ENDIF}
  53459. if (fButtonIcon <> 0) and GetIconInfo( fButtonIcon, II ) then
  53460. begin
  53461. if GetObject( II.hbmColor, Sizeof( BI ), @ BI ) <> 0 then
  53462. begin
  53463. CASE fVerticalAlign OF
  53464. vaTop:
  53465. Y := R.Top + Border;
  53466. vaBottom:
  53467. Y := R.Bottom - Border - BI.bmHeight;
  53468. else //vaCenter:
  53469. Y := R.Top + (R.Bottom - R.Top - BI.bmHeight) div 2;
  53470. END;
  53471. DrawIcon( DC, R.Left + Border, Y, fButtonIcon );
  53472. Inc( R1.Left, BI.bmWidth + Border * 2 );
  53473. end;
  53474. DeleteObject( II.hbmColor );
  53475. if II.hbmMask <> 0 then
  53476. DeleteObject( II.hbmMask );
  53477. end;
  53478. DrawFormattedText( @ Self, DC, R1, 0 );
  53479. GraphCtlDrawFocusRect( DC, R );
  53480. end;
  53481. end;
  53482. procedure TControl.GraphicButtonMouse(var Msg: TMsg);
  53483. var Pt: TPoint;
  53484. begin
  53485. CASE Msg.message OF
  53486. WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
  53487. begin
  53488. GraphButtonSetFocus;
  53489. RefInc;
  53490. SetCapture( Parent.Handle );
  53491. Parent.fPushedBtn := @ Self;
  53492. fPushed := TRUE;
  53493. Invalidate;
  53494. end;
  53495. WM_LBUTTONUP:
  53496. begin
  53497. ReleaseCapture;
  53498. Invalidate;
  53499. if fPushed then
  53500. begin
  53501. Pt.X := SmallInt( LoWord( Msg.lParam ) );
  53502. Pt.Y := SmallInt( HiWord( Msg.lParam ) );
  53503. if PtInRect( ClientRect, Pt ) then
  53504. DoClick;
  53505. fPushed := FALSE;
  53506. Parent.fPushedBtn := nil;
  53507. RefDec;
  53508. end;
  53509. end;
  53510. END;
  53511. end;
  53512. procedure TControl.GraphButtonSetFocus;
  53513. var PF: PControl;
  53514. CC: PControl;
  53515. W: HWnd;
  53516. begin
  53517. if not fTabStop then Exit;
  53518. PF := ParentForm;
  53519. if (PF.fCurrentControl <> nil) and (PF.fCurrentControl <> @ Self) and
  53520. (PF.fCurrentControl <> Parent) then
  53521. begin
  53522. CC := PF.fCurrentControl;
  53523. CC.RefInc;
  53524. Parent.Focused := TRUE;
  53525. if Assigned( CC.fLeave ) then
  53526. CC.fLeave( PF.fCurrentControl )
  53527. else
  53528. Windows.SetFocus( 0 );
  53529. CC.RefDec;
  53530. end
  53531. else
  53532. begin
  53533. W := GetFocus;
  53534. if (W <> Parent.fHandle) and (W <> 0) then
  53535. begin
  53536. Windows.SetFocus( 0 );
  53537. Parent.Focused := TRUE;
  53538. end;
  53539. end;
  53540. if Parent.fHandle <> 0 then
  53541. begin
  53542. fFocused := TRUE;
  53543. Parent.Postmsg( CM_FOCUSGRAPHCTL, Integer( @ Self ), 0 );
  53544. RefInc;
  53545. end;
  53546. if Assigned( fOnEnter ) then
  53547. fOnEnter( @ Self );
  53548. end;
  53549. procedure TControl.LeaveGraphButton( Sender: PObj );
  53550. begin
  53551. fFocused := FALSE;
  53552. if Parent.fCurrentControl = @ Self then
  53553. Parent.fCurrentControl := nil;
  53554. if ParentForm.fCurrentControl = @ Self then
  53555. ParentForm.fCurrentControl := nil;
  53556. Invalidate;
  53557. if Assigned( fOnLeave ) then
  53558. fOnLeave( @ Self );
  53559. end;
  53560. function TControl.GraphButtonKeyboardProcess(var Msg: TMsg;
  53561. var Rslt: Integer): Boolean;
  53562. var SpacePressed: Boolean;
  53563. begin
  53564. Result := FALSE;
  53565. SpacePressed := Msg.wParam = Word( ' ' );
  53566. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  53567. SpacePressed := SpacePressed or (Msg.wParam = 13);
  53568. {$ENDIF}
  53569. if not SpacePressed then Exit;
  53570. if (Msg.message = WM_KEYDOWN) or (Msg.message = WM_SYSKEYDOWN) then
  53571. begin
  53572. Parent.fPushedBtn := @ Self;
  53573. fPushed := TRUE;
  53574. Invalidate;
  53575. Result := TRUE; /////
  53576. end
  53577. else
  53578. if (Msg.message = WM_KEYUP) or (Msg.message = WM_SYSKEYUP) then
  53579. begin
  53580. fPushed := FALSE;
  53581. Parent.fPushedBtn := nil;
  53582. Invalidate;
  53583. Result := TRUE; /////
  53584. end
  53585. else
  53586. if (Msg.message = WM_CHAR) or (Msg.message = WM_SYSCHAR) then
  53587. begin
  53588. DoClick;
  53589. Result := TRUE;
  53590. end;
  53591. end;
  53592. procedure TControl.GraphicEditPaint(DC: HDC);
  53593. var R: TRect;
  53594. {$IFDEF GRAPHCTL_XPSTYLES}
  53595. R1: TRect;
  53596. Flag, Flag1: DWORD;
  53597. Theme: THandle;
  53598. {$ENDIF}
  53599. begin
  53600. R := ClientRect;
  53601. {$IFDEF GRAPHCTL_XPSTYLES}
  53602. OpenThemeDataProc;
  53603. Theme := 0;
  53604. if Assigned( fOpenThemeDataProc ) and not DoNotDrawGraphCtlsUsingXPStyles then
  53605. Theme := fOpenThemeDataProc( 0, 'Edit' );
  53606. if Theme <> 0 then
  53607. begin
  53608. Flag := 1; {ETS_NORMAL}
  53609. if not Enabled then
  53610. Flag := 4 {ETS_DISABLED}
  53611. else
  53612. if eoReadonly in fEditOptions then
  53613. Flag := 6 {ETS_READONLY}
  53614. else
  53615. if fFocused then
  53616. Flag := 5 {ETS_FOCUSED}
  53617. else
  53618. if fHot then
  53619. Flag := 2; {ETS_HOT}
  53620. fDrawThemeBackground( Theme, DC, 1 {EP_EDITTEXT}, Flag, @R, @R );
  53621. Inc( R.Left, 2 );
  53622. Dec( R.Right, 2 );
  53623. fGetThemeBackgroundContentRect( Theme, DC, 1 {EP_EDITTEXT}, Flag, @R, @R1 );
  53624. if fCaption <> '' then
  53625. begin
  53626. Flag1 := DT_SINGLELINE;
  53627. if eoMultiline in fEditOptions then
  53628. Flag1 := DT_WORDBREAK;
  53629. CASE fTextAlign OF
  53630. taCenter: Flag1 := Flag1 or DT_CENTER;
  53631. taRight: Flag1 := Flag1 or DT_RIGHT;
  53632. //else Flag1 := Flag1 or DT_LEFT;
  53633. END;
  53634. CASE fVerticalAlign OF
  53635. vaCenter: Flag1 := Flag1 or DT_VCENTER;
  53636. vaBottom: Flag1 := Flag1 or DT_BOTTOM;
  53637. //else Flag1 := Flag1 or DT_TOP;
  53638. END;
  53639. DrawFormattedTextXP( Theme, @ Self, DC, R1, 1 {EP_EDITTEXT}, Flag,
  53640. Flag1, 0 );
  53641. end;
  53642. fCloseThemeData( Theme );
  53643. end
  53644. else
  53645. {$ENDIF}
  53646. begin
  53647. if not Assigned( OnPrepaint ) and not Transparent then
  53648. begin
  53649. Canvas.Brush.Color := fColor;
  53650. Canvas.FillRect( R );
  53651. end;
  53652. DrawEdge( DC, R, BDR_SUNKENINNER or BDR_SUNKENOUTER, BF_ADJUST or BF_RECT );
  53653. DrawFormattedText( @ Self, DC, R, DT_EDITCONTROL );
  53654. end;
  53655. end;
  53656. procedure TControl.GraphicEditMouse(var Msg: TMsg);
  53657. var E: PControl;
  53658. Pt: TPoint;
  53659. begin
  53660. CASE Msg.message OF
  53661. WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
  53662. if not ( eoReadOnly in fEditOptions ) then
  53663. begin
  53664. E := EditGraphEdit;
  53665. Pt.X := Smallint( LoWord( Msg.lParam ) ) - Left;
  53666. Pt.Y := Smallint( HiWord( Msg.lParam ) ) - Top;
  53667. PostMessage( E.Handle, Msg.message, Msg.wParam,
  53668. Pt.Y shl 16 or Pt.X and $FFFF );
  53669. end;
  53670. END;
  53671. end;
  53672. function TControl.EditGraphEdit: PControl;
  53673. var E: PControl;
  53674. begin
  53675. E := NewEditBox( Parent, fEditOptions )
  53676. .SetPosition( Left, Top )
  53677. .SetSize( Width, Height )
  53678. .SetAlign( Align );
  53679. E.fTabOrder := fTabOrder;
  53680. E.Text := Text;
  53681. E.OnChange := ChangeGraphEdit;
  53682. E.Color := Color;
  53683. E.fCursor := fCursor;
  53684. E.CreateWindow;
  53685. E.OnLeave := LeaveGraphEdit;
  53686. E.fLeave := LeaveGraphEdit;
  53687. E.Focused := TRUE;
  53688. E.OnChar := OnChar;
  53689. E.OnKeyDown := OnKeyDown;
  53690. E.OnKeyUp := OnKeyUp;
  53691. E.OnDestroy := DestroyGraphEdit;
  53692. //E.Font.Assign( Font );
  53693. Result := E;
  53694. Visible := FALSE;
  53695. fEditCtl := E;
  53696. if Assigned( fOnEnter ) then
  53697. fOnEnter( @ Self );
  53698. end;
  53699. procedure TControl.LeaveGraphEdit(Sender: PObj);
  53700. begin
  53701. if PControl( Sender ).fWindowed and Assigned( fEditCtl ) then
  53702. begin
  53703. Text := PControl( Sender ).Text;
  53704. fEditCtl := nil;
  53705. Visible := TRUE;
  53706. ParentForm.fCurrentControl := @ Self;
  53707. Parent.fCurrentControl := @ Self;
  53708. Parent.Postmsg( CM_QUIT, DWORD( Sender ), 0 );
  53709. end
  53710. else
  53711. if Assigned( fEditCtl ) then
  53712. begin
  53713. fEditCtl.fLeave( fEditCtl );
  53714. end;
  53715. end;
  53716. procedure TControl.ChangeGraphEdit(Sender: PObj);
  53717. begin
  53718. Text := PControl( Sender ).Text;
  53719. end;
  53720. procedure TControl.GraphEditboxSetFocus;
  53721. begin
  53722. EditGraphEdit;
  53723. end;
  53724. procedure TControl.DestroyGraphEdit(Sender: PObj);
  53725. begin
  53726. fEditCtl := nil;
  53727. end;
  53728. procedure TControl.GraphCtlDrawFocusRect(DC: HDC; const R: TRect);
  53729. var rgn: HRgn;
  53730. begin
  53731. if fFocused and (GetActiveWindow = ParentForm.Handle) then
  53732. begin
  53733. BeginPath( DC );
  53734. Canvas.FrameRect( R );
  53735. EndPath( DC );
  53736. Canvas.FrameRect( R );
  53737. DrawFocusRect( DC, R );
  53738. rgn := PathToRegion( DC );
  53739. ExtSelectClipRgn( DC, rgn, RGN_DIFF );
  53740. DeleteObject( rgn );
  53741. end;
  53742. end;
  53743. procedure TControl.GroupBoxPaint(DC: HDC);
  53744. var bk_erased: Boolean;
  53745. procedure DoEraseBkgnd;
  53746. var R: TRect;
  53747. begin
  53748. bk_erased := TRUE;
  53749. if Assigned( OnEraseBkgnd ) then
  53750. OnEraseBkgnd( @ Self, DC )
  53751. else
  53752. begin
  53753. R := BoundsRect;
  53754. OffsetRect( R, -R.Left, -R.Top );
  53755. SetBkMode( DC, OPAQUE );
  53756. SetBkColor( DC, Color2RGB( fColor ) );
  53757. SetBrushOrgEx( DC, 0, 0, nil );
  53758. Windows.FillRect( DC, R, Global_GetCtlBrushHandle( @ Self ) );
  53759. end;
  53760. end;
  53761. var R, R1, R0: TRect;
  53762. rgn, rgn2, rgntxt, rgnsav, rgnsavall: HRgn;
  53763. i: Integer;
  53764. C: PControl;
  53765. {$IFDEF GRAPHCTL_XPSTYLES}
  53766. Theme: THandle;
  53767. Flag: DWORD;
  53768. {$ENDIF}
  53769. begin
  53770. if not fErasingBkgnd then
  53771. Exit;
  53772. R := ClientRect;
  53773. Dec( R.Top, 14 { Self_.fClientTop div 2 } );
  53774. Dec( R.Left, fClientLeft );
  53775. Inc( R.Right, fClientRight );
  53776. Inc( R.Bottom, fClientBottom );
  53777. rgnsavall := CreateRectRgn( 0, 0, 0, 0 );
  53778. GetClipRgn( DC, rgnsavall );
  53779. TRY
  53780. for i := 0 to ChildCount-1 do
  53781. begin
  53782. C := Children[ i ];
  53783. if not C.fWindowed and C.fVisible then
  53784. begin
  53785. rgn := CreateRectRgnIndirect( C.BoundsRect );
  53786. ExtSelectClipRgn( DC, rgn, RGN_DIFF );
  53787. DeleteObject( rgn );
  53788. end;
  53789. end;
  53790. {$IFDEF GRAPHCTL_XPSTYLES}
  53791. OpenThemeDataProc;
  53792. Theme := 0;
  53793. if Assigned( fOpenThemeDataProc ) and not DoNotDrawGraphCtlsUsingXPStyles then
  53794. Theme := fOpenThemeDataProc( 0, 'Button' );
  53795. if Theme <> 0 then
  53796. begin
  53797. DoEraseBkgnd;
  53798. Flag := 1; {GBS_NORMAL}
  53799. if not Enabled then
  53800. Flag := 2; {GBS_DISABLED}
  53801. R1 := R;
  53802. rgnsav := 0;
  53803. if fCaption <> '' then
  53804. begin
  53805. R1.Top := 0;
  53806. Inc( R1.Left, 8 );
  53807. Dec( R1.Right, 8 );
  53808. BeginPath( DC );
  53809. DrawFormattedTextXP( Theme, @ Self, DC, R1, 4 {BP_GROUPBOX}, Flag, 0, 0 );
  53810. EndPath( DC );
  53811. rgntxt := PathToRegion( DC );
  53812. if rgntxt = 0 then
  53813. begin
  53814. R1.Right := R1.Left + Canvas.TextWidth( fCaption );
  53815. R1.Bottom := R1.Top + Canvas.TextHeight( fCaption );
  53816. rgntxt := CreateRectRgnIndirect( R1 );
  53817. end;
  53818. DrawFormattedTextXP( Theme, @ Self, DC, R1, 4 {BP_GROUPBOX}, Flag, 0, 0 );
  53819. GetRgnBox( rgntxt, R0 );
  53820. Dec( R0.Left, 3 );
  53821. Inc( R0.Right, 3 );
  53822. DeleteObject( rgntxt );
  53823. rgn := CreateRectRgnIndirect( R0 );
  53824. end
  53825. else
  53826. begin
  53827. rgn := 0;
  53828. end;
  53829. if rgn <> 0 then
  53830. begin
  53831. rgnsav := CreateRectRgn( 0, 0, 0, 0 );
  53832. GetClipRgn( DC, rgnsav );
  53833. ExtSelectClipRgn( DC, rgn, RGN_DIFF );
  53834. DeleteObject( rgn );
  53835. end;
  53836. fDrawThemeBackground( Theme, DC, 4 {BP_GROUPBOX}, Flag, @R, @R );
  53837. if rgnsav <> 0 then
  53838. begin
  53839. SelectClipRgn( DC, rgnsav );
  53840. DeleteObject( rgnsav );
  53841. end;
  53842. fCloseThemeData( Theme );
  53843. end
  53844. else
  53845. {$ENDIF}
  53846. begin
  53847. bk_erased := FALSE;
  53848. R1 := R;
  53849. R1.Top := 0;
  53850. R1.Bottom := ClientRect.Top;
  53851. Inc( R1.Left, 16 );
  53852. Dec( R1.Right, 16 );
  53853. fVerticalAlign := vaCenter;
  53854. BeginPath( DC );
  53855. Canvas.TextOut( R1.Left, R1.Top, fCaption );
  53856. EndPath( DC );
  53857. Canvas.TextOut( R1.Left, R1.Top, fCaption );
  53858. rgntxt := PathToRegion( DC );
  53859. if rgntxt = 0 then // òàêîå - â ñëó÷àå øðèôòà ïî óìîë÷àíè³!
  53860. begin
  53861. R1.Right := R1.Left + Canvas.TextWidth( fCaption );
  53862. R1.Bottom := R1.Top + Canvas.TextHeight( fCaption );
  53863. rgntxt := CreateRectRgnIndirect( R1 );
  53864. end;
  53865. GetRgnBox( rgntxt, R0 );
  53866. rgn2 := CreateRectRgnIndirect( R0 );
  53867. rgnsav := CreateRectRgn( 0, 0, 0, 0 );
  53868. GetClipRgn( DC, rgnsav );
  53869. ExtSelectClipRgn( DC, rgn2, RGN_DIFF );
  53870. DeleteObject( rgn2 );
  53871. BeginPath( DC );
  53872. DrawEdge( DC, R, BDR_RAISEDINNER or BDR_SUNKENOUTER, BF_RECT );
  53873. EndPath( DC );
  53874. rgn := PathToRegion( DC );
  53875. if rgn = 0 then DoEraseBkgnd;
  53876. DrawEdge( DC, R, BDR_RAISEDINNER or BDR_SUNKENOUTER, BF_RECT );
  53877. SelectClipRgn( DC, rgnsav );
  53878. DeleteObject( rgnsav );
  53879. if rgn <> 0 then
  53880. begin
  53881. ExtSelectClipRgn( DC, rgn, RGN_DIFF );
  53882. DeleteObject( rgn );
  53883. end;
  53884. ExtSelectClipRgn( DC, rgntxt, RGN_DIFF );
  53885. DeleteObject( rgntxt );
  53886. if not bk_erased then DoEraseBkgnd;
  53887. end;
  53888. FINALLY
  53889. SelectClipRgn( DC, rgnsavall );
  53890. DeleteObject( rgnsavall );
  53891. END;
  53892. end;
  53893. {$ENDIF USE_GRAPHCTLS}
  53894. function TControl.MakeWordWrap: PControl;
  53895. begin
  53896. fWordWrap := TRUE;
  53897. Style := (fStyle and not SS_LEFTNOWORDWRAP) or BS_MULTILINE;
  53898. Result := @ Self;
  53899. end;
  53900. function ParentAnchorChildren( Sender: PControl; var Msg: TMsg;
  53901. var Rslt: Integer ): Boolean;
  53902. var NewW, NewH: Integer;
  53903. dW, dH: Integer;
  53904. i: Integer;
  53905. C: PControl;
  53906. {$IFNDEF ANCHORS_WM_SIZE}
  53907. CR: TRect;
  53908. {$ENDIF}
  53909. begin
  53910. Result := FALSE;
  53911. if (Msg.message = {$IFDEF ANCHORS_WM_SIZE} WM_SIZE {$ELSE} WM_WINDOWPOSCHANGED {$ENDIF} )
  53912. {$ifndef wince} and not IsIconic(Sender.Handle) {$endif} then
  53913. begin
  53914. {$IFDEF ANCHORS_WM_SIZE}
  53915. NewW := LoWord( Msg.lParam ) - Sender.fClientLeft - Sender.fClientRight;
  53916. NewH := HiWord( Msg.lParam ) - Sender.fClientTop - Sender.fClientBottom;
  53917. {$ELSE}
  53918. CR := Sender.ClientRect;
  53919. NewW := CR.Right;
  53920. NewH := CR.Bottom;
  53921. {$ENDIF}
  53922. dW := NewW - Sender.fOldWidth;
  53923. dH := NewH - Sender.fOldHeight;
  53924. for i := 0 to Sender.ChildCount - 1 do
  53925. begin
  53926. C := Sender.Children[ i ];
  53927. if dW <> 0 then
  53928. begin
  53929. if C.AnchorRight and C.AnchorLeft then
  53930. C.Width := C.Width + dW
  53931. else if C.AnchorRight then
  53932. C.Left := C.Left + dW;
  53933. end;
  53934. if dH <> 0 then
  53935. begin
  53936. if C.AnchorBottom and C.AnchorTop then
  53937. C.Height := C.Height + dH
  53938. else if C.AnchorBottom then
  53939. C.Top := C.Top + dH;
  53940. end;
  53941. end;
  53942. Sender.fOldWidth := NewW;
  53943. Sender.fOldHeight := NewH;
  53944. end;
  53945. end;
  53946. function TControl.Anchor(aLeft, aTop, aRight, aBottom: Boolean): PControl;
  53947. begin
  53948. if (not aLeft) and aRight then
  53949. SetAnchorLeft( FALSE )
  53950. else
  53951. SetAnchorLeft( aLeft );
  53952. if (not aTop) and aBottom then
  53953. SetAnchorTop( FALSE )
  53954. else
  53955. SetAnchorTop( aTop );
  53956. SetAnchorRight( aRight );
  53957. SetAnchorBottom( aBottom );
  53958. Result := @ Self;
  53959. end;
  53960. procedure TControl.SetAnchorLeft(const Value: Boolean);
  53961. begin
  53962. fAnchorLeft := Value;
  53963. if Parent <> nil then
  53964. begin
  53965. fParent.AttachProc( ParentAnchorChildren );
  53966. Parent.fOldWidth := Parent.ClientWidth;
  53967. end;
  53968. end;
  53969. procedure TControl.SetAnchorTop(const Value: Boolean);
  53970. begin
  53971. fAnchorTop := Value;
  53972. if Parent <> nil then
  53973. begin
  53974. fParent.AttachProc( ParentAnchorChildren );
  53975. fParent.fOldHeight := Parent.ClientHeight;
  53976. end;
  53977. end;
  53978. procedure TControl.SetAnchorBottom(Value: Boolean);
  53979. begin
  53980. fAnchorBottom := Value;
  53981. if Parent <> nil then
  53982. begin
  53983. fParent.AttachProc( ParentAnchorChildren );
  53984. fParent.fOldHeight := Parent.ClientHeight;
  53985. end;
  53986. end;
  53987. procedure TControl.SetAnchorRight(Value: Boolean);
  53988. begin
  53989. fAnchorRight := Value;
  53990. if Parent <> nil then
  53991. begin
  53992. Parent.AttachProc( ParentAnchorChildren );
  53993. Parent.fOldWidth := Parent.ClientWidth;
  53994. end;
  53995. end;
  53996. function TControl.GetLBTopIndex: Integer;
  53997. begin
  53998. Result := Perform(LB_GETTOPINDEX,0,0);
  53999. end;
  54000. function TControl.LBItemAtPos(X, Y: Integer): Integer;
  54001. var
  54002. R: TRect;
  54003. P: TPoint;
  54004. i: Integer;
  54005. begin
  54006. P := MakePoint(X,Y);
  54007. for i := LBTopIndex to Count -1 do begin
  54008. Perform(LB_GETITEMRECT, i , Integer(@R));
  54009. if PointInRect(P,R) then begin
  54010. Result := i;
  54011. Exit;
  54012. end;
  54013. end;
  54014. Result := -1;
  54015. end;
  54016. procedure TControl.SetLBTopIndex(const Value: Integer);
  54017. begin
  54018. Perform(LB_SETTOPINDEX,Value,0);
  54019. end;
  54020. //--------
  54021. procedure ScrollToChild(C, SB: PControl);
  54022. function DoScroll(msg, bar, d1, d2, client: integer): boolean;
  54023. var
  54024. i: integer;
  54025. begin
  54026. i:=GetScrollPos(SB.Handle, bar);
  54027. if d1 < SB.Border then
  54028. Dec(i, SB.Border - d1)
  54029. else
  54030. if d2 > client - SB.Border then
  54031. Inc(i, d2 - client + SB.Border)
  54032. else begin
  54033. Result:=False;
  54034. exit;
  54035. end;
  54036. SetScrollPos(SB.Handle, bar, i, True);
  54037. Result:=True;
  54038. end;
  54039. var
  54040. R: TRect;
  54041. begin
  54042. if C = nil then exit;
  54043. R:=C.BoundsRect;
  54044. R.TopLeft:=SB.Screen2Client(C.Parent.Client2Screen(R.TopLeft));
  54045. R.BottomRight:=SB.Screen2Client(C.Parent.Client2Screen(R.BottomRight));
  54046. if DoScroll(WM_VSCROLL, SB_VERT, R.Top, R.Bottom, SB.ClientHeight) or
  54047. DoScroll(WM_HSCROLL, SB_HORZ, R.Left, R.Right, SB.ClientWidth)
  54048. then
  54049. ScrollChildren(SB);
  54050. end;
  54051. function WndProcScrollable( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  54052. procedure ProcessScroll;
  54053. begin
  54054. NotifyScrollBox(Sender, nil);
  54055. ScrollToChild(Sender.ParentForm.ActiveControl, Sender);
  54056. end;
  54057. begin
  54058. Result:=False;
  54059. case Msg.message of
  54060. WM_SIZE:
  54061. PostMessage(Sender.fHandle, CM_SHOW, 0, 0);
  54062. WM_SHOWWINDOW:
  54063. if WordBool(Msg.wParam) then
  54064. PostMessage(Sender.fHandle, CM_SHOW, 0, 0);
  54065. CM_SHOW:
  54066. begin
  54067. ProcessScroll;
  54068. Result:=True;
  54069. end;
  54070. end;
  54071. end;
  54072. function WndProcScrollToChild( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  54073. var
  54074. P: PControl;
  54075. begin
  54076. Result:=False;
  54077. if Msg.message = WM_SETFOCUS then begin
  54078. P:=Sender.Parent;
  54079. while (P <> nil) and not Assigned(P.fScrollChildren) do
  54080. P:=P.Parent;
  54081. if P <> nil then
  54082. ScrollToChild(Sender, P);
  54083. end;
  54084. end;
  54085. procedure NotifyScroller( Self_, Child: PControl );
  54086. begin
  54087. if Assigned(Child) then begin
  54088. Child.AttachProc(@WndProcScrollToChild);
  54089. if not Assigned(Child.fNotifyChild) then
  54090. Child.fNotifyChild:=@NotifyScroller;
  54091. end;
  54092. end;
  54093. procedure TControl.MakeScrollable;
  54094. procedure AttachProcToChildren(P: PControl);
  54095. var
  54096. i: integer;
  54097. C: PControl;
  54098. begin
  54099. for i:=0 to P.ChildCount - 1 do begin
  54100. C:=P.Children[i];
  54101. NotifyScroller(P, C);
  54102. AttachProcToChildren(C);
  54103. end;
  54104. end;
  54105. begin
  54106. if not IsProcAttached( WndProcScrollBox ) then begin
  54107. fDynHandlers.Insert(0, nil);
  54108. fDynHandlers.Insert(0, @WndProcScrollBox);
  54109. end;
  54110. AttachProc( WndProcScrollable );
  54111. fScrollChildren := ScrollChildren;
  54112. FScrollLineDist[ 0 ] := 16;
  54113. FScrollLineDist[ 1 ] := 16;
  54114. fNotifyChild:=@NotifyScroller;
  54115. AttachProcToChildren(@Self);
  54116. end;
  54117. {$ENDIF WIN_GDI}
  54118. procedure TControl.DisableAlign;
  54119. begin
  54120. Include(fAligning, oaAligning);
  54121. end;
  54122. procedure TControl.EnableAlign;
  54123. begin
  54124. fAligning:=[];
  54125. Global_Align(@Self);
  54126. end;
  54127. {$IFNDEF PAS_VERSION}
  54128. // {$DEFINE ASM_VERSION}
  54129. // {$DEFINE ASM_UNICODE}
  54130. {$I KOL_ASM.inc} {$ENDIF ASM_VERSION}
  54131. {$IFDEF LIN}
  54132. {$DEFINE implementation} {$I KOL_Linux.inc} {$UNDEF implementation}
  54133. {$ENDIF LIN}
  54134. { -- }
  54135. {$IFDEF USE_CUSTOMEXTENSIONS}
  54136. {$I CUSTOM_CODE_EXTENSION.inc} // See comments in TControl
  54137. {$ENDIF USE_CUSTOMEXTENSIONS}
  54138. //[initialization]
  54139. {$IFNDEF NOT_UNLOAD_RICHEDITLIB}
  54140. {$IFDEF UNLOAD_RICHEDITLIB}
  54141. {$DEFINE INIT_FINIT}
  54142. {$ENDIF}
  54143. {$ENDIF}
  54144. {$IFDEF USE_NAMES}
  54145. {$DEFINE INIT_FINIT}
  54146. {$ENDIF}
  54147. {$IFDEF GRAPHCTL_XPSTYLES}
  54148. {$DEFINE INIT_FINIT}
  54149. {$ENDIF}
  54150. {$IFDEF KOL_MMX}
  54151. {$DEFINE INIT_FINIT}
  54152. {$ENDIF}
  54153. {$IFDEF INIT_FINIT}
  54154. initialization
  54155. {$IFDEF GRAPHCTL_XPSTYLES}
  54156. CheckThemes;
  54157. if AppTheming then
  54158. InitThemes;
  54159. {$ENDIF}
  54160. //[finalization]
  54161. finalization
  54162. {$IFDEF GRAPHCTL_XPSTYLES}
  54163. if AppTheming then
  54164. DeinitThemes;
  54165. {$ENDIF}
  54166. {$IFNDEF NOT_UNLOAD_RICHEDITLIB}
  54167. {$IFDEF UNLOAD_RICHEDITLIB}
  54168. if FRichEditModule <> 0 then
  54169. FreeLibrary( FRichEditModule );
  54170. {$ENDIF UNLOAD_RICHEDITLIB}
  54171. {$ENDIF}
  54172. {$ENDIF INIT_FINIT}
  54173. //[END OF KOL.pas]
  54174. end.