#include #include "wa2wndembed.h" #include "wa2frontend.h" #include "wa2buckitems.h" #include "embedwndguid.h" #include "main.h" #include #include "resource.h" #include #include #include "wa2cfgitems.h" #include "gen.h" #include "../Agave/Language/api_language.h" extern TList forcedoffwnds; #define BUCKETITEM_WNDTYPE L"buck" #define WINAMP_OPTIONS_WINDOWSHADE_PL 40266 ReentryFilterObject wndMsgFilter; int embedTable[] = { IPC_GETWND_PE, #ifdef MINIBROWSER_SUPPORT IPC_GETWND_MB, #endif IPC_GETWND_VIDEO}; extern int switching_skin; extern int going_fixedform; extern int going_freeform; extern HINSTANCE hInstance; //----------------------------------------------------------------------------------------------- void WaOsWndHost::onBeforeReparent(int host) { #if defined(_WIN64) embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA); #else embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA); #endif // 0x49474541 is related to keeping windows shown on litestep desktops if (ws == NULL || (int)ws == 0x49474541) { HWND w = getHWND(); if (w == wa2.getWnd(IPC_GETWND_VIDEO)) { // this tells the video to not trigger its callback on windowposchanged, otherwise it will generate a new IPC_ONSHOW SendMessageW(w, WM_USER + 0x2, 0, 1); } return ; } ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 1; // tell winamp to ignore show/hide events if (!host) { ShowWindow(getHWND(), SW_HIDE); if (!transfer && ((switching_skin && !Wa2WndEmbed::hadRememberedWndVisible(getHWND())) || !switching_skin)) { PostMessage(getHWND(), WM_USER + 101, 0, 0); } } } //----------------------------------------------------------------------------------------------- void WaOsWndHost::onAfterReparent(int host) { #if defined(_WIN64) embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA); #else embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA); #endif // 0x49474541 is related to keeping windows shown on litestep desktops if (ws == NULL || (int)ws == 0x49474541) { HWND w = getHWND(); if (w == wa2.getWnd(IPC_GETWND_VIDEO)) { // stop preventing handling of video windowposchanged SendMessageW(w, WM_USER + 0x2, 0, 0); } return ; } ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 0; // tell winamp NOT to ignore show/hide events anymore } //----------------------------------------------------------------------------------------------- int WaOsWndHost::onGetFocus() { XuiOSWndHost::onGetFocus(); ifc_window *z = findWindowByInterface(windowHolderGuid); if (z) { WindowHolder *wh = static_cast(z->getInterface(windowHolderGuid)); if (wh && wh->wndholder_wantAutoFocus()) { HWND w = getHWND(); if (IsWindow(w)) SetFocus(w); } } return 1; } //----------------------------------------------------------------------------------------------- int WaOsWndHost::wantFocus() { ifc_window *w = findWindowByInterface(windowHolderGuid); if (w) { WindowHolder *wh = static_cast(w->getInterface(windowHolderGuid)); if (wh) { return wh->wndholder_wantAutoFocus(); } } return 0; } //----------------------------------------------------------------------------------------------- int WaOsWndHost::onMouseWheelUp(int click, int lines) { return 1; } //----------------------------------------------------------------------------------------------- int WaOsWndHost::onMouseWheelDown(int click, int lines) { return 1; } //----------------------------------------------------------------------------------------------- void VideoLayoutMonitor::hook_onResize(int x, int y, int w, int h) { SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0); } //----------------------------------------------------------------------------------------------- void VideoLayoutMonitor::hook_onMove() { SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0); } //----------------------------------------------------------------------------------------------- Wa2WndEmbed::Wa2WndEmbed() { WASABI_API_SYSCB->syscb_registerCallback(static_cast(this)); } //----------------------------------------------------------------------------------------------- Wa2WndEmbed::~Wa2WndEmbed() { WASABI_API_SYSCB->syscb_deregisterCallback(static_cast(this)); wa2wndstatus.deleteAll(); } extern int we_have_ml; //----------------------------------------------------------------------------------------------- int Wa2WndEmbed::testGuid(GUID g) { if (embedWndGuidMgr.testGuid(g)) return 1; /* if (embedWndGuids.Data2 == g.Data2 && // embed wnd check :) embedWndGuids.Data3 == g.Data3 && !memcmp(embedWndGuids.Data4,g.Data4,8)) return 1;*/ return (g == pleditWndGuid || g == videoWndGuid #ifdef MINIBROWSER_SUPPORT || g == minibrowserWndGuid #endif || (we_have_ml && g == library_guid) ); } int make_sure_library_is_here_at_startup = 0; extern int m_loading_at_startup; //----------------------------------------------------------------------------------------------- ifc_window *Wa2WndEmbed::createWindowByGuid(GUID g, ifc_window *parent) { if (m_loading_at_startup) if (g == library_guid) make_sure_library_is_here_at_startup = 1; WaOsWndHost *oldhost = NULL; if (embedWndGuidMgr.testGuid(g) && !embedWndGuidMgr.getEmbedWindowState(g)) return NULL; // first check if this window is already open in a host, and if so, remove it from the wndholder foreach(wndhosts) if (wndhosts.getfor()->g == g) { WaOsWndHost *host = wndhosts.getfor()->host; oldhost = host; host->setTransfering(1); host->oswndhost_unhost(); Layout *l = static_cast(host->getDesktopParent()); if (l) { Container *c = l->getParentContainer(); if (c) { if (!WCSCASEEQLSAFE(c->getId(), L"main")) { c->close(); // deferred if needed } else { softclose: ifc_window *wnd = host->findWindowByInterface(windowHolderGuid); if (wnd != NULL) { WindowHolder *wh = static_cast(wnd->getInterface(windowHolderGuid)); if (wh != NULL) { wh->onRemoveWindow(1); } } } } else goto softclose; } } endfor; // now host the wnd in a new host WaOsWndHost *host = new WaOsWndHost(); viewer_addViewItem(host); EmbedEntry *ee = new EmbedEntry(); wndhosts.addItem(ee); ee->g = g; ee->host = host; ee->monitor = NULL; ee->dep = host->getDependencyPtr(); ee->cmds = NULL; if (g == pleditWndGuid) { RECT r = {10, 20, 5, 38}; host->oswndhost_setRegionOffsets(&r); host->oswndhost_host(wa2.getWnd(IPC_GETWND_PE)); ee->whichwnd = IPC_GETWND_PE; host->setName((L"Playlist Editor")/*(WASABI_API_LNGSTRINGW(IDS_PLAYLIST_EDITOR)*/); GuiObject *go = parent->getGuiObject(); PlaylistAppCmds *plEditAppCmds = new PlaylistAppCmds(); ee->cmds = plEditAppCmds; go->guiobject_addAppCmds(plEditAppCmds); plWnd = parent; //parent->getDesktopParent(); //ShowWindow(host->getHWND(), SW_NORMAL); } else if (g == videoWndGuid) { RECT r = {11, 20, 8, 38}; host->oswndhost_setRegionOffsets(&r); #ifdef VIDDEBUG DebugString("Video : Window service creates the host\n"); #endif HWND vid = wa2.getWnd(IPC_GETWND_VIDEO); host->oswndhost_host(vid); ((WaOsWndHost *)host)->setNoTransparency(); ee->whichwnd = IPC_GETWND_VIDEO; host->setName(WASABI_API_LNGSTRINGW(IDS_VIDEO)); ifc_window *lw = parent->getDesktopParent(); if (lw) { GuiObject *o = lw->getGuiObject(); if (o) { ee->monitor = new VideoLayoutMonitor(o->guiobject_getScriptObject()); } } SetTimer(vid, 12345, 250, NULL); GuiObject *go = parent->getGuiObject(); VideoAppCmds *videoAppCmds = new VideoAppCmds(); ee->cmds = videoAppCmds; go->guiobject_addAppCmds(videoAppCmds); vidWnd = parent; //parent->getDesktopParent(); //ShowWindow(host->getHWND(), SW_NORMAL); #ifdef MINIBROWSER_SUPPORT } else if (g == minibrowserWndGuid) { RECT r = {10, 20, 5, 38}; host->oswndhost_setRegionOffsets(&r); host->oswndhost_host(wa2.getWnd(IPC_GETWND_MB)); ee->whichwnd = IPC_GETWND_MB; host->setName("Minibrowser"); GuiObject *go = parent->getGuiObject(); mbWnd = parent; //parent->getDesktopParent(); MinibrowserAppCmds *mbAppCmds = new MinibrowserAppCmds(); ee->cmds = mbAppCmds; go->guiobject_addAppCmds(mbAppCmds); //ShowWindow(host->getHWND(), SW_NORMAL); #endif } else if (embedWndGuidMgr.testGuid(g)) /*(embedWndGuids.Data2 == g.Data2 && embedWndGuids.Data3 == g.Data3 && !memcmp(embedWndGuids.Data4,g.Data4,8))*/ { embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(g); ASSERT(ws != NULL); if (0 == (WS_BORDER & GetWindowLongPtrW(ws->me, GWL_STYLE))) { RECT r = {11, 20, 8, 14}; host->oswndhost_setRegionOffsets(&r); } else host->oswndhost_setRegionOffsets(NULL); ws->extra_data[EMBED_STATE_EXTRA_HOSTCOUNT]++; ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)parent; //parent->getDesktopParent(); ee->whichwnd = (intptr_t)ws; if (ws->flags & EMBED_FLAGS_NOTRANSPARENCY) host->setNoTransparency(); host->oswndhost_host(ws->me); wchar_t buf[512] = {0}; GetWindowTextW(ws->me, buf, 512); host->setName(buf); } else { wndhosts.removeItem(ee); delete host; delete ee; return NULL; } wa2.setOnTop(cfg_options_alwaysontop.getValueAsInt()); return host; } //----------------------------------------------------------------------------------------------- int Wa2WndEmbed::testType(const wchar_t *windowtype) { return !_wcsicmp(windowtype, BUCKETITEM_WNDTYPE) || !_wcsicmp(windowtype, L"plsc"); } //----------------------------------------------------------------------------------------------- ifc_window *Wa2WndEmbed::createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n) { if (!_wcsicmp(windowtype, BUCKETITEM_WNDTYPE)) { switch (n) { case 0: { PlBucketItem *bi = new PlBucketItem(); bi->setBitmaps(L"winamp.thinger.pledit", NULL, L"winamp.thinger.pledit.hilited", L"winamp.thinger.pledit.selected"); bucketitems.addItem(bi); return bi; } case 1: { MlBucketItem *bi = new MlBucketItem(); bi->setBitmaps(L"winamp.thinger.library", NULL, L"winamp.thinger.library.hilited", L"winamp.thinger.library.selected"); bucketitems.addItem(bi); return bi; } case 2: { VidBucketItem *bi = new VidBucketItem(); bi->setBitmaps(L"winamp.thinger.video", NULL, L"winamp.thinger.video.hilited", L"winamp.thinger.video.selected"); bucketitems.addItem(bi); return bi; } case 3: { VisBucketItem *bi = new VisBucketItem(); bi->setBitmaps(L"winamp.thinger.vis", NULL, L"winamp.thinger.vis.hilited", L"winamp.thinger.vis.selected"); bucketitems.addItem(bi); return bi; } // cases must be contiguous, enumerator stops at first NULL #ifdef MINIBROWSER_SUPPORT case 4: { MbBucketItem *bi = new MbBucketItem(); bi->setBitmaps(hInstance, IDB_MB_TAB_NORMAL, NULL, IDB_MB_TAB_HILITED, IDB_MB_TAB_SELECTED); bucketitems.addItem(bi); return bi; } #endif // n is enumertor, not whichwnd // we also need some way for the embeddedwnd to expose at least one bitmap (ideally 3) so we can make a nice bucketitem here (this code uses a pledit icon) /* default: if (n > 1024) { EmbedBucketItem *bi = new EmbedBucketItem(); bi->setBitmaps(hInstance, IDB_PLEDIT_TAB_NORMAL, NULL, IDB_PLEDIT_TAB_HILITED, IDB_PLEDIT_TAB_SELECTED); bucketitems.addItem(bi); return bi; } break;*/ } } else if (!_wcsicmp(windowtype, L"plsc")) { switch (n) { case 0: pldirs.addItem(new PlDirObject); return pldirs.getLast(); } } return NULL; } //----------------------------------------------------------------------------------------------- int Wa2WndEmbed::destroyWindow(ifc_window *w) { foreach(bucketitems) Wa2BucketItem *i = bucketitems.getfor(); ifc_window *rw = i; if (rw == w) { delete i; return 1; } endfor; foreach(wndhosts) EmbedEntry *ee = wndhosts.getfor(); WaOsWndHost *x = ee->host; if (WASABI_API_WND->rootwndIsValid(x)) { ifc_window *rw = x; if (rw == w) { ReentryFilter f(&wndMsgFilter, ee->whichwnd); if (!f.mustLeave()) { // this would hide the winamp window, which is probably not what we want to do (it should remain visible if it // was visible, no? // well, no, because we don't only run this in skin unloading, but also when a window gets destroyed (this is the wndcreation // service being called to free what it created) -- this won't happen for mmd3/pledit because mmd3 has a static window for // everything, which means that when you click close on it, it doesn't destroy it but hides it, so this code isn't called. but // if you load another skin (ie: NonStep), and you close the pledit, it immediately reappears with the wa2 look since oswndhost_unhost // reset the flags, region and parent to what they were before the window was embedded // i think that what we need is to save which windows were visible (and their location) before switching to freeform // and to restore them when we go back to wa2 mode. this will also be more consistant with the freeform behavior of // remembering visible status and coordinates on a per skin basis (since otherwise freeform dockings get screwed) // it also makes sense when we consider that we are going to need to remove all windowshade modes from the embedded // windows when going freeform. // see new functions: rememberVisibleWindows() and restoreVisibleWindows() // in any case, we need to hide the window here, at least temporarily in the case of skin unloading { if (ee->whichwnd > 1024) { embedWindowState *ws = NULL; //embedWindowState *ws = (embedWindowState *)ee->whichwnd; HWND hHost, hContent; hHost = (NULL != x) ? x->getHWND() : NULL; hContent = (NULL != hHost) ? (HWND)SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)hHost, IPC_FF_GETCONTENTWND) : NULL; if (NULL != hContent) { ws = (embedWindowState *)GetWindowLongPtrW(hContent, GWLP_USERDATA); } else { embedWndGuidMgr.retireEmbedWindowState((embedWindowState *)ee->whichwnd); } if (NULL != ws && !(wa2.isValidEmbedWndState(ws) && --ws->hostcount != 0)) { if (0 != (EMBED_FLAGS_FFCALLBACK & ws->flags) && NULL != ws->callback) { ws->callback(ws, FFC_DESTROYEMBED, (LPARAM)w); } x->oswndhost_unhost(); if (wa2.isValidEmbedWndState(ws)) ws->wasabi_window = NULL; if (!x->isTransfering() && wa2.isValidEmbedWndState(ws)) { if (IsWindow(x->getHWND())) { SendMessageW(ws->me, WM_USER + 101, 0, 0); } embedWndGuidMgr.retireEmbedWindowState(ws); } } } else { if (ee->whichwnd == IPC_GETWND_VIDEO) KillTimer(wa2.getWnd(ee->whichwnd), 12345); x->oswndhost_unhost(); if (!x->isTransfering()) wa2.setWindowVisible(ee->whichwnd, 0); #ifdef VIDDEBUG if (ee->whichwnd == IPC_GETWND_VIDEO) DebugString("Video : Window service asks WA2 to close the window\n"); #endif } } } wndhosts.removeItem(ee); embedWindowState *ws = NULL; HWND thiswnd = NULL; if (ee->whichwnd > 1024) { if (IsWindow(x->getHWND())) thiswnd = x->getHWND(); //ws=(embedWindowState *)ee->whichwnd; //thiswnd=ws->me; } else thiswnd = wa2.getWnd(ee->whichwnd); //moved to xuioswndhost //SetWindowLong(thiswnd,GWL_STYLE,GetWindowLong(thiswnd,GWL_STYLE)&~(WS_CHILDWINDOW)); switch (ee->whichwnd) { case IPC_GETWND_PE: plWnd = NULL; break; #ifdef MINIBROWSER_SUPPORT case IPC_GETWND_MB: mbWnd = NULL; break; #endif case IPC_GETWND_VIDEO: #ifdef VIDDEBUG DebugString("Video : Window service destroys host\n"); #endif vidWnd = NULL; break; default: if (ee->whichwnd > 1024 && ws && thiswnd != NULL) { ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = 0; } break; } if (ee->cmds) { GuiObject *o = w->getParent()->getGuiObject(); o->guiobject_removeAppCmds(ee->cmds); } x->oswndhost_unhost(); // ignored if already done by reentryfiltered code delete ee->monitor; delete ee->cmds; delete x; if (ee->whichwnd > 1024 && ws) { if (forcedoffwnds.haveItem(ws->me)) { RECT r; GetWindowRect(ws->me, &r); SetWindowPos(ws->me, NULL, r.left + 20000, r.top + 20000, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER); forcedoffwnds.delItem(ws->me); } } delete ee; SetFocus(wa2.getMainWindow()); return 1; } endfor; foreach (pldirs) PlDirObject *pldir = pldirs.getfor(); if (pldir == w) { delete pldir; return 1; } endfor; } return 0; } //----------------------------------------------------------------------------------------------- int Wa2WndEmbed::viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen) { if (event == ifc_window::Event_SETVISIBLE) { /* if (!param) { // the wnd may be going away, but then again, it might just be hidden to show an alternate layout of the same // container, so before continuing, we need to check if it's actually going away. There is of course an exception // in that if the window is hosted by a wndholder with autoclose="1", we should mirror the hiding state regardless // of the container state api_window *whr = item->getParent(); int except = 0; if (whr) { GuiObject *go = whr->getGuiObject(); if (go) { const char *par = go->guiobject_getXmlParam("autoclose"); if (!par || (par && ATOI(par) == 1)) except = 1; } } if (!except) { api_window *lr = item->getDesktopParent(); if (lr) { Layout *l = static_cast(lr->getInterface(layoutGuid)); if (l) { Container *c = l->getParentContainer(); if (c) { if (c->isVisible()) return 1; } } } } }*/ foreach(wndhosts) EmbedEntry *ee = wndhosts.getfor(); XuiOSWndHost *x = ee->host; ifc_window *rw = x; if (rw == item) { { ReentryFilter f(&wndMsgFilter, ee->whichwnd); if (f.mustLeave()) continue; } if (ee->whichwnd > 1024) { embedWindowState *ws = (embedWindowState *)ee->whichwnd; if (!param && wa2.isValidEmbedWndState(ws)) { if (IsWindow(ws->me)) SendMessageW(ws->me, WM_USER + 101, 0, 0); ifc_window *rwh = x->findWindowByInterface(windowHolderGuid); if (rwh != NULL) { WindowHolder *wh = static_cast(rwh->getInterface(windowHolderGuid)); if (wh != NULL) { wh->onRemoveWindow(1); } } if (wa2.isValidEmbedWndState(ws)) ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL; } else if (wa2.isValidEmbedWndState(ws)) { ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)item->getParent(); ShowWindow(ws->me, SW_NORMAL); } } else { ReentryFilter f(&wndMsgFilter, ee->whichwnd); #ifdef VIDDEBUG if (ee->whichwnd == IPC_GETWND_VIDEO && param != wa2.isWindowVisible(ee->whichwnd)) DebugString("Video : Detected that the host is %s, syncing\n", param ? "shown" : "hidden"); #endif wa2.setWindowVisible(ee->whichwnd, param); } } endfor; } return 1; } int Wa2WndEmbed::onShowWindow(Container *c, GUID guid, const wchar_t *groupid) { foreach(wndhosts) EmbedEntry *ee = wndhosts.getfor(); if (ee->g == guid) { ReentryFilter f(&wndMsgFilter, ee->whichwnd); if (f.mustLeave()) return 1; if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 1); #ifdef MINIBROWSER_SUPPORT else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 1); #endif else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 1); } endfor; return 1; } int Wa2WndEmbed::onHideWindow(Container *c, GUID guid, const wchar_t *groupid) { /* if (guid == INVALID_GUID) return 1; embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(guid); if (ws != NULL && wa2.isValidEmbedWndState(ws)) { if (IsWindow(ws->me)) SendMessageW(ws->me,WM_USER+101,0,0); api_window *x = (api_window*)ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND]; if (x && WASABI_API_WND->rootwndIsValid(x)) { api_window *rwh = x->findWindowByInterface(windowHolderGuid); if (rwh != NULL) { WindowHolder *wh = static_cast(rwh->getInterface(windowHolderGuid)); if (wh != NULL) { wh->onRemoveWindow(1); } } } ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL; } */ foreach(wndhosts) EmbedEntry *ee = wndhosts.getfor(); if (ee->g == guid) { ReentryFilter f(&wndMsgFilter, ee->whichwnd); if (f.mustLeave()) return 1; if (ee->host->isTransfering()) return 1; ifc_window *dp = ee->host->getDesktopParent(); if (dp) { Layout *l = static_cast(dp->getInterface(layoutGuid)); if (l) { if (l->getParentContainer() != c) return 1; } } if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 0); #ifdef MINIBROWSER_SUPPORT else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 0); #endif else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 0); } endfor; return 1; } extern wchar_t *INI_FILE; int Wa2WndEmbed::embedRememberProc(embedWindowState *p, embedEnumStruct *parms) { WndStatus *ws = new WndStatus; ws->wndcode = -1; // if you insert a wnd that is not in embedTable, put -1 as wndcode ws->wnd = p->me; ws->visible = IsWindowVisible(p->me); GetWindowRect(p->me, &ws->position); // ws->position=p->r; wa2wndstatus.addItem(ws); // only store the ml window position if not loading on startup if(going_freeform && !m_loading_at_startup) { HWND mlwnd = wa2.getMediaLibrary(); if(GetWindow(p->me, GW_CHILD) == mlwnd) { WritePrivateProfileStringW(L"gen_ff", L"classicmlwidth", StringPrintfW(L"%d", ws->position.right - ws->position.left), INI_FILE); WritePrivateProfileStringW(L"gen_ff", L"classicmlheight", StringPrintfW(L"%d", ws->position.bottom - ws->position.top), INI_FILE); } } return 0; } extern int m_loading_at_startup; //----------------------------------------------------------------------------------------------- // todo: remember and restore windowshade modes void Wa2WndEmbed::rememberVisibleWindows() { wa2wndstatus.deleteAll(); for (int i = 0;i < sizeof(embedTable) / sizeof(embedTable[0]);i++) { HWND w = wa2.getWnd(embedTable[i]); WndStatus *ws = new WndStatus; ws->wndcode = embedTable[i]; // if you insert a wnd that is not in embedTable, put -1 as wndcode ws->wnd = w; ws->visible = wa2.isWindowVisible(embedTable[i]); GetWindowRect(w, &ws->position); if (going_freeform) { if (embedTable[i] == IPC_GETWND_PE) { int peheight = ws->position.bottom - ws->position.top; int pewidth = ws->position.right - ws->position.left; if (!m_loading_at_startup) { WritePrivateProfileStringW(L"gen_ff", L"classicplwidth", StringPrintfW(L"%d", pewidth), INI_FILE); WritePrivateProfileStringW(L"gen_ff", L"classicplheight", StringPrintfW(L"%d", peheight), INI_FILE); } int classicpews = wa2.isWindowShade(IPC_GETWND_PE); if (!m_loading_at_startup || GetPrivateProfileIntW(L"gen_ff", L"classicplws", -1, INI_FILE) == -1) WritePrivateProfileStringW(L"gen_ff", L"classicplws", classicpews ? L"1" : L"0", INI_FILE); if (classicpews) SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0); GetWindowRect(w, &ws->position); } } wa2wndstatus.addItem(ws); } embedEnumStruct cs = { embedRememberProc, 0}; SendMessageW(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM); } int Wa2WndEmbed::hadRememberedWndVisible(HWND w) { int n = wa2wndstatus.getNumItems(); for (int i = 0;i < n;i++) { WndStatus *ws = wa2wndstatus.enumItem(i); if (ws->wnd == w && ws->visible) return 1; } return 0; } void Wa2WndEmbed::restoreVisibleWindows() { int n = wa2wndstatus.getNumItems(); HWND mlwnd = wa2.getMediaLibrary(); for (int i = 0;i < n;i++) { WndStatus *ws = wa2wndstatus.enumItem(i); if (going_fixedform && !m_loading_at_startup) { if (embedTable[i] == IPC_GETWND_PE) { int classicpews = GetPrivateProfileIntW(L"gen_ff", L"classicplws", 0, INI_FILE); if (classicpews) { SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0); } int classicwidth = GetPrivateProfileIntW(L"gen_ff", L"classicplwidth", 275, INI_FILE); int classicheight = GetPrivateProfileIntW(L"gen_ff", L"classicplheight", 145, INI_FILE); wa2.setPlEditWidthHeight(classicwidth, classicheight); } if(GetWindow(ws->wnd, GW_CHILD) == mlwnd) { // only restore the ml window size if we were able to read in saved values int mlwidth = GetPrivateProfileIntW(L"gen_ff", L"classicmlwidth", -1, INI_FILE); int mlheight = GetPrivateProfileIntW(L"gen_ff", L"classicmlheight", -1, INI_FILE); if(mlwidth != -1 && mlheight != -1) SetWindowPos(ws->wnd, 0, 0, 0, mlwidth, mlheight, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); } } // FG> as of oct19, this function only restores state for windows that WERE visible // because there is no reason to hide one, since this function is designed to bring // back those windows that were here in one mode, but aren't so anymore in another if (ws->visible) { if (ws->wndcode != -1) { wa2.setWindowVisible(ws->wndcode, ws->visible); } else { ShowWindow(ws->wnd, ws->visible ? SW_SHOWNA : SW_HIDE); } } } } PtrList Wa2WndEmbed::wa2wndstatus; //----------------------------------------------------------------------------------------------- PlaylistAppCmds::PlaylistAppCmds() : addCmd(L"Add", PL_ADD, AppCmds::SIDE_LEFT, 0), remCmd(L"Rem", PL_REM, AppCmds::SIDE_LEFT, 0), selCmd(L"Sel", PL_SEL, AppCmds::SIDE_LEFT, 0), miscCmd(L"Misc", PL_MISC, AppCmds::SIDE_LEFT, 0), listCmd(L"List", PL_LIST, AppCmds::SIDE_RIGHT, 0) { appcmds_addCmd(&addCmd); appcmds_addCmd(&remCmd); appcmds_addCmd(&selCmd); appcmds_addCmd(&miscCmd); appcmds_addCmd(&listCmd); } void PlaylistAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button) { switch (id) { case PL_ADD: wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_ADD, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN); break; case PL_REM: wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_REM, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN); break; case PL_SEL: wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_SEL, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN); break; case PL_MISC: wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_MISC, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN); break; case PL_LIST: wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_LIST, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN); break; } } #ifdef MINIBROWSER_SUPPORT //----------------------------------------------------------------------------------------------- MinibrowserAppCmds::MinibrowserAppCmds() { appcmds_addCmd(new CmdRec("Back", MB_BACK, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec("Forward", MB_FORWARD, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec("Stop", MB_STOP, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec("Reload", MB_RELOAD, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec("Misc", MB_MISC, AppCmds::SIDE_RIGHT, 1)); } void MinibrowserAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button) { switch (id) { case MB_BACK: wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_BACK); break; case MB_FORWARD: wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_FORWARD); break; case MB_STOP: wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_STOP); break; case MB_RELOAD: wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_RELOAD); break; case MB_MISC: wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN); break; } } #endif //----------------------------------------------------------------------------------------------- VideoAppCmds::VideoAppCmds() { appcmds_addCmd(new CmdRec(L"Fullscreen", VID_FULLSCREEN, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec(L"1x", VID_1X, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec(L"2x", VID_2X, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec(L"TV", VID_LIB, AppCmds::SIDE_LEFT, 1)); appcmds_addCmd(new CmdRec(L"Misc", VID_MISC, AppCmds::SIDE_RIGHT, 1)); } void VideoAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button) { switch (id) { case VID_FULLSCREEN: wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_FULLSCREEN); break; case VID_1X: wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_1X); break; case VID_2X: wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_2X); break; case VID_LIB: wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_LIB); break; case VID_MISC: wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN); break; } }