From: MikeD on


"David" <NoWhere(a)earthlink.net> wrote in message
news:#tG5H7ltKHA.4860(a)TK2MSFTNGP05.phx.gbl...
> Thanks MikeD.
>
> I'm pretty sure (??) you can add a property to a form -- have to try and
> dig up and old article if of interest (believe McKinney) -- but wasn't
> sure about any other MS control.
>

As Eduardo said, form's have a code module and are essentially a class;
therefore, you can add whatever properties, methods and additional events
you want to forms just like you write your own properties, methods, and
events in class modules.

There IS another option, depending on what you need to add. You can use the
Win32 API to add "properties" to anything that has an hWnd. The function to
do this is named SetProp. Likewise, there is a RemoveProp function and a
GetProp function. You can name the property anything you want, and it can
even be an atom (created by calling GlobalAddAtom). The data type of the
value of the property must be a Long. There's not too much practical use
(that I've found anyway) for doing this except for one, which I think is a
FAR better means than other alternatives. And that's to store a pointer to
an object when that object's not within current scope. I do this when
subclassing a control as I usually implement additional functionality via a
class module (for example, functionality not exposed by VB's ListView
control, but is available using the API, so I pass a reference to the
ListView control I want "enhanced"). In order to raise events in response
to Windows' messages that are received by subclassing, I need a reference to
the object created from the class module. Since the winproc procedure must
be in a .bas module, it doesn't have a reference to that object. I use
SetProp to set a pointer to the object and then in the winproc function, use
GetProp to get that pointer, which I then use to create a local reference to
the object. You just have to be sure to destroy the local reference BEFORE
the winproc procedure falls off the stack (exits); otherwise, the app WILL
crash.

It's actually very easy to do. To set the "property" do something like this:

(this code would go somewhere in the class module)

Dim ptrObject As Long
CopyMemory ptrObject, Me, 4&
Call SetProp(m_oListView.hwnd, "ELV", ptrObject)

Now in your winproc procedure (which must be in a .bas module), do this to
create a reference to the class module object whose pointer was previously
stored as ELV above:

Dim oELV As EListView
Dim ptrELV As Long

ptrELV = GetProp(hwnd, "ELV")
CopyMemory oELV, ptrELV, 4&

In this code, "hwnd" is a parameter Windows passes to the winproc function,
EListView would be the name of your class module.

To destroy this local reference, use this code:

CopyMemory oELV, 0&, 4&
Set oELV = Nothing

Because your app will crash if you don't destroy this local reference, it is
imperative to have an error handler in your winproc function and use the
above code to destroy the reference in your error handler.

You must also remove this property as Window's won't clean up after you.
Failure to remove the property could result in a memory leak or worse. I
do this when I unsubclass whatever it is that was subclassed. This is just a
simple call to RemoveProp:

RemoveProp hwnd, "ELV"


Here are the API declarations you need:

Public Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hwnd As
Long, ByVal lpString As String) As Long
Public Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hwnd As
Long, ByVal lpString As String, ByVal hData As Long) As Long
Public Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal
hwnd As Long, ByVal lpString As String) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(Destination As Any, Source As Any, ByVal Length As Long)

This is probably not what you're looking to do, but I thought I'd mention
it, just in case it might intrigue you and be appropriate for your needs.


--
Mike


From: Dee Earley on
On 25/02/2010 17:54, David wrote:
> In this case a picturebox?
>
> Currently I use a structure which tracks each picturebox
> and holds the variables I need.
>
> However, if it is possible to add a property to the MS Picturebox object,
> this structure could be eliminated.

This sounds very similar to a question asked a few months ago (right
down to the control types)....

Another suggestion, but you can superclass the picturebox control with a
user control that exposes the properties you need and adds the extra ones.

--
Dee Earley (dee.earley(a)icode.co.uk)
i-Catcher Development Team

iCode Systems
From: David on
Thanks all.

That refreshes my "old" memory as well as provides some options.


Mr. Meukel - interesting idea to use an unused property as a placeholder.
Will keep than in mind for the future.

Consider this thread closed.

David


"David" <NoWhere(a)earthlink.net> wrote in message
news:%23tG5H7ltKHA.4860(a)TK2MSFTNGP05.phx.gbl...
> Thanks MikeD.
>
> I'm pretty sure (??) you can add a property to a form -- have to try and
> dig up and old article if of interest (believe McKinney) -- but wasn't
> sure about any other MS control.
>
> David.
>
>
> "MikeD" <nobody(a)nowhere.edu> wrote in message
> news:%23WrrwrktKHA.4860(a)TK2MSFTNGP05.phx.gbl...
>>
>>
>> "David" <NoWhere(a)earthlink.net> wrote in message
>> news:OeRQYOktKHA.5940(a)TK2MSFTNGP02.phx.gbl...
>>> In this case a picturebox?
>>>
>>> Currently I use a structure which tracks each picturebox
>>> and holds the variables I need.
>>>
>>> However, if it is possible to add a property to the MS Picturebox
>>> object,
>>> this structure could be eliminated.
>>
>>
>> No direct way. However, you can put a PictureBox in your own UserControl
>> to which you add whatever properties, methods, and even events you'd
>> like.
>>
>> --
>> Mike
>>
>>
>
>