Войти

Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 [128] 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

iglezz
27-01-2021, 14:46
утем тыка обнаружил, что адекватно себя ведет тест, если применить RequestExecutionLevel highest. »
Моя ошибка, давно в эту тему не влазил...

Но теперь мне не понятно какие привилегии потеряет установщик с RequestExecutionLevel highest в отличие от RequestExecutionLevel admin. »
Установщик - никаких, это пользовательское понятие.
В описании RequestExecutionLevel есть ссылка на статью MSDN (https://docs.microsoft.com/en-us/previous-versions/bb756929(v=msdn.10)?redirectedfrom=MSDN) с подробностями.
user == asInvoker
highest == highestAvailable

динозавра
30-01-2021, 13:31
Хотел подытожить. Для многих будет очень познавательно. Три рабочих примера.

Unicode true
OutFile "1-test.exe"
!Include "LogicLib.nsh"
RequestExecutionLevel highest
Function .onInit
System::Call setupapi::IsUserAdmin()i.r0
${If} $0 = 1
MessageBox MB_OK|MB_ICONINFORMATION "Есть права администратора"
${Else}
MessageBox MB_OK|MB_ICONINFORMATION "Нет прав администратора. До свидания !"
Quit
${EndIf}
FunctionEnd
Section
SectionEnd
Unicode true
OutFile "2-test.exe"
!Include "LogicLib.nsh"
RequestExecutionLevel highest
Function .onInit
System::Call setupapi::IsUserAdmin()i.r0
Pop $0
${If} $0 = "admin"
MessageBox MB_OK|MB_ICONINFORMATION "Нет прав администратора. До свидания !"
Quit
${EndIf}
MessageBox MB_OK|MB_ICONINFORMATION "Есть права администратора"
FunctionEnd
Section
SectionEnd
Unicode true
OutFile "3-test.exe"
!Include "LogicLib.nsh"
RequestExecutionLevel highest
Function .onInit
UserInfo::GetAccountType
Pop $1
${If} $1 == "Guest"
${OrIf} $1 == "User"
MessageBox MB_OK|MB_ICONINFORMATION "Нет прав администратора. До свидания !"
Quit
${EndIf}
MessageBox MB_OK|MB_ICONINFORMATION "Есть права администратора"
FunctionEnd
Section
SectionEnd
Эти примеры объединяет RequestExecutionLevel highest. По другому это совсем не работает.
Есть нюанс. В виста и семь с выключенным UAC - это когда системный настройщик уведомлений в крайнем нижнем положении и в восемь и десять с полностью выключенным UAC - это когда системный настройщик уведомлений в крайнем нижнем положении и нужные отключения в реестре.
В этом случае пользователи без прав не смогут запустить установщик, не двойным кликом, не от имени администратора. Как в ХР.
Если же системный настройщик уведомлений будет в другом положении, то пользователь без прав не сможет запустить установщик двойным кликом, но все же сможет запустить его от имени администратора.
Простыми словами: добиться Quit для пользователя без прав для установщика с большими привилегиями с включенным UAC не возможно. Исходя из того, что я написал эти коды на практике мало полезны. Зря потратил два дня на обобщение всего этого. Почему тогда этого нету в справке? Поправьте меня, если я ошибаюсь.

Iska
30-01-2021, 15:35
динозавра, может, потому, что это достаточно странные хотелки?

динозавра
30-01-2021, 16:10
Iska, Не понял вопроса? В чем странность? В том, что в справочнике устаревший код, который работает только в ХР и об этом ничего не указано? Или в том, что я хочу сделать установщик, который бы не запускался с малыми правами пользователя без всяких от имени? Или странность в том, что я первый об этом очень подробно написал?

iglezz
30-01-2021, 16:28
динозавра,
Во-первых, второй пример не работает, т.к. после System::Call setupapi::IsUserAdmin()i.r0 в стеке ничего не появится и дальнейшее не имеет смысла.
Если же системный настройщик уведомлений будет в другом положении, то пользователь без прав не сможет запустить установщик двойным кликом, но все же сможет запустить его от имени администратора. »
В любом положении и в любой оси и не сможет запустить? "Несите новую ось, эта сломана!"
Серьёзно -- или система криво затвикана, или в исходных данных где-то ошибки.
Простыми словами: добиться Quit для пользователя без прав для установщика с большими привилегиями с включенным UAC не возможно. Исходя из того, что я написал эти коды на практике мало полезны. Зря потратил два дня на обобщение всего этого. Почему тогда этого нету в справке? Поправьте меня, если я ошибаюсь. »
Чего именно нет в справке и какая справки имеется в виду?

Пока вижу, что выложенные скрипты для полноценного тестирования условий запуска и получаемых результатов не содержат.
Так-же подозреваю, что решать-то надо совсем другую задачу. Стоит её озвучить.

Ибо происходящее похоже на типичную XY-проблему.

Без шуток...

Когда решается одна задача

https://i.stack.imgur.com/r0Zal.png

Но на самом деле нужно решать другую

https://i.stack.imgur.com/coI7a.png (https://ru.meta.stackoverflow.com/questions/709/%D0%A7%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-%D0%9E%D1%88%D0%B8%D0%B1%D0%BA%D0%B0-%D0%BC%D0%BE%D0%BB%D0%BE%D1%82%D0%BA%D0%B0-%D0%B8%D0%BB%D0%B8-%D0%9E%D1%88%D0%B8%D0%B1%D0%BA%D0%B0-xy/710#710)

динозавра
30-01-2021, 18:12
iglezz,
Во-первых, второй пример не работает, т.к. после System::Call setupapi::IsUserAdmin()i.r0 в стеке ничего не появится и дальнейшее не имеет смысла.
Во-первых, я не знаю, чего должно появиться в стеке, но второй пример работает, точно как и первый и третий.
В любом положении и в любой оси и не сможет запустить? "Несите новую ось, эта сломана!"
Серьёзно -- или система криво затвикана, или в исходных данных где-то ошибки.
Тут меня извините, я не правильно выразился, а вы не правильно поняли. Системный настройщик уведомлений я тестировал на всех системах по умолчанию, на нескольких 32 и 64. Установщик по двойному клику запустится, но сработает, как и надо Quit. Но его просто можно запустить от имени и никакой Quit уже не сработает.
Чего именно нет в справке и какая справки имеется в виду?
В нашей справке. Не указано, что тот код, что там, и мои в том числе работают только в ХР, ну еще на других с полностью отключенным UAC. С включенным UAC по рекомендованному умолчанию любой бесправный пользователь от имени установит прогу или чего там. Нужно только паролить.
Юмор ценю. Спасибо.
Чуть не забыл, вот видео, как в стеке ничего не появляется и дальнейшее не имеет смысла https://streamable.com/9hr0vi

iglezz
30-01-2021, 20:34
Во-первых, я не знаю, чего должно появиться в стеке, но второй пример работает, точно как и первый и третий. »
Чуть не забыл, вот видео, как в стеке ничего не появляется и дальнейшее не имеет смысла https://streamable.com/9hr0vi »
Если стек пуст, то содержимое регистра останется неизменным. В обсуждаемом примере это так и только поэтому сия конструкция работает (повезло). Зато потом, по мере усложнения скрипта, запросто вылезут сюрпризы.

Тут меня извините, я не правильно выразился, а вы не правильно поняли. Системный настройщик уведомлений я тестировал на всех системах по умолчанию, на нескольких 32 и 64. Установщик по двойному клику запустится, но сработает, как и надо Quit. Но его просто можно запустить от имени и никакой Quit уже не сработает. »
Скрипт в любом случае работает как надо, но непонимание того, как оно работает в сочетании с неясным ТЗ даёт результат "не работает".

Для начала стоит конкретизировать условия (мини-ТЗ) и только потом уже подбирать решение.
Если будет необходимость продолжать реализацию на UserInfo/IsUserAdmin, то предварительно следует изучить вывод этих команд при разных условиях запуска без условий {If/Else} -- тупо вызвать, забрать значение и вывести его в DetailPrint/MessageBox).
А потом ещё, по-хорошему, следует проверить и наличие конкретных привилегий у пользователя (на запись в фс/реестр, ...) ...
Ради чего это всё? Оно точно надо?

