More Baby Steps - CLR and Windows Screens

Started by stanl, June 13, 2013, 07:50:35 AM

Previous topic - Next topic

stanl

The attached is a basic get of the allscreens property of the .NET Windows.Forms.Screens class. The data for my laptop (single screen) is returned as ARRAY type and WB can understand it, but I am not really sure of the exact way to render it readable. The script also gets at the PrimaryDisplay which comes back as a DISPATCH.  The interest is not so much in out-doing the existing WB screen functions but to get a better understanding of these return types from .NET classes.
Deana or Tony... if you might find time to add the 1-2 lines of code that make the script more meaningful, I appreciate it.

td

Quote from: stanl on June 13, 2013, 07:50:35 AM
The attached is a basic get of the allscreens property of the .NET Windows.Forms.Screens class. The data for my laptop (single screen) is returned as ARRAY type and WB can understand it, but I am not really sure of the exact way to render it readable.

This is an example of one of the reasons the 'ObjectClrType' function exists.  WinBatch automagically detects return values as CLR objects and wraps them in a COM Automation object (DISPATCH variant). However, for performances reasons it doesn't wrap every element of a return array of objects so the user needs to perform the wrap.

Code (winbatch) Select

ObjectClrOption("use","System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
Screen = ObjectClrNew('System.Windows.Forms.Screen')
Screens = Screen.AllScreens
                                                             
foreach Item in Screens
   ScreenItem = ObjectClrType("System.Windows.Forms.Screen", Item)
   Message("Device Name", ScreenItem.DeviceName)
next
exit


Quote from: stanl on June 13, 2013, 07:50:35 AM
The script also gets at the PrimaryDisplay which comes back as a DISPATCH.  The interest is not so much in out-doing the existing WB screen functions but to get a better understanding of these return types from .NET classes.

As stated in the WinBatch documentation for the CLR functions and above, WinBatch wraps CLR based class references in COM Automation objects. If you look at the documentation for the Screen class property 'PrimaryScreen'

http://msdn.microsoft.com/en-us/library/system.windows.forms.screen.primaryscreen.aspx

you will notice that returns a class reference.  WinBatch simple wraps the return in a light weight COM automation object and you can access it just like any wrapped object returned by 'OptionsClrNew'.   
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Correction - If a CLR class has certain visibility attributes set you don't need to even use 'ObjectClrType'.  In this case the 'System.Windows.Forms.Screen' class allows WinBatch to determine its identity without using 'ObjectClrType' on the array elements.  However, I would recommend still using 'ObjectClrType' on each element, if you plan on accessing any property or method more than once or accessing more than one property or method of the class, to prevent having to perform the wrap operation more than once per class object.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Hopefully, this summary will help
Code (winbatch) Select

ObjectClrOption("use","System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
Screen = ObjectClrNew('System.Windows.Forms.Screen')

PrimScreen = Screen.PrimaryScreen

;; Don't need to use ObjectClrType because
;; class wrapped for you by WinBatch
Message("Device Name", PrimScreen.DeviceName)

Screens = Screen.AllScreens
                                                             
foreach Item in Screens
   ;; Don't need to use ObjectClrType because
   ;; the CLR class allows WinBatch to query it
   ;; about its type information.
   Message("Device Name", Item.DeviceName)

   ;; However, it is more efficient to do so.
   ScreenItem = ObjectClrType("System.Windows.Forms.Screen", Item)
   Message("Device", "Name: ":ScreenItem.DeviceName:@CRLF:"Bits per pixel: ":ScreenItem.BitsPerPixel)
next
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Of course it helps. When I looked at the MS docs for the screen class it looked like DeviceName was a property of the screen, not the PrimaryDisplay which is a property of the screen.
Now I can go chopping up some more PS into WB which looks at this class to determine whether or not the task bar is visible.
This is very helpful and I hope others seeing that who want to step into the CLR will as well.

td

Quote from: stanl on June 13, 2013, 10:33:00 AM
Of course it helps. When I looked at the MS docs for the screen class it looked like DeviceName was a property of the screen, not the PrimaryDisplay which is a property of the screen.

'DeviceName' is a property of Screen. 'PrimaryScreen' is simply returning another instance of the 'Screen' class that represents the primary screen.  It is not uncommon in FCL for a class instance to return another instance of its class.  In fact, it is not that uncommon in OO programming in general. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on June 13, 2013, 11:15:08 AM
[It is not uncommon in FCL for a class instance to return another instance of its class.  In fact, it is not that uncommon in OO programming in general.

Explains why Rutherford B. Hayes won.

td

Typoed (again) in my last post.  I corrected it by changing the sentence "'DeviceName' is simply returning another instance of the 'Screen' class that represents the primary screen. " to read "'PrimaryScreen' is simply returning another instance of the 'Screen' class that represents the primary screen. " instead.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade