Home All Groups Group Topic Archive Search About

VB6 runtime is supported on Windows 7

Author
26 Feb 2009 10:29 PM
mark.tunnard.jackson
Has anyone noticed that the VB6 runtime is now supported on Windows 7?

The support statement page - http://msdn.microsoft.com/en-us/vbrun/ms788708.aspx
- now says

The core Visual Basic 6.0 runtime will be supported for the full
lifetime of Windows Vista, Windows Server 2008 and Windows 7,which is
five years of mainstream support followed by five years of extended
support.

I don't know when it was changed, because it didn't say that a couple
of weeks ago, but it does now. Yippee!

Author
26 Feb 2009 11:10 PM
Bill McCarthy
Hi Mark,

<mark.tunnard.jack***@googlemail.com> wrote in message
Show quoteHide quote
news:817c0ef6-242c-44e4-be26-496f8f44ea6f@j8g2000yql.googlegroups.com...
> Has anyone noticed that the VB6 runtime is now supported on Windows 7?
>
> The support statement page -
> http://msdn.microsoft.com/en-us/vbrun/ms788708.aspx
> - now says
>
> The core Visual Basic 6.0 runtime will be supported for the full
> lifetime of Windows Vista, Windows Server 2008 and Windows 7,which is
> five years of mainstream support followed by five years of extended
> support.
>
> I don't know when it was changed, because it didn't say that a couple
> of weeks ago, but it does now. Yippee!

Yeh I think it only got updated this week as I saw MSDN blog posts about it
starting yesterday.  The page seems to have an ominous warning on it though
:

<quote>
VB6 runtime will ship and will be supported in Windows 7 for the lifetime of
the OS.  Developers can think of the support story for Vista being the same
as it is for Windows 7.  However there are no plans to include VB6 runtime
in future versions of Windows beyond Windows 7.
</quote>
Author
27 Feb 2009 12:12 AM
C Kevin Provance
"Bill McCarthy" <Master c*ck sucker> wrote in message
news:u$8S$iGmJHA.504@TK2MSFTNGP06.phx.gbl...
| <quote>
| VB6 runtime will ship and will be supported in Windows 7 for the lifetime
of
| the OS.  Developers can think of the support story for Vista being the
same
| as it is for Windows 7.  However there are no plans to include VB6 runtime
| in future versions of Windows beyond Windows 7.
| </quote>

So what?  Most developers worth their salt include necessary runtime files.
Go pedal your negativity someplace else.
Author
27 Feb 2009 4:49 PM
Nobody
The implication probably being that once MS stops shipping the run time they
will also stop
supporting it on that OS.

Show quoteHide quote
"C Kevin Provance" <BillMRapedMySh***@.netblows.ms> wrote in message
> So what?  Most developers worth their salt include necessary runtime
> files.
> Go pedal your negativity someplace else.
>
>
Author
27 Feb 2009 3:30 AM
Ed
On Fri, 27 Feb 2009 10:10:51 +1100, "Bill McCarthy" <TPASoft.com Are
Identity Thieves> wrote:

><quote>
>VB6 runtime will ship and will be supported in Windows 7 for the lifetime of
>the OS.  Developers can think of the support story for Vista being the same
>as it is for Windows 7.  However there are no plans to include VB6 runtime
>in future versions of Windows beyond Windows 7.
></quote>

Great, I can keep making stand alone VB6 apps for a few more years!  :)

Ownerdrawn + API or Die!
Ed
Author
27 Feb 2009 9:15 AM
MM
On Fri, 27 Feb 2009 10:10:51 +1100, "Bill McCarthy" <TPASoft.com Are
Identity Thieves> wrote:

Show quoteHide quote
>Hi Mark,
>
><mark.tunnard.jack***@googlemail.com> wrote in message
>news:817c0ef6-242c-44e4-be26-496f8f44ea6f@j8g2000yql.googlegroups.com...
>> Has anyone noticed that the VB6 runtime is now supported on Windows 7?
>>
>> The support statement page -
>> http://msdn.microsoft.com/en-us/vbrun/ms788708.aspx
>> - now says
>>
>> The core Visual Basic 6.0 runtime will be supported for the full
>> lifetime of Windows Vista, Windows Server 2008 and Windows 7,which is
>> five years of mainstream support followed by five years of extended
>> support.
>>
>> I don't know when it was changed, because it didn't say that a couple
>> of weeks ago, but it does now. Yippee!
>
>Yeh I think it only got updated this week as I saw MSDN blog posts about it
>starting yesterday.  The page seems to have an ominous warning on it though
>:
>
><quote>
>VB6 runtime will ship and will be supported in Windows 7 for the lifetime of
>the OS.  Developers can think of the support story for Vista being the same
>as it is for Windows 7.  However there are no plans to include VB6 runtime
>in future versions of Windows beyond Windows 7.
></quote>

I think Microsoft is deparate to get some kudos from the general
public, who in recent years only got to hear the term "Microsoft" in
the context of major US or European anti-trust enquiries, all of which
seem to end up with Microsoft in the doghouse. Microsoft have had to
take on board that VB6 ain't going to die until there is something new
that is equal or better, which, of course, VB.Net is not. So I see VB6
support (in the sense of supported by the OS) being maintained for a
very long time indeed. Also, the revelation that reg-free com can work
very well from XP onwards means that there will be potentially many
more VB6 applications to bear fruit over the next few years. VB6 is
the best, the most productive, the all-round world-beating programming
system ever to have been invented and Microsoft, partially its
inventor, though initially reluctantly, has had to bite the bullet and
commit to it again in order to secure its own bottom line by not
pissing off the whole world continually in that arrogant manner of
five or so years ago.

By the way, who has been banging on the loudest over many years about
DLL Hell and that it could have been handled better by wrapping every
application up with all its functionality in one entity instead of
being spread around all over the place?

Moi.

Oh, and I've just checked the price of 1 terabyte internal hard drives
and they're down to around 130 bucks nowadays. That's an awful lot of
"duplicated functionality", which was always the bugbear people moaned
about as they continued to justify DLL Hell.

MM
Author
27 Feb 2009 2:16 PM
mayayana
> Microsoft have had to
> take on board that VB6 ain't going to die until there is something new
> that is equal or better, which, of course, VB.Net is not. So I see VB6
> support (in the sense of supported by the OS) being maintained for a
> very long time indeed.

   For better or worse, they're not really focused there.
The bigger compatibility problem going forward is likely to
be the "security" problem, with non-signed, non-MS code
of any kind being increasingly unwelcome. The idea is not
that you should switch from VB to VB.Net for Windows
software. The idea is that you should drop Windows
software, buy into the cloud fad, take up .Net, and eventually
use .Net with Azure, so that MS can have a tollbooth between
you and you customers, charging *you* for your customers'
uage of *your* software.

> Also, the revelation that reg-free com can work
> very well from XP onwards means that there will be potentially many
> more VB6 applications to bear fruit over the next few years.

   I don't know how useful this is to people, but I've been
discovering the option to load reg-free COM objects lately.
It not only doesn't require registration. It also doesn't require
any special Windows version, or whathever other limitations
Microsoft's reg-free COM might have.

  This functionality never mattered to me before because I
avoid shipping OCXs or custom ActiveX DLLs. But recently I
decided that I'd like to add a DLL to a project and it seems
silly to have to deal with the potential problems of COM
registration when my DLL is going to stay in the program folder,
used only by me.

  I've adapted Matthew Curland's code, which is very compact,
and it seems to work just fine to create objects given a file
path and CLSID, with no registration needed. There's also a
version of that that was published by vbAdvance, although their
website seems to be gone now. And if I'm not mistaken, Olaf
Schmidtt also also offers that functionality in his tools.
(Sorry if I misspelled your last name, Olaf. I can never
seem to remember that spelling. :)

   I'm surprised that this method doesn't get much attention.
Other than requiring a slightly funky bit of assembly code it's
very straightforward. It just calls the APIs that Windows
would call if one were going through COM to create an object.
Unfortunately, although this method is quite simple, I don't have
a version that I feel I can legally post here in public or that I
can offer a link to. I have two versions myself, but they're
based on code that's not mine.
Author
27 Feb 2009 5:54 PM
Schmidt
Show quote Hide quote
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:u4Qn$YOmJHA.1252@TK2MSFTNGP03.phx.gbl...

>    I don't know how useful this is to people, but I've been
> discovering the option to load reg-free COM objects lately.
> It not only doesn't require registration. It also doesn't require
> any special Windows version, or whathever other limitations
> Microsoft's reg-free COM might have.
>
>   This functionality never mattered to me before because I
> avoid shipping OCXs or custom ActiveX DLLs. But recently I
> decided that I'd like to add a DLL to a project and it seems
> silly to have to deal with the potential problems of COM
> registration when my DLL is going to stay in the program folder,
> used only by me.
>
>   I've adapted Matthew Curland's code, which is very compact,
> and it seems to work just fine to create objects given a file
> path and CLSID, with no registration needed.
Be careful with the Curland-Code - it involves calling
a function from its function-pointer in a way, which
is not working (means crashing) on systems with
enabled execution-prevention IIRC.

> There's also a version of that that was published by
> vbAdvance, although their website seems to be gone
> now.
> And if I'm not mistaken, Olaf Schmidtt also also offers
> that functionality in his tools.
The vbAdvance-Version was based on my first published
Code-Snippet here:
<
http://groups.google.de/group/microsoft.public.vb.com/browse_frm/thread/2ba3a5adb9b5e90c?q=vb+sss+cf.getinstance#4776e42bced56108

But this older version is also not covering the potential
Execution-Prevention-issues in the right way.
I posted a CallFunctionByPointer-approach ca. one year
later, which is using the MemAllocation in the correct way:
<
http://groups.google.de/group/microsoft.public.vb.winapi/browse_frm/thread/3e9859b326a3134d?q=vb+sss+asm#233d3b679215ba84
(please look at ThreadEntry Nr. 8, which is the post
where I got it "right" finally ;-)

Nonetheless I'd recommend to use the small (StdAPI)-Dll,
which I made for that purpose (DirectCOM.dll) - this Dll
is known to work without any Exec-Prevention-issues
on all systems from Win98 to Vista - and it is also safe to
use in threaded scenarios, where the "direct VB5/6-based"
approaches have shown some issues, and it also covers
Lib-Handle-Caching etc.

> (Sorry if I misspelled your last name, Olaf. I can never
> seem to remember that spelling. :)
It is Schmidt - but there are also a lot of 'Schmitts'
"out there" (at least here in germany) <g>

Olaf
Author
27 Feb 2009 8:10 PM
mayayana
http://groups.google.de/group/microsoft.public.vb.winapi/browse_frm/thread/3
e9859b326a3134d?q=vb+sss+asm#233d3b679215ba84
> (please look at ThreadEntry Nr. 8, which is the post
>  where I got it "right" finally ;-)
>
> Nonetheless I'd recommend to use the small (StdAPI)-Dll,
> which I made for that purpose (DirectCOM.dll) - this Dll
> is known to work without any Exec-Prevention-issues
> on all systems from Win98 to Vista - and it is also safe to
> use in threaded scenarios, where the "direct VB5/6-based"
> approaches have shown some issues, and it also covers
> Lib-Handle-Caching etc.

  Thank you. I'd prefer to have code rather than an extra
library, but your DLL is nicely compact and frankly I only
partly understand your code and Matthew Curland's code.
So I'm really not in a position to judge whether writing my
own code is a good idea. I assume that the problem you're
talking about is when DEP is set for all processes? I'm only
vaguely familiar with that. I would have thought it was a
rare setting.

  With you DLL sample: There's not much explanation. You
don't have any documentation? Is the function GETINSTANCE
all that's needed to load an object? GETINSTANCE(Path, ClassName) ?
And the DLL reads the embedded type library to translate the
class name to CLSID? How is the object then released? You seem
to have a function UNLOADCOMDLL but I don't see any place
in your sample code where that's used.


>
> > (Sorry if I misspelled your last name, Olaf. I can never
> > seem to remember that spelling. :)
> It is Schmidt - but there are also a lot of 'Schmitts'
> "out there" (at least here in germany) <g>
>
   Ah. I'll try to remember that. There's a quirky symptom
of aging I've noticed, whereby I seem to have the most
trouble remembering things I learned after my youth. For
instance, I'm more likely to remember someone's name if
I new a person by that name in childhood.  :)
Author
27 Feb 2009 10:43 PM
Schmidt
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:OFF3seRmJHA.6060@TK2MSFTNGP05.phx.gbl...

>   Thank you. I'd prefer to have code rather than an extra
> library, but your DLL is nicely compact ...
Yep, it's a PowerBasic-Compile - and so the calling
of Functions by Pointer was not requiring any Assembler-
"workarounds" as with the VB-Code, hence no DEP-
issues possible.

> and frankly I only partly understand your code and
> Matthew Curland's code.
> So I'm really not in a position to judge whether writing my
> own code is a good idea. I assume that the problem you're
> talking about is when DEP is set for all processes?
Yep.

> I'm only vaguely familiar with that. I would have thought it
> was a rare setting.
Yes, the default-setting is, that (at least XP) only
watches the "wellknown" Binaries.

>   With you DLL sample: There's not much explanation.
> You don't have any documentation?
Yep, thought the examples were sufficient...<g>

> Is the function GETINSTANCE all that's needed to load
> an object? GETINSTANCE(Path, ClassName) ?
Yes.
Simply look at it as a fully compatible working replacement
to CreateObject().
Instead of giving the (two-part) ProgID in one Parameter,
you will have to give a fully qualified path to your AX-Dll
in the first one - and the ClassName (the "right-part" of
the ProgID) in the second Param.

One thing should be mentioned though:
The only cases where the approach does not work
regfree is, when you want to instantiate a Public-Class
of your Dll, and this *Class* does contain the definition
of a Public Type - but Public Enums on the other hand
work fine.

> And the DLL reads the embedded type library to translate the
> class name to CLSID?
Yes.

> How is the object then released?
GetInstance returns with: 'As Object'
The instantiated and delivered Object-instance is released
in the usual way, when its last reference goes out of scope
(in the same way as with CreateObject-generated instances).
Or do you mean the Dll itself?

> You seem to have a function UNLOADCOMDLL but I
> don't see any place in your sample code where that's used.
The loaded Library-Handle(s) of the AX-Dll(s) are cached
internally (and then reused) for the next instantiation-request.
After your Process (or the VB-IDE) terminates, all Lib-
Handles are freed automatically.

The UNLOADCOMDLL is there, if you want to unload
an already loaded COM-Dll and free its Lib-handle
*whilst* your process is yet running - e.g. to perform
an (online-) update or something in this regard (Dll-
replacement) without the need, to shut-down your
App completely.

In my projects I never used it so far - but it is there
and it works (but make sure, you have set all Obj-
instances which you got from this Dll to Nothing,
before you call it - there's a DllCanUnloadNow-
check included before the Unloading itself is allowed).

Olaf
Author
27 Feb 2009 11:14 PM
mayayana
>
> One thing should be mentioned though:
> The only cases where the approach does not work
> regfree is, when you want to instantiate a Public-Class
> of your Dll, and this *Class* does contain the definition
> of a Public Type - but Public Enums on the other hand
> work fine.
>
   Ugh. That's exactly what I want. I have a public
type that I want to pass a copy of to the caller,
which is compiled with a reference to the DLL. Is
there any way around that limitation?

> The UNLOADCOMDLL is there, if you want to unload
> an already loaded COM-Dll and free its Lib-handle
> *whilst* your process is yet running - e.g. to perform
> an (online-) update or something in this regard (Dll-
> replacement) without the need, to shut-down your
> App completely.
>
> In my projects I never used it so far - but it is there
> and it works (but make sure, you have set all Obj-
> instances which you got from this Dll to Nothing,
> before you call it - there's a DllCanUnloadNow-
> check included before the Unloading itself is allowed).
>

   Thanks for the explanation. I'm in a situation where I
need to keep the object loaded only for a brief time, so
I have an event in the object that tells me I'm done with
it. But it sounds like that's no problem. If I understand you
correctly I can just do:

Set Obj = nothing
UNLOADCOMDLL

No paramaters needed for that call? There's assumed to
be only 1 DLL loaded?
Author
28 Feb 2009 12:49 AM
Schmidt
Show quote Hide quote
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:%23ry0dFTmJHA.1252@TK2MSFTNGP03.phx.gbl...
>
> >
> > One thing should be mentioned though:
> > The only cases where the approach does not work
> > regfree is, when you want to instantiate a Public-Class
> > of your Dll, and this *Class* does contain the definition
> > of a Public Type - but Public Enums on the other hand
> > work fine.
> >
>    Ugh. That's exactly what I want. I have a public
> type that I want to pass a copy of to the caller,
> which is compiled with a reference to the DLL. Is
> there any way around that limitation?
Just to make sure... The Types that I mean are not
Class-Types, but UDTs - and only the ones you can
define also publically at the class-level (not the
Class-Private ones), meaning: those who start with:
Public Type MyType
    ...
