View previous topic :: View next topic |
Author |
Message |
AkulaBig
Joined: 03 Dec 2008 Posts: 338
|
(Separately) Posted: Sat Jun 21, 2025 22:32 Post subject: |
|
|
Orion9 wrote: | Чем меньше пользовательских кнопок, тем больше пустого, зияющего пространства справа, что само по себе некрасиво, на мой взгляд. |
Можно конечно все стандартные иконки показать. Но ведь мне потом с этим работать. Сборка-то у меня рабочая, а не на выставку. И так некоторые иконки я раз в год использую.
Orion9 wrote: | По той же причине верхнее меню должно иметь больше пунков |
Это мое принципиальное значение - никакого расширенного меню.
Orion9 wrote: | пустое пространство заголовка ТС просто само просит, чтобы его чем-то заполнили. |
Ну это-же у меня сделано. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Sat Jun 21, 2025 23:26 Post subject: |
|
|
Orion9 wrote: | Ну как там багофиксы продвигаются, конец виден? |
Последние три недели как-то не было возможности всем этим заниматься. Но DllCall и Callback исправил, ориентировочно завтра выложу минорную версию. |
|
Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 784
|
(Separately) Posted: Sun Jun 22, 2025 00:31 Post subject: |
|
|
AkulaBig wrote: | Можно конечно все стандартные иконки показать. |
Да нет. Дело не в стандартных иконках, а в том, что кнопок накопилось много за годы использования, особенно в последнее время. А стандартных иконок на всей панели у меня может процентов 10 от общего количества, не больше.
AkulaBig wrote: | Это мое принципиальное значение - никакого расширенного меню. |
А я бы не спешил. Многие программы в своем интерфейсе используют такую фишку, как "режим эксперта" и "режим простого пользователя", и это, на мой взгляд, правильно. Если бы я делал публичную сборку, я бы точно использовал такой подход. Но поскольку я делаю только для себя, то у меня всего одно расширенное меню как раз на пол экрана )
Loopback wrote: | DllCall и Callback исправил, ориентировочно завтра выложу минорную версию. |
Класс. Спасибо. Ждём.
Loopback wrote: | - узнать, включены ли значки
- узнать их размер
- получить панель, над которой находится курсор (ItemAtCursor)
- получить хэндл панели (RequestInfo)
- получить координаты этой панели (WinGetPos)
- вычислить прямоугольник, где может находиться курсор, с помощью размера значка
- получить координаты курсора (MouseGetPos)
- проверить, находится ли курсор в границах прямоугольника |
Нет, всё-таки не мог я дать такому алгоритму пропасть. Немного сделал по-другому, но основная идея та же.
Code: | If FieldIndex = 1 Then
Local x, y, w, h, mx, my
Local hWnd = RequestInfo(ItemAtCursor("panel"))
WinGetPos("", "", "w", "h", hWnd)
If w > 0 Then
MouseGetPos("x","y")
Static buf = Buffer(8) # POINT
buf.Zero()
buf.SetNum(0, "long", x, "long", y)
DllCall("ScreenToClient", "hwnd", hWnd, "ptr", buf.ptr)
x = buf.GetNum(0)
MediaInfoNum = 1
Switch Round(x/w*100,0)
Case 1 To 10
b_CTRL = 1
b_SHIFT = 1
Case 10 To 90
b_CTRL = 1
Case 90 To 100
MediaInfoNum = 4
EndSwitch
EndIf |
Как видите, строк совсем немного, но какой эффект! Я бы назвал это волшебным хинтом ) Панель делится на три части. Первые 10% слева выводят один хинт, 80% посередине выводят второй, последние 10% справа - третий. Счастью нет предела.
Строка If FieldIndex = 1 Then из тела рабочей функции JointHint, полный код которой привести не могу, так как он сильно завязан на множество других функций. Но для работоспособности любого кода необходимые параметры нужно задать в Switch...EndSwitch. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Sun Jun 22, 2025 18:51 Post subject: |
|
|
Версия Autorun 2.2.19.1 beta
* обновленная версия китайского перевода и справки
- исправлена проблема DllCall с вызовом функции по адресу на x64
* реорганизация и чистка старого кода в работе функций
- DllCall не работала при указании полного пути библиотеки
- исправлена работоспособность Callback с двумя и более параметрами
На полную версию пока изменений не хватает 
Last edited by Loopback on Tue Jun 24, 2025 13:17; edited 2 times in total |
|
Back to top |
|
 |
