|
well it works fine in my codes, and I have taken the code from Programming Visual C++ fifth Edition from Kruglinsky, a rather new book.
Is a method that sometimes makes multithreaded programming unnecessary.
greetings.
Daniel Cespedes
"Santa Cruz de la Sierra Paraiso Terrenal!"
daniel.cespedes@ieee.org
|
|
|
|
|
Multithreading does have its problems besides the difficulty with synchronizing shared objects, its harder to debug, and MFC doc / view does not support multithreading. However after you get over a few hurdles it is usually better to use unless you only have one background task.
John
|
|
|
|
|
I didn´t know that MFC doc/view doesn´t support multithreading, so if I want to use it I have to make a Dialog based app?
cheers!
Daniel Cespedes
"Santa Cruz de la Sierra Paraiso Terrenal!"
daniel.cespedes@ieee.org
|
|
|
|
|
John M. Drescher wrote:
MFC doc / view does not support multithreading
I didn´t know that MFC doc/view doesn´t support multithreading, so if I want to use it I have to make a Dialog based app?
cheers!
Daniel Cespedes
"Santa Cruz de la Sierra Paraiso Terrenal!"
daniel.cespedes@ieee.org
|
|
|
|
|
No you just have to make sure that you create your views in the same thread as the doc and the main application otherwise you will see a lot of asserts...
John
|
|
|
|
|
I was thinking the same...
John
|
|
|
|
|
How would I go about to solve this problem?
I have to write a text analysis program that will calculate and output the overall number of words, characters, and lines within a text file. Also, have to calculate how many characters are alphabetic, numeric, and punctuation.
It has to be in C++. Thanks.
Sample Output:
The text file consisted of 2 lines
The text file consisted of 27 words
The text file consisted of 128 characters
Alphabetic: 100
Numeric: 12
Punctuation: 8
Other: 8
Mark J Jackson
|
|
|
|
|
Use the following functions from <ctype.h>
isalpha
isdigit
ispunct
isspace
|
|
|
|
|
CString strLine;
CStdioFile file(...);
int nLineCount = 0,
nAlphaCount = 0;
while (file.ReadString(strLine) == TRUE)
{
nLineCount++;
for (x = 0; x < strLine.GetLength(); x++)
{
if (isalpha(strLine[x]))
{
nAlphaCount++;
}
else if (isdigit(strLine[x]))
{
nDigitCount++;
}
...
}
}
// to count characters (or count them above as each character is analyzed)
int nCharCount = file.GetLength();
|
|
|
|
|
Hi everyone,
I have a little question about thread. I have read the faq and managed to program threads but now I'm facing a newbie challenge : I need to access to my dialog controls and the Document. I copy this code from this forum to access the Document from anywhere in my program.
//Declaration
static CTestSDIDoc * GetDoc();
//Implementation
CTestSDIDoc * CTestSDIDoc::GetDoc()
{
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
return (CTestSDIDoc *) pFrame->GetActiveDocument();
}
In my dialog (my own progress window with static text, a progress bar, 6 bitmaps and an OK button), I want to show a green check mark when a process has done is job. The process is created with CreateProcess method. The CreateProcess is writed in the TreadFunc of my dialog class. Before calling createprocess method, I must do some initialization in the Document so I must do this :
metprof *metProfPtr = static_cast<metprof *="">(pvParam);
CTestSDIDoc *pDoc = static_cast<ctestsdidoc *="">(pvParam);
pDoc=CTestSDIDoc::GetDoc();
The bold text code works everywhere except in the TreadFunc method (I've got an assertion when running in debug mode). I want to know what Am I doing wrong ?
Here my complete ThreadFunc function:
UINT metprof::ThreadFunc(LPVOID pvParam)
{
metprof *metProfPtr = static_cast<metprof *="">(pvParam);
CTestSDIDoc *pDoc = static_cast<ctestsdidoc *="">(pvParam);
CString workingDirectory,strTemp,appArguments,strTemp2;
pDoc=CTestSDIDoc::GetDoc();
TRACE("vis: %d\n",pDoc->m_VIS);
workingDirectory=pDoc->m_modulesDirectory;
workingDirectory.Insert(workingDirectory.GetLength(),"ATMOSPHERIC\\\\");
pDoc->m_SL_COND=1;
appArguments=pDoc->m_dosPrompt;
pDoc->createMetDataFile();
pDoc->createMetProfInputFiles();
STARTUPINFO siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
strTemp2=pDoc->m_binDirectory;
strTemp2.Replace("\\\\","\\");
strTemp2.Delete(strTemp2.GetLength()-1,1);
strTemp.Format(" /c \"metprof.exe < metprof.rep -L -P \"%s\"\"",strTemp2);
appArguments.Insert(appArguments.GetLength(),strTemp);
char *str = appArguments.GetBuffer(appArguments.GetLength());
if(CreateProcess(NULL, // Application name
str,//"cmd /c \"metprof.exe < metprof.rep -L\"",// Application arguments
0,
0,
FALSE,
CREATE_NO_WINDOW,
0,
workingDirectory,//"C:\\Program Files\\Irblempkg\\IRBLEM4.1\\modules\\atmospheric\\", // Working directory
&siStartupInfo,
&piProcessInfo)){}
::WaitForSingleObject(piProcessInfo.hProcess,INFINITE);
metProfPtr->GetDlgItem(IDC_CHECKMETEO)->ShowWindow(TRUE);
pDoc->moveMetProfOutputFiles();
return 0;
}
I think I'm missing something with my code but I don't know what.
Thanks for your help,
Rene
|
|
|
|
|
Yeah, you are missing the bold text . Which part of the code does not work?
|
|
|
|
|
Could you explain little bit more what is the following code does?
metprof *metProfPtr = static_cast(pvParam);
CTestSDIDoc *pDoc = static_cast(pvParam);
P.S. I assume "<" and ">" are lost due to the editor.
|
|
|
|
|
Hi AlexO,
metprof *metProfPtr = static_cast<<metprof*>>(pvParam);
CTestSDIDoc *pDoc = static_cast<<ctestsdidoc*>>(pvParam);
These are pointers to metProf dialog class to access dialog controls like editBox etc...
The second one is a pointer too but to the Document.
If I run my program, I got an assertion but if I click on ignore button the program continues to work correctly.
Thanks for your help,
Rene
|
|
|
|
|
that is what I thought ... But it is the same pointer is it not?
As for pointers, just an idea, would it not be safer to pass HWND of the dialog and use PostMessage for notification from the worker thread?
|
|
|
|
|
You can't use MFC windows in multiple threads. Since CFrameWnd::GetActiveDocument() is MFC specific (not a Win32 function) you're pretty much screwed. You'll need to either pass the document as a parameter to your thread function, or find another way of doing it. MFC is just no good for applications where multiple threads manipulate the GUI.
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"
|
|
|
|
|
Pass all the data the thread will need as the parameter:
struct ThreadData
{
CTestSDIDoc *pDoc;
metprof *metProfPtr;
.
.
.
HWND hWnd;
};
.
.
.
ThreadData *td = new ThreadData
td.pDoc = CTestSDIDoc::GetDoc();
td.metProfPtr = ...
CWinThread *pThread = AfxBeginThread(ThreadProc, (LPVOID)td);
.
.
.
UINT ThreadProc(LPVOID lpParam)
{
ThreadData *td = (ThreadData *)lpParam;
.
.
.
delete td;
return 0;
} Also, you don't need a thread just to create a proccess.
Hope this helps...
Jonathan Craig
www.mcw-tech.com
|
|
|
|
|
Gandilf emailed me:
Your struct trick works perfectly but now I got an exception 0xC0000005 about metProfPtr. metProfPtr is a pointer to the current dialog (my own progress bar and bitmap, etc...). I need it to unhide one different bitmap at each process completion (total of processes: 6). When you talk about initializing pointer metprofPtr like td.pDoc = CTestSDIDoc::GetDoc(); for pDoc, what can I do ? (td.metProfPtr = 0 ?) Maybe you have another suggestion.
Thanks a lot,
Rene
There are two different ways to do it.
1.) Add the pointer to the dialog to the ThreadData struct.
struct ThreadData
{
.
CMyDialog *pDlg;
.
};
td.pDlg = this; This may or may not cause problems when calling methods on td->pDlg.
2.) If you know which object you wish to hide or show, you can pass a HWND handle to it. If your bitmap object is a CStatic.
struct ThreadData
{
.
HWND hWnd;
.
};
td.hWnd = m_bitmap.GetSafeHwnd(); In your thread you would call.
::ShowWindow(td->hWnd, SW_HIDE); or
::ShowWindow(td->hWnd, SW_SHOW); This is the correct way to pass window objects to a thread.
Good Luck
Jonathan Craig
www.mcw-tech.com
|
|
|
|
|
Have a look at Jonathan Craig's post above this one. If that doesn't help drop me an email [click on the email button at the bottom of this post] and I'll help you out.
Regards,
Brian Dela
|
|
|
|
|
When the secondary thread finishes up a work unit, it simply needs to post a message to the primary thread (i.e., the one that owns the UI).
|
|
|
|
|
I have a CSpinButtonCtrl control in a dialog box, and a corresponding CEdit control.
If I set the spin button to be "attached" to the CEdit control, the program asserts if I defined a variable associated with the attached CEdit control.
enum { IDD = IDD_MYDIALOG };
CSpinButtonCtrl m_ctrlSpinner;
CEdit m_ctrlEdit;
I looked all over MSDN and didn't see anything about this. Anyone have any clues/experience with this?
------- signature starts
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
Please review the Legal Disclaimer in my bio.
------- signature ends
|
|
|
|
|
I've had to do this exact thing very recently, and I didn't have any problems. I have both a spin control and and edit control declared very much like you have them. I don't see any reason for that to assert.
I did find, through a roundabout way, that the edit control needs to follow the spin control in the tabbing order on the dialog. I'm not sure if this documented or not, but I hadn't seen it before. But, apparently, this is how the "attachment" works, by the edit immediately following the spin in tabbing order.
You might check that, and you might make sure exactly why the assertion is failing. I suspect the cause of the assertion isn't simply because of the edit declaration.
Dave
"You can say that again." -- Dept. of Redundancy Dept.
|
|
|
|
|
The spin control has to immediately follow the associated edit control. If I set "autobuddy" to true, the program asserts. If I set it to false, the program, doesn't assert, but I have to handle updting the field myself.
------- signature starts
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
Please review the Legal Disclaimer in my bio.
------- signature ends
|
|
|
|
|
In my code, I have the DoDataExchange with both the spin and edit controls included with
DDX_Control (pDX, IDC_SpinControlName, var_name1)<br />
DDX_Control (pDX, IDC_EditControlName, var_name2)
but then also have a member variable in the class that creates the dialog for the edit control value. The DoDataExchange goes to/from the controls to the control variables, but then the owning class needs to go from the conrtol variable to a member variable to be used further (?).
Dave
"You can say that again." -- Dept. of Redundancy Dept.
|
|
|
|
|
That second part made no sense to me at all.
In order to do keep the program from asserting, I have to turn "autobuddy" off in the resource editor, and then call the spin button control "SetBuddy()" function to associate it with the desired edit control.
BTW, I guess I should mention that this is in PocketPC 2002...
------- signature starts
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
Please review the Legal Disclaimer in my bio.
------- signature ends
|
|
|
|
|
John Simmons / outlaw programmer wrote:
BTW, I guess I should mention that this is in PocketPC 2002...
Oh, great!! Next you're going to tell me you're using VB!!
I don't have any calls to SetBuddy(), but in the .rc file, the line for the spin control is
CONTROL "Spin1",IDC_ELEV_SPIN,"msctls_updown32", UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS, 143, 212, 11, 14
The magic of dialog editors and wizards, I guess. To me, the connection between spin and edit controls comes from the tab order, and the use of UDS_AUTOBUDDY establishes the connection.
I know this probably isn't much help, and I'm sure it will turn out to be something pretty simple, but getting all those little details worked out is always a PITA.
Good luck.
Dave
"You can say that again." -- Dept. of Redundancy Dept.
|
|
|
|
|