Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Magnification API and AutoHotkey


  • Please log in to reply
11 replies to this topic
  • Guests
  • Last active:
  • Joined: --
I'm trying to get the Magnification API working in AutoHotkey.
I have no experience in C++ or any desktop application programming for that matter, so I don't have much of an idea on how to debug this.
I've just tried to combine bits of information from here and there.

Here's my code so far, but it doesn't really work:

#NoEnv
#Persistent
OnExit, Uninitialize


Gui, +E0x80000
Gui, +AlwaysOnTop
Gui,Show,w320 h240, MagnifierWindowAHK
Gui,+LastFound
WinGet,guiHwnd,Id,A


DllCall("SetLayeredWindowAttributes", "uint", guiHwnd, NULL, 255, LWA_ALPHA:=0x2)

hInstance := DllCall("GetWindowLong", "uint", guiHwnd, "uint", GWW_HINSTANCE:=-6)


DllCall("magnification.dll\MagInitialize")

WS_CHILD := 0x40000000
WS_VISIBLE := 0x10000000
MS_SHOWMAGNIFIEDCURSOR := 0x1

magHwnd := DllCall("CreateWindow"
	, "Str", "WC_MAGNIFIER"
	, "Str", "MagnifierWindow"
	, "UInt", WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE
	, "Int", 0
	, "Int", 0
	, "Int", 320
	, "Int", 240
	, "UInt", guiHwnd
	, "UInt", 0
	, "UInt", 0
	, "UIntP", 0)


VarSetCapacity(magRect, 16, 0)
NumPut(160, magRect, 8, "Int")
NumPut(120, magRect, 12, "Int")

DllCall("MagSetWindowSource", "UInt", magHwnd, "UInt", &magRect)


return

Uninitialize:
DllCall("magnification.dll\MagUninitialize")

ExitApp

It's not a very useful code yet even if it worked, I'm just trying to get it to show something so I can continue working on it.
Can anyone help out with this?

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
This has been done multiple times in AHK. Get some hints from searching the forum.

  • Guests
  • Last active:
  • Joined: --
I couldn't find anything with the search, hence why I'm stuck. Tried MagInitialize which is essential for Magnification API and some other search terms. What should I be looking for?

octal
  • Members
  • 102 posts
  • Last active: Jul 24 2015 03:14 AM
  • Joined: 21 Feb 2011
heres A screen magnifier.

<!-- m -->http://www.autohotke...pic.php?t=11700<!-- m -->

I searched magnification.

  • Guests
  • Last active:
  • Joined: --
I know there are plenty of magnifiers out there.
But I don't want a screen magnifier.
I want to access the Windows Magnification API. I've already used the DWM API with AutoHotkey before to make DWM thumbnails, but it hasn't been much help with this one.
So I'm still asking if there's anyone who's good with WinAPI who could help me out with this?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
There are several errors in your script:
[*:2sej3qkf]WC_MAGNIFIER is the name of a constant defined in the Windows SDK. The actual value you should use is "Magnifier".
[*:2sej3qkf]You have not qualified "MagSetWindowSource" with "magnification.dll\".
[*:2sej3qkf]The SetLayeredWindowAttributes DllCall is missing parameters, but I suggest you use WinSet Transparent, 255 instead.
[*:2sej3qkf]CreateWindow is a macro, not a function, and therefore can't be called by DllCall. Use CreateWindowEx instead.
[*:2sej3qkf]Gui,+LastFound is unnecessary if you're going to refer to the window as "A". I suggest you remove the ,A parameter and use the Last Found Window in case the Gui is not activated successfully.
[*:2sej3qkf]MagSetWindowSource accepts a RECT, not a pointer to a RECT. If you're using a 32-bit AutoHotkey.exe, you must specify each of the RECT's four fields directly as parameters.
[*:2sej3qkf]GWW_HINSTANCE is mispelled and also hasn't been assigned a value (it should be -6). Fortunately, the script doesn't appear to use hInstance.Some general advice:
When debugging a DllCall, check ErrorLevel. Your script returns ErrorLevels -4 (function not found) and -2 (one or more type parameters are invalid). If you change "MagSetWindowSource" to "magnification.dll\MagSetWindowSource", the ErrorLevel changes from -4 to A-12, which indicates the parameters you passed to the function were 12 bytes less than it expected.

  • Guests
  • Last active:
  • Joined: --