Может всё-таки подобрать более популярное решение?

Юмор ценю. Спасибо. »
Этот юмор демонстрирует довольно серьёзную проблему, от которой и плодится велосипедостроение со всеми сопутствующими проблемами, выливающимися в "(Windows|Linux|MacOs|SomeSoftwareName) - глюкало|тормозило|отстой!"

динозавра
30-01-2021, 22:09
iglezz,
XY-проблема. Читал углубленно. (https://ru.meta.stackoverflow.com/questions/709/Что-такое-Ошибка-молотка-или-Ошибка-xy/710#710)
Напишу как было.
При неком разговоре один грамотный человек мне сказал следующее: "Для инсталлятора с высокими правами, который будет применяться в системах с включенным UAC не существует железного способа автоматической отмены установки, если пользователь оказался с малыми правами. Это закончилось в эпоху ХР".
Объяснять он не стал, господь не дал ему такой способности. Я насобирал в инете примеров авто отмены по привилегиям и решил доказать обратное. Но, увы все оказалось истинной. Потом я задал вопрос здесь, в надежде, что тут уже чего то придумали. Но тут началось обсуждение проблемы Y вместо X, на основе Z, почти не касаясь X.
Подтянутся знатоки с регалиями, и не прочитав или не поняв фразы, которую сказал мне один грамотный человек подытожат XY на основе Z. Проще говоря весь смысл сведется к "сам дурак".
Так что вопрос исчерпан.
ЗЫ. Если у меня с вами проблема XY происходит по недоразумению из-за моей глупости, то в мировой политике сплошь и рядом и преднамеренно. Это шутка. Общие Правила конференции не нарушены.

iglezz
31-01-2021, 00:57
динозавра,
При неком разговоре один грамотный человек мне сказал следующее: "Для инсталлятора с высокими правами, который будет применяться в системах с включенным UAC не существует железного способа автоматической отмены установки, если пользователь оказался с малыми правами. Это закончилось в эпоху ХР". »
Вот плохо, что человек объяснять не стал, ибо неточные формулировки могут допускать разночтения, ведущие к потерям времени на ненужные дискуссии и ковырялово в поисках информации/доказательной базы.
Конкретно эта формулировка не имеет смысла, т.к. в случае установщика, требующего админских прав, будет запрос UAC на старте. Прошёл - теперь права точно есть, установщик запускается и спокойно отрабатывает. А нестандартные сценарии должны быть головной болью админа системы, не сборщика установщика.
А в случае установщика, которому где-то внутри нужны админские права, проверка прав ведёт к всё тому-же UAC, т.к. до него о наличии прав у пользователя достоверно неизвестно.

Внутри установщика интересоваться админскими правами имеет смысл для ситуации, когда кроме обычной многопользовательской установки предлагается установка "только для текущего пользователя", установка портативки, и есть желание не дурить пользователю голову UAC'ом в этих случаях. Для этого есть в стандартной поставке плагин UAC.

Потом я задал вопрос здесь, в надежде, что тут уже чего то придумали. »
Не придумали, так как смысла велосипеды изобретать при наличии работающего механизма нет.
Но тут началось обсуждение проблемы Y вместо X, на основе Z, почти не касаясь X. »
Так часто случается в условиях недостатка конкретики...

динозавра
31-01-2021, 12:04
iglezz,
Так часто случается в условиях недостатка конкретики...
Я же написал, что вопрос исчерпан, а вы все философствуете. Не смогли услышать и понять, ну и ладно.
У вас не XY-проблема, а проблема начальника (https://youtu.be/GGBaeDAXNaI)
Философствуйте дальше.

K.A.V.
01-02-2021, 20:55
Ну вы даёте, ребята :o
Не в обиду будет сказано, но всё то, что выше описал динозавра о якобы некорректном коде с IsUserAdmin и RequestExecutionLevel прямо говорит о небольшом непонимании, как это всё работает.
Может, вся проблема в том, что человек просто не понимает, для чего нужно RequestExecutionLevel/манифест и что происходит, когда он "повышает" права через UAC (Запуск от имени)?

Простой пример:
Но его просто можно запустить от имени и никакой Quit уже не сработает. »
Конечно, "От имени" - это означает, что вы вышли из системы с ограниченными правами (Вы уже не Вася) и залогинились под другой учетной записью с правами админа (Вы уже Антон)
В нашей справке. Не указано, что тот код, что там, и мои в том числе работают только в ХР, ну еще на других с полностью отключенным UAC. С включенным UAC по рекомендованному умолчанию любой бесправный пользователь от имени установит прогу или чего там. Нужно только паролить. »
Всё работает правильно, просто вы не понимаете, как это работает ;)

Всё же достаточно просто, на мой взгляд
RequestExecutionLevel прописываем тот уровень прав на старте приложения (грубо говоря, это контролирует система, сразу понимая, кто перед ней и что ему нужно), который нам необходим для выполнения всех операций. Если вы делаете установку серьёзного ПО с записью в системные папки - то без повышенных прав вам не обойтись

Вы просто неправильно понимаете смысла запуска приложения через UAC (Запуск от имени администратора) и как это отразится на уровне скрипта и работе пакета установки
Вся соль в том, что когда вы повышаете права через UAC (или прописываете в скрипте RequestExecutionLevel admin), то вы можете забыть про своего "оригинального" пользователя в скрипте, под которым работаете (его имени пользователе и типе учетной записи), по-крайней мере голыми средствами NSIS вы не узнаете правды о запустившем инсталлятор (но есть но (в конце ;)))

