Предыстория: я создаю расширение для Game Maker, популярного пакета разработки игр. Расширение - это DLL, которая добавляет новые функции к встроенному скриптовому языку, но написана на C, Pascal или как угодно. Обычно он позволяет играм использовать внешние библиотеки.
В моем случае я добавляю поддержку FMOD. Это не актуально. Важно то, что для целей отладки я также добавляю диалоговое окно, отображаемое во время выполнения, которое показывает мне внутреннее состояние моей библиотеки. Мне нужна помощь с этим окном. До сегодняшнего дня я буквально не занимался программированием необработанных форм Win32 (.NET WinForms 4eva), так что я, вероятно, делаю что-то по-настоящему бестолковое.
Так или иначе. У меня есть список, и я хочу добавить вещи в список, но когда я пытаюсь добавить их, происходит сбой. Мой код:
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
- это простой класс, который окружает окно и позволяет мне манипулировать им снаружи. По сути, в какой-то другой момент я делаю это:
debugWindow = new DebugDialog(owner, hInst);
А потом, когда я выполняю и делаю интересные вещи, я делаю это:
FMODGM_Sound * sound = ...;
if(debugWindow) debugWindow->loadedSound(sound);
В loadedSound
я отправляю сообщение в список со словами «Эй, вот предмет. Продолжай и добавляй.», И оно не возвращает ошибку. Тем не менее, это также ничего не добавляет к коробке. Он возвращает 0 каждый раз, когда я это называю. Согласно документации, 0 означает, что он добавил элемент с индексом 0. Однако этот элемент не существует.
У меня есть теория, почему она не работает. Я не контролирую насос сообщений, который запускает Game Maker, поэтому, если он делает что-то необычное, я не знаю об этом и не могу его изменить. Тем не менее, все остальное в диалоге работает, включая его перемещение, нажатие на кнопку «Закрыть» и рисование выделенной области внутри списка с помощью мыши.
Кто-то, скажите, пожалуйста, что я делаю ужасно неправильно: (
Редактировать: Кто-то спросил о структуре FMODGM_Sound
, вот она:
struct FMODGM_Sound {
FMOD::Sound * sound;
std::vector<FMOD::Channel*> channels;
std::string file;
public:
FMODGM_Sound() {
sound = NULL;
}
};
Ничего особенного.