|
Thanks James,
1.
I have seen a couple of samples of STA model. No explicit code for pumping message to somewhere. Just jobs like, like CoCreateInstance, QueryInterface, and method call by the interface public method.
So, I think the function call through public method of interface (retrieved from QueryInterface) is translated into message pump. Is that correct?
2.
How does message pump work? Like enqueue a message into a double ended queue, one end is the function call, the other end is the component itself?
regards,
George
|
|
|
|
|
Yes, any call into the interface (method, property, etc.) are translated into a message and placed onto the queue (if the call crosses apartment - is crossing application boundaries). Not sure if connection points work the same way (and I rarely used them because of undesirable side-effects). When the message pump runs, the message is dispatched to the COM message handler which takes over handing of the call.
The message pump is a standard windows message queue (which is why the hidden window is required).
One correction for my above post: The message pump is run by the thread that created/owns the COM object - I remember this because I had worker threads using COM in STA that needed to run a PeekMessage /GetMessage loop for things to work. This also means that while COM creates the hidden window, it is owned by the calling thread because threads have to pump messages for their own windows.
Peace!
-=- James Please rate this message - let me know if I helped or not!<hr></hr> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Great, James!
One more comments. I think to manage a message queue, we need at least two threads acting as producer (invoke methods of COM interface and push message) and consumer (which extracts messages from message queue and interacts with COM component directly).
But STA means single threaded apartment, i.e. in the apartment, there is only one thread. So, is the thread in STA the producer or consumer? Or I am totally wrong about above producer/consumer pattern of how STA works?
regards,
George
|
|
|
|
|
When you make the cross-apartment COM call, it turns into a message, this message is queued, processed, and then returned back to you.
You and the target apartment constituite both ends of the queue/pump system.
When you see "only one thread in an STA," that means that each application only has one thread in the STA, not all applications have one shared thread in one shared STA.
Peace!
-=- James Please rate this message - let me know if I helped or not!<hr></hr> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Thanks James,
1.
My understanding is, inside the STA, no message queue is needed, and the message queue is only needed when there is call from other apartment, right?
2.
For call from other apartment, I think the call from other apartment are translated into messages into the message queue, and the thread in the STA is responsible for retrieve the message, invoke the object, and finally return the method call result by the means of message into the queue again, right?
But I have not seen samples when the STA thread explicitly retrieves message from somewhere, and convert the messages into function call to the component component inside the STA.
Does the STA thread explicitly retrieves message from somewhere, and convert the messages into function call to the component component inside the STA?
regards,
George
|
|
|
|
|
Cross-apartment STA calls, regardless of inter- or extra-process, involve the message queue. I do not believe that STA calls between two objects created in the same process and apartment involve the message queue.
The message-and-parameters getting unpacked into a method call on the COM interface, and the return/result from that call, are all handled by the COM subsystem for you. This is why you never have to write code that cracks the messages and their parameters, etc. Remember that each window has a pointer to a WinProc - in the case of COM message queue windows, this WinProc is implemented in the COM subsystem.
Peace!
-=- James Please rate this message - let me know if I helped or not!<hr></hr> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Thanks James,
Another terms which makes me confuesd is marshell. From my study, if we call from one apartment to another STA apartment, even in the same process, the call needs to be marshelled.
I am confused,
1. Is marshell the same thing as to translate method call into windows message and push into STA hidden window?
2. If no to (1), what is the different function between marshell and the message window when we call a function in STA? I think a message windows is enough (for synchronize message processing) to STA, why involve marshelling as well?
regards,
George
|
|
|
|
|
Simply, marshalling is the packaging of data so that it can be serialized/transported in an independent format. For example, you cannot (normally) pass memory directly between two applications, as each runs in its own address space. So one way is to write the data to a file, and then have the other applicatoin pick-up that file. The file is used as a way to marshall data between the two processes. The same thing happens when you use functions like htonl(...) and ntohl(...) in Winsock.
Marhsalling in COM is basically the same thing. It is a way to convert the standard Marshall-able data types (String/BSTR, 32-bit integers, characters, etc.) so that they can be passed between processes (even across the network), and reconstituted into the actual data.
Nornally, marshalling is limited to certain data types, called the automation-capable data types, or Marshall-able types. You can expand on this by writing your own marhsalling code so you can then support marhalling of more complex types between interfaces.
Peace!
-=- James Please rate this message - let me know if I helped or not!<hr></hr> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Hi James,
My questions, for exmaple why transfer data through one apartment to another STA needs marshelling? Is marshelling used for data synchronization control? Or it is just used for pack/unpack data?
Why even in the same process between two STA, marshelling is needed?
regards,
George
|
|
|
|
|
A process can only have one STA. I do not think that marshalling is used for same-process same-STA access, but an interface may still need to be automation-compliant to work with some technologies (like scripting engines). Cross-process calls need mashalling because memory is owned by a particular process.
Marhsalling is only used for packing and unpacking.
Peace!
-=- James Please rate this message - let me know if I helped or not!<hr></hr> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Hi James,
1.
A process could have more than one STA. Please read this,
http://www.codeproject.com/KB/COM/CCOMThread.aspx[^]
2.
When do we need to explicitly program message loop in STA thread? Like this code segment in the article. I have this question because I noticed all samples in the article, including the ones for cross-apartment do not explicitly get message, translate message and dispatch message.
DWORD WINAPI ThreadProc(LPVOID lpvParamater)
{
::CoInitialize(NULL);
...
...
...
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
::CoUninitialize();
return 0;
}
3.
For marshelling between apartments, I think all stub/proxy code are generated automatically by COM Runtime, right? No need for us to explicitly program stub/proxy code (e.g. using MIDL compiler do generate stub/proxy by ourselves)?
regards,
George
|
|
|
|
|
1: I was mistaken.
2: I am under the impression that you need to have a message pump running for any STA COM Calls. The primary thread in a normal apps (that already have a message pump) should not require another pump, unless you are creating a separate thread that does not have its own message pump.
3: Marshalling of standard automate-able types is automatic, IIRC.
-=- James Please rate this message - let me know if I helped or not!<hr></hr> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Thanks James,
What do you mean "standard automate-able types"? Could you provide a link about the definition please?
regards,
George
|
|
|
|
|
A good question - each time I asked it got the answers starting with "IMHO"
Take a look at this article[^] Maybe it helps.
|
|
|
|
|
Cool stuff, Nemanja!
regards,
George
|
|
|
|
|
Hi all,
I received this error message when comiling:
fatal error C1083: Cannot open include file: 'afxwin.h': No such file or directory
How can I get this file?
Many thanks in advance
|
|
|
|
|
Have you the Express Edition of Visual Studio (AFAIK that file is part of MFC , hence it is not included in such VS edition)?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
I've only VS 2005. Now how can I find thsi file?
Many thanks
|
|
|
|
|
specialhaha wrote: Now how can I find thsi file?
Like you would any other file. For VS6, it's located in the \Program Files\Microsoft Visual Studio\VC98\MFC\Include folder. If the file is not on your development machine, verify that you installed MFC.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hi,
Will this[^] be helpful ?
Regards,
Paresh.
|
|
|
|
|
I drag "Spin Control" on dialog form. Line "CONTROL '',IDC_SPIN1,'msctls_updown32' ..." is appeared in rc-file.
Can I disable left arrow or right one ?
Thanks.
|
|
|
|
|
Hi,
Is this helpful: Owner Drawn Spin Control[^]
Also, see the comment at bottom of that page for some suggestion.
Best Regards,
Suman
|
|
|
|
|
Hi
I am new to windows and vs programming.
A supplier has provided 3 files written using vc++ 2008. Files include a c++ header file, a library file and a DLL file for use with an API the suppliers system.
I want to experiment with this API but cannot work out how to use the functions that are part of the DLL. The functions are explaned in the header(.h) file.
I placed all 3 files in my new projects solutions directory and added the .h file as part of my c++ solutions header files along with Form1.h, resource.h and stdfx.h files.
I'm not sure what to do with the library(.lib) file or where to put any of the files really. I assume some how I have to attach or link the DLL file to my solution so that the header definintions mean something.
The header file also contains the following define.
// DLL Export/Import define
//
// This define makes it possible to use the SystemAPI.h file in both the DLL
// and Main Application solutions.
// The SYSTEMDLL_EXPORTS is defined in the DLL source code and should NOT be
// defined in the Main Application!
#ifdef SYSTEMDLL_EXPORTS
#define SYSTEMDLL_API extern "C" __declspec(dllexport)
#else
#define SYSTEMDLL_API extern "C" __declspec(dllimport)
#endif
Can anyone help out with this?
Thanks in advance for any help.
|
|
|
|
|
You should add the DLL library (.lib ) file to your project:
Select project->properties menu item.
On the newly appeared window, select Configuration Properties->Linker->CommandLine
Add you library file name to the Additional options text box
Moreover, you need to make the IDE aware of where your library file is (you may add the library file folder path to the known library directories: Tools->Options menu item, then Project and Solutions->VC++ Directories , select Library files item of the Show directories for list).
r0wdy wrote: The header file also contains the following define.
// DLL Export/Import define
//
// This define makes it possible to use the SystemAPI.h file in both the DLL
// and Main Application solutions.
// The SYSTEMDLL_EXPORTS is defined in the DLL source code and should NOT be
// defined in the Main Application!
#ifdef SYSTEMDLL_EXPORTS
#define SYSTEMDLL_API extern "C" __declspec(dllexport)
#else
#define SYSTEMDLL_API extern "C" __declspec(dllimport)
#endif
When compiling you should NOT define SYSTEMDLL_EXPORTS , since you're actually importing.
BTW on running the application, make sure the DLL file is reachable (for instance, put it in the same folder of the executable)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Hello everyone,
Is it legal and good code to call one constructor from another in the same class? I show the pseudo code below.
Test(bool param1, bool param2)
{
Test (param2);
}
Test(bool param2) : active (param2)
{
}
thanks in advance,
George
|
|
|
|
|