Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

900 lines
25 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: statsdlg.cpp
//
//--------------------------------------------------------------------------
// StatsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "StatsDlg.h"
#include "coldlg.h"
#include "modeless.h" // ModelessThread
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CStatsListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CStatsListCtrl)
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CStatsListCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
BOOL fControlDown;
BOOL fShiftDown;
fControlDown = (GetKeyState(VK_CONTROL) < 0);
fShiftDown = (GetKeyState(VK_SHIFT) < 0);
switch(nChar)
{
case 'c':
case 'C':
case VK_INSERT:
if (fControlDown)
CopyToClipboard();
break;
}
}
void CStatsListCtrl::CopyToClipboard()
{
CString strText, strLine, strData;
int nCount = GetItemCount();
int nColumns = 0;
TCHAR szBuffer[256];
LV_COLUMN ColumnInfo = {0};
ColumnInfo.mask = LVCF_TEXT;
ColumnInfo.pszText = szBuffer;
ColumnInfo.cchTextMax = sizeof(szBuffer);
// build up the column info
while (GetColumn(nColumns, &ColumnInfo))
{
if (!strLine.IsEmpty())
strLine += _T(",");
strLine += ColumnInfo.pszText;
nColumns++;
}
strLine += _T("\r\n");
strData += strLine;
strLine.Empty();
// now get the other data
for (int i = 0; i < nCount; i++)
{
for (int j = 0; j < nColumns; j++)
{
if (!strLine.IsEmpty())
strLine += _T(",");
strText = GetItemText(i, j);
strLine += strText;
}
strLine += _T("\r\n");
strData += strLine;
strLine.Empty();
}
int nLength = strData.GetLength() + 1;
nLength *= sizeof(TCHAR);
HGLOBAL hMem = GlobalAlloc(GPTR, nLength);
if (hMem)
{
memcpy (hMem, strData, nLength);
if (!OpenClipboard())
{
GlobalFree(hMem);
return;
}
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hMem);
CloseClipboard();
}
}
/*!--------------------------------------------------------------------------
StatsDialog::StatsDialog
-
Author: KennT
---------------------------------------------------------------------------*/
StatsDialog::StatsDialog(DWORD dwOptions) :
m_dwOptions(dwOptions),
m_ulId(0),
m_pConfig(NULL),
m_bAfterInitDialog(FALSE)
{
m_sizeMinimum.cx = m_sizeMinimum.cy = 0;
m_hEventThreadKilled = ::CreateEvent(NULL, FALSE, FALSE, NULL);
Assert(m_hEventThreadKilled);
// Initialize the array of buttons
::ZeroMemory(m_rgBtn, sizeof(m_rgBtn));
m_rgBtn[INDEX_CLOSE].m_ulId = IDCANCEL;
m_rgBtn[INDEX_REFRESH].m_ulId = IDC_STATSDLG_BTN_REFRESH;
m_rgBtn[INDEX_SELECT].m_ulId = IDC_STATSDLG_BTN_SELECT_COLUMNS;
m_rgBtn[INDEX_CLEAR].m_ulId = IDC_STATSDLG_BTN_CLEAR;
// Bug 134785 - create the ability to default to an ascending
// rather than a descending sort.
m_fSortDirection = !((dwOptions & STATSDLG_DEFAULTSORT_ASCENDING) != 0);
m_fDefaultSortDirection = m_fSortDirection;
// Multiply text header width with 2 for width of columns
m_ColWidthMultiple = 2;
m_ColWidthAdder = 0;
}
/*!--------------------------------------------------------------------------
StatsDialog::~StatsDialog
-
Author: KennT
---------------------------------------------------------------------------*/
StatsDialog::~StatsDialog()
{
if (m_hEventThreadKilled)
::CloseHandle(m_hEventThreadKilled);
m_hEventThreadKilled = 0;
}
/*!--------------------------------------------------------------------------
StatsDialog::DoDataExchange
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::DoDataExchange(CDataExchange* pDX)
{
CBaseDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(StatsDialog)
// NOTE: the ClassWizard will add DDX and DDV calls here
DDX_Control(pDX, IDC_STATSDLG_LIST, m_listCtrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(StatsDialog, CBaseDialog)
//{{AFX_MSG_MAP(StatsDialog)
ON_COMMAND(IDC_STATSDLG_BTN_REFRESH, OnRefresh)
ON_COMMAND(IDC_STATSDLG_BTN_SELECT_COLUMNS, OnSelectColumns)
ON_WM_MOVE()
ON_WM_SIZE()
ON_WM_GETMINMAXINFO()
ON_WM_CONTEXTMENU()
ON_NOTIFY(LVN_COLUMNCLICK, IDC_STATSDLG_LIST, OnNotifyListControlClick)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// StatsDialog message handlers
/*!--------------------------------------------------------------------------
StatsDialog::SetColumnInfo
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT StatsDialog::SetColumnInfo(const ContainerColumnInfo *pColumnInfo, UINT cColumnInfo)
{
if (m_pConfig)
{
m_pConfig->InitViewInfo(m_ulId, TRUE, cColumnInfo, m_fDefaultSortDirection, pColumnInfo);
}
else
{
m_viewInfo.InitViewInfo(cColumnInfo, TRUE, m_fDefaultSortDirection, pColumnInfo);
}
return hrOK;
}
/*!--------------------------------------------------------------------------
StatsDialog::MapColumnToSubitem
-
Author: KennT
---------------------------------------------------------------------------*/
int StatsDialog::MapColumnToSubitem(UINT nColumnId)
{
if (m_pConfig)
return m_pConfig->MapColumnToSubitem(m_ulId, nColumnId);
else
return m_viewInfo.MapColumnToSubitem(nColumnId);
}
/*!--------------------------------------------------------------------------
StatsDialog::MapSubitemToColumn
-
Author: KennT
---------------------------------------------------------------------------*/
int StatsDialog::MapSubitemToColumn(UINT nSubitemId)
{
if (m_pConfig)
return m_pConfig->MapSubitemToColumn(m_ulId, nSubitemId);
else
return m_viewInfo.MapSubitemToColumn(nSubitemId);
}
/*!--------------------------------------------------------------------------
StatsDialog::IsSubitemVisible
-
Author: KennT
---------------------------------------------------------------------------*/
BOOL StatsDialog::IsSubitemVisible(UINT nSubitemId)
{
if (m_pConfig)
return m_pConfig->IsSubitemVisible(m_ulId, nSubitemId);
else
return m_viewInfo.IsSubitemVisible(nSubitemId);
}
/*!--------------------------------------------------------------------------
StatsDialog::RefreshData
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT StatsDialog::RefreshData(BOOL fGrabNewData)
{
return hrOK;
}
/*!--------------------------------------------------------------------------
StatsDialog::OnInitDialog
-
Author: KennT
---------------------------------------------------------------------------*/
BOOL StatsDialog::OnInitDialog()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
RECT rcWnd, rcBtn;
CBaseDialog::OnInitDialog();
m_bAfterInitDialog = TRUE;
// If this is the first time, get the location of the buttons and
// list control relative to the edge of the screen
if (m_sizeMinimum.cx == 0)
{
::GetWindowRect(GetSafeHwnd(), &rcWnd);
// m_sizeMinimum.cx = rcWnd.right - rcWnd.left;
// m_sizeMinimum.cy = rcWnd.bottom - rcWnd.top;
m_sizeMinimum.cx = 100;
m_sizeMinimum.cy = 100;
::GetClientRect(GetSafeHwnd(), &rcWnd);
// what are the button locations?
for (int i=0; i<INDEX_COUNT; i++)
{
::GetWindowRect(GetDlgItem(m_rgBtn[i].m_ulId)->GetSafeHwnd(),
&rcBtn);
ScreenToClient(&rcBtn);
m_rgBtn[i].m_rc.left = rcWnd.right - rcBtn.left;
m_rgBtn[i].m_rc.right = rcWnd.right - rcBtn.right;
m_rgBtn[i].m_rc.top = rcWnd.bottom - rcBtn.top;
m_rgBtn[i].m_rc.bottom = rcWnd.bottom - rcBtn.bottom;
}
// what is the list control location?
// The list control top, left is locked in position
::GetWindowRect(GetDlgItem(IDC_STATSDLG_LIST)->GetSafeHwnd(), &rcBtn);
ScreenToClient(&rcBtn);
m_rcList.left = rcBtn.left;
m_rcList.top = rcBtn.top;
// The bottom, right corner follows the expansion
m_rcList.right = rcWnd.right - rcBtn.right;
m_rcList.bottom = rcWnd.bottom - rcBtn.bottom;
}
// If we have a preferred position and size do that
if (m_pConfig)
{
m_pConfig->GetStatsWindowRect(m_ulId, &m_rcPosition);
m_fSortDirection = m_pConfig->GetSortDirection(m_ulId);
}
if (m_pConfig && (m_rcPosition.top != m_rcPosition.bottom))
{
MoveWindow(m_rcPosition.left, m_rcPosition.top,
m_rcPosition.right - m_rcPosition.left,
m_rcPosition.bottom - m_rcPosition.top);
}
if (m_dwOptions & STATSDLG_FULLWINDOW)
{
RECT rcClient;
// Resize the list control if needed
GetClientRect(&rcClient);
OnSize(SIZE_MAXIMIZED, rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top);
// Disable the buttons also
for (int i=0; i<INDEX_COUNT; i++)
{
GetDlgItem(m_rgBtn[i].m_ulId)->ShowWindow(SW_HIDE);
if (i != INDEX_CLOSE)
GetDlgItem(m_rgBtn[i].m_ulId)->EnableWindow(FALSE);
}
}
// If we do not have the select columns then we hide and disable
// the select columns button.
if ((m_dwOptions & STATSDLG_SELECT_COLUMNS) == 0)
{
GetDlgItem(m_rgBtn[INDEX_SELECT].m_ulId)->ShowWindow(SW_HIDE);
GetDlgItem(m_rgBtn[INDEX_SELECT].m_ulId)->EnableWindow(FALSE);
}
// If we do not have the clear button then we hide and disable
// the clear button.
if ((m_dwOptions & STATSDLG_CLEAR) == 0)
{
GetDlgItem(m_rgBtn[INDEX_CLEAR].m_ulId)->ShowWindow(SW_HIDE);
GetDlgItem(m_rgBtn[INDEX_CLEAR].m_ulId)->EnableWindow(FALSE);
}
ListView_SetExtendedListViewStyle(GetDlgItem(IDC_STATSDLG_LIST)->GetSafeHwnd(), LVS_EX_FULLROWSELECT);
// Now initialize the headers
LoadHeaders();
RefreshData(TRUE);
if (m_pConfig)
{
Sort( m_pConfig->GetSortColumn(m_ulId) );
}
if ((m_dwOptions & STATSDLG_FULLWINDOW) == 0)
{
GetDlgItem(IDCANCEL)->SetFocus();
return FALSE;
}
return TRUE;
}
/*!--------------------------------------------------------------------------
StatsDialog::OnOK
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::OnOK()
{
}
/*!--------------------------------------------------------------------------
StatsDialog::OnCancel
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::OnCancel()
{
DeleteAllItems();
DestroyWindow();
// Explicitly kill this thread.
AfxPostQuitMessage(0);
}
/*!--------------------------------------------------------------------------
StatsDialog::PostNcDestroy
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::PostNcDestroy()
{
// Make sure that this is NULL since this is how we detect that
// the dialog is showing
m_hWnd = NULL;
m_bAfterInitDialog = FALSE;
}
/*!--------------------------------------------------------------------------
StatsDialog::PreCreateWindow
-
Author: KennT
---------------------------------------------------------------------------*/
BOOL StatsDialog::PreCreateWindow(CREATESTRUCT& cs)
{
// Have to refresh the event
Verify( ResetEvent(m_hEventThreadKilled) );
return CBaseDialog::PreCreateWindow(cs);
}
/*!--------------------------------------------------------------------------
StatsDialog::OnRefresh
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::OnRefresh()
{
if ((m_dwOptions & STATSDLG_VERTICAL) == 0)
{
DeleteAllItems();
}
RefreshData(TRUE);
}
/*!--------------------------------------------------------------------------
StatsDialog::OnSelectColumns
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::OnSelectColumns()
{
// We should bring up the columns dialog
ColumnDlg columnDlg(NULL);
ColumnData *pColumnData;
ULONG cColumns;
ULONG cVisible;
int i;
DWORD dwWidth;
if (m_pConfig)
{
cColumns = m_pConfig->GetColumnCount(m_ulId);
cVisible = m_pConfig->GetVisibleColumns(m_ulId);
}
else
{
cColumns = m_viewInfo.GetColumnCount();
cVisible = m_viewInfo.GetVisibleColumns();
}
pColumnData = (ColumnData *) alloca(sizeof(ColumnData) * cColumns);
if (m_pConfig)
m_pConfig->GetColumnData(m_ulId, cColumns, pColumnData);
else
m_viewInfo.GetColumnData(cColumns, pColumnData);
// Save the column width information
if ((m_dwOptions & STATSDLG_VERTICAL) == 0)
{
for (i=0; i<(int) cVisible; i++)
{
dwWidth = m_listCtrl.GetColumnWidth(i);
if (m_pConfig)
pColumnData[m_pConfig->MapColumnToSubitem(m_ulId, i)].m_dwWidth = dwWidth;
else
pColumnData[m_viewInfo.MapColumnToSubitem(i)].m_dwWidth = dwWidth;
}
}
columnDlg.Init(m_pConfig ?
m_pConfig->GetColumnInfo(m_ulId) :
m_viewInfo.GetColumnInfo(),
cColumns,
pColumnData
);
if (columnDlg.DoModal() == IDOK)
{
if (m_dwOptions & STATSDLG_VERTICAL)
{
//$ HACK HACK
// To save the column info for vertical columns we will save the
// width data in the first two "columns"
pColumnData[0].m_dwWidth = m_listCtrl.GetColumnWidth(0);
pColumnData[1].m_dwWidth = m_listCtrl.GetColumnWidth(1);
}
// Set the information back in
if (m_pConfig)
m_pConfig->SetColumnData(m_ulId, cColumns, pColumnData);
else
m_viewInfo.SetColumnData(cColumns, pColumnData);
// Clear out the data
DeleteAllItems();
// Remove all of the columns
if (m_dwOptions & STATSDLG_VERTICAL)
{
m_listCtrl.DeleteColumn(1);
m_listCtrl.DeleteColumn(0);
}
else
{
for (i=(int) cVisible; --i >= 0; )
m_listCtrl.DeleteColumn(i);
}
// Readd all of the columns
LoadHeaders();
// Do a refresh
RefreshData(FALSE);
}
}
void StatsDialog::OnMove(int x, int y)
{
if (!m_bAfterInitDialog)
return;
GetWindowRect(&m_rcPosition);
if (m_pConfig)
m_pConfig->SetStatsWindowRect(m_ulId, m_rcPosition);
}
/*!--------------------------------------------------------------------------
StatsDialog::OnSize
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::OnSize(UINT nType, int cx, int cy)
{
RECT rcWnd;
RECT rcBtn;
RECT rcDlg;
if (nType == SIZE_MINIMIZED)
return;
if (m_dwOptions & STATSDLG_FULLWINDOW)
{
// If we're full window, resize the list control to fill
// the entire client area
::SetWindowPos(::GetDlgItem(GetSafeHwnd(), IDC_STATSDLG_LIST), NULL,
0, 0, cx, cy, SWP_NOZORDER);
}
else if (m_sizeMinimum.cx)
{
::GetClientRect(GetSafeHwnd(), &rcDlg);
// reposition the buttons
// The widths are caluclated opposite of the normal order
// since the positions are relative to the right and bottom.
for (int i=0; i<INDEX_COUNT; i++)
{
::SetWindowPos(::GetDlgItem(GetSafeHwnd(), m_rgBtn[i].m_ulId),
NULL,
rcDlg.right - m_rgBtn[i].m_rc.left,
rcDlg.bottom - m_rgBtn[i].m_rc.top,
m_rgBtn[i].m_rc.left - m_rgBtn[i].m_rc.right,
m_rgBtn[i].m_rc.top - m_rgBtn[i].m_rc.bottom,
SWP_NOZORDER);
}
// resize the list control
::SetWindowPos(::GetDlgItem(GetSafeHwnd(), IDC_STATSDLG_LIST),
NULL,
m_rcList.left,
m_rcList.top,
rcDlg.right - m_rcList.right - m_rcList.left,
rcDlg.bottom - m_rcList.bottom - m_rcList.top,
SWP_NOZORDER);
}
if (m_bAfterInitDialog)
{
GetWindowRect(&m_rcPosition);
if (m_pConfig)
m_pConfig->SetStatsWindowRect(m_ulId, m_rcPosition);
}
}
/*!--------------------------------------------------------------------------
StatsDialog::OnGetMinMaxInfo
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::OnGetMinMaxInfo(MINMAXINFO *pMinMax)
{
pMinMax->ptMinTrackSize.x = m_sizeMinimum.cx;
pMinMax->ptMinTrackSize.y = m_sizeMinimum.cy;
}
/*!--------------------------------------------------------------------------
StatsDialog::LoadHeaders
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::LoadHeaders()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ULONG cVis;
ULONG i, iPos;
ULONG ulId;
CString st;
DWORD dwWidth;
ColumnData rgColumnData[2]; // used for vertical format
// Load those headers that we have data for
// Go through the column data finding the headers that we have
if (m_pConfig)
cVis = m_pConfig->GetVisibleColumns(m_ulId);
else
cVis = m_viewInfo.GetVisibleColumns();
if (m_dwOptions & STATSDLG_VERTICAL)
{
if (m_pConfig)
m_pConfig->GetColumnData(m_ulId, 2, rgColumnData);
else
m_viewInfo.GetColumnData(2, rgColumnData);
// For the vertical format, the data is on a column
// Thus we add two columns and fill in the data for the
// first column
st.LoadString(IDS_STATSDLG_DESCRIPTION);
dwWidth = rgColumnData[0].m_dwWidth;
if (dwWidth == AUTO_WIDTH)
{
dwWidth = m_ColWidthAdder + static_cast<DWORD>(m_ColWidthMultiple*m_listCtrl.GetStringWidth((LPCTSTR) st));
}
m_listCtrl.InsertColumn(0, st, rgColumnData[0].fmt, dwWidth, 0);
st.LoadString(IDS_STATSDLG_DETAILS);
dwWidth = rgColumnData[1].m_dwWidth;
if (dwWidth == AUTO_WIDTH)
{
dwWidth = m_ColWidthAdder + static_cast<DWORD>(m_ColWidthMultiple*m_listCtrl.GetStringWidth((LPCTSTR) st));
}
m_listCtrl.InsertColumn(1, st, rgColumnData[1].fmt, dwWidth, 1);
// Now go through and add the rows for each of our "columns"
for (i=0; i<cVis; i++)
{
// Now get the info for iPos
if (m_pConfig)
ulId = m_pConfig->GetStringId(m_ulId, i);
else
ulId = m_viewInfo.GetStringId(i);
st.LoadString(ulId);
Assert(st.GetLength());
m_listCtrl.InsertItem(i, _T(""));
m_listCtrl.SetItemText(i, 0, (LPCTSTR) st);
}
}
else
{
// For the normal horizontal format, the data is on a row
// so we need to add the various columnar data
for (i=0; i<cVis; i++)
{
int fmt = LVCFMT_LEFT;
iPos = MapColumnToSubitem(i);
// Now get the info for iPos
if (m_pConfig)
ulId = m_pConfig->GetStringId(m_ulId, i);
else
ulId = m_viewInfo.GetStringId(i);
st.LoadString(ulId);
Assert(st.GetLength());
if (m_pConfig)
{
dwWidth = m_pConfig->GetColumnWidth(m_ulId, i);
m_pConfig->GetColumnData(m_ulId, i, 1, rgColumnData);
fmt = rgColumnData[0].fmt;
}
else
{
dwWidth = m_viewInfo.GetColumnWidth(i);
m_viewInfo.GetColumnData(i, 1, rgColumnData);
fmt = rgColumnData[0].fmt;
}
if (dwWidth == AUTO_WIDTH)
{
dwWidth = m_ColWidthAdder + static_cast<DWORD>(m_ColWidthMultiple*m_listCtrl.GetStringWidth((LPCTSTR) st));
}
m_listCtrl.InsertColumn(i, st, fmt, dwWidth, iPos);
}
}
}
HRESULT StatsDialog::AddToContextMenu(CMenu* pMenu)
{
return S_OK;
}
/*!--------------------------------------------------------------------------
StatsDialog::OnContextMenu
-
Author: KennT
---------------------------------------------------------------------------*/
void StatsDialog::OnContextMenu(CWnd *pWnd, CPoint pos)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CMenu menu;
CString st;
if ((m_dwOptions & STATSDLG_CONTEXTMENU) == 0)
return;
if (pWnd->GetDlgCtrlID() != IDC_STATSDLG_LIST)
return;
// Bring up a context menu if we need to
menu.CreatePopupMenu();
st.LoadString(IDS_STATSDLG_MENU_REFRESH);
menu.AppendMenu(MF_STRING, IDC_STATSDLG_BTN_REFRESH, st);
if (m_dwOptions & STATSDLG_SELECT_COLUMNS)
{
st.LoadString(IDS_STATSDLG_MENU_SELECT);
menu.AppendMenu(MF_STRING, IDC_STATSDLG_BTN_SELECT_COLUMNS, st);
}
//virtual override to add additional context menus
AddToContextMenu(&menu);
menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
pos.x,
pos.y,
this,
NULL);
}
void StatsDialog::OnNotifyListControlClick(NMHDR *pNmHdr, LRESULT *pResult)
{
NM_LISTVIEW * pnmlv = reinterpret_cast<NM_LISTVIEW *>(pNmHdr);
if (m_pConfig)
m_pConfig->SetSortColumn(m_ulId, pnmlv->iSubItem);
// Call through to the user to sort
Sort(pnmlv->iSubItem);
if (m_pConfig)
m_pConfig->SetSortDirection(m_ulId, m_fSortDirection);
}
void StatsDialog::Sort(UINT nColumn)
{
// Default is to do nothing
}
void StatsDialog::PreDeleteAllItems()
{
}
void StatsDialog::DeleteAllItems()
{
PreDeleteAllItems();
m_listCtrl.DeleteAllItems();
}
void StatsDialog::PostRefresh()
{
if (GetSafeHwnd())
PostMessage(WM_COMMAND, IDC_STATSDLG_BTN_REFRESH);
}
/*!--------------------------------------------------------------------------
StatsDialog::SetColumnWidths
Loops through all items and calculates the max width for columns
in a listbox.
Author: EricDav
---------------------------------------------------------------------------*/
void StatsDialog::SetColumnWidths(UINT uNumColumns)
{
// Set the default column widths to the width of the widest column
int * aColWidth = (int *) alloca(uNumColumns * sizeof(int));
int nRow, nCol;
CString strTemp;
ZeroMemory(aColWidth, uNumColumns * sizeof(int));
// for each item, loop through each column and calculate the max width
for (nRow = 0; nRow < m_listCtrl.GetItemCount(); nRow++)
{
for (nCol = 0; nCol < (int) uNumColumns; nCol++)
{
strTemp = m_listCtrl.GetItemText(nRow, nCol);
if (aColWidth[nCol] < m_listCtrl.GetStringWidth(strTemp))
aColWidth[nCol] = m_listCtrl.GetStringWidth(strTemp);
}
}
// now update the column widths based on what we calculated
for (nCol = 0; nCol < (int) uNumColumns; nCol++)
{
// GetStringWidth doesn't seem to report the right thing,
// so we have to add a fudge factor of 15.... oh well.
m_listCtrl.SetColumnWidth(nCol, aColWidth[nCol] + 15);
}
}
void StatsDialog::SetConfigInfo(ConfigStream *pConfig, ULONG ulId)
{
m_pConfig = pConfig;
m_ulId = ulId;
}
void StatsDialog::SetPosition(RECT rc)
{
m_rcPosition = rc;
}
void StatsDialog::GetPosition(RECT *prc)
{
*prc = m_rcPosition;
}
void CreateNewStatisticsWindow(StatsDialog *pWndStats,
HWND hWndParent,
UINT nIDD)
{
ModelessThread * pMT;
// If the dialog is still up, don't create a new one
if (pWndStats->GetSafeHwnd())
{
::SetActiveWindow(pWndStats->GetSafeHwnd());
return;
}
pMT = new ModelessThread(hWndParent,
nIDD,
pWndStats->GetSignalEvent(),
pWndStats);
pMT->CreateThread();
}
void WaitForStatisticsWindow(StatsDialog *pWndStats)
{
if (pWndStats->GetSafeHwnd())
{
// Post a cancel to that window
// Do an explicit post so that it executes on the other thread
pWndStats->PostMessage(WM_COMMAND, IDCANCEL, 0);
// Now we need to wait for the event to be signalled so that
// its memory can be cleaned up
WaitForSingleObject(pWndStats->GetSignalEvent(), INFINITE);
}
}