问题如下:
1.我在DLL中生成了查询,怎么样在BUTTION中(生成报表)
调用其报表窗口并且又怎么传送主调窗口的参数
2.怎样创建其窗口(我已建,不知怎么调用)
3.出错信息
access violation at address 00324cf1 in modul 'ybymzs.dll',read of
address 0000035c

解决方案 »

  1.   

    能否说得详细点?
    我的理解:
    主窗体和DLL窗体的工程选项都要编译成运行期包,在Project\Option\Package
    "Build runtime package"之类的复选框。LoadLibrary('<your DLL path>\ybymzs.dll');
    proc:= GetProcAddress('<Function Name>') ;
    Proc(<parameter>);
      

  2.   

    下面的代码是用C++ Builder做的,仿照它应该很容易:
    ////////////////////////////////
    (1)MDIChildDLL.cpp
    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    #include "MDIChild.h"
    #include "SDIForm.h"#pragma argsused
    TApplication *ThisApp = NULL;
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
        if ( (reason == DLL_PROCESS_DETACH) && (ThisApp) )
            Application = ThisApp;
        return 1;
    }extern "C" void __declspec(dllexport)ShowMDIChildForm(TApplication *CallingApp);void ShowMDIChildForm(TApplication *CallingApp)
    {
        if (!ThisApp)
        {
            ThisApp = Application;
            Application = CallingApp;
        }
        Child = new TChild(Application);
        Child->Show();
    }extern "C" void __declspec(dllexport)ShowMyForm(void);void ShowMyForm(void)
    {
        MyForm = new TMyForm(NULL);
        MyForm->ShowModal();
        delete MyForm;
    }
    /////////////////////////////////////////
    ///////////////////////////////////////////
    (2)MDIChild.h
    #ifndef MDIChildH
    #define MDIChildH#include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>class TChild : public TForm
    {
    __published: // IDE-managed Components
        TLabel *Label1;
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    private: // User declarations
    public: // User declarations
        __fastcall TChild(TComponent* Owner);
    };extern PACKAGE TChild *Child;#endif
    ///////////////////////////////////////////////
    ///////////////////////////////////////////////
    (3)MDIChild.cpp
    #include <vcl.h>
    #pragma hdrstop#include "MDIChild.h"#pragma package(smart_init)
    #pragma resource "*.dfm"
    TChild *Child;__fastcall TChild::TChild(TComponent* Owner)
        : TForm(Owner)
    {
    }void __fastcall TChild::FormClose(TObject *Sender, TCloseAction &Action)
    {
        Action = caFree;    
    }
    ///////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////
    (4)ParentForm.h  调用dll的例子的头文件
    #ifndef ParentFormH
    #define ParentFormH#include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <Menus.hpp>class TParent : public TForm
    {
    __published: // IDE-managed Components
        TMainMenu *MainMenu1;
        TMenuItem *File1;
        TMenuItem *New1;
        TMenuItem *Exit1;
        TMenuItem *NewPackage1;
        TMenuItem *ShowSDIForm1;
        void __fastcall New1Click(TObject *Sender);
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        void __fastcall NewPackage1Click(TObject *Sender);
        void __fastcall ShowSDIForm1Click(TObject *Sender);
    private: // User declarations
        HINSTANCE Dll;
        Windows::HINST Package;
    public: // User declarations
        __fastcall TParent(TComponent* Owner);
    };
    extern PACKAGE TParent *Parent;
    #endif
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    (5)ParentForm.cpp  具体调用代码
    #include <vcl.h>
    #pragma hdrstop#include "ParentForm.h"#pragma package(smart_init)
    #pragma resource "*.dfm"
    TParent *Parent;__fastcall TParent::TParent(TComponent* Owner)
        : TForm(Owner)
    {
        Dll = NULL;
        Package = NULL;
    }void __fastcall TParent::New1Click(TObject *Sender)
    {
        typedef void __declspec(dllimport)ShowChildType(TApplication *);
        ShowChildType *ShowMDIChild;    if (!Dll)
            Dll = LoadLibrary("MDIChildDLL.dll");    if (Dll)
        {
            // Get the address of the function.
            ShowMDIChild = (ShowChildType *)GetProcAddress 
                                (Dll, "_ShowMDIChildForm");
            if (ShowMDIChild)
                ShowMDIChild(Application);
            else
            {
                ShowMessage(SysErrorMessage(GetLastError()));
                FreeLibrary(Dll);
            }    }
        else
        {
            ShowMessage(SysErrorMessage(GetLastError()));
            ShowMessage("Unable to load the DLL");
        }
    }void __fastcall TParent::FormClose(TObject *Sender, TCloseAction &Action)
    {
        while (MDIChildCount)
            MDIChildren[0]->Free();    if (Dll)
            FreeLibrary(Dll);
        if (Package)
            UnloadPackage(Package);
    }void __fastcall TParent::NewPackage1Click(TObject *Sender)
    {
        typedef void __declspec(dllimport)ShowChildPkType(void);
        ShowChildPkType *ShowPackageChild;
        if (!Package)
            Package = LoadPackage("MDIChildPackage.bpl");
        if (Package)
        {
            ShowPackageChild = (ShowChildPkType *)GetProcAddress
                             (HINSTANCE)Package, "_ShowMDIChildPkForm");
            if (ShowPackageChild)
                ShowPackageChild();
            else
            {
                ShowMessage(SysErrorMessage(GetLastError()));
                UnloadPackage(Package);
            }    }
        else
        {
            ShowMessage(SysErrorMessage(GetLastError()));
            ShowMessage("Unable to load the Package");
        }
    }void __fastcall TParent::ShowSDIForm1Click(TObject *Sender)
    {
        typedef void __declspec(dllimport)ShowSDIType(void);
        ShowSDIType *ShowSDIForm;    if (!Dll)
            Dll = LoadLibrary("MDIChildDLL.dll");    if (Dll)
        {
            ShowSDIForm = (ShowSDIType *)GetProcAddress
                                         (Dll, "_ShowMyForm");
            if (ShowSDIForm)
                ShowSDIForm();
            else
            {
                ShowMessage(SysErrorMessage(GetLastError()));
                FreeLibrary(Dll);
            }    }
        else
        {
            ShowMessage(SysErrorMessage(GetLastError()));
            ShowMessage("Unable to load the DLL");
        }
    }
    ////////////////////////////////////////////////////////////////
      

  3.   

    最后说明一下:
    在DLL中放置MDI子窗体一般碰到的问题是该子窗体不能找到它的父窗体,所以你就必须欺骗DLL认为它是包含了父窗体的应用程序的一部分。关键就是:
    void ShowMDIChildForm(TApplication *CallingApp)
    {
        if (!ThisApp)
        {
            ThisApp = Application;
            Application = CallingApp;
        }
        Child = new TChild(Application);
        Child->Show();
    }

    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
        if ( (reason == DLL_PROCESS_DETACH) && (ThisApp) )
            Application = ThisApp;
        return 1;
    }