123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285 |
- // some code taken from (freeware) Cool ScrollBar library by J Brown
- #include "./skinnedscrollwnd.h"
- #include "main.h"
- #include <commctrl.h>
- #include <windowsx.h>
- #include "../winamp/wa_dlg.h"
- #include "api__gen_ml.h"
- #include "./colors.h"
- #include <tataki/bitmap/bitmap.h>
- #include <tataki/bitmap/autobitmap.h>
- #include <tataki/canvas/canvas.h>
- #include <api/wnd/api_window.h>
- #include "./stockobjects.h"
- /* minimum size of scrollbar before inserted buttons are hidden to make room when the window is sized too small */
- #define MIN_COOLSB_SIZE 24
- /* min size of scrollbar when resizing a button, before the resize is stopped because the scrollbar has gotten too small */
- #define MINSCROLLSIZE 50
- /* a normal scrollbar "snaps" its scroll-thumb back into position if
- you move the mouse too far away from the window, whilst you are
- dragging the thumb, that is. #undeffing this results in the thumb
- never snapping back into position, no matter how far away you move
- the mouse */
- #define SNAP_THUMB_BACK
- /* distance (in pixels) the mouse must move away from the thumb
- during tracking to cause the thumb bar to snap back to its
- starting place. Has no effect unless SNAP_THUMB_BACK is defined */
- #define THUMBTRACK_SNAPDIST 128
- // To complement the exisiting SB_HORZ, SB_VERT, SB_BOTH
- // scrollbar identifiers
- #define COOLSB_NONE (-1)
- #define SB_INSBUT (-2)
- // Arrow size defines
- #define SYSTEM_METRIC (-1)
- // general scrollbar styles
- //
- // use the standard ESB_DISABLE_xxx flags to represent the
- // enabled / disabled states. (defined in winuser.h)
- //
- #define CSBS_THUMBALWAYS 0x0004
- #define CSBS_VISIBLE 0x0008
- #define CSBS_TRACKING 0x0010
- #define CSBS_FLATSB 0x0020
- #define CSBS_BTNVISBEFORE 0x0040 //if the buttons to the left are visible
- #define CSBS_BTNVISAFTER 0x0080 //if the buttons to the right are visible
- #define CSBS_HOVERING 0x0100 //if the buttons to the right are visible
- //cool scrollbar styles for Flat scrollbars
- #define CSBS_NORMAL 0
- #define CSBS_FLAT 1
- #define CSBS_HOTTRACKED 2
- // Button mask flags for indicating which members of SCROLLBUT
- // to use during a button insertion / modification
- #define SBBF_TYPE 0x0001
- #define SBBF_ID 0x0002
- #define SBBF_PLACEMENT 0x0004
- #define SBBF_SIZE 0x0008
- #define SBBF_BITMAP 0x0010
- #define SBBF_ENHMETAFILE 0x0020
- //#define SBBF_OWNERDRAW 0x0040 //unused at present
- #define SBBF_CURSOR 0x0080
- #define SBBF_BUTMINMAX 0x0100
- #define SBBF_STATE 0x0200
- //button styles (states)
- #define SBBS_NORMAL 0
- #define SBBS_PUSHED 1
- #define SBBS_CHECKED SBBS_PUSHED
- // scrollbar button types
- #define SBBT_PUSHBUTTON 1 //standard push button
- #define SBBT_TOGGLEBUTTON 2 //toggle button
- #define SBBT_FIXED 3 //fixed button (non-clickable)
- #define SBBT_FLAT 4 //blank area (flat, with border)
- #define SBBT_BLANK 5 //blank area (flat, no border)
- #define SBBT_DARK 6 //dark blank area (flat)
- #define SBBT_OWNERDRAW 7 //user draws the button via a WM_NOTIFY
- #define SBBT_MASK 0x1f //mask off low 5 bits
- //button type modifiers
- #define SBBM_RECESSED 0x0020 //recessed when clicked (like Word 97)
- #define SBBM_LEFTARROW 0x0040
- #define SBBM_RIGHTARROW 0x0080
- #define SBBM_UPARROW 0x0100
- #define SBBM_DOWNARROW 0x0200
- #define SBBM_RESIZABLE 0x0400
- #define SBBM_TYPE2 0x0800
- #define SBBM_TYPE3 0x1000
- #define SBBM_TOOLTIPS 0x2000 //currently unused (define COOLSB_TOOLTIPS in userdefs.h)
- //button placement flags
- #define SBBP_LEFT 1
- #define SBBP_RIGHT 2
- #define SBBP_TOP 1 //3
- #define SBBP_BOTTOM 2 //4
- #define DFCS_HOVER 0x800
- //
- // Button command notification codes
- // for sending with a WM_COMMAND message
- //
- #define CSBN_BASE 0
- #define CSBN_CLICKED (1 + CSBN_BASE)
- #define CSBN_HILIGHT (2 + CSBN_BASE)
- // Minimum size in pixels of a scrollbar thumb
- #define MINTHUMBSIZE_NT4 9
- #define MINTHUMBSIZE_2000 7
- //define some more hittest values for our cool-scrollbar
- #define HTSCROLL_LEFT (SB_LINELEFT)
- #define HTSCROLL_RIGHT (SB_LINERIGHT)
- #define HTSCROLL_UP (SB_LINEUP)
- #define HTSCROLL_DOWN (SB_LINEDOWN)
- #define HTSCROLL_THUMB (SB_THUMBTRACK)
- #define HTSCROLL_PAGEGUP (SB_PAGEUP)
- #define HTSCROLL_PAGEGDOWN (SB_PAGEDOWN)
- #define HTSCROLL_PAGELEFT (SB_PAGELEFT)
- #define HTSCROLL_PAGERIGHT (SB_PAGERIGHT)
- #define HTSCROLL_NONE (-1)
- #define HTSCROLL_NORMAL (-1)
- #define HTSCROLL_INSERTED (128)
- #define HTSCROLL_PRE (32 | HTSCROLL_INSERTED)
- #define HTSCROLL_POST (64 | HTSCROLL_INSERTED)
- // SCROLLBAR datatype. There are two of these structures per window
- typedef struct _SCROLLBAR
- {
- UINT fScrollFlags; //flags
- BOOL fScrollVisible; //if this scrollbar visible?
- SCROLLINFO scrollInfo; //positional data (range, position, page size etc)
- //data for inserted buttons
- int nButSizeBefore; //size to the left / above the bar
- int nButSizeAfter; //size to the right / below the bar
- int nMinThumbSize;
- int nBarType; //SB_HORZ / SB_VERT
- } SCROLLBAR;
- static WORD wCheckPat[8] =
- {
- 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555
- };
- // scrollwnd styles
- #define SWS_UPDATEFRAME 0x0001
- #define SWS_LEFT 0x0002
- #define SWS_DISABLENOSCROLL 0x0004
- #define SWS_HIDEHSCROLL 0x0008
- #define SWS_LISTVIEW 0x0010
- #define SWS_TREEVIEW 0x0020
- #define SWS_HIDEVSCROLL 0x0040
- #define SWS_COMBOLBOX 0x0080
- #define SWS_USEFREEFORM 0x0100
- //
- // PRIVATE INTERNAL FUNCTIONS
- //
- #define COOLSB_TIMERID1 65533 //initial timer
- #define COOLSB_TIMERID2 65534 //scroll message timer
- #define COOLSB_TIMERID3 -14 //mouse hover timer
- #define COOLSB_TIMERINTERVAL1 300
- #define COOLSB_TIMERINTERVAL2 55
- #define COOLSB_TIMERINTERVAL3 20 //mouse hover time
- //
- // direction: 0 - same axis as scrollbar (i.e. width of a horizontal bar)
- // 1 - perpendicular dimesion (i.e. height of a horizontal bar)
- //
- #define SM_CXVERTSB 1
- #define SM_CYVERTSB 0
- #define SM_CXHORZSB 0
- #define SM_CYHORZSB 1
- #define SM_SCROLL_WIDTH 1
- #define SM_SCROLL_LENGTH 0
- #ifndef WM_MOUSEWHEEL
- #define WM_MOUSEWHEEL 0x020A
- #endif
- #define INACTIVEBAR_ALPHA 127
- //
- // Special thumb-tracking variables
- //
- //
- static UINT uCurrentScrollbar = COOLSB_NONE; //SB_HORZ / SB_VERT
- static UINT uCurrentScrollPortion = HTSCROLL_NONE;
- static UINT uCurrentButton = 0;
- static RECT rcThumbBounds; //area that the scroll thumb can travel in
- static int nThumbSize; //(pixels)
- static int nThumbPos; //(pixels)
- static int nThumbMouseOffset; //(pixels)
- static int nLastPos = -1; //(scrollbar units)
- static int nThumbPos0; //(pixels) initial thumb position
- static int trackThumbPos;
- //
- // Temporary state used to auto-generate timer messages
- //
- static UINT uScrollTimerMsg = 0;
- static UINT uScrollTimerPortion = HTSCROLL_NONE;
- static UINT_PTR uScrollTimerId = 0;
- static HWND hwndCurCoolSB = 0;
- static INT bUseUpdateRgn = -1;
- static BOOL bDoHover=FALSE;
- static BOOL ignoreCaptureChange = FALSE;
- static BOOL captureSet = FALSE;
- static HBRUSH hbrChecked = NULL;
- #define GetSBForeColor() WADlg_getColor(WADLG_SCROLLBAR_FGCOLOR)
- #define GetSBBackColor() WADlg_getColor(WADLG_SCROLLBAR_BGCOLOR)
- // Send a WM_VSCROLL or WM_HSCROLL message
- #define SendScrollMessage(__hwnd, __srcMsg, __srcId, __pos) ::SendMessageW(__hwnd, __srcMsg, (MAKEWPARAM(__srcId, __pos)), 0)
- static UINT GetPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, DWORD scrollFlags);
- static void RenderBaseTexture(Canvas *canvas, const RECT *r, HWND hwnd)
- {
- // TODO: find the ifc_window * object for the media library container, and call renderBaseTexture on it
- if (WASABI_API_WND)
- {
- HWND checkWnd = GetParent(hwnd);
- while (checkWnd)
- {
- ifc_window *window = WASABI_API_WND->rootWndFromOSHandle(checkWnd);
- if (window && window->getRenderBaseTexture())
- {
- window->renderBaseTexture(canvas, r);
- return;
- }
- checkWnd = GetParent(checkWnd);
- }
- }
- // fallback code
- COLORREF bgcolor = WADlg_getColor(WADLG_WNDBG/*WADLG_SCROLLBAR_BGCOLOR*/);
- canvas->fillRect(r, bgcolor);
- }
- // swap the rectangle's x coords with its y coords
- static void __stdcall RotateRect(RECT *rect)
- {
- LONG temp;
- temp = rect->left;
- rect->left = rect->top;
- rect->top = temp;
- temp = rect->right;
- rect->right = rect->bottom;
- rect->bottom = temp;
- }
- // swap the coords if the scrollbar is a SB_VERT
- #define RotateRect0(__psb, __prc) ((__psb && __psb->nBarType == SB_VERT) ? RotateRect(__prc) : 0)
- static bool UseFreeformScrollbars()
- {
- if (config_use_ff_scrollbars && WASABI_API_SKIN && WASABI_API_SKIN->skin_isLoaded())
- {
- return WASABI_API_SKIN->skin_getVersion() >= 1.3;
- }
- else
- {
- return false;
- }
- }
- // Calculate if the SCROLLINFO members produce an enabled or disabled scrollbar
- static BOOL IsScrollInfoActive(SCROLLINFO *si)
- {
- return (si->nPage <= (UINT)si->nMax && si->nMax > si->nMin && si->nMax != 0);
- }
- // Return if the specified scrollbar is enabled or not
- static BOOL IsScrollbarActive(SCROLLBAR *sb)
- {
- return (((sb->fScrollFlags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) ||
- !(sb->fScrollFlags & CSBS_THUMBALWAYS) && !IsScrollInfoActive(&sb->scrollInfo)) ? FALSE : TRUE;
- }
- enum
- {
- HORIZ_LEFT,
- HORIZ_LEFT_PRESSED,
- HORIZ_LEFT_HOVER,
- HORIZ_LEFT_INACTIVE,
- HORIZ_RIGHT,
- HORIZ_RIGHT_PRESSED,
- HORIZ_RIGHT_HOVER,
- HORIZ_RIGHT_INACTIVE,
- VERT_UP,
- VERT_UP_PRESSED,
- VERT_UP_HOVER,
- VERT_UP_INACTIVE,
- VERT_DOWN,
- VERT_DOWN_PRESSED,
- VERT_DOWN_HOVER,
- VERT_DOWN_INACTIVE,
- };
- static int GetBitmapEnum(UINT state, BOOL hover)
- {
- int offset=0;
- if (state&DFCS_PUSHED)
- offset=1;
- if (state&DFCS_INACTIVE)
- offset=3;
- else if (hover)
- offset=2;
- switch (state&3)
- {
- case DFCS_SCROLLRIGHT:
- return HORIZ_RIGHT+offset;
- case DFCS_SCROLLLEFT:
- return HORIZ_LEFT+offset;
- case DFCS_SCROLLDOWN:
- return VERT_DOWN+offset;
- default://case DFCS_SCROLLUP:
- return VERT_UP+offset;
- }
- }
- class ScrollBitmaps
- {
- public:
- ScrollBitmaps() : v_up(L"wasabi.scrollbar.vertical.background.top"),
- v_down(L"wasabi.scrollbar.vertical.background.bottom"),
- v_mid(L"wasabi.scrollbar.vertical.background.middle"),
- h_left(L"wasabi.scrollbar.horizontal.background.left"),
- h_mid(L"wasabi.scrollbar.horizontal.background.middle"),
- h_right(L"wasabi.scrollbar.horizontal.background.right")
- {
- }
- AutoSkinBitmap v_up, v_down, v_mid, h_left, h_mid, h_right;
- };
- static ScrollBitmaps *scrollBitmaps=0;
- void SkinnedScrollWnd_Init()
- {
- scrollBitmaps = new ScrollBitmaps();
- }
- void SkinnedScrollWnd_Quit()
- {
- if (scrollBitmaps)
- {
- delete scrollBitmaps;
- scrollBitmaps=0;
- }
- }
- static HBITMAP hbmpCachedDib = NULL;
- // Paint a checkered rectangle, with each alternate pixel being assigned a different colour
- static BOOL DrawFrameCtrl(HDC hdc, LPRECT lprc, UINT uType, UINT state, BOOL hover, BOOL freeform)
- {
- int startx, starty, alpha = 255;
- const wchar_t *bitmapid=0;
- const wchar_t *backgroundid=0;
- SkinBitmap *bg=0;
- switch (GetBitmapEnum(state, hover))
- {
- case HORIZ_LEFT:
- bitmapid = L"wasabi.scrollbar.horizontal.left";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_left.getBitmap();
- startx = 0; starty = 45; break;
- case HORIZ_LEFT_PRESSED:
- bitmapid = L"wasabi.scrollbar.horizontal.left.pressed";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_left.getBitmap();
- startx = 28; starty = 45; break;
- case HORIZ_LEFT_HOVER:
- bitmapid = L"wasabi.scrollbar.horizontal.left.hover";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_left.getBitmap();
- startx = 0; starty = 45; break;
- case HORIZ_LEFT_INACTIVE:
- alpha = INACTIVEBAR_ALPHA;
- bitmapid = L"wasabi.scrollbar.horizontal.left";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_left.getBitmap();
- startx = 0; starty = 45; break;
- case HORIZ_RIGHT:
- bitmapid = L"wasabi.scrollbar.horizontal.right";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_right.getBitmap();
- startx = 14; starty = 45; break;
- case HORIZ_RIGHT_PRESSED:
- bitmapid = L"wasabi.scrollbar.horizontal.right.pressed";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_right.getBitmap();
- startx = 42; starty = 45; break;
- case HORIZ_RIGHT_HOVER:
- bitmapid = L"wasabi.scrollbar.horizontal.right.hover";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_right.getBitmap();
- startx = 14; starty = 45; break;
- case HORIZ_RIGHT_INACTIVE:
- alpha = INACTIVEBAR_ALPHA;
- bitmapid = L"wasabi.scrollbar.horizontal.right";
- if (scrollBitmaps)
- bg=scrollBitmaps->h_right.getBitmap();
- startx = 14; starty = 45; break;
- case VERT_UP:
- bitmapid = L"wasabi.scrollbar.vertical.left";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_up.getBitmap();
- startx = 0; starty = 31; break;
- case VERT_UP_PRESSED:
- bitmapid = L"wasabi.scrollbar.vertical.left.pressed";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_up.getBitmap();
- startx = 28; starty = 31; break;
- case VERT_UP_HOVER:
- bitmapid = L"wasabi.scrollbar.vertical.left.hover";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_up.getBitmap();
- startx = 0; starty = 31; break;
- case VERT_UP_INACTIVE:
- alpha = INACTIVEBAR_ALPHA;
- bitmapid = L"wasabi.scrollbar.vertical.left";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_up.getBitmap();
- startx = 0; starty = 31; break;
- case VERT_DOWN:
- bitmapid = L"wasabi.scrollbar.vertical.right";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_down.getBitmap();
- startx = 14; starty = 31; break;
- case VERT_DOWN_PRESSED:
- bitmapid = L"wasabi.scrollbar.vertical.right.pressed";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_down.getBitmap();
- startx = 42; starty = 31; break;
- case VERT_DOWN_HOVER:
- bitmapid = L"wasabi.scrollbar.vertical.right.hover";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_down.getBitmap();
- startx = 14; starty = 31; break;
- case VERT_DOWN_INACTIVE:
- alpha = INACTIVEBAR_ALPHA;
- bitmapid = L"wasabi.scrollbar.vertical.right";
- if (scrollBitmaps)
- bg=scrollBitmaps->v_down.getBitmap();
- startx = 14; starty = 31; break;
- }
- if (freeform)
- {
- SkinBitmap bmp(bitmapid);
- if (!bmp.isInvalid() && bg && !bg->isInvalid())
- {
- DCCanvas canvas(hdc);
- bg->stretchToRectAlpha(&canvas, lprc, alpha);
- bmp.stretchToRectAlpha(&canvas, lprc, alpha);
- return 1;
- }
- }
- // fallback code
- HDC hdcbmp;
- HBITMAP hbmpOld, hbmp;
- hbmp = WADlg_getBitmap();
- if (!hbmp) return FALSE;
- hdcbmp = (HDC)MlStockObjects_Get(CACHED_DC);
- if (!hdcbmp) return FALSE;
- hbmpOld = (HBITMAP)SelectObject(hdcbmp, hbmp);
-
- if (255 == alpha)
- StretchBlt(hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top, hdcbmp, startx, starty, 14, 14, SRCCOPY);
- else
- {
- HDC hdcTmp = CreateCompatibleDC(hdc);
- DIBSECTION dibSection;
- if (NULL == hbmpCachedDib ||
- sizeof(DIBSECTION) != GetObjectW(hbmpCachedDib, sizeof(DIBSECTION), &dibSection)
- || dibSection.dsBm.bmWidth < (lprc->right - lprc->left) || ABS(dibSection.dsBm.bmHeight) < (lprc->bottom - lprc->top))
- {
- if (hbmpCachedDib) DeleteObject(hbmpCachedDib);
- BITMAPINFOHEADER bi;
- ZeroMemory(&bi, sizeof(BITMAPINFOHEADER));
- bi.biSize = sizeof(BITMAPINFOHEADER);
- bi.biWidth = lprc->right - lprc->left;
- bi.biHeight = -(lprc->bottom - lprc->top);
- bi.biPlanes = 1;
- bi.biBitCount = 32;
- bi.biCompression = BI_RGB;
- hbmpCachedDib = CreateDIBSection(hdc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (VOID**)&dibSection.dsBm.bmBits, NULL, 0);
- dibSection.dsBm.bmHeight = bi.biHeight;
- dibSection.dsBm.bmWidth = bi.biWidth;
- }
-
- ASSERT(hbmpCachedDib != 0);
- HBITMAP hbmpTmp = (HBITMAP)SelectObject(hdcTmp, hbmpCachedDib);
-
- StretchBlt(hdcTmp, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, hdcbmp, startx, starty, 14, 14, SRCCOPY);
-
- LONG pitch = dibSection.dsBm.bmWidth*4, cy = lprc->bottom - lprc->top, x;
- LPBYTE cursor, line;
- COLORREF rgbBk = WADlg_getColor(WADLG_WNDBG);// BlendColors(GetSBBackColor(), WADlg_getColor(WADLG_ITEMBG), ((float)INACTIVEBAR_ALPHA)/255.0f);
- BYTE k = (((255 - alpha)*255 + 127)/255);
- BYTE r = (GetRValue(rgbBk)*k + 127)/255, g = (GetGValue(rgbBk)*k + 127)>>8, b = (GetBValue(rgbBk)*k + 127)/255;
-
- for (line = (BYTE*)dibSection.dsBm.bmBits; cy-- != 0; line += pitch )
- {
- for (x = (lprc->right - lprc->left), cursor = line; x-- != 0; cursor += 4)
- {
- cursor[0] = (cursor[0]*alpha)/255 + b;
- cursor[1] = (cursor[1]*alpha)/255 + g;
- cursor[2] = (cursor[2]*alpha)/255 + r;
- cursor[3] = 0xFF;
- }
- }
-
- BitBlt(hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top, hdcTmp, 0, 0, SRCCOPY);
- SelectObject(hdcTmp, hbmpTmp);
- DeleteDC(hdcTmp);
- }
- SelectObject(hdcbmp, hbmpOld);
- return 1;
- }
- // Draw a standard scrollbar arrow
- static int DrawScrollArrow(SCROLLBAR *sbar, HDC hdc, RECT *rect, UINT arrow, BOOL fMouseDown, BOOL fMouseOver, BOOL freeform)
- {
- UINT ret;
- UINT flags = arrow;
- //HACKY bit so this routine can be called by vertical and horizontal code
- if (sbar->nBarType == SB_VERT)
- {
- if (flags & DFCS_SCROLLLEFT) flags = flags & ~DFCS_SCROLLLEFT | DFCS_SCROLLUP;
- if (flags & DFCS_SCROLLRIGHT) flags = flags & ~DFCS_SCROLLRIGHT | DFCS_SCROLLDOWN;
- }
- if (fMouseDown) flags |= (DFCS_FLAT | DFCS_PUSHED);
- ret = DrawFrameCtrl(hdc, rect, DFC_SCROLL, flags, fMouseOver, freeform);
- return ret;
- }
- // Return the size in pixels for the specified scrollbar metric, for the specified scrollbar
- static int GetScrollMetric(SCROLLBAR *psb, int metric, DWORD scrollFlags)
- {
- int type (psb ? psb->nBarType : SB_VERT);
- switch (type)
- {
- case SB_HORZ:
- {
- switch (metric)
- {
- case SM_CXHORZSB:
- if (SWS_USEFREEFORM & scrollFlags)
- {
- SkinBitmap button(L"wasabi.scrollbar.horizontal.left"); // we assume symmetry which isn't necessary safe
- if (!button.isInvalid())
- return WASABI_API_APP->getScaleX(button.getWidth());
- }
- return WASABI_API_APP->getScaleX(14); // classic skin fixes this at 14
- default:
- if (SWS_USEFREEFORM & scrollFlags)
- {
- SkinBitmap button(L"wasabi.scrollbar.horizontal.left"); // we assume symmetry which isn't necessary safe
- if (!button.isInvalid())
- return WASABI_API_APP->getScaleY(button.getHeight());
- }
- return WASABI_API_APP->getScaleY(14); // classic skin fixes this at 14
- break;
- }
- }
- break;
- default: // case SB_VERT:
- {
- switch (metric)
- {
- case SM_CYVERTSB:
- if (SWS_USEFREEFORM & scrollFlags)
- {
- SkinBitmap button(L"wasabi.scrollbar.vertical.left"); // we assume symmetry which isn't necessary safe
- if (!button.isInvalid())
- return WASABI_API_APP->getScaleY(button.getHeight());
- }
- return WASABI_API_APP->getScaleY(14); // classic skin fixes this at 14
- default:
- if (SWS_USEFREEFORM & scrollFlags)
- {
- SkinBitmap button(L"wasabi.scrollbar.vertical.left"); // we assume symmetry which isn't necessary safe
- if (!button.isInvalid())
- return WASABI_API_APP->getScaleX(button.getWidth());
- }
- return WASABI_API_APP->getScaleX(14); // classic skin fixes this at 14
- break;
- }
- }
- break;
- }
- /*
- if ((SB_HORZ == psb->nBarType && metric == SM_CXHORZSB) || (SB_VERT == psb->nBarType && metric == SM_CYVERTSB))
- return (psb->nArrowLength == SYSTEM_METRIC) * ((psb->nArrowLength < 0) ? -14 : 1);
- else return psb->nArrowWidth * ((psb->nArrowWidth < 0) ? -14 : 1);
- */
- }
- // Fill the specifed rectangle using a solid colour
- static void PaintRect(HDC hdc, RECT *rect, COLORREF color)
- {
- COLORREF oldcol = SetBkColor(hdc, color);
- ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, rect, L"", 0, 0);
- SetBkColor(hdc, oldcol);
- }
- //
- // Set the minimum size, in pixels, that the thumb box will shrink to.
- //
- // Draw a simple blank scrollbar push-button. Can be used
- // to draw a push button, or the scrollbar thumb
- // drawflag - could set to BF_FLAT to make flat scrollbars
- static void DrawBlankButton(HDC hdc, const RECT *rect, UINT drawflag, int pushed, int vertical)
- {
- HBITMAP hbmp, hbmpOld;
- hbmp = WADlg_getBitmap();
- if (!hbmp) return;
- HDC hdcbmp = (HDC)MlStockObjects_Get(CACHED_DC);
- if (!hdcbmp) return;
- hbmpOld = (HBITMAP)SelectObject(hdcbmp, hbmp);
- #define PART1SIZE 4 //copied top
- #define PART2SIZE 5 //stretched top
- #define PART3SIZE 10 //copied middle
- #define PART4SIZE 5 //stretched bottom
- #define PART5SIZE 4 //copied bottom
- if (vertical)
- {
- int middle = (rect->bottom - rect->top) / 2;
- int startx = pushed ? 70 : 56;
- //top
- StretchBlt(hdc, rect->left, rect->top, rect->right - rect->left, PART1SIZE, hdcbmp, startx, 31, 14, PART1SIZE, SRCCOPY);
- int p = PART1SIZE;
- //stretched top
- int l = middle - PART1SIZE - (PART3SIZE / 2);
- if (l > 0)
- {
- StretchBlt(hdc, rect->left, rect->top + p, rect->right - rect->left, l, hdcbmp, startx, 31 + PART1SIZE, 14, PART2SIZE, SRCCOPY);
- p += middle - PART1SIZE - (PART3SIZE / 2);
- }
- //copied middle
- int m = (rect->bottom - rect->top) - PART1SIZE - PART5SIZE; //space that's available for middle
- m = min(m, PART3SIZE);
- if (m > 0)
- {
- StretchBlt(hdc, rect->left, rect->top + p, rect->right - rect->left, m, hdcbmp, startx, 31 + PART1SIZE + PART2SIZE, 14, m, SRCCOPY);
- p += m;
- }
- //stretched bottom
- l = rect->bottom - rect->top - p - PART5SIZE;
- if (l > 0) StretchBlt(hdc, rect->left, rect->top + p, rect->right - rect->left, l, hdcbmp, startx, 31 + PART1SIZE + PART2SIZE + PART3SIZE, 14, PART4SIZE, SRCCOPY);
- //bottom
- StretchBlt(hdc, rect->left, rect->bottom - PART5SIZE, rect->right - rect->left, PART5SIZE, hdcbmp, startx, 31 + PART1SIZE + PART2SIZE + PART3SIZE + PART4SIZE, 14, PART5SIZE, SRCCOPY);
- }
- else
- {
- int middle = (rect->right - rect->left) / 2;
- int starty = pushed ? 45 : 31;
- //top
- StretchBlt(hdc, rect->left, rect->top, PART1SIZE, rect->bottom - rect->top, hdcbmp, 84, starty, PART1SIZE, 14, SRCCOPY);
- int p = PART1SIZE;
- //stretched top
- int l = middle - PART1SIZE - (PART3SIZE / 2);
- if (l > 0)
- {
- StretchBlt(hdc, rect->left + p, rect->top, l, rect->bottom - rect->top, hdcbmp, 84 + PART1SIZE, starty, PART2SIZE, 14, SRCCOPY);
- p += middle - PART1SIZE - (PART3SIZE / 2);
- }
- //copied middle
- int m = (rect->right - rect->left) - PART1SIZE - PART5SIZE; //space that's available for middle
- m = min(m, PART3SIZE);
- if (m > 0)
- {
- StretchBlt(hdc, rect->left + p, rect->top, m, rect->bottom - rect->top, hdcbmp, 84 + PART1SIZE + PART2SIZE, starty, m, 14, SRCCOPY);
- p += m;
- }
- //stretched bottom
- l = rect->right - rect->left - p - PART5SIZE;
- if (l > 0) StretchBlt(hdc, rect->left + p, rect->top, l, rect->bottom - rect->top, hdcbmp, 84 + PART1SIZE + PART2SIZE + PART3SIZE, starty, PART4SIZE, 14, SRCCOPY);
- //bottom
- StretchBlt(hdc, rect->right - PART5SIZE, rect->top, PART5SIZE, rect->bottom - rect->top, hdcbmp, 84 + PART1SIZE + PART2SIZE + PART3SIZE + PART4SIZE, starty, PART5SIZE, 14, SRCCOPY);
- }
- SelectObject(hdcbmp, hbmpOld);
- }
- // Calculate the screen coordinates of the area taken by
- // the horizontal scrollbar. Take into account the size
- // of the window borders
- static BOOL GetHScrollRect(SkinnedScrollWnd *pWnd, RECT *prc)
- {
- if (pWnd->psbHorz->fScrollVisible)
- {
- GetClientRect(pWnd->hwnd, prc);
- MapWindowPoints(pWnd->hwnd, HWND_DESKTOP, (POINT*)prc, 2);
- prc->top = prc->bottom;
- prc->bottom += GetScrollMetric(pWnd->psbHorz, SM_CYHORZSB, pWnd->scrollFlags);
- }
- else SetRect(prc, 0, 0, 0, 0);
- return TRUE;
- }
- // Calculate the screen coordinates of the area taken by the
- // vertical scrollbar
- static BOOL GetVScrollRect(SkinnedScrollWnd *pWnd, RECT *prc)
- {
- if (pWnd->psbVert->fScrollVisible)
- {
- GetClientRect(pWnd->hwnd, prc);
- MapWindowPoints(pWnd->hwnd, HWND_DESKTOP, (POINT*)prc, 2);
- if (SWS_LEFT & pWnd->scrollFlags)
- {
- prc->right = prc->left;
- prc->left -= GetScrollMetric(pWnd->psbVert, SM_CXVERTSB, pWnd->scrollFlags);
- }
- else
- {
- prc->left = prc->right;
- prc->right += GetScrollMetric(pWnd->psbVert, SM_CXVERTSB, pWnd->scrollFlags);
- }
- }
- else SetRect(prc, 0, 0, 0, 0);
-
- return TRUE;
- }
- // Depending on what type of scrollbar nBar refers to, call the
- // appropriate Get?ScrollRect function
- //
- static BOOL GetScrollRect(SkinnedScrollWnd *pWnd, UINT nBar, RECT *prc)
- {
- if (nBar == SB_HORZ) return GetHScrollRect(pWnd, prc);
- else if (nBar == SB_VERT) return GetVScrollRect(pWnd, prc);
- else return FALSE;
- }
- //
- // Work out the scrollbar width/height for either type of scrollbar (SB_HORZ/SB_VERT)
- // rect - coords of the scrollbar.
- // store results into *thumbsize and *thumbpos
- //
- static int CalcThumbSize(SCROLLBAR *sbar, const RECT *rect, int *pthumbsize, int *pthumbpos, DWORD scrollFlags)
- {
- SCROLLINFO *si;
- int scrollsize; //total size of the scrollbar including arrow buttons
- int workingsize; //working area (where the thumb can slide)
- int siMaxMin;
- int butsize;
- int startcoord;
- int thumbpos = 0, thumbsize = 0;
- //work out the width (for a horizontal) or the height (for a vertical)
- //of a standard scrollbar button
- butsize = GetScrollMetric(sbar, SM_SCROLL_LENGTH, scrollFlags);
- if (1) //sbar->nBarType == SB_HORZ)
- {
- scrollsize = rect->right - rect->left;
- startcoord = rect->left;
- }
- /*else if(sbar->nBarType == SB_VERT)
- {
- scrollsize = rect->bottom - rect->top;
- startcoord = rect->top;
- }
- else
- {
- return 0;
- }*/
- si = &sbar->scrollInfo;
- siMaxMin = si->nMax - si->nMin + 1;
- workingsize = scrollsize - butsize * 2;
- //
- // Work out the scrollbar thumb SIZE
- //
- if (si->nPage == 0)
- {
- thumbsize = butsize;
- }
- else if (siMaxMin > 0)
- {
- /*if (SWS_HIDEHSCROLL & scrollFlags)
- thumbsize = MulDiv(si->nPage, workingsize, si->nMax);
- else*/
- thumbsize = MulDiv(si->nPage, workingsize, siMaxMin);
- if (SWS_USEFREEFORM & scrollFlags)
- {
- SkinBitmap thumb((sbar->nBarType == SB_VERT)?L"wasabi.scrollbar.vertical.button":L"wasabi.scrollbar.horizontal.button");
- if (!thumb.isInvalid())
- thumbsize = (sbar->nBarType == SB_VERT)?thumb.getHeight():thumb.getWidth();
- }
- if (thumbsize < sbar->nMinThumbSize)
- thumbsize = sbar->nMinThumbSize;
- }
- //
- // Work out the scrollbar thumb position
- //
- if (siMaxMin > 0)
- {
- int pagesize = max(1, si->nPage);
- thumbpos = MulDiv(si->nPos - si->nMin, workingsize - thumbsize, siMaxMin - pagesize);
- /*if (SWS_HIDEHSCROLL & scrollFlags)
- {
- thumbpos = (si->nPos == (si->nMax - si->nPage)) ?
- (workingsize - thumbsize) : MulDiv(si->nPos, workingsize, si->nMax);
- }*/
- if (thumbpos < 0)
- thumbpos = 0;
- if (thumbpos >= workingsize - thumbsize)
- thumbpos = workingsize - thumbsize;
- }
- thumbpos += startcoord + butsize;
- *pthumbpos = thumbpos;
- *pthumbsize = thumbsize;
- return 1;
- }
- //
- // return a hit-test value for whatever part of the scrollbar x,y is located in
- // rect, x, y: SCREEN coordinates
- // the rectangle must not include space for any inserted buttons
- // (i.e, JUST the scrollbar area)
- //
- static UINT GetHorzScrollPortion(SCROLLBAR *sbar, HWND hwnd, const RECT *rect, int x, int y, DWORD scrollFlags)
- {
- int thumbwidth, thumbpos;
- int butwidth = GetScrollMetric(sbar, SM_SCROLL_LENGTH, scrollFlags);
- int scrollwidth = rect->right - rect->left;
- int workingwidth = scrollwidth - butwidth * 2;
- if (y < rect->top || y >= rect->bottom)
- return HTSCROLL_NONE;
- CalcThumbSize(sbar, rect, &thumbwidth, &thumbpos, scrollFlags);
- //if we have had to scale the buttons to fit in the rect,
- //then adjust the button width accordingly
- if (scrollwidth <= butwidth * 2)
- {
- butwidth = scrollwidth / 2;
- }
- //check for left button click
- if (x >= rect->left && x < rect->left + butwidth)
- {
- return (ESB_DISABLE_LEFT & sbar->fScrollFlags) ? HTSCROLL_NONE : HTSCROLL_LEFT;
- }
- //check for right button click
- else if (x >= rect->right - butwidth && x < rect->right)
- {
- return (ESB_DISABLE_RIGHT & sbar->fScrollFlags) ? HTSCROLL_NONE : HTSCROLL_RIGHT;
- }
- //if the thumb is too big to fit (i.e. it isn't visible)
- //then return a NULL scrollbar area
- if (thumbwidth >= workingwidth)
- return HTSCROLL_NONE;
- //check for point in the thumbbar
- if (x >= thumbpos && x < thumbpos + thumbwidth)
- {
- return HTSCROLL_THUMB;
- }
- //check for left margin
- else if (x >= rect->left + butwidth && x < thumbpos)
- {
- return HTSCROLL_PAGELEFT;
- }
- else if (x >= thumbpos + thumbwidth && x < rect->right - butwidth)
- {
- return HTSCROLL_PAGERIGHT;
- }
- return HTSCROLL_NONE;
- }
- //
- // For vertical scrollbars, rotate all coordinates by -90 degrees
- // so that we can use the horizontal version of this function
- //
- static UINT GetVertScrollPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, DWORD scrollFlags)
- {
- UINT r;
- RotateRect(rect);
- r = GetHorzScrollPortion(sb, hwnd, rect, y, x, scrollFlags);
- RotateRect(rect);
- return r;
- }
- static const wchar_t *GetThumbID(UINT barType, UINT scrollFlags, BOOL hover)
- {
- if (barType == SB_VERT)
- {
- if (scrollFlags & CSBS_TRACKING)
- return L"wasabi.scrollbar.vertical.button.pressed";
- else if (hover)
- return L"wasabi.scrollbar.vertical.button.hover";
- else
- return L"wasabi.scrollbar.vertical.button";
- }
- else
- {
- if (scrollFlags & CSBS_TRACKING)
- return L"wasabi.scrollbar.horizontal.button.pressed";
- else if (hover)
- return L"wasabi.scrollbar.horizontal.button.hover";
- else
- return L"wasabi.scrollbar.horizontal.button";
- }
- }
- static HBRUSH SetWindowPatternBrush(HWND hwnd, HDC hdc, UINT nBarType)
- {
- RECT rw;
- GetWindowRect(hwnd, &rw);
- HWND hwndAncestor = GetAncestor(hwnd, GA_ROOT);
- if (hwndAncestor) MapWindowPoints(HWND_DESKTOP, hwndAncestor, (POINT*)&rw, 2);
- POINT ptOrg;
- if (GetViewportOrgEx(hdc, &ptOrg)) OffsetRect(&rw, ptOrg.x, ptOrg.y);
- if (nBarType == SB_VERT)
- {
- if (0 == (GetWindowLongPtrW(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR)) rw.left = rw.right;
- }
- else rw.top = rw.bottom;
- SetBrushOrgEx(hdc, rw.left, rw.top, (POINT*)&rw);
- return (HBRUSH)SelectObject(hdc, hbrChecked);
- }
- //
- // Draw a complete HORIZONTAL scrollbar in the given rectangle
- // Don't draw any inserted buttons in this procedure
- //
- // uDrawFlags - hittest code, to say if to draw the
- // specified portion in an active state or not.
- //
- //
- static LRESULT NCDrawHScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, UINT hoverFlags, DWORD scrollFlags)
- {
- SCROLLINFO *si;
- RECT ctrl, thumb;
- RECT sbm;
- int butwidth = GetScrollMetric(sb, SM_SCROLL_LENGTH, scrollFlags);
- int scrollwidth = rect->right - rect->left;
- int workingwidth = scrollwidth - butwidth * 2;
- int thumbwidth = 0, thumbpos = 0;
- int siMaxMin;
- BOOL fMouseDownL = 0, fMouseOverL = (hoverFlags == HTSCROLL_LEFT);
- BOOL fMouseDownR = 0, fMouseOverR = (hoverFlags == HTSCROLL_RIGHT);
- BOOL fMouseOverThumb = (hoverFlags == HTSCROLL_THUMB);
- COLORREF crCheck1 = GetSBForeColor();
- COLORREF crCheck2 = GetSBBackColor();
- COLORREF crInverse1 = WADlg_getColor(WADLG_SCROLLBAR_INV_FGCOLOR);
- COLORREF crInverse2 = WADlg_getColor(WADLG_SCROLLBAR_INV_BGCOLOR);
- UINT uDFCFlat = (CSBS_FLATSB & sb->fScrollFlags) ? DFCS_FLAT : 0;
- UINT uDEFlat = (CSBS_FLATSB & sb->fScrollFlags) ? BF_FLAT : 0;
- //drawing flags to modify the appearance of the scrollbar buttons
- UINT uLeftButFlags = DFCS_SCROLLLEFT;
- UINT uRightButFlags = DFCS_SCROLLRIGHT;
- if (scrollwidth <= 0)
- return 0;
- si = &sb->scrollInfo;
- siMaxMin = si->nMax - si->nMin;
- if (hwnd != hwndCurCoolSB)
- uDrawFlags = HTSCROLL_NONE;
- //
- // work out the thumb size and position
- //
- CalcThumbSize(sb, rect, &thumbwidth, &thumbpos, scrollFlags);
- if ((CSBS_TRACKING & sb->fScrollFlags) && trackThumbPos != -1)
- {
- thumbpos=trackThumbPos;
- }
- if (sb->fScrollFlags & ESB_DISABLE_LEFT) uLeftButFlags |= DFCS_INACTIVE;
- if (sb->fScrollFlags & ESB_DISABLE_RIGHT) uRightButFlags |= DFCS_INACTIVE;
- //if we need to grey the arrows because there is no data to scroll
- if ((0 == (DFCS_INACTIVE & uLeftButFlags) || 0 == (DFCS_INACTIVE & uRightButFlags)) &&
- !(sb->fScrollFlags & CSBS_THUMBALWAYS) && !IsScrollInfoActive(si))
- {
- uLeftButFlags |= DFCS_INACTIVE;
- uRightButFlags |= DFCS_INACTIVE;
- }
- if ((DFCS_INACTIVE & uLeftButFlags) && (DFCS_INACTIVE & uRightButFlags))
- {
- COLORREF rgbBk = WADlg_getColor(WADLG_WNDBG);
- crCheck1 = BlendColors(crCheck1, rgbBk, INACTIVEBAR_ALPHA);
- crCheck2 = BlendColors(crCheck2, rgbBk, INACTIVEBAR_ALPHA);
- }
- if (hwnd == hwndCurCoolSB)
- {
- fMouseDownL = (uDrawFlags == HTSCROLL_LEFT);
- fMouseDownR = (uDrawFlags == HTSCROLL_RIGHT);
- }
- if (NULL == hbrChecked) //recreate pattern brush if needed
- {
- HBITMAP hbmp = CreateBitmap(8, 8, 1, 1, wCheckPat);
- hbrChecked = CreatePatternBrush(hbmp);
- DeleteObject(hbmp);
- if (NULL == hbrChecked) return 0;
- }
-
- HBRUSH hbrOld = NULL;
- COLORREF rgbFgOld, rgbBkOld;
- rgbFgOld = SetTextColor(hdc, crCheck1);
- rgbBkOld = SetBkColor(hdc, crCheck2);
- //
- // Draw the scrollbar now
- //
- if (scrollwidth > butwidth*2)
- {
- DCCanvas canvas(hdc);
- if (SWS_USEFREEFORM & scrollFlags)
- {
- CopyRect(&ctrl, rect);
- RotateRect0(sb, &ctrl);
- RenderBaseTexture(&canvas, &ctrl, hwnd);
- }
-
- //LEFT ARROW
- SetRect(&ctrl, rect->left, rect->top, rect->left + butwidth, rect->bottom);
- RotateRect0(sb, &ctrl);
- DrawScrollArrow(sb, hdc, &ctrl, uLeftButFlags, fMouseDownL, fMouseOverL, (SWS_USEFREEFORM & scrollFlags));
- RotateRect0(sb, &ctrl);
- //MIDDLE PORTION
- //if we can fit the thumbbar in, then draw it
- if (thumbwidth > 0 && thumbwidth <= workingwidth
- && IsScrollInfoActive(si) && ((sb->fScrollFlags & ESB_DISABLE_BOTH) != ESB_DISABLE_BOTH))
- {
- SkinBitmap *bg = (scrollBitmaps && (SWS_USEFREEFORM & scrollFlags)) ?
- ((sb->nBarType== SB_VERT) ? scrollBitmaps->v_mid.getBitmap(): scrollBitmaps->h_mid.getBitmap())
- : 0;
- if ((SWS_USEFREEFORM & scrollFlags) && bg && !bg->isInvalid())
- {
- SetRect(&sbm, rect->left + butwidth, rect->top, rect->right-butwidth, rect->bottom);
- RotateRect0(sb, &sbm);
- bg->stretchToRectAlpha(&canvas, &sbm);
- SkinBitmap thumbBitmap(GetThumbID(sb->nBarType, sb->fScrollFlags, fMouseOverThumb));
- SetRect(&sbm, thumbpos, rect->top, thumbpos+thumbwidth, rect->bottom);
- RotateRect0(sb, &sbm);
- if (!thumbBitmap.isInvalid())
- thumbBitmap.stretchToRectAlpha(&canvas, &sbm);
- else
- DrawBlankButton(hdc, &sbm, uDEFlat, (CSBS_TRACKING & sb->fScrollFlags), sb->nBarType == SB_VERT);
- }
- else
- {
- //Draw the scrollbar margin above the thumb
- SetRect(&sbm, rect->left + butwidth, rect->top, thumbpos, rect->bottom);
- RotateRect0(sb, &sbm);
- if (HTSCROLL_PAGELEFT == uDrawFlags)
- {
- SetTextColor(hdc, crInverse1);
- SetBkColor(hdc, crInverse2);
- }
-
- if (GetTextColor(hdc) == GetBkColor(hdc)) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &sbm, NULL, 0, NULL);
- else
- {
- if (NULL == hbrOld) hbrOld = SetWindowPatternBrush(hwnd, hdc, sb->nBarType);
- PatBlt(hdc, sbm.left, sbm.top, sbm.right - sbm.left, sbm.bottom - sbm.top, PATCOPY);
- }
-
- if (HTSCROLL_PAGELEFT == uDrawFlags)
- {
- SetTextColor(hdc, crCheck1);
- SetBkColor(hdc, crCheck2);
- }
- RotateRect0(sb, &sbm);
- //Draw the margin below the thumb
- sbm.left = thumbpos + thumbwidth;
- sbm.right = rect->right - butwidth;
- RotateRect0(sb, &sbm);
-
- if (HTSCROLL_PAGERIGHT == uDrawFlags)
- {
- SetTextColor(hdc, crInverse1);
- SetBkColor(hdc, crInverse2);
- }
-
- if (GetTextColor(hdc) == GetBkColor(hdc)) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &sbm, NULL, 0, NULL);
- else
- {
- if (NULL == hbrOld) hbrOld = SetWindowPatternBrush(hwnd, hdc, sb->nBarType);
- PatBlt(hdc, sbm.left, sbm.top, sbm.right - sbm.left, sbm.bottom - sbm.top, PATCOPY);
- }
-
- if (HTSCROLL_PAGERIGHT == uDrawFlags)
- {
- SetTextColor(hdc, crCheck1);
- SetBkColor(hdc, crCheck2);
- }
- RotateRect0(sb, &sbm);
- //Draw the THUMB finally
- SetRect(&thumb, thumbpos, rect->top, thumbpos + thumbwidth, rect->bottom);
- RotateRect0(sb, &thumb);
- DrawBlankButton(hdc, &thumb, uDEFlat, (CSBS_TRACKING & sb->fScrollFlags), sb->nBarType == SB_VERT);
- RotateRect0(sb, &thumb);
- }
- }
- //otherwise, just leave that whole area blank
- else
- {
- OffsetRect(&ctrl, butwidth, 0);
- ctrl.right = rect->right - butwidth;
- //if we always show the thumb covering the whole scrollbar,
- //then draw it that way
- if (!IsScrollInfoActive(si) && (sb->fScrollFlags & CSBS_THUMBALWAYS)
- && ctrl.right - ctrl.left > sb->nMinThumbSize)
- {
- //leave a 1-pixel gap between the thumb + right button
- ctrl.right --;
- RotateRect0(sb, &ctrl);
- DrawBlankButton(hdc, &ctrl, uDEFlat, 0, sb->nBarType == SB_VERT);
- RotateRect0(sb, &ctrl);
- //draw the single-line gap
- ctrl.left = ctrl.right;
- ctrl.right += 1;
- RotateRect0(sb, &ctrl);
- PaintRect(hdc, &ctrl, GetSysColor(COLOR_SCROLLBAR));
- RotateRect0(sb, &ctrl);
- }
- //otherwise, paint a blank if the thumb doesn't fit in
- else
- {
- RotateRect0(sb, &ctrl);
- BOOL classic(TRUE);
- if (SWS_USEFREEFORM & scrollFlags)
- {
- SkinBitmap background(sb->nBarType== SB_VERT?L"wasabi.scrollbar.vertical.background.middle":L"wasabi.scrollbar.horizontal.background.middle");
- if (!background.isInvalid())
- {
- background.stretchToRectAlpha(&canvas, &ctrl,
- ((DFCS_INACTIVE & uLeftButFlags) && (DFCS_INACTIVE & uRightButFlags)) ? INACTIVEBAR_ALPHA : 255);
- classic = FALSE;
- }
- }
- if (classic)
- {
- if (crCheck1 == crCheck2) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &ctrl, NULL, 0, NULL);
- else
- {
- if (NULL == hbrOld) hbrOld = SetWindowPatternBrush(hwnd, hdc, sb->nBarType);
- PatBlt(hdc, ctrl.left, ctrl.top, ctrl.right - ctrl.left, ctrl.bottom - ctrl.top, PATCOPY);
- }
- }
-
- RotateRect0(sb, &ctrl);
- }
- }
- //RIGHT ARROW
- SetRect(&ctrl, rect->right - butwidth, rect->top, rect->right, rect->bottom);
- RotateRect0(sb, &ctrl);
- DrawScrollArrow(sb, hdc, &ctrl, uRightButFlags, fMouseDownR, fMouseOverR, (SWS_USEFREEFORM & scrollFlags));
- RotateRect0(sb, &ctrl);
- }
- //not enough room for the scrollbar, so just draw the buttons (scaled in size to fit)
- else
- {
- butwidth = scrollwidth / 2;
- //LEFT ARROW
- SetRect(&ctrl, rect->left, rect->top, rect->left + butwidth, rect->bottom);
- RotateRect0(sb, &ctrl);
- DrawScrollArrow(sb, hdc, &ctrl, uLeftButFlags, fMouseDownL, fMouseOverL, (SWS_USEFREEFORM & scrollFlags));
- RotateRect0(sb, &ctrl);
- //RIGHT ARROW
- OffsetRect(&ctrl, scrollwidth - butwidth, 0);
- RotateRect0(sb, &ctrl);
- DrawScrollArrow(sb, hdc, &ctrl, uRightButFlags, fMouseDownR, fMouseOverR, (SWS_USEFREEFORM & scrollFlags));
- RotateRect0(sb, &ctrl);
- //if there is a gap between the buttons, fill it with a solid color
- //if(butwidth & 0x0001)
- if (ctrl.left != rect->left + butwidth)
- {
- ctrl.left --;
- ctrl.right -= butwidth;
- RotateRect0(sb, &ctrl);
- BOOL classic(TRUE);
- if (SWS_USEFREEFORM & scrollFlags)
- {
- SkinBitmap background(sb->nBarType== SB_VERT?L"wasabi.scrollbar.vertical.background.middle":L"wasabi.scrollbar.horizontal.background.middle");
- if (!background.isInvalid())
- {
- DCCanvas canvas(hdc);
- RenderBaseTexture(&canvas, &ctrl, hwnd);
- background.stretchToRectAlpha(&canvas, &ctrl,
- ((DFCS_INACTIVE & uLeftButFlags) && (DFCS_INACTIVE & uRightButFlags)) ? INACTIVEBAR_ALPHA : 255);
- classic = FALSE;
- }
- }
- if (classic)
- {
- if (crCheck1 == crCheck2) ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &ctrl, NULL, 0, NULL);
- else
- {
- if (NULL == hbrOld) hbrOld = SetWindowPatternBrush(hwnd, hdc, sb->nBarType);
- PatBlt(hdc, ctrl.left, ctrl.top, ctrl.right - ctrl.left, ctrl.bottom - ctrl.top, PATCOPY);
- }
- }
- RotateRect0(sb, &ctrl);
- }
- }
- SetBkColor(hdc, rgbBkOld);
- SetTextColor(hdc, rgbFgOld);
- if (hbrOld)
- {
- SelectObject(hdc, hbrOld);
- SetBrushOrgEx(hdc, 0, 0, NULL);
- }
- return 0;
- }
- //
- // Draw a vertical scrollbar using the horizontal draw routine, but
- // with the coordinates adjusted accordingly
- //
- static LRESULT NCDrawVScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, UINT hoverFlags, DWORD scrollFlags)
- {
- LRESULT ret;
- RECT rc;
- rc = *rect;
- RotateRect(&rc);
- ret = NCDrawHScrollbar(sb, hwnd, hdc, &rc, uDrawFlags, hoverFlags, scrollFlags);
- RotateRect(&rc);
- return ret;
- }
- //
- // Generic wrapper function for the scrollbar drawing
- //
- static LRESULT NCDrawScrollbar(SCROLLBAR *sb, HWND hwnd, HDC hdc, const RECT *rect, UINT uDrawFlags, UINT hoverFlags, DWORD scrollFlags)
- {
- if (sb->nBarType == SB_HORZ)
- return NCDrawHScrollbar(sb, hwnd, hdc, rect, uDrawFlags, hoverFlags, scrollFlags);
- else
- return NCDrawVScrollbar(sb, hwnd, hdc, rect, uDrawFlags, hoverFlags, scrollFlags);
- }
- void SkinnedScrollWnd::PaintNonClient(HDC hdc)
- {
- RECT winrect, rcH, rcV;
- BOOL drawH = FALSE, drawV = FALSE;
- if (!psbHorz->fScrollVisible && !psbVert->fScrollVisible)
- {
- DrawBorder(hdc);
- return;
- }
-
- if (0 == (SWS_UPDATEFRAME & scrollFlags))
- {
- HWND hwndActive;
- hwndActive = GetActiveWindow();
- if (hwndActive != hwnd && !IsChild(hwndActive, hwnd)) scrollFlags |= SWS_UPDATEFRAME;
- }
- GetWindowRect(hwnd, &winrect);
- if (psbHorz->fScrollVisible)
- {
- GetHScrollRect(this, &rcH);
- OffsetRect(&rcH, -winrect.left, -winrect.top);
- if (rcH.right > rcH.left && rcH.bottom > rcH.top && RectVisible(hdc, &rcH)) drawH = TRUE;
- }
- if (psbVert->fScrollVisible)
- {
- GetVScrollRect(this, &rcV);
- OffsetRect(&rcV, -winrect.left, -winrect.top);
-
- if (rcV.right > rcV.left && rcV.bottom > rcV.top && RectVisible(hdc, &rcV)) drawV = TRUE;
- }
- DrawBorder(hdc);
-
- POINT ptOrg;
- GetViewportOrgEx(hdc, &ptOrg);
- if (drawH)
- {
- UINT fDraw, fHover;
- if (uCurrentScrollbar == SB_HORZ) { fDraw = uScrollTimerPortion; fHover = HTSCROLL_NONE; }
- else
- {
- fDraw = HTSCROLL_NONE;
- fHover = (NULL != psbHorz && 0 != (CSBS_HOVERING & psbHorz->fScrollFlags)) ? scrollPortionHover : HTSCROLL_NONE;
- }
- if (SWS_USEFREEFORM & scrollFlags)
- {
- DCBltCanvas buffer;
- buffer.cloneDC(hdc, &rcH);
- NCDrawHScrollbar(psbHorz, hwnd, buffer.getHDC(), &rcH, fDraw, fHover, scrollFlags);
- }
- else
- {
- SetViewportOrgEx(hdc, ptOrg.x + rcH.left, ptOrg.y + rcH.top, NULL);
- OffsetRect(&rcH, -rcH.left, -rcH.top);
- NCDrawHScrollbar(psbHorz, hwnd, hdc, &rcH, fDraw, fHover, scrollFlags);
- SetViewportOrgEx(hdc, ptOrg.x, ptOrg.y, NULL);
- }
- }
- if (drawV)
- {
- UINT fDraw, fHover;
- if (uCurrentScrollbar == SB_VERT) { fDraw = uScrollTimerPortion; fHover = HTSCROLL_NONE; }
- else
- {
- fDraw = HTSCROLL_NONE;
- fHover = (NULL != psbVert && 0 != (CSBS_HOVERING & psbVert->fScrollFlags)) ? scrollPortionHover : HTSCROLL_NONE;
- }
- if (SWS_USEFREEFORM & scrollFlags)
- {
- DCBltCanvas buffer;
- buffer.cloneDC(hdc, &rcV);
- NCDrawVScrollbar(psbVert, hwnd, buffer.getHDC(), &rcV, fDraw, fHover, scrollFlags);
-
- }
- else
- {
- SetViewportOrgEx(hdc, ptOrg.x + rcV.left, ptOrg.y + rcV.top, NULL);
- OffsetRect(&rcV, -rcV.left, -rcV.top);
- NCDrawVScrollbar(psbVert, hwnd, hdc, &rcV, fDraw, fHover, scrollFlags);
- SetViewportOrgEx(hdc, ptOrg.x, ptOrg.y, NULL);
- }
-
- }
- SetViewportOrgEx(hdc, ptOrg.x, ptOrg.y, NULL);
- // DRAW THE DEAD AREA
- // only do this if the horizontal and vertical bars are visible
- if (psbHorz->fScrollVisible && psbVert->fScrollVisible)
- {
- GetClientRect(hwnd, &rcH);
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&rcH, 2);
- OffsetRect(&rcH, -winrect.left, -winrect.top);
- rcH.top = rcH.bottom;
- rcH.bottom += GetScrollMetric(psbHorz, SM_CYHORZSB, scrollFlags);
- if (SWS_LEFT & scrollFlags)
- {
- rcH.right = rcH.left;
- rcH.left -= GetScrollMetric(psbVert, SM_CXVERTSB, scrollFlags);
- }
- else
- {
- rcH.left = rcH.right;
- rcH.right += GetScrollMetric(psbVert, SM_CXVERTSB, scrollFlags);
- }
- if (RectVisible(hdc, &rcH))
- {
-
- PaintRect(hdc, &rcH, WADlg_getColor(WADLG_SCROLLBAR_DEADAREA_COLOR));
- }
- }
-
- }
- void SkinnedScrollWnd::OnNcPaint(HRGN rgnUpdate)
- {
- UINT flags = DCX_PARENTCLIP | DCX_CACHE | DCX_WINDOW | DCX_CLIPSIBLINGS |
- DCX_INTERSECTUPDATE | DCX_VALIDATE;
-
- HDC hdc = GetDCEx(hwnd, ((HRGN)NULLREGION != rgnUpdate) ? rgnUpdate : NULL, flags);
-
- if (NULL == hdc)
- {
- return;
- }
-
- PaintNonClient(hdc);
-
-
- ReleaseDC(hwnd, hdc);
- }
- //
- // Need to detect if we have clicked in the scrollbar region or not
- //
- INT SkinnedScrollWnd::OnNcHitTest(POINTS pts)
- {
- RECT rc;
-
- INT r = __super::OnNcHitTest(pts);
- if (r == HTTRANSPARENT)
- {
-
-
- return r;
- }
- if (psbHorz->fScrollVisible && GetHScrollRect(this, &rc) &&
- pts.x >= rc.left && pts.x <= rc.right && pts.y >= rc.top && pts.y <= rc.bottom) return HTHSCROLL;
- if (psbVert->fScrollVisible && GetVScrollRect(this, &rc) &&
- pts.x >= rc.left && pts.x <= rc.right && pts.y >= rc.top && pts.y <= rc.bottom) return HTVSCROLL;
- return r;
- }
- //
- // Return a HT* value indicating what part of the scrollbar was clicked
- // Rectangle is not adjusted
- //
- static UINT GetHorzPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, DWORD scrollFlags)
- {
- RECT rc = *rect;
- if (y < rc.top || y >= rc.bottom) return HTSCROLL_NONE;
- //Now we have the rectangle for the scrollbar itself, so work out
- //what part we clicked on.
- return GetHorzScrollPortion(sb, hwnd, &rc, x, y, scrollFlags);
- }
- //
- // Just call the horizontal version, with adjusted coordinates
- //
- static UINT GetVertPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, DWORD scrollFlags)
- {
- UINT ret;
- RotateRect(rect);
- ret = GetHorzPortion(sb, hwnd, rect, y, x, scrollFlags);
- RotateRect(rect);
- return ret;
- }
- //
- // Wrapper function for GetHorzPortion and GetVertPortion
- //
- static UINT GetPortion(SCROLLBAR *sb, HWND hwnd, RECT *rect, int x, int y, DWORD scrollFlags)
- {
- if (sb->nBarType == SB_HORZ) return GetHorzPortion(sb, hwnd, rect, x, y, scrollFlags);
- else if (sb->nBarType == SB_VERT) return GetVertPortion(sb, hwnd, rect, x, y, scrollFlags);
- return HTSCROLL_NONE;
- }
- //
- // Input: rectangle of the total scrollbar area
- // Output: adjusted to take the inserted buttons into account
- //
- static void GetRealHorzScrollRect(SCROLLBAR *sb, RECT *rect)
- {
- if (CSBS_BTNVISBEFORE & sb->fScrollFlags) rect->left += sb->nButSizeBefore;
- if (CSBS_BTNVISAFTER & sb->fScrollFlags) rect->right -= sb->nButSizeAfter;
- }
- //
- // Input: rectangle of the total scrollbar area
- // Output: adjusted to take the inserted buttons into account
- //
- static void GetRealVertScrollRect(SCROLLBAR *sb, RECT *rect)
- {
- if (CSBS_BTNVISBEFORE & sb->fScrollFlags) rect->top += sb->nButSizeBefore;
- if (CSBS_BTNVISAFTER & sb->fScrollFlags) rect->bottom -= sb->nButSizeAfter;
- }
- //
- // Decide which type of scrollbar we have before calling
- // the real function to do the job
- //
- static void GetRealScrollRect(SCROLLBAR *sb, RECT *rect, DWORD scrollFlags)
- {
- if (sb->nBarType == SB_HORZ)
- {
- GetRealHorzScrollRect(sb, rect);
- }
- else if (sb->nBarType == SB_VERT)
- {
- GetRealVertScrollRect(sb, rect);
- }
- }
- //
- // Left button click in the non-client area
- //
- void SkinnedScrollWnd::OnNcLButtonDown(UINT nHitTest, POINTS pts)
- {
- RECT rect, winrect;
- SCROLLBAR *psb;
- hwndCurCoolSB = hwnd;
- //
- // HORIZONTAL SCROLLBAR PROCESSING
- //
- if (HTHSCROLL == nHitTest)
- {
- psb = psbHorz;
- uScrollTimerMsg = WM_HSCROLL;
- uCurrentScrollbar = SB_HORZ;
- //get the total area of the normal Horz scrollbar area
- GetHScrollRect(this, &rect);
- uCurrentScrollPortion = GetHorzPortion(psbHorz, hwnd, &rect, pts.x, pts.y, scrollFlags);
- }
- //
- // VERTICAL SCROLLBAR PROCESSING
- //
- else if (HTVSCROLL== nHitTest)
- {
- psb = psbVert;
- uScrollTimerMsg = WM_VSCROLL;
- uCurrentScrollbar = SB_VERT;
- //get the total area of the normal Horz scrollbar area
- GetVScrollRect(this, &rect);
- uCurrentScrollPortion = GetVertPortion(psbVert, hwnd, &rect, pts.x, pts.y, scrollFlags);
- }
- //
- // NORMAL PROCESSING
- //
- else
- {
- uCurrentScrollPortion = HTSCROLL_NONE;
- __super::WindowProc(WM_NCLBUTTONDOWN, (WPARAM)nHitTest, *(LPARAM*)&pts);
- return;
- }
- //
- // we can now share the same code for vertical
- // and horizontal scrollbars
- //
- switch (uCurrentScrollPortion)
- {
- //inserted buttons to the left/right
- case HTSCROLL_THUMB:
- //if the scrollbar is disabled, then do no further processing
- if (!IsScrollbarActive(psb)) return;
- GetRealScrollRect(psb, &rect, scrollFlags);
- RotateRect0(psb, &rect);
- CalcThumbSize(psb, &rect, &nThumbSize, &nThumbPos, scrollFlags);
- RotateRect0(psb, &rect);
- //remember the bounding rectangle of the scrollbar work area
- rcThumbBounds = rect;
- trackThumbPos=-1;
- psb->fScrollFlags |= CSBS_TRACKING;
- psb->scrollInfo.nTrackPos = psb->scrollInfo.nPos;
- if (nHitTest == HTVSCROLL) nThumbMouseOffset = pts.y - nThumbPos;
- else nThumbMouseOffset = pts.x - nThumbPos;
- nLastPos = psb->scrollInfo.nPos;
- nThumbPos0 = nThumbPos;
- SCROLLINFO info;
- info.cbSize = sizeof(SCROLLINFO);
- info.fMask = SIF_POS;
- info.nPos = nLastPos;
- SetScrollInfo(hwnd, psb->nBarType, &info, FALSE);
- SendScrollMessage(hwnd, uScrollTimerMsg, SB_THUMBTRACK, nLastPos);
- //if(sb->fFlatScrollbar)
- //{
- GetWindowRect(hwnd, &winrect);
- OffsetRect(&rect, -winrect.left, -winrect.top);
- InvalidateNC(InvalidateFlag_Normal, uCurrentScrollbar);
- //}
- break;
- //Any part of the scrollbar
- case HTSCROLL_LEFT:
- if (psb->fScrollFlags & ESB_DISABLE_LEFT) return;
- goto target1;
- case HTSCROLL_RIGHT:
- if (psb->fScrollFlags & ESB_DISABLE_RIGHT) return;
- goto target1;
- case HTSCROLL_PAGELEFT:
- case HTSCROLL_PAGERIGHT:
- target1:
- //if the scrollbar is disabled, then do no further processing
- if (!IsScrollbarActive(psb))
- break;
- //ajust the horizontal rectangle to NOT include
- //any inserted buttons
- GetRealScrollRect(psb, &rect, scrollFlags);
- SendScrollMessage(hwnd, uScrollTimerMsg, uCurrentScrollPortion, 0);
- // Check what area the mouse is now over :
- // If the scroll thumb has moved under the mouse in response to
- // a call to SetScrollPos etc, then we don't hilight the scrollbar margin
- if (uCurrentScrollbar == SB_HORZ)
- uScrollTimerPortion = GetHorzScrollPortion(psb, hwnd, &rect, pts.x, pts.y, scrollFlags);
- else
- uScrollTimerPortion = GetVertScrollPortion(psb, hwnd, &rect, pts.x, pts.y, scrollFlags);
- GetWindowRect(hwnd, &winrect);
- OffsetRect(&rect, -winrect.left, -winrect.top);
- //if we aren't hot-tracking, then don't highlight
- //the scrollbar thumb unless we click on it
- if (uScrollTimerPortion == HTSCROLL_THUMB) uScrollTimerPortion = HTSCROLL_NONE;
- InvalidateNC(InvalidateFlag_Normal, uCurrentScrollbar);
- //Post the scroll message!!!!
- uScrollTimerPortion = uCurrentScrollPortion;
- //set a timer going on the first click.
- //if this one expires, then we can start off a more regular timer
- //to generate the auto-scroll behaviour
- uScrollTimerId = SetTimer(hwnd, COOLSB_TIMERID1, COOLSB_TIMERINTERVAL1, 0);
- UpdateScrollBars(FALSE);
- break;
- default:
- __super::WindowProc(WM_NCLBUTTONDOWN, (WPARAM)nHitTest, *(LPARAM*)&pts);
- return;
- }
- if ((0 == (SWS_COMBOLBOX & scrollFlags)) && hwnd != GetCapture())
- {
- ignoreCaptureChange = TRUE;
- SetCapture(hwnd);
- ignoreCaptureChange = FALSE;
- captureSet = TRUE;
-
- }
- }
- //
- // Left button released
- //
- void SkinnedScrollWnd::Emulate_LeftButtonUp(UINT nFlags, POINTS pts, BOOL forwardMessage)
- {
- //current scrollportion is the button that we clicked down on
- if (uCurrentScrollPortion != HTSCROLL_NONE)
- {
- RECT rect;
- //UINT thisportion;
- POINT pt;
- RECT winrect;
- SCROLLBAR *psb;
- if (captureSet && (0 == (SWS_COMBOLBOX & scrollFlags)) && hwnd == GetCapture())
- {
- ignoreCaptureChange = TRUE;
- ReleaseCapture();
- ignoreCaptureChange = FALSE;
- }
- captureSet = FALSE;
- GetWindowRect(hwnd, &winrect);
- POINTSTOPOINT(pt, pts);
- //emulate the mouse input on a scrollbar here...
- if (SB_VERT == uCurrentScrollbar)
- {
- //get the total area of the normal Horz scrollbar area
- psb = psbVert;
- GetVScrollRect(this, &rect);
- }
- else
- {
- //get the total area of the normal Horz scrollbar area
- psb = psbHorz;
- GetHScrollRect(this, &rect);
- }
- //we need to do different things depending on if the
- //user is activating the scrollbar itself, or one of
- //the inserted buttons
- switch (uCurrentScrollPortion)
- {
- //The scrollbar is active
- case HTSCROLL_LEFT:
- case HTSCROLL_RIGHT:
- case HTSCROLL_PAGELEFT:
- case HTSCROLL_PAGERIGHT:
- case HTSCROLL_NONE:
- KillTimer(hwnd, uScrollTimerId);
- case HTSCROLL_THUMB:
- UpdateScrollBars(FALSE);
- //In case we were thumb tracking, make sure we stop NOW
- if (CSBS_TRACKING & psb->fScrollFlags)
- {
- SCROLLINFO info;
- info.cbSize = sizeof(SCROLLINFO);
- info.fMask = SIF_POS;
- info.nPos = nLastPos;
- SetScrollInfo(hwnd, psb->nBarType, &info, FALSE);
- SendScrollMessage(hwnd, uScrollTimerMsg, SB_THUMBPOSITION, nLastPos);
- psb->fScrollFlags &= ~CSBS_TRACKING;
- }
- //send the SB_ENDSCROLL message now that scrolling has finished
- SendScrollMessage(hwnd, uScrollTimerMsg, SB_ENDSCROLL, 0);
- //adjust the total scroll area to become where the scrollbar
- //really is (take into account the inserted buttons)
- GetRealScrollRect(psb, &rect, scrollFlags);
- OffsetRect(&rect, -winrect.left, -winrect.top);
- InvalidateNC(InvalidateFlag_Normal, uCurrentScrollbar);
- break;
- }
- //reset our state to default
- uCurrentScrollPortion = HTSCROLL_NONE;
- uScrollTimerPortion = HTSCROLL_NONE;
- uScrollTimerId = 0;
- uScrollTimerMsg = 0;
- uCurrentScrollbar = COOLSB_NONE;
- return;
- }
- else
- {
-
- /*
- // Can't remember why I did this!
- if(GetCapture() == hwnd)
- {
- ReleaseCapture();
- }*/
- }
- //sw->update();
- if (FALSE != forwardMessage)
- {
- __super::WindowProc(WM_LBUTTONUP, (WPARAM)nFlags, *(LPARAM*)&pts);
- }
- }
- void SkinnedScrollWnd::OnLButtonUp(UINT nFlags, POINTS pts)
- {
- Emulate_LeftButtonUp(nFlags, pts, TRUE);
- }
- static int
- ListView_ScrollWindow(HWND hwnd, int dy)
- {
- RECT rect;
- if (0 == dy)
- return NULLREGION;
-
- if (FALSE == GetClientRect(hwnd, &rect))
- return ERROR;
-
- if (0 == (LVS_NOCOLUMNHEADER & GetWindowLongPtrW(hwnd, GWL_STYLE)))
- {
- HWND headerWindow;
- headerWindow = (HWND)SendMessageW(hwnd, LVM_GETHEADER, 0, 0L);
- if (NULL != headerWindow &&
- 0 != (WS_VISIBLE & GetWindowLongPtrW(headerWindow, GWL_STYLE)))
- {
- HDLAYOUT headerLayout;
- WINDOWPOS headerPos;
- headerLayout.prc = ▭
- headerLayout.pwpos = &headerPos;
- SendMessageW(headerWindow, HDM_LAYOUT, 0, (LPARAM)&headerLayout);
- }
- }
- return ScrollWindowEx(hwnd, 0, dy, &rect, &rect, NULL, NULL, SW_INVALIDATE);
- }
- static BOOL ListView_ScrollReportModeVert(HWND hwnd, INT linesVert, BOOL horzBarHidden)
- {
- int max, pos, page;
- int itemHeight, prevPos, dy;
- RECT rect;
- unsigned long windowStyle;
-
- if (0 == linesVert)
- return TRUE;
-
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- pos = (int)SendMessageW(hwnd, LVM_GETTOPINDEX, 0, 0L);
- max = (int)SendMessageW(hwnd, LVM_GETITEMCOUNT, 0, 0L);
- page = (int)SendMessageW(hwnd, LVM_GETCOUNTPERPAGE, 0, 0L);
- if (FALSE == horzBarHidden)
- max++;
-
- if ((linesVert < 0 && pos <= 0) ||
- (linesVert > 0 && (pos + page) >= max))
- {
- return TRUE;
- }
- if (linesVert < 0 && (pos + linesVert) < 0)
- linesVert = -pos;
- else if (linesVert > 0 && (pos + page + linesVert) > max)
- linesVert = max - (page + pos);
-
- rect.left = LVIR_BOUNDS;
- if (!SendMessageW(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect))
- return FALSE;
- if (rect.top < 0)
- OffsetRect(&rect, 0, -rect.top);
- itemHeight = rect.bottom - rect.top;
- if (0 != (WS_VISIBLE & windowStyle))
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
-
- dy = linesVert * itemHeight;
- SendMessageW(hwnd, LVM_SCROLL, 0, dy);
-
- if (0 == (WS_VISIBLE & windowStyle))
- return TRUE;
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle);
- prevPos = pos;
- pos = (int)SendMessageW(hwnd, LVM_GETTOPINDEX, 0, 0L);
- linesVert = pos - prevPos;
-
- dy = linesVert * itemHeight;
- if (ERROR == ListView_ScrollWindow(hwnd, -dy))
- InvalidateRect(hwnd, NULL, FALSE);
-
- return TRUE;
- }
- static BOOL
- ListView_ScrollReportModeVertPx(HWND hwnd, int dy, BOOL horzBarHidden)
- {
- int itemHeight, lines;
- RECT rect;
- unsigned long windowStyle;
- if (0 == dy)
- return TRUE;
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- rect.left = LVIR_BOUNDS;
- if (!SendMessageW(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect))
- return FALSE;
- if (rect.top < 0)
- OffsetRect(&rect, 0, -rect.top);
- itemHeight = rect.bottom - rect.top;
- lines = dy / itemHeight;
- if (0 != lines)
- {
- if (0 != (WS_VISIBLE & windowStyle))
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
- SendMessageW(hwnd, LVM_SCROLL, 0, lines);
-
- if (0 != (WS_VISIBLE & windowStyle))
- {
- windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- windowStyle |= WS_VISIBLE;
- SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle);
- }
- }
- if (0 != (WS_VISIBLE & windowStyle))
- {
- if (ERROR == ListView_ScrollWindow(hwnd, -dy))
- InvalidateRect(hwnd, NULL, FALSE);
- }
-
- return TRUE;
- }
- //
- // This function is called whenever the mouse is moved and
- // we are dragging the scrollbar thumb about.
- //
- static void ThumbTrack(SCROLLBAR *sbar, HWND hwnd, POINTS pts, UINT scrollFlags)
- {
- POINT pt;
- RECT rc, winrect, rc2;
- int thumbpos = nThumbPos;
- //int thumbDelta;
- int pos;
- int siMaxMin = 0;
- //UINT flatflag = (CSBS_FLATSB & sbar->fScrollFlags) ? BF_FLAT : 0;
- SCROLLINFO *si;
- si = &sbar->scrollInfo;
- POINTSTOPOINT(pt, pts);
- MapWindowPoints(hwnd, HWND_DESKTOP, &pt, 1);
- if (SB_VERT == sbar->nBarType)
- {
- LONG t;
- t= pt.x; pt.x = pt.y; pt.y = t;
- RotateRect(&rcThumbBounds);
- }
- //draw the thumb at whatever position
- rc = rcThumbBounds;
- SetRect(&rc2, rc.left - THUMBTRACK_SNAPDIST*2, rc.top - THUMBTRACK_SNAPDIST,
- rc.right + THUMBTRACK_SNAPDIST*2, rc.bottom + THUMBTRACK_SNAPDIST);
- int cxH = GetScrollMetric(sbar, SM_CXHORZSB, scrollFlags);
- rc.left += cxH;
- rc.right -= cxH;
- //if the mouse is not in a suitable distance of the scrollbar,
- //then "snap" the thumb back to its initial position
- #ifdef SNAP_THUMB_BACK
- if (!PtInRect(&rc2, pt))
- {
- thumbpos = nThumbPos0;
- }
- //otherwise, move the thumb to where the mouse is
- else
- #endif //SNAP_THUMB_BACK
- {
- //keep the thumb within the scrollbar limits
- thumbpos = pt.x - nThumbMouseOffset;
- if (thumbpos < rc.left) thumbpos = rc.left;
- if (thumbpos > rc.right - nThumbSize) thumbpos = rc.right - nThumbSize;
- }
- GetClientRect(hwnd, &winrect);
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&winrect, 2);
- RotateRect0(sbar, &winrect);
- OffsetRect(&rc, -winrect.left, -winrect.top);
- thumbpos -= winrect.left;
- /*if (-1 == trackThumbPos)
- thumbDelta = thumbpos - rc.left;
- else
- thumbDelta = thumbpos - trackThumbPos;*/
- trackThumbPos = thumbpos;
- //post a SB_TRACKPOS message!!!
- siMaxMin = si->nMax - si->nMin;
- pos = (siMaxMin > 0) ? MulDiv(thumbpos - rc.left, siMaxMin - si->nPage + 1, rc.right - rc.left - nThumbSize) : (thumbpos - rc.left);
- if (si->nPage == 0)
- pos = 0; // this supposed to protect from moving on empty scrollbar
- if (pos != nLastPos)
- {
- if (SWS_LISTVIEW & scrollFlags) // list view specific
- {
- // only for listviews
- if (sbar->nBarType == SB_HORZ)
- {
- SCROLLINFO info;
- info.cbSize = sizeof(SCROLLINFO);
- info.fMask = SIF_TRACKPOS;
- if (GetScrollInfo(hwnd, SB_HORZ, &info))
- {
- INT dx = pos - info.nTrackPos;
- if (LVS_LIST == (LVS_TYPEMASK & GetWindowLongPtrW(hwnd, GWL_STYLE)))
- {
- INT cw = (INT)(INT_PTR)SendMessageW(hwnd, LVM_GETCOLUMNWIDTH, 0, 0L);
- dx = dx * cw;
- }
- SendMessageW(hwnd, LVM_SCROLL, dx, 0);
- }
- }
- else if (sbar->nBarType == SB_VERT)
- {
- SCROLLINFO info;
- info.cbSize = sizeof(SCROLLINFO);
- info.fMask = SIF_TRACKPOS;
- if (GetScrollInfo(hwnd, SB_VERT, &info) && pos != info.nTrackPos)
- {
- INT dy = pos - info.nTrackPos;
- if (LVS_REPORT == (LVS_TYPEMASK & GetWindowLongPtrW(hwnd, GWL_STYLE)))
- {
- ListView_ScrollReportModeVert(hwnd, dy, (0 != (SWS_HIDEHSCROLL & scrollFlags)));
- }
- else
- {
- SendMessageW(hwnd, LVM_SCROLL, 0, dy);
- }
- }
- }
- }
- else if ((SWS_TREEVIEW & scrollFlags) &&
- SB_VERT == sbar->nBarType &&
- ABS(nLastPos - pos) < 2)
- {
- INT i, cmd;
- i = nLastPos - pos;
- cmd = (i < 0) ? SB_LINEDOWN : SB_LINEUP;
- if (i < 0) i = -i;
- while (i--)
- {
- SendMessageW(hwnd, WM_VSCROLL, cmd, 0L);
- }
- }
- else
- {
- si->nTrackPos = pos;
- SCROLLINFO info;
- info.cbSize = sizeof(SCROLLINFO);
- info.fMask = SIF_TRACKPOS|SIF_POS;
- info.nTrackPos = pos;
- info.nPos = pos;
- SetScrollInfo(hwnd, sbar->nBarType, &info, FALSE);
- SendScrollMessage(hwnd, uScrollTimerMsg, SB_THUMBTRACK, pos);
- }
- }
- nLastPos = pos;
- if (SB_VERT == sbar->nBarType) RotateRect(&rcThumbBounds);
- }
- //
- // remember to rotate the thumb bounds rectangle!!
- //
- //
- // Called when we have set the capture from the NCLButtonDown(...)
- //
- void SkinnedScrollWnd::OnMouseMove(UINT nFlags, POINTS pts)
- {
- RECT rect;
- //static UINT lastbutton = 0;
- RECT winrect;
- //UINT buttonIdx = 0;
- SCROLLBAR *psb;
- if (nFlags)
- {
- if (MK_LBUTTON & nFlags)
- {
- UpdateScrollBars(TRUE);
- }
- }
- psb = (uCurrentScrollbar == SB_VERT) ? psbVert : psbHorz;
- if (CSBS_TRACKING & psb->fScrollFlags)
- {
- ThumbTrack(psb, hwnd, pts, scrollFlags);
- InvalidateNC(InvalidateFlag_Normal, uCurrentScrollbar);
- return;
- }
- if (uCurrentScrollPortion == HTSCROLL_NONE)
- {
- __super::WindowProc(WM_MOUSEMOVE, (WPARAM)nFlags, *(LPARAM*)&pts);
- return;
- }
- else
- {
- static UINT lastportion = 0;
- POINT pt;
- POINTSTOPOINT(pt, pts);
- MapWindowPoints(hwnd, HWND_DESKTOP, &pt, 1);
- GetWindowRect(hwnd, &winrect);
- //get the total area of the normal scrollbar area
- GetScrollRect(this, psb->nBarType, &rect);
- //see if we clicked in the inserted buttons / normal scrollbar
- //thisportion = GetPortion(sb, hwnd, &rect, LOWORD(lParam), HIWORD(lParam));
- UINT thisportion = GetPortion(psb, hwnd, &rect, pt.x, pt.y, scrollFlags);
- //we need to do different things depending on if the
- //user is activating the scrollbar itself, or one of
- //the inserted buttons
- switch (uCurrentScrollPortion)
- {
- //The scrollbar is active
- case HTSCROLL_LEFT:
- case HTSCROLL_RIGHT:
- case HTSCROLL_THUMB:
- case HTSCROLL_PAGELEFT:
- case HTSCROLL_PAGERIGHT:
- case HTSCROLL_NONE:
- //adjust the total scroll area to become where the scrollbar
- //really is (take into account the inserted buttons)
- GetRealScrollRect(psb, &rect, scrollFlags);
- OffsetRect(&rect, -winrect.left, -winrect.top);
- if (thisportion != uCurrentScrollPortion)
- {
- uScrollTimerPortion = HTSCROLL_NONE;
- if (lastportion != thisportion)
- {
- InvalidateNC(InvalidateFlag_Normal, uCurrentScrollbar);
- }
- }
- //otherwise, draw the button in its depressed / clicked state
- else
- {
- uScrollTimerPortion = uCurrentScrollPortion;
- if (lastportion != thisportion)
- {
- InvalidateNC(InvalidateFlag_Normal, uCurrentScrollbar);
- }
- }
- break;
- }
- lastportion = thisportion;
- //lastbutton = buttonIdx;
- //must return zero here, because we might get cursor anomilies
- //CallWindowProc(sw->oldproc, hwnd, WM_MOUSEMOVE, wParam, lParam);
- return;
- }
- }
- //
- // We must allocate from in the non-client area for our scrollbars
- // Call the default window procedure first, to get the borders (if any)
- // allocated some space, then allocate the space for the scrollbars
- // if they fit
- //
- INT SkinnedScrollWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *pncsp)
- {
- RECT *prc;
- INT hcy, vcx, result;
- BOOL bSizingDown;
- prc = &pncsp->rgrc[0];
- UINT updateBars = -1;
-
- hcy = GetScrollMetric(psbHorz, SM_CYHORZSB, scrollFlags);
- vcx = GetScrollMetric(psbVert, SM_CXVERTSB, scrollFlags);
- if (SWS_UPDATEFRAME & scrollFlags)
- {
- // need to reset style
- DWORD style;
- scrollFlags &= ~SWS_UPDATEFRAME;
- style = (DWORD)GetWindowLongPtrW(hwnd, GWL_STYLE);
- if ((WS_HSCROLL | WS_VSCROLL) & style) SetWindowLongPtrW(hwnd, GWL_STYLE, style & ~(WS_HSCROLL | WS_VSCROLL));
- CallDefWndProc(WM_NCCALCSIZE, (WPARAM)bCalcValidRects, (LPARAM)pncsp);
- if ((WS_HSCROLL | WS_VSCROLL) & style) SetWindowLongPtrW(hwnd, GWL_STYLE, style);
- }
- result = __super::OnNcCalcSize(bCalcValidRects, pncsp);
- bSizingDown = (bCalcValidRects &&
- ((pncsp->rgrc[0].right - pncsp->rgrc[0].left) < (pncsp->rgrc[1].right - pncsp->rgrc[1].left) ||
- (pncsp->rgrc[0].bottom - pncsp->rgrc[0].top) < (pncsp->rgrc[1].bottom - pncsp->rgrc[1].top)));
- //if there is room, allocate some space for the horizontal scrollbar
- //NOTE: Change the ">" to a ">=" to make the horz bar totally fill the
- //window before disappearing
- if ((psbHorz->fScrollFlags & CSBS_VISIBLE) && (prc->bottom - prc->top)
- #ifdef COOLSB_FILLWINDOW
- >=
- #else
- >
- #endif
- hcy)
- {
- prc->bottom -= hcy;
- if (TRUE != psbHorz->fScrollVisible)
- {
- psbHorz->fScrollVisible = TRUE;
- updateBars = SB_HORZ;
- }
- }
- else
- {
- if (FALSE != psbHorz->fScrollVisible)
- {
- psbHorz->fScrollVisible = FALSE;
- updateBars = SB_HORZ;
- }
- }
- //if there is room, allocate some space for the vertical scrollbar
- if ((psbVert->fScrollFlags & CSBS_VISIBLE) && (prc->right - prc->left) >= vcx)
- {
- if (SWS_LEFT & scrollFlags) prc->left += vcx;
- else prc->right -= vcx;
- if (TRUE != psbVert->fScrollVisible)
- {
- psbVert->fScrollVisible = TRUE;
- updateBars = (SB_HORZ == updateBars) ? SB_BOTH : SB_VERT;
- }
- }
- else
- {
- if (FALSE != psbVert->fScrollVisible)
- {
- psbVert->fScrollVisible = FALSE;
- updateBars = (SB_HORZ == updateBars) ? SB_BOTH : SB_VERT;
- }
- }
- if (-1 != updateBars)
- {
- if (SWS_COMBOLBOX & scrollFlags)
- {
- InvalidateNC(InvalidateFlag_RedrawNow, updateBars);
- }
- else if (bSizingDown)
- {
- PostMessageW(hwnd, WM_ML_IPC, TRUE, IPC_ML_SKINNEDSCROLLWND_UPDATEBARS);
- }
-
- }
- return result;
- }
- void SkinnedScrollWnd::OnNcMouseLeave()
- {
- if (HTSCROLL_NONE != scrollPortionHover)
- {
- scrollPortionHover=HTSCROLL_NONE;
- InvalidateNC(InvalidateFlag_Normal, SB_BOTH);
- }
- }
- //
- // used for hot-tracking over the scroll buttons
- //
- void SkinnedScrollWnd::OnNcMouseMove(UINT nHitTest, POINTS pts)
- {
- if (!bDoHover)
- {
- __super::WindowProc(WM_NCMOUSEMOVE, nHitTest, *(LPARAM*)&pts);
- return;
- }
- SCROLLBAR *psb=0;
- UINT scrollbar=0;
- RECT rect;
-
- if (psbHorz) psbHorz->fScrollFlags &= ~CSBS_HOVERING;
- if (psbVert) psbVert->fScrollFlags &= ~CSBS_HOVERING;
- if (HTHSCROLL == nHitTest)
- {
- psb = psbHorz;
- scrollbar = SB_HORZ;
- //get the total area of the normal Horz scrollbar area
- GetHScrollRect(this, &rect);
- }
- //
- // VERTICAL SCROLLBAR PROCESSING
- //
- else if (HTVSCROLL== nHitTest)
- {
- psb = psbVert;
- scrollbar = SB_VERT;
- //get the total area of the normal Horz scrollbar area
- GetVScrollRect(this, &rect);
- }
- //
- // NORMAL PROCESSING
- //
- else
- {
- scrollPortionHover=HTSCROLL_NONE;
- __super::WindowProc(WM_NCMOUSEMOVE, nHitTest, *(LPARAM*)&pts);
- return;
- }
- if (NULL != psb)
- {
- psb->fScrollFlags |= CSBS_HOVERING;
- UINT thisportion = GetPortion(psb, hwnd, &rect, pts.x, pts.y, scrollFlags);
- if (thisportion != scrollPortionHover)
- {
- TRACKMOUSEEVENT tracker;
- tracker.cbSize = sizeof(tracker);
- tracker.hwndTrack = hwnd;
- tracker.dwHoverTime=0;
- tracker.dwFlags = TME_LEAVE |TME_NONCLIENT; // benski> TME_NONCLIENT doesn't work on NT4.0, and we can work around it anyway
- if (TrackMouseEvent(&tracker))
- {
- scrollPortionHover=thisportion;
- InvalidateNC(InvalidateFlag_Normal, scrollbar);
- }
- }
- }
- __super::WindowProc(WM_NCMOUSEMOVE, nHitTest, *(LPARAM*)&pts);
- }
- //
- // Timer routine to generate scrollbar messages
- //
- void SkinnedScrollWnd::OnTimer(UINT_PTR idEvent, TIMERPROC fnTimer)
- {
- //let all timer messages go past if we don't have a timer installed ourselves
- if (uScrollTimerId != 0)
- {
- //if the first timer goes off, then we can start a more
- //regular timer interval to auto-generate scroll messages
- //this gives a slight pause between first pressing the scroll arrow, and the
- //actual scroll starting
- if (idEvent == COOLSB_TIMERID1)
- {
- KillTimer(hwnd, uScrollTimerId);
- uScrollTimerId = SetTimer(hwnd, COOLSB_TIMERID2, COOLSB_TIMERINTERVAL2, 0);
- return;
- }
- //send the scrollbar message repeatedly
- else if (idEvent == COOLSB_TIMERID2)
- {
- //need to process a spoof WM_MOUSEMOVE, so that
- //we know where the mouse is each time the scroll timer goes off.
- //This is so we can stop sending scroll messages if the thumb moves
- //under the mouse.
- POINT pt;
- GetCursorPos(&pt);
- MapWindowPoints(HWND_DESKTOP, hwnd, &pt, 1);
- pt.x = POINTTOPOINTS(pt);
- OnMouseMove(MK_LBUTTON, MAKEPOINTS(pt.x));
- if (uScrollTimerPortion != HTSCROLL_NONE) SendScrollMessage(hwnd, uScrollTimerMsg, uScrollTimerPortion, 0);
- UpdateScrollBars(TRUE);
- return;
- }
- }
- __super::WindowProc(WM_TIMER, (WPARAM)idEvent, (LPARAM)fnTimer);
- }
- //
- // We must intercept any calls to SetWindowLong, to check if
- // left-scrollbars are taking effect or not
- //
- static UINT curTool = -1;
- static LRESULT SendToolTipMessage0(HWND hwndTT, UINT message, WPARAM wParam, LPARAM lParam)
- {
- return SendMessageW(hwndTT, message, wParam, lParam);
- }
- #ifdef COOLSB_TOOLTIPS
- #define SendToolTipMessage SendToolTipMessage0
- #else
- #define SendToolTipMessage 1 ? (void)0 : SendToolTipMessage0
- #endif
- void SkinnedScrollWnd::OnStyleChanged(INT styleType, STYLESTRUCT *pss)
- {
- if (styleType == GWL_EXSTYLE) scrollFlags = (scrollFlags & ~SWS_LEFT) | ((WS_EX_LEFTSCROLLBAR & pss->styleNew) ? SWS_LEFT : 0);
- __super::OnStyleChanged(styleType, pss);
- }
- LRESULT SkinnedScrollWnd::OnEraseBackground(HDC hdc)
- {
- if (0 == (CSBS_TRACKING & psbVert->fScrollFlags) && 0 == (CSBS_TRACKING & psbHorz->fScrollFlags) && uCurrentScrollPortion == HTSCROLL_NONE)
- {
- LRESULT result;
- result = __super::WindowProc(WM_ERASEBKGND, (WPARAM)hdc, 0L);
- UpdateScrollBars(TRUE);
- return result;
- }
- return __super::WindowProc(WM_ERASEBKGND, (WPARAM)hdc, 0L);
- }
- void SkinnedScrollWnd::OnPrint(HDC hdc, UINT options)
- {
- if ((PRF_NONCLIENT & options) &&
- (0 == (PRF_CHECKVISIBLE & options) || IsWindowVisible(hwnd)))
- {
- PaintNonClient(hdc);
- if (PRF_CLIENT & options)
- CallPrevWndProc(WM_PRINT, (WPARAM)hdc, (LPARAM)(~(PRF_NONCLIENT | PRF_CHECKVISIBLE) & options));
- }
- else __super::OnPrint(hdc, options);
- }
- LRESULT SkinnedScrollWnd::OnListViewScroll(INT dx, INT dy)
- {
- if (0 != dy &&
- 0 != (SWS_LISTVIEW & scrollFlags) &&
- 0 != (SWS_HIDEHSCROLL & scrollFlags) &&
- (psbHorz->scrollInfo.nPage <= (UINT)psbHorz->scrollInfo.nMax))
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if (LVS_REPORT == (LVS_TYPEMASK & windowStyle))
- {
- SCROLLINFO scrollInfo;
- scrollInfo.cbSize = sizeof(SCROLLINFO);
- scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
- if (GetScrollInfo(hwnd, SB_VERT, &scrollInfo))
- {
- if (0 == dy ||
- (scrollInfo.nPos == scrollInfo.nMin && dy < 0) ||
- (scrollInfo.nPos >= (scrollInfo.nMax - (INT)scrollInfo.nPage) && dy > 0))
- return TRUE;
-
- RECT rc;
- rc.left = LVIR_BOUNDS;
- if (SendMessageW(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rc))
- {
- dy = dy / (rc.bottom - rc.top);
- if (dy < 0)
- {
- if ((scrollInfo.nPos - dy) < scrollInfo.nMin)
- dy = scrollInfo.nMin - scrollInfo.nPos;
- }
- else if (dy > 0)
- {
- if ((scrollInfo.nPos + dy) >= (scrollInfo.nMax - (INT)scrollInfo.nPage))
- dy = scrollInfo.nMax - (INT)scrollInfo.nPage - scrollInfo.nPos;
- }
-
- dy = dy * (rc.bottom - rc.top);
- if (0 == dy)
- return TRUE;
- }
- }
- }
- }
- LRESULT result = __super::WindowProc(LVM_SCROLL, (WPARAM)dx, (LPARAM)dy);
- if (result) UpdateScrollBars(TRUE);
- return result;
- }
- void SkinnedScrollWnd::OnVertScroll(UINT code, UINT pos, HWND hwndSB)
- {
- if (0 != (SWS_LISTVIEW & scrollFlags) &&
- 0 != (SWS_HIDEHSCROLL & scrollFlags) &&
- (psbHorz->scrollInfo.nPage <= (UINT)psbHorz->scrollInfo.nMax))
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if (LVS_REPORT == (LVS_TYPEMASK & windowStyle))
- {
- SCROLLINFO scrollInfo;
- scrollInfo.cbSize = sizeof(SCROLLINFO);
- switch(code)
- {
- case SB_LINEDOWN:
- scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
- if (GetScrollInfo(hwnd, SB_VERT, &scrollInfo)
- && scrollInfo.nPos >= (scrollInfo.nMax - (INT)scrollInfo.nPage))
- return;
- break;
- }
- }
- }
- __super::WindowProc(WM_VSCROLL, MAKEWPARAM(code, pos), (LPARAM)hwndSB);
- }
- void SkinnedScrollWnd::OnMouseWheel(INT delta, UINT vtKey, POINTS pts)
- {
- if (0 == delta)
- return;
- if (0 != (SWS_LISTVIEW & scrollFlags))
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if (LVS_REPORT == (LVS_TYPEMASK & windowStyle))
- {
- if (0 != (WS_VSCROLL & windowStyle))
- {
- unsigned int wheelScroll;
- int scrollLines, distance;
- if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScroll, 0))
- wheelScroll = 3;
- if (0 == wheelScroll)
- return;
- if (WHEEL_PAGESCROLL == wheelScroll)
- {
- SendMessageW(hwnd, WM_VSCROLL, MAKEWPARAM(((delta > 0) ? SB_PAGEUP : SB_PAGEDOWN), 0), 0L);
- SendMessageW(hwnd, WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, 0), 0L);
- return;
- }
- distance = delta + wheelCarryover;
- scrollLines = distance * (INT)wheelScroll / WHEEL_DELTA;
- wheelCarryover = distance - scrollLines * WHEEL_DELTA / (INT)wheelScroll;
- if (ListView_ScrollReportModeVert(hwnd, -scrollLines, (0 != (SWS_HIDEHSCROLL & scrollFlags))))
- {
- InvalidateNC(InvalidateFlag_RedrawNow, SB_VERT);
- return;
- }
- }
- else if (0 != (SWS_HIDEHSCROLL & scrollFlags))
- {
- return;
- }
- }
- }
- __super::WindowProc(WM_MOUSEWHEEL, MAKEWPARAM(vtKey, delta), *(LPARAM*)&pts);
- }
- void SkinnedScrollWnd::UpdateFrame()
- {
- if (SWS_UPDATEFRAME & scrollFlags)
- {
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_NOREDRAW);
- }
- }
- void SkinnedScrollWnd::OnSkinChanged(BOOL bNotifyChildren, BOOL bRedraw)
- {
- UINT newFlag = scrollFlags & ~SWS_USEFREEFORM;
- if (UseFreeformScrollbars())
- newFlag |= SWS_USEFREEFORM;
-
- if (newFlag != scrollFlags)
- {
- RECT rcOld;
- GetClientRect(hwnd, &rcOld);
- scrollFlags = newFlag;
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOREDRAW);
-
- }
- __super::OnSkinChanged(bNotifyChildren, bRedraw);
- if (FALSE != bRedraw)
- RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE |RDW_ERASE | RDW_FRAME);
- }
- LRESULT SkinnedScrollWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- /*case SBM_GETSCROLLINFO:
- {
- SCROLLINFO *scrollInfo = (SCROLLINFO *)lParam;
- int x=0;
- x=0;
- }
- break;*/
- case WM_NCMOUSEMOVE: OnNcMouseMove((UINT)wParam, MAKEPOINTS(lParam)); return 0;
- case WM_NCRBUTTONDOWN:
- case WM_NCRBUTTONUP:
- case WM_NCMBUTTONDOWN:
- case WM_NCMBUTTONUP: if (wParam == HTHSCROLL || wParam == HTVSCROLL) return 0;
- break;
- case WM_NCLBUTTONDBLCLK: if (wParam != HTHSCROLL && wParam != HTVSCROLL) break; // else fall to the nclbuttondown
- case WM_NCLBUTTONDOWN: OnNcLButtonDown((UINT)wParam, MAKEPOINTS(lParam)); return 0;
- case WM_NCMOUSELEAVE:
- case WM_MOUSELEAVE: OnNcMouseLeave(); break;
- case WM_LBUTTONUP: OnLButtonUp((UINT)wParam, MAKEPOINTS(lParam)); return 0;
- case WM_MOUSEMOVE: OnMouseMove((UINT)wParam, MAKEPOINTS(lParam)); return 0;
- case WM_TIMER: OnTimer((UINT_PTR)wParam, (TIMERPROC)lParam); return 0;
- case WM_ERASEBKGND: return OnEraseBackground((HDC)wParam);
- case WM_DISPLAYCHANGE:
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
- break;
- case WM_CAPTURECHANGED:
- if (!ignoreCaptureChange)
- {
- LONG pts = GetMessagePos();
- POINT pt;
- POINTSTOPOINT(pt, pts);
- MapWindowPoints(HWND_DESKTOP, hwnd, &pt, 1);
- pts = POINTTOPOINTS(pt);
- Emulate_LeftButtonUp((UINT)wParam, MAKEPOINTS(pts), FALSE);
- }
- break;
- // sometimes update frame required when this messges arrive
- case WM_ACTIVATE:
- case WM_SETFOCUS:
- case WM_HSCROLL:
- {
- LRESULT result = __super::WindowProc(uMsg, wParam, lParam);
- UpdateFrame();
- return result;
- }
- break;
- case WM_MOUSEWHEEL:
- OnMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), MAKEPOINTS(lParam));
- UpdateFrame();
- return 0;
- case WM_VSCROLL:
- OnVertScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
- UpdateFrame();
- return 0;
- case LVM_SCROLL:
- if (SWS_LISTVIEW & scrollFlags)
- return OnListViewScroll((INT)wParam, (INT)lParam);
- break;
- case WM_KEYDOWN:
- if (0 != ((SWS_LISTVIEW | SWS_TREEVIEW ) & scrollFlags))
- {
- LRESULT result = __super::WindowProc(uMsg, wParam, lParam);
- switch(wParam)
- {
- case VK_PRIOR:
- case VK_NEXT:
- case VK_UP:
- case VK_DOWN:
- case VK_HOME:
- case VK_END:
- UpdateScrollBars(TRUE);
- break;
- }
- return result;
- }
- break;
- case WM_USER + 0x3443:
- UpdateScrollBars(TRUE);
- break;
- }
- return __super::WindowProc(uMsg, wParam, lParam);
- }
- //
- // return the default minimum size of a scrollbar thumb
- //
- static int WINAPI CoolSB_GetDefaultMinThumbSize(void)
- {
- DWORD dwVersion = GetVersion();
- // set the minimum thumb size for a scrollbar. This
- // differs between NT4 and 2000, so need to check to see
- // which platform we are running under
- return (dwVersion >= 0x80000000 && LOBYTE(LOWORD(dwVersion)) >= 5) ? MINTHUMBSIZE_2000 : MINTHUMBSIZE_NT4;
- }
- BOOL SkinnedScrollWnd::ShowScrollBar(int wBar, BOOL fShow)
- {
- DWORD styleOld, styleNew;
- styleOld = GetWindowLongPtrW(hwnd, GWL_STYLE);
- styleNew = styleOld;
- if (wBar == SB_HORZ || wBar == SB_BOTH)
- {
- psbHorz->fScrollFlags = (psbHorz->fScrollFlags & ~CSBS_VISIBLE) | ((fShow) ? CSBS_VISIBLE : 0);
- styleNew = (styleNew & ~WS_HSCROLL) | ((fShow) ? WS_HSCROLL :0);
- }
- if (wBar == SB_VERT || wBar == SB_BOTH)
- {
- psbVert->fScrollFlags = (psbVert->fScrollFlags & ~CSBS_VISIBLE) | ((fShow) ? CSBS_VISIBLE : 0);
- styleNew = (styleNew & ~WS_VSCROLL) | ((fShow) ? WS_VSCROLL :0);
- }
- if (styleNew != styleOld)
- {
- SetWindowLongPtrW(hwnd, GWL_STYLE, styleNew);
- SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOREDRAW);
- }
- return TRUE;
- }
- SkinnedScrollWnd::SkinnedScrollWnd(BOOL bIsDialog)
- : SkinnedWnd(bIsDialog), psbHorz(0), psbVert(0),
- scrollFlags(0), scrollPortionHover(0), wheelCarryover(0)
- {
- if (-1 == bUseUpdateRgn)
- {
- OSVERSIONINFO osver = {0};
- osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (::GetVersionEx(&osver))
- {
- bUseUpdateRgn =
- ((VER_PLATFORM_WIN32_NT != osver.dwPlatformId ||
- (osver.dwMajorVersion < 6 && osver.dwMinorVersion != 2)));
- bDoHover = !(VER_PLATFORM_WIN32_NT == osver.dwPlatformId && osver.dwMajorVersion == 4); // can't use TrackMouseEvent with non-client areas on Windows NT 4.0
- }
- }
- }
- BOOL SkinnedScrollWnd::Attach(HWND hwndToSkin)
- {
- DWORD style;
- if (!SkinnedWnd::Attach(hwndToSkin))
- return FALSE;
- SetType(SKINNEDWND_TYPE_SCROLLWND);
- psbHorz = (SCROLLBAR*)calloc(1, sizeof(SCROLLBAR));
- psbVert = (SCROLLBAR*)calloc(1, sizeof(SCROLLBAR));
- if (!psbHorz || !psbVert) return FALSE;
- scrollFlags = 0;
- wheelCarryover = 0;
- psbHorz->scrollInfo.cbSize = sizeof(SCROLLINFO);
- psbHorz->scrollInfo.fMask = SIF_ALL;
- if (!GetScrollInfo(hwnd, SB_HORZ, &psbHorz->scrollInfo))
- ZeroMemory(&psbHorz->scrollInfo, sizeof(SCROLLINFO));
- psbVert->scrollInfo.cbSize = sizeof(SCROLLINFO);
- psbVert->scrollInfo.fMask = SIF_ALL;
- if (!GetScrollInfo(hwnd, SB_VERT, &psbVert->scrollInfo))
- ZeroMemory(&psbVert->scrollInfo, sizeof(SCROLLINFO));
- scrollPortionHover = HTSCROLL_NONE;
- //check to see if the window has left-aligned scrollbars
- if (GetWindowLongPtrW(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR) scrollFlags |= SWS_LEFT;
- style = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (WS_HSCROLL & style) psbHorz->fScrollFlags = CSBS_VISIBLE;
- if (WS_VSCROLL & style) psbVert->fScrollFlags = CSBS_VISIBLE;
- psbHorz->nBarType = SB_HORZ;
- psbVert->nBarType = SB_VERT;
- //set the default arrow sizes for the scrollbars
- psbHorz->nMinThumbSize = CoolSB_GetDefaultMinThumbSize();
- psbVert->nMinThumbSize = psbHorz->nMinThumbSize;
- scrollFlags |= SWS_UPDATEFRAME;
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_NOREDRAW);
- InvalidateNC(InvalidateFlag_Frame | InvalidateFlag_RedrawNow, SB_BOTH);
- return TRUE;
- }
- SkinnedScrollWnd::~SkinnedScrollWnd(void)
- {
- InvalidateNC(InvalidateFlag_Frame | InvalidateFlag_RedrawNow, SB_BOTH);
- if (psbHorz) free(psbHorz);
- if (psbVert) free(psbVert);
- if (hbrChecked)
- {
- DeleteObject(hbrChecked);
- hbrChecked = NULL;
- }
- }
- void SkinnedScrollWnd::DisableNoScroll(BOOL bDisable)
- {
- if (bDisable) scrollFlags |= SWS_DISABLENOSCROLL;
- else scrollFlags &= ~SWS_DISABLENOSCROLL;
- }
- BOOL SkinnedScrollWnd::IsNoScrollDisabled()
- {
- return (0 != (SWS_DISABLENOSCROLL & scrollFlags));
- }
- void SkinnedScrollWnd::InvalidateNC(InvalidateFlags invalidate, UINT bars)
- {
- HRGN rgnH = NULL, rgnV = NULL;
- RECT rc;
- int scrollLength;
- unsigned int flags;
- long frameEdge, clientEdge;
- if (0 != (InvalidateFlag_Frame & invalidate))
- {
- flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE |
- SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_NOREDRAW;
-
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, flags);
- }
- if (FALSE == GetClientRect(hwnd, &rc))
- return;
- if (SB_HORZ == bars || SB_BOTH == bars)
- {
- scrollLength = GetScrollMetric(psbHorz, SM_CYVERTSB, scrollFlags);
- clientEdge = rc.bottom;
- if (0 != (InvalidateFlag_HorzBarRemoved & invalidate))
- clientEdge -= scrollLength;
- frameEdge = clientEdge + scrollLength;
- rgnH = CreateRectRgn(rc.left, clientEdge, rc.right, frameEdge);
- }
- else
- rgnH = NULL;
- if (SB_VERT == bars || SB_BOTH == bars)
- {
- scrollLength = GetScrollMetric(psbVert, SM_CXVERTSB, scrollFlags);
- if (0 != (SWS_LEFT & scrollFlags))
- {
- clientEdge = rc.left;
- if (0 == (InvalidateFlag_VertBarRemoved & invalidate))
- clientEdge -= scrollLength;
- }
- else
- {
- clientEdge = rc.right;
- if (0 != (InvalidateFlag_VertBarRemoved & invalidate))
- clientEdge -= scrollLength;
- frameEdge = clientEdge + scrollLength;
- }
- rgnV = CreateRectRgn(clientEdge, rc.top, frameEdge, rc.bottom);
- if (NULL != rgnV && SB_BOTH == bars)
- CombineRgn(rgnH, rgnH, rgnV, RGN_OR);
- }
- else
- rgnV = NULL;
- flags = RDW_INVALIDATE | /*RDW_INTERNALPAINT | RDW_ERASE |*/ RDW_FRAME | RDW_NOCHILDREN;
- if (0 != (InvalidateFlag_RedrawNow & invalidate))
- flags |= (RDW_UPDATENOW | RDW_ERASENOW);
- HRGN rgn = ((NULL != rgnH) ? rgnH : rgnV);
- if (rgn)
- RedrawWindow(hwnd, NULL, rgn, flags);
- if (rgnH)
- DeleteRgn(rgnH);
- if (rgnV)
- DeleteRgn(rgnV);
- }
- void SkinnedScrollWnd::UpdateScrollBars(BOOL fInvalidate)
- {
- UINT bars;
- InvalidateFlags invalidateFlags;
- SCROLLINFO tsi;
- tsi.cbSize = sizeof(SCROLLINFO);
- tsi.fMask = SIF_ALL;
- bars = -1;
- invalidateFlags = InvalidateFlag_Normal /*| InvalidateFlag_RedrawNow*/;
- if (0 == (SWS_HIDEHSCROLL & scrollFlags))
- {
- if (GetScrollInfo(hwnd, SB_HORZ, &tsi) &&
- memcmp(&tsi, &psbHorz->scrollInfo, sizeof(SCROLLINFO)))
- {
- memcpy(&psbHorz->scrollInfo, &tsi, sizeof(SCROLLINFO));
- UpdateScrollBar(psbHorz, &invalidateFlags);
-
- psbHorz->scrollInfo.cbSize = sizeof(SCROLLINFO);
- psbHorz->scrollInfo.fMask = SIF_ALL;
- if (!GetScrollInfo(hwnd, SB_HORZ, &psbHorz->scrollInfo))
- ZeroMemory(&psbHorz->scrollInfo, sizeof(SCROLLINFO));
- bars = SB_HORZ;
- }
- }
- else
- {
- psbHorz->scrollInfo.cbSize = sizeof(SCROLLINFO);
- psbHorz->scrollInfo.fMask = SIF_ALL;
- if (!GetScrollInfo(hwnd, SB_HORZ, &psbHorz->scrollInfo))
- ZeroMemory(&psbHorz->scrollInfo, sizeof(SCROLLINFO));
- }
- if (0 == (SWS_HIDEVSCROLL & scrollFlags))
- {
- if (GetScrollInfo(hwnd, SB_VERT, &tsi))
- {
- if (0 != (SWS_LISTVIEW & scrollFlags) &&
- LVS_REPORT == (LVS_TYPEMASK & GetWindowLongPtrW(hwnd, GWL_STYLE)))
- {
- if (0 != (SWS_HIDEHSCROLL & scrollFlags))
- {
- tsi.nMax = (int)SendMessageW(hwnd, LVM_GETITEMCOUNT, 0, 0L);
- tsi.nPage = (unsigned int)SendMessageW(hwnd, LVM_GETCOUNTPERPAGE, 0, 0L);
- if(tsi.nMax > 0)
- tsi.nMax--;
-
- // if (psbHorz->scrollInfo.nPage <= (UINT)psbHorz->scrollInfo.nMax)
-
- }
- }
- if (memcmp(&tsi, &psbVert->scrollInfo, sizeof(SCROLLINFO)))
- {
- memcpy(&psbVert->scrollInfo, &tsi, sizeof(SCROLLINFO));
- UpdateScrollBar(psbVert, &invalidateFlags);
- bars = (SB_HORZ == bars) ? SB_BOTH : SB_VERT;
- }
- }
- }
- else
- {
- psbVert->scrollInfo.cbSize = sizeof(SCROLLINFO);
- psbVert->scrollInfo.fMask = SIF_ALL;
- if (!GetScrollInfo(hwnd, SB_VERT, &psbVert->scrollInfo))
- ZeroMemory(&psbVert->scrollInfo, sizeof(SCROLLINFO));
- }
- if ((fInvalidate || 0 != (InvalidateFlag_Frame & invalidateFlags)) &&
- -1 != bars)
- {
- InvalidateNC(invalidateFlags, bars);
- if (0 != (InvalidateFlag_Frame & invalidateFlags) &&
- 0 != (SWS_LISTVIEW & scrollFlags) &&
- LVS_REPORT == (LVS_TYPEMASK & GetWindowLongPtrW(hwnd, GWL_STYLE)))
- {
- if (0 == (LVS_NOCOLUMNHEADER & GetWindowLongPtrW(hwnd, GWL_STYLE)))
- {
- HWND hHeader = (HWND)SendMessageW(hwnd, LVM_GETHEADER, 0, 0L);
- if (NULL != hHeader)
- {
- RECT clientRect;
- WINDOWPOS wp;
- GetClientRect(hwnd, &clientRect);
- SCROLLINFO si;
- si.cbSize = sizeof(si);
- si.fMask = SIF_POS;
- if (0 != GetScrollInfo(hwnd, SB_HORZ, &si))
- clientRect.left -= si.nPos;
- HDLAYOUT layout;
- layout.prc = &clientRect;
- layout.pwpos = ℘
- if (FALSE != SendMessageW(hHeader, HDM_LAYOUT, 0, (LPARAM)&layout))
- {
- if (FALSE == fInvalidate)
- wp.flags |= SWP_NOREDRAW;
- SetWindowPos(hHeader, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags | SWP_NOZORDER | SWP_NOACTIVATE);
- }
- }
- }
- }
- }
- }
- void SkinnedScrollWnd::UpdateScrollBar(SCROLLBAR *psb, InvalidateFlags *invalidateFlags)
- {
- SCROLLINFO *psi;
- psi = &psb->scrollInfo;
- if ((psi->nPage > (UINT)psi->nMax || (psi->nPage == (UINT)psi->nMax && psi->nMax == 0) || psi->nMax <= psi->nMin))
- {
- if (psb->fScrollVisible)
- {
- if (SWS_DISABLENOSCROLL & scrollFlags)
- {
- psb->fScrollFlags |= (ESB_DISABLE_LEFT | ESB_DISABLE_RIGHT);
- }
- else
- {
- ShowScrollBar(psb->nBarType, FALSE);
- *invalidateFlags |= InvalidateFlag_Frame;
- if (SB_VERT == psb->nBarType)
- *invalidateFlags |= InvalidateFlag_VertBarRemoved;
- else
- *invalidateFlags |= InvalidateFlag_HorzBarRemoved;
- }
- }
- }
- else
- {
- if ((!psb->fScrollVisible || ((ESB_DISABLE_LEFT | ESB_DISABLE_RIGHT) & psb->fScrollFlags)) && psi->nPage > 0)
- {
- if ((SWS_DISABLENOSCROLL & scrollFlags) && ((ESB_DISABLE_LEFT | ESB_DISABLE_RIGHT) & psb->fScrollFlags))
- {
- psb->fScrollFlags &= ~(ESB_DISABLE_LEFT | ESB_DISABLE_RIGHT);
- }
- if (!psb->fScrollVisible)
- {
- if (SWS_LISTVIEW & scrollFlags)
- {
- DWORD ws = GetWindowLongPtrW(hwnd, GWL_STYLE);
- if (LVS_ICON == (LVS_TYPEMASK & ws) || LVS_SMALLICON == (LVS_TYPEMASK & ws))
- {
- switch(LVS_ALIGNMASK & ws)
- {
- case LVS_ALIGNLEFT:
- if (SB_HORZ != psb->nBarType) psb->nBarType = ((SB_BOTH == psb->nBarType) ? SB_HORZ : -1);
- break;
- case LVS_ALIGNTOP:
- if (SB_VERT != psb->nBarType) psb->nBarType = ((SB_BOTH == psb->nBarType) ? SB_VERT : -1);
- break;
- }
- }
- }
- if (-1 != psb->nBarType)
- {
- ShowScrollBar(psb->nBarType, TRUE);
- *invalidateFlags |= InvalidateFlag_Frame;
- if (SB_VERT == psb->nBarType)
- *invalidateFlags |= InvalidateFlag_VertBarAppeared;
- else
- *invalidateFlags |= InvalidateFlag_HorzBarAppeared;
- }
- }
- }
- else if (psb->fScrollVisible && 0 == psi->nPage)
- {
- if (SWS_DISABLENOSCROLL & scrollFlags)
- {
- psb->fScrollFlags |= (ESB_DISABLE_LEFT | ESB_DISABLE_RIGHT);
- }
- else
- {
- ShowScrollBar(psb->nBarType, FALSE);
- *invalidateFlags |= InvalidateFlag_Frame;
- if (SB_VERT == psb->nBarType)
- *invalidateFlags |= InvalidateFlag_VertBarRemoved;
- else
- *invalidateFlags |= InvalidateFlag_HorzBarRemoved;
- }
- }
- }
- }
- void SkinnedScrollWnd::ShowHorzScroll(BOOL fEnable)
- {
- scrollFlags = (scrollFlags & ~SWS_HIDEHSCROLL) | ((fEnable) ? 0 : SWS_HIDEHSCROLL);
- psbHorz->fScrollFlags = 0;
- InvalidateNC(InvalidateFlag_Frame | InvalidateFlag_RedrawNow, SB_HORZ);
- }
- BOOL SkinnedScrollWnd::IsHorzBarHidden()
- {
- return (0 != (SWS_HIDEHSCROLL & scrollFlags));
- }
- BOOL SkinnedScrollWnd::IsVertBarHidden()
- {
- return (0 != (SWS_HIDEVSCROLL & scrollFlags));
- }
- void SkinnedScrollWnd::ShowVertScroll(BOOL fEnable)
- {
- scrollFlags = (scrollFlags & ~SWS_HIDEVSCROLL) | ((fEnable) ? 0 : SWS_HIDEVSCROLL);
- psbVert->fScrollFlags = 0;
- InvalidateNC(InvalidateFlag_Frame | InvalidateFlag_RedrawNow, SB_VERT);
- }
- BOOL SkinnedScrollWnd::SetMode(UINT nMode)
- {
- scrollFlags &= ~(SWS_LISTVIEW | SWS_TREEVIEW | SWS_COMBOLBOX);
- switch (0xFF & nMode)
- {
- case SCROLLMODE_STANDARD_I: return TRUE;
- case SCROLLMODE_LISTVIEW_I: scrollFlags |= SWS_LISTVIEW; return TRUE;
- case SCROLLMODE_TREEVIEW_I: scrollFlags |= SWS_TREEVIEW; return TRUE;
- case SCROLLMODE_COMBOLBOX_I: scrollFlags |= SWS_COMBOLBOX; return TRUE;
- }
- return FALSE;
- }
- UINT SkinnedScrollWnd::GetMode()
- {
- if (0 != (SWS_LISTVIEW & scrollFlags))
- return SCROLLMODE_STANDARD_I;
- if (0 != (SWS_TREEVIEW & scrollFlags))
- return SCROLLMODE_TREEVIEW_I;
- if (0 != (SWS_COMBOLBOX & scrollFlags))
- return SCROLLMODE_COMBOLBOX_I;
- return SCROLLMODE_STANDARD_I;
- }
- INT SkinnedScrollWnd::AdjustHover(UINT nHitTest, POINTS pts)
- {
- SCROLLBAR *psb = NULL;
- RECT rect;
- if (psbHorz) psbHorz->fScrollFlags &= ~CSBS_HOVERING;
- if (psbVert) psbVert->fScrollFlags &= ~CSBS_HOVERING;
- scrollPortionHover = HTSCROLL_NONE;
- if (HTHSCROLL == nHitTest)
- {
- psb = psbHorz;
- GetHScrollRect(this, &rect);
- }
- else if (HTVSCROLL== nHitTest)
- {
- psb = psbVert;
- GetVScrollRect(this, &rect);
- }
- if (psb)
- {
- psb->fScrollFlags |= CSBS_HOVERING;
- scrollPortionHover = GetPortion(psb, hwnd, &rect, pts.x, pts.y, scrollFlags);
- }
- return scrollPortionHover;
- }
- BOOL SkinnedScrollWnd::OnMediaLibraryIPC(INT msg, INT_PTR param, LRESULT *pResult)
- {
- switch (msg)
- {
- case IPC_ML_SKINNEDSCROLLWND_UPDATEBARS:
- UpdateScrollBars((BOOL)param);
- *pResult = 1;
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_SHOWHORZBAR:
- ShowHorzScroll((BOOL)param);
- *pResult = 1;
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_SHOWVERTBAR:
- ShowVertScroll((BOOL)param);
- *pResult = 1;
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_SETMODE:
- *pResult = SetMode((UINT)param);
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_DISABLENOSCROLL:
- DisableNoScroll(0 != param);
- *pResult = -1;
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_ADJUSTHOVER:
- ((SBADJUSTHOVER*)param)->nResult = AdjustHover(((SBADJUSTHOVER*)param)->hitTest, ((SBADJUSTHOVER*)param)->ptMouse);
- *pResult = TRUE;
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_GETHORZBARHIDDEN:
- *pResult = IsHorzBarHidden();
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_GETVERTBARHIDDEN:
- *pResult = IsVertBarHidden();
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_GETMODE:
- *pResult = GetMode();
- return TRUE;
- case IPC_ML_SKINNEDSCROLLWND_GETNOSCROLLDISABLED:
- *pResult = IsNoScrollDisabled();
- return TRUE;
- }
- return __super::OnMediaLibraryIPC(msg, param, pResult);
- }
|