1 (изменено: Alectric, 2015-02-08 10:13:02)

Тема: AHK: Экранная лупа [переработанная]

Переписал старый скрипт экранной лупы, если пригодится кому.

#NoEnv
SetBatchLines,-1
OnExit,Exit
CoordMode,Mouse,Screen
CoordMode,tooltip,Screen
SetKeyDelay,0
SetWinDelay,20

W:=a_screenwidth//3
H:=a_screenwidth//6
X:=a_screenwidth//2-W/2

Settingspath=SOFTWARE\AHK_Zoom
SettingsDefault=
(
WinX=%X%
WinY=0
WinW=%W%
WinH=%H%
MouseFob=0
SlowDown=0
Hideframe=0
HideWin=0
HideCursor=0
InvertColors=0
yourX=
yourY=
zoom=4
)
gosub,LoadSettings

if (WinX+WinW-30<0)
  WinX:=X
if (WinX>a_screenwidth-30)
  WinX:=X
if (WinY+WinH-30<0)
  WinY=0
if (WinY>a_screenheight-30)
  WinY=0

Menu,Tray,Icon,%A_WinDir%\system32\Shell32.dll,23
Menu,Tray,NoStandard
Menu,Tray,add,Скрыть окно               Правый Ctrl,HideWin
Menu,Tray,add,Убегать от мышки,MouseFob
Menu,Tray,add,Замедлять мышь при увеличении,SlowDown
Menu,Tray,add,Скрыть рамку,Hideframe
Menu,Tray,add,Скрыть курсор,HideCursor
Menu,Tray,add,Инвертировать цвета,InvertColors
Menu,Tray,add,Задать постоянные координаты,YourCoords
Menu,Tray,add,Задать окно на которое смотреть,YourWind
Menu,Tray,add,Выход,exit
Menu,Tray,default,Выход

SysGet,CAPTION,4
SysGet,XBORDER,5
SysGet,YBORDER,6
SysGet,XEDGE,45
SysGet,YEDGE,46
borderX:=XBORDER+XEDGE
borderY:=YBORDER+YEDGE+CAPTION
DllCall("SystemParametersInfo", UInt, 0x0070, UInt, 0, UIntP, SaveMouseSpeed, UInt, 0)

Gui,2:+LastFound +Border -Caption +ToolWindow +AlwaysOnTop +E0x08000020
hGui2:=WinExist()
Gui,2:Color,000000
Gui,2:Show,W15 H15 NoActivate,Cursor
WinSet,Region,0-0 5-0 0-5,ahk_id %hGui2%
WinSet,Transparent,128,Ahk_id %hGui2%
Gui,2:hide

Gui,3:+LastFound -Caption +Border +ToolWindow +AlwaysOnTop +E0x08000020
hGui3:=WinExist()
Gui,3:Color,EEEEEE
Gui,3:Show,x0 y0 w1 h1 NoActivate,Рамка
WinSet,TransColor,EEEEEE,ahk_id %hGui3%
Gui,3:hide

Gui,4:+LastFound -Caption +Border +ToolWindow +AlwaysOnTop +E0x08000020
hGui4:=WinExist()
Gui,4:add,text,xm+20 y+10,X:
Gui,4:add,edit,x+5 yp-3 w50 vyourX,%yourX%
Gui,4:add,text,xm+20 y+10,Y:
Gui,4:add,edit,x+5 yp-3 w50 vyourY,%yourY%
Gui,4:add,text,xm+10 w120 ,Оставте пустыми чтобы выставить в центр экрана.
Gui,4:add,button,xm+10 w60 gYour,Сохранить
Gui,4:add,button,x+10 w60 gYourOff,Отменить
GuiControl,+default,Сохранить

Gui +LastFound +AlwaysOnTop -Caption +Border +Resize +ToolWindow
hGui:=WinExist()
Gui,Show,x%WinX% y%WinY% w%WinW% h%WinH%,Увеличительное окно.

hFrame:=DllCall("GetDC",Ptr,"")
hdc_Frame:=DllCall("GetDC",Ptr,hGui,Ptr)

;me:=DllCall("GetDC",Ptr,hGui,Char)
;msgbox,% hFrame "`n" me
;exitapp

if MouseFob
  Menu,Tray,Check,Убегать от мышки
if SlowDown
  Menu,Tray,Check,Замедлять мышь при увеличении
