This project will help you to understand about column based selection and how to implement Column Based selection in your project. I had been searching this type of article or help but didn't find which imposed me to create such type of application. I hope they will be beneficial who want to implement column based selection feature in their editor.
Below I have shown some pictures those depict column based selection feature in other application.
Column based selection in Visual Studio..
Column based selection in my application's rich edit control.
In most of the application column based selection can be achived by "pressing Alt + drag the mouse" . The way is same in my application also.
The strategy was simple
1. First create a new a bitmap from the viewable part of edit control. But process this bitmap in such a way that text color will be white and backgorund (except text area) color will be blue.
2. After processing keep this bitmap in a DC(device context). In my case this is
3. Now calculate user selected area and store 2 points in 2 member variable. 2 points means starting point and ending point. Ending point has to be continuously updated by mouse move message.
4. After user selected Rectangle calculation, copy only selected rectangle from
m_processedDC to destination DC, in my case which is rich edit control's DC (device context), by BitBlt() method.
5. Now user will see that some area his been selected .
Some important areas of code I going to explain below,
1. I have implemented this in CColBasedRichEdit class which is inherited from MFC's CRichEditCtrl .
2. Create a memory DC which is compatible with the application's current screen and create a bitmap which is compatible with the RichEdit control's device.
m_processedDC = ::CreateCompatibleDC(NULL);
HBITMAP bmpREdit = ::CreateCompatibleBitmap(*pDC, rcClient.Width(), rcClient.Height() );
3. Create a solid brush with current highlight color of system and fill destination DC's background with currently created brush .
COLORREF clrHilite = ::GetSysColor(COLOR_HIGHLIGHT);
HBRUSH brHilite = CreateSolidBrush( clrHilite);
::FillRect(m_processedDC, CRect(0, 0, rcClient.Width(), rcClient.Height()), brHilite);
4. Create a bitmap with the specified width and height but its contents is undefined (as NULL)
CHBITMAP hMemBmp = CreateBitmap(rcClient.Width(), rcClient.Height(), 1, 1, NULL);
here 4th parameter ask to assign number of bits per pixel and we have assigned "1", so the resulted Bitmap will be a Black & White bitmap. Now keep new bitmap in
5. Copy RichEdit's DC to '
BitBlt(m_hSelectionDC, 0, 0, rcClient.Width(), rcClient.Height(), *pDC, 0, 0, SRCCOPY);
important thing is '
m_hSelectionDC' has Black & White pixel , so if u paint '
m_hSelectionDC' some where to test then u will see that a Black & Whilte image of rich edit control. Purpose of making Black&Whilte image is if RichEdit ctrl has different color character(text).
6. Now important part. Here we can see the magic of '
BitBlt(m_processedDC, 0,0, rcClient.Width(), rcClient.Height(), m_hSelectionDC , 0, 0, MERGEPAINT );
First Inverte the pixel of source DC.
Second Merge the color of '
m_processedDC' with '
m_hSelectionDC' (pixel by pixel)
Do u remember that pixel of '
m_processedDC' is the hilight color pixel of current system.
7. Now at this point we have got/prepared our
m_processedDC<code> and it is ready to use.
8. In the mouse move message I calculate starting point and ending point of user selection.
CPoint ptTemp = PosFromChar( CharFromPos( point ) );
ptTemp.x = ptTemp.x + m_FontWidth - 2;
ptTemp.y = ptTemp.y + m_FontHeight - 2;
if(( ptTemp.x > (m_colSelEndPt.x + 4)) || ( ptTemp.x < (m_colSelEndPt.x - 4) )
|| ( ptTemp.y > (m_colSelEndPt.y + 4)) || ( ptTemp.y < (m_colSelEndPt.y - 4)) )
m_colSelEndPt = ptTemp;
9. To copy the selected area/text I have used MSDN's clipboard concept which actually allocate global memory/shared memory ,
hClipboardData = (HGLOBAL)GlobalAlloc(GMEM_DDESHARE, sizeText);
pszClipText = (LPTSTR)GlobalLock((HGLOBAL)hClipboardData);
How to use
Download the zip file, which is a VC project (I have used Visual Studio 2005 ), and compile and run.
Select text by pressing ALT key + mouse drag and release both (mouse press and ALT key).
Now click "Copy Selection" button and go to your editor and paste it.
Points of Interest
The interesting thing is appearance/looking of my application/implementation , however, is better than some application, like - Edit Plus.
I have used Rich edit control of MFC but if anyone grab the basic concept then it can be implemented with any Programming language.