Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Program Crashes After Checking for Console Mouse/Keyboard Input
Index -> Programming, C++ -> C++ Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
HRI




PostPosted: Wed Apr 27, 2011 9:38 pm   Post subject: Program Crashes After Checking for Console Mouse/Keyboard Input

I use the GNU G++ compiler (default for C::B).

First of all, this is a small connect 4 game. What I'm trying to achieve is to let the user either press a key (continues when key hit is 1-7, ignores all others) or when they click inside the board on the column they want. It only crashes if I click in a valid position or press a valid key :/

It worked perfectly fine for just keyboard input with the following code:

c++:

char column = NULL; // used for the character the user inputs
cout << "Enter a column (1 to 7): "; // output prompt

while (column = getch()) // get key press
{
        if (int(column) >= 49 && int(column) <= 55) // if character is from 1 to 7
        {
            system ("cls"); // clear screen
            return int(column) - 49; // return 0 to 6, column entered minus 1
            break; // exit while loop
        } // end if
} // end while


Now please be aware that the following is a bit messy. I've just been adding, not cleaning until it works. Also, I'm pretty sure some of this is c, but checking where the mouse was and where it was when the left button was clicked worked like a charm in a test program I made.

c++:

//inputColumn()
{
    HANDLE hand = GetStdHandle (STD_INPUT_HANDLE); // used for the window handle
    INPUT_RECORD buffer [128]; // buffer to store records
    DWORD numRead; // number of records read
    HANDLE cursor = GetStdHandle (STD_OUTPUT_HANDLE); // handle to cursor (the flashing one)
    COORD point; // a point
    point.X = 0; // left column
    point.Y = 15; // past the other graphics

    POINT pos; // a point
    RECT rec; // 4 members: top, left, bottom, right (used for window position)
    HWND hwnd = GetConsoleWindow(); // get handle to console window (I wasn't sure if hand was this or not)

    GetCursorPos (&pos); // get mouse position (this is for experimenting where coords are for where to click)
    GetWindowRect (hwnd, &rec); // get window position

    string title = ::integerToString (pos.x - rec.left - 6); // title of window starts as x coordinate of cursor
    title += " | "; // add separator
    title += ::integerToString (pos.y - rec.top - 32); // add y coord
    SetConsoleTitle (title.c_str()); // set title

    SetConsoleMode (hand, ENABLE_MOUSE_INPUT); // allow mouse input
    SetConsoleCursorPosition (cursor, point); // set cursor position to just below all other text

    char column = NULL; // used for the character the user inputs
    cout << "Enter column (1 to 7): "; // output prompt

    while (1) // infinite loop
    {
        ReadConsoleInput (hand, buffer, 128, &numRead); // read input buffer

        for (int i = 0; i < numRead; ++i) // go through read records
        {
            switch (buffer[i].EventType) // make decision based on type of event
            {
                case MOUSE_EVENT: // if mouse event
                    MouseProc (buffer [i].Event.MouseEvent, column); // call mouse procedure
                    break; // exit switch

                case KEY_EVENT: // if keyboard event
                    KeyProc (buffer [i].Event.KeyEvent, column); // call keyboard procedure
                    break; // exit switch
            } // end switch
        } // end for

        if (int(column) >= 49 && int(column) <= 55) // if character is from 1 to 7
        {
            system ("cls"); // clear screen
            return int(column) - 49; // return 0 to 6, column entered minus 1
            break; // exit while loop
        } // end if
    } // end while
} // end function


c++:

// MouseProc (takes MOUSE_EVENT_RECORD and char & (the column))

    POINT pos; // a point
    RECT rec; // up until the switch is kind of left over from a point before
    HWND hwnd = GetConsoleWindow();

    GetCursorPos (&pos);
    GetWindowRect (hwnd, &rec);

    string title = ::integerToString (pos.x - rec.left - 6);
    title += " | ";
    title += ::integerToString (pos.y - rec.top - 32);
    SetConsoleTitle (title.c_str());

    switch (mouse.dwButtonState) // check state of mouse
    {
        case FROM_LEFT_1ST_BUTTON_PRESSED: // if left button pressed
        {
            int xCoord = pos.x - rec.left - 6; // xccord is where the mouse is relative to desktop minus window's left border minus 6 for the edge of window
            int yCoord = pos.y - rec.top - 32; // ycoord is mouse's y position minus top minus 32 for top edge

            if (xCoord > 23 && xCoord < 52 && yCoord < 153) // if mouse is in first column
            {
                column = '1'; // set value of column passed as argument to '1' (remember the user was pressing '1', not '0')
                return; // exit procedure
            } // end if

            if (xCoord > 52 && xCoord < 83 && yCoord < 153) // repeat the rest for other columns (and yes, I'm going to clean it up after)
            {
                column = '2';
                return;
            }

            if (xCoord > 83 && xCoord < 116 && yCoord < 153)
            {
                column = '3';
                return;
            }

            if (xCoord > 116 && xCoord < 148 && yCoord < 153)
            {
                column = '4';
                return;
            }

            if (xCoord > 148 && xCoord < 179 && yCoord < 153)
            {
                column = '5';
                return;
            }

            if (xCoord > 179 && xCoord < 209 && yCoord < 153)
            {
                column = '6';
                return;
            }

            if (xCoord > 209 && xCoord < 240 && yCoord < 153)
            {
                column = '7';
                return;
            }
            break;
        }
    }

    column = 1; // set column's int value to 1 if none of the above
}


c++:

// KeyProc (takes KEY_EVENT_RECORD and char &)

{
    if (key.bKeyDown) // if key was pressed
    {
        if (key.wVirtualKeyCode == 0x31) // if key code is code for '1'
        {
            column = '1'; // set column to '1'
            return; // exit function
        } // end if

        if (key.wVirtualKeyCode == 0x32) // repeat for other columns (I'm obviously planning on cleaning this one up after >.>)
        {
            column = '2';
            return;
        }

        if (key.wVirtualKeyCode == 0x33)
        {
            column = '3';
            return;
        }

        if (key.wVirtualKeyCode == 0x34)
        {
            column = '4';
            return;
        }

        if (key.wVirtualKeyCode == 0x35)
        {
            column = '5';
            return;
        }

        if (key.wVirtualKeyCode == 0x36)
        {
            column = '6';
            return;
        }

        if (key.wVirtualKeyCode == 0x37)
        {
            column = '7';
            return;
        }
    }

    else
    {
        column = 1; // set column to char (1) if none of the above
    }
}


Ask any questions you have. Basically the other one that worked drew an ASCII box in the middle of the console window and then checked the mouse like this one does and makes a message box upon clicking saying either that they clicked in the box or didn't click in the box. That one worked perfectly fine.

By crash I mean it comes up with the application error window with the option to send a report to Microsoft and returns 0xC0000005.

Thanks in advance for any help!



connect 4.png
 Description:
Picture of the game when choosing a column.
 Filesize:  8.54 KB
 Viewed:  7828 Time(s)

connect 4.png


Sponsor
Sponsor
Sponsor
sponsor
DemonWasp




PostPosted: Thu Apr 28, 2011 10:48 am   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

I'm no C++ expert, but shouldn't it be:

code:
*column = '1';


if you're trying to assign to the value the pointer points to?
crossley7




PostPosted: Sat Apr 30, 2011 7:00 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

I haven't done too many games with c++ as I tought myself it last semester and have mostly done dwite style problems and mathematics related programs (ie factoring), but I did write a chess program, and it may help and clean up you code a lot if you checked out SDL. It requires a download, but makes things easier specifically mouse events and there are easy tutorials on how to use it. It handles all events in 1 variable. I haven't used STD GUI so I can't really help you with the code other than to say trying to make a game that is run in the console is not very pleasing and limits what you can do with the appearance.

If you want to make a game look good, you may as well go all out. Sorry if this post is of no use
HRI




PostPosted: Sun May 01, 2011 7:42 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

Sorry I haven't been able to check this for so long.

@DemonWasp: What I'm doing when I'm specifying a char & parameter is telling the compiler to rather than make a copy of what gets sent to the function in the argument, send the actual object itself. In this case it would send the same char variable "column" that it uses in the other function and whatever changes are made to it are carried back. This is the way the whole connect 4 program is set up, passing along objects from function to function since I couldn't get declaring the objects I'd need in a namespace to work. I will try making it pointer-oriented though, and indeed, you are correct. The * dereferences it so that it pertains to the value contained in the address as opposed to the address itself. I think this is where the confusion lied as the & operator can also be used to reference the address of a variable, but in this case it is saying to pass by reference, rather than by value.

@crossley7: I haven't actually gotten into SDL yet, although I very much plan to in the near future! The reasoning behind this is that the main focus is to get the actual engine and the AI working before making it look nice. This was supposed to be a pretty simple approach to add a neat option to the game as we haven't done any graphics or anything of the sort yet in class and I've been exploring the Windows API in my spare time. We aren't getting marked on appearance, but we will try to get it looking good after the AI is done. We were initially thinking of linking it with a java application while this runs in the background, doing the processing. It's a neat idea, but learning a C++ graphics library could go a long way. I do agree with your logic though, as I often find myself adding every little thing to make it look/act as perfect as I can muster.
DemonWasp




PostPosted: Sun May 01, 2011 9:28 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

What I meant is that:

code:
column = '1';


is wrong because it's assigning the column pointer to be '1' (value 49, or 0x00000031). When you next try to dereference the column pointer after that, you're pointing at an invalid location because you've overwritten part of the pointer. This explains the crash, because you're making an invalid memory access (segmentation fault / violation).

The correct code, as I suggested in my first response, assigns the value of the char address that column points to. You could also use the (subtly different):

code:
column = &'1';


though I wouldn't recommend that as if you ever modify the value that column points to after such an assignment, you will hit a different kind of crash (modifying read-only memory).
HRI




PostPosted: Mon May 02, 2011 7:32 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

The weird thing about that is that I have most of my other functions taking arguments of char &, Board &, Game &, whatever it is I'm passing around, but maybe I never changed any of those without using a set function O_o.

I really could've sworn that when we learned about pass-by-value and pass-by-reference the following code worked (quick draft):
c++:

void addOne (int &);

int main()
{
  int x = 0;
  cout << x;
  addOne (x);
  cout << x;
}

void addOne (int &num)
{
  ++num;
}

c++:

output:
0
1


And using pointer logic, would this not be equivalent to:
c++:

void addOne (int *);

int main()
{
  int x = 0;
  cout << x;
  addOne (&x); // this is how microsoft does it i believe
  cout << x;
}

void addOne (int *num)
{
  ++*num;
}


What I'm saying is, when I pass in column, it should be passing that actual variable's value which can be changed as I please as if the function was not a function at all, but pasted into the other function where it is called. If the addOne example works (which I'm sure it did when I tried something of the sort) then this should work the same way. Anyways, I have a bit of time now that I'll try a couple things with it and let you know what happens.
HRI




PostPosted: Mon May 02, 2011 7:58 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

Ok, I changed the parameter to char *column, and every time column was assigned a value I put a * in front. Also, I put a & before the argument column for the two procedures. It's still doing the same thing.

It didn't compile by simply just putting a * in front because I believe there wasn't an address to begin with.

Think of it this way (forgetting about some certain syntax issues):
c++:

//pass-by-value
void addOne (MyInt num)
==
void addOne (MyInt *num = new MyInt) // creates new object of type MyInt to use in function
...
delete num;
----------------------

void addOne (MyInt &num)
==
void addOne (num) // I'm not absolutely solid on how the compiler keeps track of all the variables, but it would pass the actual variable address or whatever, instead of allocating a different memory block and deallocating it after


Next test, though I hate to say it, is not using new procedures for the events... duh duh duh
HRI




PostPosted: Mon May 02, 2011 8:10 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

Yeah, Windows doesn't like you taking out their procedures. I just succeeded in making the mouse input not work and the key input doing the same thing lol
Sponsor
Sponsor
Sponsor
sponsor
DemonWasp




PostPosted: Mon May 02, 2011 10:46 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

I haven't taken the time to decipher everything you said above. What you should be doing is:

code:

void addOne ( int *num ) {
    ++(*num);
}


Which you call by:
code:

int foo = 1;
addOne ( &foo );
// foo is now equal to 2

// OR
int *bar;
*bar = 3;
addOne ( bar );
// *bar is now equal to 4
HRI




PostPosted: Thu May 05, 2011 6:34 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

I tried changing everything to your first solution of having a pointer parameter and supplying an address argument, but the same thing happened.
HRI




PostPosted: Thu May 05, 2011 6:57 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

Welllll....... I just took this code, and drew a generic, empty board in a separate program and outputted the return value. Guess what, everything worked fine :s

So the issue then is not the way the functions take arguments or change the column, but how it is implemented within the game.

I'll get back if I notice anything else.



pointer and address function.cpp
 Description:
Working version in separate source code.

Download
 Filename:  pointer and address function.cpp
 Filesize:  7.42 KB
 Downloaded:  290 Time(s)

HRI




PostPosted: Thu May 05, 2011 8:03 pm   Post subject: RE:Program Crashes After Checking for Console Mouse/Keyboard Input

BREAKING NEWS:
I'm not quite sure how it got there, but
c++:

while (column = getch())

(which is the style I use for keyboard-only inputs) should be
c++:

while (1)

That explains why the mouse wasn't working at all and why the keyboard just ended up making it confused >.>

Now for some reason it's not adding any tokens... I hope that's an easy fix though!

EDIT:
It's still acting as if a token was dropped there, it's just not showing them. I think I'm close! That's a good thing if I plan to add mouse capabilities elsewhere. It could add so much spice to the program, and there's really not enough time to learn a graphics library. Still need to do the AI...

EDIT:
heh heh heh...must've accidentally changed where it outputs the character to a space when I was transferring that to the test program...
Stupid me >.>
Display posts from previous:   
   Index -> Programming, C++ -> C++ Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 12 Posts ]
Jump to:   


Style:  
Search: