A useful DBGrid

Source: Internet
Author: User
PM

 

I. Introduction

When using VC to develop database projects, we usually have to use Microsoft's DBGrid as the database table control. In fact, Microsoft's DBGrid is not easy to use. I want to find a good help document
Cannot be found, and the interface is unfriendly. Compared with DBGrid in C ++ builder, DBGrid is a common control in database development projects, so it has been
Find a useful DBGrid, but it is not found on the Internet. The last time you accidentally saw cgridctrl (a pretty table control, if you haven't used it yet, you can go

Http://www.codetools.com/miscctrl/gridctrl.asp/download, and detailed instructions for use) supports Virtual Mode.

Even if you insert 1 million rows of data into the table, it does not actually generate 1 million rows. Instead, as your scroll bar scrolls, it calculates the rows and columns to be displayed on the screen, then we will provide you with
You can set the data to be displayed here. This gives me some inspiration. I decided to use it for a DBGrid. The following example shows an application.

Ii. Principles

The difference between DBGrid and the general grid is that the general grid is not suitable for displaying large data volumes. If your query results have tens of thousands of records, if you want to insert them to the grid
, It will be a very slow process, and if you move the scroll bar in the grid, its record rolling is also very slow, however, DBGrid does not actually insert all the recorded data into the control,
When the scroll bar of DBGrid scrolls, it calculates which rows should be displayed based on the size of the display area of DBGrid and the total number of records obtained from the query, and inserts the records of those rows into the data.
To the table, the speed is certainly very fast, and there is no limit on the amount of data.

Fortunately, the cgridctrl class has provided us with this mechanism, which adopts the virtual mode. to use this method, follow the steps below:

Step 1 initialize

Void setvirtualmode (true) is set to virtual mode
Bool setrowcount (INT nrows) sets the total number of rows.
Bool setfixedrowcount (INT nfixedrows = 1) set fixed row data
Bool setcolumncount (INT ncols) sets the number of Columns
Bool setfixedcolumncount (INT nfixedcols = 1) set a fixed number of Columns

Step 2. Response Message Display Data
Assume that cgridctrl is placed on the dialog box and its associated variable is m_grid. Use classwizard to add the ony y response function of the dialog box. The method of this response function is fixed, similar to the following code:

Bool cmyodbcdlg: onnotify (wparam, lparam, lresult * presult)
{
If (wparam = (wparam) m_grid.getdlgctrlid ())
{
* Presult = 1;
Gv_dispinfo * pdispinfo = (gv_dispinfo *) lparam;
If (gvn_getdispinfo = pdispinfo-> HDR. Code)
{
/* This is our own function. In this function, we set the data to be displayed */
Setgriditem (pdispinfo );
Return true;
}
}
Return cdialog: onnotify (wparam, lparam, presult );
}

In the above Code, setgriditem (pdispinfo) is a function we add. In this function, we set the data to be displayed. pdispinfo is
Gv_dispinfo struct object, which contains information about each cell, such as row number, column number, bitmap, background color, foreground color, etc. cgridctrl will
When the cell is displayed, the row number and column number of the cell are passed to us. We only need to set the data to be displayed in the cell. The following is an example of data display.

int CMyOdbcDlg::SetGridItem(GV_DISPINFO *pDispInfo)
{
pDispInfo->item.strText.Format("row%d,col%d",pDispInfo->item.row, pDispInfo->item.col);
return 0;
}

 

Through the above introduction, we should have used the cgridctrl virtual mode. The following describes how to use the cgridctrl virtual mode for DBGrid.
Path, MFC
The crecordset class supports multiple cursors, such as bidirectional cursors. If we use classwizard to generate a query crecordset derived class, we can
To call the function crecordset: setabsoluteposition (), it is too easy to do DBGrid in this way, because the int
Cmyodbcdlg: setgriditem (gv_dispinfo
* Pdispinfo) in the function, we already know which row and which column of data to display.
Crecordset: setabsoluteposition (pdispinfo-> item. Row) function, locate the cursor to the row, and obtain
The data of each field is enough.

However, one bad thing about using the above method is that we must use classwizard to derive a new class from crecordset for each query. this is inconvenient and is available in the VC knowledge base.
In the sixth issue, there was an article about "use crecordset separately", but the above crecordset can only be used
Crecordset: forwardonly, the cursor can only scroll forward, we cannot use crecordset: setabsoluteposition ()
Function, if you want to use it conveniently, you must find another way to provide the data of the cell to be displayed.

We know that the Oracle database does not support two-way cursors. Why can we use classwizard to move the cursors two-way for the class derived from the crecordset query? Me
In fact, the crecordset class saves the data obtained each time and stores the location of each row of records. In this way, when we call
When the crecordset: setabsoluteposition () function, it can get the data we want. No matter whether this conjecture is true or not, the above ideas have been implemented.
Now we have a very useful DBGrid. I encapsulated it into a codbcdbgridfile class. The principle is to first obtain the number of rows and columns to be queried, and then set the cgridctrl
Attribute, such as setting it to virtual mode and setting the number of rows and columns of cgridctrl. Then, the memory ing file is used to save the data of each record, and a struct is used to record the bit of this record.
.

Here is a tip: if there are hundreds of thousands of query results, it will take a long time if we save all these records in the memory ing file from the very beginning, therefore, it cannot meet the requirements
So at the beginning, we only get a part of the record set for display. When you drag the scroll bar on cgridctrl to scroll down, it will continue to get data as the user scrolls, this displays
As shown above, there is no problem at all.

Iii. Use instances

Well, I have told you so much. Let's take a look at how to use this encapsulated class codbcdbgridfile. Only four functions can be called on the external interface of this class, the following describes the four functions.

Codbcdbgridfile (cgridctrl * pgrid = NULL,
Cdatabase * pdatabase = NULL,
Cstring strsql = "",
Cstring strfilepath = ""); // constructor. The required variable must be passed in.
Int initgrid (); // initialization Function
Int setgridtext (gv_dispinfo * pdispinfo); // The interface called by the external function to return the information that each cell should display
Int release (); // release resources

Follow the steps below to know if it is practical.

Step 1
Create a project based on the dialog box, name it demo2, open the stdafx. h file, add # include <afxdb. h>, and
Odbcdbgridfile. H,
Copy odbcdbgridfile. cpp to the directory of the project and add it to the project by selecting project> Add
Project-> files, select these two files. Do not forget to include all the files in the cgridctrl class.

Step 2
In the dialog box, add a curstomer ctrol (that is, the control of a person's header) according to the preceding example, enter mfcgridctrl on the attribute class, And the ID is idc_gridodbc, then, add other edit boxes and button controls to associate variables with the four edit box controls through classwizard.

Cstring m_strpass; // Password
Cstring m_strsource; // data source name
Cstring m_strsql; // query SQL
Cstring m_struser; // User Name

Add the following member variables to the class cdemo2dlg.

CGridCtrl m_Grid;
COdbcDBGRIDFILE *m_pMapFile;
CImageList m_ImageList;
CDatabase m_db;

Of course, you need to add it to the cdemo2dlg declaration file.

#include "gridctrl.h"
#include "OdbcDBGRIDFILE.h"

Add ddx_control (PDX, idc_gridodbc, m_grid) to the cdemo2dlg: dodataexchange (cdataexchange * PDX) function );
Add the following to the cdemo2dlg constructor:

m_pMapFile = NULL;

Step 3
Use classwizard to generate cdemo2dlg cdemo2dlg: onnotify message response function. In this function, enter the following code:

BOOL CDemo2Dlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
{
if (wParam == (WPARAM)m_Grid.GetDlgCtrlID())
{
*pResult = 1;
GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;
if (GVN_GETDISPINFO == pDispInfo->hdr.code)
{
SetGridItem(pDispInfo);
return TRUE;
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}

In the above Code, setgriditem (pdispinfo) is a function we add. In this function, we set the data to be displayed.

Step 4
Onbtnquery ()
The code for this function is as follows:

Void cdemo2dlg: onbtnquery ()
{
This-> release ();/* this function is used to release resources */
Cstring strconn;
Updatedata (true );
Strconn. Format ("ODBC; DSN = % s; uid = % s; Pwd = % s", m_strsource, m_struser, m_strpass );
Bool bresult = m_db.open (strconn );
If (bresult = false)
{
Return;
}/* The above code is used to connect to the database */
M_pmapfile = new codbcdbgridfile (& m_grid, & m_db, m_strsql, "C: // csl.txt ");
M_pmapfile-> initgrid ();/* initialization function, used to create memory ing files */
}

In the above Code, the constructor of codbcdbgridfile is called. Its prototype is
Codbcdbgridfile: codbcdbgridfile (cgridctrl * pgrid, cdatabase * pdatabase, cstring strsql, cstring strfilepath). The parameter meanings are as follows:
Cgridctrl * pgrid ------- is a pointer to cgridctrl
Cdatabase * pdatabase ------ is a pointer to cdatabase. You must pass the object of a connected cdatabase.
Cstring strsql ------ A query statement, such as select * from EMP;
Cstring strfilepath ----- is the path of the file used to generate the memory ing file.

Step 5
Add the member function setgriditem (pdispinfo) to cdemo2dlg. This function is called in cdemo2dlg: onnotify (). We use this function to set the display record data.

Void cdemo2dlg: setgriditem (gv_dispinfo * pdispinfo)
{
/*
You can set it by yourself, for example, the Chinese name of the field in the first row query,
The sequence number of the first row. If you do not set the number, each
Field Names obtained from the query, the serial number of each row
*/

M_pmapfile-> setgridtext (pdispinfo );

/*
The above function is just used to get the original, you can also use it to perform another
Other attributes, such as when the value exceeds a certain value, are different before the display of DBGrid
View and foreground View
*/
}

Step 6
Add the member function release (). The following code is used to release resources.

void CDemo2Dlg::Release()
{
if(this->m_pMapFile)
{
m_pMapFile->Release();
m_db.Close();
delete m_pMapFile; m_pMapFile = NULL;
}
}

In the above Code, m_pmapfile-> release () is a member function of codbcdbgridfile, which is used to release all resources.

Step 7
Add the message response function onclose () in the dialog box to release all resources.

void CDemo2Dlg::OnClose() 
{
this->Release();
CDialog::OnClose();
}

After completing the above work, You can compile and run it. In the above edit box, enter the data source name, user name, password, and the SQL statement for query. Then you can try the result, you can look for a bigger table. It is better to have several hundred million records to test. How about this DBGrid.

Iv. Summary

The advantage of using this DBGrid is that we do not need to bind the database first during query, and it is much more convenient than the DBGrid control of Microsoft. We hope it can develop data for us using VC.
Library projects increase efficiency. If you have read the previous article and use cmyodbc and codbcset to replace the cdatabase and crecordset of MFC
The row efficiency will be greatly improved. I also wrote a similar class cmyodbcdbgridfile, and used this class as an example, which is the supporting Code 2 provided by the Article header.

 

Category: VC ++

| Add to souzang

| Browsing (262)
| Comment (0)
Previous Article: essential for Linux C Programming next article: macro definitions and inline functions of C topics

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.