用ATL 创建(Activex) 窗口

本文将不用MFC创建个Activex控件.

 

第一步:

     打开VC6.0,选择ATL COM AppWizard 创建一个工程,如下图:

 1

 

点确定,选择动态连接库点完成,如下图:

 

2

 

第二步:

     新建一个 ATL Object,选择Full Control,点Next.在Miscellaneous里把Windowed Only选上.如图:

3

4

选择确定.

 

第三步:

    新建一类取名为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控件就出来了,不过现在还控件上还什么都没.但它可以相应一些事件了.如何在上面加按钮呢,等以后现讲.

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值