Skip to content

Commit

Permalink
moved some functions, fixed vscroll
Browse files Browse the repository at this point in the history
  • Loading branch information
ppescher committed Feb 26, 2002
1 parent d3a698b commit 588b536
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 75 deletions.
84 changes: 84 additions & 0 deletions ResizableLib/ResizableComboBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ static char THIS_FILE[] = __FILE__;

CResizableComboBox::CResizableComboBox()
{
m_bClipMaxHeight = TRUE;
m_bIntegralHeight = TRUE;
}

CResizableComboBox::~CResizableComboBox()
Expand Down Expand Up @@ -55,6 +57,14 @@ HBRUSH CResizableComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

LRESULT CResizableComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case CB_GETDROPPEDCONTROLRECT:
*(LPRECT)lParam = m_rectDropDown;
MapWindowPoints(NULL, (LPRECT)lParam);
return TRUE;
}

LRESULT lResult = CComboBox::WindowProc(message, wParam, lParam);

// if listbox is attached, update horizontal extent
Expand Down Expand Up @@ -122,7 +132,81 @@ void CResizableComboBox::UpdateHorizontalExtent(LPCTSTR szText)

void CResizableComboBox::PreSubclassWindow()
{
ASSERT(GetStyle() & CBS_NOINTEGRALHEIGHT);

InitHorizontalExtent();

GetDroppedControlRect(&m_rectDropDown);
::MapWindowPoints(NULL, GetSafeHwnd(),
(LPPOINT)&m_rectDropDown, 2);

CComboBox::PreSubclassWindow();
}

int CResizableComboBox::MakeIntegralHeight(const int height)
{
int inth = height; // integral height (result)
int availh = height; // available height
int n = GetCount();

DWORD dwStyle = GetStyle();

if (!m_bIntegralHeight || n == 0)
return inth;

if (dwStyle & CBS_OWNERDRAWVARIABLE)
{
inth = 0; // try to reach availh by integral steps

// use items below the first visible
for (int i=GetTopIndex(); availh>0 && i<n; i++)
{
int h = GetItemHeight(i);
if (h == CB_ERR)
break;

inth += h;
availh -= h;
}
// to fill the remaining height, use items above
for (i=GetTopIndex()-1; availh>0 && i>=0; i--)
{
int h = GetItemHeight(i);
if (h == CB_ERR)
break;

inth += h;
availh -= h;
}
// scroll into view
SetTopIndex(i);

if (!m_bClipMaxHeight) // it can be higher than all the items
{
// to fill the remaining height, use last item
int h = GetItemHeight(n-1);
if (h != CB_ERR)
{
inth += availh - availh % h;
}
}
}
else
{
// every item has the same height (take the first)
int h = GetItemHeight(0);
if (h != CB_ERR && n != CB_ERR)
{
int rows = availh / h;
// can't be higher than all the items
if (m_bClipMaxHeight && rows > n)
rows = n;
inth = rows * h;
// scroll into view
if (n - rows < GetTopIndex())
SetTopIndex(n-rows);
}
}

return inth;
}
6 changes: 6 additions & 0 deletions ResizableLib/ResizableComboBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

class CResizableComboBox : public CComboBox
{
friend class CResizableComboLBox;

// Construction
public:
CResizableComboBox();
Expand All @@ -40,10 +42,14 @@ class CResizableComboBox : public CComboBox
virtual ~CResizableComboBox();

protected:
RECT m_rectDropDown;
BOOL m_bClipMaxHeight;
BOOL m_bIntegralHeight;
int m_iExtent;

void InitHorizontalExtent();
void UpdateHorizontalExtent(LPCTSTR szText);
int MakeIntegralHeight(const int height);

// Generated message map functions
protected:
Expand Down
83 changes: 11 additions & 72 deletions ResizableLib/ResizableComboLBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "stdafx.h"
#include "ResizableComboLBox.h"
#include "ResizableComboBox.h"

#ifdef _DEBUG
#define new DEBUG_NEW
Expand All @@ -17,7 +18,6 @@ CResizableComboLBox::CResizableComboLBox()
{
m_dwAddToStyle = WS_THICKFRAME;
m_dwAddToStyleEx = 0;//WS_EX_CLIENTEDGE;
m_bClipMaxHeight = TRUE;
m_bSizing = FALSE;
}

Expand All @@ -29,11 +29,11 @@ CResizableComboLBox::~CResizableComboLBox()

BEGIN_MESSAGE_MAP(CResizableComboLBox, CWnd)
//{{AFX_MSG_MAP(CResizableComboLBox)
ON_WM_CAPTURECHANGED()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_NCHITTEST()
ON_WM_CAPTURECHANGED()
ON_WM_WINDOWPOSCHANGING()
ON_WM_WINDOWPOSCHANGED()
//}}AFX_MSG_MAP
Expand Down Expand Up @@ -231,14 +231,20 @@ void CResizableComboLBox::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
CWnd::OnWindowPosChanging(lpwndpos);
}

