201 (изменено: serzh82saratov, 2019-01-14 22:37:48)

Re: AHK: Экранная лупа

Добавил массив для фильтра окон, сейчас в нём Notepad++ и окно копирующее лупу.
При выключении аеро фильтр окон не работает.
Из непонятного:
Без применения MagSetWindowTransform с выключенным аеро не работает.
При выключении \ включении аеро часто нарушается работоспособность лупы, при этом повышается нагрузка на процессор.


#NoEnv
#Persistent
#SingleInstance Force 
SetBatchLines -1
OnExit, Uninitialize 
CoordMode, Mouse, Screen
Gui, +HWNDhGui
Global hPic

rWidth :=  320
rHeight := 240

HWNDarr := [WinExist("ahk_class Notepad++"), hGui]

Ptr := A_PtrSize ? "UPtr" : "UInt"
if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
	DllCall("LoadLibrary", "str", "gdiplus")
VarSetCapacity(GdiplusStartupInput, A_PtrSize = 8 ? 24 : 16, 0), GdiplusStartupInput := Chr(1)
DllCall("gdiplus\GdiplusStartup", A_PtrSize = 8 ? "UPtr*" : "UInt*", pToken, Ptr, &GdiplusStartupInput, Ptr, 0)

Gui, -Caption +AlwaysOnTop +E0x02000000 +E0x00080000  ;  WS_EX_COMPOSITED := E0x02000000  WS_EX_LAYERED := E0x00080000
Gui, Margin, 0,0  
Gui, Add, text, w%rWidth% h%rHeight% 0xE hwndhPic ; SS_BITMAP = 0xE
Gui, Show, x100 NA, MagnifierCloneWindowAHK

Gui, Magnifier: +AlwaysOnTop -Caption +ToolWindow +HWNDhMagnifier
Gui, Magnifier: Show, w%rWidth% h%rHeight% NA Hide, MagnifierWindowAHK
	
DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")

WS_CHILD := 0x40000000, WS_VISIBLE := 0x10000000, MS_SHOWMAGNIFIEDCURSOR := 0x1 
	
hChildMagnifier := DllCall("CreateWindowEx"
	, "UInt", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "UInt", MS_SHOWMAGNIFIEDCURSOR | WS_CHILD | WS_VISIBLE
	, "Int", 0
	, "Int", 0
	, "Int", rWidth
	, "Int", rHeight
	, Ptr, hMagnifier
	, "UInt", 0
	, Ptr, DllCall("GetWindowLong", Ptr, hMagnifier, "UInt", GWL_HINSTANCE := -6)
	, "UInt", 0)

VarSetCapacity(HWNDstruct, HWNDarr.Count() * A_PtrSize, 0)
Loop % HWNDarr.Count()
	NumPut(HWNDarr[A_Index], HWNDstruct, (A_Index - 1) * A_PtrSize, "UPtr")
DllCall("magnification.dll\MagSetWindowFilterList", Ptr, hChildMagnifier, "Int", MW_FILTERMODE_EXCLUDE := 0, "Int", HWNDarr.Count(), Ptr, &HWNDstruct)

Matrix := "1|0|0|"
        . "0|1|0|"
        . "0|0|1"  
VarSetCapacity(MAGTRANSFORM, 36, 0)
Loop, Parse, Matrix, |  
	NumPut(A_LoopField, MAGTRANSFORM, (A_Index - 1) * 4, "Float")
DllCall("magnification.dll\MagSetWindowTransform", Ptr, hChildMagnifier, Ptr, &MAGTRANSFORM)

DllCall("magnification.dll\MagSetImageScalingCallback", Ptr, hChildMagnifier, "Int", RegisterCallback("MagImageScalingCallback", "Fast"))

VarSetCapacity(RECT, 16, 0)

; 1::
Loop
{
	MouseGetPos, MXS, MYS
	NumPut(MXS - rWidth/2, RECT, 0, "Int")
	NumPut(MYS - rHeight/2, RECT, 4, "Int")
	NumPut(rWidth, RECT, 8, "Int")
	NumPut(rHeight, RECT, 12, "Int")
	DllCall("magnification.dll\MagSetWindowSource", Ptr, hChildMagnifier, Ptr, &RECT)
}
Return 

