summaryrefslogtreecommitdiff
path: root/iup/src/win
diff options
context:
space:
mode:
authorNicolas "Pixel" Noble <pixel@nobis-crew.org>2010-09-09 02:26:30 +0200
committerNicolas "Pixel" Noble <pixel@nobis-crew.org>2010-09-09 02:32:26 +0200
commit7505e88db66798b2b8fcdff2d92a7136cd826b5b (patch)
treeb6ced565318f8e8112e35cb0ad53abe4212ef8de /iup/src/win
parente9a184546b18cf3b796bd560561f312934004c54 (diff)
Upgrading to IUP 3.2 - and cleaning up.
Diffstat (limited to 'iup/src/win')
-rwxr-xr-xiup/src/win/iupwin_clipboard.c160
-rwxr-xr-xiup/src/win/iupwin_common.c10
-rwxr-xr-xiup/src/win/iupwin_dialog.c7
-rwxr-xr-xiup/src/win/iupwin_globalattrib.c88
-rwxr-xr-xiup/src/win/iupwin_loop.c21
-rwxr-xr-xiup/src/win/iupwin_tree.c50
6 files changed, 300 insertions, 36 deletions
diff --git a/iup/src/win/iupwin_clipboard.c b/iup/src/win/iupwin_clipboard.c
index 1e0fab4..debad0d 100755
--- a/iup/src/win/iupwin_clipboard.c
+++ b/iup/src/win/iupwin_clipboard.c
@@ -20,6 +20,136 @@
#include "iupwin_drv.h"
+typedef struct _APMFILEHEADER
+{
+ WORD key1,
+ key2,
+ hmf,
+ bleft, btop, bright, bbottom,
+ inch,
+ reserved1,
+ reserved2,
+ checksum;
+} APMFILEHEADER;
+
+static WORD winAPMChecksum(APMFILEHEADER* papm)
+{
+ WORD* pw = (WORD*)papm;
+ WORD wSum = 0;
+ int i;
+
+ /* The checksum in a Placeable Metafile header is calculated */
+ /* by XOR-ing the first 10 words of the header. */
+
+ for (i = 0; i < 10; i++)
+ wSum ^= *pw++;
+
+ return wSum;
+}
+
+static void winWritePlacebleFile(HANDLE hFile, unsigned char* buffer, DWORD dwSize, LONG mm, LONG xExt, LONG yExt)
+{
+ DWORD nBytesWrite;
+ APMFILEHEADER APMHeader;
+ int w = xExt, h = yExt;
+
+ if (mm == MM_ANISOTROPIC || mm == MM_ISOTROPIC)
+ {
+ int res = 30;
+ w = xExt / res;
+ h = yExt / res;
+ }
+
+ APMHeader.key1 = 0xCDD7;
+ APMHeader.key2 = 0x9AC6;
+ APMHeader.hmf = 0;
+ APMHeader.bleft = 0;
+ APMHeader.btop = 0;
+ APMHeader.bright = (short)w;
+ APMHeader.bbottom = (short)h;
+ APMHeader.inch = 100; /* this number works fine in Word, etc.. */
+ APMHeader.reserved1 = 0;
+ APMHeader.reserved2 = 0;
+ APMHeader.checksum = winAPMChecksum(&APMHeader);
+
+ WriteFile(hFile, (LPSTR)&APMHeader, sizeof(APMFILEHEADER), &nBytesWrite, NULL);
+ WriteFile(hFile, buffer, dwSize, &nBytesWrite, NULL);
+}
+
+static int winClipboardSetSaveEMFAttrib(Ihandle *ih, const char *value)
+{
+ HENHMETAFILE Handle;
+ DWORD dwSize, nBytesWrite;
+ unsigned char* buffer;
+ HANDLE hFile;
+ (void)ih;
+
+ OpenClipboard(NULL);
+ Handle = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE);
+ if (Handle == NULL)
+ {
+ CloseClipboard();
+ return 0;
+ }
+
+ dwSize = GetEnhMetaFileBits(Handle, 0, NULL);
+
+ buffer = (unsigned char*)malloc(dwSize);
+
+ GetEnhMetaFileBits(Handle, dwSize, buffer);
+
+ hFile = CreateFile(value, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ if (hFile)
+ {
+ WriteFile(hFile, buffer, dwSize, &nBytesWrite, NULL);
+ CloseHandle(hFile);
+ }
+
+ free(buffer);
+
+ CloseClipboard();
+ return 0;
+}
+
+static int winClipboardSetSaveWMFAttrib(Ihandle *ih, const char *value)
+{
+ DWORD dwSize;
+ unsigned char* buffer;
+ METAFILEPICT* lpMFP;
+ HANDLE Handle;
+ HANDLE hFile;
+ (void)ih;
+
+ OpenClipboard(NULL);
+ Handle = (HENHMETAFILE)GetClipboardData(CF_METAFILEPICT);
+ if (Handle == NULL)
+ {
+ CloseClipboard();
+ return 0;
+ }
+
+ lpMFP = (METAFILEPICT*) GlobalLock(Handle);
+
+ dwSize = GetMetaFileBitsEx(lpMFP->hMF, 0, NULL);
+
+ buffer = (unsigned char*)malloc(dwSize);
+
+ GetMetaFileBitsEx(lpMFP->hMF, dwSize, buffer);
+
+ hFile = CreateFile(value, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ if (hFile)
+ {
+ winWritePlacebleFile(hFile, buffer, dwSize, lpMFP->mm, lpMFP->xExt, lpMFP->yExt);
+ CloseHandle(hFile);
+ }
+
+ GlobalUnlock(Handle);
+ free(buffer);
+
+ CloseClipboard();
+ return 0;
+}
+
static int winClipboardSetTextAttrib(Ihandle *ih, const char *value)
{
HANDLE hHandle;
@@ -162,6 +292,32 @@ static char* winClipboardGetImageAvailableAttrib(Ihandle *ih)
return "NO";
}
+static char* winClipboardGetWMFAvailableAttrib(Ihandle *ih)
+{
+ int check;
+ (void)ih;
+ OpenClipboard(NULL);
+ check = IsClipboardFormatAvailable(CF_METAFILEPICT);
+ CloseClipboard();
+ if (check)
+ return "YES";
+ else
+ return "NO";
+}
+
+static char* winClipboardGetEMFAvailableAttrib(Ihandle *ih)
+{
+ int check;
+ (void)ih;
+ OpenClipboard(NULL);
+ check = IsClipboardFormatAvailable(CF_ENHMETAFILE);
+ CloseClipboard();
+ if (check)
+ return "YES";
+ else
+ return "NO";
+}
+
/******************************************************************************/
Ihandle* IupClipboard(void)
@@ -185,6 +341,10 @@ Iclass* iupClipboardGetClass(void)
iupClassRegisterAttribute(ic, "IMAGE", NULL, winClipboardSetImageAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "TEXTAVAILABLE", winClipboardGetTextAvailableAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "IMAGEAVAILABLE", winClipboardGetImageAvailableAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "WMFAVAILABLE", winClipboardGetWMFAvailableAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "EMFAVAILABLE", winClipboardGetEMFAvailableAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "SAVEEMF", NULL, winClipboardSetSaveEMFAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "SAVEWMF", NULL, winClipboardSetSaveWMFAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
return ic;
}
diff --git a/iup/src/win/iupwin_common.c b/iup/src/win/iupwin_common.c
index ba68b78..0f53e68 100755
--- a/iup/src/win/iupwin_common.c
+++ b/iup/src/win/iupwin_common.c
@@ -372,7 +372,7 @@ int iupwinBaseContainerProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT
case WM_CTLCOLORSTATIC:
{
Ihandle* child = iupwinHandleGet((void*)lp);
- if (child)
+ if (child && iupChildTreeGetNativeParent(child)==ih)
{
IFctlColor cb = (IFctlColor)IupGetCallback(child, "_IUPWIN_CTLCOLOR_CB");
if (cb)
@@ -390,7 +390,11 @@ int iupwinBaseContainerProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT
if (wp == 0) /* a menu */
child = iupwinMenuGetItemHandle((HMENU)drawitem->hwndItem, drawitem->itemID);
else
+ {
child = iupwinHandleGet(drawitem->hwndItem);
+ if (child && iupChildTreeGetNativeParent(child)!=ih)
+ child = NULL;
+ }
if (child)
{
@@ -408,7 +412,7 @@ int iupwinBaseContainerProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT
case WM_VSCROLL:
{
Ihandle *child = iupwinHandleGet((void*)lp);
- if (child)
+ if (child && iupChildTreeGetNativeParent(child)==ih)
{
IFni cb = (IFni)IupGetCallback(child, "_IUPWIN_CUSTOMSCROLL_CB");
if (cb)
@@ -426,7 +430,7 @@ int iupwinBaseContainerProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT
break;
child = iupwinHandleGet(msg_info->hwndFrom);
- if (child)
+ if (child && iupChildTreeGetNativeParent(child)==ih)
{
IFnotify cb = (IFnotify)IupGetCallback(child, "_IUPWIN_NOTIFY_CB");
if (cb)
diff --git a/iup/src/win/iupwin_dialog.c b/iup/src/win/iupwin_dialog.c
index c13b88d..93fe404 100755
--- a/iup/src/win/iupwin_dialog.c
+++ b/iup/src/win/iupwin_dialog.c
@@ -423,6 +423,13 @@ static int winDialogBaseProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESUL
*result = 0;
return 1;
}
+ case WM_COPYDATA: /* usually from SetGlobal("SINGLEINSTANCE") */
+ {
+ COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lp;
+ IFnsi cb = (IFnsi)IupGetCallback(ih, "COPYDATA_CB");
+ if (cb) cb(ih, cds->lpData, cds->cbData);
+ break;
+ }
case WM_SETCURSOR:
{
if (ih->handle == (HWND)wp && LOWORD(lp)==HTCLIENT)
diff --git a/iup/src/win/iupwin_globalattrib.c b/iup/src/win/iupwin_globalattrib.c
index bcd6355..2d27ca5 100755
--- a/iup/src/win/iupwin_globalattrib.c
+++ b/iup/src/win/iupwin_globalattrib.c
@@ -17,13 +17,81 @@
#include "iupwin_drv.h"
-static int win_monitor_index = 0;
-
/* Not defined in compilers older than VC9 */
#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC (0)
#endif
+
+static int win_monitor_index = 0;
+static HANDLE win_singleintance = NULL;
+static HWND win_findwindow = NULL;
+
+
+static int winGlobalSetMutex(const char* name)
+{
+ if (win_singleintance)
+ ReleaseMutex(win_singleintance);
+
+ /* try to create a mutex (will fail if already one of that name) */
+ win_singleintance = CreateMutex(NULL, FALSE, name);
+
+ /* Return TRUE if existing semaphore opened */
+ if (win_singleintance != NULL && GetLastError()==ERROR_ALREADY_EXISTS)
+ {
+ CloseHandle(win_singleintance);
+ return 1;
+ }
+
+ /* wasn’t found, new one created therefore return FALSE */
+ return (win_singleintance == NULL);
+}
+
+static BOOL CALLBACK winGlobalEnumWindowProc(HWND hWnd, LPARAM lParam)
+{
+ char* name = (char*)lParam;
+ char str[256];
+ int len = GetWindowText(hWnd, str, 256);
+ if (len)
+ {
+ if (iupStrEqualPartial(str, name))
+ {
+ win_findwindow = hWnd;
+ return FALSE;
+ }
+ }
+
+ return TRUE; /* continue searching */
+}
+
+static HWND winGlobalFindWindow(const char* name)
+{
+ win_findwindow = NULL;
+ EnumWindows(winGlobalEnumWindowProc, (LPARAM)name);
+ return win_findwindow;
+}
+
+static void winGlobalFindInstance(const char* name)
+{
+ HWND hWnd = winGlobalFindWindow(name);
+ if (hWnd)
+ {
+ LPTSTR cmdLine = GetCommandLine();
+
+ SetForegroundWindow(hWnd);
+
+ /* Command line is not empty. Send it to the first instance. */
+ if (strlen(cmdLine) != 0)
+ {
+ COPYDATASTRUCT cds;
+ cds.dwData = (ULONG_PTR)"IUP_DATA";
+ cds.cbData = strlen(cmdLine)+1;
+ cds.lpData = cmdLine;
+ SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)&cds);
+ }
+ }
+}
+
static void winGlobalSendKey(int key, int press)
{
unsigned int keyval, state;
@@ -103,7 +171,7 @@ static void winGlobalSendKey(int key, int press)
}
}
-static BOOL CALLBACK winMonitorInfoEnum(HMONITOR handle, HDC handle_dc, LPRECT rect, LPARAM data)
+static BOOL CALLBACK winGlobalMonitorInfoEnum(HMONITOR handle, HDC handle_dc, LPRECT rect, LPARAM data)
{
RECT* monitors_rect = (RECT*)data;
monitors_rect[win_monitor_index] = *rect;
@@ -153,6 +221,16 @@ int iupdrvSetGlobal(const char *name, const char *value)
iupwin_dll_hinstance = (HINSTANCE)value;
return 0;
}
+ if (iupStrEqual(name, "SINGLEINSTANCE"))
+ {
+ if (winGlobalSetMutex(value))
+ {
+ winGlobalFindInstance(value);
+ return 0; /* don't save the attribute, mutex already exist */
+ }
+ else
+ return 1; /* save the attribute, this is the first instance */
+ }
return 1;
}
@@ -230,7 +308,7 @@ char *iupdrvGetGlobal(const char *name)
char* pstr = str;
win_monitor_index = 0;
- EnumDisplayMonitors(NULL, NULL, winMonitorInfoEnum, (LPARAM)monitors_rect);
+ EnumDisplayMonitors(NULL, NULL, winGlobalMonitorInfoEnum, (LPARAM)monitors_rect);
for (i=0; i < monitors_count; i++)
pstr += sprintf(pstr, "%d %d %d %d\n", (int)monitors_rect[i].left, (int)monitors_rect[i].top, (int)(monitors_rect[i].right-monitors_rect[i].left), (int)(monitors_rect[i].bottom-monitors_rect[i].top));
@@ -245,6 +323,8 @@ char *iupdrvGetGlobal(const char *name)
return "NO";
}
if (iupStrEqual(name, "DLL_HINSTANCE"))
+ {
return (char*)iupwin_dll_hinstance;
+ }
return NULL;
}
diff --git a/iup/src/win/iupwin_loop.c b/iup/src/win/iupwin_loop.c
index fd25537..4bcf38c 100755
--- a/iup/src/win/iupwin_loop.c
+++ b/iup/src/win/iupwin_loop.c
@@ -30,6 +30,19 @@ void iupdrvSetIdleFunction(Icallback f)
win_idle_cb = (IFidle)f;
}
+static int winLoopCallIdle(void)
+{
+ int ret = win_idle_cb();
+ if (ret == IUP_CLOSE)
+ {
+ win_idle_cb = NULL;
+ return IUP_CLOSE;
+ }
+ if (ret == IUP_IGNORE)
+ win_idle_cb = NULL;
+ return ret;
+}
+
void IupExitLoop(void)
{
PostQuitMessage(0);
@@ -74,15 +87,11 @@ int IupMainLoop(void)
}
else
{
- int ret = win_idle_cb();
- if (ret == IUP_CLOSE)
+ if (winLoopCallIdle() == IUP_CLOSE)
{
- win_idle_cb = NULL;
win_main_loop--;
return IUP_CLOSE;
}
- if (ret == IUP_IGNORE)
- win_idle_cb = NULL;
}
}
else
@@ -123,6 +132,8 @@ int IupLoopStep(void)
MSG msg;
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
return winLoopProcessMessage(&msg);
+ else if (win_idle_cb)
+ return winLoopCallIdle();
return IUP_DEFAULT;
}
diff --git a/iup/src/win/iupwin_tree.c b/iup/src/win/iupwin_tree.c
index 4a5f8be..4a8d331 100755
--- a/iup/src/win/iupwin_tree.c
+++ b/iup/src/win/iupwin_tree.c
@@ -3,7 +3,6 @@
*
* See Copyright Notice in iup.h
*/
-
#undef NOTREEVIEW
#include <windows.h>
#include <commctrl.h>
@@ -85,16 +84,6 @@ static HTREEITEM winTreeFindNodeXY(Ihandle* ih, int x, int y)
return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info);
}
-static HTREEITEM winTreeFindNodePointed(Ihandle* ih)
-{
- 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);
-}
-
int iupwinGetColor(const char* value, COLORREF *color)
{
unsigned char r, g, b;
@@ -381,7 +370,7 @@ static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItem1, HTREEITEM hItem2,
int i;
int id1 = iupTreeFindNodeId(ih, hItem1);
int id2 = iupTreeFindNodeId(ih, hItem2);
- if (id2 == -1) id2 = ih->data->node_count-1;
+
if (id1 > id2)
{
int tmp = id1;
@@ -403,13 +392,19 @@ static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItem1, HTREEITEM hItem2,
static void winTreeSelectAll(Ihandle* ih)
{
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- winTreeSelectRange(ih, hItemRoot, NULL, 0);
+ int i;
+ for (i = 0; i < ih->data->node_count; i++)
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 1);
}
static void winTreeClearSelection(Ihandle* ih, HTREEITEM hItemExcept)
{
- winTreeSelectRange(ih, hItemExcept, hItemExcept, 1);
+ int i;
+ for (i = 0; i < ih->data->node_count; i++)
+ {
+ if (ih->data->node_cache[i].node_handle != hItemExcept)
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 0);
+ }
}
static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, int id, void* userdata)
@@ -1507,7 +1502,7 @@ static int winTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char*
iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
hItemFocus = iupdrvTreeGetFocusNode(ih);
- for(i = 1; i < ih->data->node_count; /* increment only if not removed */)
+ for(i = 0; i < ih->data->node_count; /* increment only if not removed */)
{
if (winTreeIsNodeSelected(ih, ih->data->node_cache[i].node_handle))
{
@@ -2009,6 +2004,17 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y)
return 0;
}
+static void winTreeCallRightClickCb(Ihandle* ih, int x, int y)
+{
+ HTREEITEM hItem = winTreeFindNodeXY(ih, x, y);
+ if (hItem)
+ {
+ IFni cbRightClick = (IFni)IupGetCallback(ih, "RIGHTCLICK_CB");
+ if (cbRightClick)
+ cbRightClick(ih, iupTreeFindNodeId(ih, hItem));
+ }
+}
+
static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result)
{
switch (msg)
@@ -2150,8 +2156,11 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
}
}
break;
- case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
+ winTreeCallRightClickCb(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ *result = 0;
+ return 1; /* must abort the normal behavior, because it is weird and just causes trouble */
+ case WM_MBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
@@ -2366,13 +2375,6 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
return 1;
}
}
- else if(msg_info->code == NM_RCLICK)
- {
- HTREEITEM hItem = winTreeFindNodePointed(ih);
- IFni cbRightClick = (IFni)IupGetCallback(ih, "RIGHTCLICK_CB");
- if (cbRightClick)
- cbRightClick(ih, iupTreeFindNodeId(ih, hItem));
- }
else if (msg_info->code == NM_CUSTOMDRAW)
{
NMTVCUSTOMDRAW *customdraw = (NMTVCUSTOMDRAW*)msg_info;