|
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.
|
|
|
|
|
I display popup menu when right clicked on list control. I do not want it in main menu. How to hide it.
I want to display toolbar on dialog box whose buttons map to popup menu . How to do this?
|
|
|
|
|
Read
Programming Windows, Fifth Edition by Charles Petzold
Introduction to MFC Programming with Visual C++ by Richard M. Jones
|
|
|
|
|
I want ot put toolbar on dialog box .
How to do this?
|
|
|
|
|
use a SDI application instead, toolbars are not meant for dialog apps, or for simple dialogs.
anyway, look around here on CP, you'll find what you're looking for.
Maximilien Lincourt
For success one must aquire one's self
|
|
|
|
|
I have done database programming . Database used is MYSQL.
The Program updates the database. I want to make it multiuser i.e. In network, program is running on more than one machine. Changes made by
one user should be reflected at other user end.
How to do this?
|
|
|
|
|
Are you referring to a real-time update among all instances of the application? One solution is winsock and multicast.
Kuphryn
|
|
|
|
|
Yes, I am referring to real-time update of all instances of program. This is totally new for me. So can you give me more details or reference to learn this?
|
|
|
|
|
If you really want to learn winsock, I recommend Network Programming for Microsoft Windows, Second Edition by Anthony Jones and Jim Ohmund. There are several good references for winsock.
CodeProject
CodeGuru
Kuphryn
|
|
|
|
|