C++ WM_HOVER不使用WinAPI ListView
我在屏幕上有一个ListView绘图。现在,我尝试在用户将鼠标悬停在项目上时调用一个函数。我现在正在尝试使用WM_HOVER,因为它看起来是最直接的方向;然而,它似乎不起作用。我得到了C++ WM_HOVER不使用WinAPI ListView,c++,windows,listview,winapi,C++,Windows,Listview,Winapi,我在屏幕上有一个ListView绘图。现在,我尝试在用户将鼠标悬停在项目上时调用一个函数。我现在正在尝试使用WM_HOVER,因为它看起来是最直接的方向;然而,它似乎不起作用。我得到了WM_点击可以很好地工作,但不能用于悬停 WM\u HOVER会做我需要它做的事情吗,还是应该研究其他东西,比如TrackMouseEvent() 下面是一些示例代码。实际上,我认为唯一相关的部分是WndProc()下面的案例WM\u HOVER: //libraries #pragma comment (&
WM_点击
可以很好地工作,但不能用于悬停
WM\u HOVER
会做我需要它做的事情吗,还是应该研究其他东西,比如TrackMouseEvent()
下面是一些示例代码。实际上,我认为唯一相关的部分是WndProc()
下面的案例WM\u HOVER:
//libraries
#pragma comment ("lib", "Comctl32.lib")
#pragma comment ("lib", "d2d1.lib")
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <vector>
#include <string>
#include <dwrite.h>
#include <d2d1.h>
#include <commctrl.h>
#include <strsafe.h>
#define IDS_APP_TITLE 103
#define IDR_MAINFRAME 128
#define IDD_PRACTICE_DIALOG 102
#define IDD_ABOUTBOX 103
#define IDM_EXIT 105
#define IDI_PRACTICE 107
#define IDI_SMALL 108
#define IDC_PRACTICE 109
#define IDC_MYICON 2
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif
#define MAX_LOADSTRING 100
#define PROJECT_LIST_VIEW 110
BOOL mouseTracking = false;
// Global Variables:
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
std::vector<std::string> stringsVector = { "String1", "String2", "String3" };
//D2D1 pointers
ID2D1Factory* m_pD2DFactory;
ID2D1DCRenderTarget* m_pRenderTarget;
ID2D1SolidColorBrush* m_pBlackBrush;
//dimension variables
int w, h;
RECT rc;
HWND listViewHandle;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
HRESULT CreateDeviceResources(HWND hwnd, HDC hdc);
bool onRender(HWND hwnd, PAINTSTRUCT* ps);
///////////////////
//Function to insert the items into the list view
//////////////////
BOOL InsertListViewItems(HWND hWndListView, int cItems);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_PRACTICE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
// Perform application initialization:
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PRACTICE));
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
//Create the List View Control
listViewHandle = CreateWindow(WC_LISTVIEW, L"", WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_EDITLABELS, 100, 100, 500, 500, hWnd, (HMENU)PROJECT_LIST_VIEW, hInst, NULL);
InsertListViewItems(listViewHandle, stringsVector.size());
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
{
HDC hdc = BeginPaint(hWnd, &ps);
onRender(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
}
case WM_SIZE:
{
if (m_pRenderTarget)
{
m_pRenderTarget->Release();
m_pRenderTarget = nullptr;
}
break;
}
////////////////////////////////////////////
//
// HERE ARE THE MOUSE MOVE CASES
//
/////////////////////////////////////////////
case WM_MOUSEHOVER:
{
OutputDebugStringA("HOVER\n");
mouseTracking = FALSE;
break;
}
case WM_MOUSEMOVE:
if (!mouseTracking)
{
// start tracking if we aren't already
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.hwndTrack = listViewHandle; //This is the handle to the ListView window
tme.dwHoverTime = HOVER_DEFAULT;
mouseTracking = TrackMouseEvent(&tme);
}
break;
case WM_MOUSELEAVE:
mouseTracking = FALSE;
break;
case WM_NOTIFY:
{
NMLVDISPINFO* plvdi;
switch (((LPNMHDR)lParam)->code)
{
case NM_CLICK:
OutputDebugStringA("CLICK\n");
break;
case LVN_GETDISPINFO:
{
////////////////////
//This is the callback that sets the pszText attribute of the items
////////////////////
plvdi = (NMLVDISPINFO*)lParam;
const char* inString = stringsVector[plvdi->item.iItem].c_str();
size_t size = strlen(inString) + 1;
wchar_t* outString = new wchar_t[size];
size_t outSize;
mbstowcs_s(&outSize, outString, size, inString, size - 1);
LPWSTR ptr = outString;
StringCchCopy(plvdi->item.pszText, plvdi->item.cchTextMax, outString);
delete[] outString;
break;
}
}
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
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_PRACTICE));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PRACTICE);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
&m_pD2DFactory
);
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//////////////////
//Function to insert the items into the list view
//////////////////
BOOL InsertListViewItems(HWND hWndListView, int cItems)
{
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
// Initialize LVITEM members that are common to all items.
// Initialize LVITEM members that are different for each item.
lvc.iSubItem = 0;
lvc.pszText = (LPWSTR)L"test";
lvc.cx = 200;
// Insert items into the list.
if (ListView_InsertColumn(hWndListView, 0, &lvc) == -1)
return FALSE;
LVITEM lvI;
// Initialize LVITEM members that are common to all items.
lvI.pszText = LPSTR_TEXTCALLBACK; //This should send an LVN_GETDISPINFO message
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = 0;
lvI.iSubItem = 0;
lvI.state = 0;
// Initialize LVITEM members that are different for each item.
for (int index = 0; index < cItems; index++)
{
lvI.iItem = index;
lvI.iImage = index;
// Insert items into the list.
if (ListView_InsertItem(hWndListView, &lvI) == -1)
return FALSE;
}
return TRUE;
}
HRESULT CreateDeviceResources(HWND hwnd, HDC hdc)
{
HRESULT hr = S_OK;
if (!m_pRenderTarget) { //If m_pRenderTarget changes size
// Create a DC render target.
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
hr = m_pD2DFactory->CreateDCRenderTarget(&props, &m_pRenderTarget);
GetClientRect(hwnd, &rc);
if (SUCCEEDED(hr))
hr = m_pRenderTarget->BindDC(hdc, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
w = size.width;
h = size.height;
if (SUCCEEDED(hr))
{//position objects
// Create a black brush
hr = m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &m_pBlackBrush);
}
}
return hr;
}
bool onRender(HWND hwnd, PAINTSTRUCT* ps)
{
HDC hdc = ps->hdc;
HRESULT hr;
hr = CreateDeviceResources(hwnd, hdc);
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::IdentityMatrix());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
hr = m_pRenderTarget->EndDraw();
}
SetWindowPos(listViewHandle, HWND_TOP, w * .1, h * .1, w * .3, h * .3, SWP_SHOWWINDOW);
SendMessage(listViewHandle, LVM_SETCOLUMNWIDTH, 0, w * .2);
if(SUCCEEDED(hr))
return true;
return false;
}
//库
#pragma注释(“lib”、“Comctl32.lib”)
#pragma注释(“lib”、“d2d1.lib”)
#包括“targetver.h”
#定义WIN32_LEAN_和_MEAN//从Windows标题中排除很少使用的内容
//Windows头文件
#包括
//C运行时头文件
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义ID\u应用程序\u标题103
#定义IDR_大型机128
#定义IDD_实践_对话框102
#定义IDD_关于框103
#定义IDM_出口105
#定义IDI_实践107
#定义IDI_小108
#定义IDC_实践109
#定义IDC_MYICON 2
#ifndef IDC_静态
#定义IDC_静态-1
#恩迪夫
#定义最大加载字符串100
#定义项目列表视图110
BOOL mouseTracking=false;
//全局变量:
HINSTANCE hInst;//当前实例
WCHAR szTitle[MAX_LOADSTRING];//标题栏文本
WCHAR szWindowClass[最大加载字符串];//主窗口类名称
向量stringsVector={“String1”、“String2”、“String3”};
//D2D1指针
ID2D1工厂*m_PD2工厂;
ID2D1CrenderTarget*m_pRenderTarget;
ID2D1SOLIDCORBRUSH*m_pBlackBrush;
//维度变量
int w,h;
RECT-rc;
HWND listViewHandle;
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM);
ATOM MyRegisterClass(HINSTANCE HINSTANCE);
BOOL InitInstance(HINSTANCE-HINSTANCE,int-nCmdShow);
HRESULT CreateDeviceResources(HWND HWND、HDC HDC);
bool onRender(HWND-HWND,PAINTSTRUCT*ps);
///////////////////
//函数将项目插入列表视图
//////////////////
BOOL InsertListViewItems(HWND hWndListView,int cItems);
国际货币基金组织,
_在当前情况下,
_在LPWSTR lpCmdLine中,
_In_uuint(nCmdShow)
{
未引用的_参数(HPPreInstance);
未引用的_参数(lpCmdLine);
//初始化全局字符串
LoadStringW(hInstance、IDS\U APP\U TITLE、szTitle、MAX\U LOADSTRING);
LoadStringW(hInstance、IDC_PRACTICE、szWindowClass、MAX_LOADSTRING);
MyRegisterClass(hInstance);
SetProcessDPIawarenesContext(DPI\U感知\U上下文每\U监视器\U感知\U V2);
//执行应用程序初始化:
如果(!InitInstance(hInstance,nCmdShow))
{
返回FALSE;
}
HACCEL hAccelTable=装载加速器(hInstance,MAKEINTRESOURCE(IDC_实践));
味精;
//主消息循环:
while(GetMessage(&msg,nullptr,0,0))
{
if(!TranslateAccelerator(msg.hwnd、hAccelTable和msg))
{
翻译信息(&msg);
发送消息(&msg);
}
}
返回(int)msg.wParam;
}
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
PAINTSTRUCT-ps;
开关(信息)
{
案例WM_创建:
//创建列表视图控件
listViewHandle=CreateWindow(WC_LISTVIEW,L“”,WS_CHILD | WS|u VISIBLE | LVS|u REPORT | LVS|u EDITLABELS,100100500500,hWnd,(HMENU)项目(列表)视图,hInst,NULL);
InsertListViewItems(listViewHandle,stringsVector.size());
打破
案例WM_销毁:
PostQuitMessage(0);
打破
案例WM_油漆:
{
HDC HDC=开始喷漆(hWnd和ps);
onRender(hWnd和ps);
端漆(hWnd和ps);
打破
}
案例WM_大小:
{
如果(m_pRenderTarget)
{
m_pRenderTarget->Release();
m_pRenderTarget=nullptr;
}
打破
}
////////////////////////////////////////////
//
//这是鼠标移动的例子
//
/////////////////////////////////////////////
案例WM_鼠标套:
{
OutputDebugStringA(“悬停\n”);
捕鼠器追踪=错误;
打破
}
案例WM_MOUSEMOVE:
如果(!捕鼠器跟踪)
{
//如果我们还没有开始跟踪
TRACKMOUSEEVENT-tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=tme|u悬停| tme|u离开;
tme.hwndTrack=listViewHandle;//这是ListView窗口的句柄
tme.dwHoverTime=HOVER\u默认值;
mouseTracking=TrackMouseEvent(&tme);
}
打破
案例WM_MOUSELEAVE:
捕鼠器追踪=错误;
打破
案件通知:
{
NMLVDISPINFO*plvdi;
开关(((LPNMHDR)LPRAM)->代码)
{
案例NM_单击:
OutputDebugStringA(“单击\n”);
打破
案例LVN\u GETDISPINFO:
{
////////////////////
//这是设置项的pszText属性的回调
////////////////////
plvdi=(NMLVDISPINFO*)LPRAM;
const char*inString=stringsVector[plvdi->item.iItem].c_str();
尺寸=斯特伦(仪表)+1;
wchar_t*outString=新的wchar_t[size];
尺寸不要太大;
mbstowcs_s(超大、突出、尺寸、安装、尺寸-1);
LPWSTR ptr=外接;
StringCchCopy(plvdi->item.pszText,plvdi->item.cchTextMax,outString);
删除[]突出部分;
打破
}
}
打破
}
违约:
返回DefWindowProc(hWnd,消息,
ListView_SetExtendedListViewStyle(listViewHandle, LVS_EX_TRACKSELECT);
WNDPROC oldListViewProc; //A global variable
oldListViewProc = (WNDPROC)SetWindowLongPtr(listViewHandle, GWL_WNDPROC, (LONG_PTR)ListViewProc);
......
LRESULT CALLBACK ListViewProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_MOUSEHOVER:
{
OutputDebugStringA("HOVER\n");
return 0;
}
case WM_MOUSEMOVE:
if (!mouseTracking)
{
// start tracking if we aren't already
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.hwndTrack = hwnd; //This is the handle to the ListView window
tme.dwHoverTime = HOVER_DEFAULT;
mouseTracking = TrackMouseEvent(&tme);
}
break;
case WM_MOUSELEAVE:
mouseTracking = FALSE;
break;
}
return CallWindowProc(oldListViewProc, hwnd, msg, wParam, lParam);
}