Win32 SDK创建ListView控件

相关链接:
http://www.codeproject.com/KB/combobox/listview.aspx   CodeProject是个非常不错的网站,让我们可以吸收外国同行的编程经验。


Win32 SDK利用ListView控件。
为了使用ListView控件,我们需要初始化公共控件库,我们需要在程序刚刚启动时调用
InitCommonControls() 函数,如果发生链接错误,说明我们没有链接拥有该函数的库文件。它们对应的
头和库 DLL分别为 #include <commctrl.h> comctl32.lib comctl32.dll
为了使用这个控件 我们就需要知道它的窗口类,利用Spy++等文件可以找到指定进程窗口的窗口类,
而一个ListView控件也是一个子窗口,所以我们可以得到它的类名为syslistview32,其他的控件,
我们只需要按照同样的道理来得到类名即可。
有了类名还不够,我们还需要知道每种控件的风格,比如listView控件有以下的风格LVS_REPORT | LVS_SHOWSELALWAYS, 它表示要产生报表和总是显示。为了得到控件的风格,我们可以通过MSDN中MFC中的ListView风格来作参考。有了窗口类和风格,我们利用CreateWindow就可以创建并得到
这个控件的句柄了。有了句柄,我们就可以随便控制了,具体要怎么看你自己的了。

此外为了向ListView内插入项和列,我们需要两个结构体。
LVITEM和LVCOLUMN

它们的定义分别为
typedef struct _LVITEM { 
UINT mask;
int iItem;
int iSubItem;
UINT state;
UINT stateMask;
LPTSTR pszText;
int cchTextMax;
int iImage;
LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
int iIndent;
#endif
#if (_WIN32_IE >= 0x560)
int iGroupId;
UINT cColumns; // tile view columns
PUINT puColumns;
#endif

typedef struct _LVCOLUMN {
UINT mask;
int fmt;
int cx;
LPTSTR pszText;
int cchTextMax;
int iSubItem;
#if (_WIN32_IE >= 0x0300)
int iImage;
int iOrder;
#endif
} LVCOLUMN, *LPLVCOLUMN;

} LVITEM, *LPLVITEM;
有了这两个结构体,我们就可以利用SendMessage来给ListView控件发送消息来为它添加项和列。
我们分别通过下面两个消息来添加项和列。
SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
SendMessage(hButton, LVM_INSERTCOLUMN, 0, (LPARAM)&colmn);

LVM_INSERTITEM表示添加项
LVM_INSERTCOLUMN表示添加列。
为了更好的查找关于ListView的消息,我们只需要在网上或MSDN 里查找 LVM_XXXXXX 就可以找到
相关的消息了。最好自己整理出一份关于ListView的全部消息。

