我试图创建一个暂停和恢复进程的程序,它创建一个列表框,其中包含系统上所有正在运行的进程的文本字符串,但是当我单击暂停按钮暂停进程时我尝试发送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;
}
答案 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);