winapi - Win32 Virtual ListView: Cannot select full row -
yesterday downloaded sdk example virtual listview
. code run can't figure out how make listview full row select (it hightlight first column).
here how modify source code create listview:
dwstyle = ws_tabstop | ws_child | ws_visible | lvs_autoarrange | lvs_report | lvs_ownerdata; hwndlistview = createwindowex(lvs_ex_fullrowselect, // ex style wc_listview, // class name - defined in commctrl.h text(""), // dummy text dwstyle, // style 0, // x position 0, // y position 0, // width 0, // height hwndparent, // parent (hmenu)id_listview, // id g_hinst, // instance null); // no data
although followed msdn guide:
lvs_ex_fullrowselect
when item selected, item , subitems highlighted. style available in conjunction lvs_report style.
but listview still refuse select full row. how work?
here full code:
vlistvw.h
/************************************************************************** code , information provided "as is" without warranty of kind, either expressed or implied, including not limited implied warranties of merchantability and/or fitness particular purpose. copyright 1999 - 2000 microsoft corporation. rights reserved. **************************************************************************/ #include "resource.h" #ifndef win32 #define get_wm_command_id(wp, lp) (wp) #define get_wm_command_hwnd(wp, lp) (hwnd)(loword(lp)) #define get_wm_command_cmd(wp, lp) hiword(lp) #endif int pascal winmain(hinstance, hinstance, lpstr, int); bool initapplication(hinstance); bool initinstance(hinstance, int); lresult callback mainwndproc(hwnd, uint, wparam, lparam); int_ptr callback aboutdlgproc(hwnd, uint, wparam, lparam); hwnd createlistview(hinstance, hwnd); void resizelistview(hwnd, hwnd); bool initlistview(hwnd); #define id_listview 2000
vlistvw.c
/************************************************************************** code , information provided "as is" without warranty of kind, either expressed or implied, including not limited implied warranties of merchantability and/or fitness particular purpose. copyright 1999 - 2000 microsoft corporation. rights reserved. **************************************************************************/ /************************************************************************** include files **************************************************************************/ #define strict #include <windows.h> #include <windowsx.h> #include <commctrl.h> #include <tchar.h> #include <stdio.h> #include "vlistvw.h" #pragma comment(linker,"/manifestdependency:\"type='win32' name='microsoft.windows.common-controls' version='6.0.0.0' processorarchitecture='x86' publickeytoken='6595b64144ccf1df' language='*'\"") /************************************************************************** local function prototypes **************************************************************************/ #define errorhandler() errorhandlerex(__line__, __file__) void errorhandlerex(word, lpstr); lresult listviewnotify(hwnd, lparam); void switchview(hwnd, dword); bool docontextmenu(hwnd, wparam, lparam); void updatemenu(hwnd, hmenu); bool insertlistviewitems(hwnd); void positionheader(hwnd); /************************************************************************** global variables **************************************************************************/ hinstance g_hinst; tchar g_szclassname[] = text("vlistvwclass"); #define item_count 100000 /****************************************************************************** winmain ******************************************************************************/ int pascal winmain(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow) { msg msg; g_hinst = hinstance; if (!hprevinstance) if (!initapplication(hinstance)) return false; //required use common controls initcommoncontrols(); /* perform initializations apply specific instance */ if (!initinstance(hinstance, ncmdshow)) return false; /* acquire , dispatch messages until wm_quit umessage received. */ while (getmessage(&msg, null, 0x00, 0x00)) { translatemessage(&msg); dispatchmessage(&msg); } return (int)msg.wparam; } /****************************************************************************** initapplication ******************************************************************************/ bool initapplication(hinstance hinstance) { initcommoncontrols(); wndclassex wcex; atom areturn; wcex.cbsize = sizeof(wndclassex); wcex.style = 0; wcex.lpfnwndproc = (wndproc)mainwndproc; wcex.cbclsextra = 0; wcex.cbwndextra = 0; wcex.hinstance = hinstance; wcex.hcursor = loadcursor(null, idc_arrow); wcex.hbrbackground = (hbrush)(color_window + 1); wcex.lpszmenuname = makeintresource(idm_main_menu); wcex.lpszclassname = g_szclassname; wcex.hicon = loadicon(g_hinst, makeintresource(idi_mainicon)); wcex.hiconsm = loadimage(g_hinst, makeintresource(idi_mainicon), image_icon, 16, 16, 0); areturn = registerclassex(&wcex); if (0 == areturn) { wndclass wc; wc.style = 0; wc.lpfnwndproc = (wndproc)mainwndproc; wc.cbclsextra = 0; wc.cbwndextra = 0; wc.hinstance = hinstance; wc.hicon = loadicon(g_hinst, makeintresource(idi_mainicon)); wc.hcursor = loadcursor(null, idc_arrow); wc.hbrbackground = (hbrush)(color_window + 1); wc.lpszmenuname = makeintresource(idm_main_menu); wc.lpszclassname = g_szclassname; areturn = registerclass(&wc); } return areturn; } /****************************************************************************** initinstance ******************************************************************************/ bool initinstance(hinstance hinstance, int ncmdshow) { hwnd hwnd; tchar sztitle[max_path] = text(""); g_hinst = hinstance; loadstring(g_hinst, ids_apptitle, sztitle, sizeof(sztitle) / sizeof(sztitle[0])); /* create main window application instance. */ hwnd = createwindowex(0, g_szclassname, sztitle, ws_overlappedwindow, cw_usedefault, cw_usedefault, cw_usedefault, cw_usedefault, null, null, hinstance, null); /* if window not created, return "failure" */ if (!hwnd) return false; /* make window visible; update client area; , return "success" */ showwindow(hwnd, ncmdshow); updatewindow(hwnd); return true; } /****************************************************************************** mainwndproc ******************************************************************************/ lresult callback mainwndproc(hwnd hwnd, uint umessage, wparam wparam, lparam lparam) { static hwnd hwndlistview; switch (umessage) { case wm_create: // create treeview control hwndlistview = createlistview(g_hinst, hwnd); //initialize treeview control initlistview(hwndlistview); break; case wm_notify: return listviewnotify(hwnd, lparam); case wm_size: resizelistview(hwndlistview, hwnd); break; case wm_initmenupopup: updatemenu(hwndlistview, getmenu(hwnd)); break; case wm_contextmenu: if (docontextmenu(hwnd, wparam, lparam)) return false; break; case wm_command: switch (get_wm_command_id(wparam, lparam)) { case idm_large_icons: switchview(hwndlistview, lvs_icon); break; case idm_small_icons: switchview(hwndlistview, lvs_smallicon); break; case idm_list: switchview(hwndlistview, lvs_list); break; case idm_report: switchview(hwndlistview, lvs_report); break; case idm_exit: destroywindow(hwnd); break; case idm_about: dialogbox(g_hinst, makeintresource(idd_about), hwnd, aboutdlgproc); break; } break; case wm_destroy: postquitmessage(0); break; default: break; } return defwindowproc(hwnd, umessage, wparam, lparam); } /****************************************************************************** aboutdlgproc ******************************************************************************/ int_ptr callback aboutdlgproc(hwnd hdlg, uint umessage, wparam wparam, lparam lparam) { switch (umessage) { case wm_initdialog: return true; case wm_command: switch (wparam) { case idok: enddialog(hdlg, idok); break; case idcancel: enddialog(hdlg, idok); break; } return true; } return false; } /****************************************************************************** createlistview ******************************************************************************/ hwnd createlistview(hinstance hinstance, hwnd hwndparent) { dword dwstyle; hwnd hwndlistview; himagelist himlsmall; himagelist himllarge; bool bsuccess = true; dwstyle = ws_tabstop | ws_child | ws_visible | lvs_autoarrange | lvs_report | lvs_ownerdata; hwndlistview = createwindowex(lvs_ex_fullrowselect, // ex style wc_listview, // class name - defined in commctrl.h text(""), // dummy text dwstyle, // style 0, // x position 0, // y position 0, // width 0, // height hwndparent, // parent (hmenu)id_listview, // id g_hinst, // instance null); // no data if (!hwndlistview) return null; resizelistview(hwndlistview, hwndparent); //set image lists himlsmall = imagelist_create(16, 16, ilc_colorddb | ilc_mask, 1, 0); himllarge = imagelist_create(32, 32, ilc_colorddb | ilc_mask, 1, 0); if (himlsmall && himllarge) { hicon hicon; //set small image list hicon = loadimage(g_hinst, makeintresource(idi_disk), image_icon, 16, 16, lr_defaultcolor); imagelist_addicon(himlsmall, hicon); //set large image list hicon = loadicon(g_hinst, makeintresource(idi_disk)); imagelist_addicon(himllarge, hicon); listview_setimagelist(hwndlistview, himlsmall, lvsil_small); listview_setimagelist(hwndlistview, himllarge, lvsil_normal); } return hwndlistview; } /****************************************************************************** resizelistview ******************************************************************************/ void resizelistview(hwnd hwndlistview, hwnd hwndparent) { rect rc; getclientrect(hwndparent, &rc); movewindow(hwndlistview, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, true); //only call if want lvs_noscroll style //positionheader(hwndlistview); } /****************************************************************************** positionheader needs called when listview created, resized, view changed or wm_sysparameterchange message received ******************************************************************************/ void positionheader(hwnd hwndlistview) { hwnd hwndheader = getwindow(hwndlistview, gw_child); dword dwstyle = getwindowlong(hwndlistview, gwl_style); /*to ensure first item visible, create control without lvs_noscroll style , add here*/ dwstyle |= lvs_noscroll; setwindowlong(hwndlistview, gwl_style, dwstyle); //only if in report view , able header hwnd if (((dwstyle & lvs_typemask) == lvs_report) && hwndheader) { rect rc; hd_layout hdlayout; windowpos wpos; getclientrect(hwndlistview, &rc); hdlayout.prc = &rc; hdlayout.pwpos = &wpos; header_layout(hwndheader, &hdlayout); setwindowpos(hwndheader, wpos.hwndinsertafter, wpos.x, wpos.y, wpos.cx, wpos.cy, wpos.flags | swp_showwindow); listview_ensurevisible(hwndlistview, 0, false); } } /****************************************************************************** initlistview ******************************************************************************/ bool initlistview(hwnd hwndlistview) { lv_column lvcolumn; int i; tchar szstring[5][20] = { text("main column"), text("column 1"), text("column 2"), text("column 3"), text("column 4") }; //empty list listview_deleteallitems(hwndlistview); //initialize columns lvcolumn.mask = lvcf_fmt | lvcf_width | lvcf_text | lvcf_subitem; lvcolumn.fmt = lvcfmt_left; lvcolumn.cx = 120; (i = 0; < 5; i++) { lvcolumn.psztext = szstring[i]; listview_insertcolumn(hwndlistview, i, &lvcolumn); } insertlistviewitems(hwndlistview); return true; } /****************************************************************************** insertlistviewitems ******************************************************************************/ bool insertlistviewitems(hwnd hwndlistview) { //empty list listview_deleteallitems(hwndlistview); //set number of items in list listview_setitemcount(hwndlistview, item_count); return true; } /************************************************************************** listviewnotify() **************************************************************************/ lresult listviewnotify(hwnd hwnd, lparam lparam) { lpnmhdr lpnmh = (lpnmhdr)lparam; hwnd hwndlistview = getdlgitem(hwnd, id_listview); switch (lpnmh->code) { case lvn_getdispinfo: { lv_dispinfo *lpdi = (lv_dispinfo *)lparam; tchar szstring[max_path]; if (lpdi->item.isubitem) { if (lpdi->item.mask & lvif_text) { _sntprintf_s(szstring, _countof(szstring), _truncate, text("item %d - column %d"), lpdi->item.iitem + 1, lpdi->item.isubitem); _tcsncpy_s(lpdi->item.psztext, lpdi->item.cchtextmax, szstring, _truncate); } } else { if (lpdi->item.mask & lvif_text) { _sntprintf_s(szstring, _countof(szstring), _truncate, text("item %d"), lpdi->item.iitem + 1); _tcsncpy_s(lpdi->item.psztext, lpdi->item.cchtextmax, szstring, _truncate); } if (lpdi->item.mask & lvif_image) { lpdi->item.iimage = 0; } } } return 0; case lvn_odcachehint: { lpnmlvcachehint lpcachehint = (lpnmlvcachehint)lparam; /* sample doesn't use notification, sent when listview ask range of items. on notification, should load specified items local cache. still possible lvn_getdispinfo item has not been cached, therefore, application must take account chance of occurring. */ } return 0; case lvn_odfinditem: { lpnmlvfinditem lpfinditem = (lpnmlvfinditem)lparam; /* sample doesn't use notification, sent when listview needs particular item. return -1 if item not found. */ } return 0; } return 0; } /************************************************************************** errorhandlerex() **************************************************************************/ void errorhandlerex(word wline, lpstr lpszfile) { lpvoid lpvmessage; dword dwerror; tchar szbuffer[256]; // allow formatmessage() error code returned getlasterror dwerror = formatmessage(format_message_allocate_buffer | format_message_from_system, null, getlasterror(), makelangid(lang_english, sublang_english_us), (lptstr)&lpvmessage, 0, null); // check see if error occurred calling formatmessage() if (0 == dwerror) { _sntprintf_s(szbuffer, _countof(szbuffer), _truncate, text("an error occurred calling formatmessage().") text("error code %d"), getlasterror()); messagebox(null, szbuffer, text("generic"), mb_iconstop | mb_iconexclamation); return; } // display error information along place error happened. _sntprintf_s(szbuffer, _countof(szbuffer), _truncate, text("generic, line=%d, file=%s"), wline, lpszfile); messagebox(null, lpvmessage, szbuffer, mb_iconexclamation | mb_ok); } /************************************************************************** switchview() **************************************************************************/ void switchview(hwnd hwndlistview, dword dwview) { dword dwstyle = getwindowlong(hwndlistview, gwl_style); setwindowlong(hwndlistview, gwl_style, (dwstyle & ~lvs_typemask) | dwview); resizelistview(hwndlistview, getparent(hwndlistview)); } /************************************************************************** docontextmenu() **************************************************************************/ bool docontextmenu(hwnd hwnd, wparam wparam, lparam lparam) { hwnd hwndlistview = (hwnd)wparam; hmenu hmenuload, hmenu; if (hwndlistview != getdlgitem(hwnd, id_listview)) return false; hmenuload = loadmenu(g_hinst, makeintresource(idm_context_menu)); hmenu = getsubmenu(hmenuload, 0); updatemenu(hwndlistview, hmenu); trackpopupmenu(hmenu, tpm_leftalign | tpm_rightbutton, loword(lparam), hiword(lparam), 0, hwnd, null); destroymenu(hmenuload); return true; } /************************************************************************** updatemenu() **************************************************************************/ void updatemenu(hwnd hwndlistview, hmenu hmenu) { uint uid = idm_list; dword dwstyle; //uncheck of these guys checkmenuitem(hmenu, idm_large_icons, mf_bycommand | mf_unchecked); checkmenuitem(hmenu, idm_small_icons, mf_bycommand | mf_unchecked); checkmenuitem(hmenu, idm_list, mf_bycommand | mf_unchecked); checkmenuitem(hmenu, idm_report, mf_bycommand | mf_unchecked); //check appropriate view menu item dwstyle = getwindowlong(hwndlistview, gwl_style); switch (dwstyle & lvs_typemask) { case lvs_icon: uid = idm_large_icons; break; case lvs_smallicon: uid = idm_small_icons; break; case lvs_list: uid = idm_list; break; case lvs_report: uid = idm_report; break; } checkmenuradioitem(hmenu, idm_large_icons, idm_report, uid, mf_bycommand | mf_checked); }
the lvs_ex_xxx
styles extended listview styles, aren't regular window styles. can't specify them in createwindowex
call, have set them after window creation using lvm_setextendedlistviewstyle
message. example,
sendmessage(hwndlistview, lvm_setextendedlistviewstyle, lvs_ex_fullrowselect, lvs_ex_fullrowselect);
Comments
Post a Comment