Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1000 lines
26 KiB

/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
//
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
////
// bscroll.c - bitmap scroll functions
////
#include "winlocal.h"
#include <stdlib.h>
#include "bscroll.h"
#include "gfx.h"
#include "mem.h"
#include "sys.h"
#include "trace.h"
#include "wnd.h"
////
// private definitions
////
#define BSCROLLCLASS TEXT("BScrollClass")
#define ID_TIMER_SCROLL 1024
#define BSCROLL_SCROLLING 0x00000001
#define BSCROLL_DRAGGING 0x00000002
#define BSCROLL_PAUSED 0x00000004
// bscroll control struct
//
typedef struct BSCROLL
{
DWORD dwVersion;
HINSTANCE hInst;
HWND hwndParent;
HTASK hTask;
HBITMAP hbmpBackground; // $FIXUP - make copy during BScrollInit
HBITMAP hbmpForeground; // $FIXUP - make copy during BScrollInit
COLORREF crTransparent;
HPALETTE hPalette;
UINT msScroll;
int pelScroll;
DWORD dwReserved;
DWORD dwFlags;
HWND hwndBScroll;
HDC hdcMem;
HBITMAP hbmpMem;
HBITMAP hbmpMemSave;
HRGN hrgnLeft;
HRGN hrgnRight;
HRGN hrgnUp;
HRGN hrgnDown;
DWORD dwState;
int xDrag;
int yDrag;
} BSCROLL, FAR *LPBSCROLL;
// helper functions
//
LRESULT DLLEXPORT CALLBACK BScrollWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static BOOL BScrollOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct);
static BOOL BScrollOnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
static void BScrollOnDestroy(HWND hwnd);
static void BScrollOnSize(HWND hwnd, UINT state, int cx, int cy);
static void BScrollOnPaint(HWND hwnd);
static void BScrollOnTimer(HWND hwnd, UINT id);
static void BScrollOnChar(HWND hwnd, UINT ch, int cRepeat);
static void BScrollOnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
static void BScrollOnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags);
static void BScrollOnRButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
static void BScrollOnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags);
static void BScrollOnMouseMove(HWND hwnd, int x, int y, UINT keyFlags);
static int BScrollChangeDirection(LPBSCROLL lpBScroll, int x, int y, DWORD dwFlags);
static LPBSCROLL BScrollGetPtr(HBSCROLL hBScroll);
static HBSCROLL BScrollGetHandle(LPBSCROLL lpBScroll);
////
// public functions
////
// BScrollInit - initialize bscroll engine
// <dwVersion> (i) must be BSCROLL_VERSION
// <hInst> (i) instance handle of calling module
// <hwndParent> (i) window which will own the bscroll window
// <hbmpBackground> (i) bitmap to display in background
// NULL no background bitmap
// <hbmpForeground> (i) bitmap to display in foreground
// NULL no foreground bitmap
// <crTransparent> (i) transparent color in foreground bitmap
// <hPalette> (i) palette
// NULL use default palette
// <msScroll> (i) scroll rate in milleseconds
// 0 do not scroll
// <pelScroll> (i) scroll amount in pixels
// <dwReserved> (i) reserved; must be zero
// <dwFlags> (i) control flags
// BSCROLL_BACKGROUND scroll the background bitmap (default)
// BSCROLL_FOREGROUND scroll the foreground bitmap
// BSCROLL_UP scroll the window up
// BSCROLL_DOWN scroll the window down
// BSCROLL_LEFT scroll the window left
// BSCROLL_RIGHT scroll the window right
// BSCROLL_MOUSEMOVE change scroll direction on mouse movement
// BSCROLL_FLIGHTSIM reverses BSCROLL_MOUSEMOVE direction
// BSCROLL_DRAG allow scrolling using mouse drag
// return handle (NULL if error)
//
// NOTE: BScrollInit creates the window but does not start the scrolling.
// See BScrollStart and BScrollStop
//
HBSCROLL DLLEXPORT WINAPI BScrollInit(DWORD dwVersion, HINSTANCE hInst,
HWND hwndParent, HBITMAP hbmpBackground, HBITMAP hbmpForeground,
COLORREF crTransparent, HPALETTE hPalette, UINT msScroll,
int pelScroll, DWORD dwReserved, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll = NULL;
WNDCLASS wc;
RECT rcParent;
int idChild = 1;
if (dwVersion != BSCROLL_VERSION)
fSuccess = TraceFALSE(NULL);
else if (hInst == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll = (LPBSCROLL) MemAlloc(NULL, sizeof(BSCROLL), 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (!GetClientRect(hwndParent, &rcParent))
fSuccess = TraceFALSE(NULL);
else
{
lpBScroll->dwVersion = dwVersion;
lpBScroll->hInst = hInst;
lpBScroll->hTask = GetCurrentTask();
lpBScroll->hwndParent = hwndParent;
lpBScroll->hbmpBackground = hbmpBackground;
lpBScroll->hbmpForeground = hbmpForeground;
lpBScroll->crTransparent = crTransparent;
lpBScroll->hPalette = hPalette;
lpBScroll->msScroll = msScroll;
lpBScroll->pelScroll = pelScroll;
lpBScroll->dwReserved = dwReserved;
lpBScroll->dwFlags = dwFlags;
lpBScroll->hwndBScroll = NULL;
lpBScroll->hdcMem = NULL;
lpBScroll->hbmpMem = NULL;
lpBScroll->hbmpMemSave = NULL;
lpBScroll->hrgnLeft = NULL;
lpBScroll->hrgnRight = NULL;
lpBScroll->hrgnUp = NULL;
lpBScroll->hrgnDown = NULL;
lpBScroll->dwState = 0;
lpBScroll->xDrag = -1;
lpBScroll->yDrag = -1;
}
//
// We should verify lpBScroll before use it
//
if( NULL == lpBScroll )
{
return NULL;
}
// register bscroll window class unless it has been already
//
if (fSuccess && GetClassInfo(lpBScroll->hInst, BSCROLLCLASS, &wc) == 0)
{
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = (HICON) NULL;
wc.lpszMenuName = NULL;
wc.hInstance = lpBScroll->hInst;
wc.lpszClassName = BSCROLLCLASS;
wc.hbrBackground = NULL;
wc.lpfnWndProc = BScrollWndProc;
wc.style = 0L;
wc.cbWndExtra = sizeof(lpBScroll);
wc.cbClsExtra = 0;
if (!RegisterClass(&wc))
fSuccess = TraceFALSE(NULL);
}
// create a bscroll window
//
if (fSuccess && (lpBScroll->hwndBScroll = CreateWindowEx(
0L,
BSCROLLCLASS,
(LPTSTR) TEXT(""),
WS_CHILD | WS_VISIBLE,
0, 0, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top,
hwndParent,
(HMENU)IntToPtr(idChild),
lpBScroll->hInst,
lpBScroll)) == NULL)
{
fSuccess = TraceFALSE(NULL);
}
else
{
// set the cursor to something appropriate
//
SetClassLongPtr(lpBScroll->hwndBScroll, GCLP_HCURSOR,
(dwFlags & BSCROLL_DRAG) ?
(LONG_PTR) LoadCursor(NULL, IDC_SIZEALL) :
(LONG_PTR) LoadCursor(NULL, IDC_ARROW));
}
if (!fSuccess)
{
BScrollTerm(BScrollGetHandle(lpBScroll));
lpBScroll = NULL;
}
return fSuccess ? BScrollGetHandle(lpBScroll) : NULL;
}
// BScrollTerm - shutdown bscroll engine
// <hBScroll> (i) handle returned from BScrollInit
// return 0 if success
//
int DLLEXPORT WINAPI BScrollTerm(HBSCROLL hBScroll)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if (BScrollStop(hBScroll) != 0)
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpBScroll->hwndBScroll != NULL &&
!DestroyWindow(lpBScroll->hwndBScroll))
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll = MemFree(NULL, lpBScroll)) != NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? 0 : -1;
}
// BScrollStart - start bscroll animation
// <hBScroll> (i) handle returned from BScrollInit
// return 0 if success
//
int DLLEXPORT WINAPI BScrollStart(HBSCROLL hBScroll)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
fSuccess = TraceFALSE(NULL);
// set scroll timer if necessary
//
else if (!(lpBScroll->dwState & BSCROLL_SCROLLING) && lpBScroll->msScroll > 0)
{
if (!SetTimer(lpBScroll->hwndBScroll, ID_TIMER_SCROLL,
lpBScroll->msScroll, NULL))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->dwState |= BSCROLL_SCROLLING;
}
return fSuccess ? 0 : -1;
}
// BScrollStop - stop bscroll animation
// <hBScroll> (i) handle returned from BScrollInit
// return 0 if success
//
int DLLEXPORT WINAPI BScrollStop(HBSCROLL hBScroll)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
fSuccess = TraceFALSE(NULL);
// kill scroll timer if necessary
//
else if (lpBScroll->dwState & BSCROLL_SCROLLING)
{
if (!KillTimer(lpBScroll->hwndBScroll, ID_TIMER_SCROLL))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->dwState &= ~BSCROLL_SCROLLING;
}
return fSuccess ? 0 : -1;
}
// BScrollGetWindowHandle - get bscroll screen window handle
// <hBScroll> (i) handle returned from BScrollInit
// return window handle (NULL if error)
//
HWND DLLEXPORT WINAPI BScrollGetWindowHandle(HBSCROLL hBScroll)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = BScrollGetPtr(hBScroll)) == NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? lpBScroll->hwndBScroll : NULL;
}
////
// helper functions
////
// BScrollWndProc - window procedure for bscroll screen
//
LRESULT DLLEXPORT CALLBACK BScrollWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
BOOL fSuccess = TRUE;
LRESULT lResult;
switch (msg)
{
case WM_NCCREATE:
lResult = (LRESULT) HANDLE_WM_NCCREATE(hwnd, wParam, lParam, BScrollOnNCCreate);
break;
case WM_CREATE:
lResult = (LRESULT) HANDLE_WM_CREATE(hwnd, wParam, lParam, BScrollOnCreate);
break;
case WM_DESTROY:
lResult = (LRESULT) HANDLE_WM_DESTROY(hwnd, wParam, lParam, BScrollOnDestroy);
break;
case WM_SIZE:
lResult = (LRESULT) HANDLE_WM_SIZE(hwnd, wParam, lParam, BScrollOnSize);
break;
case WM_PAINT:
lResult = (LRESULT) HANDLE_WM_PAINT(hwnd, wParam, lParam, BScrollOnPaint);
break;
case WM_TIMER:
lResult = (LRESULT) HANDLE_WM_TIMER(hwnd, wParam, lParam, BScrollOnTimer);
break;
case WM_CHAR:
lResult = (LRESULT) HANDLE_WM_CHAR(hwnd, wParam, lParam, BScrollOnChar);
break;
case WM_LBUTTONDOWN:
lResult = (LRESULT) HANDLE_WM_LBUTTONDOWN(hwnd, wParam, lParam, BScrollOnLButtonDown);
break;
case WM_LBUTTONUP:
lResult = (LRESULT) HANDLE_WM_LBUTTONUP(hwnd, wParam, lParam, BScrollOnLButtonUp);
break;
case WM_RBUTTONDOWN:
lResult = (LRESULT) HANDLE_WM_RBUTTONDOWN(hwnd, wParam, lParam, BScrollOnRButtonDown);
break;
case WM_RBUTTONUP:
lResult = (LRESULT) HANDLE_WM_RBUTTONUP(hwnd, wParam, lParam, BScrollOnRButtonUp);
break;
case WM_MOUSEMOVE:
lResult = (LRESULT) HANDLE_WM_MOUSEMOVE(hwnd, wParam, lParam, BScrollOnMouseMove);
break;
default:
lResult = DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return lResult;
}
// BScrollOnNCCreate - handler for WM_NCCREATE message
//
static BOOL BScrollOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)
{
LPBSCROLL lpBScroll = (LPBSCROLL) lpCreateStruct->lpCreateParams;
lpBScroll->hwndBScroll = hwnd;
// store lpBScroll in window extra bytes
//
SetWindowLongPtr(hwnd, 0, (LONG_PTR) lpBScroll);
return FORWARD_WM_NCCREATE(hwnd, lpCreateStruct, DefWindowProc);
}
// BScrollOnCreate - handler for WM_CREATE message
//
static BOOL BScrollOnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
BOOL fSuccess = TRUE;
HDC hdc = NULL;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((hdc = GetDC(hwnd)) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll->hdcMem = CreateCompatibleDC(hdc)) == NULL)
fSuccess = TraceFALSE(NULL);
// clean up
//
if (hdc != NULL)
ReleaseDC(hwnd, hdc);
return fSuccess;
}
// BScrollOnDestroy - handler for WM_DESTROY message
//
static void BScrollOnDestroy(HWND hwnd)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else
{
SelectObject(lpBScroll->hdcMem, lpBScroll->hbmpMemSave);
if (lpBScroll->hbmpMem != NULL && !DeleteObject(lpBScroll->hbmpMem))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->hbmpMem = NULL;
if (lpBScroll->hdcMem != NULL && !DeleteDC(lpBScroll->hdcMem))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->hdcMem = NULL;
if (lpBScroll->hrgnLeft != NULL &&
!DeleteObject(lpBScroll->hrgnLeft))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->hrgnLeft = NULL;
if (lpBScroll->hrgnRight != NULL &&
!DeleteObject(lpBScroll->hrgnRight))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->hrgnRight = NULL;
if (lpBScroll->hrgnUp != NULL &&
!DeleteObject(lpBScroll->hrgnUp))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->hrgnUp = NULL;
if (lpBScroll->hrgnDown != NULL &&
!DeleteObject(lpBScroll->hrgnDown))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->hrgnDown = NULL;
}
return;
}
// BScrollOnSize - handler for WM_SIZE message
//
static void BScrollOnSize(HWND hwnd, UINT state, int cx, int cy)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else switch (state)
{
case SIZE_RESTORED:
case SIZE_MAXIMIZED:
{
HDC hdc = NULL;
HBITMAP hbmpTemp = NULL;
if ((hdc = GetDC(hwnd)) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((hbmpTemp = CreateCompatibleBitmap(hdc, cx, cy)) == NULL)
fSuccess = TraceFALSE(NULL);
else
{
lpBScroll->hbmpMemSave = (HBITMAP)
SelectObject(lpBScroll->hdcMem, hbmpTemp);
if (lpBScroll->hbmpMem != NULL &&
!DeleteObject(lpBScroll->hbmpMem))
fSuccess = TraceFALSE(NULL);
else
lpBScroll->hbmpMem = hbmpTemp;
}
if (hdc != NULL)
ReleaseDC(hwnd, hdc);
if (1)
{
POINT aptLeft[5];
POINT aptRight[5];
POINT aptUp[5];
POINT aptDown[5];
aptLeft[0].x = cx / 2;
aptLeft[0].y = cy / 2;
aptLeft[1].x = cx / 4;
aptLeft[1].y = 0;
aptLeft[2].x = 0;
aptLeft[2].y = 0;
aptLeft[3].x = 0;
aptLeft[3].y = cy;
aptLeft[4].x = cx / 4;
aptLeft[4].y = cy;
aptRight[0].x = cx / 2;
aptRight[0].y = cy / 2;
aptRight[1].x = cx - (cx / 4);
aptRight[1].y = 0;
aptRight[2].x = cx;
aptRight[2].y = 0;
aptRight[3].x = cx;
aptRight[3].y = cy;
aptRight[4].x = cx - (cx / 4);
aptRight[4].y = cy;
aptUp[0].x = cx / 2;
aptUp[0].y = cy / 2;
aptUp[1].x = 0;
aptUp[1].y = cy / 4;
aptUp[2].x = 0;
aptUp[2].y = 0;
aptUp[3].x = cx;
aptUp[3].y = 0;
aptUp[4].x = cx;
aptUp[4].y = cy / 4;
aptDown[0].x = cx / 2;
aptDown[0].y = cy / 2;
aptDown[1].x = 0;
aptDown[1].y = cy - (cy / 4);
aptDown[2].x = 0;
aptDown[2].y = cy;
aptDown[3].x = cx;
aptDown[3].y = cy;
aptDown[4].x = cx;
aptDown[4].y = cy - (cy / 4);
if (lpBScroll->hrgnLeft != NULL &&
!DeleteObject(lpBScroll->hrgnLeft))
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll->hrgnLeft = CreatePolygonRgn(aptLeft,
SIZEOFARRAY(aptLeft), WINDING)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpBScroll->hrgnRight != NULL &&
!DeleteObject(lpBScroll->hrgnRight))
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll->hrgnRight = CreatePolygonRgn(aptRight,
SIZEOFARRAY(aptRight), WINDING)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpBScroll->hrgnUp != NULL &&
!DeleteObject(lpBScroll->hrgnUp))
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll->hrgnUp = CreatePolygonRgn(aptUp,
SIZEOFARRAY(aptUp), WINDING)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpBScroll->hrgnDown != NULL &&
!DeleteObject(lpBScroll->hrgnDown))
fSuccess = TraceFALSE(NULL);
else if ((lpBScroll->hrgnDown = CreatePolygonRgn(aptDown,
SIZEOFARRAY(aptDown), WINDING)) == NULL)
fSuccess = TraceFALSE(NULL);
}
InvalidateRect(hwnd, NULL, FALSE);
}
break;
default:
break;
}
return;
}
// BScrollOnPaint - handler for WM_PAINT message
//
static void BScrollOnPaint(HWND hwnd)
{
BOOL fSuccess = TRUE;
BOOL fBitBlt = TRUE;
HDC hdc;
PAINTSTRUCT ps;
LPBSCROLL lpBScroll;
#if 0
DWORD msStartTimer = SysGetTimerCount();
DWORD msStopTimer;
#endif
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((hdc = BeginPaint(hwnd, &ps)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpBScroll->hPalette != NULL)
{
SelectPalette(hdc, lpBScroll->hPalette, FALSE);
if (lpBScroll->hPalette != NULL &&
RealizePalette(hdc) == GDI_ERROR)
fSuccess = TraceFALSE(NULL);
else if (fBitBlt)
{
SelectPalette(lpBScroll->hdcMem, lpBScroll->hPalette, FALSE);
if (RealizePalette(lpBScroll->hdcMem) == GDI_ERROR)
fSuccess = TraceFALSE(NULL);
}
}
//
// $FIXUP - BSCROLL_FOREGROUND not yet suppported
//
if (fSuccess && lpBScroll->hbmpBackground != NULL)
{
if (lpBScroll->dwState & BSCROLL_SCROLLING)
{
int dxScroll = 0;
int dyScroll = 0;
// calculate dx and dy for the scroll
//
if (lpBScroll->dwFlags & BSCROLL_LEFT)
dxScroll = -1 * lpBScroll->pelScroll;
else if (lpBScroll->dwFlags & BSCROLL_RIGHT)
dxScroll = +1 * lpBScroll->pelScroll;
if (lpBScroll->dwFlags & BSCROLL_UP)
dyScroll = -1 * lpBScroll->pelScroll;
else if (lpBScroll->dwFlags & BSCROLL_DOWN)
dyScroll = +1 * lpBScroll->pelScroll;
if (GfxBitmapScroll((fBitBlt ? lpBScroll->hdcMem : hdc),
lpBScroll->hbmpBackground,
dxScroll, dyScroll, BS_ROTATE) != 0)
fSuccess = TraceFALSE(NULL);
}
else if (GfxBitmapDisplay((fBitBlt ? lpBScroll->hdcMem : hdc),
lpBScroll->hbmpBackground, 0, 0, 0) != 0)
fSuccess = TraceFALSE(NULL);
}
if (fSuccess && lpBScroll->hbmpForeground != NULL)
{
if (GfxBitmapDrawTransparent((fBitBlt ? lpBScroll->hdcMem : hdc),
lpBScroll->hbmpForeground, 0, 0, lpBScroll->crTransparent, 0) != 0)
fSuccess = TraceFALSE(NULL);
}
if (fSuccess && fBitBlt && !BitBlt(hdc,
ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
lpBScroll->hdcMem,
ps.rcPaint.left, ps.rcPaint.top,
SRCCOPY))
fSuccess = TraceFALSE(NULL);
//
// We should call EndPaint just if we called BeginPaint
// BeginPAint should succeded too?
if((lpBScroll != NULL) && (hdc != NULL))
EndPaint(hwnd, &ps);
#if 0
msStopTimer = SysGetTimerCount();
TracePrintf_1(NULL, 8, TEXT("elapsed=%ld\n"),
(long) (msStopTimer - msStartTimer));
#endif
return;
}
// BScrollOnTimer - handler for WM_TIMER message
//
static void BScrollOnTimer(HWND hwnd, UINT id)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else switch (id)
{
case ID_TIMER_SCROLL:
{
InvalidateRect(hwnd, NULL, FALSE);
}
break;
default:
break;
}
return;
}
// BScrollOnChar - handler for WM_CHAR message
//
static void BScrollOnChar(HWND hwnd, UINT ch, int cRepeat)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
return;
}
// BScrollOnLButtonDown - handler for WM_LBUTTONDOWN message
//
static void BScrollOnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (!(lpBScroll->dwState & BSCROLL_DRAGGING) &&
!fDoubleClick && (lpBScroll->dwFlags & BSCROLL_DRAG))
{
lpBScroll->dwState |= BSCROLL_DRAGGING;
lpBScroll->xDrag = x;
lpBScroll->yDrag = y;
SetCapture(lpBScroll->hwndBScroll);
if (lpBScroll->dwState & BSCROLL_SCROLLING)
{
if (BScrollStop(BScrollGetHandle(lpBScroll)) != 0)
fSuccess = TraceFALSE(NULL);
else
lpBScroll->dwState |= BSCROLL_PAUSED;
}
}
if (fSuccess)
FORWARD_WM_LBUTTONDOWN(lpBScroll->hwndParent, fDoubleClick, x, y, keyFlags, SendMessage);
return;
}
// BScrollOnLButtonUp - handler for WM_LBUTTONUP message
//
static void BScrollOnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpBScroll->dwState & BSCROLL_DRAGGING)
{
lpBScroll->dwState &= ~BSCROLL_DRAGGING;
lpBScroll->xDrag = -1;
lpBScroll->yDrag = -1;
ReleaseCapture();
if (lpBScroll->dwState & BSCROLL_PAUSED)
{
if (BScrollStart(BScrollGetHandle(lpBScroll)) != 0)
fSuccess = TraceFALSE(NULL);
else
lpBScroll->dwState &= ~BSCROLL_PAUSED;
}
}
if (fSuccess)
FORWARD_WM_LBUTTONUP(lpBScroll->hwndParent, x, y, keyFlags, SendMessage);
return;
}
// BScrollOnRButtonDown - handler for WM_LBUTTONDOWN message
//
static void BScrollOnRButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
if (fSuccess)
FORWARD_WM_RBUTTONDOWN(lpBScroll->hwndParent, fDoubleClick, x, y, keyFlags, SendMessage);
return;
}
// BScrollOnRButtonUp - handler for WM_RBUTTONUP message
//
static void BScrollOnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
if (fSuccess)
FORWARD_WM_RBUTTONUP(lpBScroll->hwndParent, x, y, keyFlags, SendMessage);
return;
}
static void BScrollOnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) GetWindowLongPtr(hwnd, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (lpBScroll->dwState & BSCROLL_DRAGGING)
{
if (fSuccess && lpBScroll->hbmpBackground != NULL)
{
int dxScroll = x - lpBScroll->xDrag;
int dyScroll = y - lpBScroll->yDrag;
lpBScroll->xDrag = x;
lpBScroll->yDrag = y;
if (GfxBitmapScroll(lpBScroll->hdcMem,
lpBScroll->hbmpBackground,
dxScroll, dyScroll, BS_ROTATE) != 0)
fSuccess = TraceFALSE(NULL);
else
{
InvalidateRect(lpBScroll->hwndBScroll, NULL, FALSE);
UpdateWindow(lpBScroll->hwndBScroll);
}
}
}
if (fSuccess && BScrollChangeDirection(lpBScroll, x, y, 0) != 0)
fSuccess = TraceFALSE(NULL);
return;
}
static int BScrollChangeDirection(LPBSCROLL lpBScroll, int x, int y, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
RECT rc;
if (lpBScroll == NULL)
fSuccess = TraceFALSE(NULL);
else if (!(lpBScroll->dwState & BSCROLL_SCROLLING) &&
!(lpBScroll->dwState & BSCROLL_DRAGGING))
; // nothing to do
else if (!GetClientRect(lpBScroll->hwndBScroll, &rc))
fSuccess = TraceFALSE(NULL);
else if (x < 0 || x > rc.right - 1 || y < 0 || y > rc.bottom - 1)
; // outside the window; nothing to do
else if ((lpBScroll->dwFlags & BSCROLL_MOUSEMOVE) ||
(lpBScroll->dwState & BSCROLL_DRAGGING))
{
lpBScroll->dwFlags &= ~BSCROLL_LEFT;
lpBScroll->dwFlags &= ~BSCROLL_RIGHT;
lpBScroll->dwFlags &= ~BSCROLL_UP;
lpBScroll->dwFlags &= ~BSCROLL_DOWN;
if (lpBScroll->dwFlags & BSCROLL_FLIGHTSIM &&
!(lpBScroll->dwState & BSCROLL_DRAGGING))
{
if (PtInRegion(lpBScroll->hrgnLeft, x, y))
lpBScroll->dwFlags |= BSCROLL_RIGHT;
if (PtInRegion(lpBScroll->hrgnRight, x, y))
lpBScroll->dwFlags |= BSCROLL_LEFT;
if (PtInRegion(lpBScroll->hrgnUp, x, y))
lpBScroll->dwFlags |= BSCROLL_DOWN;
if (PtInRegion(lpBScroll->hrgnDown, x, y))
lpBScroll->dwFlags |= BSCROLL_UP;
}
else
{
if (PtInRegion(lpBScroll->hrgnLeft, x, y))
lpBScroll->dwFlags |= BSCROLL_LEFT;
if (PtInRegion(lpBScroll->hrgnRight, x, y))
lpBScroll->dwFlags |= BSCROLL_RIGHT;
if (PtInRegion(lpBScroll->hrgnUp, x, y))
lpBScroll->dwFlags |= BSCROLL_UP;
if (PtInRegion(lpBScroll->hrgnDown, x, y))
lpBScroll->dwFlags |= BSCROLL_DOWN;
}
}
return fSuccess ? 0 : -1;
}
// BScrollGetPtr - verify that bscroll handle is valid,
// <hBScroll> (i) handle returned from BScrollInit
// return corresponding bscroll pointer (NULL if error)
//
static LPBSCROLL BScrollGetPtr(HBSCROLL hBScroll)
{
BOOL fSuccess = TRUE;
LPBSCROLL lpBScroll;
if ((lpBScroll = (LPBSCROLL) hBScroll) == NULL)
fSuccess = TraceFALSE(NULL);
else if (IsBadWritePtr(lpBScroll, sizeof(BSCROLL)))
fSuccess = TraceFALSE(NULL);
#ifdef CHECKTASK
// make sure current task owns the bscroll handle
//
else if (lpBScroll->hTask != GetCurrentTask())
fSuccess = TraceFALSE(NULL);
#endif
return fSuccess ? lpBScroll : NULL;
}
// BScrollGetHandle - verify that bscroll pointer is valid,
// <lpBScroll> (i) pointer to BSCROLL struct
// return corresponding bscroll handle (NULL if error)
//
static HBSCROLL BScrollGetHandle(LPBSCROLL lpBScroll)
{
BOOL fSuccess = TRUE;
HBSCROLL hBScroll;
if ((hBScroll = (HBSCROLL) lpBScroll) == NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? hBScroll : NULL;
}