用ATL 创建(Activex) 窗口
2009-09-04 21:12
344 查看
本文将不用MFC创建个Activex控件.
第一步:
打开VC6.0,选择ATL COM AppWizard 创建一个工程,如下图:
点确定,选择动态连接库点完成,如下图:
第二步:
新建一个 ATL Object,选择Full Control,点Next.在Miscellaneous里把Windowed Only选上.如图:
选择确定.
第三步:
新建一类取名为CMyPanel. 类定义如下:
//MyPanel.h如下
#if !defined(AFX_MYPANEL_H__F9E3C4AB_689E_4FE7_B479_D66493B070D5__INCLUDED_)
#define AFX_MYPANEL_H__F9E3C4AB_689E_4FE7_B479_D66493B070D5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
LRESULT CALLBACK MyWinProc(HWND handle,UINT nMsg,WPARAM wParam,LPARAM lParam);
class CMyPanel;
class CMyModul
{
public:
CMyModul();
virtual ~CMyModul();
inline CMyPanel *GetPanel(){return m_pMyPl;}
void SetPanel(CMyPanel *pl);
private:
CMyPanel *m_pMyPl;
};
class CMyPanel
{
public:
CMyPanel(HWND hWnd,int x,int y,int nWidth,int nHeight);
virtual ~CMyPanel();
inline HWND GetHWND(){return m_MyhWnd;}
void ChangeSize(RECT rect);
void Paint(HWND hWnd);
void PaintGradiantRect(HDC &hdc,const RECT &rect) const;
LRESULT CALLBACK WinProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam);
private:
HWND m_MyhWnd;
RECT m_rcBound;
};
#endif
//MyPanel.cpp如下:
#include "stdafx.h"
#include "MyPanel.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyModul *pModul = NULL;
LRESULT CALLBACK MyWinProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
if(pModul && pModul->GetPanel())
{
return pModul->GetPanel()->WinProc(hWnd,nMsg,wParam,lParam);
}
else
{
return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
}
CMyModul::CMyModul()
{
WNDCLASS wc;
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MyWinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = ::GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = ::LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW));
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = __T("MyATLWnd");
RegisterClass(&wc);
}
CMyModul::~CMyModul()
{
}
void CMyModul::SetPanel(CMyPanel *pl)
{
m_pMyPl = pl;
}
CMyPanel::CMyPanel(HWND hWnd,int x,int y,int nWidth,int nHeight)
{
if(!pModul)
{
pModul = new CMyModul();
}
pModul->SetPanel(this);
m_MyhWnd = CreateWindow(TEXT("MyATLWnd"),
TEXT("MyATLWnd"),
WS_CHILD | WS_VISIBLE,
x,y,nWidth,nHeight,
hWnd,
NULL,
::GetModuleHandle(NULL),
NULL);
if(!m_MyhWnd)
{
int ret = GetLastError();
}
::SetRect(&m_rcBound,x,y,x+nWidth,y+nHeight);
}
CMyPanel::~CMyPanel()
{
::DestroyWindow(m_MyhWnd);
if(pModul)
{
delete pModul;
pModul = NULL;
}
}
void CMyPanel::ChangeSize(RECT rect)
{
::SetRect( &m_rcBound,rect.left,rect.top,rect.right,rect.bottom);
::MoveWindow(m_MyhWnd,rect.left,rect.top,
rect.right-rect.left,rect.bottom-rect.top,TRUE);
}
void CMyPanel::Paint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
hdc = BeginPaint( hWnd, &ps );
GetClientRect( hWnd, &rect );
PaintGradiantRect(hdc,rect);
EndPaint( hWnd, &ps );
}
void CMyPanel::PaintGradiantRect(HDC &hdc,const RECT &rect) const
{
RECT rectVar ={rect.left,rect.top,rect.right,rect.top};
int nTotalSize = rect.bottom-rect.top;
for(int nIndex =0; nIndex < 230;nIndex++)
{
rectVar.top = rectVar.bottom;
rectVar.bottom = rect.top + ::MulDiv(nIndex+1,nTotalSize,230);
int nColor = ::MulDiv(nIndex,255,230);
nColor = 255 - nColor;
COLORREF clrRf =
PALETTERGB((BYTE)0,(BYTE)0,(BYTE)nColor);
HBRUSH brush = CreateSolidBrush(clrRf);
FillRect(hdc,&rectVar,brush);
}
}
HRESULT CALLBACK CMyPanel::WinProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
switch(nMsg)
{
case WM_PAINT:
Paint(hWnd);
break;
case WM_LBUTTONDBLCLK:
//DBClick;
break;
default:
return DefWindowProc(hWnd,nMsg,wParam,lParam);
break;
}
return 0;
}
第四步:
在CWndCtl类中新增个成员变量:CMyPanel *m_pMyPl;然后找到宏定义BEGIN_MSG_MAP(CWndCtl),END_MSG_MAP()在这之间加入MESSAGE_HANDLER(WM_CREATE, OnCreate) 如下:
BEGIN_MSG_MAP(CWndCtl)
//...
MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()
增加函数:OnCreate
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO : Add Code for message handler. Call DefWindowProc if necessary.
RECT rect;
::GetClientRect(m_hWnd,&rect);
m_pMyPl = new CMyPanel(m_hWnd,rect.left,
rect.top,rect.right-rect.left,rect.bottom-rect.top);
::ShowWindow(m_pMyPl->GetHWND(),TRUE);
return 0;
}
改写OnDraw
HRESULT OnDraw(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)di.prcBounds;
if(m_pMyPl)
{
m_pMyPl->ChangeSize(rc);
}
return S_OK;
}
第五步:
在程序退出的地方,加上:
if(m_pMyPl)
{
delete m_pMyPl;
m_pMyPl = NULL;
}
好了,调试看看,一个Activex控件就出来了,不过现在还控件上还什么都没.但它可以相应一些事件了.如何在上面加按钮呢,等以后现讲.
第一步:
打开VC6.0,选择ATL COM AppWizard 创建一个工程,如下图:
点确定,选择动态连接库点完成,如下图:
第二步:
新建一个 ATL Object,选择Full Control,点Next.在Miscellaneous里把Windowed Only选上.如图:
选择确定.
第三步:
新建一类取名为CMyPanel. 类定义如下:
//MyPanel.h如下
#if !defined(AFX_MYPANEL_H__F9E3C4AB_689E_4FE7_B479_D66493B070D5__INCLUDED_)
#define AFX_MYPANEL_H__F9E3C4AB_689E_4FE7_B479_D66493B070D5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
LRESULT CALLBACK MyWinProc(HWND handle,UINT nMsg,WPARAM wParam,LPARAM lParam);
class CMyPanel;
class CMyModul
{
public:
CMyModul();
virtual ~CMyModul();
inline CMyPanel *GetPanel(){return m_pMyPl;}
void SetPanel(CMyPanel *pl);
private:
CMyPanel *m_pMyPl;
};
class CMyPanel
{
public:
CMyPanel(HWND hWnd,int x,int y,int nWidth,int nHeight);
virtual ~CMyPanel();
inline HWND GetHWND(){return m_MyhWnd;}
void ChangeSize(RECT rect);
void Paint(HWND hWnd);
void PaintGradiantRect(HDC &hdc,const RECT &rect) const;
LRESULT CALLBACK WinProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam);
private:
HWND m_MyhWnd;
RECT m_rcBound;
};
#endif
//MyPanel.cpp如下:
#include "stdafx.h"
#include "MyPanel.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyModul *pModul = NULL;
LRESULT CALLBACK MyWinProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
if(pModul && pModul->GetPanel())
{
return pModul->GetPanel()->WinProc(hWnd,nMsg,wParam,lParam);
}
else
{
return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
}
CMyModul::CMyModul()
{
WNDCLASS wc;
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MyWinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = ::GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = ::LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW));
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = __T("MyATLWnd");
RegisterClass(&wc);
}
CMyModul::~CMyModul()
{
}
void CMyModul::SetPanel(CMyPanel *pl)
{
m_pMyPl = pl;
}
CMyPanel::CMyPanel(HWND hWnd,int x,int y,int nWidth,int nHeight)
{
if(!pModul)
{
pModul = new CMyModul();
}
pModul->SetPanel(this);
m_MyhWnd = CreateWindow(TEXT("MyATLWnd"),
TEXT("MyATLWnd"),
WS_CHILD | WS_VISIBLE,
x,y,nWidth,nHeight,
hWnd,
NULL,
::GetModuleHandle(NULL),
NULL);
if(!m_MyhWnd)
{
int ret = GetLastError();
}
::SetRect(&m_rcBound,x,y,x+nWidth,y+nHeight);
}
CMyPanel::~CMyPanel()
{
::DestroyWindow(m_MyhWnd);
if(pModul)
{
delete pModul;
pModul = NULL;
}
}
void CMyPanel::ChangeSize(RECT rect)
{
::SetRect( &m_rcBound,rect.left,rect.top,rect.right,rect.bottom);
::MoveWindow(m_MyhWnd,rect.left,rect.top,
rect.right-rect.left,rect.bottom-rect.top,TRUE);
}
void CMyPanel::Paint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
hdc = BeginPaint( hWnd, &ps );
GetClientRect( hWnd, &rect );
PaintGradiantRect(hdc,rect);
EndPaint( hWnd, &ps );
}
void CMyPanel::PaintGradiantRect(HDC &hdc,const RECT &rect) const
{
RECT rectVar ={rect.left,rect.top,rect.right,rect.top};
int nTotalSize = rect.bottom-rect.top;
for(int nIndex =0; nIndex < 230;nIndex++)
{
rectVar.top = rectVar.bottom;
rectVar.bottom = rect.top + ::MulDiv(nIndex+1,nTotalSize,230);
int nColor = ::MulDiv(nIndex,255,230);
nColor = 255 - nColor;
COLORREF clrRf =
PALETTERGB((BYTE)0,(BYTE)0,(BYTE)nColor);
HBRUSH brush = CreateSolidBrush(clrRf);
FillRect(hdc,&rectVar,brush);
}
}
HRESULT CALLBACK CMyPanel::WinProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
switch(nMsg)
{
case WM_PAINT:
Paint(hWnd);
break;
case WM_LBUTTONDBLCLK:
//DBClick;
break;
default:
return DefWindowProc(hWnd,nMsg,wParam,lParam);
break;
}
return 0;
}
第四步:
在CWndCtl类中新增个成员变量:CMyPanel *m_pMyPl;然后找到宏定义BEGIN_MSG_MAP(CWndCtl),END_MSG_MAP()在这之间加入MESSAGE_HANDLER(WM_CREATE, OnCreate) 如下:
BEGIN_MSG_MAP(CWndCtl)
//...
MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()
增加函数:OnCreate
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO : Add Code for message handler. Call DefWindowProc if necessary.
RECT rect;
::GetClientRect(m_hWnd,&rect);
m_pMyPl = new CMyPanel(m_hWnd,rect.left,
rect.top,rect.right-rect.left,rect.bottom-rect.top);
::ShowWindow(m_pMyPl->GetHWND(),TRUE);
return 0;
}
改写OnDraw
HRESULT OnDraw(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)di.prcBounds;
if(m_pMyPl)
{
m_pMyPl->ChangeSize(rc);
}
return S_OK;
}
第五步:
在程序退出的地方,加上:
if(m_pMyPl)
{
delete m_pMyPl;
m_pMyPl = NULL;
}
好了,调试看看,一个Activex控件就出来了,不过现在还控件上还什么都没.但它可以相应一些事件了.如何在上面加按钮呢,等以后现讲.
相关文章推荐
- 使用ATL创建窗口的步骤
- 把程序嵌入网页之ATL编写ActiveX[标准窗口+接受参数]
- 用ATL和MFC来创建ActiveX
- 利用ATL技术创建ActiveX控件CircleCtl 。简单介绍 VC2003 使用 ATL 开发 ActiveX 控件(转)
- MFC中多文档ActiveX创建子窗口
- 把程序嵌入网页之ATL编写ActiveX[标准窗口+接受参数]
- ATL创建的ActiveX实现JS回调
- 为智能设备创建 ATL 多平台 ActiveX 控件
- 简单介绍 VC2003 使用 ATL 开发 ActiveX 控件
- ActiveX 部件不能创建对象
- 2.创建窗口
- 如何用blend创建自定义窗口
- 最简单的MFC窗口创建_框架
- Android 内核 - 03 创建应用窗口 和 子窗口
- 创建窗口句柄时出错。
- Windows程序编程(2):窗口创建
- 【讨论】vc++窗口的创建过程
- com,ole,atl,activex的区别和联系
- python在windows下创建隐藏窗口子进程的方法
- JavaScript窗口功能指南之创建对话框