Предыстория: Я создаю расширение для 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;
}
};
Ничего особенно необычного.
LB_ADDSTRING
возвращало бы › 0 для последующих вызовов (чего нет). Я все равно решил отойти от этого и использую сторонний инструментарий. Спасибо, в любом случае. - person Mike Caron   schedule 21.04.2011