Using Printer.Print in VB6 - vb6

I come from a Java and .NET background.
In VB6 it appears that you do not always have to create an instance of a class when using it. For example, when using the Printer class you can simply say Printer.print instead of having to create an instance first i.e. Dim printer As New Printer and then running printer.Print. I know that Printer is a system object in VB6, but why don't you have to create an instance?

Visual Basic traditionally had a large number of pre-defined identifiers that are directly recognized by the compiler. The Printer object is one of those. Under the hood, this is implemented with the [appobject] attribute but that's carefully hidden in the language. The runtime creates an instance of the COM coclass automatically, much like the As New syntax. The DAO DBEngine object would be an example of one that isn't predefined in the language parser.
This is over and done with in VB.NET, a truly object oriented language with a large class library, much like Java. There is no Printer object anymore, you're supposed to use the PrintDocument class. The Printer object is still supported for legacy code, available in the Microsoft.VisualBasic.PowerPacks.Printing.Compatibility.VB6 namespace. It however requires the New keyword to create an instance of it.
Be careful investing a lot of time and energy in VB6, it is in all respects a badly outdated language.

VB6 isn't an object oriented language in the same way as you would expect if you are used to newer languages. VB6 will do implicit instantiation and you can treat certain things as if it were static. For example, you can declare a variable of a form, but you don't have to. You can directly call a form and manipulate it without declaring it. In the case of the printer, it can't be explicitly declared and instantiated, but VB6 already has one available.

Related

create vbscript vbdataobject

