조금전에 Q&A에 올라온 질문에 답변으로 단 내용인데요
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=59619
[서론]
VCL-Control중에는
사용자가 Mouse나 Key-Board로 조작이 아닌 Coding으로 상태를 변경할때 해당 이벤트 핸들러가 호출되는 경우가 많습니다.
가량 TCheckBox->Checked를 변경시 CheckBoxOnClick이벤트가 발생하고
TEdit의 Text를 코딩으로 변경시 EditChange이벤트가 발생합니다.
문론 상태 변경시 이벤트가 호출되지 않는 경우도 많구요
그래서 개발자들이 코딩으로 Control의 상태를 변경하면서 관련 이벤트 핸들러가 호출되는지 모르고
잘못 코딩하는 경우가 많은것 같습니다.
(저도 예전에 이런것 때문에 버그 잡는다고 헤맨적 많이 있었죠)
[Coding으로 상태 변경시 이벤트핸들러 호출 되는 예]
다음과 같이 ChangeCheckBoxState 함수를 호출하면 어떻게 될까요?
ChangeCheckBoxState함수가 끝나기전 즉 CheckBox1->Checked값을 변경할시에
CheckBox1Click 함수가 호출됩니다.
화면에서 마우스로 클릭할때만 OnClick이벤트가 호출되는것이 아니라는 것입니다.
void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
ShowMessage("CheckBox1Click");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ChangeCheckBoxState(bool bChecked)
{
CheckBox1->Checked=bChecked;
}
[ 코딩으로 상태변경이 이벤트핸들러가 호출되는 다양한 경우]
CheckBox말구두 다음과 같이 다양한 경우에 그렇습니다.
아래는 모든 Control을 체크한것이 아니라 기본Control중심으로 체크 예전에 확인해 본것들입니다.
목록
컨트롤 명 |
제어내용 |
직접 Mouse로 제어시 발생 이벤트 |
코딩으로 상태변경시 발생 이벤트 |
TComboBox |
Item의 선택을 변경시 |
ComboBoxChange |
없음 |
TListBox |
Item의 선택을 변경시 |
ListBoxClick |
없음 |
TCheckBox |
Checked상태 변경시 |
CheckBoxClick |
CheckBoxClick |
TRadioButton |
Checked상태 변경시 |
RadioButtonClick |
RadioButtonClick |
TRadioGroup |
Radio버턴 선택 변경시 |
RadioGroupClick |
RadioGroupClick |
TTreeView |
Node선택 변경시 |
TreeViewChange |
TreeViewChange |
TEdit |
Text의 내용 변경시 |
EditChange |
EditChange |
TMemo |
Text의 내용 변경시 |
MemoChange |
MemoChange |
TListView |
Item선택 변경 |
ListViewChange |
ListViewChange |
TPageControl |
ActivePageIndex변경시 |
PageControlChange발생 |
없음 |
|
|
|
|
|
|
|
|
위에 정리한것 말구두 더 많이 있을것입니다.
특이사항
TRadioButton의 경우 Checked상태를 true로 변경할때만 이벤트가 호출됩니다.
Uncheck할때는 이벤트 핸들러가 호출되지 않습니다.
정리하면..
TListBox와 TComboBox 그리고 TPageControl 이외에
대부분의 WinControl에서는 마우스나 키보드로 직접 상태변경할때랑
코딩으로 상태별경할때 똑같이 관련 이벤트 핸들러가 동작하네요
코딩으로 상태변경시 이벤트핸들러 호출 안되게 하기
다음 코드와 같이 이벤트 핸들러 함수를 NULL로 해주면 Checked상태가 코딩에서
상태 변경하더라도 이벤트 핸들러가 호출될 일이 없을것입니다.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TNotifyEvent ChkBoxOnClick=CheckBox1->OnClick;
CheckBox1->OnClick=NULL;
CheckBox1->Checked=! CheckBox1->Checked;
CheckBox1->OnClick=ChkBoxOnClick;
}
//---------------------------------------------------------------------------
그럼..