GUI Listboxes

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
peeves91
Posts: 8
Joined: Wed Jul 24, 2013 2:39 pm

GUI Listboxes

Post by peeves91 »

I'm trying to use the getSelected() function with my listbox, and every time I do it, I get this error:

Unhandled exception at 0x10010740 in dumb cake thing 2.exe: 0xC0000005: Access violation reading location 0x000000b1.

The code compiles fine, but when I actually select the item, this error is thrown. Here's my event receiver code:

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
    MyEventReceiver(SAppContext & context) : Context(context)
    {
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = false;
    }
 
    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_GUI_EVENT)
        {
            s32 id = event.GUIEvent.Caller->getID();
            IGUIEnvironment* env = Context.device->getGUIEnvironment();
            
            if (event.GUIEvent.EventType == EGET_LISTBOX_CHANGED)
            {
                Context.selected = Context.listbox->getSelected();
                return true;
            }
            switch(event.GUIEvent.EventType)
            {
            case EGET_SCROLL_BAR_CHANGED:
                if (id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
                {
                    s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
                    setSkinTransparency(pos, env->getSkin());
                }
                break;
            case EGET_BUTTON_CLICKED:
                switch(id)
                {
                case GUI_ID_QUIT_BUTTON:
                    Context.device->closeDevice();
                    return true;
 
                case GUI_ID_NEW_WINDOW_BUTTON:
                    {
                    Context.listbox->addItem(L"Window created");
                    Context.counter += 30;
                    if (Context.counter > 200)
                        Context.counter = 0;
 
                    IGUIWindow* window = env->addWindow(
                        rect<s32>(100 + Context.counter, 100 + Context.counter, 300 + Context.counter, 200 + Context.counter),
                        false, // modal?
                        L"Test window");
 
                    env->addStaticText(L"Please close me",
                        rect<s32>(35,35,140,50),
                        true, // border?
                        false, // wordwrap?
                        window);
                    }
                    return true;
 
                case GUI_ID_FILE_OPEN_BUTTON:
                    Context.listbox->addItem(L"File open");
                    // There are some options for the file open dialog
                    // We set the title, make it a modal window, and make sure
                    // that the working directory is restored after the dialog
                    // is finished.
                    env->addFileOpenDialog(L"Please choose a file.", true, 0, -1);
                    return true;
 
                default:
                    return false;
                }
                break;
 
            case EGET_FILE_SELECTED:
                {
                    // show the model filename, selected in the file dialog
                    IGUIFileOpenDialog* dialog =
                        (IGUIFileOpenDialog*)event.GUIEvent.Caller;
                    Context.listbox->addItem(dialog->getFileName());
                }
                break;
 
            default:
                break;
            }
        }
 
        // Remember whether each key is down or up
        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
        return false;
    }
 
    // This is used to check whether a key is being held down
    virtual bool IsKeyDown(EKEY_CODE keyCode) const
    {
        return KeyIsDown[keyCode];
    }
 
    SAppContext returnContext()
    {
        return Context;
    }
 
private:
    // We use this array to store the current state of each key
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
    SAppContext & Context;
};
I can't figure out why its throwing this error. Any help is appreciated.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: GUI Listboxes

Post by CuteAlien »

Maybe Context.listbox isn't correctly initialized? Can't tell from your code as that part is missing. But anyway - use the debugger! That's the tool you use to find out why it crashes. If you work with a IDE (like Code::Blocks or VisualStudio)you already have a debugger in there. All you have to do is compile with debug information and it will show you the exact line where it crashes and you can look at the values of every variable then.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
peeves91
Posts: 8
Joined: Wed Jul 24, 2013 2:39 pm

Re: GUI Listboxes

Post by peeves91 »

I was looking through that, but I still can't find the problem. Here's the full code of the entire program:

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <conio.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <ctime>
 
using namespace std;
 
using namespace irr;
using namespace core;
using namespace video;
using namespace gui;
 
