Code:
#include "..\..\include\homm3.h"
Patcher* _P;
PatcherInstance* _PI;
#define GODSBTTNS
#define NOT_SHOW_MAX_MORAL false
#define o_SSTraits (*(_int_*)0x67DCF0)
#define o_DlgHeroInfoSStext ((const char*)(*(int*)0x6A80D0))
_Dlg_* __stdcall Y_HeroDlg_Create(HiHook* hook, _Dlg_* dlg)
{
    CALL_1(_Dlg_*, __thiscall, hook->GetDefaultFunc(), dlg);
    
    dlg->AddItem(_DlgStaticDef_::Create(18, 420, 44, 44, 501, "secskill.def", 0, 0, 16)); // 9 навык (id 501, 502, 503)
    dlg->AddItem(_DlgStaticText_::Create(68, 444, 90, 18, "", "smalfont.fnt", 1, 502, ALIGN_H_LEFT | ALIGN_V_CENTER, 0));
    dlg->AddItem(_DlgStaticText_::Create(68, 424, 90, 18, "", "smalfont.fnt", 1, 503, ALIGN_H_LEFT | ALIGN_V_CENTER, 0));
    
    dlg->AddItem(_DlgStaticDef_::Create(161, 420, 44, 44, 504, "secskill.def", 0, 0, 16)); // 10 навык (id 504, 505, 506)
    dlg->AddItem(_DlgStaticText_::Create(211, 444, 90, 18, "", "smalfont.fnt", 1, 505, ALIGN_H_LEFT | ALIGN_V_CENTER, 0));
    dlg->AddItem(_DlgStaticText_::Create(211, 424, 90, 18, "", "smalfont.fnt", 1, 506, ALIGN_H_LEFT | ALIGN_V_CENTER, 0));
    dlg->AddItem(_DlgStaticText_::Create(208, 141, 44, 18, "", "smalfont.fnt", 1, 507, ALIGN_H_CENTER | ALIGN_V_CENTER, 0));
    dlg->AddItem(_DlgStaticText_::Create(255, 141, 44, 18, "", "smalfont.fnt", 1, 508, ALIGN_H_CENTER | ALIGN_V_CENTER, 0));
    // скрываем названия первичных навыков
    _DlgItem_* it;
    it = dlg->GetItem(103);        if (it) it->Hide();                    // текст атака
    it = dlg->GetItem(104);        if (it) it->Hide();                    // текст защита
    it = dlg->GetItem(105);        if (it) it->Hide();                    // текст к.сила
    it = dlg->GetItem(106);        if (it) it->Hide();                    // текст знание
#ifdef GODSBTTNS
    it = dlg->GetItem(108);        if (it) it->Hide();                    // текст опыт
    it = dlg->GetItem(112);        if (it) it->Hide();                    // значение опыт
#else // GODSBTTNS
    it = dlg->GetItem(107);        if (it) it->Hide();                    // иконка проклятий
    it = dlg->GetItem(139);        if (it) it->Hide();                    // иконка бонуса богов
#endif // GODSBTTNS
    it = dlg->GetItem(118);        if (it){it->x = 250; it->y = 30;}   // иконка специальности
    it = dlg->GetItem(1);        if (it) it->width = 166;            // имя героя
    it = dlg->GetItem(140);        if (it) it->width = 166;            // класс героя
    return dlg;
}
int ss_9, ss_10;
int __stdcall Y_HeroDlg_Update(HiHook* hook, _Dlg_* dlg)
{    
    ss_9  = -1;
    ss_10 = -1;
    _Hero_* hero = o_HeroDlg_Hero;
    for (int i = 0; i < 28; i++) {
        if ( hero->second_skill_show[i] == 9 && hero->second_skill_count >= 9) //  && hero->second_skill_count >= 9 для мода secons skills scrolling
            ss_9 = i;
        if ( hero->second_skill_show[i] == 10 && hero->second_skill_count >= 10 )
            ss_10 = i;
    }
    if (ss_9 >= 0){
        ((_DlgStaticDef_*)dlg->GetItem(501))->def_frame_index = 2 + 3*ss_9 + hero->second_skill[ss_9];
        sprintf(o_TextBuffer, "%s", *(int*)(16*ss_9 + o_SSTraits) );
        ((_DlgStaticText_*)dlg->GetItem(502))->SetText(o_TextBuffer);
        sprintf(o_TextBuffer, "%s", *(int*)(hero->second_skill[ss_9]*4 + 0x6A75D4) );
        ((_DlgStaticText_*)dlg->GetItem(503))->SetText(o_TextBuffer);
    } else {
        ((_DlgStaticDef_*)dlg->GetItem(501))->def_frame_index = 0;
        ((_DlgStaticText_*)dlg->GetItem(502))->SetText("");
        ((_DlgStaticText_*)dlg->GetItem(503))->SetText("");    
    }
    if (ss_10 >= 0){
        ((_DlgStaticDef_*)dlg->GetItem(504))->def_frame_index = 2 + 3*ss_10 + hero->second_skill[ss_10];
        sprintf(o_TextBuffer, "%s", *(int*)(16*ss_10 + o_SSTraits) );
        ((_DlgStaticText_*)dlg->GetItem(505))->SetText(o_TextBuffer);
        sprintf(o_TextBuffer, "%s", *(int*)(hero->second_skill[ss_10]*4 + 0x6A75D4) );
        ((_DlgStaticText_*)dlg->GetItem(506))->SetText(o_TextBuffer);
    } else {
        ((_DlgStaticDef_*)dlg->GetItem(504))->def_frame_index = 0;
        ((_DlgStaticText_*)dlg->GetItem(505))->SetText("");
        ((_DlgStaticText_*)dlg->GetItem(506))->SetText("");    
    }
    CALL_1(void*, __thiscall, hook->GetDefaultFunc(), dlg);
    return 1;
}
int __stdcall Y_HeroDlg_UpdateLuckMoral(HiHook* hook, _Hero_* hero)
{
    if (o_CurrentDlg){
        int moral = CALL_4(int, __thiscall, 0x4E3C20, o_HeroDlg_Hero, 0, 0, NOT_SHOW_MAX_MORAL);
        if (moral > 0)
            sprintf(o_TextBuffer, "+%d", moral );
        else
            sprintf(o_TextBuffer, "%d", moral );
        ((_DlgStaticText_*)o_CurrentDlg->GetItem(507))->SetText(o_TextBuffer);
        int luck = CALL_4(int, __thiscall, 0x4E3930 , o_HeroDlg_Hero, 0, 0.0, NOT_SHOW_MAX_MORAL);
        if (luck > 0)
            sprintf(o_TextBuffer, "+%d", luck );
        else
            sprintf(o_TextBuffer, "%d", luck );
        ((_DlgStaticText_*)o_CurrentDlg->GetItem(508))->SetText(o_TextBuffer);
    }
    return CALL_1(int, __thiscall, hook->GetDefaultFunc(), hero);
}
int __stdcall Y_HeroDlg_Proc(HiHook* hook, _Dlg_* dlg, _EventMsg_* msg)
{
    if (msg->type == MT_MOUSEOVER) {
        _DlgItem_* it = dlg->FindItem(msg->x_abs, msg->y_abs);
////////////////////////////////////////////////////////////////////////////////////
        // sprintf(o_TextBuffer, "Координаты: %d %d (id: %d)", msg->x_abs -254, msg->y_abs -39, it->id );
        // _DlgMsg_ m;    CALL_2(void, __thiscall, 0x5FF3A0, dlg, m.Set(512, 3, 115, 0, 0, 0, (int)o_TextBuffer, 0));
        // dlg->Redraw(TRUE, 114, 115);
////////////////////////////////////////////////////////////////////////////////////
        if (it)    {
            if ( it->id >= 501 && it->id <= 503 && ss_9 != -1 ) {
                sprintf(o_TextBuffer, o_DlgHeroInfoSStext, *(int*)(o_HeroDlg_Hero->second_skill[ss_9]*4 + 0x6A75D4), *(int*)(o_SSTraits +16*ss_9) );
                _DlgMsg_ m;    CALL_2(void, __thiscall, 0x5FF3A0, dlg, m.Set(512, 3, 115, 0, 0, 0, (int)o_TextBuffer, 0));
                dlg->Redraw(TRUE, 114, 115);
                return 1;
            }
            if ( it->id >= 504 && it->id <= 506 && ss_10 != -1 ) {
                sprintf(o_TextBuffer, o_DlgHeroInfoSStext, *(int*)(o_HeroDlg_Hero->second_skill[ss_10]*4 + 0x6A75D4), *(int*)(o_SSTraits +16*ss_10) );
                _DlgMsg_ m;    CALL_2(void, __thiscall, 0x5FF3A0, dlg, m.Set(512, 3, 115, 0, 0, 0, (int)o_TextBuffer, 0));
                dlg->Redraw(TRUE, 114, 115);
                return 1;
            }
        }
    }
    if (msg->type == MT_MOUSEBUTTON) {
        if (msg->subtype == MST_RBUTTONDOWN || msg->subtype == MST_LBUTTONDOWN)    {
            int temp = 0;
            int style = msg->subtype == MST_LBUTTONDOWN ? 1 : 4;
            switch (msg->item_id)    {
                case 501: case 502: case 503:
                    temp = ((_DlgStaticDef_*)dlg->GetItem(501))->def_frame_index;
                    if ( temp > 0 ) {
                        sprintf(o_TextBuffer, "%s", *(int*)(6917512 + 16*ss_9 + 4*o_HeroDlg_Hero->second_skill[ss_9]) );
                        CALL_12(void, __fastcall, 0x4F6C00, o_TextBuffer, style, -1, -1, 20, temp, -1, 0, -1, 0, -1, 0);
                    }    break;
                case 504: case 505: case 506:
                    temp = ((_DlgStaticDef_*)dlg->GetItem(504))->def_frame_index;
                    if ( temp > 0 ) {
                        sprintf(o_TextBuffer, "%s", *(int*)(6917512 + 16*ss_10 + 4*o_HeroDlg_Hero->second_skill[ss_10]) );
                        CALL_12(void, __fastcall, 0x4F6C00, o_TextBuffer, style, -1, -1, 20, temp, -1, 0, -1, 0, -1, 0);                         
                    }    break;
                default:
                    break;
            }
        }
    }    
    
    return CALL_2(int, __thiscall, hook->GetDefaultFunc(), dlg, msg);
}
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    static _bool_ plugin_On = 0;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        if (!plugin_On)
        {
            plugin_On = 1;    
            _P = GetPatcher();
            _PI = _P->CreateInstance("10SecondSkills");
            // увеличиваем кол-во доступных втор.навыков для изучения
            int ss_num = 10;
            _PI->WriteByte(0x49F90B, ss_num); 
            _PI->WriteByte(0x4A7DD0, ss_num);
            _PI->WriteByte(0x4DAFCE, ss_num);
            _PI->WriteByte(0x4E256A, ss_num);
            _PI->WriteByte(0x57417F, ss_num);
            _PI->WriteByte(0x5F0C87, ss_num);
            _PI->WriteByte(0x5F0F50, ss_num);
            _PI->WriteByte(0x744AB4, ss_num);
            _PI->WriteByte(0x7447E7, ss_num);
            // сдвигаем навыки WoG богов (zgodbon.def) и проклятий
            _PI->WriteDword(0x75482A +1, 171); // богов по y (ориг =180)
            _PI->WriteByte(0x75482F +1, 66); // богов по x (ориг =63)
            _PI->WriteDword(0x7548A4 +1, 171); // проклятие по y (ориг =180)
            _PI->WriteByte(0x7548A9 +1, 113); // проклятие по x (ориг =180)
            // ОПЫТ и МАНА
            // иконка опыта (id = 119)
            _PI->WriteDword(0x4E0DDE +1, 229 -56); // posY    = 229
            _PI->WriteByte(0x4E0DE3 +1, 20);    // posX    = 19
            // опыт текст (id = 108)
            _PI->WriteDword(0x4DED67 +1, 232 -56); // ypos = 232
            _PI->WriteByte(0x4DED6C +1, 68);    // xpos = 68
            // опыт число (id = 112)
            _PI->WriteDword(0x4E123F +1, 252 -56); // ypos = 252
            _PI->WriteByte(0x4E1244 +1, 68);    // xpos = 68
            // иконка маны (id = 120)
            _PI->WriteDword(0x4E0E28 +1, 229 -56); // posY = 229    
            _PI->WriteDword(0x4E0E2D +1, 163);  // posX    = 162
            // мана текст (id = 109)
            _PI->WriteDword(0x4DEDB7 +1, 232 -56); // ypos = 232
            _PI->WriteDword(0x4DEDBC +1, 212);  // xpos = 211
            // мана число (id = 113)
            _PI->WriteDword(0x4E1289 +1, 252 -56); // ypos = 252
            _PI->WriteDword(0x4E128E +1, 212);  // xpos = 211
            // ВТОРИЧНЫЕ НАВЫКИ
            // иконки
            _PI->WriteDword(0x4DF7EF +1, 229);     // posY = 276   id = 79
            _PI->WriteDword(0x4DF83E +1, 229);     // posY = 276   id = 80
            _PI->WriteDword(0x4DF890 +1, 276);     // posY = 324   id = 81
            _PI->WriteDword(0x4DF8DF +1, 276);     // posY = 324   id = 82
            _PI->WriteDword(0x4DF931 +1, 324);     // posY = 372   id = 83
            _PI->WriteDword(0x4DF980 +1, 324);     // posY = 372   id = 84
            _PI->WriteDword(0x4DF9D2 +1, 372);     // posY = 420   id = 85
            _PI->WriteDword(0x4DFA21 +1, 372);     // posY = 420   id = 86
            // имена навыков
            _PI->WriteDword(0x4DFA74 +1, 252);     // posY = 300   id = 87
            _PI->WriteDword(0x4DFAC4 +1, 252);     // posY = 300   id = 88            
            _PI->WriteDword(0x4DFB17 +1, 300);     // posY = 348   id = 89
            _PI->WriteDword(0x4DFB67 +1, 300);     // posY = 348   id = 90
            _PI->WriteDword(0x4DFBBA +1, 348);     // posY = 396   id = 91
            _PI->WriteDword(0x4DFC0A +1, 348);     // posY = 396   id = 92
            _PI->WriteDword(0x4DFC5D +1, 396);     // posY = 444   id = 93
            _PI->WriteDword(0x4DFCAD +1, 396);     // posY = 444   id = 94
            // уровни навыков
            _PI->WriteDword(0x4DFD00 +1, 232);     // posY = 280   id = 95
            _PI->WriteDword(0x4DFD50 +1, 232);     // posY = 280   id = 96            
            _PI->WriteDword(0x4DFDA3 +1, 280);     // posY = 328   id = 97
            _PI->WriteDword(0x4DFDF3 +1, 280);     // posY = 328   id = 98            
            _PI->WriteDword(0x4DFE46 +1, 328);     // posY = 376   id = 99
            _PI->WriteDword(0x4DFE96 +1, 328);     // posY = 376   id = 100            
            _PI->WriteDword(0x4DFEE9 +1, 376);     // posY = 424   id = 101
            _PI->WriteDword(0x4DFF39 +1, 376);     // posY = 424   id = 102
            // переносим первичные навыки
            _PI->WriteByte(0x4DF477 +1, 97);       // атака        posY = 111
            _PI->WriteByte(0x4DF479 +1, 20);       // id = 50      posX = 32
            _PI->WriteDword(0x4DEEB1 +1, 142);     // текст атаки  posY = 158
            _PI->WriteByte(0x4DEEB6 +1, 20);       // id = 46      posX = 32
            _PI->WriteByte(0x4DF4C4 +1, 97);       // защита       posY = 111
            _PI->WriteByte(0x4DF4C6 +1, 67);       // id = 51      posX = 102
            _PI->WriteDword(0x4DEF02 +1, 142);     // текст защиты posY = 158
            _PI->WriteByte(0x4DEF07 +1, 67);       // id = 47      posX = 101
            _PI->WriteByte(0x4DF511 +1, 97);       // колдов       posY = 111
            _PI->WriteDword(0x4DF513 +1, 114);     // id = 52      posX = 172
            _PI->WriteDword(0x4DEF53 +1, 142);     // текст колдов posY = 158
            _PI->WriteDword(0x4DEF58 +1, 114);     // id = 48      posX = 172
            _PI->WriteByte(0x4DF561 +1, 97);       // знания       posY = 111
            _PI->WriteDword(0x4DF563 +1, 162);     // id = 53      posX = 242
            _PI->WriteDword(0x4DEFA7 +1, 142);     // текст знания posY = 158
            _PI->WriteDword(0x4DEFAC +1, 162);     // id = 49      posX = 242
            _PI->WriteDword(0x4E0CFC +1, 98);      // мораль       posY = 184
            _PI->WriteDword(0x4E0D01 +1, 209);     // id = 116     posX = 182
            _PI->WriteDword(0x4E0D48 +1, 98);      // удача        posY = 184
            _PI->WriteDword(0x4E0D4D +1, 255);     // id = 117     posX = 240
            _PI->WriteHiHook(0x4DE980, SPLICE_, EXTENDED_, THISCALL_, Y_HeroDlg_Create);
            _PI->WriteHiHook(0x4E1CC0, SPLICE_, EXTENDED_, THISCALL_, Y_HeroDlg_Update);
            _PI->WriteHiHook(0x4E1940, SPLICE_, EXTENDED_, THISCALL_, Y_HeroDlg_UpdateLuckMoral);
            _PI->WriteHiHook(0x4DD540, SPLICE_, EXTENDED_, THISCALL_, Y_HeroDlg_Proc);
        }
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}