End Type


So if we talk about UDTs, then you could try to declare
the Type either in a *.bas (which could be shared by
both projects, so that the Type, if changed, is always
"reflected" on both ends) or as a Private Type in a
Class (at both ends separately).

You could then pass a long-pointer of your UDT-
"Instance" to the Dll - and make the copy from
the passed Pointer then - not very nice - but it
would work this way (eventually using a SafeArray,
to be able to make a "deep-copy" of your type in a
more easy way, as long as your type contains members,
which are "Pointer-Types" as for example dynamic
Arrays or non-fixedlength-VB-Strings).

Another way would be, to not pass a Type,
but an Object-Reference of a small Class instead
(which contains your UDT-Variable internally
as a copy, handed over using a Friend-Function).

But a small Snippet of what you really want to achieve
would help, to give a better suggestion.

[UNLOADCOMDLL]
>    Thanks for the explanation. I'm in a situation where I
> need to keep the object loaded only for a brief time, so
> I have an event in the object that tells me I'm done with
> it. But it sounds like that's no problem. If I understand you
> correctly I can just do:
>
> Set Obj = nothing
> UNLOADCOMDLL
>
>  No paramaters needed for that call? There's assumed to
> be only 1 DLL loaded?
No.
The Declare needs exactly the same two parameters as the
GETINSTANCE-call - meaning the:
(DllName As String, ClassName As String)
To be able to lookup after the cached Lib-Handle in
the DirectCOM-internal Caching-Dictionary.

The ReturnValue of UNLOADCOMDLL is a Long,
which signalizes success with a '1'.

But as said, normally it is not needed, to unload the
Dll yourself whilst your process is running - why do
you want to do it - is your Dll that large?

If you "have to" nonetheless, then I would take at least
care, to decouple your "I'm_terminating"-Event over
a Timer, if this Event is raised by the "Dll-Object" itself.
Just to make sure the instance is really "finished"
and terminated, before proceeding with the
UnloadCall of the Dll itself.

Let me know, if I should write a small Demo, which
covers all that (maybe also your Type-Passing).
Maybe others can profite too from it.


Olaf
Author
28 Feb 2009 1:39 AM
mayayana
Show quote Hide quote
> So if we talk about UDTs, then you could try to declare
> the Type either in a *.bas (which could be shared by
> both projects, so that the Type, if changed, is always
> "reflected" on both ends) or as a Private Type in a
> Class (at both ends separately).
>
> You could then pass a long-pointer of your UDT-
> "Instance" to the Dll - and make the copy from
> the passed Pointer then - not very nice - but it
> would work this way (eventually using a SafeArray,
> to be able to make a "deep-copy" of your type in a
> more easy way, as long as your type contains members,
> which are "Pointer-Types" as for example dynamic
> Arrays or non-fixedlength-VB-Strings).
>
> Another way would be, to not pass a Type,
> but an Object-Reference of a small Class instead
> (which contains your UDT-Variable internally
>  as a copy, handed over using a Friend-Function).
>
> But a small Snippet of what you really want to achieve
> would help, to give a better suggestion.
>

    That seems doable. Thanks. I'll experiment.
   This is coming out of a discussion from last week.
I have a large project that was getting unwieldy.
I decided it would be a good idea to split up some
of the pieces. The settings window was fairly extensive
(with 6 or 7 frames) plus a good deal of code, and
could be easily split off, so I did that. It's now in a
DLL and the settings are organized into a UDT rather
than being saved to the Registry. They just get saved
to disk by writing the UDT to disk.

  So the main program opens the settings file at startup,
and if someone wants to adjust settings the main program
loads the DLL. The DLL then reads the disk file into its
own instance of the UDT, and any settings changes are
saved to that UDT. When the window is closed, the
DLL writes UDT changes to disk and the main program gets
the "done" event, at which point it gets a copy of the
new UDT and unloads the DLL.
  So for most of the time the DLL doesn't run. So far