if Hideframe
  Menu,Tray,Check,Скрыть рамку
if HideCursor
  Menu,Tray,Check,Скрыть курсор
if InvertColors
{
  Colors=0x330008 ;- инверсия.
  Menu,Tray,Check,Инвертировать цвета
}
else
  Colors=0xCC0020 ; нормальные цвета.
if HideWin
{
  Menu,Tray,Check,Скрыть окно               Правый Ctrl
  Gui,hide
}
if (yourX and yourY)
  Menu,Tray,Check,Задать постоянные координаты

getwin=1
loop
{
  sleep,10

  if GetKeyState("rctrl","P")
  {
    keywait,rctrl,L T0.4
    if !errorlevel
      gosub,HideWin
    keywait,rctrl,L
  }

  if !HideWin
  {
    oldmx:=mx
    oldmy:=my
    MouseGetPos,mx,my,mwin,mctrl
    if (yourX and yourY)
      mx:=yourX, my:=yourY

    if (getwin or mwin=hGui)
    {
      getwin=
      WinGetPos,winX,winY,WinW,WinH,ahk_id %hGui%
      GetClientSize(hGui,FrameRx,FrameRy)
    }

    if YourWind
    {
      WinGetPos,YourWindX,YourWindY,YourWindW,YourWindH,ahk_id %hYourWind%
      FrameX:=YourWindX<0 ? 0 :  YourWindX
      FrameY:=YourWindY<0 ? 0 : YourWindY
      FrameW:=YourWindX<0 ? YourWindX+YourWindW : YourWindX+YourWindW>a_screenwidth ? a_screenwidth-YourWindX : YourWindW
      FrameH:=YourWindY<0 ? YourWindY+YourWindH : YourWindY+YourWindH>a_screenheight ? a_screenheight-YourWindY : YourWindH
    }
    else
    {
      FrameW:=(FrameRx-1)//zoom
      FrameH:=(FrameRy-1)//zoom
      FrameX:=mx-WinW//zoom//2
      FrameY:=my-WinH//zoom//2
      FrameX:=FrameX<0 ? 0 : FrameX>a_screenwidth-FrameW-2 ? a_screenwidth-FrameW-2 : FrameX
      FrameY:=FrameY<0 ? 0 : FrameY>a_screenheight-FrameH-2 ? a_screenheight-FrameH-2 : FrameY
    }
    if !HideCursor
      Gui,2:Show,% "x" mx " y" my "NoActivate",Cursor
    if !Hideframe
      Gui,3:Show,x%FrameX% y%FrameY% w%FrameW% h%FrameH% NoActivate,Рамка

    if (mwin!=hGui)
    {
      DllCall("gdi32.dll\StretchBlt",Ptr,hdc_Frame
                                    ,Int,0
                                    ,Int,0
                                    ,Int,FrameRx
                                    ,Int,FrameRy
                                    ,Ptr,hFrame
                                    ,Int,FrameX
                                    ,Int,FrameY
                                    ,Int,FrameW+2
                                    ,Int,FrameH+2
                                    ,UInt,Colors)

      if !showtooltip
      {
        showtooltip=1
        tooltip,
      }
    }
    else if showtooltip
    {
      tooltip,Увеличение - %zoom%00 `%`nВ кадре %FrameW% x %FrameH% пикселей`nКлик средней кнопкой по окну - скрыть\показать курсор.`nCtrl+Колесо мыши - масштаб.`nПравая кнопка по окну - Меню,%winx%,% winy+WinH
      showtooltip=
    }

    if (mwin=hGui)
    {
      MouseGetPos,oldmmx,oldmmy
      while GetKeyState("lbutton","P")
      {
        getwin=1
        sleep,10
        tooltip
        MouseGetPos,mmx,mmy
        WinGetPos,wx,wy,ww,wh,ahk_id %hGui%
        wx:=wx+mmx-oldmmx
        wy:=wy+mmy-oldmmy
        WinMove,ahk_id %hGui%,,%wx%,%wy%
        oldmmx:=mmx
        oldmmy:=mmy
      }
    }

    if (MouseFob and mwin=hGui)
    {
      getwin=1
      wx:=mx<a_screenwidth/2 ? a_screenwidth-WinW-30 : 30
      wy:=my<a_screenheight/2 ? a_screenheight-WinH-60 : 30
      WinMove,ahk_id %hGui%,,%wx%,%wy%
      tooltip
    }
  }
  else
    sleep,100
}
Return

#if !HideWin
^WheelUp::
^WheelDoWn::
If (A_ThisHotKey="^WheelUp")
  zoom+=1
If (A_ThisHotKey="^WheelDoWn")
  zoom-=1
zoom:=zoom<1 ? 1 : zoom>35 ? 35 : zoom
if !HideCursor
  WinSet,Region,% "0-0 " (35-zoom)//3 "-0 0-" (35-zoom)//3 ,ahk_id %hGui2%
if SlowDown
  DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, SaveMouseSpeed-zoom+1, UInt, 0)
Tooltip,% zoom
settimer,removetooltip,-1000
Return
#if

MouseFob:
MouseFob:=!MouseFob
if MouseFob
  Menu,Tray,Check,Убегать от мышки
else
  Menu,Tray,unCheck,Убегать от мышки
return

InvertColors:
if InvertColors:=!InvertColors
{
  Menu,Tray,Check,Инвертировать цвета
  Colors=0x330008 ;- инверсия.
}
else
{
  Menu,Tray,unCheck,Инвертировать цвета
  Colors=0xCC0020 ;- нормально.
}
return

Hideframe:
if Hideframe:=!Hideframe
{
  Menu,Tray,Check,Скрыть рамку
  Gui,3:hide
}
else
  Menu,Tray,unCheck,Скрыть рамку
return

SlowDown:
if SlowDown:=!SlowDown
{
  DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, SaveMouseSpeed, UInt, 0)
  DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, SaveMouseSpeed-zoom+1, UInt, 0)
  Menu,Tray,Check,Замедлять мышь при увеличении
}
else
{
  DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, SaveMouseSpeed, UInt, 0)
  Menu,Tray,unCheck,Замедлять мышь при увеличении
}
return

HideWin:
if HideWin:=!HideWin
{
  Menu,Tray,Check,Скрыть окно               Правый Ctrl
  tooltip
  Gui,Hide
  Gui,2:Hide
  Gui,3:Hide
}
else
{
  Menu,Tray,unCheck,Скрыть окно               Правый Ctrl
  Gui,Show
}
return

YourWind:
YourWind:=!YourWind
if YourWind
{
  Menu,Tray,Check,Задать окно на которое смотреть
  while !GetKeyState("Rbutton","P")
  {
    sleep,10
    mousegetpos,,,hYourWind
    tooltip,Смотреть на окно с хендлом %hYourWind%`nПравая кнопка - подтвердить.
  }
}
else
  Menu,Tray,unCheck,Задать окно на которое смотреть
return

YourCoords:
gui,4:show
YourWind=0
Menu,Tray,unCheck,Задать окно на которое смотреть
return
Your:
gui,4:submit
Menu,Tray,Check,Задать постоянные координаты
if !yourX
  yourX:=a_screenwidth//2
if !yourY
  yourY:=a_screenheight//2
return
YourOff:
gui,4:submit
Menu,Tray,unCheck,Задать постоянные координаты
yourX:=yourY:=
return

RemoveToolTip:
  tooltip
return

#if (mwin=hGui)
Rbutton up::
Menu,Tray,show
return

Mbutton up::
#if

HideCursor:
HideCursor:=!HideCursor
if HideCursor
{
  Menu,Tray,Check,Скрыть курсор
  Gui,2:hide
}
else
{
  Menu,Tray,unCheck,Скрыть курсор
  Gui,2:show
  WinSet,Region,% "0-0 " (35-zoom)//3 "-0 0-" (35-zoom)//3 ,ahk_id %hGui2%
}
return

Exit:
gosub,SaveSettings
DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, SaveMouseSpeed, UInt, 0)
DllCall("gdi32.dll\DeleteDC",Ptr,hdc_Frame)
DllCall("gdi32.dll\DeleteDC",Ptr,hFrame)
ExitApp

