C++ Winapi 列表框使用 LB_GETSEL/LB_GETCURSEL 获取选定的项目
C++ Winapi Listbox getting selected Item using LB_GETSEL/LB_GETCURSEL
所以我开始了一个标准的 windows 项目并添加了一个包含一堆项目的列表框。如果我单击列表框的一个项目,我想接收列表框的文本或我之前设置的项目数据。因此,如果用户单击列表框,我会尝试通过多种方式获取此信息(从 Internet 我尝试适应我的问题),如第二个代码 window 所示。问题是,LB_GETSEL 和 LB_GETCURSEL return 都不是我可以正确使用的值。该值始终为 -1 或 LB_ERR,这显然不是一个有用的值。我正在使用 MessageBox 可视化我的 SendMessage 的 return 值。我的错误是什么?
标准window代码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
LBTest = CreateWindowExW(WS_EX_CLIENTEDGE
, L"LISTBOX", NULL
, WS_CHILD | WS_VISIBLE | WS_VSCROLL
, 7, 7, 300, 600
, hWnd, (HMENU)19, hInst, NULL);
std::wstring str;
for (int l = 0; l < 210; l++)
{
str = std::to_wstring(l);
int pos = SendMessage(LBTest, LB_ADDSTRING, 0, (LPARAM)str.c_str());
SendMessage(LBTest, LB_SETITEMDATA, pos, (LPARAM)l);
}
break;
标准window代码
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Menüauswahl bearbeiten:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case 19:
{
int count = SendMessage(LBTest, LB_GETCOUNT, 0, 0);
int iSelected = -1;
// go through the items and find the first selected one
for (int i = 0; i < count; i++)
{
// check if this item is selected or not..
if (SendMessage(LBTest, LB_GETSEL, i, 0) != LB_ERR)
{
// yes, we only want the first selected so break.
iSelected = i;
break;
}
}
std::wstring check = std::to_wstring(iSelected);
MessageBox(hWnd, check.c_str(), L"wasd", MB_OK);
//---------------------------------
/*
DWORD dwSel = SendMessage(hWnd, LB_GETCURSEL, 0, 0);
if (dwSel != LB_ERR)
{
std::wstring str;
SendMessage( LBTest, LB_GETTEXT, dwSel, (LPARAM)str.c_str());
MessageBox(hWnd, L"Error", L"test", MB_OK);
}
//--------------------------------------------------------
//int lbItem = (int)SendMessage(LBTest, LB_GETCURSEL, 0, 0);
//int i = (int)SendMessage(LBTest, LB_GETITEMDATA, lbItem, 0);
*/
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
其余 window 代码
编辑: 由于评论区的建议,我尝试更改代码,但程序仍然无法运行。该建议包括 LBN_SELCHANGE 作为我的命令回调的条件,但我不确定是否可以在 MainWindow 回调中进行此回调或需要其自己的回调。
编辑完整程序代码:
#include "stdafx.h"
#include "Testproject.h"
#include <iostream>
#include <string>
#include <thread>
#define MAX_LOADSTRING 100
const UINT WM_WINDOW_UPDATE = WM_APP + 0;
HINSTANCE hInst;
WCHAR szTitle[MAX_LOADSTRING];
WCHAR szWindowClass[MAX_LOADSTRING];
HWND Button1,LBTest;
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_TESTPROJECT, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTPROJECT));
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTPROJECT));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_TESTPROJECT);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; //
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
LBTest = CreateWindowExW(WS_EX_CLIENTEDGE
, L"LISTBOX", NULL
, WS_CHILD | WS_VISIBLE | WS_VSCROLL
, 7, 7, 300, 600
, hWnd, (HMENU)19, hInst, NULL);
std::wstring str;
for (int l = 0; l < 210; l++)
{
str = std::to_wstring(l);
int pos = SendMessage(LBTest, LB_ADDSTRING, 0, (LPARAM)str.c_str());
SendMessage(LBTest, LB_SETITEMDATA, pos, (LPARAM)l);
}
break;
}
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case LBN_SELCHANGE:
{
/*
int count = SendMessage(LBTest, LB_GETCOUNT, 0, 0);
int iSelected = -1;
// go through the items and find the first selected one
for (int i = 0; i < count; i++)
{
// check if this item is selected or not..
if (SendMessage(LBTest, LB_GETSEL, i, 0) != LB_ERR)
{
// yes, we only want the first selected so break.
iSelected = i;
break;
}
}
std::wstring check = std::to_wstring(iSelected);
MessageBox(hWnd, check.c_str(), L"wasd", MB_OK);
*/
//---------------------------------
DWORD dwSel = SendMessage(hWnd, LB_GETCURSEL, 0, 0);
if (dwSel > 0)
{
std::wstring str;
SendMessage(LBTest, LB_GETTEXT, dwSel, (LPARAM)str.c_str());
MessageBox(hWnd, str.c_str(), L"test", MB_OK);
}
MessageBox(hWnd, L"Check", L"test", MB_OK);
/*
//int lbItem = (int)SendMessage(LBTest, LB_GETCURSEL, 0, 0);
//int i = (int)SendMessage(LBTest, LB_GETITEMDATA, lbItem, 0);
*/
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_WINDOW_UPDATE:
{
g_i = static_cast<int>(wParam);
InvalidateRect(hWnd, nullptr, TRUE);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
//TODO: Zeichencode, der hdc verwendet, hier einfügen...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Meldungshandler für Infofeld.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
好的,我找到了这个问题的答案。首先,我必须了解从列表框输入的数据是如何工作的。如果我与列表框交互,则会发送 WM_Command 消息。此消息包含一个 wparam,它只是一个无符号整数,在 windows 应用程序中有 4 个字节(如果我错了请纠正我)。这 4 个字节可以拆分为 2 个消息,LOWORD 和 HIWORD,每个消息包含 2 个字节。因此,如果我与列表框交互,我会收到来自 Windows 的 WM_Command 消息,告诉我有人与我的 window 的对象交互,并且 wparam 中有 2 个信息。第一个是 LOWORD,其中包含我与之交互的实际对象。在此示例中,它是我在 CreateWindowEx 中分配给列表框的 (HMENU)19。但是 HIWORD 仍然包含有关列表框已完成的操作的信息。有几个选项,包括文本框是否聚焦以及 selected 项目是否发生变化。事实证明,无论我在该列表框中单击什么,都没有关于传入的 select 更改的信息。所以我发现,对于进入消息循环的消息,您需要在列表框的 CreateWindowEx 中指定该消息从 Windows 发送到您的程序。您可以在 dwStyle 属性中使用 LBS_NOTIFY 来做到这一点。在我的例子中,固定的 CreateWindowEx 看起来像这样:
LBTest = CreateWindowEx(WS_EX_CLIENTEDGE
, L"LISTBOX",NULL
, WS_CHILD | WS_VISIBLE | WS_VSCROLL| LBS_NOTIFY
, 7, 7, 300, 600
, hWnd, (HMENU)19, hInst, NULL);
修复后,我只需修复消息处理程序,使其看起来像这样:
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case 19:
{
switch (HIWORD(wParam))
{
case LBN_SELCHANGE:
{
int count = SendMessage(LBTest, LB_GETCOUNT, 0, 0);
int iSelected = -1;
// go through the items and find the first selected one
for (int i = 0; i < count; i++)
{
// check if this item is selected or not..
if (SendMessage(LBTest, LB_GETSEL, i, 0) > 0)
{
// yes, we only want the first selected so break.
iSelected = i;
break;
}
}
break;
}
}
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
iSelected 就是您的列表框的 selected 项目编号。您可以将其发送到 LB_GETTEXT 以获取 selected 项目的当前文本:
std::wstring check ;
SendMessage(LBTest, LB_GETTEXT, iSelected, (LPARAM)check.c_str());
你也可以通过这样做得到相同的结果:
std::wstring str;
DWORD dwSel = SendMessage(LBTest, LB_GETCURSEL, 0, 0);
if (dwSel > 0)
{
std::wstring str;
SendMessage(LBTest, LB_GETTEXT, dwSel, (LPARAM)str.c_str());
MessageBox(hWnd, str.c_str(), L"test", MB_OK);
}
这可能是比第一个解决方案更快的解决方案,因为您不必遍历所有列表框项目。
所以我开始了一个标准的 windows 项目并添加了一个包含一堆项目的列表框。如果我单击列表框的一个项目,我想接收列表框的文本或我之前设置的项目数据。因此,如果用户单击列表框,我会尝试通过多种方式获取此信息(从 Internet 我尝试适应我的问题),如第二个代码 window 所示。问题是,LB_GETSEL 和 LB_GETCURSEL return 都不是我可以正确使用的值。该值始终为 -1 或 LB_ERR,这显然不是一个有用的值。我正在使用 MessageBox 可视化我的 SendMessage 的 return 值。我的错误是什么?
标准window代码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
LBTest = CreateWindowExW(WS_EX_CLIENTEDGE
, L"LISTBOX", NULL
, WS_CHILD | WS_VISIBLE | WS_VSCROLL
, 7, 7, 300, 600
, hWnd, (HMENU)19, hInst, NULL);
std::wstring str;
for (int l = 0; l < 210; l++)
{
str = std::to_wstring(l);
int pos = SendMessage(LBTest, LB_ADDSTRING, 0, (LPARAM)str.c_str());
SendMessage(LBTest, LB_SETITEMDATA, pos, (LPARAM)l);
}
break;
标准window代码
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Menüauswahl bearbeiten:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case 19:
{
int count = SendMessage(LBTest, LB_GETCOUNT, 0, 0);
int iSelected = -1;
// go through the items and find the first selected one
for (int i = 0; i < count; i++)
{
// check if this item is selected or not..
if (SendMessage(LBTest, LB_GETSEL, i, 0) != LB_ERR)
{
// yes, we only want the first selected so break.
iSelected = i;
break;
}
}
std::wstring check = std::to_wstring(iSelected);
MessageBox(hWnd, check.c_str(), L"wasd", MB_OK);
//---------------------------------
/*
DWORD dwSel = SendMessage(hWnd, LB_GETCURSEL, 0, 0);
if (dwSel != LB_ERR)
{
std::wstring str;
SendMessage( LBTest, LB_GETTEXT, dwSel, (LPARAM)str.c_str());
MessageBox(hWnd, L"Error", L"test", MB_OK);
}
//--------------------------------------------------------
//int lbItem = (int)SendMessage(LBTest, LB_GETCURSEL, 0, 0);
//int i = (int)SendMessage(LBTest, LB_GETITEMDATA, lbItem, 0);
*/
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
其余 window 代码
编辑: 由于评论区的建议,我尝试更改代码,但程序仍然无法运行。该建议包括 LBN_SELCHANGE 作为我的命令回调的条件,但我不确定是否可以在 MainWindow 回调中进行此回调或需要其自己的回调。 编辑完整程序代码:
#include "stdafx.h"
#include "Testproject.h"
#include <iostream>
#include <string>
#include <thread>
#define MAX_LOADSTRING 100
const UINT WM_WINDOW_UPDATE = WM_APP + 0;
HINSTANCE hInst;
WCHAR szTitle[MAX_LOADSTRING];
WCHAR szWindowClass[MAX_LOADSTRING];
HWND Button1,LBTest;
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_TESTPROJECT, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTPROJECT));
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTPROJECT));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_TESTPROJECT);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; //
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
LBTest = CreateWindowExW(WS_EX_CLIENTEDGE
, L"LISTBOX", NULL
, WS_CHILD | WS_VISIBLE | WS_VSCROLL
, 7, 7, 300, 600
, hWnd, (HMENU)19, hInst, NULL);
std::wstring str;
for (int l = 0; l < 210; l++)
{
str = std::to_wstring(l);
int pos = SendMessage(LBTest, LB_ADDSTRING, 0, (LPARAM)str.c_str());
SendMessage(LBTest, LB_SETITEMDATA, pos, (LPARAM)l);
}
break;
}
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case LBN_SELCHANGE:
{
/*
int count = SendMessage(LBTest, LB_GETCOUNT, 0, 0);
int iSelected = -1;
// go through the items and find the first selected one
for (int i = 0; i < count; i++)
{
// check if this item is selected or not..
if (SendMessage(LBTest, LB_GETSEL, i, 0) != LB_ERR)
{
// yes, we only want the first selected so break.
iSelected = i;
break;
}
}
std::wstring check = std::to_wstring(iSelected);
MessageBox(hWnd, check.c_str(), L"wasd", MB_OK);
*/
//---------------------------------
DWORD dwSel = SendMessage(hWnd, LB_GETCURSEL, 0, 0);
if (dwSel > 0)
{
std::wstring str;
SendMessage(LBTest, LB_GETTEXT, dwSel, (LPARAM)str.c_str());
MessageBox(hWnd, str.c_str(), L"test", MB_OK);
}
MessageBox(hWnd, L"Check", L"test", MB_OK);
/*
//int lbItem = (int)SendMessage(LBTest, LB_GETCURSEL, 0, 0);
//int i = (int)SendMessage(LBTest, LB_GETITEMDATA, lbItem, 0);
*/
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_WINDOW_UPDATE:
{
g_i = static_cast<int>(wParam);
InvalidateRect(hWnd, nullptr, TRUE);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
//TODO: Zeichencode, der hdc verwendet, hier einfügen...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Meldungshandler für Infofeld.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
好的,我找到了这个问题的答案。首先,我必须了解从列表框输入的数据是如何工作的。如果我与列表框交互,则会发送 WM_Command 消息。此消息包含一个 wparam,它只是一个无符号整数,在 windows 应用程序中有 4 个字节(如果我错了请纠正我)。这 4 个字节可以拆分为 2 个消息,LOWORD 和 HIWORD,每个消息包含 2 个字节。因此,如果我与列表框交互,我会收到来自 Windows 的 WM_Command 消息,告诉我有人与我的 window 的对象交互,并且 wparam 中有 2 个信息。第一个是 LOWORD,其中包含我与之交互的实际对象。在此示例中,它是我在 CreateWindowEx 中分配给列表框的 (HMENU)19。但是 HIWORD 仍然包含有关列表框已完成的操作的信息。有几个选项,包括文本框是否聚焦以及 selected 项目是否发生变化。事实证明,无论我在该列表框中单击什么,都没有关于传入的 select 更改的信息。所以我发现,对于进入消息循环的消息,您需要在列表框的 CreateWindowEx 中指定该消息从 Windows 发送到您的程序。您可以在 dwStyle 属性中使用 LBS_NOTIFY 来做到这一点。在我的例子中,固定的 CreateWindowEx 看起来像这样:
LBTest = CreateWindowEx(WS_EX_CLIENTEDGE
, L"LISTBOX",NULL
, WS_CHILD | WS_VISIBLE | WS_VSCROLL| LBS_NOTIFY
, 7, 7, 300, 600
, hWnd, (HMENU)19, hInst, NULL);
修复后,我只需修复消息处理程序,使其看起来像这样:
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case 19:
{
switch (HIWORD(wParam))
{
case LBN_SELCHANGE:
{
int count = SendMessage(LBTest, LB_GETCOUNT, 0, 0);
int iSelected = -1;
// go through the items and find the first selected one
for (int i = 0; i < count; i++)
{
// check if this item is selected or not..
if (SendMessage(LBTest, LB_GETSEL, i, 0) > 0)
{
// yes, we only want the first selected so break.
iSelected = i;
break;
}
}
break;
}
}
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
iSelected 就是您的列表框的 selected 项目编号。您可以将其发送到 LB_GETTEXT 以获取 selected 项目的当前文本:
std::wstring check ;
SendMessage(LBTest, LB_GETTEXT, iSelected, (LPARAM)check.c_str());
你也可以通过这样做得到相同的结果:
std::wstring str;
DWORD dwSel = SendMessage(LBTest, LB_GETCURSEL, 0, 0);
if (dwSel > 0)
{
std::wstring str;
SendMessage(LBTest, LB_GETTEXT, dwSel, (LPARAM)str.c_str());
MessageBox(hWnd, str.c_str(), L"test", MB_OK);
}
这可能是比第一个解决方案更快的解决方案,因为您不必遍历所有列表框项目。