/** FILE: mouse.c ********** Module Header ******************************** * * Control panel applet for Mouse configuration. This file holds * everything to do with the "Mouse" dialog box in the Control Panel. * * History: * 12:30 on Tues 23 Apr 1991 -by- Steve Cathcart [stevecat] * Took base code from Win 3.1 source * 10:30 on Tues 04 Feb 1992 -by- Steve Cathcart [stevecat] * Updated code to latest Win 3.1 sources * * Copyright (C) 1990-1992 Microsoft Corporation * *************************************************************************/ //========================================================================== // Include files //========================================================================== // C Runtime #include #include #include // Application specific #include "main.h" #include "winuserp.h" #undef MOUSETRAILS //========================================================================== // Local Definitions //========================================================================== #define THRESH1 0 /* 1st MouseThreshold */ #define THRESH2 1 /* 2nd MouseThreshold */ #define SPEED 2 /* MouseSpeed */ #define ACCELMIN 0 #define ACCELMAX (ACCELMIN + 6) /* Range of 7 settings */ //========================================================================== // External Declarations //========================================================================== //========================================================================== // Local Data Declarations //========================================================================== TCHAR szDblClkSpeed[] = TEXT("DoubleClickSpeed"); TCHAR szSnapTo[] = TEXT("SnapToDefaultButton"); int rgwMouse[3]; int rgwOrigMse[3]; HWND hMouseDlg; BOOL bSwap; BOOL bOriginalSwap; short nSpeed; short nOrigSpeed; short ClickSpeed; short nOriginalDblClkSpeed; BOOL bSnapTo; BOOL bOriginalSnapTo; WORD fInvert; HWND hWndMLeftText; // global variables are bad things! HWND hWndMRightText; // get rid of these if possible! HWND hWndDblClkScroll; RECT OrigRect; RECT LeftMouseRect; RECT RightMouseRect; RECT DblClkRect; //========================================================================== // Local Function Prototypes //========================================================================== void InvertMButton (HDC hDC, WORD wButton); BOOL InitMouseDlg (HWND hDlg); void MousePaint (HDC hDC); //========================================================================== // Functions //========================================================================== BOOL InitMouseDlg (HWND hDlg) { POINT Origin; #ifdef MOUSETRAILS HDC hDC; int nTrails; int nTemp; #endif // MOUSETRAILS LoadAccelerators(hModule, (LPTSTR) MAKEINTRESOURCE(CP_ACCEL)); hMouseDlg = hDlg; Origin.x = Origin.y = 0; ClientToScreen (hDlg, (LPPOINT) &Origin); hWndMLeftText = GetDlgItem (hDlg, MOUSE_LEFT); hWndMRightText = GetDlgItem (hDlg, MOUSE_RIGHT); GetWindowRect (hDlg, &OrigRect); OrigRect.left -= Origin.x; OrigRect.right -= Origin.x; GetWindowRect (GetDlgItem (hDlg, MOUSE_DBLCLKFRAME), &DblClkRect); DblClkRect.top -= Origin.y; DblClkRect.bottom -= Origin.y; DblClkRect.left -= Origin.x; DblClkRect.right -= Origin.x; GetWindowRect (GetDlgItem (hDlg, MOUSE_LBUTTON), &LeftMouseRect); LeftMouseRect.top -= Origin.y - 1; LeftMouseRect.bottom -= Origin.y + 1; LeftMouseRect.left -= Origin.x - 1; LeftMouseRect.right -= Origin.x + 1; GetWindowRect (GetDlgItem (hDlg, MOUSE_RBUTTON), &RightMouseRect); RightMouseRect.top -= Origin.y - 1; RightMouseRect.bottom -= Origin.y + 1; RightMouseRect.left -= Origin.x - 1; RightMouseRect.right -= Origin.x + 1; SwapMouseButton (bOriginalSwap = bSwap = SwapMouseButton (TRUE)); if (bSwap) { TCHAR szLeft[4], szRight[4]; GetDlgItemText (hDlg, MOUSE_LEFT, szRight, CharSizeOf(szRight)); GetDlgItemText (hDlg, MOUSE_RIGHT, szLeft, CharSizeOf(szLeft)); SetDlgItemText (hDlg, MOUSE_LEFT, szLeft); SetDlgItemText (hDlg, MOUSE_RIGHT, szRight); } CheckDlgButton (hDlg, MOUSE_SWAP, (WORD) bSwap); SystemParametersInfo (SPI_GETSNAPTODEFBUTTON, 0, (PVOID)(LPBOOL)&bSnapTo, FALSE); bOriginalSnapTo = bSnapTo; CheckDlgButton (hDlg, MOUSE_SNAP, (WORD) bSnapTo); #ifdef MOUSETRAILS if (!(hDC = GetDC (NULL))) { CheckDlgButton (hDlg, MOUSE_TRAILS, FALSE); EnableWindow (GetDlgItem (hDlg, MOUSE_TRAILS), FALSE); } else { nTemp = MOUSETRAILS; nTrails = Escape (hDC, QUERYESCSUPPORT, sizeof (int), (LPSTR) &nTemp, NULL); EnableWindow (GetDlgItem (hDlg, MOUSE_TRAILS), nTrails); CheckDlgButton (hDlg, MOUSE_TRAILS, (nTrails > 1)); ReleaseDC (NULL,hDC); } #endif // MOUSETRAILS fInvert = (WORD) ((GetAsyncKeyState (VK_LBUTTON) & 0x80) ? MK_LBUTTON : 0); fInvert |= (GetAsyncKeyState (VK_RBUTTON) & 0x80) ? MK_RBUTTON : 0; hWndDblClkScroll = GetDlgItem (hDlg, MOUSE_CLICKSCROLL); ClickSpeed = (short) GetProfileInt ((LPTSTR)szWindows, (LPTSTR)szDblClkSpeed, CLICKMIN + CLICKRANGE / 2); nOriginalDblClkSpeed = ClickSpeed; SetScrollRange (hWndDblClkScroll, SB_CTL, CLICKMIN, CLICKMAX, FALSE); SetScrollPos (hWndDblClkScroll, SB_CTL, CLICKMIN + CLICKMAX - ClickSpeed, TRUE); SetDoubleClickTime (ClickSpeed); SystemParametersInfo (SPI_GETMOUSE, 0, (PVOID)(LPINT)rgwMouse, FALSE); rgwOrigMse[THRESH1] = rgwMouse[THRESH1]; rgwOrigMse[THRESH2] = rgwMouse[THRESH2]; rgwOrigMse[SPEED] = rgwMouse[SPEED]; /* 0 Acc = 4 1 Acc, 5 xThreshold = 5 1 Acc, 4 xThreshold = 6 1 Acc, 3 xThreshold = 7 1 Acc, 2 xThreshold = 8 1 Acc, 1 xThreshold = 9 2 Acc, 5 xThreshold = 10 2 Acc, 4 xThreshold = 11 2 Acc, 3 xThreshold = 12 2 Acc, 2 xThreshold = 13 */ nOrigSpeed = nSpeed = ACCELMIN; if (rgwMouse[SPEED] == 2) nSpeed += (24 - rgwMouse[THRESH2]) / 3; else if (rgwMouse[SPEED] == 1) nSpeed += (13 - rgwMouse[THRESH1]) / 3; nOrigSpeed = nSpeed; SetScrollRange (GetDlgItem (hDlg, MOUSE_SPEEDSCROLL), SB_CTL, ACCELMIN, ACCELMAX, FALSE); SetScrollPos (GetDlgItem (hDlg, MOUSE_SPEEDSCROLL), SB_CTL, nSpeed, TRUE); return TRUE; } void InvertMButton (HDC hDC, WORD wButton) { InvertRect (hDC, (LPRECT) ((wButton & MK_LBUTTON) ? &LeftMouseRect : &RightMouseRect)); fInvert ^= wButton; } void MousePaint (HDC hDC) { WORD wParam; UpdateWindow (hWndMLeftText); UpdateWindow (hWndMRightText); wParam = (WORD) ((GetKeyState (VK_LBUTTON) & 0x8000) ? MK_LBUTTON : 0); if ((fInvert ^ wParam) & MK_LBUTTON) { InvertMButton (hDC, MK_LBUTTON); } wParam = (WORD) ((GetKeyState (VK_RBUTTON) & 0x8000) ? MK_RBUTTON : 0); if ((fInvert ^ wParam) & MK_RBUTTON) { InvertMButton (hDC, MK_RBUTTON); } return; } BOOL MouseDlg (HWND hDlg, UINT message, DWORD wParam, LONG lParam) { PAINTSTRUCT ps; TCHAR szTemp[10]; HDC hDC; RECT Rect, rI; /* Used in WM_PAINT, testing with IntersectRect */ POINT pt; #ifdef MOUSETRAILS int nTrailSize; static BOOL bTrails; #endif // MOUSETRAILS switch (message) { case WM_INITDIALOG: InitMouseDlg (hDlg); #ifdef MOUSETRAILS bTrails = IsDlgButtonChecked (hDlg, MOUSE_TRAILS); #endif // MOUSETRAILS break; case WM_HSCROLL: if ((HWND) lParam == hWndDblClkScroll) { switch (LOWORD(wParam)) { case SB_LINEUP: ClickSpeed += CLICKRANGE / 50; break; case SB_LINEDOWN: ClickSpeed -= CLICKRANGE / 50; break; case SB_PAGEUP: ClickSpeed += CLICKRANGE / 5; break; case SB_PAGEDOWN: ClickSpeed -= CLICKRANGE / 5; break; case SB_THUMBPOSITION: ClickSpeed = (short) (CLICKMAX + CLICKMIN - HIWORD(wParam)); break; case SB_TOP: ClickSpeed = CLICKMIN; break; case SB_BOTTOM: ClickSpeed = CLICKMAX; break; case SB_THUMBTRACK: case SB_ENDSCROLL: return TRUE; break; } if (ClickSpeed > CLICKMAX) ClickSpeed = CLICKMAX; else if (ClickSpeed < CLICKMIN) ClickSpeed = CLICKMIN; SetScrollPos ((HWND) lParam, SB_CTL, CLICKMAX + CLICKMIN - ClickSpeed, TRUE); SetDoubleClickTime (ClickSpeed); } else { switch (LOWORD(wParam)) { case SB_LINEUP: nSpeed--; break; case SB_LINEDOWN: nSpeed++; break; case SB_PAGEUP: nSpeed -= 3; break; case SB_PAGEDOWN: nSpeed += 3; break; case SB_THUMBPOSITION: nSpeed = HIWORD(wParam); break; case SB_TOP: nSpeed = ACCELMAX; break; case SB_BOTTOM: nSpeed = ACCELMIN; break; case SB_THUMBTRACK: case SB_ENDSCROLL: return TRUE; break; } if (nSpeed > ACCELMAX) nSpeed = ACCELMAX; else if (nSpeed < ACCELMIN) nSpeed = ACCELMIN; SetScrollPos ((HWND) lParam, SB_CTL, nSpeed, TRUE); if (nSpeed == 0) { rgwMouse[THRESH1] = rgwMouse[THRESH2] = rgwMouse[SPEED] = 0; } else if (nSpeed < 4) { rgwMouse[SPEED] = 1; rgwMouse[THRESH1] = 13 - 3 * nSpeed; rgwMouse[THRESH2] = 0; } else { rgwMouse[SPEED] = 2; rgwMouse[THRESH1] = 4; rgwMouse[THRESH2] = 24 - 3 * nSpeed; } SystemParametersInfo (SPI_SETMOUSE, 0, (PVOID)(LPINT)rgwMouse, FALSE); } break; case WM_RBUTTONDBLCLK: case WM_LBUTTONDBLCLK: LONG2POINT (lParam, pt); if ( PtInRect (&DblClkRect, pt) ) { hDC = GetDC (hDlg); InvertRect (hDC, &DblClkRect); ReleaseDC (hDlg, hDC); ValidateRect (hDlg, &DblClkRect); } /* fall through */ case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MOUSEMOVE: hDC = GetDC (hDlg); MousePaint (hDC); ReleaseDC (hDlg, hDC); ValidateRect (hDlg, &LeftMouseRect); ValidateRect (hDlg, &RightMouseRect); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDD_HELP: goto DoHelp; #ifdef MOUSETRAILS case MOUSE_TRAILS: if (hDC = GetDC (NULL)) { if (IsDlgButtonChecked (hDlg, MOUSE_TRAILS)) { nTrailSize = -1; Escape (hDC, MOUSETRAILS, sizeof (int), (LPSTR) ((LPINT) &nTrailSize), NULL); } else { nTrailSize = 0; Escape (hDC, MOUSETRAILS, sizeof (int), (LPSTR) ((LPINT) &nTrailSize), NULL); } ReleaseDC (NULL, hDC); } break; #endif // MOUSETRAILS case MOUSE_SNAP: bSnapTo = IsDlgButtonChecked (hDlg, MOUSE_SNAP); SystemParametersInfo (SPI_SETSNAPTODEFBUTTON, bSnapTo, 0, FALSE); break; case MOUSE_SWAP: CheckDlgButton (hDlg, MOUSE_SWAP, (WORD) (bSwap = !IsDlgButtonChecked (hDlg, MOUSE_SWAP))); SwapMouseButton (bSwap); { TCHAR szLeft[4], szRight[4]; GetDlgItemText (hDlg, MOUSE_LEFT, szRight, CharSizeOf(szRight)); GetDlgItemText (hDlg, MOUSE_RIGHT, szLeft, CharSizeOf(szLeft)); SetDlgItemText (hDlg, MOUSE_LEFT, szLeft); SetDlgItemText (hDlg, MOUSE_RIGHT, szRight); } InvalidateRect (hDlg, &LeftMouseRect, TRUE); InvalidateRect (hDlg, &RightMouseRect, TRUE); UpdateWindow (hDlg); fInvert = (WORD) ((GetAsyncKeyState (VK_LBUTTON) & 0x80) ? MK_LBUTTON : 0); fInvert |= (GetAsyncKeyState (VK_RBUTTON) & 0x80) ? MK_RBUTTON : 0; #ifdef JAPAN //We need the default Dialog handling. //yutakas 1992.11.11 return FALSE; #endif break; case IDOK: /* change cursor to hourglass */ HourGlass (TRUE); if (bSnapTo != bOriginalSnapTo) SystemParametersInfo (SPI_SETSNAPTODEFBUTTON, bSnapTo, 0, SPIF_UPDATEINIFILE); if (bSwap != bOriginalSwap) SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, bSwap, 0, SPIF_UPDATEINIFILE); #ifdef MOUSETRAILS /* Support mouse trails */ if (IsWindowEnabled (GetDlgItem (hDlg, MOUSE_TRAILS))) { if (hDC = GetDC (NULL)) { if (IsDlgButtonChecked (hDlg, MOUSE_TRAILS)) { nTrailSize = -1; Escape (hDC, MOUSETRAILS, sizeof (int), (LPSTR) ((LPINT) &nTrailSize), NULL); } else { nTrailSize = 0; Escape (hDC, MOUSETRAILS, sizeof (int), (LPSTR) ((LPINT) &nTrailSize), NULL); } ReleaseDC (NULL, hDC); } } #endif // MOUSETRAILS if (ClickSpeed != nOriginalDblClkSpeed) { MyItoa (ClickSpeed, szTemp, 10); WriteProfileString (szWindows, szDblClkSpeed, szTemp); } // this sends the win.ini change message SystemParametersInfo (SPI_SETMOUSE, 0, (PVOID)(LPINT)rgwMouse, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE); HourGlass (FALSE); EndDialog (hDlg, 0L); break; case IDCANCEL: #ifdef MOUSETRAILS /* Support mouse trails */ if (IsWindowEnabled (GetDlgItem (hDlg, MOUSE_TRAILS))) { if (hDC = GetDC (NULL)) { if (bTrails) { nTrailSize = -1; Escape (hDC, MOUSETRAILS, sizeof (int), (LPSTR) ((LPINT) &nTrailSize), NULL); } else { nTrailSize = 0; Escape (hDC, MOUSETRAILS, sizeof (int), (LPSTR) ((LPINT) &nTrailSize), NULL); } ReleaseDC (NULL, hDC); } } #endif // MOUSETRAILS SetDoubleClickTime (nOriginalDblClkSpeed); SwapMouseButton (bOriginalSwap); SystemParametersInfo (SPI_SETMOUSE, 0, (PVOID)(LPINT)rgwOrigMse, FALSE); SystemParametersInfo (SPI_SETSNAPTODEFBUTTON, bOriginalSnapTo, 0, FALSE); EndDialog (hDlg, 0L); break; } break; case WM_ACTIVATE: case WM_MOUSEACTIVATE: case WM_ACTIVATEAPP: InvalidateRect (hDlg, &LeftMouseRect, TRUE); InvalidateRect (hDlg, &RightMouseRect, TRUE); UpdateWindow (hDlg); fInvert = (WORD) ((GetKeyState (VK_LBUTTON) & 0x80) ? MK_LBUTTON : 0); fInvert |= (GetKeyState (VK_RBUTTON) & 0x80) ? MK_RBUTTON : 0; return FALSE; break; case WM_PAINT: GetUpdateRect (hDlg, &Rect, FALSE); if (IntersectRect (&rI, &Rect, &LeftMouseRect)) { InvalidateRect (hDlg, &LeftMouseRect, TRUE); fInvert &= !MK_LBUTTON; } if (IntersectRect (&rI, &Rect, &RightMouseRect)) { InvalidateRect (hDlg, &RightMouseRect, TRUE); fInvert &= !MK_RBUTTON; } if (IntersectRect (&rI, &Rect, &DblClkRect)) { InvalidateRect (hDlg, &DblClkRect, TRUE); } hDC = BeginPaint (hDlg, &ps); MousePaint (hDC); EndPaint (hDlg, &ps); break; default: if (message == wHelpMessage) { DoHelp: CPHelp (hDlg); return TRUE; } else return FALSE; break; } return (TRUE); }