안녕하세요. 천리안 프로그래머포럼 C++Builder 담당 임펠리테리입니다.
제 홈페이지에도 질문을 올리셨죠? 답변은 이미 드렸지만.. 다른 분들이 궁금해
하실까봐 다시 답변을 올립니다.
----------------------------------------------------------------------------
스트링그리드(뿐만 아니라 TCustomGrid에서 상속받은 모든 그리드)에는 컬럼이나
로우의 사이즈가 변경되었을 때 발생하는 이벤트가 준비되어 있지 않습니다.
그래서.. 방법이 없을까 해서, VCL 소스를 분석해보았는데, 그런 메시지를 준비하기
위해서는 VCL의 TCustomGrid::MouseUp() 함수에서 이벤트핸들러를 호출해주는
함수를 호출해주어야 하는데, 컬럼이나 로우가 이동(Move)되었을 때는 ColumnMoved()
등의 버추얼 함수가 준비되어 있어 상속받은 TStringGrid에서 이벤트핸들러를
호출해주지만, 사이즈가 변경된 경우에 대해서는 그러한 준비가 되어있지 않습니다.
상속을 받아서 직접 오버라이딩할 메소드가 없으므로 새 컴퍼넌트를 만들어서 할
방법도 없는 거죠.
그렇다고 아주 방법이 없다..라고 말하면 재미없죠? ^^
MouseUp() 메소드를 오버라이드해서, 스트링그리드를 상속받은 새로운 컴퍼넌트를
만들어봤습니다.
아래에 소스를 첨부합니다. 내용이야 소스를 보시면 아시겠구요. OnColumnSized와
OnRowSized라는
두개의 이벤트를 만들어 추가했고, 이 이벤트는 사이즈가 변경된 컬럼이나 로우의
인덱스를 넘겨줍니다.
그럼 도움되시길...
//ImpStringGrid.h------------------------------------------------------------
#ifndef ImpStringGridH
#define ImpStringGridH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
typedef void __fastcall (__closure *TSizeEvent)(System::TObject* Sender,
int Index);
class PACKAGE TImpStringGrid : public TStringGrid
{
private:
TSizeEvent FOnColumnSized;
TSizeEvent FOnRowSized;
protected:
DYNAMIC void __fastcall MouseUp(TMouseButton Button, TShiftState Shift,
int X, int Y);
DYNAMIC void __fastcall ColumnSized(int ACol);
DYNAMIC void __fastcall RowSized(int ARow);
public:
__fastcall TImpStringGrid(TComponent* Owner);
__published:
__property TSizeEvent OnColumnSized = {read=FOnColumnSized, write=
FOnColumnSized};
__property TSizeEvent OnRowSized = {read=FOnRowSized, write=FOnRowSized};
};
//---------------------------------------------------------------------------
#endif
//ImpStringGrid.cpp ---------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ImpStringGrid.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TImpStringGrid *)
{
new TImpStringGrid(NULL);
}
namespace Impstringgrid
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TImpStringGrid)};
RegisterComponents("Imp", classes, 0);
}
}
//---------------------------------------------------------------------------
__fastcall TImpStringGrid::TImpStringGrid(TComponent* Owner)
: TStringGrid(Owner)
{
}
void __fastcall TImpStringGrid::MouseUp(TMouseButton Button, TShiftState Shift,
int X, int Y)
{
TGridState OldGridState = FGridState;
TStringGrid::MouseUp(Button, Shift, X, Y);
if(Options.Contains(goRowSizing)==false && Options.Contains(goColSizing)==
false)
return;
int ACol, ARow;
switch(OldGridState)
{
case gsColSizing:
MouseToCell(X, Y, ACol, ARow);
if(X <= CellRect(ACol, ARow).Left+3) ACol--;
ColumnSized(ACol);
break;
case gsRowSizing:
MouseToCell(X, Y, ACol, ARow);
if(Y <= CellRect(ACol, ARow).Top+3) ARow--;
RowSized(ARow);
break;
}
}
void __fastcall TImpStringGrid::ColumnSized(int ACol)
{
if(FOnColumnSized) FOnColumnSized(this, ACol);
}
void __fastcall TImpStringGrid::RowSized(int ARow)
{
if(FOnRowSized) FOnRowSized(this, ARow);
}
임펠리테리 박지훈이었습니다.
(
http://www.borlandforum.com, cbuilder@shinhae.com)