Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Command Bars
  New Posts New Posts RSS Feed - A derived class : CXTPControlPopup ...
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

A derived class : CXTPControlPopup ...

 Post Reply Post Reply
Author
Message
Sstar9 View Drop Down
Newbie
Newbie


Joined: 25 August 2006
Status: Offline
Points: 25
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sstar9 Quote  Post ReplyReply Direct Link To This Post Topic: A derived class : CXTPControlPopup ...
    Posted: 08 September 2006 at 9:55am

I wanted to create a popup control which is similar to CXTPControlPopupColor. Note the small color bar at bottom of the CXTPControlPopupColor Icon could be updated by calling its SetColor(nColor) function.  Now I wanted it add one more parameter, nWidth, to this function, so that the Color bar's thickness could be updated as well. To do this, I created a derived a class from CXTPControlPopup, the code is something like below.

// in MyControlPopupColor.h
 
class  CMyControlPopupColor : public CXTPControlPopup
{
...
 
public:
       void SetColorWidth(COLORREF clr, int nWidth);

private:
      void RedrawIcon(CXTPImageManagerIcon* pImage, CXTPImageManagerIconHandle* hIcon );
 
private:
     COLORREF m_clr;
     int m_nWidth;   
...
}
 
 
//in MyControlPopupColor.cpp
 
//SetColorWidth function
void CMyControlPopupColor::SetColorWidth(COLORREF clr, int nWidth)
{
 if (clr != m_clr)
 {
  m_clr = clr;
  
  if (nWidth < 1)
   m_nWidth = 1;
  else if(nWidth > 10)
   m_nWidth = 10;
  else
   m_nWidth = nWidth;
 
  CXTPImageManagerIconSet* pIconSet = GetImageManager()->GetIconSet(GetIconId());
  if (pIconSet)
  {
   pIconSet->RefreshAll();
   CXTPImageManagerIconSet::CIconSetMap* pMap = pIconSet->GetIcons();
   POSITION pos = pMap->GetStartPosition();
   UINT nWidth;
   CXTPImageManagerIcon* pImage;
   while (pos != NULL)
   {
    pMap->GetNextAssoc(pos, nWidth, pImage);
    CXTPImageManagerIconHandle hIcon;
    RedrawIcon(pImage, &hIcon);
    if (!hIcon.IsEmpty())
    {
     pImage->SetIcon(hIcon);
    }
   }
   RedrawParent();
  }
 }
}
 
//RedrawIcon function
void CMyControlPopupColor::RedrawIcon(CXTPImageManagerIcon* pImage, CXTPImageManagerIconHandle* pHandle)
{
 CXTPImageManagerIconHandle& hIcon = pImage->GetIcon();
 if (hIcon.IsEmpty())
  return;
 if (!hIcon.IsAlpha())
 {
  ICONINFO info;
  if (GetIconInfo(hIcon.GetIcon(), &info))
  {
   {
    CXTPCompatibleDC dc(NULL, CBitmap::FromHandle(info.hbmColor));
    CXTPCompatibleDC dcMask(NULL, CBitmap::FromHandle(info.hbmMask));
    BITMAP bmp;
    ::GetObject(info.hbmColor, sizeof(BITMAP), &bmp);
    //int nHeight = int((double)bmp.bmHeight / 5);
    int nHeight = int(1 + (bmp.bmHeight) / 30.0 * m_nWidth);
    CRect rc(0, bmp.bmHeight - nHeight, bmp.bmWidth, bmp.bmHeight);
    dc.FillSolidRect(rc, m_clr);
    dcMask.FillSolidRect(rc, 1);
   }
   *pHandle = CreateIconIndirect(&info);
   ::DeleteObject(info.hbmMask);
   ::DeleteObject(info.hbmColor);
  }
 }
 else
 {
  CDC dcSrc;
  dcSrc.CreateCompatibleDC(NULL);
  PBYTE pBits = 0;
  PBITMAPINFO pBitmapInfo = 0;
  pHandle->CopyHandle(hIcon);
  TRY
  {
   UINT nSize;
   if (!CXTPImageManagerIcon::GetBitmapBits(dcSrc, pHandle->GetBitmap(), pBitmapInfo, (LPVOID&)pBits, nSize))
    AfxThrowMemoryException();
   DWORD dwColor = 0xFF000000 | CLR_TO_RGBQUAD(m_clr);
   int temp = int (1 + (pBitmapInfo->bmiHeader.biHeight) / 30.0 * m_nWidth);
   //int nCount = pBitmapInfo->bmiHeader.biHeight / 5 * pBitmapInfo->bmiHeader.biWidth * 4;
   int nCount = temp * pBitmapInfo->bmiHeader.biWidth * 4;
   for (int i = 0; i < nCount; i += 4)
   {
    *LPDWORD(&pBits) = dwColor;
   }
   SetDIBits(dcSrc, pHandle->GetBitmap(), 0, pBitmapInfo->bmiHeader.biHeight, pBits, pBitmapInfo, DIB_RGB_COLORS);

  }
  CATCH (CMemoryException, e)
  {
   TRACE(_T("Failed -- Memory exception thrown."));
  }
  END_CATCH
  free(pBits);
  free(pBitmapInfo);
 }
}
 
 
//The SetColorWidth(.) function and RedrawIcon(.) functions are slightly modified versions of that in the CXTPControlPopupColor class. I have highlighted my modified code in red.
 
With the derived class, I found I can change Color bar's width now but there is a problem.
 
If I call SetColorWidth function twice, first time with thicker width and and second time with a thinner width, e.g.
 
first time,
 
pColorControl->SetColorWidth(COLORRED, 10);
 
second time,
 
pColorControl->SetColorWidth(COLORRED, 2);
 