MagImageScalingCallback(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) {
	Static BI_RGB := 0, CBM_INIT := 6, DIB_RGB_COLORS := 0
		, Ptr := A_PtrSize = 8 ? "UPtr" : "UInt"
		, STM_SETIMAGE := 0x172, IMAGE_BITMAP := 0x0
		, _ := VarSetCapacity(BITMAPV5HEADER, 124, 0)
		, __ := VarSetCapacity(BITMAPINFO, 44, 0)
	
	bV5Width := NumGet(srcheader + 0, 0, "UInt")
	bV5Height := NumGet(srcheader + 0, 4, "UInt") 
	
	NumPut(124, BITMAPV5HEADER, 0, "UInt")  		;	DWORD		bV5Size;
	NumPut(bV5Width, BITMAPV5HEADER, 4, "UInt")		;	LONG		bV5Width;
	NumPut(bV5Height, BITMAPV5HEADER, 8, "UInt")	;	LONG		bV5Height;
	NumPut(1, BITMAPV5HEADER, 12, "Short")			;	WORD		bV5Planes;
	NumPut(32, BITMAPV5HEADER, 14, "Short")			;	WORD		bV5BitCount;
	NumPut(BI_RGB, BITMAPV5HEADER, 16, "UInt")		;	DWORD		bV5Compression; 
	
	NumPut(44, BITMAPINFO, 0, "UInt")  				;	DWORD biSize;
	NumPut(bV5Width, BITMAPINFO, 4, "UInt")  		;	LONG  biWidth;
	NumPut(bV5Height, BITMAPINFO, 8, "UInt")  		;	LONG  biHeight;
	NumPut(1, BITMAPINFO, 12, "Short")  			;	WORD  biPlanes;
	NumPut(32, BITMAPINFO, 14, "Short")  			;	WORD  biBitCount;
	NumPut(BI_RGB, BITMAPINFO, 16, "UInt")  		;	DWORD biCompression;
 
	hDC := DllCall("GetDC", Ptr, hwnd)
	
	hBMP := DllCall("CreateDIBitmap"
		, Ptr, hDC
		, Ptr, &BITMAPV5HEADER
		, "UInt", CBM_INIT
		, Ptr,  srcdata
		, Ptr, &BITMAPINFO
		, "UInt", DIB_RGB_COLORS) 
	
	DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hBMP, Ptr, 0, A_PtrSize = 8 ? "UPtr*" : "UInt*", pBitmap)
	DllCall("gdiplus\GdipImageRotateFlip", Ptr, pBitmap, "Int", 6)   ;	Rotate180FlipX
	DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", Ptr, pBitmap, A_PtrSize = 8 ? "UPtr*" : "UInt*", hBitmap, "Int", 0xffffffff)
	
	SendMessage, STM_SETIMAGE, IMAGE_BITMAP, hBitmap,, ahk_id %hPic% 
	
	DllCall("DeleteObject", Ptr, ErrorLevel)
	DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
	DllCall("DeleteDC", Ptr, hDC)
	DllCall("DeleteObject", Ptr, hBMP)
	DllCall("DeleteObject", Ptr, hBitmap)
	Return 1
}

Escape:: 
Uninitialize: 	
	DllCall("magnification.dll\MagUninitialize")
	DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
	if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", Ptr)
		DllCall("FreeLibrary", Ptr, hModule)
	ExitApp
	
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

202

Re: AHK: Экранная лупа

if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
	DllCall("LoadLibrary", "str", "gdiplus")

Ещё такие вопросы, зачем в данном случае LoadLibrary, если функции и так вызываются.

	NumPut(124, BITMAPV5HEADER, 0, "UInt")  		;	DWORD		bV5Size;
	NumPut(bV5Width, BITMAPV5HEADER, 4, "UInt")		;	LONG		bV5Width;
	NumPut(bV5Height, BITMAPV5HEADER, 8, "UInt")	;	LONG		bV5Height;
	NumPut(1, BITMAPV5HEADER, 12, "Short")			;	WORD		bV5Planes;
	NumPut(32, BITMAPV5HEADER, 14, "Short")			;	WORD		bV5BitCount;
	NumPut(BI_RGB, BITMAPV5HEADER, 16, "UInt")		;	DWORD		bV5Compression; 
	
	NumPut(44, BITMAPINFO, 0, "UInt")  				;	DWORD biSize;
	NumPut(bV5Width, BITMAPINFO, 4, "UInt")  		;	LONG  biWidth;
	NumPut(bV5Height, BITMAPINFO, 8, "UInt")  		;	LONG  biHeight;
	NumPut(1, BITMAPINFO, 12, "Short")  			;	WORD  biPlanes;
	NumPut(32, BITMAPINFO, 14, "Short")  			;	WORD  biBitCount;
	NumPut(BI_RGB, BITMAPINFO, 16, "UInt")  		;	DWORD biCompression;

