#include "precomp.h" #include "appbarwnd.h" #include #include #include #include #include #include "../../../../Plugins/General/gen_ff/wa2cfgitems.h" #define CB_CHECK 0x101 #define DOCK_DISTANCE_X 5 #define DOCK_DISTANCE_Y 5 #ifndef WIN32 #error port me or remove me from the inheritance on this platform ! #endif #include #include #include #include "../../../../Plugins/General/gen_ff/main.h" #include "appbarwnd.h" extern _int cfg_options_appbardockingdistance; // ----------------------------------------------------------------------- AppBarWnd::AppBarWnd() { m_registered = 0; m_side = APPBAR_NOTDOCKED; m_enabled = 0; m_cur_side = APPBAR_NOTDOCKED; m_cur_autohide = 0; m_cur_hiding = 0; m_oldZOrder = NULL; m_destroying = FALSE; m_norestore = 0; m_sliding = 0; m_autounhide_timer_set = 0; m_autohide_timer_set = 0; m_suspended = 0; m_fs = 0; m_wahidden = 0; } // ----------------------------------------------------------------------- AppBarWnd::~AppBarWnd() { m_destroying = TRUE; if (m_cur_side != APPBAR_NOTDOCKED) unDock(); unregisterWinAppBar(); } // ----------------------------------------------------------------------- int AppBarWnd::registerWinAppBar() { if (m_registered) unregisterWinAppBar(); APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.hWnd = getOsWindowHandle(); abd.uCallbackMessage = APPBAR_CALLBACK; m_registered = (int)SHAppBarMessage(ABM_NEW, &abd); return m_registered; } // ----------------------------------------------------------------------- void AppBarWnd::unregisterWinAppBar() { if (m_registered) { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.hWnd = getOsWindowHandle(); SHAppBarMessage(ABM_REMOVE, &abd); m_registered = 0; } } // ----------------------------------------------------------------------- void AppBarWnd::appbar_dock(int side) { m_side = side; updateDocking(); } // ----------------------------------------------------------------------- int AppBarWnd::appbar_isDocked() { return m_side != APPBAR_NOTDOCKED; } // ----------------------------------------------------------------------- int AppBarWnd::appbar_getSide() { return m_side; } // ----------------------------------------------------------------------- void AppBarWnd::appbar_setEnabledSides(int mask) { m_enabled = mask; } // ----------------------------------------------------------------------- int AppBarWnd::appbar_getEnabledSides() { return m_enabled; } // ----------------------------------------------------------------------- int AppBarWnd::appbar_isSideEnabled(int side) { if (side == APPBAR_LEFT && !(m_enabled & APPBAR_LEFT_ENABLED)) return 0; if (side == APPBAR_TOP && !(m_enabled & APPBAR_TOP_ENABLED)) return 0; if (side == APPBAR_RIGHT && !(m_enabled & APPBAR_RIGHT_ENABLED)) return 0; if (side == APPBAR_BOTTOM && !(m_enabled & APPBAR_BOTTOM_ENABLED)) return 0; return 1; } // ----------------------------------------------------------------------- int AppBarWnd::appbar_isSideAutoHideSafe(int side) { OSWINDOWHANDLE cur = getCurAutoHide(side); if (cur == NULL || cur == getOsWindowHandle()) { RECT primary = {0}; Wasabi::Std::getViewport(&primary, hwnd, 1); DebugStringW( L"primary screen coords = %d,%d -> %d,%d (%dx%d)\n", primary.left, primary.top, primary.right, primary.bottom, primary.right - primary.left, primary.bottom - primary.top ); int monitor = 0; //int g = 0; while (1) { RECT r; int ret = Wasabi::Std::enumViewports(monitor++, &r, 1); if (ret == 0) break; if (Wasabi::Std::rectEqual(&primary, &r)) continue; DebugStringW(L"secondary screen = %d,%d -> %d,%d (%dx%d)\n", r.left, r.top, r.right, r.bottom, r.right-r.left, r.bottom-r.top); if (r.right <= primary.left && side == APPBAR_LEFT) return 0; if (r.bottom <= primary.top && side == APPBAR_TOP) return 0; if (r.left >= primary.right && side == APPBAR_RIGHT) return 0; if (r.top >= primary.bottom && side == APPBAR_BOTTOM) return 0; } } else return 0; return 1; } // ----------------------------------------------------------------------- OSWINDOWHANDLE AppBarWnd::getCurAutoHide(int side) { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.hWnd = getOsWindowHandle(); abd.uEdge = side; return (OSWINDOWHANDLE)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd); } // ----------------------------------------------------------------------- int AppBarWnd::appbar_testDock(int x, int y, RECT *dockrect) { POINT ptCursor = {x, y}; LONG cxScreen, cyScreen; int dx=999999, dy=999999; int horiz=-1, vert=-1; RECT viewRect = {0}; Wasabi::Std::getViewport(&viewRect, hwnd, 1); // Find out which edge of the screen we're closest to cxScreen = viewRect.right; cyScreen = viewRect.bottom; if (x < viewRect.left || x > cxScreen || y < viewRect.top || y > cyScreen) return APPBAR_NOTDOCKED; if (ptCursor.x < (cxScreen / 2)) { if (m_enabled & APPBAR_LEFT_ENABLED) { dx = ptCursor.x; horiz = APPBAR_LEFT; } } else { if (m_enabled & APPBAR_RIGHT_ENABLED) { dx = cxScreen - ptCursor.x; horiz = APPBAR_RIGHT; } } if (ptCursor.y < (cyScreen / 2)) { if (m_enabled & APPBAR_TOP_ENABLED) { dy = ptCursor.y; vert = APPBAR_TOP; } } else { if (m_enabled & APPBAR_BOTTOM_ENABLED) { dy = cyScreen - ptCursor.y; vert = APPBAR_BOTTOM; } } int ret = -1; #ifdef GEN_FF int dockdist = cfg_options_appbardockingdistance; #else // TODO: do a config lookup, but make it not so slow /* const GUID options_guid = { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } }; int dockdist = _intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), L"Appbars Docking Distance", 5);*/ int dockdist = 5; #endif if ((cxScreen * dy) > (cyScreen * dx)) if (dx <= dockdist) ret = horiz; if (dy <= dockdist) ret = vert; if (dockrect && ret != -1) { getDockRect(ret, dockrect); } return ret; } // ----------------------------------------------------------------------- void AppBarWnd::getDockRect(int side, RECT *rect) { LONG cxScreen, cyScreen; RECT viewRect = {0}; Wasabi::Std::getViewport(&viewRect, hwnd, 1); cxScreen = viewRect.right; cyScreen = viewRect.bottom; if (isMaximized()) { getRestoredRect(rect); if (renderRatioActive()) multRatio(rect); } else getWindowRect(rect); Layout *l = (Layout *)getInterface(layoutGuid); if (l) { RECT adj; l->getSnapAdjust(&adj); if (renderRatioActive()) { multRatio((int *)&adj.left, (int *)&adj.top); multRatio((int *)&adj.right, (int *)&adj.bottom); } int h = rect->bottom - rect->top; int w = rect->right - rect->left; h -= adj.top + adj.bottom; w -= adj.left + adj.right; rect->left += adj.left; rect->top += adj.top; rect->bottom = rect->top + h; rect->right = rect->left + w; } switch (side) { case APPBAR_TOP: case APPBAR_LEFT: OffsetRect(rect, -rect->left, -rect->top); break; case APPBAR_BOTTOM: case APPBAR_RIGHT: OffsetRect(rect, cxScreen-rect->right, cyScreen-rect->bottom); break; } switch (side) { case APPBAR_TOP: case APPBAR_BOTTOM: rect->left = viewRect.left; rect->right = cxScreen; break; case APPBAR_LEFT: case APPBAR_RIGHT: rect->top = viewRect.top; rect->bottom = cyScreen; break; } OSWINDOWHANDLE cur = getCurAutoHide(side); int safeah = appbar_isSideAutoHideSafe(side); if (!safeah || !(appbar_wantAutoHide() && (!cur || cur == getOsWindowHandle()))) { straightenRect(side, rect); } } // ----------------------------------------------------------------------- void AppBarWnd::updateDocking() { if (!isVisible()) { m_suspended = 1; return; } updateSide(); appbar_updateAutoHide(); appbar_updateAlwaysOnTop(); updateTimers(); } // ----------------------------------------------------------------------- void AppBarWnd::updateTimers() { if (m_cur_autohide) { if (m_cur_hiding) { resetAutoHideTimer(); setAutoUnHideTimer(); } else { resetAutoUnHideTimer(); setAutoHideTimer(); } } } // ----------------------------------------------------------------------- int AppBarWnd::appbar_updateAlwaysOnTop() { if (m_side == APPBAR_NOTDOCKED) return 0; SetWindowPos(getOsWindowHandle(), appbar_wantAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); return 1; } // ----------------------------------------------------------------------- int AppBarWnd::appbar_updateAutoHide() { int autohide = appbar_wantAutoHide(); if (m_cur_autohide == autohide) return 0; if (autohide && !appbar_isSideAutoHideSafe(m_cur_side)) autohide = 0; if (m_cur_autohide == autohide) return 0; if (autohide) { // cur_autohide is off, turn it on m_cur_hiding = 0; setAutoHideTimer(); } else { // cur_autohide is on, turn it off if (m_cur_hiding) resetAutoUnHideTimer(); else resetAutoHideTimer(); } m_cur_autohide = autohide; dock(m_cur_side); return 1; } // ----------------------------------------------------------------------- void AppBarWnd::onAfterReinit() { APPBARWND_PARENT::onAfterReinit(); m_autohide_timer_set = 0; m_autounhide_timer_set = 0; updateTimers(); } // ----------------------------------------------------------------------- void AppBarWnd::setAutoHideTimer(){ if (!m_autohide_timer_set) { SetTimer(getOsWindowHandle(), IDT_AUTOHIDE, cfg_uioptions_appbarshidetime, NULL); m_autohide_timer_set = 1; } } // ----------------------------------------------------------------------- void AppBarWnd::setAutoUnHideTimer(){ if (!m_autounhide_timer_set) { SetTimer(getOsWindowHandle(), IDT_AUTOUNHIDE, cfg_uioptions_appbarsshowtime, NULL); m_autounhide_timer_set = 1; } } // ----------------------------------------------------------------------- void AppBarWnd::resetAutoHideTimer(){ if (m_autohide_timer_set) { KillTimer(getOsWindowHandle(), IDT_AUTOHIDE); m_autohide_timer_set = 0; } } // ----------------------------------------------------------------------- void AppBarWnd::resetAutoUnHideTimer() { if (m_autounhide_timer_set) { KillTimer(getOsWindowHandle(), IDT_AUTOUNHIDE); m_autounhide_timer_set = 0; } } // ----------------------------------------------------------------------- void AppBarWnd::updateSide() { if (m_cur_side == m_side) return; if (m_side != m_cur_side && m_cur_side != APPBAR_NOTDOCKED && m_side != APPBAR_NOTDOCKED && m_cur_autohide) { resetAutoHideSide(m_cur_side); } if (m_side == APPBAR_NOTDOCKED) unDock(); else dock(m_side); } // ----------------------------------------------------------------------- void AppBarWnd::resetAutoHideSide(int side) { HWND cur = getCurAutoHide(side); if (cur == getOsWindowHandle()) { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.hWnd = cur; abd.uEdge = side; abd.lParam = FALSE; SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd); } } // ----------------------------------------------------------------------- void AppBarWnd::setAutoHideSide(int side) { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.hWnd = getOsWindowHandle(); abd.uEdge = side; abd.lParam = TRUE; SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd); } // ----------------------------------------------------------------------- void AppBarWnd::dock(int side) { unOwn(); if (!registerWinAppBar()) { reOwn(); m_side = APPBAR_NOTDOCKED; m_cur_side = APPBAR_NOTDOCKED; m_cur_autohide = 0; } maximize(0); RECT rect; getDockRect(side, &rect); { RECT adj = rect; if (ABS(getRenderRatio() - 1.0) > 0.01f) { int _w = adj.right-adj.left; int _h = adj.bottom-adj.top; double rr = getRenderRatio(); _w = (int)((double)(_w) / rr + 0.5); _h = (int)((double)(_h) / rr + 0.5); adj.right = adj.left + _w; adj.bottom = adj.top + _h; } snapAdjust(&adj, 1); resizeToRect(&adj); } if (!appbar_wantAutoHide() || !appbar_isSideAutoHideSafe(side)) { notifyWinAppBarPosition(side, rect); } else { getEdge(side, &rect); notifyWinAppBarPosition(side, rect); setAutoHideSide(side); m_cur_hiding = 0; } if (!m_suspended) appbar_onDock(side); #ifdef WASABI_APPBAR_ONDOCKCHANGED WASABI_APPBAR_ONDOCKCHANGED(this) #endif } // ----------------------------------------------------------------------- void AppBarWnd::unDock() { if (m_cur_side != APPBAR_NOTDOCKED) { resetAutoHideSide(m_cur_side); unregisterWinAppBar(); if (!m_destroying) { reOwn(); if (!m_norestore) restore(); #ifdef WASABI_APPBAR_ONDOCKCHANGED WASABI_APPBAR_ONDOCKCHANGED(this) #endif } m_cur_side = APPBAR_NOTDOCKED; if (!m_suspended) appbar_onUnDock(); } } // ----------------------------------------------------------------------- void AppBarWnd::notifyWinAppBarPosition(int side, RECT rect) { APPBARDATA abd; abd.cbSize = sizeof(APPBARDATA); abd.hWnd = getOsWindowHandle(); abd.rc = rect; abd.uEdge = side; SHAppBarMessage(ABM_SETPOS, &abd); m_cur_side = side; } // ----------------------------------------------------------------------- int AppBarWnd::appbar_isHiding() { return m_cur_hiding; } // ----------------------------------------------------------------------- int AppBarWnd::appbar_isAutoHiding() { return m_cur_autohide; } // ----------------------------------------------------------------------- void AppBarWnd::appbar_posChanged() { if (m_side == APPBAR_NOTDOCKED) return; RECT wr; getWindowRect(&wr); int w = wr.right-wr.left; int h = wr.bottom-wr.top; if (m_cur_autohide && m_cur_side != APPBAR_NOTDOCKED && !appbar_isSideAutoHideSafe(m_cur_side)) m_cur_autohide = 0; RECT rc; getDockRect(m_cur_side, &rc); if (!m_cur_autohide) { { RECT adj = rc; if (ABS(getRenderRatio() - 1.0) > 0.01f) { int _w = adj.right-adj.left; int _h = adj.bottom-adj.top; double rr = getRenderRatio(); _w = (int)((double)(_w) / rr + 0.5); _h = (int)((double)(_h) / rr + 0.5); adj.right = adj.left + _w; adj.bottom = adj.top + _h; } snapAdjust(&adj, 1); resizeToRect(&adj); } notifyWinAppBarPosition(m_cur_side, rc); } else { int aaw = appbar_getAutoHideWidthHeight(); RECT er; getEdge(m_cur_side, &er); notifyWinAppBarPosition(m_cur_side, er); RECT adj = {0,0,0,0}; Layout *l = (Layout *)getInterface(layoutGuid); if (l) l->getSnapAdjust(&adj); if (renderRatioActive()) multRatio(&adj); if (m_cur_hiding) { switch (m_cur_side) { case APPBAR_TOP: rc.bottom = er.top + aaw + adj.bottom; rc.top = rc.bottom - h; break; case APPBAR_BOTTOM: rc.top = er.bottom - aaw - adj.top; rc.bottom = rc.top + h; break; case APPBAR_LEFT: rc.right = er.left + aaw + adj.right; rc.left = rc.right - w; break; case APPBAR_RIGHT: rc.left = er.right - aaw - adj.left; rc.right = rc.left + w; break; } } if (ABS(getRenderRatio() - 1.0) > 0.01f) { int _w = rc.right-rc.left; int _h = rc.bottom-rc.top; double rr = getRenderRatio(); _w = (int)((double)(_w) / rr + 0.5); _h = (int)((double)(_h) / rr + 0.5); rc.right = rc.left + _w; rc.bottom = rc.top + _h; } resizeToRect(&rc); } } // ----------------------------------------------------------------------- void AppBarWnd::getEdge(int side, RECT *rc) { ASSERT(rc != NULL); Wasabi::Std::getViewport(rc, hwnd, 1); switch (side) { case APPBAR_TOP: rc->bottom = rc->top; break; case APPBAR_BOTTOM: rc->top = rc->bottom; break; case APPBAR_LEFT: rc->right = rc->left; break; case APPBAR_RIGHT: rc->left = rc->right; break; } } // ----------------------------------------------------------------------- void AppBarWnd::appBarCallback(UINT uMsg, WPARAM wParam, LPARAM lParam) { APPBARDATA abd = {0}; if (m_registered) { abd.cbSize = sizeof(abd); abd.hWnd = getOsWindowHandle(); switch (wParam) { // the taskbar's autohide or always-on-top state has changed. case ABN_STATECHANGE: DebugString("AppBarCallback: ABN_STATECHANGE\n"); break; // a full screen application is opening or closing. we must drop // to the bottom of the Z-Order and restore it later. case ABN_FULLSCREENAPP: DebugString("AppBarCallback: ABN_FULLSCREENAPP\n"); if (lParam && !m_fs) { m_fs=1; m_oldZOrder = GetWindow(getOsWindowHandle(), GW_HWNDPREV); SetWindowPos(getOsWindowHandle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } else if (!lParam && m_fs) { m_fs = 0; SetWindowPos(getOsWindowHandle(), appbar_wantAlwaysOnTop() ? HWND_TOPMOST : m_oldZOrder, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); m_oldZOrder = NULL; } break; // something changed that may have modified the possible appbar's positions case ABN_POSCHANGED: DebugString("AppBarCallback: ABN_POSCHANGED\n"); appbar_posChanged(); break; case ABN_WINDOWARRANGE: if (lParam && !m_wahidden) { m_wahidden = 1; ShowWindow(getOsWindowHandle(), SW_HIDE); } else if (!lParam && m_wahidden) { m_wahidden = 0; ShowWindow(getOsWindowHandle(), SW_NORMAL); } break; } } } // ----------------------------------------------------------------------- LRESULT AppBarWnd::wndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { if ( m_registered ) { switch ( msg ) { case WM_MOVE: { //DebugString("WM_MOVE\n"); return 0; } case WM_WINDOWPOSCHANGED: { //DebugString("WM_WINDOWPOSCHANGED\n"); //LPWINDOWPOS lpwpos = (LPWINDOWPOS)lparam; APPBARDATA abd = { 0 }; abd.cbSize = sizeof( APPBARDATA ); abd.hWnd = getOsWindowHandle(); SHAppBarMessage( ABM_WINDOWPOSCHANGED, &abd ); } case APPBAR_CALLBACK: { if ( !m_destroying ) appBarCallback( msg, wparam, lparam ); return 0; } case WM_DISPLAYCHANGE: { DebugString( "WM_DISPLAYCHANGE\n" ); appbar_posChanged(); } case WM_TIMER: { // // not using multiplexed timer for independent speed switch ( wparam ) { case IDT_AUTOHIDE: onAutoHideTimer(); break; case IDT_AUTOUNHIDE: onAutoUnHideTimer(); break; } } case WM_COMMAND: { // forward onto the main Winamp window and let it do it if ( HIWORD( wparam ) == THBN_CLICKED ) { SendMessageW( plugin.hwndParent, msg, wparam, lparam ); } } } } return APPBARWND_PARENT::wndProc( hwnd, msg, wparam, lparam ); } // ----------------------------------------------------------------------- void AppBarWnd::onAutoHideTimer() { HWND me = getOsWindowHandle(); POINT pt; RECT rc; HWND hact; if (m_cur_autohide) { if (!m_cur_hiding) { GetCursorPos(&pt); GetWindowRect(hwnd, &rc); snapAdjust(&rc, -1); hact = GetForegroundWindow(); if ((!PtInRect(&rc, pt) || screenCorner(&pt)) && (hact != me) && /*(hact!= NULL) && */(GetWindowOwner(hact) != me)) { resetAutoHideTimer(); autoHide(); setAutoUnHideTimer(); } } else { resetAutoHideTimer(); setAutoUnHideTimer(); } } } // ----------------------------------------------------------------------- void AppBarWnd::onAutoUnHideTimer() { RECT rc; POINT pt; HWND me = getOsWindowHandle(); GetWindowRect(me, &rc); snapAdjust(&rc, -1); if (m_cur_autohide) { if (m_cur_hiding) { GetCursorPos(&pt); if (PtInRect(&rc, pt) && !screenCorner(&pt)) { resetAutoUnHideTimer(); autoUnHide(); setAutoHideTimer(); } } else { resetAutoUnHideTimer(); setAutoHideTimer(); } } } // ----------------------------------------------------------------------- void AppBarWnd::autoHide() { if (m_cur_autohide) { if (!m_cur_hiding) { RECT rc; getWindowRect(&rc); int h = rc.bottom-rc.top; int w = rc.right-rc.left; int aaw = appbar_getAutoHideWidthHeight(); RECT adj={0,0,0,0}; Layout *l = static_cast(getInterface(layoutGuid)); l->getSnapAdjust(&adj); if (renderRatioActive()) multRatio(&adj); RECT viewRect = {0}; Wasabi::Std::getViewport(&viewRect, hwnd, 1); switch (m_side) { case APPBAR_TOP: rc.top = -(h - aaw + adj.top - adj.bottom); break; case APPBAR_BOTTOM: rc.top = (viewRect.bottom - viewRect.top) - aaw - adj.top; break; case APPBAR_LEFT: rc.left = -(w - aaw + adj.left - adj.right); break; case APPBAR_RIGHT: rc.left = viewRect.right - aaw - adj.left; break; } switch (m_side) { case APPBAR_TOP: case APPBAR_BOTTOM: rc.bottom = rc.top + h; break; case APPBAR_LEFT: case APPBAR_RIGHT: rc.right = rc.left + w; break; } slideWindow(&rc); m_cur_hiding = 1; } } } // ----------------------------------------------------------------------- void AppBarWnd::autoUnHide() { if (m_cur_autohide) { if (m_cur_hiding) { m_cur_hiding = 0; RECT rc; getWindowRect(&rc); int h = rc.bottom-rc.top; int w = rc.right-rc.left; int aaw = appbar_getAutoHideWidthHeight(); RECT adj={0,0,0,0}; Layout *l = static_cast(getInterface(layoutGuid)); l->getSnapAdjust(&adj); if (renderRatioActive()) multRatio(&adj); switch (m_side) { case APPBAR_TOP: rc.top += (h - aaw) - (adj.top + adj.bottom); rc.bottom += (h - aaw) - (adj.top + adj.bottom); break; case APPBAR_BOTTOM: rc.top -= (h - aaw) - (adj.top + adj.bottom); rc.bottom -= (h - aaw) - (adj.top + adj.bottom); break; case APPBAR_LEFT: rc.right += (w - aaw) - (adj.left + adj.right); rc.left += (w - aaw) - (adj.left + adj.right); break; case APPBAR_RIGHT: rc.left -= (w - aaw) - (adj.left + adj.right); rc.right -= (w - aaw) - (adj.left + adj.right); break; } slideWindow(&rc); } } } // ----------------------------------------------------------------------- const int g_dtSlideHide = 400; const int g_dtSlideShow = 200; // ----------------------------------------------------------------------- void AppBarWnd::slideWindow(RECT *prc) { if (m_cur_autohide) { m_sliding = 1; RECT rcOld; RECT rcNew; int x, y, dx, dy, dt, t, t0; BOOL fShow; HANDLE hThreadMe; int priority; HWND hwnd = getOsWindowHandle(); rcNew = *prc; /*DebugString("rcNew : left=%d, top=%d, " "right=%d, bottom=%d\n", rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);*/ if ((g_dtSlideShow > 0) && (g_dtSlideHide > 0)) { GetWindowRect(hwnd, &rcOld); fShow = TRUE;/*(rcNew.bottom - rcNew.top) > (rcOld.bottom - rcOld.top) || (rcNew.right - rcNew.left) > (rcOld.right - rcOld.left);*/ dx = (rcNew.left - rcOld.left); dy = (rcNew.top - rcOld.top); if (fShow) { rcOld = rcNew; OffsetRect(&rcOld, -dx, -dy); //DebugString("appbar_slideWindow %d %d\n", rcOld.left, rcOld.top); move(rcOld.left, rcOld.top); dt = g_dtSlideShow; } else { dt = g_dtSlideHide; } hThreadMe = GetCurrentThread(); priority = GetThreadPriority(hThreadMe); SetThreadPriority(hThreadMe, THREAD_PRIORITY_HIGHEST); t0 = GetTickCount(); while ((t = GetTickCount()) < t0 + dt) { x = rcOld.left + dx * (t - t0) / dt; y = rcOld.top + dy * (t - t0) / dt; //DebugString("appbar_slideWindow(2) %d %d\n", x, y); move(x, y); //SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); if (fShow) { UpdateWindow(hwnd); //invalidateWindowRegion(); //updateWindowRegion(); } else UpdateWindow(GetDesktopWindow()); } SetThreadPriority(hThreadMe, priority); } //DebugString("appbar_slideWindow(3) %d %d\n", rcNew.left, rcNew.top); move(rcNew.left, rcNew.top); appbar_onSlide(); } WASABI_API_MAKI->vcpu_setComplete(); m_sliding = 0; } // ----------------------------------------------------------------------- void AppBarWnd::unOwn() { // registration was successful, we should reparent the window to NULL so that minimizing the app or changing the main AOT flag does // nothing to this window Layout *l = static_cast(getInterface(layoutGuid)); if (l) { if (!l->getNoParent()) { l->setNoParent(2); // whoaaah! reinit(); } } } // ----------------------------------------------------------------------- void AppBarWnd::reOwn() { OSWINDOWHANDLE mw = WASABI_API_WND->main_getRootWnd()->getOsWindowHandle(); if (IsIconic(mw)) ShowWindow(mw, SW_RESTORE); // undock was successful, we should re-own the window to what it was previously. if the old owner is minimized, we should restore it first OSWINDOWHANDLE oldparent = WASABI_API_WND->main_getRootWnd()->getOsWindowHandle(); if (IsIconic(oldparent)) ShowWindow(oldparent, SW_RESTORE); Layout *l = static_cast(getInterface(layoutGuid)); if (l) { int oldnp = l->getNoParent(); const wchar_t *np = l->getGuiObject()->guiobject_getXmlParam(L"noparent"); int newnp = WTOI(np); if (oldnp != newnp) { l->setNoParent(newnp); // whoaaah! reinit(); } } } // ----------------------------------------------------------------------- void AppBarWnd::straightenRect(int side, RECT *r) { int w=0, h=0; int wasregistered = m_registered; if (!m_registered) registerWinAppBar(); APPBARDATA abd; abd.hWnd = hwnd; abd.cbSize = sizeof(APPBARDATA); abd.rc = *r; abd.uEdge = side; RECT viewRect = {0}; Wasabi::Std::getViewport(&viewRect, hwnd, 1); switch (side) { case APPBAR_LEFT: case APPBAR_RIGHT: w = abd.rc.right - abd.rc.left; abd.rc.top = viewRect.top; abd.rc.bottom = viewRect.bottom; break; case APPBAR_TOP: case APPBAR_BOTTOM: h = abd.rc.bottom - abd.rc.top; abd.rc.left = viewRect.left; abd.rc.right = viewRect.right; break; } SHAppBarMessage(ABM_QUERYPOS, &abd); switch (abd.uEdge) { case APPBAR_LEFT: abd.rc.right = abd.rc.left + w; break; case APPBAR_RIGHT: abd.rc.left = abd.rc.right - w; break; case APPBAR_TOP: abd.rc.bottom = abd.rc.top + h; break; case APPBAR_BOTTOM: abd.rc.top = abd.rc.bottom - h; break; } if (!wasregistered) unregisterWinAppBar(); *r = abd.rc; } // ----------------------------------------------------------------------- void AppBarWnd::appbar_setNoRestore(int no) { m_norestore = no; } // ----------------------------------------------------------------------- void AppBarWnd::onSetVisible( int show ) { if ( !show && m_side != APPBAR_NOTDOCKED && !m_suspended ) { if ( m_cur_autohide ) { resetAutoHideSide( m_cur_side ); if ( m_cur_hiding ) resetAutoUnHideTimer(); else resetAutoHideTimer(); } m_suspended = 1; unDock(); APPBARWND_PARENT::onSetVisible( show ); return; } else if ( show && m_suspended ) { APPBARWND_PARENT::onSetVisible( show ); m_suspended = 0; updateDocking(); return; } APPBARWND_PARENT::onSetVisible( show ); } // ----------------------------------------------------------------------- int AppBarWnd::screenCorner(POINT *pt) { RECT primary = {0}; Wasabi::Std::getViewport(&primary, hwnd, 1); if (pt->x > primary.right-2 && pt->x <= primary.right) { if (pt->y > primary.bottom-2 && pt->y <= primary.bottom) { // bottom right corner return 1; } else if (pt->y < primary.top+2 && pt->y >= primary.top) { // top right corner return 1; } } else if (pt->x < primary.left+2 && pt->x >= primary.left) { if (pt->y > primary.bottom-2 && pt->y <= primary.bottom) { // bottom left corner return 1; } else if (pt->y < primary.top+2 && pt->y >= primary.top) { // top left corner return 1; } } return 0; } // ----------------------------------------------------------------------- void AppBarWnd::snapAdjust(RECT *r, int way) { RECT s; Layout *l = static_cast(getInterface(layoutGuid)); if (!l) return; l->getSnapAdjust(&s); int h = r->bottom - r->top; int w = r->right - r->left; if (way == 1) { h += s.top + s.bottom; w += s.left + s.right; r->left -= s.left; r->top -= s.top; r->bottom = r->top + h; r->right = r->left + w; } else if (way == -1) { h -= s.top + s.bottom; w -= s.left + s.right; r->left += s.left; r->top += s.top; r->bottom = r->top + h; r->right = r->left + w; } } // ----------------------------------------------------------------------- void AppBarWnd::onRatioChanged() { APPBARWND_PARENT::onRatioChanged(); if (m_side != APPBAR_NOTDOCKED) appbar_posChanged(); }