void CResizableComboLBox::OnWindowPosChanged(WINDOWPOS FAR* /*lpwndpos*/)
void CResizableComboLBox::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
{
// default implementation sends a WM_SIZE message
// that can change the size again to force integral height

// since we do that manually during resize, we should also
// update the horizontal scrollbar
SendMessage(WM_HSCROLL, SB_ENDSCROLL, 0);

GetWindowRect(&m_pOwnerCombo->m_rectDropDown);
::MapWindowPoints(NULL, m_pOwnerCombo->GetSafeHwnd(),
(LPPOINT)&m_pOwnerCombo->m_rectDropDown, 2);

CWnd::OnWindowPosChanged(lpwndpos);
}

void CResizableComboLBox::ApplyLimitsToPos(WINDOWPOS* lpwndpos)
Expand Down Expand Up @@ -274,7 +280,7 @@ void CResizableComboLBox::ApplyLimitsToPos(WINDOWPOS* lpwndpos)

//TRACE(">H c(%d)\n", sizeClient.cy);
// adjust height, if needed
sizeClient.cy = MakeIntegralHeight(sizeClient.cy);
sizeClient.cy = m_pOwnerCombo->MakeIntegralHeight(sizeClient.cy);
//TRACE(">H c(%d)\n", sizeClient.cy);

// back to window rect
Expand All @@ -288,70 +294,3 @@ void CResizableComboLBox::ApplyLimitsToPos(WINDOWPOS* lpwndpos)
//TRACE("H c(%d) w(%d)\n", sizeClient.cy, lpwndpos->cy);
}

int CResizableComboLBox::MakeIntegralHeight(const int height)
{
int inth = height; // integral height (result)
int availh = height; // available height
int n = m_pOwnerCombo->GetCount();

DWORD dwStyle = GetStyle();

if (dwStyle & LBS_NOINTEGRALHEIGHT || n == 0)
return inth;

if (dwStyle & LBS_OWNERDRAWVARIABLE)
{
inth = 0; // try to reach availh by integral steps

// use items below the first visible
for (int i=m_pOwnerCombo->GetTopIndex(); availh>0 && i<n; i++)
{
int h = m_pOwnerCombo->GetItemHeight(i);
if (h == LB_ERR)
break;

inth += h;
availh -= h;
}
// to fill the remaining height, use items above
for (i=m_pOwnerCombo->GetTopIndex()-1; availh>0 && i>=0; i--)
{
int h = m_pOwnerCombo->GetItemHeight(i);
if (h == LB_ERR)
break;

inth += h;
availh -= h;
}
// scroll into view
m_pOwnerCombo->SetTopIndex(i);

if (!m_bClipMaxHeight) // it can be higher than all the items
{
// to fill the remaining height, use last item
int h = m_pOwnerCombo->GetItemHeight(n-1);
if (h != LB_ERR)
{
inth += availh - availh % h;
}
}
}
else
{
// every item has the same height (take the first)
int h = m_pOwnerCombo->GetItemHeight(0);
if (h != LB_ERR && n != LB_ERR)
{
int rows = availh / h;
// can't be higher than all the items
if (m_bClipMaxHeight && rows > n)
rows = n;
inth = rows * h;
// scroll into view
if (n - rows < m_pOwnerCombo->GetTopIndex())
m_pOwnerCombo->SetTopIndex(n-rows);
}
}

return inth;
}
6 changes: 3 additions & 3 deletions ResizableLib/ResizableComboLBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// ResizableComboLBox.h : header file
//

class CResizableComboBox;

/////////////////////////////////////////////////////////////////////////////
// CResizableComboLBox window

Expand Down Expand Up @@ -47,11 +49,9 @@ class CResizableComboLBox : public CWnd
protected:
DWORD m_dwAddToStyle;
DWORD m_dwAddToStyleEx;
BOOL m_bClipMaxHeight;
CSize m_sizeMin; // initial size (minimum)
CComboBox* m_pOwnerCombo; // owner combobox
CResizableComboBox* m_pOwnerCombo; // owner combobox

int MakeIntegralHeight(const int height);
void ApplyLimitsToPos(WINDOWPOS* lpwndpos);
void EndSizing();

Expand Down

0 comments on commit 588b536

Please sign in to comment.