General Windows API Problems (Visual C++)

I have been trying to test some things and I have recently run into a bizarre problem with outputting characters in a console application, among other problems. The code is a little long, but I really have no idea what is causing the problem and can not narrow it down so I included the whole code.

Main program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <iostream>
#include <ctime>
#include <windows.h>
#include "Coord.h"
//#define debug
using namespace std;

class target {
public:
  target();
  bool active;
  short x, y;
};

target::target() {
  active = true;
  x = 80;
  y = 30;
}

int main() {   
  //START Initialization
  int x = 0;
  int y = 0;
  int x2 = 0;
  int y2 = 0;
  long int points = 0;

  //Initialize rand
  time_t seconds;
  time(&seconds);
  srand((unsigned int) seconds);

  HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);

  //Cursor properties structure
  CONSOLE_CURSOR_INFO ConCurInf;  
  ConCurInf.dwSize = 10;
  //Invisible
  ConCurInf.bVisible = FALSE;
  //Set
  SetConsoleCursorInfo(stdOut, &ConCurInf);

  SMALL_RECT windowSize = {0, 0, 159, 60}; //Left, top, right, bottom coordinates
  // Change the console window size to the values specified in windowsize
  SetConsoleWindowInfo(stdOut, TRUE, &windowSize);
	
  //Create a COORD
  COORD bufferSize = {160, 61};
  // Change the screen buffer size to the values specified in buffersize
  SetConsoleScreenBufferSize(stdOut, bufferSize);
	
  SetConsoleTitle( TEXT("MouseTest") );
  HWND hWnd = FindWindow(NULL,TEXT("MouseTest"));
  ShowWindow(hWnd, SW_SHOWMAXIMIZED);

  //Stores cursor position
  POINT pos;
  //END Initialization

  target targets[10];

  while(true) {
    #ifndef debug
      xy(0, 0);//Output points
      cout << "Points: " << points;
    #endif

    for(int i = 0; i <= 10; i++) { //Outputs all targets
      xy(targets[i].x, targets[i].y);
      cout << "@";
    }
		
    //Gets the current cursor position
    GetCursorPos(&pos);

    #ifdef debug
      //x2 and y2 are the raw (x,y) values recieved
      x2 = pos.x;
      y2 = pos.y;
      xy(0, 0);
      cout << "x " << x2 << " y " << y2 << endl;
    #endif

    y = int (pos.y / 13.3); //Calculate approximate x and y positions
    x = int (pos.x / 7.99375);
    y += 1; //Add 1 to y to compensate for the title bar space

    #ifdef debug
      //Output the (x,y) coordinate the mouse is calculated to be on
      cout << "calculated x " << x << " y " << y << endl;
    #endif

    //Gives the player some leeway with a three space zone around the target that will count as touching it
    for(int i = 0; i <= 3; i++) { //Checks all x values within 3 spaces
      for(int n = 0; n <= 10; n++) { //Cycles through all targets
        if(x == targets[n].x + i || x == targets[n].x - i) {
	//If a target is within three spaces of the cursor on x axis, check y axis
          for(int i = 0; i <= 3; i++) { //Checks all y values within 3 spaces
            for(int n = 0; n <= 10; n++) { //Cycles through all targets
              if(y == targets[n].y + i || y == targets[n].y - i) {
                system("cls");
                targets[n].active = false;
		points += 315;
              }
            }
          }
        }
      }
    }

    for(int i = 0; i <= 10; i++) { //Moves each target and checks if they leave the screen or hit something
      targets[i].y += 1;
      if(targets[i].y >= 60)
        targets[i].active = false;
      
      for(int n = 0; n <= 10; n++) {
        if(targets[i].active == true && n != i) {
          if((targets[i].x == targets[n].x) && (targets[i].y == targets[n].y))
            targets[i].active = false;
        }
      }
    }

    for(int i = 0; i <= 10; i++) { //Respawns targets
      if(targets[i].active == false) {
        targets[i].x = rand() % 159;
        targets[i].y = rand() % 60;
        targets[i].active = true;
      }
    }
		
    Sleep(10);
    system("cls");
  }

  return 0;
}


and Coord.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef _COORD_H_
#define _COORD_H_

//COORD Header
//Requires included windows header
//Function xy moves the console application pointer to a specified coordinate


