// OpenGLControl.cpp : implementation file
//
#include "stdafx.h"
#include "MemSpyy.h"
#include "OpenGLControl.h"
#include ".\openglcontrol.h"
#include "psapi.h"
// uggg i don't like this
#include "MemSpyyDlg.h"
#define ZOOM_FACTOR 800
// COpenGLControl
IMPLEMENT_DYNAMIC(COpenGLControl, CWnd)
COpenGLControl::COpenGLControl()
{
dc = NULL;
m_CurrentStartX = 0;
m_CurrentStartY = 0;
m_PID = 0;
m_OpenGLInitialized = false;
m_Red = 1.0;
m_Blue = 1.0;
m_OriginY = 0;
m_OriginX = 0;
m_CurrentlySelected = -1;
RegisterWindowClass();
}
COpenGLControl::~COpenGLControl()
{
if (dc) //Only delete dc when really allocated
{
delete dc;
}
}
BEGIN_MESSAGE_MAP(COpenGLControl, CWnd)
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONDBLCLK()
END_MESSAGE_MAP()
void COpenGLControl::InitGL()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
m_OpenGLInitialized = true;
}
void COpenGLControl::DrawMemory( SIZE_T blockSizeBytes )
{
GLfloat sizeK = (GLfloat) (blockSizeBytes / 1024);
GLfloat xcoord;
GLfloat ycoord;
if ( sizeK <= ( ZOOM_FACTOR - m_CurrentStartX ) )
{
xcoord = m_CurrentStartX / ZOOM_FACTOR;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
m_CurrentStartX += sizeK;
xcoord = m_CurrentStartX / ZOOM_FACTOR;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
}
else
{
int numLines = (int) sizeK / (ZOOM_FACTOR * 2);
if ( 1 < numLines )
{
for ( int x = 0; x < numLines; x++ )
{
xcoord = m_CurrentStartX / ZOOM_FACTOR;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
xcoord = 1.0;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
m_CurrentStartY -= 1;
xcoord = -1.0;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
xcoord = m_CurrentStartX / ZOOM_FACTOR;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
sizeK -= (ZOOM_FACTOR * 2);
}
}
GLfloat nextLine = sizeK - (ZOOM_FACTOR - m_CurrentStartX);
xcoord = m_CurrentStartX / ZOOM_FACTOR;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
xcoord = 1.0;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
m_CurrentStartY -= 1;
xcoord = -1.0;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
m_CurrentStartX = -ZOOM_FACTOR + nextLine;
xcoord = m_CurrentStartX / ZOOM_FACTOR;
ycoord = m_CurrentStartY / ZOOM_FACTOR;
glVertex3f( xcoord, ycoord, 0 );
}
}
void COpenGLControl::DrawGLScene( bool inSelect )
{
if ( m_PID == 0 )
return;
CheckInit();
if ( inSelect )
glInitNames();
unsigned long largestFreeBlock = 0;
unsigned long totalFree = 0;
unsigned long totalDLL = 0;
m_CurrentStartX = -ZOOM_FACTOR;
m_CurrentStartY = ZOOM_FACTOR;
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Get a handle to the process.
HANDLE process = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,false, m_PID );
PVOID baseAddress = 0;
SIZE_T retVal = 1;
unsigned long numBlocks = 0;
while (retVal)
{
MEMORY_BASIC_INFORMATION memBlock;
retVal = VirtualQueryEx(process, baseAddress,&memBlock,sizeof(memBlock));
if ( inSelect )
{
glPushName( numBlocks );
m_MemoryBlocks[numBlocks] = baseAddress;
}
glBegin(GL_LINES);
if (retVal)
{
if (memBlock.State & MEM_FREE)
{
if (memBlock.RegionSize>largestFreeBlock)
largestFreeBlock = (unsigned long) memBlock.RegionSize;
totalFree += (unsigned long) memBlock.RegionSize;
if ( numBlocks == m_CurrentlySelected )
glColor3f( 1.0f, 1.0f, 1.0f );
else
glColor3f(m_Red,0.0f,0.0f);
DrawMemory( memBlock.RegionSize );
}
else
{
char mappedFile[255];
if ( GetMappedFileName( process, baseAddress, mappedFile, 255) )
{
totalDLL += (unsigned long) memBlock.RegionSize;
if ( numBlocks == m_CurrentlySelected )
glColor3f( 1.0f, 1.0f, 1.0f );
else
glColor3f(0.0f,1.0f,0.0f);
}
else
{
if ( numBlocks == m_CurrentlySelected )
glColor3f( 1.0f, 1.0f, 1.0f );
else
glColor3f(0.0f,0.0f,m_Blue);
}
DrawMemory( memBlock.RegionSize );
}
baseAddress = (void *) (((char *) baseAddress) + memBlock.RegionSize);
}
glEnd();
if ( inSelect )
glPopName();
numBlocks++;
}
CMemSpyyDlg* theParent = (CMemSpyyDlg*) GetParent();
theParent->SetLargestFree( largestFreeBlock );
theParent->SetTotalDLL( totalDLL );
theParent->SetTotalFree( totalFree );
SwapBuffers(dc->m_hDC);
}
// COpenGLControl message handlers
void COpenGLControl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// this isn't used (yet) since the dialog doesn't resize
if (cy == 0)
{
cy = 1;
}
m_Width = cx;
m_Height = cy;
glViewport(0,0,cx,cy);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0f,1.0f,-1.0f,1.0f,1.0f,-1.0f);
}
void COpenGLControl::OnPaint()
{
CheckInit();
ForceDraw();
CWnd::OnPaint();
}
void COpenGLControl::ForceDraw()
{
/** OpenGL section **/
openGLDevice.makeCurrent();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
DrawGLScene();
}
BOOL COpenGLControl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
BOOL COpenGLControl::RegisterWindowClass()
{
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetInstanceHandle();
if (!(::GetClassInfo(hInst, _T("MFCOpenGLControl"), &wndcls)))
{
// otherwise we need to register a new class
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = _T("MFCOpenGLControl");
if (!AfxRegisterClass(&wndcls))
{
AfxThrowResourceException();
return FALSE;
}
}
return TRUE;
}
void COpenGLControl::OnLButtonDown(UINT nFlags, CPoint point)
{
m_PrevLDownY = point.y;
m_PrevLDownX = point.x;
CWnd::OnLButtonDown(nFlags, point);
}
void COpenGLControl::OnMouseMove(UINT nFlags, CPoint point)
{
if ( nFlags == MK_RBUTTON)
{
if ( m_PrevRDownY < point.y )
m_Height -= (3 * (point.y - m_PrevRDownY));
else
m_Height += (3 * (m_PrevRDownY - point.y));
m_PrevRDownY = point.y;
if ( m_PrevRDownX < point.x )
m_Width += (3 * (point.x - m_PrevRDownX));
else
m_Width-= (3 * (m_PrevRDownX - point.x));
m_PrevRDownX = point.x;
}
else if ( nFlags == MK_LBUTTON)
{
if ( m_PrevLDownY < point.y )
m_OriginY -= point.y - m_PrevLDownY;
else
m_OriginY += m_PrevLDownY - point.y;
m_PrevLDownY = point.y;
if ( m_PrevLDownX < point.x )
m_OriginX += point.x - m_PrevLDownX;
else
m_OriginX -= m_PrevLDownX - point.x;
m_PrevLDownX = point.x;
}
else
{
m_PrevX = point.x;
m_PrevY = point.y;
CMemSpyyDlg* theParent = (CMemSpyyDlg*) GetParent();
//////// STATUS /////////////
GLuint selectBuffer[100000];
glSelectBuffer(100000, selectBuffer);
glRenderMode(GL_SELECT);
CRect rect;
GetWindowRect(&rect);
long halfWidth = rect.Width() / 2;
long halfHeight = rect.Height() / 2;
GLdouble xcoord = 0;
if ( point.x < halfWidth )
xcoord = -( (double) point.x / (double) halfWidth );
else
xcoord = ((double) (point.x - halfWidth)) / (double) halfWidth;
GLdouble ycoord = 0;
if ( point.y < halfHeight )
ycoord = ((double) halfHeight - (double) point.y) / ((double) halfHeight);
else
ycoord = - ( (double) ( point.y - halfHeight ) / (double) halfHeight );
GLint viewport[4];
glGetIntegerv( GL_VIEWPORT, viewport );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPickMatrix( point.x, rect.Height() - point.y - 1, 2, 2, viewport );
DrawGLScene(true);
glFlush();
long hits = glRenderMode( GL_RENDER );
if (hits > 0 )
{
int glItem = selectBuffer[3];
theParent->UpdateStatus( m_MemoryBlocks[glItem] );
m_CurrentlySelected = glItem;
}
}
glViewport(m_OriginX,m_OriginY,m_Width,m_Height);
ForceDraw();
CWnd::OnMouseMove(nFlags, point);
}
void COpenGLControl::OnRButtonDown(UINT nFlags, CPoint point)
{
m_PrevRDownY = point.y;
m_PrevRDownX = point.x;
CWnd::OnRButtonDown(nFlags, point);
}
void COpenGLControl::CheckInit()
{
if ( !m_OpenGLInitialized )
{
CRect rect;
GetWindowRect(&rect);
m_Width = m_DefaultWidth = rect.Width();
m_Height = m_DefaultHeight = rect.Height();
dc = new CClientDC(this); //Get device context of window
openGLDevice.create(dc->m_hDC); //Create opengl rendering context
InitGL();
}
}
void COpenGLControl::OnRButtonDblClk(UINT nFlags, CPoint point)
{
m_OriginX = 0;
m_OriginY = 0;
m_Width = m_DefaultWidth;
m_Height = m_DefaultHeight;
glViewport(m_OriginX,m_OriginY,m_Width,m_Height);
ForceDraw();
CWnd::OnRButtonDblClk(nFlags, point);
}