Schmidt
7/30/2011 7:35:00 PM
Am 28.07.2011 00:19, schrieb Mayayana:
> To Olaf, or anyone else who knows about
> his dhRichClient3.dll:
>
> I'm able to call a function in a DLL from
> within a class of the first DLL using
> cThreadHandler. The function can show
> me a msgbox. But I can't get a return either
> async or synchronous. Is it possible that
> this can only be done from an EXE?
I would not use this "high-level" threading-approach,
which is built into the RichClient3 - since this
one is thought more for something like "asynchronously
running Background-Workers" - then throwing Events for
"Progress" and "Finished" from the BackGround-Thread.
For working more near "to the metal" (which I think,
is important in your case) you should use the
approach which is built into DirectCOM.dll
(no dependency to the larger RichClient-lib is
involved then).
And as you already guessed correctly -
the STARTCOMOBJECT-call of DirectCOM.dll is what
you perhaps need (or should try).
This call is used in conjunction with your own
"MyThreadHandler.dll", which only hosts one
Public Class. And this Public Class needs to
provide (by convention) a Public Function:
Public Function ThreadMain(ByVal P As Long) As Long
as an entry-point for the thread - and
in 'P' you could provide a Pointer to Shared
memory for example (memory which you previously
allocated within your Main-Thread).
What's nice is - if you have your "normal unthreaded"
code already within an ActiveX-Dll - then you can
easily place such an additional (Public) ThreadClass
within that same Dll - and then call:
STARTCOMOBJECT against your very own DllFileName...
"from within" (your normal Dll-Class).
Example:
If your current Dll is named "MyIEFilter.dll"
and currently has one Public Class defined:
cMyFilter
you could then simply add an additional ThreadClass:
cMyFilterThread (this is the one which runs threaded,
and has this Public ThreadMain-Function defined).
Plus maybe an additional Private-Class (that's the way
I usually do it), which is responsible for starting up -
and later on also properly cleanup the additional
ThreadClass - this private Handler-Class could be named:
cMyFilterThreadHandler
Within this Private Class cMyFilterThreadHandler
(which runs in your normal MainThread) you can
ensure proper Startup (in Class_Initialize)
and proper Teardown (in Class_Terminate)
against your real ThreadClass (cMyFilterThread).
So these two classes behave somewhat like "linked
Classes" then - if you instantitate
cMyFilterThreadHandler in your MainThread,
then the "threaded ShadowClass" (cMyFilterThread)
is automatically also "alive" ... if you
set cMyFilterThreadHandler to Nothing, then
also cMyFilterThread (and of course also the thread
it is running on) will be destroyed.
So, if you want to use a Thread from within
cMyFilter, you would simply start your
Thread with:
Dim ThreadHandler As cMyFilterThreadHandler
Set ThreadHandler = New cMyFilterThreadHandler
after that the additional thread is running
and as soon as the ThreadHandler-Variable
goes out of scope - or is set to Nothing,
also the Thread (which runs the cMyFilterThread-
Class) will terminate.
All that, as said - possible directly within
one and the same Dll (and by placing the
appropriate Startup- and Teardown-Code within
_Initialize and _Terminate of your Handler-Class.
What (as always with threads, no matter what
language) makes the whole thing tricky is,
that you will need to find a good way, to cancel
an actually running operation as fast and clean
as possible, when it's a longer one, and performed
"in the thread" - this is, when you set the
Private Handler-Class to Nothing - and have
to ensure a proper teardown of the upstarted
ThreadClass by signaling this class, that
the MainThread "goes down" - or just wants to
get rid of the thread as fast as possible -
and signaling from the Handler-CLass to its
associated ThreadClass is usually not the
problem (e.g. in Shared Memory you can set
a simple Flag really immediately) - the
question is, if the currently (possibly a
long-run-task-performing) thread, does
have the time, to react to this "ShutDOwn-
Flag which was set "from outside" (from the
Mainthreads THreadHandler-Class).
When the ThreadClass just performed an internal
Call, which takes "seconds" to return, then
it can of course not look at this ShutDown-
Flag - and exit the ThreadMain-Function -
the Handler-Class has then (in its Class_Terminate)
either to wait appropriately - or - after some
TimeOut you find useful, perform a hard shutdown
using TerminateThread (which is not recommended,
whilst working with COM-stuff, COM-routines which
the thread currently was yet "diving in").
I don't know, what you have available in
these Filter-APIs, to cancel the processing
within the thread - or if they are "granular"
in a way, that you don't have that long
"taskrunner-calls", but only relative short
callbacks (which perform some tasks on a relative
short buffer and then return, leaving the thread
free (idling), to take a look at the ShutDown-Flag.
But perhaps you don't need any thread at all -
I cannot imagine that the APIs (the interfaces
to implement) didn't thought about possibly
slow-incoming data (from the server-end).
Without the filter, the IE would also have
to wait for the next small chunk, when it's
only "trickling in".
And *if* there's a filter inbetween, then
you're acting, as if you would be the server -
and if this, your "virtual socket" (your filter)
has no new data available at the moment
(when requested from the IE-end) - then
you should simply pass a (the same) value back,
which otherwise the "async-Downloader-Class which
would talk directly with the server" also would
have to pass back to the IE-request-handler.
Hmm, I'd like to have a look at your code...
Olaf