Возможно ли часть структуры копировать в другую, например в BITMAPINFO сразу записать BITMAPV5HEADER с 4 по 20 байт, а не записывать все части по одному.

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

203

Re: AHK: Экранная лупа

1) LoadLibrary используется для повышения производительности.
2) Можно через memcpy.

204

Re: AHK: Экранная лупа

А в 200 не скажешь почему DeleteObject  не нужен?

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

205

Re: AHK: Экранная лупа

Там одни и те же картинки меняются в цикле.
А у тебя каждый раз новые.

206

Re: AHK: Экранная лупа

Ну да, очевидно.

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

207

Re: AHK: Экранная лупа

serzh82saratov пишет:

При выключении \ включении аеро часто нарушается работоспособность лупы, при этом повышается нагрузка на процессор.

Тут видимо только ставить сообщение на DwmEnableComposition и перезагружать magnification.dll.

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

208

Re: AHK: Экранная лупа

А есть функция с указателем сдвига? Надо вырезать начиная с 4 следующие 20 байт, и вставить их начиная с 4.


VarSetCapacity(From, 24, 0)
VarSetCapacity(To, 24, 0)

NumPut(1, From, 0, "UInt")
NumPut(11, From, 16, "UInt")

NumPut(2, To, 0, "UInt")
NumPut(22, To, 16, "UInt")

MsgBox % NumGet(To, 0, "UInt") "`n" NumGet(To, 16, "UInt")

DllCall("msvcrt\memcpy"
       , "Ptr", &To
       , "Ptr", &From
       , "Uint", 24
       , "Cdecl")
	   
MsgBox % NumGet(To, 0, "UInt") "`n" NumGet(To, 16, "UInt")
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

209

Re: AHK: Экранная лупа

Сдвиг прибавляется к адресу.

&To+4

210

Re: AHK: Экранная лупа

serzh82saratov пишет:

Тут видимо только ставить сообщение на DwmEnableComposition и перезагружать magnification.dll.

Встроенная виндовая Magnify.exe при включении аеро меняет окно.

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

211

Re: AHK: Экранная лупа

serzh82saratov пишет:

Тут видимо только ставить сообщение на DwmEnableComposition и перезагружать magnification.dll.

Не удалось это сделать, так как при включении композции, процесс зависает.

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

212

Re: AHK: Экранная лупа

А думаешь кто-то будет постоянно включать/отключать композицию?

213

Re: AHK: Экранная лупа

И у меня код из 201 поста нормально работает при включении/выключении композиции.

214

Re: AHK: Экранная лупа

У меня иногда тоже работает.
А на счёт кто то будет переключать,  так она может и сама отключатся от плохой производительности, и снова включится.

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

215

Re: AHK: Экранная лупа

С таким не сталкивался.

216

Re: AHK: Экранная лупа

Я такое не только у себя наблюдал.

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

217

Re: AHK: Экранная лупа

Чаще даже не спрашивает, а выводит сообщение что уже отключено.

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

218 (изменено: Alectric, 2019-07-29 20:49:45)

Re: AHK: Экранная лупа

"Сляпал" себе лупу для Win 10 (на x86 не проверял), теперь понадобилось запустить её на Win 7. Что-то опять голова не варит.
Посмотрите, пожалуйста.

; Источник: https://autohotkey.com/board/topic/88701-magnifier-for-win7-how-to-use-the-magnification-api/

#Singleinstance force
#NoEnv
#Persistent
;#Include %a_scriptdir%/Gdip.ahk
SetBatchLines -1
Coordmode, Mouse, Screen
OnExit, Uninitialize

zoomlevel := 2
Interface_update_speed = 1
w_size:=600
h_size:=200

Gui GUI_Drawing:+AlwaysOnTop -Caption +E0x80000 +hwndhGui -Border +ToolWindow +OwnDialogs +Owner +LastFound -E0x20
GUI GUI_Drawing:Show,NA,GUI_Drawing

Gdip_Startup()
hdc := CreateCompatibleDC()
hbm := CreateDIBSection(1,1,hdc)
SelectObject(hdc, hbm)



