C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[760] [Controls] TMemo가 64KByte넘어갈때 CaretPos는?
장성호 [nasilso] 7442 읽음    2008-03-21 12:26
얼마전에 Q&A에 TMemo의 CaretPos가 이상하게 나온다고 해서 ..해보다가...
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=52783


VCL의 TMemo는  64KByte까지 만 제대로 Edit할수있습니다.
왜냐하면 win32의  EDIT를  슈퍼클래싱해놓은 컴포넌트이기 때문입니다.

그래서 내용이 64KByte넘게 들어가서 SelStart가 65535를 넘어간경우 CaretPos가 제대로된값이 나오지 않습니다.
그래서 가능하면 64KByte넘어갈때는 TMemo를 쓰지 않도록 하는것이 좋습니다.

하지만 외부 컴포넌트를 쓰지 않으면 마땅한 대안이 없어 TMemo를 써야하고
CaretPos를 써야한다면?


아래 함수를 이용하면 적당한 CaretPos를 구할수 있을 것입니다.

기냥 SelStart까지 각 Line의 Length를 구해서 ... 계산해서.. CaretPos를 구하는거죠..

TPoint __fastcall GetMemoCaretPos(TMemo *Memo)
{
    TPoint oPt=Memo->CaretPos;

    if(oPt.x>=0)return oPt;

    TPoint pt=Point(0,0);
    int iSelStart=Memo->SelStart;
    int iLen=0;

    iSelStart=iSelStart+Memo->SelLength;
    bool bFind=false;
    for(int i=0;iLines->Count;i++)
    {
        iLen+=Memo->Lines->Strings[i].Length();
        if(iLen>=iSelStart)
        {
            pt.y=i;
            pt.x=iSelStart-iLen+Memo->Lines->Strings[i].Length();
            bFind=true;
            break;
        }
        iLen+=2;
    }
    if(!bFind)
    {
        pt.x=0;
        pt.y=Memo->Lines->Count;
    }
    return pt;
}


그런데 위 함수에 문제가 있습니다.
TMemo 의 WordWrap=false인경우 또는 WordWrap=true이더라고 가로 ScrollBar가  있는 경우에는 문제없지만
WordWrap=true되어  자동줄바꿈이 되면 문제가 있습니다.


그런데 오늘 TMemo에서 현재 위치의  LineNumber를 알아오는 방법과
그 Line의 Index를 알아오는 message를 알았습니다.

뭐 간단합니다.

int LineNumber = SendMessage(Memo1->Handle,EM_LINEFROMCHAR,Memo1->SelStart,0);
또는
int LineNumber = Memo1->Perform(EM_LINEFROMCHAR,Memo1->SelStart,0);

그 다음  그 라인에서 현재 위치의 Index는?
int index=Memo1->Perform(EM_LINEINDEX, LineNumber , 0);

결론적으로 위 두가지를 이용해서 CaretPos를 구할수 있겠죠..

TPoint __fastcall GetMemoCaretPos(TMemo *Memo)
{
    if(Memo==NULL)return Point(0,0);
    TPoint pt;
    pt.y = Memo->Perform(EM_LINEFROMCHAR, Memo->SelStart, 0);
    pt.x  = Memo->SelStart - Memo->Perform(EM_LINEINDEX, pt.y, 0);
    return pt;
}

위 함수는 Memo가 WordWrap=true 인경우.. 그리고 SelStart가 65535를 넘어가는 경우에도 제대로 나옵니다.

그럼..
허정주 [tinydew4]   2008-03-21 15:39 X
WordWrap = true 이면 HScrollBar 가 없는거 아닌가요?
WordWrap = true 이면서 HScrollBar 가 있는 경우는 어떤 경우인가요? (상상이 안가서;;)
장성호 [nasilso]   2008-03-21 19:24 X
WordWrap = true 해놓아도 ScrollBars를  ssBoth로 해놓으면 HScrollBar가 생깁니다.
ScrollBars를 ssHorizontal만 해도 생기네요..

그런경우  라인이 길어도 자동줄바꿈이 안되네요...

+ -

관련 글 리스트
760 [Controls] TMemo가 64KByte넘어갈때 CaretPos는? 장성호 7442 2008/03/21
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.