Author: gadamopoulos Date: Mon May 30 22:38:36 2016 New Revision: 71465
URL: http://svn.reactos.org/svn/reactos?rev=71465&view=rev Log: [BROWSEUI] - Implement most methods of IBandSite for CBaseBarSite. - Part of the work submitted by Sylvain Deverre. CORE-8814 and CORE-10838
Modified: trunk/reactos/dll/win32/browseui/basebarsite.cpp
Modified: trunk/reactos/dll/win32/browseui/basebarsite.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/browseui/basebars... ============================================================================== --- trunk/reactos/dll/win32/browseui/basebarsite.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/browseui/basebarsite.cpp [iso-8859-1] Mon May 30 22:38:36 2016 @@ -128,6 +128,12 @@ // message handlers LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
+ // Helper functions + HRESULT FindBandByGUID(REFIID pGuid, DWORD *pdwBandID); + HRESULT ShowBand(DWORD dwBandID); + HRESULT GetInternalBandInfo(UINT uBand, REBARBANDINFO *pBandInfo); + HRESULT GetInternalBandInfo(UINT uBand, REBARBANDINFO *pBandInfo, DWORD fMask); + BEGIN_MSG_MAP(CBaseBarSite) MESSAGE_HANDLER(WM_NOTIFY, OnNotify) END_MSG_MAP() @@ -165,12 +171,12 @@ CComPtr<IObjectWithSite> site; CComPtr<IOleWindow> oleWindow; CComPtr<IDeskBand> deskBand; - CComPtr<IDockingWindow> dockingWindow; CBarInfo *newInfo; REBARBANDINFOW bandInfo; DESKBANDINFO deskBandInfo; DWORD thisBandID; HRESULT hResult; + CLSID tmp;
hResult = newBar->QueryInterface(IID_PPV_ARG(IPersist, &persist)); if (FAILED_UNEXPECTEDLY(hResult)) @@ -184,12 +190,22 @@ hResult = newBar->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand)); if (FAILED_UNEXPECTEDLY(hResult)) return hResult; - hResult = newBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow)); - if (FAILED_UNEXPECTEDLY(hResult)) - return hResult; + + // Check if the GUID already exists + hResult = persist->GetClassID(&tmp); + if (!SUCCEEDED(hResult)) + { + return E_INVALIDARG; + } + if (FindBandByGUID(tmp, &thisBandID) == S_OK) + { + return ShowBand(thisBandID); + } + hResult = site->SetSite(static_cast<IOleWindow *>(this)); if (FAILED_UNEXPECTEDLY(hResult)) return hResult; + ATLTRY(newInfo = new CBarInfo); if (newInfo == NULL) return E_OUTOFMEMORY; @@ -198,23 +214,26 @@ thisBandID = fNextBandID++; newInfo->fTheBar = newBar; newInfo->fBandID = thisBandID; - hResult = persist->GetClassID(&newInfo->fBarClass); + newInfo->fBarClass = tmp;
// get band info - deskBandInfo.dwMask = DBIM_MINSIZE | DBIM_ACTUAL | DBIM_TITLE; + deskBandInfo.dwMask = DBIM_MINSIZE | DBIM_ACTUAL | DBIM_TITLE | DBIM_BKCOLOR; deskBandInfo.wszTitle[0] = 0; - hResult = deskBand->GetBandInfo(0, 0, &deskBandInfo); + hResult = deskBand->GetBandInfo(0, (fVertical) ? DBIF_VIEWMODE_VERTICAL : DBIF_VIEWMODE_NORMAL, &deskBandInfo);
// insert band memset(&bandInfo, 0, sizeof(bandInfo)); bandInfo.cbSize = sizeof(bandInfo); bandInfo.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_TEXT | RBBIM_LPARAM | RBBIM_ID; - bandInfo.fStyle = RBBS_NOGRIPPER | RBBS_VARIABLEHEIGHT; + bandInfo.fStyle = RBBS_TOPALIGN | RBBS_VARIABLEHEIGHT | RBBS_NOGRIPPER; bandInfo.lpText = deskBandInfo.wszTitle; hResult = oleWindow->GetWindow(&bandInfo.hwndChild); + /* It seems Windows XP doesn't take account of band minsize */ +#if 0 bandInfo.cxMinChild = 200; //deskBandInfo.ptMinSize.x; bandInfo.cyMinChild = 200; //deskBandInfo.ptMinSize.y; +#endif bandInfo.cx = 0; bandInfo.wID = thisBandID; bandInfo.cyChild = -1; //deskBandInfo.ptActual.y; @@ -223,15 +242,10 @@ bandInfo.cxIdeal = 0; //deskBandInfo.ptActual.x; bandInfo.lParam = reinterpret_cast<LPARAM>(newInfo); SendMessage(RB_INSERTBANDW, -1, reinterpret_cast<LPARAM>(&bandInfo)); - - // this call is what makes the tree fill with contents - hResult = dockingWindow->ShowDW(TRUE); - if (FAILED_UNEXPECTEDLY(hResult)) - return hResult; - // for now - fCurrentActiveBar = newInfo; - return S_OK; -} + hResult = ShowBand(newInfo->fBandID); + //fCurrentActiveBar = newInfo; + return hResult; + }
HRESULT STDMETHODCALLTYPE CBaseBarSite::GetWindow(HWND *lphwnd) { @@ -299,7 +313,6 @@ CComPtr<IDeskBar> deskBar; CComPtr<IWinEventHandler> winEventHandler; NMHDR *notifyHeader; - RECT newBounds; HRESULT hResult;
hResult = S_OK; @@ -308,9 +321,13 @@ notifyHeader = (NMHDR *)lParam; if (notifyHeader->hwndFrom == m_hWnd && notifyHeader->code == RBN_AUTOSIZE) { + // For now, don't notify basebar we tried to resize ourselves, we don't + // get correct values at the moment. +#if 0 hResult = fDeskBarSite->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar)); GetClientRect(&newBounds); hResult = deskBar->OnPosRectChangeDB(&newBounds); +#endif } } if (fCurrentActiveBar != NULL) @@ -338,10 +355,23 @@ { CComPtr<IOleWindow> oleWindow; HWND ownerWindow; - HRESULT hResult; - + HRESULT hResult; + DWORD dwBandID; + if (punkSite == NULL) - fDeskBarSite.Release(); + { + + TRACE("Destroying site \n"); + /* Cleanup our bands */ + while(SUCCEEDED(EnumBands(-1, &dwBandID)) && dwBandID) + { + hResult = EnumBands(0, &dwBandID); + if(FAILED_UNEXPECTEDLY(hResult)) + continue; + RemoveBand(dwBandID); + } + fDeskBarSite = NULL; + } else { hResult = punkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow)); @@ -353,11 +383,20 @@ hResult = oleWindow->GetWindow(&ownerWindow); if (FAILED_UNEXPECTEDLY(hResult)) return hResult; - m_hWnd = CreateWindow(REBARCLASSNAMEW, NULL, WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | - WS_CLIPCHILDREN | - RBS_VARHEIGHT | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_VERTICALGRIPPER | RBS_DBLCLKTOGGLE | - CCS_LEFT | CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE, 0, 0, 0, 0, ownerWindow, NULL, + + DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER | + RBS_VARHEIGHT | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_VERTICALGRIPPER | RBS_DBLCLKTOGGLE | + CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE; + if (fVertical) + dwStyle |= CCS_VERT; + + /* Create site window */ + HWND tmp = CreateWindowW(REBARCLASSNAMEW, NULL, dwStyle, 0, 0, 0, 0, ownerWindow, NULL, _AtlBaseModule.GetModuleInstance(), NULL); + + /* Give window management to ATL */ + SubclassWindow(tmp); + SendMessage(RB_SETTEXTCOLOR, 0, CLR_DEFAULT); SendMessage(RB_SETBKCOLOR, 0, CLR_DEFAULT); } @@ -392,6 +431,8 @@ { switch (nCmdID) { + case 0: + //update band info ? case 1: // insert a new band if (V_VT(pvaIn) != VT_UNKNOWN) return E_INVALIDARG; @@ -401,6 +442,33 @@ return E_FAIL; }
+HRESULT CBaseBarSite::GetInternalBandInfo(UINT uBand, REBARBANDINFO *pBandInfo) +{ + if (!pBandInfo) + return E_INVALIDARG; + memset(pBandInfo, 0, sizeof(REBARBANDINFO)); + pBandInfo->cbSize = sizeof(REBARBANDINFO); + pBandInfo->fMask = RBBIM_LPARAM | RBBIM_ID; + + // Grab our bandinfo from rebar control + if (!SendMessage(RB_GETBANDINFO, uBand, reinterpret_cast<LPARAM>(pBandInfo))) + return E_INVALIDARG; + return S_OK; +} + +HRESULT CBaseBarSite::GetInternalBandInfo(UINT uBand, REBARBANDINFO *pBandInfo, DWORD fMask) +{ + if (!pBandInfo) + return E_INVALIDARG; + pBandInfo->cbSize = sizeof(REBARBANDINFO); + pBandInfo->fMask = fMask; + + // Grab our bandinfo from rebar control + if (!SendMessage(RB_GETBANDINFO, uBand, reinterpret_cast<LPARAM>(pBandInfo))) + return E_INVALIDARG; + return S_OK; +} + HRESULT STDMETHODCALLTYPE CBaseBarSite::AddBand(IUnknown *punk) { return InsertBar(punk); @@ -408,12 +476,19 @@
HRESULT STDMETHODCALLTYPE CBaseBarSite::EnumBands(UINT uBand, DWORD *pdwBandID) { + REBARBANDINFO bandInfo; + + if (pdwBandID == NULL) + return E_INVALIDARG; if (uBand == 0xffffffff) { *pdwBandID = (DWORD)SendMessage(RB_GETBANDCOUNT, 0, 0); return S_OK; } - return E_NOTIMPL; + if (!SUCCEEDED(GetInternalBandInfo(uBand, &bandInfo))) + return E_INVALIDARG; + *pdwBandID = bandInfo.wID; + return S_OK; }
HRESULT STDMETHODCALLTYPE CBaseBarSite::QueryBand(DWORD dwBandID, IDeskBand **ppstb, @@ -429,14 +504,77 @@
HRESULT STDMETHODCALLTYPE CBaseBarSite::RemoveBand(DWORD dwBandID) { - return E_NOTIMPL; + REBARBANDINFO bandInfo; + HRESULT hr; + CBarInfo *pInfo; + CComPtr<IObjectWithSite> pSite; + CComPtr<IDeskBand> pDockWnd; + DWORD index; + + // Retrieve the right index of the coolbar knowing the id + index = SendMessage(RB_IDTOINDEX, dwBandID, 0); + if (index == 0xffffffff) + return E_INVALIDARG; + + if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(index, &bandInfo))) + return E_INVALIDARG; + + pInfo = reinterpret_cast<CBarInfo*>(bandInfo.lParam); + if (!pInfo) + return E_INVALIDARG; + + hr = pInfo->fTheBar->QueryInterface(IID_PPV_ARG(IDeskBand, &pDockWnd)); + if (FAILED_UNEXPECTEDLY(hr)) + { + return E_NOINTERFACE; + } + hr = pInfo->fTheBar->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pSite)); + if (FAILED_UNEXPECTEDLY(hr)) + { + return E_NOINTERFACE; + } + /* Windows sends a CloseDW before setting site to NULL */ + pDockWnd->CloseDW(0); + pSite->SetSite(NULL); + + // Delete the band from rebar + if (!SendMessage(RB_DELETEBAND, index, 0)) + { + ERR("Can't delete the band\n"); + return E_INVALIDARG; + } + if (pInfo == fCurrentActiveBar) + { + // FIXME: what to do when we are deleting active bar ? Let's assume we remove it for now + fCurrentActiveBar = NULL; + } + delete pInfo; + return S_OK; }
HRESULT STDMETHODCALLTYPE CBaseBarSite::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv) { + REBARBANDINFO bandInfo; + HRESULT hr; + CBarInfo *pInfo; + DWORD index; + if (ppv == NULL) return E_POINTER; - return E_NOTIMPL; + + // Retrieve the right index of the coolbar knowing the id + index = SendMessage(RB_IDTOINDEX, dwBandID, 0); + if (index == 0xffffffff) + return E_INVALIDARG; + + if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(index, &bandInfo))) + return E_INVALIDARG; + + pInfo = reinterpret_cast<CBarInfo*>(bandInfo.lParam); + hr = pInfo->fTheBar->QueryInterface(riid, ppv); + if (!SUCCEEDED(hr)) + return E_NOINTERFACE; + return S_OK; }
HRESULT STDMETHODCALLTYPE CBaseBarSite::SetBandSiteInfo(const BANDSITEINFO *pbsinfo) @@ -491,9 +629,71 @@ if (notifyHeader->hwndFrom == m_hWnd) { } + bHandled = FALSE; /* forward notification to parent */ return 0; }
+HRESULT CBaseBarSite::FindBandByGUID(REFGUID pGuid, DWORD *pdwBandID) +{ + DWORD numBands; + DWORD i; + HRESULT hr; + REBARBANDINFO bandInfo; + CBarInfo *realInfo; + + hr = EnumBands(-1, &numBands); + if (FAILED_UNEXPECTEDLY(hr)) + return E_FAIL; + + for(i = 0; i < numBands; i++) + { + if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(i, &bandInfo))) + return E_FAIL; + realInfo = (CBarInfo*)bandInfo.lParam; + if (IsEqualGUID(pGuid, realInfo->fBarClass)) + { + *pdwBandID = realInfo->fBandID; + return S_OK; + } + } + return S_FALSE; +} + +HRESULT CBaseBarSite::ShowBand(DWORD dwBandID) +{ + UINT index; + CComPtr<IDeskBand> dockingWindow; + HRESULT hResult; + REBARBANDINFO bandInfo; + + // show our band + hResult = GetBandObject(dwBandID, IID_PPV_ARG(IDeskBand, &dockingWindow)); + if (FAILED_UNEXPECTEDLY(hResult)) + return E_FAIL; + + hResult = dockingWindow->ShowDW(TRUE); + + // Hide old band while adding new one + if (fCurrentActiveBar && fCurrentActiveBar->fBandID != dwBandID) + { + DWORD index; + index = SendMessage(RB_IDTOINDEX, fCurrentActiveBar->fBandID, 0); + if (index != 0xffffffff) + SendMessage(RB_SHOWBAND, index, 0); + } + if (FAILED_UNEXPECTEDLY(hResult)) + return hResult; + + // Display the current band + index = SendMessage(RB_IDTOINDEX, dwBandID, 0); + if (index != 0xffffffff) + SendMessage(RB_SHOWBAND, index, 1); + if (FAILED_UNEXPECTEDLY(GetInternalBandInfo(index, &bandInfo))) + return E_FAIL; + fCurrentActiveBar = (CBarInfo*)bandInfo.lParam; + return S_OK; +} + HRESULT CreateBaseBarSite(REFIID riid, void **ppv, BOOL bVertical) { return ShellObjectCreatorInit<CBaseBarSite, BOOL>(bVertical, riid, ppv);