c - Why do my owner data list view state images come up as blank on Windows XP? -
simple problem time, 1 i'm not seeing on searches: have list view control state images should show in 1 column. in wine, windows vista, windows 7, , windows 8.1, things correct. in windows xp, state images don't show up, showing white space image should be. common controls version 6 required. doing wrong?
here sample program demonstrates this.
// 17 august 2014 // scratch windows program pietro gagliardi 17 april 2014 // fixed typos , added towidestring() 1 may 2014 // borrows code scratch gtk+ program (16-17 april 2014) , code written 31 march 2014 , 11-12 april 2014 #define _unicode #define unicode #define strict #define _gnu_source // needed declare asprintf()/vasprintf() #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <windows.h> #include <commctrl.h> // needed initcommoncontrolsex() (thanks xeek in irc.freenode.net/#winapi confirming) #ifdef _msc_ver #error sorry! scratch windows program relies on mingw-only functionality! (specifically: asprintf()) #endif hmodule hinstance; hicon hdefaulticon; hcursor hdefaultcursor; hfont controlfont; void panic(char *fmt, ...); tchar *towidestring(char *what); void init(void); lresult callback wndproc(hwnd hwnd, uint msg, wparam wparam, lparam lparam) { nmhdr *nmhdr = (nmhdr *) lparam; nmlvdispinfow *fill = (nmlvdispinfo *) lparam; switch (msg) { case wm_notify: if (nmhdr->code == lvn_getdispinfo) { if (fill->item.isubitem == 0) { fill->item.state = indextostateimagemask(fill->item.iitem + 1); fill->item.statemask = lvis_stateimagemask; } else fill->item.psztext = l"no state image here"; return 0; } return defwindowproc(hwnd, msg, wparam, lparam); case wm_close: postquitmessage(0); return 0; default: return defwindowproc(hwnd, msg, wparam, lparam); } panic("oops: message %ud not return anything; bug in wndproc()", msg); } hwnd makemainwindow(void) { wndclass cls; hwnd hwnd; zeromemory(&cls, sizeof (wndclass)); cls.lpszclassname = l"mainwin"; cls.lpfnwndproc = wndproc; cls.hinstance = hinstance; cls.hicon = hdefaulticon; cls.hcursor = hdefaultcursor; cls.hbrbackground = (hbrush) (color_btnface + 1); if (registerclass(&cls) == 0) panic("error registering window class"); hwnd = createwindowex(0, l"mainwin", l"main window", ws_overlappedwindow, cw_usedefault, cw_usedefault, 300, 300, null, null, hinstance, null); if (hwnd == null) panic("opening main window failed"); return hwnd; } void buildui(hwnd mainwin) { #define cstyle (ws_child | ws_visible) #define cxstyle (0) #define setfont(hwnd) sendmessage(hwnd, wm_setfont, (wparam) controlfont, (lparam) true); hwnd lv; lvcolumn column; himagelist imglist; lv = createwindowex(ws_ex_clientedge | cxstyle, wc_listview, l"", lvs_report | lvs_ownerdata | lvs_nosortheader | lvs_showselalways | ws_hscroll | ws_vscroll | ws_tabstop | cstyle, 10, 10, 250, 250, mainwin, (hmenu) 100, hinstance, null); if (lv == null) panic("error making list view"); setfont(lv); sendmessagew(lv, lvm_setextendedlistviewstyle, lvs_ex_fullrowselect | lvs_ex_subitemimages, lvs_ex_fullrowselect | lvs_ex_subitemimages); // error checking elided point otherwise noted imglist = imagelist_create( getsystemmetrics(sm_cxsmicon), getsystemmetrics(sm_cysmicon), ilc_color32, 20, 20); imagelist_addicon(imglist, loadiconw(null, idi_error)); imagelist_addicon(imglist, loadiconw(null, idi_question)); imagelist_addicon(imglist, loadiconw(null, idi_warning)); sendmessagew(lv, lvm_setimagelist, lvsil_state, (lparam) imglist); zeromemory(&column, sizeof (lvcolumn)); column.mask = lvcf_fmt | lvcf_text | lvcf_subitem | lvcf_order; column.fmt = lvcfmt_left; column.psztext = l"state image"; column.isubitem = 0; column.iorder = 0; sendmessagew(lv, lvm_insertcolumn, 0, (lparam) (&column)); zeromemory(&column, sizeof (lvcolumn)); column.mask = lvcf_fmt | lvcf_text | lvcf_subitem | lvcf_order; column.fmt = lvcfmt_left; column.psztext = l"no state image"; column.isubitem = 1; column.iorder = 1; sendmessagew(lv, lvm_insertcolumn, 1, (lparam) (&column)); // end of error eliding if (sendmessagew(lv, lvm_setitemcount, 3, 0) == 0) panic("error setting number of items in list view"); } void firstshowwindow(hwnd hwnd); int main(void) { hwnd mainwin; msg msg; init(); mainwin = makemainwindow(); buildui(mainwin); firstshowwindow(mainwin); (;;) { bool gmret; gmret = getmessage(&msg, null, 0, 0); if (gmret == -1) panic("error getting message"); if (gmret == 0) break; translatemessage(&msg); dispatchmessage(&msg); } return 0; } dword iccflags = // icc_animate_class | // animation control // icc_bar_classes | // toolbar, statusbar, trackbar, tooltip // icc_cool_classes | // rebar // icc_date_classes | // date , time picker // icc_hotkey_class | // hot key // icc_internet_classes | // ip address entry field // icc_link_class | // hyperlink icc_listview_classes | // list-view, header // icc_nativefntctl_class | // native font // icc_pagescroller_class | // pager // icc_progress_class | // progress bar // icc_standard_classes | // "one of intrinsic user32 control classes" // icc_tab_classes | // tab, tooltip // icc_treeview_classes | // tree-view, tooltip // icc_updown_class | // up-down // icc_userex_classes | // comboboxex // icc_win95_classes | // of above 0; void init(void) { initcommoncontrolsex icc; nonclientmetrics ncm; hinstance = getmodulehandle(null); if (hinstance == null) panic("error getting hinstance"); hdefaulticon = loadicon(null, makeintresource(idi_application)); if (hdefaulticon == null) panic("error getting default window class icon"); hdefaultcursor = loadcursor(null, makeintresource(idc_arrow)); if (hdefaultcursor == null) panic("error getting default window cursor"); icc.dwsize = sizeof (initcommoncontrolsex); icc.dwicc = iccflags; if (initcommoncontrolsex(&icc) == false) panic("error initializing common controls"); ncm.cbsize = sizeof (nonclientmetrics); if (systemparametersinfo(spi_getnonclientmetrics, sizeof (nonclientmetrics), &ncm, 0) == 0) panic("error getting non-client metrics getting control font"); controlfont = createfontindirect(&ncm.lfmessagefont); if (controlfont == null) panic("error getting control font"); } void panic(char *fmt, ...) { char *msg; tchar *lerrmsg; char *fullmsg; va_list arg; dword lasterr; dword lerrsuccess; lasterr = getlasterror(); va_start(arg, fmt); if (vasprintf(&msg, fmt, arg) == -1) { fprintf(stderr, "critical error: vasprintf() failed in panic() preparing panic message; fmt = \"%s\"\n", fmt); abort(); } // according http://msdn.microsoft.com/en-us/library/windows/desktop/ms680582%28v=vs.85%29.aspx lerrsuccess = formatmessage(format_message_allocate_buffer | format_message_from_system | format_message_ignore_inserts, null, lasterr, makelangid(lang_neutral, sublang_default), (lptstr) &lerrmsg, 0, null); if (lerrsuccess == 0) { fprintf(stderr, "critical error: formatmessage() failed in panic() preparing getlasterror() string; panic message = \"%s\", last error in panic(): %ld, last error formatmessage(): %ld\n", msg, lasterr, getlasterror()); abort(); } // note self: use %ws instead of %s (thanks jon_y in irc.oftc.net/#mingw-w64) if (asprintf(&fullmsg, "panic: %s\nlast error: %ws\n", msg, lerrmsg) == -1) { fprintf(stderr, "critical error: asprintf() failed in panic() preparing full report; panic message = \"%s\", last error message: \"%ws\"\n", msg, lerrmsg); abort(); } fprintf(stderr, "%s\n", fullmsg); va_end(arg); exit(1); } void firstshowwindow(hwnd hwnd) { // need ncmdshow int ncmdshow; startupinfo si; ncmdshow = sw_showdefault; getstartupinfo(&si); if ((si.dwflags & startf_useshowwindow) != 0) ncmdshow = si.wshowwindow; showwindow(hwnd, ncmdshow); if (updatewindow(hwnd) == 0) panic("updatewindow(hwnd) failed in first show"); } tchar *towidestring(char *what) { tchar *buf; int n; size_t len; len = strlen(what); if (len == 0) { buf = (tchar *) malloc(sizeof (tchar)); if (buf == null) goto mallocfail; buf[0] = l'\0'; } else { n = multibytetowidechar(cp_utf8, 0, what, -1, null, 0); if (n == 0) panic("error getting number of bytes convert \"%s\" utf-16", what); buf = (tchar *) malloc((n + 1) * sizeof (tchar)); if (buf == null) goto mallocfail; if (multibytetowidechar(cp_utf8, 0, what, -1, buf, n) == 0) panic("erorr converting \"%s\" utf-16", what); } return buf; mallocfail: panic("error allocating memory utf-16 version of \"%s\"", what); }
the listview control uses lvm_setcallbackmask
make request item state data via lvn_getdispinfo
.
i can guess on windows 7 , upwards requirement removed owner data controls - docs don't - in xp/vista need send message have request item state.
Comments
Post a Comment