|
How to Check the iterator is valid?
|
|
|
|
|
|
In general you can't.
Steve
|
|
|
|
|
|
|
I construct a Streambuf with "an array of char". and use the steambuf to construct a ostream/istream:strm.
But the strm cannot do anything with "char array".like << | >> doesn't affect the char array data.
Have I missed something?
|
|
|
|
|
Without source code, it's hard to say.
The streams shouldn't see a char array, but a streambuf. It's up to the streambuf to provide the functionality the stream needs for its internal use.
The streaming operators << and >> work on streams, not streambuf. For instance, when streaming a character out (strm << 'o'; ) the ostream will call streambuf::sputc to add it to the buffer.
modified on Wednesday, September 7, 2011 7:37 AM
|
|
|
|
|
hi,everyone.
When using the Windows FileOpen dialog with multiple selection do you ever wonder how much memory you have to allocate for the buffer. Is one kilobyte going to be enough? Or should you make it ten? How about one Megabyte just to be safe?
It seems that no matter what you choose, you are either going to waste a whole bunch of memory just to be safe, or your user is going to select a bunch of files only to find their selection didn't work because your buffer was too small.
one way is Derive the CFileDialog class , the article as follow introduce it:
Multiple Selection in a File Dialog[]
but I have the other method: use the hook function of CFileDialog. I write some code as follow:
<pre lang="c++">
UINT_PTR CALLBACK MyOFNHookProc( HWND hdlg,
UINT uiMsg,
WPARAM wParam,
LPARAM lParam
)
{
int nResult = FALSE;
if (hdlg == NULL)
return 0;
#ifdef _DEBUG
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThreadState->m_pAlternateWndInit != NULL)
pThreadState->m_pAlternateWndInit = NULL;
#endif
switch(uiMsg)
{
case WM_NOTIFY:
{
LPOFNOTIFY pOfn = (LPOFNOTIFY)lParam;
switch(pOfn->hdr.code)
{
case CDN_SELCHANGE:
{
TCHAR dummy_buffer;
HWND hOwner = GetParent(hdlg);
HWND hParent = GetParent(hOwner);
UINT nfiles = CommDlg_OpenSave_GetSpec(hOwner, &dummy_buffer, 1);
int cbLength = CommDlg_OpenSave_GetSpec(GetParent(hdlg), NULL, 0);
cbLength += _MAX_PATH;
if(cbLength>(pOfn->lpOFN)->nMaxFile)
{
if((pOfn->lpOFN)->lpstrFile)
HeapFree(GetProcessHeap(),
0,
(pOfn->lpOFN)->lpstrFile);
(pOfn->lpOFN)->lpstrFile = (LPTSTR) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
cbLength);
(pOfn->lpOFN)->nMaxFile = cbLength;
}
nResult = TRUE;
break;
}
default:
break;
}
break;
}
default:
break;
}
return nResult;
}
void CMultiSelectDlg::OnButton1()
{
#define NAMEBUF 1024
TCHAR szFilters[]= _T("MyType Files (*.doc)|*.doc||");
CFileDialog fileDlg(TRUE, _T("doc"), _T("*.doc"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT, szFilters);
fileDlg.m_ofn.lpstrFile= (LPTSTR) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
NAMEBUF);
fileDlg.m_ofn.nMaxFile = NAMEBUF;
fileDlg.m_ofn.lpfnHook = (LPOFNHOOKPROC)MyOFNHookProc;
INT_PTR ret = fileDlg.DoModal();
if (ret == IDOK)
{
int width = 0;
CString str;
CDC *pDC = m_listbox.GetDC();
int saved = pDC->SaveDC();
pDC->SelectObject(GetFont());
UINT count = 0;
POSITION pos = fileDlg.GetStartPosition();
while (pos)
{
str = fileDlg.GetNextPathName(pos);
m_listbox.AddString(str);
CSize size(0, 0);
size = pDC->GetTextExtent(str);
width = width > size.cx ? width : size.cx;
++count;
}
pDC->RestoreDC(saved);
ReleaseDC(pDC);
m_listbox.SetHorizontalExtent(width + 5);
str.Format(_T("%u files selected"), count);
m_static.SetWindowText(str);
}
DWORD dwCode = CommDlgExtendedError();
if (FNERR_BUFFERTOOSMALL==dwCode)
{
int i =0;
}
HeapFree(GetProcessHeap(),0,
(fileDlg.m_ofn.lpstrFile));
}
the code Reference the article as follow :
How To Handle FNERR_BUFFERTOOSMALL in Windows[]
but I found when the file names buffer is enough large , it run successly; but when when the file names buffer is not enough large (it means the program will enter if(cbLength>(pOfn->lpOFN)->nMaxFile) ), when after run INT_PTR ret = fileDlg.DoModal(); the value of ret is IDCANCEL. I catch the error code, it is FNERR_BUFFERTOOSMALL . In the end even I allocate a enough large memory ,the error code still is FNERR_BUFFERTOOSMALL . Why???
|
|
|
|
|
From the last link/example you shared, I notice that the Win-KB example sets the pointer pOfn to the parent of the current window:
lpofn = (LPOPENFILENAME) GetProp(GetParent(hwnd), "OFN");
And then continues with it. You should carefully reread the example and adjust your own code accoringly.
|
|
|
|
|
lpofn = (LPOPENFILENAME) GetProp(GetParent(hwnd), "OFN");
this code I have test,it is Invalid. after run this line,the value of lpofn is NULL.
|
|
|
|
|
Hi all.
I have a memory leak on a C++ MFC app I'm trying to solve.
In the problematc part of code there are some function calls as follows:
void functionA()
{
functionX(new ClassConstructor());
}
Since this unmanaged code, is it safe to do that without freeing the memory allocated by the new operator, or it will be released after exiting the functionA scope?
Shouldn't be something like the following a good solution?
void functionA()
{
ClassConstructor *obj = new ClassContructor();
functionX(obj);
delete obj;
}
Thanks in advance 
|
|
|
|
|
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
|
|
|
|
|