2013-06-26 124 views
0

问题C#跟踪鼠标运动

我使用C#应用程序到记录键盘和鼠标的运动,处理该运动和发送串行数据输出到一个微控制器,它解释该数据并移动一组舵机。在过去,我创建了一个盒子或图像,这是我的舵机能够达到的分辨率(步数),将鼠标剪切到该框或图像上,并在光标位于该框中的位置进行处理,并将数据发送到我的伺服器移动到那个位置。

这工作得很好,直到我需要移动更多的步骤比我的显示器的分辨率。

所以我的问题是有什么选项可用于跟踪鼠标在X轴和Y轴上的分辨率达10000步/分辨率?

可能的解决途径

箱子,我想我可以隐藏和居中鼠标在屏幕上外面思考,记录了多少鼠标上的mouseMoved事件,处理数据,然后recenter鼠标的移动屏幕给我在每个轴无限的运动。

下面附上我的PIC18F2420代码。目前它通过我的C#应用​​程序的串行通信提供x和y位置。数据在收到并尽快处理时存储在环形缓冲区中。

PIC代码

#include <p18f2420.h> 
#include <cType.h> 
#include <usart.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <timers.h> 
#include <delays.h> 
/**********************************************************************************************/ 
//DEFINES 
#define switch_0 PORTCbits.RC4 
#define switch_1 PORTCbits.RC5 
#define bufferSize 48 
/**********************************************************************************************/ 
/**********************************************************************************************/ 
//Function prototypes 

void high_isr(void); 
void int2ASCII(unsigned int output); 
void UART_putChar(unsigned char value); 
char readBuffer(); 
char emptyBuffer(); 
char peekBuffer(); 
void limitServo0(); //limit movement via predetermined min/max 
void limitServo1(); 
/**********************************************************************************************/ 

unsigned char hertz = 75; //value to generate 5-=60 hertz wave default value 75 
unsigned int timer0, servo0Min, servo0Max; 
unsigned int timer1, servo1Min, servo1Max; 
unsigned char servo0Rate = 10; 
unsigned char ByteOut; 
char array[bufferSize]; //input rs-232 buffer 
char valueArray[bufferSize]; 
char dataArray[bufferSize]; 
char tempArray[bufferSize]; 
unsigned char tempIndex; 
unsigned char head = 0; 
unsigned char tail = 0; 
//variables used to disect the comma delimited string 
char CVdata; //do we have a command and value? 
char CVvalue; //bool value like above 
//BOOLEAN IF values 

/**********************************************************************************************/ 
//Interrupt Service Routine 
#pragma code high_vector=0x08 

void interrupt_at_high_vector (void) 
{ 
_asm GOTO high_isr _endasm 
} 
#pragma code /* return to the default code section */ 
#pragma interrupt high_isr 
void high_isr (void) 
{ 
if(PIR1bits.TMR2IF == 1) 
{ 
    //T0CONbits.TMR0ON = 0; 
    //T1CONbits.TMR1ON = 0;  
    INTCONbits.TMR0IF = 0; //Turn off Int Flag 
    PIR1bits.TMR1IF = 0; 
    PIR1bits.TMR2IF = 0; //Turn off Int Flag 
    LATCbits.LATC3 = 1;  //Turn on data line 
    TMR0H = timer0/256;  //Extract HIGH byte always do Hbyte first 
    TMR0L = timer0;   //Extract LOW byte 
} 
if(PIR1bits.TMR1IF == 1) 
{ 
    PIR1bits.TMR1IF = 0; 
    //T1CONbits.TMR1ON = 0; 
    //PIR1bits.TMR2IF = 0;  //Turn off Int Flag 
    INTCONbits.TMR0IF = 0; //Turn off Int Flag 
    LATCbits.LATC2 = 0; 
    PR2 = hertz;   //Generate 50-60hertz pulse 
} 
if(INTCONbits.TMR0IF == 1) 
{ 
    LATCbits.LATC2 = 1; 
    //PIR1bits.TMR1IF = 0; 
    //PIR1bits.TMR2IF = 0;  //Turn off Int Flag 
    //T0CONbits.TMR0ON = 0; 
    //T1CONbits.TMR1ON = 1; 
    INTCONbits.TMR0IF = 0; //Turn off Int Flag 
    LATCbits.LATC3 = 0; 
    TMR1H = timer1/256; 
    TMR1L = timer1; 
} 
if(PIR1bits.RCIF == 1) 
{ 
    PIR1bits.RCIF = 0; 
    array[tail] = RCREG; 
    //array[tail] = ReadUSART(); 
    tail++; 
    if(tail == bufferSize) 
    { 
     tail = 0; 
    } 
    /* Clear the interrupt flag */ 
} 
} 

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


