Thread: [pygccxml-development] Two patches proposal
Brought to you by:
mbaas,
roman_yakovenko
From: Berserker <ber...@ho...> - 2009-12-23 11:07:32
|
Hi, I'd like to discuss about two issues 1) properties generation I have some classes like this one: class Foo { Bar getBar() const; void setBar(const Bar &bar); }; getBar returns a temporary object because the return value is created by a conversion from an internal stored string (setBar saves the value in the same way) . In this case name_based_recognizer_t creates a "readonly" property "Bar" instead of a read/write one, so I'm overriding the method in this way: def check_type_compatibility(self, fget, fset): if decl_wrappers.name_based_recognizer_t.check_type_compatibility(self, fget, fset): return True t1 = fget.return_type t2 = fset.arguments[0].type if declarations.is_reference(t2): t2 = declarations.remove_cv( declarations.remove_reference( t2 ) ) if declarations.is_same( t1, t2 ): return True return False What about this change? Is it reasonable to be "merged" in the svn? 2) Implicit conversions: class Foo { public: Foo(int v, bool flag = true); // convertible from int Foo(double v1, double v2); // not convertible from double because v2 hasn't default value }; I looked at constructor_t.does_define_implicit_conversion implementation and I think that the following two lines are "incomplete": if 1 != len( self.arguments ): return False Isn't supposed to be: if 1 != len( self.arguments ) and (arguments > 1 haven't default value): return False Using the above patch Foo should be implicit convertible from int right? How can I write it? Any hope to apply the code to the svn? Bye _________________________________________________________________ Giochi, radio, TV... E tutti i tuoi amici. Cercali su Messenger http://www.messenger.it/home_comunica.aspx |
From: Roman Y. <rom...@gm...> - 2009-12-23 13:13:56
|
On Wed, Dec 23, 2009 at 1:07 PM, Berserker <ber...@ho...> wrote: > Hi, I'd like to discuss about two issues Hello > 1) properties generation > > I have some classes like this one: > > class Foo > { > Bar getBar() const; > void setBar(const Bar &bar); > }; > > getBar returns a temporary object because the return value is created by a > conversion > from an internal stored string (setBar saves the value in the same way) . > In this case name_based_recognizer_t creates a "readonly" property "Bar" > instead of a read/write one, > so I'm overriding the method in this way: > > def check_type_compatibility(self, fget, fset): > if decl_wrappers.name_based_recognizer_t.check_type_compatibility(self, > fget, fset): > return True > > t1 = fget.return_type > t2 = fset.arguments[0].type > > if declarations.is_reference(t2): > t2 = declarations.remove_cv( declarations.remove_reference( t2 ) ) > if declarations.is_same( t1, t2 ): > return True > > return False > > What about this change? Is it reasonable to be "merged" in the svn? The short answer is no :-(. The main reason for it: such code does not meat user expectations. Let me explain: foo = Foo() foo.Bar.x = 2 assert foo.Bar.x == 2 The following is explanation how I thought "add_properties" functionality should be used in such case. class custom_name_based_recognizer_t( name_based_recognizer_t ): def __init__( ... ): ... def check_type_compatibility(self, fget, fset): <your code > cls = mb.class_( ... ) cls.add_properties( recognizer=custom_name_based_recognizer_t() ) Could it be an acceptable solution? > 2) Implicit conversions: > > class Foo > { > public: > Foo(int v, bool flag = true); // convertible from int > Foo(double v1, double v2); // not convertible from double because v2 > hasn't default value > }; > > I looked at constructor_t.does_define_implicit_conversion implementation and > I think that > the following two lines are "incomplete": > > if 1 != len( self.arguments ): > return False > > Isn't supposed to be: > > if 1 != len( self.arguments ) and (arguments > 1 haven't default value): > return False > > Using the above patch Foo should be implicit convertible from int right? I am not sure. According to the MSDN ( http://msdn2.microsoft.com/en-us/library/h1y7x448.aspx ) "...C++ constructors that have just one parameter automatically perform implicit type conversion. ...". In your case the constructor has 2 arguments. I tested the following code with gcc 4.4.1 struct Foo{ Foo( int i, bool b=false ){} }; void dosmth( Foo ){ } int main( int argc, const char* argv[] ){ dosmth( 11 ); }; and it compiles fine. I don't know C++ at the level of standard. Do you know what the standard says? Does the code compile fines with MSVC compiler? > How can I write it? It is not a problem to write it: if 1 != len( self.required_args ): return False > Any hope to apply the code to the svn? The first issue - I believe you have a solution, the second one - I prefer to know the answers. If they are positive - I will apply the patch almost immediately. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2009-12-23 14:04:57
|
> The short answer is no :-(. The main reason for it: such code does not > meat user expectations. Let me explain: > > foo = Foo() > foo.Bar.x = 2 > assert foo.Bar.x == 2 > > The following is explanation how I thought "add_properties" > functionality should be used in such case. > > class custom_name_based_recognizer_t( name_based_recognizer_t ): > def __init__( ... ): ... > > def check_type_compatibility(self, fget, fset): > <your code > > > cls = mb.class_( ... ) > cls.add_properties( recognizer=custom_name_based_recognizer_t() ) > > Could it be an acceptable solution? Yes, I'm actually using that solution. I'm sad about "user expectations" but what about this case then (without the patch): foo = Foo() b1 = foo.Bar b1.x = 2 b2 = foo.Bar b2.x = ? I think that this is another case where we can discuss about "user expectations", what about? > I am not sure. According to the MSDN ( > http://msdn2.microsoft.com/en-us/library/h1y7x448.aspx ) "...C++ > constructors that have just one parameter automatically perform > implicit type conversion. ...". In your case the constructor has 2 > arguments. I tested the following code with gcc 4.4.1 > > struct Foo{ > Foo( int i, bool b=false ){} > }; > > void dosmth( Foo ){ > } > > int main( int argc, const char* argv[] ){ > dosmth( 11 ); > }; > > and it compiles fine. > > I don't know C++ at the level of standard. Do you know what the > standard says? Does the code compile fines with MSVC compiler? > > > How can I write it? > > It is not a problem to write it: > > if 1 != len( self.required_args ): > return False > > > Any hope to apply the code to the svn? > > The first issue - I believe you have a solution, the second one - I > prefer to know the answers. If they are positive - I will apply the > patch almost immediately. I'm not a "standard expert" too, but I can confirm that your code does compile on MSVC (tested on VC2005 and VC2008). Actually I "tweaked" the method in this way (probably it could be written better...): def override_does_define_implicit_conversion(self): if self.parent.is_abstract: return False if self.is_copy_constructor: return False args = len(self.arguments) if args != 1: if args > 1: for arg in self.arguments[1::]: if not arg.default_value: return False else: return False if self.parent.find_out_member_access_type(self) != declarations.ACCESS_TYPES.PUBLIC: return False return True decl_wrappers.calldef_wrapper.constructor_t.does_define_implicit_conversion = override_does_define_implicit_conversion It works but as you probably know I don't like this solution :) Thanks for your help as usual ;) _________________________________________________________________ Giochi, radio, TV... E tutti i tuoi amici. Cercali su Messenger http://www.messenger.it/home_comunica.aspx |
From: Roman Y. <rom...@gm...> - 2009-12-23 21:29:16
|
On Wed, Dec 23, 2009 at 4:04 PM, Berserker <ber...@ho...> wrote: > Yes, I'm actually using that solution. I'm sad about "user expectations" but > what > about this case then (without the patch): > > foo = Foo() > b1 = foo.Bar > b1.x = 2 > b2 = foo.Bar > b2.x = ? > > I think that this is another case where we can discuss about "user > expectations", what about? Look, I don't want to argue - my experience is different from yours. I believe, in this case Py++ provides a good way to change the default behavior. The code you are using is in the "public interface" and I am not going to break it without very, very good reason. > I'm not a "standard expert" too, but I can confirm that your code does > compile > on MSVC (tested on VC2005 and VC2008). Thanks. I read MSDN (http://msdn.microsoft.com/en-us/library/s2ff0fz8%28VS.100%29.aspx) and it defines "conversion constructor" as "...A constructor that can be called with a single argument is used for conversions from the type of the argument to the class type. ..." I changed and committed the code: http://pygccxml.svn.sourceforge.net/viewvc/pygccxml?view=rev&revision=1782 > Actually I "tweaked" the method in this way (probably it could be written > better...): Yes :-) take a look on the difference > > decl_wrappers.calldef_wrapper.constructor_t.does_define_implicit_conversion > = override_does_define_implicit_conversion > > It works but as you probably know I don't like this solution :) In this case I completely agree with you and hoe you will like SVN version better. > Thanks for your help as usual ;) You are welcome. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2009-12-24 08:25:18
|
> Look, I don't want to argue - my experience is different from yours. I > believe, in this case Py++ provides a good way to change the default > behavior. The code you are using is in the "public interface" and I am > not going to break it without very, very good reason. Sry about this, sometimes my bad english could be "misunderstanded". I didn't want to "argue". Btw happy to know that it's part of the "public interface" :) > In this case I completely agree with you and hoe you will like SVN > version better. Thanks, I'll try it today :) Bye _________________________________________________________________ 25 Gigabyte per le tue foto online http://www.windowslive.it/foto.aspx |
From: Roman Y. <rom...@gm...> - 2009-12-24 08:47:58
|
On Thu, Dec 24, 2009 at 10:25 AM, Berserker <ber...@ho...> wrote: >> Look, I don't want to argue - my experience is different from yours. I >> believe, in this case Py++ provides a good way to change the default >> behavior. The code you are using is in the "public interface" and I am >> not going to break it without very, very good reason. > > Sry about this, sometimes my bad english could be "misunderstanded". > I didn't want to "argue". Btw happy to know that it's part of the > "public interface" :) English is not mother language too. May be I choose the wrong and too much strong word. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2009-12-24 09:47:28
|
> English is not mother language too. May be I choose the wrong and too > much strong word. NP, back "in topic" I think that there is a problem with your implementation :) consider this case: class Foo { public: Foo(int a = 0, bool v = true); }; Using your code: if 1 != len( self.required_args ): return False It doesn't produces a "convertible from int" becase the required_args are 0 but here we have a "convertible from int" class too. Tested again with mine it works: args = len(self.arguments) if args != 1: if args > 1: for arg in self.arguments[1::]: if not arg.default_value: return False else: return False Let me know _________________________________________________________________ Giochi, radio, TV... E tutti i tuoi amici. Cercali su Messenger http://www.messenger.it/home_comunica.aspx |
From: Roman Y. <rom...@gm...> - 2009-12-24 10:29:40
|
On Thu, Dec 24, 2009 at 11:47 AM, Berserker <ber...@ho...> wrote: >> English is not mother language too. May be I choose the wrong and too >> much strong word. > > NP, back "in topic" I think that there is a problem with your implementation > :) > > consider this case: > > class Foo > { > public: > Foo(int a = 0, bool v = true); > }; > > Using your code: > > if 1 != len( self.required_args ): > return False > > It doesn't produces a "convertible from int" becase the required_args are 0 > but here > we have a "convertible from int" class too. > > Tested again with mine it works: > > args = len(self.arguments) > if args != 1: > if args > 1: > for arg in self.arguments[1::]: > if not arg.default_value: > return False > else: > return False > > Let me know You are right. I will fix it this evening. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2009-12-24 21:30:12
|
On Thu, Dec 24, 2009 at 12:23 PM, Roman Yakovenko <rom...@gm...> wrote: > On Thu, Dec 24, 2009 at 11:47 AM, Berserker <ber...@ho...> wrote: >>> English is not mother language too. May be I choose the wrong and too >>> much strong word. >> >> NP, back "in topic" I think that there is a problem with your implementation >> :) >> >> consider this case: >> >> class Foo >> { >> public: >> Foo(int a = 0, bool v = true); >> }; >> >> Using your code: >> >> if 1 != len( self.required_args ): >> return False >> >> It doesn't produces a "convertible from int" becase the required_args are 0 >> but here >> we have a "convertible from int" class too. >> >> Tested again with mine it works: >> >> args = len(self.arguments) >> if args != 1: >> if args > 1: >> for arg in self.arguments[1::]: >> if not arg.default_value: >> return False >> else: >> return False >> >> Let me know > > You are right. I will fix it this evening. I committed the fix. Please, let me know if it works for you or not. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2010-01-11 13:59:30
|
> >> class Foo > >> { > >> public: > >> Foo(int a = 0, bool v = true); > >> }; > >> > >> Using your code: > >> > >> if 1 != len( self.required_args ): > >> return False > >> > >> It doesn't produces a "convertible from int" becase the required_args are 0 > >> but here > >> we have a "convertible from int" class too. > >> > >> Tested again with mine it works: > >> > >> args = len(self.arguments) > >> if args != 1: > >> if args > 1: > >> for arg in self.arguments[1::]: > >> if not arg.default_value: > >> return False > >> else: > >> return False > >> > >> Let me know > > > > You are right. I will fix it this evening. > > I committed the fix. Please, let me know if it works for you or not. Hi Roman, sorry for the late response. I looked at your fix and it seems ok to me. Sorry but at the moment I can't update the svn because we are in a "release" period (I'll update soon btw). Just a "quick" question: I cannot find anything in the documentation about boost::unordered, is it supported by py++? We are using indexing_suite_version = 2 _________________________________________________________________ 25 Gygabite gratis online. Archivia e condividi i tuoi file! http://www.windowslive.it/skyDrive.aspx |
From: Roman Y. <rom...@gm...> - 2010-01-11 18:22:00
|
On Mon, Jan 11, 2010 at 3:59 PM, Berserker <ber...@ho...> wrote: > Just a "quick" question: I cannot find anything in the documentation about > boost::unordered, is it supported by py++? We are using > indexing_suite_version = 2 No. Py++ doesn't support boost::unordered containers. I have a luck to work with recent compilers, so they already have such functionality. If boost::unordered containers does not require tweaking to indexing suite v2, than it should not be too difficult to add support for them. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2010-01-12 10:01:45
|
> No. Py++ doesn't support boost::unordered containers. > > I have a luck to work with recent compilers, so they already have such > functionality. > > If boost::unordered containers does not require tweaking to indexing > suite v2, than it should not be too difficult to add support for them. I confirm that this code compiles without problems: boost::python::class_< std::map<std::string, int> > ("map_string_to_int") .def(boost::python::indexing::map_suite< std::map<std::string, int> >()); boost::python::class_< boost::unordered_map<std::string, int> > ("unordered_map_string_to_int") .def(boost::python::indexing::map_suite< boost:unordered_map<std::string, int> >()); Tested on VC2005 _________________________________________________________________ 25 Gygabite gratis online. Archivia e condividi i tuoi file! http://www.windowslive.it/skyDrive.aspx |
From: Berserker <ber...@ho...> - 2010-01-11 20:28:27
|
> No. Py++ doesn't support boost::unordered containers. > > I have a luck to work with recent compilers, so they already have such > functionality. > > If boost::unordered containers does not require tweaking to indexing > suite v2, than it should not be too difficult to add support for them. I think (but I'm not really sure...) that unordered_map and unordered_set could be "mapped" as standards maps and sets. I think it's important to support these containers since they are now part of the standard library. Let me know if I can help in some way. Bye _________________________________________________________________ Non sei a casa? Prova il nuovo Web Messenger http://www.messenger.it/web/default.aspx |
From: Roman Y. <rom...@gm...> - 2010-01-12 10:19:47
|
On Mon, Jan 11, 2010 at 10:28 PM, Berserker <ber...@ho...> wrote: >> No. Py++ doesn't support boost::unordered containers. >> >> I have a luck to work with recent compilers, so they already have such >> functionality. >> >> If boost::unordered containers does not require tweaking to indexing >> suite v2, than it should not be too difficult to add support for them. > > I think (but I'm not really sure...) that unordered_map and unordered_set > could be "mapped" as standards maps and sets. I think it's important to > support > these containers since they are now part of the standard library. So, may be Py++ should support the std containers first? > Let me know if I can help in some way. Patches :-)? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2010-01-12 10:54:16
|
> >> No. Py++ doesn't support boost::unordered containers. > >> > >> I have a luck to work with recent compilers, so they already have such > >> functionality. > >> > >> If boost::unordered containers does not require tweaking to indexing > >> suite v2, than it should not be too difficult to add support for them. > > > > I think (but I'm not really sure...) that unordered_map and unordered_set > > could be "mapped" as standards maps and sets. I think it's important to > > support > > these containers since they are now part of the standard library. > > So, may be Py++ should support the std containers first? > > > Let me know if I can help in some way. > > Patches :-)? I think that Py++ should support first std container (I mean "automatically" detect it and map to the related indexing suite). Since Py++ already detects some boost classes, I think that it should support boost::unordered too... On the other side I think that some api that allows exposing custom containers (dunno if already exists) should be available, maybe something like: my_container1 -> expose with indexing::map_suite my_container2 -> expose with indexing::list_suite _________________________________________________________________ Velocità, sicurezza e...tanto spazio! Scopri le novità di Hotmail http://www.windowslive.it/hotmail/Home_novita.aspx |
From: Roman Y. <rom...@gm...> - 2010-01-12 19:49:47
|
On Tue, Jan 12, 2010 at 12:54 PM, Berserker <ber...@ho...> wrote: > I think that Py++ should support first std container (I mean "automatically" > detect it and map to the related indexing suite). Since Py++ already detects > some boost classes, I think that it should support boost::unordered too... > On the other side I think that some api that allows exposing custom > containers > (dunno if already exists) should be available, maybe something like: > my_container1 -> expose with indexing::map_suite > my_container2 -> expose with indexing::list_suite I started to implement support for std::unordered_* and already found a first obstacle: gccxml. It is not able to handle C++0x code. I found this post: http://www.mail-archive.com/gc...@gc.../msg00462.html So, in order Py++ and pygccxml support new containers, gccxml should support them first. Tomorrow I will try to add support to boost::unordered containers. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2010-01-12 21:33:06
|
> I started to implement support for std::unordered_* and already found > a first obstacle: gccxml. It is not able to handle C++0x code. I found > this post: http://www.mail-archive.com/gc...@gc.../msg00462.html > > So, in order Py++ and pygccxml support new containers, gccxml should > support them first. > > Tomorrow I will try to add support to boost::unordered containers. Thanks, boost::unordered is what I need now :) I have some custom containers that I need to expose too. Actually I managed to compile this code: boost::python::class_< std::map<std::string, int> > ("map_string_to_int") .def(boost::python::indexing::map_suite< std::map<std::string, int> >()); boost::python::class_< my_map<std::string, int> > ("my_map_string_to_int") .def(boost::python::indexing::map_suite< my_map<std::string, int> >()); but when I execute it an assert complains about an already registered std::string to int mapped type, is there a workaround? My question is (in reality) this: will there be the support to register simoultaneusly the code I wrote in my previous post? boost::python::class_< std::map<std::string, int> > ("map_string_to_int") .def(boost::python::indexing::map_suite< std::map<std::string, int> >()); boost::python::class_< boost::unordered_map<std::string, int> > ("unordered_map_string_to_int") .def(boost::python::indexing::map_suite< boost:unordered_map<std::string, int> >()); _________________________________________________________________ Sei bravo con le parole? Gioca su Typectionary http://typectionary.it.msn.com/ |
From: Berserker <ber...@ho...> - 2010-01-12 21:53:56
|
Raffaele Romito > Date: Tue, 12 Jan 2010 21:49:29 +0200 > Subject: Re: [pygccxml-development] Two patches proposal > From: rom...@gm... > To: ber...@ho... > CC: pyg...@li... > > On Tue, Jan 12, 2010 at 12:54 PM, Berserker <ber...@ho...> wrote: > > I think that Py++ should support first std container (I mean "automatically" > > detect it and map to the related indexing suite). Since Py++ already detects > > some boost classes, I think that it should support boost::unordered too... > > On the other side I think that some api that allows exposing custom > > containers > > (dunno if already exists) should be available, maybe something like: > > my_container1 -> expose with indexing::map_suite > > my_container2 -> expose with indexing::list_suite > > I started to implement support for std::unordered_* and already found > a first obstacle: gccxml. It is not able to handle C++0x code. I found > this post: http://www.mail-archive.com/gc...@gc.../msg00462.html > > So, in order Py++ and pygccxml support new containers, gccxml should > support them first. > > Tomorrow I will try to add support to boost::unordered containers. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ _________________________________________________________________ Non sei a casa? Prova il nuovo Web Messenger http://www.messenger.it/web/default.aspx |
From: Berserker <ber...@ho...> - 2010-01-13 09:29:51
|
One more post about the "double registration" of std::pair in case of: > boost::python::class_< std::map<std::string, int> > > ("map_string_to_int") > .def(boost::python::indexing::map_suite< std::map<std::string, int> >()); > boost::python::class_< boost::unordered_map<std::string, int> > > ("unordered_map_string_to_int") > .def(boost::python::indexing::map_suite< boost:unordered_map<std::string, int> >()); I "patched" the code in pair_header.py (redefining the global variable "code") in this way: BEFORE THE PATCH: pair_exposer_t(const std::string& name){ class_< pair_type >( name.c_str() ) .def( "__len__", &exposer_type::len ) .def( "__getitem__", &exposer_type::get_item ) .add_property( "key", &exposer_type::get_key ) .add_property( "value", &exposer_type::get_mapped ); } AFTER THE PATCH: pair_exposer_t(const std::string& name){ static bool expose = true; if(expose) { class_< pair_type >( name.c_str() ) .def( "__len__", &exposer_type::len ) .def( "__getitem__", &exposer_type::get_item ) .add_property( "key", &exposer_type::get_key ) .add_property( "value", &exposer_type::get_mapped ); } expose = false; } Probably there is a better way to implement this, but now it seems working :) Let me know what's your opinion about this issue. Bye _________________________________________________________________ 25 Gygabite gratis online. Archivia e condividi i tuoi file! http://www.windowslive.it/skyDrive.aspx |
From: Roman Y. <rom...@gm...> - 2010-01-13 11:52:35
|
On Wed, Jan 13, 2010 at 11:29 AM, Berserker <ber...@ho...> wrote: > One more post about the "double registration" of std::pair in case of: > >> boost::python::class_< std::map<std::string, int> > >> ("map_string_to_int") >> .def(boost::python::indexing::map_suite< std::map<std::string, int> >()); > >> boost::python::class_< boost::unordered_map<std::string, int> > >> ("unordered_map_string_to_int") >> .def(boost::python::indexing::map_suite< boost:unordered_map<std::string, >> int> >()); > > I "patched" the code in pair_header.py (redefining the global variable > "code") in this way: > > BEFORE THE PATCH: > > pair_exposer_t(const std::string& name){ > class_< pair_type >( name.c_str() ) > .def( "__len__", &exposer_type::len ) > .def( "__getitem__", &exposer_type::get_item ) > .add_property( "key", &exposer_type::get_key ) > .add_property( "value", &exposer_type::get_mapped ); > } > > AFTER THE PATCH: > > pair_exposer_t(const std::string& name){ > static bool expose = true; > if(expose) > { > class_< pair_type >( name.c_str() ) > .def( "__len__", &exposer_type::len ) > .def( "__getitem__", &exposer_type::get_item ) > .add_property( "key", &exposer_type::get_key ) > .add_property( "value", &exposer_type::get_mapped ); > } > expose = false; > } > > Probably there is a better way to implement this, but now it seems working > :) > Let me know what's your opinion about this issue. I just committed a fix to this issue. Take a look on it, as it use boost::python registry API to check whether the class is registered or not. Enjoy. P.S. Can you start new discussion for a new issue? It is very difficult to follow you. Thanks. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Berserker <ber...@ho...> - 2010-01-13 12:55:44
|
> > Probably there is a better way to implement this, but now it seems working > > :) > > Let me know what's your opinion about this issue. > > I just committed a fix to this issue. Take a look on it, as it use > boost::python registry API to check whether the class is registered or > not. > > > Enjoy. > > P.S. Can you start new discussion for a new issue? It is very > difficult to follow you. Thanks. Thanks for the fix, I think it's perfect now :) Sry about "flooding" this topic. _________________________________________________________________ 25 Gygabite gratis online. Archivia e condividi i tuoi file! http://www.windowslive.it/skyDrive.aspx |