1. 이벤트 입력 받는 방법
2. 체크 박스 흉내 내는 방법
3. 클릭된 쎌 찾는 방법
1. 이벤트 입력 받는 방법
2가지를 해 주어야 한다. active x control에서 이벤트를 받을 수 있게 event sink map을 만들어 주어야 하고, 그 이벤트들에 대한 message map을 만들어 주어야 한다.
우선 헤더 파일에,
[code cpp]
//h 파일
afx_msg void OnClickGrid();
DECLARE_EVENTSINK_MAP()
[/code]
선언을 해준 후, cpp 파일에,
[code cpp]
//CPP파일
BEGIN_EVENTSINK_MAP(CEPisDsgnMngrView, CView)
//{{AFX_EVENTSINK_MAP(CEPisDsgnMngrView)
ON_EVENT(CEPisDsgnMngrView, IDC_FLEXGRID1, -600 /* Click */, OnClickGrid, VTS_NONE)
ON_EVENT(CEPisDsgnMngrView, IDC_FLEXGRID1, -605 /* MouseDown */, OnMouseGridDown, VTS_I2 VTS_I2 VTS_I4 VTS_I4)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
[/code]
을 적어 준다. ON_EVENT macro의 첫번째 인자는, 뷰의 이름이고, 두번째 인자는 active x의 ID이고, 세번째 인자는 이벤트에 할당된 번호이고, 네번째 인자는, 이벤트에 할당된 함수이름이고, 다섯번째 인자는 그 함수가 받을 파라미터 정보이다.
이렇게 작성한 후, cpp 파일에 함수를 만들면 된다. MSFlexGrid에 할당된 이벤트 번호는 다음과 같다.
-600 void Click();
-602 void KeyDown(short* KeyCode, short Shift);
-601 void DblClick();
-603 void KeyPress(short* KeyAscii);
-604 void KeyUp(short* KeyCode, short Shift);
-605 void MouseDown(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
-606 void MouseMove(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
-607 void MouseUp(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
69 void SelChange();
70 void RowColChange();
71 void EnterCell();
72 void LeaveCell();
73 void Scroll();
74 void Compare(long Row1, long Row2, short* Cmp);
short 형의 파라미터 정보는 VTS_I2이다. 이것에 대한 정보는, OLE Viewer를 이용한다. 즉, Object Class --> Grouped by Component Category --> Controls --> Microsoft FlexGrid Control, version 6.0 을 오른쪽 클릭한 후, View Type Information을 선택하면 볼 수 있다.
2. 체크 박스 흉내 내는 방법
쎌에 그림을 넣어 주면 된다. 체크 박스를 집어 넣을 것이라면, 2개의 그림이 필요하다. 각각을 리소스에 비트맵으로 만들어 놓은 후 다음과 같은 함수를 이용하여 쎌에 그림을 집어 넣어 준다.
[code cpp]
CPictureHolder pic ;
pic.CreateFromBitmap(IDB_BITMAP1);
_grid.SetRefCellPicture(pic.GetPictureDispatch());
[/code]
이 때, afxctl.h 파일을 include해야 한다. 그림을 없애고 싶을 때는, pic.CreateEmpty();로 생성한 그림을 설정해 주면 된다. 쎌에 있는 그림이 어떤 그림인지를 알 수 있는 방법은 없기 때문에(그 그림을 얻을 수는 있다), 체크 박스를 흉내내기 위한 토글 기능은, 각 쎌의 정보를 따로 저장하고 있는 데이터를 이용해야 한다. STL의 vector를 이용하면 될 것이다. 즉, vector<char> 정도가 좋을 것이다. 이것은 row나 col 하나의 정보만을 저장할 때이고, 만약 행/열을 모두 고려하여 체크 박스를 넣고 싶다면, 그 정보는 map에 저장하면 될 것이다. 즉, map<pair<int, int>, char> 정도가 될 것이다.
이 방법은 이 이외에도 여러 가지로 응용이 가능하다.
3. 클릭된 쎌 찾는 방법
mouse에 의해 발생한 이벤트 처리기로 넘어 오는 좌표는 pixel 단위이다. 반면, 그리드의 GetCellWidth 함수 등으로 얻는 단위는 twip이다. 따라서 pixel 단위로 된 마우스의 좌표를 트윕으로 바꾸어 주어야 한다. 다음과 같이 한다.
[code cpp]
void CPubMedView::OnMouseUpOnGrid(short Button, short shift, long x, long y)
{ //현재 x, y는 pixel 단위
CClientDC dc(this);
long TwipsPerPixelX = 1440 / dc.GetDeviceCaps(LOGPIXELSX);
long TwipsPerPixelY = 1440 / dc.GetDeviceCaps(LOGPIXELSY);
y *= TwipsPerPixelY; // 이제 twip 단위
x *= TwipsPerPixelX; // 이제 twip 단위
[/code]
모든 쎌을 다 확인할 필요는 없고, 화면에 보이는 쎌만 확인하면 된다. 따라서,
[code cpp]
long top_row = _grid.GetTopRow(); // 화면에 보이는 쎌만 선택
[/code]
로 화면에 보이는 row만 선택한 후, 각 쎌의 왼쪽 위 좌표와 오른쪽 아래 좌표를 찾아 내서, 그 안에 마우스 포인터의 위치가 포함되는지 확인한다. 즉,
[code cpp]
// 화면에 보이는 row 부터 시작하여, 어느 위치에서 마우스가 눌렸는지 알아 낸다.
BOOL bFindClickedCell = false;
// 1000은 전체 row의 갯수. 적당히 구해서 넣어 준다.
for(int i = top_row; i<1000; i++){
// 우선 어느 row에 속하는지부터 구한다. 어차피 row + col 단위의 시간 소요.
_grid.SetRow(i);
long top = _grid.GetCellTop(); // row 의 위쪽 좌표.
// row의 아래쪽 좌표를 구하기 위해 row의 높이를 구한다.
long height = _grid.GetRowHeight(i);
// 현재 마우스의 y 좌표가 i 번째 row에 속하는가?
if(top <= y && y <= top + height){
for(int k = 0; k<10; k++){ // 만약 그렇다면, 이제 col 을 구한다.
_grid.SetCol(k);
// 역시 컬럼의 왼쪽 좌표를 구한다.
long left = _grid.GetCellLeft();
// 오른쪽 좌표를 구하기 위해, 컬럼의 폭을 구한다.
long width = _grid.GetCellWidth();
// 현재 마우스 x 좌표가 k 번째 컬럼에 속하는가?
if(left <= x && x <= left + width){
// 찾았다! 이제 할 일을 한다.
}
}
}
}
[/code]
중요한 것은, 헤더가 눌린 것은 따로 처리해 주어야 한다는 것이다.
2. 체크 박스 흉내 내는 방법
3. 클릭된 쎌 찾는 방법
1. 이벤트 입력 받는 방법
2가지를 해 주어야 한다. active x control에서 이벤트를 받을 수 있게 event sink map을 만들어 주어야 하고, 그 이벤트들에 대한 message map을 만들어 주어야 한다.
우선 헤더 파일에,
[code cpp]
//h 파일
afx_msg void OnClickGrid();
DECLARE_EVENTSINK_MAP()
[/code]
선언을 해준 후, cpp 파일에,
[code cpp]
//CPP파일
BEGIN_EVENTSINK_MAP(CEPisDsgnMngrView, CView)
//{{AFX_EVENTSINK_MAP(CEPisDsgnMngrView)
ON_EVENT(CEPisDsgnMngrView, IDC_FLEXGRID1, -600 /* Click */, OnClickGrid, VTS_NONE)
ON_EVENT(CEPisDsgnMngrView, IDC_FLEXGRID1, -605 /* MouseDown */, OnMouseGridDown, VTS_I2 VTS_I2 VTS_I4 VTS_I4)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
[/code]
을 적어 준다. ON_EVENT macro의 첫번째 인자는, 뷰의 이름이고, 두번째 인자는 active x의 ID이고, 세번째 인자는 이벤트에 할당된 번호이고, 네번째 인자는, 이벤트에 할당된 함수이름이고, 다섯번째 인자는 그 함수가 받을 파라미터 정보이다.
이렇게 작성한 후, cpp 파일에 함수를 만들면 된다. MSFlexGrid에 할당된 이벤트 번호는 다음과 같다.
-600 void Click();
-602 void KeyDown(short* KeyCode, short Shift);
-601 void DblClick();
-603 void KeyPress(short* KeyAscii);
-604 void KeyUp(short* KeyCode, short Shift);
-605 void MouseDown(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
-606 void MouseMove(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
-607 void MouseUp(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
69 void SelChange();
70 void RowColChange();
71 void EnterCell();
72 void LeaveCell();
73 void Scroll();
74 void Compare(long Row1, long Row2, short* Cmp);
short 형의 파라미터 정보는 VTS_I2이다. 이것에 대한 정보는, OLE Viewer를 이용한다. 즉, Object Class --> Grouped by Component Category --> Controls --> Microsoft FlexGrid Control, version 6.0 을 오른쪽 클릭한 후, View Type Information을 선택하면 볼 수 있다.
2. 체크 박스 흉내 내는 방법
쎌에 그림을 넣어 주면 된다. 체크 박스를 집어 넣을 것이라면, 2개의 그림이 필요하다. 각각을 리소스에 비트맵으로 만들어 놓은 후 다음과 같은 함수를 이용하여 쎌에 그림을 집어 넣어 준다.
[code cpp]
CPictureHolder pic ;
pic.CreateFromBitmap(IDB_BITMAP1);
_grid.SetRefCellPicture(pic.GetPictureDispatch());
[/code]
이 때, afxctl.h 파일을 include해야 한다. 그림을 없애고 싶을 때는, pic.CreateEmpty();로 생성한 그림을 설정해 주면 된다. 쎌에 있는 그림이 어떤 그림인지를 알 수 있는 방법은 없기 때문에(그 그림을 얻을 수는 있다), 체크 박스를 흉내내기 위한 토글 기능은, 각 쎌의 정보를 따로 저장하고 있는 데이터를 이용해야 한다. STL의 vector를 이용하면 될 것이다. 즉, vector<char> 정도가 좋을 것이다. 이것은 row나 col 하나의 정보만을 저장할 때이고, 만약 행/열을 모두 고려하여 체크 박스를 넣고 싶다면, 그 정보는 map에 저장하면 될 것이다. 즉, map<pair<int, int>, char> 정도가 될 것이다.
이 방법은 이 이외에도 여러 가지로 응용이 가능하다.
3. 클릭된 쎌 찾는 방법
mouse에 의해 발생한 이벤트 처리기로 넘어 오는 좌표는 pixel 단위이다. 반면, 그리드의 GetCellWidth 함수 등으로 얻는 단위는 twip이다. 따라서 pixel 단위로 된 마우스의 좌표를 트윕으로 바꾸어 주어야 한다. 다음과 같이 한다.
[code cpp]
void CPubMedView::OnMouseUpOnGrid(short Button, short shift, long x, long y)
{ //현재 x, y는 pixel 단위
CClientDC dc(this);
long TwipsPerPixelX = 1440 / dc.GetDeviceCaps(LOGPIXELSX);
long TwipsPerPixelY = 1440 / dc.GetDeviceCaps(LOGPIXELSY);
y *= TwipsPerPixelY; // 이제 twip 단위
x *= TwipsPerPixelX; // 이제 twip 단위
[/code]
모든 쎌을 다 확인할 필요는 없고, 화면에 보이는 쎌만 확인하면 된다. 따라서,
[code cpp]
long top_row = _grid.GetTopRow(); // 화면에 보이는 쎌만 선택
[/code]
로 화면에 보이는 row만 선택한 후, 각 쎌의 왼쪽 위 좌표와 오른쪽 아래 좌표를 찾아 내서, 그 안에 마우스 포인터의 위치가 포함되는지 확인한다. 즉,
[code cpp]
// 화면에 보이는 row 부터 시작하여, 어느 위치에서 마우스가 눌렸는지 알아 낸다.
BOOL bFindClickedCell = false;
// 1000은 전체 row의 갯수. 적당히 구해서 넣어 준다.
for(int i = top_row; i<1000; i++){
// 우선 어느 row에 속하는지부터 구한다. 어차피 row + col 단위의 시간 소요.
_grid.SetRow(i);
long top = _grid.GetCellTop(); // row 의 위쪽 좌표.
// row의 아래쪽 좌표를 구하기 위해 row의 높이를 구한다.
long height = _grid.GetRowHeight(i);
// 현재 마우스의 y 좌표가 i 번째 row에 속하는가?
if(top <= y && y <= top + height){
for(int k = 0; k<10; k++){ // 만약 그렇다면, 이제 col 을 구한다.
_grid.SetCol(k);
// 역시 컬럼의 왼쪽 좌표를 구한다.
long left = _grid.GetCellLeft();
// 오른쪽 좌표를 구하기 위해, 컬럼의 폭을 구한다.
long width = _grid.GetCellWidth();
// 현재 마우스 x 좌표가 k 번째 컬럼에 속하는가?
if(left <= x && x <= left + width){
// 찾았다! 이제 할 일을 한다.
}
}
}
}
[/code]
중요한 것은, 헤더가 눌린 것은 따로 처리해 주어야 한다는 것이다.
'컴퓨터 > MFC_API' 카테고리의 다른 글
title bar의 '제목 없음' 없애기 (0) | 2009.12.27 |
---|---|
이전 경로를 유지하면서 FolderSelection 대화 상자 열기 (0) | 2009.12.27 |
Resize ScrollView (0) | 2009.12.27 |
CTreeCtrl 에서 check box를 집어 넣고 다루기 (1) | 2009.12.27 |
프로그램이 플로피 디스크를 읽는 것 방지 (0) | 2009.12.27 |