From 7505e88db66798b2b8fcdff2d92a7136cd826b5b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 9 Sep 2010 02:26:30 +0200 Subject: Upgrading to IUP 3.2 - and cleaning up. --- iup/src/win/iupwin_clipboard.c | 160 ++++++++++++++++++++++++++++++++++++++ iup/src/win/iupwin_common.c | 10 ++- iup/src/win/iupwin_dialog.c | 7 ++ iup/src/win/iupwin_globalattrib.c | 88 ++++++++++++++++++++- iup/src/win/iupwin_loop.c | 21 +++-- iup/src/win/iupwin_tree.c | 50 ++++++------ 6 files changed, 300 insertions(+), 36 deletions(-) (limited to 'iup/src/win') 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 #include @@ -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; -- cgit v1.2.3