자유롭게 질의 및 응답을 할 수 있는 게시판입니다. 개발자 여러분의 답변이 큰 도움이 됩니다.
- 제품설치/등록 오류 문의: 설치/등록 Q&A 이용 (제품 구매 고객 한정)
Delphi [DelphiXE7] 컨트롤을 동적생성하여 해제하면 Form을 닫을 수 없게 됩니다.
2014.12.21 22:19
전 왜 버그만 계속 만나는지... 이번엔 DelphiXE7에서만 일어나는 버그인지 다른 버전에서도 생기는지는 확인 못해봤네요.
FireMonkey에서 동적생성된 개체를 free(or disposeof)하면 창의 border가 얼어버려서 창을 닫을 수 없는 상태가 됩니다.
이걸 활성화하려면 마우스로 다른 컨트롤개체를 클릭하고나면 정상동작하네요.
간단하지만, 소스를 이곳에 적는 것보다 첨부파일로 추가해둡니다.(번거로우시겠지만, 한 번 컴파일해서 실행부탁합니다)
win32, android에서 해보았는데, 둘다 같은 상황에 빠지네요.
FireMonkey에서는 개체를 동적생성하여 사용하면 안된다는 황당한 해결책이 아니면 좋겠습니다^^자체 해결해보려고 다른 개체에 setfocus를 해보는 등 별짓을 해보았지만, 안되더군요.
구글링해보니 이런 문제점을 발견한 외인이 계시던데... 답변이 좀 황당하더군요....T_T(아예 Create생성자는 그냥 public에서 빼고 디자인타임에서만 올려놓고 쓰는 위지윅 개발툴이 되어야하는 것이 아닌가... 저로선 허탈해집니다^^)
댓글 3
-
Humphery
2014.12.22 19:00
-
사조성
2014.12.22 21:03
오호~
이것도 VCL과 다른 점이군요.
VCL에서는 숱하게 써왔는데 FMX에서는 금지라는 거군요T_T
나름 유용하게 써온 기법인데, 이걸 타이머로 쓰자니 좀 존심상하고 묘수가 필요하겠군요^^
답변 감사드립니다.
그리고 F12번 눌러서 디자인창의 특정 컴포넌트를 선택해두고 엔터키를 누르면 바로 Object Inspector창으로 이동하면서 특정 프로퍼티를 바로 설정(name을 변경한다던지..)할 수 있어 마우스 쓸일 별로 없고 좋았는데, XE로 넘어오면서 이런 기능이 없어졌나봐요T_T
-
Humphery
2014.12.23 03:20
VCL에서 잘동작하지만 코드만으로 보면 지양해야할 코딩 스타일입니다.
왜냐하면, 객체의 클릭이벤트에서 객체를 해제해 버리면, (아마도 계속 상관없을 테지만...)만약, VCL에서 클릭이벤트를 발생하고 자체참조하는 코드를 추가한다면 이미 클릭이벤트내에서 객체를 해제시켜 버렸기 때문에 메모리 참조 에러가 발생할 여지가 다분합니다.
(개인적인 의견입니다.)
해당 코드는 이벤트에 이후의 참조관계를 확실히 알고 있다는 전제하에서만 꼭 필요한 경우에 사용하시기 바랍니다.^^
Delphi [DelphiXE7] 컨트롤을 동적생성하여 해제하면 Form을 닫을 수 없게 됩니다.
2014.12.21 22:19
전 왜 버그만 계속 만나는지...
이번엔 DelphiXE7에서만 일어나는 버그인지 다른 버전에서도 생기는지는 확인 못해봤네요.
FireMonkey에서 동적생성된 개체를 free(or disposeof)하면 창의 border가 얼어버려서 창을 닫을 수 없는 상태가 됩니다.
이걸 활성화하려면 마우스로 다른 컨트롤개체를 클릭하고나면 정상동작하네요.
간단하지만, 소스를 이곳에 적는 것보다 첨부파일로 추가해둡니다.(번거로우시겠지만, 한 번 컴파일해서 실행부탁합니다)
win32, android에서 해보았는데, 둘다 같은 상황에 빠지네요.
FireMonkey에서는 개체를 동적생성하여 사용하면 안된다는 황당한 해결책이 아니면 좋겠습니다^^
자체 해결해보려고 다른 개체에 setfocus를 해보는 등 별짓을 해보았지만, 안되더군요.
구글링해보니 이런 문제점을 발견한 외인이 계시던데... 답변이 좀 황당하더군요....T_T
(아예 Create생성자는 그냥 public에서 빼고 디자인타임에서만 올려놓고 쓰는 위지윅 개발툴이 되어야하는 것이 아닌가... 저로선 허탈해집니다^^)
댓글 3
-
Humphery
2014.12.22 19:00
-
사조성
2014.12.22 21:03
오호~
이것도 VCL과 다른 점이군요.
VCL에서는 숱하게 써왔는데 FMX에서는 금지라는 거군요T_T
나름 유용하게 써온 기법인데, 이걸 타이머로 쓰자니 좀 존심상하고 묘수가 필요하겠군요^^
답변 감사드립니다.
그리고 F12번 눌러서 디자인창의 특정 컴포넌트를 선택해두고 엔터키를 누르면 바로 Object Inspector창으로 이동하면서 특정 프로퍼티를 바로 설정(name을 변경한다던지..)할 수 있어 마우스 쓸일 별로 없고 좋았는데, XE로 넘어오면서 이런 기능이 없어졌나봐요T_T
-
Humphery
2014.12.23 03:20
VCL에서 잘동작하지만 코드만으로 보면 지양해야할 코딩 스타일입니다.
왜냐하면, 객체의 클릭이벤트에서 객체를 해제해 버리면, (아마도 계속 상관없을 테지만...)만약, VCL에서 클릭이벤트를 발생하고 자체참조하는 코드를 추가한다면 이미 클릭이벤트내에서 객체를 해제시켜 버렸기 때문에 메모리 참조 에러가 발생할 여지가 다분합니다.
(개인적인 의견입니다.)
해당 코드는 이벤트에 이후의 참조관계를 확실히 알고 있다는 전제하에서만 꼭 필요한 경우에 사용하시기 바랍니다.^^
소스코드를 보니 버튼의 클릭이벤트에서 클릭이벤트가 발생한 버튼을 해제했습니다.
해당코드와 같이
이벤트 발생 중인 객체를 이벤트 내에서 제거하는 작업은 버튼의 클릭이벤트를 어떻게 발생하는 코드에 따라 예측할 수 없는 오류를 내뱉을 수 있습니다.(되도록 해당 코드와 같은 방식은 사용하지 않으시길 바랍니다.)
해당 코드는 되도록 버튼객체 변수에 생성하고 변수를 해제하도록 하시길 바라며,
부득이 버튼을 누르면 버튼이 해제되야 하는 경우에는 버튼이벤트 완료 이후 해제되도록 타이머등을 이용하는 방안을 추천드립니다.
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
FButton: TButton;
procedure onBtnClick(sender: TObject);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
FButton := Tbutton.Create(nil);
with FButton do begin
parent := self;
SetBounds(50,100,200,height);
text := 'IamaRuntimeButton';
OnClick := onBtnClick;
end;
// Memo1.visible := true;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FButton.Free;
end;
procedure TForm1.onBtnClick(sender: TObject);
begin
// if sender is TButton then
// sender.Free;
end;