Q&A

  • 메뉴 동적 생성..부탁합니다..
제가 하고자하는 것은 실행중인 윈도우를 메뉴에 보여주어서 그것을 선택시

화면을 다시 보여주는 것을 하려하는데

NewItem을 사용해서 메뉴에 생성되게 했는데 Event처리시



var

NewItem: TMenuItem;



NewItem.OnClick := 이벤트;

을 사용했는데 파라미터를 넘기는 방법을 몰라서 한개의 폼만 됩니다..

어떻게 해야 되는 지 가르쳐주세요...

부탁합니다...



3  COMMENTS
  • Profile
    김일영 2000.04.26 09:44
    MDI 윈도우의 경우라면 MDIForm의 WindowMenu 프로퍼티에 메인메뉴의 한 Top Level

    메뉴를 지정하고 그 Top Level 메뉴의 SubMenu를 만들때 맨 마지막에 Spacer MenuItem

    (Caption에 하이픈(-)을 지정하면 됩니다.)을 넣어주는 것만으로 '실행중인 윈도우를 ~

    다시 보여주는 것' 일체의 내용이 자동으로 됩니다.

    (아마도 이건 아닐 것이라고 생각이 들지만 혹시나 하는 생각에서...)

    만약 아니시라면 다시 질문해 주십시오...

    ========================================================================

    blacklist wrote:

    > 제가 하고자하는 것은 실행중인 윈도우를 메뉴에 보여주어서 그것을 선택시

    > 화면을 다시 보여주는 것을 하려하는데

    > NewItem을 사용해서 메뉴에 생성되게 했는데 Event처리시

    >

    > var

    > NewItem: TMenuItem;

    >

    > NewItem.OnClick := 이벤트;

    > 을 사용했는데 파라미터를 넘기는 방법을 몰라서 한개의 폼만 됩니다..

    > 어떻게 해야 되는 지 가르쳐주세요...

    > 부탁합니다...

    >

  • Profile
    김일영 2000.04.26 11:08
    아무래도 MDI 폼 아니신 것 같아서 저도 한번 해봤습니다.

    (지금 시간이 새벽 1시 50분인데... 제가 실성했단 생각이 듭니다.)



    Form1, Form2, Form3가 있는 프로젝트를 만들었고 Form1이 메인 폼이고

    Form2, Form3는 AutoCreate Form이 아닙니다.



    Form1은 WListMain 유닛에 있고, Form2는 WListSub 유닛, Form3는 WListSub2

    유닛에 있습니다.



    WListMain 유닛과 WListSub 유닛의 소스를 올립니다. 기~니까 잘 보십시오.

    그리고 소스 끝나고 설명이 쪼금 더 있습니다. 끝까지 봐주세요.



    // 소스 시작 (WListMain):

    unit WListMain;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    StdCtrls, Menus;



    type

    TForm1 = class(TForm)

    MainMenu1: TMainMenu;

    mnuWindowList: TMenuItem;

    Button1: TButton;

    Button2: TButton;

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    procedure FormCreate(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    lstWindowList: TList;

    procedure MenuItemClick(Sender: TObject);

    procedure W_Add(Sender: TObject);

    procedure W_Remove(Sender: TObject);

    end;



    var

    Form1: TForm1;



    implementation

    uses WListSub, WListSub2;

    {$R *.DFM}



    procedure TForm1.MenuItemClick(Sender: TObject);

    begin

    TForm(lstWindowList.Items[TMenuItem(Sender).MenuIndex]).Show;

    end;



    procedure TForm1.W_Add(Sender: TObject);

    // 모든 폼의 OnCreate에서 호출

    var NewItem: TMenuItem;

    begin

    lstWindowList.Add(Sender);

    NewItem := TMenuItem.Create(Self);

    NewItem.OnClick := MenuItemClick;

    NewItem.Caption := TForm(Sender).Name;

    mnuWindowList.Add(NewItem);

    end;



    procedure TForm1.W_Remove(Sender: TObject);

    // 모든 폼의 OnDestroy에서 호출

    var

    RmIndex: Integer;

    begin

    with lstWindowList do begin

    RmIndex := IndexOf(Sender);

    Delete(RmIndex);

    end;

    with mnuWindowList do begin

    Items[RmIndex].Free;

    end;

    end;



    procedure TForm1.Button1Click(Sender: TObject);

    begin

    Form2 := TForm2.Create(Self);

    Form2.Show;

    end;



    procedure TForm1.FormCreate(Sender: TObject);

    begin

    lstWindowList := TList.Create;

    W_Add(Self);

    end;



    procedure TForm1.FormDestroy(Sender: TObject);

    var

    I: Integer;

    begin

    W_Remove(Sender);

    with lstWindowList do begin

    for I := Count - 1 downto 0 do begin

    TForm(Items[I]).Free;

    end;

    Free;

    end;

    end;



    procedure TForm1.Button2Click(Sender: TObject);

    begin

    Form3 := TForm3.Create(Self);

    Form3.Show;

    end;



    end.

    // 소스 끝 (WListMain)



    // 소스 시작 (WListSub)

    unit WListSub;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    WListMain;



    type

    TForm2 = class(TForm)

    procedure FormClose(Sender: TObject; var Action: TCloseAction);

    procedure FormCreate(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;



    var

    Form2: TForm2;



    implementation



    {$R *.DFM}



    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);

    begin

    Action := caFree;

    end;



    procedure TForm2.FormCreate(Sender: TObject);

    begin

    Form1.W_Add(Self);

    end;



    procedure TForm2.FormDestroy(Sender: TObject);

    begin

    Form1.W_Remove(Self);

    end;



    end.

    // 소스 끝 (WListSub)



    이상입니다. (WListSub2는 Form2 대신 Form3(TForm2 대신 TForm3)가 쓰였다는 점

    빼고는 WListSub와 동일하므로 생략합니다.)



    추가할 설명이란 것은... 아마도 이렇게 직접 각 폼들이 자기 자신을 메뉴에 넣고 빼고

    하는 것보다 다음과 같은 코드가 근사해 보일 것이라는 것입니다만...

    for I := 0 to Screen.FormCount-1 do

    begin

    NewItem := TMenuItem.Create(Self);

    NewItem.Caption := Screen.Forms[I].Name;

    mnuWindowList.Add(NewItem);

    end;

    그러나 이런 식으로 Screen.Forms를 이용해 함수를 만들면... (의미상으로는

    mnuWindowList_Refresh 쯤에 해당할까요?) 멋있어 보이지만 막상 이걸 호출할

    마땅한 이벤트가 없다는 겁니다. 고로 각 폼마다 일일이 Add, Remove 해 주는

    방법이 시원하다는 것이 저의 결론입니다... (하지만 더 좋은 방법을 찾으실지도 모르죠)



    그리고 각 폼의 이름 대신 TList를 이용해 각 폼의 레퍼런스를 직접 저장한 것은,

    폼의 이름이 같은 경우 문제가 생기지 않도록 하기 위해서입니다.



    이상입니다. 즐거운 하루 되시길...

  • Profile
    이기현 2000.04.25 10:48
    private

    procedure MenuClick(Sender: TObject);

    end;



    procedure TForm1.SpeedButton1Click(Sender: TObject);

    var

    NewItem: TMenuItem;

    begin

    NewItem.OnClick := MenuClick;

    end;



    procedure TForm1.MenuClick(Sender: TObject);

    begin

    Edit1.Text := 'ABCDE';

    end;