|
Application은 Form1, Form2 등의 여러 폼을 모두 포함하고 있는 그런 상위 객체로 보시면 됩니다. 따라서, Application의 OnMessage의 경우 단, 하나만 설정이 가능합니다!! 그 다음, 그 이벤트 함수 안에서 어디에서 발생했는지 처리하는 방법과, 이벤트 처리 함수를 그때마다 바꿔주는 방법이 있습니다.
첫번째 방법을 추천하는데, 그 이유는 일일히 함수를 각 폼마다 작성을 하지 않아도, 한 코드를 통해서 처리를 할 수 있기 때문입니다. Sender가 없어도 ActiveControl->Parent 를 계속 쫓다보면, 결국은 어떤 폼에서 발생이 되었는지 알 수 있으실껍니다.
님이 사용하신 방법은 두번째 방법입니다. 님의 순서를 대충 그려보면 다음과 같습니다.
1. 메인폼 (Form1) 생성
2. 메세지 전달을 Form1->AppMessage 로 설정 (OnCreate 에서 바꿔주고 있음)
3. 사용자 작동.
Form1->AppMessage 로 메세지가 설정되어 있으므로 정상적 동작
4. 서브폼 (OSDForm3) 생성
5. 메세지 전달을 Form3->AppMessage 로 설정 (OnCreate 에서 바꿔주고 있음)
6. 사용자 작동.
Form3->AppMessage 로 메세지가 설정되어 있으므로 정상적 동작
7. 서브폼을 닫음
하지만 아직까지 메세지 전달은 Form3->AppMessage 으로 되어있음
8. 사용자 작동.
화면에 보이는것은 메인폼 (Form1) 이지만, 메세지 전달이 Form3->AppMessage 로 되어 있으므로 모든 처리를 Form3 것을 처리하게 됩니다. 따라서, FlatButton2->SetFocus() 이부분에서 보이지 않는 Form3 으로 포커스를 옮기려 하니 문제가 발생되는 것입니다.
따라서, 정상적인 작동을 하려면, Form3 이 꺼질때, 다시 Form1의 AppMessage 로 바꿔주는 작업이 필요합니다.
또한, 한가지 덧붙이자면, 프로그램 종료시 현재 소스로는 메모리 억세스가 일어날 수 있습니다. 프로그램이 종료될때 ON_CLOSE 등의 메세지를 보내는데, 만약, 메모리 소거 순서가 Form3 이 먼저라면 (그럴 확률이 99% 겠지만요) 프로그램 종료시, Form3은 메모리에서 소거된 상태인데, AppMessage는 계속 Form3을 참고하고 있기 때문입니다.
이런 문제는 맨 처음 말씀드린 첫번째 방법으로 맨 나중에 소거가 되는 기준 (메인폼) 을 이벤트로 잡아주시면 됩니다. 아니면, 위와 같이 프로그램 순서를 잘 생각하여서 그때그때마다 AppMessage를 바꿔주셔야 겠지요..?
heartsim 님이 쓰신 글 :
: 안녕하세요.heartsim(박경원)입니다.
:
: 음...
: 두개의 폼이 있습니다.
: 하나는 메인폼이고 다른 하나는 동적폼입니다.
: 두개의 폼에 방향키를 입력받아서 위,아래,좌,우를 나타내는 방향버튼을 제어를 하고 있습니다.
: 가령,
: 메인폼과 동적폼에 아래의 방향키 메세지 함수를 똑같이 이용했습니다.
:
: 프로그램을 실행하면, 첨에 메인폼에서 방향키가 제어가 되고
: 그리고 동적폼을 쇼우모달폼으로 띄운 후 역시 방향키 제어가 됩니다.
: 그런데, 동적폼을 close시킨 다음 다시 메인폼에서 방향키를 제어할려고 하면
: 에러가 나더군요.
:
: 에러 메세지는 다음과 같습니다.cannot focus invisible or disable form
:
:
:
:
:
: 메인폼 경우,
: void __fastcall TForm1::FormCreate(TObject *Sender)
: {
: Application->OnMessage=AppMessage;<--------------이 부분이 ??
: }
:
: void __fastcall TForm1::AppMessage(tagMSG &Msg,bool &Handled)//OSD 방향키 기능
: {
: if(Msg.message==WM_KEYDOWN)
: {
: switch(Msg.wParam)
: {
: case VK_LEFT:
: if(FlatButton1->Focused())//
: {
: FlatButton2->SetFocus();
: Msg.wParam = 0;
: }
:
: ..........
:
: }
: }
: void __fastcall TForm1::Osd1Click(TObject *Sender)
: {
: OsdForm3=new TOsdForm3(Application);
: OsdForm3->ShowModal();
: }
:
:
:
:
:
: 동적 하위폼
: void __fastcall TOsdForm3::FormCreate(TObject *Sender)
: {
: Application->OnMessage=AppMessage;<-----------이 부분???
: }
: void __fastcall TOsdForm3::AppMessage(tagMSG &Msg,bool &Handled)//OSD 방향키 기능
: {
: if(Msg.message==WM_KEYDOWN)
: {
: switch(Msg.wParam)
: {
: case VK_LEFT:
: if(OsdFlatButton3->Focused())//
: {
: OsdFlatButton2->SetFocus();
: Msg.wParam = 0;
: }
:
: ..........
:
: }
: }
:
: void __fastcall TOsdForm3::OsdFlatButton1Click(TObject *Sender)//동적폼 close
: {
: ModalResult=mrOk;
:
: }
:
:
|