1 (изменено: belyankin12, 2019-03-07 12:36:02)

Тема: AHK: Определение размеров элементов Dx9 overlay

Здравствуйте, недавно начал работать над решением вопроса перемещения элементов, создаваемых Dx9 overlay API поверх полноэкранных приложений с помощью курсора мыши. В целом решение найти удалось, концепция работает отлично, однако скрипту известны только начальные координаты элементов и соответственно я могу отталкиваться только от них, в создании области, нажатие в которой будет считаться за выбор элемента (общая концепция у меня работает через сравнение координат курсора в момент удержания и координат элементов - для ясности) и потому, если выбрать элемент в середине скрипт не сможет определить нажатие, т.к. размеры, например, текстовых элементов могут быть разные и создание одинаковой области вокруг каждого элемента будет нерентабельно. Потому возникла необходимость определять конечную координату элементов. Я использую только два типа элементов: текст и картинки, для начала нужно с ними разобраться. Собственно два вопроса:
1) Как определить разрешение изображения? И если например разрешение изображения 800х600 оно и на экране должно занимать 800 по X и 600 по Y единиц места верно? Желательно варианты без сторонних библиотех (не критично) и GUI (чтобы непосредственно перед помещением изображения на экран определять все необходимое).
2) На этот вопрос не обязательно отвечать. Размер текста я определил таким образом: создавал 11 одинаковых элементов (большие и маленькие буквы, спец. символы по отдельности, знаки препинания по отдельности) и на глаз наводил курсор на конец 10-го из них (11 там находился для наглядной поправки на кернинг), таким образом я выцепил примерную ширину в пикселях всех текстовых элементов. Есть ли более надежный метод определения размера? Я планирую постоянно использовать шрифт Times New Roman и размер 10 или 8 у элемента (однако я не уверен, что размер этот в пунктах).

Рассчитываю на вашу помощь.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

2

Re: AHK: Определение размеров элементов Dx9 overlay

Спросите у evilC на оффоруме.
Наверняка он в теме.

3

Re: AHK: Определение размеров элементов Dx9 overlay

belyankin12 пишет:

Как определить разрешение изображения?

Разрешение бывает у экрана, у изображения размеры.

belyankin12 пишет:

И если например разрешение изображения 800х600 оно и на экране должно занимать 800 по X и 600 по Y единиц места верно?

Нет, у экрана ещё есть масштабироание, если 1:1, тогда размер будет соответствовать.
Ничего не знаю про Dx9, но если исходное изображение находится в файле либо у нас есть его hBitmap, тогда определить размер не составит проблем.

Чтобы определить размер текста, нужны исходные данные — шрифт, его размер, его вид (normal, bold, italic), его толщина и как будут переноситься слова, если всё это известно, тогда тоже не проблема.

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

4

Re: AHK: Определение размеров элементов Dx9 overlay

Почему-то мне казалось, что хотя бы на первый вопрос я смогу найти ответ здесь, второй понятно, что без опыта в этом деле будет довольно трудно на него ответить. Загляну туда как-нибудь.

P.S. У этого пользователя закрытый ЛС что-ли, или нужно новым пользователям "разблокировать" функцию ЛС?

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

5

Re: AHK: Определение размеров элементов Dx9 overlay

Не уверен, что писать личные сообщения по поводу помощи в AHK хорошая идея, лучше просто на форуме вопрос задайте.

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

6 (изменено: belyankin12, 2019-03-07 16:14:54)

Re: AHK: Определение размеров элементов Dx9 overlay

teadrinker, изображение представляет собой файл на жестком диске в формате PNG (эти картинки буду создавать в фотошопе, потому не будет такого, что файл это jpg переименованный в png проводником) и если я правильно понял про масштабирование (что это программный параметр, который в моем случае будет задаваться скриптом, что помещает изображение) - то соотношение 1:1. Шрифт Times New Roman bold italic, размер 10 или 8 (только два варианта буду использовать). Но вот я не уверен что это размер в пунктах, есть какая идея как определить (функция помещающая текст зашита в dll файле, там посмотреть не смогу)? Переноса не будет, все в одну строку, толщина всегда одинаковая (какая неизвестно , но в параметрах она нигде не упоминается - полагаю стандартная величина).

