Winapi sendmessage()在函数内部不起作用

Winapi sendmessage()在函数内部不起作用,winapi,visual-c++,listbox,Winapi,Visual C++,Listbox,如果我这样做,它会工作-它会填充列表框: BOOL CALLBACK MnDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { case WM_INITDIALOG: { res = stmt->executeQuery("SELECT id FROM tremreg ORDER BY id DESC"); while (res->

如果我这样做,它会工作-它会填充列表框:

BOOL CALLBACK MnDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
    case WM_INITDIALOG:
    {
        res = stmt->executeQuery("SELECT id FROM tremreg ORDER BY id DESC");
    while (res->next())
    {
    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());
            SendMessage(GetDlgItem(hwnd, IDC_lbList), 
                              LB_ADDSTRING, 0, (LPARAM)cstr);
    }
    delete res;
}
break;
但是,如果我想保持整洁并将其放入函数中,就像这样,它将不再填充列表,即使函数本身确实运行:

VOID fRefreshListID()
{
res = stmt->executeQuery("SELECT id FROM tremreg ORDER BY id DESC");
while (res->next())
{
    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());
    SendMessage(GetDlgItem(g_hMnDialog, IDC_lbList), LB_ADDSTRING, 0, (LPARAM)cstr);
}
delete res;
}



BOOL CALLBACK MnDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
{
    fRefreshListID();
}
    break;
由于某些原因,SendMessage在函数中拒绝工作。g_hMnDialog是主对话框的全局句柄,其中包含所有控件(包括listbox)

问题:SendMessage在函数外部工作并填充列表框。但是,函数调用后不会填充listbox,即使它包含相同的代码

问题:为什么我的SendMessage在函数中不起作用,我应该采取什么步骤使它起作用


另外一个问题:如果该函数能够不断刷新列表框,那么在哪里调用该函数最好?

显而易见的解释是,在调用freshListId时,g_hMnDialog尚未初始化。就我个人而言,我会尽可能避免使用全局变量。当您调用FreshListId时,您需要将窗口句柄交给它,将其作为参数传递给FreshListId是有意义的。该函数如下所示:

void fRefreshListID(HWND hwndDialog)
{
    ....
}
HWND hwndList = GetDlgItem(hwndDialog, IDC_lbList);
if (hwndList == NULL)
    // deal with this error
std::string str = ...;
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)str.c_str());
调用API函数时,应该检查错误。我的期望是GetDlgItem返回NULL,因为g_hMnDialog无效。然后盲目地将该空值传递给SendMessage。我建议您添加一些错误检查

你的字符串处理也全部关闭了。您正在使它比需要的复杂得多。你可以这样写:

void fRefreshListID(HWND hwndDialog)
{
    ....
}
HWND hwndList = GetDlgItem(hwndDialog, IDC_lbList);
if (hwndList == NULL)
    // deal with this error
std::string str = ...;
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)str.c_str());
如果希望函数重新填充列表,则需要清除列表,或者至少替换项。目前,每次调用函数时,都会向现有项添加更多项


应用程序运行时调用函数的最佳时间是什么?您提供的信息无法详细回答这一问题。这取决于你的应用程序在做什么。要触发刷新的内容是什么?您是否希望它基于计时器,从而成为轮询方法?或者,是否要侦听通知列表内容已过期的事件。只有你才能真正回答这些问题。

旁注-char*cstr=new char[10]正在泄漏内存,无论如何都是不必要的。对于您的问题,除了可能使用不同的窗口句柄、调试并确保在每个版本中发送到相同的HWND或将其作为参数传递给函数之外,没有其他原因。我明白了。这正是我所怀疑的,我确实试着将手柄移开,但毫无效果。甚至使用主对话框的全局句柄也不起作用。您建议用什么代替char*cstr=new char[10]?最后,这是我最终使SendMessage真正工作并编译的唯一方法。str.c_str已经是您所需要的全部了它是一个常量字符*,将它复制到另一个字符*是多余的,只需将它转换到LPRAM。谢谢,现在它在没有复制的情况下工作了。尽管如此,我还是玩弄了各种通过把手的方法,但总有一些地方出了问题。而使用全局句柄似乎既不起作用,也不会将相同的hwnd从DlgProc发送到FreshListIDHWND。我不知所措,几乎所有其他函数都得到了hwnd,但不是这个函数。我猜这是复制/粘贴,以防我需要刷新列表框,我会这样做。您的FreshListID与您的WM_INITDIALOG处理程序不包含相同的代码。前者在调用GetDlgItem时使用g_hMnDialog,而后者使用传递给对话框过程的hwnd参数。这是值得研究的。好吧,我不确定我是否遗漏了如此明显的内容,但根据你的建议,我重写了函数。现在可以了。现在我觉得自己很笨。不过,谢谢你。