--- np2/win9x/winloc.cpp 2003/10/16 17:58:44 1.1.1.1 +++ np2/win9x/winloc.cpp 2003/11/04 19:23:03 1.4 @@ -1,85 +1,706 @@ -#include +#include "compiler.h" +#include "winloc.h" -#define SNAPDOTPULL 12 -#define SNAPDOTREL 16 -static int wingx; -static int wingy; -static int winflg; +enum { + SNAPDOTPULL = 12, + SNAPDOTREL = 16 +}; -void winloc_movingstart(void) { - wingx = 0; - wingy = 0; - winflg = 0; +void winloc_setclientsize(HWND hwnd, int width, int height) { + + RECT rectDisktop; + int scx; + int scy; + UINT cnt; + RECT rectWindow; + RECT rectClient; + int x, y, w, h; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDisktop, 0); + scx = GetSystemMetrics(SM_CXSCREEN); + scy = GetSystemMetrics(SM_CYSCREEN); + + cnt = 2; + do { + GetWindowRect(hwnd, &rectWindow); + GetClientRect(hwnd, &rectClient); + w = width + (rectWindow.right - rectWindow.left) + - (rectClient.right - rectClient.left); + h = height + (rectWindow.bottom - rectWindow.top) + - (rectClient.bottom - rectClient.top); + + x = rectWindow.left; + y = rectWindow.top; + if (scx < w) { + x = (scx - w) / 2; + } + else { + if ((x + w) > rectDisktop.right) { + x = rectDisktop.right - w; + } + if (x < rectDisktop.left) { + x = rectDisktop.left; + } + } + if (scy < h) { + y = (scy - h) / 2; + } + else { + if ((y + h) > rectDisktop.bottom) { + y = rectDisktop.bottom - h; + } + if (y < rectDisktop.top) { + y = rectDisktop.top; + } + } + MoveWindow(hwnd, x, y, w, h, TRUE); + } while(--cnt); +} + + +// ---- + +void winloc_movingstart(WINLOC *wl) { + + ZeroMemory(wl, sizeof(WINLOC)); } -void winloc_movingproc(RECT *prc) { +void winloc_movingproc(WINLOC *wl, RECT *rect) { RECT workrc; - int winlx, winly; - int mv1, mv2; + int winlx; + int winly; + int d; SystemParametersInfo(SPI_GETWORKAREA, 0, &workrc, 0); - winlx = prc->right - prc->left; - winly = prc->bottom - prc->top; + winlx = rect->right - rect->left; + winly = rect->bottom - rect->top; if ((winlx > (workrc.right - workrc.left)) || (winly > (workrc.bottom - workrc.top))) { return; } - mv1 = prc->left - workrc.left; - mv2 = prc->right - workrc.right; - if (winflg & 1) { - wingx += mv1; - prc->left = workrc.left; - } - else if (winflg & 2) { - wingx += mv2; - prc->left = workrc.right - winlx; - } - else if ((mv1 < SNAPDOTPULL) && (mv1 > -SNAPDOTPULL)) { - wingx += mv1; - prc->left = workrc.left; - winflg |= 1; - } - else if ((mv2 < SNAPDOTPULL) && (mv2 > -SNAPDOTPULL)) { - wingx += mv2; - prc->left = workrc.right - winlx; - winflg |= 2; - } - if ((wingx >= SNAPDOTREL) || (wingx <= -SNAPDOTREL)) { - prc->left += wingx; - wingx = 0; - winflg &= (~3); - } - prc->right = prc->left + winlx; - - mv1 = prc->top - workrc.top; - mv2 = prc->bottom - workrc.bottom; - if (winflg & 4) { - wingy += mv1; - prc->top = workrc.top; - } - else if (winflg & 8) { - wingy += mv2; - prc->top = workrc.bottom - winly; - } - else if ((mv1 < SNAPDOTPULL) && (mv1 > -SNAPDOTPULL)) { - wingy += mv1; - prc->top = workrc.top; - winflg |= 4; - } - else if ((mv2 < SNAPDOTPULL) && (mv2 > -SNAPDOTPULL)) { - wingy += mv2; - prc->top = workrc.bottom - winly; - winflg |= 8; - } - if ((wingy >= SNAPDOTREL) || (wingy <= -SNAPDOTREL)) { - prc->top += wingy; - wingy = 0; - winflg &= (~0xc); + + if (wl->flag & 1) { + wl->gx += rect->left - wl->tx; + rect->left = wl->tx; + if ((wl->gx >= SNAPDOTREL) || (wl->gx <= -SNAPDOTREL)) { + wl->flag &= ~1; + rect->left += wl->gx; + wl->gx = 0; + } + rect->right = rect->left + winlx; + } + if (wl->flag & 2) { + wl->gy += rect->top - wl->ty; + rect->top = wl->ty; + if ((wl->gy >= SNAPDOTREL) || (wl->gy <= -SNAPDOTREL)) { + wl->flag &= ~2; + rect->top += wl->gy; + wl->gy = 0; + } + rect->bottom = rect->top + winly; + } + + if (!(wl->flag & 1)) { + do { + d = rect->left - workrc.left; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = rect->right - workrc.right; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } while(0); + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + rect->left -= d; + rect->right = rect->left + winlx; + wl->flag |= 1; + wl->gx = d; + wl->tx = rect->left; + } + } + if (!(wl->flag & 2)) { + do { + d = rect->top - workrc.top; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = rect->bottom - workrc.bottom; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } while(0); + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + rect->top -= d; + rect->bottom = rect->top + winly; + wl->flag |= 2; + wl->gy = d; + wl->ty = rect->top; + } + } +} + + +// ---- + +static BYTE isconnect(const RECT *parent, const RECT *self) { + + BYTE connect; + + connect = 0; + if ((self->bottom >= parent->top) && (self->top <= parent->bottom)) { + if (self->right == parent->left) { + connect += 1; + } + else if (self->left == parent->right) { + connect += 2; + } + } + if ((!(connect & 0x0f)) && + ((self->bottom == parent->top) || (self->top == parent->bottom))) { + if (self->left == parent->left) { + connect += 3; + } + else if (self->right == parent->right) { + connect += 4; + } + } + + if ((self->right >= parent->left) && (self->left <= parent->right)) { + if (self->bottom == parent->top) { + connect += 1 << 4; + } + else if (self->top == parent->bottom) { + connect += 2 << 4; + } + } + if ((!(connect & 0xf0)) && + ((self->right == parent->left) || (self->left == parent->right))) { + if (self->top == parent->top) { + connect += 3 << 4; + } + else if (self->bottom == parent->bottom) { + connect += 4 << 4; + } + } + return(connect); +} + +WINLOCEX winlocex_create(HWND base, const HWND *child, UINT count) { + + WINLOCEX ret; + HWND *list; + UINT inlist; + UINT i; + UINT j; + HWND hwnd; + UINT allocsize; + WLEXWND *wnd; + RECT rect; + BYTE connect; + WLEXWND *p; + + if (child == NULL) { + count = 0; + } + ret = NULL; + list = NULL; + inlist = 0; + if (count) { + list = (HWND *)_MALLOC(count * sizeof(HWND *), "wnd list"); + if (list == NULL) { + goto wlecre_err1; + } + for (i=0; i= inlist) { + list[inlist++] = hwnd; + } + } + } + } + allocsize = sizeof(_WINLOCEX) + (sizeof(WLEXWND) * inlist); + ret = (WINLOCEX)_MALLOC(allocsize, "winlocex"); + if (ret == NULL) { + goto wlecre_err2; + } + ZeroMemory(ret, allocsize); + wnd = (WLEXWND *)(ret + 1); + + if (base) { + // 親と接続されてる? + ret->base = base; + GetWindowRect(base, &ret->rect); + for (i=0; irect, &rect); + if (connect) { + list[i] = NULL; + wnd->hwnd = hwnd; + CopyMemory(&wnd->rect, &rect, sizeof(RECT)); + wnd->connect = connect; +// wnd->parent = 0; + wnd++; + ret->count++; + } + } + } + // 子と接続されてる? + p = (WLEXWND *)(ret + 1); + for (i=0; icount; i++, p++) { + for (j=0; jrect, &rect); + if (connect) { + list[j] = NULL; + wnd->hwnd = hwnd; + CopyMemory(&wnd->rect, &rect, sizeof(RECT)); + wnd->connect = connect; + wnd->parent = i + 1; + wnd++; + ret->count++; + } + } + } + } + } + + for (i=0; ihwnd = hwnd; + GetWindowRect(hwnd, &wnd->rect); + wnd++; + ret->count++; + } + } + +wlecre_err2: + if (list) { + _MFREE(list); + } + +wlecre_err1: + return(ret); +} + +void winlocex_destroy(WINLOCEX wle) { + + if (wle) { + _MFREE(wle); + } +} + +void winlocex_setholdwnd(WINLOCEX wle, HWND hold) { + + RECT workrc; + RECT rect; + UINT flag; + + if ((wle == NULL) || (hold == NULL)) { + return; + } + SystemParametersInfo(SPI_GETWORKAREA, 0, &workrc, 0); + GetWindowRect(hold, &rect); + flag = 0; + if (workrc.left == rect.left) { + flag = 1; + } + else if (workrc.right == rect.right) { + flag = 2; + } + if (workrc.top == rect.top) { + flag += 1 << 4; + } + else if (workrc.bottom == rect.bottom) { + flag += 2 << 4; + } + wle->hold = hold; + wle->holdflag = flag; +} + +static BOOL gravityx(WINLOCEX wle, RECT *rect) { + + int d; + WLEXWND *wnd; + UINT i; + RECT workrc; + + d = SNAPDOTPULL; + wnd = (WLEXWND *)(wle + 1); + for (i=0; icount; i++, wnd++) { + if (!wnd->connect) { + if ((rect->bottom >= wnd->rect.top) && + (rect->top <= wnd->rect.bottom)) { + d = rect->left - wnd->rect.right; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = rect->right - wnd->rect.left; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } + if ((rect->bottom == wnd->rect.top) || + (rect->top == wnd->rect.bottom)) { + d = rect->left - wnd->rect.left; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = rect->right - wnd->rect.right; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } + } + } + if (i < wle->count) { + wle->flagx = i + 1; + rect->left -= d; + rect->right -= d; + wle->gx = d; + wle->tx = rect->left; + return(TRUE); + } + + SystemParametersInfo(SPI_GETWORKAREA, 0, &workrc, 0); + wnd = (WLEXWND *)(wle + 1); + for (i=0; icount; i++, wnd++) { + if (wnd->connect) { + d = wnd->rect.left + (rect->left - wle->rect.left) + - workrc.left; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = wnd->rect.right + (rect->right - wle->rect.right) + - workrc.right; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } + } + if (i < wle->count) { + wle->flagx = (i + 1) << 16; + rect->left -= d; + rect->right -= d; + wle->gx = d; + wle->tx = rect->left; + return(TRUE); + } + + d = rect->left - workrc.left; + if ((d >= SNAPDOTPULL) || (d <= -SNAPDOTPULL)) { + d = rect->right - workrc.right; + } + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + wle->flagx = (UINT)-1; + rect->left -= d; + rect->right -= d; + wle->gx = d; + wle->tx = rect->left; + return(TRUE); + } + return(FALSE); +} + +static BOOL gravityy(WINLOCEX wle, RECT *rect) { + + int d; + WLEXWND *wnd; + UINT i; + RECT workrc; + + d = SNAPDOTPULL; + wnd = (WLEXWND *)(wle + 1); + for (i=0; icount; i++, wnd++) { + if (!wnd->connect) { + if ((rect->right >= wnd->rect.left) && + (rect->left <= wnd->rect.right)) { + d = rect->top - wnd->rect.bottom; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = rect->bottom - wnd->rect.top; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } + if ((rect->right == wnd->rect.left) || + (rect->left == wnd->rect.right)) { + d = rect->top - wnd->rect.top; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = rect->bottom - wnd->rect.bottom; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } + } + } + if (i < wle->count) { + wle->flagy = i + 1; + rect->top -= d; + rect->bottom -= d; + wle->gy = d; + wle->ty = rect->top; + return(TRUE); + } + + SystemParametersInfo(SPI_GETWORKAREA, 0, &workrc, 0); + wnd = (WLEXWND *)(wle + 1); + for (i=0; icount; i++, wnd++) { + if (wnd->connect) { + d = wnd->rect.top + (rect->top - wle->rect.top) + - workrc.top; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + d = wnd->rect.bottom + (rect->bottom - wle->rect.bottom) + - workrc.bottom; + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + break; + } + } + } + if (i < wle->count) { + wle->flagy = (i + 1) << 16; + rect->top -= d; + rect->bottom -= d; + wle->gy = d; + wle->ty = rect->top; + return(TRUE); + } + + d = rect->top - workrc.top; + if ((d >= SNAPDOTPULL) || (d <= -SNAPDOTPULL)) { + d = rect->bottom - workrc.bottom; + } + if ((d < SNAPDOTPULL) && (d > -SNAPDOTPULL)) { + wle->flagy = (UINT)-1; + rect->top -= d; + rect->bottom -= d; + wle->gy = d; + wle->ty = rect->top; + return(TRUE); + } + return(FALSE); +} + +void winlocex_moving(WINLOCEX wle, RECT *rect) { + + int d; + UINT num; + RECT *rc; + BOOL changes; + + if (wle == NULL) { + return; + } + + // ひっついてた時 + if (wle->flagx) { + d = rect->left - wle->tx; + wle->gx += d; + rect->left -= d; + rect->right -= d; + if ((wle->gx >= SNAPDOTREL) || (wle->gx <= -SNAPDOTREL)) { + wle->flagx = 0; + rect->left += wle->gx; + rect->right += wle->gx; + wle->gx = 0; + } + } + if (wle->flagy) { + d = rect->top - wle->ty; + wle->gy += d; + rect->top -= d; + rect->bottom -= d; + if ((wle->gy >= SNAPDOTREL) || (wle->gy <= -SNAPDOTREL)) { + wle->flagy = 0; + rect->top += wle->gy; + rect->bottom += wle->gy; + wle->gy = 0; + } + } + + // リリース処理 + num = wle->flagx - 1; + if (num < wle->count) { + rc = &(((WLEXWND *)(wle + 1))[num].rect); + if ((rect->left > rc->right) || (rect->right < rc->left) || + (rect->top > rc->bottom) || (rect->bottom < rc->top)) { + rect->left += wle->gx; + rect->right += wle->gx; + wle->flagx = 0; + wle->gx = 0; + } + } + num = wle->flagy - 1; + if (num < wle->count) { + rc = &(((WLEXWND *)(wle + 1))[num].rect); + if ((rect->left > rc->right) || (rect->right < rc->left) || + (rect->top > rc->bottom) || (rect->bottom < rc->top)) { + rect->top += wle->gy; + rect->bottom += wle->gy; + wle->flagy = 0; + wle->gy = 0; + } + } + + // 重力 + do { + changes = FALSE; + if (!wle->flagx) { + changes = gravityx(wle, rect); + } + if (!wle->flagy) { + changes = gravityy(wle, rect); + } + } while(changes); +} + +void winlocex_move(WINLOCEX wle) { + + RECT workrc; + WLEXWND *wnd; + UINT i; + RECT rect; + int cx; + int cy; + RECT baserect; + int dx; + int dy; + UINT num; + RECT *rc; + + if ((wle == NULL) || (wle->base == NULL)) { + return; + } + + wnd = (WLEXWND *)(wle + 1); + for (i=0; icount; i++) { + if ((wle->hold == wnd->hwnd) && (wnd->connect)) { + break; + } + } + if ((i >= wle->count) && (wle->holdflag)) { + SystemParametersInfo(SPI_GETWORKAREA, 0, &workrc, 0); + GetWindowRect(wle->hold, &rect); + cx = rect.right - rect.left; + cy = rect.bottom - rect.top; + switch(wle->holdflag & 0x0f) { + case 1: + rect.left = workrc.left; + break; + + case 2: + rect.left = workrc.right - cx; + break; + } + switch(wle->holdflag >> 4) { + case 1: + rect.top = workrc.top; + break; + + case 2: + rect.top = workrc.bottom - cy; + break; + } + MoveWindow(wle->hold, rect.left, rect.top, cx, cy, TRUE); + } + + GetWindowRect(wle->base, &baserect); + dx = baserect.left - wle->rect.left; + dy = baserect.top - wle->rect.top; + wnd = (WLEXWND *)(wle + 1); + for (i=0; icount; i++, wnd++) { + if (wnd->connect) { + GetWindowRect(wnd->hwnd, &rect); + cx = rect.right - rect.left; + cy = rect.bottom - rect.top; + rect.left += dx; + rect.top += dy; + num = wnd->parent - 1; + if (num < wle->count) { + rc = &(((WLEXWND *)(wle + 1))[num].rect); + } + else { + rc = &baserect; + } + switch(wnd->connect & 0x0f) { + case 1: + rect.left = rc->left - cx; + break; + + case 2: + rect.left = rc->right; + break; + + case 3: + rect.left = rc->left; + break; + + case 4: + rect.left = rc->right - cx; + break; + } + switch((wnd->connect >> 4) & 0x0f) { + case 1: + rect.top = rc->top - cy; + break; + + case 2: + rect.top = rc->bottom; + break; + + case 3: + rect.top = rc->top; + break; + + case 4: + rect.top = rc->bottom - cy; + break; + } + MoveWindow(wnd->hwnd, rect.left, rect.top, cx, cy, TRUE); + wnd->rect.left = rect.left; + wnd->rect.top = rect.top; + wnd->rect.right = rect.left + cx; + wnd->rect.bottom = rect.top + cy; + } + } +} + +void winlocex_close(WINLOCEX wle) { + + WLEXWND *wnd; + UINT i; + + if ((wle == NULL) || (wle->base == NULL)) { + return; + } + wnd = (WLEXWND *)(wle + 1); + for (i=0; icount; i++) { + if (wnd->connect) { + CloseWindow(wnd->hwnd); + } + wnd++; } - prc->bottom = prc->top + winly; }