void main(void) 
{ 
/**********************************************************************************************/ 
//Initialize 
memset(array, '\0' , bufferSize); 
memset(tempArray, '\0' , bufferSize); 
memset(dataArray, '\0' , bufferSize); 
memset(valueArray, '\0' , bufferSize); 
TRISC = 0b10110000;//RC4 and RC5 inputs for switches 
servo0Max = 65000; //Max value allowed PAN 65000 
servo0Min = 62000; //Min value allowed 63500 
servo1Max = 65000; //Tilt 64138 
servo1Min = 62000; //TILT 63864 
timer0 = 64250; //Initial position 
timer1 = 64200; 
CVdata = 0; 
CVvalue = 0; 
tempIndex = 0; 
LATCbits.LATC0 = 0; 

/**********************************************************************************************/ 
//USART 

OpenUSART(USART_TX_INT_OFF & 
     USART_RX_INT_ON & 
     USART_CONT_RX & 
     USART_ASYNCH_MODE & 
     USART_EIGHT_BIT & 
     USART_BRGH_HIGH 
     , 16);//change back to 16 for 57.6 103 for 9.6 
RCSTAbits.ADDEN = 0;//Testing this out might not help with overflow 
TXSTAbits.SYNC = 0; 
INTCONbits.GIE = 1; 
INTCONbits.PEIE = 1; 
TXSTAbits.BRGH = 1; 
BAUDCONbits.BRG16 = 1; 

/**********************************************************************************************/ 
//Initialize Timer0 

OpenTimer0(TIMER_INT_ON & 
    T0_SOURCE_INT & 
    T0_16BIT); 
T0CONbits.PSA = 1; 
INTCONbits.TMR0IF = 0; 
/**********************************************************************************************/ 

/**********************************************************************************************/ 
//Initialize Timer1 
OpenTimer1(TIMER_INT_ON & 
    T1_16BIT_RW & 
    T1_SOURCE_INT & 
    T1_PS_1_1); 
T1CONbits.T1CKPS1 = 0; // bits 5-4 Prescaler Rate Select bits 
T1CONbits.T1CKPS0 = 0; // bit 4 
T1CONbits.T1OSCEN = 1; // bit 3 Timer1 Oscillator Enable Control bit 1 = on 
T1CONbits.T1SYNC = 1; // bit 2 Timer1 External Clock Input Synchronization Control bit...1 = Do not synchronize external clock input 
T1CONbits.TMR1CS = 0; // bit 1 Timer1 Clock Source Select bit...0 = Internal clock  (FOSC/4) 
T1CONbits.TMR1ON = 1; // bit 0 enables timer 
/**********************************************************************************************/ 

/**********************************************************************************************/ 
//Initialize Timer2 

OpenTimer2(TIMER_INT_ON & 
     T2_PS_1_16 & 
     T2_POST_1_16); 
PR2 = hertz; 
PIE1bits.TMR2IE = 1; 
IPR1bits.TMR2IP = 1; 
INTCONbits.GIEH = 1; //enable global interrupts 
INTCONbits.GIEL = 1; 
/**********************************************************************************************/ 

while(1) 
{ 
    while(emptyBuffer()); 
    if(CVdata == 0 && CVvalue == 1) 
    { 
     //ERROR THIS SHOULDN't HAPPEN! FLUSH BUFFER 
     CVdata = 0; 
     CVvalue = 0; 
    }  
    if(CVdata == 0 && CVvalue == 0) 
    { 
     if(peekBuffer() != ',') 
     { 
      tempArray[tempIndex] = readBuffer(); 
      tempIndex++; 
     } 
     else 
     { 
      readBuffer();//if comma sent first read it and throw away   
      if(tempIndex > 0) //comma read and data in buffer 
      { 
       memcpy(dataArray, tempArray, tempIndex); 
       tempIndex = 0; 
       CVdata = 1; 
       memset(tempArray, 'a' , bufferSize); 
      } 
     } 
    } 
    if(CVdata ==1 && CVvalue == 0) 
    { 
     if(peekBuffer() != ',') 
     { 
      if(isdigit(peekBuffer())) 
      { 
       tempArray[tempIndex] = readBuffer(); 
       tempIndex++; 
      } 
      else 
       readBuffer(); 
     } 
     else 
     { 
      //readBuffer(); 
      if(tempIndex > 0) 
      { 
       memcpy(valueArray, tempArray, tempIndex); 
       tempIndex = 0; 
       CVvalue = 1; 
       memset(tempArray, 'a', bufferSize); 

      } 
     } 
    } 
    if(CVdata == 1 && CVvalue == 1) 
    { 
     switch(dataArray[0]) 
     { 
      case 'x': 
      case 'X': 
      { 
       //timer0 = current = atof(valueArray);//ISSUE HERE first char null 
       timer0 = (unsigned int)atoi(valueArray); 
       break; 
      } 
      case 'y': 
      case 'Y': 
      { 
       timer1 = (unsigned int)atoi(valueArray); 
       break; 
      } 
     } 
     CVdata = 0; 
     CVvalue = 0; 
     memset(dataArray, 'a' , bufferSize); 
     memset(valueArray, 'a' , bufferSize); 
    } 

    limitServo0(); 
    limitServo1(); 
} 
} 

