Can't implement a class in VB6 - vb6

I'm trying to implement an interface in VB6. I have defined the class Cast_Speed like this...
Public Function Run_Time() As Long
End Function
and the implementation like this...
Option Explicit
Implements Cast_Speed
Public Function Cast_Speed_Run_Time() As Long
Cast_Speed_Run_Time = 0
End Function
but attempting to compile it gives 'object module needs to implement 'Run_Time' for interface 'Cast_Speed'. Can anyone see what I am doing wrong? My subroutines seem to be quite all right, but all the functions I try have this problem.

It doesn't like the underscore character in the method name. Try using RunTime() instead.
I just tested it without the underscore and it works fine for me:
'// class Cast_Speed
Option Explicit
Public Function RunTime() As Long
End Function
'// class Class1
Option Explicit
Implements Cast_Speed
Public Function Cast_Speed_RunTime() As Long
Cast_Speed_RunTime = 0
End Function

While you can make interface implementations public, it isn't considered good practice, any more than it is considered good practice to allow an interface to be directly instantiated as you also can do. It is simply an example of the maxim that it is possible to write extremely bad code in VB6. :)
Best practice is as follows:
Interface instancing property is PublicNotCreatable.
Implemented Interface Methods are scoped Private.
Thus:
Dim x as iMyInterface
Set x = new MyiMyInterfaceImplementation
x.CalliMyInterfaceMethodA
x.CalliMyInterfaceMethodY
And so on. If someone attempts to directly instantiate the interface, that should cause an error, and if someone attempts to call an implemented method directly instead of polymorphically through the interface that should return an error too.

Unless I'm mistaken, Interface Implementations in VB6 needed to be private (even though the interface declares them as public).
Try changing:
Public Function Cast_Speed_Run_Time() As Long
To:
Private Function Cast_Speed_Run_Time() As Long
You can also read up on implementing interfaces in VB6 here (which seems to back me up).

For a good overview of this subject, see http://msdn.microsoft.com/en-us/library/aa260635(v=vs.60).aspx#ifacebased_vbifaces .

Related

Are there penalties for just using the new keyword instead of creating a class variable before calling the class method?