SaveSettings:
if Settingspath=
  Settingspath=SOFTWARE\Unknown_AHK_Script
if SettingsDefault=
  return
loop,parse,SettingsDefault,`n
{
  Loop,parse,a_loopfield,=
  {
    if a_index=1
    {
      Setting:=a_loopfield
      Break
    }
  }
  RegWrite,REG_SZ,HKCU,%Settingspath%,%Setting%,% %Setting%
}
LoadSettings:
if Settingspath=
  Settingspath=SOFTWARE\Unknown_AHK_Script
if SettingsDefault=
  return
loop,parse,SettingsDefault,`n
{
  Loop,parse,a_loopfield,=
  {
    if a_index=1
      Setting:=a_loopfield
    else if a_index=2
      Default:=a_loopfield
    else
      Default.="=" a_loopfield
  }
  RegRead,%Setting%,HKCU,%Settingspath%,%Setting%
  RegRead,Rtmp,HKCU,%Settingspath%,%Setting%
  if Rtmp=
  {
    RegWrite,REG_SZ,HKCU,%Settingspath%,%Setting%,%Default%
    RegRead,%Setting%,HKCU,%Settingspath%,%Setting%
  }
}
Return

GetClientSize(hwnd, ByRef w, ByRef h)
{
    VarSetCapacity(rc, 16)
    DllCall("GetClientRect",Ptr,hwnd,uint,&rc)
    w := NumGet(rc, 8, "int")
    h := NumGet(rc, 12, "int")
}
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

