Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Toolkit Pro
  New Posts New Posts RSS Feed - CXTPButton images on high dpi
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

CXTPButton images on high dpi

 Post Reply Post Reply
Author
Message
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Topic: CXTPButton images on high dpi
    Posted: 22 September 2015 at 9:47am
I'm currently testing our software with the new Codejock version 17, Beta 3 release.

With the codejock version 16.4.0, on high dpi devices , the images on our buttons were scaling down relative to the button size. Now with the new codejock version, the buttons are scaling up to take into account the dpi of the device used, but they begin to get quite pixelated.

I'm trying to provide larger images, 36x36 and 48x48 on top of the 24x24 ones we currently provide and setting the icon of the button with the one that best suits the dpi setting.

The problem I'm finding with this solution is that, when the image is drawn on the button, the CXTPButtonTheme code is scaling the image up again with calls to:

XTP_DPI(pButton->GetImageSize())

This causes the image to be quite badly clipped to the button extent.

At the moment, the only solution I can see is to remove the XTP_DPI wrapper around calls to pButton->GetImageSize(), in both the CXTPButtonTheme and CXTPButtonThemeOffice2013 classes. One side effect of this change is that, the new image sizes are slightly too big or too small for scales factors outside of 100%, 150% and 200%.

Any help would be greatly appreciated.
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 24 September 2015 at 4:58am
I've also found the same problem is occurring with icons on the Status Bar. You cannot provide larger icons as the code always uses the smallest one provided and if you only provide larger icons, say 32x32 instead of 16x16, then these images get quite badly clipped.

The most elegant solution I've found to the problem is to change the CXTPStatusBarPane GetImage function to take a width parameter,

CXTPImageManagerIcon* CXTPStatusBarPane::GetImage(int nWidth /*= 0*/) const
{
     if (m_nIconIndex != -1)
          return m_pStatusBar->GetImageManager()->GetImage(m_nIconIndex, nWidth);
     return NULL;
}

and then call this function, passing in the width of the status bar item, just before drawing the image in the CXTPStatusBarPaintManager DrawStatusBarPaneEntry function,

      if(pIcon = pPane->GetImage(rcItem.Width()))
                pIcon->Draw(pDC, CPoint(rcItem.left, (rcItem.top + rcItem.bottom - szIcon.cy) / 2),
                      bEnabled ? pIcon->GetIcon() : pIcon->GetDisabledIcon(), szIcon);
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 25 September 2015 at 6:27am
I've also found an issue with our right-click context menus. Icons on the popup menu are always drawn at size 16x16, rather than using larger icons and being scaled up or down if necessary.

Digging into the code, the problem appears to lie in the CXTPCommandbar function GetIconSize.

In this function, it calls GetCommandBars() and if this fails, it returns CSize(16,16);

I've fixed this by wrapping the return value in the XTP_DPI macro, thus getting:

     CXTPCommandBars* pCommandBars = GetCommandBars();

     if (!pCommandBars)
          return XTP_DPI(CSize(16, 16));

and now I'm getting much better results.
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 06 October 2015 at 6:36am
I've had an issue with, providing larger icon sets for ribbon bar items, messing up the ribbon layout. I've mentioned this somewhere in a previous post and my solution had been to not provide 32x32 icons if I want items on the ribbon to remain small.

The issue lies in a function IsPrimaryImageExists called from within OnBeforeCalcSize in the CXTPRibbonGroup class.

At the beginning of the OnBeforCalcSize function, it calls the function GetLargeIconSize(FALSE).

I've had to change the final block of the GetLargeIconSize function to be:

if (m_szButtons == CSize(0))
{
    sz = bAutoSize ? GetAutoIconSize(TRUE) :
      pCommandBars->m_pOptions->szLargeIcons != CSize(0) ?
               pCommandBars->m_pOptions->szLargeIcons : CSize(sz.cx * 2, sz.cy * 2);
}

and in my application, set:

pCommandBars->m_pOptions->szLargeIcons = CSize(64,64)

Doing these two things now enables me to provide large icon sets for both small and large ribbon bar items.
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 13 October 2015 at 9:03am
I also had an issue displaying different size icons in gallery control items. The existing code finds the smallest icon using CXTPControlGalleryItem::GetImage() function.

