C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[17988] Re:관련 부분만 첨부했습니다.^^;
유영인 [Chris] [cuperido] 939 읽음    2002-04-27 13:45
문제가 된 부분은 잘 처리하셨는데, 메모리 소거에서 실수를 하셨네요. ^^
아래에 소스와 에러가 난 곳의 주석을 적었습니다. 첨부 파일은 프로젝트 파일로 아래 소스가지고 잘 안될시에 테스트 해보면서 해보세요.





** Main **

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit_Main.h"
#include "Unit_Sub.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMain *Main;

//---------------------------------------------------------------------------

__fastcall TMain::TMain(TComponent* Owner) : TForm(Owner)
{
}

//---------------------------------------------------------------------------

void __fastcall TMain::FormActivate(TObject *Sender)
{

Application->OnMessage = AppMessage;

}

//---------------------------------------------------------------------------

void __fastcall TMain::_btShowClick(TObject *Sender)
{

TForm             *SubForm;


SubForm = new TSub(Application);
SubForm->ShowModal();

// SubForm 을 메모리에서 제거
delete SubForm;


Main->FormActivate(Main);

}

//---------------------------------------------------------------------------

void __fastcall TMain::AppMessage(tagMSG &Msg, bool &Handled)
{

if(Msg.message == WM_KEYDOWN)
   switch(Msg.wParam) {
     case VK_LEFT : {
       _lbDirection->Caption = "Left";
       break;
     }

     case VK_RIGHT : {
       _lbDirection->Caption = "Right";
       break;
     }

     case VK_UP : {
       _lbDirection->Caption = "Up";
       break;
     }

     case VK_DOWN : {
       _lbDirection->Caption = "Down";
       break;
     }
   }

}

//---------------------------------------------------------------------------


** Sub **


//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit_Sub.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TSub *Sub;
//---------------------------------------------------------------------------
__fastcall TSub::TSub(TComponent* Owner) : TForm(Owner)
{
}

//---------------------------------------------------------------------------

void __fastcall TSub::FormActivate(TObject *Sender)
{

Application->OnMessage = AppMessage;

}

//---------------------------------------------------------------------------

void __fastcall TSub::FormDestroy(TObject *Sender)
{

Application->OnMessage = NULL;

}

//---------------------------------------------------------------------------

void __fastcall TSub::AppMessage(tagMSG &Msg, bool &Handled)
{

if(Msg.message == WM_KEYDOWN)
   switch(Msg.wParam) {
     case VK_LEFT : {
       _lbDirection->Caption = "Left";
       break;
     }

     case VK_RIGHT : {
       _lbDirection->Caption = "Right";
       break;
     }

     case VK_UP : {
       _lbDirection->Caption = "Up";
       break;
     }

     case VK_DOWN : {
       _lbDirection->Caption = "Down";
       break;
     }
   }

}

