Q&A

  • 동적 생성한 컴포넌트를 Free 한후 다시 생성하면 에러 나요 -.-
<!--CodeS-->
procedure Tm.run_MakeBtn;
   procedure SetBtn(oBtn: TAdvToolButton; vSN, vCnt: Integer; vNAME, vHINT, vLOCATION, vAPPFILE: String);
   var
      NewBtn: TAdvToolButton;
   begin
        NewBtn := TAdvToolButton.Create(self);
        NewBtn.Name := 'btn_TvT_' + IntToStr(vSN);
        NewBtn.Height := 24;
        NewBtn.Left := 1;
        NewBtn.Margin := 7;
        NewBtn.Width := 177;
        NewBtn.Parent := oBtn.Parent;
   end;
var
   oA, oW, oS: Integer;
begin
     try
        JxSCH;
        if Assigned(_MF) then begin
           JxDBSet_DS_SP(m.dsFREE, 'sp_GET_AppList', ['USN'], [m.GUSN]);
           // SN0, NAME1, HINT2, LOCATION3, APPFILE4, KIND5, VORDER6
           m.dsFREE.First;
           with m.dsFREE do begin
              while not Eof do begin
                    SetBtn(_MF.btnAPP, Fields[0].AsInteger, oA, Fields[1].AsString, Fields[2].AsString, Fields[3].AsString, Fields[4].AsString);
                 m.dsFREE.Next;
              end;
           end;
     finally
        JxDBFree_DS(m.dsFREE);
     end;
end;
<!--CodeE-->

이렇게 해서 버튼을 동적으로 생성한 다음
...

<!--CodeS-->
             for i := 0 to bxMenu.ControlCount - 1 do begin
                 if Pos('_TvT_', bxMenu.Controls[i].Name) > 0 then begin
                    bxMenu.Controls[i].Free;
                 end;
             end;
<!--CodeE-->

이렇게 모든 콤포넌트를 삭제했는데

다시 위에있는 프로시저를 호출해서 새로 생성할라 치면 에러가 나요.
A Component XXX//..////  already exists..
이런 에러..

제가 뭘 모르고 있는지 알려 주세요 -0-
4  COMMENTS
  • Profile
    도끼로이마까 2005.04.19 20:38
    컴포넌트 Free부분이 잘못되었습니다.

    Free하고나면 ControlCount가 하나씩 줄죠 ^^
    다음 루프에 인덱스는 하나 늘어나겠죠.
    그러면 그 사이에 있던 콤포넌트는 검사가 되지 않습니다...
    그래서 Free가 안된것이구 다시 생성하면 당연히 이미 존재하는 이름이 있다고 나오겠죠.
    잘못하면..List Out of bound가 발생합니다.

    아래와 같이 코딩하세요.
    리스트에 넣어둔 다음에 한번에 Free하는거죠.

    <!--CodeS-->
      var
        list: TList;
      begin
        list := TList.Create;
        for i := 0 to bxMenu.ControlCount - 1 do
        begin
          if Pos('_TvT_', bxMenu.Controls[i].Name) > 0 then
          begin
            list.Add(bxMenu.Controls[i]);
          end;
        end;

        for i := 0 to list.Count - 1 do
        begin
          TControl(list[i]).Free;
        end;

        list.Free;
      end;

    <!--CodeE-->

  • Profile
    유재우 2005.04.19 22:45
    흑.. 그래도 에러나요..

  • Profile
    도끼로이마까 2005.04.20 19:10

    <!--CodeS-->
        for i := 0 to list.Count - 1 do
        begin
          TAdvToolButton(list[i]).Free; // <<
        end;
    <!--CodeE-->

  • Profile
    [ROOKIE] 2005.04.20 04:37

    Free할때 for문을 downto로 돌려보세요.
    해보지 않아서 정확한 답변인지는ㅠㅠ
    <!--CodeS-->
    for i:=bxMenu.ControlCount - 1 downto 0 do
      -- Free구문
    <!--CodeE-->