summaryrefslogtreecommitdiff
path: root/iup/src/win
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2010-06-15 00:59:57 -0700
committerPixel <pixel@nobis-crew.org>2010-06-15 00:59:57 -0700
commiteed0eb6a476d54ce19aeff137984aa981d9e3976 (patch)
tree807891636efd2f87dcbd261e971216269973ae07 /iup/src/win
parentccc8261e4d48de89da4ddfe7b55e378ae0cd6f47 (diff)
Upgrading to iup 3.1
Diffstat (limited to 'iup/src/win')
-rwxr-xr-xiup/src/win/iupwin_button.c62
-rwxr-xr-xiup/src/win/iupwin_canvas.c54
-rwxr-xr-xiup/src/win/iupwin_common.c55
-rwxr-xr-xiup/src/win/iupwin_dialog.c26
-rwxr-xr-xiup/src/win/iupwin_draw.c374
-rwxr-xr-xiup/src/win/iupwin_drv.h5
-rwxr-xr-xiup/src/win/iupwin_filedlg.c72
-rwxr-xr-xiup/src/win/iupwin_focus.c17
-rwxr-xr-xiup/src/win/iupwin_font.c4
-rwxr-xr-xiup/src/win/iupwin_fontdlg.c6
-rwxr-xr-xiup/src/win/iupwin_frame.c43
-rwxr-xr-xiup/src/win/iupwin_globalattrib.c7
-rwxr-xr-xiup/src/win/iupwin_info.c2
-rwxr-xr-xiup/src/win/iupwin_info.h2
-rwxr-xr-xiup/src/win/iupwin_key.c20
-rwxr-xr-xiup/src/win/iupwin_label.c27
-rwxr-xr-xiup/src/win/iupwin_list.c55
-rwxr-xr-xiup/src/win/iupwin_loop.c12
-rwxr-xr-xiup/src/win/iupwin_menu.c3
-rwxr-xr-xiup/src/win/iupwin_open.c5
-rwxr-xr-xiup/src/win/iupwin_progressbar.c2
-rwxr-xr-xiup/src/win/iupwin_tabs.c56
-rwxr-xr-xiup/src/win/iupwin_text.c52
-rwxr-xr-xiup/src/win/iupwin_toggle.c32
-rwxr-xr-xiup/src/win/iupwin_tree.c1292
-rwxr-xr-xiup/src/win/iupwin_val.c37
26 files changed, 1430 insertions, 892 deletions
diff --git a/iup/src/win/iupwin_button.c b/iup/src/win/iupwin_button.c
index 7f780e3..3b05ba7 100755
--- a/iup/src/win/iupwin_button.c
+++ b/iup/src/win/iupwin_button.c
@@ -27,6 +27,7 @@
#include "iupwin_drv.h"
#include "iupwin_handle.h"
#include "iupwin_draw.h"
+#include "iupwin_info.h"
#ifndef CDIS_SHOWKEYBOARDCUES
@@ -308,18 +309,22 @@ static void winButtonDrawText(Ihandle* ih, HDC hDC, int rect_width, int rect_hei
static void winButtonDrawItem(Ihandle* ih, DRAWITEMSTRUCT *drawitem)
{
+ HDC hDC;
iupwinBitmapDC bmpDC;
int border, draw_border;
int width = drawitem->rcItem.right - drawitem->rcItem.left;
int height = drawitem->rcItem.bottom - drawitem->rcItem.top;
- HDC hDC = iupwinDrawCreateBitmapDC(&bmpDC, drawitem->hDC, width, height);
+ hDC = iupwinDrawCreateBitmapDC(&bmpDC, drawitem->hDC, width, height);
iupwinDrawParentBackground(ih, hDC, &drawitem->rcItem);
if ((drawitem->itemState & ODS_FOCUS) && !(drawitem->itemState & ODS_HOTLIGHT))
drawitem->itemState |= ODS_DEFAULT;
+ if (iupAttribGet(ih, "_IUPWINBUT_SELECTED"))
+ drawitem->itemState |= ODS_SELECTED;
+
border = winButtonGetBorder();
if (ih->data->type & IUP_BUTTON_IMAGE && iupAttribGet(ih, "IMPRESS") && !iupAttribGetStr(ih, "IMPRESSBORDER"))
@@ -365,7 +370,7 @@ static int winButtonSetImageAttrib(Ihandle* ih, const char* value)
(void)value;
if (ih->data->type != IUP_BUTTON_TEXT)
{
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
return 1;
}
else
@@ -377,7 +382,7 @@ static int winButtonSetImInactiveAttrib(Ihandle* ih, const char* value)
(void)value;
if (ih->data->type != IUP_BUTTON_TEXT)
{
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
return 1;
}
else
@@ -389,7 +394,7 @@ static int winButtonSetImPressAttrib(Ihandle* ih, const char* value)
(void)value;
if (ih->data->type != IUP_BUTTON_TEXT)
{
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
return 1;
}
else
@@ -400,7 +405,7 @@ static int winButtonSetActiveAttrib(Ihandle* ih, const char* value)
{
/* redraw IMINACTIVE image if any */
if (ih->data->type != IUP_BUTTON_TEXT)
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
return iupBaseSetActiveAttrib(ih, value);
}
@@ -425,7 +430,7 @@ static int winButtonSetAlignmentAttrib(Ihandle* ih, const char* value)
else /* "ACENTER" */
ih->data->vert_alignment = IUP_ALIGN_ACENTER;
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
return 1;
}
@@ -443,7 +448,7 @@ static int winButtonSetPaddingAttrib(Ihandle* ih, const char* value)
{
iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
if (ih->handle)
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
return 0;
}
@@ -454,7 +459,7 @@ static int winButtonSetBgColorAttrib(Ihandle* ih, const char* value)
{
iupAttribSetStr(ih, "BGCOLOR", value);
iupImageUpdateParent(ih);
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
return 1;
}
@@ -486,7 +491,9 @@ static int winButtonSetFgColorAttrib(Ihandle* ih, const char* value)
if (iupStrToRGB(value, &r, &g, &b))
{
ih->data->fgcolor = RGB(r,g,b);
- iupdrvDisplayRedraw(ih);
+
+ if (ih->handle)
+ iupdrvRedrawNow(ih);
}
return 1;
}
@@ -499,7 +506,7 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
{
/* redraw IMPRESS image if any */
if ((msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) && iupAttribGet(ih, "IMPRESS"))
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
switch (msg)
@@ -514,6 +521,13 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
case WM_RBUTTONDOWN:
{
iupwinButtonDown(ih, msg, wp, lp);
+
+ /* Feedback will NOT be done when not receiving the focus */
+ if (msg==WM_LBUTTONDOWN && !iupAttribGetBoolean(ih, "FOCUSONCLICK"))
+ {
+ iupAttribSetStr(ih, "_IUPWINBUT_SELECTED", "1");
+ iupdrvRedrawNow(ih);
+ }
break;
}
case WM_XBUTTONUP:
@@ -526,11 +540,24 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
/* BN_CLICKED will NOT be notified when not receiving the focus */
if (msg==WM_LBUTTONUP && !iupAttribGetBoolean(ih, "FOCUSONCLICK"))
{
- Icallback cb = IupGetCallback(ih, "ACTION");
+ Icallback cb;
+
+ iupAttribSetStr(ih, "_IUPWINBUT_SELECTED", NULL);
+ iupdrvRedrawNow(ih);
+
+ cb = IupGetCallback(ih, "ACTION");
if (cb && cb(ih) == IUP_CLOSE)
IupExitLoop();
}
+ if (!iupwinIsVistaOrNew())
+ {
+ /* TIPs desapear forever after a button click in XP,
+ so we force an update. */
+ char* tip = iupAttribGet(ih, "TIP");
+ if (tip)
+ iupdrvBaseSetTipAttrib(ih, tip);
+ }
break;
}
case WM_KEYDOWN:
@@ -549,7 +576,12 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
if (!iupwin_comctl32ver6)
{
iupAttribSetStr(ih, "_IUPWINBUT_ENTERWIN", NULL);
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
+ }
+ if (!iupAttribGetBoolean(ih, "FOCUSONCLICK"))
+ {
+ iupAttribSetStr(ih, "_IUPWINBUT_SELECTED", NULL);
+ iupdrvRedrawNow(ih);
}
break;
case WM_MOUSEMOVE:
@@ -558,7 +590,7 @@ static int winButtonProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
if (!iupAttribGet(ih, "_IUPWINBUT_ENTERWIN"))
{
iupAttribSetStr(ih, "_IUPWINBUT_ENTERWIN", "1");
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
}
break;
@@ -635,7 +667,7 @@ static int winButtonWmCommand(Ihandle* ih, WPARAM wp, LPARAM lp)
static int winButtonMapMethod(Ihandle* ih)
{
char* value;
- DWORD dwStyle = WS_CHILD |
+ DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS |
BS_NOTIFY; /* necessary because of the base messages */
if (!ih->parent)
@@ -661,7 +693,7 @@ static int winButtonMapMethod(Ihandle* ih)
ih->data->type = IUP_BUTTON_IMAGE;
value = iupAttribGet(ih, "TITLE");
- if (value)
+ if (value && *value!=0)
ih->data->type |= IUP_BUTTON_TEXT;
}
else
diff --git a/iup/src/win/iupwin_canvas.c b/iup/src/win/iupwin_canvas.c
index bb88b8a..b865160 100755
--- a/iup/src/win/iupwin_canvas.c
+++ b/iup/src/win/iupwin_canvas.c
@@ -45,7 +45,7 @@ static void winCanvasSetScrollInfo(HWND hWnd, int imin, int imax, int ipos, int
static int winCanvasSetBgColorAttrib(Ihandle *ih, const char *value)
{
(void)value;
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
return 1;
}
@@ -220,7 +220,7 @@ static void winCanvasUpdateHorScroll(Ihandle* ih, WORD winop)
xmax = iupAttribGetFloat(ih,"XMAX");
xmin = iupAttribGetFloat(ih,"XMIN");
- winCanvasGetScrollInfo(ih->handle, &iposx, &ipagex, SB_HORZ, winop==SB_THUMBTRACK? 1: 0);
+ winCanvasGetScrollInfo(ih->handle, &iposx, &ipagex, SB_HORZ, winop==SB_THUMBTRACK||winop==SB_THUMBPOSITION? 1: 0);
if (!iupAttribGet(ih,"LINEX"))
{
@@ -296,7 +296,7 @@ static void winCanvasUpdateVerScroll(Ihandle* ih, WORD winop)
ymax = iupAttribGetFloat(ih,"YMAX");
ymin = iupAttribGetFloat(ih,"YMIN");
- winCanvasGetScrollInfo(ih->handle, &iposy, &ipagey, SB_VERT, winop==SB_THUMBTRACK? 1: 0);
+ winCanvasGetScrollInfo(ih->handle, &iposy, &ipagey, SB_VERT, winop==SB_THUMBTRACK||winop==SB_THUMBPOSITION? 1: 0);
if (!iupAttribGet(ih, "LINEY"))
{
@@ -372,6 +372,10 @@ static int winCanvasProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
GetClientRect(ih->handle, &rect);
FillRect(hdc, &rect, iupwinBrushGet(color));
}
+ else
+ InvalidateRect(ih->handle,NULL,FALSE); /* This will invalidate all area.
+ Necessary in XP, or overlapping windows will have the effect of partial redrawing. */
+
/* always return non zero value */
*result = 1;
return 1;
@@ -382,7 +386,7 @@ static int winCanvasProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(ih->handle, &ps);
- iupAttribSetStr(ih, "HDC_WMPAINT", (char*)&hdc);
+ iupAttribSetStr(ih, "HDC_WMPAINT", (char*)hdc);
iupAttribSetStrf(ih, "CLIPRECT", "%d %d %d %d", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top);
cb(ih, ih->data->posx, ih->data->posy);
@@ -542,27 +546,13 @@ static int winCanvasProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *r
return iupwinBaseProc(ih, msg, wp, lp, result);
}
-static void winCanvasRegisterClass(void)
-{
- WNDCLASS wndclass;
- ZeroMemory(&wndclass, sizeof(WNDCLASS));
-
- wndclass.hInstance = iupwin_hinstance;
- wndclass.lpszClassName = "IupCanvas";
- wndclass.lpfnWndProc = (WNDPROC)iupwinBaseWinProc;
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; /* using CS_OWNDC will minimize the work of cdActivate in the CD library */
- wndclass.hbrBackground = NULL; /* remove the background to optimize redraw */
-
- RegisterClass(&wndclass);
-}
-
static int winCanvasMapMethod(Ihandle* ih)
{
CLIENTCREATESTRUCT clientstruct;
void *clientdata = NULL;
char *classname;
- DWORD dwStyle = WS_CHILD, dwExStyle = 0;
+ DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,
+ dwExStyle = 0;
if (!ih->parent)
return IUP_ERROR;
@@ -574,14 +564,7 @@ static int winCanvasMapMethod(Ihandle* ih)
}
if (ih->firstchild) /* can be a container */
- {
- dwStyle |= WS_CLIPSIBLINGS;
-
- if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED"))
- dwExStyle |= WS_EX_COMPOSITED;
- else
- dwStyle |= WS_CLIPCHILDREN;
- }
+ iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);
if (iupAttribGetBoolean(ih, "MDICLIENT"))
{
@@ -693,6 +676,21 @@ static void winCanvasReleaseMethod(Iclass* ic)
UnregisterClass("IupCanvas", iupwin_hinstance);
}
+static void winCanvasRegisterClass(void)
+{
+ WNDCLASS wndclass;
+ ZeroMemory(&wndclass, sizeof(WNDCLASS));
+
+ wndclass.hInstance = iupwin_hinstance;
+ wndclass.lpszClassName = "IupCanvas";
+ wndclass.lpfnWndProc = (WNDPROC)iupwinBaseWinProc;
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; /* using CS_OWNDC will minimize the work of cdActivate in the CD library */
+ wndclass.hbrBackground = NULL; /* remove the background to optimize redraw */
+
+ RegisterClass(&wndclass);
+}
+
void iupdrvCanvasInitClass(Iclass* ic)
{
if (!iupwinClassExist("IupCanvas"))
diff --git a/iup/src/win/iupwin_common.c b/iup/src/win/iupwin_common.c
index a1a7c0f..ba68b78 100755
--- a/iup/src/win/iupwin_common.c
+++ b/iup/src/win/iupwin_common.c
@@ -94,16 +94,17 @@ void iupdrvBaseLayoutUpdateMethod(Ihandle *ih)
SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
}
-void iupdrvDisplayRedraw(Ihandle *ih)
+void iupdrvRedrawNow(Ihandle *ih)
{
/* REDRAW Now */
- RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_NOCHILDREN|RDW_UPDATENOW);
+ RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_UPDATENOW);
}
-void iupdrvDisplayUpdate(Ihandle *ih)
+void iupdrvPostRedraw(Ihandle *ih)
{
/* Post a REDRAW */
- RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_NOCHILDREN);
+ /* can NOT use RDW_NOCHILDREN because IupList has internal children that needs to be redraw */
+ RedrawWindow(ih->handle,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_INTERNALPAINT);
}
void iupdrvScreenToClient(Ihandle* ih, int *x, int *y)
@@ -534,6 +535,8 @@ int iupdrvBaseSetZorderAttrib(Ihandle* ih, const char* value)
void iupdrvSetVisible(Ihandle* ih, int visible)
{
+ if (iupStrEqual(ih->iclass->name, "colorbar"))
+ ih=ih;
ShowWindow(ih->handle, visible? SW_SHOWNORMAL: SW_HIDE);
}
@@ -618,6 +621,18 @@ char* iupdrvBaseGetClientSizeAttrib(Ihandle* ih)
#define IDC_HELP MAKEINTRESOURCE(32651)
#endif
+static HCURSOR winLoadComCtlCursor(LPCTSTR lpCursorName)
+{
+ HCURSOR cur = NULL;
+ HINSTANCE hinstDll = LoadLibrary("comctl32.dll");
+ if (hinstDll)
+ {
+ cur = LoadCursor(hinstDll, lpCursorName);
+ FreeLibrary(hinstDll);
+ }
+ return cur;
+}
+
static HCURSOR winGetCursor(Ihandle* ih, const char* name)
{
static struct {
@@ -649,7 +664,7 @@ static HCURSOR winGetCursor(Ihandle* ih, const char* name)
{"APPSTARTING", IDC_APPSTARTING}
};
- HCURSOR cur;
+ HCURSOR cur = NULL;
char str[50];
int i, count = sizeof(table)/sizeof(table[0]);
@@ -676,14 +691,22 @@ static HCURSOR winGetCursor(Ihandle* ih, const char* name)
if (i == count)
{
/* check other system cursors */
- /* cursor PEN is handled here */
+
if (iupStrEqualNoCase(name, "PEN"))
- name = "CURSOR_PEN";
+ name = "CURSOR_PEN"; /* name in "iup.rc" */
/* check for an name defined cursor */
cur = iupImageGetCursor(name);
}
+ if (!cur)
+ {
+ if (iupStrEqualNoCase(name, "SPLITTER_VERT"))
+ cur = winLoadComCtlCursor(MAKEINTRESOURCE(107));
+ else if (iupStrEqualNoCase(name, "SPLITTER_HORIZ"))
+ cur = winLoadComCtlCursor(MAKEINTRESOURCE(135));
+ }
+
iupAttribSetStr(ih, str, (char*)cur);
return cur;
}
@@ -758,29 +781,29 @@ int iupwinButtonUp(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp)
if (msg==WM_LBUTTONUP)
{
b = IUP_BUTTON1;
- iupKEYSETBUTTON1(status);
+ iupKEY_SETBUTTON1(status);
}
else if (msg==WM_MBUTTONUP)
{
b = IUP_BUTTON2;
- iupKEYSETBUTTON2(status);
+ iupKEY_SETBUTTON2(status);
}
else if (msg==WM_RBUTTONUP)
{
b = IUP_BUTTON3;
- iupKEYSETBUTTON3(status);
+ iupKEY_SETBUTTON3(status);
}
else if (msg==WM_XBUTTONUP)
{
if (HIWORD(wp) == XBUTTON1)
{
b = IUP_BUTTON4;
- iupKEYSETBUTTON4(status);
+ iupKEY_SETBUTTON4(status);
}
else
{
b = IUP_BUTTON5;
- iupKEYSETBUTTON5(status);
+ iupKEY_SETBUTTON5(status);
}
}
@@ -807,6 +830,14 @@ int iupwinMouseMove(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp)
return 0;
}
+void iupwinGetNativeParentStyle(Ihandle* ih, DWORD *dwExStyle, DWORD *dwStyle)
+{
+ *dwStyle |= WS_CLIPCHILDREN;
+
+ if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED"))
+ *dwExStyle |= WS_EX_COMPOSITED;
+}
+
int iupwinCreateWindowEx(Ihandle* ih, LPCSTR lpClassName, DWORD dwExStyle, DWORD dwStyle)
{
ih->serial = iupDialogGetChildId(ih);
diff --git a/iup/src/win/iupwin_dialog.c b/iup/src/win/iupwin_dialog.c
index 39fdc0c..c13b88d 100755
--- a/iup/src/win/iupwin_dialog.c
+++ b/iup/src/win/iupwin_dialog.c
@@ -102,9 +102,9 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu
else
{
int has_titlebar = iupAttribGetBoolean(ih, "MAXBOX") ||
- iupAttribGetBoolean(ih, "MINBOX") ||
- iupAttribGetBoolean(ih, "MENUBOX") ||
- IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */
+ iupAttribGetBoolean(ih, "MINBOX") ||
+ iupAttribGetBoolean(ih, "MENUBOX") ||
+ IupGetAttribute(ih, "TITLE"); /* must use IupGetAttribute to check from the native implementation */
*caption = 0;
if (has_titlebar)
@@ -118,14 +118,17 @@ void iupdrvDialogGetDecoration(Ihandle* ih, int *border, int *caption, int *menu
*border = 0;
if (iupAttribGetBoolean(ih, "RESIZE"))
{
+ /* has_border */
*border = GetSystemMetrics(SM_CXFRAME); /* Thickness of the sizing border around the perimeter of a window */
} /* that can be resized, in pixels. */
else if (has_titlebar)
{
+ /* has_border */
*border = GetSystemMetrics(SM_CXFIXEDFRAME); /* Thickness of the frame around the perimeter of a window */
} /* that has a caption but is not sizable, in pixels. */
else if (iupAttribGetBoolean(ih, "BORDER"))
{
+ /* has_border */
*border = GetSystemMetrics(SM_CXBORDER);
}
}
@@ -712,28 +715,27 @@ static int winDialogMapMethod(Ihandle* ih)
}
if (iupAttribGetBoolean(ih, "RESIZE"))
+ {
dwStyle |= WS_THICKFRAME;
+ has_border = 1;
+ }
else
iupAttribSetStr(ih, "MAXBOX", "NO"); /* Must also remove this to RESIZE=NO work */
-
if (iupAttribGetBoolean(ih, "MAXBOX"))
{
dwStyle |= WS_MAXIMIZEBOX;
has_titlebar = 1;
}
-
if (iupAttribGetBoolean(ih, "MINBOX"))
{
dwStyle |= WS_MINIMIZEBOX;
has_titlebar = 1;
}
-
if (iupAttribGetBoolean(ih, "MENUBOX"))
{
dwStyle |= WS_SYSMENU;
has_titlebar = 1;
}
-
if (iupAttribGetBoolean(ih, "BORDER") || has_titlebar)
has_border = 1;
@@ -815,10 +817,7 @@ static int winDialogMapMethod(Ihandle* ih)
if (iupAttribGetBoolean(ih, "DIALOGFRAME") && native_parent)
dwExStyle |= WS_EX_DLGMODALFRAME; /* this will hide the MENUBOX but not the close button */
- if (iupAttribGetBoolean(ih, "COMPOSITED"))
- dwExStyle |= WS_EX_COMPOSITED;
- else
- dwStyle |= WS_CLIPCHILDREN;
+ iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);
if (iupAttribGetBoolean(ih, "HELPBUTTON"))
dwExStyle |= WS_EX_CONTEXTHELP;
@@ -878,7 +877,6 @@ static int winDialogMapMethod(Ihandle* ih)
/* Reset attributes handled during creation that */
/* also can be changed later, and can be consulted from the native system. */
iupAttribSetStr(ih, "TITLE", NULL);
- iupAttribSetStr(ih, "BORDER", NULL);
/* Ignore VISIBLE before mapping */
iupAttribSetStr(ih, "VISIBLE", NULL);
@@ -956,7 +954,7 @@ static int winDialogSetBgColorAttrib(Ihandle* ih, const char* value)
{
iupAttribStoreStr(ih, "_IUPWIN_BACKGROUND_COLOR", value);
iupAttribSetStr(ih, "_IUPWIN_BACKGROUND_BITMAP", NULL);
- RedrawWindow(ih->handle, NULL, NULL, RDW_ERASE|RDW_ERASENOW); /* force a WM_ERASEBKGND now */
+ RedrawWindow(ih->handle, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); /* post WM_ERASEBKGND and WM_PAINT */
return 1;
}
return 0;
@@ -973,7 +971,7 @@ static int winDialogSetBackgroundAttrib(Ihandle* ih, const char* value)
{
iupAttribSetStr(ih, "_IUPWIN_BACKGROUND_COLOR", NULL);
iupAttribSetStr(ih, "_IUPWIN_BACKGROUND_BITMAP", (char*)hBitmap);
- RedrawWindow(ih->handle, NULL, NULL, RDW_ERASE|RDW_ERASENOW); /* force a WM_ERASEBKGND now */
+ RedrawWindow(ih->handle, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); /* post WM_ERASEBKGND and WM_PAINT */
return 1;
}
}
diff --git a/iup/src/win/iupwin_draw.c b/iup/src/win/iupwin_draw.c
index 4a810e6..f663d20 100755
--- a/iup/src/win/iupwin_draw.c
+++ b/iup/src/win/iupwin_draw.c
@@ -14,12 +14,16 @@
#include <stdio.h>
#include <string.h>
#include <memory.h>
+#include <math.h>
#include "iup.h"
#include "iup_attrib.h"
#include "iup_class.h"
#include "iup_str.h"
+#include "iup_object.h"
+#include "iup_image.h"
+#include "iup_draw.h"
#include "iupwin_drv.h"
#include "iupwin_info.h"
@@ -38,6 +42,11 @@
#endif
+/******************************************************************************
+ Themes
+*******************************************************************************/
+
+
typedef HTHEME (STDAPICALLTYPE *_winThemeOpenData)(HWND hwnd, LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE *_winThemeCloseData)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE *_winThemeDrawBackground)(HTHEME hTheme, HDC hDC, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
@@ -61,58 +70,6 @@ static int winDrawThemeEnabled(void)
return winThemeOpenData? 1: 0;
}
-void iupwinDrawText(HDC hDC, const char* text, int x, int y, int width, int height, HFONT hFont, COLORREF fgcolor, int style)
-{
- COLORREF oldcolor;
- RECT rect;
- HFONT hOldFont = SelectObject(hDC, hFont);
-
- rect.left = x;
- rect.top = y;
- rect.right = x+width;
- rect.bottom = y+height;
-
- SetTextAlign(hDC, TA_TOP|TA_LEFT);
- SetBkMode(hDC, TRANSPARENT);
- oldcolor = SetTextColor(hDC, fgcolor);
-
- DrawText(hDC, text, -1, &rect, style|DT_NOCLIP);
-
- SelectObject(hDC, hOldFont);
- SetTextColor(hDC, oldcolor);
- SetBkMode(hDC, OPAQUE);
-}
-
-void iupwinDrawBitmap(HDC hDC, HBITMAP hBitmap, HBITMAP hMask, int x, int y, int width, int height, int bpp)
-{
- HDC hMemDC = CreateCompatibleDC(hDC);
- SelectObject(hMemDC, hBitmap);
-
- if (bpp == 32 && winAlphaBlend)
- {
- BLENDFUNCTION blendfunc;
- blendfunc.BlendOp = AC_SRC_OVER;
- blendfunc.BlendFlags = 0;
- blendfunc.SourceConstantAlpha = 0xFF;
- blendfunc.AlphaFormat = AC_SRC_ALPHA;
-
- winAlphaBlend(hDC, x, y, width, height,
- hMemDC, 0, 0, width, height,
- blendfunc);
- }
- else if (bpp == 8 && hMask)
- MaskBlt(hDC, x, y, width, height,
- hMemDC, 0, 0,
- hMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
- else
- BitBlt(hDC, x, y, width, height,
- hMemDC, 0, 0,
- SRCCOPY);
-
-
- DeleteDC(hMemDC);
-}
-
void iupwinDrawInit(void)
{
if (!winAlphaBlend)
@@ -201,7 +158,7 @@ int iupwinDrawGetThemeTabsBgColor(HWND hWnd, COLORREF *color)
if (!hTheme)
return 0;
- if (iupwinIsVista())
+ if (iupwinIsVistaOrNew())
ret = winThemeGetColor(hTheme, TABP_AEROWIZARDBODY, TIS_NORMAL, TMT_FILLCOLORHINT, color);
else
ret = winThemeGetColor(hTheme, TABP_BODY, TIS_NORMAL, TMT_FILLCOLORHINT, color);
@@ -246,6 +203,79 @@ int iupwinDrawGetThemeFrameFgColor(HWND hWnd, COLORREF *color)
return (ret == S_OK)? 1: 0;
}
+void iupwinDrawRemoveTheme(HWND hwnd)
+{
+ typedef HRESULT (STDAPICALLTYPE *winSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
+ static winSetWindowTheme mySetWindowTheme = NULL;
+ if (!mySetWindowTheme)
+ {
+ HMODULE hinstDll = LoadLibrary("uxtheme.dll");
+ if (hinstDll)
+ mySetWindowTheme = (winSetWindowTheme)GetProcAddress(hinstDll, "SetWindowTheme");
+ }
+
+ if (mySetWindowTheme)
+ mySetWindowTheme(hwnd, L"", L"");
+}
+
+
+/******************************************************************************
+ Utilities
+*******************************************************************************/
+
+
+void iupwinDrawText(HDC hDC, const char* text, int x, int y, int width, int height, HFONT hFont, COLORREF fgcolor, int style)
+{
+ COLORREF oldcolor;
+ RECT rect;
+ HFONT hOldFont = SelectObject(hDC, hFont);
+
+ rect.left = x;
+ rect.top = y;
+ rect.right = x+width;
+ rect.bottom = y+height;
+
+ SetTextAlign(hDC, TA_TOP|TA_LEFT);
+ SetBkMode(hDC, TRANSPARENT);
+ oldcolor = SetTextColor(hDC, fgcolor);
+
+ DrawText(hDC, text, -1, &rect, style|DT_NOCLIP);
+
+ SelectObject(hDC, hOldFont);
+ SetTextColor(hDC, oldcolor);
+ SetBkMode(hDC, OPAQUE);
+}
+
+void iupwinDrawBitmap(HDC hDC, HBITMAP hBitmap, HBITMAP hMask, int x, int y, int width, int height, int bpp)
+{
+ HDC hMemDC = CreateCompatibleDC(hDC);
+ SelectObject(hMemDC, hBitmap);
+
+ if (bpp == 32 && winAlphaBlend)
+ {
+ BLENDFUNCTION blendfunc;
+ blendfunc.BlendOp = AC_SRC_OVER;
+ blendfunc.BlendFlags = 0;
+ blendfunc.SourceConstantAlpha = 0xFF;
+ blendfunc.AlphaFormat = AC_SRC_ALPHA;
+
+ winAlphaBlend(hDC, x, y, width, height,
+ hMemDC, 0, 0, width, height,
+ blendfunc);
+ }
+ else if (bpp == 8 && hMask)
+ MaskBlt(hDC, x, y, width, height,
+ hMemDC, 0, 0,
+ hMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000));
+ else
+ BitBlt(hDC, x, y, width, height,
+ hMemDC, 0, 0,
+ SRCCOPY);
+
+
+ DeleteDC(hMemDC);
+}
+
static int winDrawGetStateId(int itemState)
{
if (itemState & ODS_DISABLED)
@@ -282,21 +312,6 @@ void iupdrvDrawFocusRect(Ihandle* ih, void* gc, int x, int y, int w, int h)
DrawFocusRect(hDC, &rect);
}
-void iupwinDrawRemoveTheme(HWND hwnd)
-{
- typedef HRESULT (STDAPICALLTYPE *winSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
- static winSetWindowTheme mySetWindowTheme = NULL;
- if (!mySetWindowTheme)
- {
- HMODULE hinstDll = LoadLibrary("uxtheme.dll");
- if (hinstDll)
- mySetWindowTheme = (winSetWindowTheme)GetProcAddress(hinstDll, "SetWindowTheme");
- }
-
- if (mySetWindowTheme)
- mySetWindowTheme(hwnd, L"", L"");
-}
-
void iupwinDrawParentBackground(Ihandle* ih, HDC hDC, RECT* rect)
{
unsigned char r=0, g=0, b=0;
@@ -326,3 +341,226 @@ void iupwinDrawDestroyBitmapDC(iupwinBitmapDC *bmpDC)
DeleteDC(bmpDC->hBitmapDC);
}
+
+/******************************************************************************
+ Simple Draw
+*******************************************************************************/
+
+struct _IdrawCanvas{
+ Ihandle* ih;
+ int w, h;
+
+ int release_dc;
+ HBITMAP hBitmap, hOldBitmap;
+ HDC hBitmapDC, hDC;
+};
+
+IdrawCanvas* iupDrawCreateCanvas(Ihandle* ih)
+{
+ IdrawCanvas* dc = calloc(1, sizeof(IdrawCanvas));
+ RECT rect;
+
+ /* valid only inside the ACTION callback of an IupCanvas */
+ dc->hDC = (HDC)IupGetAttribute(ih, "HDC_WMPAINT");
+ if (!dc->hDC)
+ {
+ dc->hDC = GetDC(ih->handle);
+ dc->release_dc = 1;
+ }
+
+ GetClientRect(ih->handle, &rect);
+ dc->w = rect.right - rect.left;
+ dc->h = rect.bottom - rect.top;
+
+ dc->hBitmap = CreateCompatibleBitmap(dc->hDC, dc->w, dc->h);
+ dc->hBitmapDC = CreateCompatibleDC(dc->hDC);
+ dc->hOldBitmap = SelectObject(dc->hBitmapDC, dc->hBitmap);
+
+ SetBkMode(dc->hBitmapDC, TRANSPARENT);
+ SetTextAlign(dc->hBitmapDC, TA_TOP|TA_LEFT);
+
+ return dc;
+}
+
+void iupDrawKillCanvas(IdrawCanvas* dc)
+{
+ SelectObject(dc->hBitmapDC, dc->hOldBitmap);
+ DeleteObject(dc->hBitmap);
+ DeleteDC(dc->hBitmapDC);
+ if (dc->release_dc)
+ DeleteDC(dc->hDC);
+
+ free(dc);
+}
+
+void iupDrawUpdateSize(IdrawCanvas* dc)
+{
+ int w, h;
+ RECT rect;
+ GetClientRect(dc->ih->handle, &rect);
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+
+ if (w != dc->w || h != dc->h)
+ {
+ SelectObject(dc->hBitmapDC, dc->hOldBitmap);
+ DeleteObject(dc->hBitmap);
+ DeleteDC(dc->hBitmapDC);
+
+ dc->hBitmap = CreateCompatibleBitmap(dc->hDC, dc->w, dc->h);
+ dc->hBitmapDC = CreateCompatibleDC(dc->hDC);
+ dc->hOldBitmap = SelectObject(dc->hBitmapDC, dc->hBitmap);
+
+ SetBkMode(dc->hBitmapDC, TRANSPARENT);
+ SetTextAlign(dc->hBitmapDC, TA_TOP|TA_LEFT);
+ }
+}
+
+void iupDrawFlush(IdrawCanvas* dc)
+{
+ BitBlt(dc->hDC, 0, 0, dc->w, dc->h, dc->hBitmapDC, 0, 0, SRCCOPY);
+}
+
+void iupDrawGetSize(IdrawCanvas* dc, int *w, int *h)
+{
+ if (w) *w = dc->w;
+ if (h) *h = dc->h;
+}
+
+void iupDrawParentBackground(IdrawCanvas* dc)
+{
+ unsigned char r=0, g=0, b=0;
+ char* color = iupBaseNativeParentGetBgColorAttrib(dc->ih);
+ iupStrToRGB(color, &r, &g, &b);
+ iupDrawRectangle(dc, 0, 0, dc->w-1, dc->h-1, r, g, b, 1);
+}
+
+void iupDrawRectangle(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b, int filled)
+{
+ RECT rect;
+ rect.left = x1; rect.top = y1; rect.right = x2+1; rect.bottom = y2+1;
+ SetDCBrushColor(dc->hBitmapDC, RGB(r,g,b));
+ if (filled)
+ FillRect(dc->hBitmapDC, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
+ else
+ FrameRect(dc->hBitmapDC, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
+}
+
+void iupDrawLine(IdrawCanvas* dc, int x1, int y1, int x2, int y2, unsigned char r, unsigned char g, unsigned char b)
+{
+ POINT line_poly[2];
+ HPEN hPen = CreatePen(PS_SOLID, 1, RGB(r, g, b));
+ HPEN hPenOld = SelectObject(dc->hBitmapDC, hPen);
+ line_poly[0].x = x1;
+ line_poly[0].y = y1;
+ line_poly[1].x = x2;
+ line_poly[1].y = y2;
+ Polyline(dc->hBitmapDC, line_poly, 2);
+ SelectObject(dc->hBitmapDC, hPenOld);
+ DeleteObject(hPen);
+}
+
+#define IUP_DEG2RAD 0.01745329252 /* degrees to radians (rad = CD_DEG2RAD * deg) */
+
+static int winDrawCalcArc(int c1, int c2, double a, int start)
+{
+ double proj, off;
+ if (start)
+ proj = cos(IUP_DEG2RAD * a);
+ else
+ proj = sin(IUP_DEG2RAD * a);
+ off = (c2+c1)/2.0 + (c2-c1+1)*proj/2.0;
+ return iupROUND(off);
+}
+
+void iupDrawArc(IdrawCanvas* dc, int x1, int y1, int x2, int y2, double a1, double a2, unsigned char r, unsigned char g, unsigned char b, int filled)
+{
+ int XStartArc = winDrawCalcArc(x1, x2, a1, 1);
+ int XEndArc = winDrawCalcArc(x1, x2, a2, 0);
+ int YStartArc = winDrawCalcArc(y1, y2, a1, 1);
+ int YEndArc = winDrawCalcArc(y1, y2, a2, 0);
+
+ if (filled)
+ {
+ HBRUSH hBrush = CreateSolidBrush(RGB(r,g,b));
+ HPEN hBrushOld = SelectObject(dc->hBitmapDC, hBrush);
+ BeginPath(dc->hBitmapDC);
+ Pie(dc->hBitmapDC, x1, y1, x2+1, y2+1, XStartArc, YStartArc, XEndArc, YEndArc);
+ EndPath(dc->hBitmapDC);
+ FillPath(dc->hBitmapDC);
+ SelectObject(dc->hBitmapDC, hBrushOld);
+ DeleteObject(hBrush);
+ }
+ else
+ {
+ HPEN hPen = CreatePen(PS_SOLID, 1, RGB(r, g, b));
+ HPEN hPenOld = SelectObject(dc->hBitmapDC, hPen);
+ Arc(dc->hBitmapDC, x1, y1, x2+1, y2+1, XStartArc, YStartArc, XEndArc, YEndArc);
+ SelectObject(dc->hBitmapDC, hPenOld);
+ DeleteObject(hPen);
+ }
+}
+
+void iupDrawPolygon(IdrawCanvas* dc, int* points, int count, unsigned char r, unsigned char g, unsigned char b, int filled)
+{
+ if (filled)
+ {
+ HBRUSH hBrush = CreateSolidBrush(RGB(r,g,b));
+ HPEN hBrushOld = SelectObject(dc->hBitmapDC, hBrush);
+ BeginPath(dc->hBitmapDC);
+ Polygon(dc->hBitmapDC, (POINT*)points, count);
+ EndPath(dc->hBitmapDC);
+ FillPath(dc->hBitmapDC);
+ SelectObject(dc->hBitmapDC, hBrushOld);
+ DeleteObject(hBrush);
+ }
+ else
+ {
+ HPEN hPen = CreatePen(PS_SOLID, 1, RGB(r, g, b));
+ HPEN hPenOld = SelectObject(dc->hBitmapDC, hPen);
+ Polyline(dc->hBitmapDC, (POINT*)points, count);
+ SelectObject(dc->hBitmapDC, hPenOld);
+ DeleteObject(hPen);
+ }
+}
+
+void iupDrawSetClipRect(IdrawCanvas* dc, int x1, int y1, int x2, int y2)
+{
+ HRGN clip_hrgn = CreateRectRgn(x1, y1, x2, y2);
+ SelectClipRgn(dc->hBitmapDC, clip_hrgn);
+ DeleteObject(clip_hrgn);
+}
+
+void iupDrawResetClip(IdrawCanvas* dc)
+{
+ SelectClipRgn(dc->hBitmapDC, NULL);
+}
+
+void iupDrawText(IdrawCanvas* dc, const char* text, int len, int x, int y, unsigned char r, unsigned char g, unsigned char b)
+{
+ HFONT hOldFont, hFont = (HFONT)IupGetAttribute(dc->ih, "HFONT");
+ SetTextColor(dc->hBitmapDC, RGB(r, g, b));
+ hOldFont = SelectObject(dc->hBitmapDC, hFont);
+ TextOut(dc->hBitmapDC, x, y, text, len);
+ SelectObject(dc->hBitmapDC, hOldFont);
+}
+
+void iupDrawImage(IdrawCanvas* dc, const char* name, int make_inactive, int x, int y)
+{
+ int img_w, img_h, bpp;
+ HBITMAP hMask = NULL;
+ HBITMAP hBitmap = iupImageGetImage(name, dc->ih, make_inactive);
+ if (!hBitmap)
+ return;
+
+ /* must use this info, since image can be a driver image loaded from resources */
+ iupdrvImageGetInfo(hBitmap, &img_w, &img_h, &bpp);
+
+ if (bpp == 8)
+ hMask = iupdrvImageCreateMask(IupGetHandle(name));
+
+ iupwinDrawBitmap(dc->hBitmapDC, hBitmap, hMask, x, y, img_w, img_h, bpp);
+
+ if (hMask)
+ DeleteObject(hMask);
+}
diff --git a/iup/src/win/iupwin_drv.h b/iup/src/win/iupwin_drv.h
index 3372c1a..7407a7a 100755
--- a/iup/src/win/iupwin_drv.h
+++ b/iup/src/win/iupwin_drv.h
@@ -77,6 +77,7 @@ int iupwinBaseContainerProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT
/* Creates the Window with native parent and child ID, associate HWND with Ihandle*,
and replace the WinProc by iupwinBaseWinProc */
int iupwinCreateWindowEx(Ihandle* ih, LPCSTR lpClassName, DWORD dwExStyle, DWORD dwStyle);
+void iupwinGetNativeParentStyle(Ihandle* ih, DWORD *dwExStyle, DWORD *dwStyle);
int iupwinClassExist(const char* name);
int iupwinGetColorRef(Ihandle *ih, char *name, COLORREF *color);
@@ -97,8 +98,8 @@ char* iupwinGetClipboardText(Ihandle* ih);
int iupwinGetScreenRes(void);
/* 1 point = 1/72 inch */
/* pixel = (point/72)*(pixel/inch) */
-#define IUPWIN_PT2PIXEL(_pt, _res) MulDiv(_pt, _res, 72) /* (((_pt)*(_res))/72) */
-#define IUPWIN_PIXEL2PT(_pixel, _res) MulDiv(_pixel, 72, _res) /* (((_pixel)*72)/(_res)) */
+#define iupWIN_PT2PIXEL(_pt, _res) MulDiv(_pt, _res, 72) /* (((_pt)*(_res))/72) */
+#define iupWIN_PIXEL2PT(_pixel, _res) MulDiv(_pixel, 72, _res) /* (((_pixel)*72)/(_res)) */
/* child window identifier of the first MDI child window created,
diff --git a/iup/src/win/iupwin_filedlg.c b/iup/src/win/iupwin_filedlg.c
index da66b4b..26994e5 100755
--- a/iup/src/win/iupwin_filedlg.c
+++ b/iup/src/win/iupwin_filedlg.c
@@ -63,7 +63,7 @@ static INT CALLBACK winFileDlgBrowseCallback(HWND hWnd, UINT uMsg, LPARAM lParam
}
else if (uMsg == BFFM_SELCHANGED)
{
- char* buffer = iupStrGetMemory(MAX_FILENAME_SIZE);
+ char buffer[MAX_FILENAME_SIZE];
ITEMIDLIST* selecteditem = (ITEMIDLIST*)lParam;
buffer[0] = 0;
SHGetPathFromIDList(selecteditem, buffer);
@@ -90,7 +90,7 @@ static void winFileDlgGetFolder(Ihandle *ih)
browseinfo.pszDisplayName = buffer;
browseinfo.lpfn = winFileDlgBrowseCallback;
browseinfo.lParam = (LPARAM)ih;
- browseinfo.ulFlags = BIF_NEWDIALOGSTYLE;
+ browseinfo.ulFlags = IupGetGlobal("_IUPWIN_COINIT_MULTITHREADED")? 0: BIF_NEWDIALOGSTYLE;
browseinfo.hwndOwner = parent;
selecteditem = SHBrowseForFolder(&browseinfo);
@@ -112,6 +112,37 @@ static void winFileDlgGetFolder(Ihandle *ih)
/************************************************************************************************/
+static int winFileDlgGetSelectedFile(Ihandle* ih, HWND hWnd, char* filename)
+{
+ int ret = CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE);
+ if (ret < 0)
+ return 0;
+
+ if (iupAttribGetBoolean(ih, "MULTIPLEFILES"))
+ {
+ /* check if there are more than 1 files and return only the first one */
+ int found = 0;
+ while(*filename != 0)
+ {
+ if (*filename == '"')
+ {
+ if (!found)
+ found = 1;
+ else
+ {
+ *(filename-1) = 0;
+ return 1;
+ }
+ }
+ if (found)
+ *filename = *(filename+1);
+ filename++;
+ }
+ }
+
+ return 1;
+}
+
static UINT_PTR CALLBACK winFileDlgSimpleHook(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
(void)wParam;
@@ -152,16 +183,15 @@ static UINT_PTR CALLBACK winFileDlgSimpleHook(HWND hWnd, UINT uiMsg, WPARAM wPar
IFnss cb = (IFnss)IupGetCallback(ih, "FILE_CB");
if (cb)
{
- char* filename = iupStrGetMemory(MAX_FILENAME_SIZE);
- if (CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE) <= MAX_FILENAME_SIZE)
+ char filename[MAX_FILENAME_SIZE];
+ if (winFileDlgGetSelectedFile(ih, hWnd, filename))
{
int ret;
char* file_msg;
if (!iupdrvIsFile(filename))
- break;
-
- if (pofn->hdr.code == CDN_FILEOK)
+ file_msg = "OTHER";
+ else if (pofn->hdr.code == CDN_FILEOK)
file_msg = "OK";
else
file_msg = "SELECT";
@@ -267,9 +297,9 @@ static UINT_PTR CALLBACK winFileDlgPreviewHook(HWND hWnd, UINT uiMsg, WPARAM wPa
LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT)lParam;
Ihandle* ih = (Ihandle*)GetWindowLongPtr(hWnd, DWLP_USER);
IFnss cb = (IFnss)IupGetCallback(ih, "FILE_CB");
- char* filename = iupStrGetMemory(MAX_FILENAME_SIZE);
+ char filename[MAX_FILENAME_SIZE];
iupAttribSetStr(ih, "PREVIEWDC", (char*)lpDrawItem->hDC);
- if (CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE) <= MAX_FILENAME_SIZE)
+ if (winFileDlgGetSelectedFile(ih, hWnd, filename))
{
if (iupdrvIsFile(filename))
cb(ih, filename, "PAINT");
@@ -324,16 +354,15 @@ static UINT_PTR CALLBACK winFileDlgPreviewHook(HWND hWnd, UINT uiMsg, WPARAM wPa
case CDN_SELCHANGE:
{
HWND hWndPreview = GetDlgItem(hWnd, IUP_PREVIEWCANVAS);
- char* filename = iupStrGetMemory(MAX_FILENAME_SIZE);
- if (CommDlg_OpenSave_GetFilePath(GetParent(hWnd), filename, MAX_FILENAME_SIZE) <= MAX_FILENAME_SIZE)
+ char filename[MAX_FILENAME_SIZE];
+ if (winFileDlgGetSelectedFile(ih, hWnd, filename))
{
int ret;
char* file_msg;
if (!iupdrvIsFile(filename))
- break;
-
- if (pofn->hdr.code == CDN_FILEOK)
+ file_msg = "OTHER";
+ else if (pofn->hdr.code == CDN_FILEOK)
file_msg = "OK";
else
file_msg = "SELECT";
@@ -520,9 +549,14 @@ static int winFileDlgPopup(Ihandle *ih, int x, int y)
if (iupAttribGetBoolean(ih, "MULTIPLEFILES"))
{
int i = 0;
-
+
+ char* dir = iupStrFileGetPath(openfilename.lpstrFile); /* the first part is the directory already */
+ iupAttribStoreStr(ih, "DIRECTORY", dir);
+ free(dir);
+
/* If there is more than one file, replace terminator by the separator */
- if (openfilename.lpstrFile && openfilename.lpstrFile[openfilename.nFileOffset-1] == 0 && openfilename.nFileOffset>0)
+ if (openfilename.lpstrFile[openfilename.nFileOffset-1] == 0 &&
+ openfilename.nFileOffset>0)
{
while (openfilename.lpstrFile[i] != 0 || openfilename.lpstrFile[i+1] != 0)
{
@@ -534,12 +568,16 @@ static int winFileDlgPopup(Ihandle *ih, int x, int y)
}
iupAttribSetStr(ih, "STATUS", "0");
- iupAttribSetStr(ih, "FILEEXIST", NULL);
+ iupAttribSetStr(ih, "FILEEXIST", "YES");
}
else
{
if (iupdrvIsFile(openfilename.lpstrFile)) /* check if file exists */
{
+ char* dir = iupStrFileGetPath(openfilename.lpstrFile);
+ iupAttribStoreStr(ih, "DIRECTORY", dir);
+ free(dir);
+
iupAttribSetStr(ih, "FILEEXIST", "YES");
iupAttribSetStr(ih, "STATUS", "0");
}
diff --git a/iup/src/win/iupwin_focus.c b/iup/src/win/iupwin_focus.c
index 63da02d..2328dea 100755
--- a/iup/src/win/iupwin_focus.c
+++ b/iup/src/win/iupwin_focus.c
@@ -32,7 +32,7 @@
/* Since Windows XP, the focus feedback only appears after the user press a key.
Except for the IupText where the feedback is the caret.
- Before that if you click in a control the focus feedback will be hidden.
+ Before a key is pressed if you click in a control the focus feedback will be hidden.
We manually send WM_CHANGEUISTATE because we do not use IsDialogMessage anymore,
and the focus feedback was not shown even after the used press a key.
@@ -43,19 +43,28 @@
void iupdrvSetFocus(Ihandle *ih)
{
SetFocus(ih->handle);
- SendMessage(ih->handle, WM_CHANGEUISTATE, UIS_CLEAR|UISF_HIDEFOCUS, 0);
+
+ /* See comments above */
+ SendMessage(ih->handle, WM_CHANGEUISTATE, UIS_CLEAR|UISF_HIDEFOCUS, 0); /* clear+hidefocus=showfocus */
}
void iupwinWmSetFocus(Ihandle *ih)
{
Ihandle* dialog = IupGetDialog(ih);
if (ih != dialog)
- iupAttribSetStr(dialog, "_IUPWIN_LASTFOCUS", (char*)ih); /* used by IupMenu */
+ iupAttribSetStr(dialog, "_IUPWIN_LASTFOCUS", (char*)ih); /* used by IupMenu and here. */
else
{
/* if a control inside that dialog had the focus, then reset to it when the dialog gets the focus */
Ihandle* lastfocus = (Ihandle*)iupAttribGet(dialog, "_IUPWIN_LASTFOCUS");
- if (lastfocus) IupSetFocus(lastfocus);
+ if (lastfocus)
+ {
+ /* call the callback and update current focus before changing it again */
+ iupCallGetFocusCb(ih);
+
+ IupSetFocus(lastfocus);
+ return;
+ }
}
iupCallGetFocusCb(ih);
diff --git a/iup/src/win/iupwin_font.c b/iup/src/win/iupwin_font.c
index 659e2d9..c10befb 100755
--- a/iup/src/win/iupwin_font.c
+++ b/iup/src/win/iupwin_font.c
@@ -70,7 +70,7 @@ static IwinFont* winFindFont(const char *standardfont)
if (height < 0)
height_pixels = height; /* already in pixels */
else
- height_pixels = -IUPWIN_PT2PIXEL(height, res);
+ height_pixels = -iupWIN_PT2PIXEL(height, res);
if (height_pixels == 0)
return NULL;
@@ -119,7 +119,7 @@ static void winFontFromLogFont(LOGFONT* logfont, char * font)
int is_strikeout = logfont->lfStrikeOut;
int height_pixels = logfont->lfHeight; /* negative value */
int res = iupwinGetScreenRes();
- int height = IUPWIN_PIXEL2PT(-height_pixels, res); /* return in points */
+ int height = iupWIN_PIXEL2PT(-height_pixels, res); /* return in points */
sprintf(font, "%s, %s%s%s%s %d", logfont->lfFaceName,
is_bold?"Bold ":"",
diff --git a/iup/src/win/iupwin_fontdlg.c b/iup/src/win/iupwin_fontdlg.c
index 0602441..ce27cf2 100755
--- a/iup/src/win/iupwin_fontdlg.c
+++ b/iup/src/win/iupwin_fontdlg.c
@@ -68,7 +68,7 @@ static int winFontDlgPopup(Ihandle* ih, int x, int y)
standardfont = iupAttribGet(ih, "VALUE");
if (!standardfont)
- return IUP_ERROR;
+ standardfont = IupGetGlobal("DEFAULTFONT");
/* parse the old format first */
if (!iupFontParseWin(standardfont, typeface, &height, &is_bold, &is_italic, &is_underline, &is_strikeout))
@@ -81,7 +81,7 @@ static int winFontDlgPopup(Ihandle* ih, int x, int y)
if (height < 0)
height_pixels = height; /* already in pixels */
else
- height_pixels = -IUPWIN_PT2PIXEL(height, res);
+ height_pixels = -iupWIN_PT2PIXEL(height, res);
if (height_pixels == 0)
return IUP_ERROR;
@@ -134,7 +134,7 @@ static int winFontDlgPopup(Ihandle* ih, int x, int y)
if (height < 0) /* not an error, use old value as a reference for the units */
height = height_pixels; /* return in pixels */
else
- height = IUPWIN_PIXEL2PT(-height_pixels, res); /* return in points */
+ height = iupWIN_PIXEL2PT(-height_pixels, res); /* return in points */
iupAttribSetStrf(ih, "VALUE", "%s, %s%s%s%s %d", logfont.lfFaceName,
is_bold?"Bold ":"",
diff --git a/iup/src/win/iupwin_frame.c b/iup/src/win/iupwin_frame.c
index 0949b5d..3f56aed 100755
--- a/iup/src/win/iupwin_frame.c
+++ b/iup/src/win/iupwin_frame.c
@@ -47,6 +47,27 @@ void iupdrvFrameGetDecorOffset(Ihandle* ih, int *x, int *y)
}
}
+static char* winFrameGetBgColorAttrib(Ihandle* ih)
+{
+ if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR"))
+ return NULL;
+ else
+ return iupBaseNativeParentGetBgColorAttrib(ih);
+}
+
+static int winFrameSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+ (void)value;
+
+ if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR"))
+ {
+ IupUpdate(ih); /* post a redraw */
+ return 1;
+ }
+ else
+ return 0;
+}
+
static void winFrameDrawText(HDC hDC, const char* text, int x, int y, COLORREF fgcolor)
{
COLORREF oldcolor;
@@ -126,6 +147,16 @@ static void winFrameDrawItem(Ihandle* ih, DRAWITEMSTRUCT *drawitem)
DrawEdge(hDC, &drawitem->rcItem, EDGE_SUNKEN, BF_RECT);
else
DrawEdge(hDC, &drawitem->rcItem, EDGE_ETCHED, BF_RECT);
+
+ if (iupAttribGet(ih, "_IUPFRAME_HAS_BGCOLOR"))
+ {
+ unsigned char r=0, g=0, b=0;
+ char* color = iupAttribGetStr(ih, "BGCOLOR");
+ iupStrToRGB(color, &r, &g, &b);
+ SetDCBrushColor(hDC, RGB(r,g,b));
+ InflateRect(&drawitem->rcItem, -2, -2);
+ FillRect(hDC, &drawitem->rcItem, (HBRUSH)GetStockObject(DC_BRUSH));
+ }
}
iupwinDrawDestroyBitmapDC(&bmpDC);
@@ -169,11 +200,13 @@ static int winFrameMapMethod(Ihandle* ih)
title = iupAttribGet(ih, "TITLE");
if (title)
iupAttribSetStr(ih, "_IUPFRAME_HAS_TITLE", "1");
-
- if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED"))
- dwExStyle |= WS_EX_COMPOSITED;
else
- dwStyle |= WS_CLIPCHILDREN;
+ {
+ if (iupAttribGet(ih, "BGCOLOR"))
+ iupAttribSetStr(ih, "_IUPFRAME_HAS_BGCOLOR", "1");
+ }
+
+ iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);
if (!iupwinCreateWindowEx(ih, "BUTTON", dwExStyle, dwStyle))
return IUP_ERROR;
@@ -195,7 +228,7 @@ void iupdrvFrameInitClass(Iclass* ic)
/* Driver Dependent Attribute functions */
/* Visual */
- iupClassRegisterAttribute(ic, "BGCOLOR", iupBaseNativeParentGetBgColorAttrib, NULL, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+ iupClassRegisterAttribute(ic, "BGCOLOR", winFrameGetBgColorAttrib, winFrameSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
/* Special */
iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_NOT_MAPPED);
diff --git a/iup/src/win/iupwin_globalattrib.c b/iup/src/win/iupwin_globalattrib.c
index a176925..bcd6355 100755
--- a/iup/src/win/iupwin_globalattrib.c
+++ b/iup/src/win/iupwin_globalattrib.c
@@ -148,6 +148,11 @@ int iupdrvSetGlobal(const char *name, const char *value)
winGlobalSendKey(key, 0x03);
return 0;
}
+ if (iupStrEqual(name, "DLL_HINSTANCE"))
+ {
+ iupwin_dll_hinstance = (HINSTANCE)value;
+ return 0;
+ }
return 1;
}
@@ -239,5 +244,7 @@ char *iupdrvGetGlobal(const char *name)
return "YES";
return "NO";
}
+ if (iupStrEqual(name, "DLL_HINSTANCE"))
+ return (char*)iupwin_dll_hinstance;
return NULL;
}
diff --git a/iup/src/win/iupwin_info.c b/iup/src/win/iupwin_info.c
index 8ea7dd4..4d57289 100755
--- a/iup/src/win/iupwin_info.c
+++ b/iup/src/win/iupwin_info.c
@@ -18,7 +18,7 @@
#include "iupwin_info.h"
-int iupwinIsVista(void)
+int iupwinIsVistaOrNew(void)
{
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
diff --git a/iup/src/win/iupwin_info.h b/iup/src/win/iupwin_info.h
index d39bae0..8d461fb 100755
--- a/iup/src/win/iupwin_info.h
+++ b/iup/src/win/iupwin_info.h
@@ -16,7 +16,7 @@ int iupwinGetSystemMajorVersion(void);
int iupwinGetComCtl32Version(void);
char* iupwinGetSystemLanguage(void);
int iupwinIsAppThemed(void);
-int iupwinIsVista(void);
+int iupwinIsVistaOrNew(void);
/* color */
void iupwinGetSysColor(char* color, int wincolor);
diff --git a/iup/src/win/iupwin_key.c b/iup/src/win/iupwin_key.c
index 921ed94..899e837 100755
--- a/iup/src/win/iupwin_key.c
+++ b/iup/src/win/iupwin_key.c
@@ -317,32 +317,32 @@ int iupwinKeyEvent(Ihandle* ih, int wincode, int press)
void iupwinButtonKeySetStatus(WORD keys, char* status, int doubleclick)
{
if (keys & MK_SHIFT)
- iupKEYSETSHIFT(status);
+ iupKEY_SETSHIFT(status);
if (keys & MK_CONTROL)
- iupKEYSETCONTROL(status);
+ iupKEY_SETCONTROL(status);
if (keys & MK_LBUTTON)
- iupKEYSETBUTTON1(status);
+ iupKEY_SETBUTTON1(status);
if (keys & MK_MBUTTON)
- iupKEYSETBUTTON2(status);
+ iupKEY_SETBUTTON2(status);
if (keys & MK_RBUTTON)
- iupKEYSETBUTTON3(status);
+ iupKEY_SETBUTTON3(status);
if (doubleclick)
- iupKEYSETDOUBLE(status);
+ iupKEY_SETDOUBLE(status);
if (GetKeyState(VK_MENU) & 0x8000)
- iupKEYSETALT(status);
+ iupKEY_SETALT(status);
if ((GetKeyState(VK_LWIN) & 0x8000) || (GetKeyState(VK_RWIN) & 0x8000))
- iupKEYSETSYS(status);
+ iupKEY_SETSYS(status);
if (keys & MK_XBUTTON1)
- iupKEYSETBUTTON4(status);
+ iupKEY_SETBUTTON4(status);
if (keys & MK_XBUTTON2)
- iupKEYSETBUTTON5(status);
+ iupKEY_SETBUTTON5(status);
}
diff --git a/iup/src/win/iupwin_label.c b/iup/src/win/iupwin_label.c
index d5a1f53..95dd10c 100755
--- a/iup/src/win/iupwin_label.c
+++ b/iup/src/win/iupwin_label.c
@@ -173,7 +173,7 @@ static int winLabelSetAlignmentAttrib(Ihandle* ih, const char* value)
else /* "ATOP" */
ih->data->vert_alignment = IUP_ALIGN_ATOP;
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
return 0;
}
@@ -197,7 +197,7 @@ static int winLabelSetPaddingAttrib(Ihandle* ih, const char* value)
iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
if (ih->handle && ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
return 0;
}
@@ -211,7 +211,7 @@ static int winLabelSetWordWrapAttrib(Ihandle* ih, const char* value)
else
ih->data->text_style &= ~DT_WORDBREAK;
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
return 1;
@@ -226,7 +226,7 @@ static int winLabelSetEllipsisAttrib(Ihandle* ih, const char* value)
else
ih->data->text_style &= ~DT_END_ELLIPSIS;
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
return 1;
@@ -240,12 +240,24 @@ static int winLabelSetFgColorAttrib(Ihandle* ih, const char* value)
if (iupStrToRGB(value, &r, &g, &b))
{
ih->data->fgcolor = RGB(r,g,b);
- iupdrvDisplayRedraw(ih);
+
+ if (ih->handle)
+ iupdrvRedrawNow(ih);
}
}
return 1;
}
+static int winLabelSetUpdateAttrib(Ihandle* ih, const char* value)
+{
+ (void)value;
+
+ if (ih->handle)
+ iupdrvPostRedraw(ih); /* Post a redraw */
+
+ return 1;
+}
+
static int winLabelProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result)
{
switch (msg)
@@ -257,6 +269,7 @@ static int winLabelProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *re
*result = WVR_HREDRAW|WVR_VREDRAW;
return 1;
}
+ break;
}
}
@@ -266,7 +279,7 @@ static int winLabelProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *re
static int winLabelMapMethod(Ihandle* ih)
{
char* value;
- DWORD dwStyle = WS_CHILD |
+ DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS |
SS_NOTIFY; /* SS_NOTIFY is necessary because of the base messages */
if (!ih->parent)
@@ -330,7 +343,7 @@ void iupdrvLabelInitClass(Iclass* ic)
/* IupLabel only */
iupClassRegisterAttribute(ic, "ALIGNMENT", winLabelGetAlignmentAttrib, winLabelSetAlignmentAttrib, IUPAF_SAMEASSYSTEM, "ALEFT:ACENTER", IUPAF_NO_INHERIT);
- iupClassRegisterAttribute(ic, "IMAGE", NULL, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "IMAGE", NULL, winLabelSetUpdateAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "PADDING", iupLabelGetPaddingAttrib, winLabelSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
/* IupLabel Windows and GTK only */
diff --git a/iup/src/win/iupwin_list.c b/iup/src/win/iupwin_list.c
index 8fdadb6..cb510b5 100755
--- a/iup/src/win/iupwin_list.c
+++ b/iup/src/win/iupwin_list.c
@@ -154,6 +154,8 @@ void iupdrvListInsertItem(Ihandle* ih, int pos, const char* value)
SendMessage(ih->handle, WIN_INSERTSTRING(ih), pos, (LPARAM)value);
SendMessage(ih->handle, WIN_SETITEMDATA(ih), pos, (LPARAM)iupdrvFontGetStringWidth(ih, value));
winListUpdateScrollWidth(ih);
+
+ iupListUpdateOldValue(ih, pos, 0);
}
void iupdrvListRemoveItem(Ihandle* ih, int pos)
@@ -164,8 +166,14 @@ void iupdrvListRemoveItem(Ihandle* ih, int pos)
int curpos = SendMessage(ih->handle, WIN_GETCURSEL(ih), 0, 0);
if (pos == curpos)
{
- if (curpos > 0) curpos--;
- else curpos++;
+ if (curpos > 0)
+ curpos--;
+ else
+ {
+ curpos=1;
+ if (iupdrvListGetCount(ih)==1)
+ curpos = -1; /* remove the selection */
+ }
SendMessage(ih->handle, WIN_SETCURSEL(ih), curpos, 0);
}
@@ -173,6 +181,8 @@ void iupdrvListRemoveItem(Ihandle* ih, int pos)
SendMessage(ih->handle, WIN_DELETESTRING(ih), pos, 0L);
winListUpdateScrollWidth(ih);
+
+ iupListUpdateOldValue(ih, pos, 1);
}
void iupdrvListRemoveAllItems(Ihandle* ih)
@@ -220,18 +230,29 @@ static void winListUpdateItemWidth(Ihandle* ih)
}
}
+static int winListSetBgColorAttrib(Ihandle *ih, const char *value)
+{
+ (void)value;
+ if (ih->handle)
+ iupdrvPostRedraw(ih);
+ return 1;
+}
+
static int winListSetStandardFontAttrib(Ihandle* ih, const char* value)
{
iupdrvSetStandardFontAttrib(ih, value);
- winListUpdateItemWidth(ih);
- winListUpdateScrollWidth(ih);
+ if (ih->handle)
+ {
+ winListUpdateItemWidth(ih);
+ winListUpdateScrollWidth(ih);
+ }
return 1;
}
static char* winListGetIdValueAttrib(Ihandle* ih, const char* name_id)
{
int pos = iupListGetPos(ih, name_id);
- if (pos != -1)
+ if (pos >= 0)
{
int len = SendMessage(ih->handle, WIN_GETTEXTLEN(ih), (WPARAM)pos, 0);
char* str = iupStrGetMemory(len+1);
@@ -514,8 +535,10 @@ static int winListSetNCAttrib(Ihandle* ih, const char* value)
{
HWND cbedit = (HWND)iupAttribGet(ih, "_IUPWIN_EDITBOX");
SendMessage(cbedit, EM_LIMITTEXT, ih->data->nc, 0L);
+ return 0;
}
- return 0;
+ else
+ return 1; /* store until not mapped, when mapped will be set again */
}
static int winListSetSelectionAttrib(Ihandle* ih, const char* value)
@@ -995,13 +1018,27 @@ static int winListEditProc(Ihandle* ih, HWND cbedit, UINT msg, WPARAM wp, LPARAM
if (msg==WM_KEYDOWN) /* process K_ANY before text callbacks */
{
ret = iupwinBaseProc(ih, msg, wp, lp, result);
- if (ret) return 1;
+ if (ret)
+ {
+ iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", "1");
+ *result = 0;
+ return 1;
+ }
+ else
+ iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL);
}
switch (msg)
{
case WM_CHAR:
{
+ if (iupAttribGet(ih, "_IUPWIN_IGNORE_CHAR"))
+ {
+ iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL);
+ *result = 0;
+ return 1;
+ }
+
if ((char)wp == '\b')
{
if (!winListCallEditCb(ih, cbedit, NULL, 0, -1))
@@ -1301,7 +1338,7 @@ static void winListLayoutUpdateMethod(Ihandle *ih)
static int winListMapMethod(Ihandle* ih)
{
char* class_name;
- DWORD dwStyle = WS_CHILD,
+ DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,
dwExStyle = WS_EX_CLIENTEDGE;
if (!ih->parent)
@@ -1426,7 +1463,7 @@ void iupdrvListInitClass(Iclass* ic)
iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, winListSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NOT_MAPPED);
/* Visual */
- iupClassRegisterAttribute(ic, "BGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_NOT_MAPPED);
+ iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winListSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_NOT_MAPPED);
/* Special */
iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "TXTFGCOLOR", IUPAF_NOT_MAPPED);
diff --git a/iup/src/win/iupwin_loop.c b/iup/src/win/iupwin_loop.c
index 7c5dbe7..fd25537 100755
--- a/iup/src/win/iupwin_loop.c
+++ b/iup/src/win/iupwin_loop.c
@@ -106,6 +106,18 @@ int IupMainLoop(void)
return IUP_NOERROR;
}
+int IupLoopStepWait(void)
+{
+ MSG msg;
+ int ret = GetMessage(&msg, NULL, 0, 0);
+ if (ret == -1) /* error */
+ return IUP_ERROR;
+ if (ret == 0 || /* WM_QUIT */
+ winLoopProcessMessage(&msg) == IUP_CLOSE) /* ret != 0 */
+ return IUP_CLOSE;
+ return IUP_DEFAULT;
+}
+
int IupLoopStep(void)
{
MSG msg;
diff --git a/iup/src/win/iupwin_menu.c b/iup/src/win/iupwin_menu.c
index 74a8b52..06ad93e 100755
--- a/iup/src/win/iupwin_menu.c
+++ b/iup/src/win/iupwin_menu.c
@@ -385,7 +385,10 @@ static int winMenuMapMethod(Ihandle* ih)
static void winMenuUnMapMethod(Ihandle* ih)
{
if (iupMenuIsMenuBar(ih))
+ {
SetMenu(ih->parent->handle, NULL);
+ ih->parent = NULL;
+ }
DestroyMenu((HMENU)ih->handle); /* DestroyMenu is recursive */
}
diff --git a/iup/src/win/iupwin_open.c b/iup/src/win/iupwin_open.c
index 7357cde..3629ce4 100755
--- a/iup/src/win/iupwin_open.c
+++ b/iup/src/win/iupwin_open.c
@@ -76,8 +76,9 @@ int iupdrvOpen(int *argc, char ***argv)
iupwin_hinstance = GetModuleHandle(NULL);
IupSetGlobal("HINSTANCE", (char*)iupwin_hinstance);
}
-
- CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+
+ if (CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)==RPC_E_CHANGED_MODE)
+ IupSetGlobal("_IUPWIN_COINIT_MULTITHREADED", "1");
{
INITCOMMONCONTROLSEX InitCtrls;
diff --git a/iup/src/win/iupwin_progressbar.c b/iup/src/win/iupwin_progressbar.c
index 9038d79..4a52cc4 100755
--- a/iup/src/win/iupwin_progressbar.c
+++ b/iup/src/win/iupwin_progressbar.c
@@ -106,7 +106,7 @@ static int winProgressBarSetFgColorAttrib(Ihandle* ih, const char* value)
static int winProgressBarMapMethod(Ihandle* ih)
{
- DWORD dwStyle = WS_CHILD;
+ DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS;
if (!ih->parent)
return IUP_ERROR;
diff --git a/iup/src/win/iupwin_tabs.c b/iup/src/win/iupwin_tabs.c
index 682f451..b39f7fe 100755
--- a/iup/src/win/iupwin_tabs.c
+++ b/iup/src/win/iupwin_tabs.c
@@ -232,10 +232,7 @@ static HWND winTabCreatePageWindow(Ihandle* ih)
DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,
dwExStyle = 0;
- if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED"))
- dwExStyle |= WS_EX_COMPOSITED;
- else
- dwStyle |= WS_CLIPCHILDREN;
+ iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);
hWnd = CreateWindowEx(dwExStyle, "IupTabsPage", NULL, dwStyle,
0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
@@ -255,9 +252,12 @@ static int winTabsSetPaddingAttrib(Ihandle* ih, const char* value)
iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
if (ih->handle)
+ {
SendMessage(ih->handle, TCM_SETPADDING, 0, MAKELPARAM(ih->data->horiz_padding, ih->data->vert_padding));
-
- return 0;
+ return 0;
+ }
+ else
+ return 1; /* store until not mapped, when mapped will be set again */
}
static int winTabsSetMultilineAttrib(Ihandle* ih, const char* value)
@@ -368,6 +368,13 @@ static char* winTabsGetBgColorAttrib(Ihandle* ih)
return IupGetGlobal("DLGBGCOLOR");
}
+static int winTabsSetBgColorAttrib(Ihandle *ih, const char *value)
+{
+ (void)value;
+ iupdrvPostRedraw(ih);
+ return 1;
+}
+
/* ------------------------------------------------------------------------- */
/* winTabs - Calls the user callback to change of tab */
@@ -397,6 +404,7 @@ static int winTabsWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
int prev_pos = SendMessage(ih->handle, TCM_GETCURSEL, 0, 0);
iupAttribSetInt(ih, "_IUPTABS_PREV_CHILD_POS", prev_pos);
+ /* save the previous handle if callback exists */
if (cb)
{
Ihandle* prev_child = IupGetChild(ih, prev_pos);
@@ -420,7 +428,9 @@ static int winTabsWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
Ihandle* prev_child = (Ihandle*)iupAttribGet(ih, "_IUPTABS_PREV_CHILD");
iupAttribSetStr(ih, "_IUPTABS_PREV_CHILD", NULL);
- cb(ih, child, prev_child);
+ /* avoid duplicate calls when a Tab is inside another Tab. */
+ if (prev_child)
+ cb(ih, child, prev_child);
}
}
@@ -522,7 +532,7 @@ static void winTabsChildAddedMethod(Ihandle* ih, Ihandle* child)
}
}
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
}
}
@@ -535,12 +545,11 @@ static void winTabsChildRemovedMethod(Ihandle* ih, Ihandle* child)
if (tab_page)
{
int pos = winTabsGetPageWindowPos(ih, tab_page);
+ iupTabsTestRemoveTab(ih, pos);
+
SendMessage(ih->handle, TCM_DELETEITEM, pos, 0);
DestroyWindow(tab_page);
- if (pos==0) pos++;
- iupdrvTabsSetCurrentTab(ih, pos-1);
-
iupAttribSetStr(child, "_IUPTAB_CONTAINER", NULL);
}
}
@@ -564,19 +573,14 @@ static int winTabsMapMethod(Ihandle* ih)
if (ih->data->is_multiline)
dwStyle |= TCS_MULTILINE;
- if (iupAttribGetBoolean(IupGetDialog(ih), "COMPOSITED"))
- {
- dwExStyle |= WS_EX_COMPOSITED;
+ iupwinGetNativeParentStyle(ih, &dwExStyle, &dwStyle);
- if (!ih->data->is_multiline && iupwinIsVista())
- {
- /* workaround for composite bug in Vista */
- ih->data->is_multiline = 1;
- dwStyle |= TCS_MULTILINE;
- }
+ if (dwExStyle & WS_EX_COMPOSITED && !ih->data->is_multiline && iupwinIsVistaOrNew())
+ {
+ /* workaround for composite bug in Vista */
+ ih->data->is_multiline = 1;
+ dwStyle |= TCS_MULTILINE;
}
- else
- dwStyle |= WS_CLIPCHILDREN;
if (!iupwinCreateWindowEx(ih, WC_TABCONTROL, dwExStyle, dwStyle))
return IUP_ERROR;
@@ -665,7 +669,7 @@ void iupdrvTabsInitClass(Iclass* ic)
/* Driver Dependent Attribute functions */
/* Visual */
- iupClassRegisterAttribute(ic, "BGCOLOR", winTabsGetBgColorAttrib, NULL, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+ iupClassRegisterAttribute(ic, "BGCOLOR", winTabsGetBgColorAttrib, winTabsSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
/* Special */
iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "DLGFGCOLOR", IUPAF_NOT_MAPPED);
@@ -676,5 +680,9 @@ void iupdrvTabsInitClass(Iclass* ic)
iupClassRegisterAttribute(ic, "MULTILINE", winTabsGetMultilineAttrib, winTabsSetMultilineAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "TABTITLE", NULL, winTabsSetTabTitleAttrib, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "TABIMAGE", NULL, winTabsSetTabImageAttrib, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
- iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, winTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+ iupClassRegisterAttribute(ic, "PADDING", iupTabsGetPaddingAttrib, winTabsSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+ /* necessary because transparent background does not work when not using visual styles */
+ if (!iupwin_comctl32ver6) /* Used by iupdrvImageCreateImage */
+ iupClassRegisterAttribute(ic, "FLAT_ALPHA", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
}
diff --git a/iup/src/win/iupwin_text.c b/iup/src/win/iupwin_text.c
index dfe489a..2a61724 100755
--- a/iup/src/win/iupwin_text.c
+++ b/iup/src/win/iupwin_text.c
@@ -432,8 +432,8 @@ static int winTextSetLinColToPosition(Ihandle *ih, int lin, int col)
col--;
linmax = SendMessage(ih->handle, EM_GETLINECOUNT, 0, 0L);
- if (lin > linmax)
- lin = linmax;
+ if (lin > linmax-1)
+ lin = linmax-1;
lineindex = SendMessage(ih->handle, EM_LINEINDEX, (WPARAM)lin, 0L);
@@ -639,8 +639,12 @@ static int winTextSetPaddingAttrib(Ihandle* ih, const char* value)
iupStrToIntInt(value, &(ih->data->horiz_padding), &(ih->data->vert_padding), 'x');
ih->data->vert_padding = 0;
if (ih->handle)
+ {
SendMessage(ih->handle, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELPARAM(ih->data->horiz_padding, ih->data->horiz_padding));
- return 0;
+ return 0;
+ }
+ else
+ return 1; /* store until not mapped, when mapped will be set again */
}
static int winTextSetSelectedTextAttrib(Ihandle* ih, const char* value)
@@ -713,8 +717,11 @@ static int winTextSetNCAttrib(Ihandle* ih, const char* value)
SendMessage(ih->handle, EM_EXLIMITTEXT, 0, ih->data->nc); /* so it can be larger than 64k */
else
SendMessage(ih->handle, EM_LIMITTEXT, ih->data->nc, 0L);
+
+ return 0;
}
- return 0;
+ else
+ return 1; /* store until not mapped, when mapped will be set again */
}
static int winTextSetSelectionAttrib(Ihandle* ih, const char* value)
@@ -845,7 +852,7 @@ static char* winTextGetSelectionPosAttrib(Ihandle* ih)
static int winTextSetInsertAttrib(Ihandle* ih, const char* value)
{
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
if (value)
{
@@ -867,9 +874,9 @@ static int winTextSetInsertAttrib(Ihandle* ih, const char* value)
static int winTextSetAppendAttrib(Ihandle* ih, const char* value)
{
- int len;
+ int pos;
char* str;
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
if (!value) value = "";
str = (char*)value;
@@ -881,9 +888,9 @@ static int winTextSetAppendAttrib(Ihandle* ih, const char* value)
str = iupStrToDos(str);
}
- len = GetWindowTextLength(ih->handle)+1;
- SendMessage(ih->handle, EM_SETSEL, (WPARAM)len, (LPARAM)len);
- if (ih->data->is_multiline && ih->data->append_newline)
+ pos = GetWindowTextLength(ih->handle)+1;
+ SendMessage(ih->handle, EM_SETSEL, (WPARAM)pos, (LPARAM)pos);
+ if (ih->data->is_multiline && ih->data->append_newline && pos!=1)
{
if (ih->data->has_formatting)
SendMessage(ih->handle, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)"\r");
@@ -920,7 +927,7 @@ static int winTextSetTabSizeAttrib(Ihandle* ih, const char* value)
iupStrToInt(value, &tabsize);
tabsize *= 4;
SendMessage(ih->handle, EM_SETTABSTOPS, (WPARAM)1L, (LPARAM)&tabsize);
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
return 1;
}
@@ -1120,6 +1127,7 @@ static int winTextSetBgColorAttrib(Ihandle *ih, const char *value)
SendMessage(ih->handle, EM_SETBKGNDCOLOR, 0, (LPARAM)color);
}
}
+ iupdrvPostRedraw(ih);
return 1;
}
@@ -1529,15 +1537,27 @@ static int winTextProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
ret = iupwinBaseProc(ih, msg, wp, lp, result);
if (ret)
{
+ iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", "1");
*result = 0;
return 1;
}
+ else
+ iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL);
}
switch (msg)
{
case WM_CHAR:
{
+ /* even aborting WM_KEYDOWN, a WM_CHAR will be sent, so ignore it also */
+ /* if a dialog was shown, the loop will be processed, so ignore out of focus WM_CHAR messages */
+ if (GetFocus() != ih->handle || iupAttribGet(ih, "_IUPWIN_IGNORE_CHAR"))
+ {
+ iupAttribSetStr(ih, "_IUPWIN_IGNORE_CHAR", NULL);
+ *result = 0;
+ return 1;
+ }
+
if ((char)wp == '\b')
{
if (!winTextCallActionCb(ih, NULL, 0, -1))
@@ -1736,7 +1756,7 @@ static int winTextProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
static void winTextCreateSpin(Ihandle* ih)
{
HWND hSpin;
- DWORD dwStyle = WS_CHILD|UDS_ARROWKEYS|UDS_HOTTRACK|UDS_NOTHOUSANDS;
+ DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS|UDS_ARROWKEYS|UDS_HOTTRACK|UDS_NOTHOUSANDS;
int serial = iupDialogGetChildId(ih);
if (iupStrEqualNoCase(iupAttribGetStr(ih, "SPINALIGN"), "LEFT"))
@@ -1826,7 +1846,7 @@ static void winTextLayoutUpdateMethod(Ihandle* ih)
static int winTextMapMethod(Ihandle* ih)
{
- DWORD dwStyle = WS_CHILD,
+ DWORD dwStyle = WS_CHILD|WS_CLIPSIBLINGS,
dwExStyle = 0;
char* winclass = "EDIT", *value;
@@ -1873,7 +1893,7 @@ static int winTextMapMethod(Ihandle* ih)
}
else
{
- dwStyle |= ES_AUTOHSCROLL|ES_NOHIDESEL;
+ dwStyle |= ES_AUTOHSCROLL;
if (iupAttribGetBoolean(ih, "PASSWORD"))
dwStyle |= ES_PASSWORD;
@@ -1950,8 +1970,8 @@ void iupdrvTextInitClass(Iclass* ic)
iupClassRegisterAttribute(ic, "STANDARDFONT", NULL, winTextSetStandardFontAttrib, IUPAF_SAMEASSYSTEM, "DEFAULTFONT", IUPAF_NOT_MAPPED);
/* Overwrite Visual */
- iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winTextSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_NOT_MAPPED);
- iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, winTextSetVisibleAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winTextSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "TXTBGCOLOR", IUPAF_DEFAULT);
+ iupClassRegisterAttribute(ic, "VISIBLE", iupBaseGetVisibleAttrib, winTextSetVisibleAttrib, "YES", "NO", IUPAF_DEFAULT);
/* Special */
iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "TXTFGCOLOR", IUPAF_NOT_MAPPED); /* usually black */
diff --git a/iup/src/win/iupwin_toggle.c b/iup/src/win/iupwin_toggle.c
index fcaa438..c17f594 100755
--- a/iup/src/win/iupwin_toggle.c
+++ b/iup/src/win/iupwin_toggle.c
@@ -35,7 +35,9 @@
void iupdrvToggleAddCheckBox(int *x, int *y)
{
- (*x) += 16+6;
+ (*x) += 16+8;
+ if (!iupwin_comctl32ver6)
+ (*x) += 4;
if ((*y) < 16) (*y) = 16; /* minimum height */
}
@@ -229,7 +231,7 @@ static int winToggleSetImageAttrib(Ihandle* ih, const char* value)
iupAttribSetStr(ih, "IMAGE", (char*)value);
if (iupwin_comctl32ver6)
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
else
{
int check = SendMessage(ih->handle, BM_GETCHECK, 0L, 0L);
@@ -249,7 +251,7 @@ static int winToggleSetImInactiveAttrib(Ihandle* ih, const char* value)
iupAttribSetStr(ih, "IMINACTIVE", (char*)value);
if (iupwin_comctl32ver6)
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
else
{
int check = SendMessage(ih->handle, BM_GETCHECK, 0L, 0L);
@@ -269,7 +271,7 @@ static int winToggleSetImPressAttrib(Ihandle* ih, const char* value)
iupAttribSetStr(ih, "IMPRESS", (char*)value);
if (iupwin_comctl32ver6)
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
else
{
int check = SendMessage(ih->handle, BM_GETCHECK, 0L, 0L);
@@ -339,7 +341,7 @@ static int winToggleSetActiveAttrib(Ihandle* ih, const char* value)
if (iupwin_comctl32ver6)
{
iupBaseSetActiveAttrib(ih, value);
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
return 0;
}
else
@@ -382,11 +384,21 @@ static int winToggleSetPaddingAttrib(Ihandle* ih, const char* value)
iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
if (ih->handle && iupwin_comctl32ver6 && ih->data->type == IUP_TOGGLE_IMAGE)
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
return 0;
}
+static int winToggleSetUpdateAttrib(Ihandle* ih, const char* value)
+{
+ (void)value;
+
+ if (ih->handle)
+ iupdrvPostRedraw(ih); /* Post a redraw */
+
+ return 1;
+}
+
static int winToggleSetBgColorAttrib(Ihandle* ih, const char* value)
{
(void)value;
@@ -395,7 +407,7 @@ static int winToggleSetBgColorAttrib(Ihandle* ih, const char* value)
/* update internal image cache for controls that have the IMAGE attribute */
iupAttribSetStr(ih, "BGCOLOR", value);
iupImageUpdateParent(ih);
- iupdrvDisplayRedraw(ih);
+ iupdrvRedrawNow(ih);
}
return 1;
}
@@ -591,7 +603,7 @@ static int winToggleMapMethod(Ihandle* ih)
{
Ihandle* radio = iupRadioFindToggleParent(ih);
char* value;
- DWORD dwStyle = WS_CHILD |
+ DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS |
BS_NOTIFY; /* necessary because of the base messages */
if (!ih->parent)
@@ -673,11 +685,11 @@ void iupdrvToggleInitClass(Iclass* ic)
iupClassRegisterAttribute(ic, "BGCOLOR", winToggleGetBgColorAttrib, winToggleSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
/* Special */
- iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, "DLGFGCOLOR", NULL, IUPAF_NOT_MAPPED); /* force the new default value */
+ iupClassRegisterAttribute(ic, "FGCOLOR", NULL, winToggleSetUpdateAttrib, "DLGFGCOLOR", NULL, IUPAF_NOT_MAPPED); /* force the new default value */
iupClassRegisterAttribute(ic, "TITLE", iupdrvBaseGetTitleAttrib, winToggleSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
/* IupToggle only */
- iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, NULL, IUPAF_SAMEASSYSTEM, "ACENTER:ACENTER", IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, winToggleSetUpdateAttrib, IUPAF_SAMEASSYSTEM, "ACENTER:ACENTER", IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "IMAGE", NULL, winToggleSetImageAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "IMINACTIVE", NULL, winToggleSetImInactiveAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "IMPRESS", NULL, winToggleSetImPressAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
diff --git a/iup/src/win/iupwin_tree.c b/iup/src/win/iupwin_tree.c
index e6877dc..4a5f8be 100755
--- a/iup/src/win/iupwin_tree.c
+++ b/iup/src/win/iupwin_tree.c
@@ -31,17 +31,19 @@
#include "iupwin_draw.h"
#include "iupwin_info.h"
+
typedef struct _winTreeItemData
{
COLORREF color;
unsigned char kind;
- void* userdata;
HFONT hFont;
short image;
short image_expanded;
} winTreeItemData;
-#ifndef TVN_ITEMCHANGING /* Vista Only */
+/* Vista Only */
+
+#ifndef TVN_ITEMCHANGING
typedef struct tagNMTVITEMCHANGE {
NMHDR hdr;
UINT uChanged;
@@ -54,257 +56,125 @@ typedef struct tagNMTVITEMCHANGE {
#define TVN_ITEMCHANGINGW (TVN_FIRST-17)
#endif
-static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem);
-typedef int (*winTreeNodeFunc)(Ihandle* ih, HTREEITEM hItem, void* userdata);
-
-static int winTreeForEach(Ihandle* ih, HTREEITEM hItem, winTreeNodeFunc func, void* userdata)
-{
- HTREEITEM hItemChild;
-
- if (!hItem)
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
+#ifndef TVS_EX_DOUBLEBUFFER
+#define TVS_EX_DOUBLEBUFFER 0x0004
+#endif
- while(hItem != NULL)
- {
- if (!func(ih, hItem, userdata))
- return 0;
+#ifndef TVM_SETEXTENDEDSTYLE
+#define TVM_SETEXTENDEDSTYLE (TV_FIRST + 44)
+#endif
- hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- if (hItemChild)
- {
- /* Recursively traverse child items */
- if (!winTreeForEach(ih, hItemChild, func, userdata))
- return 0;
- }
- /* Go to next sibling item */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
- }
+static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem);
- return 1;
-}
/*****************************************************************************/
/* FINDING ITEMS */
/*****************************************************************************/
-static HTREEITEM winTreeFindNodeID(Ihandle* ih, HTREEITEM hItem, HTREEITEM hNode)
-{
- TVITEM item;
- winTreeItemData* itemData;
-
- while(hItem != NULL)
- {
- /* ID control to traverse items */
- ih->data->id_control++;
-
- /* StateID founded! */
- if(hItem == hNode)
- return hItem;
- /* Get hItem attributes */
- item.hItem = hItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- /* Check whether we have child items */
- if (itemData->kind == ITREE_BRANCH)
- {
- /* Recursively traverse child items */
- HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- hItemChild = winTreeFindNodeID(ih, hItemChild, hNode);
-
- /* StateID founded! */
- if(hItemChild)
- return hItemChild;
- }
- /* Go to next sibling item */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
- }
-
- return NULL;
+InodeHandle* iupdrvTreeGetFocusNode(Ihandle* ih)
+{
+ return (InodeHandle*)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0);
}
-static int winTreeGetNodeId(Ihandle* ih, HTREEITEM hItem)
+static HTREEITEM winTreeFindNodeXY(Ihandle* ih, int x, int y)
{
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- ih->data->id_control = -1;
- if (winTreeFindNodeID(ih, hItemRoot, hItem))
- return ih->data->id_control;
- else
- return -1;
+ TVHITTESTINFO info;
+ info.pt.x = x;
+ info.pt.y = y;
+ return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info);
}
-static HTREEITEM winTreeFindUserDataID(Ihandle* ih, HTREEITEM hItem, void* userdata)
+static HTREEITEM winTreeFindNodePointed(Ihandle* ih)
{
- TVITEM item;
- winTreeItemData* itemData;
-
- while(hItem != NULL)
- {
- /* ID control to traverse items */
- ih->data->id_control++;
-
- /* Get hItem attributes */
- item.hItem = hItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- /* userdata founded! */
- if(itemData->userdata == userdata)
- return hItem;
-
- /* Check whether we have child items */
- if (itemData->kind == ITREE_BRANCH)
- {
- /* Recursively traverse child items */
- HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- hItemChild = winTreeFindUserDataID(ih, hItemChild, userdata);
-
- /* userdata founded! */
- if (hItemChild)
- return hItemChild;
- }
-
- /* Go to next sibling item */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
- }
-
- return NULL;
+ TVHITTESTINFO info;
+ DWORD pos = GetMessagePos();
+ info.pt.x = LOWORD(pos);
+ info.pt.y = HIWORD(pos);
+ ScreenToClient(ih->handle, &info.pt);
+ return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info);
}
-static int winTreeGetUserDataId(Ihandle* ih, void* userdata)
+int iupwinGetColor(const char* value, COLORREF *color)
{
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- ih->data->id_control = -1;
- if (winTreeFindUserDataID(ih, hItemRoot, userdata))
- return ih->data->id_control;
- else
- return -1;
+ unsigned char r, g, b;
+ if (iupStrToRGB(value, &r, &g, &b))
+ {
+ *color = RGB(r,g,b);
+ return 1;
+ }
+ return 0;
}
-static HTREEITEM winTreeFindNodeFromID(Ihandle* ih, HTREEITEM hItem)
+static void winTreeChildCountRec(Ihandle* ih, HTREEITEM hItem, int *count)
{
- TVITEM item;
- winTreeItemData* itemData;
-
+ hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
while(hItem != NULL)
{
- /* ID control to traverse items */
- ih->data->id_control--;
-
- /* StateID founded! */
- if(ih->data->id_control < 0)
- return hItem;
-
- /* Get hItem attributes */
- item.hItem = hItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- /* Check whether we have child items */
- if (itemData->kind == ITREE_BRANCH)
- {
- /* Recursively traverse child items */
- HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- hItemChild = winTreeFindNodeFromID(ih, hItemChild);
+ (*count)++;
- /* StateID founded! */
- if(ih->data->id_control < 0)
- return hItemChild;
- }
+ /* go recursive to children */
+ winTreeChildCountRec(ih, hItem, count);
/* Go to next sibling item */
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
}
-
- return hItem;
}
-static HTREEITEM winTreeFindNodeFromString(Ihandle* ih, const char* name_id)
+int iupdrvTreeTotalChildCount(Ihandle* ih, HTREEITEM hItem)
{
- if (name_id[0])
- {
- HTREEITEM hRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- iupStrToInt(name_id, &ih->data->id_control);
- return winTreeFindNodeFromID(ih, hRoot);
- }
- else
- return (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0);
+ int count = 0;
+ winTreeChildCountRec(ih, hItem, &count);
+ return count;
}
-/* Recursively, find a new brother for the item
- that will have its depth changed. Returns the new brother. */
-static HTREEITEM winTreeFindNewBrother(Ihandle* ih, HTREEITEM hBrotherItem)
+static void winTreeChildRebuildCacheRec(Ihandle* ih, HTREEITEM hItem, int *id)
{
- TVITEM item;
- winTreeItemData* itemData;
-
- while(hBrotherItem != NULL)
+ hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
+ while(hItem != NULL)
{
- if(ih->data->id_control < 0)
- return hBrotherItem;
-
- item.hItem = hBrotherItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- if (itemData->kind == ITREE_BRANCH)
- {
- HTREEITEM hItemChild;
-
- ih->data->id_control--;
- hItemChild = winTreeFindNewBrother(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hBrotherItem));
+ (*id)++;
+ ih->data->node_cache[*id].node_handle = hItem;
- if(ih->data->id_control < 0)
- return hItemChild;
- }
+ /* go recursive to children */
+ winTreeChildRebuildCacheRec(ih, hItem, id);
- hBrotherItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hBrotherItem);
+ /* Go to next sibling item */
+ hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
}
-
- return hBrotherItem;
}
-static HTREEITEM winTreeFindNodePointed(Ihandle* ih)
+static void winTreeRebuildNodeCache(Ihandle* ih, int id, HTREEITEM hItem)
{
- TVHITTESTINFO info;
- DWORD pos = GetMessagePos();
- info.pt.x = LOWORD(pos);
- info.pt.y = HIWORD(pos);
-
- ScreenToClient(ih->handle, &info.pt);
-
- return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info);
+ ih->data->node_cache[id].node_handle = hItem;
+ winTreeChildRebuildCacheRec(ih, hItem, &id);
}
-int iupwinGetColor(const char* value, COLORREF *color)
-{
- unsigned char r, g, b;
- if (iupStrToRGB(value, &r, &g, &b))
- {
- *color = RGB(r,g,b);
- return 1;
- }
- return 0;
-}
/*****************************************************************************/
/* ADDING ITEMS */
/*****************************************************************************/
+
+static void winTreeExpandItem(Ihandle* ih, HTREEITEM hItem, int expand);
+
void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* title, int add)
{
- TVITEM item, tviPrevItem;
+ TVITEM item;
TVINSERTSTRUCT tvins;
- HTREEITEM hPrevItem = winTreeFindNodeFromString(ih, name_id);
- int kindPrev;
+ HTREEITEM hPrevItem = iupTreeGetNodeFromString(ih, name_id);
+ HTREEITEM hItemNew;
winTreeItemData* itemData;
if (!hPrevItem)
- return;
+ {
+ /* check if the root was really specified */
+ int id = 0;
+ if (!iupStrToInt(name_id, &id) || id != -1)
+ return;
+ }
+
+ if (!title)
+ title = "";
itemData = calloc(1, sizeof(winTreeItemData));
itemData->image = -1;
@@ -318,83 +188,71 @@ void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* t
iupwinGetColor(iupAttribGetStr(ih, "FGCOLOR"), &itemData->color);
if (kind == ITREE_BRANCH)
- {
item.iSelectedImage = item.iImage = (int)ih->data->def_image_collapsed;
-
- if (ih->data->add_expanded)
- {
- item.mask |= TVIF_STATE;
- item.state = item.stateMask = TVIS_EXPANDED;
- item.iSelectedImage = item.iImage = (int)ih->data->def_image_expanded;
- }
- }
else
item.iSelectedImage = item.iImage = (int)ih->data->def_image_leaf;
/* Save the heading level in the node's application-defined data area */
tvins.item = item;
- /* get the KIND attribute of node selected */
- tviPrevItem.hItem = hPrevItem;
- tviPrevItem.mask = TVIF_PARAM|TVIF_CHILDREN;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&tviPrevItem);
- kindPrev = ((winTreeItemData*)tviPrevItem.lParam)->kind;
-
- /* Define the parent and the position to the new node inside
- the list, using the KIND attribute of node selected */
- if (kindPrev == ITREE_BRANCH && add)
- {
- tvins.hParent = hPrevItem;
- tvins.hInsertAfter = TVI_FIRST; /* insert the new node after item selected, as first child */
- }
- else
- {
- tvins.hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hPrevItem);
- tvins.hInsertAfter = hPrevItem; /* insert the new node after item selected */
- }
-
- /* Add the node to the tree-view control */
- SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
-
- if (kindPrev == ITREE_BRANCH && tviPrevItem.cChildren==0)
+ if (hPrevItem)
{
- /* this is the first child, redraw to update the '+'/'-' buttons */
- iupdrvDisplayRedraw(ih);
- }
-}
+ int kindPrev;
+ TVITEM tviPrevItem;
-static void winTreeAddRootNode(Ihandle* ih)
-{
- TVITEM item;
- TVINSERTSTRUCT tvins;
- HTREEITEM hNewItem;
- winTreeItemData* itemData;
+ /* get the KIND attribute of reference node */
+ tviPrevItem.hItem = hPrevItem;
+ tviPrevItem.mask = TVIF_PARAM|TVIF_CHILDREN;
+ SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&tviPrevItem);
+ kindPrev = ((winTreeItemData*)tviPrevItem.lParam)->kind;
- itemData = calloc(1, sizeof(winTreeItemData));
- itemData->image = -1;
- itemData->image_expanded = -1;
- itemData->kind = ITREE_BRANCH;
+ /* Define the parent and the position to the new node inside
+ the list, using the KIND attribute of reference node */
+ if (kindPrev == ITREE_BRANCH && add)
+ {
+ /* depth+1 */
+ tvins.hParent = hPrevItem;
+ tvins.hInsertAfter = TVI_FIRST; /* insert the new node after the reference node, as first child */
+ }
+ else
+ {
+ /* same depth */
+ tvins.hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hPrevItem);
+ tvins.hInsertAfter = hPrevItem; /* insert the new node after reference node */
+ }
- item.mask = TVIF_PARAM | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- item.state = item.stateMask = TVIS_EXPANDED;
- item.iSelectedImage = item.iImage = (int)ih->data->def_image_expanded;
- item.lParam = (LPARAM)itemData;
+ /* Add the new node */
+ hItemNew = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
+ iupTreeAddToCache(ih, add, kindPrev, hPrevItem, hItemNew);
- iupwinGetColor(iupAttribGetStr(ih, "FGCOLOR"), &itemData->color);
+ if (kindPrev == ITREE_BRANCH && tviPrevItem.cChildren==0) /* was 0, now is 1 */
+ {
+ /* this is the first child, redraw to update the '+'/'-' buttons */
+ if (ih->data->add_expanded)
+ winTreeExpandItem(ih, hPrevItem, 1);
+ else
+ winTreeExpandItem(ih, hPrevItem, 0);
+ }
- /* Save the heading level in the node's application-defined data area */
- tvins.item = item;
- tvins.hInsertAfter = TVI_FIRST;
- tvins.hParent = TVI_ROOT;
+ }
+ else
+ {
+ tvins.hInsertAfter = TVI_FIRST;
+ tvins.hParent = TVI_ROOT;
- /* Add the node to the tree-view control */
- hNewItem = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
+ /* Add the new node */
+ hItemNew = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
+ iupTreeAddToCache(ih, 0, 0, NULL, hItemNew);
- /* MarkStart node */
- iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)hNewItem);
+ if (ih->data->node_count == 1)
+ {
+ /* MarkStart node */
+ iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)hItemNew);
- /* Set the default VALUE */
- winTreeSetFocusNode(ih, hNewItem);
+ /* Set the default VALUE */
+ winTreeSetFocusNode(ih, hItemNew);
+ }
+ }
}
static int winTreeIsItemExpanded(Ihandle* ih, HTREEITEM hItem)
@@ -408,13 +266,28 @@ static int winTreeIsItemExpanded(Ihandle* ih, HTREEITEM hItem)
static void winTreeExpandItem(Ihandle* ih, HTREEITEM hItem, int expand)
{
- if (expand == -1)
- expand = !winTreeIsItemExpanded(ih, hItem); /* toggle */
+ TVITEM item;
+ winTreeItemData* itemData;
+
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", "1");
+ /* it only works if the branch has children */
+ SendMessage(ih->handle, TVM_EXPAND, expand? TVE_EXPAND: TVE_COLLAPSE, (LPARAM)hItem);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", NULL);
+
+ /* update image */
+ item.hItem = hItem;
+ item.mask = TVIF_HANDLE|TVIF_PARAM;
+ SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
+ itemData = (winTreeItemData*)item.lParam;
if (expand)
- SendMessage(ih->handle, TVM_EXPAND, TVE_EXPAND, (LPARAM)hItem);
+ item.iSelectedImage = item.iImage = (itemData->image_expanded!=-1)? itemData->image_expanded: (int)ih->data->def_image_expanded;
else
- SendMessage(ih->handle, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hItem);
+ item.iSelectedImage = item.iImage = (itemData->image!=-1)? itemData->image: (int)ih->data->def_image_collapsed;
+
+ item.hItem = hItem;
+ item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
/*****************************************************************************/
@@ -445,12 +318,12 @@ static void winTreeExpandTree(Ihandle* ih, HTREEITEM hItem, int expand)
/* SELECTING ITEMS */
/*****************************************************************************/
-static int winTreeIsItemSelected(Ihandle* ih, HTREEITEM hItem)
+static int winTreeIsNodeSelected(Ihandle* ih, HTREEITEM hItem)
{
return ((SendMessage(ih->handle, TVM_GETITEMSTATE, (WPARAM)hItem, TVIS_SELECTED)) & TVIS_SELECTED)!=0;
}
-static void winTreeSelectItem(Ihandle* ih, HTREEITEM hItem, int select)
+static void winTreeSelectNode(Ihandle* ih, HTREEITEM hItem, int select)
{
TV_ITEM item;
item.mask = TVIF_STATE | TVIF_HANDLE;
@@ -458,16 +331,13 @@ static void winTreeSelectItem(Ihandle* ih, HTREEITEM hItem, int select)
item.hItem = hItem;
if (select == -1)
- select = !winTreeIsItemSelected(ih, hItem);
+ select = !winTreeIsNodeSelected(ih, hItem); /* toggle */
item.state = select ? TVIS_SELECTED : 0;
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)&item);
-}
-
-static HTREEITEM winTreeGetFocusNode(Ihandle* ih)
-{
- return (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
}
/* ------------Comment from wxWidgets--------------------
@@ -475,17 +345,17 @@ static HTREEITEM winTreeGetFocusNode(Ihandle* ih)
item without changing anything else. */
static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (hItem != hItemFocus)
{
/* remember the selection state of the item */
- int wasSelected = winTreeIsItemSelected(ih, hItem);
+ int wasSelected = winTreeIsNodeSelected(ih, hItem);
int wasFocusSelected = 0;
- if (iupwinIsVista())
+ if (iupwinIsVistaOrNew() && iupwin_comctl32ver6)
iupAttribSetStr(ih, "_IUPTREE_ALLOW_CHANGE", (char*)hItem); /* Vista Only */
else
- wasFocusSelected = hItemFocus && winTreeIsItemSelected(ih, hItemFocus);
+ wasFocusSelected = hItemFocus && winTreeIsNodeSelected(ih, hItemFocus);
iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
@@ -493,58 +363,42 @@ static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem)
{
/* prevent the tree from unselecting the old focus which it would do by default */
SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)NULL); /* remove the focus */
- winTreeSelectItem(ih, hItemFocus, 1); /* select again */
+ winTreeSelectNode(ih, hItemFocus, 1); /* select again */
}
SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); /* set focus, selection, and unselect the previous focus */
if (!wasSelected)
- winTreeSelectItem(ih, hItem, 0); /* need to clear the selection if was not selected */
+ winTreeSelectNode(ih, hItem, 0); /* need to clear the selection if was not selected */
iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
iupAttribSetStr(ih, "_IUPTREE_ALLOW_CHANGE", NULL);
}
}
-typedef struct _winTreeRange{
- HTREEITEM hItem1, hItem2;
- char inside, clear;
-}winTreeRange;
-
-static int winTreeSelectRangeFunc(Ihandle* ih, HTREEITEM hItem, winTreeRange* range)
+static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItem1, HTREEITEM hItem2, int clear)
{
- int end_range = 0;
-
- if (range->inside == 0) /* detect the range start */
+ int i;
+ int id1 = iupTreeFindNodeId(ih, hItem1);
+ int id2 = iupTreeFindNodeId(ih, hItem2);
+ if (id2 == -1) id2 = ih->data->node_count-1;
+ if (id1 > id2)
{
- if (range->hItem1 == hItem) range->inside=1;
- else if (range->hItem2 == hItem) range->inside=1;
+ int tmp = id1;
+ id1 = id2;
+ id2 = tmp;
}
- else if (range->inside == 1) /* detect the range end */
+
+ for (i = 0; i < ih->data->node_count; i++)
{
- if (range->hItem1 == hItem) end_range=1;
- else if (range->hItem2 == hItem) end_range=1;
+ if (i < id1 || i > id2)
+ {
+ if (clear)
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 0);
+ }
+ else
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 1);
}
-
- if (range->inside == 1) /* if inside, select */
- winTreeSelectItem(ih, hItem, 1);
- else if (range->clear) /* if outside and clear, unselect */
- winTreeSelectItem(ih, hItem, 0);
-
- if (end_range || (range->inside && range->hItem1==range->hItem2))
- range->inside=-1; /* update after selecting the node */
-
- return 1;
-}
-
-static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItemFrom, HTREEITEM hItemTo, int clear)
-{
- winTreeRange range;
- range.hItem1 = hItemFrom;
- range.hItem2 = hItemTo;
- range.inside = 0;
- range.clear = (char)clear;
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectRangeFunc, &range);
}
static void winTreeSelectAll(Ihandle* ih)
@@ -558,9 +412,10 @@ static void winTreeClearSelection(Ihandle* ih, HTREEITEM hItemExcept)
winTreeSelectRange(ih, hItemExcept, hItemExcept, 1);
}
-static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, void* userdata)
+static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, int id, void* userdata)
{
- winTreeSelectItem(ih, hItem, -1);
+ (void)id;
+ winTreeSelectNode(ih, hItem, -1);
(void)userdata;
return 1;
}
@@ -568,14 +423,11 @@ static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, void* userdata)
typedef struct _winTreeSelArray{
Iarray* markedArray;
char is_handle;
- int id_control;
}winTreeSelArray;
-static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, winTreeSelArray* selarray)
+static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, int id, winTreeSelArray* selarray)
{
- selarray->id_control++;
-
- if (winTreeIsItemSelected(ih, hItem))
+ if (winTreeIsNodeSelected(ih, hItem))
{
if (selarray->is_handle)
{
@@ -587,7 +439,7 @@ static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, winTreeSelArra
{
int* intArrayData = (int*)iupArrayInc(selarray->markedArray);
int i = iupArrayCount(selarray->markedArray);
- intArrayData[i-1] = selarray->id_control;
+ intArrayData[i-1] = id;
}
}
@@ -599,10 +451,9 @@ static Iarray* winTreeGetSelectedArray(Ihandle* ih)
Iarray* markedArray = iupArrayCreate(1, sizeof(HTREEITEM));
winTreeSelArray selarray;
selarray.markedArray = markedArray;
- selarray.id_control = -1;
selarray.is_handle = 1;
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
+ iupTreeForEach(ih, (iupTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
return markedArray;
}
@@ -612,10 +463,9 @@ static Iarray* winTreeGetSelectedArrayId(Ihandle* ih)
Iarray* markedArray = iupArrayCreate(1, sizeof(int));
winTreeSelArray selarray;
selarray.markedArray = markedArray;
- selarray.id_control = -1;
selarray.is_handle = 0;
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
+ iupTreeForEach(ih, (iupTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
return markedArray;
}
@@ -625,7 +475,7 @@ static Iarray* winTreeGetSelectedArrayId(Ihandle* ih)
/* COPYING ITEMS (Branches and its children) */
/*****************************************************************************/
/* Insert the copied item in a new location. Returns the new item. */
-static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent, HTREEITEM hPosition, int full_copy)
+static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent, HTREEITEM hPosition, int is_copy)
{
TVITEM item;
TVINSERTSTRUCT tvins;
@@ -637,34 +487,34 @@ static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent
item.cchTextMax = 255;
SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- if (full_copy) /* during a full copy the userdata reference is not copied */
+ if (is_copy) /* during a copy the itemdata reference is not reused */
{
/* create a new one */
winTreeItemData* itemDataNew = malloc(sizeof(winTreeItemData));
memcpy(itemDataNew, (void*)item.lParam, sizeof(winTreeItemData));
- itemDataNew->userdata = NULL;
item.lParam = (LPARAM)itemDataNew;
}
- /* Copy everything including user data reference */
+ /* Copy everything including itemdata reference */
tvins.item = item;
tvins.hInsertAfter = hPosition;
tvins.hParent = hParent;
- /* Add the node to the tree-view control */
+ /* Add the new node */
+ ih->data->node_count++;
return (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
}
-static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int full_copy)
+static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int is_copy)
{
HTREEITEM hChildSrc = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemSrc);
- HTREEITEM hNewItem = TVI_FIRST;
+ HTREEITEM hItemNew = TVI_FIRST;
while (hChildSrc != NULL)
{
- hNewItem = winTreeCopyItem(ih, hChildSrc, hItemDst, hNewItem, full_copy); /* Use the same order they where enumerated */
+ hItemNew = winTreeCopyItem(ih, hChildSrc, hItemDst, hItemNew, is_copy); /* Use the same order they where enumerated */
/* Recursively transfer all the items */
- winTreeCopyChildren(ih, hChildSrc, hNewItem, full_copy);
+ winTreeCopyChildren(ih, hChildSrc, hItemNew, is_copy);
/* Go to next sibling item */
hChildSrc = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hChildSrc);
@@ -672,11 +522,18 @@ static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItem
}
/* Copies all items in a branch to a new location. Returns the new branch node. */
-static HTREEITEM winTreeCopyNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int full_copy)
+static HTREEITEM winTreeCopyMoveNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int is_copy)
{
- HTREEITEM hNewItem, hParent;
+ HTREEITEM hItemNew, hParent;
TVITEM item;
winTreeItemData* itemDataDst;
+ int id_new, count, id_src, id_dst;
+
+ int old_count = ih->data->node_count;
+
+ id_src = iupTreeFindNodeId(ih, hItemSrc);
+ id_dst = iupTreeFindNodeId(ih, hItemDst);
+ id_new = id_dst+1; /* contains the position for a copy operation */
/* Get DST node attributes */
item.hItem = hItemDst;
@@ -691,31 +548,64 @@ static HTREEITEM winTreeCopyNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hIte
hItemDst = TVI_FIRST;
}
else
- {
+ {
+ if (itemDataDst->kind == ITREE_BRANCH)
+ {
+ int child_count = iupdrvTreeTotalChildCount(ih, hItemDst);
+ id_new += child_count;
+ }
+
/* copy as next brother of item or collapsed branch */
hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItemDst);
}
- hNewItem = winTreeCopyItem(ih, hItemSrc, hParent, hItemDst, full_copy);
+ /* move to the same place does nothing */
+ if (!is_copy && id_new == id_src)
+ return NULL;
+
+ hItemNew = winTreeCopyItem(ih, hItemSrc, hParent, hItemDst, is_copy);
+
+ winTreeCopyChildren(ih, hItemSrc, hItemNew, is_copy);
+
+ count = ih->data->node_count - old_count;
+ iupTreeCopyMoveCache(ih, id_src, id_new, count, is_copy);
+
+ if (!is_copy)
+ {
+ /* Deleting the node (and its children) from the old position */
+ /* do not delete the itemdata, we reuse the references in CopyNode */
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemSrc);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
- winTreeCopyChildren(ih, hItemSrc, hNewItem, full_copy);
+ /* restore count, because we remove src */
+ ih->data->node_count = old_count;
- return hNewItem;
+ /* compensate position for a move */
+ if (id_new > id_src)
+ id_new -= count;
+ }
+
+ winTreeRebuildNodeCache(ih, id_new, hItemNew);
+
+ return hItemNew;
}
/*****************************************************************************/
/* MANIPULATING IMAGES */
/*****************************************************************************/
-static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode)
+static void winTreeUpdateImages(Ihandle* ih, int mode)
{
- HTREEITEM hItemChild;
+ HTREEITEM hItem;
TVITEM item;
winTreeItemData* itemData;
+ int i;
/* called when one of the default images is changed */
-
- while(hItem != NULL)
+ for (i = 0; i < ih->data->node_count; i++)
{
+ hItem = ih->data->node_cache[i].node_handle;
+
/* Get node attributes */
item.hItem = hItem;
item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE;
@@ -742,10 +632,6 @@ static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode)
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
}
-
- /* Recursively traverse child items */
- hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- winTreeUpdateImages(ih, hItemChild, mode);
}
else
{
@@ -756,9 +642,6 @@ static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode)
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
}
-
- /* Go to next sibling node */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
}
}
@@ -828,29 +711,57 @@ static int winTreeCallBranchLeafCb(Ihandle* ih, HTREEITEM hItem)
if (itemData->kind == ITREE_BRANCH)
{
+ if (iupAttribGet(ih, "_IUPTREE_IGNORE_BRANCH_CB"))
+ return IUP_DEFAULT;
+
if (item.state & TVIS_EXPANDED)
{
IFni cbBranchClose = (IFni)IupGetCallback(ih, "BRANCHCLOSE_CB");
if (cbBranchClose)
- return cbBranchClose(ih, winTreeGetNodeId(ih, hItem));
+ return cbBranchClose(ih, iupTreeFindNodeId(ih, hItem));
}
else
{
IFni cbBranchOpen = (IFni)IupGetCallback(ih, "BRANCHOPEN_CB");
if (cbBranchOpen)
- return cbBranchOpen(ih, winTreeGetNodeId(ih, hItem));
+ return cbBranchOpen(ih, iupTreeFindNodeId(ih, hItem));
}
}
else
{
IFni cbExecuteLeaf = (IFni)IupGetCallback(ih, "EXECUTELEAF_CB");
if (cbExecuteLeaf)
- return cbExecuteLeaf(ih, winTreeGetNodeId(ih, hItem));
+ return cbExecuteLeaf(ih, iupTreeFindNodeId(ih, hItem));
}
return IUP_DEFAULT;
}
+static void winTreeCallMultiUnSelectionCb(Ihandle* ih)
+{
+ IFnIi cbMulti = (IFnIi)IupGetCallback(ih, "MULTIUNSELECTION_CB");
+ IFnii cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB");
+ if (cbSelec || cbMulti)
+ {
+ Iarray* markedArray = winTreeGetSelectedArrayId(ih);
+ int* id_hitem = (int*)iupArrayGetData(markedArray);
+ int i, count = iupArrayCount(markedArray);
+
+ if (count > 1)
+ {
+ if (cbMulti)
+ cbMulti(ih, id_hitem, iupArrayCount(markedArray));
+ else
+ {
+ for (i=0; i<count; i++)
+ cbSelec(ih, id_hitem[i], 0);
+ }
+ }
+
+ iupArrayDestroy(markedArray);
+ }
+}
+
static void winTreeCallMultiSelectionCb(Ihandle* ih)
{
IFnIi cbMulti = (IFnIi)IupGetCallback(ih, "MULTISELECTION_CB");
@@ -885,6 +796,8 @@ static void winTreeCallSelectionCb(Ihandle* ih, int status, HTREEITEM hItem)
IFnii cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB");
if (cbSelec)
{
+ int id;
+
if (ih->data->mark_mode == ITREE_MARK_MULTIPLE && IupGetCallback(ih,"MULTISELECTION_CB"))
{
if ((GetKeyState(VK_SHIFT) & 0x8000))
@@ -894,7 +807,9 @@ static void winTreeCallSelectionCb(Ihandle* ih, int status, HTREEITEM hItem)
if (iupAttribGet(ih, "_IUPTREE_IGNORE_SELECTION_CB"))
return;
- cbSelec(ih, winTreeGetNodeId(ih, hItem), status);
+ id = iupTreeFindNodeId(ih, hItem);
+ if (id != -1)
+ cbSelec(ih, id, status);
}
}
@@ -911,8 +826,8 @@ static int winTreeCallDragDropCb(Ihandle* ih, HTREEITEM hItemDrag, HTREEITEM hIt
if (cbDragDrop)
{
- int drag_id = winTreeGetNodeId(ih, hItemDrag);
- int drop_id = winTreeGetNodeId(ih, hItemDrop);
+ int drag_id = iupTreeFindNodeId(ih, hItemDrag);
+ int drop_id = iupTreeFindNodeId(ih, hItemDrop);
return cbDragDrop(ih, drag_id, drop_id, is_shift, *is_ctrl);
}
@@ -929,8 +844,8 @@ static int winTreeSetImageBranchExpandedAttrib(Ihandle* ih, const char* value)
{
ih->data->def_image_expanded = (void*)winTreeGetImageIndex(ih, value);
- /* Update all images, starting at root node */
- winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_EXPANDED);
+ /* Update all images */
+ winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_EXPANDED);
return 1;
}
@@ -939,8 +854,8 @@ static int winTreeSetImageBranchCollapsedAttrib(Ihandle* ih, const char* value)
{
ih->data->def_image_collapsed = (void*)winTreeGetImageIndex(ih, value);
- /* Update all images, starting at root node */
- winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_COLLAPSED);
+ /* Update all images */
+ winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_COLLAPSED);
return 1;
}
@@ -949,8 +864,8 @@ static int winTreeSetImageLeafAttrib(Ihandle* ih, const char* value)
{
ih->data->def_image_leaf = (void*)winTreeGetImageIndex(ih, value);
- /* Update all images, starting at root node */
- winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_LEAF);
+ /* Update all images */
+ winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_LEAF);
return 1;
}
@@ -959,7 +874,7 @@ static int winTreeSetImageExpandedAttrib(Ihandle* ih, const char* name_id, const
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -986,7 +901,7 @@ static int winTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1025,7 +940,7 @@ static int winTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v
static int winTreeSetTopItemAttrib(Ihandle* ih, const char* value)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, value);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, value);
if (hItem)
SendMessage(ih->handle, TVM_ENSUREVISIBLE, 0, (LPARAM)hItem);
return 0;
@@ -1056,9 +971,8 @@ static int winTreeSetSpacingAttrib(Ihandle* ih, const char* value)
static int winTreeSetExpandAllAttrib(Ihandle* ih, const char* value)
{
HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- HTREEITEM hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemRoot); /* skip the root node that is always expanded */
int expand = iupStrBoolean(value);
- winTreeExpandTree(ih, hItem, expand);
+ winTreeExpandTree(ih, hItemRoot, expand);
return 0;
}
@@ -1131,7 +1045,7 @@ static char* winTreeGetTitle(Ihandle* ih, HTREEITEM hItem)
static char* winTreeGetTitleAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
return winTreeGetTitle(ih, hItem);
@@ -1140,10 +1054,13 @@ static char* winTreeGetTitleAttrib(Ihandle* ih, const char* name_id)
static int winTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* value)
{
TVITEM item;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
+ if (!value)
+ value = "";
+
item.hItem = hItem;
item.mask = TVIF_HANDLE | TVIF_TEXT;
item.pszText = (char*)value;
@@ -1151,60 +1068,11 @@ static int winTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* v
return 0;
}
-static char* winTreeGetFindUserDataAttrib(Ihandle* ih, const char* name_id)
-{
- int id;
- char* str = (char*)(name_id+1); /* skip ':' */
- void* userdata = NULL;
- if (sscanf(str, "%p", &userdata)!=1)
- return NULL;
- id = winTreeGetUserDataId(ih, userdata);
- if (id == -1)
- return NULL;
- str = iupStrGetMemory(16);
- sprintf(str, "%d", id);
- return str;
-}
-
-static char* winTreeGetUserDataAttrib(Ihandle* ih, const char* name_id)
-{
- TVITEM item;
- winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- if (!hItem)
- return NULL;
-
- item.hItem = hItem;
- item.mask = TVIF_HANDLE | TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- return itemData->userdata;
-}
-
-static int winTreeSetUserDataAttrib(Ihandle* ih, const char* name_id, const char* value)
-{
- TVITEM item;
- winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- if (!hItem)
- return 0;
-
- item.hItem = hItem;
- item.mask = TVIF_HANDLE | TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- itemData->userdata = (void*)value;
-
- return 0;
-}
-
static char* winTreeGetTitleFontAttrib(Ihandle* ih, const char* name_id)
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1220,7 +1088,7 @@ static int winTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1230,11 +1098,23 @@ static int winTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha
itemData = (winTreeItemData*)item.lParam;
if (value)
+ {
itemData->hFont = iupwinGetHFont(value);
+ if (itemData->hFont)
+ {
+ TV_ITEM item;
+ item.mask = TVIF_STATE | TVIF_HANDLE | TVIF_TEXT;
+ item.stateMask = TVIS_BOLD;
+ item.hItem = hItem;
+ item.pszText = winTreeGetTitle(ih, hItem); /* reset text to resize item */
+ item.state = (strstr(value, "Bold")||strstr(value, "BOLD"))? TVIS_BOLD: 0;
+ SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)&item);
+ }
+ }
else
itemData->hFont = NULL;
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
return 0;
}
@@ -1259,7 +1139,7 @@ static char* winTreeGetStateAttrib(Ihandle* ih, const char* name_id)
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1281,25 +1161,34 @@ static char* winTreeGetStateAttrib(Ihandle* ih, const char* name_id)
static int winTreeSetStateAttrib(Ihandle* ih, const char* name_id, const char* value)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ TVITEM item;
+ winTreeItemData* itemData;
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
- winTreeExpandItem(ih, hItem, iupStrEqualNoCase(value, "EXPANDED"));
+ /* Get Children: branch or leaf */
+ item.mask = TVIF_HANDLE|TVIF_PARAM;
+ item.hItem = hItem;
+ SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
+ itemData = (winTreeItemData*)item.lParam;
+
+ if (itemData->kind == ITREE_BRANCH)
+ winTreeExpandItem(ih, hItem, iupStrEqualNoCase(value, "EXPANDED"));
+
return 0;
}
static char* winTreeGetDepthAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- int depth = 0;
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
+ int depth = -1;
char* str;
- if (!hItem)
+ if (!hItem)
return NULL;
- while((hItemRoot != hItem) && (hItem != NULL))
+ while(hItem != NULL)
{
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem);
depth++;
@@ -1314,12 +1203,13 @@ static int winTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char
{
HTREEITEM hItemDst, hParent, hItemSrc;
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
- hItemSrc = winTreeFindNodeFromString(ih, name_id);
+
+ hItemSrc = iupTreeGetNodeFromString(ih, name_id);
if (!hItemSrc)
return 0;
- hItemDst = winTreeFindNodeFromString(ih, value);
+ hItemDst = iupTreeGetNodeFromString(ih, value);
if (!hItemDst)
return 0;
@@ -1332,11 +1222,8 @@ static int winTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char
return 0;
}
- /* Copying the node and its children to the new position */
- winTreeCopyNode(ih, hItemSrc, hItemDst, 0); /* not a full copy, preserve user data */
-
- /* do not delete the user data, we copy the references in CopyNode */
- SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemSrc);
+ /* Move the node and its children to the new position */
+ winTreeCopyMoveNode(ih, hItemSrc, hItemDst, 0);
return 0;
}
@@ -1345,12 +1232,13 @@ static int winTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char
{
HTREEITEM hItemDst, hParent, hItemSrc;
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
- hItemSrc = winTreeFindNodeFromString(ih, name_id);
+
+ hItemSrc = iupTreeGetNodeFromString(ih, name_id);
if (!hItemSrc)
return 0;
- hItemDst = winTreeFindNodeFromString(ih, value);
+ hItemDst = iupTreeGetNodeFromString(ih, value);
if (!hItemDst)
return 0;
@@ -1363,8 +1251,8 @@ static int winTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char
return 0;
}
- /* Copying the node and its children to the new position */
- winTreeCopyNode(ih, hItemSrc, hItemDst, 1);
+ /* Copy the node and its children to the new position */
+ winTreeCopyMoveNode(ih, hItemSrc, hItemDst, 1);
return 0;
}
@@ -1375,7 +1263,7 @@ static char* winTreeGetColorAttrib(Ihandle* ih, const char* name_id)
char* str;
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1398,7 +1286,7 @@ static int winTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v
unsigned char r, g, b;
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1410,7 +1298,7 @@ static int winTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v
if (iupStrToRGB(value, &r, &g, &b))
{
itemData->color = RGB(r,g,b);
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
}
return 0;
@@ -1435,7 +1323,7 @@ static char* winTreeGetChildCountAttrib(Ihandle* ih, const char* name_id)
{
int count;
char* str;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1454,18 +1342,11 @@ static char* winTreeGetChildCountAttrib(Ihandle* ih, const char* name_id)
return str;
}
-static char* winTreeGetCountAttrib(Ihandle* ih)
-{
- char* str = iupStrGetMemory(10);
- sprintf(str, "%d", (int)SendMessage(ih->handle, TVM_GETCOUNT, 0, 0));
- return str;
-}
-
static char* winTreeGetKindAttrib(Ihandle* ih, const char* name_id)
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1483,7 +1364,7 @@ static char* winTreeGetKindAttrib(Ihandle* ih, const char* name_id)
static char* winTreeGetParentAttrib(Ihandle* ih, const char* name_id)
{
char* str;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1492,15 +1373,13 @@ static char* winTreeGetParentAttrib(Ihandle* ih, const char* name_id)
return NULL;
str = iupStrGetMemory(10);
- sprintf(str, "%d", winTreeGetNodeId(ih, hItem));
+ sprintf(str, "%d", iupTreeFindNodeId(ih, hItem));
return str;
}
-static void winTreeDelNodeData(Ihandle* ih, HTREEITEM hItem)
+static void winTreeRemoveItemData(Ihandle* ih, HTREEITEM hItem, IFns cb, int id)
{
TVITEM item;
- HTREEITEM hChildItem;
-
item.hItem = hItem;
item.mask = TVIF_HANDLE|TVIF_PARAM;
if (SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item))
@@ -1508,81 +1387,153 @@ static void winTreeDelNodeData(Ihandle* ih, HTREEITEM hItem)
winTreeItemData* itemData = (winTreeItemData*)item.lParam;
if (itemData)
{
- IFnis cb = (IFnis)IupGetCallback(ih, "NODEREMOVED_CB");
- if (cb) cb(ih, winTreeGetNodeId(ih, hItem), (char*)itemData->userdata);
+ if (cb)
+ cb(ih, (char*)ih->data->node_cache[id].userdata);
+
free(itemData);
item.lParam = (LPARAM)NULL;
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
}
+}
+
+static void winTreeRemoveNodeDataRec(Ihandle* ih, HTREEITEM hItem, IFns cb, int *id)
+{
+ int old_id = *id;
- hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
+ /* Check whether we have child items */
+ /* remove from children first */
+ HTREEITEM hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
while (hChildItem)
{
- winTreeDelNodeData(ih, hChildItem);
+ /* go recursive to children */
+ winTreeRemoveNodeDataRec(ih, hChildItem, cb, id);
+
+ /* Go to next sibling item */
hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hChildItem);
}
+
+ /* actually do it for the node */
+ ih->data->node_count--;
+ (*id)++;
+
+ winTreeRemoveItemData(ih, hItem, cb, old_id);
+}
+
+static void winTreeRemoveNodeData(Ihandle* ih, HTREEITEM hItem, int call_cb)
+{
+ IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL;
+ int old_count = ih->data->node_count;
+ int id = iupTreeFindNodeId(ih, hItem);
+ int old_id = id;
+
+ winTreeRemoveNodeDataRec(ih, hItem, cb, &id);
+
+ if (call_cb)
+ iupTreeDelFromCache(ih, old_id, old_count-ih->data->node_count);
+}
+
+static void winTreeRemoveAllNodeData(Ihandle* ih, int call_cb)
+{
+ IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL;
+ int i, old_count = ih->data->node_count;
+ HTREEITEM hItem;
+
+ for (i = 0; i < ih->data->node_count; i++)
+ {
+ hItem = ih->data->node_cache[i].node_handle;
+ winTreeRemoveItemData(ih, hItem, cb, i);
+ }
+
+ ih->data->node_count = 0;
+
+ if (call_cb)
+ iupTreeDelFromCache(ih, 0, old_count);
}
static int winTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char* value)
{
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
- if(iupStrEqualNoCase(value, "SELECTED")) /* selected here means the specified one */
+ if (iupStrEqualNoCase(value, "ALL"))
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
+ winTreeRemoveAllNodeData(ih, 1);
- /* the root node can't be deleted */
- if(!hItem || hItem == hItemRoot)
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
+ return 0;
+ }
+ if (iupStrEqualNoCase(value, "SELECTED")) /* selected here means the reference one */
+ {
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
+ if(!hItem)
return 0;
- /* deleting the specified node (and it's children) */
- winTreeDelNodeData(ih, hItem);
+ /* deleting the reference node (and it's children) */
+ winTreeRemoveNodeData(ih, hItem, 1);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItem);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
return 0;
}
- else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the specified one */
+ else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the reference node */
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
HTREEITEM hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
if(!hItem)
return 0;
- /* deleting the selected node's children */
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+
+ /* deleting the reference node children */
while (hChildItem)
{
- winTreeDelNodeData(ih, hChildItem);
+ winTreeRemoveNodeData(ih, hChildItem, 1);
SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hChildItem);
hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
}
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
return 0;
}
else if(iupStrEqualNoCase(value, "MARKED"))
{
- int i, count;
- Iarray* markedArray;
- HTREEITEM* hItemArrayData;
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
+ int i, del_focus = 0;
+ HTREEITEM hItemFocus;
- /* Delete the array of marked nodes */
- markedArray = winTreeGetSelectedArray(ih);
- hItemArrayData = (HTREEITEM*)iupArrayGetData(markedArray);
- count = iupArrayCount(markedArray);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ hItemFocus = iupdrvTreeGetFocusNode(ih);
- for(i = 0; i < count; i++)
+ for(i = 1; i < ih->data->node_count; /* increment only if not removed */)
{
- if (hItemArrayData[i] != hItemRoot) /* the root node can't be deleted */
+ if (winTreeIsNodeSelected(ih, ih->data->node_cache[i].node_handle))
{
- winTreeDelNodeData(ih, hItemArrayData[i]);
- SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemArrayData[i]);
+ HTREEITEM hItem = ih->data->node_cache[i].node_handle;
+ if (hItemFocus == hItem)
+ {
+ del_focus = 1;
+ i++;
+ }
+ else
+ {
+ winTreeRemoveNodeData(ih, hItem, 1);
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItem);
+ }
}
+ else
+ i++;
}
- iupArrayDestroy(markedArray);
+ if (del_focus)
+ {
+ winTreeRemoveNodeData(ih, hItemFocus, 1);
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemFocus);
+ }
+
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
return 0;
}
@@ -1592,22 +1543,13 @@ static int winTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char*
static int winTreeSetRenameAttrib(Ihandle* ih, const char* value)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
if (ih->data->show_rename)
{
- IFni cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB");
- if (cbShowRename)
- cbShowRename(ih, winTreeGetNodeId(ih, hItemFocus));
-
+ HTREEITEM hItemFocus;
SetFocus(ih->handle); /* the tree must have focus to activate the edit */
+ hItemFocus = iupdrvTreeGetFocusNode(ih);
SendMessage(ih->handle, TVM_EDITLABEL, 0, (LPARAM)hItemFocus);
}
- else
- {
- IFnis cbRenameNode = (IFnis)IupGetCallback(ih, "RENAMENODE_CB");
- if (cbRenameNode)
- cbRenameNode(ih, winTreeGetNodeId(ih, hItemFocus), winTreeGetTitle(ih, hItemFocus));
- }
(void)value;
return 0;
@@ -1615,11 +1557,11 @@ static int winTreeSetRenameAttrib(Ihandle* ih, const char* value)
static char* winTreeGetMarkedAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
- if (winTreeIsItemSelected(ih, hItem))
+ if (winTreeIsNodeSelected(ih, hItem))
return "YES";
else
return "NO";
@@ -1627,17 +1569,23 @@ static char* winTreeGetMarkedAttrib(Ihandle* ih, const char* name_id)
static int winTreeSetMarkedAttrib(Ihandle* ih, const char* name_id, const char* value)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
- winTreeSelectItem(ih, hItem, iupStrBoolean(value));
+ if (ih->data->mark_mode==ITREE_MARK_SINGLE)
+ {
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
+ winTreeSelectNode(ih, hItemFocus, 0);
+ }
+
+ winTreeSelectNode(ih, hItem, iupStrBoolean(value));
return 0;
}
static int winTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1649,15 +1597,59 @@ static int winTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id)
static char* winTreeGetValueAttrib(Ihandle* ih)
{
char* str;
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (!hItemFocus)
- return "0"; /* default VALUE is root */
+ {
+ if (ih->data->node_count)
+ return "0"; /* default VALUE is root */
+ else
+ return "-1";
+ }
str = iupStrGetMemory(16);
- sprintf(str, "%d", winTreeGetNodeId(ih, hItemFocus));
+ sprintf(str, "%d", iupTreeFindNodeId(ih, hItemFocus));
+ return str;
+}
+
+static char* winTreeGetMarkedNodesAttrib(Ihandle* ih)
+{
+ char* str = iupStrGetMemory(ih->data->node_count+1);
+ int i;
+
+ for (i=0; i<ih->data->node_count; i++)
+ {
+ if (winTreeIsNodeSelected(ih, ih->data->node_cache[i].node_handle))
+ str[i] = '+';
+ else
+ str[i] = '-';
+ }
+
+ str[ih->data->node_count] = 0;
return str;
}
+static int winTreeSetMarkedNodesAttrib(Ihandle* ih, const char* value)
+{
+ int count, i;
+
+ if (ih->data->mark_mode==ITREE_MARK_SINGLE || !value)
+ return 0;
+
+ count = strlen(value);
+ if (count > ih->data->node_count)
+ count = ih->data->node_count;
+
+ for (i=0; i<count; i++)
+ {
+ if (value[i] == '+')
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 1);
+ else
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 0);
+ }
+
+ return 0;
+}
+
static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
{
if (ih->data->mark_mode==ITREE_MARK_SINGLE)
@@ -1665,7 +1657,7 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
if(iupStrEqualNoCase(value, "BLOCK"))
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
winTreeSelectRange(ih, (HTREEITEM)iupAttribGet(ih, "_IUPTREE_MARKSTART_NODE"), hItemFocus, 0);
}
else if(iupStrEqualNoCase(value, "CLEARALL"))
@@ -1673,14 +1665,14 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
else if(iupStrEqualNoCase(value, "MARKALL"))
winTreeSelectAll(ih);
else if(iupStrEqualNoCase(value, "INVERTALL")) /* INVERTALL *MUST* appear before INVERT, or else INVERTALL will never be called. */
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeInvertSelectFunc, NULL);
+ iupTreeForEach(ih, (iupTreeNodeFunc)winTreeInvertSelectFunc, NULL);
else if(iupStrEqualPartial(value, "INVERT")) /* iupStrEqualPartial allows the use of "INVERTid" form */
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, &value[strlen("INVERT")]);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, &value[strlen("INVERT")]);
if (!hItem)
return 0;
- winTreeSelectItem(ih, hItem, -1); /* toggle */
+ winTreeSelectNode(ih, hItem, -1); /* toggle */
}
else
{
@@ -1690,10 +1682,10 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
if (iupStrToStrStr(value, str1, str2, '-')!=2)
return 0;
- hItem1 = winTreeFindNodeFromString(ih, str1);
+ hItem1 = iupTreeGetNodeFromString(ih, str1);
if (!hItem1)
return 0;
- hItem2 = winTreeFindNodeFromString(ih, str2);
+ hItem2 = iupTreeGetNodeFromString(ih, str2);
if (!hItem2)
return 0;
@@ -1711,9 +1703,9 @@ static int winTreeSetValueAttrib(Ihandle* ih, const char* value)
if (winTreeSetMarkAttrib(ih, value))
return 0;
- hItemFocus = winTreeGetFocusNode(ih);
+ hItemFocus = iupdrvTreeGetFocusNode(ih);
- if(iupStrEqualNoCase(value, "ROOT"))
+ if(iupStrEqualNoCase(value, "ROOT") || iupStrEqualNoCase(value, "FIRST"))
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
else if(iupStrEqualNoCase(value, "LAST"))
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0);
@@ -1759,15 +1751,14 @@ static int winTreeSetValueAttrib(Ihandle* ih, const char* value)
else if(iupStrEqualNoCase(value, "PREVIOUS"))
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItemFocus);
else
- hItem = winTreeFindNodeFromString(ih, value);
+ hItem = iupTreeGetNodeFromString(ih, value);
if (hItem)
{
if (ih->data->mark_mode==ITREE_MARK_SINGLE)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
- winTreeSelectItem(ih, hItem, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
+ winTreeSelectNode(ih, hItemFocus, 0);
+ winTreeSelectNode(ih, hItem, 1);
}
winTreeSetFocusNode(ih, hItem);
}
@@ -1832,27 +1823,60 @@ static LRESULT CALLBACK winTreeEditWinProc(HWND hwnd, UINT msg, WPARAM wp, LPARA
return CallWindowProc(oldProc, hwnd, msg, wp, lp);
}
-static void winTreeDrag(Ihandle* ih, int x, int y)
+static void winTreeBeginDrag(Ihandle* ih, int x, int y)
{
- HTREEITEM hItemDrop;
+ HIMAGELIST dragImageList;
+
+ HTREEITEM hItemDrag = winTreeFindNodeXY(ih, x, y);
+ if (!hItemDrag)
+ return;
+
+ SendMessage(ih->handle, TVM_ENDEDITLABELNOW, TRUE, 0);
+
+ /* store the drag-and-drop item */
+ iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", (char*)hItemDrag);
+ /* get the image list for dragging */
+ dragImageList = (HIMAGELIST)SendMessage(ih->handle, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItemDrag);
+ if (dragImageList)
+ {
+ POINT pt;
+ ImageList_BeginDrag(dragImageList, 0, 0, 0);
+
+ pt.x = x;
+ pt.y = y;
+
+ ClientToScreen(ih->handle, &pt);
+ ImageList_DragEnter(NULL, pt.x, pt.y);
+
+ iupAttribSetStr(ih, "_IUPTREE_DRAGIMAGELIST", (char*)dragImageList);
+ }
+
+ ShowCursor(FALSE);
+ SetCapture(ih->handle); /* drag only inside the tree */
+}
+
+static void winTreeDrag(Ihandle* ih, int x, int y)
+{
+ HTREEITEM hItemDrop = winTreeFindNodeXY(ih, x, y);
+ HTREEITEM hItemDrag = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_DRAGITEM");
HIMAGELIST dragImageList = (HIMAGELIST)iupAttribGet(ih, "_IUPTREE_DRAGIMAGELIST");
+
if (dragImageList)
{
- POINT pnt;
- pnt.x = x;
- pnt.y = y;
- GetCursorPos(&pnt);
- ClientToScreen(GetDesktopWindow(), &pnt) ;
- ImageList_DragMove(pnt.x, pnt.y);
+ POINT pt;
+ pt.x = x;
+ pt.y = y;
+ ClientToScreen(ih->handle, &pt);
+ ImageList_DragMove(pt.x, pt.y);
}
- if ((hItemDrop = winTreeFindNodePointed(ih)) != NULL)
+ if (hItemDrop && hItemDrop!=hItemDrag)
{
if(dragImageList)
ImageList_DragShowNolock(FALSE);
- SendMessage(ih->handle, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)hItemDrop);
+ SendMessage(ih->handle, TVM_SETINSERTMARK, TRUE, (LPARAM)hItemDrop);
/* store the drop item to be executed */
iupAttribSetStr(ih, "_IUPTREE_DROPITEM", (char*)hItemDrop);
@@ -1860,6 +1884,8 @@ static void winTreeDrag(Ihandle* ih, int x, int y)
if(dragImageList)
ImageList_DragShowNolock(TRUE);
}
+ else
+ iupAttribSetStr(ih, "_IUPTREE_DROPITEM", NULL);
}
static void winTreeDrop(Ihandle* ih)
@@ -1882,7 +1908,7 @@ static void winTreeDrop(Ihandle* ih)
ShowCursor(TRUE);
/* Remove drop target highlighting */
- SendMessage(ih->handle, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)NULL);
+ SendMessage(ih->handle, TVM_SETINSERTMARK, 0, (LPARAM)NULL);
iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", NULL);
iupAttribSetStr(ih, "_IUPTREE_DROPITEM", NULL);
@@ -1901,16 +1927,12 @@ static void winTreeDrop(Ihandle* ih)
if (winTreeCallDragDropCb(ih, hItemDrag, hItemDrop, &is_ctrl) == IUP_CONTINUE)
{
- /* Copy the dragged item to the new position. */
- HTREEITEM hItemNew = winTreeCopyNode(ih, hItemDrag, hItemDrop, is_ctrl);
-
- if (!is_ctrl)
- {
- /* do not delete the user data, we copy the references in CopyNode */
- SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemDrag);
- }
+ /* Copy or move the dragged item to the new position. */
+ HTREEITEM hItemNew = winTreeCopyMoveNode(ih, hItemDrag, hItemDrop, is_ctrl);
- SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItemNew); /* set focus and selection */
+ /* Set focus and selection */
+ if (hItemNew)
+ SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItemNew);
}
}
@@ -1929,9 +1951,7 @@ static void winTreeExtendSelect(Ihandle* ih, int x, int y)
hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM");
if (hItemFirstSel)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
winTreeSelectRange(ih, hItemFirstSel, hItem, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
iupAttribSetStr(ih, "_IUPTREE_LASTSELITEM", (char*)hItem);
winTreeSetFocusNode(ih, hItem);
@@ -1952,10 +1972,10 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y)
if (GetKeyState(VK_CONTROL) & 0x8000) /* Control key is down */
{
/* Toggle selection state */
- winTreeSelectItem(ih, hItem, -1);
+ winTreeSelectNode(ih, hItem, -1);
iupAttribSetStr(ih, "_IUPTREE_FIRSTSELITEM", (char*)hItem);
- winTreeCallSelectionCb(ih, winTreeIsItemSelected(ih, hItem), hItem);
+ winTreeCallSelectionCb(ih, winTreeIsNodeSelected(ih, hItem), hItem);
winTreeSetFocusNode(ih, hItem);
return 1;
@@ -1965,9 +1985,11 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y)
HTREEITEM hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM");
if (hItemFirstSel)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ int last_id = iupTreeFindNodeId(ih, hItem);
winTreeSelectRange(ih, hItemFirstSel, hItem, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
+
+ /* if last selected item is a branch, then select its children */
+ iupTreeSelectLastCollapsedBranch(ih, &last_id);
winTreeCallMultiSelectionCb(ih);
winTreeSetFocusNode(ih, hItem);
@@ -1975,11 +1997,15 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y)
}
}
+ winTreeCallMultiUnSelectionCb(ih);
+
/* simple click */
winTreeClearSelection(ih, hItem);
iupAttribSetStr(ih, "_IUPTREE_FIRSTSELITEM", (char*)hItem);
iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", "1");
+ /* Call SELECT_CB for all unselected nodes */
+
return 0;
}
@@ -2039,7 +2065,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
if (wp == VK_RETURN)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (winTreeCallBranchLeafCb(ih, hItemFocus) != IUP_IGNORE)
winTreeExpandItem(ih, hItemFocus, -1);
@@ -2056,14 +2082,14 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
{
if (GetKeyState(VK_CONTROL) & 0x8000)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
/* Toggle selection state */
- winTreeSelectItem(ih, hItemFocus, -1);
+ winTreeSelectNode(ih, hItemFocus, -1);
}
}
else if (wp == VK_UP || wp == VK_DOWN)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (wp == VK_UP)
hItemFocus = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItemFocus);
else
@@ -2084,9 +2110,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
HTREEITEM hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM");
if (hItemFirstSel)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
winTreeSelectRange(ih, hItemFirstSel, hItemFocus, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
winTreeCallMultiSelectionCb(ih);
winTreeSetFocusNode(ih, hItemFocus);
@@ -2138,10 +2162,20 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
}
break;
case WM_MOUSEMOVE:
- if (ih->data->show_dragdrop && (HTREEITEM)iupAttribGet(ih, "_IUPTREE_DRAGITEM") != NULL)
- winTreeDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ if (ih->data->show_dragdrop && (wp & MK_LBUTTON))
+ {
+ if (!iupAttribGet(ih, "_IUPTREE_DRAGITEM"))
+ winTreeBeginDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ else
+ winTreeDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ }
else if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT"))
- winTreeExtendSelect(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ {
+ if (wp & MK_LBUTTON)
+ winTreeExtendSelect(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ else
+ iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", NULL);
+ }
iupwinMouseMove(ih, msg, wp, lp);
break;
@@ -2157,6 +2191,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT"))
{
iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", NULL);
+
if (iupAttribGet(ih, "_IUPTREE_LASTSELITEM"))
{
winTreeCallMultiSelectionCb(ih);
@@ -2205,14 +2240,19 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
else if (msg_info->code == TVN_SELCHANGED)
{
NMTREEVIEW* info = (NMTREEVIEW*)msg_info;
- winTreeCallSelectionCb(ih, 0, info->itemOld.hItem); /* node unselected */
- winTreeCallSelectionCb(ih, 1, info->itemNew.hItem); /* node selected */
+ if (ih->data->mark_mode!=ITREE_MARK_MULTIPLE || /* (NOT) Multiple selection with Control or Shift key is down */
+ !(GetKeyState(VK_CONTROL) & 0x8000 || GetKeyState(VK_SHIFT) & 0x8000))
+ {
+ winTreeCallSelectionCb(ih, 0, info->itemOld.hItem); /* node unselected */
+ winTreeCallSelectionCb(ih, 1, info->itemNew.hItem); /* node selected */
+ }
}
else if(msg_info->code == TVN_BEGINLABELEDIT)
{
char* value;
HWND hEdit;
NMTVDISPINFO* info = (NMTVDISPINFO*)msg_info;
+ IFni cbShowRename;
if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT"))
{
@@ -2220,6 +2260,13 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
return 1;
}
+ cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB");
+ if (cbShowRename && cbShowRename(ih, iupTreeFindNodeId(ih, info->item.hItem))==IUP_IGNORE)
+ {
+ *result = TRUE; /* prevent the change */
+ return 1;
+ }
+
hEdit = (HWND)SendMessage(ih->handle, TVM_GETEDITCONTROL, 0, 0);
/* save the edit box. */
@@ -2253,57 +2300,30 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
}
else if(msg_info->code == TVN_ENDLABELEDIT)
{
+ IFnis cbRename;
NMTVDISPINFO* info = (NMTVDISPINFO*)msg_info;
iupAttribSetStr(ih, "_IUPWIN_EDITBOX", NULL);
- if (info->item.pszText)
- {
- IFnis cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB");
- if (cbRename)
- {
- if (cbRename(ih, winTreeGetNodeId(ih, info->item.hItem), info->item.pszText) == IUP_IGNORE)
- {
- *result = FALSE;
- return 1;
- }
- }
+ if (!info->item.pszText) /* cancel, so abort */
+ return 0;
- *result = TRUE;
- return 1;
- }
- }
- else if(msg_info->code == TVN_BEGINDRAG)
- {
- if (ih->data->show_dragdrop)
+ cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB");
+ if (cbRename)
{
- NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)msg_info;
- HTREEITEM hItemDrag = pNMTreeView->itemNew.hItem;
- HIMAGELIST dragImageList;
-
- /* store the drag-and-drop item */
- iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", (char*)hItemDrag);
-
- /* get the image list for dragging */
- dragImageList = (HIMAGELIST)SendMessage(ih->handle, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItemDrag);
- if (dragImageList)
+ if (cbRename(ih, iupTreeFindNodeId(ih, info->item.hItem), info->item.pszText) == IUP_IGNORE)
{
- POINT pt = pNMTreeView->ptDrag;
- ImageList_BeginDrag(dragImageList, 0, 0, 0);
-
- ClientToScreen(ih->handle, &pt);
- ImageList_DragEnter(NULL, pt.x, pt.y);
-
- iupAttribSetStr(ih, "_IUPTREE_DRAGIMAGELIST", (char*)dragImageList);
+ *result = FALSE;
+ return 1;
}
-
- ShowCursor(FALSE);
- SetCapture(ih->handle); /* drag only inside the tree */
}
+
+ *result = TRUE;
+ return 1;
}
else if(msg_info->code == NM_DBLCLK)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
TVITEM item;
winTreeItemData* itemData;
@@ -2317,7 +2337,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
{
IFni cbExecuteLeaf = (IFni)IupGetCallback(ih, "EXECUTELEAF_CB");
if(cbExecuteLeaf)
- cbExecuteLeaf(ih, winTreeGetNodeId(ih, hItemFocus));
+ cbExecuteLeaf(ih, iupTreeFindNodeId(ih, hItemFocus));
}
}
else if(msg_info->code == TVN_ITEMEXPANDING)
@@ -2351,7 +2371,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
HTREEITEM hItem = winTreeFindNodePointed(ih);
IFni cbRightClick = (IFni)IupGetCallback(ih, "RIGHTCLICK_CB");
if (cbRightClick)
- cbRightClick(ih, winTreeGetNodeId(ih, hItem));
+ cbRightClick(ih, iupTreeFindNodeId(ih, hItem));
}
else if (msg_info->code == NM_CUSTOMDRAW)
{
@@ -2374,7 +2394,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
itemData = (winTreeItemData*)item.lParam;
- if (winTreeIsItemSelected(ih, hItem))
+ if (GetFocus()==ih->handle && (customdraw->nmcd.uItemState & CDIS_SELECTED))
customdraw->clrText = winTreeInvertColor(itemData->color);
else
customdraw->clrText = itemData->color;
@@ -2402,47 +2422,34 @@ static int winTreeConvertXYToPos(Ihandle* ih, int x, int y)
info.pt.y = y;
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)&info);
if (hItem)
- return winTreeGetNodeId(ih, hItem);
+ return iupTreeFindNodeId(ih, hItem);
return -1;
}
/*******************************************************************************************/
-static void winTreeUnMapMethod(Ihandle* ih)
-{
- Iarray* bmp_array;
- HIMAGELIST image_list;
-
- HTREEITEM itemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- winTreeDelNodeData(ih, itemRoot);
-
- image_list = (HIMAGELIST)SendMessage(ih->handle, TVM_GETIMAGELIST, TVSIL_NORMAL, 0);
- if (image_list)
- ImageList_Destroy(image_list);
-
- bmp_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY");
- if (bmp_array)
- iupArrayDestroy(bmp_array);
-
- iupdrvBaseUnMapMethod(ih);
-}
static int winTreeMapMethod(Ihandle* ih)
{
- DWORD dwStyle = WS_CHILD | WS_BORDER | TVS_SHOWSELALWAYS;
+ DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER | TVS_SHOWSELALWAYS;
- /* can be set only on the Tree View creation */
+ /* styles can be set only on the Tree View creation */
- if (!ih->data->show_dragdrop)
- dwStyle |= TVS_DISABLEDRAGDROP;
+ /* always disable the internal drag&drop, because it affects our selection and drawing */
+ dwStyle |= TVS_DISABLEDRAGDROP;
if (ih->data->show_rename)
dwStyle |= TVS_EDITLABELS;
if (!iupAttribGetBoolean(ih, "HIDELINES"))
+ {
dwStyle |= TVS_HASLINES;
+ if (!iupAttribGetInt(ih, "ADDROOT"))
+ dwStyle |= TVS_LINESATROOT;
+ }
+
if (!iupAttribGetBoolean(ih, "HIDEBUTTONS"))
dwStyle |= TVS_HASBUTTONS;
@@ -2455,6 +2462,11 @@ static int winTreeMapMethod(Ihandle* ih)
if (!iupwinCreateWindowEx(ih, WC_TREEVIEW, 0, dwStyle))
return IUP_ERROR;
+ if (!iupwin_comctl32ver6) /* To improve drawing of items when TITLEFONT is set */
+ SendMessage(ih->handle, CCM_SETVERSION, 5, 0);
+ else
+ SendMessage(ih->handle, TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER);
+
IupSetCallback(ih, "_IUPWIN_CTRLPROC_CB", (Icallback)winTreeProc);
IupSetCallback(ih, "_IUPWIN_NOTIFY_CB", (Icallback)winTreeWmNotify);
@@ -2466,7 +2478,7 @@ static int winTreeMapMethod(Ihandle* ih)
winTreeSetBgColorAttrib(ih, value);
iupAttribSetStr(ih, "BGCOLOR", NULL);
}
- else if (iupwinGetSystemMajorVersion()<6) /* force background in XP because of the editbox background */
+ else if (!iupwin_comctl32ver6 || iupwinGetSystemMajorVersion()<6) /* force background in XP because of the editbox background */
winTreeSetBgColorAttrib(ih, IupGetGlobal("TXTBGCOLOR"));
}
@@ -2475,8 +2487,8 @@ static int winTreeMapMethod(Ihandle* ih)
ih->data->def_image_collapsed = (void*)winTreeGetImageIndex(ih, "IMGCOLLAPSED");
ih->data->def_image_expanded = (void*)winTreeGetImageIndex(ih, "IMGEXPANDED");
- /* Add the Root Node */
- winTreeAddRootNode(ih);
+ if (iupAttribGetInt(ih, "ADDROOT"))
+ iupdrvTreeAddNode(ih, "-1", ITREE_BRANCH, "", 0);
/* configure for DRAG&DROP of files */
if (IupGetCallback(ih, "DROPFILES_CB"))
@@ -2484,9 +2496,31 @@ static int winTreeMapMethod(Ihandle* ih)
IupSetCallback(ih, "_IUP_XY2POS_CB", (Icallback)winTreeConvertXYToPos);
+ iupdrvTreeUpdateMarkMode(ih);
+
return IUP_NOERROR;
}
+static void winTreeUnMapMethod(Ihandle* ih)
+{
+ Iarray* bmp_array;
+ HIMAGELIST image_list;
+
+ winTreeRemoveAllNodeData(ih, 0);
+
+ ih->data->node_count = 0;
+
+ image_list = (HIMAGELIST)SendMessage(ih->handle, TVM_GETIMAGELIST, TVSIL_NORMAL, 0);
+ if (image_list)
+ ImageList_Destroy(image_list);
+
+ bmp_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY");
+ if (bmp_array)
+ iupArrayDestroy(bmp_array);
+
+ iupdrvBaseUnMapMethod(ih);
+}
+
void iupdrvTreeInitClass(Iclass* ic)
{
/* Driver Dependent Class functions */
@@ -2500,7 +2534,6 @@ void iupdrvTreeInitClass(Iclass* ic)
/* IupTree Attributes - GENERAL */
iupClassRegisterAttribute(ic, "EXPANDALL", NULL, winTreeSetExpandAllAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "INDENTATION", winTreeGetIndentationAttrib, winTreeSetIndentationAttrib, NULL, NULL, IUPAF_DEFAULT);
- iupClassRegisterAttribute(ic, "COUNT", winTreeGetCountAttrib, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_READONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "DRAGDROP", NULL, iupwinSetDragDropAttrib, NULL, NULL, IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "SPACING", iupTreeGetSpacingAttrib, winTreeSetSpacingAttrib, NULL, NULL, IUPAF_NOT_MAPPED);
iupClassRegisterAttribute(ic, "TOPITEM", NULL, winTreeSetTopItemAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
@@ -2521,7 +2554,6 @@ void iupdrvTreeInitClass(Iclass* ic)
iupClassRegisterAttributeId(ic, "NAME", winTreeGetTitleAttrib, winTreeSetTitleAttrib, IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "TITLE", winTreeGetTitleAttrib, winTreeSetTitleAttrib, IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "CHILDCOUNT", winTreeGetChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
- iupClassRegisterAttributeId(ic, "USERDATA", winTreeGetUserDataAttrib, winTreeSetUserDataAttrib, IUPAF_NO_STRING|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "COLOR", winTreeGetColorAttrib, winTreeSetColorAttrib, IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "TITLEFONT", winTreeGetTitleFontAttrib, winTreeSetTitleFontAttrib, IUPAF_NO_INHERIT);
@@ -2530,6 +2562,7 @@ void iupdrvTreeInitClass(Iclass* ic)
iupClassRegisterAttribute (ic, "MARK", NULL, winTreeSetMarkAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttribute (ic, "STARTING", NULL, winTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttribute (ic, "MARKSTART", NULL, winTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute (ic, "MARKEDNODES", winTreeGetMarkedNodesAttrib, winTreeSetMarkedNodesAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttribute (ic, "VALUE", winTreeGetValueAttrib, winTreeSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
@@ -2538,5 +2571,8 @@ void iupdrvTreeInitClass(Iclass* ic)
iupClassRegisterAttribute(ic, "RENAME", NULL, winTreeSetRenameAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "MOVENODE", NULL, winTreeSetMoveNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "COPYNODE", NULL, winTreeSetCopyNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
- iupClassRegisterAttributeId(ic, "FINDUSERDATA", winTreeGetFindUserDataAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+
+ /* necessary because transparent background does not work when not using visual styles */
+ if (!iupwin_comctl32ver6) /* Used by iupdrvImageCreateImage */
+ iupClassRegisterAttribute(ic, "FLAT_ALPHA", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
}
diff --git a/iup/src/win/iupwin_val.c b/iup/src/win/iupwin_val.c
index 706c612..5c956d9 100755
--- a/iup/src/win/iupwin_val.c
+++ b/iup/src/win/iupwin_val.c
@@ -56,6 +56,13 @@ void iupdrvValGetMinSize(Ihandle* ih, int *w, int *h)
}
}
+static int winValSetBgColorAttrib(Ihandle *ih, const char *value)
+{
+ (void)value;
+ iupdrvPostRedraw(ih);
+ return 1;
+}
+
static int winValSetStepAttrib(Ihandle* ih, const char* value)
{
int linesize;
@@ -110,18 +117,6 @@ static int winValSetValueAttrib(Ihandle* ih, const char* value)
/*********************************************************************************************/
-static int winValCtlColor(Ihandle* ih, HDC hdc, LRESULT *result)
-{
- COLORREF cr;
- if (iupwinGetParentBgColor(ih, &cr))
- {
- SetDCBrushColor(hdc, cr);
- *result = (LRESULT)GetStockObject(DC_BRUSH);
- return 1;
- }
- return 0;
-}
-
static int winValCustomScroll(Ihandle* ih, int msg)
{
double old_val = ih->data->val;
@@ -190,6 +185,19 @@ static void winValIncPageValue(Ihandle *ih, int dir)
winValCustomScroll(ih, 0);
}
+static int winValCtlColor(Ihandle* ih, HDC hdc, LRESULT *result)
+{
+ COLORREF cr;
+ if (iupwinGetParentBgColor(ih, &cr))
+ {
+ SetBkColor(hdc, cr);
+ SetDCBrushColor(hdc, cr);
+ *result = (LRESULT)GetStockObject(DC_BRUSH);
+ return 1;
+ }
+ return 0;
+}
+
static int winValProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result)
{
(void)lp;
@@ -240,7 +248,7 @@ static int winValProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *resu
static int winValMapMethod(Ihandle* ih)
{
- DWORD dwStyle = WS_CHILD | TBS_AUTOTICKS;
+ DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | TBS_AUTOTICKS;
int show_ticks;
if (!ih->parent)
@@ -312,4 +320,7 @@ void iupdrvValInitClass(Iclass* ic)
iupClassRegisterAttribute(ic, "STEP", iupValGetStepAttrib, winValSetStepAttrib, "0.01", NULL, IUPAF_NO_INHERIT); /* force new default value */
iupClassRegisterAttribute(ic, "TICKSPOS", NULL, NULL, "NORMAL", NULL, IUPAF_NOT_MAPPED);
+
+ /* Visual */
+ iupClassRegisterAttribute(ic, "BGCOLOR", NULL, winValSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
}