I had to change this function so that CXTPControlGalleryPaintManager DrawItem function intially finds the smallest icon, to work out drawing extents, and then just before drawing, finds the best icon to draw.

The change I made looks something like this:

CXTPImageManagerIcon* CXTPControlGalleryItem::GetImage(bool bSmall)
{
     if (!m_pItems)
          return NULL;

     return m_pItems->GetImageManager()->GetImage(m_nImage >= 0 ? m_nImage : m_nId, (bSmall == true) ? 0 : m_nImageWidth);
}

and calls to draw the image look like this:

if (pImage = pGalleryItem->GetImage(false))
    pImage->Draw(pDC, pt, pImage->GetIcon(bEnabled ? xtpImageNormal : xtpImageDisabled), szImage);

For this to have any effect, larger images must be supplied and gallery items must call SetImageWidth, with the smallest icon width wrapped in the XTP_DPI_X macro.
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 13 October 2015 at 12:16pm
Again, I've found a similar issue with the CXTPControlBitmap class. The class only allows for one image to be provided and scales it up accordingly.

To enable multiple images to be provided I had to make the following changes:

CSize CXTPControlBitmap::GetSize(CDC* /*pDC*/)
{
     CXTPImageManagerIcon* pIcon = GetImageManager()->GetImage(m_nId, ICON_SMALL);
     if (!pIcon)
          return CSize(0, 0);

     return XTP_DPI(pIcon->GetExtent());
}

void CXTPControlBitmap::Draw(CDC* pDC)
{
     CXTPImageManagerIcon* pIcon = GetImageManager()->GetImage(m_nId, ICON_SMALL);
     if (pIcon)
     {
        CSize szIcon = XTP_DPI(pIcon->GetExtent());
        if (pIcon = GetImageManager()->GetImage(m_nId, szIcon.cx))
            pIcon->Draw(pDC, GetRect().TopLeft(), szIcon);
     }
}
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 14 October 2015 at 12:17pm
With all these changes our applications are starting to look really nice with clean, crisp images at 150% and 200% scaling. Some of the codejock controls aren't looking so good though, especially the slider control and the gallery scroll bar.



Is it possible to improve these images or will they be fixed in the final release?
Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 443
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 14 October 2015 at 1:06pm
James, thanks for taking the time to post all of this information. Should prove useful to those of us about to undertake a similar process.

- Mark R.
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (1) Thanks(1)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 15 October 2015 at 11:34am
Glad to help Mark. It's partly for my own reference as I expect to have to go through this whole process again when 17.0 is released.

I've found another issue. In the ribbon bar system button, the icons that appear here are simply small icons, scaled up. To fix it I've changed the DrawControl function in the CXTPRibbonBackstageViewThemeResource class.

The code that looks like the following

CXTPImageManagerIcon* pIcon = pView->GetImageManager()->GetImage(pControl->GetIconId());
if (pIcon)
{
    // Office 2010 respects this rule of 120 DPI
    ...
}

I've changed to:

CXTPImageManagerIcon* pSmallIcon = pView->GetImageManager()->GetImage(pControl->GetIconId(), ICON_SMALL);
if (pSmallIcon)
{
    // Office 2010 respects this rule of 120 DPI
    CSize szIconScalled(XTPDpiHelper()->ScaleX(pSmallIcon->GetWidth(), 120), XTPDpiHelper()->ScaleY(pSmallIcon->GetHeight(), 120));

    CPoint ptIcon = CPoint(rcText.left, (rcText.top + rcText.bottom - szIconScalled.cy ) / 2);

    if (auto pBestIcon = pView->GetImageManager()->GetImage(pControl->GetIconId(), szIconScalled.cx))
        pBestIcon->Draw(pDC, ptIcon, pBestIcon->GetIcon(bEnabled ? xtpImageNormal : xtpImageDisabled), szIconScalled);

    rcText.left += XTPDpiHelper()->ScaleX(pSmallIcon->GetWidth(), 120) + m_nImageMargin;
}           
Back to Top
astoyan View Drop Down
Admin Group
Admin Group
Avatar

