Can't get 'GetKeyState' to work..

Sep 20, 2011 at 2:30pm
I am trying to use 'GetKeyState' commands in my program, but when I try compiling, I get these link errors. I do not understand why, since I had downloaded another persons code using the same commands and it ran fine.

1>Qui Vive.obj : error LNK2028: unresolved token (0A0002AC) "extern "C" short __stdcall GetKeyState(int)" (?GetKeyState@@$$J14YGFH@Z) referenced in function "int __cdecl main(int)" (?main@@$$HYAHH@Z)
1>Qui Vive.obj : error LNK2019: unresolved external symbol "extern "C" short __stdcall GetKeyState(int)" (?GetKeyState@@$$J14YGFH@Z) referenced in function "int __cdecl main(int)" (?main@@$$HYAHH@Z)
1>C:\Users\whitenite1\Documents\Visual Studio 2008\Projects\Qui Vive\Debug\Qui Vive.exe : fatal error LNK1120: 2 unresolved externals


The code I'm trying to get working is:
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
do
{
	if(GetKeyState(VK_LEFT) <0)
	{
		if (col-1 >=0)
			{
				Go_Left(col,row);
			}
			else
			{
				gotoXY(29,25,"Can't Move There!");
				Sleep(500);
				gotoXY(29,25,"           ");
			}
	}
	if(GetKeyState(VK_RIGHT) <0)
	{
		if (col+1 <5)
			{
				Go_Right(col,row);
			}
			else
			{
				gotoXY(29,25,"Can't Move!");
				Sleep(500);
				gotoXY(29,25,"           ");
			}
	}				
	if(GetKeyState(VK_UP) <0)
	{
		if (row-1 >= 0)
			{
				Go_Up(col,row);
			}
			else
			{
				gotoXY(29,25,"Can't Move!");
				Sleep(500);
				gotoXY(29,25,"           ");
			}
	}
	if(GetKeyState(VK_DOWN) <0)
	{
		if (row+1 < 5)
			{
				Go_Down(col,row);
			}
			else
			{
				gotoXY(29,25,"Can't Move!");
				Sleep(500);
				gotoXY(29,25,"           ");
			}
	}

} while (!wins);

And why does it show only two extern errors, while I have four 'GetKeyState' checks?

Sep 20, 2011 at 2:33pm
what libs are you linking to? It might just show these two errors because sometimes duplicates get cut off.
Sep 20, 2011 at 2:47pm
@hanst99
Here are the #includes I am using:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdafx.h>
#include <stdio.h>
#include <ctime>
#include "conio.h"
#include <iomanip>
#include <string>
#include <iostream>
#include <windows.h>
#include <gotoXY.inc>  // a file I created to postion text at chosen locations
#include <Box.inc>       // a file I created to put a graphic box on screen. Have used in many of 
                                    // my programs I make.
using namespace std;
using namespace System;


Thanks for looking into it...
Sep 20, 2011 at 2:47pm
No, not what includes you are using. What libraries you are linking to.
Sep 20, 2011 at 3:11pm
Do you mean GetAsyncKeyState()?
Sep 20, 2011 at 4:26pm
Sep 20, 2011 at 4:43pm
@ultifinitus - No, the other program I checked out, used 'GetKeyState()'

Here is the program, in full, that compiles and runs using MS Visual C++ 2008 Express.

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Using ARROW keys.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <stdio.h>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <string>
#include <windows.h>

using namespace std;

void Draw(int, int, int, int, int , int  );
void gotoXY(int, int);
void gotoXY(int, int, string);

HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
COORD CursorPosition;

int main(void)
{
int x,y;
x=20;
y=10;
char yn = 'y';
int wins = 0;
gotoXY(10,6,"To move, use the arrow keys.");
Draw(2,15,9,15,12,0);
gotoXY(22,14,"o");
		do
		{
			if (x==22 && y==14)
			{ 
				gotoXY(19,12,"Yippee!!");
				gotoXY(18,13,"I'm HOME!!");
				wins = 1;
			}
			gotoXY(10,24);
			cout << "The 'X' is at column " << x-15 << " row " << y-9 << " "; 
			gotoXY(x,y,"X");
		
			//Movement by pressing the arrow keys
			if(GetKeyState(VK_LEFT)<0)
			{
				if (x-1>15)
				{
					gotoXY(x,y," ");
					x--;					
				}
				else
				{
					gotoXY(x-6,y,"Ouch!");
					Sleep(500);
					gotoXY(x-6,y,"     ");
				}
			}
			if(GetKeyState(VK_RIGHT)<0)
			{
				if (x+1< 29)
				{
					 gotoXY(x,y," ");	
					x++;
				}
				else
				{
					gotoXY(x+2,y,"Ouch!");
					Sleep(500);
					gotoXY(x+2,y,"     ");
				}				
			}
			if(GetKeyState(VK_UP)<0)
			{
				if (y-1>9)
				{
					gotoXY(x,y," ");	
					y--;
				}
				else
				{
					gotoXY(x-2,y-2,"Ouch!");
					Sleep(500);
					gotoXY(x-2,y-2,"     ");
				}
			}
			if(GetKeyState(VK_DOWN)<0)
			{
				if (y+1<20)
				{
					gotoXY(x,y," ");	
					y++;
				}
				else
				{
					gotoXY(x-2,y+2,"Ouch!");
					Sleep(500);
					gotoXY(x-2,y+2,"     ");
				}
			}
			if(GetKeyState('\x0D')<0)
			{
					gotoXY(x,y,"O");
					Sleep(800);
					gotoXY(x,y,"x");
			}
			Sleep(100);
		}while ( !wins );
gotoXY(10,22);
}

