|
Hi Mike,
Thanks for reply.
I have one more question.
I am getting confused with the terms router, switch and hub.
Can someone explain the difference and which one is better and why, particularly in my case?
thanks
regards
/rsasalm
|
|
|
|
|
I have a MFC ActiveX component which processes a large inputfile. The component is contained in a VB form. I want to have a Cancel button on the VB form to tell the component to exit the loop.
Inside the component's main loop I'm calling PeekMessage then TranslateMessage and DispatchMessage to allow the user to interact with the VB form (otherwise it would just freeze up while the Component executes).
I imagine something like this would be the way to go:
bool CFileControl::Process()
{
while (!file.eof)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)//maybe used a userdefined message instead
return TRUE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//read next line of large file and process data
}
return...
}
Is it straightforward to pass a userdefined message from VB or does this break some COM rules. Otherwise has anybody any ideas? If I maybe set a flag which the loop condition could test, must I use a separate thread in order to set this flag.
Thanks for reading this far,
John
|
|
|
|
|
I think having a flag to exit the loop is better than having to send a message.
Yes, in that case you may need to have a separate thread to do (since you have a
large file...). If your control display a UI and has a button to stop the process,
you may still want to use a technic similar to the one with PeekMessage but this is
just a matter a choice. The best method in my opinion is to have a flag and use
a second thread but you will have to work a bit harder to make sure that your control
is thread safe.
Good luck!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Hi,
I'm an extreme newby to COM. What I want to do is be able to create a system where there are different components that manipulate an array of data. For example one might do a moving average, one might do a standard deviation etc. However I want other people to be able to develop components as well.
Could I develop a base interface and then VC++ and VB programmers could develop their components based on this interface and register somehow with my program. Then I could just have a Calculate( .. ) function and a GetDescription( .. ) function to create menus from.
Would I be better off just using dlls and using GetProcAddress?
Thanks
|
|
|
|
|
Since there are many functions in picture I think you should go for COM. Using COM will turn out to be simpler.
|
|
|
|
|
I have an out-proc server i'm currently writing. In this server I have a number of interfaces. I was wondering if I could do the following. All the interfaces and implementations of the interfaces are in the same project.
interface IUser {....}; // IUser definition
interface IUsers {....}; // IUsers definitions
class CUser : public IUser {....}; // The implementation of IUser
class CUsers : public IUsers {...}; // The implementation of IUsers
HRESULT CUsers::SomeFunc() {
CComPtr<IUser> pUser;
pUser.CreateInstance(__uuidof(IUser));
((CUser*)(pUser.p))->m_SomeData; // Can I do this cast from IUser to CUser?
...
}
That was my question, is the cast possible?
Justin Turney
|
|
|
|
|
Yes, but it is not safe.
Since you are in your CUser class when you create the new object, it would be safer to call new, then cast the object to the interface if the interface needed to be exported from the function.
HRESULT CUsers::SomeFunc()
{
CUser pUser = new CUser;
pUser->m_SomeData;
...
CComPtr piUser
piUser = static_cast<IUser*>(pUser);
...
}
Good Luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Justin Turney wrote:
That was my question, is the cast possible?
Why do you want to do that?
You should never do anything like that. If a proxy or stub gets involved in between then the code will not be safe.
|
|
|
|
|
Can't you implement a propget on IUser that returns the contents of m_SomeData?
|
|
|
|
|
pUser.CreateInstance(__uuidof(IUser));
__uuidof(IUser) is the UUID of IUser interface, not the his coclass CLSID. So this call will be unsuccessful.
You can use the local creation of COM object:
CComObject < CUser >* pUser;
HRESULT hr = pUser->CreateInstance( & pUser );
if( SUCCEEDED(hr) )
{
pUser->m_SomeData;
...
delete pUser;
}
With best wishes,
Vita
|
|
|
|
|
I get the impression that most plugins are implemented using COM, hence the posting here. Can anyone give me any headstart on implementing plugins in my application. OpenSource examples would be particularly useful.
Any tips or hints?
I Cargill CEng BENg MBCS
|
|
|
|
|
I have trouble creating instance of an shellwindows object in MFC dll
CreateInstance does not work in MFC DLL, but CreateInstance work well in EXE MFC
It hangs on the CreateInstance row
What could this be happening ?
/// My code //
// I Created a Dialog class in MFC DLL
BOOL CWalletDlg::ShellWindowAdvise()
{
EnableAutomation();
m_pIE5Events = new CIE5Events(this);
HRESULT hr = 0;
CoInitialize(NULL);
if (m_spSHWinds == 0) {
hr = m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));
AfxConnectionAdvise( m_spSHWinds,
__uuidof(SHDocVw:ShellWindowsEvents),
this->GetInterface( &IID_IUnknown ),
TRUE, &m_dwCookie );
return TRUE;
}
}
|
|
|
|
|
Is the exe calling CoInitialize?
|
|
|
|
|
More importantly, is the EXE calling CoInitialize on the thread that the DLL is loaded.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
I have a little problem. The background is:
I'm working on a server/client application in C# and I want to setup up a session, but when you use COM+ you can't use a session. The client is not run in a browser.
I also have to "create" the session on the server and pass it on to the client. Anyone have a suggestion on how to implement this (NOT in ASP)?
I've been trying to com up with some constructive solution for a while now, but i hit the wall before i get any results!
MikeC#
|
|
|
|
|
Is that a way to pass simple functions to COM objects like this:
ob->Method(pFunc);
where pFunc is a function like "void pFunc(void)"?
I want pFunc to be called from inside the COM object.
rechi
|
|
|
|
|
It is not considered a good practice to pass pointers in COM methods. Instead wrap the function as an interface
interface IMyFunc
{
HRESULT Func();
}
Just to give you an idea.
You can have
class A : IMyFunc
{
public:
void Func()
{
}
}
The method would look like
HRESULT Method(IMyFunc* pFunc);
A* pA;
.
.
.
ob->Method(pA);
|
|
|
|
|
It's what i was the most afraid of: interfaces wrapping functions. Unfortunately this solution consumes a large amount of time.
Thanx!
rechi
|
|
|
|
|
Bogdan Rechi wrote:
Unfortunately this solution consumes a large amount of time.
That is the price that we all have to pay for Binary Comaptible code.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
A better choice for this than wrapping the function in an interface to create an Event sink for your COM object.
Then users of your object can register with your object for certain events. Then when that event occurs your object will call all of the event sink functions that have been registered with your object. This is a very efficient way to solve your problem.
There are a lot of good examples in MSDN and there might be a few on CP.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
I need pass an array of data in a variant to an API call. I'm not sure if I'm passing the data correctly as I'm new to COM.
I appreciate if someone could verify the below snippet has a obvious problem when using COM arrays because the API call does not produce the intended results with the array data I passed.
// generate 3 element array of floats
SAFEARRAY *psa = SafeArrayCreateVector( VT_R4, 0, 3 );
float HUGEP *dp = 0;
SafeArrayAccessData( psa, (void HUGEP**)&dp );
dp[0] = 6;
dp[1] = 7;
dp[2] = 8; // set array to 6,7,8
SafeArrayUnaccessData( psa );
VARIANT va;
va.vt = VT_ARRAY | VT_R4;
va.parray = psa;
// pass va to API that takes a variant
Blah( va );
SafeArrayDestroy( psa );
|
|
|
|
|
Did you try to pass it as a reference instead?
va.vt = VT_ARRAY | VT_BYREF | VT_R4;
va.pparray= &psa;
Your code seems to work fine other than that!
What API are you using? the way it expects to
receive your data is also important.
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ernest Laurentin wrote:
Did you try to pass it as a reference instead?
Yup, didn't work too.
The API is a Avid SoftImage XSI v2 SDK. It has virtually ZERO documentation so I'm guessing how to call it by looking at headers and vbscript examples.
The vbscript version works like this
<br />
Blah( array(5,6,7) )<br />
The C++ version is defined as
<br />
virtual HRESULT STDMETHODCALLTYPE Blah( <br />
VARIANT in_pNewEffPos );<br />
The worst part is the API runs successfully (HR succeeded) but the results are wrong.
I'm not well experienced enough with COM or I would have condemn it as a bug with their API straight away.
|
|
|
|
|
Sorry it took me long to write you!
Did you try to send "long" or "short" array?
You example here both integer value not float. Maybe
the API accepts integer value not float!
One good thing about getting older, you don't lose the ages you've been!
|
|
|
|
|
Ernest Laurentin wrote:
Maybe
the API accepts integer value not float!
Thanks for the reply.
Quite impossible. It should be taking either float or double because in the UI, one can enter decimal places for the values. They can't be using fixed point maths.
But I will try again just to make doubly sure.
|
|
|
|