|
I haven't used any of the CSocket stuff for a long time, but my recollection is that CSocket objects are like CWnd objects in that you have to be really careful when you try to pass them from one thread to another.
I'd suggest that rather than passing the CAsyncSocket object from the main thread to the worker thread, you should "Detach" the socket from the CAsyncObject in the main thread, pass it by handle to the worker thread and then "Attach" it to a new CAsyncSocket object in the worker thread.
|
|
|
|
|
I have a variable (its a char*) which has the following stuff in it:
char * xyz = "C:\dir1\dir2\file.mdb, location1"
I want to put this into two variables which look like
char * dbName = "C:\\dir1\\dir2\\file.mdb"
and
char* location = "location1"
Should I first convert xyz into a CString, then do stuff to it (what exactly? to get two subCStrings then convert them back into char *s?
So I'm looking at Find, Right and Left:
If I had CString str = "abcd,efg"
Then int pos = str.Find(",") should give me zero based location 4.
then
CString leftstr = str.Left(pos) will be "abcd"
and
CString rightstr = str.Right(str.GetLength() - pos-1) will be "efg"
I cant test this out right now, so I'm wondering if this will work. Do you see any flaws with my numbers or thought process? and to do the '\' to '\\' I'd use Replace....
Thanks,
ns
|
|
|
|
|
Try my CTokenizer[^] class. It might help you.
All of my opinions are correct, even when reality makes the mistake of disagreeing with me.
ASP.NET can never fail as working with it is like fitting bras to supermodels - it's one pleasure after the next - David Wulff
|
|
|
|
|
[Part 1]
There are many ways to parse the string. It depends on whether the input string is guaranteed to be of the specified form, or if you expect the form to vary. If the input string is going to be supplied by a user, you obviously can't guarantee that it will be of the correct format. That being said, here's a quick way to "extract" the filename and location from the source string:
char* xyz = ...
char* pDelimiter = strstr (xyz, ", ");
ASSERT (pDelimiter != NULL);
*pDelimiter = '\0';
char* dbName = xyz;
pDelimiter++;
pDelimiter++;
char* location = pDelimiter;
You'll notice I put "extract" in quotes. You haven't extracted anything. You've just made dbName and location point to the desired components.
[Part 2]
Let me try and clear some confusion about escaping the backslash character: you only need to do this to keep the compiler happy (i.e. when writing a string literal). You'd never programatically replace "\" with "\\".
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
|
Is it okat to do this:
void SomeFunction()
{
try
{.....
}
catch
{...
}
................
try
{...
}
catch
{....
}
return;
}
The reason is that if I throw 2 exceptions that are supposed to be of type int, then I have to have the catch block after each try in which I throw the int, because the catch will look like
catch(int i)
{
}
.
and if I put them all together at the end of the tries, it wont know which catch goes with which try....right?
Thanks,
ns
|
|
|
|
|
maybe... i don't understand what you're asking.
if you want to catch an int, put a catch(int i) handler at the end of the "try" in which you want to catch it. you can nest trys, you can arange them sequentially, whatever. each is independent and can catch whatever you tell it to.
Conservative:
One who admires radicals centuries after they're dead.
-- Leo C. Rosten
|
|
|
|
|
Well, you might not have understood my post since I'm not the clearest explainer, but you certainly answered my question. I didnt know if one function could only have one try, and a couple of catches
(both folllowing the try). So I see I can have as many try catch as I like:
try<br />
catch<br />
catch(...)<br />
<br />
try<br />
catch<br />
<br />
try<br />
catch<br />
catch<br />
catch<br />
<br />
plain ordinary code<br />
<br />
try<br />
catch<br />
<br />
thanks,
ns
|
|
|
|
|
Yes, you can specify as many different catches as you like, but as soon as you put a catch(...), you're going to catch everything there, and nothing below ( I believe ).
Christian
We're just observing the seasonal migration from VB to VC. Most of these birds will be killed by predators or will die of hunger. Only the best will survive - Tomasz Sowinski 29-07-2002 ( on the number of newbie posters in the VC forum )
Cats, and most other animals apart from mad cows can write fully functional vb code. - Simon Walton - 6-Aug-2002
|
|
|
|
|
...for a single "try".
(just finishing the thought).
-c
Conservative:
One who admires radicals centuries after they're dead.
-- Leo C. Rosten
|
|
|
|
|
I am migrating a very large Win32 app from VC6.0 to VC7.0. I am down to one last issue (or so it seems -- these things have a way of hiding). This code works fine in VC6.0, but hangs indefintiely in VC7.0.
void QSWDoc::SetModifiedFlag(BOOL bModified)
{
CDocument::SetModifiedFlag(bModified);
CFrameWnd* pFrameWnd = (CFrameWnd*)AfxGetMainWnd();
if ( pFrameWnd != NULL )
pFrameWnd->OnUpdateFrameTitle(TRUE);
QSWController::GetQSWController().SendMessageToAllWindows(
UDM_DATACHANGED,NULL, NULL);
}
I have stepped through this code a hundred times. The issues is that pFrameWnd is not NULL, it has a valid value. However, pFrameWnd->m_strTitle's value is 0x00000000 <bad ptr="">. I confirmed that this is the source of the problem by substituting the following:
CString strTitle = pFrameWnd->GetTitle();
if( !strTitle.IsEmpty() ) ...
The hang occurs in the GetTitle() function when this code is substituted.
Sydney Liles
Software Engineer
|
|
|
|
|
Where is QSWDoc::SetModifiedFlag() being called from when the hangup occurs?
Where do you end up if you break execution during the hangup?
---
Shog9
If I could sleep forever, I could forget about everything...
|
|
|
|
|
I suppose I should have mentioned that this happens when the application is first launched.
QSWDoc::SetModifiedFlag() is being called from QSWDoc::OnNewDocument(), which calls CDocument::OnNewDocument().
If I step into or over the code pFrameWnd->OnUpdateFrameTitle(TRUE); I am absolutely hung and have to use Task Manager to close Visual Studio. At this point my call stack is referencing 00000000().
Sydney Liles
Software Engineer
|
|
|
|
|
Sydney Liles wrote:
QSWDoc::SetModifiedFlag() is being called from QSWDoc::OnNewDocument(), which calls CDocument::OnNewDocument().
Interesting... At this point (application launching) in a SDI app (maybe a MDI app too; not sure off-hand), the main window doesn't yet exist. So AfxGetMainWnd() *should* be returning NULL... Not sure why it isn't; you might want to trace through *that* call & see what's up. But in any case, you'll need to find a different place for your code; even in MFC6 you shouldn't be able to get away with this.
---
Shog9
If I could sleep forever, I could forget about everything...
|
|
|
|
|
Thanks for your help. It is not fixed yet, but by tracking through the AfxGetMainWnd() call I realized that I do have a window, sort of -- it is a splash screen and that appears to be the true source of the problem -- I am getting a pointer to something that is not truly a window or even a frame. Anyway, I am off on another bug hunt. Thanks again.
Sydney Liles
Software Engineer
|
|
|
|
|
Ok, I am playing around with VC++ again and have only done a little work on a form and am already getting compiler errors . My guess is the error will be apparent to someone who uses VC++ often. This is what I have added:
void CTestDlg::OnShowFileDlg()
{
CFileDialog cd(true);
if(IDOK == cd.DoModal())
{
FunWithFile(cd);
}
}
void CTestDlg::FunWithFile(CFileDialog cd)
{
MessageBox(_T("Hello"), _T("Test Message"), MB_OK);
}
and I get the following error messages
<br />
--------------------Configuration: Test - Win32 Debug--------------------<br />
Compiling...<br />
TestDlg.cpp<br />
C:\Documents and Settings\np0383\My Documents\C++\Test\TestDlg.cpp(181) : error C2664: 'FunWithFile' : cannot convert parameter 1 from 'class CFileDialog' to 'class CFileDialog'<br />
No copy constructor available for class 'CFileDialog'<br />
C:\Documents and Settings\np0383\My Documents\C++\Test\TestDlg.cpp(191) : error C2352: 'CWnd::MessageBoxA' : illegal call of non-static member function<br />
c:\program files\microsoft visual studio\vc98\mfc\include\afxwin.h(2197) : see declaration of 'MessageBoxA'<br />
Error executing cl.exe.<br />
<br />
Test.exe - 2 error(s), 0 warning(s)<br />
Any clues? Thanks in advance.
Nick Parker
|
|
|
|
|
You are passing the entire dialog as an object and the compiler is trying to make a copy of the dialog. When you pass a parameter as an object and not a reference or pointer then the compiler will try to make a copy of your object. Bad practice.
Instead pass a pointer to your dialog. Why are you passing a dialog? Anyway. Pass a pointer rather than the object.
FunWithFile(&cd)
and
void FunWithFile( CFileDialog* cd )
or even better
void FunWithFile( const CFileDialog* cd ) This way you pass a pointer but cannot change anything.
|
|
|
|
|
|
The clue has already been posted: you'd better pass a pointer rather than the whole object. You try to pass the whole object and consequently a copy of your object. To make a copy you need a constructor CFileDialog(const CFileDialog &) Even if you had it, it would be a poor way of implementing what you want because it would be too time- and resource- consuming. Thus pass a pointer and enjoy.
Hope this helps.
|
|
|
|
|
|
Pass the dialog by reference.
void CTestDlg::FunWithFile
(CFileDialog& cd)
{
MessageBox(_T("Hello"), _T("Test Message"), MB_OK);
}
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
|
Ravi,
The pointer thingy (like my naming convention) worked out great however I still get an error just with the MessageBox.
void CTestDlg::FunWithFile(CFileDialog& cd)
{
MessageBox(_T("Hello"), _T("Test Message"), MB_OK);
}
Does this one make sense?
<br />
--------------------Configuration: Test - Win32 Debug--------------------<br />
Compiling...<br />
TestDlg.cpp<br />
C:\Documents and Settings\np0383\My Documents\C++\Test\TestDlg.cpp(192) : error C2352: 'CWnd::MessageBoxA' : illegal call of non-static member function<br />
c:\program files\microsoft visual studio\vc98\mfc\include\afxwin.h(2197) : see declaration of 'MessageBoxA'<br />
Error executing cl.exe.<br />
<br />
Test.exe - 1 error(s), 0 warning(s)<br />
Also, how do you access the methods of the pointer to the object once it has been passed. I understand if you just want to say RTFM.
Thanks again.
Nick Parker
|
|
|
|
|
Hi Nick,
You've probably got FunWithFile declared as a static member function, ie:
in your header file, it probably looks like this:
class CTestDlg : public CDialog
{
...
static void FunWithFile(CFileDialog & cd);
...
};
If that's the case, the reason you see this is because FunWithFile is a static member function, w/ explains the message "illegal call of non-static member function" (CWnd::MessageBox is not declared as static in it's header file).
Here's a rule of thumb to follow w/ static class members (be they static data members or static member functions).
The static keywoard (when used w/ classes) effectively makes the function or member data global, but limits it's scope to a class level.
You can call CTestDlg::FunWithFile without an instance of a CTestDlg object because that function is effectively a global function, but you have to use the scope resolution operator to access the function from outside the class because the scope is limited to the class level.
void AnyFunctionYouWant()
{
CFileDialog fd(TRUE);
if( fd.DoModal() == IDOK )
{
CTestDlg::FunWithFile( fd );
}
}
If you want to, you could change your test function to use
::MessageBox(NULL, _T("blah blah"), _T("blah"), MB_OK);
AfxMessageBox(_T("blah blah blah");
HTH,
Wes
Sonork ID 100.14017 wtheronjones
|
|
|
|
|
Thanks Wes, I'll try that as soon as I get back from the gym (just got home from work). Thanks again.
Nick Parker
|
|
|
|