0

Problem

I'm using a C# application to record keyboard and mouse movement, processing that movement and sending serial data out to a micro-controller that interpreters that data and moves a set of servos. In the past I had created a box or image that was the resolution(number of steps) my servos were capable of, clipped the mouse to that box or image, and processed where the cursor was in that box and sent data to my servos to move to that position.

This worked fine and dandy till I needed to move a greater amount of steps than my monitor has resolution.

So my question is what options are available to me for tracking mouse movement up to 10,000 steps/resolution in the X and Y axis?

Possible solution route

Thinking outside the box I think I could hide and center the mouse on the screen, record how much the mouse moved on mousemoved events, process that data, then recenter the mouse on the screen to give me unlimited movement in each axis.

Enclosed below is my PIC18F2420 code. Currently it is fed x and y positions via serial communications from my C# application. Data is stored in a ring buffer as it is received and processed as soon as possible.

PIC CODE

#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;
    }
}

An Example of my previous tracking via bitmap can be viewed on my youtube channel at: http://www.youtube.com/watch?v=rBhkV3dnyiU&list=UULGlw5rGZfETaiPs49JBEuA&index=41

UPDATE

After some research it seems I can write a XNA application, capture mouse movement, and output serial communications. I would really really like a windows forms solution but I do have XNA experience so guess I'll work on converting my application until another solution presents itself.

4

1 回答 1

0

我最初有目的的解决方案成功了。在 trackingEnabled 上,我将鼠标居中并检查它每 100 毫秒移动了多少,然后我重新定位它并将数据发送到我的控制器。

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();
        }
    }
}
于 2013-07-01T03:24:48.333 回答