Tcl-Tk-Tkwidget-treectrl
view release on metacpan or search on metacpan
shellicon/shellicon.c view on Meta::CPAN
sticky &= ~(STICKY_W | STICKY_E);
}
if ((sticky & STICKY_N) && (sticky & STICKY_S)) {
if (expandY)
*heightPtr += dy;
else
sticky &= ~(STICKY_N | STICKY_S);
}
if (!(sticky & STICKY_W)) {
*xPtr += (sticky & STICKY_E) ? dx : dx / 2;
}
if (!(sticky & STICKY_N)) {
*yPtr += (sticky & STICKY_S) ? dy : dy / 2;
}
}
/* This macro gets the value of a per-state option for an element, then
* looks for a better match from the master element if it exists */
#define OPTION_FOR_STATE(xFUNC,xTYPE,xVAR,xFIELD,xSTATE) \
xVAR = xFUNC(tree, &elemX->xFIELD, xSTATE, &match); \
if ((match != MATCH_EXACT) && (masterX != NULL)) { \
xTYPE varM = xFUNC(tree, &masterX->xFIELD, xSTATE, &match2); \
if (match2 > match) \
xVAR = varM; \
}
#define BOOLEAN_FOR_STATE(xVAR,xFIELD,xSTATE) \
OPTION_FOR_STATE(PerStateBoolean_ForState,int,xVAR,xFIELD,xSTATE)
/* This macro gets the object for a per-state option for an element, then
* looks for a better match from the master element if it exists */
#define OBJECT_FOR_STATE(xVAR,xTYPE,xFIELD,xSTATE) \
xVAR = PerStateInfo_ObjForState(tree, &xTYPE, &elemX->xFIELD, xSTATE, &match); \
if ((match != MATCH_EXACT) && (masterX != NULL)) { \
Tcl_Obj *objM = PerStateInfo_ObjForState(tree, &xTYPE, &masterX->xFIELD, xSTATE, &matchM); \
if (matchM > match) \
xVAR = objM; \
}
typedef struct ElementShellIcon ElementShellIcon;
struct ElementShellIcon
{
TreeElement_ header;
#ifdef DEPRECATED
PerStateInfo draw;
#endif
Tcl_Obj *pathObj; /* path of file or directory */
char *path;
Tcl_Obj *widthObj;
int width;
Tcl_Obj *heightObj;
int height;
#define TYPE_DIRECTORY 0
#define TYPE_FILE 1
int type; /* If specified, 'path' is assumed to exist */
#define SIZE_LARGE 0
#define SIZE_SMALL 1
int size; /* SIZE_LARGE if unspecified */
HIMAGELIST hImgList; /* the system image list */
int iIcon; /* index into hImgList */
/* FIXME: overlays no longer work in Win7 */
int addOverlays; /* only when useImgList is FALSE */
int useImgList; /* if false, create icons */
#define USE_SEL_ALWAYS 0 /* always draw selected icon */
#define USE_SEL_AUTO 1 /* draw selected icon when item is selected */
#define USE_SEL_NEVER 2 /* never draw the selected icon */
int useSelected; /* when to draw the selected icon */
HICON hIcon; /* icon */
HICON hIconSel; /* selected icon */
};
#define SHELLICON_CONF_ICON 0x0001
#define SHELLICON_CONF_SIZE 0x0002
#define SHELLICON_CONF_DRAW 0x0004
static CONST char *sizeST[] = {
"large", "small", (char *) NULL
};
static CONST char *typeST[] = {
"directory", "file", (char *) NULL
};
static CONST char *useSelectedST[] = {
"always", "auto", "never", (char *) NULL
};
static Tk_OptionSpec shellIconOptionSpecs[] = {
{TK_OPTION_CUSTOM, "-addoverlays", (char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(ElementShellIcon, addOverlays),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_ICON},
#ifdef DEPRECATED
{TK_OPTION_CUSTOM, "-draw", (char *) NULL, (char *) NULL,
(char *) NULL, Tk_Offset(ElementShellIcon, draw.obj),
Tk_Offset(ElementShellIcon, draw),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_DRAW},
#endif
{TK_OPTION_PIXELS, "-height", (char *) NULL, (char *) NULL,
(char *) NULL, Tk_Offset(ElementShellIcon, heightObj),
Tk_Offset(ElementShellIcon, height),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_SIZE},
{TK_OPTION_STRING, "-path", (char *) NULL, (char *) NULL,
(char *) NULL, Tk_Offset(ElementShellIcon, pathObj),
Tk_Offset(ElementShellIcon, path),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_ICON},
{TK_OPTION_CUSTOM, "-size",(char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(ElementShellIcon, size),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_ICON},
{TK_OPTION_CUSTOM, "-type", (char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(ElementShellIcon, type),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_ICON},
{TK_OPTION_CUSTOM, "-useimagelist", (char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(ElementShellIcon, useImgList),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_ICON},
{TK_OPTION_CUSTOM, "-useselected", (char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(ElementShellIcon, useSelected),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_DRAW},
{TK_OPTION_PIXELS, "-width", (char *) NULL, (char *) NULL,
(char *) NULL, Tk_Offset(ElementShellIcon, widthObj),
Tk_Offset(ElementShellIcon, width),
TK_OPTION_NULL_OK, (ClientData) NULL, SHELLICON_CONF_SIZE},
{TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, -1, 0, (ClientData) NULL, 0}
};
static void LoadIconIfNeeded(TreeElementArgs *args)
{
TreeCtrl *tree = args->tree;
TreeElement elem = args->elem;
ElementShellIcon *elemX = (ElementShellIcon *) elem;
ElementShellIcon *masterX = (ElementShellIcon *) elem->master;
SHFILEINFO sfi;
Tcl_DString dString1, dString2;
UINT uFlags = SHGFI_SYSICONINDEX;
DWORD dwFileAttributes = 0;
char *nativePath;
int size = SIZE_LARGE;
int overlays = 1;
int type = -1;
int useImgList = TRUE;
DWORD_PTR result;
/* -useimagelist boolean */
if (elemX->useImgList != -1)
useImgList = elemX->useImgList;
else if (masterX != NULL && masterX->useImgList != -1)
useImgList = masterX->useImgList;
/* Not using the system image list. */
if (!useImgList) {
/* Already have an icon, or no path is given so no icon used */
if ((elemX->hIcon != NULL) || (elemX->path == NULL))
return;
/* Equivalent to "file nativename $path" */
nativePath = Tcl_TranslateFileName(tree->interp, elemX->path, &dString1);
if (nativePath == NULL)
return;
/* This will be passed to system calls, so convert from UTF8 */
nativePath = Tcl_UtfToExternalDString(NULL, nativePath, -1, &dString2);
uFlags = SHGFI_ICON;
/* -addoverlays boolean */
if (elemX->addOverlays != -1)
overlays = elemX->addOverlays;
else if (masterX != NULL && masterX->addOverlays != -1)
overlays = masterX->addOverlays;
if (overlays)
uFlags |= SHGFI_ADDOVERLAYS;
/* -size small or large */
if (elemX->size != -1)
size = elemX->size;
else if (masterX != NULL && masterX->size != -1)
size = masterX->size;
switch (size) {
case SIZE_LARGE: uFlags |= SHGFI_LARGEICON | SHGFI_SHELLICONSIZE; break;
case SIZE_SMALL: uFlags |= SHGFI_SMALLICON | SHGFI_SHELLICONSIZE; break;
}
/* -type file or -type directory */
if (elemX->type != -1)
type = elemX->type;
else if (masterX != NULL && masterX->type != -1)
type = masterX->type;
/* If SHGFI_USEFILEATTRIBUTES is set, SHGetFileInfo is supposed to
* assume that the file is real but not look for it on disk. This
* can be used to get the icon for a certain type of file, ex *.exe.
* In practice, lots of files get a non-generic icon when a
* valid file path is given. */
if (type != -1) {
dwFileAttributes = (type == TYPE_FILE) ?
FILE_ATTRIBUTE_NORMAL : FILE_ATTRIBUTE_DIRECTORY;
uFlags |= SHGFI_USEFILEATTRIBUTES;
}
/* MSDN says SHGFI_OPENICON returns the image list containing the
* small open icon. In practice the large open icon gets returned
* for SHGFI_LARGEICON, so we support it. */
if (/*(size == SIZE_SMALL) && */(args->state & STATE_ITEM_OPEN))
uFlags |= SHGFI_OPENICON;
CoInitialize(NULL);
result = SHGetFileInfo(
nativePath,
dwFileAttributes,
&sfi,
sizeof(sfi),
uFlags);
if (result) {
elemX->hIcon = sfi.hIcon;
/* Remember the image list so we can get the icon size */
elemX->hImgList = (size == SIZE_LARGE) ? gImgListLarge : gImgListSmall;
}
result = SHGetFileInfo(
nativePath,
dwFileAttributes,
&sfi,
sizeof(sfi),
uFlags | SHGFI_SELECTED);
if (result)
elemX->hIconSel = sfi.hIcon;
CoUninitialize();
shellicon/shellicon.c view on Meta::CPAN
#endif
/* InitCommonControlsEx must be called to use the ImageList functions */
/* This is already done by Tk on NT */
if (TkWinGetPlatformId() != VER_PLATFORM_WIN32_NT) {
INITCOMMONCONTROLSEX comctl;
ZeroMemory(&comctl, sizeof(comctl));
(void) InitCommonControlsEx(&comctl);
}
#if 1
/* Get the sytem image lists (small and large) */
CoInitialize(NULL);
gImgListSmall = (HIMAGELIST) SHGetFileInfo(".exe", FILE_ATTRIBUTE_NORMAL, &sfi,
sizeof(sfi), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
gImgListLarge = (HIMAGELIST) SHGetFileInfo(".exe", FILE_ATTRIBUTE_NORMAL, &sfi,
sizeof(sfi), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
CoUninitialize();
#else
/* FIXME: WinXP only */
/* This is broken somewhere */
hLib = LoadLibraryA("shell32");
SHGetImageListProc = (FARPROC) GetProcAddress(hLib, (LPCSTR) 727);
SHGetImageListProc(SHIL_SMALL, &IID_IImageList, &gImgListSmall);
SHGetImageListProc(SHIL_LARGE, &IID_IImageList, &gImgListLarge);
SHGetImageListProc(SHIL_EXTRALARGE, &IID_IImageList, &gImgListXtraLarge);
dbwin("small %p large %p xtralarge %p\n", gImgListSmall, gImgListLarge, gImgListXtraLarge);
FreeLibrary(hLib);
#endif
#if 0
{
typedef BOOL (WINAPI *FileIconInitProc)(BOOL fFullInit);
HMODULE hShell32 = LoadLibrary("shell32.dll");
FileIconInitProc FileIconInit = (FileIconInitProc) GetProcAddress(hShell32, (LPCSTR)660);
FileIconInit(TRUE);
}
#endif
/* Load TkTreeCtrl */
if (Tcl_PkgRequire(interp, "treectrl", PACKAGE_PATCHLEVEL, TRUE) == NULL)
return TCL_ERROR;
/* Get the stubs table from TkTreeCtrl */
stubs = Tcl_GetAssocData(interp, "TreeCtrlStubs", NULL);
if (stubs == NULL)
return TCL_ERROR;
#ifdef TREECTRL_DEBUG
if (sizeof(TreeCtrl) != stubs->sizeofTreeCtrl ||
sizeof(TreeCtrlStubs) != stubs->sizeofTreeCtrlStubs ||
sizeof(TreeElement) != stubs->sizeofTreeElement ||
sizeof(TreeElementArgs) != stubs->sizeofTreeElementArgs) {
Tcl_SetResult(interp, "probably forgot to recompile shellicon",
TCL_VOLATILE);
return TCL_ERROR;
}
#endif
/* Initialize the options table */
BooleanCO_Init(shellIconOptionSpecs, "-addoverlays");
BooleanCO_Init(shellIconOptionSpecs, "-useimagelist");
PerStateCO_Init(shellIconOptionSpecs, "-draw", &pstBoolean,
TreeStateFromObj);
StringTableCO_Init(shellIconOptionSpecs, "-size", sizeST);
StringTableCO_Init(shellIconOptionSpecs, "-type", typeST);
StringTableCO_Init(shellIconOptionSpecs, "-useselected", useSelectedST);
/* Add the "shellicon" element type */
if (TreeCtrl_RegisterElementType(interp, &elemTypeShellIcon) != TCL_OK)
return TCL_ERROR;
if (Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_PATCHLEVEL) != TCL_OK) {
return TCL_ERROR;
}
return TCL_OK;
}
DLLEXPORT int Shellicon_SafeInit(Tcl_Interp *interp)
{
return Shellicon_Init(interp);
}
( run in 0.592 second using v1.01-cache-2.11-cpan-ceb78f64989 )