【问题标题】:VC++ Trasforming a sample application into a DLLVC++ 将示例应用程序转换为 DLL
【发布时间】:2015-08-27 08:55:17
【问题描述】:

我有一个项目,我收到了一个示例代码,它是一个 exe,基本上加载到一个对话框中,两个 activeX 控件。

我需要制作一个 DLL 来使用该控件的功能。

执行此操作的最佳策略是什么? 我认为我的 DLL 需要创建一个窗口实例。 并在构建窗口时获取指向 activeX 控件的指针以使事情发生。

执行此操作的最佳策略是什么?或者是否有可能?

应用代码: 启动.h #pragma 一次

#ifndef __AFXWIN_H__
    #error "include 'stdafx.h' before including this file for PCH"
#endif

#include "resource.h"       // main symbols



// CStartUpApp:
// See StartUp.cpp for the implementation of this class
//

class CStartUpApp : public CWinApp
{
public:
    CStartUpApp();

// Overrides
    public:
    virtual BOOL InitInstance();

// Implementation

    DECLARE_MESSAGE_MAP()
};

extern CStartUpApp theApp;

StartUpDlg.h

#pragma once
#include "xnssdkdevicectrl.h"
#include "xnssdkwindowctrl.h"


// CStartUpDlg dialog
class CStartUpDlg : public CDialog
{
// Construction
public:
    CStartUpDlg(CWnd* pParent = NULL);  // standard constructor

// Dialog Data
    enum { IDD = IDD_STARTUP_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support


// Implementation
protected:
    HICON m_hIcon;

    // Generated message map functions
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()

private:
    // [ XNS ACTIVEX HELP ]
    // -----------------------------------------------------------------------
    // XNS Device control and Window control variables
    // -----------------------------------------------------------------------
    CXnssdkwindowctrl   m_ctrlXnsWindow;    // XnsWindow control
    CXnssdkdevicectrl   m_ctrlXnsDevice;    // XnsDevice control

public:
    afx_msg void OnBnClickedOk();
};

启动.cpp

#include "stdafx.h"
#include "StartUp.h"
#include "StartUpDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CStartUpApp

BEGIN_MESSAGE_MAP(CStartUpApp, CWinApp)
    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CStartUpApp construction

CStartUpApp::CStartUpApp()
{
    // TODO: add construction code here,
    // Place all significant initialization in InitInstance
}


// The one and only CStartUpApp object

CStartUpApp theApp;


// CStartUpApp initialization

BOOL CStartUpApp::InitInstance()
{
    // InitCommonControlsEx() is required on Windows XP if an application
    // manifest specifies use of ComCtl32.dll version 6 or later to enable
    // visual styles.  Otherwise, any window creation will fail.
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // Set this to include all the common control classes you want to use
    // in your application.
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);

    CWinApp::InitInstance();

    AfxEnableControlContainer();

    // Standard initialization
    // If you are not using these features and wish to reduce the size
    // of your final executable, you should remove from the following
    // the specific initialization routines you do not need
    // Change the registry key under which our settings are stored
    // TODO: You should modify this string to be something appropriate
    // such as the name of your company or organization
    SetRegistryKey(_T("Local AppWizard-Generated Applications"));

    CStartUpDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: Place code here to handle when the dialog is
        //  dismissed with OK
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: Place code here to handle when the dialog is
        //  dismissed with Cancel
    }

    // Since the dialog has been closed, return FALSE so that we exit the
    //  application, rather than start the application's message pump.
    return FALSE;
}

StartUpDlg.cpp

#include "stdafx.h"
#include "StartUp.h"
#include "StartUpDlg.h"


// [ XNS ACTIVEX HELP ]
// -----------------------------------------------------------------------
// This files are installed in {$SDK path}\sample_code\include 
// You should include this files
// -----------------------------------------------------------------------
#include "XnsCommon.h"
#include "XnsDeviceInterface.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// Macro for OutputDebugString()
#define DBG_LOG(...) do{\
    CString strMessage = _T("");\
    strMessage.AppendFormat(_T("(%S:%d)"), __FUNCTION__, __LINE__); \
    strMessage.AppendFormat(__VA_ARGS__);\
    OutputDebugString(strMessage);\
}while(0);

// Macro for AfxMessageBox()
#define ERROR_BOX(...) do{\
    CString strMessage = _T("");\
    strMessage.Format(__VA_ARGS__);\
    AfxMessageBox(strMessage);\
}while(0);


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// Dialog Data
    enum { IDD = IDD_ABOUTBOX };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CStartUpDlg dialog




CStartUpDlg::CStartUpDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CStartUpDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CStartUpDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_XNSSDKDEVICECTRL, m_ctrlXnsDevice);
    DDX_Control(pDX, IDC_XNSSDKWINDOWCTRL, m_ctrlXnsWindow);
}

BEGIN_MESSAGE_MAP(CStartUpDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
    ON_BN_CLICKED(IDOK, &CStartUpDlg::OnBnClickedOk)
END_MESSAGE_MAP()


// CStartUpDlg message handlers

BOOL CStartUpDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here

    // [ XNS ACTIVEX HELP ]
    // -----------------------------------------------------------------------
    // Initializes the DLL files. 
    // For this, XnsActiveX library requires config.xml, device.xml, 
    // and xns.xml files and the DLL file list should be mentioned 
    // in Xns.xml file. The path of the DLL file can not exceed 512 bytes
    // in length. The XnsActiveX library searches for xns.xml using 
    // XnsSDKDevice.ocx installed in "{$SDK path}\Config" folder.
    // -----------------------------------------------------------------------
    long nRet = m_ctrlXnsDevice.Initialize();
    if (nRet != ERR_SUCCESS)
    {
        DBG_LOG(_T("XnsSdkDevice:: Initialize() fail: errno=[%d]\n"), nRet);
    }

    // [ XNS ACTIVEX HELP ]
    // -----------------------------------------------------------------------
    // Initializes the XnsSdkWindow control. 
    // Namely, this will specify the window handle in order to display 
    // images on the screen. 
    // -----------------------------------------------------------------------
    nRet = m_ctrlXnsWindow.Initialize(NULL, NULL);
    DBG_LOG(_T("XnsSdkWindow:: Initialize() return=[%d](%s)\n"), 
        nRet, m_ctrlXnsDevice.GetErrorString(nRet));


    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CStartUpDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CStartUpDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CStartUpDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}


void CStartUpDlg::OnBnClickedOk()
{
    // TODO: Add your control notification handler code here
    OnOK();
}

我的 dll 头

__declspec(dllexport) long init();//initilize app with activeX controls in window
__declspec(dllexport) long getDlgInstance();//get dlg handle to be able to call activeX
__declspec(dllexport) long connect(long handle);//do stuff

【问题讨论】:

  • @Elemental 我不明白你的问题?
  • 如果您需要启动一个对话框并返回一个指向该对话框的指针,它必须是一个无模式对话框,并且您的调用程序需要在它退出之前正确关闭该对话框——这就是您想?还是应该是一个模态对话框,并且在对话框关闭之前init函数不返回?
  • 它将由 dll 控制,所以它是我想要的无模式对话框选项。

标签: c++ visual-c++ dll mfc exe


【解决方案1】:

应该不会那么难... 在没有看到您的代码的情况下(我怎么可能?),我假设您定义了函数以将 activeX 控件的指针返回给调用者。 从您之前提出的问题来看,您知道如何制作 DLL。在一个新的 DLL 项目中获取你需要的所有代码,只导出你想从宿主应用程序访问的函数,然后你就完成了

【讨论】:

  • 添加了应用代码。我的主要问题假设我的 dll 上有一个 init 函数,它将启动窗口、启动 activex 控件并将句柄返回给 Cdialog,我该怎么做?
  • 就像你说的那样。让你的函数返回你想要的句柄。如果您还想获得指向 activex 控件的引用/指针,您可以向该函数添加额外的(out-)参数。您可能还想声明一个宏来为您处理__declspec(import)__declspec(export)。这也解释了here
【解决方案2】:

您的 DLL 代码看起来像

__declspec (dllexport) CStartUpDlg *ShowStartUpDlg()
{   AFX_MANAGE_STATE(AfxGetStaticModuleState()); // in case the dialog is in the DLL's .rc file
    // alternate to the above line: AfxSetResourceHandle(hInstance); // hInstance is what you get in the DLL's InitInstance()

    CStartUpDlg *pDlg = new CStartUpDlg();
    if (pDlg == NULL)
        return NULL;
    if (!pDlg->Create(IDD_STARTUP_DLG))
        return NULL;
    pDlg->ShowWindow(SW_SHOW);
    return pDlg; // make sure you close the dialog and delete pDlg at the end of your program
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 2010-12-06
    • 2018-02-03
    • 2012-11-02
    相关资源
    最近更新 更多