/****************************************************************************
WindowScroller.cpp : implementation file
Written by : PJ Arends
pja@telus.net

Copyright © 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 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
author's name are included. Any modifications not made by the original author should
be clearly marked as such to remove any confusion between the original version and
any other versions.

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
April 30, 2006     -        moved code into the pja namespace
                   -        improved drawing code

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

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

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

// Static member pointer used by the hook procedures
pja::CWindowScroller* pja::CWindowScroller::pWindowScroller = NULL;

namespace pja
{
    // 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,
        // Add more types here
        Type_CListBox
    };

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

    // Mouse hook used to kill scroller if mouse wheel is rotated
    LRESULT CALLBACK WindowScrollerMouseHookProc(int code, WPARAM wp, LPARAM lp)
    {
        ASSERT_VALID(CWindowScroller::pWindowScroller);
        LRESULT ret = CallNextHookEx(CWindowScroller::pWindowScroller->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
//
/////////////////////////////////////////////////////////////////////////////

pja::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
    {
        // center the window on the given point
        m_pParentWnd->ClientToScreen(&Point);
        m_CenterPoint = Point;

        // create the window
        if (CreateEx(NULL,
                     AfxRegisterWndClass(0, NULL, (HBRUSH)GetStockObject(WHITE_BRUSH), NULL),
                     NULL,
                     WS_POPUP | WS_VISIBLE,
                     m_CenterPoint.x - 15,
                     m_CenterPoint.y - 15,
                     32,
                     32,
                     *m_pParentWnd,
                     NULL,
                     NULL))
        {
            // 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
            pWindowScroller = this;
            m_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, 
                                               pja::WindowScrollerKeyBoardHookProc,
                                               NULL,
                                               AfxGetApp()->m_nThreadID);

            // set up the mouse hook
            m_hMouseHook = SetWindowsHookEx(WH_MOUSE, 
                                            pja::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);
        }
        else // Window creation failed, get out
        {
            TRACE (_T("CWindowScroller::CWindowScroller - Window creation failed\n"));
        }
    }
}

BEGIN_MESSAGE_MAP(pja::CWindowScroller, CWnd)
    //{{AFX_MSG_MAP(CWindowScroller)
    ON_WM_CAPTURECHANGED()
    ON_WM_CREATE()
    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 pja::CWindowScroller::GetParentWndType() const
{
    TCHAR szClassName[256] = {0};
    ::GetClassName(*m_pParentWnd, szClassName, _countof(szClassName));
    
    if (!_tcscmp(szClassName, WC_TREEVIEW))
        return Type_CTreeView;

    if (!_tcscmp(szClassName, WC_LISTVIEW))
    {
        if ((m_pParentWnd->GetStyle() & LVS_TYPEMASK) == LVS_REPORT)
            return Type_CListView_Report;
        
        if ((m_pParentWnd->GetStyle() & LVS_TYPEMASK) == LVS_LIST)
            return Type_CListView_List;
        
        return Type_CListView_Icon;
    }

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

    // Add additional window identifier code here
    if (!_tcsicmp(szClassName, _T("ListBox")))
        return Type_CListBox;

    return Type_CWnd;
}

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

void pja::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 pja::CWindowScroller::OnCaptureChanged(CWnd *) 
{
    DestroyWindow();
}

/////////////////////////////////////////////////////////////////////////////
//
//  CWindowScroller::OnCreate  (protected member function)
//    called by the MFC framework when the window is created
//    sets the window region to an elliptical region
//
//  Parameters :
//    lpCreateStruct - not used here, passed on to base class
//
//  Returns :
//    zero if window creation is to continue
//    minus one if the window creation fails and the window is to be destroyed
//
/////////////////////////////////////////////////////////////////////////////

int pja::CWindowScroller::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
/*    return CWnd::OnCreate(lpCreateStruct);
*/
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    if (m_WndRgn.CreateEllipticRgn(0, 0, 32, 32) &&
        SetWindowRgn(m_WndRgn, FALSE))
        return 0;

    return -1;

}

