Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530/* * PROJECT: ReactOS msutb.dll * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: Language Bar (Tipbar) * COPYRIGHT: Copyright 2023-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> */
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(msutb);
//#define ENABLE_DESKBAND
typedef struct LANGBARITEMSTATE{ CLSID m_clsid; DWORD m_dwDemoteLevel; UINT_PTR m_nTimerID; UINT m_uTimeOut; BOOL m_bStartedIntentionally; BOOL m_bDisableDemoting;
BOOL IsShown() { return m_dwDemoteLevel < 2; }} LANGBARITEMSTATE, *PLANGBARITEMSTATE;
HINSTANCE g_hInst = NULL;UINT g_wmTaskbarCreated = 0;UINT g_uACP = CP_ACP;DWORD g_dwOSInfo = 0;CRITICAL_SECTION g_cs;LONG g_DllRefCount = 0;BOOL g_bWinLogon = FALSE;BOOL g_fInClosePopupTipbar = FALSE;HWND g_hwndParent = NULL;CIC_LIBTHREAD g_libTLS = { NULL, NULL };#ifdef ENABLE_DESKBANDBOOL g_bEnableDeskBand = TRUE;#elseBOOL g_bEnableDeskBand = FALSE;#endif
BOOL g_bShowTipbar = TRUE;BOOL g_bShowDebugMenu = FALSE;BOOL g_bNewLook = TRUE;BOOL g_bIntelliSense = FALSE;BOOL g_bShowCloseMenu = FALSE;UINT g_uTimeOutNonIntentional = 60 * 1000;UINT g_uTimeOutIntentional = 10 * 60 * 1000;UINT g_uTimeOutMax = 60 * 60 * 1000;BOOL g_bShowMinimizedBalloon = TRUE;POINT g_ptTipbar = { -1, -1 };BOOL g_bExcludeCaptionButtons = TRUE;BOOL g_bShowShadow = FALSE;BOOL g_fTaskbarTheme = TRUE;BOOL g_fVertical = FALSE;UINT g_uTimerElapseSTUBSTART = 100;UINT g_uTimerElapseSTUBEND = 2 * 1000;UINT g_uTimerElapseBACKTOALPHA = 3 * 1000;UINT g_uTimerElapseONTHREADITEMCHANGE = 200;UINT g_uTimerElapseSETWINDOWPOS = 100;UINT g_uTimerElapseONUPDATECALLED = 50;UINT g_uTimerElapseSYSCOLORCHANGED = 20;UINT g_uTimerElapseDISPLAYCHANGE = 20;UINT g_uTimerElapseUPDATEUI = 70;UINT g_uTimerElapseSHOWWINDOW = 50;UINT g_uTimerElapseMOVETOTRAY = 50;UINT g_uTimerElapseTRAYWNDONDELAYMSG = 50;UINT g_uTimerElapseDOACCDEFAULTACTION = 200;UINT g_uTimerElapseENSUREFOCUS = 50;BOOL g_bShowDeskBand = FALSE;UINT g_uTimerElapseSHOWDESKBAND = 3 * 1000;BOOL g_fPolicyDisableCloseButton = FALSE;BOOL g_fPolicyEnableLanguagebarInFullscreen = FALSE;DWORD g_dwWndStyle = 0;DWORD g_dwMenuStyle = 0;DWORD g_dwChildWndStyle = 0;BOOL g_fRTL = FALSE;
#define TIMER_ID_DOACCDEFAULTACTION 11
class CMsUtbModule : public CComModule{};
CMsUtbModule gModule;
class CCicLibMenuItem;class CTipbarAccItem;class CUTBMenuItem;class CMainIconItem;class CTrayIconItem;class CTipbarWnd;class CButtonIconItem;class CTrayIconWnd;
CTipbarWnd *g_pTipbarWnd = NULL;CTrayIconWnd *g_pTrayIconWnd = NULL;
CicArray<HKL> *g_prghklSkipRedrawing = NULL;
BOOL IsSkipRedrawHKL(HKL hSkipKL){ if (LOWORD(hSkipKL) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) return FALSE; // Japanese HKL will be skipped if (!g_prghklSkipRedrawing) return FALSE;
for (size_t iItem = 0; iItem < g_prghklSkipRedrawing->size(); ++iItem) { if ((*g_prghklSkipRedrawing)[iItem] == hSkipKL) return TRUE; // To be skipped }
return FALSE; // To be not skipped}
BOOL IsBiDiLocalizedSystem(void){ LOCALESIGNATURE Sig; LANGID LangID = ::GetUserDefaultUILanguage(); if (!LangID) return FALSE;
INT size = sizeof(Sig) / sizeof(WCHAR); if (!::GetLocaleInfoW(LangID, LOCALE_FONTSIGNATURE, (LPWSTR)&Sig, size)) return FALSE; return (Sig.lsUsb[3] & 0x8000000) != 0;}
BOOL GetFontSig(HWND hWnd, HKL hKL){ LOCALESIGNATURE Sig; INT size = sizeof(Sig) / sizeof(WCHAR); if (!::GetLocaleInfoW(LOWORD(hKL), LOCALE_FONTSIGNATURE, (LPWSTR)&Sig, size)) return FALSE;
HDC hDC = ::GetDC(hWnd); DWORD CharSet = ::GetTextCharsetInfo(hDC, NULL, 0); CHARSETINFO CharSetInfo; ::TranslateCharsetInfo((DWORD*)(DWORD_PTR)CharSet, &CharSetInfo, TCI_SRCCHARSET); ::ReleaseDC(hWnd, hDC);
return !!(CharSetInfo.fs.fsCsb[0] & Sig.lsCsbSupported[0]);}
void InitSkipRedrawHKLArray(void){ g_prghklSkipRedrawing = new(cicNoThrow) CicArray<HKL>(); if (!g_prghklSkipRedrawing) return;
if (g_bEnableDeskBand && (g_dwOSInfo & CIC_OSINFO_XPPLUS)) { // Japanese IME will be skipped g_prghklSkipRedrawing->Add((HKL)UlongToHandle(0xE0010411)); }
CicRegKey regKey; LSTATUS error = regKey.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\SkipRedrawHKL")); if (error != ERROR_SUCCESS) return;
TCHAR szValueName[256]; for (DWORD dwIndex = 0; ; ++dwIndex) { error = regKey.EnumValue(dwIndex, szValueName, _countof(szValueName)); if (error != ERROR_SUCCESS) break;
if (szValueName[0] == TEXT('0') && (szValueName[1] == TEXT('x') || szValueName[1] == TEXT('X'))) { HKL hKL = (HKL)UlongToHandle(_tcstoul(szValueName, NULL, 16)); g_prghklSkipRedrawing->Add(hKL); // This hKL will be skipped } }}
void UninitSkipRedrawHKLArray(void){ if (g_prghklSkipRedrawing) { delete g_prghklSkipRedrawing; g_prghklSkipRedrawing = NULL; }}
HRESULT GetGlobalCompartment(REFGUID rguid, ITfCompartment **ppComp){ ITfCompartmentMgr *pCompMgr = NULL; HRESULT hr = TF_GetGlobalCompartment(&pCompMgr); if (FAILED(hr)) return hr;
if (!pCompMgr) return E_FAIL;
hr = pCompMgr->GetCompartment(rguid, ppComp); pCompMgr->Release(); return hr;}
HRESULT GetGlobalCompartmentDWORD(REFGUID rguid, LPDWORD pdwValue){ *pdwValue = 0; ITfCompartment *pComp; HRESULT hr = GetGlobalCompartment(rguid, &pComp); if (SUCCEEDED(hr)) { VARIANT vari; hr = pComp->GetValue(&vari); if (hr == S_OK) *pdwValue = V_I4(&vari); pComp->Release(); } return hr;}
HRESULT SetGlobalCompartmentDWORD(REFGUID rguid, DWORD dwValue){ VARIANT vari; ITfCompartment *pComp; HRESULT hr = GetGlobalCompartment(rguid, &pComp); if (SUCCEEDED(hr)) { V_VT(&vari) = VT_I4; V_I4(&vari) = dwValue; hr = pComp->SetValue(0, &vari); pComp->Release(); } return hr;}
void TurnOffSpeechIfItsOn(void){ DWORD dwValue = 0; HRESULT hr = GetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, &dwValue); if (SUCCEEDED(hr) && dwValue) SetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0);}
void DoCloseLangbar(void){ ITfLangBarMgr *pLangBarMgr = NULL; HRESULT hr = TF_CreateLangBarMgr(&pLangBarMgr); if (FAILED(hr)) return;
if (pLangBarMgr) { hr = pLangBarMgr->ShowFloating(TF_SFT_HIDDEN); pLangBarMgr->Release(); }
if (SUCCEEDED(hr)) TurnOffSpeechIfItsOn();
CicRegKey regKey; LSTATUS error = regKey.Open(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), KEY_ALL_ACCESS); if (error == ERROR_SUCCESS) ::RegDeleteValue(regKey, TEXT("ctfmon.exe"));}
INT GetIconIndexFromhKL(_In_ HKL hKL){ HKL hGotKL;
INT iKL, cKLs = TF_MlngInfoCount(); for (iKL = 0; iKL < cKLs; ++iKL) { if (TF_GetMlngHKL(iKL, &hGotKL, NULL, 0) && hKL == hGotKL) return TF_GetMlngIconIndex(iKL); }
if (!TF_GetMlngHKL(0, &hGotKL, NULL, 0)) return -1;
return TF_GetMlngIconIndex(0);}
BOOL GethKLDesc(_In_ HKL hKL, _Out_ LPWSTR pszDesc, _In_ UINT cchDesc){ HKL hGotKL;
INT iKL, cKLs = TF_MlngInfoCount(); for (iKL = 0; iKL < cKLs; ++iKL) { if (TF_GetMlngHKL(iKL, &hGotKL, pszDesc, cchDesc) && hKL == hGotKL) return TRUE; }
return TF_GetMlngHKL(0, &hGotKL, pszDesc, cchDesc);}
HRESULTLangBarInsertMenu( _In_ ITfMenu *pMenu, _In_ UINT uId, _In_ LPCWSTR pszText, _In_ BOOL bChecked, _Inout_opt_ HICON hIcon){ HBITMAP hbmp = NULL, hbmpMask = NULL; if (hIcon) { HICON hIconNew = (HICON)::CopyImage(hIcon, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE); SIZE iconSize = { 16, 16 }; if (!hIconNew) hIconNew = hIcon; if (!cicGetIconBitmaps(hIconNew, &hbmp, &hbmpMask, &iconSize)) return E_FAIL; if (hIconNew) ::DestroyIcon(hIconNew); ::DestroyIcon(hIcon); }
INT cchText = lstrlenW(pszText); DWORD dwFlags = (bChecked ? TF_LBMENUF_CHECKED : 0); return pMenu->AddMenuItem(uId, dwFlags, hbmp, hbmpMask, pszText, cchText, NULL);}
HRESULT LangBarInsertSeparator(_In_ ITfMenu *pMenu){ return pMenu->AddMenuItem(-1, TF_LBMENUF_SEPARATOR, NULL, NULL, NULL, 0, NULL);}
// Is it a Far-East language ID?BOOL IsFELangId(LANGID LangID){ switch (LangID) { case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Chinese (Simplified) case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Chinese (Traditional) case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean return TRUE; default: return FALSE; }}
BOOL CheckCloseMenuAvailable(void){ BOOL ret = FALSE; ITfInputProcessorProfiles *pProfiles = NULL; LANGID *pLangIds = NULL; ULONG iItem, cItems;
if (g_fPolicyDisableCloseButton) return FALSE;
if (g_bShowCloseMenu) return TRUE;
if (SUCCEEDED(TF_CreateInputProcessorProfiles(&pProfiles)) && SUCCEEDED(pProfiles->GetLanguageList(&pLangIds, &cItems))) { for (iItem = 0; iItem < cItems; ++iItem) { if (IsFELangId(pLangIds[iItem])) break; }
ret = (iItem == cItems); }
if (pLangIds) CoTaskMemFree(pLangIds); if (pProfiles) pProfiles->Release();
return ret;}
/// @unimplementedBOOL IsTransparecyAvailable(void){ return FALSE;}
static INT CALLBACKFindEAEnumFontProc(ENUMLOGFONT *pLF, NEWTEXTMETRIC *pTM, INT nFontType, LPARAM lParam){ if ((nFontType != TRUETYPE_FONTTYPE) || (pLF->elfLogFont.lfFaceName[0] != '@')) return TRUE; *(BOOL*)lParam = TRUE; return FALSE;}
/// Are there East-Asian vertical fonts?BOOL CheckEAFonts(void){ BOOL bHasVertical = FALSE; HDC hDC = ::GetDC(NULL); ::EnumFonts(hDC, NULL, (FONTENUMPROC)FindEAEnumFontProc, (LPARAM)&bHasVertical); ::ReleaseDC(NULL, hDC); return bHasVertical;}
BOOL IsDeskBandFromReg(){ if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) // Desk band is for XP+ return FALSE;
CicRegKey regKey; if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"))) { DWORD dwValue = 0; regKey.QueryDword(TEXT("ShowDeskBand"), &dwValue); return !!dwValue; }
return FALSE;}
void SetDeskBandToReg(BOOL bShow){ CicRegKey regKey; if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"), KEY_ALL_ACCESS)) regKey.SetDword(TEXT("ShowDeskBand"), bShow);}
BOOL RegisterComCat(REFCLSID rclsid, REFCATID rcatid, BOOL bRegister){ if (FAILED(::CoInitialize(NULL))) return FALSE;
ICatRegister *pCat; HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pCat); if (SUCCEEDED(hr)) { if (bRegister) hr = pCat->RegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid)); else hr = pCat->UnRegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid));
pCat->Release(); }
::CoUninitialize();
//if (IsIE5()) // ::RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("Component Categories\\{00021492-0000-0000-C000-000000000046}\\Enum"));
return SUCCEEDED(hr);}
BOOL InitFromReg(void){ DWORD dwValue; LSTATUS error;
CicRegKey regKey1; error = regKey1.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\")); if (error == ERROR_SUCCESS) { error = regKey1.QueryDword(TEXT("ShowTipbar"), &dwValue); if (error == ERROR_SUCCESS) g_bShowTipbar = !!dwValue; }
CicRegKey regKey2; error = regKey2.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); if (error == ERROR_SUCCESS) { error = regKey2.QueryDword(TEXT("ShowDebugMenu"), &dwValue); if (error == ERROR_SUCCESS) g_bShowDebugMenu = !!dwValue; error = regKey2.QueryDword(TEXT("NewLook"), &dwValue); if (error == ERROR_SUCCESS) g_bNewLook = !!dwValue; error = regKey2.QueryDword(TEXT("IntelliSense"), &dwValue); if (error == ERROR_SUCCESS) g_bIntelliSense = !!dwValue; error = regKey2.QueryDword(TEXT("ShowCloseMenu"), &dwValue); if (error == ERROR_SUCCESS) g_bShowCloseMenu = !!dwValue; error = regKey2.QueryDword(TEXT("TimeOutNonIntentional"), &dwValue); if (error == ERROR_SUCCESS) g_uTimeOutNonIntentional = 1000 * dwValue; error = regKey2.QueryDword(TEXT("TimeOutIntentional"), &dwValue); if (error == ERROR_SUCCESS) { g_uTimeOutIntentional = 1000 * dwValue; g_uTimeOutMax = 6000 * dwValue; } error = regKey2.QueryDword(TEXT("ShowMinimizedBalloon"), &dwValue); if (error == ERROR_SUCCESS) g_bShowMinimizedBalloon = !!dwValue; error = regKey2.QueryDword(TEXT("Left"), &dwValue); if (error == ERROR_SUCCESS) g_ptTipbar.x = dwValue; error = regKey2.QueryDword(TEXT("Top"), &dwValue); if (error == ERROR_SUCCESS) g_ptTipbar.y = dwValue; error = regKey2.QueryDword(TEXT("ExcludeCaptionButtons"), &dwValue); if (error == ERROR_SUCCESS) g_bExcludeCaptionButtons = !!dwValue; error = regKey2.QueryDword(TEXT("ShowShadow"), &dwValue); if (error == ERROR_SUCCESS) g_bShowShadow = !!dwValue; error = regKey2.QueryDword(TEXT("TaskbarTheme"), &dwValue); if (error == ERROR_SUCCESS) g_fTaskbarTheme = !!dwValue; error = regKey2.QueryDword(TEXT("Vertical"), &dwValue); if (error == ERROR_SUCCESS) g_fVertical = !!dwValue; error = regKey2.QueryDword(TEXT("TimerElapseSTUBSTART"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseSTUBSTART = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseSTUBEND"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseSTUBEND = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseBACKTOALPHA"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseBACKTOALPHA = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseONTHREADITEMCHANGE"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseONTHREADITEMCHANGE = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseSETWINDOWPOS"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseSETWINDOWPOS = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseONUPDATECALLED"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseONUPDATECALLED = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseSYSCOLORCHANGED"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseSYSCOLORCHANGED = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseDISPLAYCHANGE"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseDISPLAYCHANGE = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseUPDATEUI"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseUPDATEUI = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseSHOWWINDOW"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseSHOWWINDOW = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseMOVETOTRAY"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseMOVETOTRAY = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseTRAYWNDONDELAYMSG"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseTRAYWNDONDELAYMSG = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseDOACCDEFAULTACTION"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseDOACCDEFAULTACTION = dwValue; error = regKey2.QueryDword(TEXT("TimerElapseENSUREFOCUS"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseENSUREFOCUS = dwValue; if (g_bEnableDeskBand && (g_dwOSInfo & CIC_OSINFO_XPPLUS)) { error = regKey2.QueryDword(TEXT("ShowDeskBand"), &dwValue); if (error == ERROR_SUCCESS) g_bShowDeskBand = !!dwValue; error = regKey2.QueryDword(TEXT("TimerElapseSHOWWDESKBAND"), &dwValue); if (error == ERROR_SUCCESS) g_uTimerElapseSHOWDESKBAND = dwValue; } }
CicRegKey regKey3; error = regKey3.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF")); if (error == ERROR_SUCCESS) { error = regKey3.QueryDword(TEXT("DisableCloseButton"), &dwValue); if (error == ERROR_SUCCESS) g_fPolicyDisableCloseButton = !!dwValue; }
CicRegKey regKey4; error = regKey4.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF")); if (error == ERROR_SUCCESS) { error = regKey4.QueryDword(TEXT("EnableLanguagebarInFullscreen"), &dwValue); if (error == ERROR_SUCCESS) g_fPolicyEnableLanguagebarInFullscreen = !!dwValue; }
InitSkipRedrawHKLArray();
if (g_bNewLook) { g_dwWndStyle = UIF_WINDOW_ENABLETHEMED | UIF_WINDOW_WORKAREA | UIF_WINDOW_TOOLTIP | UIF_WINDOW_TOOLWINDOW | UIF_WINDOW_TOPMOST; if (g_bShowShadow) g_dwWndStyle |= UIF_WINDOW_SHADOW; g_dwMenuStyle = 0x10000000 | UIF_WINDOW_MONITOR | UIF_WINDOW_SHADOW | UIF_WINDOW_TOOLWINDOW | UIF_WINDOW_TOPMOST; } else { g_dwWndStyle = UIF_WINDOW_WORKAREA | UIF_WINDOW_TOOLTIP | UIF_WINDOW_DLGFRAME | UIF_WINDOW_TOPMOST; g_dwMenuStyle = UIF_WINDOW_MONITOR | UIF_WINDOW_DLGFRAME | UIF_WINDOW_TOPMOST; }
g_dwChildWndStyle = UIF_WINDOW_ENABLETHEMED | UIF_WINDOW_NOMOUSEMSG | UIF_WINDOW_TOOLTIP | UIF_WINDOW_CHILD;
if (IsBiDiLocalizedSystem()) { g_dwWndStyle |= UIF_WINDOW_LAYOUTRTL; g_dwChildWndStyle |= UIF_WINDOW_LAYOUTRTL; g_dwMenuStyle |= UIF_WINDOW_LAYOUTRTL; g_fRTL = TRUE; }
return TRUE;}
/***********************************************************************/
struct CShellWndThread{ HWND m_hTrayWnd = NULL; HWND m_hProgmanWnd = NULL;
HWND GetWndTray() { if (!m_hTrayWnd || !::IsWindow(m_hTrayWnd)) m_hTrayWnd = ::FindWindowW(L"Shell_TrayWnd", NULL); return m_hTrayWnd; }
HWND GetWndProgman() { if (!m_hProgmanWnd || !::IsWindow(m_hProgmanWnd)) m_hProgmanWnd = ::FindWindowW(L"Progman", NULL); return m_hProgmanWnd; }
void clear() { m_hTrayWnd = m_hProgmanWnd = NULL; }};
/***********************************************************************/
class CUTBLangBarDlg{protected: LPTSTR m_pszDialogName; LONG m_cRefs;
public: CUTBLangBarDlg() { } virtual ~CUTBLangBarDlg() { }
static CUTBLangBarDlg *GetThis(HWND hDlg); static void SetThis(HWND hDlg, CUTBLangBarDlg *pThis); static DWORD WINAPI s_ThreadProc(LPVOID pParam); static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL StartThread(); LONG _Release();
STDMETHOD_(BOOL, DoModal)(HWND hDlg) = 0; STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) = 0; STDMETHOD_(BOOL, IsDlgShown)() = 0; STDMETHOD_(void, SetDlgShown)(BOOL bShown) = 0; STDMETHOD_(BOOL, ThreadProc)();};
/***********************************************************************/
class CUTBCloseLangBarDlg : public CUTBLangBarDlg{public: CUTBCloseLangBarDlg();
static BOOL s_bIsDlgShown;
STDMETHOD_(BOOL, DoModal)(HWND hDlg) override; STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(BOOL, IsDlgShown)() override; STDMETHOD_(void, SetDlgShown)(BOOL bShown) override;};
BOOL CUTBCloseLangBarDlg::s_bIsDlgShown = FALSE;
/***********************************************************************/
class CUTBMinimizeLangBarDlg : public CUTBLangBarDlg{public: CUTBMinimizeLangBarDlg();
static BOOL s_bIsDlgShown;
STDMETHOD_(BOOL, DoModal)(HWND hDlg) override; STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(BOOL, IsDlgShown)() override; STDMETHOD_(void, SetDlgShown)(BOOL bShown) override; STDMETHOD_(BOOL, ThreadProc)() override;};
BOOL CUTBMinimizeLangBarDlg::s_bIsDlgShown = FALSE;
/***********************************************************************/
class CCicLibMenu : public ITfMenu{protected: CicArray<CCicLibMenuItem*> m_MenuItems; LONG m_cRefs;
public: CCicLibMenu(); virtual ~CCicLibMenu();
STDMETHOD(QueryInterface)(REFIID riid, LPVOID *ppvObj) override; STDMETHOD_(ULONG, AddRef)() override; STDMETHOD_(ULONG, Release)() override; STDMETHOD(AddMenuItem)( UINT uId, DWORD dwFlags, HBITMAP hbmp, HBITMAP hbmpMask, const WCHAR *pch, ULONG cch, ITfMenu **ppSubMenu) override; STDMETHOD_(CCicLibMenu*, CreateSubMenu)(); STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)();};
/***********************************************************************/
class CCicLibMenuItem{protected: DWORD m_uId; DWORD m_dwFlags; HBITMAP m_hbmp; HBITMAP m_hbmpMask; BSTR m_bstrText; ITfMenu *m_pMenu;
public: CCicLibMenuItem(); virtual ~CCicLibMenuItem();
BOOL Init( UINT uId, DWORD dwFlags, HBITMAP hbmp, HBITMAP hbmpMask, const WCHAR *pch, ULONG cch, ITfMenu *pMenu); HBITMAP CreateBitmap(HANDLE hBitmap);};
/***********************************************************************/
class CTipbarAccessible : public IAccessible{protected: LONG m_cRefs; HWND m_hWnd; IAccessible *m_pStdAccessible; ITypeInfo *m_pTypeInfo; BOOL m_bInitialized; CicArray<CTipbarAccItem*> m_AccItems; LONG m_cSelection; friend class CUTBMenuWnd; friend class CTipbarWnd;
public: CTipbarAccessible(CTipbarAccItem *pItem); virtual ~CTipbarAccessible();
HRESULT Initialize();
BOOL AddAccItem(CTipbarAccItem *pItem); HRESULT RemoveAccItem(CTipbarAccItem *pItem); void ClearAccItems(); CTipbarAccItem *AccItemFromID(INT iItem); INT GetIDOfItem(CTipbarAccItem *pTarget);
LONG_PTR CreateRefToAccObj(WPARAM wParam); BOOL DoDefaultActionReal(INT nID); void NotifyWinEvent(DWORD event, CTipbarAccItem *pItem); void SetWindow(HWND hWnd);
// IUnknown methods STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)();
// IDispatch methods STDMETHOD(GetTypeInfoCount)(UINT *pctinfo); STDMETHOD(GetTypeInfo)( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); STDMETHOD(GetIDsOfNames)( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); STDMETHOD(Invoke)( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
// IAccessible methods STDMETHOD(get_accParent)(IDispatch **ppdispParent); STDMETHOD(get_accChildCount)(LONG *pcountChildren); STDMETHOD(get_accChild)(VARIANT varChildID, IDispatch **ppdispChild); STDMETHOD(get_accName)(VARIANT varID, BSTR *pszName); STDMETHOD(get_accValue)(VARIANT varID, BSTR *pszValue); STDMETHOD(get_accDescription)(VARIANT varID, BSTR *description); STDMETHOD(get_accRole)(VARIANT varID, VARIANT *role); STDMETHOD(get_accState)(VARIANT varID, VARIANT *state); STDMETHOD(get_accHelp)(VARIANT varID, BSTR *help); STDMETHOD(get_accHelpTopic)(BSTR *helpfile, VARIANT varID, LONG *pidTopic); STDMETHOD(get_accKeyboardShortcut)(VARIANT varID, BSTR *shortcut); STDMETHOD(get_accFocus)(VARIANT *pvarID); STDMETHOD(get_accSelection)(VARIANT *pvarID); STDMETHOD(get_accDefaultAction)(VARIANT varID, BSTR *action); STDMETHOD(accSelect)(LONG flagsSelect, VARIANT varID); STDMETHOD(accLocation)( LONG *left, LONG *top, LONG *width, LONG *height, VARIANT varID); STDMETHOD(accNavigate)(LONG dir, VARIANT varStart, VARIANT *pvarEnd); STDMETHOD(accHitTest)(LONG left, LONG top, VARIANT *pvarID); STDMETHOD(accDoDefaultAction)(VARIANT varID); STDMETHOD(put_accName)(VARIANT varID, BSTR name); STDMETHOD(put_accValue)(VARIANT varID, BSTR value);};
/***********************************************************************/
class CTipbarAccItem{public: CTipbarAccItem() { } virtual ~CTipbarAccItem() { }
STDMETHOD_(BSTR, GetAccName)() { return SysAllocString(L""); } STDMETHOD_(BSTR, GetAccValue)() { return NULL; } STDMETHOD_(INT, GetAccRole)() { return 10; } STDMETHOD_(INT, GetAccState)() { return 256; } STDMETHOD_(void, GetAccLocation)(LPRECT lprc) { *lprc = { 0, 0, 0, 0 }; } STDMETHOD_(BSTR, GetAccDefaultAction)() { return NULL; } STDMETHOD_(BOOL, DoAccDefaultAction)() { return FALSE; } STDMETHOD_(BOOL, DoAccDefaultActionReal)() { return FALSE; }};
/***********************************************************************/
class CTipbarCoInitialize{public: BOOL m_bCoInit;
CTipbarCoInitialize() : m_bCoInit(FALSE) { } ~CTipbarCoInitialize() { CoUninit(); }
HRESULT EnsureCoInit() { if (m_bCoInit) return S_OK; HRESULT hr = ::CoInitialize(NULL); if (FAILED(hr)) return hr; m_bCoInit = TRUE; return S_OK; }
void CoUninit() { if (m_bCoInit) { ::CoUninitialize(); m_bCoInit = FALSE; } }};
/***********************************************************************/
class CUTBMenuWnd : public CTipbarAccItem, public CUIFMenu{protected: CTipbarCoInitialize m_coInit; CTipbarAccessible *m_pAccessible; UINT m_nMenuWndID; friend class CUTBMenuItem;
public: CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14);
BOOL StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget);
CTipbarAccItem* GetAccItem() { return static_cast<CTipbarAccItem*>(this); } CUIFMenu* GetMenu() { return static_cast<CUIFMenu*>(this); }
STDMETHOD_(BSTR, GetAccName)() override; STDMETHOD_(INT, GetAccRole)() override; STDMETHOD_(BOOL, Initialize)() override; STDMETHOD_(void, OnCreate)(HWND hWnd) override; STDMETHOD_(void, OnDestroy)(HWND hWnd) override; STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(LRESULT, OnShowWindow)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(void, OnTimer)(WPARAM wParam) override;};
/***********************************************************************/
class CUTBMenuItem : public CTipbarAccItem, public CUIFMenuItem{protected: CUTBMenuWnd *m_pMenuUI; friend class CUTBMenuWnd;
public: CUTBMenuItem(CUTBMenuWnd *pMenuUI); ~CUTBMenuItem() override;
CUIFMenuItem* GetMenuItem() { return static_cast<CUIFMenuItem*>(this); }
STDMETHOD_(BOOL, DoAccDefaultAction)() override; STDMETHOD_(BOOL, DoAccDefaultActionReal)() override; STDMETHOD_(BSTR, GetAccDefaultAction)() override; STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override; STDMETHOD_(BSTR, GetAccName)() override; STDMETHOD_(INT, GetAccRole)() override;};
/***********************************************************************/
class CModalMenu{public: DWORD m_dwUnknown26; CUTBMenuWnd *m_pMenuUI;
public: CModalMenu() { } virtual ~CModalMenu() { }
CUTBMenuItem *InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID); void PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam); void CancelMenu();};
/***********************************************************************/
class CTipbarThread;
class CUTBContextMenu : public CModalMenu{public: CTipbarWnd *m_pTipbarWnd; CTipbarThread *m_pTipbarThread;
public: CUTBContextMenu(CTipbarWnd *pTipbarWnd);
BOOL Init(); CUTBMenuWnd *CreateMenuUI(BOOL bFlag);
UINT ShowPopup( CUIFWindow *pWindow, POINT pt, LPCRECT prc, BOOL bFlag);
BOOL SelectMenuItem(UINT nCommandId);};
/***********************************************************************/
class CUTBLBarMenuItem;
class CUTBLBarMenu : public CCicLibMenu{protected: CUTBMenuWnd *m_pMenuUI; HINSTANCE m_hInst;
public: CUTBLBarMenu(HINSTANCE hInst); ~CUTBLBarMenu() override;
CUTBMenuWnd *CreateMenuUI(); INT ShowPopup(CUIFWindow *pWindow, POINT pt, LPCRECT prcExclude);
STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)() override; STDMETHOD_(CCicLibMenu*, CreateSubMenu)() override;};
/***********************************************************************/
class CUTBLBarMenuItem : public CCicLibMenuItem{public: CUTBLBarMenu *m_pLBarMenu;
public: CUTBLBarMenuItem() { m_pLBarMenu = NULL; } BOOL InsertToUI(CUTBMenuWnd *pMenuUI);};
/***********************************************************************/
class CTipbarGripper : public CUIFGripper{protected: CTipbarWnd *m_pTipbarWnd; BOOL m_bInDebugMenu; friend class CTipbarWnd;
public: CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style);
STDMETHOD_(void, OnLButtonUp)(LONG x, LONG y) override; STDMETHOD_(void, OnRButtonUp)(LONG x, LONG y) override; STDMETHOD_(BOOL, OnSetCursor)(UINT uMsg, LONG x, LONG y) override;};
/***********************************************************************/
class CLangBarItemList : public CicArray<LANGBARITEMSTATE>{public: BOOL IsStartedIntentionally(REFCLSID rclsid);
LANGBARITEMSTATE *AddItem(REFCLSID rclsid); void Clear(); BOOL SetDemoteLevel(REFCLSID rclsid, DWORD dwDemoteLevel);
LANGBARITEMSTATE *FindItem(REFCLSID rclsid); LANGBARITEMSTATE *GetItemStateFromTimerId(UINT_PTR nTimerID);
void Load(); void SaveItem(CicRegKey *pRegKey, const LANGBARITEMSTATE *pState);
void StartDemotingTimer(REFCLSID rclsid, BOOL bIntentional); UINT_PTR FindDemotingTimerId();};
/***********************************************************************/
class CTrayIconWnd{protected: DWORD m_dwUnknown20; BOOL m_bBusy; UINT m_uCallbackMessage; UINT m_uMsg; HWND m_hWnd; DWORD m_dwUnknown21[2]; HWND m_hTrayWnd; HWND m_hNotifyWnd; DWORD m_dwTrayWndThreadId; DWORD m_dwUnknown22; HWND m_hwndProgman; DWORD m_dwProgmanThreadId; CMainIconItem *m_pMainIconItem; CicArray<CButtonIconItem*> m_Items; UINT m_uCallbackMsg; UINT m_uNotifyIconID; friend class CTipbarWnd;
static BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam); static LRESULT CALLBACK _WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public: CTrayIconWnd(); ~CTrayIconWnd();
static BOOL RegisterClass(); static CTrayIconWnd *GetThis(HWND hWnd); static void SetThis(HWND hWnd, LPCREATESTRUCT pCS);
HWND CreateWnd(); void DestroyWnd();
BOOL SetMainIcon(HKL hKL); BOOL SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz);
void RemoveAllIcon(DWORD dwFlags); void RemoveUnusedIcons(int unknown);
CButtonIconItem *FindIconItem(REFGUID rguid); BOOL FindTrayEtc(); HWND GetNotifyWnd(); BOOL OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
void CallOnDelayMsg();};
/***********************************************************************/
class CTrayIconItem{protected: HWND m_hWnd; UINT m_uCallbackMessage; UINT m_uNotifyIconID; DWORD m_dwIconAddOrModify; BOOL m_bIconAdded; CTrayIconWnd *m_pTrayIconWnd; DWORD m_dwUnknown25; GUID m_guid; RECT m_rcMenu; POINT m_ptCursor; friend class CTrayIconWnd;
public: CTrayIconItem(CTrayIconWnd *pTrayIconWnd); virtual ~CTrayIconItem() { }
BOOL _Init(HWND hWnd, UINT uCallbackMessage, UINT uNotifyIconID, const GUID& rguid); BOOL UpdateMenuRectPoint(); BOOL RemoveIcon();
STDMETHOD_(BOOL, SetIcon)(HICON hIcon, LPCWSTR pszTip); STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) { return FALSE; }; STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) { return 0; };};
/***********************************************************************/
class CButtonIconItem : public CTrayIconItem{protected: DWORD m_dwUnknown24; HKL m_hKL; friend class CTrayIconWnd;
public: CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24);
STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) override; STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override;};
/***********************************************************************/
class CMainIconItem : public CButtonIconItem{public: CMainIconItem(CTrayIconWnd *pWnd);
BOOL Init(HWND hWnd); STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override;};
/***********************************************************************/
class CLBarItemBase{protected: DWORD m_dwItemStatus; TF_LANGBARITEMINFO m_NewUIInfo; WCHAR m_szToolTipText[256]; LONG m_cRefs; ITfLangBarItemSink *m_pLangBarItemSink;
public: CLBarItemBase(); virtual ~CLBarItemBase();
HRESULT ShowInternal(BOOL bShow, BOOL bUpdate);
void InitNuiInfo( REFIID clsidService, REFGUID guidItem, DWORD dwStyle, DWORD ulSort, LPCWSTR Source);
HRESULT GetInfo(TF_LANGBARITEMINFO *pInfo); HRESULT GetStatus(DWORD *pdwStatus); HRESULT Show(BOOL fShow); HRESULT GetTooltipString(BSTR *pbstrToolTip);
HRESULT AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie); HRESULT UnadviseSink(DWORD dwCookie);};
/***********************************************************************/
class CLBarItemButtonBase : public CLBarItemBase , public ITfLangBarItem , public ITfLangBarItemButton , public ITfSource{public: HICON m_hIcon;
public: CLBarItemButtonBase() { m_hIcon = NULL; } ~CLBarItemButtonBase() override;
// IUnknown methods STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) override; STDMETHOD_(ULONG, AddRef)() override; STDMETHOD_(ULONG, Release)() override;
// ITfLangBarItem methods STDMETHOD(GetInfo)(TF_LANGBARITEMINFO *pInfo) override; STDMETHOD(GetStatus)(DWORD *pdwStatus) override; STDMETHOD(Show)(BOOL fShow) override; STDMETHOD(GetTooltipString)(BSTR *pbstrToolTip) override;
// ITfLangBarItemButton methods STDMETHOD(OnClick)(TfLBIClick click, POINT pt, LPCRECT prc) override; STDMETHOD(InitMenu)(ITfMenu *pMenu) override; STDMETHOD(OnMenuSelect)(UINT wID) override; STDMETHOD(GetIcon)(HICON *phIcon) override; STDMETHOD(GetText)(BSTR *pbstr) override;
// ITfSource methods STDMETHOD(AdviseSink)(REFIID riid, IUnknown *punk, DWORD *pdwCookie) override; STDMETHOD(UnadviseSink)(DWORD dwCookie) override;};
/***********************************************************************/
/// Language Bar international itemclass CLBarInatItem : public CLBarItemButtonBase{protected: HKL m_hKL; DWORD m_dwThreadId;
public: CLBarInatItem(DWORD dwThreadId);
STDMETHOD(InitMenu)(ITfMenu *pMenu) override; STDMETHOD(OnMenuSelect)(INT nCommandId); STDMETHOD(GetIcon)(HICON *phIcon) override; STDMETHOD(GetText)(BSTR *pbstr) override;};
/***********************************************************************/
class CTipbarItem;class CTipbarBalloonItem;
class CTipbarThread{protected: CTipbarWnd *m_pTipbarWnd; ITfLangBarItemMgr *m_pLangBarItemMgr; CicArray<CTipbarItem*> m_UIObjects; CicArray<CUIFObject*> m_Separators; DWORD m_dwUnknown32; DWORD m_dwThreadId; DWORD m_dwFlags1; DWORD m_dwFlags2; INT m_cxGrip; INT m_cyGrip; DWORD m_dwFlags3; DWORD m_dwUnknown34; LONG m_cRefs; friend class CTipbarWnd; friend class CTipbarItem;
public: CTipbarThread(CTipbarWnd *pTipbarWnd); virtual ~CTipbarThread();
HRESULT Init(DWORD dwThreadId);
HRESULT InitItemList(); HRESULT _UninitItemList(BOOL bUnAdvise);
DWORD IsDirtyItem(); BOOL IsFocusThread(); BOOL IsVertical();
void AddAllSeparators(); void RemoveAllSeparators();
void AddUIObjs(); void RemoveUIObjs();
CTipbarItem *GetItem(REFCLSID rclsid); void GetTextSize(BSTR bstr, LPSIZE pSize); void LocateItems(); void MyMoveWnd(LONG xDelta, LONG yDelta);
HRESULT _UnadviseItemsSink(); LONG _AddRef() { return ++m_cRefs; } LONG _Release();
/// @unimplemented BOOL SetFocus(CTipbarBalloonItem *pTarget) { return FALSE; }
/// @unimplemented HRESULT CallOnUpdateHandler() { return E_NOTIMPL; }
//FIXME};
/***********************************************************************/
class CTipbarItem : public CTipbarAccItem{protected: DWORD m_dwCookie; TF_LANGBARITEMINFO m_ItemInfo; DWORD m_dwUnknown16; DWORD m_dwUnknown17; CTipbarThread *m_pTipbarThread; ITfLangBarItem *m_pLangBarItem; DWORD m_dwUnknown18[2]; DWORD m_dwItemFlags; DWORD m_dwDirty; DWORD m_dwUnknown19[4]; friend class CTipbarThread; friend class CTipbarWnd;
public: CTipbarItem( CTipbarThread *pThread, ITfLangBarItem *pLangBarItem, TF_LANGBARITEMINFO *pItemInfo, DWORD dwUnknown16); ~CTipbarItem() override;
void _AddedToUI(); void _RemovedToUI(); void AddRemoveMeToUI(BOOL bFlag);
BOOL IsConnected(); void ClearConnections();
void StartDemotingTimer(BOOL bStarted);
void MyClientToScreen(LPPOINT ppt, LPRECT prc); void MyClientToScreen(LPRECT prc) { return MyClientToScreen(NULL, prc); }
STDMETHOD_(BSTR, GetAccName)() override; STDMETHOD_(void, GetAccLocation)(LPRECT prc) override; STDMETHOD_(BOOL, DoAccDefaultAction)() override; STDMETHOD(OnUnknown40)() { return S_OK; } STDMETHOD(OnUnknown41)() { return S_OK; } STDMETHOD(OnUnknown42)() { return S_OK; } STDMETHOD(OnUnknown43)() { return S_OK; } STDMETHOD(OnUpdate)(DWORD dwDirty); STDMETHOD(OnUnknown44)() { return S_OK; } STDMETHOD_(void, OnUnknown45)(DWORD dwDirty, DWORD dwStatus) { } STDMETHOD_(void, OnUpdateHandler)(ULONG, ULONG); STDMETHOD(OnUnknown46)(CUIFWindow *pWindow) { return S_OK; } STDMETHOD(OnUnknown47)(CUIFWindow *pWindow) { return S_OK; } STDMETHOD(OnUnknown48)() { return S_OK; } STDMETHOD(OnUnknown49)() { return S_OK; } STDMETHOD(OnUnknown50)() { return S_OK; } STDMETHOD(OnUnknown51)() { return S_OK; } STDMETHOD(OnUnknown52)() { return S_OK; } STDMETHOD(OnUnknown53)(BSTR bstr) { return S_OK; } STDMETHOD_(LPCWSTR, OnUnknown55)() { return NULL; } STDMETHOD(OnUnknown56)() { return S_OK; } STDMETHOD_(LPCWSTR, GetToolTip)(); STDMETHOD(OnUnknown57)(LPRECT prc) { return S_OK; } STDMETHOD(OnUnknown58)() { return S_OK; } STDMETHOD_(void, OnUnknown59)() { } STDMETHOD_(void, OnUnknown60)() { } STDMETHOD_(void, OnUnknown61)(HWND) { } STDMETHOD_(void, OnUnknown62)(HWND) { } STDMETHOD(OnUnknown63)() { return S_OK; }};
/***********************************************************************/
class CTipbarCtrlButtonHolder;class CDeskBand;
// Flags for m_dwTipbarWndFlagsenum{ TIPBAR_ATTACHED = 0x1, TIPBAR_CHILD = 0x2, TIPBAR_VERTICAL = 0x4, TIPBAR_HIGHCONTRAST = 0x10, TIPBAR_TRAYICON = 0x20, TIPBAR_UPDATING = 0x400, TIPBAR_ENSURING = 0x2000, TIPBAR_NODESKBAND = 0x4000, TIPBAR_TOOLBARENDED = 0x10000, TIPBAR_TOPFIT = 0x40000, TIPBAR_BOTTOMFIT = 0x80000, TIPBAR_RIGHTFIT = 0x100000, TIPBAR_LEFTFIT = 0x200000,};
class CTipbarWnd : public ITfLangBarEventSink , public ITfLangBarEventSink_P , public CTipbarAccItem , public CUIFWindow{ CTipbarCoInitialize m_coInit; DWORD m_dwSinkCookie; CModalMenu *m_pModalMenu; CTipbarThread *m_pThread; CLangBarItemList m_LangBarItemList; DWORD m_dwUnknown20; CUIFWndFrame *m_pWndFrame; CTipbarGripper *m_pTipbarGripper; CTipbarThread *m_pFocusThread; CicArray<CTipbarThread*> m_Threads; CicArray<CTipbarThread*> m_ThreadCreatingList; DWORD m_dwAlphaValue; DWORD m_dwTipbarWndFlags; LONG m_ButtonWidth; DWORD m_dwShowType; DWORD m_dwUnknown21; INT m_cxSmallIcon; INT m_cySmallIcon; INT m_cxDlgFrameX2; INT m_cyDlgFrameX2; HFONT m_hMarlettFont; HFONT m_hTextFont; ITfLangBarMgr_P *m_pLangBarMgr; DWORD m_dwUnknown23; CTipbarCtrlButtonHolder *m_pTipbarCtrlButtonHolder; DWORD m_dwUnknown23_1[8]; CUIFWindow *m_pBalloon; DWORD m_dwChangingThreadId; LONG m_bInCallOn; LONG m_X; LONG m_Y; LONG m_CX; LONG m_CY; CTipbarAccessible *m_pTipbarAccessible; INT m_nID; MARGINS m_Margins; DWORD m_dwUnknown23_5[4]; CTipbarThread *m_pUnknownThread; CDeskBand *m_pDeskBand; CShellWndThread m_ShellWndThread; LONG m_cRefs; friend class CUTBContextMenu; friend class CTipbarGripper; friend class CTipbarThread; friend class CTipbarItem; friend class CLBarInatItem; friend class CMainIconItem; friend VOID WINAPI ClosePopupTipbar(VOID); friend BOOL GetTipbarInternal(HWND hWnd, DWORD dwFlags, CDeskBand *pDeskBand); friend LONG MyWaitForInputIdle(DWORD dwThreadId, DWORD dwMilliseconds);
public: CTipbarWnd(DWORD style); ~CTipbarWnd() override;
CUIFWindow *GetWindow() { return static_cast<CUIFWindow*>(this); }
CTipbarAccItem *GetAccItem() { return static_cast<CTipbarAccItem*>(this); }
void Init(BOOL bChild, CDeskBand *pDeskBand); void InitHighContrast(); void InitMetrics(); void InitThemeMargins(); void UnInit();
BOOL IsFullScreenWindow(HWND hWnd); BOOL IsHKLToSkipRedrawOnNoItem(); BOOL IsInItemChangeOrDirty(CTipbarThread *pTarget);
void AddThreadToThreadCreatingList(CTipbarThread *pThread); void RemoveThredFromThreadCreatingList(CTipbarThread *pTarget);
void MoveToStub(BOOL bFlag); void RestoreFromStub();
INT GetCtrlButtonWidth(); INT GetGripperWidth(); INT GetTipbarHeight(); BOOL AutoAdjustDeskBandSize(); INT AdjustDeskBandSize(BOOL bFlag); void LocateCtrlButtons(); void AdjustPosOnDisplayChange(); void SetVertical(BOOL bVertical); void UpdatePosFlags();
void CancelMenu(); BOOL CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2); void ClearLBItemList();
HFONT CreateVerticalFont(); void UpdateVerticalFont();
void ShowOverScreenSizeBalloon(); void DestroyOverScreenSizeBalloon(); void DestroyWnd();
HKL GetFocusKeyboardLayout(); void KillOnTheadItemChangeTimer();
UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT uElapse); BOOL KillTimer(UINT_PTR uIDEvent);
void MoveToTray(); void MyClientToScreen(LPPOINT lpPoint, LPRECT prc); void SavePosition(); void SetAlpha(BYTE bAlpha, BOOL bFlag); BOOL SetLangBand(BOOL bDeskBand, BOOL bFlag2); void SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight); void SetShowText(BOOL bShow); void SetShowTrayIcon(BOOL bShow);
void ShowContextMenu(POINT pt, LPCRECT prc, BOOL bFlag); void StartBackToAlphaTimer(); BOOL StartDoAccDefaultActionTimer(CTipbarItem *pTarget);
void StartModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId); void StopModalInput(DWORD dwThreadId);
CTipbarThread *_CreateThread(DWORD dwThreadId); CTipbarThread *_FindThread(DWORD dwThreadId); void EnsureFocusThread(); HRESULT SetFocusThread(CTipbarThread *pFocusThread); HRESULT AttachFocusThread(); void RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev); void CleanUpThreadPointer(CTipbarThread *pThread, BOOL bRemove); void TerminateAllThreads(BOOL bFlag); void OnTerminateToolbar(); HRESULT OnThreadTerminateInternal(DWORD dwThreadId);
/// @unimplemented HRESULT OnThreadItemChangeInternal(DWORD dwThreadId) { return E_NOTIMPL; }
// IUnknown methods STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)();
// ITfLangBarEventSink methods STDMETHOD(OnSetFocus)(DWORD dwThreadId) override; STDMETHOD(OnThreadTerminate)(DWORD dwThreadId) override; STDMETHOD(OnThreadItemChange)(DWORD dwThreadId) override; STDMETHOD(OnModalInput)(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD(ShowFloating)(DWORD dwFlags) override; STDMETHOD(GetItemFloatingRect)(DWORD dwThreadId, REFGUID rguid, RECT *prc) override;
// ITfLangBarEventSink_P methods STDMETHOD(OnLangBarUpdate)(TfLBIClick click, BOOL bFlag) override;
// CTipbarAccItem methods STDMETHOD_(BSTR, GetAccName)() override; STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override;
// CUIFWindow methods STDMETHOD_(void, PaintObject)(HDC hDC, LPCRECT prc) override; STDMETHOD_(DWORD, GetWndStyle)() override; STDMETHOD_(void, Move)(INT x, INT y, INT nWidth, INT nHeight) override; STDMETHOD_(void, OnMouseOutFromWindow)(LONG x, LONG y) override; STDMETHOD_(void, OnCreate)(HWND hWnd) override; STDMETHOD_(void, OnDestroy)(HWND hWnd) override; STDMETHOD_(void, OnTimer)(WPARAM wParam) override; STDMETHOD_(void, OnSysColorChange)() override; STDMETHOD_(void, OnEndSession)(HWND hWnd, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(void, OnUser)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(LRESULT, OnWindowPosChanged)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(LRESULT, OnWindowPosChanging)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(LRESULT, OnShowWindow)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(LRESULT, OnSettingChange)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(LRESULT, OnDisplayChange)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(BOOL, OnEraseBkGnd)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(void, OnThemeChanged)(HWND hWnd, WPARAM wParam, LPARAM lParam) override; STDMETHOD_(void, UpdateUI)(LPCRECT prc) override; STDMETHOD_(void, HandleMouseMsg)(UINT uMsg, LONG x, LONG y) override;};
/***********************************************************************/
#ifdef ENABLE_DESKBANDclass CDeskBand{public: // FIXME: Implement this};#endif
/*********************************************************************** * CUTBLangBarDlg */
CUTBLangBarDlg *CUTBLangBarDlg::GetThis(HWND hDlg){ return (CUTBLangBarDlg*)::GetWindowLongPtr(hDlg, DWLP_USER);}
void CUTBLangBarDlg::SetThis(HWND hDlg, CUTBLangBarDlg *pThis){ ::SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pThis);}
DWORD WINAPI CUTBLangBarDlg::s_ThreadProc(LPVOID pParam){ return ((CUTBLangBarDlg *)pParam)->ThreadProc();}
BOOL CUTBLangBarDlg::StartThread(){ if (IsDlgShown()) return FALSE;
SetDlgShown(TRUE);
DWORD dwThreadId; HANDLE hThread = ::CreateThread(NULL, 0, s_ThreadProc, this, 0, &dwThreadId); if (!hThread) { SetDlgShown(FALSE); return TRUE; }
++m_cRefs; ::CloseHandle(hThread); return TRUE;}
LONG CUTBLangBarDlg::_Release(){ if (--m_cRefs == 0) { delete this; return 0; } return m_cRefs;}
STDMETHODIMP_(BOOL) CUTBLangBarDlg::ThreadProc(){ extern HINSTANCE g_hInst; ::DialogBoxParam(g_hInst, m_pszDialogName, NULL, DlgProc, (LPARAM)this); SetDlgShown(FALSE); _Release(); return TRUE;}
INT_PTR CALLBACKCUTBLangBarDlg::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (uMsg == WM_INITDIALOG) { SetThis(hDlg, (CUTBLangBarDlg *)lParam); ::ShowWindow(hDlg, SW_RESTORE); ::UpdateWindow(hDlg); return TRUE; }
if (uMsg == WM_COMMAND) { CUTBLangBarDlg *pThis = CUTBLangBarDlg::GetThis(hDlg); pThis->OnCommand(hDlg, wParam, lParam); return TRUE; }
return FALSE;}
/*********************************************************************** * CUTBCloseLangBarDlg */
CUTBCloseLangBarDlg::CUTBCloseLangBarDlg(){ m_cRefs = 1;
if (!(g_dwOSInfo & CIC_OSINFO_XPPLUS)) m_pszDialogName = MAKEINTRESOURCE(IDD_CLOSELANGBARNOBAND); else m_pszDialogName = MAKEINTRESOURCE(IDD_CLOSELANGBAR);}
STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::DoModal(HWND hDlg){ CicRegKey regKey; LSTATUS error; DWORD dwValue = FALSE; error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); if (error == ERROR_SUCCESS) regKey.QueryDword(TEXT("DontShowCloseLangBarDlg"), &dwValue);
if (dwValue) return FALSE;
StartThread(); return TRUE;}
STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam){ switch (LOWORD(wParam)) { case IDOK: DoCloseLangbar(); if (::IsDlgButtonChecked(hDlg, IDC_CLOSELANGBAR_CHECK)) { CicRegKey regKey; LSTATUS error; error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); if (error == ERROR_SUCCESS) regKey.SetDword(TEXT("DontShowCloseLangBarDlg"), TRUE); } ::EndDialog(hDlg, TRUE); break;
case IDCANCEL: ::EndDialog(hDlg, FALSE); break;
default: return FALSE; } return TRUE;}
STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::IsDlgShown(){ return s_bIsDlgShown;}
STDMETHODIMP_(void) CUTBCloseLangBarDlg::SetDlgShown(BOOL bShown){ s_bIsDlgShown = bShown;}
/*********************************************************************** * CUTBMinimizeLangBarDlg */
CUTBMinimizeLangBarDlg::CUTBMinimizeLangBarDlg(){ m_cRefs = 1; if (!(g_dwOSInfo & CIC_OSINFO_XPPLUS)) m_pszDialogName = MAKEINTRESOURCE(IDD_MINIMIZELANGBARNOBAND); else m_pszDialogName = MAKEINTRESOURCE(IDD_MINIMIZELANGBAR);}
STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::DoModal(HWND hDlg){ CicRegKey regKey; LSTATUS error;
DWORD dwValue = FALSE; error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); if (error == ERROR_SUCCESS) regKey.QueryDword(TEXT("DontShowMinimizeLangBarDlg"), &dwValue);
if (dwValue) return FALSE;
StartThread(); return TRUE;}
STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam){ switch (LOWORD(wParam)) { case IDOK: if (::IsDlgButtonChecked(hDlg, IDC_MINIMIZELANGBAR_CHECK)) { LSTATUS error; CicRegKey regKey; error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); if (error == ERROR_SUCCESS) regKey.SetDword(TEXT("DontShowMinimizeLangBarDlg"), TRUE); } ::EndDialog(hDlg, TRUE); break; case IDCANCEL: ::EndDialog(hDlg, FALSE); break; default: return FALSE; } return TRUE;}
STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::IsDlgShown(){ return s_bIsDlgShown;}
STDMETHODIMP_(void) CUTBMinimizeLangBarDlg::SetDlgShown(BOOL bShown){ s_bIsDlgShown = bShown;}
STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::ThreadProc(){ ::Sleep(700); return CUTBLangBarDlg::ThreadProc();}
/*********************************************************************** * CCicLibMenu */
CCicLibMenu::CCicLibMenu() : m_cRefs(1){}
CCicLibMenu::~CCicLibMenu(){ for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) { delete m_MenuItems[iItem]; m_MenuItems[iItem] = NULL; }}
STDMETHODIMP CCicLibMenu::QueryInterface(REFIID riid, LPVOID *ppvObj){ static const QITAB c_tab[] = { QITABENT(CCicLibMenu, ITfMenu), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
STDMETHODIMP_(ULONG) CCicLibMenu::AddRef(){ return ++m_cRefs;}
STDMETHODIMP_(ULONG) CCicLibMenu::Release(){ if (--m_cRefs == 0) { delete this; return 0; } return m_cRefs;}
STDMETHODIMP_(CCicLibMenu*) CCicLibMenu::CreateSubMenu(){ return new(cicNoThrow) CCicLibMenu();}
STDMETHODIMP_(CCicLibMenuItem*) CCicLibMenu::CreateMenuItem(){ return new(cicNoThrow) CCicLibMenuItem();}
STDMETHODIMP CCicLibMenu::AddMenuItem( UINT uId, DWORD dwFlags, HBITMAP hbmp, HBITMAP hbmpMask, const WCHAR *pch, ULONG cch, ITfMenu **ppSubMenu){ if (ppSubMenu) *ppSubMenu = NULL;
CCicLibMenu *pSubMenu = NULL; if (dwFlags & TF_LBMENUF_SUBMENU) { if (!ppSubMenu) return E_INVALIDARG; pSubMenu = CreateSubMenu(); }
CCicLibMenuItem *pMenuItem = CreateMenuItem(); if (!pMenuItem) return E_OUTOFMEMORY;
if (!pMenuItem->Init(uId, dwFlags, hbmp, hbmpMask, pch, cch, pSubMenu)) return E_FAIL;
if (ppSubMenu && pSubMenu) { *ppSubMenu = pSubMenu; pSubMenu->AddRef(); }
m_MenuItems.Add(pMenuItem); return S_OK;}
/*********************************************************************** * CCicLibMenuItem */
CCicLibMenuItem::CCicLibMenuItem(){ m_uId = 0; m_dwFlags = 0; m_hbmp = NULL; m_hbmpMask = NULL; m_bstrText = NULL; m_pMenu = NULL;}
CCicLibMenuItem::~CCicLibMenuItem(){ if (m_pMenu) { m_pMenu->Release(); m_pMenu = NULL; }
if (m_hbmp) { ::DeleteObject(m_hbmp); m_hbmp = NULL; }
if (m_hbmpMask) { ::DeleteObject(m_hbmpMask); m_hbmpMask = NULL; }
::SysFreeString(m_bstrText); m_bstrText = NULL;}
BOOL CCicLibMenuItem::Init( UINT uId, DWORD dwFlags, HBITMAP hbmp, HBITMAP hbmpMask, const WCHAR *pch, ULONG cch, ITfMenu *pMenu){ m_uId = uId; m_dwFlags = dwFlags; m_bstrText = ::SysAllocStringLen(pch, cch); if (!m_bstrText && cch) return FALSE;
m_pMenu = pMenu; m_hbmp = CreateBitmap(hbmp); m_hbmpMask = CreateBitmap(hbmpMask); if (hbmp) ::DeleteObject(hbmp); if (hbmpMask) ::DeleteObject(hbmpMask);
return TRUE;}
HBITMAP CCicLibMenuItem::CreateBitmap(HANDLE hBitmap){ if (!hBitmap) return NULL;
HDC hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); if (!hDC) return NULL;
HBITMAP hbmMem = NULL;
BITMAP bm; ::GetObject(hBitmap, sizeof(bm), &bm);
HGDIOBJ hbmOld1 = NULL; HDC hdcMem1 = ::CreateCompatibleDC(hDC); if (hdcMem1) hbmOld1 = ::SelectObject(hdcMem1, hBitmap);
HGDIOBJ hbmOld2 = NULL; HDC hdcMem2 = ::CreateCompatibleDC(hDC); if (hdcMem2) { hbmMem = ::CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); hbmOld2 = ::SelectObject(hdcMem2, hbmMem); }
::BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY);
if (hbmOld1) ::SelectObject(hdcMem1, hbmOld1); if (hbmOld2) ::SelectObject(hdcMem2, hbmOld2);
::DeleteDC(hDC); if (hdcMem1) ::DeleteDC(hdcMem1); if (hdcMem2) ::DeleteDC(hdcMem2);
return hbmMem;}
/*********************************************************************** * CTipbarAccessible */
CTipbarAccessible::CTipbarAccessible(CTipbarAccItem *pItem){ m_cRefs = 1; m_hWnd = NULL; m_pTypeInfo = NULL; m_pStdAccessible = NULL; m_bInitialized = FALSE; m_cSelection = 1; m_AccItems.Add(pItem); ++g_DllRefCount;}
CTipbarAccessible::~CTipbarAccessible(){ m_pTypeInfo = m_pTypeInfo; if (m_pTypeInfo) { m_pTypeInfo->Release(); m_pTypeInfo = NULL; } if (m_pStdAccessible) { m_pStdAccessible->Release(); m_pStdAccessible = NULL; } --g_DllRefCount;}
HRESULT CTipbarAccessible::Initialize(){ m_bInitialized = TRUE;
HRESULT hr = ::CreateStdAccessibleObject(m_hWnd, OBJID_CLIENT, IID_IAccessible, (void **)&m_pStdAccessible); if (FAILED(hr)) return hr;
ITypeLib *pTypeLib; hr = ::LoadRegTypeLib(LIBID_Accessibility, 1, 0, 0, &pTypeLib); if (FAILED(hr)) hr = ::LoadTypeLib(L"OLEACC.DLL", &pTypeLib);
if (SUCCEEDED(hr)) { hr = pTypeLib->GetTypeInfoOfGuid(IID_IAccessible, &m_pTypeInfo); pTypeLib->Release(); }
return hr;}
BOOL CTipbarAccessible::AddAccItem(CTipbarAccItem *pItem){ return m_AccItems.Add(pItem);}
HRESULT CTipbarAccessible::RemoveAccItem(CTipbarAccItem *pItem){ for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem) { if (m_AccItems[iItem] == pItem) { m_AccItems.Remove(iItem, 1); break; } } return S_OK;}
void CTipbarAccessible::ClearAccItems(){ m_AccItems.clear();}
CTipbarAccItem *CTipbarAccessible::AccItemFromID(INT iItem){ if (iItem < 0 || (INT)m_AccItems.size() <= iItem) return NULL; return m_AccItems[iItem];}
INT CTipbarAccessible::GetIDOfItem(CTipbarAccItem *pTarget){ for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem) { if (pTarget == m_AccItems[iItem]) return (INT)iItem; } return -1;}
LONG_PTR CTipbarAccessible::CreateRefToAccObj(WPARAM wParam){ return ::LresultFromObject(IID_IAccessible, wParam, this);}
BOOL CTipbarAccessible::DoDefaultActionReal(INT nID){ CTipbarAccItem *pItem = AccItemFromID(nID); if (!pItem) return FALSE; return pItem->DoAccDefaultActionReal();}
void CTipbarAccessible::NotifyWinEvent(DWORD event, CTipbarAccItem *pItem){ INT nID = GetIDOfItem(pItem); if (nID < 0) return;
::NotifyWinEvent(event, m_hWnd, -4, nID);}
void CTipbarAccessible::SetWindow(HWND hWnd){ m_hWnd = hWnd;}
STDMETHODIMP CTipbarAccessible::QueryInterface( REFIID riid, void **ppvObject){ static const QITAB c_tab[] = { QITABENT(CTipbarAccessible, IDispatch), QITABENT(CTipbarAccessible, IAccessible), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObject);}
STDMETHODIMP_(ULONG) CTipbarAccessible::AddRef(){ return ::InterlockedIncrement(&m_cRefs);}
STDMETHODIMP_(ULONG) CTipbarAccessible::Release(){ LONG count = ::InterlockedDecrement(&m_cRefs); if (count == 0) { delete this; return 0; } return count;}
STDMETHODIMP CTipbarAccessible::GetTypeInfoCount(UINT *pctinfo){ if (!pctinfo) return E_INVALIDARG; *pctinfo = (m_pTypeInfo == NULL); return S_OK;}
STDMETHODIMP CTipbarAccessible::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo){ if (!ppTInfo) return E_INVALIDARG; *ppTInfo = NULL; if (iTInfo != 0) return TYPE_E_ELEMENTNOTFOUND; if (!m_pTypeInfo) return E_NOTIMPL; *ppTInfo = m_pTypeInfo; m_pTypeInfo->AddRef(); return S_OK;}
STDMETHODIMP CTipbarAccessible::GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId){ if (!m_pTypeInfo) return E_NOTIMPL; return m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId);}
STDMETHODIMP CTipbarAccessible::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr){ if (!m_pTypeInfo) return E_NOTIMPL; return m_pTypeInfo->Invoke(this, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);}
STDMETHODIMP CTipbarAccessible::get_accParent(IDispatch **ppdispParent){ return m_pStdAccessible->get_accParent(ppdispParent);}
STDMETHODIMP CTipbarAccessible::get_accChildCount(LONG *pcountChildren){ if (!pcountChildren) return E_INVALIDARG; INT cItems = (INT)m_AccItems.size(); if (!cItems) return E_FAIL; *pcountChildren = cItems - 1; return S_OK;}
STDMETHODIMP CTipbarAccessible::get_accChild( VARIANT varChildID, IDispatch **ppdispChild){ if (!ppdispChild) return E_INVALIDARG; *ppdispChild = NULL; return S_FALSE;}
STDMETHODIMP CTipbarAccessible::get_accName( VARIANT varID, BSTR *pszName){ if (!pszName) return E_INVALIDARG; CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); if (!pItem) return E_INVALIDARG; *pszName = pItem->GetAccName(); if (!*pszName) return DISP_E_MEMBERNOTFOUND; return S_OK;}
STDMETHODIMP CTipbarAccessible::get_accValue( VARIANT varID, BSTR *pszValue){ if (!pszValue) return E_INVALIDARG; CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); if (!pItem) return E_INVALIDARG; *pszValue = pItem->GetAccValue(); if (!*pszValue) return DISP_E_MEMBERNOTFOUND; return S_OK;}
STDMETHODIMP CTipbarAccessible::get_accDescription( VARIANT varID, BSTR *description){ if (!description) return E_INVALIDARG; return m_pStdAccessible->get_accDescription(varID, description);}
STDMETHODIMP CTipbarAccessible::get_accRole( VARIANT varID, VARIANT *role){ if (!role) return E_INVALIDARG; CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); if (!pItem) return E_INVALIDARG; V_VT(role) = VT_I4; V_I4(role) = pItem->GetAccRole(); return S_OK;}
STDMETHODIMP CTipbarAccessible::get_accState( VARIANT varID, VARIANT *state){ if (!state) return E_INVALIDARG; CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); if (!pItem) return E_INVALIDARG; V_VT(state) = VT_I4; V_I4(state) = pItem->GetAccState(); return S_OK;}
STDMETHODIMP CTipbarAccessible::get_accHelp(VARIANT varID, BSTR *help){ return DISP_E_MEMBERNOTFOUND;}
STDMETHODIMP CTipbarAccessible::get_accHelpTopic( BSTR *helpfile, VARIANT varID, LONG *pidTopic){ return DISP_E_MEMBERNOTFOUND;}
STDMETHODIMP CTipbarAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *shortcut){ return DISP_E_MEMBERNOTFOUND;}
STDMETHODIMP CTipbarAccessible::get_accFocus(VARIANT *pvarID){ if (!pvarID) return E_INVALIDARG; V_VT(pvarID) = VT_EMPTY; return S_FALSE;}
STDMETHODIMP CTipbarAccessible::get_accSelection(VARIANT *pvarID){ if (!pvarID) return E_INVALIDARG;
V_VT(pvarID) = VT_EMPTY;
INT cItems = (INT)m_AccItems.size(); if (cItems < m_cSelection) return S_FALSE;
if (cItems > m_cSelection) { V_VT(pvarID) = VT_I4; V_I4(pvarID) = m_cSelection; }
return S_OK;}
STDMETHODIMP CTipbarAccessible::get_accDefaultAction( VARIANT varID, BSTR *action){ if (!action) return E_INVALIDARG; *action = NULL;
if (V_VT(&varID) != VT_I4) return E_INVALIDARG;
CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); if (!pItem) return DISP_E_MEMBERNOTFOUND; *action = pItem->GetAccDefaultAction(); if (!*action) return S_FALSE; return S_OK;}
STDMETHODIMP CTipbarAccessible::accSelect( LONG flagsSelect, VARIANT varID){ if ((flagsSelect & SELFLAG_ADDSELECTION) && (flagsSelect & SELFLAG_REMOVESELECTION)) return E_INVALIDARG; if (flagsSelect & (SELFLAG_TAKEFOCUS | SELFLAG_ADDSELECTION | SELFLAG_EXTENDSELECTION)) return S_FALSE; if (flagsSelect & SELFLAG_REMOVESELECTION) return S_OK; if (V_VT(&varID) != VT_I4) return E_INVALIDARG; if (flagsSelect & SELFLAG_TAKESELECTION) { m_cSelection = V_I4(&varID); return S_OK; } return S_FALSE;}
STDMETHODIMP CTipbarAccessible::accLocation( LONG *left, LONG *top, LONG *width, LONG *height, VARIANT varID){ if (!left || !top || !width || !height) return E_INVALIDARG;
if (!V_I4(&varID)) return m_pStdAccessible->accLocation(left, top, width, height, varID);
RECT rc; CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); pItem->GetAccLocation(&rc);
*left = rc.left; *top = rc.top; *width = rc.right - rc.left; *height = rc.bottom - rc.top; return S_OK;}
STDMETHODIMP CTipbarAccessible::accNavigate( LONG dir, VARIANT varStart, VARIANT *pvarEnd){ if (m_AccItems.size() <= 1) { V_VT(pvarEnd) = VT_EMPTY; return S_OK; }
switch (dir) { case NAVDIR_UP: case NAVDIR_LEFT: case NAVDIR_PREVIOUS: V_VT(pvarEnd) = VT_I4; V_I4(pvarEnd) = V_I4(&varStart) - 1; if (V_I4(&varStart) - 1 <= 0) V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1); return S_OK;
case NAVDIR_DOWN: case NAVDIR_RIGHT: case NAVDIR_NEXT: V_VT(pvarEnd) = VT_I4; V_I4(pvarEnd) = V_I4(&varStart) + 1; if ((INT)m_AccItems.size() <= V_I4(&varStart) + 1) V_I4(pvarEnd) = 1; return S_OK;
case NAVDIR_FIRSTCHILD: V_VT(pvarEnd) = VT_I4; V_I4(pvarEnd) = 1; return S_OK;
case NAVDIR_LASTCHILD: V_VT(pvarEnd) = VT_I4; V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1); return S_OK;
default: break; }
V_VT(pvarEnd) = VT_EMPTY; return S_OK;}
STDMETHODIMP CTipbarAccessible::accHitTest(LONG left, LONG top, VARIANT *pvarID){ if (!pvarID) return E_INVALIDARG; POINT Point = { left, top }; RECT Rect; ::ScreenToClient(m_hWnd, &Point); ::GetClientRect(m_hWnd, &Rect);
if (!::PtInRect(&Rect, Point)) { V_VT(pvarID) = VT_EMPTY; return S_OK; }
V_VT(pvarID) = VT_I4; V_I4(pvarID) = 0;
for (size_t iItem = 1; iItem < m_AccItems.size(); ++iItem) { CTipbarAccItem *pItem = m_AccItems[iItem]; if (pItem) { pItem->GetAccLocation(&Rect); if (::PtInRect(&Rect, Point)) { V_I4(pvarID) = iItem; break; } } }
return S_OK;}
STDMETHODIMP CTipbarAccessible::accDoDefaultAction(VARIANT varID){ if (V_VT(&varID) != VT_I4) return E_INVALIDARG; CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); if (!pItem) return DISP_E_MEMBERNOTFOUND; return (pItem->DoAccDefaultAction() ? S_OK : S_FALSE);}
STDMETHODIMP CTipbarAccessible::put_accName(VARIANT varID, BSTR name){ return S_FALSE;}
STDMETHODIMP CTipbarAccessible::put_accValue(VARIANT varID, BSTR value){ return S_FALSE;}
/*********************************************************************** * CUTBMenuWnd */
CUTBMenuWnd::CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14) : CUIFMenu(hInst, style, dwUnknown14){}
BOOL CUTBMenuWnd::StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget){ if (!m_pAccessible) return FALSE;
m_nMenuWndID = m_pAccessible->GetIDOfItem(pTarget); if (!m_nMenuWndID || m_nMenuWndID == (UINT)-1) return FALSE;
if (::IsWindow(m_hWnd)) { ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); ::SetTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION, g_uTimerElapseDOACCDEFAULTACTION, NULL); }
return TRUE;}
STDMETHODIMP_(BSTR) CUTBMenuWnd::GetAccName(){ WCHAR szText[64]; LoadStringW(g_hInst, IDS_MENUWND, szText, _countof(szText)); return ::SysAllocString(szText);}
STDMETHODIMP_(INT) CUTBMenuWnd::GetAccRole(){ return 9;}
STDMETHODIMP_(BOOL) CUTBMenuWnd::Initialize(){ CTipbarAccessible *pAccessible = new(cicNoThrow) CTipbarAccessible(GetAccItem()); if (pAccessible) m_pAccessible = pAccessible;
return CUIFObject::Initialize();}
STDMETHODIMP_(void) CUTBMenuWnd::OnCreate(HWND hWnd){ if (m_pAccessible) m_pAccessible->SetWindow(hWnd);}
STDMETHODIMP_(void) CUTBMenuWnd::OnDestroy(HWND hWnd){ if (m_pAccessible) { m_pAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem()); m_pAccessible->ClearAccItems(); m_pAccessible->Release(); m_pAccessible = NULL; } m_coInit.CoUninit();}
STDMETHODIMP_(HRESULT)CUTBMenuWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (lParam != -4) return S_OK;
if (!m_pAccessible) return E_OUTOFMEMORY;
if (m_pAccessible->m_bInitialized) return m_pAccessible->CreateRefToAccObj(wParam);
if (SUCCEEDED(m_coInit.EnsureCoInit())) { HRESULT hr = m_pAccessible->Initialize(); if (FAILED(hr)) { m_pAccessible->Release(); m_pAccessible = NULL; return hr; }
m_pAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem()); return m_pAccessible->CreateRefToAccObj(wParam); }
return S_OK;}
STDMETHODIMP_(LRESULT)CUTBMenuWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (m_pAccessible) { if (wParam) { m_pAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem()); m_pAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem()); } else { m_pAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem()); } }
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);}
STDMETHODIMP_(void) CUTBMenuWnd::OnTimer(WPARAM wParam){ if (wParam == TIMER_ID_DOACCDEFAULTACTION) { ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); if (m_pAccessible && m_nMenuWndID) { m_pAccessible->DoDefaultActionReal(m_nMenuWndID); m_nMenuWndID = 0; } }}
/*********************************************************************** * CUTBMenuItem */
CUTBMenuItem::CUTBMenuItem(CUTBMenuWnd *pMenuUI) : CUIFMenuItem(pMenuUI ? pMenuUI->GetMenu() : NULL){ m_pMenuUI = pMenuUI;}
CUTBMenuItem::~CUTBMenuItem(){ if (m_hbmColor) { ::DeleteObject(m_hbmColor); m_hbmColor = NULL; } if (m_hbmMask) { ::DeleteObject(m_hbmMask); m_hbmMask = NULL; }}
STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultAction(){ if (!m_pMenuUI) return FALSE;
m_pMenuUI->StartDoAccDefaultActionTimer(this); return TRUE;}
STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultActionReal(){ if (!m_pSubMenu) OnLButtonUp(0, 0); else ShowSubPopup(); return TRUE;}
STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccDefaultAction(){ WCHAR szText[64]; ::LoadStringW(g_hInst, IDS_LEFTCLICK, szText, _countof(szText)); return ::SysAllocString(szText);}
STDMETHODIMP_(void) CUTBMenuItem::GetAccLocation(LPRECT lprc){ GetRect(lprc); ::ClientToScreen(m_pMenuUI->m_hWnd, (LPPOINT)lprc); ::ClientToScreen(m_pMenuUI->m_hWnd, (LPPOINT)&lprc->right);}
STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccName(){ return ::SysAllocString(m_pszMenuItemLeft);}
/// @unimplementedSTDMETHODIMP_(INT) CUTBMenuItem::GetAccRole(){ if (FALSE) //FIXME return 21; return 12;}
/*********************************************************************** * CModalMenu */
CUTBMenuItem *CModalMenu::InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID){ CUTBMenuItem *pMenuItem = new(cicNoThrow) CUTBMenuItem(pMenuUI); if (!pMenuItem) return NULL;
WCHAR szText[256]; ::LoadStringW(g_hInst, nStringID, szText, _countof(szText));
if (pMenuItem->Initialize() && pMenuItem->Init(nCommandId, szText) && pMenuUI->InsertItem(pMenuItem)) { return pMenuItem; }
delete pMenuItem; return NULL;}
void CModalMenu::PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam){ m_pMenuUI->PostKey(bUp, wParam, lParam);}
void CModalMenu::CancelMenu(){ if (m_pMenuUI) m_pMenuUI->CancelMenu();}
/*********************************************************************** * CUTBContextMenu */
CUTBContextMenu::CUTBContextMenu(CTipbarWnd *pTipbarWnd){ m_pTipbarWnd = pTipbarWnd;}
/// @implementedBOOL CUTBContextMenu::Init(){ m_pTipbarThread = m_pTipbarWnd->m_pFocusThread; return !!m_pTipbarThread;}
/// @unimplementedCUTBMenuWnd *CUTBContextMenu::CreateMenuUI(BOOL bFlag){ DWORD dwStatus = 0;
if (FAILED(m_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus))) return NULL;
CUTBMenuWnd *pMenuUI = new (cicNoThrow) CUTBMenuWnd(g_hInst, g_dwMenuStyle, 0); if (!pMenuUI) return NULL;
pMenuUI->Initialize();
if (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED)) { CUTBMenuItem *pRestoreLangBar = InsertItem(pMenuUI, ID_RESTORELANGBAR, IDS_RESTORELANGBAR2); if (pRestoreLangBar && !m_pTipbarWnd->m_dwUnknown20) pRestoreLangBar->Gray(TRUE); } else { InsertItem(pMenuUI, ID_DESKBAND, IDS_MINIMIZE);
if (bFlag) { if (IsTransparecyAvailable()) { if (dwStatus & TF_LBI_BALLOON) { InsertItem(pMenuUI, ID_TRANS, IDS_TRANSPARENCY); } else { CUTBMenuItem *pTransparency = InsertItem(pMenuUI, ID_NOTRANS, IDS_TRANSPARENCY); if (pTransparency) pTransparency->Check(TRUE); } }
if (!(dwStatus & TF_SFT_LABELS)) { InsertItem(pMenuUI, ID_LABELS, IDS_TEXTLABELS); } else { CUTBMenuItem *pTextLabels = InsertItem(pMenuUI, ID_NOLABELS, IDS_TEXTLABELS); if (pTextLabels) pTextLabels->Check(TRUE); }
CUTBMenuItem *pVertical = InsertItem(pMenuUI, ID_VERTICAL, IDS_VERTICAL); if (pVertical) pVertical->Check(!!(m_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_VERTICAL)); } }
if (bFlag) { CUTBMenuItem *pExtraIcons = NULL;
if (dwStatus & TF_SFT_EXTRAICONSONMINIMIZED) { pExtraIcons = InsertItem(pMenuUI, ID_NOEXTRAICONS, IDS_EXTRAICONS); if (pExtraIcons) pExtraIcons->Check(TRUE); } else { pExtraIcons = CModalMenu::InsertItem(pMenuUI, ID_EXTRAICONS, IDS_EXTRAICONS); }
if (pExtraIcons) { if (::GetKeyboardLayoutList(0, NULL) == 1) { pExtraIcons->Check(TRUE); pExtraIcons->Gray(TRUE); } else { pExtraIcons->Gray(FALSE); } }
if (dwStatus & TF_SFT_DESKBAND) InsertItem(pMenuUI, ID_ADJUSTDESKBAND, IDS_ADJUSTLANGBAND);
InsertItem(pMenuUI, ID_SETTINGS, IDS_SETTINGS);
if (CheckCloseMenuAvailable()) InsertItem(pMenuUI, ID_CLOSELANGBAR, IDS_CLOSELANGBAR); }
return pMenuUI;}
UINTCUTBContextMenu::ShowPopup( CUIFWindow *pWindow, POINT pt, LPCRECT prc, BOOL bFlag){ if (g_bWinLogon) return 0;
if (m_pMenuUI) return -1;
m_pMenuUI = CreateMenuUI(bFlag); if (!m_pMenuUI) return 0;
UINT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prc, TRUE);
if (m_pMenuUI) { delete m_pMenuUI; m_pMenuUI = NULL; }
return nCommandId;}
/// @unimplementedBOOL CUTBContextMenu::SelectMenuItem(UINT nCommandId){ switch (nCommandId) { case ID_TRANS: m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LOWTRANSPARENCY); break;
case ID_NOTRANS: m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOTRANSPARENCY); break;
case ID_LABELS: m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LABELS); break;
case ID_NOLABELS: m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOLABELS); break;
case ID_DESKBAND: { if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) { m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_MINIMIZED); } else { DWORD dwStatus; m_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus);
if (dwStatus & TF_SFT_DESKBAND) break;
m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND); }
CUTBMinimizeLangBarDlg *pDialog = new(cicNoThrow) CUTBMinimizeLangBarDlg(); if (pDialog) { pDialog->DoModal(*m_pTipbarWnd->GetWindow()); pDialog->_Release(); } break; }
case ID_CLOSELANGBAR: { CUTBCloseLangBarDlg *pDialog = new(cicNoThrow) CUTBCloseLangBarDlg(); if (pDialog) { BOOL bOK = pDialog->DoModal(*m_pTipbarWnd->GetWindow()); pDialog->_Release(); if (!bOK) DoCloseLangbar(); } break; }
case ID_EXTRAICONS: m_pTipbarWnd->m_dwTipbarWndFlags &= ~TIPBAR_NODESKBAND; m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_EXTRAICONSONMINIMIZED); break;
case ID_NOEXTRAICONS: m_pTipbarWnd->m_dwTipbarWndFlags &= ~TIPBAR_NODESKBAND; m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOEXTRAICONSONMINIMIZED); break;
case ID_RESTORELANGBAR: m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_LBI_ICON); break;
case ID_VERTICAL: m_pTipbarWnd->SetVertical(!!(m_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_VERTICAL)); break;
case ID_ADJUSTDESKBAND: m_pTipbarWnd->AdjustDeskBandSize(TRUE); break;
case ID_SETTINGS: TF_RunInputCPL(); break;
default: break; }
return TRUE;}
/*********************************************************************** * CTrayIconItem */
CTrayIconItem::CTrayIconItem(CTrayIconWnd *pTrayIconWnd){ m_dwIconAddOrModify = NIM_ADD; m_pTrayIconWnd = pTrayIconWnd;}
BOOLCTrayIconItem::_Init( HWND hWnd, UINT uCallbackMessage, UINT uNotifyIconID, const GUID& rguid){ m_hWnd = hWnd; m_uCallbackMessage = uCallbackMessage; m_uNotifyIconID = uNotifyIconID; m_guid = rguid; return TRUE;}
BOOL CTrayIconItem::RemoveIcon(){ if (m_dwIconAddOrModify == NIM_MODIFY) { NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; NotifyIcon.uCallbackMessage = m_uCallbackMessage; ::Shell_NotifyIconW(NIM_DELETE, &NotifyIcon); }
m_dwIconAddOrModify = NIM_ADD; m_bIconAdded = TRUE; return TRUE;}
BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCWSTR pszTip){ if (!hIcon) return FALSE;
NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE; NotifyIcon.uCallbackMessage = m_uCallbackMessage; NotifyIcon.hIcon = hIcon; if (pszTip) { NotifyIcon.uFlags |= NIF_TIP; StringCchCopyW(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip); }
::Shell_NotifyIconW(m_dwIconAddOrModify, &NotifyIcon);
m_dwIconAddOrModify = NIM_MODIFY; m_bIconAdded = NIM_MODIFY; return TRUE;}
BOOL CTrayIconItem::UpdateMenuRectPoint(){ HWND hNotifyWnd = m_pTrayIconWnd->GetNotifyWnd(); ::GetClientRect(hNotifyWnd, &m_rcMenu); ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu); ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu.right); ::GetCursorPos(&m_ptCursor); return TRUE;}
/*********************************************************************** * CButtonIconItem */
CButtonIconItem::CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24) : CTrayIconItem(pWnd){ m_dwUnknown24 = dwUnknown24;}
/// @unimplementedSTDMETHODIMP_(BOOL) CButtonIconItem::OnMsg(WPARAM wParam, LPARAM lParam){ switch (lParam) { case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: break; default: return TRUE; }
//FIXME return TRUE;}
/// @unimplementedSTDMETHODIMP_(BOOL) CButtonIconItem::OnDelayMsg(UINT uMsg){ //FIXME return FALSE;}
/*********************************************************************** * CMainIconItem */
/// @implementedCMainIconItem::CMainIconItem(CTrayIconWnd *pWnd) : CButtonIconItem(pWnd, 1){}
/// @implementedBOOL CMainIconItem::Init(HWND hWnd){ return CTrayIconItem::_Init(hWnd, WM_USER, 0, GUID_LBI_TRAYMAIN);}
/// @implementedSTDMETHODIMP_(BOOL) CMainIconItem::OnDelayMsg(UINT uMsg){ if (!CButtonIconItem::OnDelayMsg(uMsg)) return 0;
if (uMsg == WM_LBUTTONDBLCLK) { if (g_pTipbarWnd->m_dwUnknown20) g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); } else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN) { g_pTipbarWnd->ShowContextMenu(m_ptCursor, &m_rcMenu, uMsg == WM_RBUTTONDOWN); } return TRUE;}
/*********************************************************************** * CTrayIconWnd */
CTrayIconWnd::CTrayIconWnd(){ m_uCallbackMsg = WM_USER + 0x1000; m_uNotifyIconID = 0x1000;}
CTrayIconWnd::~CTrayIconWnd(){ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) { auto& pItem = m_Items[iItem]; if (pItem) { delete pItem; pItem = NULL; } }}
void CTrayIconWnd::CallOnDelayMsg(){ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) { auto pItem = m_Items[iItem]; if (pItem && m_uCallbackMessage == pItem->m_uCallbackMessage) { pItem->OnDelayMsg(m_uMsg); break; } }}
HWND CTrayIconWnd::CreateWnd(){ m_hWnd = ::CreateWindowEx(0, TEXT("CTrayIconWndClass"), NULL, WS_DISABLED, 0, 0, 0, 0, NULL, NULL, g_hInst, this); FindTrayEtc();
m_pMainIconItem = new(cicNoThrow) CMainIconItem(this); if (m_pMainIconItem) { m_pMainIconItem->Init(m_hWnd); m_Items.Add(m_pMainIconItem); }
return m_hWnd;}
void CTrayIconWnd::DestroyWnd(){ ::DestroyWindow(m_hWnd); m_hWnd = NULL;}
BOOL CALLBACK CTrayIconWnd::EnumChildWndProc(HWND hWnd, LPARAM lParam){ CTrayIconWnd *pWnd = (CTrayIconWnd *)lParam;
TCHAR ClassName[60]; ::GetClassName(hWnd, ClassName, _countof(ClassName)); if (lstrcmp(ClassName, TEXT("TrayNotifyWnd")) != 0) return TRUE;
pWnd->m_hNotifyWnd = hWnd; return FALSE;}
CButtonIconItem *CTrayIconWnd::FindIconItem(REFGUID rguid){ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) { auto pItem = m_Items[iItem]; if (IsEqualGUID(rguid, pItem->m_guid)) return pItem; } return NULL;}
BOOL CTrayIconWnd::FindTrayEtc(){ m_hTrayWnd = ::FindWindow(TEXT("Shell_TrayWnd"), NULL); if (!m_hTrayWnd) return FALSE;
::EnumChildWindows(m_hTrayWnd, EnumChildWndProc, (LPARAM)this); if (!m_hNotifyWnd) return FALSE; m_dwTrayWndThreadId = ::GetWindowThreadProcessId(m_hTrayWnd, NULL); m_hwndProgman = FindWindow(TEXT("Progman"), NULL); m_dwProgmanThreadId = ::GetWindowThreadProcessId(m_hwndProgman, NULL); return TRUE;}
HWND CTrayIconWnd::GetNotifyWnd(){ if (!::IsWindow(m_hNotifyWnd)) FindTrayEtc(); return m_hNotifyWnd;}
/// @implementedBOOL CTrayIconWnd::OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){ if (g_pTipbarWnd) g_pTipbarWnd->AttachFocusThread();
for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) { auto *pItem = m_Items[iItem]; if (pItem) { if (uMsg == pItem->m_uCallbackMessage) { pItem->OnMsg(wParam, lParam); return TRUE; } } } return FALSE;}
BOOL CTrayIconWnd::RegisterClass(){ WNDCLASSEX wc = { sizeof(wc) }; wc.style = CS_HREDRAW | CS_VREDRAW; wc.hInstance = g_hInst; wc.hCursor = ::LoadCursor(NULL, (LPCTSTR)IDC_ARROW); wc.lpfnWndProc = CTrayIconWnd::_WndProc; wc.lpszClassName = TEXT("CTrayIconWndClass"); ::RegisterClassEx(&wc); return TRUE;}
void CTrayIconWnd::RemoveAllIcon(DWORD dwFlags){ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) { auto pItem = m_Items[iItem]; if (dwFlags & 0x1) { if (IsEqualGUID(pItem->m_guid, GUID_LBI_INATITEM) || IsEqualGUID(pItem->m_guid, GUID_LBI_CTRL)) { continue; } }
if (dwFlags & 0x2) { if (IsEqualGUID(pItem->m_guid, GUID_TFCAT_TIP_KEYBOARD)) continue; }
if (pItem->m_uNotifyIconID < 0x1000) continue;
pItem->RemoveIcon(); }}
/// @unimplementedvoid CTrayIconWnd::RemoveUnusedIcons(int unknown){ //FIXME}
BOOL CTrayIconWnd::SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz){ CButtonIconItem *pItem = FindIconItem(rguid); if (!pItem) { if (!hIcon) return FALSE; pItem = new(cicNoThrow) CButtonIconItem(this, dwUnknown24); if (!pItem) return FALSE;
pItem->_Init(m_hWnd, m_uCallbackMsg, m_uNotifyIconID, rguid); m_uCallbackMsg += 2; ++m_uNotifyIconID; m_Items.Add(pItem); }
if (!hIcon) return pItem->RemoveIcon();
return pItem->SetIcon(hIcon, psz);}
BOOL CTrayIconWnd::SetMainIcon(HKL hKL){ if (!hKL) { m_pMainIconItem->RemoveIcon(); m_pMainIconItem->m_hKL = NULL; return TRUE; }
if (hKL != m_pMainIconItem->m_hKL) { WCHAR szText[64]; HICON hIcon = TF_GetLangIcon(LOWORD(hKL), szText, _countof(szText)); if (hIcon) { m_pMainIconItem->SetIcon(hIcon, szText); ::DestroyIcon(hIcon); } else { ::LoadStringW(g_hInst, IDS_RESTORELANGBAR, szText, _countof(szText)); hIcon = ::LoadIconW(g_hInst, MAKEINTRESOURCEW(IDI_MAINICON)); m_pMainIconItem->SetIcon(hIcon, szText); }
m_pMainIconItem->m_hKL = hKL; }
return TRUE;}
CTrayIconWnd *CTrayIconWnd::GetThis(HWND hWnd){ return (CTrayIconWnd *)::GetWindowLongPtr(hWnd, GWL_USERDATA);}
void CTrayIconWnd::SetThis(HWND hWnd, LPCREATESTRUCT pCS){ if (pCS) ::SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)pCS->lpCreateParams); else ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0);}
LRESULT CALLBACKCTrayIconWnd::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ CTrayIconWnd *pThis; switch (uMsg) { case WM_CREATE: CTrayIconWnd::SetThis(hWnd, (LPCREATESTRUCT)lParam); break; case WM_DESTROY: ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0); break; case WM_TIMER: if (wParam == 100) { ::KillTimer(hWnd, 100); pThis = CTrayIconWnd::GetThis(hWnd); if (pThis) pThis->CallOnDelayMsg(); } break; default: { if (uMsg < WM_USER) return ::DefWindowProc(hWnd, uMsg, wParam, lParam); pThis = CTrayIconWnd::GetThis(hWnd); if (pThis && pThis->OnIconMessage(uMsg, wParam, lParam)) break; return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } } return 0;}
/*********************************************************************** * CLBarItemBase */
CLBarItemBase::CLBarItemBase(){ m_dwItemStatus = 0; m_szToolTipText[0] = 0; m_cRefs = 1; m_pLangBarItemSink = NULL;}
CLBarItemBase::~CLBarItemBase(){ if (m_pLangBarItemSink) m_pLangBarItemSink->Release();}
HRESULTCLBarItemBase::AdviseSink( REFIID riid, IUnknown *punk, DWORD *pdwCookie){ if (IsEqualIID(riid, IID_ITfLangBarItemSink) || m_pLangBarItemSink) return TF_E_NOOBJECT;
HRESULT hr = punk->QueryInterface(IID_ITfLangBarItemSink, (void **)&m_pLangBarItemSink); if (SUCCEEDED(hr)) *pdwCookie = 0x80000001; return hr;}
HRESULT CLBarItemBase::UnadviseSink(DWORD dwCookie){ if (dwCookie != 0x80000001) return E_FAIL;
if (!m_pLangBarItemSink) return E_UNEXPECTED;
m_pLangBarItemSink->Release(); m_pLangBarItemSink = NULL; return S_OK;}
voidCLBarItemBase::InitNuiInfo( REFIID clsidService, REFGUID guidItem, DWORD dwStyle, DWORD ulSort, LPCWSTR Source){ m_NewUIInfo.clsidService = clsidService; m_NewUIInfo.guidItem = guidItem; m_NewUIInfo.dwStyle = dwStyle; m_NewUIInfo.ulSort = ulSort; StringCchCopyW(m_NewUIInfo.szDescription, _countof(m_NewUIInfo.szDescription), Source);}
HRESULTCLBarItemBase::ShowInternal(BOOL bShow, BOOL bUpdate){ DWORD dwOldStatus = m_dwItemStatus;
if (bShow) m_dwItemStatus &= ~TF_LBI_STATUS_HIDDEN; else m_dwItemStatus |= TF_LBI_STATUS_HIDDEN;
if (bUpdate && (dwOldStatus != m_dwItemStatus)) { if (m_pLangBarItemSink) m_pLangBarItemSink->OnUpdate(TF_LBI_STATUS); }
return S_OK;}
HRESULT CLBarItemBase::GetInfo(TF_LANGBARITEMINFO *pInfo){ CopyMemory(pInfo, &m_NewUIInfo, sizeof(*pInfo)); return S_OK;}
HRESULT CLBarItemBase::GetStatus(DWORD *pdwStatus){ *pdwStatus = m_dwItemStatus; return S_OK;}
HRESULT CLBarItemBase::Show(BOOL fShow){ return ShowInternal(fShow, TRUE);}
HRESULT CLBarItemBase::GetTooltipString(BSTR *pbstrToolTip){ if (!pbstrToolTip) return E_INVALIDARG; BSTR bstr = ::SysAllocString(m_szToolTipText); *pbstrToolTip = bstr; return bstr ? S_OK : E_OUTOFMEMORY;}
/*********************************************************************** * CUTBLBarMenu */
CUTBLBarMenu::CUTBLBarMenu(HINSTANCE hInst) : CCicLibMenu(){ m_hInst = hInst;}
CUTBLBarMenu::~CUTBLBarMenu(){}
STDMETHODIMP_(CCicLibMenuItem*) CUTBLBarMenu::CreateMenuItem(){ CUTBLBarMenuItem *pItem = new(cicNoThrow) CUTBLBarMenuItem(); if (!pItem) return NULL; pItem->m_pLBarMenu = this; return pItem;}
CUTBMenuWnd *CUTBLBarMenu::CreateMenuUI(){ CUTBMenuWnd *pMenuUI = new(cicNoThrow) CUTBMenuWnd(m_hInst, g_dwMenuStyle, 0); if (!pMenuUI) return NULL;
pMenuUI->Initialize(); for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) { CUTBLBarMenuItem *pItem = (CUTBLBarMenuItem *)m_MenuItems[iItem]; pItem->InsertToUI(pMenuUI); }
return pMenuUI;}
STDMETHODIMP_(CCicLibMenu*) CUTBLBarMenu::CreateSubMenu(){ return new(cicNoThrow) CUTBLBarMenu(m_hInst);}
INT CUTBLBarMenu::ShowPopup(CUIFWindow *pWindow, POINT pt, LPCRECT prcExclude){ if (m_pMenuUI) return 0;
m_pMenuUI = CreateMenuUI(); if (!m_pMenuUI) return -1;
INT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prcExclude, TRUE);
if (m_pMenuUI) { delete m_pMenuUI; m_pMenuUI = NULL; }
return nCommandId;}
/*********************************************************************** * CUTBLBarMenuItem */
/// @unimplementedBOOL CUTBLBarMenuItem::InsertToUI(CUTBMenuWnd *pMenuUI){ if ((m_dwFlags & 4) != 0) { pMenuUI->InsertSeparator(); return TRUE; } if (m_dwFlags & 2) { //FIXME } else { //FIXME } return FALSE;}
/*********************************************************************** * CLBarItemButtonBase */
CLBarItemButtonBase::~CLBarItemButtonBase(){ if (m_hIcon) { ::DestroyIcon(m_hIcon); m_hIcon = NULL; }}
STDMETHODIMP CLBarItemButtonBase::QueryInterface(REFIID riid, void **ppvObject){ static const QITAB c_tab[] = { QITABENT(CLBarItemButtonBase, ITfLangBarItem), QITABENT(CLBarItemButtonBase, ITfLangBarItemButton), QITABENT(CLBarItemButtonBase, ITfSource), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObject);}
STDMETHODIMP_(ULONG) CLBarItemButtonBase::AddRef(){ return ++m_cRefs;}
STDMETHODIMP_(ULONG) CLBarItemButtonBase::Release(){ if (--m_cRefs == 0) { delete this; return 0; } return m_cRefs;}
/// @unimplementedSTDMETHODIMP CLBarItemButtonBase::OnClick(TfLBIClick click, POINT pt, LPCRECT prc){ if (click == TF_LBI_CLK_RIGHT) { return E_NOTIMPL; //FIXME } if (click == TF_LBI_CLK_LEFT) { return E_NOTIMPL; //FIXME } return E_NOTIMPL;}
STDMETHODIMP CLBarItemButtonBase::InitMenu(ITfMenu *pMenu){ return E_NOTIMPL;}
STDMETHODIMP CLBarItemButtonBase::OnMenuSelect(UINT wID){ return E_NOTIMPL;}
STDMETHODIMP CLBarItemButtonBase::GetIcon(HICON *phIcon){ return E_NOTIMPL;}
STDMETHODIMP CLBarItemButtonBase::GetText(BSTR *pbstr){ if (!pbstr) return E_INVALIDARG; *pbstr = ::SysAllocString(m_NewUIInfo.szDescription); return (*pbstr ? S_OK : E_OUTOFMEMORY);}
STDMETHODIMP CLBarItemButtonBase::GetInfo(TF_LANGBARITEMINFO *pInfo){ return CLBarItemBase::GetInfo(pInfo);}
STDMETHODIMP CLBarItemButtonBase::GetStatus(DWORD *pdwStatus){ return CLBarItemBase::GetStatus(pdwStatus);}
STDMETHODIMP CLBarItemButtonBase::Show(BOOL fShow){ return CLBarItemBase::Show(fShow);}
STDMETHODIMP CLBarItemButtonBase::GetTooltipString(BSTR *pbstrToolTip){ return CLBarItemBase::GetTooltipString(pbstrToolTip);}
STDMETHODIMP CLBarItemButtonBase::AdviseSink( REFIID riid, IUnknown *punk, DWORD *pdwCookie){ return CLBarItemBase::AdviseSink(riid, punk, pdwCookie);}
STDMETHODIMP CLBarItemButtonBase::UnadviseSink(DWORD dwCookie){ return CLBarItemBase::UnadviseSink(dwCookie);}
/*********************************************************************** * CLBarInatItem */
CLBarInatItem::CLBarInatItem(DWORD dwThreadId){ WCHAR szText[256]; ::LoadStringW(g_hInst, IDS_LANGUAGE, szText, _countof(szText)); InitNuiInfo(CLSID_SYSTEMLANGBARITEM, GUID_LBI_INATITEM, 0x20001, 0, szText);
::LoadStringW(g_hInst, IDS_LANGUAGEBUTTON, szText, _countof(szText)); StringCchCopyW(m_szToolTipText, _countof(m_szToolTipText), szText); m_dwThreadId = dwThreadId; m_hKL = ::GetKeyboardLayout(m_dwThreadId);
TF_InitMlngInfo(); ShowInternal(TF_MlngInfoCount() > 1, 0);}
STDMETHODIMP CLBarInatItem::GetIcon(HICON *phIcon){ HICON hIcon = NULL; INT iIndex = GetIconIndexFromhKL(m_hKL); if (iIndex != -1) hIcon = TF_InatExtractIcon(iIndex); *phIcon = hIcon; return S_OK;}
STDMETHODIMP CLBarInatItem::GetText(BSTR *pbstr){ if (!pbstr) return E_INVALIDARG;
WCHAR szText[256]; if (!GethKLDesc(m_hKL, szText, _countof(szText))) return GetText(pbstr);
*pbstr = ::SysAllocString(szText); return S_OK;}
STDMETHODIMP CLBarInatItem::InitMenu(ITfMenu *pMenu){ TF_InitMlngInfo();
INT iKL, cKLs = TF_MlngInfoCount(); for (iKL = 0; iKL < cKLs; ++iKL) { HKL hKL; WCHAR szDesc[128]; if (TF_GetMlngHKL(iKL, &hKL, szDesc, _countof(szDesc))) { HICON hIcon = NULL; INT iIndex = GetIconIndexFromhKL(hKL); if (iIndex != -1) hIcon = TF_InatExtractIcon(iIndex);
LangBarInsertMenu(pMenu, iKL, szDesc, (hKL == m_hKL), hIcon); } }
DWORD dwStatus; if (g_pTipbarWnd && g_pTipbarWnd->m_pLangBarMgr && SUCCEEDED(g_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus)) && (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED))) { LangBarInsertSeparator(pMenu);
WCHAR szText[256]; ::LoadStringW(g_hInst, IDS_RESTORELANGBAR2, szText, _countof(szText)); LangBarInsertMenu(pMenu, 2000, szText, FALSE, NULL); }
return S_OK;}
STDMETHODIMP CLBarInatItem::OnMenuSelect(INT nCommandId){ HKL hKL;
if (nCommandId == 2000) { if (g_pTipbarWnd) { ITfLangBarMgr *pLangBarMgr = g_pTipbarWnd->m_pLangBarMgr; if (pLangBarMgr) pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); } } else if (TF_GetMlngHKL(nCommandId, &hKL, NULL, 0)) { g_pTipbarWnd->RestoreLastFocus(NULL, !!(g_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_CHILD)); HWND hwndFore = ::GetForegroundWindow(); if (m_dwThreadId == ::GetWindowThreadProcessId(hwndFore, NULL)) { BOOL FontSig = GetFontSig(hwndFore, hKL); ::PostMessage(hwndFore, WM_INPUTLANGCHANGEREQUEST, FontSig, (LPARAM)hKL); } }
return S_OK;}
/*********************************************************************** * CTipbarGripper */
CTipbarGripper::CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style) : CUIFGripper((pTipbarWnd ? pTipbarWnd->GetWindow() : NULL), prc, style){ m_bInDebugMenu = FALSE; m_pTipbarWnd = pTipbarWnd;}
/// @unimplementedSTDMETHODIMP_(void) CTipbarGripper::OnLButtonUp(LONG x, LONG y){ m_pTipbarWnd->RestoreFromStub();
if (g_bEnableDeskBand && (g_dwOSInfo & CIC_OSINFO_XPPLUS)) { APPBARDATA AppBar = { sizeof(AppBar) }; AppBar.hWnd = ::FindWindowW(L"Shell_TrayWnd", NULL); if (::SHAppBarMessage(ABM_GETTASKBARPOS, &AppBar)) { RECT rc = AppBar.rc; POINT pt; ::GetCursorPos(&pt); if (g_pTipbarWnd && ::PtInRect(&rc, pt)) g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND | TF_SFT_EXTRAICONSONMINIMIZED); } }
CUIFGripper::OnLButtonUp(x, y); m_pTipbarWnd->UpdatePosFlags();}
/// @unimplementedSTDMETHODIMP_(void) CTipbarGripper::OnRButtonUp(LONG x, LONG y){ if (g_bShowDebugMenu) { // FIXME: Debugging feature }}
STDMETHODIMP_(BOOL) CTipbarGripper::OnSetCursor(UINT uMsg, LONG x, LONG y){ if (m_bInDebugMenu) return FALSE;
return CUIFGripper::OnSetCursor(uMsg, x, y);}
/*********************************************************************** * CLangBarItemList */
BOOL CLangBarItemList::IsStartedIntentionally(REFCLSID rclsid){ auto *pItem = FindItem(rclsid); if (!pItem) return FALSE; return pItem->m_bStartedIntentionally;}
LANGBARITEMSTATE *CLangBarItemList::AddItem(REFCLSID rclsid){ auto *pItem = FindItem(rclsid); if (pItem) return pItem;
pItem = Append(1); if (!pItem) return NULL;
ZeroMemory(pItem, sizeof(*pItem)); pItem->m_clsid = rclsid; pItem->m_dwDemoteLevel = 0; return pItem;}
void CLangBarItemList::Clear(){ clear();
CicRegKey regKey; LSTATUS error; error = regKey.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\CTF\\LangBar", KEY_ALL_ACCESS); if (error == ERROR_SUCCESS) regKey.RecurseDeleteKey(L"ItemState");}
BOOL CLangBarItemList::SetDemoteLevel(REFCLSID rclsid, DWORD dwDemoteLevel){ auto *pItem = AddItem(rclsid); if (!pItem) return TRUE;
pItem->m_dwDemoteLevel = dwDemoteLevel; if (!pItem->IsShown()) { if (pItem->m_nTimerID) { if (g_pTipbarWnd) g_pTipbarWnd->KillTimer(pItem->m_nTimerID); pItem->m_nTimerID = 0; pItem->m_uTimeOut = 0; } pItem->m_bDisableDemoting = FALSE; }
SaveItem(0, pItem); return TRUE;}
LANGBARITEMSTATE *CLangBarItemList::FindItem(REFCLSID rclsid){ for (size_t iItem = 0; iItem < size(); ++iItem) { auto& item = (*this)[iItem]; if (IsEqualCLSID(item.m_clsid, rclsid)) return &item; } return NULL;}
LANGBARITEMSTATE *CLangBarItemList::GetItemStateFromTimerId(UINT_PTR nTimerID){ for (size_t iItem = 0; iItem < size(); ++iItem) { auto& item = (*this)[iItem]; if (item.m_nTimerID == nTimerID) return &item; } return NULL;}
void CLangBarItemList::Load(){ CicRegKey regKey; LSTATUS error; error = regKey.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\CTF\\LangBar\\ItemState"); if (error != ERROR_SUCCESS) return;
WCHAR szKeyName[MAX_PATH]; for (DWORD dwIndex = 0; ; ++dwIndex) { error = ::RegEnumKeyW(regKey, dwIndex, szKeyName, _countof(szKeyName)); if (error != ERROR_SUCCESS) break;
CLSID clsid; if (::CLSIDFromString(szKeyName, &clsid) != S_OK) continue;
CicRegKey regKey2; error = regKey2.Open(regKey, szKeyName); if (error != ERROR_SUCCESS) continue;
auto *pItem = AddItem(clsid); if (!pItem) continue;
DWORD Data = 0; regKey2.QueryDword(L"DemoteLevel", &Data); pItem->m_dwDemoteLevel = Data; regKey2.QueryDword(L"DisableDemoting", &Data); pItem->m_bDisableDemoting = !!Data; }}
void CLangBarItemList::SaveItem(CicRegKey *pRegKey, const LANGBARITEMSTATE *pState){ LSTATUS error; CicRegKey regKey;
if (!pRegKey) { error = regKey.Create(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\CTF\\LangBar\\ItemState"); if (error != ERROR_SUCCESS) return;
pRegKey = ®Key; }
WCHAR szSubKey[MAX_PATH]; ::StringFromGUID2(pState->m_clsid, szSubKey, _countof(szSubKey));
if (pState->m_dwDemoteLevel || pState->m_bDisableDemoting) { CicRegKey regKey2; error = regKey2.Create(*pRegKey, szSubKey); if (error == ERROR_SUCCESS) { DWORD dwDemoteLevel = pState->m_dwDemoteLevel; if (dwDemoteLevel) regKey2.SetDword(L"DemoteLevel", dwDemoteLevel); else regKey2.DeleteValue(L"DemoteLevel");
regKey2.SetDword(L"DisableDemoting", pState->m_bDisableDemoting); } } else { pRegKey->RecurseDeleteKey(szSubKey); }}
void CLangBarItemList::StartDemotingTimer(REFCLSID rclsid, BOOL bIntentional){ if (!g_bIntelliSense) return;
auto *pItem = AddItem(rclsid); if (!pItem || pItem->m_bDisableDemoting) return;
if (pItem->m_nTimerID) { if (!bIntentional) return;
if (g_pTipbarWnd) g_pTipbarWnd->KillTimer(pItem->m_nTimerID);
pItem->m_nTimerID = 0; }
pItem->m_bStartedIntentionally |= bIntentional;
UINT uTimeOut = (bIntentional ? g_uTimeOutIntentional : g_uTimeOutNonIntentional); pItem->m_uTimeOut += uTimeOut;
if (pItem->m_uTimeOut < g_uTimeOutMax) { UINT_PTR uDemotingTimerId = FindDemotingTimerId(); pItem->m_nTimerID = uDemotingTimerId; if (uDemotingTimerId) { if (g_pTipbarWnd) g_pTipbarWnd->SetTimer(uDemotingTimerId, uTimeOut); } } else { pItem->m_bDisableDemoting = TRUE; }}
UINT_PTR CLangBarItemList::FindDemotingTimerId(){ UINT_PTR nTimerID = 10000;
if (empty()) return nTimerID;
for (;;) { size_t iItem = 0;
while ((*this)[iItem].m_nTimerID != nTimerID) { ++iItem; if (iItem >= size()) return nTimerID; }
++nTimerID; if (nTimerID >= 10050) return 0; }}
/*********************************************************************** * CTipbarWnd */
/// @unimplementedCTipbarWnd::CTipbarWnd(DWORD style) : CUIFWindow(g_hInst, style){ m_dwUnknown23_1[4] = 0; m_dwUnknown23_1[5] = 0; m_dwUnknown23_1[6] = 0; m_dwUnknown23_1[7] = 0;
RECT rc; cicGetScreenRect(g_ptTipbar, &rc);
//FIXME: Fix g_ptTipbar
Move(g_ptTipbar.x, g_ptTipbar.y, 100, 24); UpdatePosFlags();
m_hMarlettFont = ::CreateFontW(8, 8, 0, 0, FW_NORMAL, 0, 0, 0, SYMBOL_CHARSET, 0, 0, 0, 0, L"Marlett");
ITfLangBarMgr *pLangBarMgr = NULL; if (SUCCEEDED(TF_CreateLangBarMgr(&pLangBarMgr)) && pLangBarMgr) { pLangBarMgr->QueryInterface(IID_ITfLangBarMgr_P, (void **)&m_pLangBarMgr); pLangBarMgr->Release(); }
if (style & UIF_WINDOW_ENABLETHEMED) { if (g_fTaskbarTheme) { m_iPartId = 1; m_iStateId = 1; m_pszClassList = L"TASKBAR"; } else { m_iPartId = 0; m_iStateId = 1; m_pszClassList = L"REBAR"; } }
SetVertical(g_fVertical);
m_cRefs = 1;}
CTipbarWnd::~CTipbarWnd(){ UnInit();
if (m_hMarlettFont) ::DeleteObject(m_hMarlettFont); if (m_hTextFont) ::DeleteObject(m_hTextFont);
TFUninitLib_Thread(&g_libTLS);}
/// @unimplementedvoid CTipbarWnd::Init(BOOL bChild, CDeskBand *pDeskBand){ if (bChild) m_dwTipbarWndFlags |= TIPBAR_CHILD; else m_dwTipbarWndFlags &= ~TIPBAR_CHILD;
if (m_dwTipbarWndFlags & TIPBAR_CHILD) m_dwTipbarWndFlags &= TIPBAR_HIGHCONTRAST;
m_pDeskBand = pDeskBand;
RECT rc = { 0, 0, 0, 0 };
if (g_bNewLook && !m_pWndFrame && (m_style & 0x20000000)) { CUIFWndFrame *pWndFrame = new(cicNoThrow) CUIFWndFrame(GetWindow(), &rc, 0); if (pWndFrame) { pWndFrame->Initialize(); AddUIObj(m_pWndFrame); } }
if (!m_pTipbarGripper && !(m_dwTipbarWndFlags & TIPBAR_CHILD)) { m_pTipbarGripper = new(cicNoThrow) CTipbarGripper(this, &rc, !!(m_dwTipbarWndFlags & TIPBAR_VERTICAL)); if (m_pTipbarGripper) { m_pTipbarGripper->Initialize(); AddUIObj(m_pTipbarGripper); } }
//FIXME: CTipbarCtrlButtonHolder
if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) { Move(m_nLeft, m_nTop, GetTipbarHeight(), 0); } else { Move(m_nLeft, m_nTop, 0, GetTipbarHeight()); }}
void CTipbarWnd::InitHighContrast(){ m_dwTipbarWndFlags &= ~TIPBAR_HIGHCONTRAST;
HIGHCONTRAST HiCon = { sizeof(HiCon) }; if (::SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HiCon), &HiCon, 0)) { if (HiCon.dwFlags & HCF_HIGHCONTRASTON) m_dwTipbarWndFlags |= TIPBAR_HIGHCONTRAST; }}
void CTipbarWnd::InitMetrics(){ m_cxSmallIcon = ::GetSystemMetrics(SM_CXSMICON); m_cySmallIcon = ::GetSystemMetrics(SM_CYSMICON);
DWORD_PTR style = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); if (style & WS_DLGFRAME) { m_cxDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CXDLGFRAME); m_cyDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CYDLGFRAME); } else if (style & WS_BORDER) { m_cxDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CXBORDER); m_cyDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CYBORDER); } else { m_cxDlgFrameX2 = m_cyDlgFrameX2 = 0; }}
void CTipbarWnd::InitThemeMargins(){ ZeroMemory(&m_Margins, sizeof(m_Margins));
CUIFTheme theme; m_dwUnknown23_5[0] = 6; m_dwUnknown23_5[1] = 6; m_dwUnknown23_5[2] = 0; m_ButtonWidth = GetSystemMetrics(SM_CXSIZE);
theme.m_iPartId = 1; theme.m_iStateId = 0; theme.m_pszClassList = L"TOOLBAR"; if (SUCCEEDED(theme.InternalOpenThemeData(m_hWnd))) { ::GetThemeMargins(theme.m_hTheme, NULL, theme.m_iPartId, 1, 3602, NULL, &m_Margins); m_dwUnknown23_5[0] = 4; m_dwUnknown23_5[1] = 2; m_dwUnknown23_5[2] = 1; } theme.CloseThemeData();
theme.m_iPartId = 18; theme.m_iStateId = 0; theme.m_pszClassList = L"WINDOW"; if (SUCCEEDED(theme.InternalOpenThemeData(m_hWnd))) { SIZE partSize; ::GetThemePartSize(theme.m_hTheme, NULL, theme.m_iPartId, 1, 0, TS_TRUE, &partSize); INT size = ::GetThemeSysSize(theme.m_hTheme, 31); m_ButtonWidth = MulDiv(size, partSize.cx, partSize.cy); } theme.CloseThemeData();}
void CTipbarWnd::UnInit(){ SetFocusThread(NULL); for (size_t iItem = 0; iItem < m_Threads.size(); ++iItem) { CTipbarThread* pThread = m_Threads[iItem]; if (pThread) { pThread->_UninitItemList(TRUE); pThread->m_pTipbarWnd = NULL; pThread->_Release(); } } m_Threads.clear();
if (m_pLangBarMgr) m_pLangBarMgr->UnAdviseEventSink(m_dwSinkCookie);
if (m_pLangBarMgr) { m_pLangBarMgr->Release(); m_pLangBarMgr = NULL; }}
BOOL CTipbarWnd::IsFullScreenWindow(HWND hWnd){ if (g_fPolicyEnableLanguagebarInFullscreen) return FALSE;
DWORD_PTR style = ::GetWindowLongPtr(hWnd, GWL_STYLE); if (!(style & WS_VISIBLE) || (style & WS_CAPTION)) return FALSE;
DWORD_PTR exstyle = ::GetWindowLongPtr(hWnd, GWL_EXSTYLE); if (exstyle & WS_EX_LAYERED) return FALSE;
if ((exstyle & WS_EX_TOOLWINDOW) && (hWnd == m_ShellWndThread.GetWndProgman())) return FALSE;
return !!cicIsFullScreenSize(hWnd);}
BOOL CTipbarWnd::IsHKLToSkipRedrawOnNoItem(){ HKL hKL = GetFocusKeyboardLayout(); return IsSkipRedrawHKL(hKL);}
BOOL CTipbarWnd::IsInItemChangeOrDirty(CTipbarThread *pTarget){ if (pTarget->m_dwThreadId == m_dwChangingThreadId) return TRUE; return pTarget->IsDirtyItem();}
void CTipbarWnd::AddThreadToThreadCreatingList(CTipbarThread *pThread){ m_ThreadCreatingList.Add(pThread);}
void CTipbarWnd::RemoveThredFromThreadCreatingList(CTipbarThread *pTarget){ ssize_t iItem = m_ThreadCreatingList.Find(pTarget); if (iItem >= 0) m_ThreadCreatingList.Remove(iItem);}
void CTipbarWnd::MoveToStub(BOOL bFlag){ m_dwTipbarWndFlags |= 0x40;
RECT rcWorkArea; ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0);
if (bFlag) { m_nLeft = rcWorkArea.right - 38; m_dwTipbarWndFlags &= ~0x80; } else { RECT Rect; ::GetWindowRect(m_hWnd, &Rect); m_nLeft = rcWorkArea.right + Rect.left - Rect.right; m_dwTipbarWndFlags |= 0x80; }
m_nTop = rcWorkArea.bottom - m_cyDlgFrameX2 - GetTipbarHeight();
if (m_pFocusThread) m_pFocusThread->MyMoveWnd(0, 0);}
void CTipbarWnd::RestoreFromStub(){ m_dwTipbarWndFlags &= 0x3F; KillTimer(1); KillTimer(2);}
/// @unimplementedINT CTipbarWnd::GetCtrlButtonWidth(){ return 0;}
INT CTipbarWnd::GetGripperWidth(){ if (m_dwTipbarWndFlags & 2) return 0;
if (!m_pTipbarGripper || FAILED(m_pTipbarGripper->EnsureThemeData(m_hWnd))) return 5;
INT width = -1; SIZE partSize; HDC hDC = ::GetDC(m_hWnd); if (SUCCEEDED(m_pTipbarGripper->GetThemePartSize(hDC, 1, 0, TS_TRUE, &partSize))) { INT cx = partSize.cx; if (m_dwTipbarWndFlags & 4) cx = partSize.cy; width = cx + 4; } ::ReleaseDC(m_hWnd, hDC);
return ((width < 0) ? 5 : width);}
INT CTipbarWnd::GetTipbarHeight(){ SIZE size = { 0, 0 }; if (m_pWndFrame) m_pWndFrame->GetFrameSize(&size); INT cy = m_Margins.cyBottomHeight + m_Margins.cyTopHeight + 2; if (cy < 6) cy = 6; return m_cySmallIcon + cy + (2 * size.cy);}
BOOL CTipbarWnd::AutoAdjustDeskBandSize(){ if ((m_dwTipbarWndFlags & TIPBAR_NODESKBAND) || !m_pFocusThread || (m_pFocusThread->m_dwFlags1 & 0x800)) { return FALSE; }
DWORD dwOldWndFlags = m_dwTipbarWndFlags; m_dwTipbarWndFlags &= ~0x8000;
if (!AdjustDeskBandSize(!(dwOldWndFlags & 0x8000))) return FALSE;
m_dwTipbarWndFlags |= TIPBAR_NODESKBAND; return TRUE;}
/// @unimplementedINT CTipbarWnd::AdjustDeskBandSize(BOOL bFlag){ return 0;}
/// @unimplementedvoid CTipbarWnd::LocateCtrlButtons(){}
void CTipbarWnd::AdjustPosOnDisplayChange(){ RECT rcWorkArea; RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }; if (!GetWorkArea(&rc, &rcWorkArea)) return;
INT x = m_nLeft, y = m_nTop; if (m_dwTipbarWndFlags & TIPBAR_LEFTFIT) x = rcWorkArea.left; if (m_dwTipbarWndFlags & TIPBAR_TOPFIT) y = rcWorkArea.top; if (m_dwTipbarWndFlags & TIPBAR_RIGHTFIT) x = rcWorkArea.right - m_nWidth; if (m_dwTipbarWndFlags & TIPBAR_BOTTOMFIT) y = rcWorkArea.bottom - m_nHeight; if (x != m_nLeft || y != m_nTop) Move(x, y, m_nWidth, m_nHeight);}
void CTipbarWnd::SetVertical(BOOL bVertical){ if (bVertical) m_dwTipbarWndFlags |= TIPBAR_VERTICAL; else m_dwTipbarWndFlags &= ~TIPBAR_VERTICAL;
if (m_pTipbarGripper) { DWORD style = m_pTipbarGripper->m_style; if (bVertical) style |= 0x1; else style &= 0x1; m_pTipbarGripper->SetStyle(style); }
if (g_fTaskbarTheme) SetActiveTheme(L"TASKBAR", !!(m_dwTipbarWndFlags & TIPBAR_VERTICAL), 1);
if (!(m_dwTipbarWndFlags & TIPBAR_CHILD)) { if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) { Move(m_nLeft, m_nTop, GetTipbarHeight(), 0); } else { Move(m_nLeft, m_nTop, 0, GetTipbarHeight()); } }
if (m_hWnd) { KillTimer(7); SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); }}
void CTipbarWnd::UpdatePosFlags(){ if (m_dwTipbarWndFlags & TIPBAR_CHILD) return;
RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }, rcWorkArea; if (!GetWorkArea(&rc, &rcWorkArea)) return;
if (rcWorkArea.left + 2 < m_nLeft) m_dwTipbarWndFlags &= ~TIPBAR_LEFTFIT; else m_dwTipbarWndFlags |= TIPBAR_LEFTFIT;
if (rcWorkArea.top + 2 < m_nTop) m_dwTipbarWndFlags &= ~TIPBAR_TOPFIT; else m_dwTipbarWndFlags |= TIPBAR_TOPFIT;
if (m_nLeft + m_nWidth < rcWorkArea.right - 2) m_dwTipbarWndFlags &= ~TIPBAR_RIGHTFIT; else m_dwTipbarWndFlags |= TIPBAR_RIGHTFIT;
if (m_nTop + m_nHeight < rcWorkArea.bottom - 2) m_dwTipbarWndFlags &= ~TIPBAR_BOTTOMFIT; else m_dwTipbarWndFlags |= TIPBAR_BOTTOMFIT;}
void CTipbarWnd::CancelMenu(){ if (!m_pThread) return;
CTipbarWnd *pTipbarWnd = m_pThread->m_pTipbarWnd; if (pTipbarWnd) { if (pTipbarWnd->m_pLangBarMgr) pTipbarWnd->StartModalInput(NULL, m_pThread->m_dwThreadId); }
m_pModalMenu->CancelMenu(); StartBackToAlphaTimer();}
BOOL CTipbarWnd::CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2){ return (prc1->top < prc2->top + 5) && (prc2->right <= prc1->right + (5 * m_ButtonWidth));}
void CTipbarWnd::ClearLBItemList(){ m_LangBarItemList.Clear(); if (m_pFocusThread) OnThreadItemChange(m_pFocusThread->m_dwThreadId);}
HFONT CTipbarWnd::CreateVerticalFont(){ if (!m_hWnd) return NULL;
CUIFTheme theme; theme.m_iPartId = 1; theme.m_iStateId = 0; theme.m_pszClassList = L"TOOLBAR";
LOGFONTW lf; if (FAILED(theme.InternalOpenThemeData(m_hWnd)) || FAILED(::GetThemeFont(theme.m_hTheme, NULL, theme.m_iPartId, 0, 210, &lf))) { ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf); }
lf.lfEscapement = lf.lfOrientation = 2700; lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
if (CheckEAFonts()) { WCHAR szText[LF_FACESIZE]; szText[0] = L'@'; StringCchCopyW(&szText[1], _countof(szText) - 1, lf.lfFaceName); StringCchCopyW(lf.lfFaceName, _countof(lf.lfFaceName), szText); }
return ::CreateFontIndirectW(&lf);}
void CTipbarWnd::UpdateVerticalFont(){ if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) { if (m_hTextFont) { ::DeleteObject(m_hTextFont); SetFontToThis(NULL); m_hTextFont = NULL; } m_hTextFont = CreateVerticalFont(); SetFontToThis(m_hTextFont); } else { SetFontToThis(NULL); }}
/// @unimplementedvoid CTipbarWnd::ShowOverScreenSizeBalloon(){ //FIXME: CTipbarCtrlButtonHolder}
void CTipbarWnd::DestroyOverScreenSizeBalloon(){ if (m_pBalloon) { if (::IsWindow(*m_pBalloon)) ::DestroyWindow(*m_pBalloon); delete m_pBalloon; m_pBalloon = NULL; }}
void CTipbarWnd::DestroyWnd(){ if (::IsWindow(m_hWnd)) ::DestroyWindow(m_hWnd);}
HKL CTipbarWnd::GetFocusKeyboardLayout(){ DWORD dwThreadId = 0; if (m_pFocusThread) dwThreadId = m_pFocusThread->m_dwThreadId; return ::GetKeyboardLayout(dwThreadId);}
void CTipbarWnd::KillOnTheadItemChangeTimer(){ DWORD dwChangingThreadId = m_dwChangingThreadId; m_dwChangingThreadId = 0; KillTimer(4);
if (dwChangingThreadId) { CTipbarThread *pThread = _FindThread(dwChangingThreadId); if (pThread) pThread->m_dwUnknown34 |= 0x1; }}
UINT_PTR CTipbarWnd::SetTimer(UINT_PTR nIDEvent, UINT uElapse){ if (::IsWindow(m_hWnd)) return ::SetTimer(m_hWnd, nIDEvent, uElapse, NULL); return 0;}
BOOL CTipbarWnd::KillTimer(UINT_PTR uIDEvent){ if (::IsWindow(m_hWnd)) return ::KillTimer(m_hWnd, uIDEvent); return FALSE;}
/// @unimplementedvoid CTipbarWnd::MoveToTray(){ if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) { //FIXME }}
void CTipbarWnd::MyClientToScreen(LPPOINT lpPoint, LPRECT prc){ if (lpPoint) ::ClientToScreen(m_hWnd, lpPoint);
if (prc) { ::ClientToScreen(m_hWnd, (LPPOINT)prc); ::ClientToScreen(m_hWnd, (LPPOINT)&prc->right); }}
void CTipbarWnd::SavePosition(){ CicRegKey regKey; if (regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"))) { POINT pt = { 0, 0 }; ::ClientToScreen(m_hWnd, &pt); regKey.SetDword(TEXT("Left"), pt.x); regKey.SetDword(TEXT("Top"), pt.y); regKey.SetDword(TEXT("Vertical"), !!(m_dwTipbarWndFlags & TIPBAR_VERTICAL)); }}
/// @unimplementedvoid CTipbarWnd::SetAlpha(BYTE bAlpha, BOOL bFlag){}
BOOL CTipbarWnd::SetLangBand(BOOL bDeskBand, BOOL bFlag2){ if (bDeskBand == !!(m_dwShowType & TF_SFT_DESKBAND)) return TRUE;
BOOL ret = TRUE; HWND hwndTray = m_ShellWndThread.GetWndTray(); if (bFlag2 && hwndTray) { DWORD_PTR dwResult; HWND hImeWnd = ::ImmGetDefaultIMEWnd(hwndTray); if (hImeWnd) ::SendMessageTimeout(hImeWnd, WM_IME_SYSTEM, 0x24 - bDeskBand, (LPARAM)hwndTray, (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult); else ::SendMessageTimeout(hwndTray, 0x505, 0, bDeskBand, (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult); } else { ret = FALSE; }
if (!(m_dwTipbarWndFlags & TIPBAR_CHILD) && bDeskBand) { KillTimer(7); SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); }
return ret;}
void CTipbarWnd::SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight){ if (m_dwTipbarWndFlags & TIPBAR_CHILD) { m_nWidth = nWidth; m_nHeight = nHeight; return; }
++m_bInCallOn;
m_dwTipbarWndFlags |= TIPBAR_UPDATING;
m_X = X; m_Y = Y; m_CX = nWidth; m_CY = nHeight;
RECT rc; SIZE size = { 0, 0 }; if (m_pWndFrame) { ::SetRect(&rc, 0, 0, nWidth - m_cxDlgFrameX2, nHeight - m_cyDlgFrameX2); m_pWndFrame->SetRect(&rc); m_pWndFrame->GetFrameSize(&size); }
if (m_pTipbarGripper) { if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) { INT GripperWidth = GetGripperWidth(); ::SetRect(&rc, size.cx, size.cy, nWidth - m_cxDlgFrameX2 - size.cx, size.cy + GripperWidth); } else { INT GripperWidth = GetGripperWidth(); INT y1 = nHeight - m_cyDlgFrameX2 - size.cy; ::SetRect(&rc, size.cx, size.cy, size.cx + GripperWidth, y1); } m_pTipbarGripper->SetRect(&rc); }
--m_bInCallOn;}
void CTipbarWnd::SetShowText(BOOL bShow){ if (bShow) m_dwTipbarWndFlags |= TIPBAR_HIGHCONTRAST; else m_dwTipbarWndFlags &= ~TIPBAR_HIGHCONTRAST;
if (m_pFocusThread) OnThreadItemChange(m_pFocusThread->m_dwThreadId);
TerminateAllThreads(FALSE);}
void CTipbarWnd::SetShowTrayIcon(BOOL bShow){ if (m_dwTipbarWndFlags & TIPBAR_TRAYICON) m_dwTipbarWndFlags &= ~TIPBAR_TRAYICON; else m_dwTipbarWndFlags |= TIPBAR_TRAYICON;
if ((m_dwTipbarWndFlags & TIPBAR_TRAYICON) && m_pFocusThread) { KillTimer(10); SetTimer(10, g_uTimerElapseMOVETOTRAY); } else if (g_pTrayIconWnd) { g_pTrayIconWnd->SetMainIcon(NULL); g_pTrayIconWnd->RemoveAllIcon(0); }}
void CTipbarWnd::ShowContextMenu(POINT pt, LPCRECT prc, BOOL bFlag){ AddRef();
RECT rc; if (!prc) { rc = { pt.x, pt.y, pt.x, pt.y }; prc = &rc; }
if (m_pFocusThread) { CUTBContextMenu *pContextMenu = new(cicNoThrow) CUTBContextMenu(this); if (pContextMenu) { if (pContextMenu->Init()) { m_pThread = m_pFocusThread; StartModalInput(this, m_pFocusThread->m_dwThreadId);
m_pModalMenu = pContextMenu; DWORD dwCommandId = pContextMenu->ShowPopup(GetWindow(), pt, prc, bFlag); m_pModalMenu = NULL;
if (m_pThread) StopModalInput(m_pThread->m_dwThreadId);
m_pThread = NULL;
if (dwCommandId != (DWORD)-1) pContextMenu->SelectMenuItem(dwCommandId); }
delete pContextMenu; } }
Release();}
void CTipbarWnd::StartBackToAlphaTimer(){ UINT uTime = ::GetDoubleClickTime(); ::SetTimer(m_hWnd, 3, 3 * uTime, NULL);}
BOOL CTipbarWnd::StartDoAccDefaultActionTimer(CTipbarItem *pTarget){ if (!m_pTipbarAccessible) return FALSE; INT IDOfItem = m_pTipbarAccessible->GetIDOfItem(pTarget); m_nID = IDOfItem; if (!IDOfItem || IDOfItem == -1) return FALSE; KillTimer(11); SetTimer(11, g_uTimerElapseDOACCDEFAULTACTION); return TRUE;}
void CTipbarWnd::StartModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId){ if (!m_pLangBarMgr) return;
m_pLangBarMgr->SetModalInput(pSink, dwThreadId, 0); if (g_pTrayIconWnd) m_pLangBarMgr->SetModalInput(pSink, g_pTrayIconWnd->m_dwTrayWndThreadId, 0);
DWORD dwCurThreadId = ::GetCurrentThreadId(); m_pLangBarMgr->SetModalInput(pSink, dwCurThreadId, 1);}
void CTipbarWnd::StopModalInput(DWORD dwThreadId){ if (!m_pLangBarMgr) return;
m_pLangBarMgr->SetModalInput(NULL, dwThreadId, 0); if (g_pTrayIconWnd) m_pLangBarMgr->SetModalInput(NULL, g_pTrayIconWnd->m_dwTrayWndThreadId, 0);
DWORD dwCurThreadId = ::GetCurrentThreadId(); m_pLangBarMgr->SetModalInput(NULL, dwCurThreadId, 0);}
LONG MyWaitForInputIdle(DWORD dwThreadId, DWORD dwMilliseconds){ if (g_pTipbarWnd && (g_pTipbarWnd->m_dwShowType & TF_SFT_DESKBAND)) return 0;
if (TF_IsInMarshaling(dwThreadId)) return STATUS_TIMEOUT;
DWORD dwFlags1 = 0, dwFlags2 = 0; if (!TF_GetThreadFlags(dwThreadId, &dwFlags1, &dwFlags2, NULL) && dwFlags2) return -1;
return TF_CheckThreadInputIdle(dwThreadId, dwMilliseconds);}
CTipbarThread *CTipbarWnd::_CreateThread(DWORD dwThreadId){ CTipbarThread *pTarget = _FindThread(dwThreadId); if (pTarget) return pTarget;
MyWaitForInputIdle(dwThreadId, 2000);
pTarget = new(cicNoThrow) CTipbarThread(this); if (!pTarget) return NULL;
AddThreadToThreadCreatingList(pTarget);
HRESULT hr = pTarget->Init(dwThreadId);
RemoveThredFromThreadCreatingList(pTarget);
if (SUCCEEDED(hr) && !m_Threads.Add(pTarget)) { pTarget->_UninitItemList(TRUE); pTarget->m_pTipbarWnd = NULL; pTarget->_Release(); return NULL; }
return pTarget;}
CTipbarThread *CTipbarWnd::_FindThread(DWORD dwThreadId){ if (g_bWinLogon) return NULL;
CTipbarThread *pTarget = NULL; for (size_t iItem = 0; iItem < m_Threads.size(); ++iItem) { CTipbarThread *pThread = m_Threads[iItem]; if (pThread && pThread->m_dwThreadId == dwThreadId) { pTarget = pThread; break; } }
if (!pTarget) return NULL;
DWORD dwFlags1, dwFlags2, dwFlags3; TF_GetThreadFlags(dwThreadId, &dwFlags1, &dwFlags2, &dwFlags3);
if (!dwFlags2 || (dwFlags2 != pTarget->m_dwFlags2) || (dwFlags3 != pTarget->m_dwFlags3)) { OnThreadTerminateInternal(dwThreadId); return NULL; }
return pTarget;}
void CTipbarWnd::EnsureFocusThread(){ if (m_pFocusThread || (m_dwTipbarWndFlags & (TIPBAR_TOOLBARENDED | TIPBAR_ENSURING))) return;
m_dwTipbarWndFlags |= TIPBAR_ENSURING;
HWND hwndFore = ::GetForegroundWindow(); if (!hwndFore) return;
DWORD dwThreadId = ::GetWindowThreadProcessId(hwndFore, NULL); if (dwThreadId) OnSetFocus(dwThreadId);
m_dwTipbarWndFlags &= ~TIPBAR_ENSURING;}
HRESULT CTipbarWnd::SetFocusThread(CTipbarThread *pFocusThread){ if (pFocusThread == m_pFocusThread) return S_OK;
DWORD dwThreadId = ::GetCurrentThreadId(); DestroyOverScreenSizeBalloon();
if (m_pFocusThread) { m_pFocusThread->SetFocus(NULL); ::AttachThreadInput(dwThreadId, m_pFocusThread->m_dwThreadId, FALSE); }
m_dwTipbarWndFlags &= ~TIPBAR_ATTACHED; m_pFocusThread = pFocusThread; return S_OK;}
HRESULT CTipbarWnd::AttachFocusThread(){ if (m_dwTipbarWndFlags & TIPBAR_ATTACHED) return S_FALSE;
if (m_pFocusThread) { DWORD dwThreadId = ::GetCurrentThreadId(); ::AttachThreadInput(dwThreadId, m_pFocusThread->m_dwThreadId, TRUE); m_dwTipbarWndFlags |= TIPBAR_ATTACHED; }
return S_OK;}
void CTipbarWnd::RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev){ if (m_pLangBarMgr) m_pLangBarMgr->RestoreLastFocus(pdwThreadId, fPrev);}
void CTipbarWnd::CleanUpThreadPointer(CTipbarThread *pThread, BOOL bRemove){ if (bRemove) { ssize_t iItem = m_Threads.Find(pThread); if (iItem >= 0) m_Threads.Remove(iItem); }
if (pThread == m_pFocusThread) SetFocusThread(NULL);
if (pThread == m_pThread) m_pThread = NULL;
if (pThread == m_pUnknownThread) m_pUnknownThread = NULL;}
void CTipbarWnd::TerminateAllThreads(BOOL bFlag){ const size_t cItems = m_Threads.size();
DWORD *pdwThreadIds = new(cicNoThrow) DWORD[cItems]; if (!pdwThreadIds) return;
for (size_t iItem = 0; iItem < cItems; ++iItem) { pdwThreadIds[iItem] = 0; CTipbarThread* pThread = m_Threads[iItem]; if (pThread && (bFlag || (pThread != m_pFocusThread))) { pdwThreadIds[iItem] = pThread->m_dwThreadId; } }
for (size_t iItem = 0; iItem < cItems; ++iItem) { if (pdwThreadIds[iItem]) OnThreadTerminateInternal(pdwThreadIds[iItem]); }
delete[] pdwThreadIds;}
STDMETHODIMP CTipbarWnd::QueryInterface(REFIID riid, void **ppvObj){ static const QITAB c_tab[] = { QITABENT(CTipbarWnd, ITfLangBarEventSink), QITABENT(CTipbarWnd, ITfLangBarEventSink_P), { NULL } }; return ::QISearch(this, c_tab, riid, ppvObj);}
STDMETHODIMP_(ULONG) CTipbarWnd::AddRef(){ return ++m_cRefs;}
STDMETHODIMP_(ULONG) CTipbarWnd::Release(){ if (--m_cRefs == 0) { delete this; return 0; } return m_cRefs;}
/// @unimplementedSTDMETHODIMP CTipbarWnd::OnSetFocus(DWORD dwThreadId){ return E_NOTIMPL;}
STDMETHODIMP CTipbarWnd::OnThreadTerminate(DWORD dwThreadId){ HRESULT hr; ++m_bInCallOn; AddRef(); { hr = OnThreadTerminateInternal(dwThreadId); if (!m_pFocusThread) EnsureFocusThread(); } --m_bInCallOn; Release(); return hr;}
HRESULT CTipbarWnd::OnThreadTerminateInternal(DWORD dwThreadId){ for (size_t iItem = 0; iItem < m_Threads.size(); ++iItem) { CTipbarThread *pThread = m_Threads[iItem]; if (pThread && pThread->m_dwThreadId == dwThreadId) { m_Threads.Remove(iItem); pThread->RemoveUIObjs(); CleanUpThreadPointer(pThread, FALSE); pThread->_UninitItemList(TRUE); pThread->m_pTipbarWnd = NULL; pThread->_Release(); break; } }
return S_OK;}
STDMETHODIMP CTipbarWnd::OnThreadItemChange(DWORD dwThreadId){ if (m_dwTipbarWndFlags & TIPBAR_TOOLBARENDED) return S_OK; if (!(m_dwTipbarWndFlags & TIPBAR_CHILD) && (m_dwShowType & TF_SFT_DESKBAND)) return S_OK;
CTipbarThread *pThread = _FindThread(dwThreadId); if (pThread) { if ((!m_dwUnknown23 || m_dwUnknown23 == dwThreadId) && pThread == m_pFocusThread) { KillOnTheadItemChangeTimer(); m_dwChangingThreadId = dwThreadId; KillTimer(6); SetTimer(4, g_uTimerElapseONTHREADITEMCHANGE); } else { pThread->m_dwUnknown34 |= 0x1; } } else { for (size_t iItem = 0; iItem < m_ThreadCreatingList.size(); ++iItem) { CTipbarThread *pItem = m_ThreadCreatingList[iItem]; if (pItem && pItem->m_dwThreadId == dwThreadId) { pItem->m_dwUnknown34 |= 0x1; } } }
return S_OK;}
STDMETHODIMP CTipbarWnd::OnModalInput(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { case WM_NCLBUTTONDOWN: case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: break;
case WM_NCLBUTTONUP: case WM_NCRBUTTONUP: case WM_NCMBUTTONUP: if (m_pThread) { CUTBMenuWnd *pMenuUI = m_pModalMenu->m_pMenuUI; if (pMenuUI) { HWND hWnd = *pMenuUI; if (hWnd) { POINT pt = { (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) }; ::ScreenToClient(hWnd, &pt); uMsg += WM_LBUTTONUP - WM_NCLBUTTONUP; ::PostMessage(m_hWnd, uMsg, wParam, MAKELPARAM(pt.x, pt.y)); } } } break;
default: { if (uMsg == WM_KEYDOWN || uMsg == WM_KEYUP) { if (m_pThread) m_pModalMenu->PostKey(uMsg == WM_KEYUP, wParam, lParam); } else { CancelMenu(); } break; } }
return 0;}
/// @unimplementedSTDMETHODIMP CTipbarWnd::ShowFloating(DWORD dwFlags){ return E_NOTIMPL;}
STDMETHODIMP CTipbarWnd::GetItemFloatingRect(DWORD dwThreadId, REFGUID rguid, RECT *prc){ if (m_dwTipbarWndFlags & TIPBAR_TRAYICON) return E_UNEXPECTED;
if (!m_pFocusThread || (m_pFocusThread->m_dwThreadId != dwThreadId)) return E_FAIL;
for (size_t iItem = 0; iItem < m_pFocusThread->m_UIObjects.size(); ++iItem) { CTipbarItem* pItem = m_pFocusThread->m_UIObjects[iItem]; if (pItem) { if ((pItem->m_dwItemFlags & 0x8) && IsEqualGUID(pItem->m_ItemInfo.guidItem, rguid)) { pItem->OnUnknown57(prc); return S_OK; } } }
return E_FAIL;}
/// @unimplementedSTDMETHODIMP CTipbarWnd::OnLangBarUpdate(TfLBIClick click, BOOL bFlag){ return E_NOTIMPL;}
STDMETHODIMP_(BSTR) CTipbarWnd::GetAccName(){ WCHAR szText[256]; ::LoadStringW(g_hInst, IDS_LANGUAGEBAR, szText, _countof(szText)); return ::SysAllocString(szText);}
STDMETHODIMP_(void) CTipbarWnd::GetAccLocation(LPRECT lprc){ GetRect(lprc);}
STDMETHODIMP_(void) CTipbarWnd::PaintObject(HDC hDC, LPCRECT prc){ if (m_dwTipbarWndFlags & TIPBAR_UPDATING) { Move(m_X, m_Y, m_CX, m_CY); m_dwTipbarWndFlags &= ~TIPBAR_UPDATING; }
if (!m_pFocusThread || !m_pFocusThread->IsDirtyItem()) { m_pFocusThread->CallOnUpdateHandler(); if (g_pTipbarWnd) CUIFWindow::PaintObject(hDC, prc); }}
STDMETHODIMP_(DWORD) CTipbarWnd::GetWndStyle(){ return CUIFWindow::GetWndStyle() & ~WS_BORDER;}
STDMETHODIMP_(void) CTipbarWnd::Move(INT x, INT y, INT nWidth, INT nHeight){ CUIFWindow::Move(x, y, nWidth, nHeight);}
STDMETHODIMP_(void) CTipbarWnd::OnMouseOutFromWindow(LONG x, LONG y){ StartBackToAlphaTimer(); if ((m_dwTipbarWndFlags & 0x40) && (m_dwTipbarWndFlags & 0x80)) SetTimer(2, g_uTimerElapseSTUBEND);}
/// @unimplementedSTDMETHODIMP_(void) CTipbarWnd::OnCreate(HWND hWnd){}
STDMETHODIMP_(void) CTipbarWnd::OnDestroy(HWND hWnd){ CancelMenu();
if (m_pTipbarAccessible) m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem());
OnTerminateToolbar(); if (m_pTipbarAccessible) { m_pTipbarAccessible->ClearAccItems(); m_pTipbarAccessible->Release(); m_pTipbarAccessible = NULL; }
m_coInit.CoUninit();
if (m_pLangBarMgr) m_pLangBarMgr->UnAdviseEventSink(m_dwSinkCookie);}
/// @unimplementedSTDMETHODIMP_(void) CTipbarWnd::OnTimer(WPARAM wParam){ AddRef(); switch (wParam) { case 1: KillTimer(1); MoveToStub(FALSE); break; case 2: KillTimer(2); MoveToStub(TRUE); break; case 3: KillTimer(3); SetAlpha((BYTE)m_dwAlphaValue, TRUE); break; case 4: { LONG status = MyWaitForInputIdle(m_dwChangingThreadId, 2000); if (status) { if (status != STATUS_TIMEOUT) { KillTimer(4); m_dwChangingThreadId = 0; } } else if (!m_pThread) { KillTimer(4); DWORD dwOldThreadId = m_dwChangingThreadId; m_dwChangingThreadId = 0; OnThreadItemChangeInternal(dwOldThreadId); } break; } case 5: KillTimer(5); ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); break; case 6: KillTimer(6); if (m_pFocusThread) { if (m_pFocusThread->m_dwThreadId != m_dwChangingThreadId && !m_pFocusThread->CallOnUpdateHandler()) { if (m_pFocusThread) OnThreadItemChange(m_pFocusThread->m_dwThreadId); } } break; case 7: { DWORD dwThreadId = 0; if (KillTimer(7)) { if (m_pFocusThread) dwThreadId = m_pFocusThread->m_dwThreadId;
TerminateAllThreads(TRUE); UpdateVerticalFont();
if (dwThreadId) OnSetFocus(dwThreadId);
InitMetrics(); // FIXME: CTipbarCtrlButtonHolder
InitHighContrast(); SetAlpha(0xFF, TRUE); ::RedrawWindow(m_hWnd, NULL, NULL, (RDW_FRAME | RDW_UPDATENOW | RDW_INVALIDATE)); } break; } case 8: KillTimer(8); UpdateUI(NULL); break; case 9: KillTimer(9); //FIXME if (m_pUnknownThread == m_pFocusThread) Show(!!(m_dwUnknown23_5[3] & 0x80000000)); m_pUnknownThread = NULL; if ((m_dwUnknown23_5[3] & 0x2)) ShowOverScreenSizeBalloon(); break; case 10: KillTimer(10); MoveToTray(); break; case 11: KillTimer(11); if (m_pTipbarAccessible) { if (m_nID) { m_pTipbarAccessible->DoDefaultActionReal(m_nID); m_nID = 0; } } break; case 12: KillTimer(12); AdjustPosOnDisplayChange(); break; case 13:#ifdef ENABLE_DESKBAND if (!m_pDeskBand || !m_pDeskBand->m_dwUnknown19) { KillTimer(13); if (!m_pFocusThread) EnsureFocusThread(); }#endif break; case 14: if (SetLangBand(TRUE, TRUE)) { m_dwShowType = TF_SFT_DESKBAND; KillTimer(14); } break; default: { if (10000 <= wParam && wParam < 10050) { auto *pItem = m_LangBarItemList.GetItemStateFromTimerId(wParam); if (pItem) { auto& clsid = pItem->m_clsid; m_LangBarItemList.SetDemoteLevel(pItem->m_clsid, 2); if (m_pFocusThread) { auto *pThreadItem = m_pFocusThread->GetItem(clsid); if (pThreadItem) pThreadItem->AddRemoveMeToUI(FALSE); } } } break; } }
Release();}
STDMETHODIMP_(void) CTipbarWnd::OnSysColorChange(){ KillTimer(7); SetTimer(7, g_uTimerElapseSYSCOLORCHANGED);}
void CTipbarWnd::OnTerminateToolbar(){ m_dwTipbarWndFlags |= TIPBAR_TOOLBARENDED; DestroyOverScreenSizeBalloon(); TerminateAllThreads(TRUE); if (!(m_dwTipbarWndFlags & TIPBAR_CHILD)) SavePosition();}
STDMETHODIMP_(void) CTipbarWnd::OnEndSession(HWND hWnd, WPARAM wParam, LPARAM lParam){ if (!g_bWinLogon) OnTerminateToolbar();
if (wParam) // End session? { if (lParam & ENDSESSION_LOGOFF) { KillTimer(9); Show(FALSE); } else { OnTerminateToolbar();
AddRef(); ::DestroyWindow(hWnd); Release(); } }}
STDMETHODIMP_(void) CTipbarWnd::OnUser(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (uMsg == WM_USER + 1) { POINT pt = { (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) }; ::ClientToScreen(m_hWnd, &pt); ShowContextMenu(pt, NULL, TRUE); } else if (uMsg == g_wmTaskbarCreated) { m_ShellWndThread.clear(); }}
STDMETHODIMP_(LRESULT)CTipbarWnd::OnWindowPosChanged(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (m_pFocusThread) { for (size_t iItem = 0; iItem < m_pFocusThread->m_UIObjects.size(); ++iItem) { CTipbarItem *pItem = m_pFocusThread->m_UIObjects[iItem]; if (pItem) pItem->OnUnknown44(); } }
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);}
STDMETHODIMP_(LRESULT)CTipbarWnd::OnWindowPosChanging(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ LPWINDOWPOS pWP = (LPWINDOWPOS)lParam; if (!(pWP->flags & SWP_NOZORDER)) { if (!m_pThread && (!m_pToolTip || !m_pToolTip->m_bShowToolTip)) pWP->hwndInsertAfter = NULL; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam);}
STDMETHODIMP_(LRESULT)CTipbarWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (m_pTipbarAccessible) { if (wParam) // Show? { m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem()); m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem()); } else { m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem()); } } return ::DefWindowProc(hWnd, uMsg, wParam, lParam);}
STDMETHODIMP_(LRESULT)CTipbarWnd::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (!wParam || wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETHIGHCONTRAST) { KillTimer(7); SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); } return 0;}
STDMETHODIMP_(LRESULT)CTipbarWnd::OnDisplayChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (!(m_dwTipbarWndFlags & TIPBAR_CHILD)) { KillTimer(12); SetTimer(12, g_uTimerElapseDISPLAYCHANGE); } return ::DefWindowProc(hWnd, uMsg, wParam, lParam);}
STDMETHODIMP_(HRESULT)CTipbarWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ if (lParam != -4) return S_OK; if (!m_pTipbarAccessible) return E_OUTOFMEMORY;
if (m_pTipbarAccessible->m_bInitialized) return m_pTipbarAccessible->CreateRefToAccObj(wParam);
HRESULT hr = S_OK; if (SUCCEEDED(m_coInit.EnsureCoInit())) { hr = m_pTipbarAccessible->Initialize(); if (FAILED(hr)) { m_pTipbarAccessible->Release(); m_pTipbarAccessible = NULL; return hr; }
m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem()); return m_pTipbarAccessible->CreateRefToAccObj(wParam); }
return hr;}
STDMETHODIMP_(BOOL) CTipbarWnd::OnEraseBkGnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ return TRUE;}
STDMETHODIMP_(void) CTipbarWnd::OnThemeChanged(HWND hWnd, WPARAM wParam, LPARAM lParam){ CUIFWindow::OnThemeChanged(hWnd, wParam, lParam);}
STDMETHODIMP_(void) CTipbarWnd::UpdateUI(LPCRECT prc){ KillTimer(8);
if (m_dwChangingThreadId || m_bInCallOn || (m_pFocusThread && m_pFocusThread->IsDirtyItem())) { SetTimer(8, g_uTimerElapseUPDATEUI); return; }
if (m_dwTipbarWndFlags & TIPBAR_UPDATING) { ++m_bInCallOn; Move(m_X, m_Y, m_CX, m_CY); m_dwTipbarWndFlags &= ~TIPBAR_UPDATING; --m_bInCallOn; }
CUIFWindow::UpdateUI(NULL);}
/// @unimplementedSTDMETHODIMP_(void) CTipbarWnd::HandleMouseMsg(UINT uMsg, LONG x, LONG y){}
/*********************************************************************** * CTipbarThread */
CTipbarThread::CTipbarThread(CTipbarWnd *pTipbarWnd){ m_pTipbarWnd = pTipbarWnd; m_dwThreadId = 0; m_pLangBarItemMgr = NULL; m_cRefs = 1;}
CTipbarThread::~CTipbarThread(){ if (m_pTipbarWnd) { RemoveUIObjs(); m_pTipbarWnd->CleanUpThreadPointer(this, 1); }
_UninitItemList(1);
if (m_pLangBarItemMgr) { m_pLangBarItemMgr->Release(); m_pLangBarItemMgr = NULL; }}
HRESULT CTipbarThread::Init(DWORD dwThreadId){ m_dwThreadId = dwThreadId; if (!TF_GetThreadFlags(dwThreadId, &m_dwFlags1, &m_dwFlags2, &m_dwFlags3)) return E_FAIL; if (m_dwFlags1 & 0x8) return S_OK; return m_pTipbarWnd->m_pLangBarMgr->GetThreadLangBarItemMgr(m_dwThreadId, &m_pLangBarItemMgr, &dwThreadId);}
/// @unimplementedHRESULT CTipbarThread::InitItemList(){ return E_NOTIMPL;}
HRESULT CTipbarThread::_UninitItemList(BOOL bUnAdvise){ for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) { CTipbarItem* pItem = m_UIObjects[iItem]; if (pItem) pItem->m_dwItemFlags |= 0x10; }
HRESULT hr = S_OK; if (bUnAdvise) { if (m_dwThreadId == ::GetCurrentThreadId() || !MyWaitForInputIdle(m_dwThreadId, 2000)) hr = _UnadviseItemsSink(); }
for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) { CTipbarItem* pItem = m_UIObjects[iItem]; if (pItem) { if (m_pTipbarWnd) pItem->OnUnknown47(m_pTipbarWnd->GetWindow());
pItem->ClearConnections();
if (m_pTipbarWnd) pItem->OnUnknown50(); else pItem->OnUnknown51();
pItem->OnUnknown59(); pItem->OnUnknown42(); } }
m_UIObjects.clear();
RemoveAllSeparators();
return hr;}
void CTipbarThread::AddAllSeparators(){ for (size_t iItem = 0; iItem < m_Separators.size(); ++iItem) { CUIFObject *pItem = m_Separators[iItem]; if (pItem) m_pTipbarWnd->AddUIObj(pItem); }}
void CTipbarThread::RemoveAllSeparators(){ for (size_t iItem = 0; iItem < m_Separators.size(); ++iItem) { CUIFObject *pItem = m_Separators[iItem]; if (pItem) { if (m_pTipbarWnd) m_pTipbarWnd->RemoveUIObj(pItem); delete pItem; } } m_Separators.clear();}
void CTipbarThread::AddUIObjs(){ _AddRef();
for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) { CTipbarItem* pItem = m_UIObjects[iItem]; if (pItem && (pItem->m_dwItemFlags & 0x8)) { pItem->OnUnknown46(m_pTipbarWnd ? m_pTipbarWnd->GetWindow() : NULL); } }
AddAllSeparators(); MyMoveWnd(0, 0);
_Release();}
void CTipbarThread::RemoveUIObjs(){ for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) { CTipbarItem* pItem = m_UIObjects[iItem]; if (pItem) { pItem->OnUnknown47(m_pTipbarWnd ? m_pTipbarWnd->GetWindow() : NULL); } } RemoveAllSeparators();}
CTipbarItem *CTipbarThread::GetItem(REFCLSID rclsid){ for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) { auto *pItem = m_UIObjects[iItem]; if (pItem && IsEqualCLSID(pItem->m_ItemInfo.guidItem, rclsid)) return pItem; } return NULL;}
void CTipbarThread::GetTextSize(BSTR bstr, LPSIZE pSize){ HWND hWnd = *m_pTipbarWnd->GetWindow();
HGDIOBJ hFontOld = NULL;
HDC hDC = ::GetDC(hWnd); if (FAILED(m_pTipbarWnd->EnsureThemeData(*m_pTipbarWnd->GetWindow()))) { HFONT hFont = m_pTipbarWnd->m_hFont; if (hFont) hFontOld = ::SelectObject(hDC, hFont); INT cch = ::SysStringLen(bstr); ::GetTextExtentPoint32W(hDC, bstr, cch, pSize); if (hFontOld) ::SelectObject(hDC, hFontOld); } else { CUIFTheme theme; theme.m_iPartId = 1; theme.m_iStateId = 0; theme.m_pszClassList = L"TOOLBAR";
HFONT hFont = NULL;
if (SUCCEEDED(theme.InternalOpenThemeData(hWnd))) { LOGFONTW lf; if (SUCCEEDED(::GetThemeFont(theme.m_hTheme, NULL, theme.m_iPartId, 0, 210, &lf))) { hFont = ::CreateFontIndirectW(&lf); if (hFont) hFontOld = ::SelectObject(hDC, hFont); }
RECT rc; INT cch = ::SysStringLen(bstr); ::GetThemeTextExtent(theme.m_hTheme, hDC, theme.m_iPartId, 0, bstr, cch, 0, NULL, &rc);
pSize->cx = rc.right; pSize->cy = rc.bottom; }
if (hFontOld) ::SelectObject(hDC, hFontOld); if (hFont) ::DeleteObject(hFont); }
::ReleaseDC(hWnd, hDC);}
DWORD CTipbarThread::IsDirtyItem(){ DWORD dwDirty = 0; for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) { CTipbarItem* pItem = m_UIObjects[iItem]; if (pItem) dwDirty |= pItem->m_dwDirty; } return dwDirty;}
BOOL CTipbarThread::IsFocusThread(){ if (!m_pTipbarWnd) return FALSE; return this == m_pTipbarWnd->m_pFocusThread;}
BOOL CTipbarThread::IsVertical(){ if (!m_pTipbarWnd) return FALSE; return !!(m_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_VERTICAL);}
/// @unimplementedvoid CTipbarThread::LocateItems(){}
LONG CTipbarThread::_Release(){ if (--m_cRefs == 0) { delete this; return 0; } return m_cRefs;}
HRESULT CTipbarThread::_UnadviseItemsSink(){ if (!m_pLangBarItemMgr) return E_FAIL;
DWORD *pdwCoolkies = new(cicNoThrow) DWORD[m_UIObjects.size()]; if (!pdwCoolkies) return E_OUTOFMEMORY;
const size_t cItems = m_UIObjects.size(); for (size_t iItem = 0; iItem < cItems; ++iItem) { CTipbarItem* pItem = m_UIObjects[iItem]; if (pItem) pdwCoolkies[iItem] = pItem->m_dwCookie; }
HRESULT hr = m_pLangBarItemMgr->UnadviseItemsSink((LONG)cItems, pdwCoolkies);
delete[] pdwCoolkies;
return hr;}
void CTipbarThread::MyMoveWnd(LONG xDelta, LONG yDelta){ if (!m_pTipbarWnd || (m_pTipbarWnd->m_pFocusThread != this)) return;
RECT Rect, rcWorkArea; m_pTipbarWnd->GetRect(&Rect); POINT pt = { Rect.left, Rect.top }; cicGetWorkAreaRect(pt, &rcWorkArea);
::GetWindowRect(*m_pTipbarWnd->GetWindow(), &Rect);
LONG X0 = Rect.left + xDelta, Y0 = Rect.top + yDelta; if (m_pTipbarWnd->m_dwTipbarWndFlags & 0x1000) { if (m_pTipbarWnd->CheckExcludeCaptionButtonMode(&Rect, &rcWorkArea)) { X0 = rcWorkArea.right - (3 * m_pTipbarWnd->m_ButtonWidth + m_pTipbarWnd->m_cxDlgFrameX2 + m_cxGrip); Y0 = 0; } else { m_pTipbarWnd->m_dwTipbarWndFlags &= ~0x1000; } }
if (IsVertical()) { LONG width = m_pTipbarWnd->m_cxDlgFrameX2 + m_pTipbarWnd->GetTipbarHeight(); LONG height = m_cyGrip + m_pTipbarWnd->m_cyDlgFrameX2; m_pTipbarWnd->SetMoveRect(X0, Y0, width, height); } else { LONG width = m_cxGrip + m_pTipbarWnd->m_cxDlgFrameX2; LONG height = m_pTipbarWnd->m_cyDlgFrameX2 + m_pTipbarWnd->GetTipbarHeight(); m_pTipbarWnd->SetMoveRect(X0, Y0, width, height); }
SIZE frameSize = { 0, 0 }; if (m_pTipbarWnd->m_pWndFrame) m_pTipbarWnd->m_pWndFrame->GetFrameSize(&frameSize);
m_pTipbarWnd->LocateCtrlButtons(); m_pTipbarWnd->AutoAdjustDeskBandSize();}
/*********************************************************************** * CTipbarItem */
CTipbarItem::CTipbarItem( CTipbarThread *pThread, ITfLangBarItem *pLangBarItem, TF_LANGBARITEMINFO *pItemInfo, DWORD dwUnknown16){ m_dwUnknown19[1] = 0; m_dwUnknown19[2] = 0; m_dwUnknown19[3] = 0; m_pTipbarThread = pThread; m_ItemInfo = *pItemInfo; m_pLangBarItem = pLangBarItem; m_pLangBarItem->AddRef(); m_dwItemFlags = 0; m_dwUnknown16 = dwUnknown16; m_dwDirty = 0x1001F;}
CTipbarItem::~CTipbarItem(){ if (g_pTipbarWnd) { if (g_pTipbarWnd->m_pTipbarAccessible) g_pTipbarWnd->m_pTipbarAccessible->RemoveAccItem(this); }
if (m_pLangBarItem) m_pLangBarItem->Release();}
void CTipbarItem::_AddedToUI(){ if (!IsConnected()) return;
OnUnknown41();
m_dwItemFlags |= 0x2;
DWORD dwStatus; if (m_dwDirty) { if (m_dwDirty & 0x10000) m_pLangBarItem->GetStatus(&dwStatus); else dwStatus = 0; OnUnknown45(m_dwDirty, dwStatus); m_dwDirty = 0; }
if (m_pTipbarThread) { CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; if (pTipbarWnd) { CTipbarAccessible *pTipbarAccessible = pTipbarWnd->m_pTipbarAccessible; if (pTipbarAccessible) pTipbarAccessible->AddAccItem(this); } }
OnUnknown42();}
void CTipbarItem::_RemovedToUI(){ m_dwItemFlags &= ~0x2;
if (g_pTipbarWnd) { CTipbarAccessible *pAccessible = g_pTipbarWnd->m_pTipbarAccessible; if (pAccessible) pAccessible->RemoveAccItem(this); }}
void CTipbarItem::AddRemoveMeToUI(BOOL bFlag){ if (!IsConnected()) return;
m_pTipbarThread->LocateItems();
if (!IsConnected()) return;
m_pTipbarThread->AddAllSeparators();
CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; if (bFlag) OnUnknown46(pTipbarWnd ? pTipbarWnd->GetWindow() : NULL); else OnUnknown47(pTipbarWnd ? pTipbarWnd->GetWindow() : NULL);}
BOOL CTipbarItem::IsConnected(){ return (!(m_dwItemFlags & 0x10) && m_pTipbarThread && m_pTipbarThread->m_pTipbarWnd && m_pLangBarItem);}
void CTipbarItem::ClearConnections(){ m_pTipbarThread = NULL; if (m_pLangBarItem) { m_pLangBarItem->Release(); m_pLangBarItem = NULL; }}
/// @unimplementedvoid CTipbarItem::StartDemotingTimer(BOOL bStarted){ if (!g_bIntelliSense) return;
if (!m_pTipbarThread) return;
CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; if (!pTipbarWnd) return;
//FIXME}
STDMETHODIMP_(BOOL) CTipbarItem::DoAccDefaultAction(){ if (!m_pTipbarThread) return FALSE; CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; if (!pTipbarWnd) return FALSE; pTipbarWnd->StartDoAccDefaultActionTimer(this); return TRUE;}
/// @unimplementedSTDMETHODIMP_(void) CTipbarItem::OnUpdateHandler(ULONG, ULONG){}
STDMETHODIMP_(void) CTipbarItem::GetAccLocation(LPRECT prc){ OnUnknown57(prc);}
STDMETHODIMP_(BSTR) CTipbarItem::GetAccName(){ return ::SysAllocString(m_ItemInfo.szDescription);}
STDMETHODIMP_(LPCWSTR) CTipbarItem::GetToolTip(){ OnUnknown41();
if (!(m_dwItemFlags & 0x1)) { m_dwItemFlags |= 0x1;
BSTR bstrString; if (FAILED(m_pLangBarItem->GetTooltipString(&bstrString))) return NULL;
if (bstrString) { OnUnknown53(bstrString); ::SysFreeString(bstrString); } }
LPCWSTR pszToolTip = OnUnknown55();
OnUnknown42();
return pszToolTip;}
HRESULT CTipbarItem::OnUpdate(DWORD dwDirty){ if (!IsConnected()) return S_OK;
m_dwDirty |= dwDirty; m_dwItemFlags |= 0x20;
if ((dwDirty & 0x10000) || (m_dwItemFlags & 0x6)) { if (m_pTipbarThread) { CTipbarWnd *pTipBarWnd = m_pTipbarThread->m_pTipbarWnd; if (pTipBarWnd && *pTipBarWnd) { pTipBarWnd->KillTimer(6); pTipBarWnd->SetTimer(6, g_uTimerElapseONUPDATECALLED); } } }
return S_OK;}
void CTipbarItem::MyClientToScreen(LPPOINT ppt, LPRECT prc){ if (!m_pTipbarThread) return; if (m_pTipbarThread->m_pTipbarWnd) m_pTipbarThread->m_pTipbarWnd->MyClientToScreen(ppt, prc);}
/*********************************************************************** * GetTipbarInternal */BOOL GetTipbarInternal(HWND hWnd, DWORD dwFlags, CDeskBand *pDeskBand){ BOOL bParent = !!(dwFlags & 0x80000000); g_bWinLogon = !!(dwFlags & 0x1);
InitFromReg();
if (!g_bShowTipbar) return FALSE;
if (bParent) { g_pTrayIconWnd = new(cicNoThrow) CTrayIconWnd(); if (!g_pTrayIconWnd) return FALSE; g_pTrayIconWnd->CreateWnd(); }
g_pTipbarWnd = new(cicNoThrow) CTipbarWnd(bParent ? g_dwWndStyle : g_dwChildWndStyle); if (!g_pTipbarWnd || !g_pTipbarWnd->Initialize()) return FALSE;
g_pTipbarWnd->Init(!bParent, pDeskBand); g_pTipbarWnd->CreateWnd(hWnd);
::SetWindowText(*g_pTipbarWnd, TEXT("TF_FloatingLangBar_WndTitle"));
DWORD dwOldStatus = 0; if (!bParent) { g_pTipbarWnd->m_pLangBarMgr->GetPrevShowFloatingStatus(&dwOldStatus); g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND); }
DWORD dwStatus; g_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus); g_pTipbarWnd->ShowFloating(dwStatus);
if (!bParent && (dwOldStatus & TF_SFT_DESKBAND)) g_pTipbarWnd->m_dwTipbarWndFlags |= TIPBAR_NODESKBAND;
g_hwndParent = hWnd; return TRUE;}
/*********************************************************************** * GetLibTls (MSUTB.@) * * @implemented */EXTERN_C PCIC_LIBTHREAD WINAPIGetLibTls(VOID){ TRACE("()\n"); return &g_libTLS;}
/*********************************************************************** * GetPopupTipbar (MSUTB.@) * * @implemented */EXTERN_C BOOL WINAPIGetPopupTipbar(HWND hWnd, BOOL fWinLogon){ TRACE("(%p, %d)\n", hWnd, fWinLogon);
if (!fWinLogon) TurnOffSpeechIfItsOn();
return GetTipbarInternal(hWnd, fWinLogon | 0x80000000, NULL);}
/*********************************************************************** * SetRegisterLangBand (MSUTB.@) * * @implemented */EXTERN_C HRESULT WINAPISetRegisterLangBand(BOOL bRegister){ TRACE("(%d)\n", bRegister);
if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) // Desk band is for XP+ return E_FAIL;
BOOL bDeskBand = IsDeskBandFromReg(); if (bDeskBand == bRegister) return S_OK;
SetDeskBandToReg(bRegister);
if (!RegisterComCat(CLSID_MSUTBDeskBand, CATID_DeskBand, bRegister)) return TF_E_NOLOCK;
return S_OK;}
/*********************************************************************** * ClosePopupTipbar (MSUTB.@) * * @implemented */EXTERN_C VOID WINAPIClosePopupTipbar(VOID){ TRACE("()\n");
if (g_fInClosePopupTipbar) return;
g_fInClosePopupTipbar = TRUE;
if (g_pTipbarWnd) { g_pTipbarWnd->m_pDeskBand = NULL; g_pTipbarWnd->DestroyWnd(); g_pTipbarWnd->Release(); g_pTipbarWnd = NULL; }
if (g_pTrayIconWnd) { g_pTrayIconWnd->DestroyWnd(); delete g_pTrayIconWnd; g_pTrayIconWnd = NULL; }
UninitSkipRedrawHKLArray();
g_fInClosePopupTipbar = FALSE;}
/*********************************************************************** * DllRegisterServer (MSUTB.@) * * @implemented */STDAPI DllRegisterServer(VOID){ TRACE("()\n"); return gModule.DllRegisterServer(FALSE);}
/*********************************************************************** * DllUnregisterServer (MSUTB.@) * * @implemented */STDAPI DllUnregisterServer(VOID){ TRACE("()\n"); return gModule.DllUnregisterServer(FALSE);}
/*********************************************************************** * DllCanUnloadNow (MSUTB.@) * * @implemented */STDAPI DllCanUnloadNow(VOID){ TRACE("()\n"); return gModule.DllCanUnloadNow() && (g_DllRefCount == 0);}
/*********************************************************************** * DllGetClassObject (MSUTB.@) * * @implemented */STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv){ TRACE("()\n"); return gModule.DllGetClassObject(rclsid, riid, ppv);}
/// @implementedHRESULT APIENTRYMsUtbCoCreateInstance( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv){ if (IsEqualCLSID(rclsid, CLSID_TF_CategoryMgr)) return TF_CreateCategoryMgr((ITfCategoryMgr**)ppv); if (IsEqualCLSID(rclsid, CLSID_TF_DisplayAttributeMgr)) return TF_CreateDisplayAttributeMgr((ITfDisplayAttributeMgr **)ppv); return cicRealCoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);}
BEGIN_OBJECT_MAP(ObjectMap)#ifdef ENABLE_DESKBAND OBJECT_ENTRY(CLSID_MSUTBDeskBand, CDeskBand) // FIXME: Implement this#endifEND_OBJECT_MAP()
EXTERN_C VOID TFUninitLib(VOID){ // Do nothing}
/// @implementedBOOL ProcessAttach(HINSTANCE hinstDLL){ ::InitializeCriticalSectionAndSpinCount(&g_cs, 0);
g_hInst = hinstDLL;
cicGetOSInfo(&g_uACP, &g_dwOSInfo);
TFInitLib(MsUtbCoCreateInstance); cicInitUIFLib();
CTrayIconWnd::RegisterClass();
g_wmTaskbarCreated = RegisterWindowMessageW(L"TaskbarCreated");
gModule.Init(ObjectMap, hinstDLL, NULL); ::DisableThreadLibraryCalls(hinstDLL);
return TRUE;}
/// @implementedVOID ProcessDetach(HINSTANCE hinstDLL){ cicDoneUIFLib(); TFUninitLib(); ::DeleteCriticalSection(&g_cs); gModule.Term();}
/// @implementedEXTERN_C BOOL WINAPIDllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD dwReason, _Inout_opt_ LPVOID lpvReserved){ switch (dwReason) { case DLL_PROCESS_ATTACH: { TRACE("(%p, %lu, %p)\n", hinstDLL, dwReason, lpvReserved); if (!ProcessAttach(hinstDLL)) { ProcessDetach(hinstDLL); return FALSE; } break; } case DLL_PROCESS_DETACH: { ProcessDetach(hinstDLL); break; } } return TRUE;}