I have a program that compiles and runs with the exception of a couple of pop-up menu items that are dependent on an image (bitmap, specifically) being initialized. I can find the part of the code that generates the error message, but since there are no syntax errors I am not quite sure why this isn't working. If anyone thinks they might be able to help I can post some parts of the code....if not, a good tip on how to identify what classes and functions are dependent on each other so that I can trace what the code is doing would be great help. I am using VS2010.
Here is the code from one of the entries in the pop-up menu that leads to the bitmap problem:
void CWinSTMView::OnImageLinDcOffset()
{
CWinSTMDoc *pDoc = CreateNewDoc(GetDocument());
strcat(pDoc->m_ChanHead[0]->AppliedFilters,"Linear DC Offset. ");
int ave;
for(int i=0;i< m_NScans;i++)
{
ave = 0;
for(int j=0;j< m_NPts;j++)
{
ave += pDoc->m_Chan[0]->ipData[j+i*m_NPts];
}
ave /= m_NPts;
for(int j = 0;j< m_NPts;j++)
{
pDoc->m_Chan[0]->ipData[j+i*m_NPts] -= ave;
}
}
m_Change = 1;
Invalidate(true);
}
The above code does not execute, it leads to the following code execution:
AfxMessageBox("Bitmap has not been init");
from I think this part of the program:
#include "stdafx.h"
#include "winstmbmp.h"
CWinSTMBmp::CWinSTMBmp(void)
{
ZeroMemory(&m_HistogramData,sizeof(int)*256);
m_ImageMode = IMAGE_MODE_HORIZONTAL;
m_Inversion = false;
m_Derivative = false;
m_LineDC = false;
m_Render = false;
m_Bitmap = NULL;
m_BmpBits = NULL;
m_SizeX = 0;
m_SizeY = 0;
}
CWinSTMBmp::~CWinSTMBmp(void)
{
if(m_Bitmap != NULL)
DeleteObject(m_Bitmap);
}
bool CWinSTMBmp::Init(int sizex, int sizey, RGBQUAD* Pal)
{
if (m_Bitmap != NULL)
DeleteObject(m_Bitmap);
if (m_Bitmap == NULL)
{
ZeroMemory ( &m_ImageInfo, sizeof (BITMAPINFO) );
m_ImageInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
m_ImageInfo.bmiHeader.biWidth = sizex;
m_ImageInfo.bmiHeader.biHeight = -sizey;
m_ImageInfo.bmiHeader.biPlanes = 1;
m_ImageInfo.bmiHeader.biBitCount = 32;
m_ImageInfo.bmiHeader.biCompression = BI_RGB;
m_ImageInfo.bmiHeader.biSizeImage = 0;
m_Bitmap=CreateDIBSection ( NULL, &m_ImageInfo, DIB_RGB_COLORS, (void **)&m_BmpBits, NULL, NULL );
}
memcpy(m_RGB,Pal,sizeof(RGBQUAD)*256);
m_SizeX = sizex;
m_SizeY = sizey;
return true;
}
HBITMAP CWinSTMBmp::GetHBitmap(void)
{
return HBITMAP(m_Bitmap);
}
BITMAPINFO* CWinSTMBmp::GetBmpInfo(void)
{
return &m_ImageInfo;
}
bool CWinSTMBmp::Render(int* Data,int Min, int Max)
{
if(Data == NULL)
{
AfxMessageBox("Passing in a NULL Data Ptr");
return false;
}
if(m_Bitmap == NULL)
{
AfxMessageBox("Bitmap has not been init");
return false;
}
m_Min = Min;
m_Max = Max;
ZeroMemory(m_HistogramData,sizeof(int)*256);
int temp;
if(m_LineDC)
{
double LRange = (Max + Min)/2;
Max -= LRange;
Min -= LRange;
}
double ColorScale = 256.0 / (Max - Min);
int SlowScanInc, FastScanInc,SlowMax,FastMax;
if(m_ImageMode == IMAGE_MODE_HORIZONTAL)
{
SlowScanInc = m_SizeX;
FastScanInc = 1;
SlowMax = m_SizeY;
FastMax = m_SizeX;
}
else
{
SlowScanInc = 1;
FastScanInc = m_SizeX;
SlowMax = m_SizeX;
FastMax = m_SizeY;
}
for(int K = 0; K < SlowMax; K++)
{
int slow = K * SlowScanInc;
double Ave = 0.0;
if(m_LineDC)
{
for(int J = 0; J < FastMax; J++)
{
int fast = J * FastScanInc;
int index = slow+fast;
if(!m_Derivative)
Ave += Data[index];
if(m_Derivative && J != 0)
Ave += Data[index - FastScanInc] - Data[index];
}
if(m_ImageMode == IMAGE_MODE_HORIZONTAL)
Ave /= m_SizeX;
else
Ave /= m_SizeY;
}
for(int J = 0; J < FastMax; J++)
{
int temp=0;
int fast = J * FastScanInc;
int index = slow+fast;
if(!m_Derivative)
{
temp = round((Data[index] - Min - Ave) * ColorScale);
}
if(m_Derivative && J != 0)
{
temp = round((Data[index - FastScanInc] - Data[index] - Min - Ave) * ColorScale);
}
temp = min(temp,255);
temp = max(temp,0);
m_HistogramData[temp]++;
if(!m_Inversion)
{
m_BmpBits[index] = m_RGB[255-temp];
}
else
{
m_BmpBits[index] = m_RGB[temp];
}
}
}
return true;
}
RGBQUAD* CWinSTMBmp::GetBmpBits(void)
{
return m_BmpBits;
}
void CWinSTMBmp::SetLineDC(bool enable)
{
m_LineDC = enable;
}
void CWinSTMBmp::SetInversion(bool enable)
{
m_Inversion = enable;
}
void CWinSTMBmp::SetDer(bool enable)
{
m_Derivative = enable;
}
void CWinSTMBmp::UpdatePallet(RGBQUAD* Pal)
{
memcpy(m_RGB,Pal,sizeof(RGBQUAD)*256);
}
int* CWinSTMBmp::GetHistogramData(void)
{
return m_HistogramData;
}
void CWinSTMBmp::SetProperties(bool Derivative, bool LineDC, int Direction, bool Invert)
{
m_Inversion = Invert;
m_Derivative = Derivative;
m_LineDC = LineDC;
m_ImageMode = Direction;
}
void CWinSTMBmp::DeleteBmp(void)
{
if(m_Bitmap != NULL)
DeleteObject(m_Bitmap);
ZeroMemory(&m_HistogramData,sizeof(int)*256);
m_ImageMode = IMAGE_MODE_HORIZONTAL;
m_Inversion = false;
m_Derivative = false;
m_LineDC = false;
m_Render = false;
m_Bitmap = NULL;
m_BmpBits = NULL;
m_SizeX = 0;
m_SizeY = 0;
}
bool CWinSTMBmp::RenderUI(unsigned short* Data, int Min, int Max)
{
if(Data == NULL)
{
AfxMessageBox("Passing in a NULL Data Ptr");
return false;
}
if(m_Bitmap == NULL)
{
AfxMessageBox("Bitmap has not been init");
return false;
}
m_Min = Min;
m_Max = Max;
ZeroMemory(m_HistogramData,sizeof(int)*256);
int temp;
if(m_LineDC)
{
double LRange = (Max + Min)/2;
Max -= LRange;
Min -= LRange;
}
double ColorScale = 256.0 / (Max - Min);
int SlowScanInc, FastScanInc,SlowMax,FastMax;
if(m_ImageMode == IMAGE_MODE_HORIZONTAL)
{
SlowScanInc = m_SizeX;
FastScanInc = 1;
SlowMax = m_SizeY;
FastMax = m_SizeX;
}
else
{
SlowScanInc = 1;
FastScanInc = m_SizeX;
SlowMax = m_SizeX;
FastMax = m_SizeY;
}
for(int K = 0; K < SlowMax; K++)
{
int slow = K * SlowScanInc;
double Ave = 0.0;
if(m_LineDC)
{
for(int J = 0; J < FastMax; J++)
{
int fast = J * FastScanInc;
int index = slow+fast;
if(!m_Derivative)
Ave += Data[index];
if(m_Derivative && J != 0)
Ave += Data[index - FastScanInc] - Data[index];
}
if(m_ImageMode == IMAGE_MODE_HORIZONTAL)
Ave /= m_SizeX;
else
Ave /= m_SizeY;
}
for(int J = 0; J < FastMax; J++)
{
int temp=0;
int fast = J * FastScanInc;
int index = slow+fast;
if(!m_Derivative)
{
temp = round((Data[index] - Min - Ave) * ColorScale);
}
if(m_Derivative && J != 0)
{
temp = round((Data[index - FastScanInc] - Data[index] - Min - Ave) * ColorScale);
}
temp = min(temp,255);
temp = max(temp,0);
m_HistogramData[temp]++;
if(!m_Inversion)
{
m_BmpBits[index] = m_RGB[255-temp];
}
else
{
m_BmpBits[index] = m_RGB[temp];
}
}
}
return true;
}
bool CWinSTMBmp::RenderMetaBmp(int * Data, int Min, int Max)
{
if(Data == NULL)
{
AfxMessageBox("Passing in a NULL Data Ptr");
return false;
}
if(m_Bitmap == NULL)
{
AfxMessageBox("Bitmap has not been init");
return false;
}
if(Min == 0 && Max == 0)
{
Min = m_Min;
Max = m_Max;
}
ZeroMemory(m_HistogramData,sizeof(int)*256);
int temp;
if(m_LineDC)
{
double LRange = (Max + Min)/2;
Max -= LRange;
Min -= LRange;
}
double ColorScale = 256.0 / (Max - Min);
int SlowScanInc, FastScanInc,SlowMax,FastMax;
if(m_ImageMode == IMAGE_MODE_HORIZONTAL)
{
SlowScanInc = m_SizeX;
FastScanInc = 1;
SlowMax = m_SizeY;
FastMax = m_SizeX;
}
else
{
SlowScanInc = 1;
FastScanInc = m_SizeX;
SlowMax = m_SizeX;
FastMax = m_SizeY;
}
for(int K = 0; K < SlowMax; K++)
{
int slow = K * SlowScanInc;
double Ave = 0.0;
if(m_LineDC)
{
for(int J = 0; J < FastMax; J++)
{
int fast = J * FastScanInc;
int index = slow+fast;
if(!m_Derivative)
Ave += Data[index];
if(m_Derivative && J != 0)
Ave += Data[index - FastScanInc] - Data[index];
}
if(m_ImageMode == IMAGE_MODE_HORIZONTAL)
Ave /= m_SizeX;
else
Ave /= m_SizeY;
}
for(int J = 0; J < FastMax; J++)
{
int temp=0;
int fast = J * FastScanInc;
int index = slow+fast;
if(!m_Derivative)
{
temp = round((Data[index] - Min - Ave) * ColorScale);
}
if(m_Derivative && J != 0)
{
temp = round((Data[index - FastScanInc] - Data[index] - Min - Ave) * ColorScale);
}
temp = min(temp,255);
temp = max(temp,0);
m_HistogramData[temp]++;
if(!m_Inversion)
{
m_BmpBits[(SlowMax-1)*SlowScanInc-slow +fast] = m_RGB[255-temp];
}
else
{
m_BmpBits[(SlowMax-1)*SlowScanInc-slow +fast] = m_RGB[temp];
}
}
}
return true;
}
void CWinSTMBmp::NewLUT(RGBQUAD* newRGB)
{
memcpy(m_RGB,newRGB,sizeof(RGBQUAD)*256);
}
An error message appears after I close the window in the running program saying, 'encountered an improper argument'. I haven't found this yet in the code. Also, when I run it in debug mode I get a 'Debug Assertion Failed!' for File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\filelist.cpp, at Line: 225.
Running with CLR and Run Time Exception Throws refers to the following section of code, with a break point at:
WinSTM.exe!CWinSTMDoc::CopyDoc(CWinSTMDoc * pDocNew, int chan) Line 486 + 0x3b bytes C++
WinSTM.exe!CWinSTMView::CreateNewDoc(CWinSTMDoc * pDoc) Line 2717 C++
WinSTM.exe!CWinSTMView::OnImageLinDcOffset() Line 5052 + 0x11 bytes C++
These calls refer to the following code:
void CWinSTMView::OnImageLinDcOffset()
{
CWinSTMDoc *pDoc = CreateNewDoc(GetDocument());
CreateNewDoc code reference:
if(((CWinSTMApp*)AfxGetApp())->m_Default.PmtForSave)
pNewDoc->SetModifiedFlag(true);
CopyDoc code reference:
CString OldPath = GetPathName();
pDocNew->SetPathName(OldPath + " *");
CString OldTitle = GetTitle();
pDocNew->SetTitle(OldTitle + " *");
pDocNew->m_Ready = true;
This brings me back to the code at the beginning. However, I am still not sure exactly what is going wrong.
Thanks for all the advice! I hope this is helpful for anyone else who is tracking down a bug in a program.
Best,
Andrew