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

C++빌더 Q&A
C++Builder Programming Q&A
[46417] Re:Re:StringGrid 열의 너비 수정... 위 답변을 조금 수정하여...
장성호 [nasilso] 1058 읽음    2006-09-02 03:13
위의 답변을 수정하였습니다.
위글의 방법으로 할경우 스크롤바가 생겼을때 처리에 심각한 문제가 있습니다.

MouseMove때 Column의 경계선에 마우스가 와있는지 확인하는 방법을 바꾸었으며

또 MouseUp때 현재 sizing중이었으면 선택된 컬럼의 넓이를 수정해주는 부분도 좀 바뀌었습니다.

그리고 Sizing중일때 Mouse가 Down된 상태로 움직이므로
Cell의 선택이 바뀝니다.
이문제를 해결하기위해
Sizing중에는 Grid의 Options에서 goRangeSelect 를 뺐다고
끝난후(MouseUp)이벤트에 복귀시켰습니다.

그렇게 해도 Sizing중에 선택된 Cell이 단 하나지만 움직이는 위치에 따라 바뀝니다.
그걸 해결하기 위해 Sizing중에는 sub-classing으로 WM_MOUSEMOVE 메세지만 처리하고
return했습니다.


그러나  아직 문제가 남아있네요

[남은 문제들...]
1. Sizing하면서 StringGrid를 벗어나는 경우에 처리에 문제가 있습니다.
   이건 어떻게 해야 될까요? 아직 저도 특별한 아이디어가 안떠오르네요..
   좋은생각나면 수정해서 올려드리겠습니다.


TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
int __fastcall IABS(int a ,int b)
{
    if(a>b)return a-b;
    else return b-a;
}
//---------------------------------------------------------------------------
bool bSize;
TPoint FsPoint,LaPoint;
int iColNum;
TColor clPenColor;
TPenMode  pmPenMode;

typedef void __fastcall (__closure *TWNDPROC)(TMessage &msg); //VCL용 WNDPROC 타입 선언
TWNDPROC OriginalProc;

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    //
    for(int r=0;r<sgrd->RowCount;r++)
    {
        for(int c=0;c<sgrd->RowCount;c++)
        {
            sgrd->Cells[r][c]=IntToStr(r)+" - "+IntToStr(c);
        }
    }

    pmPenMode=sgrd->Canvas->Pen->Mode;
    clPenColor=sgrd->Canvas->Pen->Color;
    sgrd->Options=sgrd->Options>>goColSizing;


    OriginalProc=sgrd->WindowProc;  // 프로그램이 시작되면서 원래 WndProc를 따로 저장해두고..
    sgrd->WindowProc=SGridMessageProc; //내가  만든 WndProc함수를 TracBar에 설정해줍니다.


}
//---------------------------------------------------------------------------

                                                                //TarckBar 원래의 WinProc 저장할 변수
