Introduction
I've been navigating the net for some days in order to find a control like Microsoft Scandisk's one (in terms of GUI not the behavior), but I didn't find any. So I created a class named CCheckerCtrl
which does the same. You can fill a series of blocks with a color of your own choice, as well as get the color of any block.
How to use
To use the control, you import the header file as well as the .cpp file attached to this article. Then you simply open the dialog editor and place a rectangle on your dialog. We call this static control IDC_STATIC_CHECKER
. Thereafter, you instantiate an object from CCheckerCtrl
class, say m_ctrlChecker
, as a public data member of your dialog class.
Then in the message handler of WM_INITDIALOG
message you get the area of the static rectangle you already placed on your dialog box and you simply create the checker control as follows:
CRect rect;
GetDlgItem(IDC_STATIC_CHECKER)->GetWindowRect(rect);
ScreenToClient(rect);
m_ctrlChecker.Create(WS_VISIBLE | WS_CHILD | WS_VSCROLL |
WS_TABSTOP, rect, this, IDC_STATIC_CHECKER);
After doing so, the checker's window is shown on the screen. Now, we use SetTotalBlocks
method of class to set the total number of blocks we would like the checker control to contain:
m_ctrlChecker.SetTotalBlocks(500);
The function is declared as follows:
void CCheckerCtrl::SetTotalBlocks(const UINT nNumberofBlocks,
const UINT nStartIndex = 0)
where nNumberofBlocks
is the number of blocks we would like to place in checker control and nStartIndex
is the index of the starting block. Lets say you need to number those blocks from 5 to 505. To do so, you give 5 as the nStartIndex
. This way the first number of the first block will be 5, the second one 6, and so on... until 505. The default value is 0.
If you run the program now, you are faced with 500 white blocks. Now, you can simply set the color of a block by the following member function of the class:
void CCheckerCtrl::SetBlock(const UINT nBlockNumber,
const COLORREF crColor)
For example to paint the 2nd, 3rd, 4th and 5th block of the control red, we will do the following:
for(register i = 2; i < 6; i++)
m_ctrlChecker.SetBlock(i, RGB(255, 0, 0));
Now in order to make the changes to be refreshed, we simply call the Refresh
function of the class:
m_ctrlChecker.Refresh();
But sometimes you need an instant refresh of a block, so you can use Update
method of the class. The declaration is as follows:
void CCheckerCtrl::Update(const UINT nBlockNumber);
For example,
for(register i = 2; i < 6; i++)
{
m_ctrlChecker.SetBlock(i, RGB(255, 0, 0));
m_ctrlChecker.Update(i);
}
The next function of this control comes to play when we need to get the color of a specific block. To do so, GetBlock
member function is used:
COLORREF GetBlock(const UINT nBlockNumber) const;
For example to get the color of the 6th block, we do this:
COLORREF crColor = m_ctrlChecker.GetBlock(6);
Finally, we come to the last member function of the class, Reset()
which resets all the blocks' color into white, again.
There's also a pre-defined message in this class, named WM_CHECKERCTRL_RBUTTONDOWN
which is used when you need to control left-clicking, say, bring a popup menu on screen. Please note that the message will be send to the parent window which was given to the class at the creation time. You can define a handler for this message with the following prototype:
UINT OnRclickedChecker(WPARAM wParam, LPARAM lParam)
where wParam
is the control ID of checker control and lParam
is the number of block the user is clicked on. Control ID is used to distinguish between different checker controls on the same dialog box.
Final note
Since the source code is pretty straight forward and fulfilled with preconditions, post conditions & different lines of comments, I think that this article is finished now. You can reach the author via his e-mail address. Any comments, questions or suggestions are welcome. Aloha!