1、简介
ActiveX 控件是允许网站提供视频和游戏等内容的小应用。 浏览 Web 时,你也可以使用这些小应用与工具栏和股票代码等内容进行交互。 但是,这些应用有时可能出现问题,或者向你提供不需要的内容。 在某些情况下,这些应用可以用来从你的电脑收集信息、破坏电脑上的信息、在未获得你同意的情况下在你的电脑上安装软件或允许其他人远程控制你的电脑。
2、代码编写
打开VS2017,新建一个MFC ActiveX控件工程,如下图所示:
- (1)FxActiveXMfcGLFont.idl, 在里面定义接口和事件。
#include <olectl.h>
#include <idispids.h>
[ uuid(14E52866-4696-4AE1-B160-D87C2158871E), version(1.0),
helpfile("FxMfcGLFont.hlp"),
helpstring("FxMfcGLFont Control"),
control ]
library FxActiveX_MfcGLFontLib
{
importlib(STDOLE_TLB);
[ uuid(943FC7F4-152F-4FC9-AD11-C05AD35720A1),
helpstring("FxMfcGLFont 控件的调度接口")]
dispinterface _DFxActiveX_MfcGLFont
{
properties:
[id(DISPID_READYSTATE), readonly] long ReadyState;
[id(DISPID_BACKCOLOR), bindable, requestedit] OLE_COLOR BackColor;
[id(0)] OLE_COLOR _BackColor;
[id(1)] BSTR Content;
[id(2)] long Interval;
[id(3)] double SeeAngle;
[id(4)] double SeeNearest;
[id(5)] double SeeFarthest;
[id(6)] boolean WireVisible;
[id(7)] OLE_COLOR FogColor;
[id(8)] float FogDensity;
[id(9)] boolean LightEnable;
[id(10)] double CamPosX;
[id(11)] double CamPosY;
[id(12)] double CamPosZ;
[id(13)] double CamAxz;
[id(14)] double CamAzy;
methods:
[id(DISPID_ABOUTBOX)] void AboutBox();
[id(15)] OLE_HANDLE GetHandleActiveWindow();
[id(16)] void GLRender();
[id(17)] void SetText(BSTR strText);
[id(18)] void SetType(short type);
[id(19)] void StopPlayMidi();
[id(20)] void PlayMidiFile(BSTR filename);
[id(DISPID_REFRESH)] void Refresh();
};
[ uuid(55074D60-EA2A-41BE-91CC-201E278C3B52),
helpstring("FxMfcGLFont 控件的事件接口") ]
dispinterface _DFxActiveX_MfcGLFontEvents
{
properties:
methods:
[id(DISPID_READYSTATECHANGE)] void ReadyStateChange();
[id(DISPID_MOUSEDOWN)] void MouseDown(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
[id(DISPID_MOUSEUP)] void MouseUp(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
[id(DISPID_MOUSEMOVE)] void MouseMove(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
[id(DISPID_KEYDOWN)] void KeyDown(short* KeyCode, short Shift);
[id(DISPID_KEYUP)] void KeyUp(short* KeyCode, short Shift);
[id(DISPID_DBLCLICK)] void DblClick();
[id(1)] void GLDraw();
[id(2)] void Timer();
[id(3)] void EndPlayMidi();
[id(4)] void VcKeyDown(long KeyCode, short flags);
[id(5)] void VcKeyUp(long KeyCode, short flags);
[id(6)] void LeftButtonDown(long x, long y, boolean control, boolean shift);
[id(7)] void RightButtonDown(long x, long y, boolean control, boolean shift);
};
[ uuid(9EF03850-F171-4DB2-BCC6-243AF84EEAF9),
helpstring("FxMfcGLFont Control"), control ]
coclass FxActiveX_MfcGLFont
{
[default] dispinterface _DFxActiveX_MfcGLFont;
[default, source] dispinterface _DFxActiveX_MfcGLFontEvents;
};
};
- (2)FxActiveXMfcGLFontCtrl.cpp,在里面编写控件的具体实现。其主要代码如下所示:
#include "stdafx.h"
#include "FxActiveX_MfcGLFont.h"
#include "FxMfcGLFontCtrl.h"
#include "FxActiveX_MfcGLFontPropPage.h"
#include <Mmsystem.h>
#include "PlayMidi.h"
#include "app.h"
#include "./GLScene.h"
#include "./GLTest_BaseFactory.h"
#include "./GLTest_Base.h"
extern CFxActiveX_MfcGLFontApp theApp;
#define TIMER_ID1 1000
#define WM_MENU_START (WM_USER + 100)
#define WM_MENU_END (WM_MENU_START + 100)
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CFxMfcGLFontCtrl, COleControl)
BEGIN_MESSAGE_MAP(CFxMfcGLFontCtrl, COleControl)
ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit)
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_LBUTTONDBLCLK()
ON_WM_QUERYNEWPALETTE()
ON_WM_PALETTECHANGED()
ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
ON_MESSAGE(MM_MCINOTIFY, OnMciNotify)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_SIZE()
ON_WM_DROPFILES()
ON_WM_CONTEXTMENU()
ON_UPDATE_COMMAND_UI_RANGE(WM_MENU_START, WM_MENU_END, OnUpdateMenuRanges)
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CFxMfcGLFontCtrl, COleControl)
DISP_PROPERTY_EX(CFxMfcGLFontCtrl, "Content", GetContent, SetContent, VT_BSTR)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "Interval", m_interval, OnIntervalChanged, VT_I4)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "SeeAngle", m_seeAngle, OnSeeAngleChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "SeeNearest", m_seeNearest, OnSeeNearestChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "SeeFarthest", m_seeFarthest, OnSeeFarthestChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "WireVisible", m_wireVisible, OnWireVisibleChanged, VT_BOOL)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "FogColor", m_fogColor, OnFogColorChanged, VT_COLOR)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "FogDensity", m_fogDensity, OnFogDensityChanged, VT_R4)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "LightEnable", m_lightEnable, OnLightEnableChanged, VT_BOOL)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "CamPosX", m_camPosX, OnCamPosXChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "CamPosY", m_camPosY, OnCamPosYChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "CamPosZ", m_camPosZ, OnCamPosZChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "CamAxz", m_camAxz, OnCamAxzChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CFxMfcGLFontCtrl, "CamAzy", m_camAzy, OnCamAzyChanged, VT_R8)
DISP_FUNCTION(CFxMfcGLFontCtrl, "GetHandleActiveWindow", GetHandleActiveWindow, VT_HANDLE, VTS_NONE)
DISP_FUNCTION(CFxMfcGLFontCtrl, "GLRender", GLRender, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CFxMfcGLFontCtrl, "SetText", SetContent, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CFxMfcGLFontCtrl, "SetType", SetType, VT_EMPTY, VTS_I2)
DISP_FUNCTION(CFxMfcGLFontCtrl, "StopPlayMidi", StopPlayMidi, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CFxMfcGLFontCtrl, "PlayMidiFile", PlayMidiFile, VT_EMPTY, VTS_BSTR)
DISP_DEFVALUE(CFxMfcGLFontCtrl, "BackColor")
DISP_STOCKPROP_BACKCOLOR()
DISP_STOCKPROP_READYSTATE()
DISP_FUNCTION_ID(CFxMfcGLFontCtrl, "Refresh", DISPID_REFRESH, Refresh, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CFxMfcGLFontCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
BEGIN_EVENT_MAP(CFxMfcGLFontCtrl, COleControl)
EVENT_STOCK_READYSTATECHANGE()
EVENT_STOCK_KEYDOWN()
EVENT_STOCK_KEYUP()
EVENT_STOCK_DBLCLICK()
EVENT_CUSTOM("GLDraw", FireGLDraw, VTS_NONE)
EVENT_CUSTOM("Timer", FireTimer, VTS_NONE)
EVENT_CUSTOM("EndPlayMidi", FireEndPlayMidi, VTS_NONE)
EVENT_CUSTOM("VcKeyDown", FireVcKeyDown, VTS_I4 VTS_I2)
EVENT_CUSTOM("VcKeyUp", FireVcKeyUp, VTS_I4 VTS_I2)
EVENT_CUSTOM("LeftButtonDown", FireLeftButtonDown, VTS_I4 VTS_I4 VTS_BOOL VTS_BOOL)
EVENT_CUSTOM("RightButtonDown", FireRightButtonDown, VTS_I4 VTS_I4 VTS_BOOL VTS_BOOL)
END_EVENT_MAP()
BEGIN_PROPPAGEIDS(CFxMfcGLFontCtrl, 1)
PROPPAGEID(CFxActiveX_MfcGLFontPropPage::guid)
END_PROPPAGEIDS(CFxMfcGLFontCtrl)
IMPLEMENT_OLECREATE_EX(CFxMfcGLFontCtrl, "FxFishSoft.FxMfcGLFontCtrl.1",
0x9ef03850, 0xf171, 0x4db2, 0xbc, 0xc6, 0x24, 0x3a, 0xf8, 0x4e, 0xea, 0xf9)
IMPLEMENT_OLETYPELIB(CFxMfcGLFontCtrl, _tlid, _wVerMajor, _wVerMinor)
const IID BASED_CODE IID_DFxActiveX_MfcGLFont =
{ 0x943FC7F4, 0x152F, 0x4FC9, { 0xAD, 0x11, 0xC0, 0x5A, 0xD3, 0x57, 0x20, 0xA1 } };
const IID BASED_CODE IID_DFxActiveX_MfcGLFontEvents =
{ 0x55074D60, 0xEA2A, 0x41BE, { 0x91, 0xCC, 0x20, 0x1E, 0x27, 0x8C, 0x3B, 0x52 } };
static const DWORD BASED_CODE _dwFxActiveX_MfcGLFontOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;
IMPLEMENT_OLECTLTYPE(CFxMfcGLFontCtrl, IDS_FXACTIVEX_MFCGLFONT, _dwFxActiveX_MfcGLFontOleMisc)
BOOL CFxMfcGLFontCtrl::CFxMfcGLFontCtrlFactory::UpdateRegistry(BOOL bRegister)
{
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_FXACTIVEX_MFCGLFONT,
IDB_FXACTIVEX_MFCGLFONT,
afxRegInsertable | afxRegApartmentThreading,
_dwFxActiveX_MfcGLFontOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}
CFxMfcGLFontCtrl::CFxMfcGLFontCtrl()
: CGLScene()
{
InitializeIIDs(&IID_DFxActiveX_MfcGLFont, &IID_DFxActiveX_MfcGLFontEvents);
m_lReadyState = READYSTATE_LOADING;
m_String = "Hello Fish!";
SetInitialSize(800, 290);
}
CFxMfcGLFontCtrl::~CFxMfcGLFontCtrl()
{
}
void CFxMfcGLFontCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (!pdc)
return;
DoSuperclassPaint(pdc, rcBounds);
}
void CFxMfcGLFontCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
long nInterval = m_interval;
PX_Long(pPX,"Interval",m_interval, 0);
PX_Double(pPX,"SeeAngle", m_seeAngle, 45.0);
PX_Double(pPX,"SeeNearest", m_seeNearest, 0.1f);
PX_Double(pPX,"SeeFarthest", m_seeFarthest, 100.0);
PX_Bool(pPX,"WireVisible", m_wireVisible, TRUE);
PX_Color(pPX,"FogColor", m_fogColor,0x00808080);
PX_Float(pPX,"FogDensity", m_fogDensity, 0);
PX_Bool(pPX,"LightEnable", m_lightEnable, FALSE);
PX_Color(pPX,"BackColor", m_clrBackColor, 0x00808080);
PX_Double(pPX,"CamPosX", m_camPosX,0.0);
PX_Double(pPX,"CamPosY", m_camPosY,0.0);
PX_Double(pPX,"CamPosZ", m_camPosZ,-8.0);
PX_Double(pPX,"CamAxz", m_camAxz,3.1415/2);
PX_Double(pPX,"CamAzy", m_camAzy,0.0);
if (pPX->GetVersion() == (DWORD)MAKELONG(_wVerMinor, _wVerMajor)){
}
else if (pPX->IsLoading()) {
CFontHolder& stockFont = InternalGetFont();
stockFont.InitializeFont();
if (nInterval != m_interval)
OnIntervalChanged();
}
}
void CFxMfcGLFontCtrl::OnResetState()
{
COleControl::OnResetState();
}
void CFxMfcGLFontCtrl::AboutBox()
{
extern void DoAboutBox(HINSTANCE hInst, HWND hWnd);
extern App* pApp;
DoAboutBox(pApp->GetInstance(), m_hWnd);
}
DWORD CFxMfcGLFontCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();
dwFlags |= noFlickerActivate;
dwFlags |= pointerInactive;
return dwFlags;
}
int CFxMfcGLFontCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
lpCreateStruct->style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_OWNDC);
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
m_pDC = new CClientDC(this);
HDC hdc = m_pDC->GetSafeHdc();
RECT rt;
GetClientRect(&rt);
CGLScene::Init(theApp.m_hInstance, hdc, m_hWnd, rt);
SetType(0);
Refresh();
DragAcceptFiles();
SetFocus();
m_interval = 5;
if (m_interval != 0) SetTimer(TIMER_ID1,m_interval,NULL);
return 0;
}
void CFxMfcGLFontCtrl::OnDestroy()
{
COleControl::OnDestroy();
KillTimer(TIMER_ID1);
m_Palette.DeleteObject();
ReleaseDC(m_pDC);
if (m_pDC) delete m_pDC;
m_pDC = NULL;
DeleteGLTest();
}
void CFxMfcGLFontCtrl::OnTimer(UINT nIDEvent)
{
if(nIDEvent==TIMER_ID1)
{
RedrawWindow();
}
MSG msg;
while(::PeekMessage(&msg, m_hWnd, WM_TIMER, WM_TIMER, PM_REMOVE));
COleControl::OnTimer(nIDEvent);
}
void CFxMfcGLFontCtrl::OnPaint()
{
CPaintDC dc(this);
GLRender();
}
void CFxMfcGLFontCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
Refresh();
COleControl::OnLButtonDblClk(nFlags, point);
}
BOOL CFxMfcGLFontCtrl::OnQueryNewPalette()
{
Refresh();
return COleControl::OnQueryNewPalette();
}
void CFxMfcGLFontCtrl::OnPaletteChanged(CWnd* pFocusWnd)
{
COleControl::OnPaletteChanged(pFocusWnd);
Refresh();
}
BSTR CFxMfcGLFontCtrl::GetContent()
{
CString strResult = GetGLTest()->getTitle();
return strResult.AllocSysString();
}
void CFxMfcGLFontCtrl::SetContent(LPCTSTR lpszNewValue)
{
if(GetGLTest()) GetGLTest()->setTitle(lpszNewValue);
Refresh();
}
void CFxMfcGLFontCtrl::OnIntervalChanged()
{
KillTimer(TIMER_ID1);
if (m_interval) SetTimer(TIMER_ID1,m_interval,NULL);
SetModifiedFlag();
}
OLE_HANDLE CFxMfcGLFontCtrl::GetHandleActiveWindow()
{
CWnd *w=GetActiveWindow();
if(w==NULL) return NULL;
return (OLE_HANDLE)w->m_hWnd;
}
void CFxMfcGLFontCtrl::Refresh()
{
RedrawWindow();
}
void CFxMfcGLFontCtrl::PlayMidiFile(LPCTSTR filename)
{
PlayMusic(m_hWnd,filename);
}
void CFxMfcGLFontCtrl::StopPlayMidi()
{
CloseMusic();
}
LRESULT CFxMfcGLFontCtrl::OnMciNotify(WPARAM w,LPARAM l)
{
if (w == MCI_NOTIFY_SUCCESSFUL) FireEndPlayMidi();
return 0;
}
LRESULT CFxMfcGLFontCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
{
#ifdef _WIN32
WORD wNotifyCode = HIWORD(wParam);
#else
WORD wNotifyCode = HIWORD(lParam);
#endif
return 0;
}
BOOL CFxMfcGLFontCtrl::IsSubclassedControl()
{
return TRUE;
}
LRESULT CFxMfcGLFontCtrl::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
LRESULT ret = CGLScene::WindowProc(message, wParam, lParam);
return COleControl::WindowProc(message, wParam, lParam);
}
BOOL CFxMfcGLFontCtrl::PreTranslateMessage(MSG* pMsg)
{
switch (pMsg->message)
{
case WM_KEYDOWN:
if ((pMsg->lParam&0x40000000)==0) {
UINT nChar = pMsg->wParam;
FireVcKeyDown(nChar, 0);
if (nChar == VK_ESCAPE
|| nChar == VK_TAB
|| nChar == VK_DELETE )
{
GetGLTest()->onKeyDown(pMsg->wParam);
return TRUE;
}
}
break;
case WM_KEYUP:
{
FireVcKeyUp(pMsg->wParam,0);
UINT nChar = pMsg->wParam;
if (nChar == VK_ESCAPE
|| nChar == VK_TAB
|| nChar == VK_DELETE )
{
GetGLTest()->onKeyUp(pMsg->wParam);
return TRUE;
}
}
break;
case WM_SYSKEYDOWN:
if(pMsg->wParam == VK_MENU) {
GetGLTest()->onKeyDown(VK_MENU);
return TRUE;
}
break;
case WM_SYSKEYUP:
if(pMsg->wParam == VK_MENU) {
GetGLTest()->onKeyUp(VK_MENU);
return TRUE;
}
break;
}
return COleControl::PreTranslateMessage(pMsg);
}
void CFxMfcGLFontCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
COleControl::OnLButtonDown(nFlags, point);
}
void CFxMfcGLFontCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
COleControl::OnRButtonDown(nFlags, point);
}
void CFxMfcGLFontCtrl::OnSize(UINT nType, int cx, int cy)
{
COleControl::OnSize(nType, cx, cy);
m_width = cx;
m_height = cy;
if (GetGLTest()) {
GetGLTest()->onResize(cx, cy);
}
}
void CFxMfcGLFontCtrl::GLRender()
{
DWORD tickCount = GetTickCount ();
Update (tickCount - _window.lastTickCount);
_window.lastTickCount = tickCount;
if (GetGLTest() && GetGLTest()->isRendering()) {
GetGLTest()->onBeforeRender();
GetGLTest()->onRender();
GetGLTest()->onIdle();
GetGLTest()->onAfterRender();
}
}
void CFxMfcGLFontCtrl::RefreshSize()
{
if (GetGLTest()) {
GetGLTest()->onResize();
_ArcBall.setBounds((GLfloat)m_width, (GLfloat)m_height);
}
}
void CFxMfcGLFontCtrl::OnBackColorChanged()
{
GetGLTest()->setBackColor(TranslateColor(GetBackColor()));
COleControl::OnBackColorChanged();
}
void CFxMfcGLFontCtrl::OnSeeAngleChanged()
{
RefreshSize();
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnSeeNearestChanged()
{
RefreshSize();
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnSeeFarthestChanged()
{
RefreshSize();
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnWireVisibleChanged()
{
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnFogColorChanged()
{
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnFogDensityChanged()
{
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnLightEnableChanged()
{
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnCamPosXChanged()
{
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnCamPosYChanged()
{
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnCamPosZChanged()
{
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnCamAxzChanged()
{
UpdateCamDir();
SetModifiedFlag();
}
void CFxMfcGLFontCtrl::OnCamAzyChanged()
{
UpdateCamDir();
SetModifiedFlag();
}
double CFxMfcGLFontCtrl::GetCamDirX()
{
return m_camDirX;
}
double CFxMfcGLFontCtrl::GetCamDirY()
{
return m_camDirY;
return 0.0;
}
double CFxMfcGLFontCtrl::GetCamDirZ()
{
return m_camDirZ;
return 0.0;
}
void CFxMfcGLFontCtrl::SetType( short type )
{
RECT rt;
GetClientRect(&rt);
CGLScene::SetGLType(type);
}
void CFxMfcGLFontCtrl::OnDropFiles(HDROP hDropInfo)
{
if ( ::GetActiveWindow() == NULL ) {
::SetActiveWindow(m_hWnd);
}
char path[MAX_PATH];
int count = DragQueryFile(hDropInfo, -1, NULL, 0);
if (count > 0) {
DragQueryFile(hDropInfo, 0, path, sizeof(path));
if (GetGLTest()) {
GetGLTest()->onDropFiles(path);
}
}
__super::OnDropFiles(hDropInfo);
}
void CFxMfcGLFontCtrl::OnContextMenu(CWnd* , CPoint point)
{
UINT idStart = WM_MENU_START;
if (GetGLTest()) {
std::string text;
int n = GetGLTest()->getMenuCount();
if(n == 0) return;
CMenu menu;
menu.CreatePopupMenu();
menu.AppendMenu(MF_STRING , WM_MENU_END, _T("关于"));
menu.AppendMenu(MF_SEPARATOR);
for (int i = 0; i <n ;i++) {
GetGLTest()->getMenuText(i, text);
if (!text.compare("-") || text.empty()) {
menu.AppendMenu(MF_SEPARATOR);
}
else {
menu.AppendMenu(MF_STRING , idStart+i, text.c_str());
}
}
menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
}
}
void CFxMfcGLFontCtrl::OnUpdateMenuRanges(CCmdUI* pCmdUI)
{
pCmdUI->Enable();
}
BOOL CFxMfcGLFontCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
{
if (wParam == WM_MENU_START + 100) {
AboutBox();
}
else if (GetGLTest()) {
GetGLTest()->onMenu(wParam - WM_MENU_START);
}
return __super::OnCommand(wParam, lParam);
}
3、注册控件
使用管理员权限打开命令行界面,通过如下的命令注册上面的控件。
regsvr32 FxActiveX_MfcGLFont.ocx
4、结果运行
新建一个C#工程加载上面的控件,如下图所示:
- 天空盒
- 法线贴图
- 阴影效果
- 骨骼动画
- 文字打印
- 3ds动画文件格式加载
- 水面效果
- 第三方界面集成
后记
如果你觉得该方法或代码有一点点用处,可以给作者点个赞、赏杯咖啡;╮( ̄▽ ̄)╭ 如果你感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进。o_O??? 谢谢各位童鞋们啦( ′ ▽′ )ノ ( ′ ▽′)っ!!!
|