so good. It doesn't work in the IDE but works fine
with compiled versions (using Matthew Curland's code).

> But as said, normally it is not needed, to unload the
> Dll yourself whilst your process is running - why do
> you want to do it - is your Dll that large?
>

  Partly it seems sloppy to leave something unnecessary
running. A second concern is that I wonder about the
number of windows in use -- with each form, button, etc.
having a window. I've found that working on large projects
can strain the system, especially on Win98 where I usually
work. That led me to wonder whether the load of all
running VB programs might have its own limit of some kind.
Maybe a weakness of the runtime or some such? I don't
know, but VB programs do tend to have more windows, in
general, than other software. I figure it's just be good
practice to keep it all as lean as possible.

> Let me know, if I should write a small Demo, which
> covers all that (maybe also your Type-Passing).
> Maybe others can profite too from it.
>
   I'll try it out. It seems like it shouldn't be a problem.
Though I don't see why I can pass a UDT through a
secondary non-creatable class if I can't pass it through
the main class. And I don't see why I can't pass a UDT
using your DLL when I can do it using Matthew Curland's
code. How are the created objects any different? In
my tests I have no problem using the DLL unregistered
as long as I've set a reference to it when it was
registered. The main program therefore knows about
the UDT.
  In any case, I guess it's not really a problem. At worst
I could always just have the main program re-open the
settings file after the DLL closes it.
Author
28 Feb 2009 3:17 AM
Schmidt
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:ePzXnWUmJHA.4520@TK2MSFTNGP03.phx.gbl...

>    This is coming out of a discussion from last week.
Yeah, I remember - although only read it "diagonally".

Show quoteHide quote
> I have a large project that was getting unwieldy.
> I decided it would be a good idea to split up some
> of the pieces. The settings window was fairly extensive
> (with 6 or 7 frames) plus a good deal of code, and
> could be easily split off, so I did that. It's now in a
> DLL and the settings are organized into a UDT rather
> than being saved to the Registry. They just get saved
> to disk by writing the UDT to disk.
Ok.

>   So the main program opens the settings file at startup,
> and if someone wants to adjust settings the main program
> loads the DLL. The DLL then reads the disk file into its
> own instance of the UDT, and any settings changes are
> saved to that UDT. When the window is closed, the
> DLL writes UDT changes to disk and the main program
> gets the "done" event, at which point it gets a copy of the
> new UDT ...
Just a suggestion - you would not need to pass the UDT
in this case to the main-program.
If the Dll just wrote its settings to the File, and if
we talk about a smaller max. 100kB-Filesize here, then
you could read-in the updated "UDT" into the main-
program directly from the file again - which at this
moment is definitely yet in the System-FileCache -
not much difference in performance to a direct mem-read.


> ...and unloads the DLL.
Just to make sure - a loaded AX-Dll (which has not yet
delivered any Obj-Instances) consumes normally only
memory, mostly only in the size of its Disk-
representation, no window-handles, no GDI-handles
so far.

These parts are only loaded together with your upstarting
Class-Instance (or in your appropriate Init- or
ShowForm-Call against your "living Object").
If you cleanup your Object (Set to Nothing) - and
properly destroy everything internally (assuming no cycle-
refs are there), then your system gets back all the handles
and the (Class-Instance-related) memory, which is
usually a bit more than the amount of memory, your
(LoadLibrary-)loaded Dll consumes (at least if GUI-
parts are involved).

> > But as said, normally it is not needed, to unload the
> > Dll yourself whilst your process is running - why do
> > you want to do it - is your Dll that large?
> >

>   Partly it seems sloppy to leave something unnecessary
> running.
If your Dll is only ca. 500kByte, then your process is
using only ca. these 500kByte additionally (often less -
sometimes a bit more).

> A second concern is that I wonder about the
> number of windows in use -- with each form, button, etc.
> having a window.
As said, don't confuse loaded Obj-Instances with the
Dll itself - the Dll contains only the "Class-Templates"
and the Method-Definitions which a living Class-Instance
later on "jumps to". The handles and resources are
wasted in "living Code", not in the Templates.

> I've found that working on large projects
> can strain the system, especially on Win98 where I usually
> work.
Yep, the limits for e.g. WinHandles on XP are 1000
(or was it 2000?) and the limit of GDI-Handles per
process is 10000. As said, per Process.
On Win98 the limits for the whole system are already
in that range as on XP per process, IIRC.

> That led me to wonder whether the load of all
> running VB programs might have its own limit of some kind.
> Maybe a weakness of the runtime or some such?
No, this is not caused by the vbRuntime - it is just, that
many VB-Programs or -Components are often not
programmed very resource-friendly. Too many Controls
on too many (only hidden) SubFrames or Containers.

> I don't know, but VB programs do tend to have more
> windows, in general, than other software. I figure it's
> just be good practice to keep it all as lean as possible.
As said - simply set your Object to Nothing and you
are done - no need to also unload the Dll, where this
Object came from.

> Though I don't see why I can pass a UDT through a
> secondary non-creatable class if I can't pass it through
> the main class.
It is simply that you do have to hide UDTs internally.
As soon as these are "popping up" on the publically
visible COM-Interfaces, these interfaces have to be
registered then. If you try to load an unregistered
COM-Class over DirectCOM.dll, OLE performs an
additional check for the method-signatures (the
Parameters) in the call to DllGetClassFactory.

That check is done, to prepare for eventual OLE-
marshalling of the Method-Parameters. If such a
Parameter contains a "nonstandard-Type" as for
example an UDT, then the OLE-Marshaler want's
to know its size and structure beforehand - and
therefore in this case an additional registry-lookup
is performed, which DirectCOM.dll cannot avoid
anymore (and IMO also the Curland-approach cannot -
I assume the SxS-based regfree COM can, but not
sure).

> And I don't see why I can't pass a UDT using your
> DLL when I can do it using Matthew Curland's code.
I'd say you can't - but will take another look at his
code tomorrow.

> How are the created objects any different?
The approaches are very similar and perform the
very same "actions" before finally calling the
AX-Dlls exportet Function: DllGetClassObject.
Inside this function the error occurs, if the Class
in question contains Publically defined classlevel-
UDTs.

> In my tests I have no problem using the DLL
> unregistered as long as I've set a reference to it
> when it was registered.
> The main program therefore knows about the UDT.
Are you very, very sure, that you have unregistered
the Dll before testing the regfree loading?
And was this test performed on Win98?
Long time no testing on this OS - maybe the older versions
of the Ole-Dlls on Win98 have no issues yet with these
Public TypeDefs due to limited OleMarshaling-capabilities
(I remember these separate installations of DCOM-binaries
which were required for OLE-Marshaling to work).

>   In any case, I guess it's not really a problem. At worst
> I could always just have the main program re-open the
> settings file after the DLL closes it.
Ah - just what I thought above.

Olaf
Author
28 Feb 2009 5:19 AM
mayayana
> As said - simply set your Object to Nothing and you
> are done - no need to also unload the Dll, where this
> Object came from.

  I see. I had misunderstood, thinking that since
I was creating the object directly then setting the
object to Nothing would somehow not release it
on the DLL side.

> As soon as these are "popping up" on the publically
> visible COM-Interfaces, these interfaces have to be
> registered then.
.........
>
> > In my tests I have no problem using the DLL
> > unregistered as long as I've set a reference to it
> > when it was registered.
> > The main program therefore knows about the UDT.
> Are you very, very sure, that you have unregistered
> the Dll before testing the regfree loading?

   I see that you're right about that. I thought I had
this working with an early binding reference, but I find
that if I remove the DLL's HKCR\Typelib key then the program
never starts. It quits after checking for that key. I
even tried extracting the typelib and referencing that,
but VB won't take it. Apparently there's no way to tell
the main EXE that it's already got a copy of the typelib.

   I guess the file-read method is fine. The speed is
not an issue, since I'm only doing it once. I was only
avoiding that method because it seemed a bit risky to
have the main EXE trying to open the file only ms after
it's been closed by the DLL. But that's really not a risk?

   Thank you for all of your help on this. Now if I can
fix the subclass code.... Matthew Curland's code uses
a UDT of 6 longs, in which some are asm bytes. Is the
deal that I need to explicitly provide memory for that
via VirtualAlloc/VirtualLock before I use the variable, and
then call VirtualUnlock on it when I'm done? So the variable
itself is meant to be non-executable data, which DEP is
watching, and I'm just setting aside that block of memory
and reassigning it as executable space until the asm has
been run? Are there any risks/caveats in terms of the system
not giving permission for that because it's a "fishy" request
to set aside executable space in the middle of my data block?
Or do I just have a natural right to run code in allocated space
just as I have a natural right to run my own functions?

.... Or am I entirely misunderstanding how these things
work? :)
Author
28 Feb 2009 1:41 PM
Schmidt
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:utLbZRWmJHA.2460@TK2MSFTNGP06.phx.gbl...
> > As said - simply set your Object to Nothing and you
> > are done - no need to also unload the Dll, where this
> > Object came from.
>
>   I see. I had misunderstood, thinking that since
> I was creating the object directly then setting the
> object to Nothing would somehow not release it
> on the DLL side.
To be entirely sure, if your COM-Object is properly
released, simply place a msgbox or a Log-Entry in the
Class_Terminate-event.
In some regards you are right - what remains further
available is the class-template, which is needed, to
instantiate new "copies" of your Object as soon as
you need it again.

[Public UDTs in the TypeLib]
>    I see that you're right about that. I thought I had
> this working with an early binding reference, but I find
> that if I remove the DLL's HKCR\Typelib key then the program
> never starts. It quits after checking for that key. I
> even tried extracting the typelib and referencing that,
> but VB won't take it. Apparently there's no way to tell
> the main EXE that it's already got a copy of the typelib.
Yep, that seems weird - but it becomes understandable,
if you remember, that COM-Instances could be created
anywhere - and used not only InProcess.
If you create an instance from your Dll for example
inside the COM+-services - and try to access it cross-
process from your MainApp- then the calling-mechanism
cannot use the VTable-Trampoline anymore, to jump
(and pass Parameters) directly to the Class-Methods.
That is, where I often "throw in" the term OLE-
Marshaling, which is mainly only some "indirect
calling-mechanism" which requires "parameter-serializing"
to work properly. Now "you" come along with your
selfdefined UDT - and OLE is a bit "helpless", since
it is only aware of all the wellknown (Variant- and Object-)
Types - hence the additional TypeLib-Lookup, to be
able to serialize your class-defined UDT as well.
Public Enums are not affected, because the serializer
knows, how to treat them (as a 32Bit Int).

>    I guess the file-read method is fine. The speed is
> not an issue, since I'm only doing it once. I was only
> avoiding that method because it seemed a bit risky to
> have the main EXE trying to open the file only ms after
> it's been closed by the DLL. But that's really not a risk?
No, you have put something in somewhere (and that
not even from multiple threads - or using overlapped
FileIO) - so why should you not read it out in exactly
the same way. Remember, that there's also something
like memory-mapped-files, where you work in a nearly
similar way against a "cached Stream" - and that with
very high In-Out-frequencies - so that mechanism is
reliable.

>    Thank you for all of your help on this. Now if I can
> fix the subclass code.... Matthew Curland's code uses
> a UDT of 6 longs, in which some are asm bytes. Is the
> deal that I need to explicitly provide memory for that
> via VirtualAlloc/VirtualLock before I use the variable,
> and then call VirtualUnlock on it when I'm done?
Better to use this Variable only as an easy "Fill-In-
Container" - but as soon as you want to use the real
call, you should CopyMemory the 6 Longs from that
Variable to your selfallocated Memory-Chunk and
pass a pointer to that into the real call (which brings
the ASM-Code "to live") instead.

> So the variable itself is meant to be non-executable data,
> which DEP is watching,
Yes, such "data-memory-areas" should never contain
executable Code - that's the intention. For "hackers and
attackers" the "legal" VirtualAlloc-Call is not that interesting,
because they have an interest to "break in -> and then out"
from *your* process-memory - and the buffer-overflow-
attacks are the usual way to achieve this goal - but most
buffers which are "visible to the outside" + attackable this
way - are data-buffers - so the DEP makes sense there.

