감사합니다... 많은 도움이 되었습니다... 저야 워낙에 경험도 없고 델파이 개발부분에는 완전 초보수준이라 그저 누군가 물음에 답변을 주시면 그대로 믿을 뿐이지요...^^
또 실제로 해보니 탈도 없고 에러도 없고 해서 그런가부다 하고 넘어가기가 일쑤구요...
그렇다보니 실제로 제가 구현하는 것들이 에러없이 잘 돌아가기만 하면 그럭저럭 잘구성된것같구나 하는 어리석은 생각을 가끔 합니다요...^^;;
그런데 요새 그동안 안사용해 봤던 컴포넌트나 디비를 공부하면서 한가지 물음이 생기더군요...
지금 이 구성이 정말 잘 된것인지 하는...
그래서 폼 호출부분에 문제는 없는지 부족한 것은 없는지 하는 엉뚱한 물음을 던진게 되었습니다...^^
덕분에 한가지 또 알게 되었구요...^^
감사합니다...
차후로도 많은 지도 편달 부탁드리겠습니다...^^
박지훈.임프 님이 쓰신 글 :
: 보여주신 코드대로라면 그렇습니다.
: 도대체 어떤 분이 팁이라고 그런 황당한 내용을 알려주셨는지 모르겠습니다만... 얼마나 친한 분인지는 모르겠습니다만, 제가 권하고 싶기로는, 그 분과는 다른 얘기는 해도 개발 관련 기술 얘기는 안하는 편이 좋겠습니다.
:
: cust1F라는 변수로 폼 객체를 유지하려고 하는 코드로 보이는데요. 흔히 쓰이는 코드죠.
: 그런데 not (cust1F.HandleAllocated)를 같이 검사하는 부분은 거의 실효성이 없는 코드입니다.
:
: 왜 황당한 코드인지 잠깐 설명을 드리죠.
: HandleAllocated는 TWinControl의 멤버 메소드입니다. 하는 역할은, 해당 TWinControl 컨트롤에 윈도우 핸들이 생긴 상태인가를 검사해서 핸들이 있으면 true를, 없으면 false를 리턴하는 겁니다. 폼도 TWinControl의 자손이기 때문에 이 메소드가 있습니다. 그런데 원래 폼이라는 것은, 생성하는 즉시 내부적으로 일련의 작업을 거쳐서 핸들이 생성됩니다. 따라서 폼이 아예 생성되지 않았으면 모르되, 생성되어 있다면 폼의 HandleAllocated는 항상 true를 리턴할 수밖에 없습니다.
:
: 그러면 HandleAllocated가 항상 true를 리턴한다면 쓸모없는 거 아닌가, 라고 생각할 수 있는데요. 이 메소드는 컴포넌트를 개발할 때, 컨트롤이 내부적으로 자동으로 초기화되는 여러 코드들에서 핸들이 있는가 알 필요가 있을 때 쓰입니다. 컨트롤이 생성되어 초기화되는 과정에서는 핸들이 없는 상태도 존재하거든요. 또, 경우에 따라서는 컨트롤 자체는 생성되어 있는데 특수한 이유로 이미 가지고 있는 윈도우 핸들을 파괴하고 다시 생성할 때도 있습니다. 주로 에디트같은 Win32 표준 컨트롤에서 내부적으로 그런 방법을 씁니다.
:
: 따라서 컴포넌트를 직접 개발하면서 저수준 처리를 해야 하는 전문 개발자가 아닌, 일반적인 애플리케이션 개발자의 입장에서는 이 메소드를 호출할 일 자체가 없습니다. 그리고 만약 내부적으로 저수준에 접근해서 위의 코드가 유효해지는 경우(즉 핸들이 없을 수도 있는 경우)가 존재한다면, 그 경우에도 위의 코드는 잠깐 동안 핸들만 없지 이미 생성되어 있는 폼 객체가 있는데도, 그 객체 주소를 가지고 있는 유일한 변수를 새로운 객체로 덮어써버림으로써 기존의 폼 객체를 추적할 방법 자체를 완전히 잃어버리게 됩니다. 폼이 있는데도 그 폼을 잃어버리게 되니 그 메모리는 프로그램이 종료될 때까지 전혀 쓸 방법이 없겠지요. 이게 메모리 누수입니다.
:
: 일반 애플리케이션 개발자들은 전혀 볼 일도 없는 저수준용 메소드인 HandleAllocated를 언급하면서 그런 엉터리 지식을 팁이라고 알려준 걸 보면... 그분도 좀 황당한 분인 거 같은데요. 그래도 어디서, Handle을 직접 검사하면 안된다는 건 줏어들었나보네요.
:
: 이승근님이 스스로 초보라고 소개하시는 걸 그대로 믿는다면, 그런 분과는 기술 얘기는 안하시는 편이 낫고요. 몇달만 착실히 공부해도 그런 얼치기 수준은 훌쩍 넘어서게 되실 겁니다. 엉터리 팁으로 중무장하고 우습게도(혹은 안쓰럽게도) 그걸 자랑스럽게 여기는 개발자들의 공통점은, 몇년이 흘러도 전혀 발전이 없다는 거거든요.
:
: 그럼...
:
:
: 이승근 님이 쓰신 글 :
: : 감사합니다...^^
: : 1번에 대해서는 전에 어느분이 팁으로 알려주신 사항을 그대로 사용한 사항입니다...
: : 그렇다면 저 문장에서 not (cust1F.HandleAllocated) 문장만 없애면 되는건지요??
: :
: :
: : 박지훈.임프 님이 쓰신 글 :
: : : 0.
: : : 한번에 질문은 하나씩 해주세요.
: : :
: : : 1.
: : : 아래의 코드는,
: : : if(cust1F = nil ) or not (cust1F.HandleAllocated) then
: : : cust1F := Tcust1F.Create(Self)
: : : 실제 실행중에는 웬만해서는 이게 문제가 되는 경우는 없겠지만, 별로 권장할 만한 코드는 아니네요.
: : : 위 코드에서 폼의 HandleAllocated를 검사하는 것은 말 그대로 폼은 생성되었는데 윈도우 핸들이 생기기 직전의 경우가 있을 수 있어서, 아주 특정한 상황에서는 폼이 두번 생성되고 하나의 포인터를 잃어버리는 경우가 있을 수도 있습니다.
: : :
: : : 2.
: : : 짐작하시겠지만 상속을 이용해야 합니다.
: : : 그냥 TForm 폼을 상속받은 폼에서는 힘듭니다. 저같은 경우에는 TForm을 상속받은 다른 클래스 타입으로 폼을 생성시키는데, 그 특수 폼 클래스에서 파괴자를 오버라이드하든지 해서 합니다. 하지만 이렇게 하려면 폼 위저드를 직접 만들어야 하므로 폼이 열개 이내의 간단한 애플리케이션을 만들려고 하는 목적으로는 배보다 배꼽이 더 큽니다. 저는 업무용 프로그램 프레임워크를 만들면서 자동화하는 폼 위저드를 만들었습니다.
: : :
: : : 3.
: : : 데이터베이스 연결을 닫아주려면 폼의 OnClose에서 해주면 되겠지요.
: : :
: : : 4.
: : : showmodal에서 show로 바꾼다는 게 무슨 뜻인지 이해가 잘 안되네요.
: : :
: : :
: : : 이승근 님이 쓰신 글 :
: : : : 어떤 메뉴를 호출하면 form.show;를 이용하여 호출하는 것을 공부해서 실제 프로그램에 접속시켜봤습니다...
: : : : 그랬더니 아마도 실력이 없어서 그랬었겠지만 입력한 데이터가 없어지기도 하고 이런저런 문제가 발생해 그냥 하나하나 사용하고 정리할 수 있는 showmodal형식으로 바꿨습니다...
: : : : 문제는 한 모듈을 사용할때 다른 모듈을 사용할 수 없다는 점...
: : : : 그래서 다시 show를 사용하고 합니다...
: : : : 메인화면의 폼스타일을 fsMDIform으로 설정하고 다른 메뉴부분 중 show에 해당하는 메뉴의 폼스타일은 fsMDIChild로 변경했습니다...
: : : : 그리고 메뉴에서 호출할때 아래처럼 설정하였습니다...
: : : :
: : : : if(cust1F = nil ) or not (cust1F.HandleAllocated) then
: : : : cust1F := Tcust1F.Create(Self)
: : : : else
: : : : cust1F.SetFocus;
: : : : cust1F.Show;
: : : : if cust1F.WindowState = wsMinimized then
: : : : cust1F.WindowState := wsNormal;
: : : :
: : : : 또, 호출된 서브폼을 닫을때는 아래와 같이 설정하였습니다...
: : : : Query1.Close;
: : : : cust1F := nil ;
: : : : Action := caFree;
: : : :
: : : : 메인폼이 닫힐때는 아래와 같이 설정하였습니다...
: : : : Action := caFree;
: : : :
: : : :
: : : : 뭐 이러니깐 잘 작동은 되는데 몇가지 의문이 생기더군요...
: : : :
: : : : 1. 위 설정형식들이 맞는지.. 혹여 빠진것은 없거나 잘못 설정한 것은 없는지...
: : : :
: : : : 2. 다른 서브폼을 호출할때마다 위 호출문을 서브폼 이름만 바꿔서 기술해야 하는데 저것을 서브프로시져를 이용하여 사용할있는 방법은 없는지...
: : : : 예를 들어
: : : : 변수(m_formname) := 폼이름(cust1F);
: : : : 호출프로시져;
: : : : 이런 형태로 구현할수는 없는가요?? 가능하다면 변수는 어떻게 선언하면 되고 위 문장은 어떻게 기술하면 되는지요...
: : : :
: : : : 3. 폼을 여러개 열어놓고 작업하다가 프로그램 종료버튼을 누르게 되면 열렸던 폼과 그안에 데이터베이스 파일들을 자동으로 닫아주고 나가야 할텐데 어떻게 구현을 하면 되는것인지(어떠한 폼이 열렸는지 무슨 데이터(주로 Query를 사용함)가 열려있는지 알수가 없슴!!!)...
: : : : 아니면 close; 문장만 기술해주면 알아서 모두 닫아주고 빠져나가는지....
: : : :
: : : : 4. 또, showmodal에서 show로 바꿀때 특별한 체크사항은 없는지요...
: : : :
: : : : 아직도 초보에서 벗어나지 못해서 기초적인것도 모르는게 많습니다...
: : : : 아시는 분들은 많이많이 가르쳐 주십시요...^^
|