void __fastcall TForm1::sgrdMouseDown(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
    if(sgrd->Cursor==crHSplit)
    {
        bSize=true;
        FsPoint.x=X;
        FsPoint.y=0;
        LaPoint.x=X;
        LaPoint.y=sgrd->RowCount*(sgrd->DefaultRowHeight+sgrd->GridLineWidth);

        sgrd->Canvas->Pen->Mode=pmNot;
        sgrd->Canvas->Pen->Color=clBlack;
        sgrd->Canvas->MoveTo(FsPoint.x,FsPoint.y);
        sgrd->Canvas->LineTo(LaPoint.x,LaPoint.y);
        sgrd->Canvas->Pen->Mode=pmPenMode;
        sgrd->Canvas->Pen->Color=clPenColor;

    }
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::SGridMessageProc(TMessage &msg)
{
    if(msg.Msg==WM_MOUSEMOVE)
    {
        if(bSize)
        {
            int X;

//            msg.LParamHi; //Y값
//            msg.LParamLo; //X값
            X=msg.LParamLo;

            sgrd->Canvas->Pen->Mode=pmNot;
            sgrd->Canvas->Pen->Color=clBlack;
            sgrd->Canvas->MoveTo(FsPoint.x,FsPoint.y);
            sgrd->Canvas->LineTo(LaPoint.x,LaPoint.y);

            FsPoint.x=X;
            FsPoint.y=0;
            LaPoint.x=X;
            LaPoint.y=sgrd->RowCount*(sgrd->DefaultRowHeight+sgrd->GridLineWidth);
            sgrd->Canvas->MoveTo(FsPoint.x,FsPoint.y);
            sgrd->Canvas->LineTo(LaPoint.x,LaPoint.y);
            sgrd->Canvas->Pen->Mode=pmPenMode;
            sgrd->Canvas->Pen->Color=clPenColor;
            return; //MouseWheel 이벤트는 모두 return 해버리고
        }
    }
    OriginalProc(msg); //그밖에 메세지는 원래 tracbar의 WndProc함수를 돌려서 동작하도록 합니다.
}
//---------------------------------------------------------------------------
void __fastcall TForm1::sgrdMouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
    if(!bSize)
    {
        if(!Shift.Contains(ssLeft))
        {
            int iX=0;

            int iCol,iRow;
            Label1->Caption="X:"+IntToStr(X)+"  , Y:"+IntToStr(Y);
            sgrd->MouseToCell(X,Y,iCol,iRow);
            TRect rc=sgrd->CellRect(iCol,iRow);
            if(IABS(rc.right,X)<3)
            {
                sgrd->Cursor=crHSplit;
                iColNum=iCol;
                sgrd->Options>>goRangeSelect;
                return;
            }
            else if(IABS(rc.Left,X)<3)
            {
                sgrd->Cursor=crHSplit;
                iColNum=iCol-1;
                sgrd->Options>>goRangeSelect;
                return;
            }
        }
        if(sgrd->Cursor==crHSplit)
        {
            sgrd->Cursor=crDefault;//
            sgrd->Options=sgrd->Options<<goRangeSelect;
        }
    }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::sgrdMouseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{

    sgrd->Invalidate();
    sgrd->Canvas->Pen->Color=clWhite;
    if(bSize)
    {
        TRect rc=sgrd->CellRect(iColNum,0);

        if(rc.Left<=X)
        {
            sgrd->ColWidths[iColNum]=X-rc.Left;
        }
    }
    bSize=false;
    sgrd->Cursor=crDefault;
    sgrd->Options=sgrd->Options<<goRangeSelect;

}
//---------------------------------------------------------------------------

장성호 님이 쓰신 글 :
: 전에도 똑같은 질문 올리셨죠?
:
: 기본적으로는 TStringGrid * 에서는 안되기 때문에.. 답변을 못해드렸는데...
:
: 아래코드는 직접 코딩으로 구현한것입니다.
:  MouseDown , MouseMove , MouseUp 이벤트를 이용했습니다.
:
: 급하게 만들어서 문제가 좀 있습니다.
:
: [문제들]
:   1. 스크롤바가 생겼을때 처리  ( 옆으로 옮긴 위치만큼 처리안됨)
:   2. Paint문제가 좀 있는것 같아요
:   3. Click할때 Cell이 선택되는 문제...
:
: 그대로 가져가셔서 붙인후 테스트 해보세요
:
: 위 몇가지 문제만 해결하면 쓸만할 겁니다.  (특히 1번문제 반드시 처리해야함)
:
: 시간이 없어서 이만..
: 조만간 시간되면 위에 문제도 해결해서 올려드릴께요
:
: 그럼
:
:
:
:
: ==========<<샘플>>===========================================================
: TForm1 *Form1;
: //---------------------------------------------------------------------------
: __fastcall TForm1::TForm1(TComponent* Owner)
:     : TForm(Owner)
: {
: }
: //---------------------------------------------------------------------------
: bool bSize;
: TPoint FsPoint,LaPoint;
: int iColNum;
: TColor clPenColor;
: TPenMode  pmPenMode;
: void __fastcall TForm1::FormCreate(TObject *Sender)
: {
:     //
:     for(int r=0;r<sgrd->RowCount;r++)
:     {
:         for(int c=0;c<sgrd->RowCount;c++)
:         {
:             sgrd->Cells[r][c]=IntToStr(r)+" - "+IntToStr(c);
:         }
:     }
:
:     pmPenMode=sgrd->Canvas->Pen->Mode;
:     clPenColor=sgrd->Canvas->Pen->Color;
:     sgrd->Options=sgrd->Options>>goColSizing;
: }
: //---------------------------------------------------------------------------
: int __fastcall IABS(int a ,int b)
: {
:     if(a>b)return a-b;
:     else b-a;
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::sgrdMouseDown(TObject *Sender, TMouseButton Button,
:       TShiftState Shift, int X, int Y)
: {
:     if(sgrd->Cursor==crHSplit)
:     {
:         bSize=true;
:         FsPoint.x=X;
:         FsPoint.y=0;
:         LaPoint.x=X;
:         LaPoint.y=sgrd->RowCount*(sgrd->DefaultRowHeight+sgrd->GridLineWidth);
:
:
:         sgrd->Canvas->Pen->Mode=pmNot;
:         sgrd->Canvas->Pen->Color=clBlack;
:         sgrd->Canvas->MoveTo(FsPoint.x,FsPoint.y);
:         sgrd->Canvas->LineTo(LaPoint.x,LaPoint.y);
:         sgrd->Canvas->Pen->Mode=pmPenMode;
:         sgrd->Canvas->Pen->Color=clPenColor;
:
:     }
: }
: //---------------------------------------------------------------------------
:
: void __fastcall TForm1::sgrdMouseMove(TObject *Sender, TShiftState Shift,
:       int X, int Y)
: {
:     if(bSize)
:     {
:         sgrd->Canvas->Pen->Mode=pmNot;
:         sgrd->Canvas->Pen->Color=clBlack;
:         sgrd->Canvas->MoveTo(FsPoint.x,FsPoint.y);
:         sgrd->Canvas->LineTo(LaPoint.x,LaPoint.y);
:
:         FsPoint.x=X;
:         FsPoint.y=0;
:         LaPoint.x=X;
:         LaPoint.y=sgrd->RowCount*(sgrd->DefaultRowHeight+sgrd->GridLineWidth);
:         sgrd->Canvas->MoveTo(FsPoint.x,FsPoint.y);
:         sgrd->Canvas->LineTo(LaPoint.x,LaPoint.y);
:         sgrd->Canvas->Pen->Mode=pmPenMode;
:         sgrd->Canvas->Pen->Color=clPenColor;
:         //enum TPenMode {pmBlack, pmWhite, pmNop, pmNot, pmCopy, pmNotCopy, pmMergePenNot, pmMaskPenNot, pmMergeNotPen, pmMaskNotPen, pmMerge, pmNotMerge, pmMask, pmNotMask, pmXor, pmNotXor};
:
:
:     }
:     else
:     {
:         if(!Shift.Contains(ssLeft))
:         {
:             int iX=0;
:             for(int c=0;c<sgrd->RowCount;c++)
:             {
:                 iX=iX+sgrd->ColWidths[c]+1;
:                 if(IABS(iX,X)<2)
:                 {
:                     sgrd->Cursor=crHSplit;
:                     iColNum=c;
:                     sgrd->Options>>goRangeSelect;
:                     return;
:                 }
:             }
:         }
:         if(sgrd->Cursor==crHSplit)
:         {
:             sgrd->Cursor=crDefault;//
:             sgrd->Options=sgrd->Options<<goRangeSelect;
:         }
:     }
:
: }
: //---------------------------------------------------------------------------
:
:
: void __fastcall TForm1::sgrdMouseUp(TObject *Sender, TMouseButton Button,
:       TShiftState Shift, int X, int Y)
: {
:
:     sgrd->Invalidate();
:     sgrd->Canvas->Pen->Color=clWhite;
:     if(bSize)
:     {
:         int iX=0;
:         for(int c=0;c<iColNum;c++)
:         {
:             iX=iX+sgrd->ColWidths[c]+1;
:         }
:
:         sgrd->ColWidths[iColNum]=X-iX;
:     }
:     bSize=false;
:     sgrd->Cursor=crDefault;
:     sgrd->Options=sgrd->Options<<goRangeSelect;
:
: }
: //---------------------------------------------------------------------------
:
:
:
: 쥐르미온 님이 쓰신 글 :
: : 회섹으로 된 고정셀의 경우, 마우스를 셀의 경계선쪽으로 가져가면 열이나 너비를 수정할 수가 있게 되는데요. 일반 셀에서는 그것이 불가능합니다.
: :
: : 맨윗줄을 회색의 고정셀로 하지 않고도 너비 수정을 할 수 있었으면 좋겠는데요. 어떻게 해야하죠?

+ -

관련 글 리스트
46405 StringGrid 열의 너비 수정이 안되네요. ㅠ_ㅠ 고수님들, 답변 좀 부탁드립니다. 쥐르미온 912 2006/09/01
46414     Re:StringGrid 열의 너비 수정이 안되네요. ㅠ_ㅠ 고수님들, 답변 좀 부탁드립니다. 장성호 1038 2006/09/01
46417         Re:Re:StringGrid 열의 너비 수정... 위 답변을 조금 수정하여... 장성호 1058 2006/09/02
46425             Re:Re:Re:StringGrid 열의 너비 수정, 위 답변을 또 조금 수정하여...( 설명 포함 ) 장성호 1357 2006/09/02
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.