/**********************************************************************************************/ 
//Functions 

void int2ASCII(unsigned int output) 
{ 
unsigned char digit = 0; 
while (output >= 10000) { output -= 10000; digit++; } UART_putChar(digit + 0x30); digit = 0; 
while (output >= 1000) { output -= 1000; digit++; } UART_putChar(digit + 0x30); digit = 0; 
while (output >= 100) { output -= 100; digit++; } UART_putChar(digit + 0x30); digit = 0; 
while (output >= 10) { output -= 10; digit++; } UART_putChar(digit + 0x30); digit = 0; 
while (output >=  1) { output -=  1; digit++; } UART_putChar(digit + 0x30); 
} 

void UART_putChar(unsigned char value) 
{ 
while(PIR1bits.TXIF == 0);  
TXREG = value; 
} 

char readBuffer() 
{ 
if(tail != head) 
{ 
    ByteOut = array[head]; 
    head++; 
    if(head == bufferSize) 
    { 
     head = 0; 
    } 
    return ByteOut; 
} 
//LATCbits.LATC0 = 1; 
} 
char peekBuffer() 
{ 
return array[head]; 
} 
char emptyBuffer() 
{ 
if(tail == head) 
    return 1; 
else 
    return 0; 
} 
void limitServo0() 
{ 
if(timer0 > servo0Max) 
    { 
     timer0 = servo0Max; 
    } 
    if(timer0 < servo0Min) 
    { 
     timer0 = servo0Min; 
    } 
} 

void limitServo1() 
{ 
if(timer1 > servo1Max) 
    { 
     timer1 = servo1Max; 
    } 
    if(timer1 < servo1Min) 
    { 
     timer1 = servo1Min; 
    } 
} 

