Q&A

  • MDI 자식폼을 DLL로 만들어서 호출하는 방법이요..
안녕하세요..

MDI 관련 작업 작업을 하는데요..
그 자식폼을 DLL로 작성하여 호출할려고 합니다.

DLL로 자식폼을 만들었지만.

막상 부모폼에서 자식폼을 호출하면 실행시 에러가 나네요..

부모폼은 폼 스타일을 fsMDIForm 로 하고 DLL자식폼을 fsMDIChild로 설정을 했습니다.

계속 에러가 나서 DLL자식폼 스타일을 normal로 바꾸니 에러는 안나지만.
제가 해야 할 작업은 메모장 처럼 메인폼안에서 자식폼을 띄워야 해서요.

며칠을 해도 어느 부분을 어떻게 잡아줘야 할지를 몰라서 이렇게 고수님들의 도움을 받고자 합니다.

꼭 도와 주세요..^^


2  COMMENTS
  • Profile
    skysoft 2003.10.24 20:16
    인터넷에서 찾아서 조금 수정했습니다.
    참고하세요.
    (Application 객체를 DLL에 넘겨주어야 한다는군요)

    -----------------------------
    Project1: MDI 메인폼 프로젝트
    Unit1: MDI 메인폼(fsMDIForm)

    Project1Dll: DLL 프로젝트
    Unit1Dll: DLL 차일드폼(fsMDIChild)

    ----------------------------------------------MDI 메인폼 프로젝트 소스
    program Project1;

    uses
      Forms,
      Unit1 in 'Unit1.pas' {Form1};

    {$R *.RES}

    begin
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.

    -----------------------------------------------------------MDI 메인폼
    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      Menus;

    type
      TForm1 = class(TForm)
        MainMenu1: TMainMenu;
        Menu1: TMenuItem;
        procedure Menu1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

      TProcChild = procedure (ParentApplication: TApplication; ParentForm: TForm); stdcall;

    var
      Form1: TForm1;

    implementation

    {$R *.DFM}

    procedure TForm1.Menu1Click(Sender: TObject);
    var
      DllHandle: THandle;
      ProcAddr: FarProc;
      ProcChild: TProcChild;
    begin
      DllHandle := LoadLibrary('Project1Dll');
      ProcAddr := GetProcAddress(DllHandle, 'ProcChild');
      if ProcAddr <> nil then begin
        ProcChild := ProcAddr;
        ProcChild(Application, self); //어플리케이션과 메인폼을 넘겨줌
      end;
    end;

    end.

    ------------------------------------------------------Dll 프로젝트 소스
    library Project1Dll;

    { Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }

    uses
      Windows,
      Forms,
      Unit1Dll in 'Unit1Dll.pas' {Form1};

    var
      DllApplication: TApplication;

    procedure ProcChild(ParentApplication: TApplication; ParentForm: TForm); export; stdcall;
    var
      Form1: TForm1;
    begin
       Application := ParentApplication; //넘겨받은 어플리케이션 할당함

       Form1 := TForm1.Create(ParentForm);
       Form1.Show;
    end;

    procedure DLLUnloadProc(Reason: Integer); register;
    begin
      if Reason = DLL_PROCESS_DETACH then
        Application := DllApplication; //Dll 종료(?)시 어플리케이션을 원상태로 돌림.
    end;

    exports
      ProcChild;

    begin
      DllApplication := Application;
      DllProc := @DLLUnloadProc;
    end.

    -----------------------------------------------------------Dll 차일드폼
    unit Unit1Dll;

    interface

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

    type
      TForm1 = class(TForm)
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    implementation

    {$R *.DFM}

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caFree;
    end;

    end.

  • Profile
    홍성호 2003.10.25 01:01
    ^^