Joined: 24 August 2013
Status: Offline
Points: 304
Post Options Post Options   Thanks (0) Thanks(0)   Quote astoyan Quote  Post ReplyReply Direct Link To This Post Posted: 18 October 2015 at 4:15pm
Hello JamesP,

Thank you for applying so much efforts sharing your work, we appreciate it. We are aware about all these and other similar issues, the biggest challenge for us is to add DPI support to controls that have not been initially designed for anything like that and make sure we don't break any backward compatibility in most common scenarios, this is why in some cases the solutions don't seem perfect, but at least they satisfy the majority.

Your fixes have been reviewed, here is the report:
1. The CXTPStatusBarPane::GetImage fix looks like it can introduce issues in other scenarios when a wide item is used with a large image available. It'll be reviewed futher.
2. Unfortunately CXTPCommandbar::GetIconSize is already used in may places inappropriately and the provided fix will break many unexpected places in different scenarios.
3. The CXTPControlGalleryItem::GetImage fix. It looks like you always call GetImage(false) which makes no difference and the code works just like before.
4. The CXTPControlBitmap::GetSize fix changes default behavior for the function and thus most likely other customers will complain about broken behavior in their scenarios.
5. The GetAutoIconSize and CXTPRibbonBackstageViewThemeResource fixes have been verified and included.

Thank you.
Regards,
  Alexander
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 30 October 2015 at 2:51pm
Thanks for getting back to me. I've been a bit too busy getting our suite of applications ready but will respond when I have a few minutes.

We are looking to release our software shortly, maybe mid to late November, and we wondered what your schedule is for the final Version 17 release.

Thanks,
James
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 02 November 2015 at 1:41pm
I'd really appreciate it if you could give me some idea of when the final release is due, as it would help us with scheduling our development.

I've had a look at other forum posts but can't see any mention of it anywhere. I seem to recall reading it was due sometime in October.

Thanks
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (0) Thanks(0)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 17 November 2015 at 1:00pm
I've just had to make another fix for toolbars we have in our applications that are non standard sizes. In these instances it's displaying the smallest icon rather than the one that best fits the dpi setting.

Towards the end of the LoadToolBar function in the CXTPCommandBar class there's a line of code:

if (pData->wWidth != 16)
{
        SetIconSize(CSize(pData->wWidth, pData->wHeight));
}

To get it to work correctly I've wrapped the CSize in the XTP_DPI macro, giving me:

{
        SetIconSize(XTP_DPI(CSize(pData->wWidth, pData->wHeight)));
}

Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (1) Thanks(1)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 01 December 2015 at 5:54am
I've just found an issue with the CXTPCheckListBox class. The hit test rect for the check box appears to be incorrect as does the invalidation rect.

To fix this I made a changes to the CXTPCheckListBox, InvalidateCheck and OnLButtonDown functions, wrapping the m_checkListState.m_sizeCheck.cx parameters in the XTP_DPI_X macro.
Back to Top
JamesP View Drop Down
Groupie
Groupie
Avatar

Joined: 07 January 2009
Location: United Kingdom
Status: Offline
Points: 73
Post Options Post Options   Thanks (1) Thanks(1)   Quote JamesP Quote  Post ReplyReply Direct Link To This Post Posted: 22 February 2016 at 12:57pm
I've just downloaded codejock version 17.1 and am currently testing it and going through all the high dpi issues I found with the Beta 3.

1) The CXTPCheckListBox is still not considering the correct rect when clicking on and invalidating it. I've changed my solution so the constructor of the m_checkListState member wraps the m_sizeCheck variable in the XTP_DPI macro:

     m_sizeCheck.cx = XTP_DPI_X(bm.bmWidth / 3);
     m_sizeCheck.cy = XTP_DPI_Y(bm.bmHeight);


2) Large toolbars still aren't showing the correct size icon. We're still having to apply the XTP_DPI macro to the size passed to the SetIconSize function in the CXTPToolBar LoadToolBar function.


3) The issue with the CXTPRibbonBackstageViewThemeResource simply scaling up small icons has now been fixed. Thanks.


4) Some of the Codejock controls, like radio buttons, slider controls and scroll bars on gallery controls are still quite badly pixelated at high DPI.


