Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474/* * PROJECT: ReactOS Cicero * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: Cicero UIF Library * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> */
#include "precomp.h"#include "cicuif.h"
/////////////////////////////////////////////////////////////////////////////// static members
HINSTANCE CUIFTheme::s_hUXTHEME = NULL;FN_OpenThemeData CUIFTheme::s_fnOpenThemeData = NULL;FN_CloseThemeData CUIFTheme::s_fnCloseThemeData = NULL;FN_DrawThemeBackground CUIFTheme::s_fnDrawThemeBackground = NULL;FN_DrawThemeParentBackground CUIFTheme::s_fnDrawThemeParentBackground = NULL;FN_DrawThemeText CUIFTheme::s_fnDrawThemeText = NULL;FN_DrawThemeIcon CUIFTheme::s_fnDrawThemeIcon = NULL;FN_GetThemeBackgroundExtent CUIFTheme::s_fnGetThemeBackgroundExtent = NULL;FN_GetThemeBackgroundContentRect CUIFTheme::s_fnGetThemeBackgroundContentRect = NULL;FN_GetThemeTextExtent CUIFTheme::s_fnGetThemeTextExtent = NULL;FN_GetThemePartSize CUIFTheme::s_fnGetThemePartSize = NULL;FN_DrawThemeEdge CUIFTheme::s_fnDrawThemeEdge = NULL;FN_GetThemeColor CUIFTheme::s_fnGetThemeColor = NULL;FN_GetThemeMargins CUIFTheme::s_fnGetThemeMargins = NULL;FN_GetThemeFont CUIFTheme::s_fnGetThemeFont = NULL;FN_GetThemeSysColor CUIFTheme::s_fnGetThemeSysColor = NULL;FN_GetThemeSysSize CUIFTheme::s_fnGetThemeSysSize = NULL;
CUIFSystemInfo *CUIFSystemInfo::s_pSystemInfo = NULL;
CUIFColorTableSys *CUIFScheme::s_pColorTableSys = NULL;CUIFColorTableOff10 *CUIFScheme::s_pColorTableOff10 = NULL;
/////////////////////////////////////////////////////////////////////////////
void CUIFSystemInfo::GetSystemMetrics(){ HDC hDC = ::GetDC(NULL); m_cBitsPixels = ::GetDeviceCaps(hDC, BITSPIXEL); ::ReleaseDC(NULL, hDC);
HIGHCONTRAST HighContrast = { sizeof(HighContrast) }; ::SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HighContrast), &HighContrast, 0); m_bHighContrast1 = !!(HighContrast.dwFlags & HCF_HIGHCONTRASTON); COLORREF rgbBtnText = ::GetSysColor(COLOR_BTNTEXT); COLORREF rgbBtnFace = ::GetSysColor(COLOR_BTNFACE); const COLORREF black = RGB(0, 0, 0), white = RGB(255, 255, 255); m_bHighContrast2 = (m_bHighContrast1 || (rgbBtnText == black && rgbBtnFace == white) || (rgbBtnText == white && rgbBtnFace == black));}
void CUIFSystemInfo::Initialize(){ dwOSVersionInfoSize = sizeof(OSVERSIONINFO); ::GetVersionEx(this); GetSystemMetrics();}
/////////////////////////////////////////////////////////////////////////////// CUIFTheme
HRESULT CUIFTheme::InternalOpenThemeData(HWND hWnd){ if (!hWnd || !m_pszClassList) return E_FAIL;
if (!cicGetFN(s_hUXTHEME, s_fnOpenThemeData, TEXT("uxtheme.dll"), "OpenThemeData")) return E_FAIL; m_hTheme = s_fnOpenThemeData(hWnd, m_pszClassList); return (m_hTheme ? S_OK : E_FAIL);}
HRESULT CUIFTheme::EnsureThemeData(HWND hWnd){ if (m_hTheme) return S_OK; return InternalOpenThemeData(hWnd);}
HRESULT CUIFTheme::CloseThemeData(){ if (!m_hTheme) return S_OK;
if (!cicGetFN(s_hUXTHEME, s_fnCloseThemeData, TEXT("uxtheme.dll"), "CloseThemeData")) return E_FAIL;
HRESULT hr = s_fnCloseThemeData(m_hTheme); m_hTheme = NULL; return hr;}
STDMETHODIMPCUIFTheme::DrawThemeBackground(HDC hDC, int iStateId, LPCRECT pRect, LPCRECT pClipRect){ if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeBackground, TEXT("uxtheme.dll"), "DrawThemeBackground")) return E_FAIL; return s_fnDrawThemeBackground(m_hTheme, hDC, m_iPartId, iStateId, pRect, pClipRect);}
STDMETHODIMPCUIFTheme::DrawThemeParentBackground(HWND hwnd, HDC hDC, LPRECT prc){ if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeParentBackground, TEXT("uxtheme.dll"), "DrawThemeParentBackground")) return E_FAIL; return s_fnDrawThemeParentBackground(hwnd, hDC, prc);}
STDMETHODIMPCUIFTheme::DrawThemeText(HDC hDC, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect){ if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeText, TEXT("uxtheme.dll"), "DrawThemeText")) return E_FAIL; return s_fnDrawThemeText(m_hTheme, hDC, m_iPartId, iStateId, pszText, cchText, dwTextFlags, dwTextFlags2, pRect);}
STDMETHODIMPCUIFTheme::DrawThemeIcon(HDC hDC, int iStateId, LPCRECT pRect, HIMAGELIST himl, int iImageIndex){ if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeIcon, TEXT("uxtheme.dll"), "DrawThemeIcon")) return E_FAIL; return s_fnDrawThemeIcon(m_hTheme, hDC, m_iPartId, iStateId, pRect, himl, iImageIndex);}
STDMETHODIMPCUIFTheme::GetThemeBackgroundExtent(HDC hDC, int iStateId, LPCRECT pContentRect, LPRECT pExtentRect){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeBackgroundExtent, TEXT("uxtheme.dll"), "GetThemeBackgroundExtent")) return E_FAIL; return s_fnGetThemeBackgroundExtent(m_hTheme, hDC, m_iPartId, iStateId, pContentRect, pExtentRect);}
STDMETHODIMPCUIFTheme::GetThemeBackgroundContentRect(HDC hDC, int iStateId, LPCRECT pBoundingRect, LPRECT pContentRect){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeBackgroundContentRect, TEXT("uxtheme.dll"), "GetThemeBackgroundContentRect")) return E_FAIL; return s_fnGetThemeBackgroundContentRect(m_hTheme, hDC, m_iPartId, iStateId, pBoundingRect, pContentRect);}
STDMETHODIMPCUIFTheme::GetThemeTextExtent(HDC hDC, int iStateId, LPCWSTR pszText, int cchCharCount, DWORD dwTextFlags, LPCRECT pBoundingRect, LPRECT pExtentRect){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeTextExtent, TEXT("uxtheme.dll"), "GetThemeTextExtent")) return E_FAIL; return s_fnGetThemeTextExtent(m_hTheme, hDC, m_iPartId, iStateId, pszText, cchCharCount, dwTextFlags, pBoundingRect, pExtentRect);}
STDMETHODIMPCUIFTheme::GetThemePartSize(HDC hDC, int iStateId, LPRECT prc, THEMESIZE eSize, SIZE *psz){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemePartSize, TEXT("uxtheme.dll"), "GetThemePartSize")) return E_FAIL; return s_fnGetThemePartSize(m_hTheme, hDC, m_iPartId, iStateId, prc, eSize, psz);}
STDMETHODIMPCUIFTheme::DrawThemeEdge(HDC hDC, int iStateId, LPCRECT pDestRect, UINT uEdge, UINT uFlags, LPRECT pContentRect){ if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeEdge, TEXT("uxtheme.dll"), "DrawThemeEdge")) return E_FAIL; return s_fnDrawThemeEdge(m_hTheme, hDC, m_iPartId, iStateId, pDestRect, uEdge, uFlags, pContentRect);}
STDMETHODIMPCUIFTheme::GetThemeColor(int iStateId, int iPropId, COLORREF *pColor){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeColor, TEXT("uxtheme.dll"), "GetThemeColor")) return E_FAIL; return s_fnGetThemeColor(m_hTheme, m_iPartId, iStateId, iPropId, pColor);}
STDMETHODIMPCUIFTheme::GetThemeMargins(HDC hDC, int iStateId, int iPropId, LPRECT prc, MARGINS *pMargins){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeMargins, TEXT("uxtheme.dll"), "GetThemeMargins")) return E_FAIL; return s_fnGetThemeMargins(m_hTheme, hDC, m_iPartId, iStateId, iPropId, prc, pMargins);}
STDMETHODIMPCUIFTheme::GetThemeFont(HDC hDC, int iStateId, int iPropId, LOGFONTW *pFont){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeFont, TEXT("uxtheme.dll"), "GetThemeFont")) return E_FAIL; return s_fnGetThemeFont(m_hTheme, hDC, m_iPartId, iStateId, iPropId, pFont);}
STDMETHODIMP_(COLORREF)CUIFTheme::GetThemeSysColor(INT iColorId){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeSysColor, TEXT("uxtheme.dll"), "GetThemeSysColor")) return RGB(0, 0, 0); return s_fnGetThemeSysColor(m_hTheme, iColorId);}
STDMETHODIMP_(int)CUIFTheme::GetThemeSysSize(int iSizeId){ if (!cicGetFN(s_hUXTHEME, s_fnGetThemeSysSize, TEXT("uxtheme.dll"), "GetThemeSysSize")) return 0; return s_fnGetThemeSysSize(m_hTheme, iSizeId);}
STDMETHODIMP_(void)CUIFTheme::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT iStateId){ m_iPartId = iPartId; m_iStateId = iStateId; m_pszClassList = pszClassList;}
/////////////////////////////////////////////////////////////////////////////// CUIFObject
/// @unimplementedCUIFObject::CUIFObject(CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style){ m_pszClassList = NULL; m_hTheme = NULL; m_pParent = pParent; m_nObjectID = nObjectID; m_style = style;
if (prc) m_rc = *prc; else m_rc = { 0, 0, 0, 0 };
if (m_pParent) { m_pWindow = m_pParent->m_pWindow; m_pScheme = m_pParent->m_pScheme; } else { m_pWindow = NULL; m_pScheme = NULL; }
m_bEnable = m_bVisible = TRUE;
m_hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); m_bHasCustomFont = FALSE;
m_pszToolTip = NULL;
m_dwUnknown4[0] = -1; //FIXME: name m_dwUnknown4[1] = -1; //FIXME: name}
CUIFObject::~CUIFObject(){ if (m_pWindow) { CUIFToolTip *pToolTip = m_pWindow->m_pToolTip; if (pToolTip && pToolTip->m_pToolTipTarget == this) pToolTip->m_pToolTipTarget = NULL; }
if (m_pszToolTip) { delete[] m_pszToolTip; m_pszToolTip = NULL; }
for (size_t iObj = m_ObjectArray.size(); iObj > 0; ) { --iObj; delete m_ObjectArray[iObj]; } m_ObjectArray.clear();
if (m_pWindow) m_pWindow->RemoveUIObj(this);
CloseThemeData();}
STDMETHODIMP_(void) CUIFObject::OnPaint(HDC hDC){ if (!(m_pWindow->m_style & UIF_WINDOW_ENABLETHEMED) || !OnPaintTheme(hDC)) OnPaintNoTheme(hDC);}
STDMETHODIMP_(BOOL) CUIFObject::OnSetCursor(UINT uMsg, LONG x, LONG y){ return FALSE;}
STDMETHODIMP_(void) CUIFObject::GetRect(LPRECT prc){ *prc = m_rc;}
STDMETHODIMP_(BOOL) CUIFObject::PtInObject(POINT pt){ return m_bVisible && ::PtInRect(&m_rc, pt);}
STDMETHODIMP_(void) CUIFObject::PaintObject(HDC hDC, LPCRECT prc){ if (!m_bVisible) return;
if (!prc) prc = &m_rc;
OnPaint(hDC);
for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) { CUIFObject *pObject = m_ObjectArray[iItem]; RECT rc; if (::IntersectRect(&rc, prc, &pObject->m_rc)) pObject->PaintObject(hDC, &rc); }}
STDMETHODIMP_(void) CUIFObject::CallOnPaint(){ if (m_pWindow) m_pWindow->UpdateUI(&m_rc);}
STDMETHODIMP_(void) CUIFObject::Enable(BOOL bEnable){ if (m_bEnable == bEnable) return;
m_bEnable = bEnable; for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) m_ObjectArray[iItem]->Enable(bEnable);
CallOnPaint();}
STDMETHODIMP_(void) CUIFObject::Show(BOOL bVisible){ if (m_bVisible == bVisible) return;
m_bVisible = bVisible; for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) m_ObjectArray[iItem]->Show(bVisible);
if (m_bVisible || m_pParent) m_pParent->CallOnPaint();}
STDMETHODIMP_(void) CUIFObject::SetFontToThis(HFONT hFont){ m_bHasCustomFont = !!hFont; if (!hFont) hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); m_hFont = hFont;}
STDMETHODIMP_(void) CUIFObject::SetFont(HFONT hFont){ SetFontToThis(hFont);
for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) m_ObjectArray[iItem]->SetFont(hFont);
CallOnPaint();}
STDMETHODIMP_(void) CUIFObject::SetStyle(DWORD style){ m_style = style;}
STDMETHODIMP_(void) CUIFObject::AddUIObj(CUIFObject *pObject){ m_ObjectArray.Add(pObject); CallOnPaint();}
STDMETHODIMP_(void) CUIFObject::RemoveUIObj(CUIFObject *pObject){ if (m_ObjectArray.Remove(pObject)) CallOnPaint();}
STDMETHODIMP_(LRESULT) CUIFObject::OnObjectNotify(CUIFObject *pObject, WPARAM wParam, LPARAM lParam){ if (m_pParent) return m_pParent->OnObjectNotify(pObject, wParam, lParam); return 0;}
STDMETHODIMP_(void) CUIFObject::SetToolTip(LPCWSTR pszToolTip){ if (m_pszToolTip) { delete[] m_pszToolTip; m_pszToolTip = NULL; }
if (pszToolTip) { size_t cch = wcslen(pszToolTip); m_pszToolTip = new(cicNoThrow) WCHAR[cch + 1]; if (m_pszToolTip) lstrcpynW(m_pszToolTip, pszToolTip, cch + 1); }}
STDMETHODIMP_(void) CUIFObject::ClearWndObj(){ m_pWindow = NULL; for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) m_ObjectArray[iItem]->ClearWndObj();}
STDMETHODIMP_(void) CUIFObject::ClearTheme(){ CloseThemeData(); for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) m_ObjectArray[iItem]->ClearTheme();}
void CUIFObject::StartCapture(){ if (m_pWindow) m_pWindow->SetCaptureObject(this);}
void CUIFObject::EndCapture(){ if (m_pWindow) m_pWindow->SetCaptureObject(NULL);}
BOOL CUIFObject::IsCapture(){ return m_pWindow && (m_pWindow->m_pCaptured == this);}
void CUIFObject::SetRect(LPCRECT prc){ m_rc = *prc; if (m_pWindow) m_pWindow->OnObjectMoved(this); CallOnPaint();}
LRESULT CUIFObject::NotifyCommand(WPARAM wParam, LPARAM lParam){ if (m_pParent) return m_pParent->OnObjectNotify(this, wParam, lParam); return 0;}
void CUIFObject::DetachWndObj(){ if (m_pWindow) { CUIFToolTip *pToolTip = m_pWindow->m_pToolTip; if (pToolTip && pToolTip->m_pToolTipTarget == this) pToolTip->m_pToolTipTarget = NULL;
m_pWindow->RemoveUIObj(this); m_pWindow = NULL; }}
BOOL CUIFObject::IsRTL(){ if (!m_pWindow) return FALSE; return !!(m_pWindow->m_style & UIF_WINDOW_LAYOUTRTL);}
CUIFObject* CUIFObject::ObjectFromPoint(POINT pt){ if (!PtInObject(pt)) return NULL;
CUIFObject *pFound = this; for (size_t i = 0; i < m_ObjectArray.size(); ++i) { CUIFObject *pObject = m_ObjectArray[i]->ObjectFromPoint(pt); if (pObject) pFound = pObject; } return pFound;}
void CUIFObject::SetScheme(CUIFScheme *scheme){ m_pScheme = scheme; for (size_t i = 0; i < m_ObjectArray.size(); ++i) { m_ObjectArray[i]->SetScheme(scheme); }}
void CUIFObject::StartTimer(WPARAM wParam){ if (m_pWindow) m_pWindow->SetTimerObject(this, wParam);}
void CUIFObject::EndTimer(){ if (m_pWindow) m_pWindow->SetTimerObject(NULL, 0);}
/////////////////////////////////////////////////////////////////////////////// CUIFColorTable...
STDMETHODIMP_(void) CUIFColorTableSys::InitColor(){ m_rgbColors[0] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[1] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[2] = ::GetSysColor(COLOR_ACTIVEBORDER); m_rgbColors[3] = ::GetSysColor(COLOR_ACTIVECAPTION); m_rgbColors[4] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[5] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[6] = ::GetSysColor(COLOR_BTNTEXT); m_rgbColors[7] = ::GetSysColor(COLOR_CAPTIONTEXT); m_rgbColors[8] = ::GetSysColor(COLOR_GRAYTEXT); m_rgbColors[9] = ::GetSysColor(COLOR_HIGHLIGHT); m_rgbColors[10] = ::GetSysColor(COLOR_HIGHLIGHTTEXT); m_rgbColors[11] = ::GetSysColor(COLOR_INACTIVECAPTION); m_rgbColors[12] = ::GetSysColor(COLOR_INACTIVECAPTIONTEXT); m_rgbColors[13] = ::GetSysColor(COLOR_MENUTEXT); m_rgbColors[14] = ::GetSysColor(COLOR_WINDOW); m_rgbColors[15] = ::GetSysColor(COLOR_WINDOWTEXT);}
STDMETHODIMP_(void) CUIFColorTableSys::InitBrush(){ ZeroMemory(m_hBrushes, sizeof(m_hBrushes));}
STDMETHODIMP_(void) CUIFColorTableSys::DoneBrush(){ for (size_t i = 0; i < _countof(m_hBrushes); ++i) { if (m_hBrushes[i]) { ::DeleteObject(m_hBrushes[i]); m_hBrushes[i] = NULL; } }}
HBRUSH CUIFColorTableSys::GetBrush(INT iColor){ if (!m_hBrushes[iColor]) m_hBrushes[iColor] = ::CreateSolidBrush(m_rgbColors[iColor]); return m_hBrushes[iColor];}
HBRUSH CUIFColorTableOff10::GetBrush(INT iColor){ if (!m_hBrushes[iColor]) m_hBrushes[iColor] = ::CreateSolidBrush(m_rgbColors[iColor]); return m_hBrushes[iColor];}
/// @unimplementedSTDMETHODIMP_(void) CUIFColorTableOff10::InitColor(){ m_rgbColors[0] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[1] = ::GetSysColor(COLOR_WINDOW); m_rgbColors[2] = ::GetSysColor(COLOR_WINDOW); m_rgbColors[3] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[4] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[5] = ::GetSysColor(COLOR_WINDOW); m_rgbColors[6] = ::GetSysColor(COLOR_HIGHLIGHT); m_rgbColors[7] = ::GetSysColor(COLOR_WINDOWTEXT); m_rgbColors[8] = ::GetSysColor(COLOR_HIGHLIGHT); m_rgbColors[9] = ::GetSysColor(COLOR_HIGHLIGHT); m_rgbColors[10] = ::GetSysColor(COLOR_HIGHLIGHTTEXT); m_rgbColors[11] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[12] = ::GetSysColor(COLOR_BTNTEXT); m_rgbColors[13] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[14] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[15] = ::GetSysColor(COLOR_WINDOW); m_rgbColors[16] = ::GetSysColor(COLOR_HIGHLIGHT); m_rgbColors[17] = ::GetSysColor(COLOR_BTNTEXT); m_rgbColors[18] = ::GetSysColor(COLOR_WINDOW); m_rgbColors[19] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[20] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[21] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[22] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[23] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[24] = ::GetSysColor(COLOR_CAPTIONTEXT); m_rgbColors[25] = ::GetSysColor(COLOR_HIGHLIGHT); m_rgbColors[26] = ::GetSysColor(COLOR_HIGHLIGHTTEXT); m_rgbColors[27] = ::GetSysColor(COLOR_BTNFACE); m_rgbColors[28] = ::GetSysColor(COLOR_BTNTEXT); m_rgbColors[29] = ::GetSysColor(COLOR_BTNSHADOW); m_rgbColors[30] = ::GetSysColor(COLOR_BTNTEXT); m_rgbColors[31] = ::GetSysColor(COLOR_WINDOWTEXT);}
STDMETHODIMP_(void) CUIFColorTableOff10::InitBrush(){ ZeroMemory(m_hBrushes, sizeof(m_hBrushes));}
STDMETHODIMP_(void) CUIFColorTableOff10::DoneBrush(){ for (size_t i = 0; i < _countof(m_hBrushes); ++i) { if (m_hBrushes[i]) { ::DeleteObject(m_hBrushes[i]); m_hBrushes[i] = NULL; } }}
/////////////////////////////////////////////////////////////////////////////// CUIFScheme
/// @unimplementedCUIFScheme *cicCreateUIFScheme(DWORD type){#if 1 return new(cicNoThrow) CUIFSchemeDef(type);#else switch (type) { case 1: return new(cicNoThrow) CUIFSchemeOff10(1); case 2: return new(cicNoThrow) CUIFSchemeOff10(2); case 3: return new(cicNoThrow) CUIFSchemeOff10(3); default: return new(cicNoThrow) CUIFSchemeDef(type); }#endif}
STDMETHODIMP_(DWORD) CUIFSchemeDef::GetType(){ return m_dwType;}
STDMETHODIMP_(COLORREF) CUIFSchemeDef::GetColor(INT iColor){ return s_pColorTableSys->GetColor(iColor);}
STDMETHODIMP_(HBRUSH) CUIFSchemeDef::GetBrush(INT iColor){ return s_pColorTableSys->GetBrush(iColor);}
STDMETHODIMP_(INT) CUIFSchemeDef::CyMenuItem(INT cyText){ return cyText + 2;}
STDMETHODIMP_(INT) CUIFSchemeDef::CxSizeFrame(){ return ::GetSystemMetrics(SM_CXSIZEFRAME);}
STDMETHODIMP_(INT) CUIFSchemeDef::CySizeFrame(){ return ::GetSystemMetrics(SM_CYSIZEFRAME);}
STDMETHODIMP_(void) CUIFScheme::FillRect(HDC hDC, LPCRECT prc, INT iColor){ ::FillRect(hDC, prc, GetBrush(iColor));}
STDMETHODIMP_(void) CUIFScheme::FrameRect(HDC hDC, LPCRECT prc, INT iColor){ ::FrameRect(hDC, prc, GetBrush(iColor));}
STDMETHODIMP_(void) CUIFSchemeDef::DrawSelectionRect(HDC hDC, LPCRECT prc, int){ ::FillRect(hDC, prc, GetBrush(6));}
STDMETHODIMP_(void)CUIFSchemeDef::GetCtrlFaceOffset(DWORD dwUnknownFlags, DWORD dwDrawFlags, LPSIZE pSize){ if (!(dwDrawFlags & UIF_DRAW_PRESSED)) { if (dwDrawFlags & 0x2) { if (dwUnknownFlags & 0x10) { pSize->cx = pSize->cy = -1; return; } pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x20); } else { if (!(dwDrawFlags & 0x1)) { pSize->cx = pSize->cy = -((dwUnknownFlags & 1) != 0); return; } if (dwUnknownFlags & 0x4) { pSize->cx = pSize->cy = -1; return; } pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x8); } return; }
if (!(dwUnknownFlags & 0x40)) { pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x80); return; }
pSize->cx = pSize->cy = -1;}
STDMETHODIMP_(void)CUIFSchemeDef::DrawCtrlBkgd(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags){ ::FillRect(hDC, prc, GetBrush(9));
if (!(dwDrawFlags & UIF_DRAW_PRESSED) && (dwDrawFlags & 0x2)) return;
HBRUSH hbrDither = cicCreateDitherBrush(); if (!hbrDither) return;
COLORREF rgbOldText = ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNFACE)); COLORREF rgbOldBack = ::SetBkColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT));
RECT rc = *prc; ::InflateRect(&rc, -2, -2); ::FillRect(hDC, &rc, hbrDither); ::SetTextColor(hDC, rgbOldText); ::SetBkColor(hDC, rgbOldBack); ::DeleteObject(hbrDither);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawCtrlEdge( HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags){ UINT uEdge = BDR_RAISEDINNER;
if (dwDrawFlags & 0x10) { if (!(dwUnknownFlags & 0x40)) { if (dwUnknownFlags & 0x80) uEdge = BDR_SUNKENOUTER; else return; } } else if (dwDrawFlags & 0x2) { if (!(dwUnknownFlags & 0x10)) { if (dwUnknownFlags & 0x20) uEdge = BDR_SUNKENOUTER; else return; } } else if (dwDrawFlags & 0x1) { if (!(dwUnknownFlags & 0x4)) { if (dwUnknownFlags & 0x8) uEdge = BDR_SUNKENOUTER; else return; } } else if (!(dwUnknownFlags & 0x1)) { return; }
RECT rc = *prc; ::DrawEdge(hDC, &rc, uEdge, BF_RECT);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawCtrlText( HDC hDC, LPCRECT prc, LPCWSTR pszText, INT cchText, DWORD dwDrawFlags, BOOL bRight){ COLORREF rgbOldText = ::GetTextColor(hDC); INT OldBkMode = ::SetBkMode(hDC, TRANSPARENT);
if (cchText == -1) cchText = lstrlenW(pszText);
RECT rc = *prc; if (dwDrawFlags & UIF_DRAW_DISABLED) { ::OffsetRect(&rc, 1, 1); ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT)); ::ExtTextOutW(hDC, (bRight ? rc.right : rc.left), rc.top, ETO_CLIPPED, &rc, pszText, cchText, NULL); ::OffsetRect(&rc, -1, -1); }
::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT)); ::ExtTextOutW(hDC, (bRight ? rc.right : rc.left), rc.top, ETO_CLIPPED, &rc, pszText, cchText, NULL);
::SetTextColor(hDC, rgbOldText); ::SetBkMode(hDC, OldBkMode);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawCtrlIcon(HDC hDC, LPCRECT prc, HICON hIcon, DWORD dwDrawFlags, LPSIZE pSize){ if (m_bMirroring) { HBITMAP hbm1, hbm2; if (cicGetIconBitmaps(hIcon, &hbm1, &hbm2, pSize)) { DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags); ::DeleteObject(hbm1); ::DeleteObject(hbm2); } } else { UINT uFlags = DST_PREFIXTEXT | DST_TEXT; if (dwDrawFlags & UIF_DRAW_DISABLED) uFlags |= (DSS_MONO | DSS_DISABLED); ::DrawState(hDC, 0, 0, (LPARAM)hIcon, 0, prc->left, prc->top, 0, 0, uFlags); }}
STDMETHODIMP_(void)CUIFSchemeDef::DrawCtrlBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags){ if (m_bMirroring) { hbm1 = cicMirrorBitmap(hbm1, GetBrush(9)); hbm2 = cicMirrorBitmap(hbm2, (HBRUSH)GetStockObject(BLACK_BRUSH)); }
HBRUSH hBrush = (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1); BOOL bBrushCreated = FALSE; if (hbm2) { HBITMAP hBitmap = NULL; if (dwDrawFlags & UIF_DRAW_DISABLED) { hBitmap = cicCreateDisabledBitmap(prc, hbm2, GetBrush(9), GetBrush(11), TRUE); } else { if ((dwDrawFlags & UIF_DRAW_PRESSED) && !(dwDrawFlags & 0x2)) { hBrush = cicCreateDitherBrush(); bBrushCreated = TRUE; }
COLORREF rgbFace = ::GetSysColor(COLOR_BTNFACE); COLORREF rgbHighlight = ::GetSysColor(COLOR_BTNHIGHLIGHT); hBitmap = cicCreateMaskBmp(prc, hbm1, hbm2, hBrush, rgbFace, rgbHighlight); }
if (hBitmap) { ::DrawState(hDC, NULL, NULL, (LPARAM)hBitmap, 0, prc->left, prc->top, prc->right - prc->left, prc->bottom - prc->top, DST_BITMAP); ::DeleteObject(hBitmap); } } else { UINT uFlags = DST_BITMAP; if (dwDrawFlags & UIF_DRAW_DISABLED) uFlags |= (DSS_MONO | DSS_DISABLED);
::DrawState(hDC, NULL, NULL, (LPARAM)hbm1, 0, prc->left, prc->top, prc->right - prc->left, prc->bottom - prc->top, uFlags); }
if (bBrushCreated) ::DeleteObject(hBrush);
if (m_bMirroring) { ::DeleteObject(hbm1); ::DeleteObject(hbm2); }}
STDMETHODIMP_(void)CUIFSchemeDef::DrawMenuBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags){ DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawMenuSeparator(HDC hDC, LPCRECT prc){ RECT rc = *prc; rc.bottom = rc.top + (rc.bottom - rc.top) / 2; ::FillRect(hDC, &rc, (HBRUSH)UlongToHandle(COLOR_BTNSHADOW + 1));
rc = *prc; rc.top += (rc.bottom - rc.top) / 2; ::FillRect(hDC, &rc, (HBRUSH)UlongToHandle(COLOR_BTNHIGHLIGHT + 1));}
STDMETHODIMP_(void)CUIFSchemeDef::DrawFrameCtrlBkgd(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags){ DrawCtrlBkgd(hDC, prc, dwUnknownFlags, dwDrawFlags);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawFrameCtrlEdge(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags){ DrawCtrlEdge(hDC, prc, dwUnknownFlags, dwDrawFlags);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawFrameCtrlIcon(HDC hDC, LPCRECT prc, HICON hIcon, DWORD dwDrawFlags, LPSIZE pSize){ DrawCtrlIcon(hDC, prc, hIcon, dwDrawFlags, pSize);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawFrameCtrlBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags){ DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawWndFrame(HDC hDC, LPCRECT prc, DWORD type, DWORD unused1, DWORD unused2){ RECT rc = *prc; if (type && type <= 2) ::DrawEdge(hDC, &rc, BDR_RAISED, BF_RECT); else FrameRect(hDC, &rc, 14);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawDragHandle(HDC hDC, LPCRECT prc, BOOL bVertical){ RECT rc; if (bVertical) rc = { prc->left, prc->top + 1, prc->right, prc->top + 4 }; else rc = { prc->left + 1, prc->top, prc->left + 4, prc->bottom }; ::DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT);}
STDMETHODIMP_(void)CUIFSchemeDef::DrawSeparator(HDC hDC, LPCRECT prc, BOOL bVertical){ HPEN hLightPen = ::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNHIGHLIGHT)); if (!hLightPen) return;
HPEN hShadowPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); if (!hShadowPen) { ::DeleteObject(hLightPen); return; }
HGDIOBJ hPenOld = ::SelectObject(hDC, hShadowPen); if (bVertical) { ::MoveToEx(hDC, prc->left, prc->top + 1, NULL); ::LineTo(hDC, prc->right, prc->top + 1); ::SelectObject(hDC, hLightPen); ::MoveToEx(hDC, prc->left, prc->top + 2, NULL); ::LineTo(hDC, prc->right, prc->top + 2); } else { ::MoveToEx(hDC, prc->left + 1, prc->top, NULL); ::LineTo(hDC, prc->left + 1, prc->bottom); ::SelectObject(hDC, hLightPen); ::MoveToEx(hDC, prc->left + 2, prc->top, NULL); ::LineTo(hDC, prc->left + 2, prc->bottom); } ::SelectObject(hDC, hPenOld);
::DeleteObject(hShadowPen); ::DeleteObject(hLightPen);}
/////////////////////////////////////////////////////////////////////////////// CUIFIcon
HIMAGELIST CUIFIcon::GetImageList(BOOL bMirror){ if (!m_hImageList) return NULL;
if (m_hIcon) { SIZE iconSize; cicGetIconSize(m_hIcon, &iconSize);
UINT uFlags = ILC_COLOR32 | ILC_MASK; if (bMirror) uFlags |= ILC_MIRROR;
m_hImageList = ImageList_Create(iconSize.cx, iconSize.cy, uFlags, 1, 0); if (m_hImageList) ImageList_ReplaceIcon(m_hImageList, -1, m_hIcon);
return m_hImageList; }
return NULL;}
/////////////////////////////////////////////////////////////////////////////// CUIFBitmapDC
CUIFBitmapDC::CUIFBitmapDC(BOOL bMemory){ m_hBitmap = NULL; m_hOldBitmap = NULL; m_hOldObject = NULL; if (bMemory) m_hDC = ::CreateCompatibleDC(NULL); else m_hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);}
CUIFBitmapDC::~CUIFBitmapDC(){ Uninit(); ::DeleteDC(m_hDC);}
void CUIFBitmapDC::Uninit(BOOL bKeep){ if (m_hOldBitmap) { ::SelectObject(m_hDC, m_hOldBitmap); m_hOldBitmap = NULL; }
if (m_hOldObject) { ::SelectObject(m_hDC, m_hOldObject); m_hOldObject = NULL; }
if (!bKeep) { if (m_hBitmap) { ::DeleteObject(m_hBitmap); m_hBitmap = NULL; } }}
BOOL CUIFBitmapDC::SetBitmap(HBITMAP hBitmap){ if (m_hDC) m_hOldBitmap = ::SelectObject(m_hDC, hBitmap); return TRUE;}
BOOL CUIFBitmapDC::SetBitmap(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount){ m_hBitmap = ::CreateBitmap(cx, cy, cPlanes, cBitCount, 0); m_hOldBitmap = ::SelectObject(m_hDC, m_hBitmap); return TRUE;}
BOOL CUIFBitmapDC::SetDIB(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount){ BITMAPINFO bmi; ZeroMemory(&bmi, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = cx; bmi.bmiHeader.biHeight = cy; bmi.bmiHeader.biPlanes = cPlanes; bmi.bmiHeader.biBitCount = cBitCount; bmi.bmiHeader.biCompression = BI_RGB; m_hBitmap = ::CreateDIBSection(m_hDC, &bmi, DIB_RGB_COLORS, NULL, NULL, 0); m_hOldBitmap = ::SelectObject(m_hDC, m_hBitmap); return TRUE;}
void cicInitUIFUtil(void){ if (!CUIFBitmapDC::s_phdcSrc) CUIFBitmapDC::s_phdcSrc = new(cicNoThrow) CUIFBitmapDC(TRUE);
if (!CUIFBitmapDC::s_phdcMask) CUIFBitmapDC::s_phdcMask = new(cicNoThrow) CUIFBitmapDC(TRUE);
if (!CUIFBitmapDC::s_phdcDst) CUIFBitmapDC::s_phdcDst = new(cicNoThrow) CUIFBitmapDC(TRUE);
if (CUIFBitmapDC::s_phdcSrc && CUIFBitmapDC::s_phdcMask && CUIFBitmapDC::s_phdcDst) CUIFBitmapDC::s_fInitBitmapDCs = TRUE;}
void cicDoneUIFUtil(void){ if (CUIFBitmapDC::s_phdcSrc) { delete CUIFBitmapDC::s_phdcSrc; CUIFBitmapDC::s_phdcSrc = NULL; }
if (CUIFBitmapDC::s_phdcMask) { delete CUIFBitmapDC::s_phdcMask; CUIFBitmapDC::s_phdcMask = NULL; }
if (CUIFBitmapDC::s_phdcDst) { delete CUIFBitmapDC::s_phdcDst; CUIFBitmapDC::s_phdcDst = NULL; }
CUIFBitmapDC::s_fInitBitmapDCs = FALSE;}
HBITMAP cicMirrorBitmap(HBITMAP hBitmap, HBRUSH hbrBack){ BITMAP bm; if (!CUIFBitmapDC::s_fInitBitmapDCs || !::GetObject(hBitmap, sizeof(bm), &bm)) return NULL;
CUIFBitmapDC::s_phdcSrc->SetBitmap(hBitmap); CUIFBitmapDC::s_phdcDst->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32); CUIFBitmapDC::s_phdcMask->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32);
RECT rc = { 0, 0, bm.bmWidth, bm.bmHeight }; FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbrBack);
::SetLayout(*CUIFBitmapDC::s_phdcMask, LAYOUT_RTL);
::BitBlt(*CUIFBitmapDC::s_phdcMask, 0, 0, bm.bmWidth, bm.bmHeight, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCCOPY);
::SetLayout(*CUIFBitmapDC::s_phdcMask, 0);
::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, bm.bmWidth, bm.bmHeight, *CUIFBitmapDC::s_phdcMask, 1, 0, SRCCOPY);
CUIFBitmapDC::s_phdcSrc->Uninit(); CUIFBitmapDC::s_phdcMask->Uninit(); CUIFBitmapDC::s_phdcDst->Uninit(TRUE); return CUIFBitmapDC::s_phdcDst->DetachBitmap();}
HBRUSH cicCreateDitherBrush(VOID){ BYTE bytes[16]; ZeroMemory(&bytes, sizeof(bytes)); bytes[0] = bytes[4] = bytes[8] = bytes[12] = 0x55; bytes[2] = bytes[6] = bytes[10] = bytes[14] = 0xAA; HBITMAP hBitmap = ::CreateBitmap(8, 8, 1, 1, bytes); if (!hBitmap) return NULL;
LOGBRUSH lb; lb.lbHatch = (ULONG_PTR)hBitmap; lb.lbStyle = BS_PATTERN; HBRUSH hbr = ::CreateBrushIndirect(&lb); ::DeleteObject(hBitmap); return hbr;}
HBITMAPcicCreateDisabledBitmap(LPCRECT prc, HBITMAP hbmMask, HBRUSH hbr1, HBRUSH hbr2, BOOL bPressed){ if (!CUIFBitmapDC::s_fInitBitmapDCs) return NULL;
LONG width = prc->right - prc->left, height = prc->bottom - prc->top;
CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); CUIFBitmapDC::s_phdcMask->SetBitmap(hbmMask); CUIFBitmapDC::s_phdcSrc->SetDIB(width, height, 1, 32);
RECT rc = { 0, 0, width, height }; ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr1);
HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH); ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, hbrWhite);
::BitBlt(*CUIFBitmapDC::s_phdcSrc, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCINVERT); if (bPressed) ::BitBlt(*CUIFBitmapDC::s_phdcDst, 1, 1, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCPAINT); else ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCPAINT);
::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, hbr2);
::BitBlt(*CUIFBitmapDC::s_phdcSrc, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCPAINT); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCAND);
CUIFBitmapDC::s_phdcSrc->Uninit(); CUIFBitmapDC::s_phdcMask->Uninit(); CUIFBitmapDC::s_phdcDst->Uninit(TRUE); return CUIFBitmapDC::s_phdcDst->DetachBitmap();}
HBITMAPcicCreateShadowMaskBmp(LPRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hbr1, HBRUSH hbr2){ if (!CUIFBitmapDC::s_fInitBitmapDCs) return NULL;
--prc->left; --prc->top;
LONG width = prc->right - prc->left; LONG height = prc->bottom - prc->top;
CUIFBitmapDC bitmapDC(TRUE);
CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); CUIFBitmapDC::s_phdcSrc->SetBitmap(hbm1); CUIFBitmapDC::s_phdcMask->SetBitmap(hbm2); bitmapDC.SetDIB(width, height, 1, 32);
RECT rc = { 0, 0, width, height };
::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr1); ::FillRect(bitmapDC, &rc, hbr2);
::BitBlt(bitmapDC, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCPAINT); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 2, 2, width, height, bitmapDC, 0, 0, SRCAND); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCAND); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCINVERT);
CUIFBitmapDC::s_phdcSrc->Uninit(); CUIFBitmapDC::s_phdcMask->Uninit(); CUIFBitmapDC::s_phdcDst->Uninit(TRUE); return CUIFBitmapDC::s_phdcDst->DetachBitmap();}
HBITMAPcicChangeBitmapColor(LPCRECT prc, HBITMAP hbm, COLORREF rgbBack, COLORREF rgbFore){ if (!CUIFBitmapDC::s_fInitBitmapDCs) return NULL;
INT width = prc->right - prc->left; INT height = prc->bottom - prc->top;
CUIFSolidBrush brush(rgbFore);
CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); CUIFBitmapDC::s_phdcSrc->SetBitmap(hbm); CUIFBitmapDC::s_phdcMask->SetBitmap(width, height, 1, 1);
::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCCOPY); ::SelectObject(*CUIFBitmapDC::s_phdcDst, (HBRUSH)brush); ::SetBkColor(*CUIFBitmapDC::s_phdcDst, rgbBack);
::BitBlt(*CUIFBitmapDC::s_phdcMask, 0, 0, width, height, *CUIFBitmapDC::s_phdcDst, 0, 0, MERGECOPY); ::SetBkColor(*CUIFBitmapDC::s_phdcDst, RGB(255, 255, 255)); ::SetTextColor(*CUIFBitmapDC::s_phdcDst, RGB(0, 0, 0)); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, 0xE20746u);
CUIFBitmapDC::s_phdcSrc->Uninit(); CUIFBitmapDC::s_phdcMask->Uninit(); CUIFBitmapDC::s_phdcDst->Uninit(TRUE); return CUIFBitmapDC::s_phdcDst->DetachBitmap();}
HBITMAPcicConvertBlackBKGBitmap(LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hBrush){ if (!CUIFBitmapDC::s_fInitBitmapDCs) return NULL;
if (IS_INTRESOURCE(hBrush)) hBrush = ::GetSysColorBrush(HandleToLong(hBrush) - 1);
LOGBRUSH lb; ::GetObject(hBrush, sizeof(lb), &lb); if (lb.lbStyle || lb.lbColor) return NULL;
INT width = prc->right - prc->left; INT height = prc->bottom - prc->top;
HBITMAP hBitmap = cicChangeBitmapColor(prc, hbm1, 0, RGB(255, 255, 255)); if ( !hBitmap ) return NULL;
CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); CUIFBitmapDC::s_phdcSrc->SetBitmap(hBitmap); CUIFBitmapDC::s_phdcMask->SetBitmap(hbm2);
RECT rc = { 0, 0, width, height };
HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH); ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbrWhite);
::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, 0x660046u); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, 0x8800C6u);
CUIFBitmapDC::s_phdcSrc->Uninit(); CUIFBitmapDC::s_phdcMask->Uninit(); CUIFBitmapDC::s_phdcDst->Uninit(TRUE); ::DeleteObject(hBitmap); return CUIFBitmapDC::s_phdcDst->DetachBitmap();}
HBITMAPcicCreateMaskBmp(LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hbr, COLORREF rgbColor, COLORREF rgbBack){ if (!CUIFBitmapDC::s_fInitBitmapDCs) return NULL;
INT width = prc->right - prc->left; INT height = prc->bottom - prc->top; HBITMAP hBitmap = cicConvertBlackBKGBitmap(prc, hbm1, hbm2, hbr); if (hBitmap) return hBitmap;
CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32); CUIFBitmapDC::s_phdcSrc->SetBitmap(hbm1); CUIFBitmapDC::s_phdcMask->SetBitmap(hbm2);
RECT rc = { 0, 0, width, height };
COLORREF OldTextColor = ::SetTextColor(*CUIFBitmapDC::s_phdcDst, rgbColor); COLORREF OldBkColor = ::SetBkColor(*CUIFBitmapDC::s_phdcDst, rgbBack); ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr); ::SetTextColor(*CUIFBitmapDC::s_phdcDst, OldTextColor); ::SetBkColor(*CUIFBitmapDC::s_phdcDst, OldBkColor);
::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCAND); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCINVERT); CUIFBitmapDC::s_phdcSrc->Uninit(); CUIFBitmapDC::s_phdcMask->Uninit(); CUIFBitmapDC::s_phdcDst->Uninit(TRUE);
return CUIFBitmapDC::s_phdcDst->DetachBitmap();}
BOOL cicGetIconBitmaps(HICON hIcon, HBITMAP *hbm1, HBITMAP *hbm2, const SIZE *pSize){ if (!CUIFBitmapDC::s_fInitBitmapDCs) return FALSE;
SIZE size; if (pSize) { size = *pSize; } else { if (!cicGetIconSize(hIcon, &size)) return FALSE; }
CUIFBitmapDC::s_phdcSrc->SetDIB(size.cx, size.cy, 1, 32); CUIFBitmapDC::s_phdcMask->SetBitmap(size.cx, size.cy, 1, 1);
RECT rc = { 0, 0, size.cx, size.cy }; ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
::DrawIconEx(*CUIFBitmapDC::s_phdcSrc, 0, 0, hIcon, size.cx, size.cy, 0, 0, DI_NORMAL); ::DrawIconEx(*CUIFBitmapDC::s_phdcMask, 0, 0, hIcon, size.cx, size.cy, 0, 0, DI_MASK);
CUIFBitmapDC::s_phdcSrc->Uninit(TRUE); CUIFBitmapDC::s_phdcMask->Uninit(TRUE); *hbm1 = CUIFBitmapDC::s_phdcSrc->DetachBitmap(); *hbm2 = CUIFBitmapDC::s_phdcMask->DetachBitmap(); return TRUE;}
void cicDrawMaskBmpOnDC(HDC hDC, LPCRECT prc, HBITMAP hbmp, HBITMAP hbmpMask){ if (!CUIFBitmapDC::s_fInitBitmapDCs) return;
LONG cx = prc->right - prc->left, cy = prc->bottom - prc->top; CUIFBitmapDC::s_phdcDst->SetDIB(cx, cy, 1, 32); CUIFBitmapDC::s_phdcSrc->SetBitmap(hbmp); CUIFBitmapDC::s_phdcMask->SetBitmap(hbmpMask); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, cx, cy, hDC, prc->left, prc->top, SRCCOPY); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, cx, cy, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCAND); ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, cx, cy, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCINVERT); ::BitBlt(hDC, prc->left, prc->top, cx, cy, *CUIFBitmapDC::s_phdcDst, 0, 0, SRCCOPY); CUIFBitmapDC::s_phdcSrc->Uninit(FALSE); CUIFBitmapDC::s_phdcMask->Uninit(FALSE); CUIFBitmapDC::s_phdcDst->Uninit(FALSE);}
/////////////////////////////////////////////////////////////////////////////// CUIFWindow
CUIFWindow::CUIFWindow(HINSTANCE hInst, DWORD style) : CUIFObject(NULL, 0, NULL, style){ m_hInst = hInst; m_nLeft = 200; m_nTop = 200; m_nWidth = 200; m_nHeight = 200; m_hWnd = 0; m_pWindow = this; m_pCaptured = NULL; m_pTimerObject = NULL; m_pPointed = NULL; m_bPointing = FALSE; m_pToolTip = NULL; m_pShadow = NULL; m_bShowShadow = TRUE; m_pBehindModal = NULL; CUIFWindow::CreateScheme();}
CUIFWindow::~CUIFWindow(){ if (m_pToolTip) { delete m_pToolTip; m_pToolTip = NULL; } if (m_pShadow) { delete m_pShadow; m_pShadow = NULL; } for (size_t i = m_ObjectArray.size(); i > 0; ) { --i; CUIFObject *pObject = m_ObjectArray[i]; m_ObjectArray[i] = NULL; m_ObjectArray.Remove(pObject); delete pObject; } if (m_pScheme) { delete m_pScheme; m_pScheme = NULL; }}
STDMETHODIMP_(BOOL)CUIFWindow::Initialize(){ LPCTSTR pszClass = GetClassName();
WNDCLASSEX wcx; ZeroMemory(&wcx, sizeof(wcx)); wcx.cbSize = sizeof(WNDCLASSEXW); if (!::GetClassInfoEx(m_hInst, pszClass, &wcx)) { ZeroMemory(&wcx, sizeof(wcx)); wcx.cbSize = sizeof(wcx); wcx.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wcx.lpfnWndProc = CUIFWindow::WindowProcedure; wcx.cbClsExtra = 0; wcx.cbWndExtra = sizeof(LONG_PTR) * 2; wcx.hInstance = m_hInst; wcx.hIcon = NULL; wcx.hCursor = ::LoadCursor(NULL, IDC_ARROW); wcx.lpszClassName = pszClass; wcx.hbrBackground = NULL; wcx.lpszMenuName = NULL; wcx.hIconSm = NULL; ::RegisterClassEx(&wcx); }
cicUpdateUIFSys(); cicUpdateUIFScheme();
if (m_style & UIF_WINDOW_TOOLTIP) { DWORD style = (m_style & UIF_WINDOW_LAYOUTRTL) | UIF_WINDOW_TOPMOST | 0x10; m_pToolTip = new(cicNoThrow) CUIFToolTip(m_hInst, style, this); if (m_pToolTip) m_pToolTip->Initialize(); }
if (m_style & UIF_WINDOW_SHADOW) { m_pShadow = new(cicNoThrow) CUIFShadow(m_hInst, UIF_WINDOW_TOPMOST, this); if (m_pShadow) m_pShadow->Initialize(); }
return CUIFObject::Initialize();}
STDMETHODIMP_(LRESULT)CUIFWindow::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);}
void CUIFWindow::UpdateUI(LPCRECT prc){ if (::IsWindow(m_hWnd)) ::InvalidateRect(m_hWnd, prc, FALSE);}
CUIFWindow*CUIFWindow::GetThis(HWND hWnd){ return (CUIFWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);}
voidCUIFWindow::SetThis(HWND hWnd, LONG_PTR dwNewLong){ ::SetWindowLongPtr(hWnd, GWLP_USERDATA, dwNewLong);}
void CUIFWindow::CreateScheme(){ if (m_pScheme) { delete m_pScheme; m_pScheme = NULL; }
INT iScheme = 0; if (m_style & UIF_WINDOW_USESCHEME1) iScheme = 1; else if (m_style & UIF_WINDOW_USESCHEME2) iScheme = 2; else if (m_style & UIF_WINDOW_USESCHEME3) iScheme = 3;
m_pScheme = cicCreateUIFScheme(iScheme); SetScheme(m_pScheme);}
STDMETHODIMP_(DWORD)CUIFWindow::GetWndStyle(){ DWORD ret;
if (m_style & UIF_WINDOW_CHILD) ret = WS_CHILD | WS_CLIPSIBLINGS; else ret = WS_POPUP | WS_DISABLED;
if (m_style & UIF_WINDOW_USESCHEME1) ret |= WS_BORDER; else if (m_style & UIF_WINDOW_DLGFRAME) ret |= WS_DLGFRAME; else if ((m_style & UIF_WINDOW_USESCHEME2) || (m_style & 0x10)) ret |= WS_BORDER;
return ret;}
STDMETHODIMP_(DWORD)CUIFWindow::GetWndStyleEx(){ DWORD ret = 0; if (m_style & UIF_WINDOW_TOPMOST) ret |= WS_EX_TOPMOST; if (m_style & UIF_WINDOW_TOOLWINDOW) ret |= WS_EX_TOOLWINDOW; if (m_style & UIF_WINDOW_LAYOUTRTL) ret |= WS_EX_LAYOUTRTL; return ret;}
STDMETHODIMP_(HWND)CUIFWindow::CreateWnd(HWND hwndParent){ HWND hWnd = CreateWindowEx(GetWndStyleEx(), GetClassName(), GetWndTitle(), GetWndStyle(), m_nLeft, m_nTop, m_nWidth, m_nHeight, hwndParent, NULL, m_hInst, this); if (m_pToolTip) m_pToolTip->CreateWnd(hWnd); if (m_pShadow) m_pShadow->CreateWnd(hWnd); return hWnd;}
void CUIFWindow::Show(BOOL bVisible){ if (!IsWindow(m_hWnd)) return;
if (bVisible && (m_style & UIF_WINDOW_TOPMOST)) ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
m_bVisible = bVisible; ::ShowWindow(m_hWnd, (bVisible ? SW_SHOWNOACTIVATE : 0));}
STDMETHODIMP_(BOOL)CUIFWindow::AnimateWnd(DWORD dwTime, DWORD dwFlags){ if (!::IsWindow(m_hWnd)) return FALSE;
BOOL bVisible = !(dwFlags & 0x10000); OnAnimationStart(); BOOL ret = ::AnimateWindow(m_hWnd, dwTime, dwFlags); if (!ret) m_bVisible = bVisible; OnAnimationEnd(); return ret;}
void CUIFWindow::SetCaptureObject(CUIFObject *pCaptured){ if (pCaptured) { m_pCaptured = pCaptured; SetCapture(TRUE); } else { m_pCaptured = NULL; SetCapture(FALSE); }}
STDMETHODIMP_(void)CUIFWindow::SetCapture(BOOL bSet){ if (bSet) ::SetCapture(m_hWnd); else ::ReleaseCapture();}
void CUIFWindow::SetObjectPointed(CUIFObject *pPointed, POINT pt){ if (pPointed == m_pPointed) return;
if (m_pCaptured) { if (m_pCaptured == m_pPointed && m_pPointed->m_bEnable) m_pPointed->OnMouseOut(pt.x, pt.y); } else if (m_pPointed && m_pPointed->m_bEnable) { m_pPointed->OnMouseOut(pt.x, pt.y); }
m_pPointed = pPointed;
if (m_pCaptured) { if (m_pCaptured == m_pPointed && m_pPointed->m_bEnable) m_pPointed->OnMouseIn(pt.x, pt.y); } else if (m_pPointed && m_pPointed->m_bEnable) { m_pPointed->OnMouseIn(pt.x, pt.y); }}
STDMETHODIMP_(void)CUIFWindow::OnObjectMoved(CUIFObject *pObject){ if (!::IsWindow(m_hWnd)) return;
POINT pt; ::GetCursorPos(&pt); ::ScreenToClient(m_hWnd, &pt); POINT pt2 = pt; CUIFObject *pFound = ObjectFromPoint(pt); SetObjectPointed(pFound, pt2);}
STDMETHODIMP_(void)CUIFWindow::SetRect(LPCRECT prc){ RECT Rect = { 0, 0, 0, 0 };
if (::IsWindow(m_hWnd)) ::GetClientRect(m_hWnd, &Rect);
CUIFObject::SetRect(&Rect);}
STDMETHODIMP_(void)CUIFWindow::ClientRectToWindowRect(LPRECT lpRect){ DWORD style, exstyle; if (::IsWindow(m_hWnd)) { style = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); exstyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE); } else { style = GetWndStyle(); exstyle = GetWndStyleEx(); } ::AdjustWindowRectEx(lpRect, style, FALSE, exstyle);}
STDMETHODIMP_(void)CUIFWindow::GetWindowFrameSize(LPSIZE pSize){ RECT rc = { 0, 0, 0, 0 };
ClientRectToWindowRect(&rc); pSize->cx = (rc.right - rc.left) / 2; pSize->cy = (rc.bottom - rc.top) / 2;}
STDMETHODIMP_(void)CUIFWindow::OnAnimationEnd(){ if (m_pShadow && m_bShowShadow) m_pShadow->Show(m_bVisible);}
STDMETHODIMP_(void)CUIFWindow::OnThemeChanged(HWND hWnd, WPARAM wParam, LPARAM lParam){ ClearTheme();}
LRESULTCUIFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { case WM_GETOBJECT: return OnGetObject(hWnd, WM_GETOBJECT, wParam, lParam);
case WM_SYSCOLORCHANGE: cicUpdateUIFScheme(); OnSysColorChange(); return 0;
case WM_ENDSESSION: OnEndSession(hWnd, wParam, lParam); return 0;
case WM_SHOWWINDOW: if (m_pShadow && m_bShowShadow) m_pShadow->Show(wParam); return OnShowWindow(hWnd, WM_SHOWWINDOW, wParam, lParam);
case WM_SETTINGCHANGE: cicUpdateUIFSys(); cicUpdateUIFScheme(); return OnSettingChange(hWnd, WM_SETTINGCHANGE, wParam, lParam); case WM_SETCURSOR: { POINT Point; ::GetCursorPos(&Point); ::ScreenToClient(m_hWnd, &Point);
if (m_pBehindModal) { m_pBehindModal->ModalMouseNotify(HIWORD(lParam), Point.x, Point.y); return TRUE; }
if (!m_bPointing) { ::SetTimer(m_hWnd, POINTING_TIMER_ID, 1000, NULL); m_bPointing = TRUE; }
if (m_pToolTip) { MSG msg = { m_hWnd, HIWORD(lParam), 0, MAKELPARAM(Point.x, Point.y) }; m_pToolTip->RelayEvent(&msg); }
if (!(m_style & UIF_WINDOW_NOMOUSEMSG)) HandleMouseMsg(HIWORD(lParam), Point.x, Point.y);
return TRUE; } case WM_MOUSEACTIVATE: return MA_NOACTIVATE; case WM_ERASEBKGND: return OnEraseBkGnd(hWnd, WM_ERASEBKGND, wParam, lParam); case WM_CREATE: SetRect(NULL); OnCreate(hWnd); return 0; case WM_DESTROY: if (m_pToolTip && ::IsWindow(*m_pToolTip)) ::DestroyWindow(*m_pToolTip); if (m_pShadow && ::IsWindow(*m_pShadow)) ::DestroyWindow(*m_pShadow); OnDestroy(hWnd); return 0; case WM_SIZE: SetRect(NULL); return 0; case WM_ACTIVATE: return OnActivate(hWnd, WM_ACTIVATE, wParam, lParam); case WM_SETFOCUS: OnSetFocus(hWnd); return 0; case WM_KILLFOCUS: OnKillFocus(hWnd); return 0; case WM_PAINT: { PAINTSTRUCT Paint; HDC hDC = ::BeginPaint(hWnd, &Paint); PaintObject(hDC, &Paint.rcPaint); ::EndPaint(hWnd, &Paint); return 0; } case WM_PRINTCLIENT: { PaintObject((HDC)wParam, NULL); return 0; } case WM_THEMECHANGED: { OnThemeChanged(hWnd, wParam, lParam); return 0; } case WM_COMMAND: { return 0; } case WM_TIMER: { switch (wParam) { case USER_TIMER_ID: { if (m_pTimerObject) m_pTimerObject->OnTimer(); break; } case POINTING_TIMER_ID: { POINT pt; ::GetCursorPos(&pt);
POINT pt2 = pt; ::ScreenToClient(m_hWnd, &pt2);
RECT rc; ::GetWindowRect(m_hWnd, &rc);
if (::PtInRect(&rc, pt) && ::WindowFromPoint(pt) == m_hWnd) { m_pBehindModal->ModalMouseNotify(WM_MOUSEMOVE, pt2.x, pt2.y); } else { ::KillTimer(m_hWnd, POINTING_TIMER_ID); m_bPointing = FALSE; SetObjectPointed(NULL, pt2); OnMouseOutFromWindow(pt2.x, pt2.y); }
if (m_pToolTip) { MSG msg = { m_hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(pt2.x, pt2.y) }; m_pToolTip->RelayEvent(&msg); } break; } default: { OnTimer(wParam); break; } } break; } case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP: { if (m_pBehindModal) m_pBehindModal->ModalMouseNotify(uMsg, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); else HandleMouseMsg(uMsg, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); break; } case WM_KEYUP: { OnKeyUp(hWnd, wParam, lParam); break; } case WM_WINDOWPOSCHANGING: { WINDOWPOS *pwp = (WINDOWPOS *)lParam; if (m_pShadow && (pwp->flags & SWP_HIDEWINDOW)) m_pShadow->Show(FALSE); if (!(pwp->flags & SWP_NOZORDER) && pwp->hwndInsertAfter == m_pShadow->m_hWnd) pwp->flags |= SWP_NOZORDER; m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE)); return OnWindowPosChanging(hWnd, WM_WINDOWPOSCHANGING, wParam, lParam); } case WM_WINDOWPOSCHANGED: { WINDOWPOS *pwp = (WINDOWPOS *)lParam; if (m_pShadow) m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE)); return OnWindowPosChanged(hWnd, WM_WINDOWPOSCHANGED, wParam, lParam); } case WM_NOTIFY: OnNotify(hWnd, wParam, lParam); return 0; case WM_NOTIFYFORMAT: return OnNotifyFormat(hWnd, wParam, lParam); case WM_DISPLAYCHANGE: cicUpdateUIFSys(); cicUpdateUIFScheme(); return OnDisplayChange(hWnd, WM_DISPLAYCHANGE, wParam, lParam); case WM_NCDESTROY: OnNCDestroy(hWnd); return 0; case WM_KEYDOWN: OnKeyDown(hWnd, wParam, lParam); return 0; default: { if (uMsg >= WM_USER) { CUIFWindow *pThis = CUIFWindow::GetThis(hWnd); pThis->OnUser(hWnd, uMsg, wParam, lParam); break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } }
return 0;}
LRESULT CALLBACKCUIFWindow::WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ CUIFWindow *This;
if (uMsg == WM_NCCREATE) { This = (CUIFWindow*)((CREATESTRUCT*)lParam)->lpCreateParams; CUIFWindow::SetThis(hWnd, (LONG_PTR)This); This->m_hWnd = hWnd; } else { This = CUIFWindow::GetThis(hWnd); }
if (uMsg == WM_GETMINMAXINFO) { if (This) return This->WindowProc(hWnd, uMsg, wParam, lParam); else return ::DefWindowProc(hWnd, uMsg, wParam, lParam); }
if (!This) return 0;
if (uMsg == WM_NCDESTROY) { This->m_hWnd = NULL; ::SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); }
return This->WindowProc(hWnd, uMsg, wParam, lParam);}
BOOLCUIFWindow::GetWorkArea(LPCRECT prcWnd, LPRECT prcWorkArea){ if (!(m_style & (UIF_WINDOW_WORKAREA | UIF_WINDOW_MONITOR))) return FALSE;
HMONITOR hMon = ::MonitorFromRect(prcWnd, MONITOR_DEFAULTTONEAREST); MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); if (!hMon || !::GetMonitorInfo(hMon, &mi)) { if (m_style & UIF_WINDOW_WORKAREA) return ::SystemParametersInfo(SPI_GETWORKAREA, 0, prcWorkArea, 0);
prcWorkArea->left = prcWorkArea->top = 0; prcWorkArea->right = ::GetSystemMetrics(SM_CXSCREEN); prcWorkArea->bottom = ::GetSystemMetrics(SM_CYSCREEN); return TRUE; }
if (m_style & UIF_WINDOW_WORKAREA) { *prcWorkArea = mi.rcWork; return TRUE; }
*prcWorkArea = mi.rcMonitor; return TRUE;}
voidCUIFWindow::AdjustWindowPosition(){ RECT rc; rc.left = m_nLeft; rc.right = m_nLeft + m_nWidth; rc.top = m_nTop; rc.bottom = m_nTop + m_nHeight;
RECT rcWorkArea; if (!GetWorkArea(&rc, &rcWorkArea)) return;
if (m_nLeft < rcWorkArea.left) m_nLeft = rcWorkArea.left; if (m_nTop < rcWorkArea.top) m_nTop = rcWorkArea.top; if (m_nLeft + m_nWidth >= rcWorkArea.right) m_nLeft = rcWorkArea.right - m_nWidth; if (m_nTop + m_nHeight >= rcWorkArea.bottom) m_nTop = rcWorkArea.bottom - m_nHeight;}
void CUIFWindow::SetBehindModal(CUIFWindow *pBehindModal){ m_pBehindModal = pBehindModal;}
void CUIFWindow::SetTimerObject(CUIFObject *pTimerObject, UINT uElapse){ if (pTimerObject) { m_pTimerObject = pTimerObject; ::SetTimer(m_hWnd, USER_TIMER_ID, uElapse, NULL); } else { m_pTimerObject = NULL; ::KillTimer(m_hWnd, USER_TIMER_ID); }}
STDMETHODIMP_(void)CUIFWindow::PaintObject(HDC hDC, LPCRECT prc){ BOOL bGotDC = FALSE; if (!hDC) { hDC = ::GetDC(m_hWnd); bGotDC = TRUE; }
if (!prc) prc = &m_rc;
HDC hMemDC = ::CreateCompatibleDC(hDC); HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, prc->right - prc->left, prc->bottom - prc->top);
HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem); ::SetViewportOrgEx(hMemDC, -prc->left, -prc->top, NULL); if (FAILED(EnsureThemeData(m_hWnd)) || ((!(m_style & UIF_WINDOW_CHILD) || FAILED(DrawThemeParentBackground(m_hWnd, hMemDC, &m_rc))) && FAILED(DrawThemeBackground(hMemDC, m_iStateId, &m_rc, NULL)))) { if (m_pScheme) m_pScheme->FillRect(hMemDC, prc, 22); }
CUIFObject::PaintObject(hMemDC, prc); ::BitBlt(hDC, prc->left, prc->top, prc->right - prc->left, prc->bottom - prc->top, hMemDC, prc->left, prc->top, SRCCOPY); ::SelectObject(hMemDC, hbmOld); ::DeleteObject(hbmMem); ::DeleteDC(hMemDC);
if (bGotDC) ::ReleaseDC(m_hWnd, hDC);}
STDMETHODIMP_(void)CUIFWindow::Move(INT x, INT y, INT nWidth, INT nHeight){ m_nLeft = x; m_nTop = y; if (nWidth >= 0) m_nWidth = nWidth; if (nHeight >= 0) m_nHeight = nHeight; if (::IsWindow(m_hWnd)) { AdjustWindowPosition(); ::MoveWindow(m_hWnd, m_nLeft, m_nTop, m_nWidth, m_nHeight, TRUE); }}
STDMETHODIMP_(void)CUIFWindow::RemoveUIObj(CUIFObject *pRemove){ if (pRemove == m_pCaptured) SetCaptureObject(NULL);
if (pRemove == m_pTimerObject) { m_pTimerObject = NULL; ::KillTimer(m_hWnd, USER_TIMER_ID); }
if (pRemove == m_pPointed) m_pPointed = NULL;
CUIFObject::RemoveUIObj(pRemove);}
STDMETHODIMP_(void)CUIFWindow::HandleMouseMsg(UINT uMsg, LONG x, LONG y){ POINT pt = { x, y };
CUIFObject *pFound = (CUIFWindow *)ObjectFromPoint(pt);
SetObjectPointed(pFound, pt);
if (m_pCaptured) pFound = m_pCaptured;
if (!pFound || OnSetCursor(uMsg, pt.x, pt.y)) { HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW); ::SetCursor(hCursor); }
if (pFound && pFound->m_bEnable) { switch (uMsg) { case WM_MOUSEMOVE: pFound->OnMouseMove(pt.x, pt.y); break; case WM_LBUTTONDOWN: pFound->OnLButtonDown(pt.x, pt.y); break; case WM_LBUTTONUP: pFound->OnLButtonUp(pt.x, pt.y); break; case WM_RBUTTONDOWN: pFound->OnRButtonDown(pt.x, pt.y); break; case WM_RBUTTONUP: pFound->OnRButtonUp(pt.x, pt.y); break; case WM_MBUTTONDOWN: pFound->OnMButtonDown(pt.x, pt.y); break; case WM_MBUTTONUP: pFound->OnMButtonUp(pt.x, pt.y); break; } }}
/////////////////////////////////////////////////////////////////////////////// CUIFShadow
/// @unimplementedCUIFShadow::CUIFShadow(HINSTANCE hInst, DWORD style, CUIFWindow *pShadowOwner) : CUIFWindow(hInst, (style | UIF_WINDOW_TOOLWINDOW)){ m_pShadowOwner = pShadowOwner; m_rgbShadowColor = RGB(0, 0, 0); m_dwUnknown11[0] = 0; m_dwUnknown11[1] = 0; m_xShadowDelta = m_yShadowDelta = 0; m_bLayerAvailable = FALSE;}
CUIFShadow::~CUIFShadow(){ if (m_pShadowOwner) m_pShadowOwner->m_pShadow = NULL;}
/// @unimplementedvoid CUIFShadow::InitSettings(){ m_bLayerAvailable = FALSE; m_rgbShadowColor = RGB(128, 128, 128); m_xShadowDelta = m_yShadowDelta = 2;}
/// @unimplementedvoid CUIFShadow::InitShadow(){ if (m_bLayerAvailable) { //FIXME }}
void CUIFShadow::AdjustWindowPos(){ HWND hwndOwner = *m_pShadowOwner; if (!::IsWindow(m_hWnd)) return;
RECT rc; ::GetWindowRect(hwndOwner, &rc); ::SetWindowPos(m_hWnd, hwndOwner, rc.left + m_xShadowDelta, rc.top + m_yShadowDelta, rc.right - rc.left, rc.bottom - rc.top, SWP_NOOWNERZORDER | SWP_NOACTIVATE);}
void CUIFShadow::OnOwnerWndMoved(BOOL bDoSize){ if (::IsWindow(m_hWnd) && ::IsWindowVisible(m_hWnd)) { AdjustWindowPos(); if (bDoSize) InitShadow(); }}
STDMETHODIMP_(BOOL)CUIFShadow::Initialize(){ InitSettings(); return CUIFWindow::Initialize();}
STDMETHODIMP_(DWORD)CUIFShadow::GetWndStyleEx(){ DWORD exstyle = CUIFWindow::GetWndStyleEx(); if (m_bLayerAvailable) exstyle |= WS_EX_LAYERED; return exstyle;}
STDMETHODIMP_(void)CUIFShadow::OnPaint(HDC hDC){ RECT rc = m_rc; HBRUSH hBrush = ::CreateSolidBrush(m_rgbShadowColor); ::FillRect(hDC, &rc, hBrush); ::DeleteObject(hBrush);}
STDMETHODIMP_(LRESULT)CUIFShadow::OnWindowPosChanging(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){ WINDOWPOS *wp = (WINDOWPOS *)lParam; wp->hwndInsertAfter = *m_pShadowOwner; return ::DefWindowProc(hWnd, Msg, wParam, lParam);}
STDMETHODIMP_(LRESULT)CUIFShadow::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ InitSettings();
DWORD exstyle; if (m_bLayerAvailable) exstyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED; else exstyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exstyle);
AdjustWindowPos(); InitShadow();
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);}
STDMETHODIMP_(void)CUIFShadow::Show(BOOL bVisible){ if (bVisible && ::IsWindow(m_hWnd) && !::IsWindowVisible(m_hWnd)) { AdjustWindowPos(); InitShadow(); }
if (::IsWindow(m_hWnd)) { m_bVisible = bVisible; ::ShowWindow(m_hWnd, (bVisible ? SW_SHOWNOACTIVATE : SW_HIDE)); }}
/////////////////////////////////////////////////////////////////////////////// CUIFToolTip
CUIFToolTip::CUIFToolTip(HINSTANCE hInst, DWORD style, CUIFWindow *pToolTipOwner) : CUIFWindow(hInst, style){ m_pToolTipOwner = pToolTipOwner; m_rcToolTipMargin.left = 2; m_rcToolTipMargin.top = 2; m_rcToolTipMargin.right = 2; m_rcToolTipMargin.bottom = 2; m_pToolTipTarget = NULL; m_pszToolTipText = NULL; m_dwUnknown10 = 0; //FIXME: name and type m_nDelayTimeType2 = -1; m_nDelayTimeType3 = -1; m_nDelayTimeType1 = -1; m_cxToolTipWidth = -1; m_bToolTipHasBkColor = 0; m_bToolTipHasTextColor = 0; m_rgbToolTipBkColor = 0; m_rgbToolTipTextColor = 0;}
CUIFToolTip::~CUIFToolTip(){ if (m_pToolTipOwner) m_pToolTipOwner->m_pToolTip = NULL; if (m_pszToolTipText) delete[] m_pszToolTipText;}
LONGCUIFToolTip::GetDelayTime(UINT uType){ LONG nDelayTime; switch (uType) { case 1: { nDelayTime = m_nDelayTimeType1; if (nDelayTime == -1) return ::GetDoubleClickTime() / 5; return nDelayTime; } case 2: { nDelayTime = m_nDelayTimeType2; if (nDelayTime == -1) return 10 * ::GetDoubleClickTime(); return nDelayTime; } case 3: { nDelayTime = m_nDelayTimeType3; if (nDelayTime == -1) return ::GetDoubleClickTime(); return nDelayTime; } default: { return 0; } }}
void CUIFToolTip::GetMargin(LPRECT prc){ if (prc) *prc = m_rcToolTipMargin;}
COLORREFCUIFToolTip::GetTipBkColor(){ if (m_bToolTipHasBkColor) return m_rgbToolTipBkColor; return ::GetSysColor(COLOR_INFOBK);}
COLORREFCUIFToolTip::GetTipTextColor(){ if (m_bToolTipHasTextColor) return m_rgbToolTipTextColor; return ::GetSysColor(COLOR_INFOTEXT);}
CUIFObject*CUIFToolTip::FindObject(HWND hWnd, POINT pt){ if (hWnd == *m_pToolTipOwner) return m_pToolTipOwner->ObjectFromPoint(pt); return NULL;}
voidCUIFToolTip::ShowTip(){ ::KillTimer(m_hWnd, TOOLTIP_TIMER_ID);
if (!m_pToolTipTarget) return;
LPCWSTR pszText = m_pToolTipTarget->GetToolTip(); if (!pszText) return;
if (!m_pToolTipTarget || m_pToolTipTarget->OnShowToolTip()) return;
POINT Point; ::GetCursorPos(&Point); ::ScreenToClient(*m_pToolTipTarget->m_pWindow, &Point);
RECT rc; m_pToolTipTarget->GetRect(&rc); if (!::PtInRect(&rc, Point)) return;
size_t cchText = wcslen(pszText); m_pszToolTipText = new(cicNoThrow) WCHAR[cchText + 1]; if (!m_pszToolTipText) return;
lstrcpynW(m_pszToolTipText, pszText, cchText + 1);
SIZE size; GetTipWindowSize(&size);
RECT rc2 = rc; ::ClientToScreen(*m_pToolTipTarget->m_pWindow, (LPPOINT)&rc); ::ClientToScreen(*m_pToolTipTarget->m_pWindow, (LPPOINT)&rc.right); GetTipWindowRect(&rc2, size, &rc);
m_bShowToolTip = TRUE; Move(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); Show(TRUE);}
voidCUIFToolTip::HideTip(){ ::KillTimer(m_hWnd, TOOLTIP_TIMER_ID); m_bShowToolTip = FALSE;
if (m_pToolTipTarget) m_pToolTipTarget->OnHideToolTip();
if (m_bVisible) { if (m_pszToolTipText) { delete[] m_pszToolTipText; m_pszToolTipText = NULL; } Show(FALSE); }}
voidCUIFToolTip::GetTipWindowSize(LPSIZE pSize){ if (!m_pszToolTipText) return;
HDC hDC = ::GetDC(m_hWnd); HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
RECT rcText = { 0, 0, 0, 0 }; INT cyText; if (m_cxToolTipWidth <= 0) { cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | DT_SINGLELINE); } else { rcText.right = m_cxToolTipWidth; cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | DT_WORDBREAK); }
RECT rcMargin; GetMargin(&rcMargin);
RECT rc; rc.left = rcText.left - rcMargin.left; rc.top = rcText.top - rcMargin.top; rc.right = rcText.right + rcMargin.right; rc.bottom = rcText.top + cyText + rcMargin.bottom; ClientRectToWindowRect(&rc);
pSize->cx = rc.right - rc.left; pSize->cy = rc.bottom - rc.top;
::SelectObject(hDC, hFontOld); ::ReleaseDC(m_hWnd, hDC);}
voidCUIFToolTip::GetTipWindowRect(LPRECT pRect, SIZE toolTipSize, LPCRECT prc){ POINT Point; GetCursorPos(&Point);
HCURSOR hCursor = ::GetCursor(); ICONINFO IconInfo; INT yHotspot = 0; INT cyCursor = ::GetSystemMetrics(SM_CYCURSOR); if (hCursor && ::GetIconInfo(hCursor, &IconInfo)) { BITMAP bm; ::GetObject(IconInfo.hbmMask, sizeof(bm), &bm); if (!IconInfo.fIcon) { cyCursor = bm.bmHeight; yHotspot = IconInfo.yHotspot; if (!IconInfo.hbmColor) cyCursor = bm.bmHeight / 2; } if (IconInfo.hbmColor) ::DeleteObject(IconInfo.hbmColor); if (IconInfo.hbmMask) ::DeleteObject(IconInfo.hbmMask); }
RECT rcMonitor; rcMonitor.left = 0; rcMonitor.top = 0; rcMonitor.right = GetSystemMetrics(SM_CXSCREEN); rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
HMONITOR hMon = ::MonitorFromPoint(Point, MONITOR_DEFAULTTONEAREST); MONITORINFO mi; if (hMon) { mi.cbSize = sizeof(MONITORINFO); if (::GetMonitorInfo(hMon, &mi)) rcMonitor = mi.rcMonitor; }
pRect->left = Point.x; pRect->right = pRect->left + toolTipSize.cx; pRect->top = Point.y + cyCursor - yHotspot; pRect->bottom = pRect->top + toolTipSize.cy;
if (rcMonitor.right < pRect->right) { pRect->left = rcMonitor.right - toolTipSize.cx; pRect->right = rcMonitor.right; } if (pRect->left < rcMonitor.left) { pRect->left = rcMonitor.left; pRect->right = rcMonitor.left + toolTipSize.cx; } if (rcMonitor.bottom < pRect->bottom) { pRect->top = rcMonitor.bottom - toolTipSize.cy; pRect->bottom = rcMonitor.bottom; } if (pRect->top < rcMonitor.top) { pRect->top = rcMonitor.top; pRect->bottom = rcMonitor.top + toolTipSize.cy; }}
voidCUIFToolTip::RelayEvent(LPMSG pMsg){ if (!pMsg) return;
switch (pMsg->message) { case WM_MOUSEMOVE: { if (m_bEnable && ::GetKeyState(VK_LBUTTON) >= 0 && ::GetKeyState(VK_MBUTTON) >= 0 && ::GetKeyState(VK_RBUTTON) >= 0) { POINT pt = { (SHORT)LOWORD(pMsg->lParam), (SHORT)HIWORD(pMsg->lParam) }; CUIFObject *pFound = CUIFToolTip::FindObject(pMsg->hwnd, pt); if (pFound) { if (m_pToolTipTarget != pFound) { HideTip();
LONG DelayTime; if (!m_bVisible) DelayTime = GetDelayTime(3); else DelayTime = GetDelayTime(1); ::SetTimer(m_hWnd, TOOLTIP_TIMER_ID, DelayTime, NULL); } } else { HideTip(); } m_pToolTipTarget = pFound; } break; } case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: { HideTip(); break; } }}
STDMETHODIMP_(void) CUIFToolTip::OnPaint(HDC hDC){ HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); INT iBkModeOld = ::SetBkMode(hDC, TRANSPARENT);
COLORREF rgbTextColor = GetTipTextColor(); COLORREF rgbOldTextColor = ::SetTextColor(hDC, rgbTextColor);
COLORREF rgbBkColor = GetTipBkColor(); HBRUSH hbrBack = ::CreateSolidBrush(rgbBkColor); RECT rc = m_rc; if (hbrBack) { ::FillRect(hDC, &rc, hbrBack); ::DeleteObject(hbrBack); }
RECT rcMargin; GetMargin(&rcMargin);
rc.left += rcMargin.left; rc.top += rcMargin.top; rc.right -= rcMargin.right; rc.bottom -= rcMargin.bottom;
if (m_cxToolTipWidth <= 0) ::DrawTextW(hDC, m_pszToolTipText, -1, &rc, DT_SINGLELINE); else ::DrawTextW(hDC, m_pszToolTipText, -1, &rc, DT_WORDBREAK);
::SetTextColor(hDC, rgbOldTextColor); ::SetBkMode(hDC, iBkModeOld); ::SelectObject(hDC, hFontOld);}
STDMETHODIMP_(void) CUIFToolTip::Enable(BOOL bEnable){ if (!bEnable) HideTip(); CUIFObject::Enable(bEnable);}
STDMETHODIMP_(void) CUIFToolTip::OnTimer(WPARAM wParam){ if (wParam == TOOLTIP_TIMER_ID) ShowTip();}
/////////////////////////////////////////////////////////////////////////////// CUIFButton
CUIFButton::CUIFButton( CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style) : CUIFObject(pParent, nObjectID, prc, style){ m_ButtonIcon.m_hIcon = NULL; m_ButtonIcon.m_hImageList = NULL; m_dwUnknown9 = 0; m_uButtonStatus = 0; m_bPressed = FALSE; m_hbmButton1 = NULL; m_hbmButton2 = NULL; m_pszButtonText = NULL;}
CUIFButton::~CUIFButton(){ if (m_pszButtonText) { delete[] m_pszButtonText; m_pszButtonText = NULL; }
if (m_ButtonIcon.m_hImageList) ImageList_Destroy(m_ButtonIcon.m_hImageList);}
voidCUIFButton::DrawBitmapProc(HDC hDC, LPCRECT prc, BOOL bPressed){ INT width = m_rc.right - m_rc.left; INT height = m_rc.bottom - m_rc.top; if (m_hbmButton2) { HBITMAP hbmMask = cicCreateMaskBmp(&m_rc, m_hbmButton1, m_hbmButton2, (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1), 0, 0); ::DrawState(hDC, NULL, NULL, (LPARAM)hbmMask, 0, prc->left + bPressed, prc->top + bPressed, width - bPressed, height - bPressed, DST_BITMAP | (m_bEnable ? 0 : (DSS_MONO | DSS_DISABLED))); ::DeleteObject(hbmMask); } else { ::DrawState(hDC, NULL, NULL, (LPARAM)m_hbmButton1, 0, prc->left + bPressed, prc->top + bPressed, width - bPressed, height - bPressed, DST_BITMAP | (m_bEnable ? 0 : (DSS_MONO | DSS_DISABLED))); }}
voidCUIFButton::DrawEdgeProc(HDC hDC, LPCRECT prc, BOOL bPressed){ RECT rc = *prc; if (bPressed) ::DrawEdge(hDC, &rc, BDR_SUNKENOUTER, BF_RECT); else ::DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT);}
void CUIFButton::DrawIconProc(HDC hDC, LPRECT prc, BOOL bPressed){ INT width = prc->right - prc->left; INT height = prc->bottom - prc->top; RECT rc = { 0, 0, width, height };
HDC hMemDC = ::CreateCompatibleDC(hDC); if (!hMemDC) return;
HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, width, height); if (!hbmMem) { ::DeleteDC(hMemDC); return; }
HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem); if (m_bEnable) { ::BitBlt(hMemDC, rc.left, rc.top, width, height, hDC, prc->left, prc->top, SRCCOPY); } else { HBRUSH hbrWhite = (HBRUSH)::GetStockObject(WHITE_BRUSH); ::FillRect(hMemDC, &rc, hbrWhite); }
if (m_style & UIF_BUTTON_LARGE_ICON) { ::DrawIconEx(hMemDC, 2 + bPressed, 2 + bPressed, m_ButtonIcon.m_hIcon, width - 4, height - 4, 0, NULL, DI_NORMAL); } else { ::DrawIconEx(hMemDC, (width - 16) / 2 + bPressed, (height - 16) / 2 + bPressed, m_ButtonIcon.m_hIcon, 16, 16, 0, NULL, DI_NORMAL); }
::SelectObject(hMemDC, hbmOld); ::DrawState(hDC, NULL, NULL, (LPARAM)hbmMem, 0, prc->left, prc->top, width, height, DST_BITMAP | (m_bEnable ? 0 : (DSS_MONO | DSS_DISABLED))); ::DeleteObject(hbmMem); ::DeleteDC(hMemDC);}
voidCUIFButton::DrawTextProc(HDC hDC, LPCRECT prc, BOOL bPressed){ if (!m_pszButtonText) return;
HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); INT cchText = lstrlenW(m_pszButtonText); SIZE textSize; ::GetTextExtentPoint32W(hDC, m_pszButtonText, cchText, &textSize);
INT xText, yText; if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_CENTER) xText = (m_rc.right - m_rc.left - textSize.cx) / 2; else if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_RIGHT) xText = m_rc.right - m_rc.left - textSize.cx; else xText = 0;
if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_MIDDLE) yText = (m_rc.bottom - m_rc.top - textSize.cy) / 2; else if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_BOTTOM) yText = m_rc.bottom - m_rc.top - textSize.cy; else yText = 0;
::SetBkMode(hDC, TRANSPARENT);
if (m_bEnable) { ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT)); ::ExtTextOutW(hDC, xText + prc->left + bPressed, yText + prc->top + bPressed, ETO_CLIPPED, prc, m_pszButtonText, cchText, NULL); } else { ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT)); ::ExtTextOutW(hDC, xText + prc->left + bPressed + 1, yText + prc->top + bPressed + 1, ETO_CLIPPED, prc, m_pszButtonText, cchText, NULL);
::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); ::ExtTextOutW(hDC, xText + prc->left + bPressed, yText + prc->top + bPressed, ETO_CLIPPED, prc, m_pszButtonText, cchText, NULL); }
::SelectObject(hDC, hFontOld);}
STDMETHODIMP_(void)CUIFButton::Enable(BOOL bEnable){ CUIFObject::Enable(bEnable); if (!m_bEnable) { SetStatus(0); if (IsCapture()) CUIFObject::EndCapture(); }}
voidCUIFButton::GetIconSize(HICON hIcon, LPSIZE pSize){ ICONINFO IconInfo; if (::GetIconInfo(hIcon, &IconInfo)) { BITMAP bm; ::GetObject(IconInfo.hbmColor, sizeof(bm), &bm); ::DeleteObject(IconInfo.hbmColor); ::DeleteObject(IconInfo.hbmMask); pSize->cx = bm.bmWidth; pSize->cy = bm.bmHeight; } else { pSize->cx = ::GetSystemMetrics(SM_CXSMICON); pSize->cy = ::GetSystemMetrics(SM_CYSMICON); }}
voidCUIFButton::GetTextSize(LPCWSTR pszText, LPSIZE pSize){ HDC hDC = ::GetDC(NULL); INT cchText = lstrlenW(pszText); HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
if (!m_bHasCustomFont && SUCCEEDED(EnsureThemeData(*m_pWindow))) { RECT rc; GetThemeTextExtent(hDC, 0, pszText, cchText, 0, NULL, &rc); pSize->cx = rc.right; pSize->cy = rc.bottom; } else { ::GetTextExtentPoint32W(hDC, pszText, cchText, pSize); }
if (m_style & UIF_BUTTON_VERTICAL) { INT tmp = pSize->cx; pSize->cx = pSize->cy; pSize->cy = tmp; }
::SelectObject(hDC, hFontOld); ::ReleaseDC(NULL, hDC);}
STDMETHODIMP_(void)CUIFButton::OnLButtonDown(LONG x, LONG y){ SetStatus(1); StartCapture(); if ((m_style & 0x30) == 0x20) NotifyCommand(1, 0);}
/// @unimplementedSTDMETHODIMP_(void)CUIFButton::OnLButtonUp(LONG x, LONG y){ POINT pt = { x, y }; BOOL bCapture = IsCapture(); if (bCapture) EndCapture();
BOOL bNotInObject = (m_style & 0x30) == 0x20; if ((m_style & 0x30) != 0x10) { bNotInObject = !PtInObject(pt); if (bNotInObject) { SetStatus(0); return; } } else { if (!bNotInObject) { bNotInObject = !PtInObject(pt); if (!bNotInObject) { SetStatus(2); NotifyCommand(1, 0); return; } } SetStatus(0); return; }
SetStatus(2);
if (bCapture) { m_bPressed = !m_bPressed; NotifyCommand(1, 0); }}
void CUIFButton::OnMouseIn(LONG x, LONG y){ if ((m_style & 0x30) == 0x20) { if (IsCapture()) SetStatus(0); else SetStatus(2); } else { if (IsCapture()) SetStatus(1); else SetStatus(2); }}
void CUIFButton::OnMouseOut(LONG x, LONG y){ if ((m_style & 0x30) == 0x20) SetStatus(0); else if (IsCapture()) SetStatus(3); else SetStatus(0);}
STDMETHODIMP_(void)CUIFButton::OnPaintNoTheme(HDC hDC){ ::FillRect(hDC, &m_rc, (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1));
if (m_bPressed && ((m_uButtonStatus == 0) || (m_uButtonStatus == 3))) { HBRUSH hbr = cicCreateDitherBrush(); if (hbr) { COLORREF OldTextColor = ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNFACE)); COLORREF OldBkColor = ::SetBkColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT)); RECT rc = m_rc; ::InflateRect(&rc, -2, -2); ::FillRect(hDC, &rc, hbr); ::SetTextColor(hDC, OldTextColor); ::SetBkColor(hDC, OldBkColor); ::DeleteObject(hbr); } }
BOOL bPressed = (m_bPressed || (m_uButtonStatus == 1)); if (m_hbmButton1) DrawBitmapProc(hDC, &m_rc, bPressed); else if (m_ButtonIcon.m_hIcon) DrawIconProc(hDC, &m_rc, bPressed); else DrawTextProc(hDC, &m_rc, bPressed);
if (m_bPressed || (m_uButtonStatus == 1)) DrawEdgeProc(hDC, &m_rc, TRUE); else if (2 <= m_uButtonStatus && m_uButtonStatus <= 3) DrawEdgeProc(hDC, &m_rc, FALSE);}
void CUIFButton::SetIcon(HICON hIcon){ m_ButtonIcon = hIcon;
if (m_ButtonIcon.m_hIcon) GetIconSize(m_ButtonIcon.m_hIcon, &m_IconSize); else m_IconSize.cx = m_IconSize.cy = 0;
CallOnPaint();}
void CUIFButton::SetStatus(UINT uStatus){ if (uStatus != m_uButtonStatus) { m_uButtonStatus = uStatus; CallOnPaint(); }}
void CUIFButton::SetText(LPCWSTR pszText){ if (m_pszButtonText) { delete[] m_pszButtonText; m_pszButtonText = NULL; }
m_TextSize.cx = m_TextSize.cy = 0;
if (pszText) { INT cch = lstrlenW(pszText); m_pszButtonText = new(cicNoThrow) WCHAR[cch + 1]; if (!m_pszButtonText) return;
lstrcpynW(m_pszButtonText, pszText, cch + 1); GetTextSize(m_pszButtonText, &m_TextSize); }
CallOnPaint();}
/////////////////////////////////////////////////////////////////////////////// CUIFButton2
CUIFButton2::CUIFButton2( CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style) : CUIFButton(pParent, nObjectID, prc, style){ m_iStateId = 0; m_iPartId = BP_PUSHBUTTON; m_pszClassList = L"TOOLBAR";}
CUIFButton2::~CUIFButton2(){ CloseThemeData();}
DWORD CUIFButton2::MakeDrawFlag(){ DWORD dwDrawFlags = 0; if (m_bPressed) dwDrawFlags |= UIF_DRAW_PRESSED; if (m_uButtonStatus == 1) dwDrawFlags |= 0x2; else if (2 <= m_uButtonStatus && m_uButtonStatus <= 3) dwDrawFlags |= 0x1; if (!m_bEnable) dwDrawFlags |= UIF_DRAW_DISABLED; return dwDrawFlags;}
/// @unimplementedSTDMETHODIMP_(BOOL)CUIFButton2::OnPaintTheme(HDC hDC){ //FIXME return FALSE;}
STDMETHODIMP_(void)CUIFButton2::OnPaintNoTheme(HDC hDC){ if (!m_pScheme) return;
INT width = m_rc.right - m_rc.left; INT height = m_rc.bottom - m_rc.top; HDC hdcMem = ::CreateCompatibleDC(hDC); if (!hdcMem) return;
HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, width, height); if ( !hbmMem ) { ::DeleteDC(hdcMem); return; }
HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbmMem); HGDIOBJ hFontOld = ::SelectObject(hdcMem, m_hFont); RECT rcBack = { 0, 0, width, height };
INT cxText = 0, cyText = 0, cxContent = 0, cyContent = 0; INT cxyBorders, cxButton, cyButton; if (m_pszButtonText) { cxText = m_TextSize.cx; cyText = m_TextSize.cy; }
if (m_ButtonIcon.m_hIcon) { cxContent = m_IconSize.cx; cyContent = m_IconSize.cy; } else if (m_hbmButton1) { cxContent = m_BitmapSize.cx; cyContent = m_BitmapSize.cy; }
if (m_style & UIF_BUTTON_VERTICAL) { cxyBorders = ((cyText && cyContent) ? 2 : 0);
cxButton = cxContent; cyButton = cyText + cyContent + cxyBorders; if (cxText > cxContent) cxButton = cxText; } else { cxyBorders = ((cxText && cxContent) ? 2 : 0);
cxButton = cxText + cxContent + cxyBorders; cyButton = cyContent; if (cyText > cyButton) cyButton = cyText; }
INT xOffset, yOffset; if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_CENTER) xOffset = (rcBack.left + rcBack.right - cxButton) / 2; else if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_RIGHT) xOffset = rcBack.right - cxText - 2; else xOffset = rcBack.left + 2;
if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_MIDDLE) yOffset = (rcBack.top + rcBack.bottom - cyButton) / 2; else if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_BOTTOM) yOffset = rcBack.bottom - cyButton - 2; else yOffset = rcBack.top + 2;
RECT rc = { xOffset, yOffset, xOffset + cxButton, cyButton + yOffset }; SIZE offsetSize = { 0, 0 }; DWORD dwDrawFlags = MakeDrawFlag(); m_pScheme->GetCtrlFaceOffset(((m_style & 0x200) ? 0xA5 : 0x54), dwDrawFlags, &offsetSize); ::OffsetRect(&rc, offsetSize.cx, offsetSize.cy);
RECT rcImage, rcText; if (m_style & UIF_BUTTON_VERTICAL) { rcImage.left = (rc.left + rc.right - cxContent) / 2; rcImage.top = rc.top; rcImage.right = rcImage.left + cxContent; rcImage.bottom = rc.top + cyContent; rcText.left = (rc.left + rc.right - cxText) / 2; rcText.top = rc.bottom - cyText; rcText.right = rcText.left + cxText; rcText.bottom = rc.bottom; } else { rcImage.left = rc.left; rcImage.top = (rc.top + rc.bottom - cyContent) / 2; rcImage.bottom = rcImage.top + cyContent; rcImage.right = rc.left + cxContent; rcText.left = rc.right - cxText; rcText.top = (rc.top + rc.bottom - cyText) / 2; rcText.right = rc.right; rcText.bottom = rcText.top + cyText; }
if (IsRTL()) m_pScheme->m_bMirroring = TRUE;
m_pScheme->DrawCtrlBkgd(hdcMem, &rcBack, ((m_style & 0x200) ? 0xA5 : 0x54), dwDrawFlags); if (m_pszButtonText) { m_pScheme->DrawCtrlText(hdcMem, &rcText, m_pszButtonText, -1, dwDrawFlags, !!(m_style & UIF_BUTTON_VERTICAL)); }
if (m_ButtonIcon.m_hIcon) m_pScheme->DrawCtrlIcon(hdcMem, &rcImage, m_ButtonIcon.m_hIcon, dwDrawFlags, &m_IconSize); else if (m_hbmButton1) m_pScheme->DrawCtrlBitmap(hdcMem, &rcImage, m_hbmButton1, m_hbmButton2, dwDrawFlags);
if (IsRTL()) m_pScheme->m_bMirroring = FALSE;
m_pScheme->DrawCtrlEdge(hdcMem, &rcBack, ((m_style & 0x200) ? 0xA5 : 0x54), dwDrawFlags);
::BitBlt(hDC, m_rc.left, m_rc.top, width, height, hdcMem, 0, 0, SRCCOPY); ::SelectObject(hdcMem, hFontOld); ::SelectObject(hdcMem, hbmOld); ::DeleteObject(hbmMem);}
/////////////////////////////////////////////////////////////////////////////// CUIFGripper
CUIFGripper::CUIFGripper(CUIFObject *pParent, LPCRECT prc, DWORD style) : CUIFObject(pParent, 0, prc, style){ m_iStateId = 0; m_pszClassList = L"REBAR"; if (m_style & UIF_GRIPPER_VERTICAL) m_iPartId = RP_GRIPPERVERT; else m_iPartId = RP_GRIPPER;}
CUIFGripper::~CUIFGripper(){}
STDMETHODIMP_(void)CUIFGripper::OnMouseMove(LONG x, LONG y){ if (IsCapture()) { POINT pt; ::GetCursorPos(&pt); m_pWindow->Move(pt.x - m_ptGripper.x, pt.y - m_ptGripper.y, -1, -1); }}
STDMETHODIMP_(void)CUIFGripper::OnLButtonDown(LONG x, LONG y){ StartCapture(); m_ptGripper.x = x; m_ptGripper.y = y; ::ScreenToClient(*m_pWindow, &m_ptGripper); RECT rc; ::GetWindowRect(*m_pWindow, &rc); m_ptGripper.x -= rc.left; m_ptGripper.y -= rc.top;}
STDMETHODIMP_(void)CUIFGripper::OnLButtonUp(LONG x, LONG y){ if (IsCapture()) EndCapture();}
STDMETHODIMP_(BOOL)CUIFGripper::OnPaintTheme(HDC hDC){ if (FAILED(EnsureThemeData(*m_pWindow))) return FALSE;
if (m_style & UIF_GRIPPER_VERTICAL) { m_rc.top += 2; m_rc.bottom -= 2; } else { m_rc.left += 2; m_rc.right -= 2; }
if (FAILED(DrawThemeBackground(hDC, 1, &m_rc, 0))) return FALSE;
return TRUE;}
STDMETHODIMP_(void)CUIFGripper::OnPaintNoTheme(HDC hDC){ if (m_pScheme) { m_pScheme->DrawDragHandle(hDC, &m_rc, !!(m_style & UIF_GRIPPER_VERTICAL)); return; }
RECT rc; if (m_style & UIF_GRIPPER_VERTICAL) rc = { m_rc.left, m_rc.top + 1, m_rc.right, m_rc.top + 4 }; else rc = { m_rc.left + 1, m_rc.top, m_rc.left + 4, m_rc.bottom };
::DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT);}
STDMETHODIMP_(BOOL)CUIFGripper::OnSetCursor(UINT uMsg, LONG x, LONG y){ HCURSOR hCursor = ::LoadCursor(NULL, IDC_SIZEALL); ::SetCursor(hCursor); return TRUE;}
STDMETHODIMP_(void)CUIFGripper::SetStyle(DWORD style){ m_style = style; if (m_style & UIF_GRIPPER_VERTICAL) SetActiveTheme(L"REBAR", RP_GRIPPERVERT, 0); else SetActiveTheme(L"REBAR", RP_GRIPPER, 0);}
/////////////////////////////////////////////////////////////////////////////// CUIFToolbarMenuButton
CUIFToolbarMenuButton::CUIFToolbarMenuButton( CUIFToolbarButton *pParent, DWORD nObjectID, LPCRECT prc, DWORD style) : CUIFButton2(pParent, nObjectID, prc, style){ m_pToolbarButton = pParent;
HFONT hFont = ::CreateFontW(8, 8, 0, 0, FW_NORMAL, 0, 0, 0, SYMBOL_CHARSET, 0, 0, 0, 0, L"Marlett"); SetFont(hFont); SetText(L"u"); // downward triangle}
CUIFToolbarMenuButton::~CUIFToolbarMenuButton(){ ::DeleteObject(m_hFont); SetFont(NULL);}
STDMETHODIMP_(void)CUIFToolbarMenuButton::OnLButtonUp(LONG x, LONG y){ CUIFButton::OnLButtonUp(x, y); m_pToolbarButton->OnUnknownMouse0();}
STDMETHODIMP_(BOOL)CUIFToolbarMenuButton::OnSetCursor(UINT uMsg, LONG x, LONG y){ m_pToolbarButton->OnSetCursor(uMsg, x, y); return FALSE;}
/////////////////////////////////////////////////////////////////////////////// CUIFToolbarButtonElement
CUIFToolbarButtonElement::CUIFToolbarButtonElement( CUIFToolbarButton *pParent, DWORD nObjectID, LPCRECT prc, DWORD style) : CUIFButton2(pParent, nObjectID, prc, style){ m_pToolbarButton = pParent;}
STDMETHODIMP_(LPCWSTR)CUIFToolbarButtonElement::GetToolTip(){ if (m_pToolbarButton) return m_pToolbarButton->GetToolTip(); return NULL;}
STDMETHODIMP_(void)CUIFToolbarButtonElement::OnLButtonUp(LONG x, LONG y){ CUIFButton::OnLButtonUp(x, y); if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) == 0x20000) m_pToolbarButton->OnUnknownMouse0(); else m_pToolbarButton->OnLeftClick();}
STDMETHODIMP_(void)CUIFToolbarButtonElement::OnRButtonUp(LONG x, LONG y){ if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) != 0x20000) m_pToolbarButton->OnRightClick();}
/////////////////////////////////////////////////////////////////////////////// CUIFToolbarButton
CUIFToolbarButton::CUIFToolbarButton( CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style, DWORD dwToolbarButtonFlags, LPCWSTR pszUnknownText) : CUIFObject(pParent, nObjectID, prc, style){ m_dwToolbarButtonFlags = dwToolbarButtonFlags; m_pszUnknownText = pszUnknownText;}
BOOL CUIFToolbarButton::Init(){ RECT rc1, rc2; rc1 = rc2 = m_rc;
if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000) { rc1.right -= 12; rc2.left = rc1.right + 1; }
DWORD style = UIF_BUTTON_LARGE_ICON | UIF_BUTTON_V_ALIGN_MIDDLE | UIF_BUTTON_H_ALIGN_CENTER; if (m_dwToolbarButtonFlags & 0x2000) style |= 0x10; if (m_dwToolbarButtonFlags & 0x80000) style |= UIF_BUTTON_VERTICAL; m_pToolbarButtonElement = new(cicNoThrow) CUIFToolbarButtonElement(this, m_nObjectID, &rc1, style); if (!m_pToolbarButtonElement) return FALSE;
m_pToolbarButtonElement->Initialize(); AddUIObj(m_pToolbarButtonElement);
if (!m_bEnable) m_pToolbarButtonElement->Enable(FALSE);
if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000) { style = UIF_BUTTON_LARGE_ICON | UIF_BUTTON_H_ALIGN_CENTER; if (m_dwToolbarButtonFlags & 0x80000) style |= UIF_BUTTON_VERTICAL;
m_pToolbarMenuButton = new(cicNoThrow) CUIFToolbarMenuButton(this, 0, &rc2, style); if (!m_pToolbarMenuButton) return FALSE;
m_pToolbarMenuButton->Initialize(); AddUIObj(m_pToolbarMenuButton);
if (!m_bEnable) m_pToolbarMenuButton->Enable(FALSE); }
return TRUE;}
HICON CUIFToolbarButton::GetIcon(){ return m_pToolbarButtonElement->m_ButtonIcon.m_hIcon;}
void CUIFToolbarButton::SetIcon(HICON hIcon){ m_pToolbarButtonElement->SetIcon(hIcon);}
STDMETHODIMP_(void)CUIFToolbarButton::ClearWndObj(){ if (m_pToolbarButtonElement) m_pToolbarButtonElement->ClearWndObj(); if (m_pToolbarMenuButton) m_pToolbarMenuButton->ClearWndObj();
CUIFObject::ClearWndObj();}
STDMETHODIMP_(void)CUIFToolbarButton::DetachWndObj(){ if (m_pToolbarButtonElement) m_pToolbarButtonElement->DetachWndObj(); if (m_pToolbarMenuButton) m_pToolbarMenuButton->DetachWndObj();
CUIFObject::DetachWndObj();}
STDMETHODIMP_(void)CUIFToolbarButton::Enable(BOOL bEnable){ CUIFObject::Enable(bEnable); if (m_pToolbarButtonElement) m_pToolbarButtonElement->Enable(bEnable); if (m_pToolbarMenuButton) m_pToolbarMenuButton->Enable(bEnable);}
STDMETHODIMP_(LPCWSTR)CUIFToolbarButton::GetToolTip(){ return CUIFObject::GetToolTip();}
STDMETHODIMP_(void)CUIFToolbarButton::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT iStateId){ if (m_pToolbarButtonElement) m_pToolbarButtonElement->SetActiveTheme(pszClassList, iPartId, iStateId); if (m_pToolbarMenuButton) m_pToolbarMenuButton->SetActiveTheme(pszClassList, iPartId, iStateId);
m_pszClassList = pszClassList; m_iPartId = iPartId; m_iStateId = iStateId;}
STDMETHODIMP_(void)CUIFToolbarButton::SetFont(HFONT hFont){ m_pToolbarButtonElement->SetFont(hFont);}
STDMETHODIMP_(void)CUIFToolbarButton::SetRect(LPCRECT prc){ CUIFObject::SetRect(prc);
RECT rc1, rc2; rc1 = rc2 = m_rc;
if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000) { rc1.right -= 12; rc2.left = rc1.right + 1; }
if (m_pToolbarButtonElement) m_pToolbarButtonElement->SetRect(&rc1); if (m_pToolbarMenuButton) m_pToolbarMenuButton->SetRect(&rc2);}
STDMETHODIMP_(void)CUIFToolbarButton::SetToolTip(LPCWSTR pszToolTip){ CUIFObject::SetToolTip(pszToolTip); if (m_pToolbarButtonElement) m_pToolbarButtonElement->SetToolTip(pszToolTip); if (m_pToolbarMenuButton) m_pToolbarMenuButton->SetToolTip(pszToolTip);}
/////////////////////////////////////////////////////////////////////////////// CUIFWndFrame
CUIFWndFrame::CUIFWndFrame( CUIFObject *pParent, LPCRECT prc, DWORD style) : CUIFObject(pParent, 0, prc, style){ m_iPartId = 7; m_iStateId = 0; m_pszClassList = L"WINDOW"; m_dwHitTest = 0; m_cxFrame = m_cyFrame = 0;
if (m_pScheme) { if ((m_style & 0xF) && (m_style & 0xF) <= 2) { m_cxFrame = m_pScheme->CxSizeFrame(); m_cyFrame = m_pScheme->CySizeFrame(); } else { m_cxFrame = m_pScheme->CxWndBorder(); m_cyFrame = m_pScheme->CyWndBorder(); } }
m_cxMin = GetSystemMetrics(SM_CXMIN); m_cyMin = GetSystemMetrics(SM_CYMIN);}
void CUIFWndFrame::GetFrameSize(LPSIZE pSize){ pSize->cx = m_cxFrame; pSize->cy = m_cyFrame;}
DWORD CUIFWndFrame::HitTest(LONG x, LONG y){ DWORD dwFlags = 0; if ( m_rc.left <= x && x < m_rc.left + m_cxFrame) dwFlags |= 0x10; if (m_rc.top <= y && y < m_rc.top + m_cyFrame ) dwFlags |= 0x20; if (m_rc.right - m_cxFrame <= x && x < m_rc.right) dwFlags |= 0x40; if (m_rc.bottom - m_cyFrame <= y && y < m_rc.bottom) dwFlags |= 0x80; return dwFlags;}
STDMETHODIMP_(void)CUIFWndFrame::OnMouseMove(LONG x, LONG y){ if (!IsCapture()) return;
POINT Point; ::ClientToScreen(*m_pWindow, &Point);
RECT rc = m_rcWnd;
if (m_dwHitTest & 0x10) rc.left = Point.x + m_rcWnd.left - m_ptHit.x;
if (m_dwHitTest & 0x20) rc.top = Point.y + m_rcWnd.top - m_ptHit.y;
if (m_dwHitTest & 0x40) { rc.right = Point.x + m_rcWnd.right - m_ptHit.x; if (rc.right <= rc.left + m_cxMin) rc.right = rc.left + m_cxMin; }
if (m_dwHitTest & 0x80) { rc.bottom = Point.y + m_rcWnd.bottom - m_ptHit.y; if (rc.bottom <= rc.top + m_cyMin) rc.bottom = rc.top + m_cyMin; }
m_pWindow->Move(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);}
STDMETHODIMP_(void)CUIFWndFrame::OnLButtonDown(LONG x, LONG y){ POINT Point = { x, y }; DWORD hitTest = m_style & HitTest(x, y); if (!hitTest) return;
::ClientToScreen(*m_pWindow, &Point); m_ptHit = Point; m_pWindow = m_pWindow; m_dwHitTest = hitTest; ::GetWindowRect(*m_pWindow, &m_rcWnd); StartCapture();}
STDMETHODIMP_(void)CUIFWndFrame::OnLButtonUp(LONG x, LONG y){ if (IsCapture()) EndCapture();}
STDMETHODIMP_(BOOL)CUIFWndFrame::OnPaintTheme(HDC hDC){ if (FAILED(EnsureThemeData(*m_pWindow))) return FALSE;
RECT rc = m_rc; rc.right = m_cxFrame; if (FAILED(DrawThemeEdge(hDC, 0, &rc, 5, 1, NULL))) return FALSE;
rc = m_rc; rc.left = rc.right - m_cxFrame; if (FAILED(DrawThemeEdge(hDC, 0, &rc, 10, 4, NULL))) return FALSE;
rc = m_rc; rc.bottom = m_cyFrame; if (FAILED(DrawThemeEdge(hDC, 0, &rc, 5, 2, NULL))) return FALSE;
rc = m_rc; rc.top = rc.bottom - m_cyFrame; if (FAILED(DrawThemeEdge(hDC, 0, &rc, 10, 8, NULL))) return FALSE;
return TRUE;}
STDMETHODIMP_(void)CUIFWndFrame::OnPaintNoTheme(HDC hDC){ if (!m_pScheme) return;
DWORD type = 0; if ((m_style & 0xF) == 1) type = 1; else if ( (m_style & 0xF) == 2 ) type = 2;
m_pScheme->DrawWndFrame(hDC, &m_rc, type, m_cxFrame, m_cyFrame);}
STDMETHODIMP_(BOOL)CUIFWndFrame::OnSetCursor(UINT uMsg, LONG x, LONG y){ DWORD dwHitTest = m_dwHitTest; if (!IsCapture()) dwHitTest = m_style & HitTest(x, y);
LPTSTR pszCursor = NULL; switch (dwHitTest) { case 0x30: case 0xC0: pszCursor = IDC_SIZENWSE; break; case 0x90: case 0x60: pszCursor = IDC_SIZENESW; break; case 0x10: case 0x40: pszCursor = IDC_SIZEWE; break; case 0x20: case 0x80: pszCursor = IDC_SIZENS; break; default: return FALSE; }
HCURSOR hCursor = ::LoadCursor(NULL, pszCursor); ::SetCursor(hCursor); return TRUE;}
/////////////////////////////////////////////////////////////////////////////// CUIFBalloonButton
CUIFBalloonButton::CUIFBalloonButton( CUIFObject *pParent, DWORD nObjectID, LPCRECT prc, DWORD style) : CUIFButton(pParent, nObjectID, prc, style){ m_nCommandID = 0;}
STDMETHODIMP_(void)CUIFBalloonButton::OnPaint(HDC hDC){ RECT rc = m_rc; ::OffsetRect(&rc, -rc.left, -rc.top);
HDC hMemDC = ::CreateCompatibleDC(hDC); HBITMAP hbmMem = ::CreateCompatibleBitmap(hDC, rc.right, rc.bottom); HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem);
BOOL bPressed; COLORREF rgbShadow, rgbBorder; if (m_uButtonStatus == 1) { bPressed = TRUE; rgbShadow = ::GetSysColor(COLOR_BTNSHADOW); rgbBorder = ::GetSysColor(COLOR_BTNHIGHLIGHT); } else { bPressed = FALSE; if (m_uButtonStatus < 4) { rgbShadow = ::GetSysColor(COLOR_BTNHIGHLIGHT); rgbBorder = ::GetSysColor(COLOR_BTNSHADOW); } else { rgbShadow = ::GetSysColor(COLOR_INFOBK); rgbBorder = ::GetSysColor(COLOR_INFOBK); } }
COLORREF rgbInfoBk = ::GetSysColor(COLOR_INFOBK); HBRUSH hbrBack = ::CreateSolidBrush(rgbInfoBk); ::FillRect(hMemDC, &rc, hbrBack); ::DeleteObject(hbrBack);
DrawTextProc(hMemDC, &rc, bPressed);
HBRUSH hNullBrush = (HBRUSH)::GetStockObject(NULL_BRUSH); HGDIOBJ hbrOld = ::SelectObject(hMemDC, hNullBrush);
HPEN hPen = ::CreatePen(PS_SOLID, 0, rgbShadow); HGDIOBJ hPenOld = ::SelectObject(hMemDC, hPen); ::RoundRect(hMemDC, rc.left, rc.top, rc.right - 1, rc.bottom - 1, 6, 6); ::SelectObject(hMemDC, hPenOld); ::DeleteObject(hPen);
hPen = ::CreatePen(PS_SOLID, 0, rgbBorder); hPenOld = ::SelectObject(hMemDC, hPen); ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right, rc.bottom, 6, 6); ::SelectObject(hMemDC, hPenOld); ::DeleteObject(hPen);
hPen = ::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNFACE)); hPenOld = ::SelectObject(hMemDC, hPen); ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right - 1, rc.bottom - 1, 6, 6); ::SelectObject(hMemDC, hPenOld); ::DeleteObject(hPen);
::SelectObject(hMemDC, hbrOld); ::BitBlt(hDC, m_rc.left, m_rc.top, m_rc.right - m_rc.left, m_rc.bottom - m_rc.top, hMemDC, rc.left, rc.top, SRCCOPY); ::SelectObject(hMemDC, hbmOld); ::DeleteObject(hbmMem); ::DeleteDC(hMemDC);}
voidCUIFBalloonButton::DrawTextProc(HDC hDC, LPCRECT prc, BOOL bPressed){ if (!m_pszButtonText) return;
UINT uFlags = DT_SINGLELINE;
if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_CENTER) uFlags |= DT_CENTER; else if ((m_style & UIF_BUTTON_H_ALIGN_MASK) == UIF_BUTTON_H_ALIGN_RIGHT) uFlags |= DT_RIGHT;
if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_MIDDLE) uFlags |= DT_VCENTER; else if ((m_style & UIF_BUTTON_V_ALIGN_MASK) == UIF_BUTTON_V_ALIGN_BOTTOM) uFlags |= DT_BOTTOM;
COLORREF rgbOldColor = ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNTEXT)); INT nOldBkMode = ::SetBkMode(hDC, TRANSPARENT);
RECT rc = *prc; if (bPressed) ::OffsetRect(&rc, 1, 1);
HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); ::DrawTextW(hDC, m_pszButtonText, -1, &rc, uFlags); ::SelectObject(hDC, hFontOld);
::SetBkMode(hDC, nOldBkMode); ::SetTextColor(hDC, rgbOldColor);}
/////////////////////////////////////////////////////////////////////////////// CUIFBalloonWindow
CUIFBalloonWindow::CUIFBalloonWindow(HINSTANCE hInst, DWORD style) : CUIFWindow(hInst, style){ m_dwUnknown6 = -1; m_nActionID = -1; m_hRgn = NULL; m_pszBalloonText = NULL; m_bHasBkColor = m_bHasTextColor = FALSE; m_rgbBkColor = 0; m_rgbTextColor = 0; m_ptTarget.x = m_ptTarget.y = 0; ZeroMemory(&m_rcExclude, sizeof(m_rcExclude)); m_dwUnknown7 = 0; m_nBalloonType = 0; m_dwUnknown8[0] = 0; m_dwUnknown8[1] = 0; m_ptBalloon.x = m_ptBalloon.y = 0; m_cButtons = 0; m_hwndNotif = NULL; m_uNotifMsg = 0; m_rcMargin.left = 8; m_rcMargin.top = 8; m_rcMargin.right = 8; m_rcMargin.bottom = 8;}
CUIFBalloonWindow::~CUIFBalloonWindow(){ if (m_pszBalloonText) { delete[] m_pszBalloonText; m_pszBalloonText = NULL; }}
STDMETHODIMP_(BOOL)CUIFBalloonWindow::Initialize(){ CUIFWindow::Initialize();
if ((m_style & UIF_BALLOON_WINDOW_TYPE_MASK) == UIF_BALLOON_WINDOW_OK) { AddButton(IDOK); } else if ((m_style & UIF_BALLOON_WINDOW_TYPE_MASK) == UIF_BALLOON_WINDOW_YESNO) { AddButton(IDYES); AddButton(IDNO); }
return TRUE;}
STDMETHODIMP_(void)CUIFBalloonWindow::OnCreate(HWND hWnd){ m_nActionID = -1; AdjustPos();}
STDMETHODIMP_(void)CUIFBalloonWindow::OnDestroy(HWND hWnd){ SendNotification(m_nActionID); DoneWindowRegion();}
STDMETHODIMP_(void)CUIFBalloonWindow::OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam){ CUIFBalloonButton *pButton = NULL;
switch (wParam) { case VK_RETURN: pButton = (CUIFBalloonButton *)FindUIObject(0); break; case VK_ESCAPE: m_nActionID = -1; ::DestroyWindow(m_hWnd); return; case TEXT('Y'): pButton = FindButton(IDYES); break; case TEXT('N'): pButton = FindButton(IDNO); break; }
if (!pButton) return;
m_nActionID = pButton->m_nCommandID; ::DestroyWindow(m_hWnd);}
STDMETHODIMP_(LRESULT)CUIFBalloonWindow::OnObjectNotify(CUIFObject *pObject, WPARAM wParam, LPARAM lParam){ CUIFBalloonButton *pButton = (CUIFBalloonButton *)pObject; m_nActionID = pButton->m_nCommandID; ::DestroyWindow(m_hWnd); return 0;}
STDMETHODIMP_(void)CUIFBalloonWindow::OnPaint(HDC hDC){ RECT rc; GetRect(&rc); PaintFrameProc(hDC, &rc);
switch (m_nBalloonType) { case 1: rc.top += 16; break; case 2: rc.right -= 16; break; case 3: rc.left += 16; break; default: rc.bottom -= 16; break; }
RECT rcMargin; GetMargin(&rcMargin);
rc.left += rcMargin.left; rc.top += rcMargin.top; rc.right -= rcMargin.right; rc.bottom -= rcMargin.bottom;
PaintMessageProc(hDC, &rc, m_pszBalloonText);}
voidCUIFBalloonWindow::AddButton(UINT nCommandId){ RECT rc = { 0, 0, 0, 0 }; if (!((IDOK <= nCommandId) && (nCommandId <= IDNO))) return;
CUIFBalloonButton *pButton = new(cicNoThrow) CUIFBalloonButton(this, m_cButtons, &rc, 5); if (!pButton) return;
pButton->Initialize(); pButton->m_nCommandID = nCommandId;
LPCWSTR pszText;#ifdef IDS_OK extern HINSTANCE g_hInst; WCHAR szText[64]; ::LoadStringW(g_hInst, IDS_OK + (nCommandId - IDOK), szText, _countof(szText)); pszText = szText;#else switch (nCommandId) { case IDOK: pszText = L"OK"; break; case IDCANCEL: pszText = L"Cancel"; break; case IDABORT: pszText = L"&Abort"; break; case IDRETRY: pszText = L"&Retry"; break; case IDIGNORE: pszText = L"&Ignore"; break; case IDYES: pszText = L"&Yes"; break; default: pszText = L"&No"; break; }#endif
pButton->SetText(pszText);
AddUIObj(pButton); ++m_cButtons;}
/// @unimplementedvoidCUIFBalloonWindow::AdjustPos(){ //FIXME}
HRGNCUIFBalloonWindow::CreateRegion(LPCRECT prc){ POINT Points[4]; HRGN hRgn; BOOL bFlag = FALSE; LONG x, y;
switch (m_nBalloonType) { case 1: hRgn = ::CreateRoundRectRgn(prc->left, prc->top + 16, prc->right, prc->bottom, 16, 16); y = prc->top + 16; bFlag = TRUE; break;
case 2: hRgn = ::CreateRoundRectRgn(prc->left, prc->top, prc->right - 16, prc->bottom, 16, 16); x = prc->right - 17; break;
case 3: hRgn = ::CreateRoundRectRgn(prc->left + 16, prc->top, prc->right, prc->bottom, 16, 16); x = prc->left + 16; break;
default: hRgn = ::CreateRoundRectRgn(prc->left, prc->top, prc->right, prc->bottom - 16, 16, 16); y = prc->bottom - 17; bFlag = TRUE; break; }
if (bFlag) { x = Points[1].x = m_ptBalloon.x; Points[1].y = m_ptBalloon.y; Points[0].y = Points[2].y = Points[3].y = y; Points[2].x = x + 10 * (2 * (m_dwUnknown8[0] == 0) - 1); } else { Points[2].x = x; y = Points[0].y = Points[1].y = Points[3].y = m_ptBalloon.y; Points[1].x = m_ptBalloon.x; Points[2].y = y + 10 * (2 * (m_dwUnknown8[0] == 2) - 1); }
Points[0].x = Points[3].x = x;
HRGN hPolygonRgn = ::CreatePolygonRgn(Points, _countof(Points), WINDING); ::CombineRgn(hRgn, hRgn, hPolygonRgn, RGN_OR); ::DeleteObject(hPolygonRgn); return hRgn;}
voidCUIFBalloonWindow::DoneWindowRegion(){ if (m_hRgn) { ::SetWindowRgn(m_hWnd, NULL, TRUE); ::DeleteObject(m_hRgn); m_hRgn = NULL; }}
CUIFBalloonButton *CUIFBalloonWindow::FindButton(UINT nCommandID){ for (UINT iButton = 0; iButton < m_cButtons; ++iButton) { CUIFBalloonButton *pButton = (CUIFBalloonButton *)FindUIObject(iButton); if (pButton && (pButton->m_nCommandID == nCommandID)) return pButton; } return NULL;}
CUIFObject *CUIFBalloonWindow::FindUIObject(UINT nObjectID){ for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) { CUIFObject *pObject = m_ObjectArray[iItem]; if (pObject->m_nObjectID == nObjectID) return pObject; } return NULL;}
COLORREFCUIFBalloonWindow::GetBalloonBkColor(){ if (m_bHasBkColor) return m_rgbBkColor; else return ::GetSysColor(COLOR_INFOBK);}
COLORREFCUIFBalloonWindow::GetBalloonTextColor(){ if (m_bHasTextColor) return m_rgbTextColor; else return ::GetSysColor(COLOR_INFOTEXT);}
voidCUIFBalloonWindow::GetButtonSize(LPSIZE pSize){ HDC hDisplayDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
TEXTMETRIC tm; HGDIOBJ hFontOld = ::SelectObject(hDisplayDC, m_hFont); ::GetTextMetrics(hDisplayDC, &tm); ::SelectObject(hDisplayDC, hFontOld); ::DeleteDC(hDisplayDC);
pSize->cx = 16 * tm.tmAveCharWidth; pSize->cy = tm.tmHeight + 10;}
voidCUIFBalloonWindow::GetMargin(LPRECT prcMargin){ if (prcMargin) *prcMargin = m_rcMargin;}
voidCUIFBalloonWindow::SetExcludeRect(LPCRECT prcExclude){ m_rcExclude = *prcExclude; AdjustPos();}
voidCUIFBalloonWindow::SetTargetPos(POINT ptTarget){ m_ptTarget = ptTarget; AdjustPos();}
voidCUIFBalloonWindow::SetText(LPCWSTR pszText){ if (m_pszBalloonText) { delete[] m_pszBalloonText; m_pszBalloonText = NULL; }
if (pszText == NULL) pszText = L"";
size_t cch = wcslen(pszText); m_pszBalloonText = new(cicNoThrow) WCHAR[cch + 1]; if (m_pszBalloonText) lstrcpynW(m_pszBalloonText, pszText, cch + 1);
AdjustPos();}
voidCUIFBalloonWindow::InitWindowRegion(){ RECT rc; GetRect(&rc); m_hRgn = CreateRegion(&rc); if (m_hRgn) ::SetWindowRgn(m_hWnd, m_hRgn, TRUE);}
voidCUIFBalloonWindow::LayoutObject(){ SIZE size; GetButtonSize(&size);
RECT rc; GetRect(&rc);
switch (m_nBalloonType) { case 1: rc.top += 16; break; case 2: rc.right -= 16; break; case 3: rc.left += 16; break; default: rc.bottom -= 16; break; }
RECT rcMargin; GetMargin(&rcMargin); rc.left += rcMargin.left; rc.top += rcMargin.top; rc.right -= rcMargin.right; rc.bottom -= rcMargin.bottom;
LONG xLeft = (rc.left + rc.right - size.cx * (((m_cButtons - 1) / 2) - m_cButtons)) / 2; for (UINT iButton = 0; iButton < m_cButtons; ++iButton) { CUIFObject *UIObject = FindUIObject(iButton); if (!UIObject) continue;
rcMargin.left = xLeft + iButton * (size.cx * 3 / 2); rcMargin.top = rc.bottom - size.cy; rcMargin.right = rcMargin.left + size.cx; rcMargin.bottom = rc.bottom;
UIObject->SetRect(&rcMargin); UIObject->Show(TRUE); }}
voidCUIFBalloonWindow::PaintFrameProc(HDC hDC, LPCRECT prc){ HRGN hRgn = CreateRegion(prc); HBRUSH hbrBack = ::CreateSolidBrush(GetBalloonBkColor()); HBRUSH hbrFrame = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOWFRAME)); ::FillRgn(hDC, hRgn, hbrBack); ::FrameRgn(hDC, hRgn, hbrFrame, 1, 1); ::DeleteObject(hbrBack); ::DeleteObject(hbrFrame); ::DeleteObject(hRgn);}
voidCUIFBalloonWindow::PaintMessageProc(HDC hDC, LPRECT prc, LPCWSTR pszText){ HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); COLORREF rgbOldColor = ::SetTextColor(hDC, GetBalloonTextColor()); INT nOldBkMode = ::SetBkMode(hDC, TRANSPARENT); ::DrawTextW(hDC, pszText, -1, prc, DT_WORDBREAK); ::SelectObject(hDC, hFontOld); ::SetTextColor(hDC, rgbOldColor); ::SetBkMode(hDC, nOldBkMode);}
voidCUIFBalloonWindow::SendNotification(WPARAM wParam){ if (m_hwndNotif) ::PostMessage(m_hwndNotif, m_uNotifMsg, wParam, 0);}
/////////////////////////////////////////////////////////////////////////////// CUIFMenu
CUIFMenu::CUIFMenu( HINSTANCE hInst, DWORD style, DWORD dwUnknown14) : CUIFWindow(hInst, style){ m_nSelectedID = -1; m_dwUnknown14 = dwUnknown14; SetMenuFont();}
CUIFMenu::~CUIFMenu(){ for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) delete m_MenuItems[iItem];
::DeleteObject(m_hMenuFont); ClearMenuFont();}
void CUIFMenu::CancelMenu(){ if (m_pVisibleSubMenu) { UninitShow(); } else if (m_bModal) { SetSelectedId(0xFFFFFFFF); ::PostMessage(m_hWnd, WM_NULL, 0, 0); }}
void CUIFMenu::ClearMenuFont(){ SetFont(NULL); ::DeleteObject(m_hFont);}
CUIFMenuItem*CUIFMenu::GetNextItem(CUIFMenuItem *pItem){ size_t iItem, cItems = m_MenuItems.size();
if (cItems == 0) return NULL;
if (!m_pSelectedItem) return m_MenuItems[0];
for (iItem = 0; iItem < cItems; ) { if (m_MenuItems[iItem++] == pItem) break; }
for (;;) { if (iItem == cItems) iItem = 0; if (!m_MenuItems[iItem] || !m_MenuItems[iItem]->m_bMenuItemDisabled) break; ++iItem; }
return m_MenuItems[iItem];}
CUIFMenuItem*CUIFMenu::GetPrevItem(CUIFMenuItem *pItem){ ptrdiff_t iItem, cItems = m_MenuItems.size();
if (cItems == 0) return NULL;
if (!m_pSelectedItem) return m_MenuItems[cItems - 1];
for (iItem = cItems - 1; iItem >= 0; ) { if (m_MenuItems[iItem--] == pItem) break; }
for (;;) { if (iItem < 0) iItem = cItems - 1; if (!m_MenuItems[iItem] || !m_MenuItems[iItem]->m_bMenuItemDisabled) break; --iItem; }
return m_MenuItems[iItem];}
CUIFMenu*CUIFMenu::GetTopSubMenu(){ CUIFMenu *pMenu; for (pMenu = this; pMenu->m_pParentMenu; pMenu = pMenu->m_pParentMenu) ; return pMenu;}
void CUIFMenu::HandleMouseMsg(UINT uMsg, LONG x, LONG y){ POINT pt = { x, y }; if (!::PtInRect(&m_rc, pt) && (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP)) { SetSelectedId(-1); PostMessage(m_hWnd, WM_NULL, 0, 0); } CUIFWindow::HandleMouseMsg(uMsg, x, y);}
STDMETHODIMP_(BOOL)CUIFMenu::InitShow(CUIFWindow *pWindow, LPCRECT prc, BOOL bFlag, BOOL bDoAnimation){ HWND hWnd = NULL; if (pWindow) hWnd = *pWindow;
CreateWnd(hWnd);
m_bHasMargin = FALSE;
for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) { if (m_MenuItems[iItem]) m_MenuItems[iItem]->InitMenuExtent(); }
INT cxMax = 0;
m_cxMenuExtent = 0; for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) { CUIFMenuItem *pItem = m_MenuItems[iItem]; if (!pItem) continue;
INT cxItem = m_cxyMargin + pItem->m_MenuLeftExtent.cx; if (cxMax < cxItem) cxMax = cxItem; m_cxMenuExtent = max(m_cxMenuExtent, pItem->m_MenuRightExtent.cx); if (!m_bHasMargin && pItem->m_hbmColor && pItem->IsCheck()) m_bHasMargin = TRUE; }
RECT rcItem = { 0, 0, 0, 0 }; for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) { CUIFMenuItem *pItem = m_MenuItems[iItem]; if (!pItem) continue;
INT cyItem = pItem->m_MenuLeftExtent.cy; rcItem.right = rcItem.left + cxMax + m_cxMenuExtent; rcItem.bottom = rcItem.top + cyItem; pItem->SetRect(&rcItem); rcItem.top += cyItem; AddUIObj(pItem); }
rcItem.top = 0; DWORD style = ::GetWindowLongPtr(hWnd, GWL_STYLE); cxMax = rcItem.right; INT cyMax = rcItem.bottom; if (style & WS_DLGFRAME) { cxMax = rcItem.right + 2 * ::GetSystemMetrics(SM_CXDLGFRAME); cyMax += 2 * ::GetSystemMetrics(SM_CYDLGFRAME); } else if (style & WS_BORDER) { cxMax = rcItem.right + 2 * ::GetSystemMetrics(SM_CXBORDER); cyMax += 2 * ::GetSystemMetrics(SM_CYBORDER); }
RECT rc = { 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN) };
RECT rc3 = *prc; HMONITOR hMon = ::MonitorFromRect(&rc3, MONITOR_DEFAULTTONEAREST); if (hMon) { MONITORINFO mi = { sizeof(mi) }; if (::GetMonitorInfo(hMon, &mi)) rc = mi.rcMonitor; }
if (m_style & 0x200) rcItem.left -= cxMax;
INT x, y; DWORD dwFlags2 = 0;
if (bFlag) { INT bottom = prc->bottom; x = rcItem.left + prc->left; if (rcItem.top + bottom + cyMax > rc.bottom) { bottom = prc->top - cyMax; dwFlags2 = 8; } else { dwFlags2 = 4; }
y = rcItem.top + bottom;
if (rcItem.left + cxMax + prc->right > rc.right) x = rc.right - cxMax; } else { y = rcItem.top + prc->top; if (rcItem.left + prc->right + cxMax > rc.right) { x = rcItem.left + prc->left - cxMax; dwFlags2 = 2; } else { x = rcItem.left + prc->right; dwFlags2 = 1; } if (rcItem.top + cyMax + prc->bottom > rc.bottom) y = rc.bottom - cyMax; }
if (x > rc.right - cxMax) x = rc.right - cxMax; if (x < rc.left) x = rc.left; if (y > rc.bottom - cyMax) y = rc.bottom - cyMax; if (y < rc.top) y = rc.top;
Move(x, y, cxMax, -1);
SetRect(NULL);
BOOL bAnimation = FALSE; if (bDoAnimation && ::SystemParametersInfo(SPI_GETMENUANIMATION, 0, &bAnimation, 0) && bAnimation) { BOOL bMenuFade = FALSE; if (!::SystemParametersInfoA(SPI_GETMENUFADE, 0, &bMenuFade, 0)) bMenuFade = FALSE;
DWORD dwFlags = (bMenuFade ? 0x80000 : dwFlags2) | 0x40000; if (!AnimateWnd(200, dwFlags)) Show(TRUE); } else { Show(TRUE); }
if (m_pVisibleSubMenu) m_pVisibleSubMenu->m_pParentMenu = this;
return TRUE;}
BOOL CUIFMenu::InsertItem(CUIFMenuItem *pItem){ if (!m_MenuItems.Add(pItem)) return FALSE;
pItem->SetFont(m_hFont); return TRUE;}
BOOL CUIFMenu::InsertSeparator(){ CUIFMenuItemSeparator *pSep = new(cicNoThrow) CUIFMenuItemSeparator(this); if (!pSep) return FALSE;
if (!m_MenuItems.Add(pSep)) { delete pSep; return FALSE; }
pSep->Initialize(); return TRUE;}
STDMETHODIMP_(void)CUIFMenu::ModalMessageLoop(){ MSG msg;
while (::GetMessage(&msg, 0, 0, 0) && msg.message != WM_NULL && (msg.hwnd == m_hWnd || msg.message <= WM_MOUSEFIRST || WM_MOUSELAST <= msg.message)) { if (!msg.hwnd && WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) msg.hwnd = GetTopSubMenu()->m_hWnd; ::TranslateMessage(&msg); ::DispatchMessage(&msg); }}
STDMETHODIMP_(void)CUIFMenu::ModalMouseNotify(UINT uMsg, LONG x, LONG y){ if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN) CancelMenu();}
STDMETHODIMP_(void)CUIFMenu::OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam){ CUIFMenuItem *pTargetItem;
BYTE vKey = (BYTE)wParam;
switch (vKey) { case VK_ESCAPE: CancelMenu(); return;
case VK_LEFT: if (!m_pVisibleSubMenu) return;
CancelMenu(); return;
case VK_RIGHT: if (m_pSelectedItem && m_pSelectedItem->m_pSubMenu) { m_pSelectedItem->ShowSubPopup(); CUIFMenu *pSubMenu = m_pSelectedItem->m_pSubMenu; pTargetItem = pSubMenu->GetNextItem(NULL); pSubMenu->SetSelectedItem(pTargetItem); } return;
case VK_UP: pTargetItem = GetPrevItem(m_pSelectedItem); SetSelectedItem(pTargetItem); return;
case VK_DOWN: pTargetItem = GetNextItem(m_pSelectedItem); SetSelectedItem(pTargetItem); return;
case VK_RETURN: break;
default: { if (!(('A' <= vKey && vKey <= 'Z') || ('0' <= vKey && vKey <= '9'))) return;
size_t iItem; for (iItem = 0; iItem < m_MenuItems.size(); ++iItem) { CUIFMenuItem *pItem = m_MenuItems[iItem]; if (pItem->m_nMenuItemVKey == vKey) { SetSelectedItem(pItem); break; } }
if (iItem == m_MenuItems.size()) return; } }
if (m_pSelectedItem && !m_pSelectedItem->m_bMenuItemGrayed) { CUIFMenu *pSubMenu = m_pSelectedItem->m_pSubMenu; if (pSubMenu) { m_pSelectedItem->ShowSubPopup(); pTargetItem = pSubMenu->GetNextItem(NULL); pSubMenu->SetSelectedItem(pTargetItem); } else { SetSelectedId(m_pSelectedItem->m_nMenuItemID); ::PostMessage(m_hWnd, WM_NULL, 0, 0); } }}
void CUIFMenu::PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam){ if (m_bModal) { // NOTE: hWnd parameter will be populated in CUIFMenu::ModalMessageLoop. if (bUp) ::PostMessage(NULL, WM_KEYUP, wParam, lParam); else ::PostMessage(NULL, WM_KEYDOWN, wParam, lParam); }}
void CUIFMenu::SetMenuFont(){ LONG height = 14;
NONCLIENTMETRICS ncm = { sizeof(ncm) }; if (::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0)) { HFONT hFont = ::CreateFontIndirect(&ncm.lfMenuFont); SetFont(hFont);
LONG lfHeight = ncm.lfMenuFont.lfHeight; if (lfHeight < 0) lfHeight = -lfHeight; height = (ncm.iMenuHeight + lfHeight) / 2; }
m_hMenuFont = ::CreateFontW(height, 0, 0, 0, FW_NORMAL, 0, 0, 0, SYMBOL_CHARSET, 0, 0, 0, 0, L"Marlett"); INT cxSmallIcon = ::GetSystemMetrics(SM_CXSMICON); m_cxyMargin = max(height, cxSmallIcon) + 2;}
void CUIFMenu::SetSelectedId(UINT nSelectID){ CUIFMenu *pMenu = this;
while (pMenu->m_pVisibleSubMenu) pMenu = pMenu->m_pVisibleSubMenu;
pMenu->m_nSelectedID = nSelectID;}
void CUIFMenu::SetSelectedItem(CUIFMenuItem *pItem){ CUIFMenuItem *pOldItem = m_pSelectedItem; if (pOldItem == pItem) return;
m_pSelectedItem = pItem; if (pOldItem) pOldItem->CallOnPaint(); if (m_pSelectedItem) m_pSelectedItem->CallOnPaint();}
UINT CUIFMenu::ShowModalPopup(CUIFWindow *pWindow, LPCRECT prc, BOOL bFlag){ CUIFObject *pCaptured = NULL; if (pWindow) { pCaptured = pWindow->m_pCaptured; CUIFWindow::SetCaptureObject(NULL); }
UINT nSelectedID = -1; if (InitShow(pWindow, prc, bFlag, TRUE)) { m_bModal = TRUE; pWindow->SetBehindModal(this); ModalMessageLoop(); nSelectedID = m_nSelectedID; pWindow->SetBehindModal(NULL); m_bModal = FALSE; }
UninitShow();
if (pWindow) pWindow->SetCaptureObject(pCaptured);
return nSelectedID;}
void CUIFMenu::ShowSubPopup(CUIFMenu *pSubMenu, LPCRECT prc, BOOL bFlag){ m_pVisibleSubMenu = pSubMenu; InitShow(pSubMenu, prc, bFlag, TRUE);}
STDMETHODIMP_(BOOL)CUIFMenu::UninitShow(){ if (m_pParentMenu) m_pParentMenu->UninitShow();
Show(FALSE);
if (m_pVisibleSubMenu) m_pVisibleSubMenu->m_pParentMenu = NULL;
for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) RemoveUIObj(m_MenuItems[iItem]);
::DestroyWindow(m_hWnd); return TRUE;}
/////////////////////////////////////////////////////////////////////////////// CUIFMenuItem
CUIFMenuItem::CUIFMenuItem( CUIFMenu *pMenu, BOOL bDisabled) : CUIFObject(pMenu, 0, NULL, 0){ m_ichMenuItemPrefix = -1; m_nMenuItemID = 0; m_pszMenuItemLeft = m_pszMenuItemRight = NULL; m_cchMenuItemLeft = m_cchMenuItemRight = 0; m_nMenuItemVKey = 0; m_hbmColor = m_hbmMask = NULL; m_bMenuItemChecked = m_bMenuItemGrayed = FALSE; m_bMenuItemDisabled = bDisabled; m_pMenu = pMenu;}
CUIFMenuItem::~CUIFMenuItem(){ if (m_pszMenuItemLeft) { delete[] m_pszMenuItemLeft; m_pszMenuItemLeft = NULL; }
if (m_pszMenuItemRight) { delete[] m_pszMenuItemRight; m_pszMenuItemRight = NULL; }
if (m_pSubMenu) { delete m_pSubMenu; m_pSubMenu = NULL; }}
BOOL CUIFMenuItem::Init(UINT nMenuItemID, LPCWSTR pszText){ m_nMenuItemID = nMenuItemID;
if (!pszText) { m_pszMenuItemLeft = NULL; m_cchMenuItemLeft = 0; return TRUE; }
INT cch = lstrlenW(pszText); m_pszMenuItemLeft = new(cicNoThrow) WCHAR[cch + 1]; if (!m_pszMenuItemLeft) return FALSE;
const WCHAR *pch0 = pszText; INT ich1, ich2; for (ich1 = 0; *pch0 && *pch0 != L'\t'; ++ich1, ++pch0) { if (*pch0 == L'&' && *++pch0 != L'&') { m_nMenuItemVKey = ::VkKeyScanW(*pch0); if (!m_nMenuItemVKey) m_nMenuItemVKey = (BYTE)VkKeyScanA(*(BYTE*)pch0); m_ichMenuItemPrefix = ich1; } m_pszMenuItemLeft[ich1] = *pch0; } m_pszMenuItemLeft[ich1] = 0; m_cchMenuItemLeft = lstrlenW(m_pszMenuItemLeft);
if (*pch0 == L'\t') { m_cchMenuItemRight = 0; m_pszMenuItemRight = new(cicNoThrow) WCHAR[cch + 1]; if (m_pszMenuItemRight) { ++pch0; WCHAR wch = *pch0; for (ich2 = 0; *pch0; ++ich2) { m_pszMenuItemRight[ich2] = wch; wch = *++pch0; } m_pszMenuItemRight[ich2] = 0; m_cchMenuItemRight = lstrlenW(m_pszMenuItemRight); } }
return TRUE;}
STDMETHODIMP_(void)CUIFMenuItem::InitMenuExtent(){ if (!m_pszMenuItemLeft) { if (m_hbmColor) { BITMAP bm; ::GetObject(m_hbmColor, sizeof(bm), &bm); m_MenuLeftExtent.cx = bm.bmWidth + 2; m_MenuLeftExtent.cy = bm.bmHeight + 4; } else { m_MenuLeftExtent.cx = m_MenuLeftExtent.cy = 0; } return; }
HDC hDC = ::GetDC(*m_pWindow);
HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont); ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_cchMenuItemLeft, &m_MenuLeftExtent); m_MenuLeftExtent.cx += 16; m_MenuLeftExtent.cy += 8; if (m_pszMenuItemRight) { ::GetTextExtentPoint32W(hDC, m_pszMenuItemRight, m_cchMenuItemRight, &m_MenuRightExtent); m_MenuRightExtent.cy += 8; } ::SelectObject(hDC, hFontOld);
if (m_pSubMenu) m_MenuLeftExtent.cx += m_MenuLeftExtent.cy + 2; if (m_pMenu->m_style & UIF_MENU_USE_OFF10) m_MenuLeftExtent.cx += 24;
::ReleaseDC(*m_pWindow, hDC);}
BOOL CUIFMenuItem::IsCheck(){ return m_bMenuItemChecked || m_bMenuItemForceChecked;}
void CUIFMenuItem::DrawArrow(HDC hDC, INT xLeft, INT yTop){ if (!m_pSubMenu) return;
HGDIOBJ hFontOld = ::SelectObject(hDC, m_pMenu->m_hMenuFont); ::TextOutW(hDC, xLeft, yTop, L"4", 1); // rightward triangle ::SelectObject(hDC, hFontOld);}
void CUIFMenuItem::DrawBitmapProc(HDC hDC, INT xLeft, INT yTop){ if (!m_pScheme || !m_hbmColor) return;
BITMAP bm; ::GetObject(m_hbmColor, sizeof(bm), &bm);
INT width = m_pMenu->m_cxyMargin, height = m_rc.bottom - m_rc.top; if (width > bm.bmWidth) { width = bm.bmWidth; xLeft += (width - bm.bmWidth) / 2; } if (height > bm.bmHeight) { height = bm.bmHeight; yTop += (height - bm.bmHeight) / 2; }
RECT rc = { xLeft, yTop, xLeft + width, yTop + height };
if (IsRTL()) m_pScheme->m_bMirroring = TRUE;
if (m_pMenu->m_pSelectedItem != this || m_bMenuItemDisabled) m_pScheme->DrawFrameCtrlBitmap(hDC, &rc, m_hbmColor, m_hbmMask, 0); else m_pScheme->DrawFrameCtrlBitmap(hDC, &rc, m_hbmColor, m_hbmMask, UIF_DRAW_PRESSED);
if (IsRTL()) m_pScheme->m_bMirroring = FALSE;}
void CUIFMenuItem::DrawCheck(HDC hDC, INT xLeft, INT yTop){ if (!IsCheck()) return;
HGDIOBJ hFontOld = ::SelectObject(hDC, m_pMenu->m_hMenuFont); WCHAR wch = (m_bMenuItemChecked ? L'a' : L'h'); // checkmark or bullet ::TextOutW(hDC, xLeft, yTop, &wch, 1); ::SelectObject(hDC, hFontOld);}
voidCUIFMenuItem::DrawUnderline(HDC hDC, INT xText, INT yText, HBRUSH hbr){ if (m_ichMenuItemPrefix > m_cchMenuItemLeft) return;
SIZE PrePrefixSize, PostPrefixSize; ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_ichMenuItemPrefix, &PrePrefixSize); ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_ichMenuItemPrefix + 1, &PostPrefixSize);
BOOL bHeadPrefix = (m_ichMenuItemPrefix == 0);
RECT rc; rc.left = xText + PrePrefixSize.cx + !bHeadPrefix; rc.right = xText + PostPrefixSize.cx; rc.top = (yText + PostPrefixSize.cy) - 1; rc.bottom = yText + PostPrefixSize.cy; ::FillRect(hDC, &rc, hbr);}
STDMETHODIMP_(void)CUIFMenuItem::OnLButtonUp(LONG x, LONG y){ if (!m_bMenuItemGrayed && !m_bMenuItemDisabled && !m_pSubMenu) { m_pMenu->SetSelectedId(m_nMenuItemID); ::PostMessage(*m_pWindow, WM_NULL, 0, 0); }}
STDMETHODIMP_(void)CUIFMenuItem::OnMouseIn(LONG x, LONG y){ if (m_pMenu->m_pParentMenu) m_pMenu->m_pParentMenu->CancelMenu();
if (m_pSubMenu) { DWORD Delay; if (!::SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &Delay, 0)) Delay = 300;
CUIFObject::StartTimer(Delay); }
m_pMenu->SetSelectedItem(this);}
STDMETHODIMP_(void)CUIFMenuItem::OnPaint(HDC hDC){ if (m_pMenu->m_style & UIF_MENU_USE_OFF10) OnPaintO10(hDC); else OnPaintDef(hDC);}
STDMETHODIMP_(void)CUIFMenuItem::OnPaintO10(HDC hDC){ if (!m_pScheme) return;
HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
SIZE textSize; ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_cchMenuItemLeft, &textSize);
LONG cySpace = m_rc.bottom - m_rc.top - textSize.cy; LONG xCheck = m_rc.left, yCheck = m_rc.top + cySpace / 2; LONG cxyMargin = (m_pMenu->m_bHasMargin ? m_pMenu->m_cxyMargin : 0);
LONG xBitmap = m_rc.left + cxyMargin, yBitmap = m_rc.top; LONG xText = m_rc.left + m_pMenu->m_cxyMargin + cxyMargin + 8; LONG yText = m_rc.top + cySpace / 2; LONG xArrow = m_rc.left - textSize.cy + m_rc.right - 2; LONG xRightText = m_rc.right - m_pMenu->m_cxMenuExtent - 8;
RECT rc; GetRect(&rc);
if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) { rc.right = m_pMenu->m_cxyMargin + rc.left + 2; if (m_pMenu->m_bHasMargin) rc.right += m_pMenu->m_cxyMargin;
::FillRect(hDC, &rc, m_pScheme->GetBrush(9)); } else { m_pScheme->DrawCtrlBkgd(hDC, &rc, 0, UIF_DRAW_PRESSED); m_pScheme->DrawCtrlEdge(hDC, &rc, 0, UIF_DRAW_PRESSED); }
::SetBkMode(hDC, TRANSPARENT);
if (m_bMenuItemGrayed) { ::SetTextColor(hDC, m_pScheme->GetColor(11)); ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); } else if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) { ::SetTextColor(hDC, m_pScheme->GetColor(10)); ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); } else { ::SetTextColor(hDC, m_pScheme->GetColor(5)); ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); }
DrawUnderline(hDC, xText, yText, m_pScheme->GetBrush(5));
if (m_pszMenuItemRight) { ::ExtTextOutW(hDC, xRightText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemRight, m_cchMenuItemRight, NULL); }
DrawCheck(hDC, xCheck, yCheck); DrawBitmapProc(hDC, xBitmap, yBitmap); DrawArrow(hDC, xArrow, yText);
::SelectObject(hDC, hFontOld);}
STDMETHODIMP_(void)CUIFMenuItem::OnPaintDef(HDC hDC){ HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
SIZE textSize; ::GetTextExtentPoint32W(hDC, m_pszMenuItemLeft, m_cchMenuItemLeft, &textSize);
LONG cxyMargin = (m_pMenu->m_bHasMargin ? m_pMenu->m_cxyMargin : 0);
LONG cySpace = m_rc.bottom - m_rc.top - textSize.cy; LONG xCheck = m_rc.left, yCheck = m_rc.top + cySpace / 2; LONG xBitmap = m_rc.left + cxyMargin, yBitmap = m_rc.top; LONG xText = m_rc.left + cxyMargin + m_pMenu->m_cxyMargin + 2; LONG yText = m_rc.top + cySpace / 2;
LONG xArrow = m_rc.right + m_rc.left - 10;
::SetBkMode(hDC, TRANSPARENT);
if (m_bMenuItemGrayed) { UINT uOptions = ETO_CLIPPED; if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) { ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHIGHLIGHT)); ::ExtTextOutW(hDC, xText + 1, yText + 1, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); DrawCheck(hDC, xCheck + 1, yCheck + 1); DrawBitmapProc(hDC, xBitmap + 1, yBitmap + 1); DrawArrow(hDC, xArrow + 1, yText + 1); } else { ::SetBkColor(hDC, ::GetSysColor(COLOR_HIGHLIGHT)); uOptions = ETO_CLIPPED | ETO_OPAQUE; } ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); ::ExtTextOutW(hDC, xText, yText, uOptions, &m_rc, m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); DrawUnderline(hDC, xText, yText, (HBRUSH)UlongToHandle(COLOR_BTNSHADOW + 1)); } else if (m_bMenuItemDisabled || m_pMenu->m_pSelectedItem != this) { ::SetTextColor(hDC, ::GetSysColor(COLOR_MENUTEXT)); ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED, &m_rc, m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); DrawUnderline(hDC, xText, yText, (HBRUSH)UlongToHandle(COLOR_MENUTEXT + 1)); } else { ::SetTextColor(hDC, ::GetSysColor(COLOR_HIGHLIGHTTEXT)); ::SetBkColor(hDC, ::GetSysColor(COLOR_HIGHLIGHT)); ::ExtTextOutW(hDC, xText, yText, ETO_CLIPPED | ETO_OPAQUE, &m_rc, m_pszMenuItemLeft, m_cchMenuItemLeft, NULL); DrawUnderline(hDC, xText, yText, (HBRUSH)UlongToHandle(COLOR_HIGHLIGHTTEXT + 1)); }
DrawCheck(hDC, xCheck, yCheck); DrawBitmapProc(hDC, xBitmap, yBitmap); DrawArrow(hDC, xArrow, yText);
::SelectObject(hDC, hFontOld);}
STDMETHODIMP_(void)CUIFMenuItem::OnTimer(){ CUIFObject::EndTimer(); if (m_pMenu->m_pPointed == this) ShowSubPopup();}
void CUIFMenuItem::SetBitmapMask(HBITMAP hbmMask){ m_hbmMask = hbmMask; CallOnPaint();}
void CUIFMenuItem::ShowSubPopup(){ RECT rc = m_rc; ::ClientToScreen(*m_pWindow, (LPPOINT)&rc); ::ClientToScreen(*m_pWindow, (LPPOINT)&rc.right); m_pSubMenu->ShowSubPopup(m_pMenu, &rc, FALSE);}
/////////////////////////////////////////////////////////////////////////////// CUIFMenuItemSeparator
CUIFMenuItemSeparator::CUIFMenuItemSeparator(CUIFMenu *pMenu) : CUIFMenuItem(pMenu, TRUE){ m_nMenuItemID = -1;}
STDMETHODIMP_(void)CUIFMenuItemSeparator::InitMenuExtent(){ m_MenuLeftExtent.cx = 0; m_MenuLeftExtent.cy = 6;}
STDMETHODIMP_(void)CUIFMenuItemSeparator::OnPaintDef(HDC hDC){ if (!m_pScheme) return;
RECT rc; rc.left = m_rc.left + 2; rc.top = m_rc.top + (m_rc.bottom - m_rc.top - 2) / 2; rc.right = m_rc.right - 2; rc.bottom = rc.top + 2; m_pScheme->DrawMenuSeparator(hDC, &rc);}
STDMETHODIMP_(void)CUIFMenuItemSeparator::OnPaintO10(HDC hDC){ if (!m_pScheme) return;
LONG cx = m_rc.right - m_rc.left - 4; LONG cy = (m_rc.bottom - m_rc.top - 2) / 2;
RECT rc; GetRect(&rc);
rc.right = rc.left + m_pMenu->m_cxyMargin + 2; if (m_pMenu->m_bHasMargin) rc.right += m_pMenu->m_cxyMargin;
HBRUSH hBrush = m_pScheme->GetBrush(9); ::FillRect(hDC, &rc, hBrush); rc = { m_rc.left + m_pMenu->m_cxyMargin + 4, m_rc.top + cy, m_rc.left + cx + 2, m_rc.top + cy + 1 }; m_pScheme->DrawMenuSeparator(hDC, &rc);}
/////////////////////////////////////////////////////////////////////////////
void cicGetWorkAreaRect(POINT pt, LPRECT prc){ ::SystemParametersInfo(SPI_GETWORKAREA, 0, prc, 0);
HMONITOR hMon = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); if (hMon) { MONITORINFO mi = { sizeof(mi) }; if (::GetMonitorInfo(hMon, &mi)) *prc = mi.rcWork; }}
void cicGetScreenRect(POINT pt, LPRECT prc){ *prc = { 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN) }; HMONITOR hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); if (hMon) { MONITORINFO mi = { sizeof(mi) }; GetMonitorInfo(hMon, &mi); *prc = mi.rcMonitor; }}
BOOL cicIsFullScreenSize(HWND hWnd){ RECT rc;
::GetWindowRect(hWnd, &rc); return (rc.left <= 0) && (rc.top <= 0) && (rc.right >= GetSystemMetrics(SM_CXFULLSCREEN)) && (rc.bottom >= GetSystemMetrics(SM_CYFULLSCREEN));}
BOOL cicGetIconSize(HICON hIcon, LPSIZE pSize){ ICONINFO IconInfo; if (!GetIconInfo(hIcon, &IconInfo)) return FALSE;
BITMAP bm; ::GetObject(IconInfo.hbmColor, sizeof(bm), &bm); ::DeleteObject(IconInfo.hbmColor); ::DeleteObject(IconInfo.hbmMask); pSize->cx = bm.bmWidth; pSize->cy = bm.bmHeight; return TRUE;}
/////////////////////////////////////////////////////////////////////////////
void cicInitUIFSys(void){ CUIFSystemInfo::s_pSystemInfo = new(cicNoThrow) CUIFSystemInfo(); if (CUIFSystemInfo::s_pSystemInfo) CUIFSystemInfo::s_pSystemInfo->Initialize();}
void cicDoneUIFSys(void){ if (CUIFSystemInfo::s_pSystemInfo) { delete CUIFSystemInfo::s_pSystemInfo; CUIFSystemInfo::s_pSystemInfo = NULL; }}
void cicUpdateUIFSys(void){ if (CUIFSystemInfo::s_pSystemInfo) CUIFSystemInfo::s_pSystemInfo->GetSystemMetrics();}
/////////////////////////////////////////////////////////////////////////////
void cicInitUIFScheme(void){ CUIFColorTable *pColorTable;
pColorTable = CUIFScheme::s_pColorTableSys = new(cicNoThrow) CUIFColorTableSys(); if (pColorTable) { pColorTable->InitColor(); pColorTable->InitBrush(); }
pColorTable = CUIFScheme::s_pColorTableOff10 = new(cicNoThrow) CUIFColorTableOff10(); if (pColorTable) { pColorTable->InitColor(); pColorTable->InitBrush(); }}
void cicUpdateUIFScheme(void){ if (CUIFScheme::s_pColorTableSys) CUIFScheme::s_pColorTableSys->Update(); if (CUIFScheme::s_pColorTableOff10) CUIFScheme::s_pColorTableOff10->Update();}
void cicDoneUIFScheme(void){ if (CUIFScheme::s_pColorTableSys) { delete CUIFScheme::s_pColorTableSys; CUIFScheme::s_pColorTableSys = NULL; } if (CUIFScheme::s_pColorTableOff10) { delete CUIFScheme::s_pColorTableOff10; CUIFScheme::s_pColorTableOff10 = NULL; }}
/////////////////////////////////////////////////////////////////////////////
void cicInitUIFLib(void){ cicInitUIFSys(); cicInitUIFScheme(); cicInitUIFUtil();}
void cicDoneUIFLib(void){ cicDoneUIFScheme(); cicDoneUIFSys(); cicDoneUIFUtil();}
/////////////////////////////////////////////////////////////////////////////