hey i am trying to basically just make a button in my little console application which can be pressed. here's a snippet of what i use to get the cursor location
if (GetKeyState(VK_LBUTTON) < 0) {
{
POINT p;
if (GetCursorPos(&p))
{
cout<<"\nSCREEN\nx coord->";
cout<<p.x;
cout<<"\ny coord->";
cout<<p.y;
}
SetConsoleTitle("paint");
HWND hWnd;
hWnd = FindWindow(NULL, "paint");
if (ScreenToClient(hWnd, &p));
{
cout<<"\n\nWINDOW\nx coord->";
cout<<p.x;
cout<<"\ny coord->";
cout<<p.y;
}
int pwx;
int pwy;
pwx=p.x;
pwy=p.y;
this just prints the mouse coords relative to the screen and to the window to the console. i got a function in which i can draw the ascii-symbol 219 to basically "paint" in the console wherever the mouse is and whenever the left mousebutton is held down.
now:
how can i detect a click within console characters?
cout<<"press here to clear the screen->[x]";
the 2 square brackets and the 'x' should be pressable.
i can only search for pixels with the above code, but not for rows and columns..
is there a way to do this or am i completely off the track?
i'm using code::blocks
thanks for your help!
[ i just started programming like a week ago so be nice :) ]
Here is some console mouse handling code to study. It does somewhat what you wrote you needed, It works on Visual studio but i hope it is runnable on code::blocks too.
More info can be found here :https://msdn.microsoft.com/en-us/library/windows/desktop/ms685035(v=vs.85).aspx
#include <iostream>
#include <stdio.h>
#include <windows.h>
HANDLE hStdin;
DWORD fdwSaveOldMode;
void ErrorExit(LPSTR);
void KeyEventProc(KEY_EVENT_RECORD);
void MouseEventProc(MOUSE_EVENT_RECORD);
void ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);
void GetMousePosWin(MOUSE_EVENT_RECORD);
void gotoXY(int x, int y);
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
COORD CursorPosition;
int main()
{
DWORD cNumRead, fdwMode, i;
INPUT_RECORD irInBuf[128];
int counter=0;
// Get the standard input handle.
hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE)
ErrorExit("GetStdHandle");
// Save the current input mode, to be restored on exit.
if (! GetConsoleMode(hStdin, &fdwSaveOldMode) )
ErrorExit("GetConsoleMode");
// Enable the window and mouse input events.
fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
if (! SetConsoleMode(hStdin, fdwMode) )
ErrorExit("SetConsoleMode");
// Loop to read and handle the next 100 input events.
gotoXY(33,10);
std::cout << "\xDB Menu Item 1";
gotoXY(33,12);
std::cout << "\xDB Menu Item 2";
gotoXY(33,14);
std::cout << "\xDB Menu Item 3";
gotoXY(33,16);
std::cout << "\xDB Quit";
while (!counter)//++ <= 200)
{
// Wait for the events.
if (! ReadConsoleInput(
hStdin, // input buffer handle
irInBuf, // buffer to read into
128, // size of read buffer
&cNumRead) ) // number of records read
ErrorExit("ReadConsoleInput");
// Dispatch the events to the appropriate handler.
for (i = 0; i < cNumRead; i++)
{
switch(irInBuf[i].EventType)
{
case KEY_EVENT: // keyboard input
KeyEventProc(irInBuf[i].Event.KeyEvent);
break;
case MOUSE_EVENT: // mouse input
MouseEventProc(irInBuf[i].Event.MouseEvent);
gotoXY(33,8);
GetMousePosWin(irInBuf[i].Event.MouseEvent);
break;
case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing
ResizeEventProc( irInBuf[i].Event.WindowBufferSizeEvent );
break;
case FOCUS_EVENT: // disregard focus events
case MENU_EVENT: // disregard menu events
break;
default:
ErrorExit("Unknown event type");
break;
}
}
}
// Restore input mode on exit.
SetConsoleMode(hStdin, fdwSaveOldMode);
return 0;
}
VOID ErrorExit (LPSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
// Restore input mode on exit.
SetConsoleMode(hStdin, fdwSaveOldMode);
ExitProcess(0);
}
VOID KeyEventProc(KEY_EVENT_RECORD ker)
{
printf("Key event: ");
if(ker.bKeyDown)
printf("key pressed");
else printf("key released");
}
VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
#ifndef MOUSE_HWHEELED
#define MOUSE_HWHEELED 0x0008
#endif
gotoXY(33,6);
printf("Mouse event: ");
switch(mer.dwEventFlags)
{
case 0:
if(mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(46,6);
printf("left button pressed");
}
else if(mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
{
gotoXY(46,6);
printf("right button pressed");
}
else
{
gotoXY(46,6);
printf("button press");
}
break;
case DOUBLE_CLICK:
gotoXY(46,6);
printf("double click");
break;
case MOUSE_HWHEELED:
gotoXY(46,6);
printf("horizontal mouse wheel");
break;
case MOUSE_MOVED:
gotoXY(46,6);
printf("mouse moved");
//gotoXY(12,13);
//GetMousePosWin();
break;
case MOUSE_WHEELED:
gotoXY(46,6);
printf("vertical mouse wheel");
break;
default:
gotoXY(46,6);
printf("unknown");
break;
}
}
// get Window pos through windows api
void GetMousePosWin(MOUSE_EVENT_RECORD mer)
{
int x,y;
// creates the handle i need to use
//HANDLE OutputH;
INPUT_RECORD Inrec;
DWORD evRead;
HANDLE hStdIn;
DWORD dwMode;
bool Captured=false;
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
dwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
if( SetConsoleMode( hStdIn, dwMode | ENABLE_MOUSE_INPUT) == TRUE)
GetConsoleMode(hStdIn, &dwMode);
SetConsoleMode(hStdIn, (dwMode & (ENABLE_MOUSE_INPUT)));
// grab the handle to the console so i can use it
//OutputH = GetStdHandle(STD_OUTPUT_HANDLE);
//printf("Strated"); //Debug line.
do
{
PeekConsoleInput(hStdIn, &Inrec, 1, &evRead);
if( evRead )
{
ReadConsoleInput(hStdIn, &Inrec, 1, &evRead);
x= Inrec.Event.MouseEvent.dwMousePosition.X ;
y= Inrec.Event.MouseEvent.dwMousePosition.Y ;
switch (Inrec.EventType )
{
case MOUSE_EVENT:
{
Captured = true;
gotoXY(33,8);
std::cout << "x-> " << x << " ";
gotoXY(43,8);
std::cout << "y-> " << y << " ";
break;
}
}
}
}while(!Captured);
if((x==33 && y==10) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(47,10);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked menu one";
Sleep(1200);
gotoXY(47,10);
std::cout << " ";
gotoXY(33,21);
std::cout << " ";
}
if((x==33 && y==12) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(47,12);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked menu two";
Sleep(1200);
gotoXY(47,12);
std::cout << " ";
gotoXY(33,21);
std::cout << " ";
}
if((x==33 && y==14) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(47,14);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked menu three";
Sleep(1200);
gotoXY(47,14);
std::cout << " ";
gotoXY(33,21);
std::cout << " ";
}
if((x==33 && y==16) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(40,16);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked Quit";
Sleep(1200);
gotoXY(40,16);
std::cout << " ";
gotoXY(28,21);
exit(0);
}
}
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr)
{
printf("Resize event\n");
printf("Console screen buffer is %d columns by %d rows.\n", wbsr.dwSize.X, wbsr.dwSize.Y);
}
void gotoXY(int x, int y)
{
CursorPosition.X = x;
CursorPosition.Y = y;
SetConsoleCursorPosition(console,CursorPosition);
}
Related
I was given a task and I made it a little more complicated by trying to write it in C++
My assignment:
Display on the screen hexadecimal codes of characters entered from the keyboard. Use characters R, L, Q, m,p and use these codes to start an Explorer program, indicate the path to a folder, create a text file, delete a file, close the current Explorer window, respectively.
#include <Windows.h>
#include <iostream>
#include <conio.h>
#include <shellapi.h>
#include <fstream>
using namespace std;
void create_file()
{
cout << "Enter file name: ";
char filename[21] = { 0 };
cin >> filename;
strcat_s(filename, ".txt");
FILE* file;
fopen_s(&file, filename, "w");
if (file != NULL)
{
cout << "File created\n";
fclose(file);
}
else
cout << "Error creating file\n";
}
void delete_file()
{
cout << "Enter name deleting file: ";
char filename[21] = { 0 };
cin >> filename;
if (remove(filename) != 0)
cout << "Error deleting file" << endl;
else
cout << "File sucsesfull deleted" << endl;
}
void open_folder()
{
cout << "Example folder path: D:\\Server\n";
TCHAR path[MAX_PATH];
cout << "Enter folder path: ";
wcin >> path;
try
{
ShellExecute(NULL, L"open", path, NULL, NULL, SW_SHOW);
}
catch (exception)
{
cout << "Can't open folder\n";
}
}
void symbol_output(int symb)
{
cout.unsetf(ios::dec);
cout.setf(ios::hex);
cout << "Symbol " << (char)symb << ", hexadecimal: 0x";
cout << hex << symb << endl;
}
//int convert_10_to_16(int symb) //this function does not fit here
//{
// std::string d = "0123456789abcd";
// int num = symb;
// std::string res;
//
// while (num > 0)
// {
// res = d[num % 16] + res;
// num /= 16;
// }
std::cout << res << std::endl;
return num;
}
void close_window()
{
HWND hwnd;
hwnd = FindWindow(L"CabinetWClass", NULL);
if (hwnd != NULL)
SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
}
int main()
{
setlocale(LC_ALL, "");
int symb;
cout << " R - Open explorer\n L - Open folder\n Q - Creating text file\n m - Deleting text file\n p - Close the current explorer window\n";
cout << "Input e for exit" << endl;
do
{
cout << "Input Symbol: ";
symb = _getch();
symbol_output(symb);
symb = convert_10_to_16(symb);
switch (symb)
{
case 0x52: // R
ShellExecuteA(0, "open", "Explorer", NULL, NULL, SW_RESTORE);
break;
case 0x4c: // L
open_folder();
break;
case 0x51: // Q
create_file();
break;
case 0x6d: // m
delete_file();
break;
case 0x70: // p
close_window();
break;
}
} while (symb != 0x65); // e
}
int convert_10_to_16(int symb) this function is absolutely incorrect.
Be kind enough to point out my mistakes, back it up with your arguments or references such as why it should or should not be done.
Also, is there a hex type in C++ and can it be passed to Switch or do I have to use another option?
I tried to pass code without 0x in int format, but two letters include a number and a letter.
Frankly, I'm completely confused.
Using the "0x" before your hex will tell the compiler to create an int with that hexcode. Therefore, your switch statement would work without using convert_10_to_16 at all because the compiler is already making the conversion for your hexcodes.
int main()
{
setlocale(LC_ALL, "");
int symb;
cout << " R - Open explorer\n L - Open folder\n Q - Creating text file\n m - Deleting text file\n p - Close the current explorer window\n";
cout << "Input e for exit" << endl;
do
{
cout << "Input Symbol: ";
symb = _getch();
symbol_output(symb);
switch (symb)
{
case 0x52: // R
ShellExecuteA(0, "open", "Explorer", NULL, NULL, SW_RESTORE);
break;
case 0x4c: // L
open_folder();
break;
case 0x51: // Q
create_file();
break;
case 0x6d: // m
delete_file();
break;
case 0x70: // p
close_window();
break;
}
} while (symb != 0x65); // e
}
Hope that helps!
First, I use Createprocess() to open all desired windows. (Not Listed)
After the successful opening of the processes I find with the FindWindow () and FindWindowEx() all available windows. (Listed)
Sometimes the function SetWindowPos() does not work properly. A few windows were sorted out a few not. But this case does not always occur!
For improvements I always have an open ear!
//Some Variables comming from other code : numberOfWindows / numberOfStartedWindows
//Variables
bool trigger = true;
bool targetProcess = true;
HWND hwnd, hwndChilds = NULL;
int targetsFound = 0;
int targetsFoundMath = 0;
bool searchWindows = true;
//Start targetProcess
while (targetProcess) {
//If targetsFround == numberOfWindows then exit targetProcess.
if (targetsFound == numberOfWindows)
{
targetProcess = false;
}
//If all Windows are Started then start search loop
if (numberOfStartedWindows == numberOfWindows)
{
trigger = false;
}
//We starting search loop...
if (!trigger && targetProcess) {
//Find the Main Window.
hwnd = FindWindow(0, _T("World of Warcraft"));
if (hwnd)
{
targetsFound += 1;
//Set Window Foreground and call SetWindowPos to change Position
if (SetForegroundWindow(hwnd)) {
if (!SetWindowPos(hwnd, HWND_TOP, 0, 0, 1920, 800, SWP_SHOWWINDOW))
{
cout << "Error: HWND Failed with SETWINDOWPOS" << endl;
}
}
//Store HWND in StoreWindows
StoreWindows.emplace_back(hwnd);
//Now we search for child Windows
while (searchWindows)
{
//do it if targetsFound not numberOfWindows
if (targetsFound != numberOfWindows)
{
//Get Child Window
hwndChilds = FindWindowEx(NULL, hwnd, NULL, _T("World of Warcraft"));
if (hwndChilds != NULL)
{
//Little Math for Position
targetsFoundMath = (targetsFound - 1) * 384;
//if window in foreground SetWindowPos.
if(SetForegroundWindow(hwndChilds)){
if (!SetWindowPos(hwndChilds, HWND_TOP, targetsFoundMath, 800, 384, 280, SWP_SHOWWINDOW))
{
cout << "Error: HWNDChilds Failed with SETWINDOWPOS" << endl;
}
}
/*targetsFound += 1;
StoreWindows.emplace_back(hwndChilds);*/
//If all targetsFound then quit this loop after finish
if (targetsFound == numberOfWindows) {
searchWindows = false;
cout << "false" << targetsFound << endl;
}
//StoreChild Window and Add targetsfround +1
targetsFound += 1;
StoreWindows.emplace_back(hwndChilds);
}
else {
searchWindows = false;
cout << "no more child objects found!" << endl;
}
}
else
{
searchWindows = false;
}
}
}
}
}
cout << "Window Size: " << StoreWindows.size() << endl;
Funny when I debugs:
RECT debugRect;
for (int x = 0; x < StoreWindows.size(); x++)
{
GetClientRect(StoreWindows[x], &debugRect);
cout << debugRect.left << " " << debugRect.right<< " " << debugRect.bottom<< " " << debugRect.top << endl;
//debugRect.right = breite vom fenster // debugRect.bottom = Höhe
}
The output from the Position looks good but the Window isnt on the right place :/
Debug:
Im out of ideas and hope you can help me! If you need more explanations, do not hesitate to ask.
With problems it looks so..
If everything goes without problems it looks like this:
The problem was the duplicate (same) window partial to be found. Because the start process takes longer than the Find Func. Now i have Fixxed the loop. (Its wait now for all success windows.)
bool mainWindow = false;
bool searchHwndStrike = false;
int targetResult = 0;
while (true)
{
//Search first Window
if (!mainWindow) {
hwnd = FindWindow(0, _T("World of Warcraft"));
if (hwnd != NULL)
{
if (SetForegroundWindow(hwnd)) {
if (!SetWindowPos(hwnd, HWND_TOP, 0, 0, 1920, 800, SWP_SHOWWINDOW))
{
cout << "Error: HWND Failed with SETWINDOWPOS" << endl;
}
}
cout << "Main window found." << endl;
mainWindow = true;
StoreWindows.emplace_back(hwnd);
}
}else {
if (StoreWindows.size() < numberOfWindows) {
hwnd = FindWindowEx(NULL, hwnd, NULL, _T("World of Warcraft"));
if (hwnd != NULL)
{
for (int x = 0; x < StoreWindows.size(); x++)
{
if (StoreWindows[x] == hwnd)
{
searchHwndStrike = true;
}
}
if (!searchHwndStrike)
{
cout << "Child window found." << endl;
cout << targetResult << endl;
targetResult = (StoreWindows.size()-1) * 384;
//if window in foreground SetWindowPos.
if (SetForegroundWindow(hwnd)) {
if (!SetWindowPos(hwnd, HWND_TOP, targetResult, 800, 384, 280, SWP_SHOWWINDOW))
{
cout << "Error: HWNDChilds Failed with SETWINDOWPOS" << endl;
}
}
StoreWindows.emplace_back(hwnd);
}
searchHwndStrike = false;
}
}
else {
break;
}
}
}
cout << StoreWindows.size() << endl;
I need to write a program which programmatically changes the Landscape mode to Portrait of a touchscreen in Windows 7. The resolution is 1920 x 1080 and I thought I could switch the 1920 with the 1080 and use ChangeDisplaySettings or ChangeDisplaySettingsEx to make the change. but it doesn't work.
Windows CE has some sort of rotate feature, so I tried that. as in:
devmode.dmFields = DM_DISPLAYORIENTATION;
devmode.dmDisplayOrientation = DMDO_90;
ChangeDisplaySettingsEx(NULL,&devmode,NULL,CDS_RESET,NULL);
But that didn't work on a normal test desktop PC.
I can do this through Control Panel, Display, Screen Resolution, choose Portrait, so should I not be able to do via Windows API?
How can I make this change in code?
EDIT
I tried this code, but I get DISP_CHANGE_BADMODE returned by ChangeDisplaySettings.
#include <Windows.h>
#include <iostream>
int main() {
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
std::cout << "Orientation\n";
switch(dm.dmDisplayOrientation) {
case DMDO_DEFAULT: std::cout << "DMDO_DEFAULT\n"; break;
case DMDO_90: std::cout << "DMDO_90\n"; break;
case DMDO_180: std::cout << "DMDO_180\n"; break;
case DMDO_270: std::cout << "DMDO_270\n"; break;
}
std::cout << "Panning height: " << dm.dmPanningHeight << '\n'
<< "Panning width: " << dm.dmPanningWidth << '\n';
std::cout << "Colour resolution: " << dm.dmBitsPerPel << " bits per pixel\n";
std::cout << "Height in pixels: " << dm.dmPelsHeight << '\n';
std::cout << "Width in pixels: " << dm.dmPelsWidth << '\n';
if(dm.dmPelsHeight > dm.dmPelsWidth) {
std::cout << "Screen should be rotated 90 degrees\n";
std::cout << "Do you want to rotate display 90 degrees? (y or n)\n";
char ch;
std::cin >> ch;
if(ch == 'y') {
// swap height and width
DWORD tmp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = tmp;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
// determine new orientation
switch (dm.dmDisplayOrientation)
{
case DMDO_DEFAULT:
dm.dmDisplayOrientation = DMDO_270;
break;
case DMDO_270:
dm.dmDisplayOrientation = DMDO_180;
break;
case DMDO_180:
dm.dmDisplayOrientation = DMDO_90;
break;
case DMDO_90:
dm.dmDisplayOrientation = DMDO_DEFAULT;
break;
default:
// unknown orientation value
// add exception handling here
break;
}
LONG ret = ChangeDisplaySettings(&dm, CDS_TEST); //0);
std::cout << "ChangeDisplaySettings returned " << ret << '\n';
switch(ret) {
case DISP_CHANGE_SUCCESSFUL: std::cout << "display successfully changed\n"; break;
case DISP_CHANGE_BADDUALVIEW: std::cout << "The settings change was unsuccessful because the system is DualView capable\n"; break;
case DISP_CHANGE_BADFLAGS: std::cout << "An invalid set of flags was passed in.\n"; break;
case DISP_CHANGE_BADMODE: std::cout << "The graphics mode is not supported.\n"; break;
case DISP_CHANGE_BADPARAM: std::cout << "An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n"; break;
case DISP_CHANGE_FAILED: std::cout << "The display driver failed the specified graphics mode.\n"; break;
case DISP_CHANGE_NOTUPDATED: std::cout << "Unable to write settings to the registry.\n"; break;
case DISP_CHANGE_RESTART: std::cout << "The computer must be restarted for the graphics mode to work.\n"; break;
}
}
}
else
std::cout << "Screen orientation is just fine\n";
}
}
I saw an article on the web indicating that possibly it couldn't be done. But this code works.
#include <Windows.h>
#include <iostream>
int main(int argc, char* argv[]) {
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
// only change first/default display (index=0)
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
std::cout << "Current orientation\n";
switch(dm.dmDisplayOrientation) {
case DMDO_DEFAULT: std::cout << "DMDO_DEFAULT\n"; break;
case DMDO_90: std::cout << "DMDO_90\n"; break;
case DMDO_180: std::cout << "DMDO_180\n"; break;
case DMDO_270: std::cout << "DMDO_270\n"; break;
}
std::cout << "Panning height: " << dm.dmPanningHeight << '\n'
<< "Panning width: " << dm.dmPanningWidth << '\n';
std::cout << "Colour resolution: " << dm.dmBitsPerPel << " bits per pixel\n";
std::cout << "Height in pixels: " << dm.dmPelsHeight << '\n';
std::cout << "Width in pixels: " << dm.dmPelsWidth << '\n';
if(argc != 2) {
std::cout << "Usage: rotate_screen <angle>. Angle values: 0, 90, 180, 270. Angles are rotation clockwise. Use 0 to revert back\n";
exit(0);
}
// parse parameter
int rotate = atoi(argv[1]); // should do something better and safer here
if(rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
std::cout << "incorrect rotation selected\n";
}
else {
// swap height and width
DWORD tmp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = tmp;
// select fields which have changed
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYORIENTATION;
// set angle
switch(rotate) {
case 0: dm.dmDisplayOrientation = DMDO_DEFAULT; break;
case 90: dm.dmDisplayOrientation = DMDO_90; break;
case 180: dm.dmDisplayOrientation = DMDO_180; break;
case 270: dm.dmDisplayOrientation = DMDO_270; break;
default:
std::cout << "Something went wrong, aborting\n";
exit(0);
}
LONG ret = ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, NULL); //CDS_RESET, NULL); //0);
std::cout << "ChangeDisplaySettingsEx returned " << ret << '\n';
switch(ret) {
case DISP_CHANGE_SUCCESSFUL: std::cout << "display successfully changed\n"; break;
case DISP_CHANGE_BADDUALVIEW:
std::cout << "The settings change was unsuccessful because the system is DualView capable\n";
break;
case DISP_CHANGE_BADFLAGS: std::cout << "An invalid set of flags was passed in.\n"; break;
case DISP_CHANGE_BADMODE: std::cout << "The graphics mode is not supported.\n"; break;
case DISP_CHANGE_BADPARAM: std::cout << "An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n"; break;
case DISP_CHANGE_FAILED: std::cout << "The display driver failed the specified graphics mode.\n"; break;
case DISP_CHANGE_NOTUPDATED: std::cout << "Unable to write settings to the registry.\n"; break;
case DISP_CHANGE_RESTART: std::cout << "The computer must be restarted for the graphics mode to work.\n"; break;
}
}
} // enum worked
}
I am doing one of my first projects on SFML C++ and im trying to combine things now.
What im trying to do is having my Circle which i made with :
sf::CircleShape shape(50);
shape.setPosition(800, 450);
and
shape.setFillColor(sf::Color(100, 250, 50));
now i am trying to move it using W, A, S, D or arrow keys.
But i am not sure how to this, i tried several things like :
if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Up))
Sprite.Move(spriteSpeed * App.GetFrameTime(), 0);
But i am not sure what im doing wrong, can someone help me?
Thanks in advance!
This is the code i have atm.
#include "stdafx.h"
#include<SFML/Graphics.hpp>
#include<string>
#include<iostream>
int main()
{
//Here we declare the render window so we can talk to it.
sf::RenderWindow window;
//sf::VideoMode is to set the size of the window
//The seconds parameter (the string) is for setting the title
//The style is to show/hide the close button and the title bar, or to set full screen
window.create(sf::VideoMode(1600, 900), " My First SFML Game", sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize);
//----------------------------------wait for a key to be pressed-------------------------------------
//This shows a message that you should press a key
/*std::cout << "Press a key to continue." << std::endl;*/
//---------------------------------------------------------------------------------------------------
//----------------------------------Showing a message------------------------------------------------
//Define the messages that will be showed, and the display text
std::string message = "Hello my name is Jean-Paul van Houten";
std::string display = "";
int index = 0;
window.setKeyRepeatEnabled(false);
//----------------------------------------------------------------------------------------------------
sf::CircleShape shape(50);
shape.setPosition(800, 450);
//this while loop will only be called if the window is open.
while(window.isOpen())
{
//Define the event variable
sf::Event eventSF;
//Check if there is an event
while(window.pollEvent(eventSF))
{
shape.setFillColor(sf::Color(100, 250, 50));
//shape.setPosition(eventSF.mouseMove.x 0 sha,eventSF.mouseMove.y);
window.clear();
switch(eventSF.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::MouseEntered:
std::cout << "Mouse within screen bounds" << std::endl;
break;
case sf::Event::MouseLeft:
std::cout << "Mouse outisde the screen bounds" << std::endl;
break;
case sf::Event::MouseMoved:
std::cout << "X: " << eventSF.mouseMove.y << " Y: " << eventSF.mouseMove.y << std::endl;
break;
case sf::Event::MouseButtonPressed:
if(eventSF.mouseButton.button == sf::Mouse::Left)
std::cout << "Left Button Pressed At: X: " << eventSF.mouseButton.x << " Y: " << eventSF.mouseButton.y << std::endl;
break;
case sf::Event::MouseWheelMoved:
std::cout << "Scrolled: " << eventSF.mouseWheel.delta << std::endl;
break;
case sf::Event::GainedFocus:
std::cout << "Window Active" << std::endl;
break;
case sf::Event::LostFocus:
std::cout << "Window Not Active" << std::endl;
break;
case sf::Event::Resized:
std::cout << "Width: " << eventSF.size.width << " Height: " << eventSF.size.height << std::endl;
break;
case sf::Event::TextEntered:
if(eventSF.text.unicode != 8)//(eventSF.text.unicode >= 33 && eventSF.text.unicode <= 126) //This is to only include the characters between the number, now we use punctuation and letters.
std::cout << (char)eventSF.text.unicode;
else if(eventSF.text.unicode == 8)
display = display.substr(0, display.length() - 1);
system("cls");
std::cout << display;
break;
}
window.draw(shape);
//If you release a key
if(eventSF.type == sf::Event::KeyReleased)
{
//and this key is the enter key
if(eventSF.key.code == sf::Keyboard::Return)
{
display += message[index];
index ++;
system("cls"); //CLS on windows, clear on mac/linux
std::cout << display;
}
}
}
window.display();
}
}
First, you have to add the KeyPressed event handling inside the event poll switch, and inside, the code to move your sprite
switch(eventSF.type)
{
[...]
case sf::Event::KeyPressed:
if(eventSF.key.code == sf::Keyboard::Up)
{
shape.move(0, 1)
}
break;
}
Also,
shape.setFillColor(sf::Color(100, 250, 50));
shouldn't be inside the game loop.
And this
window.clear();
window.draw(shape);
window.display();
should be outside the event poll loop:
while(window.isOpen())
{
//Define the event variable
sf::Event eventSF;
//Check if there is an event
while(window.pollEvent(eventSF))
{
[...]
}
window.clear();
window.draw(shape);
window.display();
}
How to get mouse and keyboard inputs in windows c++ console application?
Is there any callback which we can register to get the input?
Also using ReadConsoleInput API is a blocking call , so to keep getting inputs and do background tasks i need to use threads. Are there any non blocking APIS to get the input
Looks like PeekConsoleInput is non-blocking so if you want to poll periodically you can use that and only call ReadConsoleInput to after you know there is input available.
There's also GetNumberOfConsoleInputEvents .
There's GetAsyncKeyState, which is both for the keyboard and the mouse.
Use the consoles own event handler for keyboard and mouse - ReadConsoleInput( )
Read more here https://msdn.microsoft.com/en-us/library/windows/desktop/ms685035(v=vs.85).aspx
#include <iostream>
#include <stdio.h>
#include <windows.h>
HANDLE hStdin;
DWORD fdwSaveOldMode;
void ErrorExit(LPSTR);
void KeyEventProc(KEY_EVENT_RECORD);
void MouseEventProc(MOUSE_EVENT_RECORD);
void ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);
void GetMousePosWin(MOUSE_EVENT_RECORD);
void gotoXY(int x, int y);
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
COORD CursorPosition;
int main()
{
DWORD cNumRead, fdwMode, i;
INPUT_RECORD irInBuf[128];
int counter=0;
// Get the standard input handle.
hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE)
ErrorExit("GetStdHandle");
// Save the current input mode, to be restored on exit.
if (! GetConsoleMode(hStdin, &fdwSaveOldMode) )
ErrorExit("GetConsoleMode");
// Enable the window and mouse input events.
fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
if (! SetConsoleMode(hStdin, fdwMode) )
ErrorExit("SetConsoleMode");
// Loop to read and handle the next 100 input events.
gotoXY(33,10);
std::cout << "\xDB Menu Item 1";
gotoXY(33,12);
std::cout << "\xDB Menu Item 2";
gotoXY(33,14);
std::cout << "\xDB Menu Item 3";
gotoXY(33,16);
std::cout << "\xDB Quit";
while (!counter)//++ <= 200)
{
// Wait for the events.
if (! ReadConsoleInput(
hStdin, // input buffer handle
irInBuf, // buffer to read into
128, // size of read buffer
&cNumRead) ) // number of records read
ErrorExit("ReadConsoleInput");
// Dispatch the events to the appropriate handler.
for (i = 0; i < cNumRead; i++)
{
switch(irInBuf[i].EventType)
{
case KEY_EVENT: // keyboard input
KeyEventProc(irInBuf[i].Event.KeyEvent);
break;
case MOUSE_EVENT: // mouse input
MouseEventProc(irInBuf[i].Event.MouseEvent);
gotoXY(33,8);
GetMousePosWin(irInBuf[i].Event.MouseEvent);
break;
case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing
ResizeEventProc( irInBuf[i].Event.WindowBufferSizeEvent );
break;
case FOCUS_EVENT: // disregard focus events
case MENU_EVENT: // disregard menu events
break;
default:
ErrorExit("Unknown event type");
break;
}
}
}
// Restore input mode on exit.
SetConsoleMode(hStdin, fdwSaveOldMode);
return 0;
}
VOID ErrorExit (LPSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
// Restore input mode on exit.
SetConsoleMode(hStdin, fdwSaveOldMode);
ExitProcess(0);
}
VOID KeyEventProc(KEY_EVENT_RECORD ker)
{
printf("Key event: ");
if(ker.bKeyDown)
printf("key pressed");
else printf("key released");
}
VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
#ifndef MOUSE_HWHEELED
#define MOUSE_HWHEELED 0x0008
#endif
gotoXY(33,6);
printf("Mouse event: ");
switch(mer.dwEventFlags)
{
case 0:
if(mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(46,6);
printf("left button pressed");
}
else if(mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
{
gotoXY(46,6);
printf("right button pressed");
}
else
{
gotoXY(46,6);
printf("button press");
}
break;
case DOUBLE_CLICK:
gotoXY(46,6);
printf("double click");
break;
case MOUSE_HWHEELED:
gotoXY(46,6);
printf("horizontal mouse wheel");
break;
case MOUSE_MOVED:
gotoXY(46,6);
printf("mouse moved");
//gotoXY(12,13);
//GetMousePosWin();
break;
case MOUSE_WHEELED:
gotoXY(46,6);
printf("vertical mouse wheel");
break;
default:
gotoXY(46,6);
printf("unknown");
break;
}
}
// get Window pos through windows api
void GetMousePosWin(MOUSE_EVENT_RECORD mer)
{
int x,y;
// creates the handle i need to use
//HANDLE OutputH;
INPUT_RECORD Inrec;
DWORD evRead;
HANDLE hStdIn;
DWORD dwMode;
bool Captured=false;
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
dwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
if( SetConsoleMode( hStdIn, dwMode | ENABLE_MOUSE_INPUT) == TRUE)
GetConsoleMode(hStdIn, &dwMode);
SetConsoleMode(hStdIn, (dwMode & (ENABLE_MOUSE_INPUT)));
// grab the handle to the console so i can use it
//OutputH = GetStdHandle(STD_OUTPUT_HANDLE);
//printf("Strated"); //Debug line.
do
{
PeekConsoleInput(hStdIn, &Inrec, 1, &evRead);
if( evRead )
{
ReadConsoleInput(hStdIn, &Inrec, 1, &evRead);
x= Inrec.Event.MouseEvent.dwMousePosition.X ;
y= Inrec.Event.MouseEvent.dwMousePosition.Y ;
switch (Inrec.EventType )
{
case MOUSE_EVENT:
{
Captured = true;
gotoXY(33,8);
std::cout << "x-> " << x << " ";
gotoXY(43,8);
std::cout << "y-> " << y << " ";
break;
}
}
}
}while(!Captured);
if((x==33 && y==10) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(47,10);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked menu one";
Sleep(1200);
gotoXY(47,10);
std::cout << " ";
gotoXY(33,21);
std::cout << " ";
}
if((x==33 && y==12) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(47,12);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked menu two";
Sleep(1200);
gotoXY(47,12);
std::cout << " ";
gotoXY(33,21);
std::cout << " ";
}
if((x==33 && y==14) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(47,14);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked menu three";
Sleep(1200);
gotoXY(47,14);
std::cout << " ";
gotoXY(33,21);
std::cout << " ";
}
if((x==33 && y==16) && mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
gotoXY(40,16);
std::cout << "\xFB";
gotoXY(33,21);
std::cout << "You picked Quit";
Sleep(1200);
gotoXY(40,16);
std::cout << " ";
gotoXY(28,21);
exit(0);
}
}
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr)
{
printf("Resize event\n");
printf("Console screen buffer is %d columns by %d rows.\n", wbsr.dwSize.X, wbsr.dwSize.Y);
}
void gotoXY(int x, int y)
{
CursorPosition.X = x;
CursorPosition.Y = y;
SetConsoleCursorPosition(console,CursorPosition);
}