; Create magnifier control
hInstance := DllCall("GetWindowLong", "Ptr", hGui, "Ptr", GWL_HINSTANCE:=-6)
DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")
DllCall("magnification\MagSetWindowFilterList","UPtr", magHwnd, "Uint", 0, "Int", 1, "UPtr*", hGui) ; MW_Filtermode_Exclude

magHwnd := DllCall("CreateWindowEx"
	, "Ptr", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "Ptr", WS_CHILD := 0x40000000 | MS_SHOWMAGNIFIEDCURSOR := 0x1 | WS_VISIBLE := 0x10000000
	, "Int", 0
	, "Int", 0
	, "Int", a_screenwidth*2
	, "Int", a_screenheight*2
	, "Ptr", hGui
	, "Ptr", 0
	, "Ptr", hInstance
	, "Ptr", 0)

; Magnification transform matrix (Initializing the control)

gosub,ChangeZoom

loop
{
  sleep,% Interface_update_speed
  if (zoomlevel>1)
  {
    doonce=
    MouseGetPos, now_x, now_y
    cs_x := now_x - (w_size)/2
    cs_y := now_y - (h_size)/2
    VarSetCapacity(magRECT, 16)
    NumPut(cs_x, magRECT, 0, "uint"), NumPut(cs_y, magRECT, 4, "uint")
    DllCall("magnification.dll\MagSetWindowSource", "Ptr", magHwnd, "Ptr", &magRECT)
    UpdateLayeredWindow(hGui, hdc, now_x - (w_size)/2*zoomlevel, now_y - (h_size)/2*zoomlevel, w_size*zoomlevel, h_size*zoomlevel)
  }
  else if !doonce
  {
    doonce=1
    UpdateLayeredWindow(hGui,hdc,0,0,1,1,0)
  }
}
return


^WheelUp::
if (zoomlevel<10)
  zoomlevel++
gosub,ChangeZoom
return

^WheelDown::
if (zoomlevel>1)
  zoomlevel--
gosub,ChangeZoom
return



ChangeZoom:
Matrix := zoomlevel "|0|0|"
        . "0|" zoomlevel "|0|"
        . "0|0|" zoomlevel
StringSplit, Matrix, Matrix, |
VarSetCapacity(magMatrix, 36, 0)
Loop, 9
  NumPut(Matrix, magMatrix, (A_Index-1)*4, "float")
DllCall("magnification.dll\MagSetWindowTransform", "Ptr", magHwnd, "Ptr", &magMatrix)
tooltip,% (zoomlevel>1) ? zoomlevel : "Off"
settimer,tooltip,-1000
return

tooltip:
tooltip
return

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


; ------------------- from gdip library --------------------
UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	if ((x != "") && (y != ""))
		VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")

	if (w = "") ||(h = "")
		WinGetPos,,, w, h, ahk_id %hwnd%

	return DllCall("UpdateLayeredWindow"
					, Ptr, hwnd
					, Ptr, 0
					, Ptr, ((x = "") && (y = "")) ? 0 : &pt
					, "int64*", w|h<<32
					, Ptr, hdc
					, "int64*", 0
					, "uint", 0
					, "UInt*", Alpha<<16|1<<24
					, "uint", 2)
}
; ------------------- from gdip library --------------------

CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	hdc2 := hdc ? hdc : GetDC()
	VarSetCapacity(bi, 40, 0)

	NumPut(w, bi, 4, "uint")
	, NumPut(h, bi, 8, "uint")
	, NumPut(40, bi, 0, "uint")
	, NumPut(1, bi, 12, "ushort")
	, NumPut(0, bi, 16, "uInt")
	, NumPut(bpp, bi, 14, "ushort")

	hbm := DllCall("CreateDIBSection"
					, Ptr, hdc2
					, Ptr, &bi
					, "uint", 0
					, A_PtrSize ? "UPtr*" : "uint*", ppvBits
					, Ptr, 0
					, "uint", 0, Ptr)

	if !hdc
		ReleaseDC(hdc2)
	return hbm
}

SelectObject(hdc, hgdiobj)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
}
CreateCompatibleDC(hdc=0)
{
   return DllCall("CreateCompatibleDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
Gdip_Startup()
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
		DllCall("LoadLibrary", "str", "gdiplus")
	VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
	DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)
	return pToken
}
GetDC(hwnd=0)
{
	return DllCall("GetDC", A_PtrSize ? "UPtr" : "UInt", hwnd)
}
ReleaseDC(hdc, hwnd=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
}
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.