Initializing The DesktopView With A List Of Remote Databases

In the last installment, we began the examination of a desktop MFC application that scans a remote device, inventorying the databases it finds there. Now, we continue our exploration of this example, RemoteDBScan.

Initialization

When the RemoteDBScan application opens, it displays a control populated with a list of remote databases and their attributes. We build and initialize the list control in the OnInitialUpdate() member of the CRemoteDBScanView class. Building a list view is a two-step process. First, we add columns to the list control, and after that we can add individual rows, one item at a time.

Before we begin to build the list control, we do the base class initialization, calling CListViewEx:: OnInitialUpdate(). Next, we test the CRemoteDBScanView member variable m_bColumnsExist to see whether columns have already been added to the control (m_bColumnsExist is set to FALSE in the constructor for the class). If there are columns already, we bail out of the initialization. Otherwise, we set this member to TRUE and procede.

void CRemoteDBScanView::OnInitialUpdate()
{
   CListViewEx::OnInitialUpdate();


   // TODO: You may populate your ListView with items by directly
   // accessing its list control through a call to GetListCtrl().
   CListViewEx::OnInitialUpdate();
   if( m_bColumnsExist )
   {
      return;
   }
   else
   {
      m_bColumnsExist = TRUE;
   }

Now, we add seven columns to the list control. To add columns, first we get a reference to the list control associated with the view.

// insert columns
CListCtrl& ListCtrl = GetListCtrl();

We define the attributes of individual columns by initializing an LV_COLUMN structure. Here’s the typedef for LV_COLUMN:

typedef struct _LVCOLUMN {
   UINT mask;           //mask flags define which members are valid
   int fmt;             //flag for column heading alignment
   int cx;              //column width in pixels
   LPTSTR pszText;      //column heading
   int cchTextMax;      //length of heading buffer
   int iSubItem;        //this column's sub item index
   int iImage;          //image list index for column icon
   int iOrder;          //0 based column index
} LVCOLUMN;

The LV_ COLUMN structure is used both to set and retrieve information about a column. The mask member defines which members of the structure are to be considered valid, and has these possible values:

Table 1: LV_COLUMN Mask Flag Constants and Their Meanings

Mask Flag Constant Meaning
LVCF_FMT fmt is valid or should be returned
LVCF_IMAGE iImage is valid or should be returned
LVCF_ORDER iOrder is valid or should be returned
LVCF_SUBITEM iSubItem is valid or should be returned
LVCF_TEXT pPszText is valid or should be returned
LVCF_WIDTH cx is valid or should be returned

The mask flags may be combined with logical OR, so that you can set or retrieve as many or few LV_COLUMN members as you like.

The fmt member controls the column heading alignment and the placement of an optional image next to the heading. The heading of the leftmost column must be left aligned. You can use one of heading styles shown in the table below:

Table 2: LV_COLUMN Heading Style Flags and Their Meanings

Heading Format Flag Meaning
LVCFMT_CENTER Center heading text
LVCFMT_LEFT Left align heading text
LVCFMT_RIGHT Right align heading text

Now, we declare and initialize an LV_COLUMN structure. We set the mask for members fmt, cx, pszText an iSubItem members. We get the dimensions of the client area, and use this to set the column width. Looping through the string resources, we load the caption string for each column and also use the loop index to set the value of iSubItem. We set each column heading format to left alignment, and insert the column with a call to ListCtrl.InsertColumn().

int i;
LV_COLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

CRect rectClient;
this->GetClientRect( &rectClient );
for(i = IDS_DATABASE_NAME; i<= IDS_DATABASE_CEOID; i++)
{
   CString str;
   str.LoadString(i);
   lvc.iSubItem = i - IDS_DATABASE_NAME;
   lvc.pszText = (LPSTR)(LPCTSTR)str;
   lvc.cx = rectClient.right / (IDS_DATABASE_CEOID -
                                IDS_DATABASE_NAME);
   lvc.fmt = LVCFMT_LEFT;
   ListCtrl.InsertColumn(i,&lvc);
}

Once we have columns in the list control, we are ready to add rows containing the remote database attributes. The first step is a familiar one—we initialize RAPI with a call to CeRapiInit().

HRESULT hr = CeRapiInit();
if( hr != ERROR_SUCCESS )
   {return ;}

If we are successful, we’ll begin our search for remote databases.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read