> and I'm just setting aside that block of memory
> and reassigning it as executable space until the
> asm has been run?
Don't know what you mean with that.
I would not try to "mess around" with that "already
VB-allocated MemoryChunk".
If you want to use your Type-Structure further,
you could also define a dynamic Array of that
UDT, which gets never "redimed", to prevent
VB from allocating memory for it.
Instead you could bind that empty Array to
a SafeArray-Structure, which then gets your
properly allocated (and flagged) memory-chunk
(over the pData-Member).
Then you could use instead of:
UDT.SomeMember
something like:
UDTArr(0).SomeMember
to interact with it using "normal VB-statements",
working against your selfallocated block of memory.

Olaf
Author
28 Feb 2009 3:07 PM
mayayana
> > and I'm just setting aside that block of memory
> > and reassigning it as executable space until the
> > asm has been run?
> Don't know what you mean with that.
> I would not try to "mess around" with that "already
> VB-allocated MemoryChunk".

   OK, I get it. I've never used VirtualAlloc before.
My first impression was that I was using it to somehow
redefine the pre-allocated memory space of a variable,
like granting file permissions. Looking at your code again
I see that I misunderstood how the whole thing works.
The return is a pointer to new space. That explains your
direction to copy the variable content to the newly
allocated space.

   Thanks.
Author
2 Mar 2009 12:08 AM
mayayana
I've got your code working to wrap Matthew Curland's
subclass and it seems to be working fine.
   I haven't checked it yet against extreme DEP
settings, but I'm assuming that's OK. I can't imagine
how you worked all of this out, but it worked fine to
wrap a SetWindowLong call to pass along the WindowProc
address in a subclass. (This is Curland's code that allows
UserControls to subclass themselves.)

   I just have a couple of questions. I'm subclassing
dozens controls -- all custom controls mounted on
UCs. It all happens at startup, naturally.

1) Can I safely
store the handle from LoadLibrary and just call it once
in the first place, then free it after startup? And what if
a given program is already using a specific library?

2) Can I safely store the ProcAddress within a specific
load? In other words, if I only load the library once then
I assume there's no need to keep getting the function
address. But if I load it separate times then the lib. could
conceivably be loaded into different addresses each time?

  I'm just wondering the best way to work this when I'm
making perhaps 20-50 calls in a short time.
Author
2 Mar 2009 4:35 AM
Schmidt
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:uZ2RItsmJHA.1248@TK2MSFTNGP03.phx.gbl...

>   I've got your code working to wrap Matthew Curland's
> subclass and it seems to be working fine.
Are you yet on the regfree-topic?

>    I haven't checked it yet against extreme DEP
> settings, but I'm assuming that's OK. I can't imagine
> how you worked all of this out, but it worked fine to
> wrap a SetWindowLong call to pass along the WindowProc
> address in a subclass. (This is Curland's code that allows
> UserControls to subclass themselves.)
If we talk about SubClassing (without thunking), then
you normally don't need these special VirtualAlloc-
MemAllocation, because passing only a pointer to
a function (around) is not the same thing as executing code
on an allocated memory-chunk that contains ASM-
snippets/instructions.
CallWindowProc, when used with a "normally derived"
WindowProc-Pointer does not need the VirtualAlloc-
Functions.
On the other hand CallWindowProc is one of the few
ways, to achieve executing of *any* function (by pointer)
with classic VB - but then  usually combined with the
"wellknown Block" of a few ASM-Instructions.
So don't confuse these two "use-cases" of CallWindowProc.
The VirtualAlloc-approach (with Page_Execute_Read_Write)
is only needed for the placement of "runtime-generated-
ASM-instructions" - it has nothing (directly) to do with
CallWindowProc.

And if you want to use "proven" SubClassing-Code with
thunking, then I'd recommend, to take a look at PSC,
the latest Updates for this approach already cover the
DEP-issues appropriately IIRC.

No need, to reinvent the wheel again regarding SubClassing.

Regarding your other questions - (if these have to do with
the regfree-loading) - as already said, there's already a "safe-
solution" with DirectCOM.dll, successively "hardened"
over time - and stable in a whole lot of imaginable scenarios
(including threading) since 2007.
Especially the unloading of LibHandles (if stemming from
loaded AX-Dlls) needs "special attention", because
e.g. before the unloading of such a LibHandle you need
to call DllCanUnloadNow, to make sure there's no Instance
"yet alive" which was derived from it. If your App is terminating,
you should do this check as late as possible - but the teardown-
process of VB is sometimes "special", not to mention potential
cycle-refs (which normally shouldn't "be there"), but if you
have such a case "accidentally", and for example perform a
loop around DllCanUnloadNow (in case it gives false), then
you could loop forever.

I also recently tried, to include the regfree-loading directly
into the new version of dhRichClient3.dll, to get rid of
DirectCOM.dll, but especially when combined with threading,
the approach was not reliable (when starting new thread-objects
regfree within the VB-IDE). With DirectCOM.dll everything
was stable again, so it is included again in my toolset as
it was before.

I also prefer solutions, which come "just as a single Exe",
(if possible) and also try, to keep the Dll-Count as low as
possible if I have "the chance" (therefore my attempt, to get
rid of DirectCOM.dll, to achieve a "two-Dlls-only Toolset"),
....but not "at all costs". ;-)

Olaf
Author
2 Mar 2009 3:39 PM
mayayana
Show quote Hide quote
>
> >   I've got your code working to wrap Matthew Curland's
> > subclass and it seems to be working fine.

> Are you yet on the regfree-topic?
......
> If we talk about SubClassing (without thunking), then
> you normally don't need these special VirtualAlloc-
> MemAllocation, because passing only a pointer to
> a function (around) is not the same thing as executing code
> on an allocated memory-chunk that contains ASM-
> snippets/instructions.
> CallWindowProc, when used with a "normally derived"
> WindowProc-Pointer does not need the VirtualAlloc-
> Functions.
> On the other hand CallWindowProc is one of the few
> ways, to achieve executing of *any* function (by pointer)
> with classic VB - but then  usually combined with the
> "wellknown Block" of a few ASM-Instructions.
> So don't confuse these two "use-cases" of CallWindowProc.
> The VirtualAlloc-approach (with Page_Execute_Read_Write)
> is only needed for the placement of "runtime-generated-
> ASM-instructions" - it has nothing (directly) to do with
> CallWindowProc.
>

  Sorry, I should have been more clear. I was assuming
that you knew what I was referring to. Matthew Curland
provided code in his book. (If you have the code it's a
combination of subclass.bas and PushParamThunk.bas.)
He uses asm to enable the ability for a UserControl to
call a subclass function and end up getting the WindowProc
redirected back to an internal WindowProc. I've been using
it for a long time. Before that code I avoided subclassing.
Now I find it very easy to have dozens of custom controls
because they're all using this "self-subclassing" technique.

   From your earlier posts I gathered that this method would
be a problem with the extreme DEP setting, and as I understood
you code and explanation, the trick is to allocate memory
outside of VB, not classified as a data block, in which to copy
the function pointer and parameters, then use the
CallWindowProc trick to execute that.

   I don't know whether you have Curland's code, and I can't
post it all here, but the gist of it is that I'm running the
following call in his subclass sub...

..wndprocNext = SetWindowLong(hwnd, GWL_WNDPROC, .wndprocThunk.pfn)

.... in accord with your online sample that you linked to,
using VitualAlloc, etc. .wndprocThunk.pfn, in this case,
is a pointer to the memory space of 6 longs, where the
asm code is.

..... As I'm writing this I just thought of a wrinkle -- something
that didn't occur to me last night:
  I'm copying the above parameters into allocated space,
but I haven't copied the 6 longs. I guess I'll actually need
to also do that if I want to avoid execution from VB data
space, and then point .wndprocThunk.pfn at that.  .....

   That point aside, the new code is working well. It's just
that I might be loading
5-50 custom controls at startup. depending on the program.
(In general I subclass my own owner-drawn RTB, my own
custom buttons, and, in many cases, listboxes. So for a multi-
window program that can easily reach 50 subclasses.)
So I was thinking that the repeated lib. loads are probably
not so great. But I don't have much knowledge about
optimizing that sort of thing, since VB typically handles it.
What I'm doing currently is to use a module-level variable
for both the lib. handle and the proc address, like so:

  If HLib = 0 Then HLib = LoadLibrary("user32")
     If HLib = 0 Then Exit Sub


  If HProc = 0 Then HProc = GetProcAddress(HLib, "SetWindowLongA")
     If HProc = 0 Then
        FreeLibrary HLib
        Exit Sub
    End If

  Then I've got a public sub FreeLib that's called after