yozhik

Joined: 04 May 2014 Posts: 257 Location: Электросталь
|
(Separately) Posted: Sun Jun 22, 2025 21:11 Post subject: |
|
|
Loopback wrote: | На полную версию пока изменений не хватает |
Добавьте StrRegexReplace  _________________ Amo ergo sum |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Sun Jun 22, 2025 23:10 Post subject: |
|
|
yozhik
Регэкспы в todo  |
|
Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 784
|
(Separately) Posted: Mon Jun 23, 2025 00:32 Post subject: |
|
|
Loopback wrote: | На полную версию пока изменений не хватает |
Зато хватает, чтобы потестировать объект Callback )
 Hidden text Code: | RegisterCommand 60025 "WindowTest"
Static hWnd = 0
Const PBM_SETPOS = 1026, _
PBM_SETRANGE = 1025, _
PBS_MARQUEE = 0x08, _
PBM_SETMARQUEE = 1034
Const TD_WARNING_ICON = 65535, _
TD_ERROR_ICON = 65534, _
TD_INFORMATION_ICON = 65533, _
TD_SHIELD_ICON = 65532
Const TDCBF_OK_BUTTON = 1, _
TDCBF_YES_BUTTON = 2, _
TDCBF_NO_BUTTON = 4, _
TDCBF_CANCEL_BUTTON = 8, _
TDCBF_RETRY_BUTTON = 0x10, _
TDCBF_CLOSE_BUTTON = 0x20
Global g_WndProc, g_Task = 0
Global oWP = Callback("TestWinProc", "hwnd;uint;wparam;lparam")
Func WindowTest()
RunThread WinTest
EndFunc
Func TestWinProc(hWnd, uMsg, wParam, lParam)
Static WM_CLOSE = 0x0010
#OutputDebugString("Autorun: " & uMsg)
If uMsg = WM_CLOSE Then
If DllCall("DestroyWindow", "handle", hWnd) Then
g_Task = 0
EndIf
Return 0
EndIf
Return DllCall("CallWindowProcW", _
"ptr", g_WndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndFunc
Func WinTest()
If hWnd > 0 Then
If WinGetState(1, hWnd) Then
SendMessage(hWnd, 0x0010, 0, 0)
Return
EndIf
hWnd = 0
Endif
hWnd = DllCall("CreateWindowExW", _
"dword", 0, _
"wstr", "msctls_progress32", _
"wstr", "", _
"dword", 0x10C80000, _
"int", 200, "int", 100, "int", 300, "int", 50, _
"handle", AUTORUN_TCHANDLE, _
"handle", 0, "handle", 0, "ptr", 0, _
"handle")
If hWnd = 0 Then Return
g_WndProc = DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hWnd, _
"int", -4, _
"long_ptr", oWP.Ptr)
#DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), "hwnd", hWnd, "int", -16, "long_ptr", 0x10C00000)
hIco = SendMessage(AUTORUN_TCHANDLE, 0x7f, 2, 0)
SendMessage(hWnd, 0x80, 0, hIco)
WinSetStyle(PBS_MARQUEE, 2, hWnd)
WinSetText("Estimating...", hWnd)
g_Task = 1
SendMessage(hWnd, PBM_SETMARQUEE, 1, 0)
For i = 1 to 15
Sleep(100)
If g_Task = 0 Then Break
Next
If g_Task > 0 Then
SendMessage(hWnd, PBM_SETMARQUEE, 0, 0)
WinSetStyle(PBS_MARQUEE, 4, hWnd)
SendMessage(hWnd, PBM_SETPOS, 0, 0)
For i = 1 to 10
SendMessage(hWnd, PBM_SETPOS, i*10, 0)
WinSetText("Processed " & i*10 & "%", hWnd)
Sleep(300)
If g_Task = 0 Then Break
Next
EndIf
If g_Task = 0 Then
MsgBox("Операция прервана", "", 48)
Else
If DllCall("DestroyWindow", "handle", hWnd) Then hWnd = 0
MsgBox("Операция успешно завершена", "", 64)
EndIf
EndFunc
|
Сделано, конечно, немножко криво, но это только для теста. Всё работает. Однако TCx64 при вызове WindowTest валится. В чём может быть проблема?
Также сделал функцию на волшебный хинт в целях демонстрации, но TCx64 при его вызове тоже валится, хотя в 32-битной версии всё работает. Валится на третьем шаге, т.е. на вызове функции из DLL по адресу, а не по имени:
 Hidden text Code: | Func MagicHint(FileName, FieldIndex, UnitIndex)