I am using a program which makes it possible to customize dialogues via vbscript. Now, the form has an attribute which seems to be a vbDataObject (VarType returns 13).
How can I read the content and create a new vbDataObject to assign it to the attribute?
Don't know if this is exactly the answer, but it seems that vbDataObject's are indeed COM objects, but they just do not expose an IDispatch interface (so they're not true automation objects). As such, VBScript just isn't capable of accessing their content, since it needs an IDispatch interface for it. It just has an IUnknown interface which it doesn't know what to do with.
Passing them around should be possible, though, so if another true automation COM object can manipulate them for you (maybe there is such an object in the app designed to do this?), you could use that to make an object with the correct settings and pass that to the form.
Another option is to contact the authors of the app and ask them if they're willing to give this one object an IDispatch interface as well. Since they presumably went the length to put IDispatch interfaces on most of their objects, this omission might just be an oversight on their part.

How to use IProjectionBuffer in MEF without creating editor instance?

I am trying to create a Visual Studio extension which handles a multi-language content type. Much like some mvc-templates and Django or ASP.NET which a certain part of the code is in another language.
I know that I should use Projection and I already checked Django for Visual Studio extension but the solution there includes creating a Language Service and going to the trouble of creating all bits and pieces related to a code editor. Here I am trying to achieve the same goal just by using MEF.
I know that you can use IProjectionBuffer CreateProjectionBuffer() to create a projection but the question is how to replace the current TextBuffer with the created one and when is the best time to do it.
Also one may expect that if he specifies a base definition of type "projection" like this:
[Export]
[Name("Whatever")]
[BaseDefinition("code")]
[BaseDefinition("projection")]
internal static ContentTypeDefinition WhateverContentType = null;
the received TextBuffer in providers to be of type IProjectionBuffer (after all IProjectionBuffer is inherited from ITextBuffer). Which are not and it seems that a projection base definition has no effect what so ever.
So if I want to rephrase my question in a tldr version:
How and when do you apply an IProjectionBuffer to current view (using MEF and without creating an editor instance)?
So if I understand your question correctly, the answer is "you don't." A IWpfTextView is bound to a implementation of ITextBuffer (or a derived type, like IProjectionBuffer) at creation time, and can't be changed. Even if you could, many other extensions and language services would be most surprised by this and would probably crash.
To address your second question about content types: simply declaring you have a base content type of "projection" doesn't make you a projection buffer. All that really states is you might be creating projection buffers of that type, and when you do you want some extra ITagger support so taggers project through to the source buffers as you might expect them to.

Registering Window Class

I guess my question is relatively easy for those of you who spent time dealing with Win32 API.
So my question is:
After initializing a WNDCLASSEX instance we need to "register" it using the "RegisterClassEx" function, why? Why do we do that? What's the meaning of this registration and in what cases I need to register things?
The ATOM returned by RegisterClassEx uniquely identifies your "window class" which can then be referred to in other windows APIs. [MSDN]
Effectively it is a hash so as to reduce the amount of data processed each time a window is created or looked for. It does also mean that multiple windows with same features can be easily created and identified.
I was addressing the practical reasons above. Hans Passant's answer correctly explains this is the OO class concept provided for C. Further MSDN example.
The word Class in the function name is significant. When you write code in an object oriented language, like C++, Delphi, Java or C# etcetera, then you use the class keyword to create objects that have behavior. But the winapi was designed to be used from C, a language that doesn't have such functionality. The RegisterClassEx() function is an emulation of that, it lets you create a window that "derives" its behavior from a named class, behavior that you can override. With every window that you create using that class name behaving identically.
The WNDCLASSEX structure you pass gives a window its default behavior. The most significant members of this structure are:
lpszClassName. That's the equivalent of the C++ class name. You can later call CreateWindowEx() and pass that name to get a window that behaves a certain way. Windows itself calls RegisterClassEx() to register several of its built-in window classes that you then can readily re-use in your own code. "EDIT", "BUTTON" and "LISTBOX" are good examples of that.
lpfnWndProc. This is what gives a window class its specific default behavior. The address of its window procedure that implement message handlers for specific messages. You can further customize the default behavior, in other words "derive" your own class from the base class, by specifying another window procedure in the CreateWindowEx() call. Such a window procedure must always call DefWindowProc(), the equivalent of calling the base class method. Or in other words, a window has one virtual method.
hIcon, etcetera. These are the equivalent of properties of the base class, they set default values that affect the default message handlers. Helping you to keep your window procedure simple. It is for example rarely necessary to write a message handler for WM_ERASEBKGND, the hbrBackground member sets the default background for a window.
Windows requires you to call RegisterClassEx() even if you don't plan on re-using a window. Which is by far the most common usage of the function in your own code. You don't start to really take advantage of it until you write a library that implements controls, windows that other code can use. Like "EDIT".

Using Cocoa class names with Cappuccino

Is it possible to use Cocoa names for equivalent Cappuccino classes while developing for Cappuccino?
I'm thinking about trying to leverage JSCocoa, Cappuccino and Emscripten to develop either pure-Javascript or pure-Objective-C app, which would end up being compiled in the same way using native Cocoa or Cappuccino. But the first step in sharing the code would be to have Cappuccino use the same class names as Cocoa does, or vice versa.
You could probably create a subclass of every Cappuccino class and call it by its NS* name, then import that file of subclasses.
However, since you are going to have to have a compilation step no matter what (to transform pointers to variables and some type declarations to var statements if nothing else) you might as well take that chance to replace NS with CP in references to anything global.

vb6 : accessing registry values

I'm writing a simple vb6 button which tests the access of the registry values.
I have the following:
Private Function registry_read(key_path, key_name) as variant
Dim registry as object
set registry = CreateObject("WScript.shell")
registry_read = registry.regread(key_path & key_name)
End function
Private Sub Command1_Click()
MsgBox registry_read("HKEY_LOCAL_MACHINE\SOFTWARE\PROCESS\frmMain_Values\", "Version")
end Sub
I have Project Menu -> References
and select Microsoft WMI Scripting V1.1 Library selected
and Windows Script Host Object Model referenced
however my msgbox is still coming up blank. I did check the registry path and it is correct. any ideas?
thanks in advance.
You need to comment out the line 'on error resume next' while you are developing. If an error is occurring, you will not be able to see the details. It could be not found or access denied etc.
Also there are two ways to reference an object. Early binding ie Dim rs as new adobdb.recordset and late binding set rs = CreateObject("Adodb.recordset"). The first method (early binding) forces you to declare a reference and the second (late) does not. There are advantages and disadvantages to both (ie early binding is faster, gives intellisense, easier debugging, etc) http://word.mvps.org/faqs/interdev/earlyvslatebinding.htm
#bugtussle While your statements are correct, wqw's statements are also. Whether you use the New keyword or CreateObject actually hasn't anything to do with whether an object is early or late bound. What does matter is whether you declare the object variable with a registered type or not. I believe that you actually explain this correctly in your article.
I'd like to mention also that your article is well-written and has good information, but IMHO contains also a couple of minor inaccuracies. What you call "Dual Interface" binding in your article (and explain well) is generally referred to as "vTable" or "very early" binding. VB6 supports vTable binding where possible.
Now, as you have said, the sole requirement to be a COM class is that the class must implement iUnknown. A "dual interface" simply means a COM class that implements both iUnknown and iDispatch: a COM class that supports late binding must implement the latter. VB doesn't directly support COM objects that don't implement iDispatch (having some COM classes that don't support late binding and some that do would pretty clearly be problematical in VB); in other words VB only supports COM classes that implement a dual interface. (However, there are tricks using SendMessage's GETOLEINTERFACE message that bypass the requirement.)
Also, it isn't quite that iUnknown is bypassed altogether, it is that iUnknown.QueryInterface() is bypassed, instead going directly to the virtual table. iUnknown.AddRef() is still called, of course.
Regarding New vs. CreateObject: VB has an optimization strategy for classes defined within a project that are instantiated within that project using the New keyword. However, there are also important differences between the two if you are using a class outside of a project context; this page http://msdn.microsoft.com/en-us/library/Aa241758 does a good job of summarizing them.
I'm curious as well to know what error the OP got. :)

Resources