101

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

Ну да.

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

102

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

Ещё можно тень "размазать", наложив несколько раз подряд, сдвигая на 1 px.

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

103

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

Как то видел окно которое не было видно в GetDC, то есть лупа смотрела сквозь него, и изображение под ним обновлялось, никто не знает что за стили могут быть у таких окон?

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

104

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

Не думаю, что здесь есть какие-то стили.
Возможно directx окно.

105

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

По смутным воспоминаниям какое то OSD из ахк скрипта. На GDI возможно вывести окно вне контекста рабочего стола? Хочу заблюрить кусок экрана, и обновлять blur исходя из того что под ним.

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

106

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

Я знаю, как можно черный экран сделать вместо получения изображения через
setwindowdisplayaffinity, но как прозрачный не копался. Возможно есть какие-то флаги. А чего ты добиться хочешь, я так и не понял.

107

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

Malcev пишет:

setwindowdisplayaffinity

Спасибо, гляну.
Хочу размыть область экрана, blur эффект (гауссово размытие), но экран может измениться, а чтобы отобразить это изменение надо скрыть окно с блюром, чтобы узнать что на экране.

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

108 (изменено: Malcev, 2019-01-09 13:55:57)

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

Думаю такое можно сделать 2 способами. Через gdi, но захватывая все видимые окна по очереди и отрисовывая их. Либо делая скриншот через апи лупы. Там есть такая функция, но это придется самому реализовывать. Еще можно попробовать сделать скриншот через gdi и если лупы видно не будет, то можно на окно лупы накладывать blur через dwm api.

109 (изменено: MandarinKa02, 2019-01-10 00:17:53)

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

DEL

110

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

setwindowdisplayaffinity

Там только один флаг.

Malcev пишет:

Через gdi, но захватывая все видимые окна по очереди и отрисовывая их.

Ну это жесть, там надо ещё Z-Order вычислять, чтобы знать какое на какое наложено, а PrintWindow не со всеми окнами дружит.

Malcev пишет:

Либо делая скриншот через апи лупы

Да, кажется это была лупа, но сейчас не могу найти рабочий пример, этот берёт картинку только на х64 и далее не обновляет, кушая процессор.


#NoEnv
#Persistent
#SingleInstance Force

OnExit, Uninitialize
SetBatchLines, -1

Gui, +E0x80000
Gui, +AlwaysOnTop -Caption
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)

loop
DllCall("magnification.dll\MagSetWindowSource"
	, "UInt", magHwnd
	, "Int", -110
	, "Int", 110
	, "Int", 320
	, "Int", 240)

return

Escape::
GuiEscape:
GuiClose:	
Uninitialize:
	Gui, Destroy 
	DllCall("magnification.dll\MagUninitialize")
	ExitApp
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

111 (изменено: Malcev, 2019-01-11 18:39:28)

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

serzh82saratov пишет:

там надо ещё Z-Order вычислять

Не надо.
https://autohotkey.com/docs/commands/WinGet.htm#List

serzh82saratov пишет:

сейчас не могу найти рабочий пример

Пример для взятия скриншота:
https://www.codeproject.com/Articles/60 … on-library
Враппер апи лупы на автоит:
https://www.autoitscript.com/forum/topi … ipulation/

112 (изменено: serzh82saratov, 2019-01-11 18:52:44)

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

Malcev пишет:

Не надо.

Как не надо, надо же всё равно смотреть какое выше, координаты чтобы края видимых за ним знать, и WinGet List всех окон это долго.

Malcev пишет:

Пример для взятия скриншота

В общем на АНК ничего нет.

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

113

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

serzh82saratov пишет:

надо же всё равно смотреть какое выше

WinGet list возвращает их в порядке z-order.

serzh82saratov пишет:

Вообщем на АНК ничего нет

Переведи с автоит.
Там вызовы dllcall практически идентичны.

114

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

Прошу не писать "вобщем" и "вообщем".

115

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

Исправил.

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

116

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

Malcev пишет:

WinGet list возвращает их в порядке z-order.

Знаю, но это же всё равно долго.

Malcev пишет:

Там вызовы dllcall практически идентичны.

Попробую.

Malcev пишет:

Пример для взятия скриншота:

Это совсем тяжело, а в чём примерно отличие от DllCall("GetDC", "UPtr", 0, "UPtr")?

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

117

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

Отличие в том, что есть возможность внести в список окна, которые не надо захватывать:
https://docs.microsoft.com/en-us/window … filterlist

118 (изменено: Malcev, 2019-01-11 21:35:19)

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

serzh82saratov пишет:

Да, кажется это была лупа, но сейчас не могу найти рабочий пример, этот берёт картинку только на х64 и далее не обновляет, кушая процессор.

Для ahk64 бит функцию MagSetWindowSource надо вызывать так:

VarSetCapacity(rect, 16, 0)
NumPut(-110, rect, 0, "int")
NumPut(110, rect, 4, "int")
NumPut(320, rect, 8, "int")
NumPut(240, rect, 12, "int")
loop
{
   DllCall("magnification.dll\MagSetWindowSource", "ptr", magHwnd, ptr, &rect)
   sleep 50
}

Если требуется передавать в вызове копию структуры, то есть свои правила.

Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed as if they were integers of the same size. Structs or unions of other sizes are passed as a pointer to memory allocated by the caller.
So indeed, struct S {int;int;} must be passed as int64 for x64 calling convention, and it can be for cdecl too. But struct S2 {char c1;short s;char c2;} would need to be passed as "ptr", &S2 for x64. But, for cdecl, S2 would be passed as "int64", c1 | (s << 16) | (c2 << 32), you cannot do "char", c1, "short", s, "char", c2. Finally struct d {double; double; ... double;} must be passed as "ptr", &d for x64 and "double", d1, ..., "double", dn for cdecl.

119 (изменено: serzh82saratov, 2019-01-11 21:39:43)

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

Malcev пишет:

Для ahk64 бит функцию MagSetWindowSource надо вызывать так:

Работает! А на х32 это возможно запускать?

Malcev пишет:

Если требуется передавать в вызове копию структуры

А зачем это может понадобится?
Не пойму, всё что надо это вроде как правильно вызвать:

DllCall("magnification\MagSetWindowFilterList","Ptr",magHwnd,"Int",0,"Int",1,"Ptr*",guiHwnd)

может в "Ptr*" надо как то по другому передавать.

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

120

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

serzh82saratov пишет:

А на х32 это возможно запускать?

На x32 должен работать твой код из 110 поста.
Но в udf пишут:

; Built-In Windows Magnification API (since Windows Vista)
;
; NOTE: TRY to run this at the same bit-mode your O/S is running in, as the GUI can be funky at times
; when run in an incompatible bit mode.  So for 64-bit O/S's, run this as x64 only!

Не знаю так оно или нет - я не копался.

serzh82saratov пишет:

А зачем это может понадобится?

Это надо спрашивать у авторов библиотеки.

serzh82saratov пишет:

Не пойму, всё что надо это вроде как правильно вызвать:

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

121

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

Copy of structure vs pointer:
https://flaviocopes.com/golang-methods-receivers/
https://github.com/golang/go/wiki/CodeR … eiver-type

122

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

Malcev пишет:

Copy of structure vs pointer:

Это для меня дебри, я даже не понял к чему ты это привёл.

Malcev пишет:

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

А зачем нужна MagImageScalingCallback?
С MagSetWindowFilterList разобрался. То есть теперь мне надо запустить окно лупы скрыто, запустить окно с блюром, добавить его в исключения и как то выуживать битмап из лупы которая показывает в скрытом окне экран в тех же координатах что и окно с блюром.

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

123

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

Malcev пишет:

Не знаю так оно или нет - я не копался.

Иногда запускается под х32.

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

124 (изменено: Malcev, 2019-01-11 22:28:23)

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

serzh82saratov пишет:

Это для меня дебри, я даже не понял к чему ты это привёл.

