为什么LB_GETITEMDATA返回0?

时间:2014-08-16 07:05:59

标签: c++ winapi listbox

我试图创建一个暂停和恢复进程的程序,它创建一个列表框,其中包含系统上所有正在运行的进程的文本字符串,但是当我单击暂停按钮暂停进程时我尝试发送WM_GETITEMDATA用于列表框中当前选定的项目,但该值返回0.我希望返回值是一个字符串,其中包含LB_ADDSTRING的lParam文本。

我认为这与我使用LB_ADDSTRING的函数的范围有关,因为当我在LB_ADDSTRING之后立即使用LB_GETITEMDATA时,它正确地返回LB_ADDSTRING的lParam的值。由于我不确定我的错误所在,我将完整的源代码添加到我的问题的底部。这是我用来向列表框添加字符串的函数:

void RefreshList()
{
    SendMessage (hlist, LB_RESETCONTENT, 0, 0);
    HANDLE hSnapShot3 = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    PROCESSENTRY32 pEntry3;
    pEntry3.dwSize = sizeof (pEntry3);
    BOOL hRes3 = Process32First(hSnapShot3, &pEntry3);
    int listitem = 0;
    while (hRes3)
    {

        SendMessage (hlist, LB_ADDSTRING, 0, (LPARAM)pEntry3.szExeFile);
        SendMessage (hlist, LB_SETITEMDATA, listitem, (LPARAM)pEntry3.szExeFile);
        SendMessage(hlist, LB_GETITEMDATA, listitem, NULL);
        MessageBox(0,0,0,0);
        listitem++;
        hRes3 = Process32Next(hSnapShot3, &pEntry3);
    }
    CloseHandle(hSnapShot3);
}

这是windows程序的一部分,我点击上下文菜单并尝试发送消息LB_GETITEMDATA:

    case WM_COMMAND:
        if (HIWORD(wParam) == 0 && LOWORD(wParam) == 1)
        {
        selection = SendMessage(hlist, LB_GETCURSEL, 0, 0);
        LRESULT selectionname = SendMessage(hlist, LB_GETITEMDATA, selection, NULL);
        }

这是完整的代码