На пальцах:
1. Вася (не админ) => RequestExecutionLevel user => В скрипте: Вася (IsUserAdmin == 0)
2. Вася (не админ) => RequestExecutionLevel admin => В скрипте: Антон (IsUserAdmin == 1)

Не понимаю, зачем такое (опять же) извращение с определением типа учетной записи/закрытие инсталлера и т.д. (вы точно установщик пишите?)
Т.к. нормальные установщики "без задних мыслей" никогда не стесняются попросить ОС дать ей чуточку привилегий, чтобы избавить всех от лишних проблем и правильной установки ПО

Можно, конечно, попробовать пойти другим путём и повышать права самостоятельно через ShellExecEx, запоминать от имени какой учетной записи был изначально запущен процесс установки.
Но выглядит это довольно странно :)

1. RequestExecutionLevel user
2. !include ".\ShellExecEx.nsh"
3. Распаковть ShellExecEx.nsh в папку со своим скриптом установщика
4. При запуске установщика определяем тип учетной записи и имя пользователя, если нужно для дальнейших извращений - где-нибудь сохраняем
5. В нужном месте запускаем сами себя с просьбой о повышении прав
${ShellExecEx} $0 'runas' '"$EXEPATH"' '' '' '' 2
Дальше делайте что хотите...Закрывайте оригинальный процесс под Васей не админом, проверяйте статус процесса и т.д.

