Color Zoomer/Picker & Screen Magnifier
#1
Posted 08 April 2007 - 05:18 AM
#2
Paulo-nli
Posted 18 April 2007 - 11:24 PM
Another great script...and an unusual one. :shock:
I will need to spend the rest of the day reading msdn pages to understand what this script is doing.
#3
Posted 19 April 2007 - 12:57 AM
Thanks. In fact, this is the one I'm the most proud of.Wow!!
Another great script...and an unusual one. :shock:
I will need to spend the rest of the day reading msdn pages to understand what this script is doing.
BTW, it may not work in Windows below XP in its current form.
I'm ready to update it for W2K if there is a report of no working in it (:I don't think it'll ever work in w9x).
#4
tic
Posted 22 April 2007 - 02:28 PM
#NoEnv
#SingleInstance, Force
SetWinDelay, 10
nZ := 4 ; Zoom Factor
nR := 220//2//nZ * nZ - 1 ; Rectangle of the Zoomer
CoordMode, Mouse
CoordMode, Pixel
ToolTip, %A_Space%
WinGet, hWnd, ID, ahk_class tooltips_class32
WinSet, ExStyle, +0x08000000, ahk_id %hWnd%
hDC_SC := DllCall("GetDC", "Uint", 0)
hDC_TT := DllCall("GetDC", "Uint", hWnd)
Loop
{
MouseGetPos, xmouse, ymouse
DllCall("StretchBlt", "Uint", hDC_TT, "int", 0, "int", 0, "int", 2*nR, "int", 2*nR, "Uint", hDC_SC, "int", xmouse-nR//nZ, "int", ymouse-nR//nZ, "int", 2*nR//nZ, "int", 2*nR//nZ, "Uint", 0x00CC0020)
WinMove, ahk_id %hWnd%,, xmouse-nR, ymouse-nR, 2*nR, 2*nR
GetKeyState, state, NumpadAdd
if state = D
goto Exit
}
DllCall("ReleaseDC", "Uint", 0, "Uint", hDC_SC)
DllCall("ReleaseDC", "Uint", hWnd, "Uint", hDC_TT)
Exit:
ExitAppbut i was wondering how i could get the cursor to act normally through the program. Somehow make it think the window is transparent, but actually have it still showing?
Any help would be much appreciated
#5
Posted 22 April 2007 - 03:10 PM
Is there something I can change, such that semi-transparent windows are also shown? It would be nice if I could re-open the magnifier without restarting the script. Is it safe? Also, when the color value is shown, Ctrl-C or something could copy it to the ClipBoard. Is it hard to add?
#6
Posted 22 April 2007 - 04:59 PM
but i was wondering how i could get the cursor to act normally through the program. Somehow make it think the window is transparent, but actually have it still showing?
I'm not 100% sure what you meant. I just guess you want so-called trans-mouse. If so, replace the following line in the script
WinSet, ExStyle, +0x08000000, ahk_id %hWnd%with
WinSet, ExStyle, +0x00000020, ahk_id %hWnd%
#7
Posted 22 April 2007 - 05:18 PM
Not sure this is directed to me. Anyway, there is no (semi-)transparent windows around here. Would you be a little more specific about what you have in mind?Is there something I can change, such that semi-transparent windows are also shown?
Actually in my own script, I used the directive #SingleInstance Off, so as to be able to trigger multiple instances of the script. Would you like to trigger the zoomer multiple times from the single instance of the script?It would be nice if I could re-open the magnifier without restarting the script. Is it safe? Also, when the color value is shown, Ctrl-C or something could copy it to the ClipBoard. Is it hard to add?
And, adding Ctrl-C is straightforward, especially with single instance of the picker, I think.
#8
Posted 22 April 2007 - 10:37 PM
I meant, if I have semi-transparent windows shown (even when they are opaque), the magnifier box does not show them, but the windows underneath. As if the topmost windows were fully transparent.Not sure this is directed to me. Anyway, there is no (semi-)transparent windows around here. Would you be a little more specific about what you have in mind?Is there something I can change, such that semi-transparent windows are also shown?
When I got the color values and close the bubble, the script does not terminate, but cannot be activated again. I have to manually close the script, and restart when I need it again, otherwise there will be many dormant instances open (making the tray full of AHK icons). I think it is quite common to read the color values of several pixels, which could be much easier with a resident script, (re)activated with a hotkey. The question was, is it safe not to exit the script, but re-open the zoomer window?I used the directive #SingleInstance Off, so as to be able to trigger multiple instances of the script. Would you like to trigger the zoomer multiple times from the single instance of the script?
Would you consider adding it to the script?adding Ctrl-C is straightforward, especially with single instance of the picker, I think.
#9
Posted 22 April 2007 - 11:34 PM
Ah, I see.I meant, if I have semi-transparent windows shown (even when they are opaque), the magnifier box does not show them, but the windows underneath. As if the topmost windows were fully transparent.
Transparent windows, more precisely Layered windows, are not part of the screen. They live in different layers, similar to the Mouse cursor which I believe lives in sort of the topmost layer.
As a matter of fact, this is the underlying reason to make this apparently impossible script become really possible. The zoomer window, i.e., AHK's tooltip window, is a layered window itself!
Although it's possible to capture these layered windows (:see my screen capture script <!-- m -->http://www.autohotke...topic18146.html<!-- m --> ), it's not feasible here to do it. Then, this zoomer window would start capturing itself, so effectively nothing would be captured.
When I got the color values and close the bubble, the script does not terminate, but cannot be activated again. I have to manually close the script, and restart when I need it again, otherwise there will be many dormant instances open (making the tray full of AHK icons). I think it is quite common to read the color values of several pixels, which could be much easier with a resident script, (re)activated with a hotkey. The question was, is it safe not to exit the script, but re-open the zoomer window?
Would you consider adding it to the script?adding Ctrl-C is straightforward, especially with single instance of the picker, I think.
I'll have to go now. I'll answer these part later.
#10
Posted 23 April 2007 - 03:41 AM
#NoEnv
#SingleInstance, Force
SetWinDelay, 10
size = 1
startagain:
nZ := 3 ; Zoom Factor
nR := size*100 ; Rectangle of the Zoomer
CoordMode, Mouse
CoordMode, Pixel
ToolTip, %A_Space%
WinGet, hWnd, ID, ahk_class tooltips_class32
WinSet, ExStyle, +0x00000020, ahk_id %hWnd%
hDC_SC := DllCall("GetDC", "Uint", 0)
hDC_TT := DllCall("GetDC", "Uint", hWnd)
Loop
{
MouseGetPos, xmouse, ymouse
DllCall("StretchBlt", "Uint", hDC_TT, "int", 0, "int", 0, "int", 2*nR, "int", 2*nR, "Uint", hDC_SC, "int", xmouse-nR//nZ, "int", ymouse-nR//nZ, "int", 2*nR//nZ, "int", 2*nR//nZ, "Uint", 0x00CC0020)
WinMove, ahk_id %hWnd%,, xmouse-nR, ymouse-nR, 2*nR, 2*nR
GetKeystate, state, NumpadAdd
if state = D
{
size += 0.1
goto startagain
}
GetKeystate, state, NumpadSub
if state = D
{
if size >= 1
{
size -= 0.1
goto startagain
}
}
WinSet, AlwaysOnTop, On, ahk_id %hWnd%
}
F6::
Exit:
ExitAppControls are F6 to exit and numpad plus and minus to make larger and smaller. As you can see it flickers and a double box appears when resizing and I can't understand why (not that I understand what the whole of that stretchblt call does
Thanks very much for making such a great script!
#11
Posted 23 April 2007 - 07:56 AM
It's because you created a new tooltip each time when resizing. You may prefer using it this way:As you can see it flickers and a double box appears when resizing
#NoEnv
#SingleInstance, Force
SetWinDelay, 10
nZ := 3 ; Zoom Factor
nR := 100 ; Rectangle of the Zoomer
CoordMode, Mouse
CoordMode, Pixel
ToolTip, %A_Space%
WinGet, hWnd, ID, ahk_class tooltips_class32
WinSet, ExStyle, +0x00000020, ahk_id %hWnd%
hDC_SC := DllCall("GetDC", "Uint", 0)
hDC_TT := DllCall("GetDC", "Uint", hWnd)
Loop
{
If GetKeyState("NumpadAdd")
nR++
If GetKeyState("NumpadSub") && nR > 100
nR--
MouseGetPos, xmouse, ymouse
DllCall("StretchBlt", "Uint", hDC_TT, "int", 0, "int", 0, "int", nR*2, "int", nR*2, "Uint", hDC_SC, "int", xmouse-nR//nZ, "int", ymouse-nR//nZ, "int", nR//nZ*2, "int", nR//nZ*2, "Uint", 0x00CC0020)
WinMove, ahk_id %hWnd%,, xmouse-nR, ymouse-nR, nR*2, nR*2
WinSet, AlwaysOnTop, On, ahk_id %hWnd%
}
F6::
Exit:
DllCall("ReleaseDC", "Uint", 0, "Uint", hDC_SC)
DllCall("ReleaseDC", "Uint", hWnd, "Uint", hDC_TT)
ExitApp
Thanks!Thanks very much for making such a great script!
#12
Posted 23 April 2007 - 08:01 AM
It'll also capture transparent windows, and mouse cursor too.
/*
Esc key: Exit the application.
*/
#NoEnv
#SingleInstance, Force
SetWinDelay, 10
CoordMode, Mouse
nZ := 3 ; Zoom Factor
nW := A_ScreenWidth // 2 //2//nZ ; Width of (small) Target Rectangle
nH := A_ScreenHeight// 6 //2//nZ ; Height of (small) Target Rectangle
ToolTip, %A_Space%
WinClose, ahk_class SysShadow
WinGet, hWnd, ID, ahk_class tooltips_class32
hDC_SC := DllCall("GetDC", "Uint", 0)
hDC_LW := DllCall("GetDC", "Uint", hWnd)
hDC_TT := DllCall("GetDC", "Uint", hWnd)
DllCall("SetStretchBltMode", "Uint", hDC_TT, "int", 4)
Loop
{
MouseGetPos, xmouse, ymouse
DllCall("BitBlt", "Uint", hDC_LW, "int", 0, "int", 0, "int", 2*nW, "int", 2*nH, "Uint", hDC_SC, "int", xmouse-nW, "int", ymouse-nH, "Uint", 0x40CC0020)
; CaptureCursor(hDC_LW, nW, nH) ; Capture magnified mouse cursor too.
DllCall("StretchBlt", "Uint", hDC_TT, "int", 0, "int", 0, "int", 2*nW*nZ, "int", 2*nH*nZ, "Uint", hDC_LW, "int", 0, "int", 0, "int", 2*nW, "int", 2*nH, "Uint", 0x00CC0020)
CaptureCursor(hDC_TT, nW*nZ, nH*nZ) ; Capture un-magnified mouse cursor too.
WinMove, ahk_id %hWnd%,, xmouse-nW*nZ-1, ymouse+nH, 2*nW*nZ+2, 2*nH*nZ+2
If GetKeyState("Esc")
Break
}
DllCall("ReleaseDC", "Uint", 0, "Uint", hDC_SC)
DllCall("ReleaseDC", "Uint", hWnd, "Uint", hDC_LW)
DllCall("ReleaseDC", "Uint", hWnd, "Uint", hDC_TT)
CaptureCursor(hDC, xCenter, yCenter)
{
VarSetCapacity(mi, 20, 0)
mi := Chr(20)
DllCall("GetCursorInfo", "Uint", &mi)
ptr := &mi + 4
bShow := *ptr++ | *ptr++ << 8 | *ptr++ << 16 | *ptr++ << 24
hCursor := *ptr++ | *ptr++ << 8 | *ptr++ << 16 | *ptr++ << 24
DllCall("GetIconInfo", "Uint", hCursor, "Uint", &mi)
ptr := &mi + 4
xHotspot := *ptr++ | *ptr++ << 8 | *ptr++ << 16 | *ptr++ << 24
yHotspot := *ptr++ | *ptr++ << 8 | *ptr++ << 16 | *ptr++ << 24
hBMMask := *ptr++ | *ptr++ << 8 | *ptr++ << 16 | *ptr++ << 24
hBMColor := *ptr++ | *ptr++ << 8 | *ptr++ << 16 | *ptr++ << 24
If hBMMask
DllCall("DeleteObject", "Uint", hBMMask)
If hBMColor
DllCall("DeleteObject", "Uint", hBMColor)
If bShow
DllCall("DrawIcon", "Uint", hDC, "int", xCenter - xHotspot, "int", yCenter - yHotspot, "Uint", hCursor)
}
#13
Posted 23 April 2007 - 08:21 AM
I guess you closed them using other means than the defined hotkeys.When I got the color values and close the bubble, the script does not terminate, but cannot be activated again. I have to manually close the script, and restart when I need it again, otherwise there will be many dormant instances open (making the tray full of AHK icons). I think it is quite common to read the color values of several pixels, which could be much easier with a resident script, (re)activated with a hotkey. The question was, is it safe not to exit the script, but re-open the zoomer window?
I think it's easy to correct using SetTimer which will check the visibility/existence of the zoomer window.
It's too bad to not be able to utilize the x button in the balloon tip.
It seems due to the persistent nature of the script when there exists non-trivial tooltip window created by AHK itself.
Sure. BTW, how do you prefer it to behave? Automatic copy to the clipboard when picking the color?Would you consider adding it to the script?
Or, doing it when necessary via hotkey?
I found it rather non-trivial to use (the same) hotkey when multiple balloon tips are around.
And, in which format? RBG, BGR, or 0xBBGGRR (#...)...
#14
Posted 23 April 2007 - 03:13 PM
I'm afraid you've gone too far above my understanding of ahk and the windows calls you use. I cant edit it! :0
I dont wanna use up your time with doing this, but my ambition is to make lots of things for a remote that will make it easier to use with windows. My project is with the wiimote and can be viewed here:
<!-- m -->http://www.wiili.org... ... t1528.html<!-- m -->
For my next release I had the idea of using the IR of the wiimote to allow you to point at the screen and at any time be able to zoom. I dont want the actual zoom to increase on a button press as I think 3 or 4 zoom is sufficient, but wanted the bounding area of the zoom to increase and decrease, and look like this pic from paper mario
<!-- m -->http://uk.media.wii.... ... 80431.html<!-- m -->
I managed to form an elipse over the magnifier you created, but the edges were jagged and was wondering if theres any way to antialiase them??
Also, is it possible to create a similar effect to paper mario on the rest of the screen where everything is slightly blurred and greyed out, and the mouse cursor needs to be within the zoom box.
Dont worry if thats a tall order, as I know it is!!! That last magnifier you just posted is so good! any more help would make my day
#15
Posted 23 April 2007 - 03:19 PM
- I start the script when needed normally, as other programs
- It stays resident, but does nothing
- Upon a hotkey press (Alt-Win-Z), the zoomer window pops up and follows the mouse
- At a mouse click the balloon tip comes up with the color value
- Esc closes it, until the next Alt-Win-Z
- Ctrl-C copies the color value to the clipboard, otherwise the same as Esc.
- A configuration window could be opened with Ctrl-Win-Alt-Z (which also closes the zoomer). Here you could set the color format, saved in an ini file, or in the registry.
The hotkeys are just examples, choose what you see fit.
I did not see a need for multiple instances of the script, except for comparing colors. If there is always at most one is open, a hotkey could copy the color value to the clipboard, without conflicts. For comparing colors, one could save the last 2 or 3 picked colors, and rotate the values in the current balloon tip upon a hotkey press (Alt-Win-Z).
These are just ideas. They may not work well in practice, but the script is very useful, so making it easier to use looks important.




