JD2022-TU1/main/extern/Camcam/TestApp/Docking.cpp

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(&regRect, 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, &regRect))
{
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, &regRectCurrent, &regShiftCurrent))
return false;
if (!GetRectRegion(wnd, &regRectDst, &regShiftDst))
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, &regRectCurrent, NULL))
return false;
if (!GetRectRegion(wnd, &regRectDst, 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;
}