all subclasses are done, which calls FreeLibrary. That
covers startup. If there are forms loaded/unloaded during
program running then they'll need their own FreeLib call,
presumably. That *seems* to me like a good design, but
I wasn't sure. Would it make more sense to just call
FreeLib at program close, since I'll usually have user32
loaded by VB anyway?

   Sorry to go on for so long with this. I use this subclass
code for pretty much everything, so I wanted to make sure
I get it right.

> And if you want to use "proven" SubClassing-Code with
> thunking, then I'd recommend, to take a look at PSC,
> the latest Updates for this approach already cover the
> DEP-issues appropriately IIRC.
>
> No need, to reinvent the wheel again regarding SubClassing.
>
  PSC? I don't know what you mean.


> I also prefer solutions, which come "just as a single Exe",
> (if possible) and also try, to keep the Dll-Count as low as
> possible if I have "the chance" (therefore my attempt, to get
> rid of DirectCOM.dll, to achieve a "two-Dlls-only Toolset"),
> ...but not "at all costs". ;-)
>
   I actually hadn't got to that point yet. I was
figuring I'd probably use your DLL, but I also
have adapted Matthew Curland's code for that,
so it might not be a big deal to do the DEP-safe
call with that. I'm assuming that he's forseen
any potential issues in the code that he wrote.
(On the other hand, I *am* hesitant to edit code
that I really don't understand very well. :)
Author
2 Mar 2009 6:29 PM
Schmidt
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:uplBK10mJHA.1252@TK2MSFTNGP03.phx.gbl...


>    From your earlier posts I gathered that this method would
> be a problem with the extreme DEP setting, and as I understood
> you code and explanation, the trick is to allocate memory
> outside of VB, not classified as a data block, in which to copy
> the function pointer and parameters, then use the
> CallWindowProc trick to execute that.
Yep, exactly.
From what you write, I see now, that you are using
something like "thunked-subclassing", which indeed
involves (smaller) ASM-instructions.
Just make sure, that the pointer you pass finally to
the CallWindowProc-Function (if used in "tricky-
mode") is a pointer, derived from VirtualAlloc.

Then you should be fine regarding the (deep) DEP-issues.


> What I'm doing currently is to use a module-level variable
> for both the lib. handle and the proc address, like so:
>
>   If HLib = 0 Then HLib = LoadLibrary("user32")
> ...
Yep, you will only need to do this once (for all future
usage over the Apps Lifetime).
And also the DllCanUnloadNow-comments I made
earlier don't apply here, since you do not load
an AX-Dll, so a simple FreeLibrary should be enough
at the latest possible time, when your project shuts
down. But even when you don't FreeLib the handle,
it will be closed anyway (by the OS itself), when your
Process is terminated.
But it is nonetheless good, if you cleanup the handle
yourself, especially when you run within the IDE
(where no real process-shutdown is done).

>   Then I've got a public sub FreeLib that's called after
> all subclasses are done, which calls FreeLibrary. That
> covers startup. If there are forms loaded/unloaded during
> program running then they'll need their own FreeLib call,
> presumably. That *seems* to me like a good design, but
> I wasn't sure. Would it make more sense to just call
> FreeLib at program close, since I'll usually have user32
> loaded by VB anyway?
As said above, no "intermediate" FreeLib is needed -
just make sure, that the handle is publically visible
over the process-lifetime.

> > And if you want to use "proven" SubClassing-Code with
> > thunking, then I'd recommend, to take a look at PSC,
> > the latest Updates for this approach already cover the
> > DEP-issues appropriately IIRC.
> >
> > No need, to reinvent the wheel again regarding SubClassing.
> >
>   PSC? I don't know what you mean.
Sorry, meant Planet-Source-Code.

>    I actually hadn't got to that point yet. I was
> figuring I'd probably use your DLL, but I also
> have adapted Matthew Curland's code for that,
> so it might not be a big deal to do the DEP-safe
> call with that. I'm assuming that he's forseen
> any potential issues in the code that he wrote.
> (On the other hand, I *am* hesitant to edit code
> that I really don't understand very well. :)
No problem with that - the Curland-Code is fine,
as long as you adapt it to the more DEP-tolerant
allocation, only thought that the problems you described
had to do with adapting the regfree-loading-approach,
"spread all over your project" with your "own hacks" ;-)
- and it was sounding as if you would have "to fight"
with it a bit, hence my recommendation.

Olaf
Author
2 Mar 2009 9:26 PM
mayayana
> No problem with that - the Curland-Code is fine,
> as long as you adapt it to the more DEP-tolerant
> allocation, only thought that the problems you described
> had to do with adapting the regfree-loading-approach,
> "spread all over your project" with your "own hacks" ;-)

   OK, thanks. While I get the idea of this in principle,
I have almost no background in asm or C++. Thus the
memory managing tricks are difficult to follow, so there's
not much chance of me getting into trouble by writing
my own asm from scratch.  :)
Author
2 Mar 2009 6:30 PM
RB Smissaert
> PSC? I don't know what you mean.

Planet Source Code:
http://www.planet-source-code.com/

RBS
Author
27 Feb 2009 11:17 PM
mayayana
Olaf,

  Another question if I may:

  You seem to be saying that XP security, with DEP
set for all processes, will result in a crash with
*any* use of assembly in VB. Is that right? I happen
to be using Matthew Curland's code with assembly
in my version of a RichEdit window for subclassing.

Show quoteHide quote
> Yep, it's a PowerBasic-Compile - and so the calling
> of Functions by Pointer was not requiring any Assembler-
> "workarounds" as with the VB-Code, hence no DEP-
> issues possible.
>
Author
28 Feb 2009 12:56 AM
Schmidt
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:%23dI%23THTmJHA.3760@TK2MSFTNGP03.phx.gbl...

>   You seem to be saying that XP security, with DEP
> set for all processes, will result in a crash with
> *any* use of assembly in VB. Is that right?
No, not generally.
You can check if Assembly-Code is doing it "the
right way", if it is using the VirtualAlloc-API with
the appropriate PAGE_EXECUTE_READWRITE-
Flag.

> I happen to be using Matthew Curland's code with
> assembly in my version of a RichEdit window for subclassing.
As said, take a look, how the memAllocation of the
ASM-Code is done.
If it is simply placed in a VB-Variable, or a VB-
ByteArray, that's not enough to avoid DEP-issues.

Please take a look at the second link I've posted,
how to allocate Memory for the Assembly-Code
over the VirtualAlloc-API.

Olaf
Author
28 Feb 2009 2:12 AM
mayayana
> > I happen to be using Matthew Curland's code with
> > assembly in my version of a RichEdit window for subclassing.
> As said, take a look, how the memAllocation of the
> ASM-Code is done.
> If it is simply placed in a VB-Variable, or a VB-
> ByteArray, that's not enough to avoid DEP-issues.
>
> Please take a look at the second link I've posted,
> how to allocate Memory for the Assembly-Code
> over the VirtualAlloc-API.
>

   OK, thanks. I've been reading up on DEP and I
see what you mean. (I also saved your code sample
from that link.) You're basically getting permission
to run from that memory, as I understand it.
Author
28 Feb 2009 3:19 AM
Schmidt
Show quote Hide quote
"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
news:%23$qWRpUmJHA.5980@TK2MSFTNGP06.phx.gbl...
>
> > > I happen to be using Matthew Curland's code with
> > > assembly in my version of a RichEdit window for subclassing.
> > As said, take a look, how the memAllocation of the
> > ASM-Code is done.
> > If it is simply placed in a VB-Variable, or a VB-
> > ByteArray, that's not enough to avoid DEP-issues.
> >
> > Please take a look at the second link I've posted,
> > how to allocate Memory for the Assembly-Code
> > over the VirtualAlloc-API.
> >
>
>    OK, thanks. I've been reading up on DEP and I
> see what you mean. (I also saved your code sample
> from that link.) You're basically getting permission
> to run from that memory, as I understand it.
Yep, the Assembly-Code has to be placed on "properly-
flagged" memory.

Olaf
Author
28 Feb 2009 2:11 AM
Henning
Isn't inline asm nice ;) Maybe time to upgrade to the latest version, been
years since I used it (7.0).

/Henning