#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <process.h>
#include <Tlhelp32.h>
#include <winbase.h>
#include <string.h>
#include <stdio.h>
#include <windowsx.h>
#define list1 1
#define button1 2
int selection;
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ProcessListProc (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "mainwindowclass";
HWND hlist;
HWND hwnd;
void RefreshList()
{
    SendMessage (hlist, LB_RESETCONTENT, 0, 0);
    HANDLE hSnapShot3 = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    PROCESSENTRY32 pEntry3;
    pEntry3.dwSize = sizeof (pEntry3);
    BOOL hRes3 = Process32First(hSnapShot3, &pEntry3);
    int listitem = 0;
    while (hRes3)
    {

        SendMessage (hlist, LB_ADDSTRING, 0, (LPARAM)pEntry3.szExeFile);
        SendMessage (hlist, LB_SETITEMDATA, listitem, (LPARAM)pEntry3.szExeFile);
        SendMessage(hlist, LB_GETITEMDATA, listitem, NULL);
        MessageBox(0,0,0,0);
        listitem++;
        hRes3 = Process32Next(hSnapShot3, &pEntry3);
    }
    CloseHandle(hSnapShot3);
}

int SuspendProcess(TCHAR processname)
{
    int doublePID = 0;
    DWORD pidtoacton;
    DWORD Result;
    HANDLE hSnapShot3 = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    PROCESSENTRY32 pEntry3;
    pEntry3.dwSize = sizeof (pEntry3);
    BOOL hRes3 = Process32First(hSnapShot3, &pEntry3);
    while (hRes3)
    {
            if (processname == pEntry3.szExeFile);
            {
                if (doublePID != 0)
                {
                    MessageBox (NULL, "2 processes of the same type detected, support not yet implimented!", NULL, MB_OK);
                }
            pidtoacton = pEntry3.th32ProcessID;
            doublePID++;
            }
    hRes3 = Process32Next(hSnapShot3, &pEntry3);
    }
    HANDLE tsnap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0);
    THREADENTRY32 tentry;
    tentry.dwSize = sizeof (tentry);
    BOOL CRec = Thread32First(tsnap, &tentry);
    while (CRec)
    {
        if (tentry.th32OwnerProcessID == pidtoacton)
     {
         HANDLE handletoacton = OpenThread(2, 0, tentry.th32ThreadID);
         Result = SuspendThread(handletoacton);
         if (Result == -1)
         {
             MessageBox (NULL, "An unknown error has occured when attempting to suspend a thread in the process", NULL, MB_OK);
         }
     }
     CRec = Thread32Next(tsnap, &tentry);
    }
    CloseHandle(tsnap);
}

    MSG messages;
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
          /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
    MSG messages2;

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
    /* Register the window class, and if it fails quit the program */

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Process suspender",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               350,                 /* The programs width */
               650,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
           );

    hlist = CreateWindowEx (0,TEXT("listbox"),NULL,WS_CHILD|WS_VISIBLE|LBS_NOTIFY|LBS_STANDARD|LBS_HASSTRINGS,10,15,320,500,hwnd,(HMENU)list1,NULL,NULL);
    RefreshList();

    HWND hWndButton = CreateWindowEx(NULL,
                                     TEXT("button"),
                                     TEXT("refresh"),
                                     WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
                                     130,
                                     535,
                                     80,
                                     30,
                                     hwnd,
                                     (HMENU)button1,
                                     NULL,
                                     NULL);

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
    case WM_CONTEXTMENU:
    {
        if ((HWND)wParam == hlist)
        {
         INPUT clickin;
         clickin.type = 0;
         clickin.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
         clickin.mi.dx = 0;
         clickin.mi.dy = 0;
         clickin.mi.mouseData = 0;
         clickin.mi.time = 0;
         clickin.mi.dwExtraInfo = 0;
         SendInput(1,&clickin,sizeof(clickin));
         clickin.mi.dwFlags = MOUSEEVENTF_LEFTUP;
         SendInput(1,&clickin,sizeof(clickin));
         GetMessage (&messages, NULL, 0, 0);
         TranslateMessage(&messages);
         DispatchMessage(&messages);
         int xPos = GET_X_LPARAM(lParam);
         int yPos = GET_Y_LPARAM(lParam);
         HMENU rightclickmenu = CreatePopupMenu();
         InsertMenu(rightclickmenu, 1, MF_BYCOMMAND | MF_STRING | MF_ENABLED, 1, "Suspend");
         InsertMenu(rightclickmenu, 0, MF_BYCOMMAND | MF_STRING | MF_ENABLED, 0, "Resume");
         TrackPopupMenu(rightclickmenu, TPM_TOPALIGN | TPM_LEFTALIGN, xPos, yPos, 0, hwnd, NULL);
        }
        break;
    }
    case WM_DESTROY:
        PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
        break;
    case WM_COMMAND:
        if (HIWORD(wParam) == 0 && LOWORD(wParam) == 1)
        {
        selection = SendMessage(hlist, LB_GETCURSEL, 0, 0);
        LRESULT selectionname = SendMessage(hlist, LB_GETITEMDATA, selection, NULL);
        }
        switch (wParam)
        {
        case button1:
            RefreshList();
            break;
        }
    default:
        return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}

1 个答案:

答案 0 :(得分:2)

正如@JonathanPotter在评论中提到的那样,您需要使用LB_GETTEXT来检索项目的文本。

如果您打算使用LB_SETITEMDATA来存储每个项目的进程ID,那么最好始终使用LB_ADDSTRING返回的索引,而不要假设索引将始终递增1,这将适用于已排序和未排序的列表框:

listitem = SendMessage(hlist, LB_ADDSTRING, 0, (LPARAM)pEntry3.szExeFile);
SendMessage(hlist, LB_SETITEMDATA, listitem, (LPARAM)pEntry3.th32ProcessID);