//---------------------------------------------------------------------------
void __fastcall TSub::_btCloseClick(TObject *Sender)
{

ModalResult = mrOk;

// 만약 아래에서 직접 이렇게 써주면 다음번 실행에서 에러가 납니다.
// Sub->Release;
// 그 이유는, Sub는 동적생성시에 필요한 기반이고, 지금 이 폼은 Sub가
// 아닌 Sub_1 입니다. ShowMessage(Name); 해보시면 알 수 있습니다.
// 따라서, Sub를 Release 하면, 다음번 동적 생성이 될 수 없겠죠.

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


heartsim 님이 쓰신 글 :
: 안녕하세요...
: 아침부터 답변주셔서 정말 감사하구요...
: 음...어제 회사에서 밤을 지샜습니다. @@;
: 오랜만에 날을 지샜더니 상당히 몸이 무겁군요........................
:
: 디버깅이란 거 참 어렵네요..^^;
:
: 음...
: 일단 질문관련 소스부분을 첨부해드릴게요.
: 마음같아서는 전체 소스를 보내드리고 싶지만^^; 보안(?)상의 문제로 관련 일부분만을 보내드리는군요.
: 죄송^^;
:
: 메인폼 부분:
: void __fastcall TForm1::FormActivate(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(FlatButton6->Focused())//가운데 중앙 버튼
:                                         {
:                                                 FlatButton7->SetFocus();//좌측버튼
:                                                 Msg.wParam = 0;
:                                         }
:                                         else if(FlatButton8->Focused())//우측버튼
:                                         {
:                                                 FlatButton6->SetFocus();
:                                                 Msg.wParam = 0;
:                                         }
:                                         else if(FlatButton7->Focused())
:                                         {
:                                                 FlatButton7->SetFocus();
:                                                 Msg.wParam = 0;
:                                         }
:                                         else
:                                         {
:                                                 FlatButton6->SetFocus();
:                                                 Msg.wParam = 0;
:                                         }
:                                
:                         }
:                         break;
:
:                         case VK_RIGHT:
:                         {
:                                         if(FlatButton6->Focused())//
:                                         {
:                                                 FlatButton8->SetFocus();
:                                                 Msg.wParam = 0;
:                                         }
:
:                                         else if(FlatButton8->Focused())
:                                         {
:                                                 FlatButton8->SetFocus();
:                                                 Msg.wParam = 0;
:                                         }
:                                         else if(FlatButton7->Focused())
:                                         {
:                                                 FlatButton6->SetFocus();
:                                                 Msg.wParam = 0;
:                                         }
:                                         else
:                                         {
:                                                 FlatButton6->SetFocus();
:                                                 Msg.wParam = 0;
:                                         }
:                         }
:                         break;
:
:                         case VK_UP:
:                                 if(FlatButton6->Focused())//
:                                 {
:                                         FlatButton4->SetFocus();//위쪽 버튼
:                                         Msg.wParam = 0;
:                                 }
:
:                                 else if(FlatButton5->Focused())//아래버튼
:                                 {
:                                         FlatButton6->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else if(FlatButton4->Focused())
:                                 {
:                                         FlatButton4->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else
:                                 {
:                                         FlatButton6->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                         break;
:
:                         case VK_DOWN:
:                                 if(FlatButton6->Focused())//
:                                 {
:                                         FlatButton5->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:
:                                 else if(FlatButton5->Focused())
:                                 {
:                                         FlatButton5->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else if(FlatButton4->Focused())
:                                 {
:                                         FlatButton6->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else
:                                 {
:                                         FlatButton6->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                         break;
:                 }
:
:         }
:
: }
:
:
: 동적 하위폼:
: void __fastcall TOsdForm3::FormCreate(TObject *Sender)
: {
:         Application->OnMessage=AppMessage;
: }
: void __fastcall TOsdForm3::AppMessage(tagMSG &Msg,bool &Handled)//OSD 방향키 기능
: {
: //        Msg.hwnd=OsdForm3->Handle;
:
:         if(Msg.message==WM_KEYDOWN)
:         {
:
:                 switch(Msg.wParam)
:                 {
:                         case VK_LEFT:
:                         {
:                                if(FlatButton3->Focused())//중앙 가운데 버튼
:                                 {
:                                         FlatButton2->SetFocus();//왼쪽 버튼
:                                         Msg.wParam = 0;
:                                 }
:
:                                 else if(FlatButton6->Focused())//오른쪽 버튼
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else if(FlatButton2->Focused())
:                                 {
:                                         FlatButton2->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                         }
:                         break;
:
:                         case VK_RIGHT:
:                         {
:                                 if(FlatButton3->Focused())//
:                                 {
:                                         FlatButton6->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:
:                                 else if(FlatButton6->Focused())
:                                 {
:                                         FlatButton6->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else if(FlatButton2->Focused())
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                         }
:                         break;
:
:                         case VK_UP:
:                         {
:                                 if(FlatButton3->Focused())//
:                                 {
:                                         FlatButton4->SetFocus();//위쪽 버튼
:                                         Msg.wParam = 0;
:                                 }
:
:                                 else if(FlatButton5->Focused())//아래쪽 버튼
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else if(FlatButton4->Focused())
:                                 {
:                                         FlatButton4->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                         }
:                         break;
:
:                         case VK_DOWN:
:                         {
:                                 if(FlatButton3->Focused())//
:                                 {
:                                         FlatButton5->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:
:                                 else if(FlatButton5->Focused())
:                                 {
:                                         FlatButton5->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else if(FlatButton4->Focused())
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                                 else
:                                 {
:                                         FlatButton3->SetFocus();
:                                         Msg.wParam = 0;
:                                 }
:                         }
:                         break;
:                 }
:         }
: }
: void __fastcall TOsdForm3::FlatButton1Click(TObject *Sender)//종료 OK BUTTON
: {
:         Form1->SetFocus();
:         //Form1->OnActivate;
:
:         ModalResult=mrOk;
:         Close();
: }
:
: void __fastcall TOsdForm3::FormClose(TObject *Sender, TCloseAction &Action)
: {
:         Action=caFree;
: }
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
: 유영인 [Chris] 님이 쓰신 글 :
: : 긁적.. 찾아보니 있긴 있는데.. 차이가 좀 있네요. 그 부분 프로젝트가 복잡하지 않다면 한번 첨부를 시켜보시는 것은 어떠세요? 기밀 자료면 문제가 있겠지만.. 소스가 포함되 있는 질문은.. 좀 더 확실한 답변을 해드릴 수 있을것 같아서요.. -_-a
: :
: :
: : heartsim 님이 쓰신 글 :
: : : 유영인님 답변 감사합니다.^^;
: : :
: : : 어느정도 감을 잡긴 했지만...
: : : 문제는 AppMessage를 바꿔주는 부분이 잘 안되는군요. @@;
: : : 일단 두번째 방법으로 문제를 해결해 보고 싶어서 계속 시도중인데...자꾸 삽질만 하네요.^^;
: : :
: : : 음...OsdForm3를 종료하는 시점에서 Form1->OnActivate를 추가해줬습니다.
: : : 이외에도 여러 방법으로 시도중인데, 잘 안되는군요.
: : :
: : : Help me?? --;
: : :
: : : void __fastcall TOsdForm3::OsdFlatButton1Click(TObject *Sender)//동적폼 close
: : : {
: : :          ModalResult=mrOk;//모달폼 종료
: : :          OsdForm3->Release;//동적폼인 모달폼을 메모리에서 제거
: : :
: : :          Form1->OnActivate;//메인폼을 다시 엑티베이트 함..
: : :         //여기 OnActivate안에 Application->OnMessage = AppMessage;가 있음
: : : }
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : : 유영인 [Chris] 님이 쓰신 글 :
: : : : OnCreate는 만들때 한번만 실행되므로, AppMessage 변경이 한번만 이루어지고요.. 우리는 계속 폼이 바뀔때마다 AppMessage를 바꿔주어야 하니, OnActivate 에 설정을 해주셔야 합니다.
: : : :
: : : : 만약 delete 를 하시면 서브폼들은 OnCreate에서는 상관 없겠지요. 뭐.. --;
: : : :
: : : :
: : : : 유영인 [Chris] 님이 쓰신 글 :
: : : : : 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;
: : : : : :
: : : : : : }
: : : : : :
: : : : : :

+ -

관련 글 리스트
17965 두개의 폼에서의 방향키 제어 에러?? heartsim 1030 2002/04/26
17968     Re:두개의 폼에서의 방향키 제어 에러?? 유영인 [Chris] 1281 2002/04/26
17970         아참 중요한거 하나 깜빡.. 유영인 [Chris] 1076 2002/04/26
17976             AppMessage 교체??? heartsim 1127 2002/04/26
17981                 Re:첨부 파일 유영인 [Chris] 1071 2002/04/27
17983                     관련 부분만 첨부했습니다.^^; heartsim 916 2002/04/27
17988                         Re:관련 부분만 첨부했습니다.^^; 유영인 [Chris] 939 2002/04/27
17990                             대단히 감사합니다.^^ heartsim 1004 2002/04/27
17979                 Re:AppMessage 교체??? 유영인 [Chris] 1159 2002/04/27
17966     Re:두개의 폼에서의 방향키 제어 에러?? 꼴(이성렬) 891 2002/04/26
17991         정말 감사합니다.^^ heartsim 989 2002/04/27
17967         Re:Re:두개의 폼에서의 방향키 제어 에러?? heartsim 1051 2002/04/26
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.