P.S. Понял насчет ЛС.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

7

Re: AHK: Определение размеров элементов Dx9 overlay

Чтобы проверить, что за размеры у шрифта, просто добавьте текст в с этими данными в GUI и посмотрите, будет ли размер в окне соответствовать видимому на экране. Размер картинки, два варианта:

filePath := "D:\pic.png"
if oSize := _GetImageSize(filePath)
   MsgBox, % oSize.W . "`n" oSize.H

if oSize := GetImageSize(filePath)
   MsgBox, % oSize.W . "`n" oSize.H

_GetImageSize(imageFilePath)  {
   Gui, New
   Gui, Add, Pic, hwndhPic, % imageFilePath
   DetectHiddenWindows, On
   WinGetPos,,, PicW, PicH, ahk_id %hPic%
   Gui, Destroy
   Return { W: PicW, H: PicH }
}

GetImageSize(imageFilePath)  {
   if !hBitmap := LoadPicture(imageFilePath, "GDI+")  {
      MsgBox, Не удалось получить hBitmap
      Return
   }
   VarSetCapacity(BITMAP, size := 4*4 + A_PtrSize*2, 0)
   DllCall("GetObject", Ptr, hBitmap, Int, size, Ptr, &BITMAP)
   DllCall("DeleteObject", Ptr, hBitmap)
   Return { W: NumGet(BITMAP, 4, "UInt"), H: NumGet(BITMAP, 8, "UInt") }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8 (изменено: belyankin12, 2019-03-07 17:43:13)

Re: AHK: Определение размеров элементов Dx9 overlay

Методом подбора (текст в DX9 оказался ни чуть не italic) и линеечкой определил что самое близкое значение для размера 10 в DX9 является bold s17 в GUI, дальше что делать? Скрин: http://prntscr.com/mulr46. Размер картинки через битмап определяется отлично, только вопрос такой, чего не надо делать с картинкой чтобы битмап этот потерялся у неё и все сломалось?

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

9

Re: AHK: Определение размеров элементов Dx9 overlay

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

String = Unilaya Pora O4ey O4arovanie

Gui, ToolTipWindow:New, -Caption +ToolWindow +LastFound
Gui, ToolTipWindow:Default
Gui, Font, s17 bold cBlue, Times New Roman
Gui, Margin, 0, 0
Gui, Color, 0xFFFFE1
Gui, Add, Text,, % String
Gui, Show, y100

WinGetPos,,, W, H
MsgBox, % "Ширина окна " W "`nВысота окна " H
Gui, Destroy

if dim := GetTextSize(String, "Times New Roman", "s17 bold")
   MsgBox, % "Ширина текста " . dim.w . "`nВысота текста " . dim.h
ExitApp

GetTextSize(String, FontName, Options)
{
   static SIZE
   coding := A_IsUnicode ? "W" : "A"
   LOGPIXELSY := 90
   FW_NORMAL := 400, FW_BOLD := 700
   DEFAULT_CHARSET := 1
   DEFAULT_QUALITY := OUT_DEFAULT_PRECIS := CLIP_DEFAULT_PRECIS := 0

   if !RegExMatch(Options, "i).*s(\d+).*", Found)
   {
      MsgBox, Не задан размер шрифта!
      Return
   }
   s := Found1

   if !InStr(Options, "bold")
   {
      if !RegExMatch(Options, "i).*w(\d+).*", Found)
         w := FW_NORMAL
      Else
         w := Found1
   }
   Else
      w := FW_BOLD
   if w not Between 1 and 1000
   {
      MsgBox, Неверно задан параметр w.`nДолжен быть в пределах от 1 до 1000
      Return
   }

   italic    := InStr(Options, "italic") > 0
   underline := InStr(Options, "underline") > 0
   strike    := InStr(Options, "strike") > 0

   hDC := DllCall("GetDC", UInt, 0, Ptr)

   nHeight := -DllCall("MulDiv", Int, s
                  , Int, DllCall("GetDeviceCaps", Ptr, hDC, Int, LOGPIXELSY), Int, 72)
   hFont := DllCall("CreateFont" . coding
                                , Int, nHeight, Int, 0
                                , Int, 0, Int, 0, Int, w
                                , UInt, italic, UInt, underline, UInt, strike
                                , UInt, DEFAULT_CHARSET, UInt, OUT_DEFAULT_PRECIS
                                , UInt, CLIP_DEFAULT_PRECIS, UInt, DEFAULT_QUALITY
                                , UInt, 0, Str, FontName, Ptr)

   hPrevObj := DllCall("SelectObject", Ptr, hDC, Ptr, hFont, Ptr)

   VarSetCapacity(Buf, 40)
   DllCall("GetTextFace" . coding, Ptr, hDC, Int, 40, Str, Buf)
   if (Buf != FontName)
   {
      FreeMemory(hPrevObj, hDC, hFont)
      MsgBox, Указанный шрифт не поддерживается системой!
      Return
   }

   VarSetCapacity(RC, 16, 0)
   height := DllCall("DrawText", Ptr, HDC, Str, String, Int, StrLen(String), Ptr, &RC, UInt, DT_CALCRECT := 0x400)
   width := NumGet(RC, 8, "Int") - NumGet(RC, "Int")
   FreeMemory(hPrevObj, hDC, hFont)
   Return {w: width, h: height}
}

FreeMemory(hPrevObj, hDC, hFont)
{
   DllCall("SelectObject", Ptr, hDC, Ptr, hPrevObj)
   DllCall("ReleaseDC", UInt, 0, Ptr, hDC)
   DllCall("DeleteObject", Ptr, hFont)
}

Первый вариант в окне просто для сравнения.

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

10

Re: AHK: Определение размеров элементов Dx9 overlay

teadrinker, спасибо за помощь, завтра испытаю на деле.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

11 (изменено: belyankin12, 2019-03-10 15:18:56)

Re: AHK: Определение размеров элементов Dx9 overlay

Завтра испытаю на деле, сказал я, позабыв что 8 марта день рабства для меня . Сейчас проверил - область определения была гораздо больше реальной, причем увеличивалась она линейно с увеличением длины текста. Потом я вспомнил что этот API не дружит с разрешениями экрана отличными чем 800х600, потому применил формулу 800*ширина текста/1920 и вот теперь область достаточно идеальная для моих целей (полагаю, что текст с большим количеством спец. символов теряет в своей ширине примерно 10-20 пикселей, для примера использовал этот)

Oasdflkajdlaksdjaslkdjsal dlkajsldk asdasdpa poa spod \[pasd  |\\ \ \ \as ds \ \s dd s/  / ds/ /  ds d\s ds\ ds \ds \d s\ ; на последнем /ds заканчивается область

ибо я все равно не планирую использовать слишком длинные строки с огромным количеством символов. Хотя все равно любопытно почему так (кстати GUI выдает несколько большую ширину конкретно этого текста чем функция с DllCall - я полагаю функция с GUI надежнее?). В любом случае огромное Вам спасибо!

P.S. Кстати интересует ваше мнение, это вообще нормально что ширина одного и того же текста  на разных разрешениях будет разной?

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

12

Re: AHK: Определение размеров элементов Dx9 overlay

Чем выше разрешение, тем меньше ширина текста. Если бы размер шрифта был  подобран правильно, точнее было бы с DllCall.

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

13

Re: AHK: Определение размеров элементов Dx9 overlay

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

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.