您的位置:首页 > 其它

用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控件就出来了,不过现在还控件上还什么都没.但它可以相应一些事件了.如何在上面加按钮呢,等以后现讲.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: