basewnd.cpp 127 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743
  1. #include <precomp.h>
  2. #include <bfc/wasabi_std.h>
  3. #include <bfc/wasabi_std_wnd.h>
  4. #include <api/wnd/wndevent.h>
  5. #include <bfc/bfc_assert.h>
  6. #include <api/wnd/wndclass/tooltip.h>
  7. #include <api/wnd/cursor.h>
  8. #include <api/wnd/accessible.h>
  9. #include <api/service/svcs/svc_accessibility.h>
  10. #include <api/wnd/paintsets.h>
  11. #include <api/wnd/PaintCanvas.h>
  12. #ifdef _WIN32
  13. #include <shellapi.h> // for HDROP
  14. #endif
  15. #include <tataki/canvas/bltcanvas.h>
  16. #define DESKTOPALPHA
  17. #define REFRESH_RATE 25
  18. #define DRAWTIMERID 125
  19. #include <api/wnd/basewnd.h>
  20. #include <api/wnd/usermsg.h>
  21. #include <api/wnd/paintcb.h>
  22. #include <tataki/canvas/canvas.h>
  23. #include <bfc/file/filename.h>
  24. #include <tataki/region/region.h>
  25. #include <api/wnd/wndclass/guiobjwnd.h>
  26. #include <api/script/scriptguid.h>
  27. #include <api/wnd/notifmsg.h>
  28. #include <api/metrics/metricscb.h>
  29. #include <api/wndmgr/gc.h>
  30. #include <api/wndmgr/layout.h>
  31. namespace Agave
  32. {
  33. #include "../Agave/Config/api_config.h"
  34. }
  35. //#define TIP_TIMER_ID 1601
  36. #define TIP_DESTROYTIMER_ID 1602
  37. #define TIP_AWAY_ID 1603
  38. #define TIP_AWAY_DELAY 100
  39. #define TIP_TIMER_THRESHOLD 350
  40. #define TIP_LENGTH 3000
  41. #define VCHILD_TIMER_ID_MIN 2000
  42. #define VCHILD_TIMER_ID_MAX 2100
  43. #define BUFFEREDMSG_TIMER_ID 1604
  44. #define DEFERREDCB_INVALIDATE 0x201 // move to .h
  45. #define DEFERREDCB_FOCUSFIRST 0x202 // move to .h
  46. #define DC_KILLGHOST 0x204
  47. #ifdef _WIN32
  48. #define WM_DEFER_CALLBACK (WM_USER+0x333)
  49. #endif
  50. class DragSet : public PtrList<void>, public NamedW {};
  51. //CUT? static void register_wndClass(HINSTANCE);
  52. //CUT? #define ROOTSTRING "RootWnd"
  53. //CUT? #define BASEWNDCLASSNAME "BaseWindow_" ROOTSTRING
  54. #ifndef WM_MOUSEWHEEL
  55. #define WM_MOUSEWHEEL 0x20A
  56. #endif
  57. static ifc_window *stickyWnd;
  58. static RECT sticky;
  59. static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL;
  60. /*api_window *api_window::rootwndFromPoint(POINT &point, int level) {
  61. api_window *wnd;
  62. wnd = WASABI_API_WND->rootWndFromPoint(&point);
  63. return api_window::rootwndFromRootWnd(wnd, level, &point);
  64. }
  65. api_window *api_window::rootwndFromRootWnd(api_window *wnd, int level, POINT *point) {
  66. for (;;) {
  67. if (wnd == NULL || level < 0) return NULL;
  68. if (point) {
  69. RECT r;
  70. wnd->getWindowRect(&r);
  71. if (!PtInRect(&r, *point)) return NULL; // PORT ME
  72. }
  73. if (level == 0) return wnd;
  74. wnd = wnd->getRootWndParent();
  75. level--;
  76. }
  77. // should never get here
  78. }*/
  79. static BOOL DisabledWindow_OnMouseClick(HWND hwnd)
  80. {
  81. DWORD windowStyle = (DWORD)GetWindowLongPtrW(hwnd, GWL_STYLE);
  82. if (WS_DISABLED != ((WS_CHILD | WS_DISABLED) & windowStyle))
  83. return FALSE;
  84. HWND hActive = GetActiveWindow();
  85. HWND hPopup = GetWindow(hwnd, GW_ENABLEDPOPUP);
  86. BOOL beepOk = (hPopup == hActive || hwnd == GetWindow(hActive, GW_OWNER));
  87. if (!beepOk && NULL == hPopup)
  88. {
  89. for (HWND hWalker = hwnd; ;)
  90. {
  91. hWalker = GetWindow(hWalker, GW_OWNER);
  92. if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE))))
  93. break;
  94. if (hActive == GetWindow(hWalker, GW_ENABLEDPOPUP))
  95. {
  96. beepOk = TRUE;
  97. break;
  98. }
  99. }
  100. }
  101. if (beepOk)
  102. {
  103. static const GUID accessibilityConfigGroupGUID =
  104. { 0xe2e7f4a, 0x7c51, 0x478f, { 0x87, 0x74, 0xab, 0xbc, 0xf6, 0xd5, 0xa8, 0x57 } };
  105. #define GetBoolConfig(__group, __itemName, __default)\
  106. ((NULL != (__group)) && NULL != (item = group->GetItem(__itemName)) ? item->GetBool() : (__default))
  107. waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
  108. Agave::api_config *config = (NULL != serviceFactory) ? (Agave::api_config *)serviceFactory->getInterface() : NULL;
  109. Agave::ifc_configgroup *group = (NULL != config) ? config->GetGroup(accessibilityConfigGroupGUID) : NULL;
  110. Agave::ifc_configitem *item;
  111. if (GetBoolConfig(group, L"modalflash", true))
  112. {
  113. FLASHWINFO flashInfo;
  114. flashInfo.cbSize = sizeof(FLASHWINFO);
  115. flashInfo.hwnd = hActive;
  116. flashInfo.dwFlags = FLASHW_CAPTION;
  117. flashInfo.uCount = 2;
  118. flashInfo.dwTimeout = 100;
  119. FlashWindowEx(&flashInfo);
  120. }
  121. if (GetBoolConfig(group, L"modalbeep", false))
  122. MessageBeep(MB_OK);
  123. if (NULL != config)
  124. serviceFactory->releaseInterface(config);
  125. }
  126. else
  127. {
  128. for (HWND hWalker = hwnd; NULL == hPopup;)
  129. {
  130. hWalker = GetWindow(hWalker, GW_OWNER);
  131. if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE))))
  132. break;
  133. hPopup = GetWindow(hWalker, GW_ENABLEDPOPUP);
  134. }
  135. SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
  136. if (NULL != hPopup && hPopup != hwnd)
  137. {
  138. BringWindowToTop(hPopup);
  139. SetActiveWindow(hPopup);
  140. }
  141. }
  142. return TRUE;
  143. }
  144. int WndWatcher::viewer_onItemDeleted(ifc_dependent *item)
  145. {
  146. if (item == dep)
  147. {
  148. dep = NULL;
  149. watcher->wndwatcher_onDeleteWindow(watched);
  150. watched = NULL;
  151. }
  152. return 1;
  153. }
  154. BaseWnd::BaseWnd()
  155. {
  156. uiwaslocked = 0;
  157. m_takenOver = 0;
  158. rootfocus = NULL;
  159. rootfocuswatcher.setWatcher(this);
  160. alwaysontop = 0;
  161. customdefaultcursor = NULL;
  162. preventcancelcapture = 0;
  163. ratiolinked = 1;
  164. deleting = 0;
  165. hinstance = NULL;
  166. hwnd = NULL;
  167. parentWnd = NULL;
  168. dragging = 0;
  169. prevtarg = NULL;
  170. inputCaptured = 0;
  171. btexture = NULL;
  172. postoninit = 0;
  173. inited = 0;
  174. skipnextfocus = 0;
  175. ncb = FALSE;
  176. accessible = NULL;
  177. tooltip = NULL;
  178. tip_done = FALSE;
  179. tipshowtimer = FALSE;
  180. tipawaytimer = FALSE;
  181. tipdestroytimer = FALSE;
  182. start_hidden = 0;
  183. notifyWindow = NULL;
  184. lastClick[0] = 0;
  185. lastClick[1] = 0;
  186. lastClickP[0].x = 0;
  187. lastClickP[0].y = 0;
  188. lastClickP[1].x = 0;
  189. lastClickP[1].y = 0;
  190. destroying = FALSE;
  191. curVirtualChildCaptured = NULL;
  192. curVirtualChildFocus = NULL;
  193. virtualCanvas = NULL; virtualCanvasH = virtualCanvasW = 0;
  194. deferedInvalidRgn = NULL;
  195. hasfocus = 0;
  196. focus_on_click = 1;
  197. lastnullregion = 0;
  198. ratio = 1;
  199. lastratio = 1;
  200. rwidth = rheight = 0;
  201. skin_id = -1;
  202. wndalpha = 255;
  203. activealpha = 255;
  204. inactivealpha = 255;
  205. w2k_alpha = 0; //FUCKO
  206. scalecanvas = NULL;
  207. clickthrough = 0;
  208. mustquit = 0;
  209. returnvalue = 0;
  210. notifyid = 0;
  211. cloaked = 0;
  212. disable_tooltip_til_recapture = 0;
  213. subtractorrgn = NULL;
  214. composedrgn = NULL;
  215. wndregioninvalid = 1;
  216. regionop = REGIONOP_NONE;
  217. rectrgn = 1;
  218. need_flush_cascaderepaint = 0;
  219. deferedCascadeRepaintRgn = NULL;
  220. this_visible = 0;
  221. this_enabled = 1;
  222. renderbasetexture = 0;
  223. oldCapture = NULL;
  224. my_guiobject = NULL;
  225. want_autoresize_after_init = 0;
  226. resizecount = 0;
  227. suggested_w = 320;
  228. suggested_h = 200;
  229. maximum_w = maximum_h = AUTOWH;
  230. minimum_w = minimum_h = AUTOWH;
  231. rx = 0;
  232. ry = 0;
  233. rwidth = 0;
  234. rheight = 0;
  235. allow_deactivate = 1;
  236. minimized = 0;
  237. inonresize = 0;
  238. #ifndef WA3COMPATIBILITY
  239. m_target = NULL;
  240. #endif
  241. nodoubleclick = noleftclick = norightclick = nomousemove = nocontextmnu = 0;
  242. focusEventsEnabled = 1;
  243. maximized = 0;
  244. MEMSET(&restore_rect, 0, sizeof(RECT));
  245. ghostbust = 0;
  246. lastActiveWnd = NULL;
  247. }
  248. BaseWnd::~BaseWnd()
  249. {
  250. //ASSERT(virtualChildren.getNumItems() == 0);
  251. childtabs.deleteAll();
  252. if (WASABI_API_WND && WASABI_API_WND->getModalWnd() == this) WASABI_API_WND->popModalWnd(this);
  253. destroying = TRUE;
  254. curVirtualChildFocus = NULL;
  255. #ifdef _WIN32
  256. if (inputCaptured && GetCapture() == getOsWindowHandle()) ReleaseCapture();
  257. #else
  258. #warning port me
  259. #endif
  260. for (int i = 0;i < ghosthwnd.getNumItems();i++)
  261. Wasabi::Std::Wnd::destroyWnd(ghosthwnd.enumItem(i));
  262. if (hwnd != NULL && !m_takenOver)
  263. {
  264. #ifdef URLDROPS
  265. if (acceptExternalDrops()) Wasabi::Std::Wnd::revokeDragNDrop(hwnd /*, &m_target*/);
  266. #else
  267. #ifndef WA3COMPATIBILITY
  268. if (m_target != NULL)
  269. {
  270. Wasabi::Std::Wnd::revokeDragNDrop(hwnd);
  271. }
  272. #endif
  273. #endif
  274. int popact = !wantActivation();
  275. if (popact) WASABI_API_WND->appdeactivation_push_disallow(this);
  276. Wasabi::Std::Wnd::destroyWnd(hwnd);
  277. if (popact) WASABI_API_WND->appdeactivation_pop_disallow(this);
  278. }
  279. deleteFrameBuffer(virtualCanvas);
  280. virtualCanvas = NULL;
  281. delete scalecanvas;
  282. scalecanvas = NULL;
  283. resetDragSet();
  284. notifyParent(ChildNotify::DELETED);
  285. if (tipdestroytimer)
  286. killTimer(TIP_DESTROYTIMER_ID);
  287. if (tipshowtimer)
  288. {
  289. // TODO: on the mac, use CreateMouseTrackingRegion
  290. TRACKMOUSEEVENT tracker;
  291. tracker.cbSize=sizeof(tracker);
  292. tracker.dwFlags = TME_HOVER|TME_CANCEL;
  293. tracker.hwndTrack = this->getOsWindowHandle();
  294. tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
  295. TrackMouseEvent(&tracker);
  296. }
  297. if (tipawaytimer)
  298. killTimer(TIP_AWAY_ID);
  299. destroyTip();
  300. delete tooltip;
  301. if (uiwaslocked)
  302. killTimer(BUFFEREDMSG_TIMER_ID);
  303. if (deferedInvalidRgn)
  304. delete deferedInvalidRgn;
  305. delete composedrgn;
  306. delete subtractorrgn;
  307. delete deferedCascadeRepaintRgn;
  308. if (parentWnd != NULL)
  309. parentWnd->unregisterRootWndChild(this);
  310. if (!m_takenOver && WASABI_API_WND) WASABI_API_WND->unregisterRootWnd(this);
  311. hwnd = NULL;
  312. }
  313. int BaseWnd::init(ifc_window *parWnd, int nochild)
  314. {
  315. if (parWnd == NULL)
  316. return 0;
  317. OSWINDOWHANDLE phwnd = parWnd->getOsWindowHandle();
  318. ASSERT(phwnd != NULL);
  319. parentWnd = parWnd; // set default parent wnd
  320. int ret = init(parWnd->getOsModuleHandle(), phwnd, nochild);
  321. if (!ret)
  322. parentWnd = NULL; // abort
  323. return ret;
  324. }
  325. int BaseWnd::init(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild)
  326. {
  327. RECT r;
  328. int w, h;
  329. ASSERTPR(getOsWindowHandle() == NULL, "don't you double init you gaybag");
  330. hinstance = moduleHandle;
  331. #ifdef _WIN32
  332. ASSERT(hinstance != NULL);
  333. #endif
  334. //CUT register_wndClass(hinstance);
  335. if (parent != NULL)
  336. {
  337. Wasabi::Std::Wnd::getClientRect(parent, &r);
  338. }
  339. else
  340. {
  341. Wasabi::Std::setRect(&r, 0, 0, getPreferences(SUGGESTED_W), getPreferences(SUGGESTED_H));
  342. }
  343. w = (r.right - r.left);
  344. h = (r.bottom - r.top);
  345. rwidth = w;
  346. rheight = h;
  347. rx = r.left;
  348. ry = r.top;
  349. int popact = !wantActivation();
  350. if (popact) WASABI_API_WND->appdeactivation_push_disallow(this);
  351. //CUThwnd = createWindow(r.left, r.top, w, h, nochild, parent, hinstance);
  352. hwnd = Wasabi::Std::Wnd::createWnd(&r, nochild, acceptExternalDrops(), parent, hinstance, static_cast<ifc_window*>(this));
  353. #ifdef __APPLE__
  354. #warning remove me
  355. Wasabi::Std::Wnd::showWnd(hwnd);
  356. #endif
  357. if (popact) WASABI_API_WND->appdeactivation_pop_disallow(this);
  358. //ASSERT(hwnd != NULL); // lets fail nicely, this could happen for some win32 reason, we don't want to fail the whole app for it, so lets just fail the wnd
  359. if (hwnd == NULL) return 0;
  360. if (wantActivation()) bringToFront();
  361. //CUT nreal++;
  362. //FUCKO
  363. #ifdef _WIN32 // PORT ME
  364. #ifdef URLDROPS
  365. if (acceptExternalDrops()) RegisterDragDrop(hwnd, &m_target);
  366. #else
  367. #ifndef WA3COMPATIBILITY
  368. if (!m_target && WASABI_API_WND != NULL)
  369. m_target = WASABI_API_WND->getDefaultDropTarget();
  370. if (m_target != NULL)
  371. {
  372. RegisterDragDrop(hwnd, (IDropTarget *)m_target);
  373. }
  374. #endif
  375. #endif
  376. #endif
  377. this_visible = 0;
  378. onInit();
  379. this_visible = !start_hidden;
  380. onPostOnInit();
  381. return 1;
  382. }
  383. #ifndef WA3COMPATIBILITY
  384. void BaseWnd::setDropTarget(void *dt)
  385. {
  386. #ifdef _WIN32
  387. if (isVirtual()) return ;
  388. if (isInited() && m_target != NULL)
  389. {
  390. Wasabi::Std::Wnd::revokeDragNDrop(getOsWindowHandle());
  391. m_target = NULL;
  392. }
  393. m_target = dt;
  394. if (m_target != NULL && isInited())
  395. {
  396. RegisterDragDrop(gethWnd(), (IDropTarget *)m_target);
  397. }
  398. #else
  399. #warning port me
  400. #endif
  401. }
  402. void *BaseWnd::getDropTarget()
  403. {
  404. return m_target;
  405. }
  406. #endif
  407. int BaseWnd::onInit()
  408. {
  409. const wchar_t *s = getName();
  410. if (s != NULL)
  411. setOSWndName(s);
  412. inited = 1;
  413. if (getParent())
  414. getParent()->registerRootWndChild(this);
  415. if (WASABI_API_WND != NULL)
  416. WASABI_API_WND->registerRootWnd(this);
  417. #ifdef _WIN32
  418. if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable())
  419. w2k_alpha = 0; //FUCKO
  420. if (w2k_alpha)
  421. {
  422. setLayeredWindow(1);
  423. }
  424. if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
  425. WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW(L"WINAMP_WM_DIRECT_MOUSE_WHEEL");
  426. #endif
  427. return 0;
  428. }
  429. int BaseWnd::onPostOnInit()
  430. {
  431. postoninit = 1; // from now on, isInited() returns 1;
  432. if (want_autoresize_after_init) onResize();
  433. else invalidateWindowRegion();
  434. if (isVisible()) onSetVisible(1);
  435. if (getTabOrder() == -1) setAutoTabOrder();
  436. ifc_window *dp = getDesktopParent();
  437. if ((dp == NULL || dp == this) && WASABI_API_TIMER != NULL)
  438. postDeferredCallback(DEFERREDCB_FOCUSFIRST, 0, 500);
  439. return 0;
  440. }
  441. void BaseWnd::setLayeredWindow(int i)
  442. {
  443. if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle())) return ;
  444. if (!isInited()) return ;
  445. Wasabi::Std::Wnd::setLayeredWnd(getOsWindowHandle(), i);
  446. #if 0//CUT
  447. if (i)
  448. {
  449. SetWindowLong(getOsWindowHandle(), GWL_EXSTYLE, GetWindowLong(getOsWindowHandle(), GWL_EXSTYLE) & ~WS_EX_LAYERED);
  450. SetWindowLong(getOsWindowHandle(), GWL_EXSTYLE, GetWindowLong(getOsWindowHandle(), GWL_EXSTYLE) | WS_EX_LAYERED);
  451. }
  452. else
  453. {
  454. SetWindowLong(getOsWindowHandle(), GWL_EXSTYLE, GetWindowLong(getOsWindowHandle(), GWL_EXSTYLE) & ~WS_EX_LAYERED);
  455. }
  456. #endif
  457. setTransparency(-1);
  458. }
  459. int BaseWnd::getCursorType(int x, int y)
  460. {
  461. if (!customdefaultcursor)
  462. return BASEWND_CURSOR_POINTER;
  463. return BASEWND_CURSOR_USERSET;
  464. }
  465. void BaseWnd::onSetName()
  466. {
  467. if (isInited() && !isVirtual())
  468. Wasabi::Std::Wnd::setWndName(getOsWindowHandle(), getNameSafe());
  469. notifyParent(ChildNotify::NAMECHANGED);
  470. if (accessible)
  471. accessible->onSetName(getName());
  472. }
  473. OSWINDOWHANDLE BaseWnd::getOsWindowHandle()
  474. {
  475. OSWINDOWHANDLE handle;
  476. if ( isVirtual() )
  477. handle = getParent()->getOsWindowHandle();
  478. else
  479. handle = hwnd;
  480. return handle;
  481. }
  482. OSMODULEHANDLE BaseWnd::getOsModuleHandle()
  483. {
  484. return hinstance;
  485. }
  486. void BaseWnd::onTip()
  487. {
  488. tipshowtimer = FALSE;
  489. tip_done = TRUE;
  490. POINT p;
  491. Wasabi::Std::getMousePos(&p);
  492. if (WASABI_API_WND->rootWndFromPoint(&p) == (ifc_window *)this)
  493. {
  494. createTip();
  495. setTimer(TIP_DESTROYTIMER_ID, TIP_LENGTH);
  496. tipdestroytimer = TRUE;
  497. }
  498. setTimer(TIP_AWAY_ID, TIP_AWAY_DELAY);
  499. tipawaytimer = TRUE;
  500. }
  501. void BaseWnd::timerCallback(int id)
  502. {
  503. switch (id)
  504. {
  505. case BUFFEREDMSG_TIMER_ID:
  506. checkLockedUI();
  507. break;
  508. // case TIP_TIMER_ID:
  509. //onTip();
  510. //break;
  511. case TIP_DESTROYTIMER_ID:
  512. killTimer(TIP_DESTROYTIMER_ID);
  513. killTimer(TIP_AWAY_ID);
  514. tipawaytimer = FALSE;
  515. tipdestroytimer = FALSE;
  516. destroyTip();
  517. break;
  518. case TIP_AWAY_ID:
  519. onTipMouseMove();
  520. break;
  521. }
  522. }
  523. int BaseWnd::isInited()
  524. {
  525. return inited;
  526. }
  527. int BaseWnd::isDestroying()
  528. {
  529. return destroying;
  530. }
  531. int BaseWnd::wantSiblingInvalidations()
  532. {
  533. return FALSE;
  534. }
  535. void BaseWnd::setRSize(int x, int y, int w, int h)
  536. {
  537. rwidth = w;
  538. rheight = h;
  539. rx = x;
  540. ry = y;
  541. }
  542. void BaseWnd::resize(int x, int y, int w, int h, int wantcb)
  543. {
  544. inonresize = 1;
  545. if (x == AUTOWH) x = NOCHANGE;
  546. if (y == AUTOWH) y = NOCHANGE;
  547. if (w == AUTOWH) w = NOCHANGE;
  548. if (h == AUTOWH) h = NOCHANGE;
  549. if (getNumMinMaxEnforcers() > 0)
  550. {
  551. int min_w = getPreferences(MINIMUM_W);
  552. int min_h = getPreferences(MINIMUM_H);
  553. int max_w = getPreferences(MAXIMUM_W);
  554. int max_h = getPreferences(MAXIMUM_H);
  555. if (min_w != AUTOWH && w != NOCHANGE && w < min_w) w = min_w;
  556. if (max_w != AUTOWH && w != NOCHANGE && w > max_w) w = max_w;
  557. if (min_h != AUTOWH && h != NOCHANGE && h < min_h) h = min_h;
  558. if (max_h != AUTOWH && h != NOCHANGE && h > max_h) h = max_h;
  559. }
  560. int noresize = (w == NOCHANGE && h == NOCHANGE);
  561. int nomove = (x == NOCHANGE && y == NOCHANGE)/* || (x == rx && y == ry)*/;
  562. if (x == NOCHANGE) x = rx;
  563. if (y == NOCHANGE) y = ry;
  564. if (w == NOCHANGE) w = rwidth;
  565. if (h == NOCHANGE) h = rheight;
  566. #ifdef _DEBUG
  567. ASSERT(x < 0xFFF0);
  568. ASSERT(y < 0xFFF0);
  569. ASSERT(w < 0xFFF0);
  570. ASSERT(h < 0xFFF0);
  571. #endif
  572. double thisratio = getRenderRatio();
  573. int different_ratio = (lastratio != thisratio);
  574. lastratio = thisratio;
  575. int noevent = (resizecount > 1 && w == rwidth && h == rheight);
  576. //ifc_window *dp = getDesktopParent();
  577. if (different_ratio == 1 && noevent == 1)
  578. {
  579. if (Wasabi::Std::Wnd::getTopmostChild(getOsWindowHandle()) != INVALIDOSWINDOWHANDLE)
  580. noevent = 0;
  581. invalidateWindowRegion();
  582. }
  583. RECT oldsize, newsize = Wasabi::Std::makeRect(x, y, w, h);
  584. if (hwnd != NULL)
  585. BaseWnd::getNonClientRect(&oldsize);
  586. else
  587. oldsize = newsize;
  588. setRSize(x, y, w, h);
  589. if (handleRatio() && renderRatioActive())
  590. {
  591. multRatio(&w, &h);
  592. if (getParent() != NULL)
  593. {
  594. multRatio(&x, &y);
  595. }
  596. }
  597. if (!noevent)
  598. {
  599. if (wantcb && isPostOnInit())
  600. {
  601. resizecount = MIN(5, ++resizecount);
  602. if (!isVirtual())
  603. invalidateWindowRegion();
  604. onResize();
  605. if (ensureWindowRegionValid())
  606. updateWindowRegion();
  607. }
  608. }
  609. if (getOsWindowHandle() != NULL)
  610. {
  611. RECT oldsizescaled;
  612. getWindowRect(&oldsizescaled);
  613. RECT newsizescaled = {x, y, x + w, y + h};
  614. if (MEMCMP(&newsizescaled, &oldsizescaled, sizeof(RECT)))
  615. {
  616. //CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, w, h,
  617. //CUT SWP_NOZORDER |
  618. //CUT SWP_NOACTIVATE |
  619. //CUT (!wantRedrawOnResize() ? SWP_NOCOPYBITS: 0) |
  620. //CUT (ncb ? SWP_NOCOPYBITS : 0) |
  621. //CUT ( nomove ? SWP_NOMOVE : 0) |
  622. //CUT ( noresize ? SWP_NOSIZE : 0) |
  623. //CUT 0);
  624. Wasabi::Std::Wnd::setWndPos( getOsWindowHandle(), NULL, x, y, w, h, TRUE, TRUE, !wantRedrawOnResize() || ncb, nomove, noresize );
  625. }
  626. //else
  627. //{
  628. // DebugStringW(L"BaseWnd::resize optimized\n");
  629. //}
  630. onAfterResize();
  631. if (ncb)
  632. invalidate();
  633. else
  634. {
  635. RECT r;
  636. if (hwnd != NULL)
  637. {
  638. if (newsize.left == oldsize.left && newsize.top == oldsize.top)
  639. {
  640. if (newsize.right > oldsize.right)
  641. {
  642. // growing in width
  643. r.left = oldsize.right;
  644. r.right = newsize.right;
  645. r.top = newsize.top;
  646. r.bottom = newsize.bottom;
  647. invalidateRect(&r);
  648. if (newsize.bottom > oldsize.bottom)
  649. {
  650. // growing in width & height
  651. r.left = oldsize.left;
  652. r.right = newsize.right;
  653. r.top = oldsize.bottom;
  654. r.bottom = newsize.bottom;
  655. invalidateRect(&r);
  656. }
  657. }
  658. else if (newsize.bottom > oldsize.bottom)
  659. {
  660. if (newsize.bottom > oldsize.bottom)
  661. {
  662. // growing in height
  663. r.left = oldsize.left;
  664. r.right = newsize.right;
  665. r.top = oldsize.bottom;
  666. r.bottom = newsize.bottom;
  667. invalidateRect(&r);
  668. }
  669. }
  670. }
  671. }
  672. }
  673. }
  674. inonresize = 0;
  675. }
  676. void BaseWnd::forcedOnResizeChain(ifc_window *w)
  677. {
  678. w->triggerEvent(TRIGGER_ONRESIZE);
  679. int n = w->getNumRootWndChildren();
  680. for (int i = 0;i < n;i++)
  681. {
  682. forcedOnResizeChain(w->enumRootWndChildren(i));
  683. }
  684. }
  685. int BaseWnd::forcedOnResize()
  686. {
  687. forcedOnResizeChain(this);
  688. return 1;
  689. }
  690. int BaseWnd::onResize()
  691. {
  692. if (!isVirtual() || (getRegionOp() != REGIONOP_NONE))
  693. invalidateWindowRegion();
  694. // you are not supposed to call onResize until after onInit has returned. If what you wanted was to generate
  695. // an onResize event to do some custom client coordinates recalculations (ie: to apply on your children)
  696. // then you don't need to do anything since onResize is going to be called after onInit() is done. If you still want to
  697. // trigger it because your code might be called by onInit and after onInit, use isPostOnInit() as a test.
  698. // if what you wanted was to signal a object that you just resized it, then you don't need to do anything beside
  699. // resize(...), it will generate the event on its own if the window is inited, and will defer to until after onInit
  700. // if it is not.
  701. // shortly put: do not call onResize before or inside onInit()
  702. // if you have any valid reason for doing that, i'd like to know about it so i can make it possible. -FG
  703. #ifdef _DEBUG
  704. if (!isPostOnInit())
  705. {
  706. //__asm int 3;
  707. ASSERTPR(isPostOnInit(), "do not call onResize before or inside onInit()");
  708. }
  709. #endif
  710. return FALSE;
  711. }
  712. void BaseWnd::resizeToClient(BaseWnd *wnd)
  713. {
  714. if (wnd != NULL)
  715. wnd->resize(&clientRect());
  716. }
  717. int BaseWnd::onPostedMove()
  718. {
  719. /*
  720. if (w2k_alpha && Wasabi::Std::Wnd::isDesktopAlphaAvailable() && !cloaked)
  721. {
  722. RECT r;
  723. getWindowRect(&r);
  724. Wasabi::Std::Wnd::moveLayeredWnd(hwnd, r.left, r.top);
  725. }*/
  726. return FALSE;
  727. }
  728. void BaseWnd::resize(RECT *r, int wantcb)
  729. {
  730. resize(r->left, r->top, r->right - r->left, r->bottom - r->top, wantcb);
  731. }
  732. void BaseWnd::move(int x, int y)
  733. {
  734. //DebugStringW( L"BaseWnd::move( x = %d, y = %d )\n", x, y );
  735. setRSize(x, y, rwidth, rheight);
  736. Wasabi::Std::Wnd::setWndPos( getOsWindowHandle(), NULL, x, y, 0, 0, TRUE, TRUE, ncb, FALSE, TRUE );
  737. //CUT if (!ncb)
  738. //CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_DEFERERASE);
  739. //CUT else
  740. //CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_DEFERERASE);
  741. }
  742. #ifdef EXPERIMENTAL_INDEPENDENT_AOT
  743. BOOL CALLBACK EnumOwnedTopMostWindows(HWND hwnd, LPARAM lParam)
  744. {
  745. enumownedstruct *st = (enumownedstruct *)lParam;
  746. if (hwnd != st->hthis && GetWindow(hwnd, GW_OWNER) == st->owner)
  747. {
  748. ifc_window *w = (ifc_window*)GetWindowLong(hwnd, GWL_USERDATA);
  749. if (w != NULL && w->getAlwaysOnTop())
  750. st->hlist->addItem(w);
  751. }
  752. return TRUE;
  753. }
  754. void BaseWnd::saveTopMosts()
  755. {
  756. HWND owner = GetWindow(getOsWindowHandle(), GW_OWNER);
  757. enumownedstruct st;
  758. ontoplist.removeAll();
  759. if (owner != NULL)
  760. {
  761. st.owner = owner;
  762. st.hlist = &ontoplist;
  763. st.hthis = getOsWindowHandle();
  764. EnumWindows(EnumOwnedTopMostWindows, (long)&st);
  765. }
  766. }
  767. void BaseWnd::restoreTopMosts()
  768. {
  769. HWND owner = GetWindow(getOsWindowHandle(), GW_OWNER);
  770. if (owner != NULL)
  771. {
  772. for (int i = 0;i < ontoplist.getNumItems();i++)
  773. {
  774. ontoplist.enumItem(i)->setAlwaysOnTop(1);
  775. }
  776. }
  777. }
  778. #endif
  779. void BaseWnd::bringToFront()
  780. {
  781. // when we set a window to the top of the zorder (not topmost), win32 finds the owner and removes any topmost flag its children may
  782. // have because it assumes we want this window over these, which we definitly don't. so we need to first go thru all the owner's children,
  783. // make a list of the ones with a topmost flag, set this window on top, and set the topmost flags back. yay
  784. ASSERT(!isVirtual());
  785. #ifdef EXPERIMENTAL_INDEPENDENT_AOT
  786. saveTopMosts();
  787. #endif
  788. //CUT SetWindowPos(getOsWindowHandle(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE|SWP_DEFERERASE|SWP_NOOWNERZORDER);
  789. Wasabi::Std::Wnd::bringToFront(getOsWindowHandle());
  790. #ifdef EXPERIMENTAL_INDEPENDENT_AOT
  791. restoreTopMosts();
  792. #endif
  793. }
  794. void BaseWnd::bringToBack()
  795. {
  796. ASSERT(!isVirtual());
  797. #ifdef EXPERIMENTAL_INDEPENDENT_AOT
  798. saveTopMosts();
  799. #endif
  800. //CUT SetWindowPos(getOsWindowHandle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE|SWP_DEFERERASE|SWP_NOOWNERZORDER);
  801. Wasabi::Std::Wnd::sendToBack(getOsWindowHandle());
  802. #ifdef EXPERIMENTAL_INDEPENDENT_AOT
  803. restoreTopMosts();
  804. #endif
  805. }
  806. void BaseWnd::setVisible(int show)
  807. {
  808. int visible = isVisible(1);
  809. if (!!visible == !!show) return ;
  810. invalidate();
  811. this_visible = !!show;
  812. /*if (!getParent() || getParent() == WASABI_API_WND->main_getRootWnd() && IsWindow(getOsWindowHandle())) {
  813. if (!show) {
  814. setLayeredWindow(0);
  815. if (setLayeredWindowAttributes)
  816. setLayeredWindowAttributes(hwnd, RGB(0,0,0), 255, LWA_ALPHA);
  817. } else {
  818. setLayeredWindow(w2k_alpha);
  819. }
  820. }*/
  821. if (!getParent() || getParent() == WASABI_API_WND->main_getRootWnd() || getParent()->isVisible())
  822. {
  823. onSetVisible(show);
  824. }
  825. }
  826. void BaseWnd::setCloaked(int cloak)
  827. {
  828. if (cloaked == cloak) return ;
  829. cloaked = cloak;
  830. if (isVirtual()) return ;
  831. if (cloaked)
  832. {
  833. //CUTif (IsWindowVisible(getOsWindowHandle()))
  834. //CUT ShowWindow(getOsWindowHandle(), SW_HIDE);
  835. if (Wasabi::Std::Wnd::isWndVisible(getOsWindowHandle()))
  836. Wasabi::Std::Wnd::hideWnd(getOsWindowHandle());
  837. }
  838. else
  839. {
  840. if (isVisible(1))
  841. //CUTShowWindow(getOsWindowHandle(), SW_NORMAL);
  842. Wasabi::Std::Wnd::showWnd(getOsWindowHandle());
  843. }
  844. }
  845. void BaseWnd::onSetVisible(int show)
  846. {
  847. /* for debug purposes - don't delete please
  848. #include "../../../studio/container.h"
  849. #include "../../../studio/layout.h"
  850. if (!show && getGuiObject() && STRCASEEQLSAFE(getGuiObject()->guiobject_getId(), "normal")) {
  851. Layout *l = (Layout *)getInterface(layoutGuid);
  852. if (l) {
  853. if (l->getParentContainer() && STRCASEEQLSAFE(l->getParentContainer()->getId(), "main")) {
  854. DebugString("Hiding main player\n");
  855. }
  856. }
  857. }*/
  858. if (!isVirtual())
  859. if (hwnd != NULL)
  860. if (!cloaked)
  861. {
  862. //CUT // SetWindowPos(getOsWindowHandle(),NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_SHOWWINDOW);
  863. //CUT ShowWindow(getOsWindowHandle(), show ? SW_SHOWNA : SW_HIDE);
  864. if (show)
  865. Wasabi::Std::Wnd::showWnd(getOsWindowHandle(), TRUE);
  866. else
  867. Wasabi::Std::Wnd::hideWnd(getOsWindowHandle());
  868. }
  869. /* if (!show)
  870. postDeferredCallback(0x7849);
  871. else {*/
  872. foreach(rootwndchildren)
  873. ifc_window *w = rootwndchildren.getfor();
  874. if (w && w->isVisible(1)) // check internal flag only
  875. w->onSetVisible(show);
  876. endfor;
  877. dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_SETVISIBLE, show);
  878. //}
  879. /* if (getDesktopParent() == this) {
  880. cascadeRepaint(0);
  881. }*/
  882. /*#ifdef WIN32 // os-specific non virtual child wnd support
  883. if (!isVirtual()) {
  884. HWND w = GetWindow(getOsWindowHandle(), GW_CHILD);
  885. while (w != NULL) {
  886. api_window *rootwnd = (api_window*)GetWindowLong(w, GWL_USERDATA);
  887. if (rootwnd && rootwnd != this)
  888. if (rootwnd->isInited())
  889. rootwnd->onSetVisible(show);
  890. w = GetWindow(w, GW_HWNDNEXT);
  891. }
  892. }
  893. #endif*/
  894. if (!isVirtual())
  895. {
  896. if (!show)
  897. {
  898. deferedInvalidate();
  899. delete virtualCanvas;
  900. virtualCanvas = NULL;
  901. }
  902. }
  903. invalidateWindowRegion();
  904. }
  905. void BaseWnd::setEnabled(int en)
  906. {
  907. int enabled = isEnabled(1);
  908. if (!!enabled == !!en) return ;
  909. invalidate();
  910. this_enabled = !!en;
  911. if (!getParent() || getParent() == WASABI_API_WND->main_getRootWnd() || getParent()->isEnabled())
  912. {
  913. onEnable(en);
  914. }
  915. }
  916. int BaseWnd::isEnabled(int within)
  917. {
  918. if (!isVirtual() && !getOsWindowHandle()) return 0;
  919. if (!this_enabled) return 0;
  920. if (within) return this_enabled; // whatever, local
  921. if (isVirtual()) // virtual, global
  922. if (getParent())
  923. return getParent()->isEnabled();
  924. else
  925. return 0;
  926. // non virtual, global
  927. //CUT if (GetWindowLong(getOsWindowHandle(), GWL_STYLE) & WS_POPUP) return this_enabled;
  928. if (Wasabi::Std::Wnd::isPopup(getOsWindowHandle())) return this_enabled;
  929. //CUT if (!Wasabi::Std::Wnd::isValidWnd(GetParent(gethWnd()))) return this_enabled;
  930. if (!Wasabi::Std::Wnd::isValidWnd(Wasabi::Std::Wnd::getParent(getOsWindowHandle()))) return this_enabled;
  931. if (getParent()) return getParent()->isEnabled(); // not a popup, check its parent or fail
  932. return this_enabled;
  933. }
  934. int BaseWnd::onEnable(int en)
  935. {
  936. if (!isVirtual())
  937. {
  938. if (hwnd != NULL)
  939. //CUT EnableWindow(getOsWindowHandle(), en);
  940. Wasabi::Std::Wnd::setEnabled(getOsWindowHandle(), en);
  941. foreach(rootwndchildren)
  942. ifc_window *w = rootwndchildren.getfor();
  943. if (w->isEnabled(1)) // check internal flag only
  944. w->onEnable(en);
  945. endfor;
  946. }
  947. return 1;
  948. }
  949. void BaseWnd::setFocus()
  950. {
  951. if (curVirtualChildFocus != NULL)
  952. {
  953. curVirtualChildFocus->onKillFocus();
  954. curVirtualChildFocus = NULL;
  955. }
  956. onSetRootFocus(this);
  957. //CUT SetFocus(getOsWindowHandle());
  958. Wasabi::Std::Wnd::setFocus(getOsWindowHandle());
  959. }
  960. void BaseWnd::setFocusOnClick(int f)
  961. {
  962. focus_on_click = f;
  963. }
  964. api_region *BaseWnd::getDeferedInvalidRgn()
  965. {
  966. return deferedInvalidRgn;
  967. }
  968. void BaseWnd::deferedInvalidate()
  969. {
  970. if (!hasVirtualChildren() || !isVisible(1)) return ;
  971. RECT r = Wasabi::Std::makeRect(0, 0, 0, 0);
  972. getNonClientRect(&r);
  973. deferedInvalidateRect(&r);
  974. }
  975. void BaseWnd::deferedInvalidateRect(RECT *r)
  976. {
  977. if (!hasVirtualChildren()) return ;
  978. RegionI h(r);
  979. deferedInvalidateRgn(&h);
  980. }
  981. void BaseWnd::deferedInvalidateRgn(api_region *h)
  982. {
  983. if (!hasVirtualChildren()) return ;
  984. if (!deferedInvalidRgn)
  985. {
  986. deferedInvalidRgn = new RegionI();
  987. }
  988. deferedInvalidRgn->addRegion(h);
  989. }
  990. void BaseWnd::deferedValidate()
  991. {
  992. if (!hasVirtualChildren() || !isVisible(1)) return ;
  993. RECT r = Wasabi::Std::makeRect(0,0,0,0);
  994. getNonClientRect(&r);
  995. deferedValidateRect(&r);
  996. }
  997. void BaseWnd::deferedValidateRect(RECT *r)
  998. {
  999. if (!hasVirtualChildren()) return ;
  1000. RegionI h(r);
  1001. deferedValidateRgn(&h);
  1002. }
  1003. void BaseWnd::deferedValidateRgn(api_region *h)
  1004. {
  1005. if (!hasVirtualChildren()) return ;
  1006. if (!deferedInvalidRgn) return ;
  1007. deferedInvalidRgn->subtractRgn(h);
  1008. }
  1009. int BaseWnd::hasVirtualChildren()
  1010. {
  1011. return 1; //virtualChildren.getNumItems() > 0;
  1012. }
  1013. void BaseWnd::invalidate()
  1014. {
  1015. invalidateFrom(this);
  1016. }
  1017. void BaseWnd::invalidateFrom(ifc_window *who)
  1018. {
  1019. if (hasVirtualChildren()) deferedInvalidate();
  1020. //CUT if (hwnd != NULL && isVisible(1)) InvalidateRect(getOsWindowHandle(), NULL, FALSE);
  1021. if (hwnd != NULL && isVisible(1))
  1022. Wasabi::Std::Wnd::invalidateRect(getOsWindowHandle());
  1023. }
  1024. void BaseWnd::invalidateRectFrom(RECT *r, ifc_window *who)
  1025. {
  1026. if (hasVirtualChildren()) deferedInvalidateRect(r);
  1027. RegionI rg(r);
  1028. invalidateRgnFrom(&rg, who);
  1029. }
  1030. void BaseWnd::invalidateRgn(api_region *r)
  1031. {
  1032. invalidateRgnFrom(r, this);
  1033. }
  1034. void BaseWnd::invalidateRect(RECT *r)
  1035. {
  1036. invalidateRectFrom(r, this);
  1037. }
  1038. void BaseWnd::invalidateRgnFrom(api_region *r, ifc_window *who)
  1039. {
  1040. if (parentWnd) parentWnd->onChildInvalidate(r, who);
  1041. PaintCallbackInfoI pc(NULL, r);
  1042. dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_ONINVALIDATE, 0, &pc);
  1043. if (hwnd != NULL && isVisible(1))
  1044. {
  1045. if (hasVirtualChildren())
  1046. {
  1047. api_region *_r = r->clone();
  1048. int j = virtualChildren.searchItem(who);
  1049. for (int i = 0;i < virtualChildren.getNumItems();i++)
  1050. {
  1051. ifc_window *w = virtualChildren[i];
  1052. if (w != who && w->wantSiblingInvalidations())
  1053. w->onSiblingInvalidateRgn(_r, who, j, i);
  1054. }
  1055. deferedInvalidateRgn(_r);
  1056. physicalInvalidateRgn(_r);
  1057. r->disposeClone(_r);
  1058. }
  1059. else
  1060. {
  1061. deferedInvalidateRgn(r);
  1062. physicalInvalidateRgn(r);
  1063. }
  1064. }
  1065. }
  1066. void BaseWnd::physicalInvalidateRgn(api_region *r)
  1067. {
  1068. if (hwnd != NULL && isVisible(1))
  1069. {
  1070. if (renderRatioActive())
  1071. {
  1072. api_region *clone = r->clone();
  1073. clone->scale(getRenderRatio(), getRenderRatio(), TRUE);
  1074. //CUT InvalidateRgn(getOsWindowHandle(), clone->getOSHandle(), FALSE);
  1075. Wasabi::Std::Wnd::invalidateRegion(getOsWindowHandle(), clone->getOSHandle());
  1076. r->disposeClone(clone);
  1077. }
  1078. else
  1079. //CUT InvalidateRgn(getOsWindowHandle(), r->getOSHandle(), FALSE);
  1080. Wasabi::Std::Wnd::invalidateRegion(getOsWindowHandle(), r->getOSHandle());
  1081. }
  1082. }
  1083. void BaseWnd::validate()
  1084. {
  1085. //CUT if (hwnd != NULL) ValidateRect(getOsWindowHandle(), NULL);
  1086. if (hwnd != NULL)
  1087. Wasabi::Std::Wnd::validateRect(getOsWindowHandle());
  1088. }
  1089. void BaseWnd::validateRect(RECT *r)
  1090. {
  1091. if (hwnd != NULL)
  1092. {
  1093. if (renderRatioActive())
  1094. {
  1095. RECT r2 = *r;
  1096. Wasabi::Std::scaleRect(&r2, getRenderRatio());
  1097. //CUT ValidateRect(getOsWindowHandle(), &r2);
  1098. Wasabi::Std::Wnd::validateRect(getOsWindowHandle(), &r2);
  1099. }
  1100. else
  1101. //CUT ValidateRect(getOsWindowHandle(), r);
  1102. Wasabi::Std::Wnd::validateRect(getOsWindowHandle(), r);
  1103. }
  1104. }
  1105. void BaseWnd::validateRgn(api_region *reg)
  1106. {
  1107. if (hwnd != NULL)
  1108. {
  1109. if (renderRatioActive())
  1110. {
  1111. api_region *clone = reg->clone();
  1112. clone->scale(getRenderRatio(), getRenderRatio(), TRUE);
  1113. //CUT ValidateRgn(getOsWindowHandle(), clone->getOSHandle());
  1114. Wasabi::Std::Wnd::validateRegion(getOsWindowHandle(), clone->getOSHandle());
  1115. reg->disposeClone(clone);
  1116. }
  1117. else
  1118. //CUT ValidateRgn(getOsWindowHandle(), reg->getOSHandle());
  1119. Wasabi::Std::Wnd::validateRegion(getOsWindowHandle(), reg->getOSHandle());
  1120. }
  1121. }
  1122. void BaseWnd::repaint()
  1123. {
  1124. /* if (hasVirtualChildren()) {
  1125. api_region *h = new api_region();
  1126. int s = GetUpdateRgn(getOsWindowHandle(), h->getHRGN(), FALSE);
  1127. if (s != NULLREGION && s != ERROR) {
  1128. virtualDrawRgn(h);
  1129. }
  1130. delete h;
  1131. }*/
  1132. //CUTif (hwnd != NULL) UpdateWindow(getOsWindowHandle());
  1133. if (hwnd != NULL)
  1134. Wasabi::Std::Wnd::update(getOsWindowHandle());
  1135. }
  1136. void BaseWnd::getClientRect(RECT *rect)
  1137. {
  1138. /* rect->left = rx;
  1139. rect->right = rx + rwidth;
  1140. rect->top = ry;
  1141. rect->bottom = ry + rheight;*/
  1142. //ASSERT(hwnd != NULL);
  1143. if (!Wasabi::Std::Wnd::isValidWnd(hwnd))
  1144. {
  1145. MEMSET(rect, 0, sizeof(RECT));
  1146. return ;
  1147. }
  1148. GetClientRect(getOsWindowHandle(), rect);
  1149. ////Wasabi::Std::Wnd::getClientRect(getOsWindowHandle(), rect);
  1150. rect->right = rect->left + rwidth;
  1151. rect->bottom = rect->top + rheight;
  1152. }
  1153. RECT BaseWnd::clientRect()
  1154. {
  1155. RECT ret;
  1156. getClientRect(&ret);
  1157. return ret;
  1158. }
  1159. void BaseWnd::getNonClientRect(RECT *rect)
  1160. {
  1161. // ASSERT(hwnd != NULL);
  1162. if (!hwnd)
  1163. getClientRect(rect);
  1164. else
  1165. {
  1166. Wasabi::Std::Wnd::getClientRect(getOsWindowHandle(), rect);
  1167. if (getRenderRatio() != 1.0)
  1168. {
  1169. rect->right = rect->left + rwidth;
  1170. rect->bottom = rect->left + rheight;
  1171. }
  1172. }
  1173. /* rect->left = rx;
  1174. rect->right = rx + rwidth;
  1175. rect->top = ry;
  1176. rect->bottom = ry + rheight;*/
  1177. }
  1178. RECT BaseWnd::nonClientRect()
  1179. {
  1180. RECT ret;
  1181. getNonClientRect(&ret);
  1182. return ret;
  1183. }
  1184. void BaseWnd::getWindowRect(RECT *rect)
  1185. {
  1186. //CUT#ifdef WIN32
  1187. //CUT ASSERT(hwnd != NULL);
  1188. //CUT GetWindowRect(getOsWindowHandle(), rect);
  1189. //CUT#else
  1190. //CUT#error port me
  1191. //CUT#endif
  1192. Wasabi::Std::Wnd::getWindowRect(getOsWindowHandle(), rect);
  1193. }
  1194. // get position relative to parent (same coordinate system for basewnd & virtualwnd)
  1195. void BaseWnd::getPosition(POINT *pt)
  1196. {
  1197. pt->x = rx;
  1198. pt->y = ry;
  1199. }
  1200. void *BaseWnd::dependent_getInterface(const GUID *classguid)
  1201. {
  1202. HANDLEGETINTERFACE(ifc_window);
  1203. //CUT HANDLEGETINTERFACE(api_window);
  1204. return NULL;
  1205. }
  1206. RECT BaseWnd::windowRect()
  1207. {
  1208. RECT ret;
  1209. getWindowRect(&ret);
  1210. return ret;
  1211. }
  1212. void BaseWnd::clientToScreen(int *x, int *y)
  1213. {
  1214. int _x = x ? *x : 0;
  1215. int _y = y ? *y : 0;
  1216. if (renderRatioActive())
  1217. {
  1218. _x = (int)((double)_x * getRenderRatio());
  1219. _y = (int)((double)_y * getRenderRatio());
  1220. }
  1221. Wasabi::Std::Wnd::clientToScreen(getOsWindowHandle(), &_x, &_y);
  1222. if (x) *x = _x;
  1223. if (y) *y = _y;
  1224. }
  1225. void BaseWnd::clientToScreen(RECT *r)
  1226. {
  1227. clientToScreen((int*)&r->left, (int*)&r->top);
  1228. clientToScreen((int*)&r->right, (int*)&r->bottom);
  1229. }
  1230. void BaseWnd::clientToScreen(POINT *p)
  1231. {
  1232. clientToScreen((int *)&p->x, (int *)&p->y);
  1233. }
  1234. void BaseWnd::screenToClient(int *x, int *y)
  1235. {
  1236. //CUT POINT p;
  1237. int _x = x ? *x : 0;
  1238. int _y = y ? *y : 0;
  1239. //CUT ScreenToClient(getOsWindowHandle(), &p);
  1240. Wasabi::Std::Wnd::screenToClient(getOsWindowHandle(), &_x, &_y);
  1241. if (renderRatioActive())
  1242. {
  1243. _x = (int)((double)_x / getRenderRatio());
  1244. _y = (int)((double)_y / getRenderRatio());
  1245. }
  1246. if (x) *x = _x;
  1247. if (y) *y = _y;
  1248. }
  1249. void BaseWnd::screenToClient(RECT *r)
  1250. {
  1251. screenToClient((int*)&r->left, (int*)&r->top);
  1252. screenToClient((int*)&r->right, (int*)&r->bottom);
  1253. }
  1254. void BaseWnd::screenToClient(POINT *p)
  1255. {
  1256. screenToClient((int *)&p->x, (int *)&p->y);
  1257. }
  1258. void BaseWnd::setParent(ifc_window *newparent)
  1259. {
  1260. ASSERTPR(newparent != NULL, "quit being a weeny");
  1261. ASSERTPR(parentWnd == NULL || newparent == parentWnd, "can't reset parent");
  1262. parentWnd = newparent;
  1263. if (isInited())
  1264. {
  1265. OSWINDOWHANDLE w1 = getOsWindowHandle();
  1266. OSWINDOWHANDLE w2 = newparent->getOsWindowHandle();
  1267. if (w1 != w2)
  1268. //CUT SetParent(w1, w2);
  1269. Wasabi::Std::Wnd::setParent(w1, w2);
  1270. }
  1271. }
  1272. //FUCKO
  1273. int BaseWnd::reparent(ifc_window *newparent)
  1274. {
  1275. #ifdef _WIN32
  1276. if (!isVirtual())
  1277. {
  1278. if (isInited())
  1279. {
  1280. ifc_window *old = getParent();
  1281. if (!old && newparent)
  1282. {
  1283. ::SetParent(getOsWindowHandle(), newparent->getOsWindowHandle());
  1284. SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) & ~WS_POPUP);
  1285. SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) | WS_CHILD);
  1286. }
  1287. else if (old && !newparent)
  1288. {
  1289. SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) & ~WS_CHILD);
  1290. SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) | WS_POPUP);
  1291. ::SetParent(getOsWindowHandle(), NULL);
  1292. }
  1293. else
  1294. {
  1295. ::SetParent(getOsWindowHandle(), newparent ? newparent->getOsWindowHandle() : NULL);
  1296. }
  1297. }
  1298. }
  1299. parentWnd = newparent;
  1300. onSetParent(newparent);
  1301. #ifdef WASABI_ON_REPARENT
  1302. WASABI_ON_REPARENT(getOsWindowHandle());
  1303. #endif
  1304. #else
  1305. #warning port me
  1306. #endif
  1307. return 1;
  1308. }
  1309. ifc_window *BaseWnd::getParent()
  1310. {
  1311. return parentWnd;
  1312. }
  1313. ifc_window *BaseWnd::getRootParent()
  1314. {
  1315. return this;
  1316. }
  1317. //PORTME
  1318. ifc_window *BaseWnd::getDesktopParent()
  1319. {
  1320. #ifdef _WIN32
  1321. // NONPORTABLE
  1322. HWND w = getOsWindowHandle();
  1323. HWND last = w;
  1324. if (!w) return NULL;
  1325. HWND p = w;
  1326. wchar_t cn[256] = {0};
  1327. while (p && !(GetWindowLong(p, GWL_STYLE) & WS_POPUP))
  1328. {
  1329. GetClassNameW(p, cn, 255); cn[255] = 0;
  1330. if (!wcscmp(cn, BASEWNDCLASSNAME))
  1331. last = p;
  1332. p = GetParent(p);
  1333. }
  1334. if (p)
  1335. {
  1336. GetClassNameW(p, cn, 255); cn[255] = 0;
  1337. if (!wcscmp(cn, BASEWNDCLASSNAME))
  1338. return (ifc_window*)GetWindowLongPtrW(p, GWLP_USERDATA);
  1339. else if (last != NULL)
  1340. return (ifc_window*)GetWindowLongPtrW(last, GWLP_USERDATA);
  1341. }
  1342. #else
  1343. #warning port me
  1344. #endif
  1345. return NULL;
  1346. }
  1347. int BaseWnd::notifyParent(int msg, int param1, int param2)
  1348. {
  1349. ifc_window *notifywnd = getNotifyWindow();
  1350. if (getParent() == NULL && notifywnd == NULL) return 0;
  1351. if (notifywnd == NULL) notifywnd = getParent();
  1352. ASSERT(notifywnd != NULL);
  1353. return notifywnd->childNotify(this, msg, param1, param2);
  1354. }
  1355. int BaseWnd::passNotifyUp(ifc_window *child, int msg, int param1, int param2)
  1356. {
  1357. // Same code as above to decide for whom we should notify.
  1358. ifc_window *notifywnd = getNotifyWindow();
  1359. if (getParent() == NULL && notifywnd == NULL) return 0;
  1360. if (notifywnd == NULL) notifywnd = getParent();
  1361. ASSERT(notifywnd != NULL);
  1362. // And here we just change the api_window pointer.
  1363. return notifywnd->childNotify(child, msg, param1, param2);
  1364. }
  1365. void BaseWnd::setNotifyId(int id)
  1366. {
  1367. notifyid = id;
  1368. }
  1369. int BaseWnd::getNotifyId()
  1370. {
  1371. return notifyid;
  1372. }
  1373. DragInterface *BaseWnd::getDragInterface()
  1374. {
  1375. return this;
  1376. }
  1377. ifc_window *BaseWnd::rootWndFromPoint(POINT *pt)
  1378. {
  1379. // pt is in client coordinates
  1380. int x = (int)((double)pt->x / getRenderRatio());
  1381. int y = (int)((double)pt->y / getRenderRatio());
  1382. ifc_window *ret = findRootWndChild(x, y);
  1383. if (ret == NULL) ret = this;
  1384. return ret;
  1385. }
  1386. int BaseWnd::rootwnd_paintTree(ifc_canvas *canvas, api_region *r)
  1387. {
  1388. BaseCloneCanvas c(canvas);
  1389. return paintTree(&c, r);
  1390. }
  1391. const wchar_t *BaseWnd::getRootWndName()
  1392. {
  1393. return getName();
  1394. }
  1395. const wchar_t *BaseWnd::getId()
  1396. {
  1397. return NULL;
  1398. }
  1399. void BaseWnd::setSkinId(int id)
  1400. {
  1401. skin_id = id;
  1402. }
  1403. void BaseWnd::setPreferences(int what, int v)
  1404. {
  1405. switch (what)
  1406. {
  1407. case MAXIMUM_W: maximum_w = v; break;
  1408. case MAXIMUM_H: maximum_h = v; break;
  1409. case MINIMUM_W: minimum_w = v; break;
  1410. case MINIMUM_H: minimum_h = v; break;
  1411. case SUGGESTED_W: suggested_w = v; break;
  1412. case SUGGESTED_H: suggested_h = v; break;
  1413. }
  1414. }
  1415. int BaseWnd::getPreferences(int what)
  1416. {
  1417. if (getNumMinMaxEnforcers() > 0)
  1418. {
  1419. int min_x = minimum_w, min_y = minimum_h, max_x = maximum_w, max_y = maximum_h, sug_x = suggested_w, sug_y = suggested_h;
  1420. for (int i = 0;i < getNumMinMaxEnforcers();i++)
  1421. {
  1422. int tmin_x = MINIMUM_W, tmin_y = MINIMUM_H, tmax_x = MAXIMUM_W, tmax_y = MAXIMUM_H, tsug_x = SUGGESTED_W, tsug_y = SUGGESTED_H;
  1423. ifc_window *w = enumMinMaxEnforcer(i);
  1424. if (w)
  1425. {
  1426. tmin_x = w->getPreferences(MINIMUM_W);
  1427. tmin_y = w->getPreferences(MINIMUM_H);
  1428. tmax_x = w->getPreferences(MAXIMUM_W);
  1429. tmax_y = w->getPreferences(MAXIMUM_H);
  1430. tsug_x = w->getPreferences(SUGGESTED_W);
  1431. tsug_y = w->getPreferences(SUGGESTED_H);
  1432. if (tmin_x == -1) tmin_x = AUTOWH;
  1433. if (tmin_y == -1) tmin_y = AUTOWH;
  1434. if (tmax_x == -1) tmax_x = AUTOWH;
  1435. if (tmax_y == -1) tmax_y = AUTOWH;
  1436. if (tsug_x == -1) tsug_x = AUTOWH;
  1437. if (tsug_y == -1) tsug_y = AUTOWH;
  1438. #ifndef DISABLE_SYSFONTSCALE
  1439. TextInfoCanvas textInfoCanvas(this);
  1440. double fontScale = textInfoCanvas.getSystemFontScale();
  1441. GuiObject *o = static_cast<GuiObject *>(getInterface(guiObjectGuid));
  1442. if (o != NULL)
  1443. {
  1444. if (o->guiobject_getAutoSysMetricsW())
  1445. {
  1446. if (tmin_x != AUTOWH) tmin_x = (int)((float)tmin_x * fontScale);
  1447. if (tmax_x != AUTOWH) tmax_x = (int)((float)tmax_x * fontScale);
  1448. if (tsug_x != AUTOWH) tsug_x = (int)((float)tsug_x * fontScale);
  1449. }
  1450. if (o->guiobject_getAutoSysMetricsH())
  1451. {
  1452. if (tmin_y != AUTOWH) tmin_y = (int)((float)tmin_y * fontScale);
  1453. if (tmax_y != AUTOWH) tmax_y = (int)((float)tmax_y * fontScale);
  1454. if (tsug_y != AUTOWH) tsug_y = (int)((float)tsug_y * fontScale);
  1455. }
  1456. }
  1457. #endif
  1458. RECT cor;
  1459. w->getNonClientRect(&cor);
  1460. RECT wr;
  1461. getNonClientRect(&wr);
  1462. int xdif = (wr.right - wr.left) - (cor.right - cor.left);
  1463. int ydif = (wr.bottom - wr.top) - (cor.bottom - cor.top);
  1464. if (tmin_x != AUTOWH) tmin_x += xdif;
  1465. if (tmin_y != AUTOWH) tmin_y += ydif;
  1466. if (tmax_x != AUTOWH) tmax_x += xdif;
  1467. if (tmax_y != AUTOWH) tmax_y += ydif;
  1468. if (tsug_x != AUTOWH) tsug_x += xdif;
  1469. if (tsug_y != AUTOWH) tsug_y += ydif;
  1470. }
  1471. if (min_x != AUTOWH) min_x = (tmin_x != AUTOWH) ? MAX(min_x, tmin_x) : min_x; else min_x = tmin_x;
  1472. if (max_x != AUTOWH) max_x = (tmax_x != AUTOWH) ? MAX(max_x, tmax_x) : max_x; else max_x = tmax_x;
  1473. if (min_y != AUTOWH) min_y = (tmin_y != AUTOWH) ? MAX(min_y, tmin_y) : min_y; else min_y = tmin_y;
  1474. if (max_y != AUTOWH) max_y = (tmax_y != AUTOWH) ? MAX(max_y, tmax_y) : max_y; else max_y = tmax_y;
  1475. if (sug_x != AUTOWH) sug_x = (tsug_x != AUTOWH) ? MAX(sug_x, tsug_x) : sug_x; else sug_x = tsug_x;
  1476. if (sug_y != AUTOWH) sug_y = (tsug_y != AUTOWH) ? MAX(sug_y, tsug_y) : sug_y; else sug_y = tsug_y;
  1477. }
  1478. if (min_x != AUTOWH && min_x == max_x) sug_x = min_x;
  1479. if (min_y != AUTOWH && min_y == max_y) sug_y = min_y;
  1480. switch (what)
  1481. {
  1482. case MINIMUM_W: return min_x;
  1483. case MINIMUM_H: return min_y;
  1484. case MAXIMUM_W: return max_x;
  1485. case MAXIMUM_H: return max_y;
  1486. case SUGGESTED_W: return sug_x;
  1487. case SUGGESTED_H: return sug_y;
  1488. }
  1489. }
  1490. switch (what)
  1491. {
  1492. case SUGGESTED_W: return suggested_w;
  1493. case SUGGESTED_H: return suggested_h;
  1494. case MAXIMUM_W: return maximum_w;
  1495. case MAXIMUM_H: return maximum_h;
  1496. case MINIMUM_W: return minimum_w;
  1497. case MINIMUM_H: return minimum_h;
  1498. }
  1499. return AUTOWH;
  1500. }
  1501. void BaseWnd::setStartHidden(int wtf)
  1502. {
  1503. start_hidden = wtf;
  1504. }
  1505. //PORTME
  1506. #ifdef _WIN32
  1507. #define EQUAL_CLSNAME(__name1, __name2)\
  1508. (CSTR_EQUAL == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),\
  1509. NORM_IGNORECASE, (__name1), -1, (__name2), -1))
  1510. static BOOL BaseWnd_IsFrameWindow(HWND hwnd)
  1511. {
  1512. WCHAR szClass[64] = {0};
  1513. if (NULL == hwnd || !GetClassNameW(hwnd, szClass, ARRAYSIZE(szClass)))
  1514. return FALSE;
  1515. return EQUAL_CLSNAME(szClass, L"Winamp v1.x") ||
  1516. EQUAL_CLSNAME(szClass, L"BaseWindow_RootWnd");
  1517. }
  1518. LRESULT BaseWnd::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1519. {
  1520. if (!isDestroying()) switch (uMsg)
  1521. {
  1522. case WM_DEFER_CALLBACK:
  1523. timerclient_onDeferredCallback(wParam, lParam);
  1524. break;
  1525. case WM_SYSCOMMAND:
  1526. {
  1527. if ((wParam & 0xfff0) == SC_SCREENSAVE || (wParam & 0xfff0) == SC_MONITORPOWER)
  1528. {
  1529. ifc_window *main = WASABI_API_WND->main_getRootWnd();
  1530. if (main && main != this)
  1531. return SendMessageW(main->gethWnd(), uMsg, wParam, lParam);
  1532. }
  1533. break;
  1534. }
  1535. //CUT case WM_CREATE:
  1536. //CUT hwnd = hWnd;
  1537. //CUT break;
  1538. //CUT case WM_CLOSE:
  1539. //CUT return 0;
  1540. case WM_PAINT:
  1541. {
  1542. if (inonresize && !wantRedrawOnResize()) return 1;
  1543. ASSERT(hwnd != NULL);
  1544. if (!isVisible(1) || IsIconic(hWnd)) break;
  1545. RECT r;
  1546. if (GetUpdateRect(hWnd, &r, FALSE))
  1547. {
  1548. if (virtualOnPaint())
  1549. {
  1550. return 0;
  1551. }
  1552. }
  1553. }
  1554. break;
  1555. case WM_PRINTCLIENT:
  1556. {
  1557. bool old_cloaked = (!!cloaked);
  1558. cloaked = true;
  1559. DCCanvas dc((HDC)wParam, this);
  1560. paint(&dc, 0);
  1561. cloaked = old_cloaked;
  1562. if (lParam & PRF_CHILDREN)
  1563. {
  1564. RECT wnd_size;
  1565. GetWindowRect(hwnd, &wnd_size);
  1566. HWND child = GetWindow(hwnd, GW_CHILD);
  1567. while (child != NULL)
  1568. {
  1569. if (GetWindowLongPtrW(child, GWL_STYLE) & WS_VISIBLE)
  1570. {
  1571. RECT child_size;
  1572. GetWindowRect(child, &child_size);
  1573. if (child_size.right && child_size.bottom)
  1574. {
  1575. BltCanvas bitmap(child_size.right, child_size.bottom, child);;
  1576. SendMessageW(child, WM_PRINT, (WPARAM)bitmap.getHDC(), PRF_CHILDREN | PRF_CLIENT | PRF_NONCLIENT/*| PRF_OWNED*/);
  1577. //bitmap->makeAlpha(255);
  1578. //set alpha to 255
  1579. int w, h;
  1580. bitmap.getDim(&w, &h, NULL);
  1581. ARGB32 *m_pBits = (ARGB32 *)bitmap.getBits();
  1582. int nwords = w*h;
  1583. for (; nwords > 0; nwords--, m_pBits++)
  1584. {
  1585. unsigned char *pixel = (unsigned char *)m_pBits;
  1586. pixel[3] = 255; // alpha
  1587. }
  1588. POINT offset;
  1589. offset.x = child_size.left - wnd_size.left;
  1590. offset.y = child_size.top - wnd_size.top;
  1591. //BLENDFUNCTION blendFn;
  1592. //blendFn.BlendOp = AC_SRC_OVER;
  1593. //blendFn.BlendFlags = 0;
  1594. //blendFn.SourceConstantAlpha = 255;
  1595. //blendFn.AlphaFormat = 0;
  1596. //AlphaBlend((HDC)wParam, offset.x, offset.y, child_size.right-child_size.left, child_size.bottom-child_size.top,
  1597. // bitmap->getHDC(), 0, 0, child_size.right-child_size.left, child_size.bottom-child_size.top, blendFn);
  1598. StretchBlt((HDC)wParam, offset.x, offset.y, child_size.right-child_size.left, child_size.bottom-child_size.top,
  1599. bitmap.getHDC(), 0, 0, child_size.right-child_size.left, child_size.bottom-child_size.top, SRCCOPY);
  1600. }
  1601. }
  1602. child = GetWindow(child, GW_HWNDNEXT);
  1603. }
  1604. }
  1605. }
  1606. return 0;
  1607. //CUT case WM_NCPAINT: return 0;
  1608. //CUT case WM_SYNCPAINT: return 0;
  1609. case WM_SETCURSOR:
  1610. if (checkModal()) return TRUE;
  1611. if (hWnd == (HWND)wParam)
  1612. {
  1613. DWORD windowStyle = (DWORD)GetWindowLongPtrW(hWnd, GWL_STYLE);
  1614. switch(HIWORD(lParam))
  1615. {
  1616. case WM_LBUTTONDOWN:
  1617. case WM_RBUTTONDOWN:
  1618. case WM_MBUTTONDOWN:
  1619. case 0x020B/*WM_XBUTTONDOWN*/:
  1620. DisabledWindow_OnMouseClick(hWnd);
  1621. break;
  1622. }
  1623. int ct = BASEWND_CURSOR_POINTER;
  1624. int _x, _y;
  1625. Wasabi::Std::getMousePos(&_x, &_y);
  1626. screenToClient(&_x, &_y);
  1627. OSCURSORHANDLE c = NULL;
  1628. if (0 == (WS_DISABLED & windowStyle))
  1629. {
  1630. if (!handleVirtualChildMsg(WM_SETCURSOR, _x, _y, &ct, &c))
  1631. {
  1632. ct = getCursorType(_x, _y);
  1633. }
  1634. }
  1635. wchar_t *wincursor = NULL;
  1636. switch (ct)
  1637. {
  1638. case BASEWND_CURSOR_USERSET:
  1639. if (c == NULL)
  1640. c = getCustomCursor(_x, _y);
  1641. if (c != NULL)
  1642. {
  1643. SetCursor(c);
  1644. return TRUE;
  1645. }
  1646. else wincursor = IDC_ARROW; // Ensure to have at least a cursor
  1647. break;
  1648. case BASEWND_CURSOR_POINTER:
  1649. wincursor = IDC_ARROW;
  1650. break;
  1651. case BASEWND_CURSOR_NORTHSOUTH:
  1652. wincursor = IDC_SIZENS;
  1653. break;
  1654. case BASEWND_CURSOR_EASTWEST:
  1655. wincursor = IDC_SIZEWE;
  1656. break;
  1657. case BASEWND_CURSOR_NORTHWEST_SOUTHEAST:
  1658. wincursor = IDC_SIZENWSE;
  1659. break;
  1660. case BASEWND_CURSOR_NORTHEAST_SOUTHWEST:
  1661. wincursor = IDC_SIZENESW;
  1662. break;
  1663. case BASEWND_CURSOR_4WAY:
  1664. wincursor = IDC_SIZEALL;
  1665. break;
  1666. case BASEWND_CURSOR_EDIT:
  1667. wincursor = IDC_IBEAM;
  1668. break;
  1669. default:
  1670. wincursor = IDC_ARROW;
  1671. break;
  1672. }
  1673. if (wincursor != NULL)
  1674. {
  1675. SetCursor(LoadCursor(NULL, wincursor));
  1676. return TRUE;
  1677. }
  1678. }
  1679. return FALSE;
  1680. case WM_TIMER:
  1681. timerCallback((int)wParam);
  1682. return 0;
  1683. case WM_GETOBJECT:
  1684. if (lParam == OBJID_CLIENT)
  1685. {
  1686. Accessible *acc = getAccessibleObject();
  1687. if (acc != NULL)
  1688. {
  1689. LRESULT lAcc = acc->getOSHandle((int)wParam);
  1690. return lAcc;
  1691. }
  1692. }
  1693. break; // Fall through to DefWindowProc
  1694. case WM_SETFOCUS:
  1695. if (!focusEventsEnabled) break;
  1696. if (isInited())
  1697. {
  1698. if (rootfocus != NULL && rootfocus != this)
  1699. {
  1700. if (rootfocus != curVirtualChildFocus)
  1701. rootfocus->setFocus();
  1702. break;
  1703. }
  1704. else
  1705. {
  1706. if (wantFocus())
  1707. {
  1708. onGetFocus();
  1709. break;
  1710. }
  1711. else
  1712. {
  1713. ifc_window *w = getTab(TAB_GETFIRST);
  1714. if (w != NULL)
  1715. {
  1716. w->setFocus();
  1717. }
  1718. }
  1719. }
  1720. }
  1721. break;
  1722. case WM_KILLFOCUS:
  1723. {
  1724. ifc_window *rp = getRootParent();
  1725. if (!WASABI_API_WND->rootwndIsValid(rp) || !Wasabi::Std::Wnd::isValidWnd(rp->getOsWindowHandle())) break;
  1726. if (!focusEventsEnabled) break;
  1727. #ifdef WASABI_COMPILE_WND
  1728. if (WASABI_API_WND) WASABI_API_WND->forwardOnKillFocus(); // resets the keyboard active keys buffer
  1729. #endif
  1730. if (!WASABI_API_WND->rootwndIsValid(curVirtualChildFocus)) curVirtualChildFocus = NULL;
  1731. if (curVirtualChildFocus)
  1732. {
  1733. curVirtualChildFocus->onKillFocus();
  1734. curVirtualChildFocus = NULL;
  1735. }
  1736. else
  1737. if (hasfocus) onKillFocus();
  1738. break;
  1739. }
  1740. // dragging and dropping
  1741. case WM_LBUTTONDOWN:
  1742. {
  1743. if (lParam == 0xdeadc0de)
  1744. return 1;
  1745. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam))
  1746. return 0;
  1747. WASABI_API_WND->popupexit_check(this);
  1748. if (checkModal())
  1749. return 0;
  1750. abortTip();
  1751. int xPos = (signed short)LOWORD(lParam);
  1752. int yPos = (signed short)HIWORD(lParam);
  1753. xPos = (int)((float)xPos / getRenderRatio());
  1754. yPos = (int)((float)yPos / getRenderRatio());
  1755. if (!getCapture() && hasVirtualChildren() && handleVirtualChildMsg(WM_LBUTTONDOWN, xPos, yPos))
  1756. return 0;
  1757. if (isEnabled() && !dragging)
  1758. {
  1759. autoFocus(this);
  1760. int r = 0;
  1761. if (wantLeftClicks())
  1762. r = onLeftButtonDown(xPos, yPos);
  1763. if (checkDoubleClick(uMsg, xPos, yPos) && wantDoubleClicks() && onLeftButtonDblClk(xPos, yPos))
  1764. return 0;
  1765. return r;
  1766. }
  1767. }
  1768. break;
  1769. case WM_RBUTTONDOWN:
  1770. {
  1771. if (lParam == 0xdeadc0de) return 1;
  1772. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  1773. WASABI_API_WND->popupexit_check(this);
  1774. if (checkModal()) return 0;
  1775. abortTip();
  1776. int xPos = (signed short)LOWORD(lParam);
  1777. int yPos = (signed short)HIWORD(lParam);
  1778. xPos = (int)((float)xPos / getRenderRatio());
  1779. yPos = (int)((float)yPos / getRenderRatio());
  1780. if (!getCapture() && hasVirtualChildren())
  1781. if (handleVirtualChildMsg(WM_RBUTTONDOWN, xPos, yPos))
  1782. return 0;
  1783. if (isEnabled() && !dragging)
  1784. {
  1785. autoFocus(this);
  1786. int r = 0;
  1787. if (wantRightClicks())
  1788. r = onRightButtonDown(xPos, yPos);
  1789. if (checkDoubleClick(uMsg, xPos, yPos) && wantDoubleClicks()) if (onRightButtonDblClk(xPos, yPos)) return 0;
  1790. return r;
  1791. }
  1792. }
  1793. break;
  1794. case WM_MOUSEHOVER:
  1795. if (checkModal()) return 0;
  1796. if (!getCapture() && hasVirtualChildren())
  1797. if (handleVirtualChildMsg(WM_MOUSEHOVER, 0, 0))
  1798. return 0;
  1799. break;
  1800. case WM_MOUSEMOVE:
  1801. {
  1802. /* static int mm=0;
  1803. DebugString("mousemove %d\n", mm++);*/
  1804. if (checkModal()) return 0;
  1805. int xPos = (signed short)LOWORD(lParam);
  1806. int yPos = (signed short)HIWORD(lParam);
  1807. xPos = (int)((float)xPos / getRenderRatio());
  1808. yPos = (int)((float)yPos / getRenderRatio());
  1809. if (dragging)
  1810. {
  1811. POINT pt = {xPos, yPos};
  1812. clientToScreen(&pt);
  1813. ifc_window *targ;
  1814. int candrop = 0;
  1815. // find the window the mouse is over
  1816. targ = NULL;
  1817. if (stickyWnd)
  1818. {
  1819. RECT wr;
  1820. GetWindowRect(stickyWnd->getOsWindowHandle(), &wr);
  1821. if (pt.x >= wr.left - sticky.left &&
  1822. pt.x <= wr.right + sticky.right &&
  1823. pt.y >= wr.top - sticky.top &&
  1824. pt.y <= wr.bottom + sticky.bottom) targ = stickyWnd;
  1825. else stickyWnd = NULL;
  1826. }
  1827. if (targ == NULL && WASABI_API_WND) targ = WASABI_API_WND->rootWndFromPoint(&pt); // FG> not to self, check
  1828. DI prevtargdi(prevtarg);
  1829. DI targdi(targ);
  1830. if (prevtarg != targ)
  1831. {
  1832. // window switch
  1833. if (prevtarg != NULL) prevtargdi.dragLeave(this);
  1834. if (targ != NULL) targdi.dragEnter(this);
  1835. }
  1836. if (targ != NULL)
  1837. candrop = targdi.dragOver(pt.x, pt.y, this);
  1838. if (targ == NULL || !candrop)
  1839. SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO)));
  1840. else
  1841. SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)));
  1842. prevtarg = targ;
  1843. }
  1844. else if (isEnabled())
  1845. {
  1846. tipbeenchecked = FALSE;
  1847. if (!getCapture() && hasVirtualChildren())
  1848. {
  1849. if (handleVirtualChildMsg(WM_MOUSEMOVE, xPos, yPos))
  1850. return 0;
  1851. }
  1852. if (getCapture())
  1853. {
  1854. if (wantMouseMoves())
  1855. if (onMouseMove(xPos, yPos))
  1856. return 0;
  1857. }
  1858. if (!tipbeenchecked) onTipMouseMove();
  1859. return 0;
  1860. }
  1861. }
  1862. break;
  1863. case WM_LBUTTONUP:
  1864. {
  1865. if (lParam == 0xdeadc0de) return 1;
  1866. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  1867. if (checkModal()) return 0;
  1868. int xPos = (signed short)LOWORD(lParam);
  1869. int yPos = (signed short)HIWORD(lParam);
  1870. xPos = (int)((float)xPos / getRenderRatio());
  1871. yPos = (int)((float)yPos / getRenderRatio());
  1872. abortTip();
  1873. if (!dragging && !getCapture() && hasVirtualChildren())
  1874. {
  1875. if (handleVirtualChildMsg(WM_LBUTTONUP, xPos, yPos))
  1876. return 0;
  1877. }
  1878. if (dragging)
  1879. {
  1880. clientToScreen(&xPos, &yPos);
  1881. int res = 0;
  1882. if (prevtarg != NULL)
  1883. {
  1884. res = DI(prevtarg).dragDrop(this, xPos, yPos);
  1885. }
  1886. // inform source what happened
  1887. dragComplete(res);
  1888. resetDragSet();
  1889. prevtarg = NULL;
  1890. stickyWnd = NULL;
  1891. suggestedTitle = NULL;
  1892. SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
  1893. Wasabi::Std::Wnd::releaseCapture();
  1894. dragging = 0;
  1895. }
  1896. else if (isEnabled())
  1897. {
  1898. if (wantLeftClicks())
  1899. if (onLeftButtonUp(xPos, yPos)) return 0;
  1900. }
  1901. }
  1902. break;
  1903. case WM_RBUTTONUP:
  1904. {
  1905. if (lParam == 0xdeadc0de) return 1;
  1906. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  1907. if (checkModal()) return 0;
  1908. abortTip();
  1909. int xPos = (signed short)LOWORD(lParam);
  1910. int yPos = (signed short)HIWORD(lParam);
  1911. xPos = (int)((float)xPos / getRenderRatio());
  1912. yPos = (int)((float)yPos / getRenderRatio());
  1913. if (!getCapture() && hasVirtualChildren())
  1914. {
  1915. if (handleVirtualChildMsg(WM_RBUTTONUP, xPos, yPos))
  1916. return 0;
  1917. }
  1918. if (isEnabled() && !dragging)
  1919. {
  1920. if (wantRightClicks())
  1921. if (onRightButtonUp(xPos, yPos)) return 0;
  1922. }
  1923. }
  1924. break;
  1925. case WM_CONTEXTMENU:
  1926. {
  1927. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  1928. if (checkModal()) return 0;
  1929. ASSERT(hWnd != NULL);
  1930. int xPos = (signed short)LOWORD(lParam);
  1931. int yPos = (signed short)HIWORD(lParam);
  1932. if (hWnd == getOsWindowHandle())
  1933. {
  1934. if (wantContextMenus())
  1935. if (onContextMenu(xPos, yPos)) return 0;
  1936. }
  1937. else if (GetParent(hWnd) == getOsWindowHandle())
  1938. {
  1939. if (wantContextMenus())
  1940. if (onChildContextMenu(xPos, yPos)) return 0;
  1941. }
  1942. }
  1943. break;
  1944. case WM_ERASEBKGND:
  1945. return (onEraseBkgnd((HDC)wParam));
  1946. case WM_MOUSEWHEEL:
  1947. {
  1948. abortTip();
  1949. int l, a;
  1950. l = (short)HIWORD(wParam) / 120;
  1951. a = (short)HIWORD(wParam);
  1952. if (!l)
  1953. if (a > 0) l = 1;
  1954. else if (a < 0)l = 0;
  1955. a = l >= 0 ? l : -l;
  1956. if (GetAsyncKeyState(VK_MBUTTON)&0x8000)
  1957. {
  1958. if (l >= 0) l = 0; // Fast Forward 5s
  1959. else l = 1; // Rewind 5s
  1960. }
  1961. else
  1962. {
  1963. if (l >= 0) l = 2; // Volume up
  1964. else l = 3; // Volume down
  1965. }
  1966. int r = 0;
  1967. if (l & 1)
  1968. r = onMouseWheelDown(!(BOOL)(l & 2), a);
  1969. else
  1970. r = onMouseWheelUp(!(BOOL)(l & 2), a);
  1971. if (r == 0)
  1972. {
  1973. r = WASABI_API_WND->forwardOnMouseWheel(l, a);
  1974. }
  1975. // if it wasn't handled by this wnd, nor by the api, send it to the main wnd, unless we're it
  1976. if (r == 0)
  1977. {
  1978. if (WASABI_API_WND->main_getRootWnd() != this)
  1979. r = (int)SendMessageW(WASABI_API_WND->main_getRootWnd()->gethWnd(), uMsg, wParam, lParam);
  1980. }
  1981. return r;
  1982. }
  1983. case WM_WA_RELOAD:
  1984. {
  1985. if (wParam == 0)
  1986. freeResources();
  1987. else
  1988. reloadResources();
  1989. return 0;
  1990. }
  1991. case WM_WA_GETFBSIZE:
  1992. {
  1993. SIZE *s = (SIZE *)wParam;
  1994. s->cx = rwidth;
  1995. s->cy = rheight;
  1996. return 0;
  1997. }
  1998. case WM_USER + 8976: // wheel in tip, delete tip
  1999. abortTip();
  2000. return 0;
  2001. case WM_CHAR:
  2002. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  2003. if (WASABI_API_WND->interceptOnChar((TCHAR) wParam)) return 0;
  2004. if (curVirtualChildFocus == NULL)
  2005. {
  2006. if (onChar(((TCHAR) wParam))) return 0;
  2007. }
  2008. else
  2009. {
  2010. if (curVirtualChildFocus->onChar(((TCHAR) wParam))) return 0;
  2011. }
  2012. if (WASABI_API_WND && WASABI_API_WND->forwardOnChar(this, (TCHAR) wParam, (int)lParam)) return 0;
  2013. break;
  2014. case WM_KEYDOWN:
  2015. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  2016. if (WASABI_API_WND->interceptOnKeyDown((int) wParam)) return 0;
  2017. if (curVirtualChildFocus == NULL)
  2018. {
  2019. if (onKeyDown((int) wParam)) return 0;
  2020. }
  2021. else
  2022. {
  2023. if (curVirtualChildFocus->onKeyDown((int)wParam)) return 0;
  2024. }
  2025. if (WASABI_API_WND && WASABI_API_WND->forwardOnKeyDown(this, (int) wParam, (int)lParam)) return 0;
  2026. break;
  2027. case WM_KEYUP:
  2028. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  2029. if (WASABI_API_WND->interceptOnKeyUp((int) wParam)) return 0;
  2030. if (curVirtualChildFocus == NULL)
  2031. {
  2032. if (onKeyUp((int) wParam)) return 0;
  2033. }
  2034. else
  2035. {
  2036. if (curVirtualChildFocus->onKeyUp((int)wParam)) return 0;
  2037. }
  2038. if (WASABI_API_WND && WASABI_API_WND->forwardOnKeyUp(this, (int) wParam, (int)lParam)) return 0;
  2039. break;
  2040. case WM_SYSKEYDOWN:
  2041. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  2042. if (WASABI_API_WND->interceptOnSysKeyDown((int) wParam, (int)lParam)) return 0;
  2043. if (curVirtualChildFocus == NULL)
  2044. {
  2045. if (onSysKeyDown((int) wParam, (int)lParam)) return 0;
  2046. }
  2047. else
  2048. {
  2049. if (curVirtualChildFocus->onSysKeyDown((int)wParam, (int)lParam)) return 0;
  2050. }
  2051. if (WASABI_API_WND && WASABI_API_WND->forwardOnSysKeyDown(this, (int) wParam, (int)lParam)) return 0;
  2052. break;
  2053. case WM_SYSKEYUP:
  2054. if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
  2055. if (WASABI_API_WND->interceptOnSysKeyUp((int) wParam, (int)lParam)) return 0;
  2056. if (curVirtualChildFocus == NULL)
  2057. {
  2058. if (onSysKeyUp((int) wParam, (int)lParam)) return 0;
  2059. }
  2060. else
  2061. {
  2062. if (curVirtualChildFocus->onSysKeyUp((int)wParam, (int)lParam)) return 0;
  2063. }
  2064. if (WASABI_API_WND && WASABI_API_WND->forwardOnSysKeyUp(this, (int) wParam, (int)lParam)) return 0;
  2065. break;
  2066. case WM_MOUSEACTIVATE:
  2067. {
  2068. if (checkModal() || !wantActivation())
  2069. return MA_NOACTIVATE;
  2070. //SetFocus(getOsWindowHandle());
  2071. return MA_ACTIVATE;
  2072. }
  2073. case WM_ACTIVATEAPP:
  2074. if (wParam == FALSE)
  2075. {
  2076. if (WASABI_API_WND != NULL)
  2077. {
  2078. WASABI_API_WND->popupexit_signal();
  2079. WASABI_API_SYSCB->syscb_issueCallback(SysCallback::GC, GarbageCollectCallback::GARBAGECOLLECT);
  2080. WASABI_API_WND->kbdReset();
  2081. if (ghosthwnd.getNumItems() > 0 && ghostbust)
  2082. {
  2083. ghostbust = 0; postDeferredCallback(DC_KILLGHOST);
  2084. }
  2085. return 0;
  2086. }
  2087. }
  2088. break;
  2089. case WM_ACTIVATE:
  2090. switch(LOWORD(wParam))
  2091. {
  2092. case WA_ACTIVE:
  2093. case WA_CLICKACTIVE:
  2094. if (WASABI_API_WND != NULL)
  2095. WASABI_API_WND->popupexit_check(this);
  2096. onActivate();
  2097. if (WA_CLICKACTIVE == LOWORD(wParam))
  2098. {
  2099. POINT pt;
  2100. DWORD pts = GetMessagePos();
  2101. POINTSTOPOINT(pt, pts);
  2102. MapWindowPoints(HWND_DESKTOP, hwnd, &pt, 1);
  2103. HWND hTarget = ChildWindowFromPointEx(hwnd, pt, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED | CWP_SKIPTRANSPARENT);
  2104. if (hTarget && hTarget != hwnd) lastActiveWnd = hTarget;
  2105. }
  2106. if (lastActiveWnd != hwnd && NULL != lastActiveWnd && IsWindow(lastActiveWnd))
  2107. {
  2108. SendMessageW(lastActiveWnd, uMsg, wParam, lParam);
  2109. return 0;
  2110. }
  2111. break;
  2112. default:
  2113. onDeactivate();
  2114. lastActiveWnd = GetFocus();
  2115. if (NULL != lastActiveWnd && !IsChild(hwnd, lastActiveWnd))
  2116. lastActiveWnd = NULL;
  2117. {
  2118. #ifndef ARRAYSIZE
  2119. #define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))
  2120. #endif
  2121. if (NULL != lastActiveWnd && !BaseWnd_IsFrameWindow(lastActiveWnd))
  2122. {
  2123. while (lastActiveWnd)
  2124. {
  2125. if (BaseWnd_IsFrameWindow(GetWindow(lastActiveWnd, GW_OWNER)))
  2126. break;
  2127. lastActiveWnd = GetAncestor(lastActiveWnd, GA_PARENT);
  2128. }
  2129. }
  2130. }
  2131. if (lastActiveWnd != hwnd && NULL != lastActiveWnd)
  2132. {
  2133. SendMessageW(lastActiveWnd, uMsg, wParam, lParam);
  2134. return 0;
  2135. }
  2136. break;
  2137. }
  2138. break;
  2139. case WM_NCACTIVATE:
  2140. if (allowDeactivation())
  2141. return TRUE;
  2142. return FALSE;
  2143. case WM_WINDOWPOSCHANGING:
  2144. {
  2145. if (!isVirtual() && Wasabi::Std::Wnd::isPopup(hwnd))
  2146. {
  2147. WINDOWPOS *wp = (WINDOWPOS *)lParam;
  2148. if (wp->x != rx || wp->y != ry) wp->flags |= SWP_NOMOVE;
  2149. }
  2150. }
  2151. break;
  2152. case WM_WINDOWPOSCHANGED:
  2153. {
  2154. WINDOWPOS *lpwp = (WINDOWPOS *)lParam; // points to size and position data
  2155. if (lpwp->flags & SWP_HIDEWINDOW)
  2156. {
  2157. minimized = 1;
  2158. onMinimize();
  2159. }
  2160. else if (lpwp->flags & SWP_SHOWWINDOW)
  2161. {
  2162. minimized = 0;
  2163. onRestore();
  2164. }
  2165. if (!inonresize)
  2166. {
  2167. int w = rwidth;
  2168. int h = rheight;
  2169. multRatio(&w, &h);
  2170. if (lpwp->cx != w || lpwp->cy != h)
  2171. {
  2172. DebugStringW(L"external onResize\n");
  2173. w = lpwp->cx;
  2174. h = lpwp->cy;
  2175. divRatio(&w, &h);
  2176. setRSize(rx, ry, w, h);
  2177. if (isPostOnInit())
  2178. onResize();
  2179. }
  2180. }
  2181. onPostedMove();
  2182. return 0;
  2183. }
  2184. case WM_DROPFILES:
  2185. {
  2186. if (checkModal()) break;
  2187. WASABI_API_WND->pushModalWnd();
  2188. onExternalDropBegin();
  2189. HDROP h = (HDROP)wParam;
  2190. POINT dp = {0};
  2191. DragQueryPoint(h, &dp);
  2192. clientToScreen(&dp);
  2193. // build a file list
  2194. wchar_t buf[WA_MAX_PATH] = {0};
  2195. PtrList<FilenamePS> keep;
  2196. SetCursor(LoadCursor(NULL, IDC_WAIT));
  2197. //CUT #if UTF8
  2198. //CUT // doesn't really need UTF8, the "buf" is never written to.
  2199. //CUT // made to be NULL to enforce this concept.
  2200. int nfiles = DragQueryFile(h, 0xffffffff, NULL, 0);
  2201. //CUT #else
  2202. //CUT int nfiles = DragQueryFile(h, 0xffffffff, buf, sizeof(buf));
  2203. //CUT #endif
  2204. // convert them all to PlayItem *'s
  2205. for (int i = 0; i < nfiles; i++)
  2206. {
  2207. DragQueryFileW(h, i, buf, WA_MAX_PATH);
  2208. addDroppedFile(buf, &keep); // recursive
  2209. }
  2210. SetCursor(LoadCursor(NULL, IDC_ARROW));
  2211. dragging = 1;
  2212. if (dragEnter(this))
  2213. {
  2214. if (dragOver(dp.x, dp.y, this)) dragDrop(this, dp.x, dp.y);
  2215. }
  2216. else
  2217. {
  2218. dragLeave(this);
  2219. #ifdef FORWARD_DRAGNDROP
  2220. HWND w = WASABI_API_WND->main_getRootWnd()->gethWnd();
  2221. SendMessageW(w, WM_DROPFILES, wParam, lParam);
  2222. #endif
  2223. }
  2224. dragging = 0;
  2225. // remove data
  2226. keep.deleteAll();
  2227. resetDragSet();
  2228. onExternalDropEnd();
  2229. WASABI_API_WND->popModalWnd();
  2230. }
  2231. return 0; // dropfiles
  2232. case WM_CAPTURECHANGED:
  2233. /* static int cc=0;
  2234. DebugString("capture changed! %d\n", cc++);*/
  2235. if (preventcancelcapture) return 0;
  2236. inputCaptured = 0;
  2237. if (curVirtualChildCaptured != NULL)
  2238. {
  2239. ifc_window *w = curVirtualChildCaptured;
  2240. curVirtualChildCaptured = NULL;
  2241. w->onCancelCapture();
  2242. }
  2243. else
  2244. {
  2245. onCancelCapture();
  2246. }
  2247. return 0;
  2248. } //switch
  2249. if (WINAMP_WM_DIRECT_MOUSE_WHEEL == uMsg &&
  2250. WM_NULL != WINAMP_WM_DIRECT_MOUSE_WHEEL)
  2251. {
  2252. wndProc(hWnd, WM_MOUSEWHEEL, wParam, lParam);
  2253. return TRUE;
  2254. }
  2255. if (uMsg >= WM_USER)
  2256. {
  2257. int ret;
  2258. if (onUserMessage(uMsg, (int)wParam, (int)lParam, &ret))
  2259. return ret;
  2260. return 0;
  2261. }
  2262. return DefWindowProcW(hWnd, uMsg, wParam, lParam);
  2263. }
  2264. #endif
  2265. int BaseWnd::onUserMessage(int msg, int w, int l, int *r)
  2266. {
  2267. return 0;
  2268. }
  2269. int BaseWnd::checkDoubleClick(int b, int x, int y)
  2270. {
  2271. #ifdef _WIN32
  2272. uint32_t now = Wasabi::Std::getTickCount();
  2273. switch (b)
  2274. {
  2275. case WM_LBUTTONDOWN:
  2276. if (lastClick[0] > now - Wasabi::Std::getDoubleClickDelay())
  2277. {
  2278. lastClick[0] = 0;
  2279. if (ABS(lastClickP[0].x - x) > Wasabi::Std::getDoubleClickX() || ABS(lastClickP[0].y - y) > Wasabi::Std::getDoubleClickY()) return 0;
  2280. return 1;
  2281. }
  2282. lastClick[0] = now;
  2283. lastClickP[0].x = x;
  2284. lastClickP[0].y = y;
  2285. break;
  2286. case WM_RBUTTONDOWN:
  2287. if (lastClick[1] > now - Wasabi::Std::getDoubleClickDelay())
  2288. {
  2289. lastClick[1] = 0;
  2290. if (ABS(lastClickP[1].x - x) > Wasabi::Std::getDoubleClickX() || ABS(lastClickP[1].y - y) > Wasabi::Std::getDoubleClickY()) return 0;
  2291. return 1;
  2292. }
  2293. lastClick[1] = now;
  2294. lastClickP[1].x = x;
  2295. lastClickP[1].y = y;
  2296. break;
  2297. }
  2298. #else
  2299. #warning port me
  2300. #endif
  2301. return 0;
  2302. }
  2303. int BaseWnd::onMouseWheelUp(int click, int lines)
  2304. {
  2305. return 0;
  2306. }
  2307. int BaseWnd::onMouseWheelDown(int click, int lines)
  2308. {
  2309. return 0;
  2310. }
  2311. int BaseWnd::onContextMenu(int x, int y)
  2312. {
  2313. return 0;
  2314. }
  2315. int BaseWnd::onChildContextMenu(int x, int y)
  2316. {
  2317. return 0;
  2318. }
  2319. int BaseWnd::onDeferredCallback(intptr_t param1, intptr_t param2)
  2320. {
  2321. switch (param1)
  2322. {
  2323. case DEFERREDCB_FLUSHPAINT:
  2324. do_flushPaint();
  2325. break;
  2326. case DEFERREDCB_INVALIDATE:
  2327. if (isPostOnInit())
  2328. invalidate();
  2329. break;
  2330. case DC_KILLGHOST:
  2331. if (ghosthwnd.getNumItems() > 0)
  2332. {
  2333. preventcancelcapture = 1;
  2334. for (int i = 0;i < ghosthwnd.getNumItems();i++)
  2335. Wasabi::Std::Wnd::destroyWnd(ghosthwnd.enumItem(i));
  2336. ghosthwnd.freeAll();
  2337. preventcancelcapture = 0;
  2338. }
  2339. break;
  2340. case DEFERREDCB_FOCUSFIRST:
  2341. assignRootFocus(NULL);
  2342. if (Wasabi::Std::Wnd::getFocus() == getOsWindowHandle())
  2343. {
  2344. focusNext();
  2345. }
  2346. break;
  2347. case 0x7849 /*DEFERREDCB_ONHIDE*/:
  2348. {
  2349. foreach(rootwndchildren)
  2350. ifc_window *w = rootwndchildren.getfor();
  2351. if (w->isVisible(1)) // check internal flag only
  2352. w->onSetVisible(0);
  2353. endfor;
  2354. dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_SETVISIBLE, 0);
  2355. break;
  2356. }
  2357. }
  2358. return 0;
  2359. }
  2360. int BaseWnd::onPaint(Canvas *canvas)
  2361. {
  2362. #if 0
  2363. // example:
  2364. PaintCanvas c;
  2365. if (!c.beginPaint(this)) return 0;
  2366. (do some painting)
  2367. c will self -destruct on return
  2368. #endif
  2369. if (renderbasetexture)
  2370. {
  2371. PaintCanvas paintcanvas;
  2372. if (canvas == NULL)
  2373. {
  2374. if (!paintcanvas.beginPaint(this)) return 0;
  2375. canvas = &paintcanvas;
  2376. }
  2377. RECT r;
  2378. getNonClientRect(&r);
  2379. RenderBaseTexture(canvas, r);
  2380. }
  2381. return 0;
  2382. }
  2383. int BaseWnd::onPaint(Canvas *canvas, api_region *h)
  2384. {
  2385. if (!canvas) return onPaint(canvas);
  2386. #ifdef _WIN32
  2387. int sdc = SaveDC(canvas->getHDC());
  2388. #elif defined(__APPLE__)
  2389. CGContextSaveGState(canvas->getHDC());
  2390. #endif
  2391. canvas->selectClipRgn(h);
  2392. int rs = onPaint(canvas);
  2393. #ifdef _WIN32
  2394. RestoreDC(canvas->getHDC(), sdc);
  2395. #elif defined(__APPLE__)
  2396. CGContextRestoreGState(canvas->getHDC());
  2397. #endif
  2398. return rs;
  2399. }
  2400. int BaseWnd::getTransparency()
  2401. {
  2402. return wndalpha;
  2403. }
  2404. void BaseWnd::setTransparency(int amount)
  2405. {
  2406. //if (wndalpha == amount) return;
  2407. if (amount == 254) amount = 255;
  2408. if (amount == 1) amount = 0;
  2409. if (amount != -1) wndalpha = amount; else amount = wndalpha;
  2410. if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable())
  2411. {
  2412. wndalpha = 255;
  2413. return ;
  2414. }
  2415. if (w2k_alpha)
  2416. {
  2417. invalidate();
  2418. return ;
  2419. }
  2420. #ifdef WIN32
  2421. if (!isInited() || isVirtual()) return ;
  2422. if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle())) return ;
  2423. if (amount < -1) amount = 0;
  2424. else if (amount > 255) amount = 255;
  2425. //CUT DWORD dwLong = GetWindowLong(hwnd, GWL_EXSTYLE);
  2426. if (amount == 255 && !forceTransparencyFlag())
  2427. {
  2428. Wasabi::Std::Wnd::setLayeredWnd(hwnd, FALSE);
  2429. //CUT if (dwLong & WS_EX_LAYERED)
  2430. //CUT SetWindowLong(hwnd, GWL_EXSTYLE, dwLong & ~WS_EX_LAYERED);
  2431. has_alpha_flag = 0;
  2432. }
  2433. else
  2434. {
  2435. if (!Wasabi::Std::Wnd::isLayeredWnd(hwnd))
  2436. Wasabi::Std::Wnd::setLayeredWnd(hwnd, TRUE);
  2437. //CUT if (!(dwLong & WS_EX_LAYERED))
  2438. //CUT SetWindowLong(hwnd, GWL_EXSTYLE, dwLong | WS_EX_LAYERED);
  2439. Wasabi::Std::Wnd::setLayeredAlpha(hwnd, amount);
  2440. //CUT setLayeredWindowAttributes(hwnd, RGB(0,0,0), amount, LWA_ALPHA);
  2441. has_alpha_flag = 1;
  2442. }
  2443. #endif
  2444. }
  2445. int BaseWnd::forceTransparencyFlag()
  2446. {
  2447. return 0;
  2448. }
  2449. int BaseWnd::beginCapture()
  2450. {
  2451. if (!getCapture())
  2452. {
  2453. disable_tooltip_til_recapture = 0;
  2454. curVirtualChildCaptured = NULL;
  2455. /* oldCapture = */Wasabi::Std::Wnd::setCapture(getOsWindowHandle());
  2456. /* if (oldCapture) {
  2457. DebugString("Stolen capture detected, this may be ok, but try to avoid it if possible. Saving old capture\n");
  2458. }*/
  2459. inputCaptured = 1;
  2460. }
  2461. return 1;
  2462. }
  2463. int BaseWnd::endCapture()
  2464. {
  2465. preventcancelcapture = 1;
  2466. if (Wasabi::Std::Wnd::getCapture() == getOsWindowHandle()) Wasabi::Std::Wnd::releaseCapture();
  2467. /* if (oldCapture) {
  2468. DebugString("Restoring old capture\n");
  2469. SetCapture(oldCapture);
  2470. oldCapture = NULL;
  2471. }*/
  2472. inputCaptured = 0;
  2473. preventcancelcapture = 0;
  2474. return 1;
  2475. }
  2476. int BaseWnd::getCapture()
  2477. {
  2478. if (inputCaptured && Wasabi::Std::Wnd::getCapture() == getOsWindowHandle() && curVirtualChildCaptured == NULL) return 1;
  2479. return 0;
  2480. }
  2481. void BaseWnd::cancelCapture()
  2482. {
  2483. if (curVirtualChildCaptured != NULL)
  2484. {
  2485. curVirtualChildCaptured->cancelCapture();
  2486. return ;
  2487. }
  2488. if (getCapture()) endCapture();
  2489. onCancelCapture();
  2490. }
  2491. int BaseWnd::onMouseMove(int x, int y)
  2492. {
  2493. onTipMouseMove();
  2494. return 0;
  2495. }
  2496. void BaseWnd::onTipMouseMove()
  2497. {
  2498. POINT p;
  2499. if (dragging) return ;
  2500. if (disable_tooltip_til_recapture) return ;
  2501. tipbeenchecked = TRUE;
  2502. Wasabi::Std::getMousePos(&p);
  2503. if (WASABI_API_WND->rootWndFromPoint(&p) != (ifc_window *)this)
  2504. {
  2505. // leaving area
  2506. tip_done = FALSE;
  2507. if (tipawaytimer)
  2508. killTimer(TIP_AWAY_ID);
  2509. tipawaytimer = FALSE;
  2510. if (tipshowtimer)
  2511. {
  2512. // TODO: on the mac, use CreateMouseTrackingRegion
  2513. TRACKMOUSEEVENT tracker;
  2514. tracker.cbSize=sizeof(tracker);
  2515. tracker.dwFlags = TME_HOVER|TME_CANCEL;
  2516. tracker.hwndTrack = this->getOsWindowHandle();
  2517. tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
  2518. TrackMouseEvent(&tracker);
  2519. }
  2520. tipshowtimer = FALSE;
  2521. destroyTip();
  2522. }
  2523. else
  2524. {
  2525. // moving in area
  2526. const wchar_t *t = getTip();
  2527. if (!disable_tooltip_til_recapture && !tipshowtimer && !tip_done && t != NULL && *t != 0)
  2528. {
  2529. //entering area & need tip
  2530. // TODO: on the mac, use CreateMouseTrackingRegion
  2531. TRACKMOUSEEVENT tracker;
  2532. tracker.cbSize=sizeof(tracker);
  2533. tracker.dwFlags = TME_HOVER;
  2534. tracker.hwndTrack = this->getOsWindowHandle();
  2535. tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
  2536. TrackMouseEvent(&tracker);
  2537. tipshowtimer = TRUE;
  2538. }
  2539. /*else if (tipshowtimer)
  2540. {
  2541. TRACKMOUSEEVENT tracker;
  2542. tracker.cbSize=sizeof(tracker);
  2543. tracker.dwFlags = TME_HOVER;
  2544. tracker.hwndTrack = this->getOsWindowHandle();
  2545. tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
  2546. TrackMouseEvent(&tracker);
  2547. }*/
  2548. }
  2549. }
  2550. int BaseWnd::onLeftButtonDblClk(int x, int y)
  2551. {
  2552. return 0;
  2553. }
  2554. int BaseWnd::onRightButtonDblClk(int x, int y)
  2555. {
  2556. return 0;
  2557. }
  2558. int BaseWnd::onGetFocus()
  2559. {
  2560. // return TRUE if you override this
  2561. hasfocus = 1;
  2562. notifyParent(ChildNotify::GOTFOCUS);
  2563. getRootParent()->onSetRootFocus(this);
  2564. invalidate();
  2565. Accessible *a = getAccessibleObject();
  2566. if (a != NULL)
  2567. a->onGetFocus();
  2568. return 1;
  2569. }
  2570. int BaseWnd::onKillFocus()
  2571. {
  2572. // return TRUE if you override this
  2573. hasfocus = 0;
  2574. notifyParent(ChildNotify::KILLFOCUS);
  2575. invalidate();
  2576. return 1;
  2577. }
  2578. #if defined(_WIN64)
  2579. int BaseWnd::childNotify(ifc_window* child, int msg, int p1, int p2)
  2580. {
  2581. return 0;
  2582. }
  2583. #else
  2584. int BaseWnd::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2)
  2585. {
  2586. return 0;
  2587. }
  2588. #endif
  2589. int BaseWnd::addDragItem(const wchar_t *droptype, void *item)
  2590. {
  2591. ASSERT(droptype != NULL);
  2592. if (item == NULL) return -1;
  2593. DragSet *set;
  2594. int pos = dragCheckData(droptype);
  2595. if (pos == -1)
  2596. {
  2597. set = new DragSet();
  2598. set->setName(droptype);
  2599. dragsets.addItem(set);
  2600. pos = dragsets.getNumItems() - 1;
  2601. }
  2602. else set = dragsets[pos];
  2603. set->addItem(item);
  2604. return pos;
  2605. }
  2606. #ifdef _WIN32
  2607. int BaseWnd::handleDrag()
  2608. {
  2609. abortTip();
  2610. if (dragsets.getNumItems() == 0) return 0;
  2611. Wasabi::Std::Wnd::setCapture(hwnd);
  2612. SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)));
  2613. dragging = 1;
  2614. stickyWnd = NULL;
  2615. return 1;
  2616. }
  2617. #endif
  2618. int BaseWnd::resetDragSet()
  2619. {
  2620. dragsets.deleteAll();
  2621. return 1;
  2622. }
  2623. int BaseWnd::dragEnter(ifc_window *sourceWnd)
  2624. {
  2625. ifc_window *rw = getParent(); //api_window::rootwndFromRootWnd(getParent()); //FG> note to self, check!
  2626. if (rw) return DI(rw).dragEnter(sourceWnd);
  2627. return 0;
  2628. }
  2629. int BaseWnd::dragSetSticky(ifc_window *wnd, int left, int right, int up, int down)
  2630. {
  2631. ASSERT(dragging);
  2632. stickyWnd = wnd;
  2633. if (left < 0) left = 0;
  2634. if (right < 0) right = 0;
  2635. if (up < 0) up = 0;
  2636. if (down < 0) down = 0;
  2637. Wasabi::Std::setRect(&sticky, left, up, right, down);
  2638. return 1;
  2639. }
  2640. void BaseWnd::setSuggestedDropTitle(const wchar_t *title)
  2641. {
  2642. ASSERT(title != NULL);
  2643. suggestedTitle = title;
  2644. }
  2645. const wchar_t *BaseWnd::dragGetSuggestedDropTitle()
  2646. {
  2647. return suggestedTitle; // can be NULL
  2648. }
  2649. int BaseWnd::dragCheckData(const wchar_t *type, int *nitems)
  2650. {
  2651. for (int i = 0; i < dragsets.getNumItems(); i++)
  2652. {
  2653. if (!WCSICMP(type, dragsets[i]->getName()))
  2654. {
  2655. if (nitems != NULL) *nitems = dragsets[i]->getNumItems();
  2656. return i;
  2657. }
  2658. }
  2659. return -1;
  2660. }
  2661. void *BaseWnd::dragGetData(int slot, int itemnum)
  2662. {
  2663. if (slot < 0 || slot >= dragsets.getNumItems()) return 0;
  2664. if (itemnum < 0 || itemnum >= dragsets[slot]->getNumItems()) return 0;
  2665. return dragsets[slot]->enumItem(itemnum);
  2666. }
  2667. void BaseWnd::addDroppedFile(const wchar_t *filename, PtrList<FilenamePS> *plist)
  2668. {
  2669. #ifdef RECURSE_SUBDIRS_ON_DROP
  2670. const char *slash = filename + STRLEN(filename) - 1;
  2671. for (; slash > filename; slash--) if (*slash == '/' || *slash == '\\') break;
  2672. if (STREQL(slash + 1, ".") || STREQL(slash + 1, "..")) return ;
  2673. char buf[WA_MAX_PATH] = {0};
  2674. STRCPY(buf, filename);
  2675. // try to resolve shortcuts
  2676. char *ext = buf + STRLEN(buf) - 1;
  2677. for (; ext > buf; ext--) if (*ext == '.' || *ext == '\\' || *ext == '/') break;
  2678. #ifdef WIN32
  2679. if (!STRICMP(ext, ".lnk"))
  2680. {
  2681. char buf2[MAX_PATH] = {0};
  2682. if (StdFile::resolveShortcut(buf, buf2)) STRCPY(buf, buf2);
  2683. }
  2684. #endif
  2685. int isdir = 0;
  2686. // handle root dir specially?
  2687. WIN32_FIND_DATA data = {0};
  2688. HANDLE r = FindFirstFile(buf, &data);
  2689. if (!r) return ;
  2690. FindClose(r);
  2691. if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) isdir = 1;
  2692. if (isdir)
  2693. {
  2694. onExternalDropDirScan(buf);
  2695. // enumerate that dir
  2696. char search[WA_MAX_PATH] = {0};
  2697. wsprintf(search, "%s\\*.*", buf);
  2698. HANDLE files = FindFirstFile(search, &data);
  2699. if (files == INVALID_HANDLE_VALUE) return ; // nothin' in it
  2700. for (;;)
  2701. {
  2702. wchar_t obuf[WA_MAX_PATH] = {0};
  2703. swprintf(obuf, L"%s\\%s", buf, data.cFileName);
  2704. addDroppedFile(obuf, plist);
  2705. if (!FindNextFile(files, &data))
  2706. {
  2707. FindClose(files);
  2708. return ;
  2709. }
  2710. }
  2711. // should never get here
  2712. }
  2713. else
  2714. {
  2715. addDragItem(DD_FILENAME, plist->addItem(new FilenamePS(StringPrintfW(L"file:%s", buf))));
  2716. }
  2717. #else
  2718. addDragItem(DD_FILENAME, plist->addItem(new FilenamePS(StringPrintfW(L"file:%s", filename))));
  2719. #endif
  2720. }
  2721. bool BaseWnd::getNoCopyBits(void)
  2722. {
  2723. return ncb;
  2724. }
  2725. void BaseWnd::setNoCopyBits(bool newncb)
  2726. {
  2727. ncb = newncb;
  2728. }
  2729. int BaseWnd::onEraseBkgnd(HDC dc)
  2730. {
  2731. return 1;
  2732. }
  2733. void BaseWnd::setIcon(OSICONHANDLE icon, int _small)
  2734. {
  2735. Wasabi::Std::Wnd::setIcon(getOsWindowHandle(), icon, !_small);
  2736. //CUT SendMessageW(getOsWindowHandle(), WM_SETICON, _small ? ICON_SMALL : ICON_BIG, (int)icon);
  2737. }
  2738. const wchar_t *BaseWnd::getTip()
  2739. {
  2740. return tip;
  2741. }
  2742. void BaseWnd::setTip(const wchar_t *_tooltip)
  2743. {
  2744. tip = _tooltip;
  2745. abortTip();
  2746. }
  2747. int BaseWnd::getStartHidden()
  2748. {
  2749. return start_hidden;
  2750. }
  2751. void BaseWnd::abortTip()
  2752. {
  2753. if (tipshowtimer)
  2754. {
  2755. // TODO: on the mac, use CreateMouseTrackingRegion
  2756. TRACKMOUSEEVENT tracker;
  2757. tracker.cbSize=sizeof(tracker);
  2758. tracker.dwFlags = TME_HOVER|TME_CANCEL;
  2759. tracker.hwndTrack = this->getOsWindowHandle();
  2760. tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
  2761. TrackMouseEvent(&tracker);
  2762. }
  2763. tipshowtimer = FALSE;
  2764. if (tipawaytimer)
  2765. killTimer(TIP_AWAY_ID);
  2766. tipawaytimer = FALSE;
  2767. if (tipdestroytimer)
  2768. killTimer(TIP_DESTROYTIMER_ID);
  2769. tipdestroytimer = FALSE;
  2770. destroyTip();
  2771. tip_done = FALSE;
  2772. RECT r;
  2773. if (getOsWindowHandle() && Wasabi::Std::Wnd::getUpdateRect(getOsWindowHandle(), &r) != 0) // FG> avoids xoring over disapearing tip
  2774. repaint();
  2775. }
  2776. int BaseWnd::isVisible(int within)
  2777. {
  2778. if (!isVirtual() && !getOsWindowHandle()) return 0;
  2779. if (!this_visible) return 0;
  2780. if (within) return this_visible; // whatever, local
  2781. if (isVirtual()) // virtual, global
  2782. if (getParent())
  2783. return getParent()->isVisible();
  2784. else
  2785. return 0;
  2786. // non virtual, global
  2787. if (Wasabi::Std::Wnd::isPopup(getOsWindowHandle())) return this_visible;
  2788. if (!Wasabi::Std::Wnd::isValidWnd(Wasabi::Std::Wnd::getParent(getOsWindowHandle()))) return 0;
  2789. if (getParent()) return getParent()->isVisible(); // not a popup, check its parent or fail
  2790. return this_visible;
  2791. }
  2792. void BaseWnd::registerRootWndChild(ifc_window *child)
  2793. {
  2794. rootwndchildren.addItem(child);
  2795. if (child->isVirtual())
  2796. virtualChildren.addItem(child);
  2797. }
  2798. void BaseWnd::unregisterRootWndChild(ifc_window *child)
  2799. {
  2800. delTabOrderEntry(child);
  2801. rootwndchildren.removeItem(child);
  2802. if (curVirtualChildCaptured == child)
  2803. {
  2804. setVirtualChildCapture(NULL);
  2805. }
  2806. if (curVirtualChildFocus == child)
  2807. curVirtualChildFocus = NULL;
  2808. virtualChildren.removeItem(child);
  2809. //WASABI_API_WND->timer_remove(this, -1);
  2810. if (isPostOnInit() && isVisible())
  2811. postDeferredCallback(DEFERREDCB_INVALIDATE, 0);
  2812. }
  2813. int BaseWnd::isVirtual()
  2814. {
  2815. return 0;
  2816. }
  2817. //CUT?inline int isInRect(RECT *r,int x,int y) {
  2818. //CUT? if (x>=r->left&&x<=r->right&&y>=r->top&&y<=r->bottom) return 1;
  2819. //CUT? return 0;
  2820. //CUT?}
  2821. int BaseWnd::ensureVirtualCanvasOk()
  2822. {
  2823. RECT ncr;
  2824. if (isVirtual() && getParent()) return 1;
  2825. int size_w = rwidth;
  2826. int size_h = rheight;
  2827. if (!size_w || !size_h) return 0;
  2828. if (!virtualCanvas || virtualCanvasH != size_h || virtualCanvasW != size_w)
  2829. {
  2830. if (virtualCanvas)
  2831. {
  2832. deleteFrameBuffer(virtualCanvas);
  2833. virtualCanvas = NULL;
  2834. }
  2835. delete scalecanvas;
  2836. scalecanvas = NULL;
  2837. virtualCanvas = createFrameBuffer(size_w, size_h);
  2838. prepareFrameBuffer(virtualCanvas, size_w, size_h);
  2839. virtualCanvas->setBaseWnd(this);
  2840. virtualCanvasH = size_h; virtualCanvasW = size_w;
  2841. BaseWnd::getNonClientRect(&ncr);
  2842. deferedInvalidateRect(&ncr);
  2843. }
  2844. return 1;
  2845. }
  2846. Canvas *BaseWnd::createFrameBuffer(int w, int h)
  2847. {
  2848. return new BltCanvas(w, h, getOsWindowHandle());
  2849. }
  2850. void BaseWnd::prepareFrameBuffer(Canvas *canvas, int w, int h)
  2851. {
  2852. RECT r = {0, 0, w, h};
  2853. RegionI reg(&r);
  2854. virtualBeforePaint(&reg);
  2855. #ifdef _WIN32
  2856. canvas->selectClipRgn(NULL);
  2857. canvas->fillRect(&r, 0);
  2858. #elif defined(__APPLE__)
  2859. CGContextClearRect(canvas->getHDC(), CGRectInfinite); // TODO: make "clear" function in canvas
  2860. #endif
  2861. virtualAfterPaint(&reg);
  2862. }
  2863. void BaseWnd::deleteFrameBuffer(Canvas *canvas)
  2864. {
  2865. delete canvas;
  2866. }
  2867. // paints the client content, followed by the virtual child tree. recursive
  2868. int BaseWnd::paintTree(Canvas *canvas, api_region *r)
  2869. {
  2870. onPaint(canvas, r);
  2871. #ifdef WASABI_DRAW_FOCUS_RECT
  2872. if (gotFocus())
  2873. {
  2874. RECT ncr;
  2875. getNonClientRect(&ncr);
  2876. // try to use skinned focus rect
  2877. if (WASABI_API_WND->paintset_present(Paintset::FOCUSRECT))
  2878. WASABI_API_WND->paintset_render(Paintset::FOCUSRECT, canvas, &ncr, 128);
  2879. else // otherwise this looks kinda nice :P
  2880. canvas->drawRect(&ncr, 0, 0xFFFFFF, 128);
  2881. }
  2882. #endif
  2883. if (isVirtual() && !hasVirtualChildren()) return 0;
  2884. api_region *hostrgn = NULL;
  2885. api_region *update = r;
  2886. if (!(hwnd != NULL && getParent() == NULL))
  2887. {
  2888. hostrgn = getRegion();
  2889. update = r->clone();
  2890. if (hostrgn && !isRectRgn())
  2891. {
  2892. RECT ncr = clientRect();
  2893. api_region *hostclone = hostrgn->clone();
  2894. hostclone->addRegion(getComposedRegion());
  2895. hostclone->offset(ncr.left, ncr.top);
  2896. update->andRegion(hostclone);
  2897. hostrgn->disposeClone(hostclone);
  2898. }
  2899. }
  2900. RegionI client_update;
  2901. for (int i = 0;i < virtualChildren.getNumItems();i++)
  2902. {
  2903. if (!virtualChildren[i]->isVisible(1)) continue;
  2904. RECT rChild;
  2905. ifc_window *w = virtualChildren[i];
  2906. w->getNonClientRect(&rChild);
  2907. if ((rChild.right != rChild.left) && (rChild.bottom != rChild.top))
  2908. if (update->intersectRect(&rChild, &client_update))
  2909. {
  2910. w->paintTree(canvas, &client_update);
  2911. }
  2912. }
  2913. if (update != r) r->disposeClone(update);
  2914. return 1;
  2915. }
  2916. void BaseWnd::setVirtualCanvas(Canvas *c)
  2917. {
  2918. virtualCanvas = c;
  2919. }
  2920. int BaseWnd::pointInWnd(POINT *p)
  2921. {
  2922. RECT r;
  2923. if (!isVisible(1)) return 0;
  2924. getWindowRect(&r);
  2925. if (!Wasabi::Std::pointInRect(r, *p))
  2926. return 0;
  2927. for (int i = 0; i < getNumRootWndChildren(); i++)
  2928. {
  2929. ifc_window *c = enumRootWndChildren(i);
  2930. if (!c->isVisible(1)) continue;
  2931. RECT rChild;
  2932. c->getWindowRect(&rChild);
  2933. if (Wasabi::Std::pointInRect(rChild, *p))
  2934. return 0;
  2935. }
  2936. //NONPORTABLE
  2937. /* HWND child = GetWindow(getOsWindowHandle(), GW_CHILD);
  2938. while (child != NULL) {
  2939. if (IsWindowVisible(child)) {
  2940. RECT r2;
  2941. GetWindowRect(child, &r2);
  2942. if (Std::pointInRect(r2, *p))
  2943. return 0;
  2944. }
  2945. child = GetWindow(child, GW_HWNDNEXT);
  2946. }*/
  2947. return 1;
  2948. }
  2949. int BaseWnd::paint(Canvas *c, api_region *r)
  2950. {
  2951. if (isVirtual())
  2952. {
  2953. RegionI d;
  2954. RECT cr;
  2955. getClientRect(&cr);
  2956. if (r == NULL)
  2957. {
  2958. d.addRect(&cr);
  2959. }
  2960. else
  2961. {
  2962. d.addRegion(r);
  2963. d.offset(cr.left, cr.top);
  2964. }
  2965. ifc_window *rp = getRootParent();
  2966. deferedInvalidate();
  2967. rp->paint(NULL, &d);
  2968. BltCanvas *cc = static_cast<BltCanvas*>(rp->getFrameBuffer());
  2969. if (r != NULL) c->selectClipRgn(r);
  2970. cc->blit(cr.left, cr.top, c, 0, 0, cr.right - cr.left, cr.bottom - cr.top);
  2971. return 1;
  2972. }
  2973. if (!ensureVirtualCanvasOk()) return 0;
  2974. RegionI *deleteme = NULL;
  2975. if (r == NULL)
  2976. {
  2977. RECT cr;
  2978. getNonClientRect(&cr);
  2979. deleteme = new RegionI(&cr);
  2980. r = deleteme;
  2981. }
  2982. virtualBeforePaint(r);
  2983. RECT rcPaint;
  2984. r->getBox(&rcPaint);
  2985. double ra = getRenderRatio();
  2986. if (deferedInvalidRgn)
  2987. {
  2988. api_region *nr = NULL;
  2989. if (renderRatioActive())
  2990. {
  2991. nr = r->clone();
  2992. double d = 1.0 / ra;
  2993. nr->scale(d, d, TRUE);
  2994. }
  2995. if (deferedInvalidRgn->isEmpty() == 0)
  2996. {
  2997. // some deferednvalidated regions needs to be repainted
  2998. // TODO: need a "clear region" function in canvas
  2999. api_region *i = deferedInvalidRgn->clone();
  3000. #ifdef _WIN32
  3001. FillRgn(virtualCanvas->getHDC(), i->getOSHandle(), (HBRUSH)GetStockObject(BLACK_BRUSH));
  3002. #elif defined(__APPLE__)
  3003. CGContextSaveGState(virtualCanvas->getHDC());
  3004. virtualCanvas->selectClipRgn(i);
  3005. CGContextClearRect(virtualCanvas->getHDC(), CGRectInfinite);
  3006. // virtualCanvas->selectClipRgn(0);
  3007. CGContextRestoreGState(virtualCanvas->getHDC());
  3008. #endif
  3009. paintTree(virtualCanvas, i);
  3010. deferedValidateRgn(i);
  3011. deferedInvalidRgn->disposeClone(i);
  3012. }
  3013. if (nr) r->disposeClone(nr);
  3014. }
  3015. virtualAfterPaint(r);
  3016. if (c != NULL)
  3017. {
  3018. commitFrameBuffer(c, &rcPaint, ra); //TH WDP2-212
  3019. }
  3020. delete deleteme;
  3021. return 1;
  3022. }
  3023. int BaseWnd::virtualOnPaint()
  3024. {
  3025. #ifdef _WIN32
  3026. RECT cr;
  3027. getNonClientRect(&cr);
  3028. if (cr.left >= cr.right || cr.top >= cr.bottom) return 0;
  3029. if (!ensureVirtualCanvasOk()) return 0;
  3030. RegionI reg;
  3031. //CUT GetUpdateRgn(getOsWindowHandle(), r->getOSHandle(), FALSE);
  3032. Wasabi::Std::Wnd::getUpdateRegion(getOsWindowHandle(), reg.getOSHandle());
  3033. PaintCanvas paintcanvas;
  3034. if (!paintcanvas.beginPaint(this))
  3035. {
  3036. virtualAfterPaint(&reg); return 0;
  3037. }
  3038. // DO NOT DELETE - This looks like it does nothing, but it actually makes the GDI call us again with WM_PAINT if some window
  3039. // moves over this one between BeginPaint and EndPaint. We still use GetUpdateRgn so we don't have to check for
  3040. // the version of Windows. See doc. If this function is not available (should be here in 95/98/NT/2K, but we never know)
  3041. // then we use the rcPaint rect... less precise, but still works.
  3042. //CUT if (getRandomRgn) {
  3043. if (Wasabi::Std::Wnd::haveGetRandomRegion())
  3044. {
  3045. RegionI zap;
  3046. //CUT getRandomRgn(paintcanvas.getHDC(), zap.getOSHandle(), SYSRGN);
  3047. Wasabi::Std::Wnd::getRandomRegion(paintcanvas.getHDC(), zap.getOSHandle());
  3048. }
  3049. else
  3050. {
  3051. RECT z;
  3052. paintcanvas.getRcPaint(&z);
  3053. reg.setRect(&z);
  3054. }
  3055. // -------------
  3056. /*// for debug
  3057. HDC dc = GetDC(getOsWindowHandle());
  3058. InvertRgn(dc, r->getHRGN());
  3059. InvertRgn(dc, r->getHRGN());
  3060. ReleaseDC(getOsWindowHandle(), dc);*/
  3061. paint(&paintcanvas, &reg);
  3062. #else
  3063. #warning port me or remove me
  3064. #endif
  3065. return 1;
  3066. }
  3067. ifc_window *BaseWnd::enumVirtualChild(int _enum)
  3068. {
  3069. return virtualChildren[_enum];
  3070. }
  3071. int BaseWnd::getNumVirtuals()
  3072. {
  3073. return virtualChildren.getNumItems();
  3074. }
  3075. ifc_window *BaseWnd::enumRootWndChildren(int n)
  3076. {
  3077. return rootwndchildren.enumItem(n);
  3078. }
  3079. int BaseWnd::getNumRootWndChildren()
  3080. {
  3081. return rootwndchildren.getNumItems();
  3082. }
  3083. ifc_window *BaseWnd::findRootWndChild(int x, int y, int only_virtuals)
  3084. {
  3085. for (int i = getNumRootWndChildren() - 1; i > -1; i--)
  3086. {
  3087. RECT r;
  3088. ifc_window *child = enumRootWndChildren(i);
  3089. //DebugStringW(L"findRootWndChild = entering = %s\n", child->getId());
  3090. if (only_virtuals && !child->isVirtual()) continue;
  3091. child->getNonClientRect(&r);
  3092. int _x = x;
  3093. int _y = y;
  3094. if (!child->isVirtual())
  3095. {
  3096. POINT pt;
  3097. child->getPosition(&pt);
  3098. _x -= pt.x;
  3099. _y -= pt.y;
  3100. }
  3101. int iv = child->isVisible(1);
  3102. //int gpa = child->getPaintingAlpha();
  3103. POINT _p = Wasabi::Std::makePoint(_x, _y);
  3104. if (iv /*&& gpa > 0*/ && Wasabi::Std::pointInRect(r, _p))
  3105. {
  3106. // GROUP
  3107. ifc_window *z = child->findRootWndChild(_x, _y);
  3108. if (z) return z;
  3109. }
  3110. /*gpa > 0 &&*/
  3111. /*if (iv && _x>=r.left&&_x<=r.right&&_y>=r.top&&_y<=r.bottom && !child->isClickThrough() && child->ptInRegion(_x, _y)) {
  3112. return child;
  3113. }*/
  3114. }
  3115. return (!isClickThrough() && ptInRegion(x, y)) ? this : NULL;
  3116. }
  3117. //PORTME
  3118. int BaseWnd::handleVirtualChildMsg(UINT uMsg, int x, int y, void *p, void *d)
  3119. {
  3120. #ifdef _WIN32
  3121. ifc_window *child = NULL;
  3122. if (curVirtualChildCaptured)
  3123. child = curVirtualChildCaptured;
  3124. else
  3125. child = findRootWndChild(x, y, 1); // warning, can return this which is not virtual
  3126. // ASSERT(child != NULL); // BU this came up and I don't know why, looks like it should never happen
  3127. // FG> actually it can happen when coming back from a popup menu when cpu usage is high, the window might be
  3128. // hidden (destroying) and ptInRegion returns false.
  3129. if (!child) return 0;
  3130. //int isvirtual = child->isVirtual();
  3131. if (child) child = child->getForwardWnd();
  3132. if (child && child->isEnabled())
  3133. {
  3134. switch (uMsg)
  3135. {
  3136. case WM_LBUTTONDOWN:
  3137. /* if (isvirtual && child != curVirtualChildFocus)
  3138. focusVirtualChild(child);*/
  3139. autoFocus(child);
  3140. if (child->wantLeftClicks())
  3141. child->onLeftButtonDown(x, y);
  3142. if (child->checkDoubleClick(uMsg, x, y) && child->wantDoubleClicks())
  3143. child->onLeftButtonDblClk(x, y);
  3144. return 1;
  3145. case WM_RBUTTONDOWN:
  3146. /* if (isvirtual && child != curVirtualChildFocus)
  3147. focusVirtualChild(child);*/
  3148. autoFocus(child);
  3149. if (child->wantRightClicks())
  3150. child->onRightButtonDown(x, y);
  3151. if (child->checkDoubleClick(uMsg, x, y) && child->wantDoubleClicks())
  3152. child->onRightButtonDblClk(x, y);
  3153. return 1;
  3154. case WM_LBUTTONUP:
  3155. if (child->wantLeftClicks())
  3156. child->onLeftButtonUp(x, y);
  3157. return 1;
  3158. case WM_RBUTTONUP:
  3159. if (child->wantRightClicks())
  3160. child->onRightButtonUp(x, y);
  3161. return 1;
  3162. case WM_MOUSEMOVE:
  3163. {
  3164. if (curVirtualChildCaptured == child || (curVirtualChildCaptured == NULL))
  3165. {
  3166. if (child->wantMouseMoves())
  3167. child->onMouseMove(x, y);
  3168. return 1;
  3169. }
  3170. return 0;
  3171. }
  3172. case WM_MOUSEHOVER:
  3173. ((BaseWnd *)child)->onTip();
  3174. break;
  3175. case WM_SETCURSOR:
  3176. int a = child->getCursorType(x, y);
  3177. if (!p) return 0;
  3178. *(int *)p = a;
  3179. if (a == BASEWND_CURSOR_USERSET)
  3180. {
  3181. OSCURSORHANDLE c = child->getCustomCursor(x, y);
  3182. if (!d) return 0;
  3183. *(OSCURSORHANDLE *)d = c;
  3184. }
  3185. return 1;
  3186. }
  3187. }
  3188. #else
  3189. #warning port me or remove me
  3190. #endif
  3191. return 0;
  3192. }
  3193. int BaseWnd::onLeftButtonDown(int x, int y)
  3194. {
  3195. disable_tooltip_til_recapture = 1;
  3196. abortTip();
  3197. return 0;
  3198. }
  3199. int BaseWnd::onLeftButtonUp(int x, int y)
  3200. {
  3201. disable_tooltip_til_recapture = 1;
  3202. abortTip();
  3203. return 0;
  3204. }
  3205. void BaseWnd::setVirtualChildCapture(ifc_window *child)
  3206. {
  3207. if (child)
  3208. {
  3209. if (!inputCaptured)
  3210. {
  3211. beginCapture();
  3212. }
  3213. }
  3214. else
  3215. {
  3216. endCapture();
  3217. }
  3218. curVirtualChildCaptured = child;
  3219. }
  3220. ifc_window *BaseWnd::getVirtualChildCapture()
  3221. {
  3222. if (inputCaptured && Wasabi::Std::Wnd::getCapture() == getOsWindowHandle())
  3223. return curVirtualChildCaptured;
  3224. else
  3225. if (inputCaptured) inputCaptured = 0;
  3226. return NULL;
  3227. }
  3228. ifc_window *BaseWnd::getBaseTextureWindow()
  3229. {
  3230. // return our base texture window if we have it
  3231. if (btexture)
  3232. return btexture;
  3233. // return our parent's if they have it
  3234. if (getParent())
  3235. return getParent()->getBaseTextureWindow();
  3236. else
  3237. return NULL;
  3238. }
  3239. void BaseWnd::renderBaseTexture(ifc_canvas *c, const RECT &r, int alpha)
  3240. {
  3241. WASABI_API_WND->skin_renderBaseTexture(getBaseTextureWindow(), c, r, this, alpha);
  3242. }
  3243. void BaseWnd::setBaseTextureWindow(ifc_window *w)
  3244. {
  3245. btexture = w;
  3246. }
  3247. void BaseWnd::setNotifyWindow(ifc_window *newnotify)
  3248. {
  3249. notifyWindow = newnotify;
  3250. }
  3251. ifc_window *BaseWnd::getNotifyWindow()
  3252. {
  3253. return destroying ? NULL : notifyWindow;
  3254. }
  3255. int BaseWnd::gotFocus()
  3256. {
  3257. return hasfocus && curVirtualChildFocus == NULL;
  3258. }
  3259. int BaseWnd::isActive()
  3260. {
  3261. OSWINDOWHANDLE h = hwnd;
  3262. if (h == NULL)
  3263. {
  3264. ifc_window *par = getParent();
  3265. if (par == NULL) return 0;
  3266. h = par->getOsWindowHandle();
  3267. }
  3268. if (h == NULL) return 0;
  3269. return (Wasabi::Std::Wnd::getActiveWindow() == h);
  3270. }
  3271. int BaseWnd::onChar(unsigned int c)
  3272. {
  3273. switch (c)
  3274. {
  3275. case 9: // TAB
  3276. if (Std::keyModifier(STDKEY_SHIFT))
  3277. focusPrevious();
  3278. else
  3279. focusNext();
  3280. return 1;
  3281. }
  3282. return 0;
  3283. }
  3284. /*int BaseWnd::focusVirtualChild(api_window *child) {
  3285. if (!gotFocus()) setFocus();
  3286. if (!child->wantFocus()) return 0;
  3287. setVirtualChildFocus(child);
  3288. return 1;
  3289. }*/
  3290. int BaseWnd::wantFocus()
  3291. {
  3292. return 0;
  3293. }
  3294. // Return 1 if there is a modal window that is not this
  3295. int BaseWnd::checkModal()
  3296. {
  3297. if (bypassModal()) return 0;
  3298. ifc_window *w = WASABI_API_WND->getModalWnd();
  3299. if (w && w != static_cast<ifc_window*>(this) && w != getDesktopParent())
  3300. {
  3301. return 1;
  3302. }
  3303. return 0;
  3304. }
  3305. int BaseWnd::cascadeRepaintFrom(ifc_window *who, int pack)
  3306. {
  3307. RECT r;
  3308. BaseWnd::getNonClientRect(&r);
  3309. return BaseWnd::cascadeRepaintRect(&r, pack);
  3310. }
  3311. int BaseWnd::cascadeRepaint(int pack)
  3312. {
  3313. return cascadeRepaintFrom(this, pack);
  3314. }
  3315. int BaseWnd::cascadeRepaintRgn(api_region *r, int pack)
  3316. {
  3317. return cascadeRepaintRgnFrom(r, this, pack);
  3318. }
  3319. int BaseWnd::cascadeRepaintRect(RECT *r, int pack)
  3320. {
  3321. return cascadeRepaintRectFrom(r, this, pack);
  3322. }
  3323. int BaseWnd::cascadeRepaintRectFrom(RECT *r, ifc_window *who, int pack)
  3324. {
  3325. RegionI reg(r);
  3326. int rt = cascadeRepaintRgnFrom(&reg, who, pack);
  3327. return rt;
  3328. }
  3329. void BaseWnd::_cascadeRepaintRgn(api_region *rg)
  3330. {
  3331. if (!ensureVirtualCanvasOk()) return ;
  3332. WndCanvas paintcanvas;
  3333. if (paintcanvas.attachToClient(this) == 0)
  3334. return;
  3335. virtualBeforePaint(rg);
  3336. deferedInvalidateRgn(rg);
  3337. paintTree(virtualCanvas, rg);
  3338. virtualAfterPaint(rg);
  3339. double ra = getRenderRatio();
  3340. RECT rcPaint;
  3341. rg->getBox(&rcPaint);
  3342. RECT rc;
  3343. getClientRect(&rc); //JF> this gets it in virtual (non-scaled) coordinates,
  3344. // so we need to do these comparisons before scaling.
  3345. rcPaint.bottom = MIN((int)rc.bottom, (int)rcPaint.bottom);
  3346. rcPaint.right = MIN((int)rc.right, (int)rcPaint.right);
  3347. if (renderRatioActive()) // probably faster than scaling the clone
  3348. {
  3349. rcPaint.left = (int)((rcPaint.left - 1) * ra);
  3350. rcPaint.top = (int)((rcPaint.top - 1) * ra);
  3351. rcPaint.right = (int)(rcPaint.right * ra + 0.999999);
  3352. rcPaint.bottom = (int)(rcPaint.bottom * ra + 0.999999);
  3353. }
  3354. rcPaint.left = MAX(0, (int)rcPaint.left);
  3355. rcPaint.top = MAX(0, (int)rcPaint.top);
  3356. rcPaint.right = MIN((int)rcPaint.right, (int)(rwidth * ra));
  3357. rcPaint.bottom = MIN((int)rcPaint.bottom, (int)(rheight * ra));
  3358. commitFrameBuffer(&paintcanvas, &rcPaint, ra);
  3359. }
  3360. void BaseWnd::packCascadeRepaintRgn(api_region *rg)
  3361. {
  3362. if (!deferedCascadeRepaintRgn) deferedCascadeRepaintRgn = new RegionI;
  3363. deferedCascadeRepaintRgn->addRegion(rg);
  3364. need_flush_cascaderepaint = 1;
  3365. }
  3366. int BaseWnd::cascadeRepaintRgnFrom(api_region *_rg, ifc_window *who, int pack)
  3367. {
  3368. api_region *rg = _rg->clone();
  3369. int j = virtualChildren.searchItem(who);
  3370. for (int i = 0; i < virtualChildren.getNumItems(); i++)
  3371. {
  3372. ifc_window *w = virtualChildren[i];
  3373. if (w != who && w->wantSiblingInvalidations())
  3374. w->onSiblingInvalidateRgn(rg, who, j, i);
  3375. }
  3376. if (!pack)
  3377. {
  3378. _cascadeRepaintRgn(rg);
  3379. }
  3380. else
  3381. {
  3382. packCascadeRepaintRgn(rg);
  3383. }
  3384. _rg->disposeClone(rg);
  3385. return 1;
  3386. }
  3387. void BaseWnd::setDesktopAlpha(int a)
  3388. {
  3389. if (a && !Wasabi::Std::Wnd::isDesktopAlphaAvailable()) return ;
  3390. if (a == w2k_alpha) return ;
  3391. w2k_alpha = a;
  3392. if (!a && scalecanvas)
  3393. {
  3394. delete scalecanvas;
  3395. scalecanvas = NULL;
  3396. }
  3397. setLayeredWindow(w2k_alpha);
  3398. onSetDesktopAlpha(a);
  3399. }
  3400. void BaseWnd::onSetDesktopAlpha(int a) { }
  3401. void BaseWnd::commitFrameBuffer(Canvas *paintcanvas, RECT *r, double ra)
  3402. {
  3403. if (w2k_alpha && Wasabi::Std::Wnd::isDesktopAlphaAvailable() && !cloaked)
  3404. {
  3405. //CUT BLENDFUNCTION blend= {AC_SRC_OVER, 0, wndalpha, AC_SRC_ALPHA };
  3406. //CUT POINT pt={0,0};
  3407. RECT spr;
  3408. getWindowRect(&spr);
  3409. //CUT POINT sp={spr.left,spr.top};
  3410. //CUT SIZE ss={spr.right-spr.left, spr.bottom-spr.top};
  3411. int sw = spr.right - spr.left, sh = spr.bottom - spr.top;
  3412. //CUT SysCanvas c;
  3413. if (handleRatio() && renderRatioActive())
  3414. {
  3415. // eek slow!
  3416. RECT r;
  3417. getWindowRect(&r);
  3418. int w = r.right - r.left;
  3419. int h = r.bottom - r.top;
  3420. if (!scalecanvas) scalecanvas = new BltCanvas(w, h, getOsWindowHandle());
  3421. virtualCanvas->stretchblit(0, 0, (int)((double)virtualCanvasW * 65536.0), (int)((double)virtualCanvasH * 65536.0), scalecanvas, 0, 0, w, h);
  3422. }
  3423. //CUT updateLayeredWindow(hwnd, c.getHDC(), &sp, &ss, (scalecanvas ? scalecanvas : virtualCanvas)->getHDC(), &pt, 0, &blend, ULW_ALPHA);
  3424. Wasabi::Std::Wnd::updateLayeredWnd(hwnd, spr.left, spr.top, sw, sh, (scalecanvas ? scalecanvas : virtualCanvas)->getHDC(), wndalpha);
  3425. }
  3426. else
  3427. {
  3428. if (ABS(ra - 1.0) <= 0.01)
  3429. {
  3430. virtualCanvas->blit(r->left, r->top, paintcanvas, r->left, r->top, r->right - r->left, r->bottom - r->top);
  3431. }
  3432. else
  3433. {
  3434. RECT tr = *r;
  3435. double invra = 65536.0 / ra;
  3436. int lp = tr.left;
  3437. int tp = tr.top;
  3438. int w = tr.right - tr.left;
  3439. int h = tr.bottom - tr.top;
  3440. int sx = (int)((double)lp * invra);
  3441. int sy = (int)((double)tp * invra);
  3442. int sw = (int)((double)w * invra);
  3443. int sh = (int)((double)h * invra);
  3444. virtualCanvas->stretchblit(sx, sy, sw, sh, paintcanvas, lp, tp, w, h);
  3445. }
  3446. }
  3447. }
  3448. void BaseWnd::flushPaint()
  3449. {
  3450. postDeferredCallback(DEFERREDCB_FLUSHPAINT, 0);
  3451. }
  3452. void BaseWnd::do_flushPaint()
  3453. {
  3454. if (!deferedInvalidRgn || deferedInvalidRgn->isEmpty()) return ;
  3455. api_region *r = deferedInvalidRgn->clone();
  3456. cascadeRepaintRgn(r);
  3457. deferedInvalidRgn->disposeClone(r);
  3458. deferedInvalidRgn->empty();
  3459. }
  3460. int BaseWnd::isMouseOver(int x, int y)
  3461. {
  3462. POINT pt = {x, y};
  3463. clientToScreen(&pt);
  3464. return (WASABI_API_WND->rootWndFromPoint(&pt) == this);
  3465. }
  3466. void BaseWnd::freeResources()
  3467. {}
  3468. void BaseWnd::reloadResources()
  3469. {
  3470. invalidate();
  3471. }
  3472. double BaseWnd::getRenderRatio()
  3473. {
  3474. if (!handleRatio()) return 1.0;
  3475. if (!ratiolinked) return ratio;
  3476. return getParent() ? getParent()->getRenderRatio() : ratio;
  3477. }
  3478. void BaseWnd::setRenderRatio(double r)
  3479. {
  3480. // "snap" to 1.0
  3481. if (ABS(r - 1.0) <= 0.02f) r = 1.0;
  3482. if (scalecanvas)
  3483. {
  3484. delete scalecanvas;
  3485. scalecanvas = NULL;
  3486. }
  3487. if (isInited() && r != ratio && !isVirtual() && (!getParent() || !ratiolinked))
  3488. {
  3489. // must scale size & region accordingly
  3490. RECT rc;
  3491. BaseWnd::getWindowRect(&rc);
  3492. rc.right = rc.left + rwidth;
  3493. rc.bottom = rc.top + rheight;
  3494. ratio = r;
  3495. resize(&rc);
  3496. invalidate();
  3497. if (isPostOnInit())
  3498. onRatioChanged();
  3499. }
  3500. }
  3501. void BaseWnd::setRatioLinked(int l)
  3502. {
  3503. ratiolinked = l;
  3504. if (isPostOnInit())
  3505. setRenderRatio(ratio);
  3506. }
  3507. int BaseWnd::renderRatioActive()
  3508. {
  3509. return ABS(getRenderRatio() - 1.0) > 0.01f;
  3510. }
  3511. void BaseWnd::multRatio(int *x, int *y)
  3512. {
  3513. double rr = getRenderRatio();
  3514. if (x) *x = (int)((double)(*x) * rr);
  3515. if (y) *y = (int)((double)(*y) * rr);
  3516. }
  3517. void BaseWnd::multRatio(RECT *r)
  3518. {
  3519. Wasabi::Std::scaleRect(r, getRenderRatio());
  3520. }
  3521. void BaseWnd::divRatio(int *x, int *y)
  3522. {
  3523. double rr = getRenderRatio();
  3524. if (x) *x = (int)((double)(*x) / rr + 0.5);
  3525. if (y) *y = (int)((double)(*y) / rr + 0.5);
  3526. }
  3527. void BaseWnd::divRatio(RECT *r)
  3528. {
  3529. double rr = getRenderRatio();
  3530. Wasabi::Std::scaleRect(r, 1./rr);
  3531. }
  3532. void BaseWnd::bringVirtualToFront(ifc_window *w)
  3533. {
  3534. changeChildZorder(w, 0);
  3535. }
  3536. void BaseWnd::bringVirtualToBack(ifc_window *w)
  3537. {
  3538. changeChildZorder(w, virtualChildren.getNumItems()-1);
  3539. }
  3540. void BaseWnd::bringVirtualAbove(ifc_window *w, ifc_window *b)
  3541. {
  3542. ASSERT(b->isVirtual());
  3543. int p = virtualChildren.searchItem(b);
  3544. if (p == -1) return ;
  3545. changeChildZorder(w, p);
  3546. }
  3547. void BaseWnd::bringVirtualBelow(ifc_window *w, ifc_window *b)
  3548. {
  3549. ASSERT(b->isVirtual());
  3550. int p = virtualChildren.searchItem(b);
  3551. if (p == -1) return ;
  3552. changeChildZorder(w, p + 1);
  3553. }
  3554. void BaseWnd::changeChildZorder(ifc_window *w, int newpos)
  3555. {
  3556. int p = newpos;
  3557. p = MAX(p, (int)0);
  3558. p = MIN(p, virtualChildren.getNumItems()-1);
  3559. RECT cr;
  3560. w->getClientRect(&cr);
  3561. PtrList<ifc_window> l;
  3562. int i;
  3563. for (i = 0;i < virtualChildren.getNumItems();i++)
  3564. if (virtualChildren[i] != w)
  3565. l.addItem(virtualChildren[i]);
  3566. p = virtualChildren.getNumItems() - newpos - 1;
  3567. virtualChildren.removeAll();
  3568. int done = 0;
  3569. for (i = 0;i < l.getNumItems();i++)
  3570. if (i == p && !done)
  3571. {
  3572. virtualChildren.addItem(w);
  3573. i--;
  3574. done++;
  3575. }
  3576. else
  3577. {
  3578. RECT dr, intersection;
  3579. l.enumItem(i)->getClientRect(&dr);
  3580. if (Wasabi::Std::rectIntersect(intersection, dr, &cr))
  3581. l[i]->invalidateRect(&intersection);
  3582. virtualChildren.addItem(l.enumItem(i));
  3583. }
  3584. if (i == p && !done)
  3585. virtualChildren.addItem(w);
  3586. w->invalidate();
  3587. }
  3588. int BaseWnd::onActivate()
  3589. {
  3590. if (hasVirtualChildren())
  3591. {
  3592. int l = getNumVirtuals();
  3593. for (int i = 0; i < l; i++)
  3594. {
  3595. ifc_window *r = enumVirtualChild(i);
  3596. r->onActivate();
  3597. }
  3598. }
  3599. return 0;
  3600. }
  3601. int BaseWnd::onDeactivate()
  3602. {
  3603. if (hasVirtualChildren())
  3604. {
  3605. int l = getNumVirtuals();
  3606. for (int i = 0; i < l; i++)
  3607. {
  3608. ifc_window *r = enumVirtualChild(i);
  3609. r->onDeactivate();
  3610. }
  3611. }
  3612. return 0;
  3613. }
  3614. int BaseWnd::getDesktopAlpha()
  3615. {
  3616. return w2k_alpha;
  3617. }
  3618. api_region *BaseWnd::getRegion()
  3619. {
  3620. return NULL;
  3621. }
  3622. //CUT int BaseWnd::isTransparencyAvailable() {
  3623. //CUT #ifdef WIN32
  3624. //CUT #else
  3625. //CUT #pragma warning port me!
  3626. //CUT #endif
  3627. //CUT return 0;
  3628. //CUT }
  3629. int BaseWnd::handleTransparency()
  3630. {
  3631. return 1; // by default all windows handle transparency, only windows blitting directly on the SCREEN (if you blit directly on the DC it's still ok),
  3632. } // for instance, a vis or a video using overlay should return 0, this will let the layout auto manage its alpha as that window is shown/hiden
  3633. void BaseWnd::setAlpha(int active, int inactive)
  3634. {
  3635. if (active == 254) active = 255;
  3636. if (active == 1) active = 0;
  3637. if (inactive == 254) inactive = 255;
  3638. if (inactive == 1) inactive = 0;
  3639. int oldactivealpha = activealpha;
  3640. active = MIN(255, MAX(0, active));
  3641. if (inactive != -1) inactive = MIN(255, MAX(0, inactive));
  3642. if (active != activealpha)
  3643. {
  3644. activealpha = active;
  3645. if (isActive())
  3646. {
  3647. invalidate();
  3648. if ((oldactivealpha == 0 || activealpha == 0) && (oldactivealpha != 0 || activealpha != 0))
  3649. invalidateWindowRegion();
  3650. }
  3651. }
  3652. if (inactive == -1) inactive = active;
  3653. if (inactive != inactivealpha)
  3654. {
  3655. inactivealpha = inactive;
  3656. if (!isActive())
  3657. {
  3658. invalidate();
  3659. if ((oldactivealpha == 0 || activealpha == 0) && (oldactivealpha != 0 || activealpha != 0))
  3660. invalidateWindowRegion();
  3661. }
  3662. }
  3663. }
  3664. void BaseWnd::getAlpha(int *active, int *inactive)
  3665. {
  3666. if (active) *active = activealpha;
  3667. if (inactive) *inactive = inactivealpha;
  3668. }
  3669. int BaseWnd::getPaintingAlpha(void)
  3670. {
  3671. int a = isActive() ? MIN(255, MAX(0, activealpha)) : MIN(255, MAX(0, inactivealpha));
  3672. ASSERT(a >= 0 && a <= 255);
  3673. if (getParent() && getParent()->isVirtual())
  3674. {
  3675. int b = getParent()->getPaintingAlpha();
  3676. a = (int)((double)a / 255.0 * (double)b);
  3677. }
  3678. if (a == 254) a = 255;
  3679. if (a == 1) a = 0;
  3680. if (!isEnabled()) a = (int)(a*0.6);
  3681. return a;
  3682. }
  3683. void BaseWnd::setClickThrough(int ct)
  3684. {
  3685. clickthrough = ct;
  3686. }
  3687. int BaseWnd::isClickThrough()
  3688. {
  3689. return clickthrough;
  3690. }
  3691. int BaseWnd::handleRatio()
  3692. {
  3693. return 1;
  3694. }
  3695. #include <api/script/objects/c_script/c_rootobj.h>
  3696. int BaseWnd::createTip()
  3697. {
  3698. destroyTip();
  3699. tooltip = new Tooltip(getTip());
  3700. return -1;
  3701. }
  3702. void BaseWnd::destroyTip()
  3703. {
  3704. // this is to avoid pb if destroytip() is being called by a time while destroying tip
  3705. Tooltip *tt = tooltip;
  3706. tooltip = NULL;
  3707. delete tt;
  3708. }
  3709. int BaseWnd::runModal()
  3710. {
  3711. //PORTME
  3712. #ifdef _WIN32
  3713. ifc_window *dp = getDesktopParent();
  3714. if (dp && dp != this)
  3715. return dp->runModal();
  3716. MSG msg;
  3717. // SetCapture(NULL);
  3718. SetFocus(getOsWindowHandle());
  3719. WASABI_API_WND->pushModalWnd(this);
  3720. returnvalue = 0;
  3721. mustquit = 0;
  3722. // Main message loop:
  3723. while (!mustquit)
  3724. {
  3725. mustquit = !GetMessage(&msg, NULL, 0, 0);
  3726. if (!msg.hwnd || !TranslateAccelerator(msg.hwnd, NULL, &msg))
  3727. {
  3728. TranslateMessage(&msg);
  3729. DispatchMessage(&msg);
  3730. }
  3731. }
  3732. WASABI_API_WND->popModalWnd(this);
  3733. // SetCapture(NULL);
  3734. return returnvalue;
  3735. #else
  3736. #warning port me
  3737. return 0;
  3738. #endif
  3739. }
  3740. void BaseWnd::endModal(int ret)
  3741. {
  3742. ifc_window *dp = getDesktopParent();
  3743. if (dp && dp != this)
  3744. {
  3745. dp->endModal(ret);
  3746. return ;
  3747. }
  3748. returnvalue = ret;
  3749. mustquit = 1;
  3750. }
  3751. int BaseWnd::wantAutoContextMenu()
  3752. {
  3753. return 1;
  3754. }
  3755. void BaseWnd::onCancelCapture()
  3756. {}
  3757. ifc_window *BaseWnd::getNextVirtualFocus(ifc_window *w)
  3758. {
  3759. if (w == NULL)
  3760. {
  3761. if (childtabs.getNumItems() > 0)
  3762. return childtabs.getFirst()->wnd;
  3763. }
  3764. int a = getTabOrderEntry(w) + 1;
  3765. if (a < childtabs.getNumItems())
  3766. return childtabs.enumItem(a)->wnd;
  3767. return NULL;
  3768. }
  3769. void BaseWnd::setVirtualChildFocus(ifc_window *w)
  3770. {
  3771. ASSERT(w && w->isVirtual());
  3772. if (curVirtualChildFocus)
  3773. curVirtualChildFocus->onKillFocus();
  3774. curVirtualChildFocus = w;
  3775. onSetRootFocus(w);
  3776. Wasabi::Std::Wnd::setFocus(getOsWindowHandle());
  3777. if (curVirtualChildFocus)
  3778. curVirtualChildFocus->onGetFocus();
  3779. }
  3780. int BaseWnd::ptInRegion(int x, int y)
  3781. {
  3782. RECT cr;
  3783. getNonClientRect(&cr);
  3784. POINT pt = {x - cr.left, y - cr.top};
  3785. api_region *reg = getRegion();
  3786. if (isRectRgn())
  3787. return (x >= cr.left && x <= cr.right && y >= cr.top && y <= cr.bottom);
  3788. return reg ? reg->ptInRegion(&pt) : 0;
  3789. }
  3790. api_region *BaseWnd::getComposedRegion()
  3791. {
  3792. ensureWindowRegionValid();
  3793. return composedrgn;
  3794. }
  3795. api_region *BaseWnd::getSubtractorRegion()
  3796. {
  3797. ensureWindowRegionValid();
  3798. return subtractorrgn;
  3799. }
  3800. int BaseWnd::ensureWindowRegionValid()
  3801. {
  3802. if (!isInited()) return 0;
  3803. if (wndregioninvalid)
  3804. {
  3805. computeComposedRegion();
  3806. return 1;
  3807. }
  3808. return 0;
  3809. }
  3810. void BaseWnd::invalidateWindowRegion()
  3811. {
  3812. wndregioninvalid = 1;
  3813. if (getParent()) getParent()->invalidateWindowRegion();
  3814. }
  3815. void BaseWnd::computeComposedRegion()
  3816. {
  3817. if (!isPostOnInit()) return ;
  3818. wndregioninvalid = 0;
  3819. RECT r;
  3820. getNonClientRect(&r);
  3821. api_region *reg = getRegion();
  3822. RegionI *_reg = NULL;
  3823. if (!reg)
  3824. {
  3825. _reg = new RegionI;
  3826. reg = _reg;
  3827. if (isRectRgn())
  3828. reg->setRect(&r);
  3829. }
  3830. else
  3831. if (isRectRgn())
  3832. reg->setRect(&r);
  3833. api_region *wr = reg->clone();
  3834. if (!subtractorrgn) subtractorrgn = new RegionI();
  3835. subtractorrgn->empty();
  3836. if (!composedrgn) composedrgn = new RegionI;
  3837. composedrgn->empty();
  3838. RegionI *subme = NULL;
  3839. RegionI *andme = NULL;
  3840. RegionI *orme = NULL;
  3841. // if subregion is now empty, we need to only use our region
  3842. RECT gr;
  3843. getNonClientRect(&gr);
  3844. for (int i = 0;i < virtualChildren.getNumItems();i++)
  3845. {
  3846. ifc_window *srw = virtualChildren.enumItem(i);
  3847. if (!srw->isVisible(1) || srw->getPaintingAlpha() == 0) continue;
  3848. if (srw->getRegionOp() != REGIONOP_NONE)
  3849. {
  3850. api_region *sr = srw->getComposedRegion();
  3851. if (sr)
  3852. {
  3853. api_region *osr = sr->clone();
  3854. RECT r;
  3855. srw->getNonClientRect(&r);
  3856. r.left -= gr.left;
  3857. r.top -= gr.top;
  3858. osr->offset(r.left, r.top);
  3859. /* sr->debug();
  3860. osr->debug();*/
  3861. if (srw->getRegionOp() == REGIONOP_OR)
  3862. {
  3863. if (!orme) orme = new RegionI;
  3864. orme->addRegion(osr);
  3865. }
  3866. else if (srw->getRegionOp() == REGIONOP_AND)
  3867. {
  3868. if (!andme) andme = new RegionI;
  3869. andme->addRegion(osr);
  3870. }
  3871. else if (srw->getRegionOp() == REGIONOP_SUB)
  3872. {
  3873. if (!subme) subme = new RegionI;
  3874. subme->addRegion(osr);
  3875. }
  3876. else if (srw->getRegionOp() == REGIONOP_SUB2)
  3877. {
  3878. if (!subme) subme = new RegionI;
  3879. subtractorrgn->addRegion(osr);
  3880. }
  3881. sr->disposeClone(osr);
  3882. }
  3883. }
  3884. api_region *sr = srw->getSubtractorRegion();
  3885. if (sr != NULL && !sr->isEmpty())
  3886. {
  3887. api_region *osr = sr->clone();
  3888. RECT r;
  3889. srw->getNonClientRect(&r);
  3890. r.left -= gr.left;
  3891. r.top -= gr.top;
  3892. osr->offset(r.left, r.top);
  3893. subtractorrgn->addRegion(osr);
  3894. sr->disposeClone(osr);
  3895. }
  3896. }
  3897. if (andme)
  3898. {
  3899. wr->andRegion(andme);
  3900. delete andme;
  3901. }
  3902. if (orme)
  3903. {
  3904. wr->addRegion(orme);
  3905. delete orme;
  3906. }
  3907. if (subme)
  3908. {
  3909. wr->subtractRgn(subme);
  3910. delete subme;
  3911. }
  3912. composedrgn->addRegion(wr);
  3913. reg->disposeClone(wr);
  3914. delete _reg;
  3915. }
  3916. void BaseWnd::updateWindowRegion()
  3917. {
  3918. if (!isPostOnInit() || isVirtual()) return ;
  3919. if (getDesktopAlpha())
  3920. {
  3921. // if desktopalpha is on, we can't use regions (thanks MS), we have to rely on the framebuffer correctness
  3922. //CUT SetWindowRgn(getOsWindowHandle(), NULL, FALSE);
  3923. Wasabi::Std::Wnd::setWndRegion(getOsWindowHandle(), NULL);
  3924. return ;
  3925. }
  3926. api_region *_r = getComposedRegion();
  3927. api_region *_s = getSubtractorRegion();
  3928. ASSERT(_r != NULL && _s != NULL);
  3929. api_region *z = _r->clone();
  3930. z->subtractRgn(_s);
  3931. assignWindowRegion(z);
  3932. _r->disposeClone(z);
  3933. }
  3934. // wr is NOT scaled!!!
  3935. void BaseWnd::assignWindowRegion(api_region *wr)
  3936. {
  3937. ASSERT(wr != NULL);
  3938. if (!isPostOnInit()) return ;
  3939. int isrect = wr->isRect();
  3940. RECT r;
  3941. BaseWnd::getWindowRect(&r);
  3942. //DebugStringW( L"\nBaseWnd::assignWindowRegion() r before - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
  3943. r.right -= r.left;
  3944. r.left = 0;
  3945. r.bottom -= r.top;
  3946. r.top = 0;
  3947. //DebugStringW( L"BaseWnd::assignWindowRegion() r after - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
  3948. RECT z;
  3949. wr->getBox(&z);
  3950. //DebugStringW( L"BaseWnd::assignWindowRegion() z before - x = %d, y = %d, w = %d, h = %d \n", z.left, z.top, z.right - z.left, z.bottom - z.top );
  3951. z.left = 0;
  3952. z.top = 0;
  3953. //DebugStringW( L"BaseWnd::assignWindowRegion() z after - x = %d, y = %d, w = %d, h = %d \n", z.left, z.top, z.right - z.left, z.bottom - z.top );
  3954. if (renderRatioActive())
  3955. {
  3956. double i = getRenderRatio();
  3957. wr->scale(i, i, FALSE);
  3958. }
  3959. RECT sz;
  3960. wr->getBox(&sz);
  3961. //DebugStringW( L"BaseWnd::assignWindowRegion() sz before - x = %d, y = %d, w = %d, h = %d \n", sz.left, sz.top, sz.right - sz.left, sz.bottom - sz.top );
  3962. sz.right -= sz.left;
  3963. sz.bottom -= sz.top;
  3964. sz.left = 0;
  3965. sz.top = 0;
  3966. //DebugStringW( L"BaseWnd::assignWindowRegion() sz after - x = %d, y = %d, w = %d, h = %d \n", sz.left, sz.top, sz.right - sz.left, sz.bottom - sz.top );
  3967. if (isrect &&
  3968. ((z.right == rwidth && z.bottom == rheight) ||
  3969. (sz.left == r.left && sz.right == r.right && sz.top == r.top && sz.bottom == r.bottom) ||
  3970. (0)
  3971. )
  3972. )
  3973. {
  3974. //CUT SetWindowRgn(getOsWindowHandle(), NULL, TRUE);
  3975. if (!lastnullregion)
  3976. {
  3977. Wasabi::Std::Wnd::setWndRegion(getOsWindowHandle(), NULL, TRUE);
  3978. lastnullregion = 1;
  3979. }
  3980. }
  3981. else
  3982. {
  3983. //DebugStringW(L"setting region, rwidth = %d, rheight = %d, z.right = %d, z.bottom = %d\n", rwidth, rheight, z.right, z.bottom);
  3984. //CUT SetWindowRgn(getOsWindowHandle(), wr->makeWindowRegion(), TRUE);
  3985. Wasabi::Std::Wnd::setWndRegion(getOsWindowHandle(), wr->makeWindowRegion(), TRUE);
  3986. lastnullregion = 0;
  3987. }
  3988. }
  3989. void BaseWnd::performBatchProcesses()
  3990. {
  3991. // recompute the window region if needed and apply it to the HWND
  3992. if (wndregioninvalid && !isVirtual())
  3993. if (ensureWindowRegionValid())
  3994. updateWindowRegion();
  3995. if (need_flush_cascaderepaint)
  3996. {
  3997. _cascadeRepaintRgn(deferedCascadeRepaintRgn);
  3998. deferedCascadeRepaintRgn->empty();
  3999. need_flush_cascaderepaint = 0;
  4000. }
  4001. }
  4002. int BaseWnd::getRegionOp()
  4003. {
  4004. return regionop;
  4005. }
  4006. void BaseWnd::setRegionOp(int op)
  4007. {
  4008. if (regionop != op)
  4009. {
  4010. regionop = op;
  4011. invalidateWindowRegion();
  4012. }
  4013. }
  4014. int BaseWnd::isRectRgn()
  4015. {
  4016. return rectrgn;
  4017. }
  4018. void BaseWnd::setRectRgn(int i)
  4019. {
  4020. rectrgn = i;
  4021. }
  4022. TimerClient *BaseWnd::timerclient_getMasterClient()
  4023. {
  4024. if (!isVirtual()) return this;
  4025. ifc_window *w = getParent();
  4026. if (w)
  4027. {
  4028. TimerClient *tc = w->getTimerClient();
  4029. if (tc)
  4030. return tc->timerclient_getMasterClient();
  4031. }
  4032. return NULL;
  4033. }
  4034. void BaseWnd::timerclient_onMasterClientMultiplex()
  4035. {
  4036. performBatchProcesses();
  4037. }
  4038. TimerClient *BaseWnd::getTimerClient()
  4039. {
  4040. return this;
  4041. }
  4042. ifc_dependent *BaseWnd::rootwnd_getDependencyPtr()
  4043. {
  4044. return this;
  4045. }
  4046. ifc_dependent *BaseWnd::timerclient_getDependencyPtr()
  4047. {
  4048. return this;
  4049. }
  4050. void BaseWnd::addMinMaxEnforcer(ifc_window *w)
  4051. {
  4052. minmaxEnforcers.addItem(w);
  4053. signalMinMaxEnforcerChanged();
  4054. }
  4055. void BaseWnd::removeMinMaxEnforcer(ifc_window *w)
  4056. {
  4057. minmaxEnforcers.removeItem(w);
  4058. signalMinMaxEnforcerChanged();
  4059. }
  4060. void BaseWnd::signalMinMaxEnforcerChanged(void)
  4061. {
  4062. ifc_window *w = getDesktopParent();
  4063. if (w == NULL || w == this) onMinMaxEnforcerChanged();
  4064. else w->signalMinMaxEnforcerChanged();
  4065. }
  4066. int BaseWnd::getNumMinMaxEnforcers()
  4067. {
  4068. return minmaxEnforcers.getNumItems();
  4069. }
  4070. ifc_window *BaseWnd::enumMinMaxEnforcer(int n)
  4071. {
  4072. return minmaxEnforcers.enumItem(n);
  4073. }
  4074. int BaseWnd::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
  4075. {
  4076. return 1;
  4077. }
  4078. int BaseWnd::sendAction(ifc_window *target, const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen)
  4079. {
  4080. ASSERT(target != NULL);
  4081. return target->onAction(action, param, x, y, p1, p2, data, datalen, this);
  4082. }
  4083. int BaseWnd::virtualBeforePaint(api_region *r)
  4084. {
  4085. if (!virtualCanvas) return 0;
  4086. PaintCallbackInfoI pc(virtualCanvas, r);
  4087. dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_ONPAINT, PaintCallback::BEFOREPAINT, &pc);
  4088. return 1;
  4089. }
  4090. int BaseWnd::virtualAfterPaint(api_region *r)
  4091. {
  4092. if (!virtualCanvas) return 0;
  4093. PaintCallbackInfoI pc(virtualCanvas, r);
  4094. dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_ONPAINT, PaintCallback::AFTERPAINT, &pc);
  4095. return 1;
  4096. }
  4097. int BaseWnd::timerclient_onDeferredCallback(intptr_t p1, intptr_t p2)
  4098. {
  4099. TimerClientI::timerclient_onDeferredCallback(p1, p2);
  4100. return onDeferredCallback(p1, p2);
  4101. }
  4102. void BaseWnd::timerclient_timerCallback(int id)
  4103. {
  4104. TimerClientI::timerclient_timerCallback(id);
  4105. timerCallback(id);
  4106. }
  4107. int BaseWnd::setTimer(int id, int ms)
  4108. {
  4109. return timerclient_setTimer(id, ms);
  4110. }
  4111. int BaseWnd::killTimer(int id)
  4112. {
  4113. return timerclient_killTimer(id);
  4114. }
  4115. void BaseWnd::postDeferredCallback(intptr_t p1, intptr_t p2, int mindelay)
  4116. {
  4117. #ifdef _WIN32
  4118. // TODO: re-enable, but post to some other window (e.g. some singleton window), not this window
  4119. // because our message pump might be blocked
  4120. // maybe make a hidden window in api_timer for this purpose
  4121. //if (mindelay)
  4122. timerclient_postDeferredCallback(p1, p2, mindelay);
  4123. //else
  4124. //PostMessage(hwnd, WM_DEFER_CALLBACK, p1, p2);
  4125. #else
  4126. #warning "port me - I can be optimized - don't use timers for this, use mac os x equiv of PostMessage!"
  4127. timerclient_postDeferredCallback(p1, p2, mindelay);
  4128. #endif
  4129. }
  4130. int BaseWnd::bypassModal()
  4131. {
  4132. return 0;
  4133. }
  4134. void BaseWnd::setRenderBaseTexture(int r)
  4135. {
  4136. renderbasetexture = r;
  4137. if (isInited()) invalidate();
  4138. }
  4139. int BaseWnd::getRenderBaseTexture()
  4140. {
  4141. return renderbasetexture;
  4142. }
  4143. GuiObject *BaseWnd::getGuiObject()
  4144. {
  4145. if (my_guiobject == NULL)
  4146. {
  4147. my_guiobject = static_cast<GuiObject *>(getInterface(guiObjectGuid));
  4148. }
  4149. return my_guiobject;
  4150. }
  4151. //CUT someday
  4152. int BaseWnd::getFlag(int flag)
  4153. {
  4154. /* switch (flag) {
  4155. }*/
  4156. return 0;
  4157. }
  4158. int BaseWnd::triggerEvent(int event, intptr_t p1, intptr_t p2)
  4159. {
  4160. //PORTME
  4161. switch (event)
  4162. {
  4163. case TRIGGER_ONRESIZE:
  4164. if (isPostOnInit())
  4165. onResize();
  4166. break;
  4167. case TRIGGER_INVALIDATE:
  4168. if (isPostOnInit())
  4169. invalidate();
  4170. break;
  4171. }
  4172. return 0;
  4173. }
  4174. void BaseWnd::registerAcceleratorSection(const wchar_t *name, int global)
  4175. {
  4176. #if defined(WASABI_COMPILE_LOCALES)
  4177. WASABI_API_LOCALE->locales_registerAcceleratorSection(name, this, global);
  4178. #endif
  4179. }
  4180. int BaseWnd::onAcceleratorEvent(const wchar_t *name)
  4181. {
  4182. for (int i = 0;i < getNumRootWndChildren();i++)
  4183. if (enumRootWndChildren(i)->onAcceleratorEvent(name))
  4184. return 1;
  4185. return 0;
  4186. }
  4187. int BaseWnd::allowDeactivation()
  4188. {
  4189. return allow_deactivate & ((WASABI_API_WND == NULL) || WASABI_API_WND->appdeactivation_isallowed(this));
  4190. }
  4191. void BaseWnd::onMinimize()
  4192. {
  4193. if (!isVirtual())
  4194. {
  4195. dropVirtualCanvas();
  4196. }
  4197. }
  4198. void BaseWnd::dropVirtualCanvas()
  4199. {
  4200. deferedInvalidate();
  4201. delete virtualCanvas;
  4202. virtualCanvas = NULL;
  4203. }
  4204. void BaseWnd::onRestore()
  4205. {
  4206. if (getDesktopParent() == this)
  4207. {
  4208. cascadeRepaint(TRUE);
  4209. }
  4210. }
  4211. ifc_window *BaseWnd::findWindow(const wchar_t *id)
  4212. {
  4213. RootWndFinder find_object;
  4214. find_object.reset();
  4215. find_object.setFindId(id);
  4216. ifc_window *ret = findWindowChain(&find_object);
  4217. #ifdef _DEBUG
  4218. if (ret == NULL)
  4219. DebugStringW(L"findWindow : window not found by id ! %s \n", id);
  4220. #endif
  4221. return ret;
  4222. }
  4223. ifc_window *BaseWnd::findWindowByInterface(GUID interface_guid)
  4224. {
  4225. RootWndFinder find_object;
  4226. find_object.reset();
  4227. find_object.setFindGuid(interface_guid);
  4228. ifc_window *ret = findWindowChain(&find_object);
  4229. #ifdef _DEBUG
  4230. char str[256] = {0};
  4231. nsGUID::toChar(interface_guid, str);
  4232. if (ret == NULL)
  4233. DebugStringW(L"findWindow : object not found by guid ! %s \n", str);
  4234. #endif
  4235. return ret;
  4236. }
  4237. ifc_window *BaseWnd::findWindowByCallback(FindObjectCallback *cb)
  4238. {
  4239. ifc_window *ret = findWindowChain(cb);
  4240. #ifdef _DEBUG
  4241. if (ret == NULL)
  4242. DebugStringW(L"findWindow : object not found by callback!\n");
  4243. #endif
  4244. return ret;
  4245. }
  4246. ifc_window *BaseWnd::findWindowChain(FindObjectCallback *cb, ifc_window *wcaller)
  4247. {
  4248. if (!cb) return NULL;
  4249. if (cb->findobjectcb_matchObject(this)) return this;
  4250. // first lets not look in subdirectories
  4251. for (int i = 0;i < getNumRootWndChildren();i++)
  4252. {
  4253. ifc_window *child = enumRootWndChildren(i);
  4254. if (!child || child == wcaller) continue;
  4255. if (cb->findobjectcb_matchObject(child))
  4256. return child;
  4257. }
  4258. // ok so it wasn't in our content, lets try to find it as a grandchildren
  4259. for (int i = 0;i < getNumRootWndChildren();i++)
  4260. {
  4261. ifc_window *child = enumRootWndChildren(i);
  4262. if (child->getNumRootWndChildren() > 0)
  4263. {
  4264. ifc_window *ret = child->findWindowChain(cb, this);
  4265. if (ret) return ret;
  4266. }
  4267. }
  4268. // so it wasnt one of our children, we'll hop the tree up one level and ask our parent to find it
  4269. // for us. of course, our parents are smart, they won't ask us back when asking our sibblings
  4270. ifc_window *p = getParent();
  4271. if (p != NULL && wcaller != p)
  4272. {
  4273. return p->findWindowChain(cb, this);
  4274. }
  4275. return NULL;
  4276. }
  4277. const wchar_t *BaseWnd::timerclient_getName()
  4278. {
  4279. tcname = StringPrintfW(L"name=\"%S\", id=\"%s\"", getRootWndName(), getId());
  4280. return tcname;
  4281. }
  4282. void BaseWnd::setTabOrder(int a)
  4283. {
  4284. if (getParent() != NULL)
  4285. getParent()->setVirtualTabOrder(this, a);
  4286. }
  4287. int BaseWnd::getTabOrder()
  4288. {
  4289. if (getParent() != NULL)
  4290. return getParent()->getVirtualTabOrder(this);
  4291. return -1;
  4292. }
  4293. void BaseWnd::recursive_setVirtualTabOrder(ifc_window *w, float a, float lambda)
  4294. {
  4295. ASSERT(w != NULL);
  4296. childtabs.setAutoSort(0);
  4297. int i = getTabOrderEntry(a);
  4298. if (i != -1)
  4299. {
  4300. TabOrderEntry *toe = childtabs.enumItem(i);
  4301. if (toe->wnd != w)
  4302. {
  4303. lambda += TABORDER_K;
  4304. if (lambda != 1.0)
  4305. recursive_setVirtualTabOrder(toe->wnd, a + lambda, lambda);
  4306. }
  4307. else
  4308. {
  4309. return ;
  4310. }
  4311. }
  4312. i = getTabOrderEntry(w);
  4313. if (i != -1)
  4314. {
  4315. delete childtabs.enumItem(i);
  4316. childtabs.removeByPos(i);
  4317. }
  4318. TabOrderEntry *toe = new TabOrderEntry;
  4319. toe->wnd = w;
  4320. toe->order = a;
  4321. childtabs.addItem(toe);
  4322. }
  4323. void BaseWnd::setVirtualTabOrder(ifc_window *w, int a)
  4324. {
  4325. if (a == -1)
  4326. {
  4327. delTabOrderEntry(w);
  4328. return ;
  4329. }
  4330. recursive_setVirtualTabOrder(w, (float)a);
  4331. }
  4332. int BaseWnd::getVirtualTabOrder(ifc_window *w)
  4333. {
  4334. int a = (int)getTabOrderEntry(w);
  4335. if (a == -1) return -1;
  4336. return (int)childtabs.enumItem(a);
  4337. }
  4338. int BaseWnd::getTabOrderEntry(ifc_window *w)
  4339. {
  4340. foreach(childtabs)
  4341. if (childtabs.getfor()->wnd == w)
  4342. return foreach_index;
  4343. endfor;
  4344. return -1;
  4345. }
  4346. void BaseWnd::delTabOrderEntry(int i)
  4347. {
  4348. int a = getTabOrderEntry((float)i);
  4349. if (a == -1) return ;
  4350. childtabs.removeByPos(a);
  4351. }
  4352. void BaseWnd::delTabOrderEntry(ifc_window *w)
  4353. {
  4354. int a = getTabOrderEntry(w);
  4355. if (a == -1) return ;
  4356. delete childtabs.enumItem(a);
  4357. childtabs.removeByPos(a);
  4358. }
  4359. int BaseWnd::getTabOrderEntry(float order)
  4360. {
  4361. foreach(childtabs)
  4362. if (childtabs.getfor()->order == order)
  4363. return foreach_index;
  4364. endfor;
  4365. return -1;
  4366. }
  4367. void BaseWnd::setAutoTabOrder()
  4368. {
  4369. if (!getParent()) return ;
  4370. getParent()->setVirtualAutoTabOrder(this);
  4371. }
  4372. void BaseWnd::setVirtualAutoTabOrder(ifc_window *w)
  4373. {
  4374. delTabOrderEntry(w);
  4375. float o = 0;
  4376. for (int i = 0;i < childtabs.getNumItems();i++)
  4377. {
  4378. o = MAX(o, childtabs.enumItem(i)->order);
  4379. }
  4380. setVirtualTabOrder(w, ((int)o) + 1);
  4381. }
  4382. void BaseWnd::focusNext()
  4383. {
  4384. ifc_window *dp = getDesktopParent();
  4385. if (dp != this)
  4386. {
  4387. if (dp != NULL)
  4388. dp->focusNext();
  4389. return ;
  4390. }
  4391. ifc_window *w = getTab(TAB_GETNEXT);
  4392. if (w != NULL) w->setFocus();
  4393. }
  4394. void BaseWnd::focusPrevious()
  4395. {
  4396. ifc_window *dp = getDesktopParent();
  4397. if (dp != this)
  4398. {
  4399. if (dp != NULL)
  4400. getDesktopParent()->focusPrevious();
  4401. return ;
  4402. }
  4403. ifc_window *w = getTab(TAB_GETPREVIOUS);
  4404. if (w != NULL) w->setFocus();
  4405. }
  4406. void BaseWnd::recursive_buildTabList(ifc_window *from, PtrList<ifc_window> *list)
  4407. {
  4408. for (int i = 0;i < from->getNumTabs();i++)
  4409. {
  4410. ifc_window *r = from->enumTab(i);
  4411. if (r->isVisible() && r->getPaintingAlpha() > 0)
  4412. {
  4413. if (r->wantFocus())
  4414. list->addItem(r);
  4415. recursive_buildTabList(r, list);
  4416. }
  4417. }
  4418. }
  4419. ifc_window *BaseWnd::getTab(int what)
  4420. {
  4421. PtrList<ifc_window> listnow;
  4422. recursive_buildTabList(this, &listnow);
  4423. int p = listnow.searchItem(rootfocus);
  4424. if (p == -1)
  4425. for (int i = 0; i < listnow.getNumItems(); i++)
  4426. {
  4427. ifc_window *r = listnow.enumItem(i);
  4428. if (r->gotFocus())
  4429. {
  4430. //DebugString("desync of rootfocus, fixing\n");
  4431. p = i;
  4432. assignRootFocus(r);
  4433. break;
  4434. }
  4435. }
  4436. if (what == TAB_GETNEXT && rootfocus != NULL)
  4437. {
  4438. p++;
  4439. if (p >= listnow.getNumItems())
  4440. p = 0;
  4441. return listnow.enumItem(p);
  4442. }
  4443. else if (what == TAB_GETPREVIOUS && rootfocus != NULL)
  4444. {
  4445. p--;
  4446. if (p < 0) p = listnow.getNumItems() - 1;
  4447. return listnow.enumItem(p);
  4448. }
  4449. else if (what == TAB_GETCURRENT)
  4450. {
  4451. return rootfocus;
  4452. }
  4453. else if (what == TAB_GETFIRST || (what == TAB_GETNEXT && rootfocus == NULL))
  4454. {
  4455. return listnow.getFirst();
  4456. }
  4457. else if (what == TAB_GETLAST || (what == TAB_GETPREVIOUS && rootfocus == NULL))
  4458. {
  4459. return listnow.getLast();
  4460. }
  4461. return NULL;
  4462. }
  4463. int BaseWnd::getNumTabs()
  4464. {
  4465. return childtabs.getNumItems();
  4466. }
  4467. ifc_window *BaseWnd::enumTab(int i)
  4468. {
  4469. childtabs.sort();
  4470. return childtabs.enumItem(i)->wnd;
  4471. }
  4472. void BaseWnd::onSetRootFocus(ifc_window *w)
  4473. {
  4474. assignRootFocus(w);
  4475. ifc_window *dp = getDesktopParent();
  4476. if (dp && dp != this) dp->onSetRootFocus(w);
  4477. }
  4478. void BaseWnd::autoFocus(ifc_window *w)
  4479. {
  4480. if (w->getFocusOnClick() && w->wantFocus())
  4481. {
  4482. w->setFocus();
  4483. return ;
  4484. }
  4485. ifc_window *g = w;
  4486. while (1)
  4487. {
  4488. ifc_window *p = g->getParent();
  4489. if (p == NULL) break;
  4490. ifc_window *dp = p->getDesktopParent();
  4491. if (dp && dp != p)
  4492. {
  4493. if (p->wantFocus() && p->getFocusOnClick())
  4494. {
  4495. p->setFocus();
  4496. return ;
  4497. }
  4498. g = p;
  4499. }
  4500. else
  4501. break;
  4502. }
  4503. }
  4504. void BaseWnd::setNoLeftClicks(int no)
  4505. {
  4506. noleftclick = no;
  4507. }
  4508. void BaseWnd::setNoRightClicks(int no)
  4509. {
  4510. norightclick = no;
  4511. }
  4512. void BaseWnd::setNoDoubleClicks(int no)
  4513. {
  4514. nodoubleclick = no;
  4515. }
  4516. void BaseWnd::setNoMouseMoves(int no)
  4517. {
  4518. nomousemove = no;
  4519. }
  4520. void BaseWnd::setNoContextMenus(int no)
  4521. {
  4522. nocontextmnu = no;
  4523. }
  4524. void BaseWnd::setDefaultCursor(Cursor *c)
  4525. {
  4526. customdefaultcursor = c;
  4527. }
  4528. OSCURSORHANDLE BaseWnd::getCustomCursor(int x, int y)
  4529. {
  4530. #ifdef _WIN32
  4531. return customdefaultcursor ? customdefaultcursor->getOSHandle() : NULL;
  4532. #else
  4533. #warning port me
  4534. return 0;
  4535. #endif
  4536. }
  4537. Accessible *BaseWnd::createNewAccObj()
  4538. {
  4539. waServiceFactory *f = WASABI_API_SVC->service_enumService(WaSvc::ACCESSIBILITY, 0);
  4540. if (f != NULL)
  4541. {
  4542. svc_accessibility *svc = castService<svc_accessibility>(f);
  4543. if (svc != NULL)
  4544. {
  4545. Accessible *a = svc->createAccessibleObject(this);
  4546. WASABI_API_SVC->service_release(svc);
  4547. return a;
  4548. }
  4549. }
  4550. return NULL;
  4551. }
  4552. Accessible *BaseWnd::getAccessibleObject(int createifnotexist)
  4553. {
  4554. if (!createifnotexist) return accessible;
  4555. if (!accessible)
  4556. accessible = createNewAccObj();
  4557. else
  4558. accessible->addRef();
  4559. return accessible;
  4560. }
  4561. int BaseWnd::accessibility_getState()
  4562. {
  4563. int state = 0;
  4564. if (!isVisible()) state |= STATE_SYSTEM_INVISIBLE;
  4565. //if (isVirtual() && !wantFocus()) state |= STATE_SYSTEM_INVISIBLE;
  4566. if (gotFocus()) state |= STATE_SYSTEM_FOCUSED;
  4567. return state;
  4568. }
  4569. void BaseWnd::activate()
  4570. {
  4571. Wasabi::Std::Wnd::setActiveWindow(getRootParent()->getOsWindowHandle());
  4572. }
  4573. void BaseWnd::setOSWndName(const wchar_t *name)
  4574. {
  4575. if (isVirtual()) return ;
  4576. //#ifdef COMPILE_WASABI_SKIN // for some reason this isn't being correctly defined
  4577. if (name)
  4578. {
  4579. Wasabi::Std::Wnd::setWndName(getOsWindowHandle(), name);
  4580. }
  4581. else
  4582. Wasabi::Std::Wnd::setWndName(getOsWindowHandle(), L"");
  4583. }
  4584. const wchar_t *BaseWnd::getOSWndName()
  4585. {
  4586. if (isVirtual()) return NULL;
  4587. wchar_t str[4096] = {0};
  4588. Wasabi::Std::Wnd::getWndName(getOsWindowHandle(), str, 4095);
  4589. str[4095] = '\0';
  4590. osname = str;
  4591. return osname;
  4592. }
  4593. #ifdef EXPERIMENTAL_INDEPENDENT_AOT
  4594. void BaseWnd::setAlwaysOnTop(int i)
  4595. {
  4596. // this function should not optimize itself
  4597. if (getDesktopParent() == this)
  4598. {
  4599. if (i)
  4600. {
  4601. //CUT SetWindowPos(getOsWindowHandle(), HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER);
  4602. Wasabi::Std::Wnd::setTopmost(getOsWindowHandle(), TRUE);
  4603. }
  4604. else
  4605. {
  4606. saveTopMosts();
  4607. //CUT SetWindowPos(getOsWindowHandle(), HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER);
  4608. Wasabi::Std::Wnd::setTopmost(getOsWindowHandle(), FALSE);
  4609. restoreTopMosts();
  4610. }
  4611. alwaysontop = i;
  4612. return ;
  4613. }
  4614. ifc_window *p = getParent();
  4615. if (p != NULL)
  4616. p->setAlwaysOnTop(i);
  4617. }
  4618. int BaseWnd::getAlwaysOnTop()
  4619. {
  4620. if (getDesktopParent() == this)
  4621. return alwaysontop;
  4622. ifc_window *p = getParent();
  4623. if (!p) return 0;
  4624. return p->getAlwaysOnTop();
  4625. }
  4626. #endif
  4627. void BaseWnd::wndwatcher_onDeleteWindow(ifc_window *w)
  4628. {
  4629. if (w == rootfocus)
  4630. {
  4631. rootfocus = NULL;
  4632. }
  4633. }
  4634. void BaseWnd::assignRootFocus(ifc_window *w)
  4635. {
  4636. rootfocuswatcher.watchWindow(w);
  4637. rootfocus = w;
  4638. }
  4639. Canvas *BaseWnd::getFrameBuffer()
  4640. {
  4641. return virtualCanvas;
  4642. }
  4643. void BaseWnd::setForeignWnd(int i)
  4644. {
  4645. m_takenOver = i;
  4646. }
  4647. int BaseWnd::bufferizeLockedUIMsg(int uMsg, int wParam, int lParam)
  4648. {
  4649. if (WASABI_API_SKIN && !WASABI_API_SKIN->skin_getLockUI()) return 0;
  4650. if (!uiwaslocked)
  4651. {
  4652. uiwaslocked = 1;
  4653. setTimer(BUFFEREDMSG_TIMER_ID, 20);
  4654. }
  4655. bufferedMsgStruct msg;
  4656. msg.msg = uMsg;
  4657. msg.wparam = wParam;
  4658. msg.lparam = lParam;
  4659. bufferedmsgs.addItem(msg);
  4660. return 1;
  4661. }
  4662. void BaseWnd::checkLockedUI()
  4663. {
  4664. //PORTME :(
  4665. #ifdef _WIN32
  4666. if (WASABI_API_SKIN && !WASABI_API_SKIN->skin_getLockUI())
  4667. {
  4668. uiwaslocked = 0;
  4669. killTimer(BUFFEREDMSG_TIMER_ID);
  4670. while (bufferedmsgs.getNumItems() > 0)
  4671. {
  4672. bufferedMsgStruct msg = bufferedmsgs.enumItem(0);
  4673. bufferedmsgs.delByPos(0);
  4674. SendMessageW(gethWnd(), msg.msg, msg.wparam, msg.lparam);
  4675. }
  4676. uiwaslocked = 0;
  4677. killTimer(BUFFEREDMSG_TIMER_ID);
  4678. }
  4679. #else
  4680. #warning port me
  4681. #endif
  4682. }
  4683. int BaseWnd::isMinimized()
  4684. {
  4685. ifc_window *w = getDesktopParent();
  4686. if (w == this || w == NULL) return minimized;
  4687. return w->isMinimized();
  4688. }
  4689. int BaseWnd::reinit()
  4690. {
  4691. #ifdef _WIN32
  4692. int nochild = (GetWindowLong(gethWnd(), GWL_STYLE) & WS_POPUP) ? 1 : 0;
  4693. int r = reinit(parentWnd ? parentWnd : WASABI_API_WND->main_getRootWnd(), nochild);
  4694. if (w2k_alpha)
  4695. setLayeredWindow(1);
  4696. return r;
  4697. #else
  4698. #warning port me!
  4699. #endif
  4700. }
  4701. int BaseWnd::reinit(ifc_window *parWnd, int nochild)
  4702. {
  4703. OSWINDOWHANDLE phwnd = parWnd->getOsWindowHandle();
  4704. ASSERT(phwnd != NULL);
  4705. int ret;
  4706. if (!nochild) parentWnd = parWnd;
  4707. else parentWnd = NULL;
  4708. ret = reinit(parWnd->getOsModuleHandle(), phwnd, nochild);
  4709. if (!ret) parentWnd = NULL; // abort
  4710. return ret;
  4711. }
  4712. int BaseWnd::reinit(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild)
  4713. {
  4714. RECT r;
  4715. int w, h;
  4716. onBeforeReinit();
  4717. pushWindowRect();
  4718. preventcancelcapture = 1;
  4719. int _isvisible = isVisible(1);
  4720. int hadcapture = inputCaptured;
  4721. //DebugString("had capture = %d\n", hadcapture);
  4722. Wasabi::Std::Wnd::releaseCapture();
  4723. unparentHWNDChildren();
  4724. BaseWnd::getClientRect(&r);
  4725. hinstance = moduleHandle;
  4726. ASSERT(hinstance != NULL);
  4727. w = (r.right - r.left);
  4728. h = (r.bottom - r.top);
  4729. rwidth = w;
  4730. rheight = h;
  4731. rx = r.left;
  4732. ry = r.top;
  4733. WASABI_API_WND->appdeactivation_push_disallow(this);
  4734. // destroy old window
  4735. Wasabi::Std::Wnd::hideWnd(hwnd); //Wasabi::Std::Wnd::destroyWnd(hwnd);
  4736. ghosthwnd.addItem(hwnd);
  4737. hwnd = Wasabi::Std::Wnd::createWnd(&r, nochild, acceptExternalDrops(), parent, hinstance, static_cast<ifc_window*>(this));
  4738. #ifdef __APPLE__
  4739. #warning remove me
  4740. Wasabi::Std::Wnd::showWnd(hwnd);
  4741. #endif
  4742. WASABI_API_WND->appdeactivation_pop_disallow(this);
  4743. //ASSERT(hwnd != NULL); // lets fail nicely, this could happen for some win32 reason, we don't want to fail the whole app for it, so lets just fail the wnd
  4744. if (hwnd == NULL)
  4745. {
  4746. preventcancelcapture = 0;
  4747. return 0;
  4748. }
  4749. //CUT nreal++;
  4750. #ifdef _WIN32
  4751. //FUCKO
  4752. #ifdef URLDROPS
  4753. if (acceptExternalDrops()) RegisterDragDrop(hwnd, &m_target);
  4754. #elif !defined(WA3COMPATIBILITY)
  4755. if (!m_target && WASABI_API_WND != NULL)
  4756. m_target = WASABI_API_WND->getDefaultDropTarget();
  4757. if (m_target != NULL)
  4758. {
  4759. RegisterDragDrop(hwnd, (IDropTarget *)m_target);
  4760. }
  4761. #endif
  4762. #else
  4763. #warning port me - register drag & drop
  4764. #endif
  4765. this_visible = _isvisible;
  4766. //onInit();
  4767. //this_visible = !start_hidden;
  4768. reparentHWNDChildren();
  4769. popWindowRect();
  4770. invalidateWindowRegion();
  4771. updateWindowRegion();
  4772. if (this_visible)
  4773. Wasabi::Std::Wnd::showWnd(hwnd, FALSE);
  4774. if (hadcapture)
  4775. {
  4776. Wasabi::Std::Wnd::setCapture(hwnd);
  4777. }
  4778. preventcancelcapture = 0;
  4779. forcedOnResize();
  4780. redrawHWNDChildren();
  4781. //onPostOnInit();
  4782. onAfterReinit();
  4783. #ifdef WASABI_ON_REPARENT
  4784. WASABI_ON_REINIT(getOsWindowHandle());
  4785. #endif
  4786. return 1;
  4787. }
  4788. ReparentWndEntry::ReparentWndEntry(OSWINDOWHANDLE _wnd, OSWINDOWHANDLE parentwnd)
  4789. {
  4790. wnd = _wnd;
  4791. Wasabi::Std::Wnd::getWindowRect(wnd, &rect);
  4792. Wasabi::Std::Wnd::screenToClient(wnd, (int *)&(rect.left), (int *)&(rect.top));
  4793. Wasabi::Std::Wnd::clientToScreen(parentwnd, (int *)&(rect.left), (int *)&(rect.top));
  4794. }
  4795. void ReparentWndEntry::unparent()
  4796. {
  4797. Wasabi::Std::Wnd::setWndPos(wnd, NULL, rect.left, -30000, 0, 0, TRUE, TRUE, FALSE, FALSE, TRUE);
  4798. Wasabi::Std::Wnd::setParent(wnd, NULL);
  4799. }
  4800. void ReparentWndEntry::reparent(OSWINDOWHANDLE newparent)
  4801. {
  4802. Wasabi::Std::Wnd::setParent(wnd, newparent);
  4803. Wasabi::Std::Wnd::setWndPos(wnd, NULL, rect.left, rect.top, 0, 0, TRUE, TRUE, FALSE, FALSE, TRUE);
  4804. }
  4805. #ifdef _WIN32
  4806. void BaseWnd::unparentHWNDChildren()
  4807. {
  4808. // just in case
  4809. reparentwnds.deleteAll();
  4810. #ifndef WIN32
  4811. #error port me ! // make a list of all the children oswindows and reparent them to the desktop somewhere we can't see
  4812. #endif
  4813. OSWINDOWHANDLE wnd = GetWindow(getOsWindowHandle(), GW_CHILD);
  4814. while (wnd)
  4815. {
  4816. reparentwnds.addItem(new ReparentWndEntry(wnd, getOsWindowHandle()));
  4817. wnd = GetWindow(wnd, GW_HWNDNEXT);
  4818. }
  4819. foreach(reparentwnds)
  4820. reparentwnds.getfor()->unparent();
  4821. endfor;
  4822. }
  4823. #endif
  4824. void BaseWnd::reparentHWNDChildren()
  4825. {
  4826. // reparent to the new oswindowhandle
  4827. foreach(reparentwnds)
  4828. reparentwnds.getfor()->reparent(getOsWindowHandle());
  4829. endfor;
  4830. }
  4831. void BaseWnd::redrawHWNDChildren()
  4832. {
  4833. // reparent to the new oswindowhandle
  4834. foreach(reparentwnds)
  4835. Wasabi::Std::Wnd::update(getOsWindowHandle());
  4836. endfor;
  4837. }
  4838. void BaseWnd::maximize(int axis)
  4839. {
  4840. //DebugString("maximize!\n");
  4841. // if already maximized, don't use current rect, use restore_rect
  4842. if (!maximized)
  4843. {
  4844. restore_rect.left = rx;
  4845. restore_rect.top = ry;
  4846. restore_rect.right = rx + rwidth;
  4847. restore_rect.bottom = ry + rheight;
  4848. }
  4849. RECT nr = restore_rect;
  4850. RECT dr;
  4851. Wasabi::Std::getViewport(&dr, NULL, NULL, getOsWindowHandle(), 0);
  4852. if (axis & MAXIMIZE_WIDTH)
  4853. {
  4854. nr.left = dr.left;
  4855. nr.right = dr.right;
  4856. }
  4857. if (axis & MAXIMIZE_HEIGHT)
  4858. {
  4859. nr.top = dr.top;
  4860. nr.bottom = dr.bottom;
  4861. }
  4862. maximized = 1;
  4863. if (axis != 0) resize(&nr);
  4864. onMaximize();
  4865. }
  4866. void BaseWnd::restore(int what)
  4867. {
  4868. if (maximized)
  4869. {
  4870. //DebugString("restore!\n");
  4871. if (what == (RESTORE_X | RESTORE_Y | RESTORE_WIDTH | RESTORE_HEIGHT))
  4872. resize(&restore_rect);
  4873. else
  4874. {
  4875. resize((what & RESTORE_X) ? restore_rect.left : NOCHANGE,
  4876. (what & RESTORE_Y) ? restore_rect.top : NOCHANGE,
  4877. (what & RESTORE_WIDTH) ? restore_rect.right - restore_rect.left : NOCHANGE,
  4878. (what & RESTORE_HEIGHT) ? restore_rect.bottom - restore_rect.top : NOCHANGE);
  4879. }
  4880. maximized = 0;
  4881. onRestore();
  4882. }
  4883. }
  4884. void BaseWnd::pushWindowRect()
  4885. {
  4886. //DebugString("pushWindowRect\n");
  4887. RECT wr;
  4888. getWindowRect(&wr);
  4889. wr.right = wr.left + rwidth;
  4890. wr.bottom = wr.top + rheight;
  4891. windowrectstack.push(wr);
  4892. }
  4893. int BaseWnd::popWindowRect(RECT *rc, int applyhow)
  4894. {
  4895. //DebugString("popWindowRect\n");
  4896. if (windowrectstack.peek() == 0) return 0;
  4897. RECT _rc;
  4898. windowrectstack.pop(&_rc);
  4899. RECT r;
  4900. getWindowRect(&r);
  4901. divRatio(&r);
  4902. if (applyhow)
  4903. {
  4904. if (applyhow == PWR_POSITION)
  4905. {
  4906. move(_rc.left, _rc.top);
  4907. if (rc)
  4908. {
  4909. int w = r.right - r.left;
  4910. int h = r.bottom - r.top;
  4911. rc->left = _rc.left;
  4912. rc->top = _rc.top;
  4913. rc->right = rc->left + w;
  4914. rc->bottom = rc->top + h;
  4915. }
  4916. }
  4917. else
  4918. {
  4919. if (applyhow & PWR_X) r.left = _rc.left;
  4920. if (applyhow & PWR_Y) r.top = _rc.top;
  4921. if (applyhow & PWR_WIDTH) r.right = r.left + (_rc.right - _rc.left);
  4922. if (applyhow & PWR_HEIGHT) r.bottom = r.top + (_rc.bottom - _rc.top);
  4923. resizeToRect(&r);
  4924. if (rc) *rc = _rc;
  4925. }
  4926. }
  4927. else if (rc) *rc = _rc;
  4928. return 1;
  4929. }
  4930. void BaseWnd::setRestoredRect(RECT *r)
  4931. {
  4932. if (!r)
  4933. return ;
  4934. restore_rect = *r;
  4935. maximized = 1;
  4936. }
  4937. int BaseWnd::getRestoredRect(RECT *r)
  4938. {
  4939. if (!r)
  4940. return 0;
  4941. if (!maximized)
  4942. return 0;
  4943. *r = restore_rect;
  4944. return 1;
  4945. }
  4946. void BaseWnd::notifyDeferredMove(int x, int y)
  4947. {
  4948. rx = x;
  4949. ry = y;
  4950. }
  4951. void BaseWnd::setWindowTitle(const wchar_t *title)
  4952. {
  4953. Layout *l = static_cast<Layout *>(getInterface(layoutGuid));
  4954. if (l)
  4955. {
  4956. Container *c = l->getParentContainer();
  4957. if (c)
  4958. {
  4959. c->setName(title);
  4960. }
  4961. }
  4962. }
  4963. #ifdef __APPLE__
  4964. OSStatus BaseWnd::eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
  4965. {
  4966. return eventNotHandledErr;
  4967. }
  4968. #endif