|
Try with an ISAPI extension. You can send HTTP headers and read resoponses very easily. Search MSDN for CHttpServer and CHttpServerContext classes.
Best regards,
Alexandru Savescu
|
|
|
|
|
Actually, I want to do this on the client side.
/ravi
"There is always one more bug..."
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Has anybody been able to pull this off?
I am able to get a tooltip to work over the edit box portion, but
when the dropdown is active, I can't capture mousemoves over the dropdown
or get tooltips to show up no matter what I do!
Please advise if you can
Thanks
-Julie
|
|
|
|
|
I need to create a MDIChildFrame with a caption bar , a minimize and a maximise button . I want to get rid of the Close icon for the Childframe on the rightmost corner . How do i create this ?
Thanks
|
|
|
|
|
While creating the active x component i unchecked the visible radio button. How do I make the component visible in my Dialog application during runtime. My active x class CActiveX derives from CWnd.
thanks
|
|
|
|
|
ShowWindow(SW_SHOW)
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I have a function that taken a variable argument list. I wanted to just forward those arguments to another function that also takes a variable argument list.
Example:
void f2(const char* string, ...);
void f1(const char* string, ...)
{
... (prepend something to string, call it string2)
f2(string2, ?); //what goes in ?
}
What needs to be done to make this work?
Thanks
|
|
|
|
|
It can be done in a wildly non-portable fashion just like this (some details may need more careful handling for this to actually work): the variable argument list is stored in the stack and its beginning can be accessed with the macro va_start . So one can just copy a large enough portion of the stack and transfer it to f2 . The scheme is as follows:
struct stack_chunk
{
char memory[1024];
};
void f1(const char *string,...)
{
stack_chunk chunk;
va_list v;
va_start(v,string);
memcpy(&chunk,v,sizeof(chunk));
va_end(v);
...
f2(string2,chunk);
} Please tell us it this worked.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Yep, this worked. Thanks!!!
|
|
|
|
|
You can have a look at the wvsprintf function.
Best regards,
Alexandru Savescu
|
|
|
|
|
Hello all, I was wondering if someone could help me with this little problem.
I have the class constructor where I initialize protected member m_categoria (LPCTSTR):
CAdministrador::CAdministrador()
{
char buffer[_MAX_PATH];
_getcwd( buffer, _MAX_PATH );
CString nom = "";
nom = nom + buffer + "\\General";
m_categoria = nom;
AfxMessageBox(m_categoria);
}
The value comes out Ok in the message box; but then I try to look at the value in another function and I get crap:
BOOL CAdministrador::AgregarCategoria(LPCTSTR nombre)
{
AfxMessageBox(categoria);
CString nom = "";
nom = nom + m_categoria + "\\" + nombre;
if (_mkdir(nom) == 0)
return TRUE;
else
return FALSE;
}
The call is simply this:
CAdministrador admin;
if (!admin.AgregarCategoria("blah"))
AfxMessageBox("didn't work...");
Please excuse me if this question is extremely dumb
marcela bovio
|
|
|
|
|
Hola Marcela!
When you write
m_categoria = nom; you're accessing the internal representation (as a LPCTSTR ) of the CString nom . m_categoria will be OK as long as these two conditions hold:nom is not modified.nom is not destroyed. The latter is precisely what's happening when the constructor exits, so m_categoria will basically point to some junk area in the heap from now on. Best way to handle this is declaring m_categoria as a CString itself, so that it keeps and manages its own memory.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Man, you're fast. So often I see a question, click on it to read it, and when I do, you've just answered it !!!
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
"I'm somewhat suspicious of STL though. My (test,experimental) program worked first time. Whats that all about??!?!
- Jon Hulatt, 22/3/2002
|
|
|
|
|
And I lose quite a bit of time doing the pretty HTML formatting
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thank you!
marcela bovio
|
|
|
|
|
I have a dialog window application, and i need to know how to add tool tip text to a button. Can someone please help me with this one. PLEASE!!!!! I do not want to have to use someone's pre built classes either.
|
|
|
|
|
Look at the buttons section here at CodePeoject. Davide Calabro's CButtonST v3.4 (MFC Flat buttons) seems a popular one, and includes a lot of additional goodies.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
You need to override the PreTranslateMessage member function of your CDialog class and call the CMyToolTipCtrl.RelayEvent
Best regards,
Alexandru Savescu
|
|
|
|
|
Argh....
I have code that looks like this:
in "ObjectCache.h":
template <class T>
class CObjectCache {
...
};
in "App.h":
#include "ObjectCache.h"
#include "DataObject.h"
class CApp {
CObjectCache<CDataObject> m_Cache;
...
};
Can anyone think of any reason why the compiler would be yacking on the m_Cache line? It's telling my that "m_Cache uses undefined class 'CObjectCache<class CDataObject>'
But as far as I can see, the class is defined - everything is defined in ObjectCache.h and it's included. And everything for the contained class CDataObject is defined in DataObject.h that's included.
I've transplanted this code into a plain application, and it works fine. In my MFC application, it's crapping out.
Any ideas at all?
J
|
|
|
|
|
Maybe it's the precompiled headers feature playing tricks again. Make sure your first #include in every .cpp is stdafx.h . If this doesn't work, try a "Rebuild all" as a last resort.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Joaquín M López Muñoz wrote:
Make sure your first #include in every .cpp is stdafx.h.
Done.
Joaquín M López Muñoz wrote:
If this doesn't work, try a "Rebuild all" as a last resort.
Doesn't fix it.
I'm quite stumped. I've even dug through the preprocessor output (/E option) and my template is defined nicely (and so is the contained class).
ARrrrrgh.
J
|
|
|
|
|
Why don't you post your code here? Sometimes some obvious error is just yelling at you from the code and one just does not notice.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Ok, it's gigantic though. Apologies for posting so much, but I have a feeling even this isn't enough to see the whole problem...
What follows is three class definitions. The first is the template that handles caching. This class has been transplanted to several other contexts and compiles just fine. The second class is one of the classes I'm trying to contain in the cache template. It just houses a bunch of data - you probably don't need to worry about the details. The third class is the MFC document object. It aggregates one of the cache templates for caching CDataSlice objects.
The compile error is:
flawdoc.h(51) : error C2079: 'm_SliceCache' uses undefined class 'CObjectCache<class CDataSlice>'
and it occurs in every file that includes flawdoc.h (which is most of the project). Line 51 is the line that defines the contained CObjectCache<CDataSlice> m_SliceCache in CFLAWDoc.
Thanks for taking the time, Joaquin. If you can find anything, I'll owe you big time.
J
/* ObjectCache.h
*
*
*/
#ifndef _OBJECTCACHE_H_
#define _OBJECTCACHE_H_
#include <list>
/* CObjectCache
*
* This class provides cached objects. Initialization simply ensures that
* there is at least one block's worth of objects available. New object
* are acquired through GetFreeObject(). When objects are no longer needed,
* they can be returned to the cache through ReleaseObject(). The destructor
* makes sure that all memory gets cleaned up nicely.
*/
template <class T>
class CObjectCache {
// Block Size
//
// m_nBlockSize is the size of block set for this instance of the cache.
// It represents the number of objects to be stored in each cache block.
int m_nBlockSize;
// Block List
//
// This is a list of pointers to object blocks allocated by the cache.
// When a new block needs to be added, it is allocated and initialized,
// and then its base pointer is added to this list. Blocks are only
// removed from this list when the cache is destroyed.
std::list<byte *> m_listBlocks;
// Free List
//
// This is a list of unused objects. Objects are removed from the front of
// this list when required, and they are cleared and placed on the back
// of this list when released.
std::list<T *> m_listFree;
// AddBlock()
//
// This helper routine allocates a new block of objects, clears them, and
// then adds a pointer to each one to the free list. It returns true if
// successful - false if the allocation fails.
bool AddBlock() {
byte *pBase;
T *pT;
pBase = new byte[m_nBlockSize * sizeof(T)];
if(pBase == NULL) return false;
memset(pBase, 0, m_nBlockSize * sizeof(T));
m_listBlocks.push_back(pBase);
for(int i = 0; i < m_nBlockSize; i++) {
pT = new ((void *) &pBase[i * sizeof(T)]) T();
pT->Clear();
m_listFree.push_back(pT);
}
return true;
}
public:
CObjectCache(int nBlockSize = 1000) :
m_nBlockSize(nBlockSize) {}
virtual ~CObjectCache() {
std::list<byte *>::iterator b;
for(b = m_listBlocks.begin(); b != m_listBlocks.end(); b++) {
delete [] *b;
*b = NULL;
}
m_listBlocks.clear();
m_listFree.clear();
}
// Initialization
//
// This routine fills the free list with one block of empty slices.
bool Initialize(int nBlockCount = 1) {
if(m_listFree.size() == 0) {
for(int i = 0; i < nBlockCount; i++)
if(!AddBlock()) return false;
return true;
}
return true;
}
// Acquisition
//
// This routine returns the next available free object. If the free list
// is empty, a new block is added. If AddBlock() fails, this routine
// returns NULL.
T *GetFreeObject() {
T *pT;
if(m_listFree.empty()) {
if(!AddBlock()) {
return NULL;
}
}
pT = m_listFree.front();
m_listFree.pop_front();
return pT;
}
// Release
//
// This routine clears and returns the passed object to the free list.
void ReleaseSlice(T *pT) {
ASSERT(pT);
pT->Clear();
m_listFree.push_back(pT);
}
};
/* DataSlice.h
*
*
*/
#ifndef _DATASLICE_H_
#define _DATASLICE_H_
#include "PythonObject.h"
#include "Interfaces.h"
#include "ObjectCache.h"
class CProbeCorrection;
class CSoftwareGain;
class CPosF;
/* CDataSlice
*
* This class represents a single rotary slice of data in one channel of a
* C-Scan.
* The best way to use this class is to create a new instance passing the
* transformed axial position and raw encoder count. Then, call Load()
* passing and open and properly positioned file stream and a valid CPosF
* object representing the stage 0 offsets that are needed.
*/
class CDataSlice : public ICScanSlice, public CPythonObject {
PO_DECLARE_OBJECT();
// Clear
//
// This flag is set when the slice has been cleared. It allows you to call
// Initialize() and pass the axial position. I didn't want anyone calling
// a mutator like SetAxialPosition() at any time because it could
// possibly mess a few things up.
bool m_bClear;
// Stage 0
//
// At this stage, the data consists of the raw points loaded out of the
// file with the station-specific and inspection-head-specific offsets
// applied. The encoder count value is the raw value loaded from the file
// and is not propagated to stages 1 and 2.
int m_nEncoderCount;
float m_fStage0AxialPosition;
byte m_byStage0Min;
byte m_byStage0Max;
byte m_abyStage0Data[3600];
// Stage 1
//
// At this stage, the data consists of the stage 0 data with the probe
// corrections applied.
float m_fStage1AxialPosition;
byte m_abyStage1Data[3600];
// Stage 2
//
// At this stage, the data consists of the stage 1 data with the software
// gain applied. (Arguably, we probably don't need m_fStage2AxialPosition
// because at present, no further transformations are applied and the
// position will always be the same as the stage 1 position.)
float m_fStage2AxialPosition;
byte m_byStage2Min;
byte m_byStage2Max;
byte m_abyStage2Data[3600];
// ApplyRotaryOffset
//
// This helper routine applies the given rotary offset to the source data
// array while copying to the destination data array.
void ApplyRotaryOffset(byte *abyDest, byte *abySource, int nRotary);
// ApplyAxialOffset
//
// This helper routine applies the given axial offset to the axial
// position variable pointed to by pfDest.
void ApplyAxialOffset(float *pfDest, float fAxial);
// ApplyGain
//
// This helper routine applies the given multiplier gain to all the points
// in the source data array as it is being copied to the destination data
// array.
void ApplyGain(byte *abyDest, byte *abySource, float fMultiplier);
// PrepareStage1
//
// This helper routine clears all data from stage 1 and rebuilds it from
// stage 0 data and the passed probe correction.
void PrepareStage1(CProbeCorrection *pPC);
// PrepareStage2
//
// This helper routine clears all data from stage 2 and rebuilds it from
// stage 1 data and the passed software gain.
void PrepareStage2(CSoftwareGain *pSG);
// Hidden Constructor and Destructor
//
// We only want the slice cache to be able to construct and destroy data
// slices. We make them private but allow the cache to be our friend.
public: // TODO: put this back the way it was!!
//friend class CObjectCache<CDataSlice>;
CDataSlice();
virtual ~CDataSlice();
public:
// Placement operator new()
//
// It looks like we don't need this. This type of initialization is new to
// me, and I haven't figured out what the compiler generates for me. But
// I can compile and run the application just fine with this override
// commented out, I'm guessing the compiler has figured it out.
//inline void *operator new(size_t, void *p) {return p;}
// Initialization
//
inline void Initialize(float fAxialPosition, int nEncoderCount) {
ASSERT(m_bClear);
m_nEncoderCount = nEncoderCount;
m_fStage0AxialPosition = fAxialPosition;
}
// Clear()
//
void Clear();
// ReapplyEnvironment
//
// This routine rebuilds both stage 1 and 2 data sets based on the passed
// probe correction and software gain. Until this is called for the
// first time (after loading), all retrieved data will be zeros.
void ReapplyEnvironment(CProbeCorrection *pPC, CSoftwareGain *pSG);
// ReapplySoftwareGain
//
// This routine rebuilds stage 2 data based on the passed software gain.
void ReapplySoftwareGain(CSoftwareGain *pSG);
// Load
//
// This routine loads a full slice of data into stage 0 from the given
// file stream. It also applies the passed offset. After loading data,
// always remember to reapply the environment settings.
bool Load(CFile *pFile, CPosF &rposOffset);
// operator<()
//
// This operator is used when sorting data slices. It compares axial
// positions, and returns true if the axial position of this slice is
// less than the axial position of the passed slice.
bool operator<(const CDataSlice &s);
// ICScanSlice
//
// These methods implement the ICScanSlice interface.
inline int GetEncoderCount() const {return m_nEncoderCount;}
inline float GetAxialPosition() const {return m_fStage2AxialPosition;}
inline byte GetMin() const {return m_byStage2Min;}
inline byte GetMax() const {return m_byStage2Max;}
inline byte *GetData() {return m_abyStage2Data;}
inline byte GetDataAt(int nIndex) const {
ASSERT(nIndex >= 0);
ASSERT(nIndex < 3600);
return m_abyStage2Data[nIndex];
}
// Python Access
//
PO_DECLARE_GETATTR();
};
#endif
#endif
/* FLAWDoc.h
*
*
*/
#ifndef _FLAWDOC_H_
#define _FLAWDOC_H_
#include "Doc.h"
#include "Interfaces.h"
#include "PythonObject.h"
#include "DataSet.h"
#include "DataChannel.h"
#include "Environ.h"
#include "RevData.h"
#include "AnnotationCollection.h"
#include "ObjectCache.h"
#include "DataSlice.h"
/* CFLAWDoc
*
*/
class CFLAWDoc :
public CDoc,
public ICScanDocument,
public CPythonObject,
public IEnvironChangeListener
{
PO_DECLARE_OBJECT();
// New Data
//
// This is the collection of channels - each a collection of slices - all
// pre-transformed and ready to be merged for drawing. Each slice
// contains three levels of data: raw (including station and head
// offsets), probe-corrected and software-gained.
CDataSet *m_pData;
// Data Slice Cache
//
// This cache stores preallocated CDataSlice objects. It speeds the load
// process. Slice objects need to be returned here when they are no
// longer needed.
//typedef CObjectCache<CDataSlice> SliceCache;
//SliceCache m_SliceCache;
CObjectCache<CDataSlice> m_SliceCache;
// Environment
//
// This is the environment that the user is currently using.
CEnviron m_ENV;
// Indications
//
CAnnotationCollection m_AnnotationCollection;
// Helpers
//
void LoadCScanProperties();
void LoadBScanProperties();
protected:
DECLARE_DYNCREATE(CFLAWDoc)
// _GetDocumentType
//
// This routine is overridden from CDoc and provides the type of the
// document.
virtual inline DocType _GetDocumentType() {return C_SCAN;}
// _QueryInterface
//
// This routine returns the CScan document interface if C_SCAN is passed.
// Otherwise it returns NULL. This routine is for conversion of interface
// pointers. If you have an IDocument pointer and you know it's a CScan
// document (from calling GetDocumentType()), you can query for the
// ICScanDocument interface by calling this routine.
virtual inline void *_QueryInterface(DocType t) {
if(t == C_SCAN) return static_cast<ICScanDocument *>(this);
return NULL;
}
// Error State
void _DumpState(CCrashDump &cd);
public:
CFLAWDoc();
virtual ~CFLAWDoc();
// ICScanDocument
//
// These routines implement the ICScanDocument interface.
inline int GetChannelCount() const {return m_pData->GetChannelCount();}
inline ICScanChannel *GetChannel(int nIndex) const {
ASSERT(nIndex >= 0);
ASSERT(nIndex < m_pData->GetChannelCount());
return m_pData->GetChannel(nIndex);
}
// Internal ICScanDocument Equivalents
//
// Use these methods when accessing the channels from within the Flaw
// application (as opposed to from an extension command library).
inline CDataChannel *InternalGetChannel(int nIndex) const {return m_pData->GetChannel(nIndex);}
// GetData()
//
// This method provides access to all channels of data directly.
inline CDataSet *GetData() const {return m_pData;}
// GetNumRecords()
//
// This routine returns the number of slices in the first channel. It's
// here to save a bit of clutter.
inline int GetNumRecords() {
if(m_pData == NULL) return 0;
return m_pData->GetChannel(0)->GetSliceCount();
}
// UpdateRawData()
//
// This routine updates the document's state from the data file. If the
// file has not changed, nothing happens. Otherwise, the new data is
// loaded and displayed.
bool UpdateRawData(bool bShowProgress = true);
// Environment Access
//
inline CEnviron &GetEnv() {return m_ENV;}
void SetEnv(CEnviron &env);
// IEnvironChangeListener
//
// These routines implement the IEnvironChangeListener interface.
void OnEnvironProbeCorrectionChanged(int nChannel);
void OnEnvironSoftwareGainChanged(int nChannel);
// Python
//
PO_DECLARE_GETATTR();
PO_DECLARE_SETATTR();
//{{AFX_VIRTUAL(CFLAWDoc)
public:
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
virtual void DeleteContents();
virtual BOOL OnNewDocument();
//}}AFX_VIRTUAL
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
//{{AFX_MSG(CFLAWDoc)
afx_msg void OnUpdateViewProperties(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
#endif
J
|
|
|
|
|
Could you post the offendig .cpp as well?
Also, I've seen an unmatched #endif , but I guess it's a only copy&paste error.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
<small><b>Joaquín M López Muñoz wrote:
</b></small><i>Also, I've seen an unmatched #endif, but I guess it's a only copy&paste error. </i>
As stupid as it would have made me look, you got my hopes up there! But yes, just a copy and paste error.
What follows is one of the offending .cpp files (with the corresponding header file as well). I'm sure the only thing you need to look at it the include order at the top of the .cpp.
Flaw.hpp just includes a bunch of constants carried over from the previous version.
J
/* BFrame.h
*
*
*/
#ifndef _BFRAME_H_
#define _BFRAME_H_
#include "Flaw.hpp"
class CFLAWDoc;
class CBFrame
{
private:
// Data is essentially a 3D graph
// ------------------------------
// so list the dimensions
cbDIMENSIONS size;
short frame_number; // current frame (starts from 0)
short line_number; // current line within current frame
LONG channel_offset; // beginning of B-Scan Channel
POSL current; // current position corresponding to
// data (raw axial)
public:
CFile f; // File class
void SetDoc (CFLAWDoc *p);
CFLAWDoc *pDoc; // ptr to the Document Class
DWORD Axial ();
short WavePoints ();
short FrameNumber ();
short LineNumber ();
short RotaryPoints ();
short AxialPoints ();
void SetAxialPoints (short ap);
void SetChannelOffset (long co);
CBFrame (CString FileName, // Constructor for reading B-Scan
LONG ChannelOffset);
virtual ~CBFrame();
cbRETURN_CODE Read (short *frame, short *line, BYTE * data);
cbRETURN_CODE ReadFramePosition (short frame, POSL *pos);
BYTE Seek (DWORD axial); // Locate frame associated with
// specified axial position (raw value)
// in units of 0.00807
BYTE Seek (short frame, short line, short point = 0);
BYTE Seek (short frame, POSL *pos);
BYTE Seek (short frame);
BYTE AdvanceFrame (BYTE inc);
};
#endif // !defined(AFX_BFRAME_H__76544D71_721F_11D4_88BF_006008662998__INCLUDED_)
// BFrame.cpp: implementation of the CBFrame class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BFrame.h"
#include "FlawDoc.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// Constructor for Circumferential B-scan frame - read
// ============================================
// file is expected to be already opened, as specified by FileName
// and offset to beginning of data specified by ChannelOffset
CBFrame::CBFrame (CString FileName, long ChannelOffset)
{
channel_offset = ChannelOffset;
CFileException e;
if (!f.Open (FileName,
CFile::modeRead |
CFile::shareDenyWrite |
CFile::typeBinary,
&e))
{
AfxMessageBox ("Error: Unable to open File",MB_OK, NULL);
}
long seek = f.Seek (ChannelOffset, CFile::begin);
f.Read (&size.WavePoints, sizeof (size.WavePoints));
f.Read (&size.RotaryPoints, sizeof (size.RotaryPoints));
f.Read (&size.AxialPoints, sizeof (size.AxialPoints));
frame_number = 0;
line_number = 0;
}
CBFrame::~CBFrame()
{
}
// Functions to provide access to private data variables
short CBFrame::WavePoints ()
{
return size.WavePoints;
}
short CBFrame::FrameNumber ()
{
return frame_number;
}
short CBFrame::LineNumber ()
{
return line_number;
}
short CBFrame::RotaryPoints ()
{
return size.RotaryPoints;
}
DWORD CBFrame::Axial ()
{
return current.axial;
}
short CBFrame::AxialPoints ()
{
return size.AxialPoints;
}
// Functions to alter private data variables
void CBFrame::SetChannelOffset (long co)
{
channel_offset = co;
}
void CBFrame::SetAxialPoints (short ap)
{
size.AxialPoints = ap;
}
// Seek a particular frame based on axial value
// ============================================
// axial is raw value in units of flAXIAL_MM_PER_BIT
BYTE CBFrame::Seek (DWORD axial)
{
long offset;
if ((axial >= (DWORD) pDoc->GetFirstPosition()->GetAxial()
) &&
(axial <= (DWORD) pDoc->GetLastPosition()->GetAxial()
)
)
{
// Remember
// --------
// that the axial increment is rounded up to the nearest
// measurable axial value
WORD inc;
inc = pDoc->GetAxialIncrement();
inc += (1 << flAXIAL_BITS_DROPPED) - 1;
inc >>= flAXIAL_BITS_DROPPED;
// June 1, 1993
// ------------
// remove roundup with (inc >> 1). Gives more accurate mapping
frame_number = (short)( (axial -
(DWORD) pDoc->GetFirstPosition()->GetAxial())/inc);
// Ensure frame number within range
// --------------------------------
if (frame_number < 0)
{
frame_number = 0;
}
if (frame_number >= size.AxialPoints)
{
frame_number = size.AxialPoints - 1;
}
offset = channel_offset + 6 /* sizeof (cbDIMENSIONS) */;
offset += frame_number * ((long) size.WavePoints * size.RotaryPoints +
6 /* sizeof (POSL) */);
f.Seek (offset, CFile::begin);
return TRUE;
}
return FALSE;
}
// Seek the beginning of a particular frame
// ========================================
// and return the position information associated with that frame
BYTE CBFrame::Seek (short frame, POSL *pos)
{
long offset;
// Make sure parameters are legal
// ------------------------------
if (!(frame >= 0 && frame < size.AxialPoints))
{
return (FALSE);
}
offset = channel_offset + 6 /* sizeof (cbDIMENSIONS) */;
offset += frame * ((long) size.WavePoints * size.RotaryPoints +
6 /* sizeof (POSL) */);
f.Seek (offset, CFile::begin);
f.Read (pos, 6 /* sizeof (POSL) */);
frame_number = frame;
line_number = 0;
return (TRUE);
}
// Seek the beginning of a particular frame
// ========================================
// Recall that the first record of each frame is the position associated
// with that frame
BYTE CBFrame::Seek (short frame)
{
long offset;
/* Make sure parameters are legal
------------------------------ */
if (!(frame >= 0 && frame < size.AxialPoints))
{
return (FALSE);
}
offset = channel_offset + 6 /* sizeof (cbDIMENSIONS) */;
offset += frame * ((long) size.WavePoints * size.RotaryPoints +
6 /* sizeof (POSL) */);
f.Seek (offset, CFile::begin);
frame_number = frame;
line_number = 0;
return (TRUE);
}
// Seek particular frame and line, and point in line
// =================================================
byte CBFrame::Seek (short frame, short line, short point)
{
long offset;
/* Make sure parameters are legal
------------------------------ */
if (!(frame >= 0 && frame < size.AxialPoints))
{
return (FALSE);
}
if (!(line >= 0 && line < size.RotaryPoints))
{
return (FALSE);
}
offset = channel_offset + 6 /* sizeof (cbDIMENSIONS) */;
offset += frame * ((long) size.WavePoints * size.RotaryPoints +
6 /* sizeof (POSL) */) + 6 /* sizeof (POSL) */;
offset += (long) line * size.WavePoints + point;
f.Seek (offset, CFile::begin);
frame_number = frame;
line_number = line;
return (TRUE);
}
// Read next line
// ==============
// Returns pointer to buffer if successful
// Returns NULL at end-of-frame, and end-of-file.
// end-of-frame can be distinquished by end-of-file by examining
// frame and line. If end-of-file, frame = line = -1.
// If end-of-frame, frame = next frame value, line = 0.
cbRETURN_CODE CBFrame::Read (short *frame, short *line, BYTE * data)
{
/* Special case if line_number = 0
-------------------------------
read in the position. This may be optionally displayed by the system */
if (line_number == 0)
{
Seek (frame_number);
if (f.Read (¤t, 6 /* sizeof (POSL) */) != 6 /* sizeof (POSL) */)
{
return cbUNKNOWN;
}
}
/* Is there another line to read in present frame?
----------------------------------------------- */
if (line_number < size.RotaryPoints)
{
*line = line_number++;
*frame = frame_number;
if (f.Read (data, size.WavePoints) != (unsigned) size.WavePoints)
{
return cbUNKNOWN;
}
return (cbOK);
}
/* Is there another frame to read?
------------------------------- */
if (frame_number < size.AxialPoints - 1)
{
*frame = ++frame_number;
*line = line_number = 0;
return cbEND_OF_FRAME;
}
/* End of file
----------- */
*frame = frame_number = -1;
*line = line_number = -1;
return cbEND_OF_DATA;
}
// This advances the frame number if possible. The parameter is
// used to indicate whether to increment or decrement the
// frame number.
BYTE CBFrame::AdvanceFrame (BYTE inc)
{
/* Special case
------------
line_number should be 0, but if not, advance frame_number */
if (line_number != 0)
{
if (frame_number < size.AxialPoints - 1)
{
++frame_number;
}
}
/* Is there another frame to read?
-------------------------------
Remember that frame_number is set at the next frame, not the
current frame */
if (inc)
{
if (frame_number < size.AxialPoints)
{
return (TRUE);
}
return (FALSE);
}
// else
{
if (frame_number > 1)
{
frame_number -= 2;
return (TRUE);
}
return (FALSE);
}
}
// This function retrieves the recorded position information
// associated with the axial slice in the given frame.
cbRETURN_CODE CBFrame::ReadFramePosition (short frame, POSL *pos)
{
if (!Seek (frame))
{
return cbUNKNOWN;
}
if (f.Read (pos, 6 /* sizeof (POSL) */))
{
return cbUNKNOWN;
}
return cbOK;
}
// Assign pointer to the Document Class
void CBFrame::SetDoc(CFLAWDoc *p)
{
pDoc = p;
}
J
|
|
|
|
|