Могу предположить, что такой метод, как вариант, может использоваться в установщике, где только 1 выборочный компонент из 10 требует повышения прав и не всегда необходимо тыкать пользователю о необходимости админских прав

Или я тут жути нагнал и не понял, о чем вы? :dont-know

Iska
01-02-2021, 22:25
…то вы можете забыть про своего "оригинального" пользователя в скрипте, под которым работаете (его имени пользователе и типе учетной записи), »
…кроме случая, когда этот пользователь и так принадлежит группе, имеющей административные привилегии. Тогда, на положительный ответ на запрос UAC, будет просто повышение привилегий текущего пользователя до административных без смены аккаунта на другой.


3. Антон (админ) => RequestExecutionLevel admin => В скрипте: Антон (IsUserAdmin == 1) — так должно работать?

K.A.V.
01-02-2021, 22:41
3. Антон (админ) => RequestExecutionLevel admin => В скрипте: Антон (IsUserAdmin == 1) — так должно работать? »
Да, я просто описывал ситуацию при работе в ограниченной учетной записи :)

Iska
01-02-2021, 22:54
K.A.V., спасибо, ясно.

Kopejkin
02-02-2021, 17:16
Не могу сообразить! Подскажите, пожалуйста.
Нужно найти строку, например, 127.0.0.1 www.somesite.net в файле hosts и если строка существует, выполнить действие не связанное ни с найденной строкой, ни с самим файлом.

Begin2Fly
02-02-2021, 17:41
Не могу сообразить! Подскажите, пожалуйста.
Нужно найти строку, например, 127.0.0.1 www.somesite.net в файле hosts и если строка существует, выполнить действие не связанное ни с найденной строкой, ни с самим файлом. »
Вот этот (https://nsis.sourceforge.io/Search_for_text_in_file) код работает. Искать лучше без 127.0.0.1, потому что может использоваться другой адрес. Можно, конечно, попроще переписать или поискать, но этот я проверял.

MKN
04-02-2021, 12:00
Можно, конечно, попроще переписать »
Да уж, там портянка из кода ещё та... :)
Лучше использовать NewTextreplace плагин (поддерживает utf-8, utf-16LE / BE и все ANSI) :
OutFile "NewTextReplaceTest.exe"
!include "NewTextReplace.nsh"

