From 092d9b814c8c2e523fa2a73c69fa26cda1a5c17f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 2 Jul 2015 19:41:38 +0000 Subject: unified project for clist_nicer git-svn-id: http://svn.miranda-ng.org/main/trunk@14474 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Clist_nicer/src/coolsblib.cpp | 917 ++++++++++++++++++++++++++++++++++ 1 file changed, 917 insertions(+) create mode 100644 plugins/Clist_nicer/src/coolsblib.cpp (limited to 'plugins/Clist_nicer/src/coolsblib.cpp') diff --git a/plugins/Clist_nicer/src/coolsblib.cpp b/plugins/Clist_nicer/src/coolsblib.cpp new file mode 100644 index 0000000000..bf4e14421d --- /dev/null +++ b/plugins/Clist_nicer/src/coolsblib.cpp @@ -0,0 +1,917 @@ +/* + + Cool Scrollbar Library Version 1.2 + + Module: coolsblib.c + Copyright (c) J Brown 2001 + + This code is freeware, however, you may not publish + this code elsewhere or charge any money for it. This code + is supplied as-is. I make no guarantees about the suitability + of this code - use at your own risk. + + It would be nice if you credited me, in the event + that you use this code in a product. + + VERSION HISTORY: + + V1.2: TreeView problem fixed by Diego Tartara + Small problem in thumbsize calculation also fixed (thanks Diego!) + + V1.1: Added support for Right-left windows + Changed calling convention of APIs to WINAPI (__stdcall) + Completely standalone (no need for c-runtime) + + V1.0: Apr 2001: Initial Version + +*/ + +#include "stdafx.h" +#include "coolscroll.h" +#include "userdefs.h" +#include "coolsb_internal.h" + +static TCHAR szPropStr[] = _T("CoolSBSubclassPtr"); + +LRESULT CALLBACK CoolSBWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +SCROLLWND* GetScrollWndFromHwnd(HWND hwnd) +{ + return (SCROLLWND *)GetProp(hwnd, szPropStr); +} + +SCROLLBAR* GetScrollBarFromHwnd(HWND hwnd, UINT nBar) +{ + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + if (!sw) + return 0; + + if (nBar == SB_HORZ) + return &sw->sbarHorz; + if (nBar == SB_VERT) + return &sw->sbarVert; + return 0; +} + +BOOL WINAPI CoolSB_IsCoolScrollEnabled(HWND hwnd) +{ + if (GetScrollWndFromHwnd(hwnd)) + return TRUE; + return FALSE; +} + +BOOL GetScrollRect(SCROLLWND *sw, UINT nBar, HWND hwnd, RECT *rect); + +// +// Special support for USER32.DLL patching (using Detours library) +// The only place we call a real scrollbar API is in InitializeCoolSB, +// where we call EnableScrollbar. +// +// We HAVE to call the origial EnableScrollbar function, +// so we need to be able to set a pointer to this func when using +// using Detours (or any other LIB??) +// + +typedef BOOL(WINAPI *WPROC)(HWND, UINT, UINT); + +static WPROC pEnableScrollBar = 0; + +void WINAPI CoolSB_SetESBProc(WPROC proc) +{ + pEnableScrollBar = proc; +} + +static void RedrawNonClient(HWND hwnd, BOOL fFrameChanged) +{ + if (fFrameChanged == FALSE) { + /* + RECT rect; + HRGN hrgn1, hrgn2; + + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + + GetScrollRect(sw, SB_HORZ, hwnd, &rect); + hrgn1 = CreateRectRgnIndirect(&rect); + + GetScrollRect(sw, SB_VERT, hwnd, &rect); + hrgn2 = CreateRectRgnIndirect(&rect); + + CombineRgn(hrgn1, hrgn2, hrgn1, RGN_OR); + + SendMessage(hwnd, WM_NCPAINT, (WPARAM)hrgn1, 0); + + DeleteObject(hrgn1); + DeleteObject(hrgn2);*/ + + SendMessage(hwnd, WM_NCPAINT, 1, 0); + } + else { + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE + | SWP_FRAMECHANGED | SWP_DRAWFRAME); + } +} + +// +// return the default minimum size of a scrollbar thumb +// +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 + if (dwVersion < 0x80000000) // Windows NT/2000 + { + if (LOBYTE(LOWORD(dwVersion)) >= 5) + return MINTHUMBSIZE_2000; + return MINTHUMBSIZE_NT4; + } + + return MINTHUMBSIZE_NT4; +} + +static 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; +} +// +// Initialize the cool scrollbars for a window by subclassing it +// and using the coolsb window procedure instead +// +BOOL WINAPI InitializeCoolSB(HWND hwnd) +{ + SCROLLWND *sw; + SCROLLINFO *si; + INITCOMMONCONTROLSEX ice; + TOOLINFO ti; + RECT rect; + DWORD dwCurStyle; + //BOOL fDisabled; + + if (pEnableScrollBar == 0) + pEnableScrollBar = EnableScrollBar; + + 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); + + //check to see if the window has left-aligned scrollbars + if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR) + sw->fLeftScrollbar = TRUE; + else + sw->fLeftScrollbar = FALSE; + + dwCurStyle = GetWindowLongPtr(hwnd, GWL_STYLE); + + SetProp(hwnd, szPropStr, (HANDLE)sw); + + //try to enable the scrollbar arrows - if the return value is + //non-zero, then the scrollbars were previously disabled + //fDisabled = pEnableScrollBar(hwnd, SB_HORZ, ESB_ENABLE_BOTH); + + //scrollbars will automatically get enabled, even if + //they aren't to start with....sorry, but there isn't an + //easy alternative. + if (dwCurStyle & WS_HSCROLL) + sw->sbarHorz.fScrollFlags = CSBS_VISIBLE; + + if (dwCurStyle & WS_VSCROLL) + sw->sbarVert.fScrollFlags = CSBS_VISIBLE; + + //need to be able to distinguish between horizontal and vertical + //scrollbars in some instances + sw->sbarHorz.nBarType = SB_HORZ; + sw->sbarVert.nBarType = SB_VERT; + + sw->sbarHorz.fFlatScrollbar = CSBS_NORMAL; + sw->sbarVert.fFlatScrollbar = CSBS_NORMAL; + + //set the default arrow sizes for the scrollbars + sw->sbarHorz.nArrowLength = SYSTEM_METRIC; + sw->sbarHorz.nArrowWidth = SYSTEM_METRIC; + sw->sbarVert.nArrowLength = SYSTEM_METRIC; + sw->sbarVert.nArrowWidth = SYSTEM_METRIC; + + sw->bPreventStyleChange = FALSE; + + mir_subclassWindow(hwnd, CoolSBWndProc); + + CoolSB_SetMinThumbSize(hwnd, SB_BOTH, CoolSB_GetDefaultMinThumbSize()); + +#ifdef COOLSB_TOOLTIPS + ice.dwSize = sizeof(ice); + ice.dwICC = ICC_BAR_CLASSES; + InitCommonControlsEx(&ice); + + sw->hwndToolTip = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW, TOOLTIPS_CLASS, _T(""), + WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hwnd, NULL, GetModuleHandle(0), + NULL); + + ti.cbSize = sizeof(TOOLINFO); + ti.uFlags = TTF_IDISHWND; + ti.hwnd = hwnd; + ti.uId = (UINT)hwnd; + ti.lpszText = LPSTR_TEXTCALLBACK; + ti.hinst = GetModuleHandle(0); + + SendMessage(sw->hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); + +#else + + UNREFERENCED_PARAMETER(ice); + UNREFERENCED_PARAMETER(ti); + sw->hwndToolTip = 0; + +#endif + + //send the window a frame changed message to update the scrollbars + RedrawNonClient(hwnd, TRUE); + + return TRUE; +} + +BOOL WINAPI CoolSB_EnableScrollBar(HWND hwnd, int wSBflags, UINT wArrows) +{ + SCROLLBAR *sbar; + UINT oldstate; + BOOL bFailed = FALSE; + + if (!CoolSB_IsCoolScrollEnabled(hwnd)) + return EnableScrollBar(hwnd, wSBflags, wArrows); + + if ((wSBflags == SB_HORZ || wSBflags == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) { + oldstate = sbar->fScrollFlags; + + //clear any existing state, and OR in the disabled flags + 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; + + //clear any existing state, and OR in the disabled flags + sbar->fScrollFlags = (sbar->fScrollFlags & ~ESB_DISABLE_BOTH) | wArrows; + + if (oldstate == sbar->fScrollFlags) + bFailed = TRUE; + } + + return !bFailed; +} + +BOOL WINAPI CoolSB_GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi) +{ + BOOL copied = FALSE; + + if (!lpsi) + return FALSE; + + SCROLLINFO *mysi = GetScrollInfoFromHwnd(hwnd, fnBar); + if (!mysi) + 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 CoolSB_GetScrollPos(HWND hwnd, int nBar) +{ + SCROLLINFO *mysi = GetScrollInfoFromHwnd(hwnd, nBar); + if (!mysi) + return GetScrollPos(hwnd, nBar); + + return mysi->nPos; +} + +BOOL WINAPI CoolSB_GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) +{ + if (!lpMinPos || !lpMaxPos) + return FALSE; + + SCROLLINFO *mysi = GetScrollInfoFromHwnd(hwnd, nBar); + if (!mysi) + return GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos); + + *lpMinPos = mysi->nMin; + *lpMaxPos = mysi->nMax; + + return TRUE; +} + +int WINAPI CoolSB_SetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw) +{ + BOOL fRecalcFrame = FALSE; + + if (!lpsi) + return FALSE; + + SCROLLINFO *mysi = GetScrollInfoFromHwnd(hwnd, fnBar); + if (!mysi) + 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(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)); + } + + SCROLLBAR *sbar = GetScrollBarFromHwnd(hwnd, fnBar); + if (sbar == NULL) + return 0; + + if ((lpsi->fMask & SIF_DISABLENOSCROLL) || (sbar->fScrollFlags & CSBS_THUMBALWAYS)) { + if (!sbar->fScrollVisible) { + CoolSB_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) { + CoolSB_ShowScrollBar(hwnd, fnBar, FALSE); + fRecalcFrame = TRUE; + } + } + else { + if (!sbar->fScrollVisible) { + CoolSB_ShowScrollBar(hwnd, fnBar, TRUE); + fRecalcFrame = TRUE; + } + } + } + + if (fRedraw && !CoolSB_IsThumbTracking(hwnd)) + RedrawNonClient(hwnd, fRecalcFrame); + + return mysi->nPos; +} + + +int WINAPI CoolSB_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw) +{ + int oldpos; + + SCROLLINFO *mysi = GetScrollInfoFromHwnd(hwnd, nBar); + if (!mysi) + return SetScrollPos(hwnd, nBar, nPos, fRedraw); + + //validate and set the scollbar position + oldpos = mysi->nPos; + mysi->nPos = max(nPos, mysi->nMin); + mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0)); + + if (fRedraw && !CoolSB_IsThumbTracking(hwnd)) + RedrawNonClient(hwnd, FALSE); + + return oldpos; +} + +int WINAPI CoolSB_SetScrollRange(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw) +{ + SCROLLINFO *mysi = GetScrollInfoFromHwnd(hwnd, nBar); + if (!mysi) + return SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw); + + if (CoolSB_IsThumbTracking(hwnd)) + return mysi->nPos; + + //hide the scrollbar if nMin == nMax + //nMax-nMin must not be greater than MAXLONG + mysi->nMin = nMinPos; + mysi->nMax = nMaxPos; + + if (fRedraw) + RedrawNonClient(hwnd, FALSE); + + return TRUE; +} + +// +// Show or hide the specified scrollbars +// +BOOL WINAPI CoolSB_ShowScrollBar(HWND hwnd, int wBar, BOOL fShow) +{ + SCROLLBAR *sbar; + BOOL bFailed = FALSE; + DWORD dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE); + + if (!CoolSB_IsCoolScrollEnabled(hwnd)) + return ShowScrollBar(hwnd, wBar, fShow); + + if ((wBar == SB_HORZ || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) { + sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; + sbar->fScrollFlags |= fShow ? CSBS_VISIBLE : 0; + //bFailed = TRUE; + + if (fShow) SetWindowLongPtr(hwnd, GWL_STYLE, dwStyle | WS_HSCROLL); + else SetWindowLongPtr(hwnd, GWL_STYLE, dwStyle & ~WS_HSCROLL); + } + + if ((wBar == SB_VERT || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) { + sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE; + sbar->fScrollFlags |= fShow ? CSBS_VISIBLE : 0; + //bFailed = TRUE; + + if (fShow) SetWindowLongPtr(hwnd, GWL_STYLE, dwStyle | WS_VSCROLL); + else SetWindowLongPtr(hwnd, GWL_STYLE, dwStyle & ~WS_VSCROLL); + } + + if (bFailed) { + return FALSE; + } + else { + //DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); + //style |= WS_VSCROLL; + + //if (s + //SetWindowLongPtr(hwnd, GWL_STYLE, style); + + SetWindowPos(hwnd, 0, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOACTIVATE | SWP_FRAMECHANGED); + + return TRUE; + } +} + +// +// Remove cool scrollbars from the specified window. +// +HRESULT WINAPI UninitializeCoolSB(HWND hwnd) +{ + SCROLLWND *sw = GetScrollWndFromHwnd(hwnd); + if (!sw) + return E_FAIL; + + RemoveProp(hwnd, szPropStr); + //SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + + //finally, release the memory needed for the cool scrollbars + HeapFree(GetProcessHeap(), 0, sw); + + //Force WM_NCCALCSIZE and WM_NCPAINT so the original scrollbars can kick in + RedrawNonClient(hwnd, TRUE); + + return S_OK; +} + +#ifdef INCLUDE_BUTTONS + +// +// Cool scrollbar specific interface (BUTTON support) +// + +// +// Insert a button into the scrollbar area +// +// wSBflags - SB_HORZ / SB_VERT only +// uPos - position into which to insert. +// can be 0 to insert at the start, or -1 to insert +// at the end of previously inserted buttons +// + +BOOL WINAPI CoolSB_InsertButton(HWND hwnd, int wSBflags, UINT nPos, SCROLLBUT *psb) +{ + SCROLLBAR *sbar; + SCROLLBUT *sbut; + UINT i; + + if ( !psb) return FALSE; + + if ( !(sbar = GetScrollBarFromHwnd(hwnd, wSBflags))) + return FALSE; + + //check that we havn't reached the maximum allowed buttons yet + if (sbar->nButtons == MAX_COOLSB_BUTS) + return FALSE; + + //insert at end + if (nPos == -1) + { + sbut = &sbar->sbButtons[sbar->nButtons]; + } + //otherwise, need to make room + else if ((int)nPos < 0 || (int)nPos > (UINT)sbar->nButtons) + { + return FALSE; + } + else + { + //insert space for the button at the specified position + for (i = sbar->nButtons; i > nPos; i--) + { + sbar->sbButtons[i] = sbar->sbButtons[i-1]; + } + + sbut = &sbar->sbButtons[nPos]; + } + + //only set the button's properties if they are + //specified by the SCROLLBUT->fMask. + //Otherwise, use a default property value + + if (psb->fMask & SBBF_TYPE) + sbut->uButType = psb->uButType; + else + sbut->uButType = SBBT_PUSHBUTTON; + + if (psb->fMask & SBBF_STATE) + sbut->uState = psb->uState; + else + sbut->uState = 0; + + if (psb->fMask & SBBF_ID) + sbut->uCmdId = psb->uCmdId; + else + sbut->uCmdId = 0; + + if (psb->fMask & SBBF_SIZE) + sbut->nSize = psb->nSize; + else + sbut->nSize = -1; + + if (psb->fMask & SBBF_PLACEMENT) + sbut->uPlacement = psb->uPlacement; + else + sbut->uPlacement = SBBP_LEFT; + + if (psb->fMask & SBBF_BITMAP) + sbut->hBmp = psb->hBmp; + else + sbut->hBmp = 0; + + if (psb->fMask & SBBF_ENHMETAFILE) + sbut->hEmf = psb->hEmf; + else + sbut->hEmf = 0; + + if (psb->fMask & SBBF_CURSOR) + sbut->hCurs = psb->hCurs; + else + sbut->hCurs = 0; + + /* + We don't use the callback function anymore. The uButType + member must now specify SBBT_OWNERDRAW, and a WM_NOTIFY will + be sent when a button must be drawn + if ((psb->fMask & SBBF_OWNERDRAW) && ((psb->uButType & SBBT_MASK) == SBBT_OWNERDRAW)) + pDrawProc = psb->pDrawProc; + else + pDrawProc = 0;*/ + + sbar->nButtons++; + sbut->nSizeReserved = sbut->nSize; + + //MAKE SURE that any resizable buttons are only to the left / above + //a scrollbar. We don't support resize operations to the right of a scrollbar + if ((sbut->uButType & SBBM_RESIZABLE) && sbut->uPlacement == SBBP_RIGHT) + sbut->uButType &= ~SBBM_RESIZABLE; + + if (psb->fMask & SBBF_BUTMINMAX) + { + sbut->nMinSize = psb->nMinSize; + sbut->nMaxSize = psb->nMaxSize; + } + else + { + sbut->nMinSize = 0; + sbut->nMaxSize = -1; + } + + return TRUE; +} + +static SCROLLBUT *GetButtonFromId(SCROLLBAR *sbar, UINT uCmdId) +{ + int i; + for (i = 0; i < sbar->nButtons; i++) + { + if (sbar->sbButtons[i].uCmdId == uCmdId) + return &sbar->sbButtons[i]; + } + + return 0; +} + +// +// Modify the properties of the specified scrollbar button. +// wSBflags - SB_HORZ / SB_VERT only +// uItem - the command identifier specified when the button was created, +// or a non-negative position of the button, depending on if +// fByCmd is FALSE or TRUE, respectively +// +BOOL WINAPI CoolSB_ModifyButton (HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd, SCROLLBUT *psb) +{ + SCROLLBAR *sbar; + SCROLLBUT *sbut; + + if ( !psb) return FALSE; + + //find if this window is CoolScroll enabled + if ( !(sbar = GetScrollBarFromHwnd(hwnd, wSBflags))) + return FALSE; + + //find the button to modify, depending on if we + //are modifying by position or command id + if (fByCmd == FALSE) + { + //button from position + if ((int)uItem < 0 || (int)uItem >= (UINT)sbar->nButtons) + return FALSE; + else + sbut = &sbar->sbButtons[uItem]; + } + else if (fByCmd == TRUE) + { + //button from command identifier + if ( !(sbut = GetButtonFromId(sbar, uItem))) + return FALSE; + } + + if (psb->fMask & SBBF_TYPE) sbut->uButType = psb->uButType; + if (psb->fMask & SBBF_STATE) sbut->uState = psb->uState; + if (psb->fMask & SBBF_ID) sbut->uCmdId = psb->uCmdId; + if (psb->fMask & SBBF_SIZE) sbut->nSize = psb->nSize; + if (psb->fMask & SBBF_PLACEMENT) sbut->uPlacement = psb->uPlacement; + if (psb->fMask & SBBF_BITMAP) sbut->hBmp = psb->hBmp; + if (psb->fMask & SBBF_ENHMETAFILE) sbut->hEmf = psb->hEmf; + if (psb->fMask & SBBF_CURSOR) sbut->hCurs = psb->hCurs; + + if (psb->fMask & SBBF_BUTMINMAX) + { + sbut->nMinSize = psb->nMinSize; + sbut->nMaxSize = psb->nMaxSize; + } + + return TRUE; +} + +BOOL WINAPI CoolSB_RemoveButton(HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd) +{ + int i; + SCROLLBAR *sbar; + + //find if this window is CoolScroll enabled + if ( !(sbar = GetScrollBarFromHwnd(hwnd, wSBflags))) + return FALSE; + + //find the button to modify, depending on if we + //are modifying by position or command id + if (fByCmd == FALSE && ((int)uItem < 0 || (int)uItem >= (UINT)sbar->nButtons)) + { + return FALSE; + } + else if (fByCmd == TRUE) + { + //find the button with the specified command id + for (i = 0; i < sbar->nButtons; i++) + { + if (sbar->sbButtons[i].uCmdId == uItem) + { + //change the id to an index + uItem = i; + break; + } + } + + //if we failed to find the button... + if (i == sbar->nButtons) return FALSE; + } + + //remove the button! + for (i = uItem; i < sbar->nButtons - 1; i++) + { + sbar->sbButtons[i] = sbar->sbButtons[i+1]; + } + + sbar->nButtons--; + + RedrawNonClient(hwnd, TRUE); + + return TRUE; +} + +// +// fill in the supplied SCROLLBUT structure +// +BOOL WINAPI CoolSB_GetButton(HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd, SCROLLBUT *psb) +{ + SCROLLBAR *sbar; + SCROLLBUT *sbut; + + if ( !psb) return FALSE; + + //find if this window is CoolScroll enabled + if ( !(sbar = GetScrollBarFromHwnd(hwnd, wSBflags))) + return FALSE; + + //find the button to modify, depending on if we + //are modifying by position or command id + if (fByCmd == FALSE) + { + //button from position + if ((int)uItem < 0 || (int)uItem >= (UINT)sbar->nButtons) + return FALSE; + else + sbut = &sbar->sbButtons[uItem]; + } + else if (fByCmd == TRUE) + { + //button from command identifier + if ( !(sbut = GetButtonFromId(sbar, uItem))) + return FALSE; + } + + //copy them across + *psb = *sbut; + + return FALSE; +} + +#else + +BOOL WINAPI CoolSB_InsertButton(HWND, int, UINT, SCROLLBUT*) { return FALSE; } +BOOL WINAPI CoolSB_ModifyButton(HWND, int, UINT, BOOL, SCROLLBUT*) { return FALSE; } +BOOL WINAPI CoolSB_RemoveButton(HWND, int, UINT, BOOL) { return FALSE; } +BOOL WINAPI CoolSB_GetButton(HWND, int, UINT, BOOL, SCROLLBUT*) { return FALSE; } + +#endif //INCLUDE_BUTTONS + +// +// Set the size of the scrollbars +// +BOOL WINAPI CoolSB_SetSize(HWND hwnd, int wBar, int nLength, int nWidth) +{ + SCROLLBAR *sbar; + + if (nLength == 0 || nWidth == 0) + return FALSE; + + if (nLength < -8 || nWidth < -8) + return FALSE; + + if (nLength > 256 || nWidth > 256) + return FALSE; + + if (!GetScrollWndFromHwnd(hwnd)) + return FALSE; + + if ((wBar == SB_HORZ || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) { + sbar->nArrowLength = nLength; + sbar->nArrowWidth = nWidth; + } + + if ((wBar == SB_VERT || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) { + sbar->nArrowLength = nLength; + sbar->nArrowWidth = nWidth; + } + + RedrawNonClient(hwnd, TRUE); + return TRUE; +} + +// +// Alter the display mode of the scrollbars +// wBar - SB_HORZ / SB_VERT / SB_BOTH +// nStyle - CSBF_NORMAL / CSBF_FLAT / CSBF_HOTTRACKED +// +BOOL WINAPI CoolSB_SetStyle(HWND hwnd, int wBar, UINT nStyle) +{ + SCROLLBAR *sbar; + + if (!GetScrollWndFromHwnd(hwnd)) + return FALSE; + + if ((wBar == SB_HORZ || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) + sbar->fFlatScrollbar = nStyle; + + if ((wBar == SB_VERT || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) + sbar->fFlatScrollbar = nStyle; + + RedrawNonClient(hwnd, FALSE); + return TRUE; +} + +// +// Set if the thumb is always visible, even if there is no data to +// scroll. Setting this keeps the scrollbar enabled, but the thumb +// covers the whole area +// +BOOL WINAPI CoolSB_SetThumbAlways(HWND hwnd, int wBar, BOOL fThumbAlways) +{ + SCROLLBAR *sbar; + + if (!GetScrollWndFromHwnd(hwnd)) + return FALSE; + + if ((wBar == SB_HORZ || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) { + if (fThumbAlways) + sbar->fScrollFlags |= CSBS_THUMBALWAYS; + else + sbar->fScrollFlags &= ~CSBS_THUMBALWAYS; + } + + if ((wBar == SB_VERT || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) { + if (fThumbAlways) + sbar->fScrollFlags |= CSBS_THUMBALWAYS; + else + sbar->fScrollFlags &= ~CSBS_THUMBALWAYS; + } + + RedrawNonClient(hwnd, FALSE); + + return TRUE; +} + +// +// Set the minimum size, in pixels, that the thumb box will shrink to. +// +BOOL WINAPI CoolSB_SetMinThumbSize(HWND hwnd, UINT wBar, UINT size) +{ + SCROLLBAR *sbar; + + if (!GetScrollWndFromHwnd(hwnd)) + return FALSE; + + if (size == -1) + size = CoolSB_GetDefaultMinThumbSize(); + + if ((wBar == SB_HORZ || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ))) + sbar->nMinThumbSize = size; + + if ((wBar == SB_VERT || wBar == SB_BOTH) && (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT))) + sbar->nMinThumbSize = size; + + return TRUE; +} -- cgit v1.2.3