Local bCaps = DllCall("GetKeyState", "int", 0x14, "short")
Local b_CTRL = BitAND(bCaps, 1), b_Shift = IsPressed(0x10)
If Not b_CTRL then b_CTRL = IsPressed (0x11)
If Not b_CTRL Then Return
Static Pipe, Idx = 0, _
sPath = COMMANDER_PATH & "\Ini\Tools\Libs\", _
sLang ="file://" & sPath & "ru.csv", _
sHint ="file://" & sPath & "hint.txt", _
sLib = "MediaInfo" & (auX64 ? "" : "_i386") & ".dll", _
hLib = DllCall("LoadLibrary", "Wstr", sPath & sLib, "Ptr"), _
pNew, pOpen, pDel, pOpt, pInfo
OutputDebugString("Autorun: 1")
If hLib = 0 And FieldIndex > 1 Then Return
If FieldIndex = 1 Then
If hLib = 0 Then Return "Error LoadLibrary " & sLib
Idx = 0
pNew = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_New", "Ptr")
pOpen = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Open", "Ptr")
pDel = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Delete", "Ptr")
pOpt = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Option", "Ptr")
pInfo = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Inform", "Ptr")
OutputDebugString("Autorun: 2")
Local hMI = DllCall(pNew, "Ptr")
If hMI = 0 Then Return "MediaInfo_New couldn't create new object"
OutputDebugString("Autorun: 3")
If DllCall(pOpen, 'Ptr', hMI, "Wstr", FileName, "Uint") <> 1 Then
DllCall(pDel, "Ptr", hMI)
Return "MediaInfo_Open couldn't open file " & FileName
EndIf
OutputDebugString("Autorun: 4")
Local x, y, w, bHint = 0
Local hWnd = RequestInfo(ItemAtCursor("panel"))
WinGetPos("", "", "w", "", hWnd)
If w > 0 Then
MouseGetPos("x","y")
Static buf = Buffer(8) # POINT
buf.Zero()
buf.SetNum(0, "long", x, "long", y)
DllCall("ScreenToClient", "hwnd", hWnd, "ptr", buf.ptr)
x = buf.GetNum(0)
Switch Round(x/w*100,0)
Case 1 To 10
b_SHIFT = 1
Case 10 To 90
Case 90 To 100
bHint = true
EndSwitch
EndIf
DllCall(pOpt, 'Ptr', hMI, "Wstr", "Language", "Wstr", sLang, "Wstr")
If b_Shift Then
DllCall(pOpt, 'Ptr', hMI, "Wstr", "Complete", "Wstr", "1", "Wstr")
Else
DllCall(pOpt, 'Ptr', hMI, "Wstr", "Complete", "Wstr", "0", "Wstr")
EndIf
If bHint Then
DllCall(pOpt, "Ptr", hMI, "Wstr", "Output", "Wstr", sHint, "Wstr")
Else
DllCall(pOpt, "Ptr", hMI, "Wstr", "Output", "Wstr", "", "Wstr")
EndIf
Pipe = DllCall(pInfo, 'Ptr', hMI, "Uint", 0, "Wstr")
DllCall(pDel, "Ptr", hMI)
If IsPressed(0x5B) Then Idx = 50
Endif
Return TrimSpaces(StrPart(Pipe, auLF, FieldIndex + Idx))
EndFunc |
А так всё работает. Код стал более компактным и чистым. Для работы требуется прописать в autorun.cfg поля:
 Hidden text Code: | Pragma AutorunPluginFields "C1:::MagicHint" "C2:::MagicHint" "C3:::MagicHint" "C4:::MagicHint" "C5:::MagicHint" "C6:::MagicHint" "C7:::MagicHint" "C8:::MagicHint" "C9:::MagicHint" "C10:::MagicHint" "C11:::MagicHint" "C12:::MagicHint" "C13:::MagicHint" "C14:::MagicHint" "C15:::MagicHint" "C16:::MagicHint" "C17:::MagicHint" "C18:::MagicHint" "C19:::MagicHint" "C20:::MagicHint" "C21:::MagicHint" "C22:::MagicHint" "C23:::MagicHint" "C24:::MagicHint" "C25:::MagicHint" "C26:::MagicHint" "C27:::MagicHint" "C28:::MagicHint" "C29:::MagicHint" "C30:::MagicHint" "C31:::MagicHint" "C32:::MagicHint" "C33:::MagicHint" "C34:::MagicHint" "C35:::MagicHint" "C36:::MagicHint" "C37:::MagicHint" "C38:::MagicHint" "C39:::MagicHint" "C40:::MagicHint" "C41:::MagicHint" "C42:::MagicHint" "C43:::MagicHint" "C44:::MagicHint" "C45:::MagicHint" "C46:::MagicHint" "C47:::MagicHint" "C48:::MagicHint" "C49:::MagicHint" "C50:::MagicHint" "C51:::MagicHint" "C52:::MagicHint" "C53:::MagicHint" "C55:::MagicHint" "C55:::MagicHint" "C56:::MagicHint" "C57:::MagicHint" "C58:::MagicHint" "C59:::MagicHint" "C60:::MagicHint" |