2

Re: AHK: Экранная лупа [переработанная]

Работает, но есть недостатки. Тип данных хэндлов — Ptr, а не UInt, работает только потому, что размер хэндла не превышает UInt, но гарантии этого нет. Окно дёргается при перемещении. Странный пункт меню — "Убрать увеличилку". (Выход?)

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: Alectric, 2015-02-06 22:20:05)

Re: AHK: Экранная лупа [переработанная]

Особо не разбираюсь в хэндлах... поможете? (просто взял что нашел)
Дерготню пока не получается убрать (не пойму почему дергается), думаю над этим.
Да выход, изменю на привычное все таки.

Кстати размерности совпадают? А то сомневаюсь в правильности формул, там где borderX.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

4 (изменено: serzh82saratov, 2015-02-06 22:25:31)

Re: AHK: Экранная лупа [переработанная]

Мне понравилось. Считаю и соразмерное замедление мыши очень удобным, но только по модификатору.

П.С. Код не ковырял.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5 (изменено: Alectric, 2015-02-06 22:32:13)

Re: AHK: Экранная лупа [переработанная]

Исправил дергатню, дошло до меня наконец. (SetWinDelay)

Могу добавить изменение настройки - SpeedZoom=1  ; уменьшать скорость мыши при увеличении.
Только на какую клавишу?

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

6

Re: AHK: Экранная лупа [переработанная]

Alectric пишет:

Особо не разбираюсь в хэндлах... поможете? (просто взял что нашел)

Нашли под AHK-basic. Может, просто имеет смысл разобраться? Например, ф-ция GetDC(). Смотрим тип данных параметра — HWND. Заглядываем сюда: Ptr. Не помешает ещё ознакомиться с Windows Data Types.
Кроме того, нужно посмотреть, какой тип данных функция возвращает.

Return value
If the function succeeds, the return value is a handle to the DC for the specified window's client area.
If the function fails, the return value is NULL.

Соответственно handle, который всегlа Ptr. Если DllCall возвращает что-либо, кроме Int и Bool, это должно быть указано явно. Верный вариант:

hdc_Frame:=DllCall("GetDC", Ptr ,gui, Ptr)

И так по всем случаям использования DllCall.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7 (изменено: Alectric, 2015-02-06 23:42:58)

Re: AHK: Экранная лупа [переработанная]

И сразу вопрос:

hdc_Frame:=DllCall("GetDC", Ptr ,gui, Ptr)

Почему тут два Ptr, и какой к чему относится?

Например тут в конце не указан тип данных:


      DllCall("gdi32.dll\StretchBlt",Ptr,hdc_Frame
                                    ,Int,0
                                    ,Int,0
                                    ,Int,FrameRx
                                    ,Int,FrameRy
                                    ,Ptr,Frame
                                    ,UInt,FrameX
                                    ,UInt,FrameY
                                    ,Int,FrameW+2
                                    ,Int,FrameH+2
                                    ,UInt,0xCC0020)

Или тут:

  Ret := DllCall("ReadProcessMemory", UInt, hProcess
                                    , UInt, ReadAddress
                                    , UInt, &Buf
                                    , UInt, ReadSize
                                    , UInt, 0)
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

8

Re: AHK: Экранная лупа [переработанная]

Alectric пишет:

Почему тут два Ptr, и какой к чему относится?

