背景故事:我正在为游戏制作者创建一个扩展程序,这是一款流行的游戏开发套件。扩展是一个DLL,它为内置脚本语言添加新函数,但是用C或Pascal或其他语言编写。通常,它用于允许游戏使用外部库。
在我的情况下,我正在添加FMOD支持。这不相关。与调试目的相关的是,我还添加了一个在运行时显示的对话框,显示了我库的内部状态。我需要这个窗口的帮助。在今天(.NET WinForms 4eva)之前,我确实没有完全没有原始的Win32表格编程,所以我可能正在做一些真正无能为力的事情。
反正。我有一个列表框,我想在列表框中添加内容,但是当我尝试添加它们时,它会失败。我的代码:
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;
}
};
没什么特别的花哨。
答案 0 :(得分:0)
您能否显示FMODGM_Sound结构和文件字段的声明?
如果替换
会发生什么LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, sound_text);
用?
LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, "some constant text");
答案 1 :(得分:0)
您的DLL是编译为Unicode版本还是多字节版本?
如果是Unicode,则sound_text应为Unicode字符串。我想该文件是一个std :: string,因此file.c_str()将返回一个多字节字符串。
答案 2 :(得分:0)
我有一个非常类似的问题,已经解决了。基本上,您必须将其作为c样式字符串传递而不是(str.c_str())
。虽然我是一个完整的新手,但在谷歌搜索如何使用它之后,它起作用了。
虽然我使用的代码与你的代码完全不同,但它可能是一个很好的例子。
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);
编辑:哇,我甚至都没看过日期。我是一名死灵法师......