Ты же спрашивал почему авторы функции MagSetWindowSource  требуют чтобы им отправляли копию структуры, а не указатель на структуру.
Наверное, это происходит из-за каких-то причин описываемых по этим ссылкам.
Не совсем понял твой алгоритм.
Я изначально предполагал 2 алгоритма.
Первый:
1) Создать прозрачное окно с лупой
2) Брать снимок через Gdi
3) Анализировать этот снимок
4) По результатам анализа делать размытие через wdm на окно с лупой.
Если первый чем-то не подходит, то второй:
1) Создать прозрачное окно Gdi
2) Создать прозрачное окно с лупой
3) Брать снимок через лупу, беря в исключения окно Gdi
4) Анализировать этот снимок
5) По результатам анализа делать размытие через gdi на окно с Gdi.
Для второго алгоритма нужен MagImageScalingCallback, иначе не достать информацию с снимка через лупу.

125

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

Malcev пишет:

Если первый чем-то не подходит, то второй:

Я почти тоже самое и предложил, только не пойму почему у тебя оба окна должны быть прозрачные.

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

126

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

Gdi не прозрачный.
А чего не хочешь пойти по более легкому первому алгоритму?

127

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

1) Создать прозрачное окно с лупой
2) Брать снимок через Gdi
3) Анализировать этот снимок
4) По результатам анализа делать размытие через wdm на окно с лупой.

Мне это не понятно.

Точнее первое теперь не понятно, ни GetDC ни PrintWindow не получают данные из magnification.

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

128

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

А тебе нужно данные именно из magnification?
Я так понял, что ты просто хочешь размывать участки экрана в зависимости от его контента.

129

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

Участок экрана закрыт окном GDI с размытием, нужно получить картинку под ним, чтобы обновить размытие. Чтобы узнать что под ним, надо воспользоватся лупой не беря окно с размытием.

Malcev пишет:

Я так понял, что ты просто хочешь размывать участки экрана в зависимости от его контента.

Ну да.

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

130

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

Так размывай окно с лупой, а картинку получай через gdi.

131

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

Это как?

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

132

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

https://docs.microsoft.com/en-us/window … hindwindow

133

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

Мне на это дело сверху ещё надо кучу своих картинок кинуть уже без размытия.

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

134

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

EnableBlurBehindWindow это наверное не то размытие, я не нашёл там параметра глубины.

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

135

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

Это стандартное размытие, которое использует виндовс без дополнительных настроек.
Но тебе видно придется-таки получать CreateCompatibleDC из колбека.

136

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

Malcev пишет:

нужен MagImageScalingCallback, иначе не достать информацию с снимка через лупу.

С такими примечаниями, не хочется.
А почему ты так уверен, что не может быть других вариантов?

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

137

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

Я других не знаю. Да и вообще программ с таким функционалом ни разу не встречал.

138 (изменено: serzh82saratov, 2019-01-12 01:14:31)

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

Malcev пишет:

Я других не знаю

Просто интересно чем это окно так отличается, если в других можно получить картинку из DC, а тут нет.

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

139

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

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

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

140

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

