Win32 SDK Gui编程系列之--ListView自绘OwnerDraw

ListView自绘OwnerDraw

1.ListView自绘OwnerDraw

正在试错是否使用了列表视图,尽量制作出智能的表格编辑器。本页显示了业主抽签的表格数据(二维数组数据)的显示方法。

显示画面和整个程序如下所示。使用ListView_GetSubItemRect宏的话,就不需要getRect函数了。

当nCol的值为0时得到的区域不是第一列,而是全列即整个行的区域。因为下面的程序是左对齐显示的,所以没有问题,但是要把显示放在中间或改变第1列的背景颜色的话,需要第1列的区域。为此,第1列的右端需要从第2列的左端进行修正。

Listview51.c

//ListView

#include <windows.h>
#include <commctrl.h>
#pragma  comment(lib, "comctl32.lib")

#define  NROW   12
#define  NCOL   4
char  *colname[NCOL] = { "No.", "Name", "Attr", "Age" };
char  *table[NROW][NCOL] = { 
	{"01","张三","老大", "15"}, {"02","李四","老二","11"}, {"03","王五","老三","9"}, 
	{"04","张三","老大", "15"}, {"05","李四","老二","11"}, {"06","王五","老三","9"}, 
	{"07","张三","老大", "15"}, {"08","李四","老二","11"}, {"09","王五","老三","9"}, 
        {"10","张三","老大", "15"}, {"11","李四","老二","11"}, {"12","王五","老三","9"}, 
};

HWND   hList;

//  ListView_GetSubItemRect(hwnd, nRow, nCol, LVIR_BOUNDS, pRect);
BOOL getRect(HWND hwnd, int nRow, int nCol, RECT *pRect) {
    pRect->left = LVIR_BOUNDS;
    pRect->top = nCol;
    return (BOOL)SendMessage(hwnd, LVM_GETSUBITEMRECT, (WPARAM)nRow, (LPARAM)pRect);
}

// ListView的所有者抽签。行单位。
int onDrawItem(HWND hwnd, WPARAM wp, LPARAM lp) {
    DRAWITEMSTRUCT *pds = (DRAWITEMSTRUCT *)lp;
    if (pds->hwndItem == hList) {
	int  nCol, nRow = pds->itemID;
	HDC  hdc = pds->hDC;
	for (nCol = 0; nCol < NCOL; nCol++) {
	    RECT rc;
	    getRect(hList, nRow, nCol, &rc);
	    rc.left += 4;
	    DrawText(hdc, table[nRow][nCol], -1, &rc, DT_VCENTER|DT_SINGLELINE|DT_LEFT);
	}
    }
    return TRUE;
}

void onCreate(HWND hWnd) {
    int iCol, iRow;

    hList = CreateWindowEx(0, WC_LISTVIEW, NULL, 
		WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_OWNERDRAWFIXED,
        	0, 0, 1, 1, hWnd, (HMENU)777, NULL, NULL);
    SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES);
    for (iCol = 0; iCol < NCOL; iCol++) {
    	LVCOLUMN col = { LVCF_FMT|LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM, 0, 
			 70, colname[iCol], 0, iCol };
        SendMessage(hList, LVM_INSERTCOLUMN, iCol, (LPARAM)&col);
    }
    for (iRow = 0; iRow < NROW; iRow++) {
	LVITEM item = { LVIF_TEXT, iRow };
        SendMessage(hList, LVM_INSERTITEM, 0, (LPARAM)&item);
    }
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) {
    switch (umsg) {
      case WM_CREATE: onCreate(hwnd); return 0;
      case WM_DRAWITEM: return onDrawItem(hwnd, wp, lp);
      case WM_SIZE: MoveWindow(hList, 0, 0, lp&0xffff, lp>>16, TRUE); return 0;
      case WM_DESTROY: PostQuitMessage(0); return 0;
    }
    return DefWindowProc(hwnd, umsg, wp, lp);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) {
    MSG msg;
    WNDCLASS wc = { 0, WindowProc, 0, 0, hInst, NULL, LoadCursor(NULL,IDC_ARROW), NULL, NULL, "mh" };
    if (!RegisterClass(&wc)) return FALSE;
    InitCommonControls();
    if (!CreateWindowEx(0, "mh", "ListView", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
	 		100, 100, 250, 200, NULL, NULL, hInst, NULL)) return FALSE;
    while (GetMessage(&msg,NULL,0,0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

猜你喜欢

转载自blog.csdn.net/weixin_55465758/article/details/136018873