Hello everyone,
I am using SystemParametersInfo API in my application to change the cursor speed.
At some times, this API makes my OS hanged.
Is this API makes system hang.
If so, is there any solution?
Below is the code,
// FreeCursorDlg.cpp : implementation file
//
const int kCallbackTimeridFreeCursor = 1237;
bool bSet = false;
int speedinfo[3];
define SETMOUSESPEED 0x0071 // hardcoded event for SystemParametersInfo
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CFreeCursorDlg dialog
CFreeCursorDlg::CFreeCursorDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CFreeCursorDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
speedinfo[0] = 6; // CURSOR_THRESHOLD1;
speedinfo[1] = 10; // CURSOR_THRESHOLD2;
speedinfo[2] = 1; // CURSOR_SPEED;
}
void CFreeCursorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CFreeCursorDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON_FREECURSOR, &CFreeCursorDlg::OnBnClickedButtonFreecursor)
END_MESSAGE_MAP()
// CFreeCursorDlg message handlers
BOOL CFreeCursorDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CFreeCursorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CFreeCursorDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFreeCursorDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CFreeCursorDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent == kCallbackTimeridFreeCursor) {
SetFreeCursor();
bSet = bSet ? false : true;
}
CDialogEx::OnTimer(nIDEvent);
}
void CFreeCursorDlg::OnBnClickedButtonFreecursor()
{
KillTimer(kCallbackTimeridFreeCursor);
UINT_PTR timerid = SetTimer(kCallbackTimeridFreeCursor, 10, NULL);
if (timerid == 0) {
AfxMessageBox(L"UnableToObtainTimer For FreeCursor");
}
}
void CFreeCursorDlg::SetFreeCursor() {
ClipCursor(NULL);
SetInitialCursorSpeed();
::SetFocus(m_hWnd);
if (!bSet) {
ShowCursor(true);
ClipCursor(NULL);
} else {
ShowCursor(false);
ClipCursorOn();
}
SetCursorSpeed();
POINT pntSaveCursorPos;
GetCursorPos(&pntSaveCursorPos);
SetCursorPos(pntSaveCursorPos.x, pntSaveCursorPos.y);
}
void CFreeCursorDlg::ShowCursor(bool boShow) {
if(boShow == true) {
int nCount = ::ShowCursor( TRUE );
while( nCount < 0 )
{
nCount = ::ShowCursor( TRUE );
}
} else {
int nCount = ::ShowCursor( FALSE );
while( nCount >= 0 )
{
nCount = ::ShowCursor( FALSE );
}
}
}
void CFreeCursorDlg::ClipCursorOn() {
CRect rect;
::GetWindowRect(m_hWnd, rect);
if(( rect.top != 0 ) && ( rect.bottom != 0 ) && ( rect.left != 0 ) && ( rect.right != 0 ))
{
ClipCursor(&rect);
}
}
void CFreeCursorDlg::SetCursorSpeed() {
SystemParametersInfo(SPI_SETMOUSE, 0, speedinfo, 0);
int iSpeed = 8;
BOOL boResult = SystemParametersInfo(SPI_SETMOUSESPEED, 0, reinterpret_cast<PVOID>(static_cast<INT_PTR>(iSpeed)), 0);
}
void CFreeCursorDlg::SetInitialCursorSpeed() {
int ini_speedinfo[3];
INT_PTR nSpeed;
if (!bSet) {
ini_speedinfo[0] = 8; // CURSOR_THRESHOLD1;
ini_speedinfo[1] = 12; // CURSOR_THRESHOLD2;
ini_speedinfo[2] = 3; // CURSOR_SPEED;
nSpeed = 9;
}
else {
ini_speedinfo[0] = 9; // CURSOR_THRESHOLD1;
ini_speedinfo[1] = 13; // CURSOR_THRESHOLD2;
ini_speedinfo[2] = 2; // CURSOR_SPEED;
nSpeed = 4;
}
SystemParametersInfo(SPI_SETMOUSE, 0, ini_speedinfo, 0);
BOOL result = SystemParametersInfo(SETMOUSESPEED, 0,
reinterpret_cast<void*>(nSpeed), 0);
}
Thanks in advance.
Ratheesh