Section
${textreplace::FindInFile} "$EXEDIR\my_file.txt" "слово" "/S=1" $0 ; /S=1 С учетом регистра (быстрее)
MessageBox MB_OK "$0" ; если 1 - слово найдено
${textreplace::Unload}
SectionEnd
В плагине ещё много полезных функций и ключей.

MKN
05-02-2021, 13:35
Подскажите пожалуйста, как лучше (и попроще) реализовать такую задачу ? :

На кастомной странице есть созданное новое окно или область ListBox + разные элементы (чекбоксы, кнопки...).
Необходимо, при наведении указателя мыши или курсора на какой либо элемент(например на чекбокс) послать в это окно или ListBox(отобразить в нём) некую информацию (из переменной) на время "наведения" (если указатель перемещён с элемента, инфа исчезает).
Нечто по аналогии с выводом ToolTips, только не во всплывающем окне, а в имеющемся.

ps Попутно вопрос - в ToolTip плагинах (ToolTips.dll или nsTips от kotkovets ) всплывающее сообщение через некоторое время закрывается-исчезает. Можно ли этого избежать ? (Т.е., пока курсор или указатель мыши находятся на элементе, сообщение "удерживается" на месте.)

динозавра
05-02-2021, 15:37
K.A.V., здравствуйте. Спасибо за разложенный по полочкам ответ. Все просто и в доступной форме.
Я сумел связаться с человеком из-за фразы, которого произошел весь этот сыр - бор. Напомню ее:
"Для инсталлятора с высокими правами, который будет применяться в системах с включенным UAC не существует железного способа автоматической отмены установки, если пользователь оказался с малыми правами. Это закончилось в эпоху ХР".
Я дал ссылку на мои попытки объяснить.

Вот его ответ. В начале были смайлы смеха:

"Настаиваю! Невозможно сделать установщик с высокими правами с предоставленными примерами кодов , чтобы запустил его бесправный пользователь при включенном UAC и всплыло инф. сообщение "Нет прав администратора. До свидания !", после которого последовала бы команда quit и произошло завершение. Такое с включенным UAC сделать не возможно. Система переберет права на себя и чихать она хотела на ваше написанное MessageBox MB_OK "Нет прав администратора. До свидания !" и следующее за ним quit. Такой фокус закончился в ХР. Ты в теме не верно задал вопрос, следовательно получил множество толкований не по сути. А суть я выше описал. Тебе должны были кратко ответить, что никакого сообщения и завершения с включенным UAC не будет. Точка. А тебе начали рассказывать о принципах работы контроля учетных записей.
Я сейчас "на пальцах" тебе докажу, что те коды не рабочие и рабочие. В зависимости, что подразумевать под термином "рабочие".
И так.
Первый пример. Если ты в код пишешь проверку на "бесправного" с сообщением и завершением, а "бесправный" с включенным UAC сообщение не увидит, и завершение не произойдет значит код не исполнил записанные в нем действия. Код не рабочий. Точка.
Второй пример. Если ты в код пишешь проверку на "бесправного" с сообщением и завершением и система правильно определила "бесправного", но проигнорировала заложенное в коде сообщение и завершение, тем самым дав возможность продолжить установку от админа, с условием, что запись админа не под паролем. Система предусмотрела, что админ с отсутствием пароля может доверять "бесправному". Код рабочий. Точка.
Умная система игнорирует примитивный код."


Лично я все понял. Действительно доступно и без высоких материй. А я считал, что этот человек совсем не умеет объяснять. Вопрос закрыт.

K.A.V.
06-02-2021, 09:34
На кастомной странице есть созданное новое окно или область ListBox + разные элементы (чекбоксы, кнопки...).
Необходимо, при наведении указателя мыши или курсора на какой либо элемент(например на чекбокс) послать в это окно или ListBox(отобразить в нём) некую информацию (из переменной) на время "наведения" (если указатель перемещён с элемента, инфа исчезает).
Нечто по аналогии с выводом ToolTips, только не во всплывающем окне, а в имеющемся. »
Вообще, там надо вроде как всё ловить в OnNotify функции для конкретного элемента (nsDialogs), но, честно признаться, давно уже "не в теме" и отловить там у меня не получилось
Могу предложить вариант с помощью создания функции с таймером, в которй будем определять положение курсора и решать, что делать дальше, в зависимости от того, над каким элементом сейчас находится курсор

