visual-c++mfcclistctrl

Calculating the correct width to resize image to display in a CListCtrl


At the moment I am having to fudge my code like this:

CRect rcList;
m_ListThumbnail.GetClientRect(rcList);
rcList.DeflateRect(25, 25);

// Use monitor 1 to work out the thumbnail sizes
CRect rcMonitor = m_monitors.rcMonitors.at(0);

m_iThumbnailWidth = rcList.Width();

double dHt = ((double)rcMonitor.Height() / (double)rcMonitor.Width()) * (double)m_iThumbnailWidth;
m_iThumbnailHeight = (int)dHt;

I fudge it by deflating the rectangle by 25. m_ListThumbnail is a CListCtrl and I am trying to render my thumbnails so that I do not need a horizontal scroll bar.

When I render the thumbnails of the monitors, I attempt to massage these thumbnail values (incomplete):

nWidth = m_iThumbnailWidth;

double dHt = ((double)rcCapture.Height() / (double)rcCapture.Width()) * (double)m_iThumbnailWidth;
nHeight = (int)dHt;

if (nHeight > m_iThumbnailHeight)
{
    AfxMessageBox(L"Need to investigate!");
}

Where rcCapture is the size of the monitor.

If I remove the DeflateRect line, my window displays like this:

enter image description here

As you can see, it is note as I expected. There is a horizontal scroll bar and I have to resize quite a bit to see the thumbnail:

enter image description here

All I want to compute is a set of thumbnail dimensions so that the scaled down monitor image is going to fit in the CListCtrl. I don't really want the user to have to resize the window.


Update

With my adjusted code which now uses the primary monitor aspect ratio to work out the thumbnail sizes (as added above) renders the app with better whitespace:

enter image description here

That was the reason of the extra space at the bottom because the monitors were 16:9 and I was squishing into 4:3. So that is fixed.

But as you can see, using the CListCtrl client width is not sufficient.


Update

This is the rendering code:

// Set the mode first!
SetStretchBltMode(dcImage, COLORONCOLOR);

int iTop = (m_iThumbnailHeight - nHeight) / 2;

// Copy (and resize)
bRet = ::StretchBlt(dcImage, 0, iTop,
    nWidth, 
    nHeight, 
    dcScreen.m_hDC, 
    rcCapture.left, 
    rcCapture.top, 
    rcCapture.Width(), 
    rcCapture.Height(), SRCCOPY | CAPTUREBLT);

Solution

  • The control renders the icon with a margin. When I used GetItemPosition function it indicated that the x value was 21. This is why my DeflateRect(25, 25) worked. But I don;t know how the CListCtrl computed that margin value.


    Eventually I found out how to do this without deflating, by using the SetIconSpacing function. Like this:

    m_ListThumbnail.SetIconSpacing(
        CSize(m_iThumbnailWidth, ::GetSystemMetrics(SM_CXHSCROLL)));
    

    Once the above has been done the window looks like this:

    enter image description here

    Things might be a little different when there are 3 or 4 monitor thumbnails, thus causing a vertical scroll bar. But I only have two monitors to test with.