Hello.

I am working on a robot which is somehow controlled by the mouse. I was forced to turn to Windows programming, which now I am really beginning to take a liking to. Anyway, I have written a program. I will include everything, only for completeness.

Code:
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include "Clock3.h"

#define SamplingTime  20    //in milliseconds; ideally, it should be 20 ms

#define KP   1
#define KI   1
#define KD   1

#define DATAPORT 0x378
#define CONTROLPORT 0x37a


LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);  //Callback function prototype

//Main program:
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, 
                   LPSTR lpszArgs, int nWinMode)
{
  char szWinName[] = "MyWin"; /* name of window class */
  HWND hwnd;
  MSG msg;
  WNDCLASSEX wcl;
  
  /* Define a window class. */
  wcl.cbSize = sizeof(WNDCLASSEX); 

  wcl.hInstance = hThisInst; /* handle to this instance */
  wcl.lpszClassName = szWinName; /* window class name */
  wcl.lpfnWndProc = WindowFunc; /* window function */
  wcl.style = 0; /* default style */

  wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* standard icon */
  wcl.hIconSm = LoadIcon(NULL, IDI_WINLOGO); /* small icon */
  wcl.hCursor = LoadCursor(NULL, IDC_ARROW); /* cursor style */

  wcl.lpszMenuName = NULL; /* no main menu */
  wcl.cbClsExtra = 0; /* no extra */
  wcl.cbWndExtra = 0; /* information needed */

  /* Make the window white. */
  wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 

  /* Register the window class. */
  if(!RegisterClassEx(&wcl)) return 0;

  /* Now that a window class has been registered, a window
     can be created. */
  hwnd = CreateWindow(
    szWinName, /* name of window class */
    "Processing Mouse Messages", /* title */
    WS_OVERLAPPEDWINDOW, /* window style - normal */
    CW_USEDEFAULT, /* X coordinate - let Windows decide */
    CW_USEDEFAULT, /* Y coordinate - let Windows decide */
    CW_USEDEFAULT, /* width - let Windows decide */
    CW_USEDEFAULT, /* height - let Windows decide */
    HWND_DESKTOP, /* no parent window */
    NULL, /* no menu */
    hThisInst, /* handle of this instance of the program */
    NULL /* no additional arguments */
  );

  /* Display the window. */
  ShowWindow(hwnd, nWinMode);
  UpdateWindow(hwnd);

  /* Create the message loop. */
  while(GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg); /* translate keyboard messages */
    DispatchMessage(&msg); /* return control to Windows 98 */
  }
  return msg.wParam;
}

