"AND" "OR"
Главная Информер Журнал Форум

И В Радинский (c) .. , 18.07.1999.


Часто при работе с БД, или просто с отдельной таблицей приходиться сталкиваться с делемой - как отобразить в табличном виде содержимое того или иного запроса. Использовать DbGrid? Использовать DataGrid? А может Microsoft FlexGrid? Или лучьше Microsoft Hierarchical FlexGrid? Обилие Grid-ов смущает и вносит сумятицу, тратишь пол-дня на тестирование очередного Grid-а, чтобы в конце концов от него отказаться - обычное дело, когда пару месяцов их не используешь. А ведь часто надо просто отобразить данные, безо всякого модифицирования данных! Вот тут и всоминаешь про CListCtrl. Всю эту рутину по заполнению данными я оформил в класс CListCtrlDb.

/////////////////////////////////////////////////////////////////////////////
// CListCtrlDb window
class
CListCtrlDb : public CListCtrl
{

// Construction
public:
    CListCtrlDb();


// Implementation
public:
   
void FillControl();
    BOOL SetSQL(LPCTSTR szSQL);
    BOOL OpenRecordset();
    BOOL PrepareColumns();

   
void PrepareControl();
    BOOL SetRecordset(CRecordset *pRecordset);

   
virtual ~CListCtrlDb();

protected:
    CRecordset* m_pRecordset;
    CString m_strSQL;

   
int nFieldCount;
};

/////////////////////////////////////////////////////////////////////////////
// CListCtrlDb

CListCtrlDb::CListCtrlDb()
{
    m_pRecordset = NULL;
    nFieldCount =
0;
}

CListCtrlDb::~CListCtrlDb()
{
}

BOOL CListCtrlDb::SetRecordset(CRecordset *pRecordset)
{

    // проверим параметры
    ASSERT(pRecordset);

    // теперь можно и установить Recordset
    m_pRecordset = pRecordset;

   
return TRUE;
}


void CListCtrlDb::PrepareControl()
{
    ASSERT(::IsWindow(m_hWnd));

    DWORD dwStyle = GetWindowLong(m_hWnd, GWL_STYLE);
    dwStyle &= ~(LVS_TYPEMASK); dwStyle &= ~(LVS_EDITLABELS);

    SetWindowLong( m_hWnd, GWL_STYLE, dwStyle | LVS_REPORT |
        LVS_SHOWSELALWAYS | LVS_SINGLESEL);


    // Полнострочное выделение
    DWORD styles = LVS_EX_FULLROWSELECT;

    ListView_SetExtendedListViewStyleEx(m_hWnd, styles, styles );
}

BOOL CListCtrlDb::PrepareColumns()
{
    // проверим m_pRecordset
    ASSERT(m_pRecordset);
    ASSERT(m_pRecordset->IsOpen());

    // Удалим все колонки
   
while(DeleteColumn(0));

    // Получим колличество полей в запросе
    nFieldCount = m_pRecordset->GetODBCFieldCount();

 
  // Добавим столько колонок, сколько в запросе,
   // причем названия колонок берутся из самого запроса
   

    for (int i = 0; i < nFieldCount; i++)
    {
        CODBCFieldInfo fi;
        m_pRecordset->GetODBCFieldInfo(i, fi);
       
        InsertColumn(i, fi.m_strName);
    }

   
return TRUE;
}

BOOL CListCtrlDb::OpenRecordset()
{
   // если это длительная операция, то пользователь

   // должен хотябы догадываться об этом
    CWaitCursor wait;

   
return m_pRecordset->Open(CRecordset::snapshot,
        m_strSQL, CRecordset::readOnly);
}

BOOL CListCtrlDb::SetSQL(LPCTSTR szSQL)
{
    // РТПЧЕТЙН РБТБНЕФТЩ
    ASSERT(szSQL);

    m_strSQL = szSQL;

   
return TRUE;
}

void CListCtrlDb::FillControl()
{
    // РТПЧЕТЙН m_pRecordset
    ASSERT(m_pRecordset);
    ASSERT(m_pRecordset->IsOpen());

    // ЕУМЙ ЬФП ДМЙФЕМШОБС ПРЕТБГЙС, ФП РПМШЪПЧБФЕМШ
    // ДПМЦЕО ИПФСВЩ ДПЗБДЩЧБФШУС ПВ ЬФПН
    CWaitCursor wait;

    // ХДБМЙН ЧУЕ ЮФП ВЩМП
    DeleteAllItems();


    LVITEM lvItem;
    lvItem.mask = LVIF_TEXT;

    CString strItem;
   
int nItem = 0;

    // ЪБРПМОЙН ListCtrlDb
    m_pRecordset->MoveFirst();
   
do
    {
       
for (int nSubItem = 0; nSubItem < nFieldCount; nSubItem++)
        {
            m_pRecordset->GetFieldValue(nSubItem, strItem);   

            lvItem.iItem = nItem;
            lvItem.iSubItem = nSubItem;
            lvItem.pszText = strItem.GetBuffer(strItem.GetLength() +
1);

            if (nSubItem ==
0)
                InsertItem(&lvItem);
            else
                SetItem(&lvItem);
        }

        m_pRecordset->MoveNext();
        nItem++;
    }
   
while(!m_pRecordset->IsEOF());

}
/////////////////////////////////////////////////////////////////////////////

йУПМШЪПЧБОЙЕ ЛМБУУБ ДПЧПМШОП РТПУФП:

  1. дПВБЧЙФШ РЕТЕНЕООХА ФЙРБ CListCtrlDb Ч ДЙБМПЗ, Ч ЛПФПТПН ЙУРПМШЪХЕФУС ListCtrl.
  2. б ДБМШЫЕ РТЙНЕТОП ФБЛ:

    m_ctrlList.SetRecordset(m_pRecordset);
    m_ctrlList.SetSQL(
"select * from Streets");

   
if (!m_ctrlList.OpenRecordset())
       
return;

   
if (!m_ctrlList.PrepareColumns())
       
return;

    m_ctrlList.FillControl();

й  ЧУЕ!