|
One suggestion: Create a third class to hold this data. Then from each of the forms reference the instance of the class that you set up to hold/manage the data.
Does this help?
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
Coming soon: The Second EuroCPian Event[^].
|
|
|
|
|
Hi,
I have read about reflections, seems to be a cool thing... but It's seems more oriented to do case tools than other things ? Am I Wrong ? Some people says me that it's used on huge projects... but I think all that thing of calling "Invoke" and things like that remembers me to the IDispatch nightmare and GUIDS and ...
|
|
|
|
|
Reflection is definitely useful for case tools, but it can be used in production code, although the size of the project doesn't matter. For instance, reflection is used by the runtime and XML serialization routines. Reflection could also be used - while not recommended - to get/set a private field in a class if you really need to (its name could be changed at any time, though, which is one reason it's not recommended). You could use reflection to discover type information at runtime, which makes it a good solution in many things like IDispatch interfaces, although reflection is much easier to use, IMO, than dispatch (just less things you have to do to accomplish the same thing, which is pretty universal comparing .NET to lower-level languages like C and C++).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have an app which uses an ActiveX component. No problmes there. I have now converted it to run as a windows service, which also work fine when i configure the service to run using my NT Login account. However, when i configure the service to run using the System Account, i get an exception:
System.IO.FileNotFoundException: The specified module could not be found.
when the code tried to instantiate the ActiveX control.
I have the Path to the Dll in the system environment. Does any one have any ideas?
Thanks
|
|
|
|
|
With ActiveX, the PATH environment variable doesn't really matter (it can, but is not typically necessary, because...). When an ActiveX control is registered, it's server's path (the executable that contains the control) is registered in the Windows registry under HKEY_CLASS_ROOT\CLSID. This is one thing that makes COM so attractive - you don't have to worry about where the file is (thus helping to eliminate DLL hell, so long as you follow good COM guidelines about interface naming and the like).
Make sure the ActiveX DLL (or OCX or whatever) is registered correctly using regsvr32.exe.
The other possibility is that the interop assembly was not found. When you import an ActiveX control (or even a typelib) interop assemblies are generated, which are also called Runtime Callable Wrappers, or RCWs. Those assemblies must be either in the same directory as the service executable, in the probing path (configurable in the .config file, which must also be in the same directory as the service executable and named the same as the executable + ".config"), using the <assemblyBinding> section in your .config file, or installed into the Global Assembly Cache (GAC), which requires that the assembly be signed (it's easy, just use sn.exe -k KeyFile.snk to generate a key pair).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
We have a strange problem in equating string and BSTR between a ATL server and c# client.
I have given a similar sample below.
What am i doing wrong?
c# client
=====
AirlineInfoObjClass _aobj=new AirlineInfoObjClass();
string _time=_aobj.GetAirlineTiming("IC5678");
Console.WriteLine("The timing is {0}", _time);
ATL DLL
=====
STDMETHODIMP CAirlineInfoObj::GetAirlineTiming(BSTR bstrAirline, BSTR *pbstrDetails)
{
// TODO: Add your implementation code here
USES_CONVERSION;
BSTR m_Airline=SysAllocString(L"IC5678");
if(m_Airline == bstrAirline)
{
*pbstrDetails = SysAllocString (L"16:45:00 - Will arrive at Terminal 3");
}
else
{
// Return the Airline name if not found
*pbstrDetails = bstrAirline;
}
return S_OK;
}
The above always returns me the airline name,while theoretically it should return the "16:45:00........" message.Can someone help?
|
|
|
|
|
This is an error in your C++ code. The == operator on BSTRs does a pointer comparison (since BSTR is a typedef for unsigned short* ). Use wcscmp .
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Yes. And also make sure pbstrDetails is marked as [out, retval] in your IDL.
Sincerely,
-Ron
|
|
|
|
|
We are in the process of converting ATL clients to C#.
However,I have not been able to make errors to get progated properly.
I have read that teh ATL component is reqired to support the ISupportErrorInfo interface for erro propagation to work.
Subsquently here is the point where error is raised from a ATL dll
else
{
CreateErrorInfo(&pErrorInfo);
if(hSuccess)
{
pErrorInfo->SetGUID(IID_IAirlineInfoObj);
pErrorInfo->SetDescription(SysAllocString(L"Data not found"));
IErrorInfo* _errInfo=NULL;
hSuccess=pErrorInfo->QueryInterface(IID_IErrorInfo,(void**)&_errInfo);
if(hSuccess)
{
SetErrorInfo(0,_errInfo);
}
}
return E_FAIL;
}
And the C# client tries to trap it as follows
catch(Exception e)
{
Console.WriteLine( " The exception is {0}",System.Runtime.InteropServices.Marshal.GetHRForException(e));
}
This does not work.How do i retrieve the data I had set on the IErrorInfo interface in the COM server?
|
|
|
|
|
What exactly doesn't work? The runtime should throw a System.Runtime.InteropServices.COMException when your COM component returns an E_FAIL error code, unless you've used the PreserveSig attribute. Visual Studio and the tlbimp tool default to throwing exceptions for COM error codes.
The message and help information you specified in the ErrorInfo object should be present in the Message , HelpLink and Source properties of the COMException object.
You may find the ATL function AtlReportError easier to deal with than handling the error info object directly.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Hi guys! Im using a third party external type library (C API) currently running in VB6. This is a low-level COM so it can't be converted to MSIL code nor it can be reference as COM inside a C# app. What I did is call this as an unmanaged code thru Platform Invoke. Most of the methods/functions were working fine except for some where it returns an exception of System.NullReferenceException. I found out that the method i called calls another method (with parameters) from a Module. However VB.Net and C# doesn't support this upgrade? Is this true? Then how do i go around with this? What other options can I resort to? I really have to CALL those methods/functions in my project because its the main core of my app logic process. Pls advise. Tnx!
|
|
|
|
|
Can I clarify? You're using a DLL with flat exports from VB6 using the Declare statement, and it calls back into your VB program (you pass function pointers into the DLL using the VB AddressOf syntax)?
You're probably getting access violations (the CLR converts an access violation SEH exception into a System.NullReferenceException managed exception) because you haven't initialised the callback function pointers.
To get a callback from unmanaged into managed code, you need to use a delegate . See MSDN: Implementing Callback Functions[^].
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
No. I have a third party COM API(Neteng.tlb file) which is full COM compliant. I used this COM object in my VB 6 programs by adding a reference to it. When i browse its library thru Object Browser i noticed it has a lot of enumerations(enum in c#) and types(struct in c#) defined. It also exposes one method (NE_AddElement) but this is a MEMBER of a Module.
-----------------------------------------------------------------
It says in Object Browser like...
Sub NE_AddElement(netedit As Long, elatt As ElementAttRec)
Member of NETENG.NETENGAPI
Add the given element using the specified element record.
WHERE NETENGAPI IS...
Module NETENGAPI
Member of NETENG
-----------------------------------------------------------------
That means that this method belongs to the Module not to the class so after i made a reference to the COM i can automatically used the NE_AddElement method defined there and it works fine. My VB 6 program can recognized the method.
Now i tried using the same COM API (Neteng.tlb) inside a VB.Net/C#. I made a reference to that COM API (as a COM object) inside my VS.NET IDE using the COM portion and it goes fine. I was successful at doing that but when i compile the code it RETURNED a compilation error saying:
----------
The name 'NE_AddElement' does not exist in the class "myclass name here"(CS0103)
----------
Why is that it can't recognized the NE_AddElement method though i have successfully Add a Reference to its COM? When i checked the equivalent InterOp assembly created after making the referencing i noticed it only exposes the class level enumerations and class level structs. Members of NETENGAPI (a Module) like the method NE_AddElement were not exposed. In VB 6 it can recognized the method as member of the NETENGAPI module. Can someone tell me how My VB.NET/C# program can fully recognized and in doing so used the NE_AddElement method!!!! Tnx in advanced!!!
|
|
|
|
|
Have you opened your library (which, btw, isn't the TLB file - that's only the typelib which contains information about the COM objects in your library) in depends.exe to find the exported function? It may be mangled using C++ decoration.
I'm curious why you can't create an RCW, though. If it is a COM control and contains a typelib (either as an external file or embedded in the .rsrc section of the executable) you can run tlbimp.exe on it (or the external .tlb file). If that doesn't seem to work, you should open the DLL in VS.NET to view the resources and see if the typelib uses an ID other than 0, which using tlbimp.exe you can specify the name of the DLL along with the ID for the embedded typelib like so:
tlbimp.exe MyLib.dll/1 If this also contains an ActiveX control, you can use aximp.exe to create an interop assembly that contains a control/controls that derive from AxHost , which derives from Control an can be used in a container control.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Its not a COM control its just a COM file(neteng.tlb). I noticed there's two other file in the same installation directory of that DLL (neteng.lib and neteng_CB.lib). How are this files related to neteng.tlb COM file?Which file should i import using tlbimp.exe?Importing neteng.lib or neteng_CB.lib via tlbimp says its not a valid type library. But i can import neteng.tlb and and it can create an assembly. This is exactly the same COM i used in my vb 6 program. I noticed also that the interop assembly created for the COM doesnt show any existence of a class. Only the namespace name, structs and enums are shown. The module and its methods were not exposed. So how would i be able to call the methods of the module as part of the created interop assembly if in the first place i can't see them present in the created assembly? Many Thanx!
|
|
|
|
|
As I said in my reply, you use tlbimp.exe on the typelib - either an external .tlb or a typelib as a resource in an execute. A typelib, BTW, contains no executable code. There is still a COM server somewhere on your server that implements the interfaces that the typelib describes. That's all typelibs are - information about COM objects implemented in an executable (the COM server) that languages and frameworks can use to discover type information at design-time and compile-time.
Even VB only uses the typelib for type information. At runtime, the CLSIDs (class IDs) are used to find the executed and its class factory creates an instance of the COM object with that CLSID (this is a very basic overview). If tlbimp.exe doesn't see a certain object or method, it's probably because it violates some rules of COM and cannot be imported.
You should familiarize yourself with COM since VB hides all that from you, and run oleview.exe (part of the Platform SDK tools, which is installed by default with Visual Studio) passing the path to your typelib as the sole parameter. This will show you the IDL. Take a look at the method and, if you want, post back the method signature in this thread.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'm just trying to toggly between two check boxes a draw x values and a draw y values. I found this code but I'm getting a stack overflow error when I click on the check box....
private void XvaluescheckBox_CheckedChanged(object sender, System.EventArgs e)
{
// Toggle boolean
switch(this.XvaluescheckBox.CheckState)
{
case CheckState.Checked:
// Code for checked state.
this.m_bDrawXValues = false;
this.XvaluescheckBox.CheckState = CheckState.Unchecked;
break;
case CheckState.Unchecked:
// Code for unchecked state.
this.m_bDrawXValues = true;
this.XvaluescheckBox.CheckState = CheckState.Checked;
break;
case CheckState.Indeterminate:
// Code for indeterminate state.
break;
}
}
private void YvaluescheckBox_CheckedChanged(object sender, System.EventArgs e)
{
// Toggle boolean
switch(this.YvaluescheckBox.CheckState)
{
case CheckState.Checked:
// Code for checked state.
this.m_bDrawXValues = true;
this.YvaluescheckBox.CheckState = CheckState.Unchecked;
break;
case CheckState.Unchecked:
// Code for unchecked state.
this.m_bDrawXValues = false;
this.YvaluescheckBox.CheckState = CheckState.Checked;
break;
case CheckState.Indeterminate:
// Code for indeterminate state.
break;
}
}
|
|
|
|
|
You're changin the check state of the checkbox inside the CheckChanged event handler -- i.e. as soon as your check state has changed, your function gets called. Your function then changes the check state, once again calling your function, which goes forever in a loop until the stack overflows.
If you need to change the check state of the checkbox inside the check change function, unhook the event handler first. Try something like
private void YvaluescheckBox_CheckedChanged(object sender, System.EventArgs e)
{
switch(this.YvaluescheckBox.CheckState)
{
case CheckState.Checked:
this.m_bDrawXValues = true;
this.YvaluescheckBox.CheckChanged -= new EventHandler(YvaluescheckBox_CheckedChanged);
this.YvaluescheckBox.CheckState = CheckState.Unchecked;
this.YvaluescheckBox.CheckChanged += new EventHandler(YvaluescheckBox_CheckedChanged);
break;
Or, just don't set the check state of the check box inside your check state change event handler like you're doing there.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
If you have two (or more) checked buttons and only one of them should be set at a time, then you should use option buttons.
I see dumb people
|
|
|
|
|
So do I, all the time!
I used the radio buttons, those work nicely..Doh!
|
|
|
|
|
Isnt CheckedChanged called after the checkboxes state is changed? Basically, your recieving the event, and changing a property of the checkbox, that causes the event to be fired again, so its a vicious circle.
Instead, try:
private void XvaluescheckBox_CheckedChanged(object sender, System.EventArgs e)
{
this.m_bDrawXValues = this.XvaluescheckBox.Checked;
}
private void YvaluescheckBox_CheckedChanged(object sender, System.EventArgs e)
{
this.m_bDrawYValues = this.YvaluescheckBox.Checked;
}
I havent tested it, but that should work. Strictly speaking, you dont even need the m_bDrawXValues and m_bDrawYValues variables, you can use the Checked property of the checkboxes.
To those who didn't make it, we will remember you. To those who did is back. - Megan Forbes in Black FridayAnother Post by NnamdiOnyeyiri
|
|
|
|
|
Hi
I made an application with Crystal dependecie. When I made the Setup Project, this detect it. And add a crystal packet, but when I build the project, and try to install this in another PC without Crystal assembly, the install begins but in the middle stop with a warning about a miss assembly, I imagine this miss assembly is Crystal, cuz I only use .NET and Crystal assembly, anyone else.
What can I do??
Thanks.
----
hxxbin
|
|
|
|
|
|
Thanks I'm lookin' the article about in MSDN.
----
hxxbin
|
|
|
|
|