const int screenx = 640;
const int screeny = 480;
const float refreshInterval = 500;
 
// Declare a structure to hold some context for the event receiver so that it
// has it available inside its OnEvent() method.
struct SAppContext
{
    IrrlichtDevice *device;
    s32 counter;
    IGUIListBox* listbox;
    int selected;
};
 
// Define some values that we'll use to identify individual GUI controls.
enum
{
    GUI_ID_QUIT_BUTTON = 101,
    GUI_ID_NEW_WINDOW_BUTTON,
    GUI_ID_FILE_OPEN_BUTTON,
    GUI_ID_TRANSPARENCY_SCROLL_BAR
};
 
void setSkinTransparency(s32 alpha, irr::gui::IGUISkin * skin)
{
    for (s32 i=0; i<irr::gui::EGDC_COUNT ; ++i)
    {
        video::SColor col = skin->getColor((EGUI_DEFAULT_COLOR)i);
        col.setAlpha(alpha);
        skin->setColor((EGUI_DEFAULT_COLOR)i, col);
    }
}
 
// gets the most recent task data from the command line
vector<core::stringw> refreshData()
{
    vector<core::stringw> mybuffer;
    FILE *pipe = _popen("tasklist", "r");
    char buffer[256];
    while (!feof(pipe))
    {
        if (fgets(buffer, 256, pipe) != NULL)
        {
 
        }
        mybuffer.push_back(buffer); 
    }
    _pclose(pipe);
    return mybuffer;
}
 
class MyEventReceiver : public IEventReceiver
{
public:
    MyEventReceiver(SAppContext & context) : Context(context)
    {
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = false;
    }
 
    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == EET_GUI_EVENT)
        {
            s32 id = event.GUIEvent.Caller->getID();
            IGUIEnvironment* env = Context.device->getGUIEnvironment();
            
            if (event.GUIEvent.EventType == EGET_LISTBOX_CHANGED)
            {
                Context.selected = Context.listbox->getSelected();
                return true;
            }
            switch(event.GUIEvent.EventType)
            {
            case EGET_SCROLL_BAR_CHANGED:
                if (id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
                {
                    s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
                    setSkinTransparency(pos, env->getSkin());
                }
                break;
            case EGET_BUTTON_CLICKED:
                switch(id)
                {
                case GUI_ID_QUIT_BUTTON:
                    Context.device->closeDevice();
                    return true;
 
                case GUI_ID_NEW_WINDOW_BUTTON:
                    {
                    Context.listbox->addItem(L"Window created");
                    Context.counter += 30;
                    if (Context.counter > 200)
                        Context.counter = 0;
 
                    IGUIWindow* window = env->addWindow(
                        rect<s32>(100 + Context.counter, 100 + Context.counter, 300 + Context.counter, 200 + Context.counter),
                        false, // modal?
                        L"Test window");
 
                    env->addStaticText(L"Please close me",
                        rect<s32>(35,35,140,50),
                        true, // border?
                        false, // wordwrap?
                        window);
                    }
                    return true;
 
                case GUI_ID_FILE_OPEN_BUTTON:
                    Context.listbox->addItem(L"File open");
                    // There are some options for the file open dialog
                    // We set the title, make it a modal window, and make sure
                    // that the working directory is restored after the dialog
                    // is finished.
                    env->addFileOpenDialog(L"Please choose a file.", true, 0, -1);
                    return true;
 
                default:
                    return false;
                }
                break;
 
            case EGET_FILE_SELECTED:
                {
                    // show the model filename, selected in the file dialog
                    IGUIFileOpenDialog* dialog =
                        (IGUIFileOpenDialog*)event.GUIEvent.Caller;
                    Context.listbox->addItem(dialog->getFileName());
                }
                break;
 
            default:
                break;
            }
        }
 
        // Remember whether each key is down or up
        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
        return false;
    }
 
    // This is used to check whether a key is being held down
    virtual bool IsKeyDown(EKEY_CODE keyCode) const
    {
        return KeyIsDown[keyCode];
    }
 
    SAppContext returnContext()
    {
        return Context;
    }
 
