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);
|
LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
|
||||||
HIMAGELIST (*WINAPI fv_ImageList_Create)(int, int, UINT, int, int);
|
HIMAGELIST (*WINAPI fv_ImageList_Create)(int, int, UINT, int, int);
|
||||||
int (*WINAPI fv_ImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
int (*WINAPI fv_ImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
||||||
|
BOOL (*WINAPI fv_ImageList_Destroy)(HIMAGELIST);
|
||||||
|
|
||||||
#define wantedICCClasses ( \
|
#define wantedICCClasses ( \
|
||||||
ICC_PROGRESS_CLASS | /* progress bars */ \
|
ICC_PROGRESS_CLASS | /* progress bars */ \
|
||||||
|
@ -121,7 +122,8 @@ DWORD initCommonControls(char **errmsg)
|
||||||
fv_ImageList_Create = (HIMAGELIST (*WINAPI)(int, int, UINT, int, int)) f;
|
fv_ImageList_Create = (HIMAGELIST (*WINAPI)(int, int, UINT, int, int)) f;
|
||||||
LOAD("ImageList_Add");
|
LOAD("ImageList_Add");
|
||||||
fv_ImageList_Add = (int (*WINAPI)(HIMAGELIST, HBITMAP, HBITMAP)) f;
|
fv_ImageList_Add = (int (*WINAPI)(HIMAGELIST, HBITMAP, HBITMAP)) f;
|
||||||
|
LOAD("ImageList_Destroy");
|
||||||
|
fv_ImageList_Destroy = (BOOL (*WINAPI)(HIMAGELIST)) f;
|
||||||
|
|
||||||
if ((*ficc)(&icc) == FALSE) {
|
if ((*ficc)(&icc) == FALSE) {
|
||||||
*errmsg = "error initializing Common Controls (comctl32.dll)";
|
*errmsg = "error initializing Common Controls (comctl32.dll)";
|
||||||
|
|
|
@ -94,11 +94,13 @@ noscale:
|
||||||
xpanic("error deleting scaled bitmap", GetLastError());
|
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)
|
if (SendMessageW(hwnd, uMsg, wParam, (LPARAM) il) != (LRESULT) old)
|
||||||
;//TODO xpanic("error setting image list", GetLastError());
|
xpanic("error setting image list", GetLastError());
|
||||||
// TODO free old one here if any
|
if (old != NULL && (*fv_ImageList_Destroy)(old) == 0)
|
||||||
|
xpanic("error freeing old checkbox image list", GetLastError());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT dfcState(int cbstate)
|
static UINT dfcState(int cbstate)
|
||||||
|
|
|
@ -31,15 +31,15 @@ func (i *imagelist) Len() ImageIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
type imageListApply interface {
|
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)
|
width := C.GetSystemMetrics(C.SM_CXSMICON)
|
||||||
height := C.GetSystemMetrics(C.SM_CYSMICON)
|
height := C.GetSystemMetrics(C.SM_CYSMICON)
|
||||||
il := C.newImageList(width, height)
|
il := C.newImageList(width, height)
|
||||||
for index := range i.list {
|
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.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 {
|
struct tableData {
|
||||||
void *gotable;
|
void *gotable;
|
||||||
|
HIMAGELIST imagelist;
|
||||||
HTHEME theme;
|
HTHEME theme;
|
||||||
HIMAGELIST checkboxImageList;
|
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)
|
static void tableSetCheckboxImageList(HWND hwnd, struct tableData *t)
|
||||||
{
|
{
|
||||||
HIMAGELIST old;
|
HIMAGELIST old;
|
||||||
|
|
||||||
old = t->checkboxImageList;
|
old = t->checkboxImageList;
|
||||||
t->checkboxImageList = makeCheckboxImageList(hwnd, &t->theme);
|
t->checkboxImageList = makeCheckboxImageList(hwnd, &t->theme);
|
||||||
if (SendMessageW(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM) (t->checkboxImageList)) == (LRESULT) NULL)
|
applyImageList(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, t->checkboxImageList, old);
|
||||||
;//TODO xpanic("error setting image list", GetLastError());
|
|
||||||
// TODO free old one here if any
|
|
||||||
// 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)
|
// 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)
|
if (SendMessageW(hwnd, LVM_SETCALLBACKMASK, LVIS_STATEIMAGEMASK, 0) == FALSE)
|
||||||
xpanic("error marking state image list as application-managed", GetLastError());
|
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
|
tablePushed(t->gotable, -1, -1); // in case button held as drag out
|
||||||
// and let the list view do its thing
|
// and let the list view do its thing
|
||||||
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
|
return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam);
|
||||||
case msgTableMakeInitialImageList:
|
case msgLoadImageList:
|
||||||
|
tableLoadImageList(hwnd, t, (HIMAGELIST) lParam);
|
||||||
|
return 0;
|
||||||
|
case msgTableMakeInitialCheckboxImageList:
|
||||||
tableSetCheckboxImageList(hwnd, t);
|
tableSetCheckboxImageList(hwnd, t);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_THEMECHANGED:
|
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
|
// 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)
|
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
|
// 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++ {
|
for i := 0; i < ty.NumField(); i++ {
|
||||||
C.tableAppendColumn(t._hwnd, C.int(i), toUTF16(ty.Field(i).Name))
|
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) {
|
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 {
|
func (t *table) Selected() int {
|
||||||
|
|
|
@ -38,7 +38,8 @@ enum {
|
||||||
msgEndModal,
|
msgEndModal,
|
||||||
msgAreaKeyDown,
|
msgAreaKeyDown,
|
||||||
msgAreaKeyUp,
|
msgAreaKeyUp,
|
||||||
msgTableMakeInitialImageList,
|
msgLoadImageList,
|
||||||
|
msgTableMakeInitialCheckboxImageList,
|
||||||
};
|
};
|
||||||
|
|
||||||
// uitask_windows.c
|
// 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 LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
|
||||||
extern HIMAGELIST (*WINAPI fv_ImageList_Create)(int, int, UINT, int, int);
|
extern HIMAGELIST (*WINAPI fv_ImageList_Create)(int, int, UINT, int, int);
|
||||||
extern int (*WINAPI fv_ImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
extern int (*WINAPI fv_ImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
||||||
|
extern BOOL (*WINAPI fv_ImageList_Destroy)(HIMAGELIST);
|
||||||
|
|
||||||
// control_windows.c
|
// control_windows.c
|
||||||
extern HWND newControl(LPWSTR, DWORD, DWORD);
|
extern HWND newControl(LPWSTR, DWORD, DWORD);
|
||||||
|
@ -137,7 +139,7 @@ extern void areaMarkTextFieldDone(HWND);
|
||||||
extern HBITMAP unscaledBitmap(void *, intptr_t, intptr_t);
|
extern HBITMAP unscaledBitmap(void *, intptr_t, intptr_t);
|
||||||
extern HIMAGELIST newImageList(int, int);
|
extern HIMAGELIST newImageList(int, int);
|
||||||
extern void addImage(HIMAGELIST, HWND, HBITMAP, int, int, 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 {
|
enum {
|
||||||
checkboxStateChecked = 1 << 0,
|
checkboxStateChecked = 1 << 0,
|
||||||
checkboxStateHot = 1 << 1,
|
checkboxStateHot = 1 << 1,
|
||||||
|
|
Loading…
Reference in New Issue