无法将项目添加到 Win32 列表框控件
背景故事:我正在为 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;
}
};
没有什么特别奇特的。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您能显示 FMODGM_Sound 结构和文件字段的声明吗?
如果替换
为 会发生什么?
Can you show a declaration of FMODGM_Sound structure and file field?
What happen if replace
with ?
您的 DLL 是否编译为 Unicode 版本或多字节版本?
如果是 Unicode,则 sound_text 应该是 Unicode 字符串。我猜该文件是一个 std::string,因此 file.c_str() 将返回一个多字节字符串。
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.
我有一个非常相似的问题,已经解决了。基本上,您必须将其作为 c 样式字符串传递,而不是
(str.c_str())
。虽然我是一个完全的新手,但在谷歌搜索如何使用它之后,它起作用了。尽管我使用的代码具有与您完全不同的功能,但也许它会是一个很好的例子。
编辑:哇,我什至没有看日期。我是死灵法师...
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.
EDIT: Wow, I did not even look at the dates. I'm a necromancer...