ps Попутно вопрос - в ToolTip плагинах (ToolTips.dll или nsTips от kotkovets ) всплывающее сообщение через некоторое время закрывается-исчезает. Можно ли этого избежать ? (Т.е., пока курсор или указатель мыши находятся на элементе, сообщение "удерживается" на месте.) »
Насчет плагинов не скажу, но можно напрямую в NSIS запихнуть (один фиг ты будешь курсор отслеживать на элементах ;))


!include "nsDialogs.nsh"
!include "MUI2.nsh"
!include "LogicLib.nsh"
!include "WinMessages.nsh"

Name nsDialogs
OutFile nsDialogs.exe
RequestExecutionLevel user
ShowInstDetails show

Var Dialog

Var hwnd_Text # хэндл текстового поля
var hwnd_Button # хэндл кнопки, над которой отслеживаем курсор
var onMouseOverFuncAddr # адрес функции, которая будет выполняться при отслеживании курсора
var ttip

Page custom pgPageCreate pgPageLeave
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"


##########################################
# ToolTip
##########################################
!define WS_POPUP 0x80000000
!define TTF_SUBCLASS 0x010
!define /math TTM_ACTIVATE ${WM_USER} + 1
!define /math TTM_ADDTOOL ${WM_USER} + 4
!define /math TTM_SETTOOLINFO ${WM_USER} + 9
!define /math TTM_TRACKACTIVATE ${WM_USER} + 17

Function ShowToolTip
StrCpy $2 $ttip
System::Call 'USER32::IsWindowVisible(ir2)i.r0'
${If} $0 == 0
pop $1
StrCpy $2 ""
${If} $ttip = 0
System::Call 'USER32::CreateWindowEx(i${WS_EX_TOPMOST},t"tooltips_class32",i,i${WS_POPUP},i,i,i,i,i0,i,i,i)i.r2'
StrCpy $ttip $2
${EndIf}
FindWindow $3 "#32770" "" $HWNDPARENT
System::Call '*(i40,i${TTF_SUBCLASS},i$3,i0x408,i,i,i,i,i0,tr1)i.r1'
SendMessage $ttip ${TTM_ADDTOOL} 0 $1
SendMessage $ttip ${TTM_SETTOOLINFO} 0 $1
SendMessage $ttip ${TTM_ACTIVATE} 1 0
SendMessage $ttip ${TTM_TRACKACTIVATE} 1 $1
System::Free $1
${EndIf}
FunctionEnd
##########################################
# ToolTip
##########################################


Function my_onMouseOver # функция с выполнением по таймеру, здесь можно отслеживать курсор на всех элекемнтах диалога
; получаем координаты курсора
System::Alloc 16
Pop $0
System::Call USER32::GetCursorPos(ir0)
System::Call *$0(i.r1,i.r2)
System::Free $0
System::Call USER32::WindowFromPoint(ir1,ir2)i.r1
; в переменной $1 теперь хэндл элемента, над которым курсор

${If} $1 = $hwnd_Button
${NSD_SetText} $hwnd_Text "Курсор над кнопкой"
push "мой текст в tooltip"
call ShowToolTip
${Else}
${NSD_SetText} $hwnd_Text "Курсор вне кнопки"
SendMessage $ttip ${TTM_ACTIVATE} 0 0
${EndIf}

FunctionEnd


Function .onInit
GetFunctionAddress $onMouseOverFuncAddr my_onMouseOver ; получаем адрес функции, которая будет выполняться по таймеру для отслеживания курсора
FunctionEnd


Function pgPageCreate
nsDialogs::Create 1018
Pop $Dialog

${If} $Dialog == error
Abort
${EndIf}

${NSD_CreateText} 30% 10u 40% 15u "..."
Pop $hwnd_Text

${NSD_CreateButton} 30% 50u 40% 12u "Кнопочка"
Pop $hwnd_Button

nsDialogs::CreateTimer $onMouseOverFuncAddr 100 ; создаём таймер для отслеживания курсора

nsDialogs::Show
FunctionEnd

Function pgPageLeave
FunctionEnd

Section
SectionEnd


ps
Красоту и качество кода не гарантирую, уж простите, давно этим не занимался




© OSzone.net 2001-2012