现在的位置: 首页 > 综合 > 正文

atl dll中调用wtl

2013年08月17日 ⁄ 综合 ⁄ 共 9077字 ⁄ 字号 评论关闭

环境 xp sp3,vs2003

1.新建 ATL-ATL项目,项目名test0507,不要选中属性化,不要选中支持 mfc,

2.stdafx.h添加

#include <atlapp.h>
#include <atlwin.h>

#include <atlframe.h>
#include <atlctrls.h>
#include <atldlgs.h>
#include <atlctrlw.h>
#include <atlsplit.h>
#include <atlctrlx.h>

3.在原有的Ctest0507Module类基础上添加AddMessageLoop等函数

#ifndef _DLLMAIN_H
#define _DLLMAIN_H

class Ctest0507Module : public CAtlDllModuleT< Ctest0507Module >
{
public :
	DECLARE_LIBID(LIBID_test0507Lib)
	DECLARE_REGISTRY_APPID_RESOURCEID(IDR_TEST0507, "{3759AAE6-F16A-43A7-9FB6-F72A495C0F21}")
public:
	virtual ~Ctest0507Module()
	{
		m_MsgLoopMap.RemoveAll();
	}

	BOOL AddMessageLoop(CMessageLoop* pMsgLoop,DWORD dwThreadID=::GetCurrentThreadId())
	{
		CStaticDataInitCriticalSectionLock lock;
		if(FAILED(lock.Lock()))
		{
			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
			ATLASSERT(FALSE);
			return FALSE;
		}


		//		ATLASSERT(m_MsgLoopMap.Lookup(dwThreadID) == NULL);   // not in map yet

		BOOL bRet = m_MsgLoopMap.Add(dwThreadID, pMsgLoop);

		lock.Unlock();

		return bRet;
	}

	BOOL RemoveMessageLoop(DWORD dwThreadID=::GetCurrentThreadId())
	{
		CStaticDataInitCriticalSectionLock lock;
		if(FAILED(lock.Lock()))
		{
			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
			ATLASSERT(FALSE);
			return FALSE;
		}

		BOOL bRet = m_MsgLoopMap.Remove(dwThreadID);

		lock.Unlock();

		return bRet;
	}

	CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const
	{
		CStaticDataInitCriticalSectionLock lock;
		if(FAILED(lock.Lock()))
		{
			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
			ATLASSERT(FALSE);
			return NULL;
		}

		CMessageLoop* pLoop=  m_MsgLoopMap.Lookup(dwThreadID);

		lock.Unlock();

		return pLoop;
	}
protected:
	ATL::CSimpleMap<DWORD, CMessageLoop*> m_MsgLoopMap;
};

extern Ctest0507Module _AtlModule;

#endif

4.添加test05062View.h,MainFrm.h

// test05062View.h : interface of the CTest05062View class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

class CTest05062View : public CWindowImpl<CTest05062View>
{
public:
	DECLARE_WND_CLASS(NULL)

	BOOL PreTranslateMessage(MSG* pMsg)
	{
		pMsg;
		return FALSE;
	}

	BEGIN_MSG_MAP(CTest05062View)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)

	LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		CPaintDC dc(m_hWnd);

		//TODO: Add your drawing code here

		return 0;
	}
};

// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

extern Ctest0507Module _AtlModule;

class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
	public CMessageFilter, public CIdleHandler
{
public:
	DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

	CSplitterWindow m_splitter;
	CPaneContainer m_pane;
	CTreeViewCtrl m_treeview;
	CTest05062View m_view;
	CCommandBarCtrl m_CmdBar;

	virtual BOOL PreTranslateMessage(MSG* pMsg)
	{
		if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))
			return TRUE;

		return m_view.PreTranslateMessage(pMsg);
	}

	virtual BOOL OnIdle()
	{
		UIUpdateToolBar();
		return FALSE;
	}

	BEGIN_UPDATE_UI_MAP(CMainFrame)
		UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
		UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
		UPDATE_ELEMENT(ID_VIEW_TREEPANE, UPDUI_MENUPOPUP)
	END_UPDATE_UI_MAP()

	BEGIN_MSG_MAP(CMainFrame)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
		COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
		COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
		//COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
		COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
		//COMMAND_ID_HANDLER(ID_VIEW_TREEPANE, OnViewTreePane)
		//COMMAND_ID_HANDLER(ID_PANE_CLOSE, OnTreePaneClose)
		CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
		CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
	END_MSG_MAP()

	// Handler prototypes (uncomment arguments if needed):
	//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)

	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// create command bar window
		//HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
		// attach menu
		//m_CmdBar.AttachMenu(GetMenu());
		// load command bar images
		//m_CmdBar.LoadImages(IDR_MAINFRAME);
		// remove old menu
		//SetMenu(NULL);

		//HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);

		//CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
		//AddSimpleReBarBand(hWndCmdBar);
		//AddSimpleReBarBand(hWndToolBar, NULL, TRUE);

		CreateSimpleStatusBar();

		m_hWndClient = m_splitter.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

		//m_pane.SetPaneContainerExtendedStyle(PANECNT_NOBORDER);
		m_pane.Create(m_splitter, _T("tree"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);

		m_treeview.Create(m_pane, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS,
			WS_EX_CLIENTEDGE);
		m_treeview.SetFont(AtlGetDefaultGuiFont());
		m_pane.SetClient(m_treeview);

		m_view.Create(m_splitter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);

		m_splitter.SetSplitterPanes(m_pane, m_view);
		UpdateLayout();
		m_splitter.SetSplitterPosPct(25);

		//UIAddToolBar(hWndToolBar);
		UISetCheck(ID_VIEW_TOOLBAR, 1);
		UISetCheck(ID_VIEW_STATUS_BAR, 1);

		// register object for message filtering and idle updates
		CMessageLoop* pLoop = _AtlModule.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->AddMessageFilter(this);
		pLoop->AddIdleHandler(this);

		return 0;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		// unregister message filtering and idle updates
		CMessageLoop* pLoop = _AtlModule.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->RemoveMessageFilter(this);
		pLoop->RemoveIdleHandler(this);

		bHandled = FALSE;
		return 1;
	}

	LRESULT OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		PostMessage(WM_CLOSE);
		return 0;
	}

	LRESULT OnFileNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		// TODO: add code to initialize document

		return 0;
	}

	LRESULT OnViewToolBar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		static BOOL bVisible = TRUE;	// initially visible
		bVisible = !bVisible;
		CReBarCtrl rebar = m_hWndToolBar;
		int nBandIndex = rebar.IdToIndex(ATL_IDW_BAND_FIRST + 1);	// toolbar is 2nd added band
		rebar.ShowBand(nBandIndex, bVisible);
		UISetCheck(ID_VIEW_TOOLBAR, bVisible);
		UpdateLayout();
		return 0;
	}

	//LRESULT OnViewStatusBar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	//{
	//	BOOL bVisible = !::IsWindowVisible(m_hWndStatusBar);
	//	::ShowWindow(m_hWndStatusBar, bVisible ? SW_SHOWNOACTIVATE : SW_HIDE);
	//	UISetCheck(ID_VIEW_STATUS_BAR, bVisible);
	//	UpdateLayout();
	//	return 0;
	//}

	LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CAboutDlg dlg;
		dlg.DoModal();
		return 0;
	}

// 	LRESULT OnViewTreePane(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// 	{
// 		bool bShow = (m_splitter.GetSinglePaneMode() != SPLIT_PANE_NONE);
// 		m_splitter.SetSinglePaneMode(bShow ? SPLIT_PANE_NONE : SPLIT_PANE_RIGHT);
// 		UISetCheck(ID_VIEW_TREEPANE, bShow);
// 
// 		return 0;
// 	}

	//LRESULT OnTreePaneClose(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndCtl, BOOL& /*bHandled*/)
	//{
	//	if(hWndCtl == m_pane.m_hWnd)
	//	{
	//		m_splitter.SetSinglePaneMode(SPLIT_PANE_RIGHT);
	//		UISetCheck(ID_VIEW_TREEPANE, 0);
	//	}

	//	return 0;
	//}
};

5.新建atl简单对象Simple,添加方法Hello

// Simple.h : CSimple 的声明

#pragma once
#include "resource.h"       // 主符号

#include "test0507.h"

class CMainFrame;
// CSimple

class ATL_NO_VTABLE CSimple : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CSimple, &CLSID_Simple>,
	public IDispatchImpl<ISimple, &IID_ISimple, &LIBID_test0507Lib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
	CSimple()
	{
	}

DECLARE_REGISTRY_RESOURCEID(IDR_SIMPLE)


BEGIN_COM_MAP(CSimple)
	COM_INTERFACE_ENTRY(ISimple)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}
	
	void FinalRelease() 
	{
	}

public:

	STDMETHOD(Hello)(void);
	CMessageLoop m_MsgLoop;
	CMainFrame* wndMain;
};

OBJECT_ENTRY_AUTO(__uuidof(Simple), CSimple)

// Simple.cpp : CSimple 的实现

#include "stdafx.h"
#include "Simple.h"
#include "test05062view.h"
#include "MainFrm.h"
#include ".\simple.h"

// CSimple

void runloop(void* p)
{
	CMessageLoop* theLoop = (CMessageLoop*)p;
	theLoop->Run();
}

STDMETHODIMP CSimple::Hello(void)
{
	// TODO: 在此添加实现代码
	::MessageBox(NULL, "JHEL;", "ASDF", MB_OK);
	
	_AtlModule.AddMessageLoop(&m_MsgLoop);

	wndMain = new CMainFrame;
	if(wndMain->CreateEx() == NULL)
	{
		ATLTRACE(_T("Main window creation failed!\n"));
		return 0;
	}

	wndMain->ShowWindow(SW_SHOW);

	DWORD nThread = _beginthread(runloop, 0, (void*)&m_MsgLoop);

	return S_OK;
}

6.新建一个mfc对话框exe,调用Hello()

stdafx.h

#import "..\test0507/Debug/test0507.dll" no_namespace

对话框头文件

ISimplePtr m_p;

对话框实现文件

void Ctest05073Dlg::OnBnClickedOk()
{
    // TODO: 在此添加控件通知处理程序代码
    
    m_p.CreateInstance(__uuidof(Simple));
    m_p->Hello();
    //OnOK();
}

上面主要追求wtl cframe的弹出,故对new CMainFrame没有处理

源码下载:http://download.csdn.net/detail/dragoo1/5341336

抱歉!评论已关闭.