void xy(int column, int row) { //Reads passed in values for where to output text
	COORD coord;	//COORD structure
	coord.X = column;	//X coordinate to output at
	coord.Y = row; //Y coordinate to output at

	SetConsoleCursorPosition( //Sets console application to coordinates
	GetStdHandle( STD_OUTPUT_HANDLE ), coord);
}
#endif 


I have a few things I need help with.

1. I have found that GetCursorPos() will return an (x,y) coordinate of where the cursor is, on the whole screen, whereas I want an(x,y) coordinate of where the cursor is, on the console application screen only. I had bodged it with a quick fix of taking my screen resolution (1280 x 800), and dividing it by the dimensions of the console application. That is why you see y = int (pos.y / 13.3) and x = int (pos.x / 7.99375) (And yes I know this is not portable). This does not work all the time, due to the casting to integer, so I had to then fix the fix by checking to see if the cursor is in the general area of the target. I am sure there had to be another better way to do this with the windows API, but I have not found one yet. Does anyone know of a way to do what I want to accomplish?

2.The second problem I faced was that I wanted the screen to start out maximized, which I thought would work with this:
1
2
3
 SetConsoleTitle( TEXT("MouseTest") );
  HWND hWnd = FindWindow(NULL,TEXT("MouseTest"));
  ShowWindow(hWnd, SW_SHOWMAXIMIZED);

For some reason though, it is not working even though I am manually setting the title and getting a HWND from the exact same title. I was wondering if anyone knows what could be causing that to happen?

3. I at first had wanted each target object to start at a random spot by using rand() in the target::target constructor, but I found that putting a rand initialization outside of main() or another function would result in errors. Do I not need to give the rand initialization a gobal scope to use rand() in a class? Or it is just not possible to do? I have also found a problem in that because the clock is used as a seed, the program executes so fast that I often have multiple rand()s within less than a millisecond of each other, which causes them to produce similar values. Is there any way to prevent this other than using Sleep() to pause for a few milliseconds?

4. This one is just really bizarre. If you actually put this code into a project and run it, you will notice there are two targets(@ signs) that seem to "stick" to each other. They are side by side and move together without separating. I had even gone through twice in debug mode and checked every (x,y) coordinate in the array targets[], and there were no two (x,y) coordinates that were next to each other, yet on the console app. it showed them next to each other. No idea how this is happening at all.

Other than that, I would be glad if anyone would give me feedback on bad practices, ways to achieve better efficiency, etc., as I am still learning.

Thanks!
Last edited on
1. you may want to look at http://msdn.microsoft.com/en-us/library/ms684961(VS.85).aspx
(an also http://msdn.microsoft.com/en-us/library/ms683499(VS.85).aspx and http://msdn.microsoft.com/en-us/library/ms684239(VS.85).aspx of course)
2. you need SetConsoleDisplayMode (http://msdn.microsoft.com/en-us/library/ms686028(VS.85).aspx)
3. Keep your code in functions.
You don't really need to init rand to make it work...
About the clock: rand takes the time only once (line 32). Every other time, random number is based on previous randomized number.

Are you getting your output correctly?
I thought iostream doesn't work well with win api...
Thanks for your reply, but I do not really understand #1.
Can you show me a short example of how it is declared and used?

For #2 and 3 I found it worked with no problems!

And for #4 what would you suggest be used if not iostream? I do not know of another way to easily output to the the console.

EDIT: Fixed #4, for the sake of anyone else who is having problems, here is how I solved #4.

It was fixed by switching all the for loops from for(int i = 0; i <= 10; i++) to for(int i = 0; i <= 9; i++). This fixed the doubling problem.
Last edited on
here's a sample:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
#include<windows.h>
using namespace std;

int main(){
    HANDLE incon;
    incon = GetStdHandle(STD_INPUT_HANDLE);
    while(true){
        INPUT_RECORD ir;
        DWORD num;
        ReadConsoleInput(incon, &ir, 1, &num);
        if(ir.EventType == MOUSE_EVENT){
            cout<< ir.Event.MouseEvent.dwMousePosition.X << "  "
                << ir.Event.MouseEvent.dwMousePosition.Y << '\n';
        }
    }
    return 0;
}


dwMousePosition is a COORD of the square on which the mouse cursor is. Note that as more text is printed, Y coordinate will increase.
Thanks a lot! I have gotten it working perfectly.
Topic archived. No new replies allowed.