sendmessage() doesn't work inside a function

If I do it like this, it works - it populates the 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->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;

However, if I wanted to be tidy and put it inside a function, like this, it would no longer populate the list, even though the function itself DOES run.:

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;

For some reason, SendMessage() refuses to work while inside a function. g_hMnDialog is a global handle for the main dialog which contains ALL of the controls, listbox included.

PROBLEM: SendMessage(), works and populates the listbox outside a function. However, the function does not populate the listbox once called, even though it contains the same code.

QUESTION: Why does my SendMessage() does not work inside a function, and what steps should I take to make it work?

BONUS QUESTION: Where would be the best place to call this function (once/if) it works to constantly refresh the listbox?

Answers


The obvious explanation would be that g_hMnDialog is not yet initialised at the time when you call fRefreshListID(). Personally, I would avoid using global variables where possible. When you call fRefreshListID(), you have the window handle to hand to it makes sense to pass it as a parameter to fRefreshListID(). The function would look like this:

void fRefreshListID(HWND hwndDialog)
{
    ....
}

You should be checking for errors when you call API functions. My expectation is that GetDlgItem returns NULL because g_hMnDialog is not valid. You then blindly pass that NULL on to SendMessage. I recommend that you add some error checking.

Your string handling is all off too. You are making it much more complex than needed. You can write it like this:

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());

If you want the function to repopulate the list you will need to clear the list, or at least replace items. As it stands, each time you call your function you will add more items to the existing ones.

What is the best time to call the function while the application is running? That cannot be answered in detail with the information you provided. It depends on what your application is doing. What do you want to trigger a refresh? Do you want it to be based on a timer and so be a polling approach? Or do you want to listen for an event that tells you that the list contents are out of date. Only you can really answer those questions.


Need Your Help

How to update whole column in sql server table

c# sql-server sql-update

I want to update a column values in sql server table after copying those value from some other table. i.e.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.