Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PROTECTED hDevice, channel / What does the statement PROTECTED provide

Status
Not open for further replies.

dkean4

Programmer
Feb 15, 2015
282
US
I built this program about 15 to 20 years ago and I completely forgot what this keyword "PROTECTED" provides. If you need to see it in context here is a snippet of the code... VFP sees it as part of its language code by Highlighting it and uppercasing it as you type it in. I guess I got old and although I used it in the past I have no memory of its nature of protection. Furthermore, VFP HELP does not provide any clues about its use or meaning! I scoured the VFP Help assistant.[alien]

Code:
[COLOR=#AD7FA8]DEFINE CLASS[/color][/b] TMidiNote As Session
[b][COLOR=#AD7FA8]#DEFINE[/color][/b] MIDI_STATUS_PLAYNOTE 9
[b][COLOR=#AD7FA8]#DEFINE[/color][/b] MIDI_STATUS_PATCH 12
[b][COLOR=#AD7FA8]PROTECTED[/color][/b] hDevice, channel
    hDevice=0
    channel=0
 
	[b][COLOR=#AD7FA8]PROCEDURE[/color][/b] Init(lDeclare)
	    THIS.declare
	    IF NOT THIS.OpenDevice()
	        RETURN .F.
	    ENDIF
	 
	[b][COLOR=#AD7FA8]PROCEDURE[/color][/b] Destroy
	    THIS.CloseDevice
	    
	[b][COLOR=#AD7FA8]PROCEDURE[/color][/b] midiReset
	    = midiOutReset(THIS.hDevice)

	 
	[b][COLOR=#AD7FA8]PROTECTED FUNCTION[/color][/b] OpenDevice() As Boolean
	    IF midiOutGetNumDevs() = 0
	        MESSAGEBOX("No Midi Devices found.",48, "MIDI Error")
	        RETURN .F.
	    ENDIF
	 
	    LOCAL hDevice, nResult
	    hDevice=0
	    nResult = midiOutOpen(@hDevice, 0,0,0,0)
	    THIS.hDevice = m.hDevice
	    IF nResult <> 0
	        MESSAGEBOX("Call to midiOutOpen failed: " + TRANSFORM(nResult), 48, "MIDI Error")
	    ENDIF
	RETURN (m.nResult=0)
	 
	[b][COLOR=#AD7FA8]PROTECTED PROCEDURE[/color][/b] CloseDevice
	    IF THIS.hDevice <> 0
	        = midiOutReset(THIS.hDevice)
	        = midiOutClose(THIS.hDevice)
	        THIS.hDevice = 0
	    ENDIF]

I am trying to add features to this massive application, so, any help would be very appreciated.

Dennis Kean

Simplicity is the extreme degree of sophistication.
Leonardo da Vinci
 
 https://files.engineering.com/getfile.aspx?folder=0761c101-cc7a-4aaf-8283-05934ebee211&file=Capture.JPG
Hi,

vfp help said:
DEFINE CLASS Command - Property Definition Clause
The PROTECTED keyword prevents access and changes to the specified properties from outside of the class definition. Methods and events in the class or subclass definition can access protected properties.

Simply: Methods and properties signed as "PROTECTED" you can't use from object instance:
[pre]loo=CREATEOBJECT("TMidiNote")
?loo.hDevice && fail
?loo_OpenDevice() && fail
RELE loo
[/pre]

MartinaJ
 
Hi Dennis,

on top of that meaning, the aim of protected and hidden properties is to implement the OOP principle of encapsulation.

See
Wikipedia said:
the restricting of direct access to some of an object's components

The hDevice and channel properties are kept under internal control and you also don't call OpenDevice from outside, that's done at init. Do you have forgotten some OOP concepts? I can see the reason being that the init already automatically calls OpenDevice and that's something that shouldn't be called twice, also changing the device handle wouldn't really change it, so you keep that protected from outside changes.

I'd look into the case of having two or more midi devices, I don't see a way this class definition allows you to specify which one to use, and unprotecting hDevice will not help. As far as I see from the code, it's not specifying which midi device to use, but it's a device handle you get from opening a device, like a connection handle.

From the OOP perspective, it's a good choice to have the hDevice handle as protected property. Assuming all further midi device operations are done by this class, nothing else needs the hDevice handle to work and changing it would harm the functioning, so there's no need to make it a readable property and much less allowing to overwrite its value from outside.

Obviously, if other classes/objects you instantiate in parallel to this class should also act on the same midi device, this encapsulation is hindering that. But that would also be against another aspect of OOP, the single-responsibility principle, so only one class (or class family, inheriting this responsibility and specialising) should do the midi handling. In this specific topic, I'd say it's natural to have one class instance for one device, there's no reason I can think of for two instances to act on the same device.

Chriss
 
I don't know whether you question really is just the basic question that can be answered with the help itself or if it's motivated by this class stopping to work as necessary. Maybe you did add another midi device and now fail to see how this class isn't implementing the choice of which device to use. The core point I see is the midiOutOpen(@hDevice, 0,0,0,0) call with all the literal 0 parameters. But I refrain from going into details. Just pointing it out, it's rarely a good idea to make all literal parameters without at least a comment about what they mean, and what values they could also be. Just for future reference. If you have a second (or more) midi device, here's a proof of how such a negligence in the past hits you now.

It's not that bad, obviously, as even though I didn't program this and am no midi expert (except helping Jan Flikweert with aspects unrelated to midi itself in his midi code), still I can spot this problem of automatic initialization without more specific parameterization of midiOutOpen. It's easy to fix, just once more looking at reference documentation: there you see what all your 0s mean.

Chriss
 
Also, apologies that this seems to be quite harsh criticism, see the positive side of the question, whether you forgot something you once knew. As far as the usage of protected goes, this is perfect use of it.

And let me add this leads me to believe you're among the ones with more background knowledge here.

It's not wrong in itself to ask about something the help has in its reference section, too, as I recently said in another thread, too. It just could be a more concrete question, if you at least already looked up the definition yourself. As Martina quotes it, it's part of the topic about DEFINE CLASS, a bit buried.

But the help search on "protected" ranks the topis "Protecting and Hiding Class Members" as #1:
The search index of the CHM coming with VFP9 (SP0, the version without SP) had an issue, but I recommend using at least the latest SP2 help or even better the VFP community maintained help file at has fixed all issues and you can find things in the help, really.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top