Первый относится к параметру gui, который хендл окна (лучше обозначать с первым сиволом h — hGui), последний относится к тому, что ф-ция возвращает.

Например тут в конце не указан тип данных

Смотрим StretchBlt, ReadProcessMemory. В обоих случаях

Return value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is 0 (zero).

В хелпе:

ReturnType: If the function returns a 32-bit signed integer (Int), BOOL, or nothing at all, ReturnType may be omitted.

В данном случае в обоих случаях BOOL, значит можно ничего не указывать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9 (изменено: Alectric, 2015-02-07 09:36:51)

Re: AHK: Экранная лупа [переработанная]

А откуда брать код для последнего параметра в StretchBlt function? По ссылке указаны только названия вроде "BLACKNESS", при этом у меня в коде прописано значение 0xCC0020 (цвет я думаю).
И вообще где брать подобные параметры если они указанны просто текстом? (или мне нужно подучить английский?..)

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

10

Re: AHK: Экранная лупа [переработанная]

Это константы. В описании функции смотрим пункт Requirements:

Minimum supported client
Windows 2000 Professional [desktop apps only]

Minimum supported server
Windows 2000 Server [desktop apps only]

Header   Wingdi.h (include Windows.h)

Library   Gdi32.lib

DLL   Gdi32.dll

Подобные константы обычно определены в файлах Header, в данном случае это Wingdi.h. Если его нет на компьютере, ищем поиском в гугле.
Wingdi.h
Соответственно, 0xCC0020 — это SRCCOPY.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Экранная лупа [переработанная]

Еще константы можно найти, например, здесь поиском. А у меня они есть просто списком, и есть скрипт — вводишь константу, получаешь значение.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: Экранная лупа [переработанная]

Скрипт со списком есть в коллекции?

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

13

Re: AHK: Экранная лупа [переработанная]

Я подобный скрипт брал на англофоруме, автор SKAN. Ссылка, к сожалению утеряна, но вот сам скрипт: https://yadi.sk/d/ope20jSAeX2h2. Запустить lookup.ahk, нажать Ctrl-AppsKey.

14

Re: AHK: Экранная лупа [переработанная]

Доброго времени суток. А можно сделать так что бы скрипт показывал не от курсора а от центра экрана. Буду очень признателен.

OS: Win11x64, AutoHotkey v1.1.25.01 (Unicode 64-bit).

15 (изменено: Alectric, 2015-02-08 09:18:48)

Re: AHK: Экранная лупа [переработанная]

Готово. Опробуй.
Пункт меню: "Задать постоянные координаты".

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

16 (изменено: Ядрён, 2015-02-10 03:01:47)

Re: AHK: Экранная лупа [переработанная]

Alectric пишет:

Готово. Опробуй.
Пункт меню: "Задать постоянные координаты".

Что то не то, лупа то смотрит в центр экрана, только вот показывает она аж 9 окон в окне.Я хотел так что бы можно было выставить её по центру экрана и к примеру колёсиком мыши крутить а под ней  пролистывалась страничка хрома в увеличенном виде.

OS: Win11x64, AutoHotkey v1.1.25.01 (Unicode 64-bit).

17

Re: AHK: Экранная лупа [переработанная]

Это нужно как-то делать само окно лупы прозрачным для  StretchBlt... Сомневаюсь что это возможно.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

18

Re: AHK: Экранная лупа [переработанная]

Не показывает второй монитор. Стандартная лупа показывает.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

19

Re: AHK: Экранная лупа [переработанная]

Скорей всего проблема с координатами. У меня нет возможности поработать с 2-мя мониторами.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

20

Re: AHK: Экранная лупа [переработанная]

Отрицательные координаты, видимо, надо учесть.

21

Re: AHK: Экранная лупа [переработанная]

У меня нет возможности поработать с 2-мя мониторами.

Если видеокарточка поддерживает 2 монитора, то можно проверить их работоспособность и на одном мониторе.

22 (изменено: Alectric, 2015-10-05 11:10:28)

Re: AHK: Экранная лупа [переработанная]

Если честно - просто нет желания разбираться. (вдохновение кончилось и "чет я приуныл")

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

23

Re: AHK: Экранная лупа [переработанная]

YMP пишет:

Отрицательные координаты, видимо, надо учесть.

Пока нет, когда второй в положительных координатах, тоже самое.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui