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
[812] [Controls] TStringGrid에서 Thumb으로 Scroll중에 Grid갱신하기
장성호 [nasilso] 8281 읽음    2008-10-11 00:27
예전에 볼포Q&A에 누가 질문해서 해보았던것인데...
누가 또 질문해서 이곳에 올려놓습니다.

TStringGrid에서 Vertical Scroll중에 Grid갱신하기

기본 TStringGrid에서는 ScrollBar를 이용해서 Scroll할때 
중간에 썸(THUMB) 버튼을 잡아서 움직이는 중에는 Grid의 내용이 갱신이 되지 않습니다.

StringGrid의 ScrollBar의 썸(Thumb)을 잡아 움직이는 중에도 Grid의 내용이 갱신되도록 만들어 보았습니다.
(참. 세로 스크롤만 햇습니다.)

1. sub-classing으로 WM_VSCROLL 메세지를 확인한후
2. scroll방향에 맞게 SB_PAGEDOWN / SB_PAGEUP 메세지를 Grid WndProc에 보내면 된다.


  
void * SGridProc; 
FARPROC SGridDefaultProc; 

void __fastcall TForm1::FormCreate(TObject *Sender) 
{ 
    SGridProc = MakeObjectInstance(StringGridProc); 
    SGridDefaultProc = (FARPROC)SetWindowLong(StringGrid1->Handle,GWL_WNDPROC, (LPARAM)SGridProc); 
} 
//--------------------------------------------------------------------------- 
WPARAM OW=0; 
void __fastcall TForm1::StringGridProc(TMessage &Msg) 
{ 
    if(Msg.Msg==WM_VSCROLL) 

        Msg.Result = CallWindowProc(SGridDefaultProc,StringGrid1->Handle,Msg.Msg,Msg.WParam,Msg.LParam); 

        if(Msg.WParam>10) 
        { 
            if(OW.WParam)StringGrid1->Perform(WM_VSCROLL,SB_PAGEDOWN,0); 
            else StringGrid1->Perform(WM_VSCROLL,SB_PAGEUP,0); 
            OW=Msg.WParam; 
        } 
    } 
    else 
    { 
        Msg.Result = CallWindowProc(SGridDefaultProc,StringGrid1->Handle,Msg.Msg,Msg.WParam,Msg.LParam); 
    } 
} 
//--------------------------------------------------------------------------- 
void __fastcall TForm1::FormDestroy(TObject *Sender) 
{ 
    SetWindowLong(StringGrid1->Handle,GWL_WNDPROC, (LPARAM)SGridDefaultProc); 
    FreeObjectInstance(SGridProc); 
} 
//--------------------------------------------------------------------------- 
       




[중요사항]

* 중간에 WParam이 10보다 큰경우에만 처리한것은
   Scroll이 시작이나 종료될때  10보다 작은 WParam값을 가지므로 정확한 방향값을 알수 없기 때문이다.

* SendMessage를 하지 않고 Perform을 한것은 똑같은 WM_VSCROLL 메세지이므로
  동작이 꼬이지 않고 바로 StringGrid의 WinProc를 호출하기 위함이다.


  다시말해

  StringGrid1->Perform(WM_VSCROLL,SB_PAGEDOWN,0); 이 코드는
  CallWindowProc(SGridDefaultProc,StringGrid1->Handle,WM_VSCROLL,SB_PAGEDOWN,0); 과 같은 내용이다.

   SubClassing을 MakeObjectInstance 라는 VCL함수를 이용하였으므로
   반드시 종료할때는 FreeObjectInstance로 free해주도록 한다.





MakeObjectInstance  를 이용하지 않고 TControl의 WindowProc를 이용한 sub-classing으로 수정해서 올립니다.

그것이 좀더 직관적이어서 쓰기편할것 같습니다.


   
//xxx.h 

    TWndMethod SGridOrgProc2; 
    void __fastcall TForm1::StringGridProc2(TMessage &Msg); 

//xxx.cpp 

void __fastcall TForm1::FormCreate(TObject *Sender) 
{ 
    //테스트용 초기화 

    for(int i=0;iRowCount;i++) 
        StringGrid2->Cells[0][i]=IntToStr(i+1); 

    //sub-classing 설정 

    SGridOrgProc2=StringGrid2->WindowProc; 
    StringGrid2->WindowProc=StringGridProc2; 

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

WPARAM OW2=0; 
void __fastcall TForm1::StringGridProc2(TMessage &Msg) 
{ 
    SGridOrgProc2(Msg); 
    if(Msg.Msg==WM_VSCROLL) 
    { 
        if(Msg.WParam>10) 
        { 
            WPARAM w=Msg.WParam; 
            if(OW2) 
            { 
                Msg.WParam=SB_PAGEDOWN; 
                SGridOrgProc2(Msg); 
            } 
            else 
            { 
                Msg.WParam=SB_PAGEUP; 
                Msg.LParam=0; 
                SGridOrgProc2(Msg); 
            } 
            OW2=w; 
        } 
    } 
}        




Delphi버젼

    
var 
  SGridOrgProc: TWndMethod; 
  OW: Integer; 
procedure TForm1.FormCreate(Sender: TObject); 
var 
  i: Integer; 
begin 

  for i:=0 to StringGrid1.RowCount-1 do 
  begin 
    StringGrid1.Cells[0,i]:=IntToStr(i); 
  end; 

  SGridOrgProc:=StringGrid1.WindowProc; 
  StringGrid1.WindowProc:=StringGridProc; 

end; 

procedure TForm1.StringGridProc(var Msg: TMessage); 
var 
  w: Integer; 
begin 
  SGridOrgProc(Msg); 
  if(Msg.Msg=WM_VSCROLL)then 
  begin 
    if(Msg.WParam>10)then 
    begin 
      w:=Msg.WParam; 
      if(OW)then 
      begin 
        Msg.WParam:=SB_PAGEDOWN; 
        SGridOrgProc(Msg); 
      end 
      else 
      begin 
        Msg.WParam:=SB_PAGEUP; 
        Msg.LParam:=0; 
        SGridOrgProc(Msg); 
      end; 
      OW:=w; 
    end; 
  end; 
end;        




그럼..
장성호 [nasilso]   2008-10-14 12:51 X
TStringGrid 의 Options에 goThumbTracking 라는게 있네요
goThumbTracking = true로 해주면 잘됩니다.

지난번에도 이런게 있는줄 확인 했는데...

기억이 나질 않아서... 쩝쩝...

역시 머리 나쁘면 손발이 고생입니다.

장성호 [nasilso]   2012-01-31 12:25 X
TDBGrid에서 ThumbTracking옵션 적용은 어떻게?
참고
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=66102

+ -

관련 글 리스트
812 [Controls] TStringGrid에서 Thumb으로 Scroll중에 Grid갱신하기 장성호 8281 2008/10/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.