Win32 C++ 如何在 ListView 子类中处理 LVM_SETCOLUMNWIDTH?
Win32 C++ How to handle LVM_SETCOLUMNWIDTH in a ListView subclass?
我有一个 ListView,我想根据 ListView 本身的大小调整其列的大小(根据 window 大小调整大小)。 ListView 是一个单独的 WNDPROC
子类,其中 WM_NOTIFY
用于处理其他消息。
为了调整 header 列的大小,我正在使用 ListView_SetColumnWidth()
,但这仅在我停用单独的 ListView WNDPROC
或从中删除 WM_NOTIFY
处理时才有效.
我已经尝试在 ListView 及其 header 的 WNDPROC
中手动处理 LVM_SETCOLUMNWIDTH
以查看消息是否通过,但无济于事。
我不太确定如何进行;任何帮助将不胜感激。
作为参考,我的 ListView 中的 WM_NOTIFY
WNDPROC
:
case WM_NOTIFY:
{
UINT debugval = (((LPNMHDR)lParam)->code);
switch (((LPNMHDR)lParam)->code)
{
case HDN_BEGINTRACK:
{
return TRUE; //Prevent manual resizing.
break;
}
case LVM_SETCOLUMNWIDTH:
{
::MessageBox(hwnd, L"test", L"test", MB_OK);
break;
}
}
break;
}
LVM_SETCOLUMNWIDTH
是它自己的单独消息,它不会像您编码的那样通过 WM_NOTIFY
传递。您需要将 case LVM_SETCOLUMNWIDTH
移动到外部 switch
中。并确保您为所有不想丢弃的消息调用 CallWindowProc()
或 DefSubclassProc()
(取决于您创建子类的方式)。
试试像这样的东西:
switch (uMsg)
{
case WM_NOTIFY:
{
UINT code = (((LPNMHDR)lParam)->code);
switch (code)
{
case HDN_BEGINTRACK:
{
return TRUE; //Prevent manual resizing.
}
}
break;
}
case LVM_SETCOLUMNWIDTH:
{
...
break;
}
}
return CallWindowProc(..., hwnd, uMsg, wParam, lParam);
or
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
I have a ListView whose columns I'd like to resize in relation to the size of the ListView itself (which is sized based on the window size).
所以在mainwindow中需要通过SetWindowPos
, and modify the size of the ListView columns through ListView_SetColumnWidth
修改Listview的大小。
喜欢下面的代码:
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
int cxClient = LOWORD(lParam);
int cyClient = HIWORD(lParam);
SetWindowPos(Instructions_ListView, NULL, cxClient / 3, cyClient / 4, cxClient / 5, cyClient / 2, SWP_SHOWWINDOW);
ListView_SetColumnWidth(Instructions_ListView, 0, cxClient / 10);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
那么在ListView的WNDPROC
函数中,LVM_SETCOLUMNWIDTH
是自己独有的消息,不属于WM_NOTIFY
。其他默认消息通过DefSubclassProc
处理。
所以可以参考下面的代码:
LRESULT CALLBACK ListProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_NOTIFY:
{
UINT debugval = (((LPNMHDR)lParam)->code);
switch (debugval)
{
case HDN_BEGINTRACK:
return true;
}
break;
}
case LVM_SETCOLUMNWIDTH:
OutputDebugString(L"LVM_SETCOLUMNWIDTH triggered\n");
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
终于对我有用了:
我有一个 ListView,我想根据 ListView 本身的大小调整其列的大小(根据 window 大小调整大小)。 ListView 是一个单独的 WNDPROC
子类,其中 WM_NOTIFY
用于处理其他消息。
为了调整 header 列的大小,我正在使用 ListView_SetColumnWidth()
,但这仅在我停用单独的 ListView WNDPROC
或从中删除 WM_NOTIFY
处理时才有效.
我已经尝试在 ListView 及其 header 的 WNDPROC
中手动处理 LVM_SETCOLUMNWIDTH
以查看消息是否通过,但无济于事。
我不太确定如何进行;任何帮助将不胜感激。
作为参考,我的 ListView 中的 WM_NOTIFY
WNDPROC
:
case WM_NOTIFY:
{
UINT debugval = (((LPNMHDR)lParam)->code);
switch (((LPNMHDR)lParam)->code)
{
case HDN_BEGINTRACK:
{
return TRUE; //Prevent manual resizing.
break;
}
case LVM_SETCOLUMNWIDTH:
{
::MessageBox(hwnd, L"test", L"test", MB_OK);
break;
}
}
break;
}
LVM_SETCOLUMNWIDTH
是它自己的单独消息,它不会像您编码的那样通过 WM_NOTIFY
传递。您需要将 case LVM_SETCOLUMNWIDTH
移动到外部 switch
中。并确保您为所有不想丢弃的消息调用 CallWindowProc()
或 DefSubclassProc()
(取决于您创建子类的方式)。
试试像这样的东西:
switch (uMsg)
{
case WM_NOTIFY:
{
UINT code = (((LPNMHDR)lParam)->code);
switch (code)
{
case HDN_BEGINTRACK:
{
return TRUE; //Prevent manual resizing.
}
}
break;
}
case LVM_SETCOLUMNWIDTH:
{
...
break;
}
}
return CallWindowProc(..., hwnd, uMsg, wParam, lParam);
or
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
I have a ListView whose columns I'd like to resize in relation to the size of the ListView itself (which is sized based on the window size).
所以在mainwindow中需要通过SetWindowPos
, and modify the size of the ListView columns through ListView_SetColumnWidth
修改Listview的大小。
喜欢下面的代码:
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
int cxClient = LOWORD(lParam);
int cyClient = HIWORD(lParam);
SetWindowPos(Instructions_ListView, NULL, cxClient / 3, cyClient / 4, cxClient / 5, cyClient / 2, SWP_SHOWWINDOW);
ListView_SetColumnWidth(Instructions_ListView, 0, cxClient / 10);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
那么在ListView的WNDPROC
函数中,LVM_SETCOLUMNWIDTH
是自己独有的消息,不属于WM_NOTIFY
。其他默认消息通过DefSubclassProc
处理。
所以可以参考下面的代码:
LRESULT CALLBACK ListProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_NOTIFY:
{
UINT debugval = (((LPNMHDR)lParam)->code);
switch (debugval)
{
case HDN_BEGINTRACK:
return true;
}
break;
}
case LVM_SETCOLUMNWIDTH:
OutputDebugString(L"LVM_SETCOLUMNWIDTH triggered\n");
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
终于对我有用了: