|
Yep, I was also thinking about, taking the src of the image and then downloading it again and so. Though it is kind of stupid to download the images two times, so I was hoping for an easier solution.
But I quess I have to live with this ... Thanx
|
|
|
|
|
You don't actually have to download it twice. Use the moniker functions like IE does like URLDownloadToCacheFile , which even gives you callback. The file is pulled from the cache based on the browser's cache settings. You can also bind an image to the URL moniker directly, which is how IE / Windows usually handles things. This, agian, should be under the control of the cache settings.
Reminiscent of my younger years...
10 LOAD "SCISSORS"
20 RUN
|
|
|
|
|
That sounds good. at least better than downloading the images twice. I'll have to try that.
Thnx again for your answer
|
|
|
|
|
i wrote a EXE server.registered the dll and exe. when i am running my client program it throws an error that required interfaces are not implemented.
the client is a standard OPC client, it only detects the IConnectionPointImpl
default interface.the other custom interfaces are not detected by the client.
what may be the cause.
cheers
satish
|
|
|
|
|
I have a query regarding component versioning.
I had a component named "Old_VC_Exe_Component" exposed as an STA, out-of proc COM server, developed in VC++. This is for our internal use and not for client.
"Old_VC_Exe_Component" is wrapped by another component "Old_VB_Dll_Component_Wrapper" which is in-proc COM server developed in VB, and this is exposed as SDK to client.
Now we are planning to provide new version of our product.
In new version, we are thinking of removing the wrapper layer. That is we want to expose "Old_VC_Exe_Component" to client (as "New_VC_Exe_Component") instead of "Old_VB_Dll_Component_Wrapper".
We can change server code at server end. And the requirement is that, client of "Old_VB_Dll_Component_Wrapper" SDK should not be required to make any change in his code, when we replace "Old_VB_Dll_Component_Wrapper" by "New_VC_Exe_Component".
Can you tell me is this possible? Or what can be the possible issues in doing this?
|
|
|
|
|
Yes, of course. Your new component should have the same CLSID (or ProgID, translated into necessary CLSID) and the same set of interfaces as the old DLL-component.
There is a "location transparency" rule in COM. Look at MSDN for more information about this.
With best wishes,
Vita
|
|
|
|
|
Thanks. I am facign following trouble:
Create a COM component "InProcVB.dll" as in-proc DLL in VB exposing some interfaces and methods .
Write its client as "clientVB".
Write another COM component as "OutOfProc.exe" as out-of-proc exe server in VC. This has same
interface/class/InterfaceIDs/ClassIDs as that of "InProcVB.dll". This is written with purpose of
replacing "InProcVB.dll". And, the expectation is that client need not re-compile. (As defined by
rule "Location transparency of COM).
After developing "OutOfProc.exe", we unregistered "InProcVB.dll", and registered "OutOfProc.exe".
Executed "clientVB" without any change. It gave error type-mismatch. The error point was:
Dim objSrvClass as SrvClass
set SrvClass = CreateObject("Server.Class") --> Problem: Type mismatch.
If I change code as
Dim objSrvClass as Object
set SrvClass = CreateObject("Server.Class")
It works well.
Please suggest.
|
|
|
|
|
I have no problem at all.
I made the VB's Server.dll, VC's Server.exe and testing Project1.exe. Tested object has one method xxx in VB server
Public Sub xxx()
MsgBox "xxx subroutine is called"
End Sub
and in VC server
STDMETHODIMP CClass::xxx()
{
MessageBox(NULL,"ATL xxx is called", "ATL", MB_OK);
return S_OK;
}
and testing code in Project1 project
Sub Main()
Dim x As Server.Class
Set x = CreateObject("Server.Class")
x.xxx
End Sub
When i register some COM server, I have relevant message: if VB, then VB, if VC, then VC. I.e.
>regsvr32 Server.dll
>Project1.exe
Having ... xxx subroutine is called
>regsvr32 /u Server.dll
>Server.exe -RegServer
>Project1.exe
Having ... ATL xxx is called
>Server.exe -UnRegServer
There is no magic. It's possible that you have a mistake. I also firstly made a mistake - I have mixed up the coclass and interface IDs. And I had "Type mismatch"
With best wishes,
Vita
|
|
|
|
|
Thanks for your efforts. Can you please send us the code of both VB and VC server and client samples that you have written?
This will help us in locating problem at our end.
Regards.
|
|
|
|
|
Just wondering if anyone has done any study into the speed of COM? In particular, a comparison of the time taken to access a COM object's methods with a locally defined object's methods.
In my application I have put all of the ADO functionality into a COM object, however, it's really slow to query the database (through the COM object) and then display the results. I am considering using a simple C++ class instead, since there is only one application accessing the database anyhow.
Any comments or ideas on this would be really helpfull.
|
|
|
|
|
You need to answer following before perfromace measurement:
What is type of your server? out-of-proc/in-proc?
What interfaces are you using? Dispatch/Dual?
What is the frequency of clietn server interaction?
|
|
|
|
|
Here are the results of the test, performed on NT4SP3, Pentium Pro 300Mhz, 128Mb RAM, and a 10Base-T network connection:
Early Bound Late Bound Cached
In Process 20 ms 90 ms 80 ms
Out of Proc 1952 ms 5137 ms 2944 ms
Remote 14952 ms 36403 ms 20089 ms
|
|
|
|
|
Thanks for your test results.
My server is a DLL with proxy/stub merged, with a dispatch interface. The server is always local and in-process. This is the fastest possible configuration, right?
The client-server interaction is fairly high frequency... i think this is my problem. For example, to populate a dialog before it is displayed, the client queries the server to Find() the appropriate record (ADO to an Access DB), then the client uses separate calls to retrieve each field (about 10 fields). The server is not doing much work here, just returning global variables that were set during the previous Find() method.
My customer requires this to run on a pre-pentium machine, 100MHz, 24Mb RAM, Win 98. Of course, on my development beast, the screen updates instantly, but the customer machine takes about 7 seconds (yuk )
Do you think it's the COM component slowing it down?
Jo
|
|
|
|
|
The solution for this is that you should club separate calls into a single call. For example:
Suppose you have a collection of 100 items, and collection's object has 4 attributes each. To display all the properties, your client is doing something like this:
For each item of collection:
{
Get object
get first prop of object
get second prop of object
get third prop of object
get fourth prop of object
}
So, you are making 5 *100 = 500 calls to COM server. Instead you should define prototype like this:
Collection->GetAllproperties([out] Variantarray)
So, single call to COM server will achieve this.
Regards.
|
|
|
|
|
As long as the threading model of the thread matches that of the component, there shouldn't be any proxy/stub work going on, and the call into the component is just a virtual function call, which isn't much more costly than a non-virtual call.
If both parts (client and component) are written in C++, or if the client is VB6, try to ensure that your component exposes a vtable interface as well as the dispatch interface - a dual interface, as it's known. This is basically a custom interface derived from IDispatch, so that callers which can early bind do so, while late-binding callers aren't shut out.
If the threading model of the component doesn't match the threading model of the caller, COM will introduce a proxy and stub to marshal between the caller and the component within the thread. This is less costly than having the component as a local server process, but more costly than a plain call.
This might happen if your component is marked 'Free' but your client is either VB6, or calls CoInitialize or CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); to initialise COM from C++. If the component is marked 'Both', it will behave as if you'd specified 'Apartment' if the thread that created it runs in the Single-Threaded Apartment (conditions as above), or 'Free' if the creator runs in the Multi-Threaded Apartment.
I suspect, though, that your database accesses are what's killing you. Measure the actual performance of Access on that system configuration. It's going to be sluggish - indeed with only 24Mb of RAM, it's likely to be constantly swapping.
Generally it's a good idea to compile your app with the 'Minimize Size' compiler options - in VB, this is Project Properties > Compile tab > select Compile to Native Code and Optimize for Small Code.
In VC 6.0, I use the /Oxs option - full optimization, favor small code - and the /Og option - global optimizations. I also use /Gy (enable function-level linking) and specify /OPT:REF to the linker (Remove unreferenced functions). This last is the default, but it gets turned off if you generate debugging information for the release build, which I do. Specifying /OPT:WIN98 might improve your startup time on Windows 98.
Doing this can reduce your code size, which can reduce the number of page faults you take.
You could also try using a profiler to find out where the hotspots are. The Win32 SDK contains a tool called the Call Attributed Profiler, or CAP.
--
Mike Dimmick
|
|
|
|
|
Thanks Mike, for such a detailed response!
I have been working through each of your points.
My COM objects and the exe use apartment threading, and a dual interface.
(All of the components are written in VC++).
The exe initialises COM with ...
struct InitOle {
InitOle() { ::CoInitialize(NULL); }
~InitOle() { ::CoUninitialize(); }
} _init_InitOle_;
And then creates the COM objects with ...
CoCreateInstance( CLSID_SubstrateMgr,
NULL,
CLSCTX_INPROC_SERVER,
IID_ISubstrateMgr,
(void **) &g_pSubstrateMgr);
Is this the fastest method?
I have used all of the optimisation settings you suggested, although I can't see any noticable difference.
I believe you are right about the database access being the trouble spot. If the COM calls aren't that much worse than a function call, I can leave my COM interfaces alone and focus on the database access.
Thanks again for your help.
Jo
|
|
|
|
|
Keep in mind that ADO is dog slow. Use OLEDB directly and you will see 2-3 times perfomance increase. Example: I created an ASP page that used ADO to return a simple recordset(SELECT TOP 50 FROM TABLE1) and loop through the recordset to generate an HTML table. Then I wrote a C++ COM object that that accessed OLEDB directly instead of ADO from my ASP page. Then I used ATL Server and my C++ COM object.
Here's what I found: 1) ASP/ADO - 70 requests/sec 2) ASP/C++ COM/OLEDB - 290 request/sec 3) ATL Server/C++ COM/OLEDB - 370 request/sec.
The problem with ADO is that everything is a VARIANT so it can be easily used by scripting clients. OLEDB is meant to be used by compiled/early bound languages.
|
|
|
|
|
I ported Mario Zucca's grid control to WinCE using eVC++ 3.0 compiler, but making it a Full Control to that it can be easily used in c++ MFC programs like any other ActiveX control. All that went without very many problems -- except being able to fire events. So I just copied the code to do that into my project and it seemed to work.
Then I created a test C++ MFC Dialog-based program, added the control and using ClassWizzard created the events that were exposed and explained above. That too seemed to work. However, When the control attempts to fire the event, it cannot because it doesn't realize that it has any client containers!
For example: m_vec.GetSize(); always returns 0. Does anyone know how to fix this problem?
<br />
HRESULT Fire_BeforeEdit(INT Row, INT Col, VARIANT_BOOL * Cancel)<br />
{<br />
CComVariant varResult = VT_EMPTY;<br />
T* pT = static_cast<T*>(this);<br />
int nConnectionIndex;<br />
CComVariant* pvars = new CComVariant[3];<br />
<br />
int nConnections = m_vec.GetSize();<br />
<br />
<br />
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)<br />
{<br />
pT->Lock();<br />
|
|
|
|
|
Hello!
Can I access COM object from java?
Thanks
|
|
|
|
|
EZ JCom lets you call COM objects from Java. Check http://www.ezjcom.com/
|
|
|
|
|
I would like to create a COM object with all my ADO methods. I then would like to have Visual Basic pass a recordset pointer to my COM DLL. Is this possible? If so how would I go about it?
Thanks
|
|
|
|
|
Hi itz possible,
you implement all the ADO classes into your class. Take a template
Implements {ADOCLASSNAME}
then... call the ado object.
I dont why you want to call all this.
Best of Luck
|
|
|
|
|
We have written an ou-of-proc, Free threaded, ATL server.
When 4 web users call this server for 5-6 hours, this server hangs, and a new instance of the server is launched in the memory. And the new server also not responds to user calls.
Can somebody tell me the possible cause of this trouble?
|
|
|
|
|
I have soem queries regarding component versioning.
I had a component named "Old_Component" exposed as an STA, out-of proc COM server, developed in VC++. This is wrapped by another component "Old_Component_Wrapper" which is in-proc COM server and exposed to client.
Now we are planning to provide new version of our product.
In new version, we are thinking of removing the wrapper layer. That is we want to expose "Old_Component" to client instead of "Old_Component_Wrapper". Can you tell me is this possible? Or what can be the possible issues in doing this?
|
|
|
|
|
Yes, it is possible. All you are doing is taking a contained or aggregated server and making it an independent out-proc server.
Kuphryn
|
|
|
|