diff options
Diffstat (limited to 'iup/src/win/iupwin_globalattrib.c')
-rwxr-xr-x | iup/src/win/iupwin_globalattrib.c | 88 |
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; } |