|
Sorry if I can't help you. All I can tell you is your bug
is maybe related to MFC. I always use ATL to develop ActiveX control.
I know MFC has a macro, I think it's: AFX_MANAGE_STATE( ), where I have
seen developer using: AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
but again I have never use it. Do you always fire event from the same thread?
What's the other thread is doing?
|
|
|
|
|
i tried throwing that in there to no avail, but i went and searched for firing events from worker threads with AFX_MANAGE_STATE in there as well and found some stuff, so i'm working on trying one of those out right at this moment..
do you think you could show me how to raise an event from C++ using an ATL control ? (for kicks i can try it through ATL and see how well it works then)
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
Okay I will send you an example how I did something similar.
|
|
|
|
|
I made a simple demo for you. I sent it to your email at:
heaven_bounty@yahoo.com
Let me know if it helps you!
|
|
|
|
|
That's what baffles me is that it's the exact same idea except that it's in an MFC ActiveX Control...
here's my question:
1. Make a new COM ATL Project.
-I picked FULL CONTROL when i made a new ATL obj... I assume that to be fine.
-Do i want to merge proxy/stub code?
-Support Connection points, of course
-Apartment threading (it wont let you choose Free if you choose to make a
control) so... should i just be making an ATL object and wrap it in a Control?
-Do i need to check free threaded marshalling?(i assumed so)
-Aggregation: (No) i have no clue what this does... i've basically learned COM/ATL/ActiveX from common lingo and trial and error.
2. ok after all of that is done, (the real question is coming, i promise)
- I compile,
- Implement Connection points? I cannot compile to where i can call events in the code and it doesnt show up (like the way you have it in CProxy...).
that's my dilemma. oh and when i try to add a function to the CProxy_... i get: "The implementation file for class CProxy_ITesterEvents<class t=""> cannot be found" ---- what am i not doing, that i should be doing??
well, that's all for now, i'm gonna keep messing with it. RSVP
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
1) Make a new COM ATL Project [ ok ]
- Picked Full .. [ ok ]
- Attributes: Apartment, Dual, Aggregation: Yes [or No] doesn't matter for now
- Connection points [x], Error Info [ ] (no, or I don't mind), Free Thread [ ] (no, I don't
mind, that's not the cause of your problem).
- Select settings for Miscellaneous, Stock Properties [ ok ]
2) Build your project, It should build fine (very important, must work)
3) Add event function to your connection point, right-click "_YourObjectEvents" and select
Add Method ( I am sure you did everything correctly so far...)
4) Verify that you have COM_INTERFACE_ENTRY(IConnectionPointContainer) in your COM_MAP
5) Implement the connection point:
- right-click your "YourObjectClass", chose "Implement Connection Point..."
- check your "_YourObjectEvents" and Click Ok
6) At that point, the proxy stub will be added for you, if you don't see it. You must have
it already on your folder. You may want to delete previous proxy stub class (files) every
time you add a new method (event) to your connection point.
7) Follow the example in the thread function that I sent you.
|
|
|
|
|
cool, ok that's what i've been doing. now after i implement the connection points i get an error:
BEGIN_CONNECTION_POINT_MAP(Ccrap)
CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
CONNECTION_POINT_ENTRY(IID__IcrapEvents)
END_CONNECTION_POINT_MAP()
it says that IID_IcrapEvents is undeclared... any clue about that?
also, when it asked me if i wanted a .dll or exe it also had a Checkbox that asked if you wanted to merge proxy/stub code. Is that necessary?
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
MasterWang wrote:
it says that IID_IcrapEvents is undeclared... any clue about that?
You mean DIID_IcrapEvents
MasterWang wrote:
also, when it asked me if i wanted a .dll or exe it also had a Checkbox that asked if you wanted to merge proxy/stub code. Is that necessary?
No!
|
|
|
|
|
oh! wow, there's that error that i told you before, but yes "Fire_Done()" is there though (woohoo!).
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
and it gives it to me as IID_Iklfasjdf, not DIID_afklj;ds
but when i changed it to DIID, we have no errors. i'm sure i'll post something shortly here on my status.
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
that DIID_YOUROBJECTEvent is defined in "YourObject_i.c".
This is an auto-created file.
Glad to see you get there!
|
|
|
|
|
ok ok, good news/bad news... the good news is that it compiles and fires the events, bad news is that it still crashes...
i'm calling CoInitializeEx() and CoUninit
at the beginning/end of the worker thread,
still testin' and messin' with it.
anything that i forgot about that i should for sure have in there?..
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
All I can do to help you is:
Ask you to test your control in the "ActiveX Control container Test" program.
If it works, look for what you are doing wrong in your client!
By the way, always use the same thread to access your object, ie: do not
access your object from the event handler!
Good luck
|
|
|
|
|
hahahahaha!!!!!!!!! woo hoooooooooooo!!!!!!!!!!!!!!!!!!!!!
yaaaaaaaaaaaaaaaaaaaaaaa-hooooooooooooooooooooooooooooo!!!!!!!!!!!!!!!
oh, hey, it works or whatever.
(trying to keep straight face )
yeah!!!! i think i know why it was botching up when we had identical code.
-When i added the first event to the project, i didnt compile afterwards and i think that's why that IID -> DIID wasnt working properly, and that's why it had never worked. so i just slowly did one thing at a time compiling after i did something else. and it works now! yeah!!!!!
Cool, thanks for being patient with all 4,000 threads in the forum and all!
woooooooooooo hooooooooooooooo!!!!!!!!!!!!!!
Ok there's the One and only God, then there's you! wooooooooo hooooooo!!!
thanks again!!!!! yeah!!!!!!!!!!!!!
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
Nice to see that you believe in the ONLY God.
I am happy for you!
Merry Christmas & Happy new year!
- God bless the World
|
|
|
|
|
haha - well it's nice to know that i'm not the only one now in this field!
~Timothy T. Rymer
www.digipen.edu
tim.xpertz.com
|
|
|
|
|
How the interfaces are internaly designed,what is the exact role of Interface?
Terminater
|
|
|
|
|
Which interfaces?
Are you talking about IUnknown and IDispatch?
Michael
|
|
|
|
|
Hey guys and gals,
I've read some things on MSDN about trying to fire events from an ActiveX Control written in VC++ 6.0, but i just cant seem to get it. Is there any way to raise an event and get it to the main program from a worker thread? Is there any way you can explain this so that i can "comprehend" it? Can i just get some basics on how to do it? and if you do something strange, try to explain it.. (like any MFC Macro stuff cuz i really never use MFC if i dont have to) just do it in steps! 1.2.3.4.5.! <sigh> I'd love to hear a different insight on all of this... it's been bugging me for about a month, and i've been able to work around it, and now it's time to fix it.
SHABBA!!
|
|
|
|
|
It's a lot more complicated that it deserves an article by its own:
1) Yes you can fire even from a different thread but you need to make
sure that your component is MTA and not STA.
2) call CoInitializeEx(NULL, COINIT_MULTITHREADED) in the secondary thread;
and make sure your object is thread safe.
3) Since I have never used MFC to create ActiveX control, I don't know about
MFC Macro stuff for ActiveX.
4) In ATL, the wizard will create template file correctly for you if you
are using MTA or Free Thread marshaling.
This is just to help you start!
Good luck
|
|
|
|
|
it sounds like it would do the trick, but for some reason it wont recognize the header file <objbase.h>
which is where i'm supposed to get it from, and i am also linking to
ole32.lib as well, and it still says that it doesnt recognize the function...
i did use MTA just for the record..
but i also used an MFC ActiveX Control Wizard instead of ATL COM, which i had tried before, but i didnt add a control, so i'm gonna try that...
SHABBA!!
|
|
|
|
|
For your linking problem, I have no clue but as far as calling
CoInitializeEx from all threads that access the ActiveX
control, it should work. In the main thread, call CoInitializeEx in InitInstance(),
don't forget to call CoUninitialize() .
Good luck!
|
|
|
|
|
Hi,
I never succeeded firing Event directly from
Worker thread.
But one work-around way is to use Thread Messages.
You can use PostMessage(...) in your worker thread
to post a message to the main thread.
and in the Message Handler you can fire your Event.
Thanks
Firoz
|
|
|
|
|
i've tried that to no success... i'm gonna try CoInitializeEx(), and if that doesnt work, this is probably the only other way (that i feel like doing) that's not too much work. But i did try it, and it didnt work, i think it's because i didnt have a handle to the Window... and then people said to make an invisible window, and they just stopped. and didnt show you how... so that's where i'm at on that path.
SHABBA!!
|
|
|
|
|
Hi Shabba,
Ooops..I forgot to mention that.
You are right, you need a Window.
The steps are very simple...
...some modifications to your CoClass.
For Creating the Window ...
^^^^^^^^^^^^^^^
1) #include <atlwin.h>
2) Derive your CoClass from CWindowImpl<Your CoClass Name> .
3) DECLARE_WND_CLASS("Your CoClass Name")
4) Implementation for FinalConstruct() and FinalRelease().
In FinalConstruct(), you create the Window. and,
In FinalRelease(), you destroy the Window.
For Handling UserDefined Thread messages ...
^^^^^^^^^^^^^^^^^^^^^^^^^^
5) The MessageMap macro...
BEGIN_MSG_MAP(Your CoClass)
MESSAGE_HANDLER(500, OnUserMessage)
END_MSG_MAP()
6) Implementation for OnUserMessage() handler function.
Now, inside this handler, you can fire your COM Event.
Thats it.
Now in your Worker ThreadProc, whenever you want to fire the event,
use PostMessage(...).
Note: Postmessage needs HWND.
You can do either of this...
1) use HWND_BROADCAST or
2) use the HWND returned when you created the Window (in FinalConstruct()).
eg. ::PostMessage(HWND_BROADCAST,500,0,0);
Firoz
The following sample code may be Helpful...
#ifndef __LAWORKTHR_H_
#define __LAWORKTHR_H_
#include "resource.h"
#include "LAWorkThreadExeCP.h"
#include <atlwin.h>
class ATL_NO_VTABLE CLAWorkThr :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CLAWorkThr, &CLSID_LAWorkThr>,
public IConnectionPointContainerImpl<CLAWorkThr>,
public IDispatchImpl<ILAWorkThr, &IID_ILAWorkThr, &LIBID_LAWORKTHREADEXELib>,
public CProxy_ILAWorkThrEvents< CLAWorkThr >,
public CWindowImpl<CLAWorkThr>
{
public:
CLAWorkThr()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_LAWORKTHR)
DECLARE_NOT_AGGREGATABLE(CLAWorkThr)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CLAWorkThr)
COM_INTERFACE_ENTRY(ILAWorkThr)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CLAWorkThr)
CONNECTION_POINT_ENTRY(DIID__ILAWorkThrEvents)
END_CONNECTION_POINT_MAP()
DECLARE_WND_CLASS("CLAWorkThr")
HRESULT FinalConstruct()
{
HWND hwnd = Create(::GetDesktopWindow(),CWindow::rcDefault,"MyAtlWindow",WS_POPUP);
g_Myhwnd = hwnd;
if (hwnd)
return S_OK;
else
return HRESULT_FROM_WIN32(GetLastError());
}
void FinalRelease()
{
if (m_hWnd != NULL)
{
DestroyWindow();
}
}
BEGIN_MSG_MAP(CLAWorkThr)
MESSAGE_HANDLER(500, OnUserMessage)
END_MSG_MAP()
LRESULT OnUserMessage(UINT uMsg, WPARAM wpar, LPARAM lpar, BOOL& bHandled)
{
Fire_MyEvent();
return 0;
}
public:
STDMETHOD(MyMethod)();
};
#endif //__LAWORKTHR_H_
|
|
|
|
|