/* This function is called by Windows 98 and is passed 
   messages from the message queue.
*/
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message,
                            WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  static char str[255] = "", key; /* holds output string */
  static char *clr = "                                                                                  ";
  static BOOL greenlight = 0;	//static variables are initialized only once
  static BOOL delta_t;
  static LONG xref, i=1;
  static LONG x[3];
  static short move[4]={5,6,10,9};	// %0101 -> %0110 -> %1010 -> %1001, just like the website

  static Clock timer, clock;
    typedef UINT (CALLBACK* LPFNDLLFUNC1)(INT,INT);
    typedef UINT (CALLBACK* LPFNDLLFUNC2)(INT); 
        HINSTANCE hDLL; // Handle to DLL 
        LPFNDLLFUNC1 Output; // Function pointer 
        LPFNDLLFUNC2 Input; // Function pointer 
        INT Addr; 
        INT AddrIn; 
        INT Value; 
        hDLL = LoadLibrary("Inpout32"); 
        if (hDLL != NULL)
        { 
          Output = (LPFNDLLFUNC1)GetProcAddress(hDLL,"Out32"); 
          Input = (LPFNDLLFUNC2)GetProcAddress(hDLL,"Inp32"); 
          if (!Output || !Input) 
          { 
            // handle the error FreeLibrary(hDLL); 
          } 
        } 
        Addr = 0x378; 
        AddrIn = 0x379; 
        Value = 0; 
        Output(Addr, Value); 
        INT somenum = Input(Addr);
       /* end of motor stuff */

  switch(message) {

  case WM_CHAR:
	  hdc = GetDC(hwnd);
	  switch(wParam)
	  {
	    case 'r': case 'R':			//Pressing 'r' or 'R' sets reference point, resets timer
			greenlight = 1;
			timer.reset();
			xref=x[2];
			x[1]=0;
			TextOut(hdc, 10, 400, clr, strlen(clr));
			sprintf(str, "xref = %d", xref);
			TextOut(hdc, 10, 400, str, strlen(str));
			Output(CONTROLPORT,0); //set the mode of LPT1 to write mode
			break;
		case 's': case 'S':			//Pressing 's' or 'S' halts all operations
			greenlight = 0;
			Output(DATAPORT,0);
			break;
		case 'q': case 'Q':
			PostQuitMessage(0);
			ReleaseDC(hwnd, hdc);
		default:
			greenlight = greenlight;
	  }
	  ReleaseDC(hwnd, hdc);
	  break;


    case WM_RBUTTONDOWN: // Clicking right mouse button clears some data
      hdc = GetDC(hwnd);
	  TextOut(hdc, 10, 100, clr, strlen(clr));
	  TextOut(hdc, 10, 200, clr, strlen(clr));
	  TextOut(hdc, 10, 230, clr, strlen(clr));
	  TextOut(hdc, 100, 400, clr, strlen(clr));
      ReleaseDC(hwnd, hdc);
      break;

    
	case WM_LBUTTONDOWN: // Clicking left mouse button closes the window (terminates operations)
      hdc = GetDC(hwnd);
	  PostQuitMessage(0);
      ReleaseDC(hwnd, hdc);
      break;

	
	case WM_MOUSEMOVE:  // Processing pointer motion
	  hdc = GetDC(hwnd);
	  if (greenlight == 1)
	  {
		  /* Just Displaying */
		  TextOut(hdc, 10, 50, clr, strlen(clr));
		  sprintf(str, "Time passed is %f seconds", (float)timer.time()/1000);
		  TextOut(hdc, 10, 50, str, strlen(str));
		  
		  /* Sampling begins here */
		  if (timer.sample(SamplingTime))
		  {
			BOOL delta_t=(long)timer+SamplingTime;
			x[0]=x[1];
			x[1]=LOWORD(lParam)-xref;
			//theta

			TextOut(hdc, 10, 200, clr, strlen(clr));
			sprintf(str, "x[0] = %d", x[0]);
			TextOut(hdc, 100, 200, str, strlen(str));
			TextOut(hdc, 10, 230, clr, strlen(clr));
			sprintf(str, "x[1] = %d", x[1]);
			TextOut(hdc, 100, 230, str, strlen(str));

			TextOut(hdc, 100, 400, clr, strlen(clr));
			sprintf(str, "%d", delta_t);
			TextOut(hdc, 100, 400, str, strlen(str));
			TextOut(hdc, 10, 100, clr, strlen(clr));
			sprintf(str, "The angular velocity is %f pixels/sec", (float)(x[1]-x[0])/delta_t*1000);
			TextOut(hdc, 10, 100, str, strlen(str));
			//theta_dot

			/* won't work here because it will only enter here if you move the mouse */
			clock.reset();
			if (LOWORD(lParam)-xref > 0)
			{ /* move motor clockwise */	}

			if (LOWORD(lParam)-xref < 0)
			{/* move motor counter-clockwise */}
		  }
	  }
	  x[2]=LOWORD(lParam);		//Set x-coordinate of reference point
	  TextOut(hdc, 10, 10, clr, strlen(clr));
	  sprintf(str, "Mouse coordinates are at (%d, %d)", LOWORD(lParam), HIWORD(lParam));
	  TextOut(hdc, 10, 10, str, strlen(str));

	  /* Calculating the desired force (PID) */
		//float F_desired = KP*(0-theta) + KD*theta_dot + KI*

	  /* Motor commands corresponding to F_desired go here */

	  ReleaseDC(hwnd,hdc);
	  break;


    case WM_DESTROY: // Terminate the program
	  PostQuitMessage(0);
      break;


    default:
	   /* Let Windows 98 process any messages not specified in
         the preceding switch statement. */
      return DefWindowProc(hwnd, message, wParam, lParam);
  }
  return 0;
}
Here is the code for Clock.h:

Code:
MMRESULT begin = timeBeginPeriod(1);
MMRESULT end = timeEndPeriod(2);

#define ERR 10 /* Be careful!! You don't want this to be too fast OR TOO SLOW!! */

class Clock
{
	private:
		long timestarted, center;		//time started (in seconds)
		bool obtainedOneSample;
	public:
		Clock();
		bool sample(const short&);
		VOID reset();
		VOID wait(const long&);		//wait a certain number of seconds
		long time();					//return the time in seconds since last reset
		operator long();
};

Clock::Clock()
{
	(*this).reset();
	obtainedOneSample = 0;
}

VOID Clock::reset()
{
	timestarted = timeGetTime();
	obtainedOneSample = 0;
	return;
}

long Clock::time()
{
	return timeGetTime()-timestarted;  //return time elapsed in seconds
}

VOID Clock::wait(const long &tsec)
{
	UINT beginning = timeGetTime();
	while ((beginning + tsec) > timeGetTime())
	{ /* wait */}
	return;
}

bool Clock::sample(const short &msec)
{
	long a=time()%msec;		//center = remainder

	if ((a >= 0 && a <= ERR) && obtainedOneSample==false)
	{
		obtainedOneSample=true;
		center=a;
		return true;
	}

	if (a > ERR)
		obtainedOneSample=false;

	return false;
}

Clock::operator long()
{
	return center;
}
My question is the following: is there no way to make the motor turn continuously as long as the displacement of the mouse position on the cursor is non-zero? What I have here does not work because the motor moves only when the mouse cursor changes (and I understand why). I am not concerned with the commands here; I have everything. I am just wondering WHERE to put them so that I get what I want. I doubt it is possible, but if you can find a way around it, please let me know. Thanks a million.

--Bill