Example
(1)
var classVar = new class();
classVar.Method();
(2)
new class().Method();
I like the second way, less wordy.
Is there a performance difference?
Is it considered bad coding practice?
If your Method() doesn't use anything from that class, why is it defined there? You could use namespace instead.
The only difference between your (1) and (2) is that the class instance is destructed immediately in (2).
in your case Method seems to be static (ie there is no useful data stored inside the instance of 'class' (note I am ignoring all the invalid / not recommended name issues). Assuming this is c# but all languages have the same ideas, you would go
public class class{ // ugh
public void static Method(){
Console.WriteLine("I am Method");
}
}
now you can go
class.Method();
so the code is neatly filed away inside 'class' but you dont have to pay any overhead.
If you really need to instantiate 'class' then presumably you need to do more than just call one method on it. In which case
new class().Method();
makes no sense, since you call create it, call a method and destroy it.
Really a more concrete example is needed

Why must I use UserControl.MousePointer instead of Me.MousePointer?

In VB6 on a UserControl, I must use UserControl.MousePointer = vbDefault instead of Me.MousePointer = vbDefault. I can use Me.MousePointer on a Form (and Form.MousePointer doesn't work).
Why must I use UserControl.MousePointer instead of Me.MousePointer?
I mean literally the text "UserControl", not UserControl as the placeholder for another control name.
Me isn't what you seem to think it is. It is a reference to the current instance of the module you use it in, not "magic."
To get what you want you must add this property to the default interface of your UserControl, e.g.:
Option Explicit
Public Property Get MousePointer() As MousePointerConstants
MousePointer = UserControl.MousePointer
End Property
Public Sub Test()
MsgBox Me.MousePointer
End Sub
In VB6 Forms are a little different, probably as a holdover from 16-bit VB to make porting old code easier. These always seem to inherit from a hidden interface. This is defined in a type library you don't have access to since Microsoft did not release it as part of VB6. Attempting to query it typically comes up with an error like:
Cannot jump to 'MousePointer' because it is in the library 'Unknown10' which is not currently referenced
From this alone it seems likely that using Me always carries a small performance penalty. Instead of going directly to the module's procedures it appears to me that you are going through its default COM interface.
You'd have to inspect the compiled code to determine whether there is a performance penalty, and if so how much. I don't see this documented so otherwise we are just guessing about it.
In any case there is little reason to ever use Me unless you must in order to qualify something.
Crummy example but:
Option Explicit
Private mCharm As Long
Public Property Get Charm() As Long
Charm = mCharm
End Property
Public Property Let Charm(ByVal RHS As Long)
mCharm = RHS
'Maybe we do more here such as update the user interface or some
'other things.
End Property
Public Sub GetLucky(ByVal Charm As Long)
'Do some stuff.
Charm = Charm + Int(Rnd() * 50000)
'etc.
Me.Charm = Charm 'Here we use Me so we can assign to the property Charm.
End Sub
That's really about the only legitimate use for Me anyway: scoping to the desired namespace. Relying on it because in typing it brings up IntelliSense is just lazy.
If anything Forms are "broken" not UserControls.
Figured it out. It turns out that since a UserControl is an ActiveX control, VB6 does some magic for you. With a Form control, it's not an ActiveX control which is why the MousePointer property is accessible via Me, like you'd expect.
For UserControl's, the UserControl control you create in VB6 sits on another control - the ActiveX control. That ActiveX control is accessible via UserControl. Something like this:
class ActiveXControl
{
int MousePointer;
VBUserControl control;
}
class VBUserControl
{
}
class YourUserControl : VBUserControl
{
ActiveXControl UserControl;
// we must use UserControl.MousePointer
}
but for a Form, it's more like this:
class Form
{
int MousePointer;
}
class YourForm : Form
{
// we actually inherit from Form so we use Me.MousePointer
}

Mocking objects instantiated inside a class to be tested

So I am learning TDD using the many resources here on SO, but I just cant seem to figure out what I do with private/protected objects instantiated inside a given method/constructor. Lets say I have a connection string. That connection string is used to construct a Sqlcommand or Sqlhelper. Well I want to mock that Sqlhelper so that when I test other methods I don't have to rely on the results coming from my database. But I cant access the Sqlhelper.
How do I work around this?
Its generally best (except for a very few rare occasions) to test only the public interface of the class as a whole. Try not to use one of the workaround methods (such as private objects) unless you really have to. Accessing private members of classes in tests tends to look good at first as theres less code to write to test an object, however when things start to change (and they will) anything accessing the internals of a class makes it more difficult to change its implementation, this can be crippling to a project if most of the tests are written in this way.
In this particular case you are interacting with an external dependency outside of your control (i.e. SqlHelper), I'd recommend wrapping the SqlHelper object in your own object that implements an ISqlHelper interface (or a more reasonably named interface for your scenario).
e.g.
public interface ISqlHelperWrapper
{
void ExecuteQuery();
}
Then inject this in through the constructor of you're object under test:
public class SqlConsumer
{
private ISqlHelperWrapper _sqlHelper;
public SqlConsumer(ISqlHelperWrapper helper)
{
this._sqlHelper = helper;
}
public void QuerySomething()
{
this._sqlHelper.ExecuteQuery();
}
}
Not only is this a better design (you've isolated the sql implementation specific stuff from the SqlConsumer, and given it fewer reasons to change). But you can now mock the ISqlHelper instance using a mocking framework as well as switch the implementation on construction.
Given your connectionstring scenario above, you could initialise the sqlhelperwrapper (There are better names for this) with the connectionstring and your SqlConsumer object doesn't need to know about it.

Is there any way to make the DialogProc work without declaring as Nonstatic

I have developed any button application using createDialogParam and DialogProc. first i declared DialoProc method as static in order to make every thing work fine and it worked but now the situation is that there are so many variables(Not globally declared) and functions which i have to use inside DialogProc function and now i want to make it Non static because making it static makes me not implement few more things.
If i don't declare it static it gives error
m_hwndPreview = CreateDialogParam( g_hInst,MAKEINTRESOURCE(IDD_MAINDIALOG), m_hwndParent,(DLGPROC)DialogProc, (LPARAM)this); //('type cast' cannot convert from 'overloaded-function'
//to 'DLGPROC')
Is there any solution to make dialogProc function without declaring it static ???
It must be a static function because Windows calls it from C code, not C++ code. But there are several ways your static function can retrieve a 'this' pointer that you saved somewhere, then use that pointer to call a class member function. Every GUI library available for Windows solves this problem: Consider using one.

Should I minimize the number of interfaces in a controller?

In the below snip I have my controller which takes three interfaces. These are wired up via Ninject. Ok all great, definately a step in the right direction. My questions are this?
1.) Would it be better to wrap the 3 interfaces up in to one interface and a implement that way, thus reducing the amount of params passed to the ctor of the controller?
2.) Leave it alone, it is working?
I am always looking for ways to abstract the hell out of everything..
Thoughts?
public class RegistrationController : Controller
{
private readonly ICategoriesService _categoriesService;
private readonly IAuthenticationService _authenticationService;
private readonly IRegistrationService _registrationService;
// Ctor
public RegistrationController(ICategoriesService categoriesService,
IAuthenticationService authenticationService,
IRegistrationService registrationService)
{
_categoriesService = categoriesService;
_authenticationService = authenticationService;
_registrationService = registrationService;
}
}
Having a huge interface (or a huge class, which is what you'll need in order to implement a huge interface) because it is "convenient" is widely considered an antipattern. Based on the names of your current interfaces, they seem to be nicely and logically structured around what kind of operations they provide, and I suggest that you keep them that way (this also gives higher flexibility, since there may be other places where you only need some of the interfaces).
By the way: If you have proper unit tests and integration tests, "leave it alone, it's working" is a phrase that is never needed. ;-)

Resources