一个我以前通过位图跟踪的例子可以在我的YouTube频道的观看:http://www.youtube.com/watch?v=rBhkV3dnyiU&list=UULGlw5rGZfETaiPs49JBEuA&index=41

UPDATE

经过一番研究,看来我可以写一个XNA应用程序,捕捉鼠标移动和输出串行通信。我真的很喜欢windows窗体解决方案,但是我确实有XNA经验,所以我会努力将我的应用程序转换为另一种解决方案。

回答

0

我最初的目的是解决问题。在trackingEnabled上我居中鼠标,并检查它每隔100ms移动了多少,然后重新接收并将数据发送到我的控制器。

using System; 
using System.Timers; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 

using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using PIC18F_Servo_Control_V2; 

namespace FSI_Grid1 
{ 
    public partial class Form1 : Form 
    { 
     TabControl LeftControlTab; 
     System.Timers.Timer myTimer; 
     public delegate void UpdateStatusBarDelegate(); 

     TabPage myTabPage; 
     Grid myGrid; 
     serialConnection myConnection; 
     int timerDelay = 100; 
     int initialX, initialY, currentX, currentY, minX, minY, maxX, maxY; 
     int MouseCurrentX, MouseCurrentY, MouseMovedX, MouseMovedY;//tracking mousemovement 
     int offsetX, offsetY;//how much each arrow click moves the servos 
     bool trackingActive;//are we in tracking mode? 
     bool MouseMovedFlag; 
     int YOffsetValue;//used to offset dynamically generated buttons in tab groups 
     int XCenter, YCenter; 

     enum States { Startup, MouseTracking, KeyboardTracking, Script, Idle };//state engine 
     States CurrentState; 

     public Form1() 
     { 
      currentX = initialX = 63503; 
      currentY = initialY = 64012; 
      minX = 62000; 
      maxX = 65000; 
      minY = 62000; 
      maxY = 65000; 
      offsetX = 10; 
      offsetY = 10; 
      trackingActive = false; 
      YOffsetValue = 0; 
      CurrentState = States.Startup; 
      MouseMovedFlag = false; 

      myTimer = new System.Timers.Timer(timerDelay); 
      myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
      myTimer.Elapsed += new ElapsedEventHandler(TrackMouse); 
      myTimer.Enabled = false; 

      InitializeComponent(); 
      InitializeGrid(); 
      InitializeLeftControlTab(); 
      InitializeSerial(); 

      //Initialize StatusBar 

      RadioButton button = (RadioButton)this.Controls.Find("SelectKeyboardRadioButton", true)[0]; 
      button.Checked = true; 

      activeStatus.Text = "Keyboard Tracking DEACTIVATED"; 
      activeStatus.BackColor = Color.Red; 
      ConnectionStatus.Text = "Disconnected!"; 
      xOffsetStatus.Text = "X offset value " + offsetX.ToString(); 
      yOffsetStatus.Text = "Y offset value " + offsetY.ToString(); 
      //this.MouseMove += new MouseEventHandler(Form_MouseMove); 

      XCenter = this.Location.X + this.Width/2; 
      YCenter = this.Location.Y + this.Height/2; 
     } 

     ~Form1() 
     { 
      if (myConnection.connected) 
       myConnection.disconnect(); 
     } 

     private void widthTextBox_KeyPress(object sender, KeyPressEventArgs e) 
     { 
      e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar); 
     } 

     private void widthTextBox_KeyUp(object sender, KeyEventArgs e) 
     { 
      TextBox text = (TextBox)this.Controls.Find("widthTextBox", true)[0]; 
      xOffsetStatus.Text = text.Text; 
      offsetX = Convert.ToInt16(text.Text); 
     } 

