#include "StdAfx.h" #include "..\include\SkinTools.h" #include "..\..\detours\detours.h" static TCHAR szPropStr[] = _T("SkinScrollBarPtr"); SCROLLWND *GetScrollWndFromHwnd(HWND hwnd) { return (SCROLLWND *)GetProp(hwnd, szPropStr); } static void RedrawNonClient(HWND hwnd, BOOL fFrameChanged) { if(fFrameChanged == FALSE) { SendMessage(hwnd, WM_NCPAINT, (WPARAM)NULL, 0); } else { SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_DRAWFRAME); } } SCROLLBAR *GetScrollBarFromHwnd(HWND hwnd, UINT nBar) { SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); if(!sw) return 0; if(nBar == SB_HORZ) return &sw->sbarHorz; else if(nBar == SB_VERT) return &sw->sbarVert; else return 0; } BOOL WINAPI Skin_IsThumbTracking(HWND hwnd) { SCROLLWND *sw; if((sw = GetScrollWndFromHwnd(hwnd)) == NULL) return FALSE; else return sw->fThumbTracking; } BOOL WINAPI Skin_IsCoolScrollEnabled(HWND hwnd) { if(GetScrollWndFromHwnd(hwnd)) return TRUE; else return FALSE; } SCROLLINFO *GetScrollInfoFromHwnd(HWND hwnd, int fnBar) { SCROLLBAR *sb = GetScrollBarFromHwnd(hwnd, fnBar); if(sb == 0) return FALSE; if(fnBar == SB_HORZ) { return &sb->scrollInfo; } else if(fnBar == SB_VERT) { return &sb->scrollInfo; } else return NULL; } BOOL WINAPI InitializeCoolSB(HWND hwnd) { SCROLLWND *sw; SCROLLINFO *si; RECT rect; DWORD dwCurStyle; //BOOL fDisabled; GetClientRect(hwnd, &rect); //if we have already initialized Cool Scrollbars for this window, //then stop the user from doing it again if(GetScrollWndFromHwnd(hwnd) != 0) { return FALSE; } //allocate a private scrollbar structure which we //will use to keep track of the scrollbar data sw = (SCROLLWND *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCROLLWND)); si = &sw->sbarHorz.scrollInfo; si->cbSize = sizeof(SCROLLINFO); si->fMask = SIF_ALL; GetScrollInfo(hwnd, SB_HORZ, si); si = &sw->sbarVert.scrollInfo; si->cbSize = sizeof(SCROLLINFO); si->fMask = SIF_ALL; GetScrollInfo(hwnd, SB_VERT, si); if(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR) sw->fLeftScrollbar = TRUE; else sw->fLeftScrollbar = FALSE; dwCurStyle = GetWindowLong(hwnd, GWL_STYLE); SetProp(hwnd, szPropStr, (HANDLE)sw); if(dwCurStyle & WS_HSCROLL) sw->sbarHorz.fScrollFlags = CSBS_VISIBLE; if(dwCurStyle & WS_VSCROLL) sw->sbarVert.fScrollFlags = CSBS_VISIBLE; sw->sbarHorz.nBarType = SB_HORZ; sw->sbarVert.nBarType = SB_VERT; sw->sbarHorz.nArrowLength = 0; sw->sbarHorz.nArrowWidth = 0; sw->sbarVert.nArrowLength = 0; sw->sbarVert.nArrowWidth = 0; sw->bPreventStyleChange = FALSE; RedrawNonClient(hwnd, TRUE); return TRUE; } HRESULT WINAPI UninitializeCoolSB(HWND hwnd) { int i = 0; SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); if(!sw) return E_FAIL; RemoveProp(hwnd, szPropStr); HeapFree(GetProcessHeap(), 0, sw); RedrawNonClient(hwnd, TRUE); return S_OK; } BOOL WINAPI Skin_EnableScrollBar(HWND hwnd, int wSBflags, UINT wArrows) { SCROLLBAR *sbar; UINT oldstate; BOOL bFailed = FALSE; if(!Skin_IsCoolScrollEnabled(hwnd)) return EnableScrollBar(hwnd, wSBflags, wArrows); if((wSBflags == SB_HORZ || wSBflags == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) { oldstate = sbar->fScrollFlags; sbar->fScrollFlags = (sbar->fScrollFlags & ~ESB_DISABLE_BOTH) | wArrows; if(oldstate == sbar->fScrollFlags) bFailed = TRUE; } if((wSBflags == SB_VERT || wSBflags == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) { oldstate = sbar->fScrollFlags; sbar->fScrollFlags = (sbar->fScrollFlags & ~ESB_DISABLE_BOTH) | wArrows; if(oldstate == sbar->fScrollFlags) bFailed = TRUE; } return !bFailed; } BOOL WINAPI Skin_GetScrollBarInfo(HWND hwnd) { return FALSE; } BOOL WINAPI Skin_GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi) { SCROLLINFO *mysi; BOOL copied = FALSE; if(!lpsi) return FALSE; if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar))) { return GetScrollInfo(hwnd, fnBar, lpsi); } if(lpsi->fMask & SIF_PAGE) { lpsi->nPage = mysi->nPage; copied = TRUE; } if(lpsi->fMask & SIF_POS) { lpsi->nPos = mysi->nPos; copied = TRUE; } if(lpsi->fMask & SIF_TRACKPOS) { lpsi->nTrackPos = mysi->nTrackPos; copied = TRUE; } if(lpsi->fMask & SIF_RANGE) { lpsi->nMin = mysi->nMin; lpsi->nMax = mysi->nMax; copied = TRUE; } return copied; } int WINAPI Skin_GetScrollPos (HWND hwnd, int nBar) { SCROLLINFO *mysi; if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) return GetScrollPos(hwnd, nBar); return mysi->nPos; } BOOL WINAPI Skin_GetScrollRange (HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) { SCROLLINFO *mysi; if(!lpMinPos || !lpMaxPos) return FALSE; if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) return GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos); *lpMinPos = mysi->nMin; *lpMaxPos = mysi->nMax; return TRUE; } int WINAPI Skin_SetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw) { SCROLLINFO *mysi; SCROLLBAR *sbar; BOOL fRecalcFrame = FALSE; if(!lpsi) return FALSE; if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar))) return SetScrollInfo(hwnd, fnBar, lpsi, fRedraw); if(lpsi->fMask & SIF_RANGE) { mysi->nMin = lpsi->nMin; mysi->nMax = lpsi->nMax; } //The nPage member must specify a value from 0 to nMax - nMin +1. if(lpsi->fMask & SIF_PAGE) { UINT t = (UINT)(mysi->nMax - mysi->nMin + 1); mysi->nPage = min(max(0, lpsi->nPage), t); } //The nPos member must specify a value between nMin and nMax - max(nPage - 1, 0). if(lpsi->fMask & SIF_POS) { mysi->nPos = max(lpsi->nPos, mysi->nMin); mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0)); } sbar = GetScrollBarFromHwnd(hwnd, fnBar); if((lpsi->fMask & SIF_DISABLENOSCROLL) )//|| (sbar->fScrollFlags & CSBS_THUMBALWAYS)) { if(!sbar->fScrollVisible) { Skin_ShowScrollBar(hwnd, fnBar, TRUE); fRecalcFrame = TRUE; } } else { if( mysi->nPage > (UINT)mysi->nMax || mysi->nPage == (UINT)mysi->nMax &&mysi->nMax == 0 || mysi->nMax <= mysi->nMin) { if(sbar->fScrollVisible) { Skin_ShowScrollBar(hwnd, fnBar, FALSE); fRecalcFrame = TRUE; } } else { if(!sbar->fScrollVisible) { Skin_ShowScrollBar(hwnd, fnBar, TRUE); fRecalcFrame = TRUE; } } } if(fRedraw && !Skin_IsThumbTracking(hwnd)) RedrawNonClient(hwnd, fRecalcFrame); return mysi->nPos; } int WINAPI Skin_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw) { SCROLLINFO *mysi; int oldpos; if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) { return SetScrollPos(hwnd, nBar, nPos, fRedraw); } oldpos = mysi->nPos; mysi->nPos = max(nPos, mysi->nMin); mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0)); if(fRedraw && !Skin_IsThumbTracking(hwnd)) RedrawNonClient(hwnd, FALSE); return oldpos; } int WINAPI Skin_SetScrollRange (HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw) { SCROLLINFO *mysi; SCROLLBAR *sbar; BOOL fRecalcFrame = FALSE; if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar))) return SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw); if(Skin_IsThumbTracking(hwnd)) return mysi->nPos; mysi->nMin = nMinPos; mysi->nMax = nMaxPos; sbar = GetScrollBarFromHwnd(hwnd, nBar); if( mysi->nMax <= mysi->nMin) { if(sbar->fScrollVisible) { Skin_ShowScrollBar(hwnd, nBar, FALSE); fRecalcFrame = TRUE; } } else { if(!sbar->fScrollVisible) { Skin_ShowScrollBar(hwnd, nBar, TRUE); fRecalcFrame = TRUE; } } if(fRedraw) RedrawNonClient(hwnd, fRecalcFrame); return TRUE; } BOOL WINAPI Skin_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow) { SCROLLBAR *sbar; BOOL bFailed = FALSE; DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE); if(!Skin_IsCoolScrollEnabled(hwnd)) return ShowScrollBar(hwnd, wBar, fShow); if((wBar == SB_HORZ || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) { bFailed = TRUE; sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0); if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_HSCROLL); else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_HSCROLL); } if((wBar == SB_VERT || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) { bFailed = TRUE; sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0); if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_VSCROLL); else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_VSCROLL); } if(bFailed) { return FALSE; } else { SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); return TRUE; } } static BOOL (WINAPI *Detour_EnableScrollBar )(HWND hwnd, UINT wSBflags, UINT wArrows) = EnableScrollBar; static BOOL (WINAPI *Detour_GetScrollInfo )(HWND hwnd, int fnBar, LPSCROLLINFO lpsi) = GetScrollInfo; static int (WINAPI *Detour_GetScrollPos )(HWND hwnd, int nBar) = GetScrollPos; static BOOL (WINAPI *Detour_GetScrollRange )(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) = GetScrollRange; static int (WINAPI *Detour_SetScrollInfo )(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL fRedraw) = SetScrollInfo; static int (WINAPI *Detour_SetScrollPos )(HWND hwnd, int nBar, int nPos, BOOL fRedraw) = SetScrollPos; static int (WINAPI *Detour_SetScrollRange )(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw) = SetScrollRange; static BOOL (WINAPI *Detour_ShowScrollBar )(HWND hwnd, int wBar, BOOL fShow) = ShowScrollBar; static BOOL WINAPI Tramp_EnableScrollBar(HWND hwnd, int wSBflags, UINT wArrows) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_EnableScrollBar(hwnd, wSBflags, wArrows); else return Detour_EnableScrollBar(hwnd, wSBflags, wArrows); } static BOOL WINAPI Tramp_GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_GetScrollInfo(hwnd, fnBar, lpsi); else return Detour_GetScrollInfo(hwnd, fnBar, lpsi); } static int WINAPI Tramp_GetScrollPos(HWND hwnd, int nBar) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_GetScrollPos(hwnd, nBar); else return Detour_GetScrollPos(hwnd, nBar); } static BOOL WINAPI Tramp_GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos); else return Detour_GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos); } static int WINAPI Tramp_SetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_SetScrollInfo(hwnd, fnBar, lpsi, fRedraw); else return Detour_SetScrollInfo(hwnd, fnBar, lpsi, fRedraw); } static int WINAPI Tramp_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_SetScrollPos(hwnd, nBar, nPos, fRedraw); else return Detour_SetScrollPos(hwnd, nBar, nPos, fRedraw); } static int WINAPI Tramp_SetScrollRange(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw); else return Detour_SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw); } static BOOL WINAPI Tramp_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow) { if(Skin_IsCoolScrollEnabled(hwnd)) return Skin_ShowScrollBar(hwnd, wBar, fShow); else return Detour_ShowScrollBar(hwnd, wBar, fShow); } BOOL WINAPI SB_InitializeApp(void) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)Detour_EnableScrollBar, Tramp_EnableScrollBar); DetourAttach(&(PVOID&)Detour_GetScrollInfo, Tramp_GetScrollInfo); DetourAttach(&(PVOID&)Detour_GetScrollPos, Tramp_GetScrollPos); DetourAttach(&(PVOID&)Detour_GetScrollRange, Tramp_GetScrollRange); DetourAttach(&(PVOID&)Detour_SetScrollInfo, Tramp_SetScrollInfo); DetourAttach(&(PVOID&)Detour_SetScrollPos, Tramp_SetScrollPos); DetourAttach(&(PVOID&)Detour_SetScrollRange, Tramp_SetScrollRange); DetourAttach(&(PVOID&)Detour_ShowScrollBar, Tramp_ShowScrollBar); DetourTransactionCommit(); return TRUE; } BOOL WINAPI SB_UninitializeApp(void) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)Detour_EnableScrollBar, Tramp_EnableScrollBar); DetourDetach(&(PVOID&)Detour_GetScrollInfo, Tramp_GetScrollInfo); DetourDetach(&(PVOID&)Detour_GetScrollPos, Tramp_GetScrollPos); DetourDetach(&(PVOID&)Detour_GetScrollRange, Tramp_GetScrollRange); DetourDetach(&(PVOID&)Detour_SetScrollInfo, Tramp_SetScrollInfo); DetourDetach(&(PVOID&)Detour_SetScrollPos, Tramp_SetScrollPos); DetourDetach(&(PVOID&)Detour_SetScrollRange, Tramp_SetScrollRange); DetourDetach(&(PVOID&)Detour_ShowScrollBar, Tramp_ShowScrollBar); DetourTransactionCommit(); return TRUE; }