Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Column based selection in rich edit control.

0.00/5 (No votes)
22 May 2012 1  
Column based selection in rich edit control.

 

Introduction 

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.  

 

Background     

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 m_processedDC.  

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 . 

Code  explanation

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() );
	::SelectObject(m_processedDC, bmpREdit);
 

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/*BitsPerPixel*/, 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 m_hSelectionDC DC.

5. Copy RichEdit's DC to 'm_hSelectionDC

  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 'MERGEPAINT'.

 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  and it is ready to use. 

8. In the mouse move message I calculate starting point and ending point of user selection.  

// Adjust end line position
CPoint ptTemp =  PosFromChar( CharFromPos( point ) );
ptTemp.x = ptTemp.x + m_FontWidth - 2;
ptTemp.y = ptTemp.y + m_FontHeight - 2;
//m_colSelEndPt = ptTemp;
		
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;

Invalidate();
UpdateWindow();  } 
 

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);
    SetClipboardData(CF_UNICODETEXT/*CF_TEXT*/, 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.    

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here