Listview 在我的子类过程中未收到WM_LBUTTONUP
我试图捕捉用户在单击listview后释放鼠标左键的事件 在下面的代码中,我需要双击以获得beep。所需的行为是在用户释放鼠标左键时立即收到嘟嘟声 代码比文字更能说明问题,下面是一个最小的例子:Listview 在我的子类过程中未收到WM_LBUTTONUP,listview,winapi,mouseevent,Listview,Winapi,Mouseevent,我试图捕捉用户在单击listview后释放鼠标左键的事件 在下面的代码中,我需要双击以获得beep。所需的行为是在用户释放鼠标左键时立即收到嘟嘟声 代码比文字更能说明问题,下面是一个最小的例子: #include <windows.h> #include <windowsx.h> // various listview macros etc #include <CommCtrl.h> #include <stdio.h> // swp
#include <windows.h>
#include <windowsx.h> // various listview macros etc
#include <CommCtrl.h>
#include <stdio.h> // swprintf_s()
// enable Visual Styles
#pragma comment( linker, "/manifestdependency:\"type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \
language='*'\"")
// link with Common Controls library
#pragma comment( lib, "comctl32.lib")
//global variables
HINSTANCE hInst;
// subclass procedure for listview -> implements drag and drop
LRESULT CALLBACK Example(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam,
UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (message)
{
case WM_LBUTTONUP:
{
MessageBeep(0); // so I know it is received
}
return DefSubclassProc(hwnd, message, wParam, lParam);
case WM_NCDESTROY:
::RemoveWindowSubclass(hwnd, Example, 0);
return DefSubclassProc(hwnd, message, wParam, lParam);
}
return ::DefSubclassProc(hwnd, message, wParam, lParam);
}
// main window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
//================ create an example listview
RECT rec = { 0 };
GetClientRect(hwnd, &rec);
HWND hwndLV = CreateWindowEx(0, WC_LISTVIEW,
L"", WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | WS_CLIPCHILDREN,
50, 50, 250, 200, hwnd, (HMENU)2000, hInst, 0);
// set extended listview styles
ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER);
// add some columns
LVCOLUMN lvc = { 0 };
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
for (long nIndex = 0; nIndex < 5; nIndex++)
{
wchar_t txt[50];
swprintf_s(txt, 50, L"Column %d", nIndex);
lvc.iSubItem = nIndex;
lvc.cx = 60;
lvc.pszText = txt;
ListView_InsertColumn(hwndLV, nIndex, &lvc);
}
// add some items
LVITEM lvi;
lvi.mask = LVIF_TEXT;
for (lvi.iItem = 0; lvi.iItem < 10000; lvi.iItem++)
{
for (long nIndex = 0; nIndex < 5; nIndex++)
{
wchar_t txt[50];
swprintf_s(txt, 50, L"Item %d%d", lvi.iItem, nIndex);
lvi.iSubItem = nIndex;
lvi.pszText = txt;
if (!nIndex) // item
SendDlgItemMessage(hwnd, 2000, LVM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&lvi));
else // sub-item
SendDlgItemMessage(hwnd, 2000, LVM_SETITEM, 0, reinterpret_cast<LPARAM>(&lvi));
}
}
//============================ subclass it
SetWindowSubclass(hwndLV, Example, 0, 0);
}
return 0L;
case WM_CLOSE:
::DestroyWindow(hwnd);
return 0L;
case WM_DESTROY:
{
::PostQuitMessage(0);
}
return 0L;
default:
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
// store hInstance in global variable for later use
hInst = hInstance;
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
// register main window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"Main_Window";
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!", MB_ICONEXCLAMATION |
MB_OK);
return 0;
}
// initialize common controls
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&iccex);
// create main window
hwnd = CreateWindowEx(0, L"Main_Window", L"Listview Drag and Drop",
WS_OVERLAPPEDWINDOW,
50, 50, 400, 400, NULL, NULL, hInstance, 0);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
#包括
#包括//各种listview宏等
#包括
#包括//swprintf_s()
//启用视觉样式
#pragma注释(链接器,“/manifestdependency:\”类型='win32'\
name='Microsoft.Windows.Common控件'version='6.0.0.0'\
processorArchitecture='*'publicKeyToken='6595b64144ccf1df'\
语言=“*”\“”)
//与公共控件库的链接
#pragma注释(lib,“comctl32.lib”)
//全局变量
HINSTANCE hInst;
//listview->实现拖放的子类过程
LRESULT回调示例(HWND-HWND、UINT消息、WPARAM-WPARAM、LPARAM-LPARAM、,
UINT_PTR uIdSubclass,DWORD_PTR dwRefData)
{
开关(信息)
{
案例WM_LBUTTONUP:
{
MessageBeep(0);//所以我知道它已收到
}
返回defsublassproc(hwnd、message、wParam、lParam);
案例WM\NCU:
::RemoveWindowsSubClass(hwnd,示例,0);
返回defsublassproc(hwnd、message、wParam、lParam);
}
return::defsublassproc(hwnd、message、wParam、lParam);
}
//主窗口程序
LRESULT回调WndProc(HWND HWND,UINT msg,WPARAM WPARAM,LPARAM LPARAM)
{
开关(msg)
{
案例WM_创建:
{
//===================创建示例listview
RECT rec={0};
GetClientRect(hwnd和rec);
HWND hwndLV=CreateWindowEx(0,WC_列表视图,
L'',WS|U儿童| WS|U可见| WS|U边界| LVS|U报告| WS|U儿童,
50,50,250,200,hwnd,(汉努)2000,hInst,0);
//设置扩展的listview样式
ListView_SetExtendedListViewStyle(hwndLV、LVS_EX_FULLROWSELECT、LVS_EX_GRIDLINES、LVS_EX_DOUBLEBUFFER);
//添加一些列
lvc列lvc={0};
lvc.mask=LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_子项;
lvc.fmt=LVCFMT_左;
对于(长nIndex=0;nIndex<5;nIndex++)
{
wchar_t txt[50];
swprintf_s(文本,50,L“第%d列”,索引为nIndex);
lvc.iSubItem=nIndex;
lvc.cx=60;
lvc.pszText=txt;
ListView_InsertColumn(hwndLV、nIndex和lvc);
}
//添加一些项目
lvi项目;
lvi.mask=LVIF_文本;
对于(lvi.iItem=0;lvi.iItem<10000;lvi.iItem++)
{
对于(长nIndex=0;nIndex<5;nIndex++)
{
wchar_t txt[50];
swprintf_s(txt,50,L“项目%d%d”,lvi.iItem,nIndex);
lvi.iSubItem=nIndex;
lvi.pszText=txt;
如果(!nIndex)//项
SendDlgItemMessage(hwnd,2000年,LVM_插入项,0,重新解释(和lvi));
其他//分项
SendDlgItemMessage(hwnd,2000,LVM_SETITEM,0,重新解释(和lvi));
}
}
//==============================================为其子类
SetWindowsSubClass(hwndLV,示例,0,0);
}
返回0升;
案例WM_结束:
::销毁窗口(hwnd);
返回0升;
案例WM_销毁:
{
::PostQuitMessage(0);
}
返回0升;
违约:
return::DefWindowProc(hwnd、msg、wParam、lParam);
}
返回0;
}
//温曼
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、LPSTR lpCmdLine、,
国际展览(nCmdShow)
{
//将hInstance存储在全局变量中供以后使用
hInst=hInstance;
WNDCLASSEX wc;
HWND-HWND;
味精;
//注册主窗口类
wc.cbSize=sizeof(WNDCLASSEX);
wc.style=0;
wc.lpfnWndProc=WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInst;
wc.hIcon=加载图标(hInstance,IDI_应用程序);
wc.hCursor=LoadCursor(空,IDC_箭头);
wc.hbrBackground=GetSysColorBrush(颜色窗口);
wc.lpszMenuName=NULL;
wc.lpszClassName=L“主窗口”;
wc.hIconSm=加载图标(hInstance,IDI_应用程序);
如果(!RegisterClassEx(&wc))
{
MessageBox(NULL,L“窗口注册失败!”,L“错误!”,MB_图标连接|
MB_OK);
返回0;
}
//初始化公共控件
INITCOMMONCONTROLSEX iccex;
iccex.dwSize=sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC=ICC_列表视图_类;
InitCommonControlsEx(&iccex);
//创建主窗口
hwnd=CreateWindowEx(0,L“主窗口”,L“列表视图拖放”,
WS_重叠窗口,
50,50,400,400,NULL,NULL,hInstance,0);
显示窗口(hwnd、nCmdShow);
更新窗口(hwnd);
while(GetMessage(&Msg,NULL,0,0)>0)
{
翻译信息(&Msg);
发送消息(&Msg);
}
返回Msg.wParam;
}
单击listview中的一行后,不会发出蜂鸣音。我做错了什么?根据本次讨论:
:
…我正在对列表视图进行细分,以查看WM_LBUTTONDOWN和
WM_LBUTTONUP。。。我的问题是:我看到了WM_LBUTTONDOWN,但从来没有看到WM_LBUTTONUP。Spy++告诉我这两条消息都将发送到控件。我对控件如何“吃掉”WM_LBUTTONUP感到困惑
问题在于,列表控件本身设计了一些
相当复杂的点击处理。当列表控件的默认值为
windowproc接收WM_LBUTTONDOWN或WM_RBUTTONDOWN消息,它进入
它自己的模式消息循环,持续到相应的
接收到WM_LBUTTONUP或WM_RBUTTONUP消息。是的,基本上,这
模态消息循环吃掉WM_LBUTTONUP/WM_RBUTTONUP消息;你的窗户
代码永远不会变