И две вспомогательные функции:
 Hidden text Code: | Func TrimSpaces(String)
Local a, b
If Not StrPos(String, ":") Then Return String
a = StrPart(String, ":", 1)
b = StrPart(String, ":", 2) & StrPart(String, ":", 3)
Return StrTrim(a) & ": " & FixCP(StrTrim(b))
EndFunc
Func FixCP(String)
If MediaInfoLock = 0 Then Return String
Local bUsedRepl
Local nSize = StrLen(String)
Local buf = Buffer(nSize)
buf.Zero()
# iso-8859-1 = 28591
DllCall("WideCharToMultiByte", _
"uint", 28591, _
"dword", 0, _
"wstr", String, _
"int", -1, _
"ptr", 0, _
"int", 0, _
"ptr", 0, _
"bool*", @bUsedRepl)
If bUsedRepl Then Return String
DllCall("WideCharToMultiByte", _
"uint", 28591, _
"dword", 0, _
"wstr", String, _
"int", -1, _
"ptr", buf.ptr, _
"int", nSize, _
"ptr", 0, _
"ptr", 0)
Local fixed = buf.GetStr(0, nSize, "ANSI")
Free(buf)
Return fixed
EndFunc
|
А также файл hint.txt положить в папку MediaInfo и путь в скрипте поменять:
 Hidden text Code: | General;Name: %FileName%.%FileExtension%\r\nSize: %FileSize/String4%\r\n[Duration: %Duration%]\r\n[Duration: %Duration/String1%]\r\n[Duration: %Duration/String5%]\r\n[General: %BitRate/String%][(%BitRate_Mode%)][, %Format%][(%Format/Family%)]$if(%Cover%,\, Cover)[, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Channel(s)%ch][, %Resolution/String%][, %FrameRate/String%][, %SamplingRate/String%][, %Bits-(Pixel*Frame)%bpf][, %Language%]\r\n