void Draw(int style, int col, int row, int length,int height, int shadow )
{
	// Draws a 1 or 2 line box 
	int a;
	style--;
	//style=b*6;
	char box[2][6];
	box[0][0] = '\xDA';
	box[0][1] = '\xBF';
	box[0][2] = '\xC0';
	box[0][3] = '\xD9';
	box[0][4] = '\xB3';
	box[0][5] = '\xC4';
	box[1][0] = '\xC9';
	box[1][1] = '\xBB';
	box[1][2] = '\xC8';
	box[1][3] = '\xBC';
	box[1][4] = '\xBA'; 
	box[1][5] = '\xCD';
	char tl,tr,bl,br,side,edge;
	tl = box[style][0];
	tr = box[style][1];
	bl = box[style][2];
	br = box[style][3];
	side = box[style][4];
	edge = box[style][5];

	string Line(length-2,edge);
	string Line2(length-2,' ');
	string Shadow(length,'\xB0');
	gotoXY(col,row);
	cout << tl << Line << tr;
	for (a = 1; a <height-1;a++)
	{
		gotoXY(col,row+a);
		cout << side << Line2 << side;
		if (shadow)
			cout << "\xB0";
	}
	gotoXY(col,(height+row)-1);
	cout << bl << Line << br;
	if (shadow)
	{
		cout << "\xB0";
		gotoXY(col+1,row+height , Shadow );
	}
}

void gotoXY(int x, int y) 
{ 
CursorPosition.X = x; 
CursorPosition.Y = y; 
SetConsoleCursorPosition(console,CursorPosition); 
}

void gotoXY(int x, int y, string text) 
{ 

CursorPosition.X = x; 
CursorPosition.Y = y; 
SetConsoleCursorPosition(console,CursorPosition);
cout << text;
}


@handt99
No extra libraries needed. And from what I understand, libraries are just compiled headers, which would be 'stdafx.h'. Anyway, that really isn't relevant, since the above program does work, but mine doesn't.

Note: Right now I'm running this out of a IDE, I'll be adding code to not close right after program ends
Sep 20, 2011 at 5:26pm
And from what I understand, libraries are just compiled headers,


Then your understanding is wrong. Look up what "library" means in the context.

This runs in VC++ Express because VC++ automatically adds a bunch of libraries required for windows programming to the list of libraries to be linked whenever you create a new project. If you run this from command line you'd have to link to those libraries manually, which you are quite apparently not doing.
Sep 20, 2011 at 7:23pm
@hanst99

Okay, but that still really doesn't explain why the 'Using ARROW Keys' program, works as is, but the other one, that pretty much follows the same format, doesn't.
Sep 20, 2011 at 7:33pm
You said you compiled one from the IDE and the other from the command line.

File->new -> project-> win32 -> win32 console application.

Copy& paste your code into that project.
Sep 20, 2011 at 10:23pm
Follow hanst99's last advice; it should work.

For clarification, there aren't a bunch of pre-included libraries in Visual Studio's C++ projects. I think they are just 3: user32.lib, kernel32.lib and advapi32.lib. I could be wrong about the last one; instead it may be the one for GDI, which I don't recall the name right now. The point is: They are just a few and are automatically included in the linking part if you compile from the IDE, and I think this is configurable, but don't ask me how/where. I don't know if they are included or not if you compile from the command line.

For future reference, MSDN Online tells you which library you need to properly link. Look up the function in MSDN, then go to the bottom under the "Requirements" section. You'll be told what header to #include and what library to link against in order to use that particular function.

You can automatically add libraries for the linker to use using the #pragma comment statement:

#pragma comment(lib, "advapi32.lib")
Sep 20, 2011 at 11:20pm
Actually, I have ONLY compiled in the IDE. And I did load it as a win32 Console. If I don't, I get errors saying 'console' not defined, etc. Well, I'm going to look into a different way of getting input from the keyboard. Anyone know of a simple way to check a key, and act on it, without hitting enter? I had used that way, with a 'Hex Program' I wrote, but lost the source code when the compiler wanted to update it, for some reason. I accidentally clicked on YES, and now I have a 6000 byte file that doesn't show any text, and won't load into the IDE. I still have the compiled program, and all that made it, except for the valid .cpp file. Thanks for your help..
Topic archived. No new replies allowed.