after the second call, the color bar thichness does not reduced to 2. The reason is color bar drawn first time is not removed during the 2nd to the function.
 
To solve this problem, I have tried to restore the original toolbar control's Icon by calling
 
pColorControl->Reset();
pColorControl->SetIconId(Orignal_Icon_ID);
 
before the second call to SetColorWidth(.) function. However, this does not work.  I cannot remove previously drawn color bar on the Icon. 
 
Could anybody help by giving some suggestions on how the above code should be modified to achieve the purpose? I would like to use Alpha toolbar icons in my application, hence I don't want the modified control Icon appear in different style from other icons on the Toolbar.  
 
 
Sharing makes life better
Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post Posted: 08 September 2006 at 10:20am
Obviously after you draw icon with width = 10 you changed icon and now width 2 can't be used for this icon. As solution you can reload this icon from original resource(bitmap or ico file)
pCommandBars->GetImageManager()->SetIcons(...);
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS
Back to Top
kevins View Drop Down
Newbie
Newbie
Avatar

Joined: 22 August 2006
Location: United States
Status: Offline
Points: 15
Post Options Post Options   Thanks (0) Thanks(0)   Quote kevins Quote  Post ReplyReply Direct Link To This Post Posted: 11 September 2006 at 3:34pm
I have a similar problem. With our color tools we want the color bar to be an empty box when None is selected. So in the RedrawIcon routine I don't want to draw anything on the tool, but what I end up with is the last color drawn on the tool. I tried the following as suggested:

      pCommandBars->GetImageManager()->SetIcons(IDR_TOOLBAR_COLOR);
      pCommandBars->RedrawCommandBars();

But it did not help. I bet I could reproduce the problem by editing CXTPControlPopupColor::RedrawIcon, but I don't want to go to that effort until I have to.

Any more ideas for a solution? Do I need to do something different to get it redrawn?

Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post Posted: 11 September 2006 at 4:23pm

Hi,

it have to work. don't call SetColor at all if color is none.
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS
Back to Top
kevins View Drop Down
Newbie
Newbie
Avatar

Joined: 22 August 2006
Location: United States
Status: Offline
Points: 15
Post Options Post Options   Thanks (0) Thanks(0)   Quote kevins Quote  Post ReplyReply Direct Link To This Post Posted: 11 September 2006 at 5:27pm
I don't think that works, if I understand what you mean.

As an example, in the Custom Themes example I modified CCustomThemesView::OnUpdateText so that I did not set the color if Red was selected. When I select Red nothing happens. I need a way to get the tool to go back to how it looks in the resources.

void CCustomThemesView::OnUpdateText(CCmdUI* pCmdUI)
{
    CXTPControlPopupColor* pPopup = DYNAMIC_DOWNCAST(CXTPControlPopupColor, CXTPControl::FromUI(pCmdUI));
   if (pPopup)
   {
      if (m_clr != (COLORREF)0x0000FF) // RED
         pPopup->SetColor(m_clr);
   }
   pCmdUI->Enable(TRUE);
}


Can you elaborate on what you are doing?

Back to Top
Sstar9 View Drop Down
Newbie
Newbie


Joined: 25 August 2006
Status: Offline
Points: 25
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sstar9 Quote  Post ReplyReply Direct Link To This Post Posted: 11 September 2006 at 9:16pm

In my Case, What Oleg suggested does work. By calling the XTPImageManager->SetIcons(ID_MyToolbar) first and then call the MyButton->SetColorWidth() again. I can reset the Toolbar button's icon to its default as in the Remource and redraw the color bar.

But one problem with the solution is by calling the XTPImageManager->SetIcons(ID_MyToolbar), all the control buttons' icons get updated to its default. But in my case, I just want to Update one. I am not sure if there is better solution than calling XTPImageManager->SetIcons(ID_MyToolbar) .

 

Sharing makes life better
Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post Posted: 12 September 2006 at 12:29am
Hi,
You can create new toolbar with only one icon. and call
XTPImageManager->SetIcons(ID_MyToolbar_withIconINeed) .
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS
Back to Top
kevins View Drop Down
Newbie
Newbie
Avatar

Joined: 22 August 2006
Location: United States
Status: Offline
Points: 15
Post Options Post Options   Thanks (0) Thanks(0)   Quote kevins Quote  Post ReplyReply Direct Link To This Post Posted: 13 September 2006 at 4:53pm
Sstar9, the problem gets even worse if you have created a new toolbar via customization!

Oleg's solution works for me. I do have to call Redraw.

CXTPCommandBar *pToolBar = (CXTPToolBar*)pCmdUI->m_pOther;
pToolBar->Redraw();

I had actually come up with a solution very similar to Oleg's but I was hoping for a better solution. Having to add copies of my tools in the resources seems like a bit of a work-around.

So Oleg, if you can keep this problem on a wish list or something that would be good.

Oh, final tidbit. None of this is necessary if the toolbars are customized to the Large Icons. It just simply works! Go figure. I think the tools must be automatically refreshing when they are at this size (perhaps this needs to be done when they are not large as well...).

Back to Top
ddlittle View Drop Down
Senior Member
Senior Member


Joined: 19 February 2004
Location: United States
Status: Offline
Points: 132
Post Options Post Options   Thanks (0) Thanks(0)   Quote ddlittle Quote  Post ReplyReply Direct Link To This Post Posted: 27 September 2006 at 6:34pm
Oleg,
 
I'm not sure what you mean.  Do you mean that toolbars on dialogs don't use CImageLists?  I tried creating a dummy toolbar with one button and doing what you mentioned, but got the same result.
 
For some weird reason, "Large" icons display the correct buttons, but the customize box doesn't seem to send my dialog a message telling me it's time to resize and reposition everything.
 
Thanks!
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.172 seconds.