Video;Video #%StreamKindID%: [%Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Resolution/String%][, %FrameRate/String%][, %BitRate/String%][(%BitRate_Mode%)][, %Bits-(Pixel*Frame)%bpf][, %Format%][(%Format/Family%)][, %Language%][, %Channel(s)%ch][, %SamplingRate/String%]\r\n
Audio;Audio #%StreamKindID%: [%Channel(s)%ch][, %Resolution/String%][, %SamplingRate/String%][, %BitRate/String%][(%BitRate_Mode%)][, %Format%][(%Format/Family%)][, %Format_Profile%][, %Language%][, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %FrameRate/String%][, %Bits-(Pixel*Frame)%bpf]\r\n
;
Text;Text #%StreamKindID%: %Format%[(%Format/Family%)][@%Language%][, %StreamSize/String4%][, %BitRate/String%][(%BitRate_Mode%)][, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Channel(s)%ch][, %Resolution/String%][, %FrameRate/String%][, %SamplingRate/String%][, %Bits-(Pixel*Frame)%bpf]\r\n
Chapters;Chapters #%StreamKindID%: %Format%[(%Format/Family%)][@%Language%][, %Total% entries][, %StreamSize/String4%][, %BitRate/String%][(%BitRate_Mode%)][, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Channel(s)%ch][, %Resolution/String%][, %FrameRate/String%][, %SamplingRate/String%][, %Bits-(Pixel*Frame)%bpf]\r\n
;
Image;Image #%StreamKindID%: [%Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Resolution/String%][, %FrameRate/String%][, %StreamSize/String4%][, %BitRate/String%][(%BitRate_Mode%)][, %Bits-(Pixel*Frame)%bpf][, %Format%][(%Format/Family%)][, %Language%][, %Channel(s)%ch][, %SamplingRate/String%]\r\n
;
Menu;Menu #%StreamKindID%: [%MenuID/String%][, %Duration% Format:%Format/String%]
; |
Будут вызываться три разные подсказки в зависимости от позиции указателя на панели. Но данные подсказки выбраны только в качестве демонстрации, на самом деле подсказки могут быть совершенно любыми. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Mon Jun 23, 2025 13:06 Post subject: |
|
|
Orion9 wrote: | В чём может быть проблема? |
Надо указать тип возвращаемого значения c размером указателя (ptr, long_ptr) для вызова SetWindowLong, сейчас возвращается int, что не подходит для x64. |
|
Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 784
|
(Separately) Posted: Mon Jun 23, 2025 13:52 Post subject: |
|
|
Loopback wrote: | сейчас возвращается int, что не подходит для x64 |
Точно! Торопился, пропустил. Но хорошо, что это мелкая ошибка никак не связанная с плагином.
Теперь бы ещё вот с этим разобраться:
Code: | pNew = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_New", "Ptr")
Local hMI = DllCall(pNew, "Ptr") |
Возможно на второй строчке ТСх64 падает.
Я еще попробовал сабклассинг подсказки сделать через SetClassLong, но что-то он не работает:
Code: | Local hTip = WinFind(0, "TToolTip")
g_WndProc = DllCall("SetClassLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hTip, _
"int", -24, _
"long", oWP.Ptr, "ptr")
OutputDebugString("g_WndProc=" & g_WndProc & " oWP.Ptr=" & oWP.Ptr) |
Вообще такое впечатление, что Гислер мониторит адрес оконной процедуры в классе и возвращает значение по умолчанию при его изменении. Хотя в этом я плохо разбираюсь, так что далеко идущих выводов делать, пожалуй, не стоит. Но если повесить на ControlSetHint /F /D:50 28
 Hidden text Code: | Func ButtonBarTestHint()