Thanks Lexikos!
I'll look into it again. Like I said I have don't have much knowledge in this area so I had to just blindly combine stuff I have no idea of how to use :( And it shows in the errors I've made.

  • Guests
  • Last active:
  • Joined: --
I'm back with some fixes and possibly new problems.
It shows a window now, like it did before I added SetLayeredWindowAttributes (which had errors by me).

I get no errors with ErrorLevel anymore (thanks for the advice, I tried getting the errors through GetLastError, but probably failed with that too), and the only thing I can see is wrong is magHwnd being 0.

Did I still miss something? Here's my current code:

#NoEnv
#Persistent
OnExit, Uninitialize



Gui, +E0x80000
Gui, +AlwaysOnTop
Gui,Show,w320 h240, MagnifierWindowAHK
Gui,+LastFound
WinGet,guiHwnd,Id


WinSet, Transparent, 255


hInstance := DllCall("GetWindowLong"
	, "UInt", guiHwnd
	, "UInt", GWL_HINSTANCE:=-6)


DllCall("magnification.dll\MagInitialize")


WS_CHILD := 0x40000000
WS_VISIBLE := 0x10000000
MS_SHOWMAGNIFIEDCURSOR := 0x1

magHwnd := DllCall("CreateWindowEx"
	, "UInt", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "UInt", WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE
	, "Int", 0
	, "Int", 0
	, "Int", 320
	, "Int", 240
	, "UInt", guiHwnd
	, "UInt", 0
	, "UInt", hInstance
	, "UInt", 0)


DllCall("magnification.dll\MagSetWindowSource"
	, "UInt", magHwnd
	, "Int", 0
	, "Int", 0
	, "Int", 160
	, "Int", 120)

return



Uninitialize:
DllCall("magnification.dll\MagUninitialize")

ExitApp


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

I tried getting the errors through GetLastError, but probably failed with that too

DllCall calls SetLastError before calling the function, so calling GetLastError via DllCall is fairly pointless. You should use A_LastError instead, and look up the value here. In this case it is 1407, which is ERROR_CANNOT_FIND_WND_CLASS.

When you specify a dll hasn't already been loaded, DllCall automatically loads it to call the function, and unloads it after calling the function. Consequently, the window class is unregistered immediately after MagInitialize returns. To avoid this, load the dll before-hand:
DllCall("LoadLibrary", "str", "magnification.dll")


MzAHK
  • Members
  • 8 posts
  • Last active: Sep 08 2013 01:16 PM
  • Joined: 26 Feb 2011
Getting closer, but I still only have a black control in the window.
Added magnification transformation matrix (I hope I did it right) and Gui, Destroy on exit (MagUninitialize would fail otherwise), but that didn't change anything.
Now I don't get errors with ErrorLevel or A_LastError either, so I don't know how to debug.

Registered a username by the way. Thanks for the A_LastError advice too, it helped find the MagUninitialize error.


EDIT: Scratch all that. I think I have it working. I don't know what I did yet though. Sorry for the trouble.
EDIT2: It showed a black control at first. Then it just suddenly started working even though I didn't change the code and now it shows the black screen again. Getting a bit weird.

#NoEnv
#Persistent
OnExit, Uninitialize


Gui, +E0x80000
Gui, +AlwaysOnTop
Gui,Show,w320 h240, MagnifierWindowAHK
Gui,+LastFound
WinGet,guiHwnd,Id


WinSet, Transparent, 255


hInstance := DllCall("GetWindowLong"
	, "UInt", guiHwnd
	, "UInt", GWL_HINSTANCE:=-6)


DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")


WS_CHILD := 0x40000000
WS_VISIBLE := 0x10000000
MS_SHOWMAGNIFIEDCURSOR := 0x1

magHwnd := DllCall("CreateWindowEx"
	, "UInt", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "UInt", WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE
	, "Int", 0
	, "Int", 0
	, "Int", 320
	, "Int", 240
	, "UInt", guiHwnd
	, "UInt", 0
	, "UInt", hInstance
	, "UInt", 0)



; Magnification transform matrix

Matrix := "1|0|0|"
        . "0|1|0|"
        . "0|0|1"

StringSplit, Matrix, Matrix, |

VarSetCapacity(magMatrix, 36, 0)
Loop, 9
{
	NumPut(Matrix, magMatrix, (A_Index-1)*4, "float")
}

DllCall("magnification.dll\MagSetWindowTransform"
	, "UInt", magHwnd
	, "UInt", &magMatrix)


DllCall("magnification.dll\MagSetWindowSource"
	, "UInt", magHwnd
	, "Int", 0
	, "Int", 0
	, "Int", 320
	, "Int", 240)

return


Uninitialize:
Gui, Destroy

DllCall("magnification.dll\MagUninitialize")

ExitApp


MzAHK
  • Members
  • 8 posts
  • Last active: Sep 08 2013 01:16 PM
  • Joined: 26 Feb 2011
There's one thing that bothers me with this API implementation. The Magnify.exe on Windows 7 (and probably Vista too) uses the same API or at least loads the DLL so I thought I could achieve same results if I use the API. But the samples on the Magnification API page result in A LOT slower performance than that of Magnify.exe because the SetTimer function can only get to 10-16 millisecond intervals. Magnify.exe on the other hand is smooth and realtime even when set to fullscreen. Do you think they've made it somehow differently or is it just calling MagSetWindowSource (which updates the magnifier) as fast as it can?

EDIT: Actually it's still laggy even if I put the updater inside Loop without a Sleep.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

EDIT2: It showed a black control at first. Then it just suddenly started working even though I didn't change the code and now it shows the black screen again. Getting a bit weird.

Do you have a 64-bit version of Windows? I had similar results running on AutoHotkey Basic and AutoHotkey_L 32-bit, but it seems to work reliably on AutoHotkey_L 64-bit. (All the "UInt" params which accept a hwnd or pointer should be changed to "Ptr" for 64-bit compatibility.)