aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp')
-rw-r--r--Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp1113
1 files changed, 1113 insertions, 0 deletions
diff --git a/Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp b/Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp
new file mode 100644
index 00000000..11629fc1
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp
@@ -0,0 +1,1113 @@
+#include "precomp.h"
+#include "appbarwnd.h"
+#include <tataki/region/region.h>
+#include <api/wnd/resizable.h>
+#include <api/wndmgr/layout.h>
+#include <api/config/items/cfgitem.h>
+#include <api/config/items/attrint.h>
+#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 <windows.h>
+#include <windowsx.h>
+#include <shlobj.h>
+#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<Layout*>(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<Layout*>(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<Layout*>(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<Layout *>(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<Layout*>(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();
+} \ No newline at end of file