WindowFrame &wndFrame = WindowFrame::Instance();
   
    GetWindowRect(hWnd, &rect);
    cx = rect.right-rect.left;
    cy = rect.bottom-rect.top;

    switch(msg)
    {
    case WM_CREATE:
        {
            rowIndex = 7;
            hButton = CreateWindow("syslistview32", "",
                                     WS_VISIBLE|WS_CHILD|WS_BORDER|
                                    LVS_REPORT | LVS_SHOWSELALWAYS,
                                    10, 20,
                                    cx-30,
                                    cy-100,
                                    hWnd, NULL, wndFrame.getInstance(), NULL);
            // 添加数据
            LV_ITEM item;       // 项
            LV_COLUMN colmn;     // 列
            ZeroMemory(&item, sizeof(LV_ITEM));
            ZeroMemory(&colmn, sizeof(LV_COLUMN));
           
            colmn.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; // 风格
            colmn.cx = 0x28;
            colmn.pszText = "进程名"; // 文字
            colmn.cx = 0x42;         // 后面列
            SendMessage(hButton, LVM_INSERTCOLUMN, 0, (LPARAM)&colmn);
            colmn.pszText = "内存使用";
            SendMessage(hButton, LVM_INSERTCOLUMN, 0, (LPARAM)&colmn);
            colmn.pszText = "ID";
            SendMessage(hButton, LVM_INSERTCOLUMN, 0, (LPARAM)&colmn);

            // 添加一些行项
            item.mask = LVIF_TEXT;       // 文字
            item.cchTextMax = MAX_PATH;       // 文字长度
            item.iItem = 0;
            item.iSubItem = 0;
            item.pszText = "中国";
            SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
            item.pszText = "日本";
            SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
            item.pszText = "德国";
            SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
            item.pszText = "俄国";
            SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
            item.pszText = "美国";
            SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
            item.pszText = "英国";
            SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
            item.pszText = "法国";
            SendMessage(hButton, LVM_INSERTITEM, 0, (LPARAM)&item);
        }
        break;

 

如果你想通过自定义滚动条来替换ListView原有的滚动条,同时隐藏原有的滚动条,可以考虑以下方法: 1. 在创建ListView控件时,将其style参数设置为LVS_NOSCROLL,这样就可以隐藏原有的滚动条。 ```cpp HWND hwndListView = CreateWindow(WC_LISTVIEW, NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_NOSCROLL, x, y, cx, cy, hwndParent, (HMENU)ID_LISTVIEW, hInstance, NULL); ``` 2. 创建自定义滚动条控件,并将其与ListView控件绑定。在自定义滚动条控件的WM_VSCROLL消息处理函数中,通过SendMessage函数发送WM_VSCROLL消息给ListView控件,从而控制ListView的滚动。 3. 在ListView控件的WM_SIZE消息处理函数中,根据ListView控件的大小和内容的大小来设置自定义滚动条的大小和位置。 4. 如果自定义滚动条控制ListView的同时,想隐藏原有的滚动条,可以在自定义滚动条控件的WM_VSCROLL消息处理函数中,调用ShowScrollBar函数将原有的滚动条隐藏。但是由于ShowScrollBar函数的实现方式可能会导致一闪而过的情况出现,可以考虑使用双缓冲技术来解决这个问题。在WM_PAINT消息处理函数中,使用双缓冲绘制自定义滚动条控件,然后再将绘制好的图像一次性地显示出来,避免了闪烁的情况。 下面是一个简单的示例代码,仅供参考: ```cpp // 创建ListView控件 HWND hwndListView = CreateWindow(WC_LISTVIEW, NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_NOSCROLL, x, y, cx, cy, hwndParent, (HMENU)ID_LISTVIEW, hInstance, NULL); // 创建自定义滚动条控件 HWND hwndScrollBar = CreateWindow(TEXT("SCROLLBAR"), NULL, WS_CHILD | WS_VISIBLE | SBS_VERT, x, y, cx, cy, hwndParent, (HMENU)ID_SCROLLBAR, hInstance, NULL); // 将自定义滚动条控件ListView控件绑定 SetWindowLong(hwndScrollBar, GWL_ID, (LONG)GetDlgItem(hwndParent, ID_LISTVIEW)); SetWindowLong(hwndScrollBar, GWL_STYLE, GetWindowLong(hwndScrollBar, GWL_STYLE) | SBS_RIGHTALIGN); // 自定义滚动条控件的WM_VSCROLL消息处理函数 LRESULT CALLBACK ScrollBarProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_VSCROLL: { HWND hwndListView = (HWND)GetWindowLong(hwnd, GWL_ID); int iScrollPos = GetScrollPos(hwnd, SB_CTL); switch (LOWORD(wParam)) { case SB_LINEUP: iScrollPos -= 1; break; case SB_LINEDOWN: iScrollPos += 1; break; case SB_PAGEUP: iScrollPos -= 10; break; case SB_PAGEDOWN: iScrollPos += 10; break; case SB_TOP: iScrollPos = 0; break; case SB_BOTTOM: iScrollPos = GetScrollRange(hwnd, SB_CTL) - GetScrollPage(hwnd, SB_CTL); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: iScrollPos = HIWORD(wParam); break; } iScrollPos = max(0, iScrollPos); iScrollPos = min(iScrollPos, GetScrollRange(hwnd, SB_CTL) - GetScrollPage(hwnd, SB_CTL)); SetScrollPos(hwnd, SB_CTL, iScrollPos, TRUE); SendMessage(hwndListView, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, iScrollPos), 0); // 隐藏原有的滚动条 ShowScrollBar(hwndListView, SB_VERT, FALSE); // 双缓冲绘制自定义滚动条控件 PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rcClient; GetClientRect(hwnd, &rcClient); HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom); HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap); // 绘制自定义滚动条控件 DrawScrollBar(hdcMem, rcClient, iScrollPos); BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hBitmapOld); DeleteObject(hBitmap); DeleteDC(hdcMem); EndPaint(hwnd, &ps); return 0; } case WM_PAINT: { // 双缓冲绘制自定义滚动条控件 PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rcClient; GetClientRect(hwnd, &rcClient); HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom); HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap); // 绘制自定义滚动条控件 int iScrollPos = GetScrollPos(hwnd, SB_CTL); DrawScrollBar(hdcMem, rcClient, iScrollPos); BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hBitmapOld); DeleteObject(hBitmap); DeleteDC(hdcMem); EndPaint(hwnd, &ps); return 0; } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } // ListView控件的WM_SIZE消息处理函数 void OnSize(HWND hwnd, UINT state, int cx, int cy) { // 获取ListView控件的句柄 HWND hwndListView = GetDlgItem(hwnd, ID_LISTVIEW); // 设置自定义滚动条控件的位置和大小 HWND hwndScrollBar = GetDlgItem(hwnd, ID_SCROLLBAR); SetWindowPos(hwndScrollBar, NULL, cx - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH, cy, SWP_NOZORDER); // 设置自定义滚动条控件的范围和页面大小 int iScrollRange = GetScrollRange(hwndListView, SB_VERT); int iScrollPage = GetScrollPage(hwndListView, SB_VERT); SetScrollRange(hwndScrollBar, SB_CTL, 0, iScrollRange - iScrollPage, FALSE); SetScrollPage(hwndScrollBar, SB_CTL, iScrollPage, FALSE); } // 绘制自定义滚动条控件 void DrawScrollBar(HDC hdc, RECT rcClient, int iScrollPos) { // TODO: 绘制自定义滚动条控件 } ``` 其中,SCROLLBAR_WIDTH是自定义滚动条控件的宽度。GetScrollRange和GetScrollPage是获取ListView控件的滚动范围和页面大小的函数。DrawScrollBar是用来绘制自定义滚动条控件的函数,可以根据需要自行实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值