Show quoteHide quote
"Schmidt" <s**@online.de> skrev i meddelandet
news:u3%23dm3SmJHA.5028@TK2MSFTNGP04.phx.gbl...
>
> "mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
> news:OFF3seRmJHA.6060@TK2MSFTNGP05.phx.gbl...
>
>>   Thank you. I'd prefer to have code rather than an extra
>> library, but your DLL is nicely compact ...
> Yep, it's a PowerBasic-Compile - and so the calling
> of Functions by Pointer was not requiring any Assembler-
> "workarounds" as with the VB-Code, hence no DEP-
> issues possible.
>
>> and frankly I only partly understand your code and
>> Matthew Curland's code.
>> So I'm really not in a position to judge whether writing my
>> own code is a good idea. I assume that the problem you're
>> talking about is when DEP is set for all processes?
> Yep.
>
>> I'm only vaguely familiar with that. I would have thought it
>> was a rare setting.
> Yes, the default-setting is, that (at least XP) only
> watches the "wellknown" Binaries.
>
>>   With you DLL sample: There's not much explanation.
>> You don't have any documentation?
> Yep, thought the examples were sufficient...<g>
>
>> Is the function GETINSTANCE all that's needed to load
>> an object? GETINSTANCE(Path, ClassName) ?
> Yes.
> Simply look at it as a fully compatible working replacement
> to CreateObject().
> Instead of giving the (two-part) ProgID in one Parameter,
> you will have to give a fully qualified path to your AX-Dll
> in the first one - and the ClassName (the "right-part" of
> the ProgID) in the second Param.
>
> One thing should be mentioned though:
> The only cases where the approach does not work
> regfree is, when you want to instantiate a Public-Class
> of your Dll, and this *Class* does contain the definition
> of a Public Type - but Public Enums on the other hand
> work fine.
>
>> And the DLL reads the embedded type library to translate the
>> class name to CLSID?
> Yes.
>
>> How is the object then released?
> GetInstance returns with: 'As Object'
> The instantiated and delivered Object-instance is released
> in the usual way, when its last reference goes out of scope
> (in the same way as with CreateObject-generated instances).
> Or do you mean the Dll itself?
>
>> You seem to have a function UNLOADCOMDLL but I
>> don't see any place in your sample code where that's used.
> The loaded Library-Handle(s) of the AX-Dll(s) are cached
> internally (and then reused) for the next instantiation-request.
> After your Process (or the VB-IDE) terminates, all Lib-
> Handles are freed automatically.
>
> The UNLOADCOMDLL is there, if you want to unload
> an already loaded COM-Dll and free its Lib-handle
> *whilst* your process is yet running - e.g. to perform
> an (online-) update or something in this regard (Dll-
> replacement) without the need, to shut-down your
> App completely.
>
> In my projects I never used it so far - but it is there
> and it works (but make sure, you have set all Obj-
> instances which you got from this Dll to Nothing,
> before you call it - there's a DllCanUnloadNow-
> check included before the Unloading itself is allowed).
>
> Olaf
>
>
Author
28 Feb 2009 3:28 AM
Schmidt
"Henning" <computer_h***@coldmail.com> schrieb im Newsbeitrag
news:49a89e80$0$16213$57c3e1d3@news3.bahnhof.se...

[PowerBasic]
> Isn't inline asm nice ;)
Never have used that feature of PowerBasic
(I'm not an ASM-expert).

The Function-Call by Pointer is available
directly in PowerBasic over the "using" syntax.

> Maybe time to upgrade to the latest version, been
> years since I used it (7.0).
I've also 7.0, but I use it not very often.
The newest version can create COM-Classes now
I've read somewhere - but FreeBasic is also nice -
and the TinyCC too... :-)

Olaf
Author
27 Feb 2009 8:20 PM
MM
Show quote Hide quote
On Fri, 27 Feb 2009 18:54:37 +0100, "Schmidt" <s**@online.de> wrote:

>
>"mayayana" <mayayaX***@rcXXn.com> schrieb im Newsbeitrag
>news:u4Qn$YOmJHA.1252@TK2MSFTNGP03.phx.gbl...
>
>>    I don't know how useful this is to people, but I've been
>> discovering the option to load reg-free COM objects lately.
>> It not only doesn't require registration. It also doesn't require
>> any special Windows version, or whathever other limitations
>> Microsoft's reg-free COM might have.
>>
>>   This functionality never mattered to me before because I
>> avoid shipping OCXs or custom ActiveX DLLs. But recently I
>> decided that I'd like to add a DLL to a project and it seems
>> silly to have to deal with the potential problems of COM
>> registration when my DLL is going to stay in the program folder,
>> used only by me.
>>
>>   I've adapted Matthew Curland's code, which is very compact,
>> and it seems to work just fine to create objects given a file
>> path and CLSID, with no registration needed.
>Be careful with the Curland-Code - it involves calling
>a function from its function-pointer in a way, which
>is not working (means crashing) on systems with
>enabled execution-prevention IIRC.
>
>> There's also a version of that that was published by
>> vbAdvance, although their website seems to be gone
>> now.
>> And if I'm not mistaken, Olaf Schmidtt also also offers
>> that functionality in his tools.
>The vbAdvance-Version was based on my first published
>Code-Snippet here:
><
>http://groups.google.de/group/microsoft.public.vb.com/browse_frm/thread/2ba3a5adb9b5e90c?q=vb+sss+cf.getinstance#4776e42bced56108
>
>But this older version is also not covering the potential
>Execution-Prevention-issues in the right way.
>I posted a CallFunctionByPointer-approach ca. one year
>later, which is using the MemAllocation in the correct way:
><
>http://groups.google.de/group/microsoft.public.vb.winapi/browse_frm/thread/3e9859b326a3134d?q=vb+sss+asm#233d3b679215ba84
>(please look at ThreadEntry Nr. 8, which is the post
> where I got it "right" finally ;-)
>
>Nonetheless I'd recommend to use the small (StdAPI)-Dll,
>which I made for that purpose (DirectCOM.dll) - this Dll
>is known to work without any Exec-Prevention-issues
>on all systems from Win98 to Vista - and it is also safe to
>use in threaded scenarios, where the "direct VB5/6-based"
>approaches have shown some issues, and it also covers
>Lib-Handle-Caching etc.
>
>> (Sorry if I misspelled your last name, Olaf. I can never
>> seem to remember that spelling. :)
>It is Schmidt - but there are also a lot of 'Schmitts'
>"out there" (at least here in germany) <g>
>
>Olaf
>

Olaf, is DirectCOM.dll freeware?

MM
Author
27 Feb 2009 10:10 PM
Schmidt
"MM" <kylix***@yahoo.co.uk> schrieb im Newsbeitrag
news:5ligq4d1bbmn8pj7nrvo8s6i51d73d8a8o@4ax.com...

> Olaf, is DirectCOM.dll freeware?
Yes, it is part of my small framework, which is in
the Public Domain and consists of three Dlls currently:

dhRichClient3.dll
sqlite36_engine.dll
DirectCOM.dll

Only the first one is an AX-Dll, so you would have
to put a reference to it in your project-settings, if
you want to use its Classes earlybound.

But DirectCOM.dll can load any AX-Dll regfree over
the GETINSTANCE(DllPath, ClassName) - Call,
not only the dhRichClient3.dll-Classes.

Included in the RichClient-AX is a Class, which makes
the instantiation of RichClient-internal (Public) Classes
even more easier, once you "bootstrapped" (meaning
the regfree loading) the appropriate cFactory-Class
(usually in a *.bas-module, so that the Factory is
"visible" throughout your whole VB-Project).

Behind this "Factory" are currently a Constructor-Helper,
simply called 'c' and a class called 'regfree', which
offers the regfree loading (and also the new regfree
thread-instanciations) then behind a COM-Interface.

But DirectCOM.dll can also be used "standalone",
if you don't need the functionality of the RichClient-
Classes.

Olaf
Author
28 Feb 2009 2:31 PM
Jason Keats
Schmidt wrote:
>
> But DirectCOM.dll can load any AX-Dll regfree over
> the GETINSTANCE(DllPath, ClassName) - Call,
> not only the dhRichClient3.dll-Classes.
>

Will DirectCOM.dll also work with OCXs?
Author
28 Feb 2009 4:21 PM
Schmidt
"Jason Keats" <jke***@melbpcDeleteThis.org.au> schrieb im Newsbeitrag
news:eecTTFbmJHA.1216@TK2MSFTNGP02.phx.gbl...
> Schmidt wrote:
> >
> > But DirectCOM.dll can load any AX-Dll regfree over
> > the GETINSTANCE(DllPath, ClassName) - Call,
> > not only the dhRichClient3.dll-Classes.
> >
>
> Will DirectCOM.dll also work with OCXs?
Not directly.
In the older dhRichClient.dll (version 2.3) - there
is support for regfree OCX-Loading builtin.
www.datenhaus.de/Downloads/dhRichClientDemo.zip
It contains this older RichClient-Version with the
appropriate "regfree OCX-Loading"-Demos.

Basically you would have to instantiate a cFactory
first from dhRichClient.dll in a regfree manner
(over the DirectCOM.dll  GETINSTANCE()-call).

Behind this Factory-Object is a method .AddControl
available then, which is able to load OCXes directly
from the FileSystem regfree.
But this OCX-loading-mechanism (though working
well for most VB-created OCXes) sometimes
has problems with 3rd-party OCXes, although
most of them work too with it (as e.g. the FlexGrids
or the VB-DataGrid, MonthView, DatePicker, etc.).

This mechanism is not that straightforward to use
as the relative simple and reliable GetInstance-Call.
To integrate such a loaded OCX-Control in the correct
way into the VB-known Control-Hierarchy (to ensure
a well working Tab-Order, etc.), you will have also have
to include an empty ucDummy.ctl into your Project.
As said, the Demos from the link above show, how
to setup your project and to use all that stuff then,
but be aware, that it needs some time, until you
are familiar with the needed steps. Probably only
worth the effort, if you want the regfree OCX-loading
to work also on Win98 or W2K.
If your target-systems are XP and higher, then I'd
recommend the SxS-based loading. Creating the
correct manifests is probably a bit easier then,
compared with the efforts with that alternative
OCX-loading-approach.

In the new RichClient3 I've therefore removed the
AddControl-feature, also because the new (Dll-based)
WidgetSet is "lurking around the corner" - so one will
only need the GetInstance-Call for "Control"-Loading
against this Set then.

Olaf
Author
2 Mar 2009 2:12 PM
Jason Keats
Schmidt wrote:
Show quoteHide quote
> "Jason Keats" <jke***@melbpcDeleteThis.org.au> schrieb im Newsbeitrag
> news:eecTTFbmJHA.1216@TK2MSFTNGP02.phx.gbl...
>> Schmidt wrote:
>>> But DirectCOM.dll can load any AX-Dll regfree over
>>> the GETINSTANCE(DllPath, ClassName) - Call,
>>> not only the dhRichClient3.dll-Classes.
>>>
>> Will DirectCOM.dll also work with OCXs?
> Not directly.
> In the older dhRichClient.dll (version 2.3) - there
> is support for regfree OCX-Loading builtin.
> www.datenhaus.de/Downloads/dhRichClientDemo.zip
> It contains this older RichClient-Version with the
> appropriate "regfree OCX-Loading"-Demos.
>
> Basically you would have to instantiate a cFactory
> first from dhRichClient.dll in a regfree manner
> (over the DirectCOM.dll  GETINSTANCE()-call).
>
> Behind this Factory-Object is a method .AddControl
> available then, which is able to load OCXes directly
> from the FileSystem regfree.
> But this OCX-loading-mechanism (though working
> well for most VB-created OCXes) sometimes
> has problems with 3rd-party OCXes, although
> most of them work too with it (as e.g. the FlexGrids
> or the VB-DataGrid, MonthView, DatePicker, etc.).
>
> This mechanism is not that straightforward to use
> as the relative simple and reliable GetInstance-Call.
> To integrate such a loaded OCX-Control in the correct
> way into the VB-known Control-Hierarchy (to ensure
> a well working Tab-Order, etc.), you will have also have
> to include an empty ucDummy.ctl into your Project.
> As said, the Demos from the link above show, how
> to setup your project and to use all that stuff then,
> but be aware, that it needs some time, until you
> are familiar with the needed steps. Probably only
> worth the effort, if you want the regfree OCX-loading
> to work also on Win98 or W2K.
> If your target-systems are XP and higher, then I'd
> recommend the SxS-based loading. Creating the
> correct manifests is probably a bit easier then,
> compared with the efforts with that alternative
> OCX-loading-approach.
>
> In the new RichClient3 I've therefore removed the
> AddControl-feature, also because the new (Dll-based)
> WidgetSet is "lurking around the corner" - so one will
> only need the GetInstance-Call for "Control"-Loading
> against this Set then.
>
> Olaf

Thanks for the detailed response, Olaf.

If the OCX was normally invisible (eg, a spell checker dialog), and
therefore didn't require a tab order, would the empty ucDummy.ctl still
be necessary?
Author
2 Mar 2009 6:35 PM
Schmidt
"Jason Keats" <jke***@melbpcDeleteThis.org.au> schrieb im Newsbeitrag
news:O%23g4$D0mJHA.3380@TK2MSFTNGP04.phx.gbl...

> If the OCX was normally invisible (eg, a spell checker
> dialog), and therefore didn't require a tab order,
> would the empty ucDummy.ctl still be necessary?
Yes, but this ucDummy.ctl is only needed once per
project, is generically usable for any type of OCX-
Ctl that you want to load regfree - and it can be a
Project-private UserControl, which then only needs
and contains two small functions (one inside
UserControl_Initialize and one in
UserControl_Terminate) thereby ensuring the
correct "connections" (and disconnections) to
(and from) the VB-UserControl-Hierarchy then.
No way without that - but as said, no bigger problem,
if you invest one or two hours into the appropriate
Demos.

Olaf
Author
27 Feb 2009 6:19 PM
Ulrich Korndoerfer
Hi,

mayayana schrieb:

Show quoteHide quote
> ...
>> Also, the revelation that reg-free com can work
>> very well from XP onwards means that there will be potentially many
>> more VB6 applications to bear fruit over the next few years.
>
>    I don't know how useful this is to people, but I've been
> discovering the option to load reg-free COM objects lately.
> It not only doesn't require registration. It also doesn't require
> any special Windows version, or whathever other limitations
> Microsoft's reg-free COM might have.
>
>   This functionality never mattered to me before because I
> avoid shipping OCXs or custom ActiveX DLLs. But recently I
> decided that I'd like to add a DLL to a project and it seems
> silly to have to deal with the potential problems of COM
> registration when my DLL is going to stay in the program folder,
> used only by me.
>
>   I've adapted Matthew Curland's code, which is very compact,
> and it seems to work just fine to create objects given a file
> path and CLSID, with no registration needed. There's also a
> version of that that was published by vbAdvance, although their
> website seems to be gone now. And if I'm not mistaken, Olaf
> Schmidtt also also offers that functionality in his tools.
> (Sorry if I misspelled your last name, Olaf. I can never
> seem to remember that spelling. :)
>

Download link is:

<http://www.thecommon.net/10.html>

And Olafs surname is Schmidt :-)

>    I'm surprised that this method doesn't get much attention.
> ...

This surprises me too. Olafs dll for reg free COM is out since years,
and can handle ActiveX components (OCX) too. It does not depend on XP or
above and gives full control to the programmer.

The MS "official" ways for reg free COM are clumsy and handicapped. They
more obscure getting reg free COM to work than to actively support it.
Must be some marketing reasons behind why MS does so as it does.

--
Ulrich Korndoerfer

VB tips, helpers, solutions -> http://www.proSource.de/Downloads/
Author
27 Feb 2009 4:59 AM
mayayana
> Has anyone noticed that the VB6 runtime is now supported on Windows 7?
>

  Thanks for that. I had been wondering about secondary
support. For instance, the RTB control wouldn't be much
good if there's no RichEdit v. 1 emulation. But the
page you linked is very clear and detailed, and it looks
like there's little, if anything, to be concerned about in
terms of secondary files.
Author
27 Feb 2009 8:55 AM
MM
On Thu, 26 Feb 2009 14:29:17 -0800 (PST),
mark.tunnard.jack***@googlemail.com wrote:

>Has anyone noticed that the VB6 runtime is now supported on Windows 7?
>
>The support statement page - http://msdn.microsoft.com/en-us/vbrun/ms788708.aspx
>- now says
>
>The core Visual Basic 6.0 runtime will be supported for the full
>lifetime of Windows Vista, Windows Server 2008 and Windows 7,which is
>five years of mainstream support followed by five years of extended
>support.
>
>I don't know when it was changed, because it didn't say that a couple
>of weeks ago, but it does now. Yippee!

Yes, I have already successfully tested my VB6 application on Windows
7 Beta. It works absolutely fine.

MM