Данная статья продолжает серию постов о продукте VMProtect Integration Kit (VMPKit).
В первой части были рассмотрены функции-обертки WinAPI, упрощающие работу с подсистемой UAC, функции VMPKit для управления хранением лицензий, сервисные функции для API VMProtect, упрощающие работу с ним, и некоторые другие вспомогательные функции.
В данной части будет рассмотрена подсистема протоколирования VMPKit, реализованная для упрощения отладки процесса активации приложений.
Подсистема VMPKit GUI предоставляет несколько функций, упрощающих использование Shell-диалогов WinAPI для выбора файла для сохранения, выбора файла для записи и выбора каталога.
Также в данной части будет описана часть API VMPKit, которая реализует графический интерфейс активации приложения, ввод серийного номера, и отображает гибко настраиваемый диалог «О Программе»
Содержание
- Протоколирование
- Флаги, используемые при открытии лога
- Инициализация и закрытие
- Запись сообщений
- Пример лог-файла, содержащий сведения о системе
- Обертки для shell-функций WinAPI
- Флаги shell-функций
- Флаги функций VMPIK_OpenFileDialog/VMPIK_SaveFileDialog
- Флаги функции VMPIK_BrowseForFolder
- Флаги, общие для всех shell-функций
- Shell-Функции VMPKit
- Флаги shell-функций
- Подсистема GUI
- Скриншоты диалогов
- Флаги диалога активации
- Коды возврата диалоговых функций активации
- Функция VMPIK_ParseSerialNumberFormat
- Функция VMPIK_InputSerialNumberDlg
- Функция VMPIK_ActivateAppDlg
- Функция VMPIK_ActivateAppDlgEx
- Диалог «О Программе»
- Флаги диалога «О Программе»
- Функция диалога «О Программе»
- Функция-хелпер для масштабного коэффициента
Отмазка aka disclaimer
VMPKit является молодым продуктом, и нельзя говорить, что он доведен до совершенства. Если вы обнаружите в нем недоработки или ошибки, пожалуйста, не спешите оставлять гневные комментарии, попробуйте с начала связаться с нами для устранения проблемы.
О данном руководстве
Данная статья является в настоящий момент наиболее полным руководством/справочником по VMPKit. Документация на официальном сайте vmpkit.com в настоящее время отстает по полноте и детализации от данной статьи.
Протоколирование
Подсистема протоколирования VMPKit спроектированна прежде всего для протоколирования действий пользователя и реакции VMPKit, происходящих в процессе активирования приложения, но может быть использована и в других частях программного обеспечения, использующего VMPKit. Подсистема протоколирования является однопоточной и в многопоточном окружении ею следует пользоваться с осторожностью. Подсистема протоколирования спроектированна с учетом возможности протоколировать процесс активации при активации приложения из инсталляционной setup-программы.
Флаги, используемые при открытии лога
VMPIK_LOG_DEFAULT
— значение флагов по умолчанию.VMPIK_LOG_OVERWRITE
— указывает, что при открытии лог-файла его содержимое следует перезаписать. Используется при вызове функцииVMPIK_LogCreate
. Если не указаны флагиVMPIK_LOG_OVERWRITE
иVMPIK_LOG_APPEND
и файл с заданным именем существует, открытие лог-файла завершится ошибкой.VMPIK_LOG_APPEND
— указывает, что при открытии лог-файла новое содержимое будет добавляться в конец существующего файла. Используется при вызове функцииVMPIK_LogCreate
. Если не указаны флагиVMPIK_LOG_OVERWRITE
иVMPIK_LOG_APPEND
и файл с заданным именем существует, открытие лог-файла завершится ошибкой.VMPIK_LOG_APPPATH
— данный флаг указывает использовать путь к исполняемому файлу приложения, если путь не задан аргументом функцииVMPIK_LogCreateTemporary
.VMPIK_LOG_EXTRACTPATH
— данный флаг указывает, что путь, заданный аргументом функцииVMPIK_LogCreateTemporary
на самом деле является именем файла, и путь к лог-файлу необходимо извлечь из указанного полного имени файла. Данную возможность удобно использовать, когда необходимо создать лог-файл в том же каталоге, что и какой-либо другой файл с известным именем.
Инициализация и закрытие
HANDLE VMPIKAPI VMPIK_LogRelease( );
Функция VMPIK_LogRelease
возвращает хэндл лог-файла и очищает внутренние структуры, связанные с протоколированием, не закрывая лог-файл.
BOOL VMPIKAPI VMPIK_LogClose( );
Функция VMPIK_LogClose
закрывает лог-файл и очищает внутренние структуры, связанные с протоколированием.
BOOL VMPIKAPI VMPIK_LogSetHandle( HANDLE hLogFile );
Функция VMPIK_LogSetHandle
устанавливает хэндл лог-файла и инициализирует внутренние структуры, связанные с протоколированием.
BOOL VMPIKAPI VMPIK_LogCreate( DWORD dwFlags, LPCTWSTR lpszLogFile );
Функция VMPIK_LogCreate
создает лог-файл с именем lpszLogFile
в соответствии со значениями флагов dwFlags
.
BOOL VMPIKAPI VMPIK_LogCreateTemporary( DWORD dwFlags, LPCTSTR lpszLogFilePath, LPCTSTR lpszLogFileNamePrefix, LPCTSTR lpszLogFileNameExt, UINT n, LPTSTR filenameBuf, UINT fnBufSize );
Функция VMPIK_LogCreateTemporary
создает временный файл с именем вида «$PATH$PREFIX$NNNN.$EXT», где $NNNN — параметр n
, оформатированный как 4х-разрядное шестнадцатеричное число. Если такой файл существует, то значение n
будет увеличиваться до тех пор, пока не будет создан новый файл или пока число попыток не превысит 65536.
Если параметр lpszLogFilePath
задан как 0 (или указывает на пустую строку), и не заданны флаги VMPIK_LOG_APPPATH
и VMPIK_LOG_EXTRACTPATH
, то будет использоваться путь для временных файлов, который возвращает функция WinAPI GetTempPath
.
Функция VMPIK_LogCreateTemporary
может возвращать имя созданного лог-файла, если задан параметр filenameBuf
.
Запись сообщений
BOOL VMPIKAPI VMPIK_LogWriteString( LPCSTR str );
Функция VMPIK_LogWriteString
производит запись строки в лог-файл. Каждый символ перевода строки 'n' преобразуется в последовательность «rn». После каждого перевода строки в начало новой строки добавляется текущее время. Рекомендуется производить запись строк в виде «nSome message to log» вместо «Some message to logn»; в лог файле строка будет выглядет так — «[2014/03/09 16:18:24] Some message to log»
Unicode версия функции VMPIK_LogWriteString
предварительно перекодирует строку в Ansi кодировку.
BOOL VMPIKAPIV VMPIK_LogPrint( LPCTSTR fmt, ... );
Функция VMPIK_LogPrint
осуществляет форматный вывод в лог-файл.
void VMPIKAPI VMPIK_LogWriteSysInfo();
Функция VMPIK_LogWriteSysInfo
записывает в лог-файл основные сведения о системе и о приложении.
[2014/03/10 21:00:55] Application version: 1.2.3.4
[2014/03/10 21:00:55] Windows version: 6.1/x64, Service Pack 1
[2014/03/10 21:00:55] CPU: 4 X x64
[2014/03/10 21:00:55] Memory: 8155 Mb, used: 55%
[2014/03/10 21:00:55] Is User Administrator: Yes
[2014/03/10 21:00:55] Is Run as Administrator: No
[2014/03/10 21:00:55] Is Process Elevated: No
[2014/03/10 21:00:55] Process Integrity Level: MEDIUM
[2014/03/10 21:00:55] Default Virtualization Status: Enabled
Обертки для shell-функций WinAPI
Если использование функции GetOpenFileName для отображения диалогов сохранения и открытия файлов не слишком сложно, то уже использование SHBrowseForFolder представляет некоторую трудность, с учетом ее различного поведения даже под Windows 2000 и Windows XP.
В современных ОС Windows (Windows Vista+) в Microsoft отошли от использования этих функций, и для отображения аналогичных диалогов предлагают использовать COM-интерфейсы IFileOpenDialog и IFileSaveDialog, при этом отображаемые диалоги довольно сильно отличаются внешним видом от диалогов из предыдущих версий Windows.
Современные GUI-библиотеки в основном предоставляют упрощающие жизнь обертки над shell-функциями, но в каждом случае надо уточнять вопрос с совместимостью с различными версиями Windows. Также возможна ситуация, когда разработка ведется в старых системах разработки с использованием устаревших SDK (например, Delphi 5-7), или необходимо минимизировать использование GUI-библиотек, но хочется, хотя бы частично, придать приложению современный вид, и/или автоматически выбирать вид отображаемых диалогов в зависимости от версии Windows. Последнее требование, так же как и необходимость минимизации использования GUI-библиотек, как раз и имело место быть при создании GUI VMPKit, и было решено вынести эти функции в публичный интерфейс VMPKit.
Еще одним аргументом за использование shell-функций VMPKit является то, что COM-интерфейсы IFileOpenDialog и IFileSaveDialog не имеют версий, работающих с Ansi-строками, и добавление диалогов в стиле Vista+ в старое ANSI-приложение дополнительно затруднено.
Еще одной не слишком важной, но полезной функцией является функция отображения MessageBox'а без звукового сигнала — в случае, если при показе MessageBox'а используется флаг, указывающий использовать какую-либо иконку, стандартная WinAPI функция MessageBox выдает звуковой сигнал. Иногда хочется этого избежать и отключить вывод звука совсем или сделать его вывод опционально.
Флаги shell-функций
Флаги функций VMPIK_OpenFileDialog/VMPIK_SaveFileDialog
VMPIK_OSFD_HIDEREADONLY
— скрывает чекбокс «только для чтения». Соответствует флагу WinAPIOFN_HIDEREADONLY
. Используется по умолчанию, в отличие отOFN_HIDEREADONLY
. Не используется в Vista+.VMPIK_OSFD_NOHIDEREADONLY
— отображает чекбокс «только для чтения». Отменяет действие флагаVMPIK_OSFD_HIDEREADONLY
. Не используется в Vista+.VMPIK_OSFD_OVERWRITEPROMPT
— выводит запрос на перезапись файла, если он уже существует. Соответствует флагу WinAPIOFN_FILEMUSTEXIST
.VMPIK_OSFD_FILEMUSTEXIST
— файл с указанным именем должен существовать. Соответствует флагу WinAPIOFN_FILEMUSTEXIST
.VMPIK_OSFD_ALLOWMULTISELECT
— позволяет выбирать несколько файлов одновременно. Соответствует флагу WinAPIOFN_ALLOWMULTISELECT
.VMPIK_OSFD_NOCHANGEDIR
— запрещает смену каталога. Соответствует флагу WinAPIOFN_NOCHANGEDIR
. Не действует дляVMPIK_OpenFileDialog
.VMPIK_OSFD_PATHMUSTEXIST
— указывает, что пользователь должен вводить только имена существующих файлов и каталогов. Соответствует флагу WinAPIOFN_PATHMUSTEXIST
.
Флаги функции VMPIK_BrowseForFolder
VMPIK_OSFD_NONEWDIALOGSTYLE
— соответствует флагу WinAPIBIF_NEWDIALOGSTYLE
. Не используется в Vista+.VMPIK_OSFD_NONEWFOLDERBUTTON
— соответствует флагу WinAPIBIF_NONEWFOLDERBUTTON
. Не используется в Vista+.VMPIK_OSFD_INCLUDEFILES
— соответствует флагу WinAPIBIF_BROWSEINCLUDEFILES
. Не используется в Vista+.
Флаги, общие для всех shell-функций
VMPIK_OSFD_FORCESHOWHIDDEN
— задает опцию показа скрытых файлов и папок вне зависимости от настроек системы. Соответствует флагу WinAPIOFN_FORCESHOWHIDDEN
.VMPIK_OSFD_ADDTORECENT
— указывает, что выбранный файл/папку следует добавить в список часто используемых.VMPIK_OSFD_CLASSICDIALOG
— принудительно отображает диалоги в классическом стиле (W2K/WinXP).
Shell-Функции VMPKit
INT VMPIKAPI VMPIK_SilentMessageBoxEx( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, BOOL bSilent );
INT VMPIKAPI VMPIK_SilentMessageBox ( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
Вышеприведенные функции полностью аналогичны функции WinAPI MessageBox, но в одной версии вывод звука является опциональным, в другой — отключен совсем.
BOOL VMPIKAPI VMPIK_OpenFileDialog( HWND hWndParent, DWORD osfdFlags, LPCTSTR lpszDialogTitle, LPCTSTR lpszDefExt, LPCTSTR lpszFilter, LPCTSTR lpszInitialDir, LPTSTR lpszFilenameBuf, DWORD dwBufSize, /*out*/ DWORD *pFilterIndex );
Функция VMPIK_OpenFileDialog
отображает диалог открытия файла. Можно задать заголовок и каталог, который будет выбран изначально.
BOOL VMPIKAPI VMPIK_SaveFileDialog( HWND hWndParent, DWORD osfdFlags, LPCTSTR lpszDialogTitle, LPCTSTR lpszDefExt, LPCTSTR lpszFilter, LPCTSTR lpszInitialDir, LPTSTR lpszFilenameBuf, DWORD dwBufSize, /*out*/ DWORD *pFilterIndex );
Функция VMPIK_SaveFileDialog
отображает диалог сохранения файла. Можно задать заголовок и каталог, который будет выбран изначально.
BOOL VMPIKAPI VMPIK_BrowseForFolder(HWND hWndParent, DWORD osfdFlags, LPCTSTR lpszDialogTitle, LPCTSTR lpszInitialDir, LPTSTR lpszFilenameBuf, DWORD dwBufSize, LPTSTR lpszDisplayBuf, DWORD dwDisplaySize );
Функция VMPIK_BrowseForFolder
отображает диалог выбора папки. Можно задать заголовок и каталог, который будет выбран изначально. Помимо пути к выбранному каталогу, может возвращать его отображаемое название, если задан параметр lpszDisplayBuf
. Так, для каталога «C:UserAll UsersDocuments» отображаемое название будет — «Общие документы».
Подсистема GUI
VMPKit содержит несколько функций для отображения диалогов: простой диалог ввода серийного номера; диалог активации, поддерживающий различные способы активации; диалог «О Программе», поддерживающий различные режимы отображения.
Скриншоты диалогов
Флаги диалога активации
Диалог активации является очень гибко настраиваемым. Для настройки диалога активации используются одновременно два способа: 1) задание соответствующих значений аргументов при вызове диалоговых функций, и задание флагов диалога активации. В некоторых случаях эти способы могу дополнять друг друга.
VMPIK_AADF_ACTIVATE_SERIAL
— включает возможность активации при помощи серийного номера (кода активации). При отображении диалога активации одна из двух опций:VMPIK_AADF_ACTIVATE_SERIAL
илиVMPIK_AADF_ACTIVATE_KEY_FILE
должна быть включена.VMPIK_AADF_ACTIVATE_KEY_FILE
— включает возможность активации при помощи ключевого файла лицензии. При отображении диалога активации одна из двух опций:VMPIK_AADF_ACTIVATE_SERIAL
илиVMPIK_AADF_ACTIVATE_KEY_FILE
должна быть включена.VMPIK_AADF_ACTIVATE_TRIAL
— включает возможность активации trial лицензии.VMPIK_AADF_ACTIVATE_LATER
— включает опцию «активировать позже».VMPIK_AADF_REACTIVATE
— включает режим реактивации (деактивация и последующая активация).VMPIK_AADF_DEACTIVATE
— включает режим деактивации. При успешной деактивации данные лицензии удаляются с компьютера пользователя.VMPIK_AADF_ACTIVATE_MASK
— маска режимов активации.VMPIK_AADF_SELECT_ACTIVATE_MASK
— маска изначально выбранного типа активации.VMPIK_AADF_SIMPLE_SERIAL_INPUT
— включает режим ввода серийного номера, без активации и каких-либо действий.VMPIK_AADF_OFFLINE
— добавляет опцию offline активации/деактивации.VMPIK_AADF_ACTIVATION_TYPE
— тип активации — для текущего пользователя/для всех пользователей.VMPIK_AADF_SELECT_USER_GROUP
— тоже, что иVMPIK_AADF_ACTIVATION_TYPE
.VMPIK_AADF_SELECT_ACTIVATE_SERIAL
,VMPIK_AADF_SELECT_ACTIVATE_KEY_FILE
,VMPIK_AADF_SELECT_ACTIVATE_TRIAL
,VMPIK_AADF_SELECT_ACTIVATE_LATER
— задает изначально выбранную опцию активации.VMPIK_AADF_SELECT_ACTIVATION_TYPE_CURRENT_USER
,VMPIK_AADF_SELECT_ACTIVATION_TYPE_ALL_USERS
— задает изначально выбранный тип активации (для текущего пользователя/для всех пользователей).VMPIK_AADF_DLG_RESIZE
— включает возможность изменения размера диалога.VMPIK_AADF_UPPERCASE
— ограничивает ввод и приводит вводимые буквы серийного номера к верхнему регистру.VMPIK_AADF_LOWERCASE
— ограничивает ввод и приводит вводимые буквы серийного номера к нижнему регистру.VMPIK_AADF_DEACTIVATE_OFFLINE_KEEP_LICENSE
— offline при деактивации не удаляет данные лицензии с компьютера.VMPIK_AADF_SERIAL_NUMBER_FORMAT_STR
— задаем формат серийного номера в виде форматной строки.VMPIK_AADF_SHOW_CONNECTION_REQUIRED
— показывать строку «требуется подключение к интернету» для соответствующих опций.VMPIK_AADF_CLASSIC_FILE_DIALOGS
— указывает использовать классические (Win2K/WinXP) диалоги открытия/сохранения файлов в системах Vista+.VMPIK_AADF_VERTICAL_BUTTONS
— задает вертикальное расположение кнопок «Ok»/«Cancel»/«Elevate».VMPIK_AADF_BUTTONS_AT_LEFT
— задает расположение кнопок по левому краю.VMPIK_AADF_BUTTONS_AT_RIGHT
— задает расположение кнопок по правому краю.VMPIK_AADF_SHOW_ELEVATION_BUTTON
— указывает всегда показывать кнопку «Elevate».VMPIK_AADF_ALWAYS_SILENT_MESSAGEBOX
— при выводе сообщений MessageBox не будет использоваться звуковое сопровождение.VMPIK_AADF_SHOW_OFFLINE_API_ERRORS
— указывает показывать ошибки при вызове offline-API.VMPIK_AADF_DONT_SHOW_ACTIVATION_SUCCESS
— указывает не показывать сообщение об успешной активации.VMPIK_AADF_DISABLE_LICENSE_DROP_TARGET
— указывает не использовать возможности Drag'n'Drop для поля файла лицензии.VMPIK_AADF_BOTTOM_RIGHT_POS
— при задании точки, в которой будет отображаться диалог, использовать координаты правого нижнего угла вместо левого верхнего.
Коды возврата диалоговых функций активации
VMPIK_AADR_OK
— активация прошла успешно, диалог закрыт по кнопке «Ok»/«Close».VMPIK_AADR_SUCCESS
— тоже, что иVMPIK_AADR_OK
.VMPIK_AADR_CANCELED
— пользователь отменил активацию «Cancel»/Escape
.VMPIK_AADR_INVALID_PARAM
— неверный параметр. В этом случае диалог не показывается пользователю.VMPIK_AADR_ELEVATION_REQUIRED
— возвращается, если пользователь нажал кнопку «Elevate».VMPIK_AADR_SAVE_FAILED
— активация прошла успешно, но возникла ошибка при сохранении данных лицензии. Данная ситуация теоретически не должна возникать, так как перед активацией возможность записи данных в нужное месторасположение проверяется.
Функция VMPIK_ParseSerialNumberFormat
Вспомогательная функция разбора форматной строки серийного номера. Используется при задании формата серийного номера строкой вместо массива целых чисел. Если часть формата серийного номера начинается с символа '#', то длина этой части является её размером, вне зависимости от остальных символов. Если формата серийного номера состоит из цифр, то они задают длину данной части, но не больше 32. Примеры эквивалентных форматных строк: «8-####-##-6», «8-4-2-6», «8-4-#4-6» ("#4" — 2, считается длина части), "########-####-##-######".
UINT VMPIKAPI VMPIK_ParseSerialNumberFormat( LPCTSTR strFormat, TCHAR sepChar, UINT *pSerialNumberNumChars, UINT *pNumPartsFound);
Функция VMPIK_InputSerialNumberDlg
INT VMPIKAPI VMPIK_InputSerialNumberDlg( HWND hWndParent
, LPCTSTR lpcDlgTitle
, HICON hIcon
, HICON hIconSmall
, POINT *pLeftTop
, UINT serialNumberNumParts
, UINT serialNumberNumChars
, const UINT *pSerialNumberNumChars
, CHAR serialNumberSeparator
, LPCTSTR lpcSerialNumberIncludeCharsMask
, LPCTSTR lpcSerialNumberExcludeCharsMask
, UINT fAadFlags
, LPSTR lpEnteredSerialBuf
, UINT *pEnteredSerialBufSize
);
Функция VMPIK_InputSerialNumberDlg
выводит диалог ввода серийного номера. Поддерживается копирование серийного номера из буфера обмена как целиком во все поля (если серийных номер скопирован целиком), так и в отдельное поле.
hWndParent
— хэндл родительского окна.lpcDlgTitle
— заголовок диалога. Можно задавать 0.hIcon
— маленькая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXICON). Можно задавать 0.hIconSmall
— большая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXSMICON). Можно задавать 0.pLeftTop
— задает положение верхнего левого угла диалога. Можно задавать 0, в этом случае диалог будет спозиционирован по центру экрана/родительского окна.serialNumberNumParts
— количество частей в серийном номере, не более 16.serialNumberNumChars
— количество символов в каждой части серийного номера.pSerialNumberNumChars
— массив целых чисел, задающих длины отдельных частей серийного номера, при этом параметрserialNumberNumChars
игнорируется. Можно задать указатель на строку формата, при этом параметрserialNumberNumParts
также будет проигнорирован.serialNumberSeparator
— разделитель частей серийного номера. Задание 0 указывает использовать стандартный разделитель — '-'.lpcSerialNumberIncludeCharsMask
— строка, задающая фильтр допустимых символов.lpcSerialNumberExcludeCharsMask
— строка, задающая фильтр исключаемых символов.fAadFlags
— флаги, см Флаги диалога активации.lpEnteredSerialBuf
— буфер, в который будет помещен введенный серийный номер.pEnteredSerialBufSize
— размер буфера для серийного номера.
Функция VMPIK_ActivateAppDlg
INT VMPIKAPI VMPIK_ActivateAppDlg ( HWND hWndParent
, LPCTSTR lpcDlgTitle
, HICON hIcon
, HICON hIconSmall
, POINT *pLeftTop
, DWORD activationSaveLoadFlags
, HKEY hRootKeyCurrentUser
, LPCTSTR lpcRegOrFilePathCurrentUser
, HKEY hRootKeyAllUsers
, LPCTSTR lpcRegOrFilePathAllUsers
, LPCTSTR lpcRegValOrFileName
, LPCTSTR lpcSerialRegValOrFileName
, LPCTSTR lpcTrialFlagRegValOrFileName
, UINT serialNumberNumParts
, UINT serialNumberNumChars
, const UINT *pSerialNumberNumChars
, CHAR serialNumberSeparator
, UINT fAadFlags
, LPCTSTR lpcOnlineActivationUrl
, LPCTSTR lpcOfflineActivationUrl
, LPCSTR lpcTrialLicenseSerial
, LPVOID lpvCallbackParam
, PFN_VMPIK_ActivateOnlineCallback ActivateOnlineProc
, PFN_VMPIK_DeactivateOnlineCallback DeactivateOnlineProc
, PFN_VMPIK_GetOfflineActivationStringCallback GetOfflineActivationStringProc
, PFN_VMPIK_GetOfflineDeactivationStringCallback GetOfflineDeactivationStringProc
, PFN_VMPIK_ActivateCheckLicenseCallback ActivateCheckLicenseProc
);
Функция VMPIK_ActivateAppDlg
является упрощенной, по сравнению с VMPIK_ActivateAppDlgEx
, версией функции вывода диалога активации.
hWndParent
— хэндл родительского окна.lpcDlgTitle
— заголовок диалога. Можно задавать 0.hIcon
— маленькая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXICON). Можно задавать 0.hIconSmall
— большая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXSMICON). Можно задавать 0.pLeftTop
— задает положение верхнего левого угла диалога. Можно задавать 0, в этом случае диалог будет спозиционирован по центру экрана/родительского окна.activationSaveLoadFlags
— см. флаги сохранения данных лицензии.hRootKeyCurrentUser
— задает ветку реестра, куда будут записываться данные лицензии при активации для текущего пользователя. Следует задать 0 для сохранения в файл.lpcRegOrFilePathCurrentUser
— задает путь в реестре или файловой системе, по которому будут сохранены данные лицензии при активации для текущего пользователя.hRootKeyAllUsers
— задает ветку реестра, куда будут записываться данные лицензии при активации для всех пользователей. Следует задать 0 для сохранения в файл.lpcRegOrFilePathAllUsers
— задает путь в реестре или файловой системе, по которому будут сохранены данные лицензии при активации для всех пользователей. Может быть равен 0.lpcRegValOrFileName
— задает имя переменной в реестре или имя файла, в котором будут сохранены данные лицензии. Может быть равен 0.lpcSerialRegValOrFileName
— задает имя переменной в реестре или имя файла, в котором будет сохранен серийный номер (код активации), использованный при активации. Может быть равен 0.lpcTrialFlagRegValOrFileName
— задает имя переменной в реестре или имя файла, в котором будет сохранен Trial признак лицензии, если будет произведена активация пробной версии. Может быть равен 0.serialNumberNumParts
— количество частей в серийном номере, не более 16.serialNumberNumChars
— количество символов в каждой части серийного номера.pSerialNumberNumChars
— массив целых чисел, задающих длины отдельных частей серийного номера, при этом параметрserialNumberNumChars
игнорируется. Можно задать указатель на строку формата, при этом параметрserialNumberNumParts
также будет проигнорирован.serialNumberSeparator
— разделитель частей серийного номера. Задание 0 указывает использовать стандартный разделитель — '-'.fAadFlags
— флаги, см Флаги диалога активации.lpcOnlineActivationUrl
— задает URL, который используется для online активации. Данный параметр игнорируется в версии для VMProtect (там URL «зашивается» при защите модуля).lpcOfflineActivationUrl
— задает URL, который используется для online активации. Данный параметр игнорируется в версии для VMProtect (там URL «зашивается» при защите модуля).lpcTrialLicenseSerial
— задает серийный номер (код активации), который будет использоваться для активации пробной версии.lpvCallbackParam
— параметр для функций обратного вызова. Может быть равен 0.ActivateOnlineProc
— указатель на функцию online активации. Может быть равен 0.DeactivateOnlineProc
— указатель на функцию online деактивации. Может быть равен 0.GetOfflineActivationStringProc
— указатель на функцию, возвращающую строку данных для offline активации. Может быть равен 0.GetOfflineDeactivationStringProc
— указатель на функцию, возвращающую строку данных для offline деактивации. Может быть равен 0.ActivateCheckLicenseProc
— указатель на функцию, осуществляющую проверку лицензии. Может быть равен 0.
Для того, чтобы активировать приложение только для текущего пользователя или только для всех пользователей, необходимо задать только параметры hRootKeyCurrentUser
и lpcRegOrFilePathCurrentUser
. Для того, чтобы включить возможность выбора типа активации, следует указать флаг VMPIK_AADF_SELECT_USER_GROUP
(VMPIK_AADF_ACTIVATION_TYPE
), а также задать параметры hRootKeyAllUsers
и lpcRegOrFilePathAllUsers
.
Функции обратного вызова можно не задавать, указав значение 0, при этом будут использоваться встроенные реализации, использующие API VMProtect. Данная возможность добавлена для поддержки сторонних процедур активации.
Адреса (URL) активации и деактивации игнорируются при использовании встроенных реализаций, использующих VMProtect — при защите приложения VMProtect «зашивает» эти адреса в защищаемый модуль.
Поддержка Drag'n'Drop. Функция VMPIK_ActivateAppDlg
(также как и функция Функция VMPIK_ActivateAppDlgEx
) поддерживает перетаскивание ключевого файла данных лицензии на диалог активации, если данный способ активации разрешен флагами активации. Перетаскивание работает для всего диалога, не только для поля ввода имени файла лицензии. После перетаскивания сразу происходит активация данной лицензии, и выводится сообщение об успехе операции или об ошибке.
Функция VMPIK_ActivateAppDlgEx
INT VMPIKAPI VMPIK_ActivateAppDlgEx( HWND hWndParent
, LPCTSTR lpcDlgTitle
, HICON hIcon
, HICON hIconSmall
, POINT *pLeftTop
, DWORD activationSaveLoadFlags
, HKEY hRootKeyCurrentUser
, LPCWSTR lpcRegOrFilePathCurrentUser
, HKEY hRootKeyAllUsers
, LPCTSTR lpcRegOrFilePathAllUsers
, LPCTSTR lpcRegValOrFileName
, LPCTSTR lpcSerialRegValOrFileName
, LPCTSTR lpcTrialFlagRegValOrFileName
, UINT serialNumberNumParts
, UINT serialNumberNumChars
, const UINT *pSerialNumberNumChars
, CHAR serialNumberSeparator
, LPCTSTR lpcSerialNumberIncludeCharsMask
, LPCTSTR lpcSerialNumberExcludeCharsMask
, UINT fAadFlags
, LPCTSTR lpcOnlineActivationUrl
, LPCTSTR lpcOfflineActivationUrl
, LPCSTR lpcTrialLicenseSerial
, LPVOID lpvCallbackParam
, PFN_VMPIK_ActivateOnlineCallback ActivateOnlineProc
, PFN_VMPIK_DeactivateOnlineCallback DeactivateOnlineProc
, PFN_VMPIK_GetOfflineActivationStringCallback GetOfflineActivationStringProc
, PFN_VMPIK_GetOfflineDeactivationStringCallback GetOfflineDeactivationStringProc
, PFN_VMPIK_ActivateCheckLicenseCallback ActivateCheckLicenseProc
, LPCTSTR lpcActivationFailedCustomTitle
, LPCTSTR lpcActivationSuccessCustomTitle
, LPCTSTR lpcActivationSuccessCustomMessage
, LPCTSTR lpcDeactivationFailedCustomTitle
, LPCTSTR lpcDeactivationSuccessCustomTitle
, LPCTSTR lpcDeactivationSuccessCustomMessage
, INT *pLastActivationStatus
, LPSTR lpEnteredSerialBuf
, UINT *pEnteredSerialBufSize
, LPSTR lpLicenseBuf
, UINT *pLicenseBufSize
);
Функция VMPIK_ActivateAppDlgEx
является расширенной версией функции вывода диалога активации.
hWndParent
— хэндл родительского окна.lpcDlgTitle
— заголовок диалога. Можно задавать 0.hIcon
— маленькая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXICON). Можно задавать 0.hIconSmall
— большая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXSMICON). Можно задавать 0.pLeftTop
— задает положение верхнего левого угла диалога. Можно задавать 0, в этом случае диалог будет спозиционирован по центру экрана/родительского окна.activationSaveLoadFlags
— см. флаги сохранения данных лицензии.hRootKeyCurrentUser
— задает ветку реестра, куда будут записываться данные лицензии при активации для текущего пользователя. Следует задать 0 для сохранения в файл.lpcRegOrFilePathCurrentUser
— задает путь в реестре или файловой системе, по которому будут сохранены данные лицензии при активации для текущего пользователя.hRootKeyAllUsers
— задает ветку реестра, куда будут записываться данные лицензии при активации для всех пользователей. Следует задать 0 для сохранения в файл.lpcRegOrFilePathAllUsers
— задает путь в реестре или файловой системе, по которому будут сохранены данные лицензии при активации для всех пользователей. Может быть равен 0.lpcRegValOrFileName
— задает имя переменной в реестре или имя файла, в котором будут сохранены данные лицензии. Может быть равен 0.lpcSerialRegValOrFileName
— задает имя переменной в реестре или имя файла, в котором будет сохранен серийный номер (код активации), использованный при активации. Может быть равен 0.lpcTrialFlagRegValOrFileName
— задает имя переменной в реестре или имя файла, в котором будет сохранен Trial признак лицензии, если будет произведена активация пробной версии. Может быть равен 0.serialNumberNumParts
— количество частей в серийном номере, не более 16.serialNumberNumChars
— количество символов в каждой части серийного номера.pSerialNumberNumChars
— массив целых чисел, задающих длины отдельных частей серийного номера, при этом параметрserialNumberNumChars
игнорируется. Можно задать указатель на строку формата, при этом параметрserialNumberNumParts
также будет проигнорирован.serialNumberSeparator
— разделитель частей серийного номера. Задание 0 указывает использовать стандартный разделитель — '-'.lpcSerialNumberIncludeCharsMask
— строка, задающая фильтр допустимых символов.lpcSerialNumberExcludeCharsMask
— строка, задающая фильтр исключаемых символов.fAadFlags
— флаги, см Флаги диалога активации.lpcOnlineActivationUrl
— задает URL, который используется для online активации. Данный параметр игнорируется в версии для VMProtect (там URL «зашивается» при защите модуля).lpcOfflineActivationUrl
— задает URL, который используется для online активации. Данный параметр игнорируется в версии для VMProtect (там URL «зашивается» при защите модуля).lpcTrialLicenseSerial
— задает серийный номер (код активации), который будет использоваться для активации пробной версии.lpvCallbackParam
— параметр для функций обратного вызова. Может быть равен 0.ActivateOnlineProc
— указатель на функцию online активации. Может быть равен 0.DeactivateOnlineProc
— указатель на функцию online деактивации. Может быть равен 0.GetOfflineActivationStringProc
— указатель на функцию, возвращающую строку данных для offline активации. Может быть равен 0.GetOfflineDeactivationStringProc
— указатель на функцию, возвращающую строку данных для offline деактивации. Может быть равен 0.ActivateCheckLicenseProc
— указатель на функцию, осуществляющую проверку лицензии. Может быть равен 0.lpcActivationFailedCustomTitle
— заголовок сообщения об ошибке активации.lpcActivationSuccessCustomTitle
— заголовок сообщения об успешной активации.lpcActivationSuccessCustomMessage
— сообщение об успешной активации.lpcDeactivationFailedCustomTitle
— заголовок сообщения об ошибке деактивации.lpcDeactivationSuccessCustomTitle
— заголовок сообщения об успешной деактивации.lpcDeactivationSuccessCustomMessage
— сообщение об успешной деактивации.pLastActivationStatus
— статус последней осуществленной попытки активации.lpEnteredSerialBuf
— буфер, в который будет помещен введенный серийный номер.pEnteredSerialBufSize
— размер буфера для серийного номера.lpLicenseBuf
— буфер, в который будет помещены данные активированной лицензии.pLicenseBufSize
— размер буфера для данных лицензии.
Функция VMPIK_ActivateAppDlgEx
предоставляет некоторые дополнительные возможности по сравнению с функцией VMPIK_ActivateAppDlg
.
Функция VMPIK_ActivateAppDlgEx
позволяет задавать маску допустимых для ввода в поле серийного номера символов (lpcSerialNumberIncludeCharsMask
), а также маску недопустимых символов (lpcSerialNumberExcludeCharsMask
).
Также функция VMPIK_ActivateAppDlgEx
позволяет задать заголовки для сообщений об успешной/неуспешной активации/деактивации.
Дополнительно данная функция позволяет получить введенный серийный номер (код активации) и данные лицензии для дальнейшей обработки. Это может быть полезно, если попытка записи данных лицензии после успешной активации по каким-либо причинам завершилась ошибкой.
Диалог «О Программе»
Создание диалога «О Программе» иногда представляет некоторую сложность — некоторые новые продукты часто в первых версиях не имеют такого диалога вообще. Также, если диалог «О Программе» создан для одной программы, часто переделка его под потребности другой программы занимает некоторое время.
VMPKit пытается помочь в данном вопросе и предоставляет достаточно гибко настраиваемый диалог «О Программе», который может отображать различную информацию о программе, и автоматически адаптируется под выводимую информацию.
Диалог «О Программе», предоставляемый VMPKit, умеет копировать всю отображаемую информацию в буфер обмена (в текстовом виде) по нажатию клавиш Ctrl+C или Ctrl+Ins. Данная функция удобна при поддержке приложения — достаточно дать пользователю простые инструкции, и он без труда предоставит все необходимые сведения о программе в вашу службу поддержки.
Диалог «О Программе» конфигурируется заданием нужных значений в соответствующих аргументах функции диалога, а также использует для настройки флаги опций.
Флаги диалога «О Программе»
VMPIK_ABOUT_CLOSE_BUTTON
— задает использовать кнопку «Close» вместо кнопки «Ok».VMPIK_ABOUT_BUTTON_WITH_IMAGE
— задает расположить кнопку «Ok»/«Close» непосредственно под изображением.VMPIK_ABOUT_BUTTON_AT_LEFT
— указывает разместить кнопку «Ok»/«Close» слева внизу (по умолчанию — справа внизу).VMPIK_ABOUT_BUTTON_AT_CENTER
— указывает разместить кнопку «Ok»/«Close» по-центру внизу (по умолчанию — справа внизу).VMPIK_ABOUT_IMAGE_BITMAP
— задает тип изображенияHBITMAP
(по умолчанию —HICON
).VMPIK_ABOUT_IMAGE_EMF
— задает тип изображения Enhanced Metafile.VMPIK_ABOUT_IMAGE_AT_LEFT
— указывает разместить изображение слева от информационной части диалога (по умолчанию — справа).VMPIK_ABOUT_PREPEND_COPYRIGHT_SIGN
— указывает предварять при выводе строку копирайта символом копирайта.VMPIK_ABOUT_COMPOSITE_COPYRIGHT_SIGN
— указывает использовать символ копирайта как комбинацию — "©".VMPIK_ABOUT_COPYRIGHT_APPEND_ALL_RIGHTS
— указывает добавлять строку «All rights reserved» («Все права защищены») к строке копирайта.VMPIK_ABOUT_SYS_INFO_WINDOWS_INFO
— добавляет в раздел сведений о системе информацию о текущей версии Windows.VMPIK_ABOUT_SYS_INFO_MEM_INFO
— добавляет в раздел сведений о системе информацию об использовании памяти.VMPIK_ABOUT_SYS_INFO_CPU_INFO
— добавляет в раздел сведений о системе информацию о процессоре.VMPIK_ABOUT_DISABLE_CLIPBOARD_COPY
— запрещает копирование информации в буфер обмена по нажатию клавиш Ctrl+C или Ctrl+Ins.VMPIK_ABOUT_ALWAYS_SHOW_REGISTERED
— указывает всегда отображать раздел сведений о регистрации, даже если не указаны имя, email пользователя и срок окончания действия лицензии.VMPIK_ABOUT_CLOSE_ON_URL_EVENT
— указывает закрывать диалог при переходе на сайт по клику на соответствующей метке.VMPIK_ABOUT_BOTTOM_RIGHT_POS
— указывает использовать правый нижний угол для позиционирования диалога.VMPIK_ABOUT_COPY_ADDITIONAL_INFO
— указывает копировать в буфер обмена также и дополнительную информацию (если задана) по нажатию клавиш Ctrl+C или Ctrl+Ins.VMPIK_ABOUT_PURCHASE_BTN_NONE
— запрещает отображение кнопки «Купить».VMPIK_ABOUT_PURCHASE_BTN_DEF_SIZE
— задает размер кнопки по ширине «Купить» по умолчанию.VMPIK_ABOUT_PURCHASE_BTN_HALF_SIZE
— задает размер кнопки по ширине «Купить» в половину вычисленного при адаптации размера диалога.VMPIK_ABOUT_PURCHASE_BTN_FULL_SIZE
— задает размер кнопки по ширине «Купить» как размер, вычисленный при адаптации размера диалога.VMPIK_ABOUT_CLOSE_ON_PURCHASE_EVENT
— указывает закрывать диалог при нажатии кнопки «Купить».VMPIK_ABOUT_VERSION_SHORT_FROM_APP_MODULE
— указывает использовать отображаемую версию как короткую версию модуля приложения («1.0»).VMPIK_ABOUT_VERSION_SHORTEX_FROM_APP_MODULE
— указывает использовать отображаемую версию как расширенную короткую версию модуля приложения («1.2.3»).VMPIK_ABOUT_VERSION_LONG_FROM_APP_MODULE
— указывает использовать отображаемую версию как версию модуля приложения («1.2.3.4»).VMPIK_ABOUT_VERSION_FILE_VERSION
— использовать версию файла модуля приложения вместо версии продукта.
Функция диалога «О Программе»
INT VMPIKAPI VMPIK_AboutAppDlgW( HWND hWndParent
, LPCWSTR lpcDlgTitle
, const VMPIK_ABOUTDLG_FONTS_INFOW *lpcLabelsFonts
, UINT horScale
, HICON hIcon
, HICON hIconSmall
, HANDLE hAppImage
, POINT *pLeftTop
, DWORD aboutFlags
/*--------------------------*/
, LPCWSTR lpcAppName
, LPCWSTR lpcAppNameSubtitle
, LPCWSTR lpcAppInfoString
, LPCWSTR lpcAppVersionString
/*--------------------------*/
, LPCWSTR lpcAppCopyrightString
, LPCWSTR lpcAppUrlString
/*--------------------------*/
, BOOL bTrial
, LPCWSTR lpcRegisteredToNameString
, LPCWSTR lpcRegisteredToEmailString
, LPCWSTR lpcRegistrationExpiresDateString
, LPCWSTR lpcPurchaseButtonText
, LPCWSTR lpcPurchaseUrl
/*--------------------------*/
, LPCWSTR lpcAdditionalInfoTextTitle
, LPCWSTR lpcAdditionalInfoText
/*--------------------------*/
, PFN_VMPIK_AboutBoxImageClickCallback pfnImageClickCallback
, LPVOID lpvImageClickCallbackParam
);
hWndParent
— хэндл родительского окна.lpcDlgTitle
— заголовок диалога. Можно задавать 0.lpcLabelsFonts
— указатель на структуру, содержащую информацию о шрифтах, используемых при отображении различных элементов диалога.horScale
— при выводе диалога его размеры автоматически адаптируются на основании заданных данных, но адаптация может быть не точной, и часть информации может быть «обрезана», или наоборот, может оставаться пустое пространство. Данный параметр позволяет уменьшить этот эффект, дополнительно масштабируя диалог по горизонтали. Этот коэффициент рекомендуется делать зависимым от локали, так как строки данных диалога для различных могут иметь разную длину. Данные коэффициент задается в процентах. Задание 0 (также как и заданий 100) оставляет ширину диалога без изменений.hIcon
— маленькая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXICON). Можно задавать 0.hIconSmall
— большая иконка. При использовании функции LoadImage следует задавать размер GetSystemMetrics(SM_CXSMICON). Можно задавать 0.hAppImage
— изображение, помещаемое на диалог. Расположение и тип изображения задается флагами.pLeftTop
— задает положение верхнего левого угла диалога. Можно задавать 0, в этом случае диалог будет спозиционирован по центру экрана/родительского окна.aboutFlags
— см. флаги диалога «О Программе».lpcAppName
— название приложения, выводится увеличенным шрифтом в самом верху.lpcAppNameSubtitle
— подзаголовок, выводится под названием; может отсутствовать.lpcAppInfoString
— строка информации о приложении, выводится под подзаголовком; может отсутствовать.lpcAppVersionString
— строка версии приложения. Может отсутствовать, при этом может использоваться версия модуля приложения — управляется флагами.lpcAppCopyrightString
— строка копирайта, может отсутствовать.lpcAppUrlString
— задает домашний URL, подсвечивается цветом ссылки. При клике происходит переход по указанному адресу.bTrial
— секция диалога — сведения о регистрации. Задает признак, полная или пробная лицензия активна в данный момент.lpcRegisteredToNameString
— секция диалога — сведения о регистрации. Указывает, на кого зарегистрированна программа.lpcRegisteredToEmailString
— секция диалога — сведения о регистрации. Указывает, на кого зарегистрированна программа (email).lpcRegistrationExpiresDateString
— секция диалога — сведения о регистрации. Дата истечения срока действия текущей лицензии.lpcPurchaseButtonText
— секция диалога — сведения о регистрации. Текст кнопки «Купить».lpcPurchaseUrl
— секция диалога — сведения о регистрации. Если задан, то отображается кнопка купить, при нажатии которой происходит переход по указанному адресу.lpcAdditionalInfoTextTitle
— задает заголовок секции дополнительных сведений.lpcAdditionalInfoText
— задает текст дополнительных сведений, помещаемых в многострочный прокручиваемый текстовый элемент.pfnImageClickCallback
— задает обработчик клика по изображению. Может использоваться для добавления «пасхалки».lpvImageClickCallbackParam
— параметр, передаваемый в обработчикpfnImageClickCallback
.
Функция-хелпер для масштабного коэффициента
Как описано выше, иногда может потребоваться масштабирование диалога «О Программе» по горизонтали. Коэффициент должен быть зависимым от текущей локали, и неплохой идеей является решение хранить его в виде строки в строковых ресурсах. Данная функция-хелпер помогает извлекать его из ресурсов и преобразовывать в целое число, как требуется. Данная функция доступна как inline-функция и описана в заголовочном файле VMPKit.
inline
UINT VMPIKAPI VMPIK_AboutAppDlgLoadHorScale( HINSTANCE hInstance, int strId, UINT defVal )
{
TCHAR buf[32];
VMPIK_LoadString( hInstance, strId, buf, ARRAYSIZE(buf)-1, _T("0"));
return _tcstol( buf, 0, 10 );
}
Продолжение следует
Данная статья не является заключительной в серии постов о VMPKit, ожидайте продолжения в скором будущем.
Автор: kruzhevnik