NT4/private/utils/fdisk/arrowin.c
2020-09-30 17:12:29 +02:00

345 lines
12 KiB
C

/** FILE: arrowin.c ******** Module Header ********************************
*
* Control panel arrow window class routines. This file contains the
* window procedure and utility functions for managing the "cpArrow"
* window class/spinner control for use by Control Panel applet dialogs.
*
* History:
* 15:30 on Thur 25 Apr 1991 -by- Steve Cathcart [stevecat]
* Took base code from Win 3.1 source
*
* Copyright (C) 1990-1991 Microsoft Corporation
*
*************************************************************************/
//==========================================================================
// Include files
//==========================================================================
// C Runtime
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
// Windows SDK
/* cut out unnec stuff from windows.h */
#define NOCLIPBOARD
#define NOMETAFILE
#define NOREGION
#define NOSYSCOMMANDS
#define NOATOM
#define NOGDICAPMASKS
#include <windows.h>
//==========================================================================
// Local Definitions
//==========================================================================
#define SHIFT_TO_DOUBLE 1
#define DOUBLECLICK 0
#define PRESSINVERT 1
#define POINTSPERARROW 3
#define ARROWXAXIS 15
#define ARROWYAXIS 15
//==========================================================================
// External Declarations
//==========================================================================
extern HANDLE hModule;
//==========================================================================
// Local Data Declarations
//==========================================================================
#if 0
POINT Arrow[11] = { 16, 1, 2, 14, 12, 14, 12, 20, 2, 20, 16, 33,
29, 20, 20, 20, 20, 14, 29, 14/*, 16,1*/};
#endif
#if 0
POINT ArrowUp[7] = {5, 2, 8, 5, 6, 5, 6, 7, 4, 7, 4, 5, 2, 5};
POINT ArrowDown[7] = { 4, 10, 6, 10, 6, 12, 8, 12, 5, 15, 2, 12, 4, 12};
#endif
POINT ArrowUp[POINTSPERARROW] = {7, 1, 3, 5, 11, 5};
POINT ArrowDown[POINTSPERARROW] = {7, 13, 3, 9, 11, 9};
BOOL bRight;
RECT rUp, rDown;
LPRECT lpUpDown;
FARPROC lpArrowProc;
HANDLE hParent;
//==========================================================================
// Local Function Prototypes
//==========================================================================
//==========================================================================
// Functions
//==========================================================================
WORD UpOrDown()
{
LONG l;
WORD retval;
POINT pt;
l = GetMessagePos();
pt.y = (int) HIWORD(l);
pt.x = (int) LOWORD(l);
if (PtInRect((LPRECT) &rUp, pt))
retval = SB_LINEUP;
else if (PtInRect((LPRECT) &rDown, pt))
retval = SB_LINEDOWN;
else
retval = (WORD)-1; /* -1, because SB_LINEUP == 0 */
return(retval);
}
WORD ArrowTimerProc(hWnd, wMsg, nID, dwTime)
HANDLE hWnd;
WORD wMsg;
short nID;
DWORD dwTime;
{
WORD wScroll;
if ((wScroll = UpOrDown()) != -1)
{
if (bRight == WM_RBUTTONDOWN)
wScroll += SB_PAGEUP - SB_LINEUP;
// [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
GetWindowLong(hWnd, GWL_ID)), (LONG) hWnd);
}
/* Don't need to call KillTimer(), because SetTimer will reset the right one */
SetTimer(hWnd, nID, 50, (TIMERPROC)lpArrowProc);
return(0);
#if 0
wMsg = wMsg;
dwTime = dwTime;
#endif
}
#if PRESSINVERT
void InvertArrow(HANDLE hArrow, WORD wScroll)
{
HDC hDC;
lpUpDown = (wScroll == SB_LINEUP) ? &rUp : &rDown;
hDC = GetDC(hArrow);
ScreenToClient(hArrow, (LPPOINT) &(lpUpDown->left));
ScreenToClient(hArrow, (LPPOINT) &(lpUpDown->right));
InvertRect(hDC, lpUpDown);
ClientToScreen(hArrow, (LPPOINT) &(lpUpDown->left));
ClientToScreen(hArrow, (LPPOINT) &(lpUpDown->right));
ReleaseDC(hArrow, hDC);
ValidateRect(hArrow, lpUpDown);
return;
}
#endif
LONG ArrowControlProc(HWND hArrow, UINT message, UINT wParam, LONG lParam)
{
PAINTSTRUCT ps;
RECT rArrow;
HBRUSH hbr;
short fUpDownOut;
WORD wScroll;
POINT tPoint;
SIZE tSize;
switch (message)
{
/*
case WM_CREATE:
break;
case WM_DESTROY:
break;
*/
case WM_MOUSEMOVE:
if (!bRight) /* If not captured, don't worry about it */
break;
if (lpUpDown == &rUp)
fUpDownOut = SB_LINEUP;
else if (lpUpDown == &rDown)
fUpDownOut = SB_LINEDOWN;
else
fUpDownOut = -1;
switch (wScroll = UpOrDown())
{
case SB_LINEUP:
if (fUpDownOut == SB_LINEDOWN)
InvertArrow(hArrow, SB_LINEDOWN);
if (fUpDownOut != SB_LINEUP)
InvertArrow(hArrow, wScroll);
break;
case SB_LINEDOWN:
if (fUpDownOut == SB_LINEUP)
InvertArrow(hArrow, SB_LINEUP);
if (fUpDownOut != SB_LINEDOWN)
InvertArrow(hArrow, wScroll);
break;
default:
if (lpUpDown)
{
InvertArrow(hArrow, fUpDownOut);
lpUpDown = 0;
}
}
break;
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN:
if (bRight)
break;
bRight = message;
SetCapture(hArrow);
hParent = GetParent(hArrow);
GetWindowRect(hArrow, (LPRECT) &rUp);
CopyRect((LPRECT) &rDown, (LPRECT) &rUp);
rUp.bottom = (rUp.top + rUp.bottom) / 2;
rDown.top = rUp.bottom + 1;
wScroll = UpOrDown();
#if PRESSINVERT
InvertArrow(hArrow, wScroll);
#endif
#if SHIFT_TO_DOUBLE
if (wParam & MK_SHIFT)
{
if (message != WM_RBUTTONDOWN)
goto ShiftLClick;
else
goto ShiftRClick;
}
#endif
if (message == WM_RBUTTONDOWN)
wScroll += SB_PAGEUP - SB_LINEUP;
// [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
lpArrowProc = MakeProcInstance((FARPROC) ArrowTimerProc, hModule);
SetTimer(hArrow, GetWindowLong(hArrow, GWL_ID), 200, (TIMERPROC)lpArrowProc);
break;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
if ((UINT) (bRight - WM_LBUTTONDOWN + WM_LBUTTONUP) == message)
{
bRight = 0;
ReleaseCapture();
#if PRESSINVERT
if (lpUpDown)
InvertArrow(hArrow, (WORD)((lpUpDown == &rUp) ? SB_LINEUP : SB_LINEDOWN));
#endif
if (lpArrowProc)
{
// [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
SendMessage(hParent, WM_VSCROLL, MAKELONG(SB_ENDSCROLL,
GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
KillTimer(hArrow, GetWindowLong(hArrow, GWL_ID));
FreeProcInstance(lpArrowProc);
ReleaseCapture();
lpArrowProc = 0;
}
}
break;
case WM_LBUTTONDBLCLK:
ShiftLClick:
wScroll = UpOrDown() + (WORD) (SB_TOP - SB_LINEUP);
// [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
break;
case WM_RBUTTONDBLCLK:
ShiftRClick:
wScroll = UpOrDown() + (WORD) (SB_THUMBPOSITION - SB_LINEUP);
// [stevecat] - changed WM_VSCROLL message parameter ordering for WIN32
SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
SendMessage(hParent, WM_VSCROLL, MAKELONG(wScroll,
GetWindowLong(hArrow, GWL_ID)), (LONG) hArrow);
/*
hDC = GetDC(hArrow);
InvertRect(hDC, (LPRECT) &rArrow);
ReleaseDC(hArrow, hDC);
ValidateRect(hArrow, (LPRECT) &rArrow);
*/
break;
case WM_PAINT:
BeginPaint(hArrow, &ps);
GetClientRect(hArrow, (LPRECT) &rArrow);
if (hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)))
{
FillRect(ps.hdc, (LPRECT) &rArrow, hbr);
DeleteObject(hbr);
}
hbr = SelectObject(ps.hdc, GetStockObject(BLACK_BRUSH));
SetTextColor(ps.hdc, GetSysColor(COLOR_WINDOWFRAME));
SetMapMode(ps.hdc, MM_ANISOTROPIC);
SetViewportOrgEx(ps.hdc, rArrow.left, rArrow.top, &tPoint);
SetViewportExtEx(ps.hdc, rArrow.right - rArrow.left,
rArrow.bottom - rArrow.top, &tSize);
SetWindowOrgEx(ps.hdc, 0, 0, &tPoint);
SetWindowExtEx(ps.hdc, ARROWXAXIS, ARROWYAXIS, &tSize);
MoveToEx(ps.hdc, 0, (ARROWYAXIS / 2), &tPoint);
LineTo(ps.hdc, ARROWXAXIS, (ARROWYAXIS / 2));
/*
Polygon(ps.hdc, (LPPOINT) Arrow, 10);
*/
Polygon(ps.hdc, (LPPOINT) ArrowUp, POINTSPERARROW);
Polygon(ps.hdc, (LPPOINT) ArrowDown, POINTSPERARROW);
SelectObject(ps.hdc, hbr);
EndPaint(hArrow, &ps);
break;
default:
return(DefWindowProc(hArrow, message, wParam, lParam));
break;
}
return(0L);
}
BOOL RegisterArrowClass (HANDLE hModule)
{
WNDCLASS wcArrow;
wcArrow.lpszClassName = "cpArrow";
wcArrow.hInstance = hModule;
wcArrow.lpfnWndProc = ArrowControlProc;
wcArrow.hCursor = LoadCursor(NULL, IDC_ARROW);
wcArrow.hIcon = NULL;
wcArrow.lpszMenuName = NULL;
wcArrow.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wcArrow.style = CS_HREDRAW | CS_VREDRAW;
#if DOUBLECLICK
wcArrow.style |= CS_DBLCLKS;
#endif
wcArrow.cbClsExtra = 0;
wcArrow.cbWndExtra = 0;
return(RegisterClass((LPWNDCLASS) &wcArrow));
}