|
in a .cpp file, you need to have:
#include "MyClass.h"
CBitmap myClass::MyBitmap;
-c
------------------------------
Smaller Animals Software, Inc.
http://www.smalleranimals.com
|
|
|
|
|
thanks, it was easy;)
Remi Morin
Rmorin@Operamail.com
Remi.Morin@Lyrtech.com
|
|
|
|
|
What is the difference between
[code]
char something[64];
[/code]
and
[code]
char something = new char[64];
...
delete something
[/code]
I only know that the memory is allocated different, but don't know exactly how.
Is there one initialization which is better or faster?
thanks for your help
|
|
|
|
|
in a function
MyFunction()
{
char something[64];
[code]
}
the memory is static with the function itself, it's mean that window allocate some memory for the function and that include this 64 char
it's why we don't have to bother to delete this memory, it' will be flushed whit the function itself.
function2()
{
[code]
char something = new char[64];
...
delete something
[/code]
}
this way you call a function who call window, windows allocate memory and return a pointer to this memory. in each case the memory is allocated by windows but in one case it is allocate whit (and for) the function and in the other case it is allocated dynamicaly. In fact the when you start you'r program the something[64] is allocated. And when you close you'r program it is desallocated so it is faster because it is allocated one time, and in the other case it is allocated each time you call this function.
Remi Morin
Rmorin@Operamail.com
Remi.Morin@Lyrtech.com
Le rêve est la seule chose vraiement réelle et vraiement consistante
|
|
|
|
|
You may try something very funny
class MyProjectView :public CView
{
...
public:
CString strTemp
...
}
void Function1(int paramControl)
{
char Something[64]
if(paramControl == 1){
sprintf(something,"test of allocation memory");
}
else{
strTemp.Format("%s",strTemp);
}
}
then somewhere call two time this function IN RELEASE (Debug mode do some initialisation and it will never work) like this
Function1(1);
Function1(2);
dc.TextOut(50,50,strTemp);
and you will be able to see test if allocation memory, because the space in memory for the function have never change the string is still there if you don't overwrite so you can "read" in the string what you have done before
Remi Morin
Rmorin@Operamail.com
Remi.Morin@Lyrtech.com
|
|
|
|
|
heuuuuu, soory it's false, in each case the memory is allocated on the stack. So don't read what I've said before, it's false. each of them are near to be the same. Sorry for the error.
Remi Morin
Rmorin@Operamail.com
Remi.Morin@Lyrtech.com
|
|
|
|
|
function2()
{
char* something = new char[64];
...
delete [] something;
}
1- New is returning a pointer !
2- Delete has to delete the array so use []
wimel
|
|
|
|
|
Differences:
char something[64];
An array of 64 elements, each of sizeof(char) bytes, is allocated on the stack and given the name "something". This is extremely fast, as it only requires the stack pointer to be moved down by 64 bytes. When the function returns, the stack is automatically cleaned up, which includes this array. The drawback is that number of elements in the array (64 in this case) must be predetermined at compile time. In fact, the compiler checks that this value is constant.
char* something = new char[64];
delete [] something;
An array of 64 elements, each of sizeof(char) bytes, is allocated on the heap and returned as a pointer which is given the name "something". This is typically a slower operation since the heap manager spends more time managing its available space for all dynamic allocations. It also requires that the programmer explicitly tell the heap when the memory is no longer needed (by calling delete). The benefit is that the program can set the size of the array (64 in this case) at run time. In other words, the value can just as well be an integer variable.
Regards,
Alvaro
|
|
|
|
|
With thanks to Michael Butler, I've figured out where my ATL project is dying. I have added four fields to my database. They are being populated correctly. Previously, retrieved my values like this:
_RecordsetPtr records = NULL;
records.CreateInstance(__uuidof(Recordset));
try
{
records->CursorType = adOpenStatic;
records->CursorLocation = adUseClient;
records->Open("SELECT * FROM FileDatabase",
_variant_t((IDispatch*)m_Connection, true), adOpenKeyset, adLockOptimistic,
adCmdUnknown);
}
catch(...)
{
}
records->MoveFirst();
vector<ISAFileEntry*> vecDatabase;
do
{
CComObject<CSAFileEntry>* pFileEntry = NULL;
CComObject<CSAFileEntry>::CreateInstance(&pFileEntry);
if (pFileEntry)
{
FieldsPtr spFields = records->GetFields();
string s = (bstr_t) spFields->Item["FileName"]->Value;
for (string::iterator it = s.begin(); it != s.end(); ++it)
if (*it == '?') *it = '\'';
pFileEntry->m_FileName = s.c_str();
pFileEntry->m_FileLength = spFields->Item["FileLength"];
pFileEntry->m_DownloadCount = spFields->Item["TimesDownloaded"];
pFileEntry->m_LastModified = spFields->Item["LastModified"];
but since adding four more fields, I find all my numeric values are being read a 0, although Access show me real values have been stored.
Changing to this:
string s = (bstr_t) spFields->Item["FileName"]->Value;
for (string::iterator it = s.begin(); it != s.end(); ++it)
if (*it == '?') *it = '\'';
pFileEntry->m_FileName = s.c_str();
pFileEntry->m_FileLength = spFields->Item["FileLength"]->Value;
pFileEntry->m_DownloadCount = spFields->Item["TimesDownloaded"]->Value;
pFileEntry->m_LastModified = spFields->Item["LastModified"]->Value;
pFileEntry->m_Frames = spFields->Item["Frames"];
pFileEntry->m_Seconds = spFields->Item["Seconds"];
pFileEntry->m_Width = spFields->Item["Width"];
pFileEntry->m_Height = spFields->Item["Height"];
Works for my old values ( I added ->Value to them ), but my new values are still 1, and if I add ->Value to them, it crashes in the first iteration. Can anyone suggest what might be the problem ?
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
Which "field" does it crash on? Do the names match the field names in the database? Do they all cause the problem or can you rem some out and it works?
I'm old fashioned and access my fields by position rather than name
variant_t vt;
vt = m_pRecordset->Fields->GetItem(variant_t((short)4))->GetValue();
Michael
|
|
|
|
|
Any of the four I've added, I've tried them all. Yes, the fields are spelled right, I've checked a bajillion times.
The following code is how the information got put into the database in the first place, and it's there and fine.
spFields->Item["FileName"]->Value = (bstr_t) temp;
spFields->Item["FilePath"]->Value = (bstr_t) bstrPath;
spFields->Item["FileLength"]->Value = (*it)->m_FileLength;
spFields->Item["LastModified"]->Value = (*it)->m_LastModified;
spFields->Item["TimesDownloaded"]->Value = (long)0;
spFields->Item["Frames"]->Value = lFrames;
spFields->Item["Seconds"]->Value = lSeconds;
spFields->Item["Width"]->Value = Width;
spFields->Item["Height"]->Value = Height;
What I don't get is how come it crashes when I add ->Value, otherwise it just returns 1 ? I mean, I know ADO crashes at the drop of a pin and gives you no debugging help, but still.
I don't know how to access by position ( and I'd really like to make this work both ways if I can ), because the whole point of this project is to learn more ATL and some ADO. Please ellucidate.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
Well, ADO isn't something I've done a lot with so it could be a case of the blind leading the blind
the spFields collection has a Count property
long nRecordCount = pRst->Fields->Count
how many fields does it say your recordset has?
you could try looping through a record like below and see if it displays all your data (I've hacked this from one of the platform sdk samples)
FieldPtr pFld = NULL;
_variant_t vIndex;
pRst->MoveFirst();
long limit = 0;
limit = ((pRst->Fields->Count) - 1);
for (short iIndex = 0; iIndex <= limit; iIndex++)
{
vIndex = iIndex;
pFld = pRst->Fields->GetItem(&vIndex);
printf("Field %d : Name = '%s', ", iIndex,
(LPCSTR)pFld->GetName());
_variant_t FldVal = pFld->GetValue();
}
|
|
|
|
|
I've solved it, thanks. I read my recordset in like this:
_RecordsetPtr records = NULL;
records.CreateInstance(__uuidof(Recordset));
try
{
records->CursorType = adOpenStatic;
records->CursorLocation = adUseClient;
records->Open("SELECT * FROM FileDatabase",
_variant_t((IDispatch*)m_Connection, true), adOpenKeyset, adLockOptimistic,
adCmdUnknown);
}
catch(...)
{
}
and if the database file in empty it crashes big time. Do you know why that might be ? Anyhow, as a result the first record is a dummy record. I needed to reread some ADO stuff to get clear in my mind what I was manipulating, then I checked the VARIANT coming back from ->Value and found it was VT_NULL, because when I added those four fields, I didn't add dummy values for the dummy record.
I'd love your insight on my empty DB problem though, and on accessing values by position, if you don't mind.
Thanks for the help.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
|
You should put try...catch blocks around your spFields->Item["field"]; statements because this call could throw exceptions. The exception you find might give you an indication on why it is failing.
Jeremy.
|
|
|
|
|
Thanks - I came to that conclusion last night ( I'd actually taken a book to bed, and was thinking about what I'd read when I bounded out of bed to solve the problem ). However, in my experience the exception for ADO is *always* unknown error and ADO flags don't offer much help either. I've grown to hate ADO with every failed attempt to pass perfectly valid SQL to it.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
I have an IEnumXXX class, and another class which contains my database methods. Tonight I removed some unwanted methods from the database class based on help I got earlier today - no problems.
However, I started work on my MFC client for the database and discovered that now when I get any numeric data from my enumeration, the values are all garbage. Everything comes out with a value of 1. The database is fine, and the program used to return real values. Can anyone suggest what may have gone wrong ? I deleted the methods from the idl, .h and .cpp files, renumbered the methods so they ran from 1 with no gaps and rebuilt all. I had no errors or warnings.
#ifndef __SAFILEENTRY_H_
#define __SAFILEENTRY_H_
#include "resource.h"
class ATL_NO_VTABLE CSAFileEntry :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSAFileEntry, &CLSID_SAFileEntry>,
public IDispatchImpl<ISAFileEntry, &IID_ISAFileEntry, &LIBID_SADATABASELib>
{
public:
CSAFileEntry()
{
}
CComBSTR m_FileName;
CComBSTR m_FilePath;
long m_FileLength;
long m_DownloadCount;
long m_LastModified;
long m_Frames;
long m_Seconds;
long m_Width;
long m_Height;
DECLARE_REGISTRY_RESOURCEID(IDR_SAFILEENTRY)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSAFileEntry)
COM_INTERFACE_ENTRY(ISAFileEntry)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
public:
STDMETHOD(get_Height)( long *pVal);
STDMETHOD(get_Width)( long *pVal);
STDMETHOD(get_Seconds)( long *pVal);
STDMETHOD(get_Frames)( long *pVal);
STDMETHOD(get_Modified)( long *pVal);
STDMETHOD(get_DownloadCount)( short *pVal);
STDMETHOD(get_FileLength)( long *pVal);
STDMETHOD(get_FilePath)( BSTR *pVal);
STDMETHOD(get_FileName)( BSTR *pVal);
};
#endif //__SAFILEENTRY_H_
Only get_FilePath and get_FileName are working, and I've traced in to make sure the values in the class are indeed kaput.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
What is the code like for functions, get_Height for instance.
I guess it is a simple
(*pVal) = m_Height;
Or are you doing something else?
Michael
|
|
|
|
|
That is precisely what my GetHeight function looks like and the thing is, it used to work, but now if I break in the function, m_Height always equals 1. I know from opening it in access that the actual values are fine in the database, but now only the string values come out fine.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
What function fills the class variables with data? Does the data go into the class variables okay?
What happens if your initialise m_Height to 255 in the constructor? Does it still give 1?
Michael
|
|
|
|
|
If I make it 255 in the constructor, it still comes out as 1. If I make it 255 in the function, it comes out 255. I traced into my function that reads the data:
try
{
records->CursorType = adOpenStatic;
records->CursorLocation = adUseClient;
records->Open("SELECT * FROM FileDatabase",
_variant_t((IDispatch*)m_Connection, true), adOpenKeyset, adLockOptimistic,
adCmdUnknown);
}
catch(...)
{
}
records->MoveFirst();
vector<ISAFileEntry*> vecDatabase;
do
{
CComObject<CSAFileEntry>* pFileEntry = NULL;
CComObject<CSAFileEntry>::CreateInstance(&pFileEntry);
if (pFileEntry)
{
FieldsPtr spFields = records->GetFields();
string s = (bstr_t) spFields->Item["FileName"]->Value;
for (string::iterator it = s.begin(); it != s.end(); ++it)
if (*it == '?') *it = '\'';
pFileEntry->m_FileName = s.c_str();
pFileEntry->m_FileLength = spFields->Item["FileLength"];
pFileEntry->m_DownloadCount = spFields->Item["TimesDownloaded"];
pFileEntry->m_LastModified = spFields->Item["LastModified"];
pFileEntry->m_Width = spFields->Item["Width"];
pFileEntry->m_Height = spFields->Item["Height"];
pFileEntry->m_Frames = spFields->Item["Frames"];
pFileEntry->m_Seconds = spFields->Item["Seconds"];
and when the data comes out of the database and into the pFileEntry, it is already corrupted, they are already all 1's.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
I'm not familiar with the database calls so this may be a stab in the dark,
your string is accessed via
string s = (bstr_t) spFields->Item["FileName"]->Value
yet your numbers are dont use the Value variable. Is this right
pFileEntry->m_Height = spFields->Item["Height"];
Michael
|
|
|
|
|
Well, how about that ? Thanks so much. I'm half way there now. The File Lengths are loading fine, but the properties I added most recently crash if I put ->Value after them. I guess it's back to the drawing board to try and figure out why.
Thanks again for all the help.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
I needed to handle dialog button's events like WM_MOUSEMOVE and WM_RBUTTONDOWN, so i created a new class inherited form CButton and handled the events easily but the problem is that i couldn't find a way to access the parent dialog's functions so that i can change the dialog's properties, like for example changing a static text. Is there any way to hadle button's events and enable data exchange with the parent dialog?
|
|
|
|
|
GetParent will give you a pointer to the parent dialog CWnd class. You can then cast it to your dialog class.
CParentDialog* pParent = (CParentDialog*) GetParent();
|
|
|
|