316 lines
No EOL
6.7 KiB
C++
316 lines
No EOL
6.7 KiB
C++
|
|
#include "Scene.h"
|
|
|
|
extern void TrackerSetWindow(s32 X,s32 Y,s32 Sizex , s32 SizeY , s32 Visible , s32 Border, HWND putAfter);
|
|
|
|
BOOL GetRectRegion(HWND wnd, RECT *rect, SIZE *shift)
|
|
{
|
|
RECT regRect;
|
|
memset(®Rect, 0, sizeof(RECT));
|
|
memset(rect, 0, sizeof(RECT));
|
|
|
|
if (!GetWindowRect(wnd, rect))
|
|
return false;
|
|
|
|
HRGN reg = CreateRectRgn(0, 0, 0, 0);
|
|
if (GetWindowRgn(wnd, reg) != ERROR)
|
|
{
|
|
if (!GetRgnBox(reg, ®Rect))
|
|
{
|
|
DeleteObject(reg);
|
|
return false;
|
|
}
|
|
} else
|
|
{
|
|
regRect.right = rect->right - rect->left;
|
|
regRect.bottom = rect->bottom - rect->top;
|
|
}
|
|
DeleteObject(reg);
|
|
|
|
if (regRect.left != regRect.right &&
|
|
regRect.top != regRect.bottom)
|
|
{
|
|
rect->left += regRect.left;
|
|
rect->right = rect->left + (regRect.right - regRect.left);
|
|
rect->top += regRect.top;
|
|
rect->bottom = rect->top + (regRect.bottom - regRect.top);
|
|
}
|
|
if (shift)
|
|
{
|
|
shift->cx = regRect.left;
|
|
shift->cy = regRect.top;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
int DockToWindow(HWND OwnerHwnd, HWND wnd, u32 dockMask, int posX, int posY, int PutAfter)
|
|
{
|
|
int dockX, dockY;
|
|
RECT regRectCurrent, regRectDst;
|
|
SIZE regShiftCurrent, regShiftDst;
|
|
|
|
if (!GetRectRegion(OwnerHwnd, ®RectCurrent, ®ShiftCurrent))
|
|
return false;
|
|
if (!GetRectRegion(wnd, ®RectDst, ®ShiftDst))
|
|
return false;
|
|
|
|
if (dockMask & 1)
|
|
{
|
|
switch (posX)
|
|
{
|
|
case 1: // dock IN left
|
|
dockX = regRectDst.left;
|
|
break;
|
|
case 2: // dock IN right
|
|
dockX = regRectDst.right - (regRectCurrent.right - regRectCurrent.left);
|
|
break;
|
|
case 3: // dock OUT left of dst
|
|
dockX = regRectDst.left - (regRectCurrent.right - regRectCurrent.left);
|
|
break;
|
|
case 4: // dock OUT right of dst
|
|
dockX = regRectDst.right;
|
|
break;
|
|
default:
|
|
dockX = regRectCurrent.left;
|
|
}
|
|
} else
|
|
dockX = posX + regShiftCurrent.cx;
|
|
|
|
if (dockMask & 2)
|
|
{
|
|
switch (posY)
|
|
{
|
|
case 1: // dock IN top
|
|
dockY = regRectDst.top;
|
|
break;
|
|
case 2: // dock IN bottom
|
|
dockY = regRectDst.bottom - (regRectCurrent.bottom - regRectCurrent.top);
|
|
break;
|
|
case 3: // dock OUT top of dst
|
|
dockY = regRectDst.top - (regRectCurrent.bottom - regRectCurrent.top);
|
|
break;
|
|
case 4: // dock OUT bottom of the dst
|
|
dockY = regRectDst.bottom;
|
|
break;
|
|
default:
|
|
dockY = regRectCurrent.top;
|
|
}
|
|
} else
|
|
dockY = posY + regShiftCurrent.cy;
|
|
|
|
if (dockX != regRectCurrent.left ||
|
|
dockY != regRectCurrent.top)
|
|
{
|
|
dockX -= regShiftCurrent.cx;
|
|
dockY -= regShiftCurrent.cy;
|
|
|
|
if (PutAfter)
|
|
TrackerSetWindow(dockX,dockY,-1,-1,-1,-1, wnd);
|
|
else
|
|
TrackerSetWindow(dockX,dockY,-1,-1,-1,-1,(HWND)-1);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int IsWindowNeer(HWND OwnerHwnd, HWND wnd, int margePixels, int deltaX, int deltaY, int *posX, int *posY)
|
|
{
|
|
RECT regRectCurrent;
|
|
RECT regRectDst;
|
|
*posX = 0;
|
|
*posY = 0;
|
|
|
|
if (!GetRectRegion(OwnerHwnd, ®RectCurrent, NULL))
|
|
return false;
|
|
if (!GetRectRegion(wnd, ®RectDst, NULL))
|
|
return false;
|
|
|
|
regRectCurrent.left += deltaX;
|
|
regRectCurrent.right += deltaX;
|
|
regRectCurrent.top += deltaY;
|
|
regRectCurrent.bottom += deltaY;
|
|
|
|
if (abs(regRectDst.left - regRectCurrent.left) <= margePixels)
|
|
*posX = 1;
|
|
if (abs(regRectDst.right - regRectCurrent.right) <= margePixels)
|
|
*posX = 2;
|
|
if (abs(regRectDst.left - regRectCurrent.right) <= margePixels)
|
|
*posX = 3;
|
|
if (abs(regRectDst.right - regRectCurrent.left) <= margePixels)
|
|
*posX = 4;
|
|
|
|
if (abs(regRectDst.top - regRectCurrent.top) <= margePixels)
|
|
*posY = 1;
|
|
if (abs(regRectDst.bottom - regRectCurrent.bottom) <= margePixels)
|
|
*posY = 2;
|
|
if (abs(regRectDst.top - regRectCurrent.bottom) <= margePixels)
|
|
*posY = 3;
|
|
if (abs(regRectDst.bottom - regRectCurrent.top) <= margePixels)
|
|
*posY = 4;
|
|
|
|
return *posX || *posY;
|
|
}
|
|
|
|
typedef struct WndInfo_
|
|
{
|
|
HWND wnd;
|
|
char wndName[512];
|
|
int nbMatch;
|
|
} WndInfo;
|
|
|
|
BOOL CALLBACK EnumWindowByName(HWND hwnd, LPARAM lParam)
|
|
{
|
|
WndInfo *wndInfoPtr = (WndInfo *)lParam;
|
|
char wndName[512];
|
|
|
|
GetWindowText(hwnd, wndName, 512);
|
|
if (!strcmp(wndInfoPtr->wndName, wndName))
|
|
{
|
|
wndInfoPtr->wnd = hwnd;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#define NB_WND_CACHE 16
|
|
static WndInfo wndCache[NB_WND_CACHE];
|
|
static int wndCacheNb = 0;
|
|
|
|
|
|
HWND GetWindowByName(char *name)
|
|
{
|
|
if (!wndCacheNb)
|
|
memset(wndCache, 0, sizeof(wndCache));
|
|
|
|
for (int i=0; i<wndCacheNb; i++)
|
|
{
|
|
if (!strcmp(name, wndCache[i].wndName))
|
|
{
|
|
wndCache[i].nbMatch++;
|
|
return wndCache[i].wnd;
|
|
}
|
|
}
|
|
|
|
WndInfo wndInfo;
|
|
wndInfo.wnd = 0;
|
|
strcpy(wndInfo.wndName, name);
|
|
|
|
EnumWindows(EnumWindowByName,(WPARAM)&wndInfo);
|
|
if (wndCacheNb < NB_WND_CACHE)
|
|
{
|
|
wndCache[wndCacheNb] = wndInfo;
|
|
wndCache[wndCacheNb].nbMatch = 1;
|
|
wndCacheNb++;
|
|
} else
|
|
{
|
|
int minMatch = wndCache[0].nbMatch;
|
|
int minIndex = 0;
|
|
for (int i=1; i<NB_WND_CACHE; i++)
|
|
{
|
|
if (wndCache[i].nbMatch < minMatch)
|
|
{
|
|
minMatch = wndCache[i].nbMatch;
|
|
minIndex = i;
|
|
}
|
|
}
|
|
wndCache[minIndex] = wndInfo;
|
|
wndCache[minIndex].nbMatch = 1;
|
|
}
|
|
return wndInfo.wnd;
|
|
}
|
|
|
|
int RemoveWindowFromCache(char *name)
|
|
{
|
|
for (int i=0; i<wndCacheNb; i++)
|
|
{
|
|
if (!strcmp(name, wndCache[i].wndName))
|
|
{
|
|
memset(&wndCache[i], 0, sizeof(WndInfo));
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ClearCache()
|
|
{
|
|
wndCacheNb = 0;
|
|
memset(wndCache, 0, sizeof(wndCache));
|
|
}
|
|
|
|
|
|
typedef struct ExprList_
|
|
{
|
|
char expr[512];
|
|
char **nameList;
|
|
int nbName;
|
|
int nbAlloc;
|
|
} ExprList;
|
|
|
|
|
|
int SimpleExprTest(char *expr, char *strToTest)
|
|
{
|
|
char exprToSearch[512];
|
|
int exprToSearchLen = 0;
|
|
char *localStr;
|
|
int SMode = 0;
|
|
|
|
memset(exprToSearch, 0, sizeof(exprToSearch));
|
|
while (*expr)
|
|
{
|
|
if (*expr == '*')
|
|
{
|
|
if (exprToSearchLen > 0)
|
|
{
|
|
localStr = strstr(strToTest, exprToSearch);
|
|
if (!localStr)
|
|
return false;
|
|
strToTest = localStr + exprToSearchLen;
|
|
memset(exprToSearch, 0, sizeof(exprToSearch));
|
|
exprToSearchLen = 0;
|
|
}
|
|
} else
|
|
{
|
|
exprToSearch[exprToSearchLen++] = *expr;
|
|
}
|
|
expr++;
|
|
}
|
|
if (exprToSearchLen > 0)
|
|
{
|
|
if (strlen(strToTest) < exprToSearchLen ||
|
|
strcmp(strToTest+(strlen(strToTest)-exprToSearchLen), exprToSearch))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
BOOL CALLBACK EnumWindowByExpr(HWND hwnd, LPARAM lParam)
|
|
{
|
|
ExprList *exprList = (ExprList *)lParam;
|
|
char wndName[512];
|
|
|
|
GetWindowText(hwnd, wndName, 512);
|
|
if (SimpleExprTest(exprList->expr, wndName))
|
|
{
|
|
if (exprList->nbAlloc >= exprList->nbName)
|
|
{
|
|
exprList->nbAlloc += 8;
|
|
if (!exprList->nameList) exprList->nameList = (char **)CC_malloc(exprList->nbAlloc*sizeof(char *));
|
|
else exprList->nameList = (char **)CC_realloc(exprList->nameList, exprList->nbAlloc*sizeof(char *));
|
|
}
|
|
exprList->nameList[exprList->nbName++] = strdup(wndName);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
char ** GetWindowsByExpression(char *expr, int *nbElmts)
|
|
{
|
|
ExprList exprList;
|
|
memset(&exprList, 0, sizeof(ExprList));
|
|
strcpy(exprList.expr, expr);
|
|
|
|
EnumWindows(EnumWindowByExpr,(WPARAM)&exprList);
|
|
*nbElmts = exprList.nbName;
|
|
return exprList.nameList;
|
|
} |