环境 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