Click here to Skip to main content
15,891,136 members
Articles / Desktop Programming / MFC

CWindowScroller

Rate me:
Please Sign up or sign in to vote.
4.83/5 (39 votes)
7 May 2016CPOL5 min read 179.6K   4.5K   78  
An MFC control for adding middle mouse button scrolling to any CWnd derived window
/****************************************************************************
WindowScroller.cpp : implementation file

Written by : PJ Arends
pja@telus.net

Copyright (c) 2003 PJ Arends

-----------------------------------------------------------------------------
This code is provided as is, with no warranty as to it's suitability or usefulness
in any application in which it may be used. This code has not been tested for
UNICODE builds.

This code may be used in any way you desire. This file may be redistributed by any
means as long as it is not sold for profit, and providing that this notice and the
authors name are included.

If any bugs are found and fixed, a note to the author explaining the problem and
fix would be nice.
-----------------------------------------------------------------------------

Revision History:

  Some code provided by:
    Jean-Michel LE FOL - jean-michel.lefol@libertysurf.fr
    Dieter Hammer      - Dieter.Hammer@ePost.de

January 10, 2003   -        original release
January 20, 2003   - JMLF - added code for scrolling list views
January 23, 2003   -        fixed middle button click'n hold bug
February 16, 2003  -        added 'mouse button up' handlers
March 1, 2003      -        added bUseThumbPos parameter to constructor
                              as requested by Neville Franks - readonly@getsoft.com
March 8, 2003      -        fixed bug that crashed program if window creation fails
March 10, 2003     -        total rewrite of scrolling code, now supports tree views
                             and list views in all modes
                   -        added GetParentWndType() function
July 10, 2003               added support for list box controls
December 10, 2015           cleaned up the registered windows messages
                             added the RWM_ONSTARTWINDOWSCROLLER message
                             messages are now declared as static const UINT in Windowscroller.h
May 4, 2016                 fixed drawing code, now using a transparent layered window instead of a window region

****************************************************************************/

#include "stdafx.h"
#include "WindowScroller.h"
#include <afxcview.h>        // for list view and tree view support
#include <math.h>            // for abs()

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// WindowTypes enumeration. Used to identify the type of window being scrolled.
enum WindowTypes
{
    Type_CWnd = 0,
    Type_CScrollView,
    Type_CTreeView,
    Type_CListView_Report,
    Type_CListView_List,
    Type_CListView_Icon,
    Type_CListBox
    // Add more types here
};

// Global pointer used by the hook procedures
CWindowScroller *pGWindowScroller = NULL;

// Keyboard hook used to kill scroller window if a key is pressed
LRESULT CALLBACK WindowScrollerKeyBoardHookProc(int code, WPARAM wp, LPARAM lp)
{
    ASSERT_VALID(pGWindowScroller);
    LRESULT ret = CallNextHookEx(pGWindowScroller->m_hKeyboardHook, code, wp, lp);
    ReleaseCapture();
    return ret;
}

// Mouse hook used to kill scroller if mouse wheel is rotated
LRESULT CALLBACK WindowScrollerMouseHookProc(int code, WPARAM wp, LPARAM lp)
{
    ASSERT_VALID(pGWindowScroller);
    LRESULT ret = CallNextHookEx(pGWindowScroller->m_hMouseHook, code, wp, lp);
    if (wp == WM_MOUSEWHEEL)
    {
        ReleaseCapture();
        ret = 1;          // eat the WM_MOUSEWHEEL message
    }
    return ret;
}

/////////////////////////////////////////////////////////////////////////////
// CWindowScroller

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller constructor  (public member function)
//    Constructs, initializes, and runs the window scroller
//
//  Parameters :
//    pParent      [in] : Pointer to the window that has to be scrolled
//    Point        [in] : The point, in pParent client coordinates, where the scroller
//                        window is to be centered on
//    Pixels       [in] : The pixel ratio that is used to calculate the scrolling speed
//    Elapse       [in] : The delay time between scrolling messages
//    Direction    [in] : The allowable directions to scroll, either Horizontal, Vertical
//                        or Both (default)
//    bUseThumbPos [in] : Set the flag to be used within the WM_VSCROLL/WM_HSCROLL message
//                        TRUE for SB_THUMBPOSITION (default)
//                        FALSE for SB_THUMBTRACK
//
/////////////////////////////////////////////////////////////////////////////

