(c)2002 Pavel Pindora
Email
Kontakt
Pro více informací je zde formulář
Operace s registry a VisualC++
Jak řešit přenos zvuku z mikrofonu po IP síti new 9.9.2002
Zavedení dalšího toolbaru a checked (un..) tlačítka v něm new 2.8.2003
Obsluha joysticku new 8.8.2003
Active Scripting new 29.12.2003
Get message from WebSphere MQ new 15.5.2005
OpenGl grafika a VisualC++
Následující aplikace ukazuje způsob jak využít OpenGl grafiku v aplikaci napsanou za pomocí Visual C++ od Microsoft Corporation.Je na ni demonstrováno použití prvků typu polygon,čtverec,prstenec.Polygon má nanesenou texturu,která je však jako zdroj (resource) vložena do aplikace, je však možno použít bitmapu ze souboru.
Následující obrázek znázorňuje spuštěnou aplikaci přeloženou jako EXE soubor.

Popis jednotlivých položek menu :
File Edit View Help vzniknou automaticky při generování MFC aplikace a nemají žádnou funkci.
Povolit Texturu na prvek polygon je nanesena textura z resource, konkrétně Prerijní vítr.bmp.
Zakázat Texturu prvek je holý,bez textury
Povolit Barvu každý bod prvku je vybarven, kromě prstence ten má vždy základní červenou barvu.
Zakázat Barvu Prvku jsou vybarveny základní červenou barvu.
Jak to vlastně funguje?
Při volání funkce COpenGL_MFCView::Create(...) ( WM_CREATE ) se inicializuje OpenGl rozhraní ale nejdříve se spustí Timer potom se z resource převezme bitmapa Prérijní vítr.bmp a určí se její velikost, alokuje pro ní buffer bitbuffer, zjistí se velikost okna a jeho HDC (hdc) a s těmito parametry se volá COpenGL_MFCView::CreateContext(...) tam se provede vlastní inicializace.
Jakmile vyšlou Windows událost na překreslení okna, vyvolá se funkce COpenGL_MFCView::OnDraw(...) a pokud je okContext v pořádku vykreslí se prvky voláním COpenGL_MFCView::MFCViewPolygon(...) tam se určuje natočení,velikost,barva prvku a pokud je splněna podmínka nanese se textura na jeden z nich. Aby nám prvky plavaly v prostoru je potřeba vysílat událost překreslování okna a volat tak cyklicky COpenGL_MFCView::OnDraw(...) o to se právě stará timer, který vyvolává funkci COpenGL_MFCView::OnTimer...) a ta zašle událost WM_PAINT.
/***************************************************************
Výpis a komentář ke zdrojovému programu.
***************************************************************/
// OpenGL_MFCView.cpp : implementation of the COpenGL_MFCView class
//
#include "stdafx.h"
#include "OpenGL_MFC.h"
#include "OpenGL_MFCDoc.h"
#include "CntrItem.h"
#include "OpenGL_MFCView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COpenGL_MFCView
IMPLEMENT_DYNCREATE(COpenGL_MFCView, CView)
BEGIN_MESSAGE_MAP(COpenGL_MFCView, CView)
//{{AFX_MSG_MAP(COpenGL_MFCView)
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_WM_SIZE()
ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
ON_COMMAND(ID_BUTTON32771, OnButton32771)
ON_COMMAND(ID_BUTTON32772, OnButton32772)
ON_WM_TIMER()
ON_WM_CREATE()
ON_COMMAND(ID_ZAKTEX, OnZaktex)
ON_COMMAND(ID_POVTEX, OnPovtex)
ON_COMMAND(ID_POVBARVU, OnPovbarvu)
ON_COMMAND(ID_ZAKBARVU, OnZakbarvu)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COpenGL_MFCView construction/destruction
COpenGL_MFCView::COpenGL_MFCView()
{
m_pSelection = NULL;
// TODO: add construction code here
/********************************************************************************/
static int defaultOverride[13]={0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91};
/********************************************************************************/
static PALETTEENTRY MFCViewdefaultPalEntry[20] =
{
{ 0, 0, 0, 0 },
{ 0x80,0, 0, 0 },
{ 0, 0x80,0, 0 },
{ 0x80,0x80,0, 0 },
{ 0, 0, 0x80, 0 },
{ 0x80,0, 0x80, 0 },
{ 0, 0x80,0x80, 0 },
{ 0xC0,0xC0,0xC0, 0 },
{ 192, 220, 192, 0 },
{ 166, 202, 240, 0 },
{ 255, 251, 240, 0 },
{ 160, 160, 164, 0 },
{ 0x80,0x80,0x80, 0 },
{ 0xFF,0, 0, 0 },
{ 0, 0xFF,0, 0 },
{ 0xFF,0xFF,0, 0 },
{ 0, 0, 0xFF, 0 },
{ 0xFF,0, 0xFF, 0 },
{ 0, 0xFF,0xFF, 0 },
{ 0xFF,0xFF,0xFF, 0 }
};
/********************************************************************************/
static unsigned char MFCViewthreeto8[8] =
{
0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
};
/********************************************************************************/
static unsigned char MFCViewtwoto8[4] =
{
0, 0x55, 0xaa, 0xff
};
/********************************************************************************/
static char MFCViewoneto8[2] = { (char)0,(char)255 };
/********************************************************************************/
defaultPalEntry = MFCViewdefaultPalEntry;
threeto8 = MFCViewthreeto8;
twoto8 = MFCViewtwoto8;
oneto8 = MFCViewoneto8;
m_pPal = NULL;
m_fRadius = 7;
m_wAngleX = 0.1f;//(float(joyposY - 32768) / 32768.0f) * 20.0f;
m_wAngleY = 0.1f;//(float(joyposX - 32768) / 32768.0f) * 20.0f;
m_wAngleZ = 0.1f;
}
COpenGL_MFCView::~COpenGL_MFCView()
{
}
BOOL COpenGL_MFCView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// COpenGL_MFCView drawing
void COpenGL_MFCView::OnDraw(CDC* pDC)
{
COpenGL_MFCDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (m_pSelection == NULL)
{
POSITION pos = pDoc->GetStartPosition();
m_pSelection = (COpenGL_MFCCntrItem*)pDoc->GetNextClientItem(pos);
}
if (m_pSelection != NULL)
m_pSelection->Draw(pDC, CRect(10, 10, 210, 210));
//*************************************************************
HDC hdc = pDC->m_hDC;
if( okContext==TRUE )
{
MFCViewPolygon( hdc,rt );
};
//*************************************************************
}
void COpenGL_MFCView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: remove this code when final selection model code is written
m_pSelection = NULL; // initialize selection
}
/////////////////////////////////////////////////////////////////////////////
// COpenGL_MFCView printing
BOOL COpenGL_MFCView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void COpenGL_MFCView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void COpenGL_MFCView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
void COpenGL_MFCView::OnDestroy()
{
// Deactivate the item on destruction; this is important
// when a splitter view is being used.
CView::OnDestroy();
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
{
pActiveItem->Deactivate();
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
wglDeleteContext( m_hrc );
}
/////////////////////////////////////////////////////////////////////////////
// OLE Client support and commands
BOOL COpenGL_MFCView::IsSelected(const CObject* pDocItem) const
{
// The implementation below is adequate if your selection consists of
// only COpenGL_MFCCntrItem objects. To handle different selection
// mechanisms, the implementation here should be replaced.
// TODO: implement this function that tests for a selected OLE client item
return pDocItem == m_pSelection;
}
void COpenGL_MFCView::OnInsertObject()
{
// Invoke the standard Insert Object dialog box to obtain information
// for new COpenGL_MFCCntrItem object.
COleInsertDialog dlg;
if (dlg.DoModal() != IDOK)
return;
BeginWaitCursor();
COpenGL_MFCCntrItem* pItem = NULL;
TRY
{
// Create new item connected to this document.
COpenGL_MFCDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pItem = new COpenGL_MFCCntrItem(pDoc);
ASSERT_VALID(pItem);
// Initialize the item from the dialog data.
if (!dlg.CreateItem(pItem))
AfxThrowMemoryException(); // any exception will do
ASSERT_VALID(pItem);
if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem->DoVerb(OLEIVERB_SHOW, this);
ASSERT_VALID(pItem);
// As an arbitrary user interface design, this sets the selection
// to the last item inserted.
// TODO: reimplement selection as appropriate for your application
m_pSelection = pItem; // set selection to last inserted item
pDoc->UpdateAllViews(NULL);
}
CATCH(CException, e)
{
if (pItem != NULL)
{
ASSERT_VALID(pItem);
pItem->Delete();
}
AfxMessageBox(IDP_FAILED_TO_CREATE);
}
END_CATCH
EndWaitCursor();
}
// The following command handler provides the standard keyboard
// user interface to cancel an in-place editing session. Here,
// the container (not the server) causes the deactivation.
void COpenGL_MFCView::OnCancelEditCntr()
{
// Close any in-place active item on this view.
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
{
pActiveItem->Close();
}
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
// Special handling of OnSetFocus and OnSize are required for a container
// when an object is being edited in-place.
void COpenGL_MFCView::OnSetFocus(CWnd* pOldWnd)
{
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL && pActiveItem->GetItemState() == COleClientItem::activeUIState)
{
/ / need to set focus to this item if it is in the same view
CWnd* pWnd = pActiveItem->GetInPlaceWindow();
if (pWnd != NULL)
{
pWnd->SetFocus(); // don't call the base class
return;
}
}
CView::OnSetFocus(pOldWnd);
}
void COpenGL_MFCView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
pActiveItem->SetItemRects();
}
/////////////////////////////////////////////////////////////////////////////
// COpenGL_MFCView diagnostics
#ifdef _DEBUG
void COpenGL_MFCView::AssertValid() const
{
CView::AssertValid();
}
void COpenGL_MFCView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
COpenGL_MFCDoc* COpenGL_MFCView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COpenGL_MFCDoc)));
return (COpenGL_MFCDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// COpenGL_MFCView message handlers
BOOL COpenGL_MFCView::Create(
LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID,
CCreateContext* pContext
)
{
// TODO: Add your specialized code here and/or call the base class
BOOL cr = CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
BOOL bmp;
SetTimer( 1,5,NULL );
GL_hWnd = pParentWnd->m_hWnd;
LPCTSTR lpszResourceName = "Prérijní vítr.bmp";
bmp = GLBitmapa.LoadBitmap( IDB_BITMAP2 );
pBitMap = new BITMAP;
DWORD GetBMP = GLBitmapa.GetBitmap( pBitMap );
GetBMP = pBitMap->bmWidth * pBitMap->bmHeight * pBitMap->bmBitsPixel ;
bitbuffer = malloc( GetBMP );
GetBMP = GLBitmapa.GetBitmapBits( GetBMP, bitbuffer );
delete bitbuffer;
bitbuffer = malloc( GetBMP );memset(bitbuffer,0x84,GetBMP);
bmp = GLBitmapa.GetBitmapBits( GetBMP, bitbuffer );
int i, j;
double ti, tj;
pParentWnd->GetClientRect( &rt );
CDC *xdc = pParentWnd->GetDC();
hdc = xdc->m_hDC;
CreateContext(hdc, rt);
okContext=TRUE;
return cr;
}
void COpenGL_MFCView::CreateContext(HDC gl_hdc, RECT &rc)
{
PIXELFORMATDESCRIPTOR pfd;
GLfloat fMaxObjSize, fAspect;
GLfloat fNearPlane, fFarPlane;
if (!bSetupPixelFormat(gl_hdc))
return;
CreateRGBPalette(gl_hdc);
::SelectPalette(gl_hdc, m_hPal, FALSE);
::RealizePalette(gl_hdc);
int n = ::GetPixelFormat(gl_hdc);
::DescribePixelFormat(gl_hdc, n, sizeof(pfd), &pfd);
m_hrc = wglCreateContext(gl_hdc);
wglMakeCurrent(gl_hdc, m_hrc);
GLenum target = GL_TEXTURE_2D;
GLenum tar[9];
glTexImage2D(
target,
0,
3,
pBitMap->bmWidth,
pBitMap->bmHeight,
0,
GL_COLOR_INDEX,//GL_RGB,
GL_BITMAP,
bitbuffer //CBitmap scanline[GLBitmapa.height-1]
);
/* glTexImage2D(target,1,3,pBitMap->bmWidth,pBitMap->bmHeight,0,GL_COLOR_INDEX,GL_BITMAP,bitbuffer);
glTexImage2D(target,2,3,pBitMap->bmWidth,pBitMap->bmHeight,0,GL_COLOR_INDEX,GL_BITMAP,bitbuffer);
glTexImage2D(target,3,3,pBitMap->bmWidth,pBitMap->bmHeight,0,GL_COLOR_INDEX,GL_BITMAP,bitbuffer);
glTexImage2D(target,4,3,pBitMap->bmWidth,pBitMap->bmHeight,0,GL_COLOR_INDEX,GL_BITMAP,bitbuffer);
glTexImage2D(target,5,3,pBitMap->bmWidth,pBitMap->bmHeight,0,GL_COLOR_INDEX,GL_BITMAP,bitbuffer);
target = glGetError();
char poleGLErr[50];
if( GL_NO_ERROR == target )
sprintf( poleGLErr,"%s","GL_NO_ERROR" );
if( GL_STACK_OVERFLOW == target )
sprintf( poleGLErr,"%s","GL_STACK_OVERFLOW" );
if( GL_STACK_UNDERFLOW == target )
sprintf( poleGLErr,"%s","GL_STACK_UNDERFLOW" );
if( GL_OUT_OF_MEMORY == target )
sprintf( poleGLErr,"%s","GL_OUT_OF_MEMORY" );
if( GL_INVALID_ENUM == target )
sprintf( poleGLErr,"%s","GL_INVALID_ENUM" );
if( GL_INVALID_VALUE == target )
sprintf( poleGLErr,"%s","GL_INVALID_VALUE" );
if( GL_INVALID_OPERATION == target )
sprintf( poleGLErr,"%s","GL_INVALID_OPERATION" );
if( GL_NO_ERROR != target )
MessageBox(
poleGLErr, // address of text in message box
"Hlášení GL textury",// address of title of message box
MB_OK // style of message box
);
glClearDepth(10.0f);
glEnable(GL_DEPTH_TEST);
if (rc.bottom)
fAspect = (GLfloat)rc.right/rc.bottom;
else // don't divide by zero, not that we should ever run into that...
fAspect = 1.0f;
fNearPlane = 1.0f;
fFarPlane = 20.0f;
fMaxObjSize = 12.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(
30.0f,
// Ke mne, ode mne
fAspect,
// roztahnout zuzit
fNearPlane, //
fFarPlane
);
}
BOOL COpenGL_MFCView::bSetupPixelFormat(HDC hdc)
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
// size of this pfd
1,
// version number
PFD_DRAW_TO_WINDOW |
// support window
PFD_SUPPORT_OPENGL |
// support OpenGL
PFD_DOUBLEBUFFER,
// double buffered
PFD_TYPE_RGBA,
// RGBA type
24,
// 24-bit color depth
0, 0, 0, 0, 0, 0,
// color bits ignored
0,
// no alpha buffer
0,
// shift bit ignored
0,
// no accumulation buffer
0, 0, 0, 0,
// accum bits ignored
32,
// 32-bit z-buffer
0,
// no stencil buffer
0,
// no auxiliary buffer
PFD_MAIN_PLANE,
// main layer
0,
// reserved
0, 0, 0
// layer masks ignored
};
int pixelformat;
if ( (pixelformat = ChoosePixelFormat(hdc, &pfd)) == 0 )
{
return FALSE;
}
if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE)
{
return FALSE;
}
return TRUE;
}
void COpenGL_MFCView::CreateRGBPalette(HDC hdc)
{
PIXELFORMATDESCRIPTOR pfd;
int n, i;
if (m_pPal)
return;
n = ::GetPixelFormat(hdc);
::DescribePixelFormat(hdc, n, sizeof(pfd), &pfd);
if (pfd.dwFlags & PFD_NEED_PALETTE)
{
n = 1 << pfd.cColorBits;
m_pPal = (PLOGPALETTE) new char[sizeof(LOGPALETTE) + n * sizeof(PALETTEENTRY)];
if(m_pPal == NULL)
{
GL_Error = true;
return;
};
m_pPal->palVersion = 0x300;
m_pPal->palNumEntries = n;
for (i=0; i<n; i++)
{
m_pPal->palPalEntry[i].peRed = ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift);
m_pPal->palPalEntry[i].peGreen =ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift);
m_pPal->palPalEntry[i].peBlue = ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift);
m_pPal->palPalEntry[i].peFlags = 0;
}
/* fix up the palette to include the default GDI palette */
if ((pfd.cColorBits == 8) &&
(pfd.cRedBits == 3) && (pfd.cRedShift == 0) &&
(pfd.cGreenBits == 3) && (pfd.cGreenShift == 3) &&
(pfd.cBlueBits == 2) && (pfd.cBlueShift == 6)
)
{
for (i = 1 ; i <= 12 ; i++)
m_pPal->palPalEntry[defaultOverride[i]] = defaultPalEntry[i];
}
m_hPal = ::CreatePalette((LPLOGPALETTE)m_pPal);
::SelectPalette(hdc, m_hPal, FALSE);
::RealizePalette(hdc);
}
}
unsigned char COpenGL_MFCView::ComponentFromIndex(int i, UINT nbits, UINT shift)
{
unsigned char val;
val = (unsigned char) (i >> shift);
switch (nbits)
{
case 1:
val &= 0x1;
return oneto8[val];
case 2:
val &= 0x3;
return twoto8[val];
case 3:
val &= 0x7;
return threeto8[val];
default:
return 0;
};
}
void COpenGL_MFCView::MFCViewPolygon( HDC hdc, RECT rc )
{
GLenum modGL;
static GLclampf alpha;
alpha+=1;
glClearColor( 0.0f, 0.0f, 0.0f, 10.0f );// Barva pozadi 10.0f
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
kteryMatrixMode=1;
if( kteryMatrixMode==1 )
{
glMatrixMode(GL_PROJECTION);
kteryMatrixMode=0;
};
if( kteryMatrixMode==2 )
{
glMatrixMode(GL_MODELVIEW);
kteryMatrixMode=0;
};
glTranslatef( 0, 0 , -m_fRadius );
glRotatef(m_wAngleX, 1.0f, 0.0f, 0.0f);
glRotatef(m_wAngleY, 0.0f, 1.0f, 0.0f);
glRotatef(m_wAngleZ, 0.0f, 0.0f, 1.0f);
// modGL = GL_LINES; // 1 Linky
// modGL = GL_LINE_STRIP; // 2 Spojene linky
// modGL = GL_LINE_LOOP; // 3 Spojene linky
// modGL = GL_TRIANGLES; // 4 trojuhelniky
// modGL = GL_TRIANGLE_STRIP; // 5 Spojil trojuhelniky
// modGL = GL_TRIANGLE_FAN; // 6 Vyplnene trojuhelniky
modGL = GL_POLYGON;// 7 Polygon
//modGL = GL_QUADS;
if( PovolitTex==1)
glEnable(GL_TEXTURE_2D);
else
glDisable(GL_TEXTURE_2D);
glBegin( modGL );//GL_QUAD_STRIP
// 1.bod 1.trojuhelnik
if( PovolitBar==1) glColor3f ( 1.0f, 0.1f, 1.0f);
glTexCoord2f(0.0, 0.0);
glVertex3f ( 1.35f, 0.5f, 0.5f);
// 2.bod 1.trojuhelnik
if( PovolitBar==1) glColor3f (1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0, 8.0);
glVertex3f (-1.5f, -0.5f, -0.5f);
// 3.bod 1.trojuhelnik
if( PovolitBar==1) glColor3f (1.0f, 1.0f, 1.0f);
glTexCoord2f(8.0, 8.0);
glVertex3f (-1.5f, 1.5f, 0.5f);
if( PovolitBar==1) glColor3f (1.0f, 1.0f, 0.0f);
glTexCoord2f(8.0, 0.0);
glVertex3f (2.5f, -2.5f, 0.5f);
glEnd();
glDisable(GL_TEXTURE_2D);
glBegin( modGL=GL_QUAD_STRIP );//GL_QUAD_STRIP
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, -0.5f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, -0.5f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.5f);
auxSolidTorus (0.275, 0.85);
glEnd();
glPopMatrix();
glFinish();
SwapBuffers(wglGetCurrentDC());
};
void COpenGL_MFCView::OnButton32771()
{
// TODO: Add your command handler code here
m_fRadius+=0.1f;
}
void COpenGL_MFCView::OnButton32772()
{
// TODO: Add your command handler code here
m_fRadius-=0.1f;
}
void COpenGL_MFCView::OnTimer(UINT nIDEvent)
{
SendMessage( WM_PAINT );
m_wAngleX -= 0.1f;
m_wAngleY -= 0.1f;
m_wAngleZ += 1.0f;
CView::OnTimer ( nIDEvent);
}
int COpenGL_MFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
void COpenGL_MFCView::OnZaktex()
{
// TODO: Add your command handler code here
PovolitTex = 0;
}
void COpenGL_MFCView::OnPovtex()
{
// TODO: Add your command handler code here
PovolitTex = 1;
}
void COpenGL_MFCView::OnPovbarvu()
{
// TODO: Add your command handler code here
PovolitBar = 1;
}
void COpenGL_MFCView::OnZakbarvu()
{
// TODO: Add your command handler code here
PovolitBar = 0;
}
hCom = CreateFile(
"COM1",
// Který seriový port chceme otevřít
GENERIC_READ | GENERIC_WRITE,
0,
/* comm devices must be opened w/exclusive-access*/
NULL, /* no security attrs */
OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
0, /* not overlapped I/O */
NULL /* hTemplate must be NULL for comm devices */
);
if( hCom==INVALID_HANDLE_VALUE )
return 1;// Chyba v otevření COM1
//******************* Nastavení parametrů COM1 **************************
DCB dcb; //Struktura parametru COM1
ok
= GetCommState( hCom,&dcb );
// Sejmutí původních parametrů COM1
dcb.BaudRate = Nspeed;
// Požadovaná přenosová rychlost např 9600
dcb.ByteSize = (char) Nsizeb;
// Velikost slova např. 8 bitů
dcb.Parity
= NOPARITY;
// Parita žádná
dcb.StopBits = (char) Nstopb;
// Počet stop bitů např.1
ok
= SetCommState( hComk,&dcb ); // Nastavení nových
parametrů COM portu
//******************* Vyslání dat na COM1 **************************
WriteFile( hCom,
(TxData+i), // znak z char pole indexované proměnnou i
1, // počet vysílaných dat
&datw, // skutečný počet odvysílaných dat
NULL
);
close(hCom);// Uzavření COM1
//*******************************************************************************************
Operace s registry a VisualC++
Funkce GetKeyRegistry načte z registru , daný v parametru key, hodnotu položky
definovanou v parametru value.Hodnota bude zpětně vrácena v value.Funkce ,
pokud je neúspěšná vrátí 0.
DWORD GetKeyRegistry( char *key,char *value )
{
HKEY hKeyResult = 0;
DWORD dwDisposition = 0;
DWORD lpcbValue = 65000,
iGKR;
unsigned long lpType = REG_BINARY;
unsigned char lpData[65000];
HKEY hKey;
int jeAlpha;
if( strlen(key)==0 )
{
sprintf( value,"!!!!!! Není zadán Key !!!!!!" );
return false;
};
if( strlen(value)==0 )
{
sprintf( value,"!!!!!! Není zadán Name of value !!!!!!" );
return false;
};
LONG lResult = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,//Hlavní klíč kde se bude hledat key,
hey,//"MyDoc\\shell\\&Test\\command",
0,
KEY_ALL_ACCESS,//KEY_QUERY_VALUE,
&hKey
);
if ( lResult == ERROR_SUCCESS )
{
lResult = RegQueryValueEx
(
hKey,
value,//key,
0,
&lpType,
lpData,
&lpcbValue
);
if ( lResult == ERROR_SUCCESS )
{
memset( value,0,lpcbValue+10 );
sprintf( value,"%s",(char*)lpData );
value[lpcbValue]=0;
}
else
{
RegCloseKey( hKey );
sprintf( value,"%s Error=%d","! Hodnota nebyla dosazena ! ",lResult );
return false;
};
}
else
{
sprintf( value,"!!!!!! Registr nebyl otevřen !!!!!!" );
return false;
};
RegCloseKey( hKey );
//--------------------------------------------------------
return lpcbValue;
}
//**************************************************************************************************Funkce Zápis_do_Reg zapíše do subregistru (pomocíRegSetValueEx),
daný v parametruKey, a položky definovanou v parametruNameValue,hodnotu obsaženou
v Value.
Funkce, pokud je neúspěšná, vrátí nenulovou hodnotu.
Pokud key neexistuje je vytvořen funkcí RegCreateKeyEx.
int Zapis_do_Reg(char *Key, char *NameValue, char *Value)
{
HKEY hKeyResult = 0;
DWORD dwDisposition = 0;
LONG lResult = RegCreateKeyEx
(
HKEY_LOCAL_MACHINE,
Key,
0, // reserved
"",
REG_OPTION_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKeyResult,
&dwDisposition
);
if ( lResult == ERROR_SUCCESS )
{
lResult = RegSetValueEx
(
hKeyResult,
NameValue,
0,
REG_BINARY,
(unsigned char*)Value,
lstrlen( Value )
);
RegCloseKey( hKeyResult );
if ( lResult != ERROR_SUCCESS )
return 8;
}
else
return 7;
return 0;
}
//**************************************************************************************************
Programujeme FTP klienta,nástin řešení
HINTERNET hOpen,
hConnect;
if ( !(hOpen = InternetOpen (
"FTP EVC (C)2001",
LOCAL_INTERNET_ACCESS ,
0,//pristupove data pro proxy ,
0,//pristupove data pro proxy
0
) )
)
{
...( EditMees,"Error InternetOpen for FTP\r\n",0 );
return ;
}
else
{
openFTP = true;
bool ok ´Open(poleIP,poleUser,polePass);//Otevřeme FTP kanál
.
.
.
////////// Nyni kdyz je ok=true muzeme provest vyhledani souboru funkci
////////// FtpFindFirstFile ,ktera naplni strukturu pData /////
WIN32_FIND_DATA pData;
HINTERNET hFind
if ( !(hFind = FtpFindFirstFile (hConnect,path, &pData, 0, 0) ))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
...( ...,"This directory is empty\r\n",0 );
return;
}
else
{
...( ...,"FindFirst error: \r\n",0 );
InternetCloseHandle (hFind);
};
};
if (pData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
TREEDIRC//Vypíšeme někde název adresáře
}
else
{
if( kdeItem==FTPRootItem )
{
TREEFILE//Vypíšeme někde název souboru
}
};
InternetCloseHandle (hFind);
/////////////////////////////////////////////////////////////////////////////
bool Open(CHAR *szHost,CHAR *szUser,CHAR *szPass)
{
if ( !(hConnect = InternetConnect (
hOpen,
szHost, //INTERNET IP adresa,
INTERNET_DEFAULT_FTP_PORT, //INTERNET_INVALID_PORT_NUMBER,
szUser, //INTERNET Host např administrator,
szPass, //INTERNET heslo pro přístup na FTP,
INTERNET_SERVICE_FTP,
INTERNET_FLAG_PASSIVE ,
0
)
)
)
{
//Chyba otevření FTP kanálu
return FALSE;
}
return TRUE;
}
//**************************************************************************************************
Jak řešit přenos zvuku z mikrofonu po IP síti
COSoundInput odeslání zvukových samplů na IP síť

COVoiceClient Příjem zvukových samplů z IP sítě

COSoundOutput

COSoundOutput WaveOutThreadProc

Zavedení dalšího toolbaru a checked (un..) tlačítka v něm
Například, obrázek ukazuje checknute tlacitko 2

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//********* Standartní toolbar generovaný MFC *************
if(
!m_wndToolBar.CreateEx
(
this,
TBSTYLE_FLAT,
WS_CHILD |
WS_VISIBLE |
CBRS_TOP |
CBRS_GRIPPER |
CBRS_TOOLTIPS |
CBRS_FLYBY |
CBRS_SIZE_DYNAMIC
)
|| !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)
)
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
//********* Efektovy toolbar který chceme přidat *************
if (
!m_wndEfektBar.CreateEx
(
this,
TBSTYLE_FLAT,
WS_CHILD |
WS_VISIBLE |
CBRS_TOP |
CBRS_GRIPPER |
CBRS_TOOLTIPS |
CBRS_FLYBY |
CBRS_SIZE_DYNAMIC
)
|| !m_wndEfektBar.LoadToolBar(IDR_TOOLBAREFEKTS)
)
{
TRACE0("Failed to create Efekts toolbar\n");
return -1; // fail to create
}
//******************************************
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
//******************************************
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndEfektBar.EnableDocking(CBRS_ALIGN_ANY);
EfektToolBar = &m_wndEfektBar;/*** potreba dat do glob.ukazatele abych nekde jinde mohl pouzit***
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
DockControlBar(&m_wndEfektBar);
return 0;
}
Událost od Timeru OnTimer vypne nebo zapne Check Buttonu dle potreby rozliseneho napr. pomoci if
for( int i=0;i<MAXEFBUTTON;i++ )
{
if( button[i]!=0 )
{
EfektToolBar->SendMessage(TB_CHECKBUTTON, button[i],MAKELONG( 0,0 ));// Reset check
if( i+1==efekt )
{
EfektToolBar->SendMessage(TB_CHECKBUTTON, button[i],MAKELONG( 1,0 ));// Set check
}
}
}
V button[i] jsou vlastni ID např. ID_BUTTONEfekt1, které předtím
vyberu.
// TODO: remove this code when final draw code is complete.
//------------------------------------------
MMRESULT reslt = joyGetPos( 1,pji );
if( reslt==JOYERR_NOERROR )
{
JoyPoziceX = (pji->wXpos - 32767);JoyPoziceX = JoyPoziceX / 1000;
JoyPoziceY = (pji->wYpos - 32767);JoyPoziceY = JoyPoziceY / 1000;
if( abs(JoyPoziceX)==1 )
JoyPoziceX = 0;
if( abs(JoyPoziceY)==1 )
JoyPoziceY = 0;
//--------------------------------
if( pji->wButtons&0x01 )//Ukazovak
{
JoyCountr1 = 5;
}
else
JoyCountr1--;
if( JoyCountr1>0 )
JoyButton1 = 1;
else
JoyButton1 = 0;
//--------------------------------
if( pji->wButtons&0x02 )//Palec vrchni button
{
JoyCountr2 = 5;
}
else
JoyCountr2--;
if( JoyCountr2>0 )
JoyButton2 = 1;
else
JoyButton2 = 0;
//--------------------------------
};
//------------------------------------------
Všechny proměnné jsou globální a typu
integer kromě struktůry pji
//---------- Joystick ---------------------
LPJOYINFO pji = new JOYINFO;// Joystick
int JoyPoziceX;
int JoyPoziceY;
int JoyButton1;
int JoyButton2;
int JoyCountr1;
int JoyCountr2;
.
Active scriptingU některých programů je vhodné aby uživatel mohl vytvářet vlastní části kódu, kterými by mohl chod aplikace ovlivňovat . Je to v těch případech, kdy je například potřeba modifikovat barvu,polohu nebo další vlastnosti nějakého objektu, případně přiřazovat hodnoty vnitřním proměnným , které se mohou naší aplikaci poslat do reálného světa. Využití scriptingu je např. ve vizualzačních programech , např VisualProg ale i v enginech pro tvorbu 3D efektů,simulací , např 3DOT a v neposlední řadě i her ale zde je potřeba brát ohled na rychlost zpracování skriptu .
Pro prvotní pokusy jsem vytvořil pomocí ClassWizardu ve VC++6 SDI aplikaci do které jsem implementoval tlačítko, kterým se spustí skript, prozatím implementován do String Table v resourcích.

Pro přehlednost uvedu výpis jednoduchého skriptu:
Dim jmeno1
Dim jmeno2
jmeno1 = UserData1.GetValue()
jmeno2 = UserData2.GetValue()
jmeno1 = jmeno1 + 1
jmeno2 = jmeno2 + 10
UserData1.SetValue(jmeno1)
UserData2.SetValue(jmeno2)
Jedná se tedy o Visual Basic ale je možno jednoduše navolit i Java skript.
Co je na něm nejdůležitější ?
Rozhraní mezi skriptem, který si bude modifikovat uživatel (UserData1,2) a naší aplikací. Uživatel může ovlivnit naší vnitřní proměnnou, kterou pak je možno např. vyslat na seriový port apod. Případně si vyčíst hodnotu od nás a použít skript k nějakému rozhodnutí. Ve skriptu je taková proměnná UserData1 a 2. Pro jednoduchost si skript přečte hodnotu UserData1,2 pomocí metody GetValue něco s ní provede a uloží zpět do naší aplikace SetValue.

Nejprve tedy vytvoříme vlastní rozhraní ( class ) , ke kterému bude skript přistupovat, pomocí MFC přidáme class UserData. Nezapomeneme navolit Automation.

Potom vytvoříme metody pro skriptovací rozhraní, GetValue a SetValue ,pomocí ClassWizardu

Založíme proměnnou s názvem DataZVB, která bude pomocí SetValue modifikována a čtena GetValue . Pro názornost uvedu obrázek tříd aplikace.

Další třídou, která implementuje vlastní skriptovací
stroj je class SPO_ScriptEngine : public CCmdTarget. Zde je potřeba
implementovat rozhraní mezi BEGIN_INTERFACE_PART
a END_INTERFACE_PART
//
SPO_ScriptEngine.h: interface for the SPO_ScriptEngine class. |
Dále jsou
zde ještě metody DeInicScript,InicScript,AddNamedItem,RunScript,CreateEngine
Všechny
metody mezi BEGIN_INTERFACE_PART
a END_INTERFACE_PART je potřeba
vepsat do SPO_ScriptEngine např GetLCID bude vypadat takto:
HRESULT SPO_ScriptEngine::XActiveScriptSite::GetLCID( /* [out] */ LCID __RPC_FAR *plcid )
{
*plcid = GetSystemDefaultLCID();
return S_OK;
}
Zbytek si lehce zjístite přímo ve zdrojovém kódu.
Vlastní volání skriptovacího stroje jsem vytvořil v CActiveScriptingView::OnButtonscript()

|
Pro úplnost výpis logovacích zpráv
|
Get message from WebSphere MQVisual C++ 6.0 MFC dialog project WebSphereMQ



|