summaryrefslogtreecommitdiff
path: root/iup/src/win/iupwin_globalattrib.c
diff options
context:
space:
mode:
Diffstat (limited to 'iup/src/win/iupwin_globalattrib.c')
-rwxr-xr-xiup/src/win/iupwin_globalattrib.c88
1 files changed, 84 insertions, 4 deletions
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;
}