1

Backstory: I'm creating an Extension for Game Maker, a popular game development suite. An extension is a DLL that adds new functions to the built in scripting language, but is written in C or Pascal or whatever. Typically, it's used to allow games to use external libraries.

In my case, I'm adding FMOD support. This isn't relevant. What's relevant is that for debugging purposes, I am also adding a dialog that I display at runtime that shows me the internal state of my library. I need help with this window. I have literally done absolutely no raw Win32 forms programming before today (.NET WinForms 4eva), so I'm probably doing something really clueless.

Anyway. I have a listbox, and I want to add things to the list box, but when I try to add them, it fails. My code:

extern DebugDialog * debugDialog;

DebugDialog::DebugDialog(HWND owner, HINSTANCE hInst) {
    this->hWnd = 0;

    HWND hWnd = CreateDialogParam(hInst,
                        MAKEINTRESOURCE(IDD_DEBUGDIALOG),
                        owner,
                        DialogProc,
                        reinterpret_cast<LPARAM>(this));

    ShowWindow(hWnd, SW_SHOW);

}

DebugDialog::~DebugDialog(void) {
    DestroyWindow(this->getHWnd());
    debugDialog = NULL;
}

BOOL CALLBACK DebugDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    DebugDialog * self;

    if(message == WM_INITDIALOG) {
        self = reinterpret_cast<DebugDialog *>(lParam);
        self->hWnd = hWnd;
        SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self));
    } else {
        self = reinterpret_cast<DebugDialog*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
    }

    if(self) {
        return self->HandleMessage(message, wParam, lParam);
    } else {
        return FALSE;
    }
}


BOOL DebugDialog::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch(uMsg) {
        case WM_INITDIALOG:
            MessageBox(this->getHWnd(), "Okay!", "Debug", 0);
            return TRUE;

        case WM_COMMAND:
            switch(LOWORD(wParam)) {
                case ID_CLOSE:
                case IDOK:
                case IDCANCEL:
                    delete this;
                    return TRUE;
                default:
                    return FALSE;
            }
            return TRUE;
    }

    return false;
}

void DebugDialog::loadedSound(FMODGM_Sound * sound) {
    HWND hwndList = GetDlgItem(this->getHWnd(), IDC_LIST);

    LPARAM sound_text = (LPARAM)sound->file.c_str();

    LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, sound_text);
    SendMessage(hwndList, LB_SETITEMDATA, lResult, (LPARAM)sound);

}

DebugDialog is a simple class that wraps the window, and lets me manipulate it from the outside. Basically, at some other point, I do this:

debugWindow = new DebugDialog(owner, hInst);

And then as I execute and do interesting things, I do this:

FMODGM_Sound * sound = ...;

if(debugWindow) debugWindow->loadedSound(sound);

In loadedSound, I send a message to the list box saying "Hey, here's an item. Go ahead and make with the adding.", and it doesn't return an error. However, it also doesn't add anything to the box. It returns 0 each and every time I call it. According to the documentation, 0 means that it added an item, whose index is 0. However, that item doesn't exist.

I have a theory as to why it's not working. I have no control over the message pump that Game Maker runs, so if it's doing anything funky, I don't know about it, nor can I change it. That said, everything else about the dialog works, including moving it, clicking on my Close button, and drawing the marquee thing inside the listbox with the mouse.

Someone, please tell me what I'm doing horribly wrong :(

Edit: Someone asked about the FMODGM_Sound struct, so here it is:

struct FMODGM_Sound {
FMOD::Sound * sound;
std::vector<FMOD::Channel*> channels;
    std::string file;

public:
    FMODGM_Sound() {
        sound = NULL;
    }
};

Nothing particularly fancy.

Mike Caron
  • 14,351
  • 4
  • 49
  • 77
  • Does GetLastError() say anything? Hint: You can add the "@err" variable in the Debug watch assuming you are using MSVC. – Jonas Engström Apr 20 '11 at 08:47
  • @Jonas Gulle, I've done that (it's very handy :D). No errors show up, unfortunately. – Mike Caron Apr 20 '11 at 19:56
  • What happens if you [UpdateWindow(hwndList)](http://msdn.microsoft.com/en-us/library/dd145167%28v=vs.85%29.aspx) right after the SendMessage call? – Jonas Engström Apr 20 '11 at 21:59
  • It's not a paint issue... If it were, I'd be able to click on the items, and the `LB_ADDSTRING` message would return > 0 for subsequent calls (which it doesn't). I've decided to move away from this anyway, and am using a third party toolkit. Thanks anyway. – Mike Caron Apr 20 '11 at 22:55

3 Answers3

0

I had a very similar problem, which was solved. Basically, you have to pass it as a c-style string instead (str.c_str()). Though I am a complete newbie, after googling around how to use that, it worked.

Though the code I'm using serves an entirely different function than yours, maybe it will be a good example.

int i = res->getInt("ID");
    std::string str = boost::lexical_cast<std::string>(i);
    char *cstr = new char[10];
    strcpy_s(cstr, 10, str.c_str());
    SendDlgItemMessage(hwnd, IDC_lbList, LB_ADDSTRING, 0, (LPARAM)cstr);

EDIT: Wow, I did not even look at the dates. I'm a necromancer...

Laurgrin
  • 19
  • 5
0

Can you show a declaration of FMODGM_Sound structure and file field?

What happen if replace

LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, sound_text);

with ?

LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, "some constant text");
Andrew D.
  • 8,130
  • 3
  • 21
  • 23
  • Nothing different happens. Same if (on a hunch), I use `L"some constant text"` instead. – Mike Caron Apr 20 '11 at 20:05
  • May be your list box is designed as "OWNER_DRAWN"? Check this (from MSDN http://msdn.microsoft.com/en-us/library/bb775181%28v=vs.85%29.aspx): If the list box has an owner-drawn style but not the LBS_HASSTRINGS style, this parameter is stored as item data instead of a string. You can send the LB_GETITEMDATA and LB_SETITEMDATA messages to retrieve or modify the item data. – Andrew D. Apr 21 '11 at 07:23
0

Does the your DLL compiled as Unicode version or multibytes version?

If it is Unicode, the sound_text should be an Unicode string. I guess the file is a std::string, so file.c_str() will return a multibytes string.

Yi Zhao
  • 6,768
  • 1
  • 18
  • 18
  • 1
    In accordance with this call: MessageBox(this->getHWnd(), "Okay!", "Debug", 0); project is compiled as MBCS (otherwise a compilation error must occur: convertion from CHAR to WCHAR) – Andrew D. Apr 20 '11 at 11:40
  • This is correct. It's compiled as Multibyte. This is mostly for compatibility with Game Maker, whose string format is `char*`. – Mike Caron Apr 20 '11 at 20:01
  • Is it the right HWND by `GetDlgItem(this->getHWnd(), IDC_LIST);`? I think you should verify it first. – Yi Zhao Apr 21 '11 at 02:18