private:
    // We use this array to store the current state of each key
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
    SAppContext & Context;
};
 
int getPID(stringw line)
{
    for (int c = 1; c < line.size(); c++)
    {
        if (line.subString(c - 1, 1) == " " && (line.subString(c, 1) == "0" || line.subString(c, 1) == "1" || line.subString(c, 1) == "2" || line.subString(c, 1) == "3" || line.subString(c, 1) == "4" || line.subString(c, 1) == "5" || line.subString(c, 1) == "6" || line.subString(c, 1) == "7" || line.subString(c, 1) == "8" || line.subString(c, 1) == "9"))
        {
            for (int i = c; i < line.size(); i++)
            {
                if (line.subString(i + 1, 1) == " " && (line.subString(i, 1) == "0" || line.subString(i, 1) == "1" || line.subString(i, 1) == "2" || line.subString(i, 1) == "3" || line.subString(i, 1) == "4" || line.subString(i, 1) == "5" || line.subString(i, 1) == "6" || line.subString(i, 1) == "7" || line.subString(i, 1) == "8" || line.subString(i, 1) == "9"))
                {
                    for (int d = 0; d < 10000; d++)
                    {
                        if (core::stringw(d) == line.subString(c, i - c))
                        {
                            cout << d << endl;
                            return d;
                        }
                    }
                }
            }
        }
    }
}
 
int main()
{
    // sets up the irrlicht device and driver
    IrrlichtDevice *device = createDevice( video::EDT_SOFTWARE, dimension2d<u32>(screenx, screeny), 16, false, false, false, 0);
    IVideoDriver *driver = device->getVideoDriver();
    device->setResizable(true);
 
    // sets up the gui environment
    IGUIEnvironment *env = device->getGUIEnvironment();
    IGUIListBox *listbox = env->addListBox(rect<s32>(10, 10, screenx - 10, screeny - 10));
    vector<core::stringw> outputData;
 
    listbox->setSelected(10);
 
    // Store the appropriate data in a context structure.
    SAppContext context;
    context.device = device;
    context.counter = 0;
    context.listbox = listbox;
    context.selected = 0;
    MyEventReceiver receiver(context);
    device->setEventReceiver(&receiver);
 
    // the buffer array for taking stuff from the cmd line
    char buffer [256];
    
    while (device->run())
    {
        if (receiver.IsKeyDown(irr::KEY_F5))
        {
            outputData = refreshData();
            listbox->clear();
 
            // parses through the lines that the cmd returned and displays each one of them
            for (int c = 0; c < outputData.size(); c++)
                listbox->addItem(stringw(outputData[c]).c_str());
        }
        // listbox->getSelected();
        // checks if 'enter' is clicked AND something is selected in the listbox
        cout << receiver.returnContext().selected << endl;
        
        /*if (receiver.IsKeyDown(irr::KEY_RETURN))
        {
            if (listbox->getSelected() != -1)
                printf("PID: %i\n", getPID(outputData[listbox->getSelected()]));
        }*/
        // draws the gui
        driver->beginScene(true, true, SColor(255, 255, 255, 255));
        env->drawAll();
        driver->endScene();
    }
    return 0;
}
 
If you could please help me solve this, I would be EXTREMELY appreciative.
Sorry about all the commented out code; I'm still doing a lot of debugging.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: GUI Listboxes

Post by CuteAlien »

Uhm... too much code. Reduce your application as much as you can if you search for help. Usually you find the bug while doing so ;-) (I still gave it a shot, but it doesn't compile on Linux and I don't want to reboot right now).

And as I said above - use the debugger to see where it crashes and which values the variables have at that point. Don't be afraid of debugging - it's an essential skill when programming which you will need pretty much every day when coding (I've barely had a day c++ coding the last years where I didn't use the debugger). And it will make finding bugs so much easier for you ...
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply