环境 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
// 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; //} };
// 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