|
OK, that's no problem but what happened to CString, is it bug or not?
Thanks.
|
|
|
|
|
Its not a bug in CString, its the function that returns CString. They have to call the original function and in the course of that add the length parameter. And thinking that 256 chars would have been enough....
If you look at the library code there will be a GetBuffer(256) statement with the length also set to 256. Make sure these match in your code or you could get an overflow.
Elaine
The tigress is here
|
|
|
|
|
What are you using to verify the length of the CString object? Have you stepped into CListCtrl::GetItemText() to watch how it is behaving?
|
|
|
|
|
I just used GetLength() to check the length of the returned CString object.
The return value is 256.
The length of the text in the CListCtrl is surely over 256 bytes.
The second function can extract whole text when the last parameter nLen
is large enought to hold whole text.
Thanks.
|
|
|
|
|
Ok, but did you step through the MFC code?
|
|
|
|
|
With your advice, I looked at the MFC code.
The function was defined as follows.
CString CListCtrl::GetItemText(int nItem, int nSubItem) const
{
ASSERT(::IsWindow(m_hWnd));
LVITEM lvi;
memset(&lvi, 0, sizeof(LVITEM));
lvi.iSubItem = nSubItem;
CString str;
int nLen = 128;
int nRes;
do
{
nLen *= 2;
lvi.cchTextMax = nLen;
lvi.pszText = str.GetBufferSetLength(nLen);
nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
(LPARAM)&lvi);
} while (nRes == nLen-1);
str.ReleaseBuffer();
return str;
}
At first look at, it looks like to extract whole text using do-while statement.
But in my code, nRes is 256, so do-while is applied only one time.
|
|
|
|
|
I used the following code snippet and both TRACE() calls output 300:
CString str;<br />
int len;<br />
str = "12345678901234567890123456789012345678901234567890";<br />
str += "12345678901234567890123456789012345678901234567890";<br />
str += "12345678901234567890123456789012345678901234567890";<br />
str += "12345678901234567890123456789012345678901234567890";<br />
str += "12345678901234567890123456789012345678901234567890";<br />
str += "12345678901234567890123456789012345678901234567890";<br />
len = str.GetLength();<br />
TRACE("len = %d\n", len);<br />
ctrlList.InsertItem(0, str);<br />
str.Empty();<br />
str = ctrlList.GetItemText(0, 0);<br />
len = str.GetLength();<br />
TRACE("len = %d\n", len);
|
|
|
|
|
You are right.
I found it worked well in alphanumeric text.
I'm a Korean. When the string is Korean, it fails.
Thanks.
|
|
|
|
|
Makes me wonder if you aren't having a Unicode problem.
|
|
|
|
|
OK, it looks like it definitely related to data-type mapping.
I will check it later because of the lack of time.
Thank you for your consideration.
|
|
|
|
|
I got a class derived from CList, as
class CPointList : public CList<CPoint*,CPoint*&>
{
...
}
I want to declare it DYNAMIC, but as i wrote this in .cpp
IMPLEMENT_DYNAMIC(CPointList,CList<CPoint*,CPoint*&>
The compiler gave an error:
warning C4002: too many actual parameters for macro 'IMPLEMENT_DYNAMIC'
How can I declare it to be dynamic?
|
|
|
|
|
Charles Liu wrote:
How can I declare it to be dynamic?
Yes, but instead of CList<CPoint*,CPoint*&> , you need to use CObject . CList is not DECLARE_DYNAMIC() , so you can't specify it as the base class.
Doing this means that you can tell what class the CPointList is, but it will appear to be a direct descendent of CObject , ie. RUNTIME_CLASS(CPointList)->GetBaseClass() will return RUNTIME_CLASS(CObject) .
BTW, the reason the compiler tells you it has too many parameters is because the preprocessor doesn't care about C syntax - it just splits the macro at the commas. It does not care (and does not know) that the second comma is inside a template definition, and assumes it to be separating parameters. The only comma is treats differently is one that's inside a string.
Ryan
Being little and getting pushed around by big guys all my life I guess I compensate by pushing electrons and holes around. What a bully I am, but I do enjoy making subatomic particles hop at my bidding - Roger Wright (2nd April 2003, The Lounge)
Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late - John Nichol "Point Of Impact"
|
|
|
|
|
how to read data from digital camera?
includeh10
|
|
|
|
|
Typically, the CF card is exposed as a disk drive. When your camera is attached to your computer, see if you can browse to it in explorer. On mine, I have full read/write access and can drag and drop files from the camera to the hard disk using explorer. Assuming that this works the same on yours, simply use the standard file functions to read the files from the CF card.
onwards and upwards...
|
|
|
|
|
Hi all,
Does anyone perhaps know what the CommTimeOuts formula is for determining ReadIntervalTimeout or where can I find it?
How do I determine what value to assign when receiving total bits of 10 per character, at 9600 baud?
Any help/advise would be appreciated.
Thanks
Louis
|
|
|
|
|
Thanks.
Is there a minimum Asynch Timeout value.
Cheers
Louis
|
|
|
|
|
I ve got a DialogBox with one ComboBox and 2 EditBox.
If the user choose for example : "dog"in the combobow i want that one of the edit can not be edited (set read only)..
Fot that i use that :
void CDialogBoxClass::OnSelchangeComboEvent()
{ UpdateData(true);
if(m_combo=="dog")
m_editctrl.EnableWindow(FALSE);
else
m_editctrl.EnableWindow(TRUE);
}
The problem is that this function start before the new value of m_combo would be assigned in the comboBOx.... if someone could help me
Frackasse
|
|
|
|
|
I'm guessing that you are calling SetCurSel() in the dialog's OnInitDialog() method. Add a variable m_bInitializing of type bool to your dialog class and set it to false in the constructor. At the beginning of OnInitDialog(), set it to true, and at the end of OnInitDialog(), right before the return statement, set it to false.
void CDialogBoxClass::OnSelchangeComboEvent()
{
CString str;
if (! m_bInitializing)
{
m_comboctrl.GetWindowText(str);
if ("dog" == str)
m_editctrl.EnableWindow(FALSE);
else
m_editctrl.EnableWindow(TRUE);
}
}
|
|
|
|
|
i tried what u write but it is exactly the same result... maybe u don t understand my question : if i use this :
void CAddEvent::OnSelchangeComboEvent()
{ CString str;
m_eventcontrol.GetWindowText(str);
MessageBox(str);
}
The messageBox returns me the old value of the CString in the comboBox (means not the new value the user has choosen but the value he wants to change) so the problem is when i want to know if(str=="dog") str is not the right CString....
Frackasse
|
|
|
|
|
The CBN_SELCHANGE notification message is sent when the user changes (note the past tense here) the current selection in the list box of a combo box. Not seeing the rest of your code, I can only hypothesize. Another solution might be:
CString str;<br />
int nIndex = m_comboctrl.GetCurSel();<br />
m_comboctrl.GetLBText(nIndex, str);
|
|
|
|
|
|
How to covert CString to TCHAR and CString to LPCWSTR?
Where can I read about this?
|
|
|
|
|
If you need to copy a CString object to an array of TCHAR you could do:
<font color="green">
</font>
TCHAR *czArray = NULL;
<font color="green">
czArray = new TCHAR[strText.GetLength() + 1];
_tcscpy(czArray, (LPCTSTR)strText);
<font color="green">
delete [] czArray;
The CString object has the LPCTSTR operator cast, so you can just cast your CString object to a LPCWSTR (LPCSTR if not unicode). Note that this is used in the above example for the _tcscpy function
For further reading, have a look at the strings section of Codeproject, there are a few good articles that is a must-read.
"..Even my comments have bugs!"
Inspired by Toni78
|
|
|
|
|
the easy way:
<br />
USES_CONVERSION;<br />
<br />
CString Str(_T("This is my string"));<br />
<br />
char charBuf[255];<br />
strcpy( charbuf, T2CA(Str) );<br />
<br />
wchar_t wcharBuf[255];<br />
wsccpy( wcharBuf, T2CW(Str) );<br />
<br />
TCHAR tcharBuf[255];<br />
_tcscpy( tcharBuf, Str );<br />
this works in UNICODE and non-UNICODE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
Santa Cruz Networks
|
|
|
|
|
Hi i've got an object that I want to use with a number of dialogues, so I declared it in my App class, and I was then going to use a pointer to the app object to acess it in all my dialogues.
How do I get the pointer to the app to access the object?
At the moment I have something like
CtheApp* m_pApp;
but how do I initialise the pointer to point at the app?
I tried something like
m_pApp = &theApp;
but I just get the compiler saying that theApp is an undeclared variable but I thought it was a global. Can someone enlighten me as to the way to proceed?
Thanks
Andy
|
|
|
|