|
Is it a console app or a GUI app?
You shouldn't have to call ExitProcess and definitely shouldn't have to use TerminateProcess.
Some info: Terminating a Process[^]
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
The difference b/w ExitProcess and TerminateProcess is ExitProcess will send DETACH message to all the loaded dll where TerminateProcess won't. So the error may occured on unloading some dll loaded by ur application.
AJay
|
|
|
|
|
Hi guys,
I´m not sure I am using the corect terminology, since I´m pretty new to MFC programming. Sorry for that.
I created an object of a wrapper-class from an OCX libray (included with class _myObjectClass : public COleDispatchDriver ).
As opposed to other classes in this library and what "OCX" suggests, this one is non-visual (no ActiveX).
I can use this object in a function just fine, except for when calling the function from a thread.
This works fine:
<br />
void TestDlg::DoIt()<br />
{<br />
_myObject m_obj;<br />
<br />
m_obj.CreateDispatch("xxxx.xxxx");<br />
<br />
m_obj.ObjMethod(xxx);<br />
}<br />
<br />
<br />
void TestDlg::OnButton()<br />
{<br />
DoIt();<br />
}<br />
But this does not
<br />
static UINT MyThread(LPVOID p);<br />
<br />
UINT TestDlg::MyThread(LPVOID p)<br />
{<br />
TestDlg * app=(TestDlg *) p;<br />
<br />
app->DoIt();<br />
<br />
return 0;<br />
}<br />
<br />
void TestDlg::DoIt()<br />
{<br />
_myObject m_obj;<br />
<br />
m_obj.CreateDispatch("xxxx.xxxx");<br />
<br />
m_obj.ObjMethod(xxx);<br />
}<br />
<br />
void TestDlg::OnButton()<br />
{<br />
AfxBeginThread(MyThread, this);<br />
}<br />
Can anyone explain that behaviour or even suggest a solution?
Any advice or idea is greatly appreciated.
Thanks in advance,
..kyer
|
|
|
|
|
Verwenden Sie bitte PostMessage() anstatt thread.
Try using PostMessage to send a message to your dialog rather than calling the public function from a thread. You should always try to avoid executing functions in a dialog from an external thread.
Best Wishes,
-Randor
|
|
|
|
|
Thanks a lot for your advice.
I implemented it and it works. But now my dialogue is blocked while the function is executed. It does not run as a second thread anymore, which is my goal.
Do you have any other suggestions?
Kind regards,
..kyer
|
|
|
|
|
Why can't you just move all of the COM instantiation and function calls into the thread?
Also if you are accessing/writing to a variable visible to more than one thread, you will need to protect that variable with a critical section or other thread synchronization object. In other words, if variable N is readable/writable to both threads A and B then you will need to protect this variable. A simple CriticalSection object should be sufficient.
It is 1800 here in Norway/Norwegen and I am leaving the office for the day, but there are many articles here on Codeproject which address the issues with regards to multithreading your application and synchronizing access to variables.
Good luck!
-Randor
|
|
|
|
|
Randor,
many thanks for your help. I´ll try and see what I can learn about COM instantiation.
Kind regards,
..kyer
|
|
|
|
|
Solution:
You have to call CoInitalize to initialize the library in the thread and UnInitialize to close it.
Like this:
<br />
void TestDlg::DoIt()<br />
{<br />
CoInitialize(NULL);<br />
<br />
_myObject m_obj;<br />
<br />
m_obj.CreateDispatch("xxxx.xxxx");<br />
<br />
m_obj.ObjMethod(xxx);<br />
<br />
CoUninitialize();<br />
}
|
|
|
|
|
Hello all,
Now I writing about TTS program. I already got the TTS function from the Microsoft word.
but Now I effort to write for MS Excel. The following is a piece of code of MSWord.
CMSWordSpy::CMSWordSpy()
: m_nStart(-1)
, m_nEnd(-1)
, m_bstrText(_T(""))
, m_pApp(NULL)
, m_pWindow(NULL)
, m_pRangeReplace(NULL)
, m_pRangeOrg(NULL)
, m_pScanRange(NULL)
, m_bWordIsRunning(false)
, m_hwnd(NULL)
, m_hwndRef(NULL)
{}
CMSWordSpy::~CMSWordSpy()
{}
void CMSWordSpy::dump_com_error(_com_error &e)
{
/*
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
CString s;
s.Format(_T("code=%08lx, meaning=%s, Source=%s, Description = %s"),
e.Error(),
e.ErrorMessage(),
(LPCTSTR) bstrSource,
(LPCTSTR) bstrDescription);
LOG(s);
TRACE(s);
*/
}
void CMSWordSpy::Connect(BOOL bNewDoc, BOOL bMaximize)
{
if (m_bWordIsRunning)
return;
try
{
if (SUCCEEDED(m_pApp.GetActiveObject(L"Word.Application")))
{
TTS.Speak(_T("Key stone is connecting to Microsoft Word."),
_T("Windows"), LH_MODESENTENCE, -1, -1, TRUE);
if (bMaximize)
m_pApp->WindowState = wdWindowStateMaximize;
if (bNewDoc)
{
DocumentsPtr pDocs = m_pApp->Documents;
pDocs->Add();
}
m_bWordIsRunning = true;
}
}
catch (_com_error &e)
{
dump_com_error(e);
}
}
void CMSWordSpy::Disconnect()
{
if (m_bWordIsRunning)
{
try
{
TTS.Speak(_T("Key stone is disconnecting from Microsoft Word"),
_T("Windows"), LH_MODESENTENCE, -1, -1, TRUE);
// Setting smart pointers to NULL automatically
// handles any necessary release.
m_pWindow = NULL;
m_pRangeReplace = NULL;
m_pRangeOrg = NULL;
m_pScanRange = NULL;
m_pApp = NULL;
}
catch (_com_error &e)
{
dump_com_error(e);
}
}
m_bWordIsRunning = false;
}
but now i got the error in msword.tlh file. that's file is auto generate file.
<b>error is C2011 'enum redefinition'</b>
is anyone help me for that problem ?
Thanks,
tun
|
|
|
|
|
tunminhein wrote: error is C2011 'enum redefinition'
What does your code snippet have to do with this error?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hello,
is there something what i have to change in my project settings if i want to
compile on dual core cpu, maybe in Linker options or something else??
Sorry, but i never work before with dual core!
Thank you in advance!
termal
|
|
|
|
|
No, process scheduling is handled by the OS kernel. However your application should be designed with multiple threads to take full advantage of multiple processors.
Best Wishes,
-David delaune
|
|
|
|
|
Hello,
thank you for your quick answer!
regards
termal!
|
|
|
|
|
If you are using VS 2005 ensure that you have service pack 1 installed as this will generate code with better support for intel duo processors.
|
|
|
|
|
Hello,
no i use vs6 with sp6.
thanks
termal
|
|
|
|
|
template< typename A, typename B> class CMyClass{
...
}
I need to do template specialization only to set A=MyTypeName , so...what syntax is required?
something like this? (in the .cpp file?)
template<:confused::confused:,typename B>
CMyClass<MyTypeName,B>::foo(){..}
Russell
|
|
|
|
|
Doesn't work as when adding default values to parameters in a function definition?
I mean something like:
template < typename A /*= MyTypeName*/, typename B >
or something like that.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|
|
no, sorry,...I have to specialize MyTypeName1 , MyTypeName2 and MyTypeName3 , so default values are not the solution.
I need a 'partial' specialization, I think. But I don't find the right sintax.
Russell
|
|
|
|
|
But this partial spezialitation is to use the same template function with different typenames but doing differnt things if one type or another? or to support different typenames with the same functionality?
I think I don't understand you correctly.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|
|
|
Have you seen the article that is in an answer in the message below??
this article[^]
Maybe you can take something there. I have found it ok, and maybe, that with the typename T and the explicit instatiation is the solution you are looking for.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
|
|
|
|
|
I don't work very often with that kind of things but I think that template specialization only works at the class level, not at the method level: you need to specialize your class and there, you can override the functions you like.
I think, in your situation it will be like this:
template <typename B><br />
class CMyClass<MyTypeName,B><br />
{<br />
};
I'm not 100% sure thought, so you'll have to check.
|
|
|
|
|
And what about ...?
template < class A, class B >
class CMyClass < A, B >::foo (class A1)
{
if (A1->IsKindOf (RUNTIME_CLASS ( A )))
else
}
EDIT: I actually am not sure if I understand the question right. A bit more info would be nice.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|
|
sure...in that way it could work, but I prefere to use a simple "template specialization" it works well if all typename s must be specialized. But this is the first time that I have to specialize only a typename , so I I'm trying to find the correct sintax.
thanks for your time
Russell
|
|
|
|
|
I'm trying... I'll tell you the results tomorrow.
thanks
Russell
|
|
|
|