Local hTip = WinFind(0, "TToolTip")
g_WndProc = DllCall("SetClassLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hTip, _
"int", -24, _
"long", oWP.Ptr, "ptr")
OutputDebugString("g_WndProc=" & g_WndProc & " oWP.Ptr=" & oWP.Ptr)
Local hDC = DllCall("GetWindowDC", "ptr", hTip, "ptr")
hIco = SendMessage(AUTORUN_TCHANDLE, 0x7f, 2, 0)
Local x, y, w, h
WinGetPos("x", "y", "w", "h", hTip)
DllCall("DrawIconEx", _
"ptr", hDC, _
"int", 10, _
"int", 10, _
"ptr", hIco, _
"int", 16, _
"int", 16, _
"uint", 0, _
"ptr", 0, _
"uint", 0x0003)
DllCall("ReleaseDC", "ptr", AUTORUN_TCHANDLE, "ptr", hDC)
WinSetPos(100, "", "", "", 1, hTip)
EndFunc
|
То видно, как подсказка с прорисованной иконкой меняет позицию, а затем исчезает и заменяется новой дефолтной подсказкой. Странное какое-то поведение.
Добавлено спустя 8 минут:
Я имею в виду, что после вызова SetClassLong, который вроде срабатывает:
Code: | Func ButtonBarTestHint()
Local hTip = WinFind(0, "TToolTip")
g_WndProc = DllCall("SetClassLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hTip, _
"int", -24, _
"long", oWP.Ptr, "ptr") |
Нет входа в оконную процедуру TestWinProc:
Code: | Global g_WndProc
Global oWP = Callback("TestWinProc", "hwnd;uint;wparam;lparam")
Func TestWinProc(hWnd, uMsg, wParam, lParam)
Static WM_CLOSE = 0x0010
OutputDebugString("Autorun: " & uMsg)
If uMsg = WM_CLOSE Then
If DllCall("DestroyWindow", "handle", hWnd) Then
g_Task = 0
EndIf
Return 0
EndIf
Return DllCall("CallWindowProcW", _
"ptr", g_WndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndFunc |
С вызовом SetWindowLong это работает. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Mon Jun 23, 2025 19:58 Post subject: |
|
|
Orion9 wrote: | Возможно на второй строчке ТСх64 падает |
Да, что-то я пропустил это сообщение. Действительно, неправильно преобразовывался передаваемый адрес под x64. Не стал делать новую версию, заменил во вчерашней, все равно сайт забыл обновить.
Orion9 wrote: | Я еще попробовал сабклассинг подсказки сделать через SetClassLong, но что-то он не работает |
Видимо потому, что подсказка Autorun не использует TToolTip, в основе лежит static. Впрочем, SetClassLong и не сработает, поскольку меняет параметры класса для окон, которые будут созданы после её использования, а ControlSetHint создает окно подсказки один раз при первом запуске. |
|
Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 784
|
(Separately) Posted: Tue Jun 24, 2025 00:30 Post subject: |
|
|
Loopback wrote: | Не стал делать новую версию, заменил во вчерашней |
Теперь всё работает и в 64-битной версии, класс! А с вызовом функций по адресам теперь ещё и быстрее должно быть, хотя визуально это сложно отличить.
Loopback wrote: | подсказка Autorun не использует TToolTip, в основе лежит static |
Да, я видел. Ещё по этому поводу хотел спросить у вас, как вы расчет размеров окна делаете, но не стал лишний раз донимать ) Ведь текст static можно легко заменить через WinSetText, например:
Code: | Local hWnd = LAST_HINT_WINDOW
If hWnd > 0 Then
If WinGetState(1, hWnd) Then
WinSetText("Тест...." & auCRLF & "Загрузка"& auCRLF & "Загрузка....", hWnd)
WinSetPos("", "", "", 50, 2, hWnd)
WinRedraw(2, hWnd)
EndIf
Endif |
А вот изменить размер окна под новый текст уже сложнее. Здесь с метрикой шрифта надо заморачиваться, как пишут на сайте microsoft:
Но с вызовом SetClassLong я хотел добиться другого, если это, конечно, вообще возможно.
Я хотел как раз вот этого:
Loopback wrote: | SetClassLong... меняет параметры класса для окон, которые будут созданы после её использования |
Я хотел поменять оконную функцию у гислеровской подсказки, т.е. у всего класса подсказок, называющихся TToolTip. Как я понял, гислеровская подсказка - это обычное дочернее окно, в которое он рисует текст функцией TextOut, превращая его в растровое изображение. Извлечь из этого какую-то пользу вряд ли возможно при таком раскладе, но я просто хотел посмотреть, будет ли работать сабклассинг с функцией обратного вызова, установленной через SetClassLong, хотя это не так важно.
Зато проверил Callback на диалоге задач )
 Hidden text Code: | RegisterCommand 60027 "TaskDialogIndirect"
