-
AlexSpl
имя: Александр
- Эксперт
-
- Сообщения: 5587
- Зарегистрирован: 17 сен 2010, 12:58
- Пол:
- Награды: 14
-
-
- Поблагодарили: 2185 раз.
|
AlexSpl » 28 авг 2017, 18:38
Участник форума DF2 igrik поделился примером создания кастомных диалогов для HD мода. Я немного переделал код и написал плагин, демонстрирующий работу с диалогами: - Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS #include "HotA\homm3.h"
Patcher* _P; PatcherInstance* _PI; static _bool_ plugin_On = 0;
// Количество раундов int n;
// Создаём стандартный задник с рамкой цвета игрока void setStdBackground(_Dlg_* dlg) { CALL_5 (int, __thiscall, 0x48FA80, dlg, dlg->x, dlg->y, dlg->width, dlg->height);
for (int i = dlg->field_4C; i <= dlg->field_50; ++i) { CALL_5 (int, __thiscall, 0x5FF400, dlg, 512, 13, i, o_GameMgr->GetMeID()); } }
void __fastcall scrollDlgCallback(int click_id, _Dlg_* dlg) { // Выводим в текстовое поле текущее значение, выбранное с помощью ползунка n = click_id + 1; sprintf(o_TextBuffer, "%d", n); ((_DlgStaticText_*)dlg->GetItem(14))->SetText(o_TextBuffer); dlg->Redraw(TRUE); }
void yDlgShow(int width, int height, int count, char* captionText, char* messageText, bool middle = true, int x = 0, int y = 0) { // Создаём по центру экрана пустой диалог с тенью _Dlg_* dlg = _CustomDlg_::Create(DLG_X_CENTER, DLG_Y_CENTER, width, height, DF_SCREENSHOT | DF_SHADOW, NULL); // Добавляем задник (фон) и рамку по цвету игрока setStdBackground(dlg); // Добавляем заголовок диалога dlg->AddItem(_DlgStaticText_::Create(0, 20, dlg->width, 30, captionText, "bigfont.fnt", 7, 1, ALIGN_H_CENTER | ALIGN_V_TOP, 0));
// Добавляем текст dlg->AddItem(_DlgStaticText_::Create(0, 50, dlg->width, 50, messageText, "medfont.fnt", 1, 0, ALIGN_H_CENTER | ALIGN_V_TOP, 0));
// Добавляем полосу горизонтальной прокрутки dlg->AddItem(_DlgScroll_::Create(30, dlg->height - 90, dlg->width - 30 * 2 + 1, 16, 40, count, (_ptr_)scrollDlgCallback, 0, 18, 0)); // Добавляем текстовое поле для отображения значений, выбираемых с помощью ползунка dlg->AddItem(_DlgStaticText_::Create((dlg->width - 30) / 2 + 1, dlg->height - 61, 30, 30, "1", "medfont.fnt", 1, 14, ALIGN_H_CENTER | ALIGN_V_CENTER, 0));
// Добавляем кнопку OK dlg->AddItem(_DlgStaticPcx8_::Create(30, dlg->height - 61, 0, "Box64x30.pcx")); dlg->AddItem(_DlgButton_::Create(31, dlg->height - 60, 64, 30, 30722, "iOkay.def", 0, 1, 1, 28, 2));
// Добавляем кнопку Cancel dlg->AddItem(_DlgStaticPcx8_::Create(dlg->width - 31 - 64, dlg->height - 61, 0, "Box64x30.pcx")); dlg->AddItem(_DlgButton_::Create(dlg->width - 30 - 64, dlg->height - 60, 64, 30, 30721, "iCancel.def", 0, 1, 1, 1, 2));
if ( !middle ) dlg->SetPos(x, y); dlg->Run(); dlg->Destroy(TRUE); }
int __stdcall blindSpell(LoHook* h, HookContext* c) { if ( c->ebx == SPL_BLIND ) { n = 1; // Если герой скастовал Blind, показываем диалог yDlgShow(240, 140, 10, "Blind", "Please set spell duration\nfrom 1 to 10 rounds:");
// Если нажата кнопка OK (30722), то устанавливаем длительность заклинания Blind = n, // иначе - длительность остаётся по умолчанию if ( o_WndMgr->result_dlg_item_id == 30722 ) c->eax = n; }
return EXEC_DEFAULT; }
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch ( ul_reason_for_call ) { case DLL_PROCESS_ATTACH: if ( !plugin_On ) { plugin_On = 1; _P = GetPatcher(); _PI = _P->CreateInstance("HD.Plugin.TestCustomDialog"); _PI->WriteLoHook(0x44467E, blindSpell); } break;
case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
Сам плагин в архиве: * * * Чуть позже выяснил, что предпоследний аргумент здесь: - Код: Выделить всё
// Добавляем полосу горизонтальной прокрутки dlg->AddItem(_DlgScroll_::Create(30, dlg->height - 90, dlg->width - 30 * 2 + 1, 16, 40, count, (_ptr_)scrollDlgCallback, 0, 18, 0));
это шаг при клике на полосе прокрутки, его нужно установить в 1 (пока что). Последний аргумент, судя по всему, флаг (bool) - разрешёно ли управление ползунком с клавиатуры. * * * 2Ben80: Так что, если у Вас есть время и желание, можете продолжить работу над Disguise
|