www.pudn.com > opengl_activex.zip > GL3dOcxCtl.cpp


// GL3dOcxCtl.cpp : Implementation of the CGL3dOcxCtrl ActiveX Control class. 
 
#include "stdafx.h" 
#include "GL3dOcx.h" 
#include "GL3dOcxCtl.h" 
#include "GL3dOcxPpg.h" 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
IMPLEMENT_DYNCREATE(CGL3dOcxCtrl, COleControl) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Message map 
 
BEGIN_MESSAGE_MAP(CGL3dOcxCtrl, COleControl) 
	//{{AFX_MSG_MAP(CGL3dOcxCtrl) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_PAINT() 
	ON_WM_LBUTTONDBLCLK() 
	ON_WM_PALETTECHANGED() 
	ON_WM_QUERYNEWPALETTE() 
	//}}AFX_MSG_MAP 
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Dispatch map 
 
BEGIN_DISPATCH_MAP(CGL3dOcxCtrl, COleControl) 
	//{{AFX_DISPATCH_MAP(CGL3dOcxCtrl) 
	DISP_PROPERTY_EX(CGL3dOcxCtrl, "Content", GetContent, SetContent, VT_BSTR) 
	DISP_FUNCTION(CGL3dOcxCtrl, "GLRender", GLRender, VT_EMPTY, VTS_NONE) 
	DISP_FUNCTION(CGL3dOcxCtrl, "SetStrText", SetStrText, VT_EMPTY, VTS_BSTR) 
	DISP_STOCKPROP_READYSTATE() 
	//}}AFX_DISPATCH_MAP 
	DISP_FUNCTION_ID(CGL3dOcxCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE) 
END_DISPATCH_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Event map 
 
BEGIN_EVENT_MAP(CGL3dOcxCtrl, COleControl) 
	//{{AFX_EVENT_MAP(CGL3dOcxCtrl) 
	EVENT_CUSTOM("GLDraw", FireGLDraw, VTS_NONE) 
	EVENT_STOCK_READYSTATECHANGE() 
	//}}AFX_EVENT_MAP 
END_EVENT_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Property pages 
 
// TODO: Add more property pages as needed.  Remember to increase the count! 
BEGIN_PROPPAGEIDS(CGL3dOcxCtrl, 1) 
	PROPPAGEID(CGL3dOcxPropPage::guid) 
END_PROPPAGEIDS(CGL3dOcxCtrl) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Initialize class factory and guid 
 
IMPLEMENT_OLECREATE_EX(CGL3dOcxCtrl, "GL3DOCX.GL3dOcxCtrl.1", 
	0xa015e022, 0x7691, 0x11d3, 0x95, 0x5d, 0x84, 0x22, 0xf5, 0xc0, 0, 0) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Type library ID and version 
 
IMPLEMENT_OLETYPELIB(CGL3dOcxCtrl, _tlid, _wVerMajor, _wVerMinor) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Interface IDs 
 
const IID BASED_CODE IID_DGL3dOcx = 
		{ 0xa015e020, 0x7691, 0x11d3, { 0x95, 0x5d, 0x84, 0x22, 0xf5, 0xc0, 0, 0 } }; 
const IID BASED_CODE IID_DGL3dOcxEvents = 
		{ 0xa015e021, 0x7691, 0x11d3, { 0x95, 0x5d, 0x84, 0x22, 0xf5, 0xc0, 0, 0 } }; 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Control type information 
 
static const DWORD BASED_CODE _dwGL3dOcxOleMisc = 
	OLEMISC_ACTIVATEWHENVISIBLE | 
	OLEMISC_IGNOREACTIVATEWHENVISIBLE | 
	OLEMISC_SETCLIENTSITEFIRST | 
	OLEMISC_INSIDEOUT | 
	OLEMISC_CANTLINKINSIDE | 
	OLEMISC_RECOMPOSEONRESIZE; 
 
IMPLEMENT_OLECTLTYPE(CGL3dOcxCtrl, IDS_GL3DOCX, _dwGL3dOcxOleMisc) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::CGL3dOcxCtrlFactory::UpdateRegistry - 
// Adds or removes system registry entries for CGL3dOcxCtrl 
 