Global TASK_THREAD = 0
Global oTaskWinProc = Callback("TaskWinProc", "hwnd;uint;wparam;lparam;long_ptr")
Func TaskWinProc(hWnd, Msg, wParam, lParam, lpRefData)
If Msg = 0 Then
RunThread("ProgressMove", hWnd)
Return 1
EndIf
If Msg = 2 Then
If wParam = 4 Then
If TASK_THREAD > 0 Then
TASK_THREAD = 0
Return 1
EndIf
RunThread("ProgressMove", hWnd)
Return 1
Else
If TASK_THREAD > 0 Then TASK_THREAD = 0
Return 0
EndIf
EndIf
EndFunc
Func ProgressMove(hWnd)
TASK_THREAD = 1
Local sMsg = "Initializing...", buf = Buffer(64)
buf.SetStr(sMsg & Chr(0))
SendMessage(hWnd, 1127, 1, 0)
SendMessage(hWnd, 1131, 1, 0)
SendMessage(hWnd, 1138, 0, buf.ptr)
For i = 1 to 30
Sleep(100)
If i = 7 Then
sMsg = "Processing..."
ElseIf i = 20 Then
sMsg = "Finishing..."
EndIf
If i = 7 Or i = 20 Then
buf.SetStr(sMsg & Chr(0))
SendMessage(hWnd, 1138, 0, buf.ptr)
EndIf
If TASK_THREAD = 0 Then Break
Next
sMsg = "Content"
buf.SetStr(sMsg & Chr(0))
SendMessage(hWnd, 1138, 0, buf.ptr)
Free(buf)
SendMessage(hWnd, 1131, 0, 0)
SendMessage(hWnd, 1127, 0, 0)
SendMessage(hWnd, 1130, 0, 0)
If TASK_THREAD = 0 Then
MsgBox("Операция прервана", "", 48)
Else
MsgBox("Операция успешно завершена", "", 64)
EndIf
TASK_THREAD = 0
EndFunc
Func TaskDialogIndirect()
If auX64 Then
MsgBox("Unsupported version","",48)
Return
EndIf
Local hRes, bn
Local buf = Buffer(96)
Local sTitle = "Title"
Local sInstr = "Instruction"
Local sContn = "Content"
Local sExpand = "Expanded text"
Local sFooter = "Autorun " & FileGetVersion(AUTORUN_PATH & "\Autorun.wdx", "FileVersion")
Local ttl = Buffer(StrLen(sTitle)*2+2), _
ins = Buffer(StrLen(sInstr)*2+2), _
con = Buffer(StrLen(sContn)*2+2), _
exp = Buffer(StrLen(sExpand)*2+2), _
ftr = Buffer(StrLen(sFooter)*2+2)
ttl.SetStr(sTitle & Chr(0))
ins.SetStr(sInstr & Chr(0))
con.SetStr(sContn & Chr(0))
exp.SetStr(sExpand & Chr(0))
ftr.SetStr(sFooter & Chr(0))
buf.Zero()
buf.SetNum(0, "uint", buf.size, _
"hwnd", AUTORUN_TCHANDLE, _
"handle", 0, _
"dword", 0x0408, _
"dword", 21, _
"ptr", ttl.ptr, _
"ptr", 65535, _
"ptr", ins.ptr, _
"ptr", con.ptr, _
"uint", 0, _
"ptr", 0, _
"int", 0, _
"uint", 0, _
"ptr", 0, _
"int", 0, _
"ptr", 0, _
"ptr", exp.ptr, _
"ptr", 0, _
"ptr", 0, _
"ptr", 65533, _
"ptr", ftr.ptr, _
"ptr", oTaskWinProc.ptr, _
"long_ptr", 0, _
"uint", 0)
hRes = DllCall("TaskDialogIndirect", _
"ptr", buf.ptr, _
"int*", @bn, _
"int*", 0, _
"bool*", 0)
EndFunc
|
Поскольку под x64 нужно отдельно структуру высчитывать, я не стал с этим заморачиваться. Но на 32-битном ТС всё отлично работает. Прикольный муляж, кстати, получился )
Так что Callback нормально работает. Спасибо за багофикс. Это открывает теперь большие возможности. |
|
Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1535
|
(Separately) Posted: Tue Jun 24, 2025 13:16 Post subject: |
|
|
Orion9 wrote: | Здесь с метрикой шрифта надо заморачиваться, как пишут на сайте microsoft: |
Верно, шрифт необходимо учитывать. Для расчёта в функции DrawText есть замечательный флаг DT_CALCRECT. Перед расчётом нужно для DC с SelectObject выбрать шрифт, который будет использоваться для отрисовки.
Orion9 wrote: | Как я понял, гислеровская подсказка - это обычное дочернее окно, в которое он рисует текст функцией TextOut, превращая его в растровое изображение. |
TToolTip - похоже что самописный контрол подсказки, т.к. в дельфи такого класса нет. Как именно и на основе чего он сделан и как отрисовывается не знаю, но принципы везде одинаковы.
Orion9 wrote: | Прикольный муляж, кстати, получился ) |
Да, симпатично выглядит. |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|