CEdit::CharFromPos failing for large text, need help 
Author Message
 CEdit::CharFromPos failing for large text, need help

Hi there

It's the same question as yesterday, only now I wrote code for regular CEdit
derived class (using MFC classwizard) with a few small differences. This
code should be copy pastable easily.
The workaround is method CharFromPos_. You can test it in your right button
down handler and use it to set the caret to the mouse cursor on right
clicking. You will see that the caret is placed incorrectly when tabs are on
the line clicked.

Thanks for any help, I am really stuck!
Tom.

void CEditCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
 int beg_sel, end_sel, char_ind = CharFromPos_(point);
 GetSel(beg_sel, end_sel);

 if(beg_sel!=end_sel)                           // if HasSelection()
  if(char_ind<beg_sel || char_ind>end_sel)   // if clicked outside selection
region
   SetSel(char_ind, char_ind);     // then move cursor to clicked position
  else
   ;                                              // else retain selection
 else
  SetSel(char_ind, char_ind);     // else move cursor to clicked position

 CEdit::OnRButtonDown(nFlags, point);

Quote:
}

// The workaround: doesn't work when tabs are on the line
UINT CEditCtrl::CharFromPos_(CPoint pt)
{
 CRect rect;
 GetClientRect(&rect);

 UINT char_ind = 0;
 if(rect.PtInRect(pt))
 {
  LONG dbu = GetDialogBaseUnits();
  WORD hbu = LOWORD(dbu);
  WORD vbu = HIWORD(dbu);
  CClientDC client_dc(this);
  CFont* old_font = client_dc.SelectObject( GetFont() );
  int tab_pxls = client_dc.GetOutputTextExtent("\t", 1).cx;
  tab_pxls *= (hbu / 4);
  TEXTMETRIC text_metric;
  client_dc.GetTextMetrics(&text_metric);
  int height_row = client_dc.GetOutputTextExtent(" ",1).cy +
text_metric.tmExternalLeading; // Height of a line
  int line_count = GetLineCount();
  WORD left_margin = LOWORD(GetMargins());

  int   line_ind = (pt.y!=0) ? int( GetFirstVisibleLine() + floor((pt.y - 1)
/ double(height_row)) ) : 0;
  int   pos      = 0;
  if(line_ind>line_count-1)
   line_ind = line_count-1;

  if(pt.x>=int(left_margin))
  {
   CString line = GetTextAt(line_ind);
   if(!line.IsEmpty())
   {
    LPCTSTR line_= line;
    int inter_char_pxl = client_dc.GetTextCharacterExtra();
    int x_pos = left_margin;
    for(; x_pos<pt.x && pos!=line.GetLength(); ++pos)
     if(line_[pos]=='\t')
      x_pos += tab_pxls - ((x_pos - left_margin) % tab_pxls);
     else
      x_pos += client_dc.GetOutputTextExtent(&line_[pos], 1).cx +
inter_char_pxl;

    if(x_pos>=pt.x)
     --pos;
   }
  }
  client_dc.SelectObject(old_font);
  char_ind = LineIndex(line_ind) + pos;
 }
 return char_ind;

Quote:
}

CString CEditCtrl::GetTextAt(int line_index)
{
 CString ret;
 LPTSTR line_buf = ret.GetBuffer(4096);
 int cc = GetLine((line_index==-1) ? (LineFromChar()) : (line_index),
line_buf, 4096-1);
 line_buf[cc]='\0';
 ret.ReleaseBuffer();
 return ret;
Quote:
}



Sun, 11 Sep 2005 14:33:13 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. CEdit::CharFromPos -- trying to write a bugfix, please help (having problems with tabs)

2. Help: Need to display a large text file

3. Workaround for CEdit::CharFromPos (final!)

4. CEdit::CharFromPos workaround: almost there ... one more problem

5. CEdit::CharFromPos

6. Getting the text from CEdit, I need help?

7. Need to Set text from Dialog CEdit to Active Window in MDI text app

8. Getting the text from CEdit, I need help?

9. Need to display a large amount of text in a view

10. Malloc fails in large program - Help.

11. Need help on save texts format by Textout to a text file

12. Help - Insertion in large text files

 

 
Powered by phpBB® Forum Software