So 3shost ate my previous post (and destroyed some previously working settings), so this is my third shot at telling you about the new magnification APIs available in Vista. Basically, the idea is that the system provides the user with a set of uniform APIs that allows them to magnify a part of the screen (usually for accessibility purposes).
You might think that this process is relatively difficult -- but it's really quite easy. You first have to initialize the magnification services with a call to MagInitialize. Then you create your magnification control with CreateWindow, and set up the magnification transformation matrix (how much you want to magnify by -- but you can shear, etc as well if you'd like). Finally, you set the source rectangle of what area to magnify and update the control.
The first step is trivial, and I do it in the Open event of my window where I'm creating the control:
[rbcode]
// Initialize the magnifier
Soft Declare Sub MagInitialize Lib "Magnification" ()
if System.IsFunctionAvailable( "MagInitialize", "Magnification" ) then
MagInitialize
end if
[/rbcode]
Creating the control is a typical call to CreateWindow, where we pass in "Magnifier" as the class type for the control. Note that I also modify the flag to show the cursor magnified as well, but you can leave that off if you'd like.[rbcode]
// Now we want to make the magnifier control
Soft Declare Function CreateWindowExW Lib "User32" ( zero as Integer, className as WString, _
title as WString, style as Integer, x as Integer, y as Integer, width as Integer, _
height as Integer, parent as Integer, menu as Integer, hInst as Integer, lParam as Integer ) as Integer
Soft Declare Function GetModuleHandleW Lib "Kernel32" ( null as Integer ) as Integer
if System.IsFunctionAvailable( "CreateWindowExW", "User32" ) then
Const MS_SHOWMAGNIFIEDCURSOR = &h1
Const WS_CHILD = &h40000000
Const WS_VISIBLE = &h10000000
mCtrlWnd = CreateWindowExW( 0, "Magnifier", "", MS_SHOWMAGNIFIEDCURSOR + WS_CHILD + WS_VISIBLE, _
0, 0, 300, 300, self.Handle, 0, GetModuleHandleW( 0 ), 0 )
end if[/rbcode]
The final step for creating the control is to initialize its transformation matrix. This may sound like some complex math-like thing, but it's really quite simple. All you need to specify is the magnification on the x and y axis -- it should be pretty easy for you to accomplish once you see how it's done:[rbcode]
Soft Declare Sub MagSetWindowTransform Lib "Magnification" ( hctl as Integer, t as Ptr )
dim transform as new MemoryBlock( 3 * 3 * 4 )
transform.SingleValue( 0 ) = 4.0
transform.SingleValue( 16 ) = 4.0
transform.SingleValue( 32 ) = 1.0
MagSetWindowTransform( mCtrlWnd, transform )[/rbcode]
Now the control is setup properly and is ready for magnifying parts of the screen. I made an Update method which is called from a timer's Action event that does all of the work. It checks out where the mouse cursor is and magnifies an area around the cursor. It also takes care to make sure that the magnification area is on screen (no sense in trying to magnify the black pixels that are off screen, right?). The basic idea is that you calculate a rectangle that you want to view, call MagSetWindowSource to tell the control what source it should be magnifying, and then update the window.[rbcode]
Protected Sub Update()
Soft Declare Sub MagSetWindowSource Lib "Magnification" ( hctl as Integer, r as Win32RECT )
dim width, height as Integer
width = self.Width / 4
height = self.Height / 4
dim r as Win32RECT
r.left = System.MouseX - width / 2
r.top = System.MouseY - height / 2
if r.left < 0 then r.left = 0
if r.top < 0 then r.left = 0
if r.left > Screen( 0 ).Width - width then r.left = Screen( 0 ).Width - width
if r.top > Screen( 0 ).Height - height then r.top = Screen( 0 ).Height - height
r.right = r.top + width
r.bottom = r.right + height
MagSetWindowSource( mCtrlWnd, r )
Declare Sub SetWindowPos Lib "User32" ( hwnd as Integer, after as Integer, _
x as Integer, y as Integer, width as Integer, height as Integer, flags as Integer )
Const HWND_TOPMOST = -1
Const SWP_NOSIZE = &h1
Const SWP_NOMOVE = &h2
Const SWP_NOACTIVATE = &h10
SetWindowPos( self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE + SWP_NOMOVE + SWP_NOSIZE )
Declare Sub InvalidateRect Lib "User32" ( hctl as Integer, r as Integer, force as Boolean )
InvalidateRect( mCtrlWnd, 0, true )
End Sub[/rbcode]
That's all there is to it! As you can see, the magnification APIs are really easy to use in Vista. The unfortunate thing is that the majority of people won't have much of a need for them. However, if you are making an accessibility application (I can think of at least one reader who might be interested in this sort of thing), using these APIs when available is a good thing.
Note: please excuse the horrible formatting of the source code. So it turns out that what 3shost broke was my WordPress configuration. If any word starts with "set", then it will eat the post entirely when attempting to save it to the database. So I was using the HTML entity for the 's', which gets around the problem. Except you can't use those in pre tags, or so it seems. This has never been an issue before this week and only happened after 3shost corrupted my database (a post was lost, but its comments were attached to another post instead). Oh yay.
They have screwed up RBLibrary also, I am rebuilding databases nightly, forget newsletters and what not. Completely untenable.
wow !
Nasty hosting
What the hell have they screwed up to make all this crap quit working ?
Better yet why ?
wow
Nasty hosting
What the hell have they screwed up to make all this crap quit working
Better yet why
Helluva question -- but moot. My service contract is up in Jan, and I don't plan to renew.
Hah, it turns out the auto-mailer is broken as well. Nice.
I had to post my comment at least 3 times before it took it once
Piles of error messages etc
Makes my poor little mac mini as my server seem pretty damn robust and reliable :)
I'm using a Linux box as the server with 3shost. Not certain how they managed to stuff things up to this extent.
Aaron,
Call me up, collect if you have to. Like as soon as you read this.
I emailed you Lis' # (to your RBLibrary.com address). You can call that. Otherwise, email me your # (I have it back in MN, not here).