
Color Zoomer/Picker & Screen Magnifier

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.

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).

#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: ExitApp
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?
Any help would be much appreciated

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?

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%

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.

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.

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.

#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: ExitApp
Controls 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!

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!

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) }

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 (#...)...

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

- 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.
