C++ 无法将项添加到Win32列表框控件

C++ 无法将项添加到Win32列表框控件,c++,winapi,listbox,dialog,game-maker,C++,Winapi,Listbox,Dialog,Game Maker,背景故事:我正在为Game Maker创建一个扩展,这是一个流行的游戏开发套件。扩展是向内置脚本语言添加新函数的DLL,但它是用C或Pascal或其他语言编写的。通常,它用于允许游戏使用外部库 在我的例子中,我添加了FMOD支持。这无关紧要。与此相关的是,出于调试目的,我还添加了一个在运行时显示的对话框,显示库的内部状态。我需要人帮我打开这扇窗户。在今天之前,我几乎没有做过任何原始的Win32表单编程(.NET WinForms 4eva),所以我可能在做一些真正不懂的事情 无论如何。我有一个列

背景故事:我正在为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);

}
然后当我执行和做有趣的事情时,我会这样做:

debugWindow = new DebugDialog(owner, hInst);
FMODGM_Sound * sound = ...;

if(debugWindow) debugWindow->loadedSound(sound);
loadedSound
中,我向列表框发送了一条消息,说“嘿,这里有一个项目。继续添加吧”,它不会返回错误。但是,它也不会向框中添加任何内容。每次我调用它时,它都返回0。根据文档,0表示它添加了一个索引为0的项。但是,该项不存在

我有一个理论解释为什么它不起作用。我无法控制游戏制作者运行的信息泵,所以如果它做了一些令人不快的事情,我不知道,也不能改变它。这就是说,对话框的所有其他功能都可以正常工作,包括移动它、单击我的关闭按钮以及用鼠标在列表框中绘制字幕

有人,请告诉我我做错了什么:(

编辑:有人问起
FMODGM_声音
struct,这里是:

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

public:
    FMODGM_Sound() {
        sound = NULL;
    }
};
struct FMODGM\u声音{
FMOD::声音*声音;
矢量信道;
std::字符串文件;
公众:
FMODGM_声音(){
声音=零;
}
};

没有什么特别特别特别的。

你能展示FMODGM_声音结构和文件字段的声明吗

如果更换,会发生什么

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

LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, "some constant text");

DLL编译为Unicode版本还是多字节版本


如果是Unicode,则声音文本应该是Unicode字符串。我猜该文件是std::string,因此file.c_str()将返回一个多字节字符串。

我遇到了一个非常类似的问题,已经解决了。基本上,您必须将其作为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);
inti=res->getInt(“ID”);
std::string str=boost::词法转换(i);
char*cstr=新字符[10];
strcpy_s(cstr,10,str.c_str());
SendDlgItemMessage(hwnd,IDC_lbList,LB_ADDSTRING,0,(LPARAM)cstr);

编辑:哇,我甚至都没看日期。我是一名亡灵巫师…

GetLastError()有什么说法吗?提示:假设您使用的是MSVC,您可以在调试表中添加“@err”变量。@Jonas Gulle,我已经这样做了(非常方便:D)。不幸的是,没有显示错误。如果在SendMessage调用之后立即执行,会发生什么情况?这不是绘画问题…如果是,我可以单击项目,后续调用的
LB_ADDSTRING
消息将返回>0(它没有)。我已决定不再使用此工具,而是使用第三方工具包。无论如何,谢谢。根据此调用:MessageBox(this->getHWnd(),“OK!”,“Debug”,0);将项目编译为MBCS(否则必须发生编译错误:从CHAR转换为WCHAR)这是正确的。它被编译为多字节。这主要是为了与Game Maker兼容,Game Maker的字符串格式是
char*
。它是
GetDlgItem(This->getHWnd(),IDC_LIST);
?我想你应该先验证它。没有什么不同。如果(凭直觉)我使用
L“一些常量文本”,情况也是一样的
相反。可能是您的列表框设计为“OWNER\u Drawed”?请检查(来自MSDN):如果列表框具有OWNER\u Drawed样式,但不是LBS\u HASSTRINGS样式,则此参数存储为项目数据而不是字符串。您可以发送LB\u GETITEMDATA和LB\u SETITEMDATA消息以检索或修改项目数据。