И без аеро каким то чудом определяется задний фон.
И по краям появляются артефакты. (


#SingleInstance, Force
#NoEnv
SetBatchLines, -1
CoordMode, Mouse

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

Gui, -Caption +E0x80000 +AlwaysOnTop +ToolWindow +OwnDialogs +E0x08000000 +HWNDhGui  ; +E0x20
Gui Show, NA, test 

x:= 505
y:= 505
w:= 600
h:= 600 
xv := 400
yv := 200

Blur := 22

hdcSrc := GetDCEx(0)
hdcDest := CreateCompatibleDC()
GoTo Update 
 
1::  
Update:
	; Gui, hide
	; KeyWait, 1
	hBitmap := CreateDIBSection(w, h, hdcDest)
	SelectObject(hdcDest, hBitmap)  
	StretchBlt(hdcDest, 0, 0, w, h, hdcSrc, xv, yv, w,  h) 
	pBitmap := Gdip_CreateBitmapFromHBITMAP(hBitmap)
	DeleteObject(hBitmap)
	pBlurBitmap := Gdip_BlurBitmap(pBitmap, Blur)
	Gdip_DisposeImage(pBitmap)
	G := Gdip_GraphicsFromHDC(hdcDest)
	Gdip_DrawImage(G, pBlurBitmap, 0, 0, w, h, 0, 0, w, h)
	Gdip_DisposeImage(pBlurBitmap) 
	Gdip_DeleteGraphics(G) 
	UpdateLayeredWindow(hGui, hdcDest, xv, yv, w, h)
	Gui, Show, NA  
	Return 

esc::
Exit: 
	DeleteDC(hdcSrc) 
	DeleteDC(hdcDest)  
	Gdip_Shutdown(pToken)
	ExitApp 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

141

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

У меня при включенном аэро (win7 x64 ahk 64 bit) и при adjust for best appearance в настройках perfomance при нажатии пригтскрин окно лупы копируется в клипбоард.
Если к окну лупы применить MagSetWindowFilterList с хендлом на какое-либо окно, то это окно в лупе показываться не будет и соответственно в буфере обмена тоже.

142

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

То что лупа может исключать окна мы разобрались, а буфер обмена что даёт?
DC рабочего стола даёт картинку лупы при любых раскладах, это сразу было известно.

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

143

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

Ну во-первых не при любых раскладах. А во-вторых если мы можем получить  снимок лупы, то следовательно мы можем получить снимок без размытого окна. Разве не это твоя цель?

144

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

Malcev пишет:

Ну во-первых не при любых раскладах.

А что может быть?

Malcev пишет:

А во-вторых если мы можем получить  снимок лупы, то следовательно мы можем получить снимок без размытого окна. Разве не это твоя цель?

Да, но как получить снимок лупы которой не должно быть видно на экране. Как он окажется в буфере, и чем пригтскрин отличается от DC всего экрана?

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

145

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

serzh82saratov пишет:

А что может быть?

Если выключим desktop composition, то в принтскрине лупы не будет.

serzh82saratov пишет:

Да, но как получить снимок лупы которой не должно быть видно на экране. Как он окажется в буфере, и чем пригтскрин отличается от DC всего экрана?

Там же всё пошагово расписано:

Malcev пишет:

Пример для взятия скриншота:
https://www.codeproject.com/Articles/60 … on-library

146

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

Malcev пишет:

Если выключим desktop composition, то в принтскрине лупы не будет.

Если выключим, то и лупа ненужна.

Malcev пишет:

Там же всё пошагово расписано:

Так мы же обсуждали:

This is a simple way to take a screenshot using the powerful Magnification library. However there is a problem that is need to be solved. The MagImageScalingCallback() function is deprecated, and could be removed from newer versions of Windows. So we need to find another way to access the data. Currently I haven't not found any solution yet. If anyone could find anyway, please let me know.

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

147

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

serzh82saratov пишет:

Если выключим, то и лупа ненужна.

Почему?

serzh82saratov пишет:

Так мы же обсуждали:

Во всяком случае за 5 лет не убрали.
Ну а с семерки уж точно уже не уберут.

148

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

serzh82saratov пишет:

без аеро каким то чудом определяется задний фон.

В 140 код, попробуй обновлять на кл. 1.

Malcev пишет:

Ну а с семерки уж точно уже не уберут.

Если делать, то уже с расчётом на 10.

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

149

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

В GetDCEx DCX_EXCLUDERGN может иметь отношение к теме?

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

150

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

Не знаю, но думаю вряд ли это поможет.
А зачем тебе вообще это надо?
Что за приложение ты делаешь в котором этот функционал необходим?

151

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

Да теперь просто стало любопытно, как получить скриншот без некоторых окон.

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

152

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

Походу только через Magnification API.
А для "наведения красоты" возможно достаточно такого примера:

gui, +hwndhwnd
Gui, color, 000001
gui, add, button, gExt,Toggle
gui, show, w300 h200, Glass

ext()
{
	static toggle:=0
	global hwnd
	toggle:=!toggle
	WinSet,TransColor, % toggle ? "000001" : "off", % "ahk_id " hwnd
	Dwm_ExtendFrameIntoClientArea(hwnd,toggle?-1:0)
	return
}

Dwm_ExtendFrameIntoClientArea(hwnd,l:=0,r:=0,t=0,b:=0)
{
	;	Extends the window frame into the client area.
	;	Input:
	;			hwnd, unique id to the window to which to extend window frame
	;			l,r,t,b is left, right top and bottom margins, respectively. Use negative to create "sheet of glass"-effect
	; 	Output:
	;			hresult, error msg. 0 is ok!
	;	Notes:
	;			https://msdn.microsoft.com/en-us/library/windows/desktop/aa969512(v=vs.85).aspx
	;			https://msdn.microsoft.com/en-us/library/windows/desktop/bb773244(v=vs.85).aspx (margins struct)
	VarSetCapacity(margin,16,0)
	NumPut(l,margin,0,"Int")
	NumPut(r,margin,4,"Int")
	NumPut(t,margin,8,"Int")
	NumPut(b,margin,12,"Int")
	hr:=DllCall("Dwmapi.dll\DwmExtendFrameIntoClientArea", "Uint", hwnd, "Uint", &margin)
	return hr	; 0 is ok!
}

Dwm_EnableBlurBehindWindow(hwnd,onOff,x1:=0,y1:=0,x2:=0,y2:=0,fTransitionOnMaximized:=0)
{
	;
	; 	Enables the blur effect on a specified window.
	;	Input:
	;		hwnd, The handle to the window on which the blur behind data is applied.
	;		onOff, 1 to turn the effect on, 0 offset
	;		x1,...,y2, The region within the client area where the blur behind will be applied. Let be 0 to apply the blur behind on the entire client area.
	;		fTransitionOnMaximized, 1 if the window's colorization should transition to match the maximized windows; otherwise, 0.
	;	Output:
	;		hresult, error msg. 0 is ok!
	;	Url:
	;		https://msdn.microsoft.com/en-us/library/windows/desktop/aa969508(v=vs.85).aspx - DwmEnableBlurBehindWindow function
	;
	
	
	;	DWM_BLURBEHIND structure:
	;	Url:
	;		https://msdn.microsoft.com/en-us/library/windows/desktop/aa969500(v=vs.85).aspx
	; 	Create region
	hrgn:=DllCall("Gdi32.dll\CreateRectRgn", "Int", x1, "Int", y1, "Int", x2, "Int", y2)

	VarSetCapacity(DWM_BLURBEHIND,12+A_PtrSize,0)
	NumPut(1|2|4,DWM_BLURBEHIND,0,"Uint")								; dwFlags
	NumPut(onOff,DWM_BLURBEHIND,4,"Int")								; fEnable
	NumPut(hrgn,DWM_BLURBEHIND,8,"Uint")								; hrgn
	NumPut(fTransitionOnMaximized,DWM_BLURBEHIND,8+A_PtrSize,"Int")		; fTransitionOnMaximized
	
	hr:= DllCall("Dwmapi.dll\DwmEnableBlurBehindWindow", "Uint", hwnd, "Uint", &DWM_BLURBEHIND)
	DllCall("Gdi32.dll\DeleteObject", "Uint", hrgn)						; The region is not needed after the call.
	return hr ; 0 is ok!
}

153

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

Без аеро не работает. Лучше уже обычное полупрозрачное.

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

154

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

serzh82saratov пишет:

Без аеро не работает

Ты ж на Win10 ориентируешься.
Кстати я ошибся, функционал не 5 лет не убирают, а уже скоро как 10.
озможно причина именно в:

serzh82saratov пишет:

получить скриншот без некоторых окон

И я погуглил, в некоторых разработках она до сих пор используется.

155

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

Надо будет попробовать, а у тебя получилось?

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

156

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

Я не пробовал - Visual Studio не установлена.
Мне такие примеры удобнее тестировать сначала на приведенном языке, так как мало ли вообще работать не будет, а ты будешь голову ломать, что не те/не там структуры или пойнтеры отправляешь/получаешь.
А тут всегда можно посмотреть полученный результат в функциях исходного примера и сравнить со своим.

157

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

Там нужен второй параметр void *srcdata?

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

158

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

Почему нужен? Ты же его получаешь.

159

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

А что в нём?

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

160

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

Пойнтер на битмап.

161

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

Непохоже, у меня с него картинки нет.
https://pt.stackoverflow.com/questions/ … api-magnif
Там что то с CreateDIBitmap.
https://autohotkey.com/board/topic/3423 … -gradient/

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

162

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

The srcdata parameter is the pointer to the bitmap source, and the srcheader contains the information of the captured image, so we can use these two parameters to create the BITMAPINFOHEADER and the BITMAPFILEHEADER.

163

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

Я читал, а если по русски.

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

164

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

Получаем ссылку на битмап и сам хедер.
Исходя из полученных данных создаем структуры BITMAPINFOHEADER и BITMAPFILEHEADER.
После чего переворачиваем горизонтально полученное изображение, соединяем всё это и получаем bmp.

165 (изменено: Malcev, 2019-01-13 05:24:21)

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

Но это только выводы из прочитанного.
Я конечно же могу ошибаться, так как не C не C++ не знаю.
У нас на форуме в этом YMP дока.
На крайний случай можно будет на оф.форуме спросить, там точно есть сишники.
Кстати, смотри, что автор в комментах пишет:
https://www.codeproject.com/Articles/60 … x4590085xx

166

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

Ты про это - My conclusion is that MagSetImageScalingCallback function is deprecated in Windows 7 and later (32 Bits only).

Исходя из полученных данных создаем структуры BITMAPINFOHEADER и BITMAPFILEHEADER.

Да уж...

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

167

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

Про это:
вопрос

I have Windows7 32bit, VS2010 Professional. I copied your files and it compiled - 0 warnings or errors. Great work.
I do have a question, is there a function in the magnification library to resize the bitmap before it is saved?

ответ

Thank you for your question. The library has the SetMagnificationFactor() function that lets you to set the factor to the captured image. But unfortunately, the main purpose of this library is "magnifying things", not "capturing things" so you cannot set the factor less then 1.
So to resize the bitmap, I think you can perform these steps in the callback function:
1. Create a compatible device context from the magnification window
2. Create a compatible HBITMAP
3. Use the SetDIBits() function to set the bitmap data into the HBITMAP object
4. Create another device context and another HBITMAP object
5. Use the StretchBlt() function to zoom in or zoom out the first HBITMAP object into the second HBITMAP object
6. Then you can save the content of the second HBITMAP to file, as described in here[^]

serzh82saratov пишет:

Да уж...

Да не так уж там всё и сложно, наверное.
Нужно смотреть, что возвращает функция на c++ и пытаться получить тоже самое на ahk.

168

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

В примере на дельфи вроде всё понятно, но у меня самое простое не выходит

ToolTip % NumGet(srcheader, 0, "UInt" ) "х" NumGet(srcheader, 4, "UInt" )

MAGIMAGEHEADER structure тут же должны быть ширина и высота картинки - 320х240.


#NoEnv
#Persistent
#SingleInstance Force

OnExit, Uninitialize

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

Gui, +AlwaysOnTop -Caption +toolwindow +HWNDhGui 
Gui,Show, w320 h240 na, MagnifierWindowAHK

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

WS_CHILD := 0x40000000
WS_VISIBLE := 0x10000000
MS_SHOWMAGNIFIEDCURSOR := 0x1 
	
magHwnd := DllCall("CreateWindowEx"
	, "UInt", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "UInt",   MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE | WS_CHILD
	, "Int", 0
	, "Int", 0
	, "Int", 320
	, "Int", 240
	, "Ptr", hGui
	, "UInt", 0
	, "Ptr", hInstance
	, "UInt", 0)
	
DllCall("magnification.dll\MagSetImageScalingCallback"
	, "Ptr", magHwnd
	, "Int", RegisterCallback("MagImageScalingCallback", "Fast"))

VarSetCapacity(rect, 16, 0)
NumPut(0, rect, 0, "int")
NumPut(0, rect, 4, "int")
NumPut(320, rect, 8, "int")
NumPut(240, rect, 12, "int")

DllCall("magnification.dll\MagSetWindowSource", "ptr", magHwnd, ptr, &rect)  
return

MagImageScalingCallback(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) { 
	ToolTip % NumGet(srcheader, 0, "UInt" ) "`n" NumGet(srcheader, 4, "UInt" )
}

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

169

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

На x32 так:

ToolTip % srcheader "`n" destdata

На x64:

ToolTip % NumGet(srcheader+0, 0, "UInt" ) "х" NumGet(srcheader+0, 4, "UInt" )

https://autohotkey.com/docs/commands/Re … llback.htm

170 (изменено: serzh82saratov, 2019-01-13 13:05:32)

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

Ух, тяжело.

Malcev пишет:

На x32 так:

Это что получается, если какой то параметр является указателем на структуру, то каждая её часть превращается в отдельный параметр!?

Malcev пишет:

На x64:

Зачем плюсовать ноль?
Перед твоим ответом ответом как раз читал RegisterCallback, но хоть убей не пойму как можно прийти к таким выводам.

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

171 (изменено: serzh82saratov, 2019-01-13 13:10:00)

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

Malcev пишет:

На x32 так:

И это когда ос64, или на ос32 также?
И magnification.dll работает на ос32?

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

172

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

serzh82saratov пишет:

Зачем плюсовать ноль?

if the variable contains the target address; in that case, pass an expression such as MyVar+0.

https://autohotkey.com/docs/commands/NumGet.htm

serzh82saratov пишет:

Это что получается, если какой то параметр является указателем на структуру, то каждая её часть превращается в отдельный параметр!?

В принципе я сам не понимаю почему так происходит, так как в таком виде должна передаваться копия структуры.
На x32 я имел в виду версию ahk.

serzh82saratov пишет:

И magnification.dll работает на ос32?

А почему бы ей там не работать?
Вот тут мы обсуждали dllcall:
http://forum.script-coding.com/viewtopi … 83#p130683

173

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

Malcev пишет:

На x32 я имел в виду версию ahk.

Я так тебя и понял, то есть анк32 на ос64. Если ос32, то получаем через NumGet?

Malcev пишет:

А почему бы ей там не работать?

Так на ос64 из под анк32 почему не работаетсама лупа?

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

174

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

serzh82saratov пишет:

Если ос32, то получаем через NumGet?

Не понял вопроса.

serzh82saratov пишет:

Так на ос64 из под анк32 почему не работаетсама лупа?

Наверное потому, что на win x64 32-bit dll лупы не корректно работает.

175 (изменено: serzh82saratov, 2019-01-13 14:09:48)

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

Malcev пишет:

Не понял вопроса.

На анк32 в ос64 параметр как структура не передаётся, в ос32 структура передаётся?

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

176

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

serzh82saratov пишет:

На анк32 в ос64 структура не передаётся,

Структура-то передается, только у меня в экране лупы отображается черный прямоугольник (либо проблема отображения, либо битмап пустой).

177

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

Malcev пишет:

Структура-то передается

ToolTip % srcheader "`n" destdata

Так ведь не структура, а её части отдельными параметрами.

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

178

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

Отдельными параметрами должна передаваться копия структуры для x32 вызова.
Получается в ахк колбек передает копию структуры, а не ссылку на нее.
Хотя пишут, что:

If an incoming parameter is the address of a structure, the individual members may be extracted by following the steps at DllCall structures.

Можно на оффоруме спросить.

179

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

Так это как же тогда функцию расписывать надо, с кучей параметров, и

A function assigned to a callback address may accept up to 31 parameters

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

180

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

Надо на win32 проверить, может такое явление происходит из-за вызова 32битной длл на win64.

181

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

Я тоже так подумал.

Теперь надо создать переменную _info под структуру, как вычислить её размер?

    Fillchar(_info, sizeof(_info), 0);

    _info.bmiHeader.biSize:= sizeOf(TBitmapInfoHeader);
    _info.bmiHeader.biWidth:= _srcheader.width;
    _info.bmiHeader.biHeight:=  -_srcheader.height;
    _info.bmiHeader.biplanes:= 1;
    _info.bmiHeader.biBitCount:= 32;
    _info.bmiHeader.biCompression:= BI_RGB;

    _bitmap:= 0;
    _bitmap:= CreateDIBitmap(_DC, _info.bmiHeader, CBM_INIT, _srcdata, _info, DIB_RGB_COLORS);
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

182

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

Ну как берешь и считаешь.
https://www.autoitscript.com/autoit3/do … Create.htm

183

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

То есть структуру для CreateDIBitmap.

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

184

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

Это сплюсовать. CIEXYZTRIPLE не нашёл размер.

  DWORD        bV5Size;
  LONG         bV5Width;
  LONG         bV5Height;
  WORD         bV5Planes;
  WORD         bV5BitCount;
  DWORD        bV5Compression;
  DWORD        bV5SizeImage;
  LONG         bV5XPelsPerMeter;
  LONG         bV5YPelsPerMeter;
  DWORD        bV5ClrUsed;
  DWORD        bV5ClrImportant;
  DWORD        bV5RedMask;
  DWORD        bV5GreenMask;
  DWORD        bV5BlueMask;
  DWORD        bV5AlphaMask;
  DWORD        bV5CSType;
  CIEXYZTRIPLE bV5Endpoints;
  DWORD        bV5GammaRed;
  DWORD        bV5GammaGreen;
  DWORD        bV5GammaBlue;
  DWORD        bV5Intent;
  DWORD        bV5ProfileData;
  DWORD        bV5ProfileSize;
  DWORD        bV5Reserved;
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

185

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

Это структура.

186

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

Ptr?

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

187

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

Или добавить размер этой структуры?

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

188 (изменено: Malcev, 2019-01-13 15:02:01)

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

Со структурой всё правильно работает так как возвращается копия, а не ссылка.

srcheader

Type: MAGIMAGEHEADER

The description of the input format.

Надо считать сколько занимают ее члены.

189

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

Посчитаешь, можешь сравнить результат.
http://d3s.mff.cuni.cz/teaching/princip … 20Wiki.pdf

190 (изменено: serzh82saratov, 2019-01-13 15:13:14)

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

Так CIEXYZTRIPLE считать как указатель, или плюсовать её размер?

Malcev пишет:

Со структурой всё правильно работает так как возвращается копия, а не ссылка.

Это на что ответ?

Malcev пишет:

Надо считать сколько занимают ее члены.

Так мы же это и пытаемся сделать...

Malcev пишет:

Посчитаешь, можешь сравнить результат.

Там BITMAPV5HEADER идёт последним, как понять сколько он занимает.

Если считать CIEXYZTRIPLE как Ptr, то 92.


def_Struct := "
(LTrim Join
  DWORD        bV5Size;
  LONG         bV5Width;
  LONG         bV5Height;
  WORD         bV5Planes;
  WORD         bV5BitCount;
  DWORD        bV5Compression;
  DWORD        bV5SizeImage;
  LONG         bV5XPelsPerMeter;
  LONG         bV5YPelsPerMeter;
  DWORD        bV5ClrUsed;
  DWORD        bV5ClrImportant;
  DWORD        bV5RedMask;
  DWORD        bV5GreenMask;
  DWORD        bV5BlueMask;
  DWORD        bV5AlphaMask;
  DWORD        bV5CSType;
  Ptr          bV5Endpoints;
  DWORD        bV5GammaRed;
  DWORD        bV5GammaGreen;
  DWORD        bV5GammaBlue;
  DWORD        bV5Intent;
  DWORD        bV5ProfileData;
  DWORD        bV5ProfileSize;
  DWORD        bV5Reserved;
)"

oStruct := new DllStruct(def_Struct)

msgbox % oStruct.GetSize()




; ======================================================================================================================
; AHK_L 1.1 +
; ======================================================================================================================
; Function:         Class definitions for windows structures used with DllCall
; AHK version:      1.1.05.06 (U 32) / (U64)
; Language:         English
; Tested on:        Win XPSP3, Win VistaSP2 (x86) / Win 7 (x64)
; Version:          0.0.01.09/2011-12-09/just me
; Remarks:          To create a structure create a new instance of the class using
;                      MyStruct := New DllStruct(StructStr)
;
;                   The parameter "StructStr" describes the fields of the structure as follows:
;                   "TYPE name[n];"
;                        TYPE            : Datatype, for valid types see AHKTypes and WINTypes below
;                        name (optional) : Name to access the field with the methods described below. If name is not 
;                                          specified, you have to access the field by it's 1-based index, otherwise
;                                          TYPE and name must be seperated with at least one space.
;                                          If name is preceded with a "*" the TYPE will be changed to "UPTR".
;                        [n]  (optional) : Number of occurrences, if [n] is not specified it defaults to 1.
;                                          To access a certain occurrence with Get/SetData methods you have to pass
;                                          the 1-based index within the parameter Index. String types (CHAR [n], 
;                                          TCHAR [n], WCHAR [n]) are always accessed as strings.
;                                          To supply names for occurences append a colon (:) to the counter (n)
;                                          followed by the names seperated by commas (,) and the closing bracket,
;                                          e.g. "[4: Left, Top, Right, Bottom]". To access an occurence by name just
;                                          pass the name instead of the numeric index.
;                        ;               : Each field description must be closed with a semicolon
;
;                   Alignment and padding:
;                   By default, each structure member is aligned to start at an address which is a multiple of its
;                   length. In addition the structure is padded to set the size to be a multiple of its longest
;                   member when needed. This can be changed by specifing "Align n;" within "StructStr" where n may
;                   be 0, 1, 2, 4, or 8. It changes alignment for all subsequent structure members be a multiple of n
;                   or their size, whatever is smaller. "Align 0;" restores the default alignment.
;                   Since inluding of embedded structures by name is not supported, the script doesn't notice the start
;                   or end of these structures. But sometimes the structure's size has to be aligned, especially
;                   in 64-bit environments. To avoid displacements you should enclose the structure decleration in
;                   braces followed by a semicolon, e.g. "{; HWND hwndFrom; UINT_PTR idFrom; UINT code; };" (NMHDR).
; 
;                   The following public methods provide access to the structure's memory/fields (see below): 
;                   Init           Sets structure's memory to binary NULL
;                   GetData        Gets the current value of a field
;                   SetData        Sets the value of a field
;                   GetCount       Returns the number of occurrences of a field defined as TYPE [nn]
;                   GetPtr         Returns a pointer to the structure or one of the fields
;                   GetSize        Returns the size of the structure or one of the fields in bytes
;
;                   It's also possible to access fields using the object syntax "Class.Property". To access
;                   a subitem of a field with multiple occurences (e.g. "LONG [4];") you must use the array syntax
;                   Class.Property[4] or Class.Property["Name"]. 
;                   The notation "Class.Property.4" is not supported and will yield a blank result.
;
;                   Fields with multiple occurrences may be accessed as a whole if no subitem index is passed. To 
;                   set the values you have to pass an appropriate array containing all values, reading access returns
;                   an array containing them.   
;
;                   Names of "private" properties/methods are prefixed with underscores, they must not be
;                   set/called by the script!
;                   
;                   You can find the description of windows data types at 
;                   http://msdn.microsoft.com/en-us/library/aa383751%28VS.85%29.aspx
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
;=======================================================================================================================
Class DllStruct {
   ; ===================================================================================================================
   ; Base Class Definition
   ; ===================================================================================================================
   Class _Base {
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; Meta-Functions +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ================================================================================================================
      ; CONSTRUCTOR __New - you must not instantiate instances
      ; ================================================================================================================
      __New(P*) {
         Return False
      }
      ; ================================================================================================================
      ; __Get      Get pseudo properties 
      ; ================================================================================================================
      __Get(Name, Index = 0) {
         Return This.GetData(Name, Index)
      }
      ; ================================================================================================================
      ; __Set      Set pseudo properties
      ; ================================================================================================================
      __Set(Name, Params*) {
         If !IsObject(Params) || (Params.MaxIndex() > 2)
            Return ""
         If (Params.MaxIndex() = 1) {
            Index := 0
            Value := Params[1]
         } Else {
            Index := Params[1]
            Value := Params[2]
         }
         Return This.SetData(Name, Value, Index)
      }
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; Private Methods ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ================================================================================================================
      ; PRIVATE METHOD _IsInt()
      ; ================================================================================================================
      _IsInt(Value) {
         If Value Is Not Integer
            Return False
         Return True
      }
      ; ================================================================================================================
      ; PRIVATE METHOD _IsIn()
      ; ================================================================================================================
      _IsIn(Value, MatchList) {
         If Value Not In %MatchList%
            Return False
         Return True
      }
      ; ================================================================================================================
      ; PRIVATE METHOD _StructHasField()
      ; ================================================================================================================
      _StructHasField(ByRef Name) {
         StringUpper, Name, Name
         If !(This._IsInt(Name)) {
            If !This._StructObj.HasKey(Name) {
               This.Error := True
               Return False
            }
            Name := This._StructObj[Name]
         }
         If !This._StructArr.HasKey(Name) {
            This.Error := True
            Return False
         }
         Return True
      }
      ; ================================================================================================================
      ; PRIVATE METHOD _FieldHasIndex()
      ; ================================================================================================================
      _FieldHasIndex(ByRef Index, Field) {
         If !(This._IsInt(Index)) {
            If Field.Names.HasKey(Index) {
               Index := Field.Names[Index]
               Return True
            } Else {
               This.Error := True
               Return False
            }
         }
         If (Index < 0) || (Index > Field.Cnt) {
            This.Error := True
            Return False
         }
         Return True
      }
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; PUBLIC Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      ; ================================================================================================================
      ; METHOD Init           Sets structure's memory to NULL
      ; Return values:        On success  - True
      ;                       On failure  - False, This.Error is set
      ; ================================================================================================================
      Init() {
         This.Error := False
         If !(This._Ptr) || !(This._Alloc) {
            This.Error := True
            Return False
         }
         DllCall("Kernel32.dll\RtlZeroMemory", "Ptr", This._Ptr, "Ptr", This._Size)
         If (ErrorLevel) {
            This.Error := True
            Return False
         }
         Return True
      }
      ; ================================================================================================================
      ; METHOD GetData        Get current value of structure field
      ; Parameters:           Name        - Name or index of the field
      ;                       Index       - Optional: 1-based index of subitem (Name[nn])
      ; Return values:        On success  - Field value
      ;                       On failure  - False, This.Error is set
      ; Remarks:              To access a certain field "Name" must contain the 1-based field index or the name defined
      ;                       in the structure description string.
      ; ================================================================================================================
      GetData(Name, Index = 0) {
         This.Error := False
         If !This._StructHasField(Name) {
            This.Error := True
            Return False
         }
         Field := This._StructArr[Name]
         If !This._FieldHasIndex(Index, Field) {
            This.Error := True
            Return False
         }
         If (Index = 0) && (Field.Cnt > 1) {
            Value := []
            Loop, % Field.Cnt
               Value.Insert(NumGet(This._Ptr + 0, Field.Pos + ((A_Index - 1) * Field.Len), Field.Type))
            Return Value
         }
         If (Index > 0)
            Index--
         If (Field.Type = "ASTR") || (Field.Type = "WSTR") {
            CP := (Field.Type = "WSTR" ? "UTF-16" : "CP0")
            Len := (Field.Type = "WSTR" ? Field.Len // 2 : Field.Len)
            Value := StrGet(This._Ptr + Field.Pos, Len, CP)
         } Else {
            Value := NumGet(This._Ptr + 0, Field.Pos + (Index * Field.Len), Field.Type)
         }
         Return Value
      }
      ; ================================================================================================================
      ; METHOD SetData        Set value of a structure field
      ; Parameters:           Name        - Name or index of the field
      ;                       Value       - New value 
      ;                       Index       - Optional: 1-based index of subitem (Name[nn])
      ; Return values:        On success  - True
      ;                       On failure  - False, This.Error is set
      ; Remarks:              To access a certain field "Name" must contain the 1-based field index or the name defined
      ;                       in the structure description string.
      ; ================================================================================================================
      SetData(Name, Value, Index = 0) {
         This.Error := False
         If !This._StructHasField(Name) {
            This.Error := True
            Return False
         }
         Field := This._StructArr[Name]
         If !This._FieldHasIndex(Index, Field) {
            This.Error := True
            Return False
         }
         If (Index = 0) && IsObject(Value) && (Value.MaxIndex() = Field.Cnt) {
            For I, V In Value
               NumPut(V, This._Ptr + 0, Field.Pos + ((I - 1) * Field.Len), Field.Type)
            Return True
         }
         If (Index > 0)
            Index--
         If (Field.Type = "ASTR") || (Field.Type = "WSTR") {
            CP := (Field.Type = "WSTR" ? "UTF-16" : "CP0")
            Len := (Field.Type = "WSTR" ? Field.Len // 2 : Field.Len)
            StrPut(Value, This._Ptr + Field.Pos, Len, CP)
         } Else {
            NumPut(Value, This._Ptr + 0, Field.Pos + (Index * Field.Len), Field.Type)
         }
         Return True
      }
      ; ================================================================================================================
      ; METHOD GetCount       Returns the number of occurrences of a field defined as TYPE [nn]
      ; Parameters:           Name        - Name or index of the field
      ; Return values:        On success  - Integer value > 0
      ;                       On failure  - False, This.Error is set
      ; Remarks:              To access a certain field "Name" must contain the 1-based field index or the name defined
      ;                       in the structure description string.
      ; ================================================================================================================
      GetCount(Name) {
         This.Error := False
         If !(This._Ptr) {
            This.Error := True
            Return False
         }
         If !This._StructHasField(Name) {
            This.Error := True
            Return False
         }
         Field := This._StructArr[Name]
         Return (Field.Cnt)
      }
      ; ================================================================================================================
      ; METHOD GetPtr         Returns a pointer to the structure or one of the fields
      ; Parameters:           Name        - Optional: Name or index of the field
      ; Return values:        On success  - Address of the structure or the field passed in Name
      ;                       On failure  - False, This.Error is set
      ; Remarks:              To access a certain field "Name" must contain the 1-based field index or the name defined
      ;                       in the structure description string.
      ; ================================================================================================================
      GetPtr(Name = "") {
         This.Error := False
         If !(This._Ptr) {
            This.Error := True
            Return False
         }
         If (Name = "")
            Return This._Ptr
         If !This._StructHasField(Name) {
            This.Error := True
            Return False
         }
         Field := This._StructArr[Name]
         Return (This._Ptr + Field.Pos)
      }
      ; ================================================================================================================
      ; METHOD GetSize        Returns the size of the structure or one of the fields in bytes
      ; Parameters:           Name        - Optional: Name or index of the field
      ; Return values:        On success  - Size in bytes of the structure or the field passed in Name
      ;                       On failure  - False, This.Error is set
      ; Remarks:              To access a certain field "Name" must contain the 1-based field index or the name defined
      ;                       in the structure description string.
      ; ================================================================================================================
      GetSize(Name = "") {
         This.Error := False
         If !(This._Size) {
            This.Error := True
            Return False
         }
         If (Name = "")
            Return This._Size
         If !This._StructHasField(Name) {
            This.Error := True
            Return False
         }
         Field := This._StructArr[Name]
         Return (Field.Len * Field.Cnt)
      }
   }
   ; ===================================================================================================================
   ; Helper Class for Windows Types
   ; ===================================================================================================================
   Class _WINTypes {
      Static ATOM := "USHORT"
      Static BOOL := "INT"
           , BOOLEAN := "UCHAR"
           , BYTE := "UCHAR"
      Static COLORREF := "UINT"
      Static DWORD32 := "UINT"
           , DWORD64 := "UINT64"
           , DWORD := "UINT"
           , DWORD_PTR := "UPTR"
           , DWORDLONG := "UINT64"
      Static HACCEL := "UPTR"
           , HALF_PTR := (A_PtrSize = 8 ? "INT" : "SHORT")
           , HANDLE := "UPTR"
           , HBITMAP := "UPTR"
           , HBRUSH := "UPTR"
           , HCOLORSPACE := "UPTR"
           , HCONV := "UPTR"
           , HCONVLIST := "UPTR"
           , HCURSOR := "UPTR"
           , HDC := "UPTR"
           , HDDEDATA := "UPTR"
           , HDESK := "UPTR"
           , HDROP := "UPTR"
           , HDWP := "UPTR"
           , HENHMETAFILE := "UPTR"
           , HFILE := "INT"
           , HFONT := "UPTR"
           , HGDIOBJ := "UPTR"
           , HGLOBAL := "UPTR"
           , HHOOK := "UPTR"
           , HICON := "UPTR"
           , HINSTANCE := "UPTR"
           , HKEY := "UPTR"
           , HKL := "UPTR"
           , HLOCAL := "UPTR"
           , HMENU := "UPTR"
           , HMETAFILE := "UPTR"
           , HMODULE := "UPTR"
           , HMONITOR := "UPTR"
           , HPALETTE := "UPTR"
           , HPEN := "UPTR"
           , HRESULT := "INT"
           , HRGN := "UPTR"
           , HRSRC := "UPTR"
           , HSZ := "UPTR"
           , HWINSTA := "UPTR"
           , HWND := "UPTR"
      Static INT32 := "INT"
           , INT_PTR := "PTR"
      Static LANGID := "USHORT"
           , LCID := "UINT"
           , LCTYPE := "UINT"
           , LGRPID := "UINT"
           , LONG32 := "INT"
           , LONG64 := "INT64"
           , LONG := "INT"
           , LONG_PTR := "PTR"
           , LONGLONG := "INT64"
           , LPARAM := "PTR"
           , LPBOOL := "UPTR"
           , LPBYTE := "UPTR"
           , LPCOLORREF := "UPTR"
           , LPCSTR := "UPTR"
           , LPCTSTR := "UPTR"
           , LPCVOID := "UPTR"
           , LPCWSTR := "UPTR"
           , LPDWORD := "UPTR"
           , LPHANDLE := "UPTR"
           , LPINT := "UPTR"
           , LPLONG := "UPTR"
           , LPSTR := "UPTR"
           , LPTSTR := "UPTR"
           , LPVOID := "UPTR"
           , LPWORD := "UPTR"
           , LPWSTR := "UPTR"
           , LRESULT := "PTR"
      Static PBOOL := "PTR"
           , PBOOLEAN := "PTR"
           , PBYTE := "PTR"
           , PCHAR := "PTR"
           , PCSTR := "PTR"
           , PCTSTR := "PTR"
           , PCWSTR := "PTR"
           , PDWORD32 := "PTR"
           , PDWORD64 := "PTR"
           , PDWORD := "PTR"
           , PDWORD_PTR := "PTR"
           , PDWORDLONG := "PTR"
           , PFLOAT := "PTR"
           , PHALF_PTR := "PTR"
           , PHANDLE := "UPTR"
           , PHKEY := "UPTR"
           , PINT32 := "UPTR"
           , PINT64 := "UPTR"
           , PINT := "UPTR"
           , PINT_PTR := "UPTR"
           , PLCID := "UPTR"
           , PLONG32 := "UPTR"
           , PLONG64 := "UPTR"
           , PLONG := "UPTR"
           , PLONG_PTR := "UPTR"
           , PLONGLONG := "UPTR"
           , POINTER_32 := "UINT"
           , POINTER_64 := "PTR"
           , POINTER_SIGNED := "PTR"
           , POINTER_UNSIGNED := "UPTR"
           , PSHORT := "UPTR"
           , PSIZE_T := "UPTR"
           , PSSIZE_T := "UPTR"
           , PSTR := "UPTR"
           , PTBYTE := "UPTR"
           , PTCHAR := "UPTR"
           , PTSTR := "UPTR"
           , PUCHAR := "UPTR"
           , PUHALF_PTR := "UPTR"
           , PUINT32 := "UPTR"
           , PUINT64 := "UPTR"
           , PUINT := "UPTR"
           , PUINT_PTR := "UPTR"
           , PULONG32 := "UPTR"
           , PULONG64 := "UPTR"
           , PULONG := "UPTR"
           , PULONG_PTR := "UPTR"
           , PULONGLONG := "UPTR"
           , PUSHORT := "UPTR"
           , PVOID := "UPTR"
           , PWCHAR := "UPTR"
           , PWORD := "UPTR"
           , PWSTR := "UPTR"
      Static SC_HANDLE := "UPTR"
           , SC_LOCK := "UPTR"
           , SERVICE_STATUS_HANDLE := "UPTR"
           , SIZE_T := "UPTR"
           , SSIZE_T := "PTR"
      Static TBYTE := (A_ISUNICODE ? "USHORT" : "UCHAR")
           , TCHAR := (A_ISUNICODE ? "USHORT" : "UCHAR")
      Static UHALF_PTR := (A_PtrSize = 8 ? "UINT" : "USHORT")
           , UINT32 := "UINT"
           , UINT_PTR := "UPTR"
           , ULONG32 := "UINT"
           , ULONG64 := "UINT64"
           , ULONG := "UINT"
           , ULONG_PTR := "UPTR"
           , ULONGLONG := "UINT64"
           , USN := "INT64"
      Static VOID := "PTR"
      Static WCHAR := "USHORT"
           , WORD := "USHORT"
           , WPARAM := "UPTR"
   }
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; CLASS Properties and Methods ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; ===================================================================================================================
   ; CONSTRUCTOR __New
   ; Parameters:        StructStr   - String describing the structure fields
   ;                    Pointer     - Optional: Pointer to the structure as returned from SendMessage or API-Calls
   ; Return values:     On success  - new object
   ;                    On failure  - False, ErrorLevel contains additional informations
   ; ===================================================================================================================
   __New(StructStr, Pointer = "") {
      Static AHKTypes := {CHAR: 1, SHORT: 2, INT: 4, INT64: 8, PTR: A_PtrSize
                        , UCHAR: 1, USHORT: 2, UINT: 4, UINT64: 8, UPTR: A_PtrSize}
      Static StructsP := {RECT: "{;LONG [4: Left, Top, Right, Bottom];};"
                        , POINT: "{;LONG [2: X, Y];};"
                        , POINTS: "{;SHORT [2: X, Y];};"}
      ; Create class variables -----------------------------------------------------------------------------------------
      This._DllStruct := ""   ; Structure variable                               (Binary)
      This._StructArr := []   ; Array of structure fields                        (Object)
      This._StructObj := {}   ; Object for field names                           (Object)
      This._Alloc := False    ; Did the class allocate memory?                   (BOOL)
      This._Ptr := 0          ; Structure pointer                                (Pointer)
      This._Size := 0         ; Structure size                                   (Integer)
      This.Error := False     ; Set to True in case of errors                    (BOOL)
      ; ----------------------------------------------------------------------------------------------------------------
      Align := FieldIndex := MaxLen := MaxStructLen := Pad := Ptr := Size := StructAlign := 0
      InStruct := False
      StructStr := RegExReplace(StructStr, "[\r\n]")
      StructStr := RTrim(StructStr, ";")
      Loop, Parse, StructStr, `;
      {
         If !(A_LoopField) {
            ErrorLevel := "Improper structure declaration!"
            Return False
         }
         StringUpper, Part, A_LoopField
         Part := RegExReplace(Trim(Part), "\s+", " ")
         Rep := ""
         If RegExMatch(Part, "\[(?P<ep>[^\]]+)\]$", R) {
            Rep := RegExReplace(Rep, "\s+")
            Part := RegExReplace(Part, "\s*\[.*$")
         }
         StringSplit, Parts, Part, %A_Space%
         If (Parts0 > 2) {
            ErrorLevel := "Improper field declaration: " . Part . "!"
            Return False
         }
         ; Check for alignment presetting
         If (Parts1 = "Align") {
            If (Parts0 = 2) && (StrLen(Parts2) = 1) && InStr("01248", Parts2) {
               If (InStruct) {
                  StructAlign := Parts2
               } Else {
                  Align := Parts2
               }
               Continue
            }
            ErrorLevel := "Invalid alignment value""" . Parts2 . """!"
            Return False
         }
         ; Check for explicit padding
         If (Parts1 = "Pad") {
            If (Parts0 = 2) && (StrLen(Parts2) = 1) && InStr("012345678", Parts2) {
               Size += Parts2
               Continue
            }
            ErrorLevel := "Invalid padding value""" . Parts2 . """!"
            Return False
         }
         ; Check for embedded structures
         If (Parts1 = "{") {  ; start of structure
            If (InStruct) {
               ErrorLevel := "Improper use of ""{""!"
               Return False
            }
            ; Set / initialize structure related variables
            InStruct := True
            MaxStructLen := 0
            StructAlign := Align
            Continue
         }
         If (Parts1 = "}") {  ; end of structure
            If !(InStruct) || (MaxStructLen = 0) {
               ErrorLevel := "Improper use of ""}""!"
               Return False
            }
            ; Align structure's size if required and reset structure related variables
            StructAlign := (StructAlign) && (StructAlign < MaxStructLen) ? StructAlign : MaxStructLen
            If (Pad := Mod(Size, StructAlign))
               Size += StructAlign - Pad
            MaxStructLen := 0
            InStruct := False
            StructAlign := 0
            Continue
         }
         ; 
         Cnt  := 1
         If (Rep) && !RegExMatch(Rep, "^\d+", Cnt) {
            ErrorLevel := "Improper repetition factor """ . Rep . """!"
            Return False
         }
         If (Parts0 = 2) {
            If (SubStr(Parts2, 1, 1) = "*") {
               Parts1 := "UPTR"
               Parts2 := RegExReplace(Parts2, "^\*+")
            }
         }
         Type := Parts1
         If This._WINTypes.HasKey(Parts1)
            Type := This._WINTypes[Parts1]
         If !AHKTypes.HasKey(Type) {
            ErrorLevel := "Invalid data type """ . Parts1 . """!"
            Return False
         }
         Len := AHKTypes[Type]
         If (Len > MaxLen)
            MaxLen := Len
         If (Len > MaxStructLen)
            MaxStructLen := Len
         If (Pad := Mod(Size, ((Align) && (Align < Len))? Align : Len))
            Size += Len - Pad
         Pos := Size
         If (Cnt > 1) {
            If (Parts1 = "WCHAR")
               Type := "WSTR"
            Else If (Parts1 = "CHAR")
               Type := "ASTR"
            Else If (Parts1 = "TCHAR")
               Type := (A_IsUnicode ? "WSTR" : "ASTR")
         }
         If (Type = "ASTR") || (Type = "WSTR") {
            Len := Cnt * (Type = "WSTR" ? 2 : 1)
            Rep := ""
            Cnt := 1
         }
         Names := {}
         If InStr(Rep, ":") {
            StringReplace, Rep, Rep, %Cnt%:
            StringSplit, Name, Rep, `,
            If (Name0 = Cnt) {
               Loop, %Name0%
                  Names[Name%A_Index%] := A_Index
            }
         }
         FieldIndex++
         This._StructArr[FieldIndex] := {"Type": Type, "Pos": Pos, "Len": Len, "Cnt": Cnt, "Names": Names}
         Size += (Len * Cnt)
         If (Parts0 = 2)
            This._StructObj[Parts2] := FieldIndex
      }
      Align := (Align) && (Align < MaxLen) ? Align : MaxLen
      If (Pad := Mod(Size, Align))
         Size += Align - Pad
      If (Pointer <> "") {
         This._Ptr := Pointer
         This._Size := Size
      } Else {
         If (This.SetCapacity("_DllStruct", Size) <> Size)
            Return False
         This._Size := Size
         Ptr := This.GetAddress("_DllStruct")
         If !(Ptr)
            Return False
         This._Ptr := Ptr
         This._Alloc := True
      }
      This.Base := This._Base
      If This._Alloc
         This.Init()
   }
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

191 (изменено: Malcev, 2019-01-13 15:29:31)

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

Ответ на то, что для x32 надо перечислять все члены. На счет последней структуры ptr она не может быть ровна, так как возвращается ее копия. Последним идет не член структуры, а ее название (считать не надо).

192

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

Malcev пишет:

Ответ на то, что для x32 надо перечислять все члены.

А если их больше 31.

Malcev пишет:

На счет последней структуры ptr она не может быть ровна, так как возвращается ее копия.

Так как её считать.

Malcev пишет:

Последним идет не член структуры, а ее название (считать не надо).

DWORD        bV5Reserved; нее надо считать.

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

193

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

А их разве больше? Считать надо сумму ее членов.  Ресервед тоже учитывать.

194

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

Запутали друг друга, давай по порядку, с х32 потом.
Как считать CIEXYZTRIPLE bV5Endpoints, если это не Ptr, то сколько байт под него выделять и почему?

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

195 (изменено: serzh82saratov, 2019-01-13 17:07:24)

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

Malcev пишет:

Посчитаешь, можешь сравнить результат.

Перепутал колонку, думал 124 это смещение.
Значит размер 124.

serzh82saratov пишет:

Если считать CIEXYZTRIPLE как Ptr, то 92.

И DllStruct запускал под х32, под х64 выдаёт 104.

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

196 (изменено: serzh82saratov, 2019-01-13 23:07:45)

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

Размышления чайника:
Разные размеры из за того что размер Ptr зависит от битности.
Значит CIEXYZTRIPLE  = 36.

И DllStruct запускал под х32, под х64 выдаёт 104

Хотя нет, под х32 если 94, то под х64 должно быть 94+4=98.

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

197 (изменено: serzh82saratov, 2019-01-14 01:17:46)

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

Все кроме CIEXYZTRIPLE  занимают 88, CIEXYZTRIPLE это набор из 9 координат, координата = FLOAT. 88+9*4=124.


MagImageScalingCallback(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) { 
	Static BI_RGB := 0, CBM_INIT := 6, DIB_RGB_COLORS := 0
	
	bV5Width := NumGet(srcheader + 0, 0, "UInt")
	bV5Height := NumGet(srcheader + 0, 4, "UInt")
	
	VarSetCapacity(BITMAPV5HEADER, 124, 0) 
	
	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;
 
	hDC := DllCall("GetDC", A_PtrSize ? "UPtr" : "UInt", hwnd)
	
	hBMP := DllCall("CreateDIBitmap"
		, "Ptr", hDC
		, "Ptr", &BITMAPV5HEADER
		, "UInt", CBM_INIT
		, "Ptr", &srcdata
		, "UInt", ??????
		, "UInt", DIB_RGB_COLORS)
}

Не знаю насколько я тут вообще что то понял, теперь пытаюсь разобратся с:

https://docs.microsoft.com/en-us/window … tedibitmap

const BITMAPINFO       *pbmi,

Надо создать BITMAPINFO structure, только что в ней заполнять, какие то из полей.


	VarSetCapacity(BITMAPINFO, 44, 0) 
	
	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;
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

198 (изменено: serzh82saratov, 2019-01-14 01:49:06)

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

Впервые разобрался с апи!
Конечно не без советов и безграничного терпения от Malcev.
Осталось перевернуть картинку.


#NoEnv
#Persistent
#SingleInstance Force

OnExit, Uninitialize

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

Gui, +AlwaysOnTop -Caption +ToolWindow +HWNDhGui 
Gui, Show, x320 y0 w320 h240 NA, MagnifierWindowAHK

Global hPic
Gui 2: -Caption +AlwaysOnTop +ToolWindow
Gui, 2: Margin, 0,0  
Gui, 2: Add, text, w320 h240 0xE hwndhPic ; SS_BITMAP = 0xE 
Gui, 2: Show, x640 y0 NA

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

WS_CHILD := 0x40000000
WS_VISIBLE := 0x10000000
MS_SHOWMAGNIFIEDCURSOR := 0x1 
	
magHwnd := DllCall("CreateWindowEx"
	, "UInt", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "UInt",   MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE | WS_CHILD
	, "Int", 0
	, "Int", 0
	, "Int", 320
	, "Int", 240
	, "Ptr", hGui
	, "UInt", 0
	, "Ptr", hInstance
	, "UInt", 0)

DllCall("magnification\MagSetWindowFilterList","Ptr",magHwnd,"Int",0,"Int",1,"Ptr*", WinExist("ahk_class Notepad++"))  ;  MW_FILTERMODE_EXCLUDE

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

VarSetCapacity(rect, 16, 0)
NumPut(0, rect, 0, "int")
NumPut(0, rect, 4, "int")
NumPut(320, rect, 8, "int")
NumPut(240, rect, 12, "int")

Loop
	DllCall("magnification.dll\MagSetWindowSource", "ptr", magHwnd, 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)
		
		
	hBitmap := DllCall("CopyImage", Ptr, hBMP, "UInt", 0, "Int", 320, "Int", 240, "UInt", 0)
	
	SendMessage, STM_SETIMAGE, IMAGE_BITMAP, hBitmap,, ahk_id %hPic%
	
	DllCall("DeleteDC", Ptr, hDC)
	DllCall("DeleteObject", Ptr, hBMP)
	DllCall("DeleteObject", Ptr, hBitmap)
	return 1
}

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

АП: Память куда то утекает. (

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

199

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

Потому что не удаляешь битмап.
Из Gdi+:

SetImage(hwnd, hBitmap)
{
	SendMessage, 0x172, 0x0, hBitmap,, ahk_id %hwnd%
	E := ErrorLevel
	DeleteObject(E)
	return E
}

200

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

Точно, забыл. Оно как то не явно создаёт битмап. Под рукой был этот пример, в нём без DeleteObject с памятью всё нормально, но он не идёт под х64.


#SingleInstance Force
#NoEnv
  ;	https://autohotkey.com/board/topic/34232-for-gdi-experts-how-to-resample-image-to-produce-gradient/?p=216747
  
SetBatchLines, -1
; Process	Priority,,high

Hex2=
(Join
424D8600000000000000360000002800
00000500000005000000010018000000
00005000000000000000000000000000
0000000000000000800080FF00004000
80FF000080000080FF00004000008000
00400080FF000000400000800080FF00
0080000040000080FF00004000008000
00400080FF000000800080FF00004000
80FF00008000
)
Hex1=
(Join
424D8600000000000000360000002800
00000500000005000000010018000000
00005000000000000000000000000000
00000000000000008000008000004000
0080000080000000800000400080FF00
0040000080000000400080FF00008000
80FF000040000000800000400080FF00
00400000800000008000008000004000
008000008000
)

Hex=
(JOIN
424D5A000000000000003600000028000000030000000300000001001800000000002400000000000000000000
00000000000000000000004000008000004000000000008030B3F0000080000000000040000080000040000000
)
VarSetCapacity( BMP,(cLen:=StrLen(hex)//2))
Loop %cLen% 
	NumPut("0x" SubStr(hex,2*a_index-1,2),BMP,a_index-1,"char")

VarSetCapacity( BMP1,(cLen1:=StrLen(hex1)//2))
Loop %cLen1% 
	NumPut("0x" SubStr(hex1,2*a_index-1,2),BMP1,a_index-1,"char")

VarSetCapacity( BMP2,(cLen2:=StrLen(hex2)//2))
Loop %cLen2% 
	NumPut("0x" SubStr(hex2,2*a_index-1,2),BMP2,a_index-1,"char")

	
	
Hex=
Hex1=
Hex2=
DIB_PAL_COLORS := 1

Gui 1:-Caption +LastFound  
Gui, Margin, 0,0

GUI1:=WinExist() , hDC:=DllCall("GetDC",UInt,Gui1) 

Gui, Add, text, w640 h480 0xE vPic hwndhPic ; SS_BITMAP = 0xE 

hBMP := DllCall( "CreateDIBitmap", UInt,hDC, UInt,(bmiHAddr:=&BMP+14) 
,UInt,(CBM_INIT:=6), UInt,&BMP+NumGet(BMP,10), UInt,&BMP+14, UInt,(DIB_PAL_COLORS) )
hBitmap:=DllCall("CopyImage",UInt, hBMP,UInt,0,Int,640,Int,480, UInt,0)

hBMP1 := DllCall( "CreateDIBitmap", UInt,hDC, UInt,(bmiHAddr1:=&BMP1+14) 
,UInt,(CBM_INIT:=6), UInt,&BMP1+NumGet(BMP1,10), UInt,&BMP1+14, UInt,(DIB_PAL_COLORS) )
hBitmap1:=DllCall("CopyImage",UInt, hBMP1,UInt,0,Int,640,Int,480, UInt,0)

hBMP2 := DllCall( "CreateDIBitmap", UInt,hDC, UInt,(bmiHAddr2:=&BMP2+14) 
,UInt,(CBM_INIT:=6), UInt,&BMP2+NumGet(BMP2,10), UInt,&BMP2+14, UInt,(DIB_PAL_COLORS) )
hBitmap2:=DllCall("CopyImage",UInt, hBMP2,UInt,0,Int,640,Int,480, UInt,0)

SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBitmap,, ahk_id %hPic%
Gui, Show, w640 h480

Loop
{
	SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBitmap,, ahk_id %hPic%
	Sleep, 50
	SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBitmap1,, ahk_id %hPic%
	Sleep, 50
	SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBitmap2,, ahk_id %hPic%
	Sleep, 50
	SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBitmap1,, ahk_id %hPic%
	Sleep, 50
}
Return

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