|
The object instantiated by the new needs a matching delete . It's not clear who's responsible for deleting it from what you've told us, but someone needs to. A comment on this code you posted:
sirtimid wrote: void functionA()
{
ClassConstructor *obj = new ClassContructor();
functionX(obj);
delete obj;
}
In this case there's no reason to use the heap. Do something like this instead:
void functionA()
{
ClassConstructor obj;
functionX(&obj);
}
Steve
|
|
|
|
|
Thanks a lot!
I'll try that out 
|
|
|
|
|
Ok guys... i've been working on this section of code for about a week now and i'm giving up...can someone help me?
I've got the basics down, but the code won't compile:
Argument of type LPWSTR* is incompatible with parameter type of LPWSTR
LPWSTR strPath[ MAX_PATH ];
SHGetSpecialFolderPath(
0,
strPath,
CSIDL_APPDATA,
FALSE );
LPWSTR appDataPath = *strPath;
_tcscat(appDataPath, L"\\SSST\Settings.ini");
MessageBox(NULL,(LPCTSTR)appDataPath, NULL, NULL);
|
|
|
|
|
The problem with your code is as follows:
LPWSTR strPath[ MAX_PATH ];
The "LP" in "LPWSTR" stands for Long Pointer. So the above code declares an array of pointers, NOT an array of WCHARs.
You need to declare it as:
WCHAR strPath[ MAX_PATH ];
Also, this code is wrong:
LPWSTR appDataPath = *strPath;
_tcscat(appDataPath, L"\\SSST\Settings.ini");
You haven't allocated any memory for the appDataPath string. So you must make it something like:
LPWSTR appDataPath = new WCHAR[ 400 ]; I chose 400 arbitrarily to make it big enough.
And be sure to deallocate appDataPath when you are done with it by saying:
delete [] appDataPath;
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Great! that works perfect, the only issue is that now the MessageboxA shows a ton of chinese/gibberish characters at the front.. i'm assuming that these are the buffer characters?
i'm new to C++ (in fact this is only my second attempt at C++)... counting "Hello World!"
|
|
|
|
|
I should have mentioned that you should zero out the buffer before using it:
LPWSTR appDataPath = new WCHAR[ 400 ];
ZeroMemory( appDataPath, sizeof( WCHAR ) * 400 );
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Though what the other poster said is correct, you need to make a few extra modifications. First I'll give you the working 'proper' code, and then I'll explain:
TCHAR strPath[ MAX_PATH + 50 ];
SHGetSpecialFolderPath(
0, strPath, CSIDL_APPDATA, FALSE );
_tcscat(strPath, _T("\\SSST\\Settings.ini"));
MessageBox(NULL, strPath, NULL, MB_OK);
First of all, you were mixing WCHAR definitions with TCHAR functions (such as _tcscat, MessageBox). Depending on whether you compile for Unicode or not, the TCHAR definition changed from a char to a wchar_t, and so do all the tchar.h routines, as well as the Windows API functions (which switch to their wide variants).
To fix this, use TCHAR and LPTSTR's in your program. For string literals, enclose them in a _T macro as shown, which automatically adds the L prefix if needed and omits it if not unicode.
Then a simplification: you can just strcat (_tcscat) in strPath, no need to add extra variables and certainly no need to use new, which adds the overhead of extra memory management and can lead to memory leaks if you forget to clean it up.
And finally, the last argument of the MessageBox is a UINT flag, and not a pointer, so you shouldn't pass NULL to it, but rather one of the predefined constants.
Hope this helps.
|
|
|
|
|
it did help significantly, i appreciate the explanation rather than a code dump...
I'm still a bit confused about the TCHAR and WCHAR definitions... they seem to convert themselves... i guess these are one of those "C++ Macros" that i've been reading about?
i figured i could just strcat() the strings in the same line, but i'm still trying to figure out C++
i've made the changes stated above, but i am now getting a "Debug Assertion Error" on my line:
delete [] strPath
i've figured out that an assertion error is similar to a conditioned break point... i've found the line of code in one of the C++ files:
dbgdel.cpp
void operator delete(
void *pUserData
)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK);
__TRY
pHead = pHdr(pUserData);
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg( pUserData, pHead->nBlockUse );
__FINALLY
_munlock(_HEAP_LOCK);
__END_TRY_FINALLY
return;
}
#endif /* _DEBUG */
the code looks like i've passed an invalid param to the delete function... should i not be disposing of this variable, it is not used anywhere else in my code as of yet? or is there another method for disposing of this var?
|
|
|
|
|
jwalker343 wrote:
I'm still a bit confused about the TCHAR and WCHAR definitions... they seem to convert themselves... i guess these are one of those "C++ Macros" that i've been reading about?
These are indeed macro's. The definition of TCHAR sort of goes like:
#ifdef _UNICODE
#define TCHAR WCHAR // Unicode is on -> Wide character type
#else
#define TCHAR CHAR // Unicode is off -> Normal character type
#endif
jwalker343 wrote: i figured i could just strcat() the strings in the same line, but i'm still trying to figure out C++
The thing with TCHARs is that they work very nicely in allowing your code to compile and work both when compiling for Ansi and for Unicode (Wide) character sets. But, there is a catch. You need to make sure all your string function follow the t-pattern. That's why, in tchar.h there are a lot of macro's that switch definition based on whether _UNICODE is true or not. These are the _txyz macro's, such as _tcscat for strcat/wcscat, or _tcslen for strlen or wcslen.
If you define all your strings as TCHAR and use the associated _txyz routines, then your code will compile for all character sets without having to change. This does require a slight awareness though. Code like sizeof() can work differently. sizeof always gives the size in 'char', and that's equal to strlen for ansi, but equal to twice the wcslen for unicode (as wcslen gives the amount of wide characters, and each character is 2 bytes (chars) in size).
There is a lot of intricacies to C++, certainly when targeting a specific platform, such as Windows. One of those intricacies is tchar.h and all its facets
At any rate, you were right in your assumption: you can just use strcat the way you wanted to.
jwalker343 wrote: i've made the changes stated above, but i am now getting a "Debug Assertion Error" on my line:
Now, to the problem at hand: I think you are mixing two bits of code. The one I gave and the one given by the other poster. You posted a piece of code in the beginning. If you replace exactly that code with the code I posted (and add/remove nothing) then it should work.
I think you added a delete[] strPath to the snippet I gave, as per the other posters code. delete[] is necessary when you allocate memory using new[]. However, in this snippet the strPath is a fixed size array (MAX_PATH + 50, in my example) allocated on the stack, so it is automatically cleaned up as it goes out of scope (at function return). delete is for (manually) heap-allocated memory, and thus gives an error when used on stack-memory.
So, guideline is: are you using new to allocate memory? -> Then use delete after you are done with it.
Are you using new[..] to allocate memory? -> Then use delete[] after you are done with it.
Else, the memory is stack allocated and you don't need to manually free it.
|
|
|
|
|
wow, very helpful...
explains why C++ is such a powerful language... it's almost as if the entire language can change pretty quickly depending on all of your own settings... that's crazy!!
and the memory allocation seems understandable as well now that you explain it like that... basically if you specifically ask for new memory, you've got to deal with it yourself...
Thanks a bunch MicroVirus... i'm looking to release my first CodeProject Article on this project in the coming months... i'll be sure to mention your help!
|
|
|
|
|
I have a program source code, want, who can help me! Thank you, give me your e-mail.
|
|
|
|
|
I am a noob just starting out trying to code extensions for IE, and I have an ATL project with a BHO working with very basic functionality right now. I have a button that displays in the IE Menu toolbar, but need to show a form when the user clicks the button and be able to submit and process data. I have been researching this a lot but am at a loss as to what the best approach would be. There seem to be no tutorials online for this. Has anyone done this before?
|
|
|
|
|
I was reading http://msdn.microsoft.com/en-us/library/bb250489.aspx[^] after I saw your post. Scrolling down to around 2/3 of the page under the heading Responding to Events, there is the following:
From MSDN:
Finally, add a simple OnDocumentComplete event handler.
void STDMETHODCALLTYPE CHelloWorldBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
HWND hwnd;
HRESULT hr = m_spWebBrowser->get_HWND((LONG_PTR*)&hwnd);
if (SUCCEEDED(hr))
{
MessageBox(hwnd, L"Hello World!", L"BHO", MB_OK);
}
}
Notice that the message box uses the top-level window of the site as its parent window, rather than simply passing NULL in that parameter. In Internet Explorer 6, a NULL parent window does not block the application, meaning that the user can continue to interact with the browser while the message box is waiting for user input. In some situations, this can cause the browser to hang or crash. In the rare case that a BHO needs to display a UI, it should always ensure that the dialog box is application modal by specifying a handle to the parent window.
Basically, where the MessageBox is, is *any* dialog box you want or create. The actual creation and display of the dialog inside a BHO is exactly the same as for a normal windows application. Just be sure to set the parent to the browser hWnd, as is suggested by this article.
So, to learn how to do this, all you need to do is learn how to display a dialog in a normal 32 bits application. And then hook it up to your BHO and display it at the right time.
|
|
|
|
|
Hi,
I have created a Class CProgressDlg, derived from CDialog, which encapsulates the thread creation, message sending, cancel button, etc. associated a Dialog with one or more Progress Bar(s). The whole lot was compiled into an MFC Extension DLL, and I wrote an equivalent Header file which hides all the uglies needed to implement the class.
The exposed Class Declaration is as follows:
-
class CProgressDlg : public CDialog
{
DECLARE_DYNAMIC( CProgressDlg )
virtual ~CProgressDlg();
public:
PFN_DLG_PROGRESS_THREADPROC SetProgressProcedure(PFN_DLG_PROGRESS_THREADPROC pFn);
void OnCancel();
BOOL ShouldTerminate();
CProgressDlg(UINT nIDTemplate,CWnd* pParent =NULL); protected:
virtual void DoDataExchange(CDataExchange* pDX); void UpdateData(BOOL bSaveAndValidate = TRUE);
void EndDialog(int ExitCode);
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
private:
char Reserved[16];
};
I Tried to Use this code as Follows:-
class CBackupDlg : public CProgressDlg
{
public:
DWORD ProcessAllFiles(void*);
CBackupDlg(CWnd* pParent = NULL); enum { IDD = IDD_ACTIONDLG };
CProgressCtrl m_cProgressCtrl;
CString m_sDataRemainung;
CString m_sProcessStage;
CString m_sFileNowProcessing;
CString m_sTimeRemaining;
protected:
virtual void DoDataExchange(CDataExchange* pDX); protected:
DECLARE_MESSAGE_MAP()
};
The CPP File has the Following :-
CBackupDlg::CBackupDlg(CWnd* pParent )
: CProgressDlg(CBackupDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_qwCopySize=0;
}
BEGIN_MESSAGE_MAP(CBackupDlg, CProgressDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BROWSE_DEST, OnBrowseDest)
ON_BN_CLICKED(IDC_BROWSE_SOURCE, OnBrowseSource)
ON_BN_CLICKED(IDC_BROWSE_SUBDIR, OnBrowseSubdir)
END_MESSAGE_MAP()
When Compiling I get the following Errors:-
At the Initialiser:
error C2614: 'CBackupDlg' : illegal member initialization: 'CProgressDlg' is not a base or member
At BEGIN_MESSAGE_MAP
error C2248: 'messageMap' : cannot access protected member declared in class 'CProgressDlg'
What is going on here. The Same Headers and Code has been used numerous times. The ProgressDlg Header is included via StdAfx.h, so, should be visible everywhere. I've gone over the code time and time again. Can't find anything out of Order.
By the way, Everything Compiles Fine if I replace CProgressDlg with CDialog in the Initialiser and the MESSAGE_MAP Macro. Ofcourse If I try to run with that, I get Run Time Errors as Expected.
Pulling out my hair at this stage, Any helpfull comment is appreciated.
Regards
Bram van Kampen
modified on Sunday, August 21, 2011 6:46 AM
|
|
|
|
|
I'm not an MFC expert but should the line
DECLARE_DYNAMIC( CProgressDlg )
not be public?
|
|
|
|
|
Richard MacCutchan wrote: I'm not an MFC expert but should the line
DECLARE_DYNAMIC( CProgressDlg )
not be public?
Well,
DECLARE_DYNAMIC() is defined in the Microsoft 'AFX.H' as follows:-
#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static const AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \
It sets it's own inheritance Access Model Prepending it with 'public' should not (and does not) have any effect. Actually, looking at the macro above, The DECLARE_DYNAMIC(...) macro causes all following properties to be declared public by default. The CPP language has no(t yet)(a) syntax to 'push' or 'pop' the 'public', 'protected', 'private' storage type 'state'.
I made a stupid error there somewhere, that upsets the Class Hierarchie as perceived by the compiler.
Thanks
Bram van Kampen
|
|
|
|
|
I have always found these MFC macros more than somewhat confusing - great if they work, but almost impossible to debug.
|
|
|
|
|
Is CProgressDlg inside any namespace that you need to use?
|
|
|
|
|
How to add Common Controls 6.0 to DLL / ATL ?
I don't have the source code of the EXE, I'm writing only the DLL linked to it.
If I put this line in the stdafx.h of the DLL it doesn't work:
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
InitCommonControls(); / InitCommonControlsEx();
is not working neither,
I need Common Controls 6.0 to show my tooltips controls and they work only with the manifestdependency line at the exe file / or manifest file to exe
Thanks for anyone who can help,
Mithrill
|
|
|
|
|
How can I check whether an iterator was assigned a value or not? In other words, if I create an iterator with default constructor what value will it present which I could check against?
It is not the trivial case such this:
list<int>::iterator it;
but this:
map<AClass *,list<int>::iterator> aci;
AClass *ptr=someinitializedaclassptr;
if(aci[ptr]==UNINITIALIZED_ITERATOR)
{
dosomething();
}
In above example issuing aci[ptr] creates already an entry in the map with default constructed value list<int>::iterator if there isn't a key of value ptr .
modified on Friday, August 5, 2011 7:48 AM
|
|
|
|
|
|
Well, it is obvious it has no special value as int val; . The problem is how to check this. I'll try the below code:
#include "list"
#include "map"
#include "iostream"
using namespace std;
int main()
{
list<int>::iterator it,itnull;
map<int,list<int>::iterator> imap;
it = imap[1]; if(it==itnull) cout<<"it unitialized"<<endl; else
cout<<"it has other value"<<endl;
return 0;
}
|
|
|
|
|
So I am digging around deep in the registry
So far so good, but I need to access specifics for each subkey
for (i=0; i<cSubKeys; i++) {
cbName = MAX_KEY_LENGTH;
retCode = RegEnumKeyEx(hKey, i, achKey, &cbName, 0, 0, 0, &ftLastWriteTime);
if (retCode == ERROR_SUCCESS) {
RegQueryValueEx(hKey,L"DisplayName",NULL,NULL,(LPBYTE) lpData, &buffersize);
applist.push_back(lpData);
}
}
Anyway all I get are a bunch of "-" so am I getting the right type etc?
http://www.contract-developer.tk
|
|
|
|
|
What are the types of lpData and applist ?
The best things in life are not things.
|
|
|
|
|
I added another layer of hKey
lpData is char*
applist is CString
I got it figured out with a lot more code needed
http://www.contract-developer.tk
|
|
|
|
|