Added cleanup of Windows image lists.
This commit is contained in:
parent
107e66715b
commit
e25831c609
|
@ -11,6 +11,7 @@ BOOL (*WINAPI fv_RemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
|
|||
LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
|
||||
HIMAGELIST (*WINAPI fv_ImageList_Create)(int, int, UINT, int, int);
|
||||
int (*WINAPI fv_ImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
||||
BOOL (*WINAPI fv_ImageList_Destroy)(HIMAGELIST);
|
||||
|
||||
#define wantedICCClasses ( \
|
||||
ICC_PROGRESS_CLASS | /* progress bars */ \
|
||||
|
@ -121,7 +122,8 @@ DWORD initCommonControls(char **errmsg)
|
|||
fv_ImageList_Create = (HIMAGELIST (*WINAPI)(int, int, UINT, int, int)) f;
|
||||
LOAD("ImageList_Add");
|
||||
fv_ImageList_Add = (int (*WINAPI)(HIMAGELIST, HBITMAP, HBITMAP)) f;
|
||||
|
||||
LOAD("ImageList_Destroy");
|
||||
fv_ImageList_Destroy = (BOOL (*WINAPI)(HIMAGELIST)) f;
|
||||
|
||||
if ((*ficc)(&icc) == FALSE) {
|
||||
*errmsg = "error initializing Common Controls (comctl32.dll)";
|
||||
|
|
|
@ -94,11 +94,13 @@ noscale:
|
|||
xpanic("error deleting scaled bitmap", GetLastError());
|
||||
}
|
||||
|
||||
void applyImageList(HWND hwnd, UINT uMsg, WPARAM wParam, HIMAGELIST il)
|
||||
void applyImageList(HWND hwnd, UINT uMsg, WPARAM wParam, HIMAGELIST il, HIMAGELIST old)
|
||||
{
|
||||
if (SendMessageW(hwnd, uMsg, wParam, (LPARAM) il) == (LRESULT) NULL)
|
||||
;//TODO xpanic("error setting image list", GetLastError());
|
||||
// TODO free old one here if any
|
||||
if (SendMessageW(hwnd, uMsg, wParam, (LPARAM) il) != (LRESULT) old)
|
||||
xpanic("error setting image list", GetLastError());
|
||||
if (old != NULL && (*fv_ImageList_Destroy)(old) == 0)
|
||||
xpanic("error freeing old checkbox image list", GetLastError());
|
||||
|
||||
}
|
||||
|
||||
static UINT dfcState(int cbstate)
|
||||
|
|
|
@ -31,15 +31,15 @@ func (i *imagelist) Len() ImageIndex {
|
|||
}
|
||||
|
||||
type imageListApply interface {
|
||||
apply(C.HWND, C.UINT, C.WPARAM)
|
||||
apply(C.HWND, C.UINT)
|
||||
}
|
||||
|
||||
func (i *imagelist) apply(hwnd C.HWND, uMsg C.UINT, wParam C.WPARAM) {
|
||||
func (i *imagelist) apply(hwnd C.HWND, uMsg C.UINT) {
|
||||
width := C.GetSystemMetrics(C.SM_CXSMICON)
|
||||
height := C.GetSystemMetrics(C.SM_CYSMICON)
|
||||
il := C.newImageList(width, height)
|
||||
for index := range i.list {
|
||||
C.addImage(il, hwnd, i.list[index], C.int(i.width[index]), C.int(i.height[index]), width, height)
|
||||
}
|
||||
C.applyImageList(hwnd, uMsg, wParam, il)
|
||||
C.SendMessageW(hwnd, uMsg, 0, C.LPARAM(uintptr(unsafe.Pointer(il))))
|
||||
}
|
||||
|
|
|
@ -27,19 +27,27 @@ static void handle(HWND hwnd, WPARAM wParam, LPARAM lParam, void (*handler)(void
|
|||
|
||||
struct tableData {
|
||||
void *gotable;
|
||||
HIMAGELIST imagelist;
|
||||
HTHEME theme;
|
||||
HIMAGELIST checkboxImageList;
|
||||
};
|
||||
|
||||
static void tableLoadImageList(HWND hwnd, struct tableData *t, HIMAGELIST new)
|
||||
{
|
||||
HIMAGELIST old;
|
||||
|
||||
old = t->imagelist;
|
||||
t->imagelist = new;
|
||||
applyImageList(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, t->imagelist, old);
|
||||
}
|
||||
|
||||
static void tableSetCheckboxImageList(HWND hwnd, struct tableData *t)
|
||||
{
|
||||
HIMAGELIST old;
|
||||
|
||||
old = t->checkboxImageList;
|
||||
t->checkboxImageList = makeCheckboxImageList(hwnd, &t->theme);
|
||||
if (SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM) (t->checkboxImageList)) == (LRESULT) NULL)
|
||||
;//TODO xpanic("error setting image list", GetLastError());
|
||||
// TODO free old one here if any
|
||||
applyImageList(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, t->checkboxImageList, old);
|
||||
// thanks to Jonathan Potter (http://stackoverflow.com/questions/25354448/why-do-my-owner-data-list-view-state-images-come-up-as-blank-on-windows-xp)
|
||||
if (SendMessageW(hwnd, LVM_SETCALLBACKMASK, LVIS_STATEIMAGEMASK, 0) == FALSE)
|
||||
xpanic("error marking state image list as application-managed", GetLastError());
|
||||
|
@ -86,7 +94,10 @@ static LRESULT CALLBACK tableSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
|
|||
tablePushed(t->gotable, -1, -1); // in case button held as drag out
|
||||
// and let the list view do its thing
|
||||
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
|
||||
case msgTableMakeInitialImageList:
|
||||
case msgLoadImageList:
|
||||
tableLoadImageList(hwnd, t, (HIMAGELIST) lParam);
|
||||
return 0;
|
||||
case msgTableMakeInitialCheckboxImageList:
|
||||
tableSetCheckboxImageList(hwnd, t);
|
||||
return 0;
|
||||
case WM_THEMECHANGED:
|
||||
|
|
|
@ -40,7 +40,7 @@ func finishNewTable(b *tablebase, ty reflect.Type) Table {
|
|||
// LVS_EX_SUBITEMIMAGES gives us images in subitems, which will be important when both images and checkboxes are added
|
||||
C.tableAddExtendedStyles(t._hwnd, C.LVS_EX_FULLROWSELECT | C.LVS_EX_SUBITEMIMAGES)
|
||||
// this must come after the subclass because it uses one of our private messages
|
||||
C.SendMessageW(t._hwnd, C.msgTableMakeInitialImageList, 0, 0)
|
||||
C.SendMessageW(t._hwnd, C.msgTableMakeInitialCheckboxImageList, 0, 0)
|
||||
for i := 0; i < ty.NumField(); i++ {
|
||||
C.tableAppendColumn(t._hwnd, C.int(i), toUTF16(ty.Field(i).Name))
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func (t *table) Unlock() {
|
|||
}
|
||||
|
||||
func (t *table) LoadImageList(il ImageList) {
|
||||
il.apply(t._hwnd, C.LVM_SETIMAGELIST, C.LVSIL_SMALL)
|
||||
il.apply(t._hwnd, C.msgLoadImageList)
|
||||
}
|
||||
|
||||
func (t *table) Selected() int {
|
||||
|
|
|
@ -38,7 +38,8 @@ enum {
|
|||
msgEndModal,
|
||||
msgAreaKeyDown,
|
||||
msgAreaKeyUp,
|
||||
msgTableMakeInitialImageList,
|
||||
msgLoadImageList,
|
||||
msgTableMakeInitialCheckboxImageList,
|
||||
};
|
||||
|
||||
// uitask_windows.c
|
||||
|
@ -55,6 +56,7 @@ extern BOOL (*WINAPI fv_RemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
|
|||
extern LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
|
||||
extern HIMAGELIST (*WINAPI fv_ImageList_Create)(int, int, UINT, int, int);
|
||||
extern int (*WINAPI fv_ImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
||||
extern BOOL (*WINAPI fv_ImageList_Destroy)(HIMAGELIST);
|
||||
|
||||
// control_windows.c
|
||||
extern HWND newControl(LPWSTR, DWORD, DWORD);
|
||||
|
@ -137,7 +139,7 @@ extern void areaMarkTextFieldDone(HWND);
|
|||
extern HBITMAP unscaledBitmap(void *, intptr_t, intptr_t);
|
||||
extern HIMAGELIST newImageList(int, int);
|
||||
extern void addImage(HIMAGELIST, HWND, HBITMAP, int, int, int, int);
|
||||
extern void applyImageList(HWND, UINT, WPARAM, HIMAGELIST);
|
||||
extern void applyImageList(HWND, UINT, WPARAM, HIMAGELIST, HIMAGELIST);
|
||||
enum {
|
||||
checkboxStateChecked = 1 << 0,
|
||||
checkboxStateHot = 1 << 1,
|
||||
|
|
Loading…
Reference in New Issue