     private void heightTextBox_KeyPress(object sender, KeyPressEventArgs e) 
     { 
      e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar); 
     } 

     private void heightTextBox_KeyUp(object sender, KeyEventArgs e) 
     { 
      TextBox text = (TextBox)this.Controls.Find("heightTextBox", true)[0]; 
      yOffsetStatus.Text = text.Text; 
      offsetY = Convert.ToInt16(text.Text); 
     } 

     private void LeftControlTab_DrawItem(object sender, DrawItemEventArgs e) 
     { 
      Graphics g = e.Graphics; 
      Brush _textBrush; 

      // Get the item from the collection. 
      TabPage _tabPage = LeftControlTab.TabPages[e.Index]; 

      // Get the real bounds for the tab rectangle. 
      Rectangle _tabBounds = LeftControlTab.GetTabRect(e.Index); 

      if (e.State == DrawItemState.Selected) 
      { 

       // Draw a different background color, and don't paint a focus rectangle. 
       _textBrush = new SolidBrush(Color.Red); 
       g.FillRectangle(Brushes.White, e.Bounds); 
      } 
      else 
      { 
       _textBrush = new System.Drawing.SolidBrush(e.ForeColor); 
       g.FillRectangle(Brushes.LightGray, e.Bounds); 
       //e.DrawBackground(); 
      } 

      // Use our own font. 
      Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel); 

      // Draw string. Center the text. 
      StringFormat _stringFlags = new StringFormat(); 
      _stringFlags.Alignment = StringAlignment.Center; 
      _stringFlags.LineAlignment = StringAlignment.Center; 
      g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags)); 

     } 

     private void InitializeLeftControlTab() 
     { 
      LeftControlTab = new TabControl(); 

      LeftControlTab.Location = new Point(10, 30); 
      LeftControlTab.Size = new Size(300, 500); 
      LeftControlTab.Alignment = TabAlignment.Left; 
      LeftControlTab.SizeMode = TabSizeMode.Fixed; 
      LeftControlTab.ItemSize = new Size(30, 90); 
      LeftControlTab.DrawMode = TabDrawMode.OwnerDrawFixed; 

      /*EVENT HANDLER*/ 

      LeftControlTab.DrawItem += new DrawItemEventHandler(LeftControlTab_DrawItem); 

      /*TABS*/ 


      int offset = 100; //how far to the right the edit boxes are 
      myTabPage = new TabPage(); 
      myTabPage.Text = "Appearance"; 
      LeftControlTab.Controls.Add(myTabPage); 

      myTabPage = new TabPage(); 
      myTabPage.Text = "Settings"; 

      /*LABEL*/ 

      Label OffsetLabel = new Label(); 
      OffsetLabel.Text = "Step resolution"; 
      OffsetLabel.Location = new Point(0,YOffset()); 
      myTabPage.Controls.Add(OffsetLabel); 

      /*WIDTH LABEL*/ 

      Label widthLabel = new Label(); 
      widthLabel.Text = "Width"; 
      widthLabel.Location = new Point(0, YOffset()); 
      myTabPage.Controls.Add(widthLabel); 

      /*WIDTH TEXTBOX*/ 

      TextBox widthTextBox = new TextBox(); 
      widthTextBox.Name = "widthTextBox"; 
      widthTextBox.Text = myGrid.Width.ToString(); 
      widthTextBox.Location = new Point(widthLabel.Location.X + offset, widthLabel.Location.Y); 
      myTabPage.Controls.Add(widthTextBox); 


      widthTextBox.KeyPress += new KeyPressEventHandler(widthTextBox_KeyPress);        //EVENT HANDLER 
      widthTextBox.KeyUp += new KeyEventHandler(widthTextBox_KeyUp);         //EVENT HANDLER 
      /*HEIGHT LABEL*/ 

      Label heightLabel = new Label(); 
      heightLabel.Text = "Height"; 
      heightLabel.Location = new Point(0, YOffset()); 
      myTabPage.Controls.Add(heightLabel); 

      /*HEIGHT TEXTBOX*/ 

      TextBox heightTextBox = new TextBox(); 
      heightTextBox.Name = "heightTextBox"; 
      heightTextBox.Text = myGrid.Height.ToString(); 
      heightTextBox.Location = new Point(heightLabel.Location.X + offset, heightLabel.Location.Y); 
      myTabPage.Controls.Add(heightTextBox); 

      /*RADIOBUTTON LABEL*/ 

      GroupBox RadioLabel = new GroupBox(); 
      RadioLabel.Text = "Tracking Style"; 
      RadioLabel.Location = new Point(0, YOffset()); 
      myTabPage.Controls.Add(RadioLabel); 

      /*RADIO BUTTONS*/ 

      RadioButton SelectMouse = new RadioButton(); 
      SelectMouse.Location = new Point(10, 20); 
      SelectMouse.Text = "Mouse"; 
      SelectMouse.Name = "SelectMouseRadioButton"; 
      SelectMouse.CheckedChanged += new EventHandler(RadioButtons_CheckedChanged); 
      RadioLabel.Controls.Add(SelectMouse); 

      RadioButton SelectKeyboard = new RadioButton(); 
      SelectKeyboard.Location = new Point(10, 42); 
      SelectKeyboard.Text = "Keyboard"; 
      SelectKeyboard.Name = "SelectKeyboardRadioButton"; 
      SelectKeyboard.CheckedChanged += new EventHandler(RadioButtons_CheckedChanged); 
      RadioLabel.Controls.Add(SelectKeyboard); 

      heightTextBox.KeyPress += new KeyPressEventHandler(heightTextBox_KeyPress);        //EVENT HANDLER 
      heightTextBox.KeyUp += new KeyEventHandler(heightTextBox_KeyUp);         //EVENT HANDLER 
      //EVENT HANDLER 
      LeftControlTab.Controls.Add(myTabPage); 

      Controls.Add(LeftControlTab); 
     } 

     private void InitializeGrid() 
     { 
      myGrid = new Grid(offsetX, offsetY); 
     } 

     private void connectToolStripMenuItem_Click(object sender, EventArgs e) 
     { 
      serialConnectionDialogBox serialBox = new serialConnectionDialogBox(); 
      Point temp = this.Location; 
      temp.X += 30; 
      temp.Y += 70; 
      serialBox.Location = temp; 
      DialogResult results = serialBox.ShowDialog(); 
      if (results == DialogResult.Yes && !myConnection.connected) 
      { 
       myConnection.setCOMMPort(serialBox.commPortComboBox.Text); 
       myConnection.setBaudRate(Convert.ToInt32(serialBox.baudRateComboBox.Text)); 
       myConnection.connect();     
      } 
      if (myConnection.connected) 
      { 
       ConnectionStatus.Text = "X " + currentX.ToString() + "Y " + currentY.ToString(); 
      } 
     } 

     private void InitializeSerial() 
     { 
      myConnection = new serialConnection(); 

     } 

     protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
     { 
      bool updatePos = false; 

      switch (keyData) 
      { 
       case Keys.Left: 
        currentX += offsetX; 
        updatePos = true; 
        break; 
       case Keys.Right: 
        currentX -= offsetX; 
        updatePos = true; 
        break; 
       case Keys.Up: 
        currentY += offsetY; 
        updatePos = true; 
        break; 
       case Keys.Down: 
        currentY -= offsetY; 
        updatePos = true; 
        break; 
       case Keys.F5: 
        if (trackingActive) 
        { 
         trackingActive = false; 
         LeftControlTab.Enabled = true; 
         if(CurrentState == States.KeyboardTracking) 
          activeStatus.Text = "Keyboard Tracking DEACTIVATED"; 
         if (CurrentState == States.MouseTracking) 
          activeStatus.Text = "Mouse Tracking DEACTIVATED"; 
         activeStatus.BackColor = Color.Red; 
         myTimer.Enabled = false; 
        } 
        else 
        { 
         trackingActive = true; 
         LeftControlTab.Enabled = false; 
         if (CurrentState == States.KeyboardTracking) 
          activeStatus.Text = "Keyboard Tracking ACTIVATED"; 
         if (CurrentState == States.MouseTracking) 
          activeStatus.Text = "Mouse Tracking ACTIVATED"; 
         activeStatus.BackColor = Color.Green; 
         myTimer.Enabled = true; 
        } 
        break; 
      } 

      if (updatePos == true) 
      { 
       updatePos = false; 
       Point temp = new Point(); 
       temp.X = currentX = clipX(currentX); 
       temp.Y = currentY = clipY(currentY); 
       String tx = "x," + Convert.ToString(temp.X) + ",y," + Convert.ToString(temp.Y) + ","; 
       myConnection.sendData(tx); 
       ConnectionStatus.Text = "X " + currentX.ToString() + "Y " + currentY.ToString(); 
      } 

      return base.ProcessCmdKey(ref msg, keyData); 
     } 

     private void disconnectToolStripMenuItem_Click_1(object sender, EventArgs e) 
     { 
      if (myConnection.connected) 
      { 
       myConnection.disconnect(); 
       ConnectionStatus.Text = "Disconnected!"; 
      } 
     } 

     private void RadioButtons_CheckedChanged(object sender, EventArgs e) 
    { 
     if (sender == (RadioButton)this.Controls.Find("SelectMouseRadioButton", true)[0]) 
     { 
      CurrentState = States.MouseTracking; 
      activeStatus.Text = "Mouse Tracking "; 
     } 
     if (sender == (RadioButton)this.Controls.Find("SelectKeyboardRadioButton", true)[0]) 
     { 
      CurrentState = States.KeyboardTracking; 
      activeStatus.Text = "Keyboard Tracking "; 
     } 
     if (trackingActive) 
      activeStatus.Text += "ACTIVATED"; 
     else 
      activeStatus.Text += "DEACTIVATED"; 

    } 


     private void TrackMouse(object source, ElapsedEventArgs e) 
     { 
      if (trackingActive && CurrentState == States.MouseTracking) 
      { 
       MouseMovedFlag = true; 
       MouseMovedX = -1 * (Cursor.Position.X - XCenter); 
       MouseMovedY = -1 * (Cursor.Position.Y - YCenter); 

       currentX += MouseMovedX; 
       currentX = clipX(currentX); 
       currentY += MouseMovedY; 
       currentY = clipY(currentY); 

       statusStrip1.Invoke(new UpdateStatusBarDelegate(this.UpdateStatusBar), null); 

       Cursor.Position = new Point(XCenter, YCenter); 
      } 
     } 

     private int clipX(int tempX) 
     { 
      if(tempX < minX) 
       tempX = minX; 

      if(tempX > maxX) 
       tempX = maxX; 
      return tempX; 
     } 

     private int clipY(int tempY) 
     { 
      if(tempY < minY) 
       tempY = minY; 

      if (tempY > maxY) 
       tempY = maxY; 

      return tempY; 
     } 
     private int YOffset() 
     { 
      int tempValue = YOffsetValue; 
      if (tempValue == 0) 
      { 
       YOffsetValue += 22; 
       return tempValue; 
      } 
      else 
      { 
       YOffsetValue += 22; 
       return tempValue; 
      } 
     } 

     void OnTimedEvent(object source, ElapsedEventArgs e) 
     { 
      if (true) 
      { 
       if (MouseMovedFlag || trackingActive) 
       { 
        Point temp = new Point(); 
        temp.X = currentX; 
        temp.Y = currentY; 

        String tx = "x," + Convert.ToString(temp.X) + ",y," + Convert.ToString(temp.Y) + ","; 
        myConnection.sendData(tx); 
       } 
      } 
     } 

     void UpdateStatusBar() 
     { 
      ConnectionStatus.Text = "X " + currentX.ToString() + "Y " + currentY.ToString(); 
      ConnectionStatus.Invalidate(); 
      this.Update(); 
     } 
    } 
}