Print Page | Close Window

Crash in CXTPImageManager::SplitBitmap

Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Toolkit Pro
Forum Description: Topics Related to Codejock Toolkit Pro
URL: http://forum.codejock.com/forum_posts.asp?TID=11838
Printed Date: 24 June 2025 at 6:17am
Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com


Topic: Crash in CXTPImageManager::SplitBitmap
Posted By: PierreL
Subject: Crash in CXTPImageManager::SplitBitmap
Date Posted: 15 August 2008 at 1:00pm
Hello,

I'm getting an Access violation exception in the SplitBitmap function called from the SetIcons(CBitmap&, ...) function. Here are the conditions where this happens:

[Using ToolkitPro 11.2.2 on XP SP2]

- OS color quality setting is set to 16 bits
- Calling SetIcons(CBitmap&,...) function with a single
32bpp bitmap creates this access violation at line 3407 (xtpimagemanager.cpp) :
  
    *pDestBits++ = *pBitsIter++;



This is not an issue when the OS color quality is set to 32 bits.

Has anyone encountered this before?


Thanks,
Peter.




Replies:
Posted By: Oleg
Date Posted: 18 August 2008 at 1:35am
Hi,
Instead of SetIcons(CBitmap&,...)  try SetIcons(UINT..) to allow ImageManager manually load this bitmap.


-------------
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS


Posted By: PierreL
Date Posted: 18 August 2008 at 11:08am
Thanks for the reply Oleg,

I would do that if I was loading my bitmap from resources. What I'm doing is constructing a bitmap at runtime.

My goal is to construct a bitmap for a CXTPopupControl-derived class so it has the same width as my "host" window (on resize). To do so I use three HBITMAP parts that I've pre-loaded. I construct this bitmap in a memDC and use BitBlt. I do the left part, then iterate 'x' times for the middle part then end with the right part. I'm possibly doing something wrong in my construction of this bitmap? Here's a sample of what I'm doing (I removed the sanity checks and error handling). Again, this works in a 32 bits display setting.



void MyPopupCtrl::BuildBitmap(CSize in_popupCtrlSize)
{  
    CDC* pDC = GetDC();

    CDC memDC;
    memDC.CreateCompatibleDC(pDC);

    /// re-create the bitmap cache.
    m_bmpCache.DeleteObject();
    m_bmpCache.CreateCompatibleBitmap(pDC,
                                      in_popupCtrlSize.cx,
                                      in_popupCtrlSize.cy);

    CBitmap* pOldBitmap = memDC.SelectObject(&m_bmpCache);

    /// Select the leftmost part of the bitmap into the source DC
    CXTPCompatibleDC srcDCLeft(pDC, m_hbmpLeft);
    
    CXTPEmptyRect rcDest, rcSrc;
    rcDest.SetRect(0, 0, m_bmpLeftSize.cx, m_bmpLeftSize.cy);
    rcSrc.SetRect(0, 0, m_bmpLeftSize.cx, m_bmpLeftSize.cy);

    /// Write to the memDC
    BitBlt(memDC,
           rcDest.left,rcDest.top, rcDest.Width(), rcDest.Height(),
           srcDCLeft,0,0,SRCCOPY);

    /// Select the middle part into a source DC
    CXTPCompatibleDC srcDCMid(pDC, m_hbmpMid);
    /// Reset the destination rect by moving the x-coordinate.
    rcDest.left += m_bmpLeftSize.cx;
    rcDest.right = rcDest.left + m_bmpMidSize.cx;
    rcSrc.SetRect(0, 0, m_bmpMidSize.cx, m_bmpMidSize.cy);

    /// Iterate and copy the mid part multiple times until we reach the right end.
    for (int partCount = 0; partCount < midPartCount; partCount++)
    {
        BitBlt(memDC,
               rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
               srcDCMid,0,0,SRCCOPY);
        rcDest.left += m_bmpMidSize.cx;
        rcDest.right+= m_bmpMidSize.cx;
    }

    /// Add the last part (right end) to the bitmap.
    CXTPCompatibleDC srcDCRight(pDC, m_hbmpRight);
    /// Reset the destination rect with the moved x-coordinate.
    rcDest.left = nTotalWidth - m_bmpRightSize.cx;
    rcDest.right= nTotalWidth;
    rcSrc.SetRect(0, 0, m_bmpRightSize.cx, m_bmpRightSize.cy);
   
    /// Write to the memDC
    BitBlt(memDC, rcDest.left,rcDest.top,rcDest.Width(),rcDest.Height(),srcDCRight,0,0,SRCCOPY);
 
    /// Replace the image manager with our own:
    InitializeImageManager(); // uses m_bmpCache.
    SetTheme(xtpPopupThemeCustom);
    SetBackgroundBitmap(ID_BITMAP_BACKGROUND);

    memDC.SelectObject(pOldBitmap);
}


void MyPopupCtrl::InitializeImageManager()
{
    static UINT uiCmds[] = {ID_BITMAP_BACKGROUND};

    if(!m_pImageMgr)
    {
        m_pImageMgr = new CXTPImageManager();
        m_pImageMgr->SetIcons(m_bmpCache, uiCmds, 1, CSize(0), xtpImageNormal, m_isAlpha);
        SetImageManager(m_pImageMgr);
    }
    else
    {
        m_pImageMgr->RemoveIcon(ID_BITMAP_BACKGROUND);
        m_pImageMgr->SetIcons(m_bmpCache, uiCmds, 1, CSize(0), xtpImageNormal, m_isAlpha);
    }
}



One last note is that my three HBITMAP parts are actually PNGs and are loaded like the this:

m_hbmpLeft = CXTPImageManagerIcon::LoadBitmapFromResource(MAKEINTRESOURCE(ID_LEFT), &isAlpha);

Thanks for your time,
Peter



Posted By: Oleg
Date Posted: 18 August 2008 at 3:19pm
After you change them, they not Alpha bitmaps. don't set m_isAlpha to TRUE.

-------------
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS


Posted By: PierreL
Date Posted: 18 August 2008 at 4:15pm
But I need them to be alpha!? If I set m_isAlpha to FALSE then my popup ctrl is black, I don't see my bitmap background image.

This popup control's bitmap needs to be semi-transparent.


Posted By: Oleg
Date Posted: 19 August 2008 at 1:35am
Try to replace
 m_bmpCache.CreateCompatibleBitmap(pDC,
                                      in_popupCtrlSize.cx,
                                      in_popupCtrlSize.cy);
 
to
m_bmpCache.Attach(XTPImageManager::Create32BPPDIBSection( pDC, in_popupCtrlSize.cx, in_popupCtrlSize.cy);


-------------
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS


Posted By: PierreL
Date Posted: 19 August 2008 at 3:24pm


That's exactly what I was missing.
Thank you Oleg!

I appreciate it,
Peter



Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net