/////////////////////////////////////////////////////////////////////////////
//
//  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 pja::CWindowScroller::OnDestroy() 
{
    CWnd::OnDestroy();

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

    UnhookWindowsHookEx(m_hKeyboardHook);
    UnhookWindowsHookEx(m_hMouseHook);
    pWindowScroller = 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 pja::CWindowScroller::OnLButtonDown(UINT, CPoint) 
{
    ReleaseCapture();
}

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

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

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

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

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

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

LRESULT pja::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 pja::CWindowScroller::OnMouseMove(UINT, CPoint) 
{
    SetMyCursor();
}

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

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

//    CBrush brush(GetSysColor(COLOR_WINDOW));
//    CBrush *pOld = (CBrush *)dc.SelectObject(&brush);
//    dc.Ellipse(1, 1, 34, 34);
    dc.DrawIcon(0, 0, m_hIcon);
//    dc.SelectObject(pOld);
}

/////////////////////////////////////////////////////////////////////////////
//
//  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 pja::CWindowScroller::OnTimer(UINT nIDEvent) 
{
    CPoint pt;
    GetCursorPos(&pt);
    CRect WindowRect;

    AfxGetMainWnd()->GetWindowRect(&WindowRect);

    if (nIDEvent == 0x1FEB && WindowRect.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;

            // Add additional cases here
            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;

            default:
                TRACE (_T("CWindowScroller::OnTimer - Unknown window type\n"));
                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 pja::CWindowScroller::PostNcDestroy() 
{
    delete this;
}

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

void pja::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 pja::CWindowScroller::BuildCursors()
{
    LPBYTE pData = NULL;
    HINSTANCE hInst = AfxGetInstanceHandle();

    BYTE BothIconData[] = {0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 
                           0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 
                           0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 
                           0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0xC0, 0xC0, 
                           0xC0, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 
                           0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 
                           0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 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, 0x08, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 
                           0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
                           0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x08, 0x88, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x88, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 
                           0x00, 0x88, 0x80, 0x00, 0x08, 0x88, 0x80, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x08, 0x88, 0x88, 0x00, 0x08, 0x88, 0x88, 0x00, 
                           0x08, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 
                           0x88, 0x00, 0x00, 0x88, 0x80, 0x00, 0x08, 0x88, 0x80, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x08, 
                           0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x08, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 
                           0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0x88, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 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, 0xF8, 0x3F, 0xFF, 0xFF, 0x87, 0xC3, 0xFF, 0xFF, 0x7F, 
                           0xFD, 0xFF, 0xFC, 0xFF, 0xFE, 0x7F, 0xFB, 0xFF, 0xFF, 0xBF, 
                           0xF7, 0xFE, 0xFF, 0xDF, 0xEF, 0xFC, 0x7F, 0xEF, 0xEF, 0xF8, 
                           0x3F, 0xEF, 0xDF, 0xF0, 0x1F, 0xF7, 0xBF, 0xE0, 0x0F, 0xFB, 
                           0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xBF, 0xFB, 0xFB, 0xBF, 0x3F, 
                           0xF9, 0xFB, 0x7E, 0x3E, 0xF8, 0xFD, 0x7C, 0x3C, 0x78, 0x7D, 
                           0x78, 0x38, 0x38, 0x3D, 0x7C, 0x3C, 0x78, 0x7D, 0x7E, 0x3E, 
                           0xF8, 0xFD, 0xBF, 0x3F, 0xF9, 0xFB, 0xBF, 0xBF, 0xFB, 0xFB, 
                           0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xE0, 0x0F, 0xFB, 0xDF, 0xF0, 
                           0x1F, 0xF7, 0xEF, 0xF8, 0x3F, 0xEF, 0xEF, 0xFC, 0x7F, 0xEF, 
                           0xF7, 0xFE, 0xFF, 0xDF, 0xFB, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 
                           0xFE, 0x7F, 0xFF, 0x7F, 0xFD, 0xFF, 0xFF, 0x87, 0xC3, 0xFF, 
                           0xFF, 0xF8, 0x3F, 0xFF};

    BYTE UpDnIconData[] = {0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 
                           0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 
                           0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 
                           0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0xC0, 0xC0, 
                           0xC0, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 
                           0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 
                           0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 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, 0x08, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 
                           0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
                           0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0x88, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x08, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 
                           0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0x88, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 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, 0xF8, 0x3F, 0xFF, 0xFF, 0x87, 0xC3, 0xFF, 0xFF, 0x7F, 
                           0xFD, 0xFF, 0xFC, 0xFF, 0xFE, 0x7F, 0xFB, 0xFF, 0xFF, 0xBF, 
                           0xF7, 0xFE, 0xFF, 0xDF, 0xEF, 0xFC, 0x7F, 0xEF, 0xEF, 0xF8, 
                           0x3F, 0xEF, 0xDF, 0xF0, 0x1F, 0xF7, 0xBF, 0xE0, 0x0F, 0xFB, 
                           0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xFF, 
                           0xFF, 0xFB, 0x7F, 0xFE, 0xFF, 0xFD, 0x7F, 0xFC, 0x7F, 0xFD, 
                           0x7F, 0xF8, 0x3F, 0xFD, 0x7F, 0xFC, 0x7F, 0xFD, 0x7F, 0xFE, 
                           0xFF, 0xFD, 0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xFF, 0xFF, 0xFB, 
                           0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xE0, 0x0F, 0xFB, 0xDF, 0xF0, 
                           0x1F, 0xF7, 0xEF, 0xF8, 0x3F, 0xEF, 0xEF, 0xFC, 0x7F, 0xEF, 
                           0xF7, 0xFE, 0xFF, 0xDF, 0xFB, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 
                           0xFE, 0x7F, 0xFF, 0x7F, 0xFD, 0xFF, 0xFF, 0x87, 0xC3, 0xFF, 
                           0xFF, 0xF8, 0x3F, 0xFF};

    BYTE LtRtIconData[] = {0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 
                           0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 
                           0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 
                           0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0xC0, 0xC0, 
                           0xC0, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 
                           0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 
                           0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 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, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x08, 0x88, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x88, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 
                           0x00, 0x88, 0x80, 0x00, 0x08, 0x88, 0x80, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x08, 0x88, 0x88, 0x00, 0x08, 0x88, 0x88, 0x00, 
                           0x08, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 
                           0x88, 0x00, 0x00, 0x88, 0x80, 0x00, 0x08, 0x88, 0x80, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x08, 
                           0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                           0x00, 0x00, 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, 0xF8, 0x3F, 0xFF, 0xFF, 0x87, 0xC3, 0xFF, 0xFF, 0x7F, 
                           0xFD, 0xFF, 0xFC, 0xFF, 0xFE, 0x7F, 0xFB, 0xFF, 0xFF, 0xBF, 
                           0xF7, 0xFF, 0xFF, 0xDF, 0xEF, 0xFF, 0xFF, 0xEF, 0xEF, 0xFF, 
                           0xFF, 0xEF, 0xDF, 0xFF, 0xFF, 0xF7, 0xBF, 0xFF, 0xFF, 0xFB, 
                           0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xBF, 0xFB, 0xFB, 0xBF, 0x3F, 
                           0xF9, 0xFB, 0x7E, 0x3E, 0xF8, 0xFD, 0x7C, 0x3C, 0x78, 0x7D, 
                           0x78, 0x38, 0x38, 0x3D, 0x7C, 0x3C, 0x78, 0x7D, 0x7E, 0x3E, 
                           0xF8, 0xFD, 0xBF, 0x3F, 0xF9, 0xFB, 0xBF, 0xBF, 0xFB, 0xFB, 
                           0xBF, 0xFF, 0xFF, 0xFB, 0xBF, 0xFF, 0xFF, 0xFB, 0xDF, 0xFF, 
                           0xFF, 0xF7, 0xEF, 0xFF, 0xFF, 0xEF, 0xEF, 0xFF, 0xFF, 0xEF, 
                           0xF7, 0xFF, 0xFF, 0xDF, 0xFB, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 
                           0xFE, 0x7F, 0xFF, 0x7F, 0xFD, 0xFF, 0xFF, 0x87, 0xC3, 0xFF, 
                           0xFF, 0xF8, 0x3F, 0xFF};

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

    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)