BOOL CGL3dOcxCtrl::CGL3dOcxCtrlFactory::UpdateRegistry(BOOL bRegister) 
{ 
	// TODO: Verify that your control follows apartment-model threading rules. 
	// Refer to MFC TechNote 64 for more information. 
	// If your control does not conform to the apartment-model rules, then 
	// you must modify the code below, changing the 6th parameter from 
	// afxRegApartmentThreading to 0. 
 
	if (bRegister) 
		return AfxOleRegisterControlClass( 
			AfxGetInstanceHandle(), 
			m_clsid, 
			m_lpszProgID, 
			IDS_GL3DOCX, 
			IDB_GL3DOCX, 
			afxRegApartmentThreading, 
			_dwGL3dOcxOleMisc, 
			_tlid, 
			_wVerMajor, 
			_wVerMinor); 
	else 
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::CGL3dOcxCtrl - Constructor 
 
CGL3dOcxCtrl::CGL3dOcxCtrl() 
{ 
	InitializeIIDs(&IID_DGL3dOcx, &IID_DGL3dOcxEvents); 
 
	m_lReadyState = READYSTATE_LOADING; 
	// TODO: Call InternalSetReadyState when the readystate changes. 
 
	// TODO: Initialize your control's instance data here. 
    m_String = "3DOCX";  
 
	m_shininess = 10.0f; 
	m_Lightposition[0] = 100.0f; 
	m_Lightposition[1] = 0.0f; 
	m_Lightposition[2] = 0.0f; 
	m_Lightposition[3] = 0.0f; 
	m_Lightspecular[0] = 0.3f; 
	m_Lightspecular[1] = 0.3f; 
	m_Lightspecular[2] = 0.1f; 
	m_Lightspecular[3] = 1.0f; 
	m_Lightdiffuse[0] = 0.1f; 
	m_Lightdiffuse[1] = 0.1f; 
	m_Lightdiffuse[2] = 0.1f; 
	m_Lightdiffuse[3] = 1.0f; 
	m_Lightambient[0] = 0.3f; 
	m_Lightambient[1] = 0.3f; 
	m_Lightambient[2] = 0.3f; 
	m_Lightambient[3] = 1.0f; 
 
	m_cx = 0; 
	m_cy = 0; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::~CGL3dOcxCtrl - Destructor 
 
CGL3dOcxCtrl::~CGL3dOcxCtrl() 
{ 
	// TODO: Cleanup your control's instance data here. 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::OnDraw - Drawing function 
 
void CGL3dOcxCtrl::OnDraw( 
			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) 
{ 
	// TODO: Replace the following code with your own drawing code. 
    FireGLDraw(); 
} 
 
 
void CGL3dOcxCtrl::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	 
	// TODO: Add your message handler code here 
    FireGLDraw(); 
	 
	// Do not call COleControl::OnPaint() for painting messages 
} 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::DoPropExchange - Persistence support 
 
void CGL3dOcxCtrl::DoPropExchange(CPropExchange* pPX) 
{ 
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); 
	COleControl::DoPropExchange(pPX); 
 
	// TODO: Call PX_ functions for each persistent custom property. 
 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::GetControlFlags - 
// Flags to customize MFC's implementation of ActiveX controls. 
// 
// For information on using these flags, please see MFC technical note 
// #nnn, "Optimizing an ActiveX Control". 
DWORD CGL3dOcxCtrl::GetControlFlags() 
{ 
	DWORD dwFlags = COleControl::GetControlFlags(); 
 
 
	// The control will not be redrawn when making the transition 
	// between the active and inactivate state. 
	dwFlags |= noFlickerActivate; 
 
	// The control can receive mouse notifications when inactive. 
	// TODO: if you write handlers for WM_SETCURSOR and WM_MOUSEMOVE, 
	//		avoid using the m_hWnd member variable without first 
	//		checking that its value is non-NULL. 
	dwFlags |= pointerInactive; 
	return dwFlags; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::OnResetState - Reset control to default state 
 
void CGL3dOcxCtrl::OnResetState() 
{ 
	COleControl::OnResetState();  // Resets defaults found in DoPropExchange 
 
	// TODO: Reset any other control state here. 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl::AboutBox - Display an "About" box to the user 
 
void CGL3dOcxCtrl::AboutBox() 
{ 
	CDialog dlgAbout(IDD_ABOUTBOX_GL3DOCX); 
	dlgAbout.DoModal(); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CGL3dOcxCtrl message handlers 
 
void CGL3dOcxCtrl::GLRender()  
{ 
	// TODO: Add your dispatch handler code here 
	int cx, cy; 
	GetControlSize(&cx, &cy); 
	if(m_cx != cx || m_cy != cy) 
	{ 
	   m_cx = cx; 
	   m_cy = cy; 
	   SetViewPort(); 
	} 
 
	dcRender(); 
 
} 
 
int CGL3dOcxCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	lpCreateStruct->style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_OWNDC); 
	 
	if (COleControl::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	SetupEnv(); 
 
    Refresh(); 
 
	return 0; 
} 
 
 
void CGL3dOcxCtrl::OnDestroy()  
{ 
	COleControl::OnDestroy(); 
	 
	// TODO: Add your message handler code here 
	wglDeleteContext(m_hRC); 
    m_Palette.DeleteObject(); 
    ReleaseDC(m_pDC); 
} 
 
 
void CGL3dOcxCtrl::SetupEnv(void) 
{ 
	PIXELFORMATDESCRIPTOR pfd = 
	{ 
		sizeof(PIXELFORMATDESCRIPTOR), 
		1, 
		PFD_DRAW_TO_WINDOW| 
		PFD_SUPPORT_OPENGL| 
		PFD_DOUBLEBUFFER,   
		PFD_TYPE_RGBA, 
		24, 
		0,0,0,0,0,0, 
        0,0,0,0,0,0,0, 
		32, 
		0,0, 
		PFD_MAIN_PLANE, 
		0, 
		0,0,0 
	}; 
 
	//get device context  
	//m_hDC = ::GetDC(this->m_hWnd); 
	m_pDC = GetDC(); 
 
	int pixelFormat = 
		ChoosePixelFormat(m_pDC->m_hDC, &pfd); 
	BOOL success =  
		SetPixelFormat(m_pDC->m_hDC, pixelFormat, &pfd); 
 
	DescribePixelFormat(m_pDC->m_hDC, pixelFormat, 
		  sizeof(pfd), &pfd); 
 
	if(pfd.dwFlags & PFD_NEED_PALETTE) 
        SetupPalette(); 
 
	m_hRC = wglCreateContext(m_pDC->m_hDC); 
 
	wglMakeCurrent(m_pDC->m_hDC,m_hRC); 
 
	m_Font.SetXOffset(-0.30f); 
	m_Font.SetXScale(1.2f); 
	m_Font.SetYScale(1.5f); 
	m_Font.SetZScale(1.0f); 
	m_Font.SetXRotate(25.0f); 
	//m_Font.SetZRotate(-1.0f); 
 
	m_Font.SetFontType(GL_FONT_SOLID); 
	m_Font.SetText(m_String); 
	m_Font.CreateFont(m_pDC, "Arial Black"); 
 
    SetupFontColor();		   
 
    wglMakeCurrent(m_pDC->m_hDC, NULL); 
} 
 
 
void CGL3dOcxCtrl::SetupPalette(void) 
{ 
	PIXELFORMATDESCRIPTOR pfd;  // Pixel Format Descriptor          
	LOGPALETTE *pPal;			// Pointer to memory for logical palette 
	int PixelFormat;			// Pixel format index 
    int paletteSize;            // Number of entries in palette  
	BYTE RedMask;               // Range for each color entry (7,7,and 3) 
	BYTE GreenMask; 
	BYTE BlueMask; 
 
	// Get the pixel format index and retrieve the pixel format description 
    PixelFormat = GetPixelFormat(m_pDC->m_hDC); 
    DescribePixelFormat(m_pDC->m_hDC, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 
     
	 
 
	// Get the number of entries in palette. 256 colors for 8 bits  
    paletteSize = 1 << pfd.cColorBits; 
     
	// Allocate for the logical palette 
	pPal = (LOGPALETTE*) 
	malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY)); 
     
	 
	// Fill the logical palette header information  
	pPal->palVersion = 0x300;            //support Windows3.0 
    pPal->palNumEntries = paletteSize;   //number of colors entries 
 
    // Set the 1st entries of logical palette with the current system palette  
    (void) GetSystemPaletteEntries(m_pDC->m_hDC, 0, paletteSize, &pPal->palPalEntry[0]); 
 
	//Set the RGB mask 
	RedMask = (1 << pfd.cRedBits) - 1; 
	GreenMask = (1 << pfd.cGreenBits) - 1; 
	BlueMask = (1 << pfd.cBlueBits) - 1; 
 
	//Set all entries of the logical palette  
    for (int i=0; ipalPalEntry[i].peRed = 
		    (((i >> pfd.cRedShift) & RedMask) * 255) / RedMask; 
	    pPal->palPalEntry[i].peGreen = 
		    (((i >> pfd.cGreenShift) & GreenMask) * 255) / GreenMask; 
	    pPal->palPalEntry[i].peBlue = 
		    (((i >> pfd.cBlueShift) & BlueMask) * 255) / BlueMask; 
	    pPal->palPalEntry[i].peFlags = 0; 
    } 
 
	//Create the palette 
    m_Palette.CreatePalette(pPal); 
 
	m_pDC->SelectPalette(&m_Palette, FALSE); 
	m_pDC->RealizePalette(); 
 
	//Free the memory allocated for the logical palette  
    free(pPal); 
} 
 
void CGL3dOcxCtrl::SetupFontColor(void) 
{ 
	float fv[4]; 
	 
	fv[0] = 0.3; 
	fv[1] = 0.3; 
	fv[2] = 0.3; 
	fv[3] = 1.0; 
	m_Font.SetEmission(fv); 
 
	fv[0] = 0.4; 
	fv[1] = 0.4; 
	fv[2] = 0.4; 
	fv[3] = 1.0; 
	m_Font.SetSpecular(fv); 
 
	fv[0] = 0.4; 
	fv[1] = 1.0; 
	fv[2] = 0.4; 
	fv[3] = 1.0; 
	m_Font.SetAmbient(fv); 
 
	fv[0] = 0.3; 
	fv[1] = 0.3; 
	fv[2] = 0.3; 
	fv[3] = 1.0; 
	m_Font.SetDiffuse(fv); 
 
	m_Font.SetShininess(0.1f); 
} 
 
void CGL3dOcxCtrl::dcRender(void) 
{ 
	wglMakeCurrent(m_pDC->m_hDC, m_hRC); 
	glShadeModel(GL_SMOOTH); 
	glEnable(GL_DEPTH_TEST); 
	 
	//clear color buffer 
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	 
	//set light model 
	glLightfv(GL_LIGHT0, GL_AMBIENT, m_Lightambient);//set light ambient 
	glLightfv(GL_LIGHT0, GL_DIFFUSE, m_Lightdiffuse);//set light specular 
	glLightfv(GL_LIGHT0, GL_SPECULAR, m_Lightspecular);//set light specular 
	glLightfv(GL_LIGHT0, GL_POSITION, m_Lightposition);//set light position 
 
	glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
 
    glTranslatef(-1.2f, -0.1f, -4.2f); 
	 
    m_Font.GLDrawText(); 
 
	glFlush(); 
 
 
	SwapBuffers(m_pDC->m_hDC); 
    wglMakeCurrent(m_pDC->m_hDC, NULL); 
 
} 
 
 
void CGL3dOcxCtrl::SetViewPort(void) 
{ 
	wglMakeCurrent(m_pDC->m_hDC, m_hRC); 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 7.0); 
	glViewport(0, 0, m_cx, m_cy); 
	wglMakeCurrent(m_pDC->m_hDC, NULL); 
} 
 
/**********************************************/ 
/* Property                                   */ 
/**********************************************/ 
 
/* The property of string which is shown */ 
BSTR CGL3dOcxCtrl::GetContent()  
{ 
	// TODO: Add your property handler here 
	CString strResult = m_Font.GetText(); 
 
	return strResult.AllocSysString(); 
} 
 
void CGL3dOcxCtrl::SetContent(LPCTSTR lpszNewValue)  
{ 
	// TODO: Add your property handler here 
	wglMakeCurrent(m_pDC->m_hDC, m_hRC); 
	m_Font.SetText(lpszNewValue); 
	m_Font.CreateFont(m_pDC, "Arial Black"); 
	wglMakeCurrent(m_pDC->m_hDC, NULL); 
    Refresh(); 
} 
 
 
/**********************************************/ 
/* Method                                     */ 
/**********************************************/ 
 
/* The property of string which is shown */ 
void CGL3dOcxCtrl::SetStrText(LPCTSTR strText)  
{ 
	// TODO: Add your dispatch handler code here 
	wglMakeCurrent(m_pDC->m_hDC, m_hRC); 
	m_Font.SetText(strText); 
	m_Font.CreateFont(m_pDC, "Arial Black"); 
	wglMakeCurrent(m_pDC->m_hDC, NULL); 
    Refresh(); 
} 
 
 
 
void CGL3dOcxCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
    Refresh(); 
	 
	COleControl::OnLButtonDblClk(nFlags, point); 
} 
 
void CGL3dOcxCtrl::OnPaletteChanged(CWnd* pFocusWnd)  
{ 
	COleControl::OnPaletteChanged(pFocusWnd); 
	 
	// TODO: Add your message handler code here 
    Refresh(); 
 
} 
 
BOOL CGL3dOcxCtrl::OnQueryNewPalette()  
{ 
	// TODO: Add your message handler code here and/or call default 
    Refresh(); 
	 
	return COleControl::OnQueryNewPalette(); 
}