CWindowScroller::CWindowScroller(CWnd *pParent,
                                 CPoint Point,
                                 int Pixels,        // = 15
                                 UINT Elapse,       // = 30
                                 int Direction,     // = Both
                                 BOOL bUseThumbPos) // = TRUE
{
    ASSERT_VALID (pParent);
    ASSERT (Pixels > 0);
    ASSERT (Elapse > 0);
    ASSERT (Direction >= Vertical && Direction <= Both);

    // Initialize all member variables
    Initialize();

    m_pParentWnd = pParent;
    m_Alignment = Direction;

    DWORD dwStyle = m_pParentWnd->GetStyle();

    // ensure the parent window allows vertical scrolling
    CScrollBar* pBar = m_pParentWnd->GetScrollBarCtrl(SB_VERT);
    BOOL bHasBar = ((pBar != NULL) && pBar->IsWindowEnabled()) || (dwStyle & WS_VSCROLL);
    if (!bHasBar)
        m_Alignment &= ~Vertical;

    // ensure the parent window allows horizontal scrolling
    pBar = m_pParentWnd->GetScrollBarCtrl(SB_HORZ);
    bHasBar = ((pBar != NULL) && pBar->IsWindowEnabled()) || (dwStyle & WS_HSCROLL);
    if (!bHasBar)
        m_Alignment &= ~Horizontal;

    if (!m_Alignment)
    {   // scrolling not allowed or not needed, cleanup and get out
        TRACE (_T("CWindowScroller::CWindowScroller - No scrolling allowed or needed\n"));
        delete this;
    }
    else
    {
        // inform parent window that the window scroller has started
        if (0 != m_pParentWnd->SendMessage(RWM_ONSTARTWINDOWSCROLLER, 0, 0))
        {   // Parent window blocked us. cleanup and get out
            TRACE(_T("CWindowScroller::CWindowScroller - Scrolling blocked by user\n"));
            delete this;
        }
        else
        {
            // center the window on the given point
            m_pParentWnd->ClientToScreen(&Point);
            m_CenterPoint = Point;

            // create the window
            if (!CreateEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT,
                AfxRegisterWndClass(NULL),
                NULL,
                WS_POPUP | WS_VISIBLE,
                m_CenterPoint.x - 17,
                m_CenterPoint.y - 17,
                40,
                40,
                *m_pParentWnd,
                NULL,
                NULL))
            {   // Window creation failed, get out
                TRACE(_T("CWindowScroller::CWindowScroller - Window creation failed\n"));
            }
            else
            {
                SetLayeredWindowAttributes(RGB(255, 0, 0), 0, LWA_COLORKEY);

                // we give the parent window the focus to ensure it's caption bar shows the active colour
                // also not doing so causes an assertion in debug mode when a key is pressed on the keyboard
                m_pParentWnd->SetFocus();

                // ensure we get all mouse messages
                SetCapture();

                // set up the keyboard hook
                pGWindowScroller = this;
                m_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD,
                    WindowScrollerKeyBoardHookProc,
                    NULL,
                    AfxGetApp()->m_nThreadID);

                // set up the mouse hook
                m_hMouseHook = SetWindowsHookEx(WH_MOUSE,
                    WindowScrollerMouseHookProc,
                    NULL,
                    AfxGetApp()->m_nThreadID);

                // create all the necessary cursors and icon
                BuildCursors();

                // Set the scrolling speed
                m_ScrollRatio = Pixels;

                // Set the scrolling flag used with WM_VSCROLL/WM_HSCROLL
                m_ScrollFlag = bUseThumbPos ? SB_THUMBPOSITION : SB_THUMBTRACK;

                // Determine the parent window type
                m_ParentWndType = GetParentWndType();

                // Set the mouse cursor
                SetMyCursor();

                // Start the timer
                SetTimer(0x1FEB, Elapse, NULL);
            }
        }
    }
}

BEGIN_MESSAGE_MAP(CWindowScroller, CWnd)
    //{{AFX_MSG_MAP(CWindowScroller)
    ON_WM_CAPTURECHANGED()
    ON_WM_DESTROY()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MBUTTONDOWN()
    ON_WM_MBUTTONUP()
    ON_WM_MOUSEMOVE()
    ON_WM_PAINT()
    ON_WM_RBUTTONDOWN()
    ON_WM_RBUTTONUP()
    ON_WM_TIMER()
    //}}AFX_MSG_MAP
#ifdef WM_XBUTTONDOWN
    ON_MESSAGE(WM_XBUTTONDOWN, OnXButtonDown)
    ON_MESSAGE(WM_XBUTTONUP, OnXButtonUp)
#endif // WM_XBUTTONDOWN
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CWindowScroller message handlers

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::GetParentWndType  (protected member function)
//    Because different window types have different scrolling rules, this
//    function is used to determine the window type.
//
//  Parameters :
//    None
//
//  Returns :
//    The parent window type
//
/////////////////////////////////////////////////////////////////////////////

UINT CWindowScroller::GetParentWndType()
{
    TCHAR szClassName[256] = {0};
    ::GetClassName(*m_pParentWnd, szClassName, sizeof szClassName);
    
    if (0 == _tcscmp(szClassName, _T("SysTreeView32")))
        return Type_CTreeView;

    if (0 == _tcscmp(szClassName, _T("SysListView32")))
    {
        if ((m_pParentWnd->GetStyle() & 0x3) == LVS_REPORT)
            return Type_CListView_Report;
        
        if ((m_pParentWnd->GetStyle() & 0x3) == LVS_LIST)
            return Type_CListView_List;
        
        return Type_CListView_Icon;
    }

    if (m_pParentWnd->IsKindOf(RUNTIME_CLASS(CScrollView)))
        return Type_CScrollView;

    if (0 == _tcscmp(szClassName, _T("ListBox")))
        return Type_CListBox;

    // Add additional window identifier code here

    return Type_CWnd;
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::Initialize  (protected member function)
//    Initializes all the member variables to zero or NULL
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::Initialize()
{
    m_Alignment = 0;
    m_bWindowScrolled = FALSE;
    m_CenterPoint.x = m_CenterPoint.y = 0;
    m_DownCursor = NULL;
    m_DownLeftCursor = NULL;
    m_DownRightCursor = NULL;
    m_hIcon = NULL;
    m_hKeyboardHook = NULL;
    m_hMouseHook = NULL;
    m_HorzScroll = 0;
    m_hWnd = NULL;
    m_LeftCursor = NULL;
    m_NeutralCursor = NULL;
    m_ParentWndType = 0;
    m_pParentWnd = NULL;
    m_RightCursor = NULL;
    m_ScrollFlag = 0;
    m_ScrollRatio = 0;
    m_UpCursor = NULL;
    m_UpLeftCursor = NULL;
    m_UpRightCursor = NULL;
    m_VertScroll = 0;
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::OnCaptureChanged  (protected member function)
//    Handles the WM_CAPTURECHANGED message.
//    This function gets called when another app that is started via keyboard
//    shortcut keys (such as on the MS Internet keyboard) or via the
//    scheduled tasks manager grabs the mouse capture.
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::OnCaptureChanged(CWnd *) 
{
    DestroyWindow();
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::OnDestroy  (protected member function)
//    called by the MFC framework when the window is destroyed
//    cleans up all the system resources that were used
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::OnDestroy() 
{
    CWnd::OnDestroy();

    // inform parent window that scroller window is being destroyed
    m_pParentWnd->PostMessage(RWM_ONDESTROYWINDOWSCROLLER, 0, 0);

    UnhookWindowsHookEx(m_hKeyboardHook);
    UnhookWindowsHookEx(m_hMouseHook);
    pGWindowScroller = NULL;
    KillTimer(0x1FEB);

    DestroyIcon(m_hIcon);
    DestroyCursor(m_DownCursor);
    DestroyCursor(m_DownLeftCursor);
    DestroyCursor(m_DownRightCursor);
    DestroyCursor(m_LeftCursor);
    DestroyCursor(m_NeutralCursor);
    DestroyCursor(m_RightCursor);
    DestroyCursor(m_UpCursor);
    DestroyCursor(m_UpLeftCursor);
    DestroyCursor(m_UpRightCursor);
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::On?Button?  (protected member functions)
//    Call ReleaseCapture() if any mouse button is pressed or released
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
//  Note : calling ReleaseCapture() causes OnCaptureChanged() to be called.
//         OnCaptureChanged() calls DestroyWindow()
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::OnLButtonDown(UINT, CPoint) 
{
    ReleaseCapture();
}

void CWindowScroller::OnLButtonUp(UINT, CPoint) 
{
    if (m_bWindowScrolled)
        ReleaseCapture();
}

void CWindowScroller::OnMButtonDown(UINT, CPoint) 
{
    ReleaseCapture();
}

void CWindowScroller::OnMButtonUp(UINT, CPoint) 
{
    if (m_bWindowScrolled)
        ReleaseCapture();
}

void CWindowScroller::OnRButtonDown(UINT, CPoint) 
{
    ReleaseCapture();
}

void CWindowScroller::OnRButtonUp(UINT, CPoint) 
{
    if (m_bWindowScrolled)
        ReleaseCapture();
}

LRESULT CWindowScroller::OnXButtonDown(WPARAM, LPARAM)
{
    ReleaseCapture();
    return TRUE;
}

LRESULT CWindowScroller::OnXButtonUp(WPARAM, LPARAM)
{
    if (m_bWindowScrolled)
        ReleaseCapture();
    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::OnMouseMove  (protected member function)
//    handles the WM_MOUSEMOVE message
//    calls SetMyCursor() to set the mouse cursor and calculate the scrolling
//    direction and speed
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::OnMouseMove(UINT, CPoint) 
{
    SetMyCursor();
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::OnPaint  (protected member function)
//    handles the WM_PAINT message
//    paints the window
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::OnPaint() 
{
    CPaintDC dc(this); // device context for painting

    CRect rc;
    GetClientRect(&rc);
    dc.FillSolidRect(&rc, RGB(255, 0, 0));
    dc.DrawIcon(0, 0, m_hIcon);
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::OnTimer  (protected member function)
//    handles the WM_TIMER message
//    If the parent window is a ListView, it is sent a LVM_SCROLL message (thanks JMLF)
//    If the parent window is a CScrollView, the parent window is scrolled
//    If the parent window is any other window, the parent window is sent
//    a WM_HSCROLL and/or a WM_VSCROLL message with either a SB_THUMBPOSITION or
//    SB_THUMBTRACK flag depending on the value of m_ScrollFlag.
//
//  Parameters :
//    nIDEvent [in] - The ID of the timer that triggered this message
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::OnTimer(UINT_PTR nIDEvent) 
{
    CPoint pt;
    GetCursorPos(&pt);
    CRect rc;
    AfxGetMainWnd()->GetWindowRect(&rc);
    if (nIDEvent == 0x1FEB && rc.PtInRect(pt) && (m_HorzScroll || m_VertScroll))
    {
        m_bWindowScrolled = TRUE;
        CPoint OriginalPoint (m_pParentWnd->GetScrollPos(SB_HORZ), m_pParentWnd->GetScrollPos(SB_VERT));
        CPoint NewPoint = OriginalPoint;
        NewPoint.x += m_HorzScroll;
        NewPoint.y += m_VertScroll;

        int xMax = m_pParentWnd->GetScrollLimit(SB_HORZ);
        int yMax = m_pParentWnd->GetScrollLimit(SB_VERT);

        if (NewPoint.x < 0)
            NewPoint.x = 0;
        else if (NewPoint.x > xMax)
            NewPoint.x = xMax;

        if (NewPoint.y < 0)
            NewPoint.y = 0;
        else if (NewPoint.y > yMax)
            NewPoint.y = yMax;

        if (NewPoint != OriginalPoint)
        {
            switch (m_ParentWndType)
            {
            case Type_CListView_Report:
                {
                    CListView *pView = static_cast<CListView *>(m_pParentWnd);
                    CListCtrl& list = pView->GetListCtrl();

                    int item = list.GetTopIndex();
                    if (item && m_VertScroll < 0)
                        --item;

//                    CRect rc;
                    list.GetItemRect(item, rc, LVIR_BOUNDS);
                    int height = rc.Height();

                    static int cumulative = 0;
                    cumulative += NewPoint.y - OriginalPoint.y;
                    m_pParentWnd->SendMessage(LVM_SCROLL, NewPoint.x - OriginalPoint.x, cumulative);
                    if (abs(cumulative) >= (height + 1) / 2)
                        cumulative = 0;
                }
                break;

            case Type_CListView_List:
                {
                    CListView *pView = static_cast<CListView *>(m_pParentWnd);
                    CListCtrl& list = pView->GetListCtrl();

//                    CRect rc;
                    list.GetItemRect(0, rc, LVIR_BOUNDS);
                    int width = rc.Width();

                    static int cumulative = 0;
                    cumulative += NewPoint.x - OriginalPoint.x;
                    int columns = cumulative / width;
                    m_pParentWnd->SendMessage(LVM_SCROLL, columns, NewPoint.y - OriginalPoint.y);
                    if (columns)
                        cumulative = 0;
                }
                break;

            case Type_CListView_Icon:
                m_pParentWnd->SendMessage(LVM_SCROLL, NewPoint.x - OriginalPoint.x, NewPoint.y - OriginalPoint.y);
                break;

            case Type_CTreeView:
                if (NewPoint.x != OriginalPoint.x)
                {
                    m_pParentWnd->SetScrollPos(SB_HORZ, NewPoint.x);
                    m_pParentWnd->SendMessage(WM_HSCROLL, MAKEWPARAM (m_ScrollFlag, NewPoint.x), NULL);
                }

                if (NewPoint.y != OriginalPoint.y)
                {
                    CTreeView *pView = static_cast<CTreeView *>(m_pParentWnd);
                    CTreeCtrl& tree = pView->GetTreeCtrl();

                    int height = tree.GetItemHeight();
                    
                    static int cumulative = 0;
                    cumulative += NewPoint.y - OriginalPoint.y;
                    if (abs(cumulative) >= height)
                    {
                        m_pParentWnd->SetScrollPos(SB_VERT, NewPoint.y);
                        m_pParentWnd->SendMessage(WM_VSCROLL, MAKEWPARAM (m_ScrollFlag, NewPoint.y), NULL);
                        cumulative = 0;
                    }
                }
                break;

            case Type_CScrollView:
                m_pParentWnd->SetScrollPos(SB_HORZ, NewPoint.x);
                m_pParentWnd->SetScrollPos(SB_VERT, NewPoint.y);
                m_pParentWnd->ScrollWindow(OriginalPoint.x - NewPoint.x, OriginalPoint.y - NewPoint.y);
                break;

            case Type_CWnd:
                if (NewPoint.x != OriginalPoint.x)
                {
                    m_pParentWnd->SetScrollPos(SB_HORZ, NewPoint.x);
                    m_pParentWnd->SendMessage(WM_HSCROLL, MAKEWPARAM (m_ScrollFlag, NewPoint.x), NULL);
                }
                
                if (NewPoint.y != OriginalPoint.y)
                {
                    m_pParentWnd->SetScrollPos(SB_VERT, NewPoint.y);
                    m_pParentWnd->SendMessage(WM_VSCROLL, MAKEWPARAM (m_ScrollFlag, NewPoint.y), NULL);
                }
                break;

            case Type_CListBox:
                if (NewPoint.x != OriginalPoint.x)
                {
                    m_pParentWnd->SetScrollPos(SB_HORZ, NewPoint.x);
                    m_pParentWnd->SendMessage(WM_HSCROLL, MAKEWPARAM(m_ScrollFlag, NewPoint.x), NULL);
                }

                if (NewPoint.y != OriginalPoint.y)
                {
                    CListBox *pBox = static_cast<CListBox *>(m_pParentWnd);

                    int item = pBox->GetTopIndex();
                    if (item && m_VertScroll < 0)
                        --item;

                    int height = pBox->GetItemHeight(item);

                    static int cumulative = 0;
                    cumulative += NewPoint.y - OriginalPoint.y;
                    if (abs(cumulative) >= height)
                    {
                        m_pParentWnd->SetScrollPos(SB_VERT, NewPoint.y);
                        m_pParentWnd->SendMessage(WM_VSCROLL, MAKEWPARAM(m_ScrollFlag, NewPoint.y), NULL);
                        cumulative = 0;
                    }
                }
                break;

            // Add additional cases here

            default:
                TRACE (_T("CWindowScroller::OnTimer - Unknown window type"));
                break;
            } // switch (m_ParentWndType)
        } // if (NewPoint != OriginalPoint)
    } // if (nIDEvent == 0x1FEB && rc.PtInRect(pt) && (m_HorzScroll || m_VertScroll))
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::PostNcDestroy  (protected member function)
//    called by the MFC framework after the window has been destroyed
//    deletes this instance of the CWindowScroller class
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::PostNcDestroy() 
{
    delete this;
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::SetMyCursor  (protected member function)
//    Sets the mouse cursor and calculates the scrolling distance
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

void CWindowScroller::SetMyCursor()
{
    m_HorzScroll = 0;
    m_VertScroll = 0;
    CPoint pt;
    GetCursorPos(&pt);
    int ydiff = pt.y - m_CenterPoint.y;
    int xdiff = pt.x - m_CenterPoint.x;

    switch (m_Alignment)
    {
    case Vertical:
        {
            if (abs(xdiff) > 16)
                m_bWindowScrolled = TRUE;
            if (abs(ydiff) < 17)
                SetCursor(m_NeutralCursor);
            else
            {
                if (ydiff > 0)
                    SetCursor(m_DownCursor);
                else
                    SetCursor(m_UpCursor);
                m_VertScroll = ydiff / m_ScrollRatio;
                if (!m_VertScroll)
                    m_VertScroll = ydiff > 0 ? 1 : -1;
            }
        }
        break;

    case Horizontal:
        {
            if (abs(ydiff) > 16)
                m_bWindowScrolled = TRUE;
            if (abs(xdiff) < 17)
                SetCursor(m_NeutralCursor);
            else
            {
                if (xdiff > 0)
                    SetCursor(m_RightCursor);
                else
                    SetCursor(m_LeftCursor);
                m_HorzScroll = xdiff / m_ScrollRatio;
                if (!m_HorzScroll)
                    m_HorzScroll = xdiff > 0 ? 1 : -1;
            }
        }
        break;

    case Both:
        {
            if (abs(ydiff) < 17 && abs(xdiff) < 17)
                SetCursor(m_NeutralCursor);
            else
            {
                if (abs(ydiff) < 17)
                {
                    if (xdiff > 0)
                        SetCursor(m_RightCursor);
                    else
                        SetCursor(m_LeftCursor);
                    m_HorzScroll = xdiff / m_ScrollRatio;
                    if (!m_HorzScroll)
                        m_HorzScroll = xdiff > 0 ? 1 : -1;
                }
                else if (abs(xdiff) < 17)
                {
                    if (ydiff > 0)
                        SetCursor(m_DownCursor);
                    else
                        SetCursor(m_UpCursor);
                    m_VertScroll = ydiff / m_ScrollRatio;
                    if (!m_VertScroll)
                        m_VertScroll = ydiff > 0 ? 1 : -1;
                }
                else
                {
                    if (xdiff > 0)
                    {
                        if (ydiff > 0)
                            SetCursor(m_DownRightCursor);
                        else
                            SetCursor(m_UpRightCursor);
                    }
                    else
                    {
                        if (ydiff > 0)
                            SetCursor(m_DownLeftCursor);
                        else
                            SetCursor(m_UpLeftCursor);
                    }
                    m_HorzScroll = xdiff / m_ScrollRatio;
                    if (!m_HorzScroll)
                        m_HorzScroll = xdiff > 0 ? 1 : -1;
                    m_VertScroll = ydiff / m_ScrollRatio;
                    if (!m_VertScroll)
                        m_VertScroll = ydiff > 0 ? 1 : -1;
                }
            }
        }
        break;

    default:
        ASSERT (FALSE);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::BuildCursors  (protected member function)
//    creates the icon and cursors that are needed
//
//  Parameters :
//    None
//
//  Returns :
//    Nothing
//
/////////////////////////////////////////////////////////////////////////////

#pragma warning (push)
#pragma warning (disable : 4706) // assignment within conditional expression

void CWindowScroller::BuildCursors()
{
    LPBYTE pData = NULL;
    HINSTANCE hInst = AfxGetInstanceHandle();

    // Icon data converted to text using bin2text http://www.codeproject.com/Tips/845393/Convert-a-Binary-File-to-a-Hex-Encoded-Text-File
    // use -s 22 to skip first 22 byte headers in the icon file
    BYTE BothIconData[] = { 0x28, 0x00, 0x00, 0x00,   0x20, 0x00, 0x00, 0x00,   0x40, 0x00, 0x00, 0x00,   0x01, 0x00, 0x04, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0xFF, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0xFF, 0xFF, 0xFF, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x01, 0x11, 0x11,
                            0x11, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x11, 0x12, 0x22, 0x22,
                            0x22, 0x11, 0x10, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x11,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x21, 0x10,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x01, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x21,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x12, 0x22,   0x22, 0x22, 0x22, 0x12,
                            0x22, 0x22, 0x22, 0x22,   0x10, 0x00, 0x00, 0x00,   0x00, 0x01, 0x22, 0x22,   0x22, 0x22, 0x21, 0x11,
                            0x22, 0x22, 0x22, 0x22,   0x21, 0x00, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x11, 0x11,
                            0x12, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x21, 0x11, 0x11,
                            0x11, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x11, 0x11, 0x11,
                            0x11, 0x12, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x12, 0x22,   0x22, 0x21, 0x00, 0x00,   0x12, 0x22, 0x22, 0x21,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x12,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x21, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x11,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x11, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x11,   0x12, 0x22, 0x10, 0x00,   0x12, 0x22, 0x21, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x11,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x12,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x21,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x22,   0x22, 0x22, 0x10, 0x00,   0x01, 0x22, 0x22, 0x22,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x12, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x11, 0x11, 0x11,
                            0x11, 0x12, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x21, 0x11, 0x11,
                            0x11, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x11, 0x11,
                            0x12, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x01, 0x22, 0x22,   0x22, 0x22, 0x21, 0x11,
                            0x22, 0x22, 0x22, 0x22,   0x21, 0x00, 0x00, 0x00,   0x00, 0x00, 0x12, 0x22,   0x22, 0x22, 0x22, 0x12,
                            0x22, 0x22, 0x22, 0x22,   0x10, 0x00, 0x00, 0x00,   0x00, 0x00, 0x01, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x21,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x11,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x21, 0x10,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x11, 0x12, 0x22, 0x22,
                            0x22, 0x11, 0x10, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x01, 0x11, 0x11,
                            0x11, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00};

    BYTE UpDnIconData[] = { 0x28, 0x00, 0x00, 0x00,   0x20, 0x00, 0x00, 0x00,   0x40, 0x00, 0x00, 0x00,   0x01, 0x00, 0x04, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0xFF, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0xFF, 0xFF, 0xFF, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x01, 0x11, 0x11,
                            0x11, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x11, 0x12, 0x22, 0x22,
                            0x22, 0x11, 0x10, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x11,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x21, 0x10,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x01, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x21,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x12, 0x22,   0x22, 0x22, 0x22, 0x12,
                            0x22, 0x22, 0x22, 0x22,   0x10, 0x00, 0x00, 0x00,   0x00, 0x01, 0x22, 0x22,   0x22, 0x22, 0x21, 0x11,
                            0x22, 0x22, 0x22, 0x22,   0x21, 0x00, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x11, 0x11,
                            0x12, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x21, 0x11, 0x11,
                            0x11, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x11, 0x11, 0x11,
                            0x11, 0x12, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x12, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x22, 0x10, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x11, 0x11, 0x11,
                            0x11, 0x12, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x21, 0x11, 0x11,
                            0x11, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x11, 0x11,
                            0x12, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x01, 0x22, 0x22,   0x22, 0x22, 0x21, 0x11,
                            0x22, 0x22, 0x22, 0x22,   0x21, 0x00, 0x00, 0x00,   0x00, 0x00, 0x12, 0x22,   0x22, 0x22, 0x22, 0x12,
                            0x22, 0x22, 0x22, 0x22,   0x10, 0x00, 0x00, 0x00,   0x00, 0x00, 0x01, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x21,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x11,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x21, 0x10,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x11, 0x12, 0x22, 0x22,
                            0x22, 0x11, 0x10, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x01, 0x11, 0x11,
                            0x11, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00};

    BYTE LtRtIconData[] = { 0x28, 0x00, 0x00, 0x00,   0x20, 0x00, 0x00, 0x00,   0x40, 0x00, 0x00, 0x00,   0x01, 0x00, 0x04, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0xFF, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0xFF, 0xFF, 0xFF, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x01, 0x11, 0x11,
                            0x11, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x11, 0x12, 0x22, 0x22,
                            0x22, 0x11, 0x10, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x11,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x21, 0x10,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x01, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x21,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x12, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x10, 0x00, 0x00, 0x00,   0x00, 0x01, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x21, 0x00, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x12, 0x22,   0x22, 0x21, 0x00, 0x00,   0x12, 0x22, 0x22, 0x21,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x22,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x12,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x21, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x11,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x11, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x11,   0x12, 0x22, 0x10, 0x00,   0x12, 0x22, 0x21, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x11,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x11,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x12,   0x22, 0x22, 0x10, 0x00,   0x12, 0x22, 0x22, 0x21,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x11, 0x22,   0x22, 0x22, 0x10, 0x00,   0x01, 0x22, 0x22, 0x22,   0x12, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x12, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x01, 0x22, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x21, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x12, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x22, 0x10, 0x00, 0x00,   0x00, 0x01, 0x22, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x21, 0x00, 0x00, 0x00,   0x00, 0x00, 0x12, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x22,   0x10, 0x00, 0x00, 0x00,   0x00, 0x00, 0x01, 0x22,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x22, 0x21,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x11,   0x22, 0x22, 0x22, 0x22,
                            0x22, 0x22, 0x21, 0x10,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x11, 0x12, 0x22, 0x22,
                            0x22, 0x11, 0x10, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x01, 0x11, 0x11,
                            0x11, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00};

    pData = m_Alignment == Vertical ? UpDnIconData : m_Alignment == Horizontal ? LtRtIconData : BothIconData;
    VERIFY (m_hIcon = CreateIconFromResourceEx(pData, 744, TRUE, 0x00030000, 0, 0, 0));

    BYTE BothCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                             0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x10,
                             0x10, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x40, 0x04, 0x00,
                             0x00, 0xBF, 0xFA, 0x00, 0x01, 0x40, 0x05, 0x00, 0x02, 0x40,
                             0x04, 0x80, 0x04, 0x41, 0x04, 0x40, 0x08, 0x42, 0x84, 0x20,
                             0x10, 0x44, 0x44, 0x10, 0x20, 0x48, 0x24, 0x08, 0x10, 0x44,
                             0x44, 0x10, 0x08, 0x42, 0x84, 0x20, 0x04, 0x41, 0x04, 0x40,
                             0x02, 0x40, 0x04, 0x80, 0x01, 0x40, 0x05, 0x00, 0x00, 0xBF,
                             0xFA, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00,
                             0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x04,
                             0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                             0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xE0,
                             0x0F, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0x80, 0x03, 0xFF,
                             0xFF, 0x40, 0x05, 0xFF, 0xFE, 0x3F, 0xF8, 0xFF, 0xFC, 0x3F,
                             0xF8, 0x7F, 0xF8, 0x3E, 0xF8, 0x3F, 0xF0, 0x3C, 0x78, 0x1F,
                             0xE0, 0x38, 0x38, 0x0F, 0xC0, 0x30, 0x18, 0x07, 0xE0, 0x38,
                             0x38, 0x0F, 0xF0, 0x3C, 0x78, 0x1F, 0xF8, 0x3E, 0xF8, 0x3F,
                             0xFC, 0x3F, 0xF8, 0x7F, 0xFE, 0x3F, 0xF8, 0xFF, 0xFF, 0x40,
                             0x05, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xC0, 0x07, 0xFF,
                             0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8,
                             0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    BYTE UpDnCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                             0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x10,
                             0x10, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x40, 0x04, 0x00,
                             0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                             0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x04,
                             0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
                             0xF8, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00,
                             0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x04,
                             0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                             0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xE0,
                             0x0F, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0x80, 0x03, 0xFF,
                             0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                             0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8,
                             0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
                             0x07, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xC0, 0x07, 0xFF,
                             0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8,
                             0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    BYTE LtRtCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x80, 0x02, 0x00, 0x01, 0x40, 0x05, 0x00, 0x02, 0x40,
                             0x04, 0x80, 0x04, 0x41, 0x04, 0x40, 0x08, 0x42, 0x84, 0x20,
                             0x10, 0x44, 0x44, 0x10, 0x20, 0x48, 0x24, 0x08, 0x10, 0x44,
                             0x44, 0x10, 0x08, 0x42, 0x84, 0x20, 0x04, 0x41, 0x04, 0x40,
                             0x02, 0x40, 0x04, 0x80, 0x01, 0x40, 0x05, 0x00, 0x00, 0x80,
                             0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0x7F, 0xFD, 0xFF, 0xFE, 0x3F, 0xF8, 0xFF, 0xFC, 0x3F,
                             0xF8, 0x7F, 0xF8, 0x3E, 0xF8, 0x3F, 0xF0, 0x3C, 0x78, 0x1F,
                             0xE0, 0x38, 0x38, 0x0F, 0xC0, 0x30, 0x18, 0x07, 0xE0, 0x38,
                             0x38, 0x0F, 0xF0, 0x3C, 0x78, 0x1F, 0xF8, 0x3E, 0xF8, 0x3F,
                             0xFC, 0x3F, 0xF8, 0x7F, 0xFE, 0x3F, 0xF8, 0xFF, 0xFF, 0x7F,
                             0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    pData = m_Alignment == Vertical ? UpDnCursorData : m_Alignment == Horizontal ? LtRtCursorData : BothCursorData;
    VERIFY (m_NeutralCursor = CreateCursor (hInst, 15, 15, 32, 32, pData + 128, pData));

    if (m_Alignment & Vertical)
    {
        BYTE UpCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                               0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x10,
                               0x10, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x40, 0x04, 0x00,
                               0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                               0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x04,
                               0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                               0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xE0,
                               0x0F, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0x80, 0x03, 0xFF,
                               0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                               0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8,
                               0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_UpCursor = CreateCursor(hInst, 15, 15, 32, 32, UpCursorData + 128, UpCursorData));

        BYTE DnCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                               0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x04,
                               0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
                               0xF8, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00,
                               0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x04,
                               0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                               0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8,
                               0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
                               0x07, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xC0, 0x07, 0xFF,
                               0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8,
                               0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_DownCursor = CreateCursor(hInst, 15, 15, 32, 32, DnCursorData + 128, DnCursorData));
    }

    if (m_Alignment & Horizontal)
    {
        BYTE LtCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x80, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x02, 0x40,
                               0x00, 0x00, 0x04, 0x41, 0x00, 0x00, 0x08, 0x42, 0x80, 0x00,
                               0x10, 0x44, 0x40, 0x00, 0x20, 0x48, 0x20, 0x00, 0x10, 0x44,
                               0x40, 0x00, 0x08, 0x42, 0x80, 0x00, 0x04, 0x41, 0x00, 0x00,
                               0x02, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0x7F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F,
                               0xFF, 0xFF, 0xF8, 0x3E, 0xFF, 0xFF, 0xF0, 0x3C, 0x7F, 0xFF,
                               0xE0, 0x38, 0x3F, 0xFF, 0xC0, 0x30, 0x1F, 0xFF, 0xE0, 0x38,
                               0x3F, 0xFF, 0xF0, 0x3C, 0x7F, 0xFF, 0xF8, 0x3E, 0xFF, 0xFF,
                               0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0x7F,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_LeftCursor = CreateCursor(hInst, 15, 15, 32, 32, LtCursorData + 128, LtCursorData));

        BYTE RtCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
                               0x04, 0x80, 0x00, 0x01, 0x04, 0x40, 0x00, 0x02, 0x84, 0x20,
                               0x00, 0x04, 0x44, 0x10, 0x00, 0x08, 0x24, 0x08, 0x00, 0x04,
                               0x44, 0x10, 0x00, 0x02, 0x84, 0x20, 0x00, 0x01, 0x04, 0x40,
                               0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
                               0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF,
                               0xF8, 0x7F, 0xFF, 0xFE, 0xF8, 0x3F, 0xFF, 0xFC, 0x78, 0x1F,
                               0xFF, 0xF8, 0x38, 0x0F, 0xFF, 0xF0, 0x18, 0x07, 0xFF, 0xF8,
                               0x38, 0x0F, 0xFF, 0xFC, 0x78, 0x1F, 0xFF, 0xFE, 0xF8, 0x3F,
                               0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF,
                               0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_RightCursor = CreateCursor(hInst, 15, 15, 32, 32, RtCursorData + 128, RtCursorData));
    }

    if (m_Alignment == Both)
    {
        BYTE UpLtCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE,
                                 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
                                 0x02, 0x04, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x02, 0x10,
                                 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x02, 0x42, 0x80, 0x00,
                                 0x02, 0x84, 0x40, 0x00, 0x01, 0x08, 0x20, 0x00, 0x00, 0x04,
                                 0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01,
                                 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF,
                                 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xFC, 0x0F,
                                 0xFF, 0xFF, 0xFC, 0x1E, 0xFF, 0xFF, 0xFC, 0x3C, 0x7F, 0xFF,
                                 0xFC, 0x78, 0x3F, 0xFF, 0xFE, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8,
                                 0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_UpLeftCursor = CreateCursor(hInst, 15, 15, 32, 32, UpLtCursorData + 128, UpLtCursorData));

        BYTE UpRtCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0xFF, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80,
                                 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x20, 0x80, 0x00, 0x00,
                                 0x10, 0x80, 0x00, 0x01, 0x08, 0x80, 0x00, 0x02, 0x84, 0x80,
                                 0x00, 0x04, 0x42, 0x80, 0x00, 0x08, 0x21, 0x00, 0x00, 0x04,
                                 0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x7F,
                                 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF,
                                 0xE0, 0x7F, 0xFF, 0xFE, 0xF0, 0x7F, 0xFF, 0xFC, 0x78, 0x7F,
                                 0xFF, 0xF8, 0x3C, 0x7F, 0xFF, 0xF0, 0x1E, 0xFF, 0xFF, 0xF8,
                                 0x3F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_UpRightCursor = CreateCursor(hInst, 15, 15, 32, 32, UpRtCursorData + 128, UpRtCursorData));

        BYTE DnRtCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                                 0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x21, 0x00, 0x00, 0x04,
                                 0x42, 0x80, 0x00, 0x02, 0x84, 0x80, 0x00, 0x01, 0x08, 0x80,
                                 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x20, 0x80, 0x00, 0x00,
                                 0x40, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x01, 0x00, 0x80,
                                 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                                 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x1E, 0xFF, 0xFF, 0xF8,
                                 0x3C, 0x7F, 0xFF, 0xFC, 0x78, 0x7F, 0xFF, 0xFE, 0xF0, 0x7F,
                                 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF,
                                 0x80, 0x7F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x7F,
                                 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_DownRightCursor = CreateCursor(hInst, 15, 15, 32, 32, DnRtCursorData + 128, DnRtCursorData));

        BYTE DnLtCursorData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00,
                                 0x00, 0x04, 0x40, 0x00, 0x01, 0x08, 0x20, 0x00, 0x02, 0x84,
                                 0x40, 0x00, 0x02, 0x42, 0x80, 0x00, 0x02, 0x21, 0x00, 0x00,
                                 0x02, 0x10, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x02, 0x04,
                                 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
                                 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF,
                                 0xFF, 0xF8, 0x3F, 0xFF, 0xFE, 0xF0, 0x1F, 0xFF, 0xFC, 0x78,
                                 0x3F, 0xFF, 0xFC, 0x3C, 0x7F, 0xFF, 0xFC, 0x1E, 0xFF, 0xFF,
                                 0xFC, 0x0F, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xFC, 0x03,
                                 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF,
                                 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

        VERIFY (m_DownLeftCursor = CreateCursor(hInst, 15, 15, 32, 32, DnLtCursorData + 128, DnLtCursorData));
    }
}

#pragma warning (pop)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
President
Canada Canada
Father of two, brother of two, child of two.
Spouse to one, uncle to many, friend to lots.
Farmer, carpenter, mechanic, electrician, but definitely not a plumber.
Likes walks with the wife, board games, card games, travel, and camping in the summer.
High school graduate, college drop-out.
Hobby programmer who knows C++ with MFC and the STL.
Has dabbled with BASIC, Pascal, Fortran, COBOL, C#, SQL, ASM, and HTML.
Realized long ago that programming is fun when there is nobody pressuring you with schedules and timelines.

Comments and Discussions