5) As you already noted, you did not implement my CXTPControlBitmap::GetSize fix, stating that it "changes default behavior for the function and thus most likely other customers will complain about broken behavior in their scenarios." It is still a necessary fix for us to enable us to show the best size image for the dpi.


6) There is still an issue with gallery control items showing icon sizes that best fit the dpi. The existing code just displays the smallest icon using CXTPControlGalleryItem::GetImage() function. I've had to change this function to take a boolean parameter, and change the CXTPControlGalleryPaintManager DrawItem function to intially find the smallest icon, to work out drawing extents, and then just before drawing, finds the best icon to draw. So the code inside the CXTPControlGalleryItem GetImage function now looks like this:

CXTPImageManagerIcon* CXTPControlGalleryItem::GetImage(bool bSmall)
{
    if (!m_pItems)
      return NULL;

    return m_pItems->GetImageManager()->GetImage(m_nImage >= 0 ? m_nImage : m_nId, (bSmall == true) ? 0 : m_nImageWidth);
}

and the CXTPControlGalleryPaintManager DrawItem function now looks something like:

void CXTPControlGalleryPaintManager::DrawItem(...)
{
    ...
    CXTPImageManagerIcon* pImage = pGalleryItem->GetImage(true);
    ...
    if (...)
    {
      ...
      if (pImage = pGalleryItem->GetImage(false))
        pImage->Draw(...);
      ...
    }
    else if (...)
    {
      ...
      if (pImage = pGalleryItem->GetImage(false))
        pImage->Draw(...);
      ...
    }
    else if (...)
    {
      ...
      if (pImage = pGalleryItem->GetImage(false))
        pImage->Draw(...);
    }
    ...
}

For this to have any effect, larger images must be supplied and gallery items must call SetImageWidth, with the smallest icon width wrapped in the XTP_DPI_X macro. Excuse me if my previous explanation of the problem and my solution weren't clear enough.


7) The issue I was having with providing larger icon sets for ribbon bar items, messing up the ribbon layout has now been fixed. Thankyou.


8) The issue with right-click context menus always showing the smallest icon has not been fixed. I appreciate you could not implement our fix, but we will continue to use it, as it hasn't caused any unexpected results for us or our customers.


9) The issue we found with icons on the Status Bar simply scaling up the smallest icon provided, also has not been fixed. I trust you are looking into this and we will continue to use our fix.


10) The inital problem we found with icons on buttons simply scaling up the smallest size provided is still an issue. We will continue to remove the XTP_DPI macro from calls to pButton->GetImageSize() in both the CXTPButtonTheme and CXTPButtonThemeOffice2013 classes.


In addition to this, the new version appears to badly clip tooltip text. I don't know if you're aware of this. It may be expecting a small size image when calculating the tooltip rect and then when it displays the tooltip, it uses the largest image and doesn't have enough room to display the text. I'll look into it further.            
Back to Top
evoX View Drop Down
Senior Member
Senior Member
Avatar

Joined: 25 July 2007
Status: Offline
Points: 207
Post Options Post Options   Thanks (0) Thanks(0)   Quote evoX Quote  Post ReplyReply Direct Link To This Post Posted: 15 January 2017 at 4:22pm
CXTPButton have the same problem :(
Images are scaled very badly on larger DPI and button text remain small and is not scaled up.
Even if I specify a larger icon for the button, it still gets scaled and messed up. Is there a way to disable the image scaling on CXTPButton ? And enlarge the button text font?


Product: Xtreme ToolkitPro 19.30
Platform: Windows 10 64bit
Language: Visual C++ (VS 2019)
Back to Top
cpede View Drop Down
Senior Member
Senior Member


Joined: 13 August 2004
Location: Denmark
Status: Offline
Points: 668
Post Options Post Options   Thanks (0) Thanks(0)   Quote cpede Quote  Post ReplyReply Direct Link To This Post Posted: 27 January 2017 at 9:36am
Yes, please fix the CXTPButton images with high DPI.

-cpede
Product: Xtreme ToolkitPro (24.0.0)
Platform: Windows 10 (x64)
Language: Visual Studio 2017 (C++)
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.234 seconds.