rodecomp/Source/UI/UIMacroUserInfoWnd.cpp
ragnarok-clanker a95a95d16d Decompile fn_09856 (UIMacroReporterWnd::SendMsg)
Batch #8360 by eAthena: 0 byte-identical, 1 confirmed by peer review.

- fn_09856 UIMacroReporterWnd::SendMsg: logic confirmed by peer review

Peer-reviewed-by: Yommy, System4z, dori
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
2026-10-31 17:08:08 +00:00

867 lines
27 KiB
C++

#include "UI/UIMacroUserInfoWnd.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Mode/ModeMgr.h"
#include "Client/Session.h"
#include "Contents/Actors/GameActor.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Mode/ModeMgr.h"
#include "Client/Session.h"
#include "Contents/Actors/GameActor.h"
#include "Contents/MapInfoMgr.h"
#include "Contents/MessageTable.h"
#include "Contents/World/World.h"
#include "Network/Connection/Connection.h"
#include "Network/Packets/PacketLengths.h"
#include "Contents/World/World.h"
#include "Network/Connection/Connection.h"
#include "Network/Packets/PacketLengths.h"
#include "UI/Buttons/UIBitmapButton.h"
#include "UI/Buttons/UIButton.h"
#include "UI/Buttons/UICheckBox.h"
#include "UI/Buttons/UIRadioBtn.h"
#include "UI/Buttons/UITextButton.h"
#include "UI/Edit/UIEditCtrl.h"
#include "UI/Layout/SnapMgr.h"
#include "UI/Layout/WindowSnapping.h"
#include "Contents/UserData/NormalItemSlots.h"
#include "UI/Lists/UIScrollBar.h"
#include "UI/Window/FrameFocus.h"
#include "UI/Window/InputFocus.h"
#include "UI/Window/UIWindowMgr.h"
#include "UI/Window/WindowBorder.h"
#include "UI/Window/WindowDialogs.h"
#include "Utility/Text/FormatString.h"
#include <algorithm>
#include <atlconv.h>
#include <cstdlib>
#include <cstring>
#include <timeapi.h>
#include <vector>
// OFFSET: 0x007EE980
// FUNCTION: fn_09831
MacroReporterEntry::MacroReporterEntry(std::string name, int id, short unknown_001C)
: name(name), id(id), unknown_001C(unknown_001C) {}
// OFFSET: 0x007EEA00
// FUNCTION: fn_09832
UIMacroReporterWnd::UIMacroReporterWnd(UIWindowContext& windows, UIFrameContext& frames, UIButtonContext& controls)
: UIFrameWnd(windows, frames, 0), m_scrollBar(nullptr), m_scrollable(false), unknown_00C8(13), m_firstRow(0), m_visibleRows(10), unknown_00D4(nullptr),
m_reportButton(nullptr), m_mode(0), m_edit(nullptr), unknown_00F4(1), unknown_00F8(5), m_state(nullptr), unknown_010C(false), m_controls(&controls) {
this->m_tabs[0] = nullptr;
this->m_tabs[1] = nullptr;
this->m_tabs[2] = nullptr;
this->m_tabs[3] = nullptr;
this->m_namesValid = false;
this->m_targetValid = false;
this->m_nameCount = 0;
}
// OFFSET: 0x007EEBC0
// FUNCTION: fn_09833
UIMacroUserInfoWnd::UIMacroUserInfoWnd(UIWindowContext& windows, UIFrameContext& frames, UIButtonContext& controls)
: UIFrameWnd(windows, frames, 0), m_controls(&controls) {
}
// OFFSET: 0x007EF2C0
// FUNCTION: fn_09839
void UIMacroReporterWnd::sub_7EF2C0(MacroReporterEntry* entry) {
if (entry) {
this->sub_7EF2E0(entry->id);
}
}
// OFFSET: 0x007EF2E0
// FUNCTION: fn_09840
void UIMacroReporterWnd::sub_7EF2E0(int aid) {
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
if (!actor) {
return;
}
if (!g_session.IsPlayerJobId(actor->GetEffectiveJob(-1))) {
return;
}
mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
std::string name = mode->ActorName(aid);
for (auto it = this->m_entries.begin(); it != this->m_entries.end(); ++it) {
if (it->id == aid) {
goto found;
}
}
this->m_entries.push_back(MacroReporterEntry(name, aid, static_cast<short>(actor->GetEffectiveJob(-1))));
found:
this->sub_7EF430(aid, name);
this->UpdateScrollBar();
}
struct AccessibleButton : public UIButton {
using UIButton::m_argument;
};
struct AccessibleTextButton : public UITextButton {
using UITextButton::m_hoverColor;
};
// OFFSET: 0x007EF430
// FUNCTION: fn_09841
void UIMacroReporterWnd::sub_7EF430(int aid, std::string name) {
for (std::size_t i = 0; i < this->m_rows.size(); ++i) {
if (this->m_rows[i].second->geometry.id == aid) {
return;
}
}
auto* btn1 = new UIBitmapButton();
btn1->SetBitmap("유저인터페이스\\basic_interface\\que_close_on.bmp", 0, 0);
btn1->SetBitmap("유저인터페이스\\basic_interface\\que_close_off.bmp", 1, 0);
btn1->SetBitmap("유저인터페이스\\basic_interface\\que_close_off.bmp", 2, 0);
btn1->SetSize(btn1->BitmapWidth(), btn1->BitmapHeight());
btn1->SetId(211);
reinterpret_cast<AccessibleButton*>(btn1)->m_argument = aid;
btn1->Enable(0);
this->AddChild(btn1);
std::string truncated = this->sub_7EF680(0x8E, name.c_str(), 0, 13, 0);
auto* btn2 = new UITextButton(*this->m_context, *this->m_controls);
btn2->Configure("", 0, 0, 13, 0, 1);
static_cast<AccessibleTextButton*>(btn2)->m_hoverColor = 0x2D2D2D;
btn2->label = truncated;
btn2->ResizeToText();
btn2->SetTooltip(name.c_str());
btn2->SetId(aid);
btn2->Enable(0);
this->AddChild(btn2);
this->m_rows.push_back(std::make_pair(btn1, btn2));
}
// OFFSET: 0x007EF680
// FUNCTION: fn_09842
std::string UIMacroReporterWnd::sub_7EF680(int maxWidth, const char* text, int font, int height, unsigned char bold) {
std::string source(text);
const int width = this->TextWidth(this->m_controls->fonts, this->m_controls->locale, text, 0, font, height, bold, 0);
this->TextWidth(this->m_controls->fonts, this->m_controls->locale, "...", 0, font, height, bold, 0);
if (maxWidth >= width) {
return text;
}
std::string fitted(text);
std::wstring wide(ATL::CA2WEX<128>(text, CP_THREAD_ACP));
while (wide.size() > 1) {
if (wide.size() >= 2) {
const std::size_t size = wide.size();
const std::size_t cut = (wide[size - 2] & 0x80) != 0 && (wide[size - 1] & 0x80) != 0 ? 2 : 1;
wide.resize(size - cut);
}
fitted = ATL::CW2AEX<128>(wide.c_str(), CP_THREAD_ACP);
fitted += "...";
if (this->TextWidth(this->m_controls->fonts, this->m_controls->locale, fitted.c_str(), 0, font, height, bold, 0) <= maxWidth) {
return fitted;
}
}
fitted = ATL::CW2AEX<128>(wide.c_str(), CP_THREAD_ACP);
fitted += "...";
return fitted;
}
// OFFSET: 0x007F0480
// FUNCTION: fn_09845
bool UIMacroUserInfoWnd::Slot08() {
return true;
}
// OFFSET: 0x007F0EE0
// FUNCTION: fn_09847
void UIMacroUserInfoWnd::Slot15(int, int) {
this->AddCloseButton(*this->m_controls, "", 0);
}
// OFFSET: 0x007F0EF0
// FUNCTION: fn_09848
void UIMacroReporterWnd::Paint() {
if (this->m_mode == 0 || this->m_mode == 1) {
this->m_reportButton->SetDisabled(this->m_entries.empty());
this->m_reportButton->Invalidate();
} else if (this->m_mode == 2 || this->m_mode == 3) {
this->m_reportButton->SetDisabled(!(this->m_namesValid == 1 && this->m_targetValid == 1));
this->m_reportButton->Invalidate();
}
DrawFilledRoundedBorder(*this, 0, 0, this->geometry.width, this->geometry.height, 0xFFFFFFFF);
this->DrawTitleBar(this->m_controls->fonts, this->m_controls->locale, true, "", 0);
this->DrawButtonBar(1, 0, 1);
if (this->m_mode != 0 && this->m_mode != 1) {
return;
}
for (int row = 0, y = 56; row < this->m_visibleRows; ++row, y += 22) {
this->FillRegion(14, y, 214, 18, 0xE6E6E6);
}
for (unsigned int index = 0; index < this->m_rows.size(); ++index) {
this->m_rows[index].first->Enable(0);
this->m_rows[index].second->Enable(0);
}
int y = 57;
for (unsigned int index = this->m_firstRow; static_cast<int>(index) < this->m_firstRow + this->m_visibleRows; ++index, y += 22) {
if (index >= this->m_rows.size()) {
return;
}
this->m_rows[index].first->Enable(1);
this->m_rows[index].first->Move(15, y + 2);
this->m_rows[index].second->Enable(1);
this->m_rows[index].second->Move(36, y);
}
}
// OFFSET: 0x007F10F0
// FUNCTION: fn_09849
void UIMacroUserInfoWnd::Paint() {
this->ClearSurface(0xFAFAFA);
this->DrawTextAt(this->m_controls->fonts, this->m_controls->locale, 5, 5, this->m_name.c_str(), 0, 0, 12, 0, 1, 0);
this->DrawTextAt(this->m_controls->fonts, this->m_controls->locale, 5, 20, this->m_message.c_str(), 0, 0, 12, 0, 0, 0);
}
// OFFSET: 0x007F1160
// FUNCTION: fn_09850
void UIMacroReporterWnd::Slot25(int x, int y) {
if (this->unknown_010C == 1 && y >= 18) {
return;
}
if (g_dragWindowId != this->geometry.id) {
g_windowMgr.BringToFront(this->geometry.id);
g_dragWindowId = this->geometry.id;
}
g_windowMgr.SetCapture(this);
this->ToScreen(x, y);
this->m_dragX = x;
this->m_dragY = y;
this->m_originX = this->geometry.x;
this->m_originY = this->geometry.y;
this->m_frameContext->snapping.graph.CaptureOrigins(this);
}
// OFFSET: 0x007F11F0
// FUNCTION: fn_09851
void UIMacroReporterWnd::Slot31(int, int) {
if (g_windowMgr.Capture() != this) {
return;
}
g_dragWindowId = -1;
g_windowMgr.ReleaseCapture();
this->m_frameContext->snapping.graph.Refresh(this);
}
// OFFSET: 0x007F1230
// FUNCTION: fn_09852
void UIMacroReporterWnd::Slot19() {
for (auto it = this->m_removedRows.begin(); it != this->m_removedRows.end();) {
if ((*it)->Disabled()) {
this->RemoveChild(*it, 1);
it = this->m_removedRows.erase(it);
} else {
++it;
}
}
this->Invalidate();
}
// OFFSET: 0x007F12A0
// FUNCTION: fn_09853
void UIMacroReporterWnd::Slot35(int delta) {
if (this->m_scrollable == 1) {
this->SendMsg(this->m_scrollBar, 7, delta < 0 ? 3 : -3, 0, 0, 0);
}
}
// OFFSET: 0x007F12E0
// FUNCTION: fn_09854
void UIMacroReporterWnd::UpdateScrollBar() {
const int count = static_cast<int>(this->m_rows.size());
if (count == 0 || !this->m_scrollBar) {
return;
}
const int maximum = (std::max)(count - this->m_visibleRows, 0);
this->m_scrollable = maximum > 0;
if (maximum < 1) {
this->m_firstRow = 0;
this->m_scrollBar->SetRange(0, this->m_visibleRows, count);
} else {
this->m_scrollBar->SetRange(maximum, this->m_visibleRows, count);
if (this->m_firstRow < 0) {
this->m_firstRow = 0;
this->m_scrollBar->SetPosition(0);
} else {
if (maximum < this->m_firstRow) {
this->m_firstRow = maximum;
}
this->m_scrollBar->SetPosition(this->m_firstRow);
}
}
this->m_scrollBar->Invalidate();
this->Invalidate();
}
// OFFSET: 0x007EFE30
// FUNCTION: fn_09843
bool UIMacroReporterWnd::ValidateNames(unsigned char notify) {
this->m_nameCount = 0;
bool invalid = false;
for (int i = 0; i < this->m_visibleRows; ++i) {
std::string name = this->m_names[i];
if (name.empty()) {
continue;
}
std::string displayName = g_mapInfoMgr->GetDisplayName(name + ".rsw");
if (displayName == LookupMessage(187)) {
if (notify == 1) {
g_windowMgr.SendNotice(
1,
reinterpret_cast<std::intptr_t>(FormatOwnedString("%d번 %s", i + 1, LookupMessage(4010)).c_str()),
0xFF,
0,
0,
0
);
}
invalid = true;
} else {
++this->m_nameCount;
}
}
if (this->m_nameCount > 0 && !invalid) {
return true;
}
return false;
}
// OFFSET: 0x007F01A0
// FUNCTION: fn_09844
bool UIMacroReporterWnd::ValidateTarget(unsigned char notify) {
std::string text = this->m_target;
if (text.empty() || text.size() - 4 > 4) {
if (notify == 1) {
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(FormatOwnedString("%s", LookupMessage(4011)).c_str()), 0xFF, 0, 0, 0);
}
return false;
}
const int value = std::atoi(text.c_str());
char digits[16] = {};
if (text.size() != 0) {
std::memset(digits, '0', text.size());
}
if (value == 0 && text.compare(digits) != 0) {
if (notify == 1) {
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(FormatOwnedString("%s", LookupMessage(4011)).c_str()), 0xFF, 0, 0, 0);
}
return false;
}
text = "1" + this->m_target;
char number[16] = {};
int scale = 1;
for (std::size_t index = 1; index < text.size(); ++index) {
scale *= 10;
}
_itoa(scale + value, number, 10);
if (text.compare(number) != 0) {
if (notify == 1) {
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(FormatOwnedString("%s", LookupMessage(4011)).c_str()), 0xFF, 0, 0, 0);
}
return false;
}
return true;
}
// OFFSET: 0x007F25C0
// FUNCTION: fn_09857
int UIMacroUserInfoWnd::SendMsg(
UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4
) {
if (message == 6 && argument1 == 201) {
g_windowMgr.CloseWindow(287);
}
return this->UIFrameWnd::SendMsg(sender, message, argument1, argument2, argument3, argument4);
}
// OFFSET: 0x007F26C0
// FUNCTION: fn_09858
void UIMacroReporterWnd::Slot11() {
if (this->m_state) {
this->m_state->width = this->geometry.width;
this->m_state->height = this->geometry.height;
this->m_state->x = this->geometry.x;
this->m_state->y = this->geometry.y;
this->m_state->unknown_0011 = this->unknown_010C;
this->m_state->entries.clear();
this->m_state->entries.resize(this->m_entries.size());
for (unsigned int index = 0; index < this->m_entries.size(); ++index) {
this->m_state->entries[index] = this->m_entries[index];
}
}
}
// OFFSET: 0x007F13C0
// FUNCTION: fn_09855
void __stdcall SendMacroUserInfoPacket(std::uint16_t first, std::uint16_t second, std::uint8_t third) {
struct Packet {
std::uint16_t id;
std::uint16_t first;
std::uint16_t second;
std::uint8_t third;
} packet{0x0A6C, first, second, third};
CRagConnection* connection = &GetRagConnection();
const PacketLengths& lengths = reinterpret_cast<const PacketLengths&>(GetRagConnection());
connection->Send(lengths.FixedLength(packet.id), &packet);
}
// OFFSET: 0x007F0490
// FUNCTION: fn_09846
void UIMacroReporterWnd::Slot15(int, int) {
this->AddBaseButton(*this->m_controls);
this->AddCloseButton(*this->m_controls, "", 0);
this->m_scrollBar = new UIScrollBar(*this->m_context);
this->m_scrollBar->Configure(186, 56, 1, 216);
this->AddChild(this->m_scrollBar);
UICheckBox* check = new UICheckBox(*this->m_context, *this->m_controls);
this->unknown_00D4 = check;
check->SetSize(42, 20);
check->SetBitmaps("유저인터페이스\\btn_q_active_a.bmp", "유저인터페이스\\btn_q_active.bmp");
check->Move(202, 27);
check->SetChecked(0);
this->AddChild(check);
UIBitmapButton* report = new UIBitmapButton(*this->m_context, *this->m_controls);
this->m_reportButton = report;
report->SetBitmap("유저인터페이스\\btn_ok.bmp", 0, 0);
report->SetBitmap("유저인터페이스\\btn_ok_a.bmp", 1, 0);
report->SetBitmap("유저인터페이스\\btn_ok_b.bmp", 2, 0);
report->SetBitmap("유저인터페이스\\btn_ok_c.bmp", 3, 0);
report->SetSize(report->BitmapWidth(), report->BitmapHeight());
report->Move(202, 285);
report->SetId(345);
this->AddChild(report);
std::string labels[4] = {LookupMessage(2887), LookupMessage(2888), LookupMessage(4006), LookupMessage(4007)};
std::string tooltips[4] = {LookupMessage(2889), LookupMessage(2890), LookupMessage(4008), LookupMessage(4009)};
int index = 0;
for (; index < 2; ++index) {
UIRadioBtn* tab = new UIRadioBtn(*this->m_context, *this->m_controls);
this->m_tabs[index] = tab;
tab->SetSize(50, 12);
tab->Move(14 + index * 55, 31);
tab->SetText(labels[index].c_str());
tab->SetId(215);
tab->value = index;
tab->SendMsg(this, 13, index == this->m_mode, 0, 0, 0);
if (const char* tooltip = tooltips[index].c_str()) {
tab->tooltip = tooltip;
}
this->AddChild(tab);
}
for (; index < 4; ++index) {
UIRadioBtn* tab = new UIRadioBtn(*this->m_context, *this->m_controls);
this->m_tabs[index] = tab;
tab->SetSize(50, 12);
tab->Move(70 + index * 30, 31);
tab->SetText(labels[index].c_str());
tab->SetId(215);
tab->value = index;
tab->SendMsg(this, 13, index == this->m_mode, 0, 0, 0);
if (const char* tooltip = tooltips[index].c_str()) {
tab->tooltip = tooltip;
}
this->AddChild(tab);
}
int y = 56;
for (int row = 0; row < this->m_visibleRows; ++row) {
UIEditCtrl* field = new UIEditCtrl();
this->m_fields[row] = field;
field->SetSize(214, 18);
field->Move(14, y);
field->flat = 0;
field->Border(125, 125, 125);
field->preserveInput = 1;
field->invalidatesParent = 1;
field->disabled = 1;
field->Invalidate();
if (const char* tooltip = LookupMessage(4012)) {
field->tooltip = tooltip;
}
this->AddChild(field);
this->m_names[row] = "";
y += 22;
}
this->m_target = "";
UIEditCtrl* target = new UIEditCtrl();
this->m_edit = target;
target->SetSize(15, 14);
target->Move(this->TextWidth(this->m_controls->fonts, this->m_controls->locale, labels[1].c_str(), 0, 0, 12, 0, 0) + 83, 30);
target->flat = 0;
target->Border(125, 125, 125);
target->maximum = 1;
target->preserveInput = 1;
target->invalidatesParent = 1;
target->SetText(IntToString(this->unknown_00F4, 0).c_str());
if (const char* tooltip = LookupMessage(2891)) {
target->tooltip = tooltip;
}
this->AddChild(target);
if (this->m_mode != 1) {
target->disabled = 1;
target->Invalidate();
}
this->m_entries.clear();
}
namespace {
#pragma pack(push, 1)
struct PACKET_CZ_MACRO_REPORT_HEADER {
/* 0000 */ std::uint16_t packetType;
/* 0002 */ std::uint16_t packetLength;
/* 0004 */ char target[16];
/* 0014 */ std::uint8_t type;
/* 0015 */ std::uint8_t count;
};
struct PACKET_CZ_MACRO_REPORT_ACCOUNT {
/* 0000 */ short packetType;
/* 0002 */ std::uint32_t accountId;
};
#pragma pack(pop)
}
// OFFSET: 0x007F1420
// FUNCTION: fn_09856
int UIMacroReporterWnd::SendMsg(
UIWindow* sender, int message, std::intptr_t argument1, std::intptr_t argument2, std::intptr_t argument3, std::intptr_t argument4
) {
switch (message) {
case 0:
if (this->m_mode == 2) {
if (sender) {
const int index = (sender->geometry.y - 56) / 22;
this->m_names[index] = static_cast<UIEditCtrl*>(sender)->Text();
}
} else if (this->m_mode == 3) {
if (sender && sender == this->m_fields[0]) {
this->m_target = static_cast<UIEditCtrl*>(this->m_fields[0])->Text();
}
} else if (sender == this->m_edit) {
UIEditCtrl* edit = static_cast<UIEditCtrl*>(this->m_edit);
std::string text = edit->Text();
if (text.size() > 1) {
edit->SetText(IntToString(this->unknown_00F4, 0).c_str());
} else if (text.c_str()[0] >= '0' && text.c_str()[0] <= '9') {
this->unknown_00F4 = std::atoi(text.c_str());
if (this->unknown_00F4 > this->unknown_00F8) {
this->unknown_00F4 = this->unknown_00F8;
edit->SetText(IntToString(this->unknown_00F8, 0).c_str());
}
} else {
edit->SetText(IntToString(this->unknown_00F4, 0).c_str());
}
}
break;
case 6:
switch (argument1) {
case 201:
g_windowMgr.CloseWindow(286);
break;
case 211: {
for (auto it = this->m_entries.begin(); it != this->m_entries.end(); ++it) {
if (argument2 == it->id) {
for (auto next = it + 1; next != this->m_entries.end(); ++next, ++it) {
it->name.swap(next->name);
it->id = next->id;
it->unknown_001C = next->unknown_001C;
}
this->m_entries.pop_back();
break;
}
}
for (auto it = this->m_rows.begin(); it != this->m_rows.end(); ++it) {
if (sender == it->first) {
it->first->SetDisabled(1);
it->first->Invalidate();
this->m_removedRows.push_back(it->first);
it->second->SetDisabled(1);
it->second->Invalidate();
this->m_removedRows.push_back(it->second);
this->m_rows.erase(it);
break;
}
}
this->UpdateScrollBar();
break;
}
case 213:
if (this->unknown_00D4 != sender) {
break;
}
this->unknown_010C = argument2 != 0;
switch (this->m_mode) {
case 0:
case 1:
if (argument2) {
this->geometry.targetAlpha = 128;
} else {
this->geometry.targetAlpha = 255;
}
this->geometry.alphaStart = timeGetTime();
break;
case 2:
case 3:
this->m_namesValid = this->ValidateNames(1);
this->m_targetValid = this->ValidateTarget(1);
break;
}
break;
case 215: {
if (this->unknown_010C == true) {
switch (this->m_mode) {
case 0:
case 1:
if (argument2 == 2 || argument2 == 3) {
static_cast<UICheckBox*>(this->unknown_00D4)->SetChecked(0);
}
break;
case 2:
case 3:
if (argument2 == 0 || argument2 == 1) {
static_cast<UICheckBox*>(this->unknown_00D4)->SetChecked(0);
}
break;
}
}
if (this->m_mode == 2) {
this->ValidateNames(0);
} else if (this->m_mode == 3) {
this->ValidateTarget(0);
}
this->m_mode = argument2;
for (int index = 0; index < 4; ++index) {
this->m_tabs[index]->SendMsg(this, 13, 0, 0, 0, 0);
}
sender->SendMsg(this, 13, 1, 0, 0, 0);
UIEditCtrl* edit = static_cast<UIEditCtrl*>(this->m_edit);
if (sender == this->m_tabs[1]) {
edit->disabled = 0;
} else {
edit->disabled = 1;
}
edit->Invalidate();
if (sender == this->m_tabs[0] || sender == this->m_tabs[1]) {
InputFocus focus{g_windowMgr.hoverWindow};
focus.Set(nullptr);
for (int index = 0; index < this->m_visibleRows; ++index) {
UIEditCtrl* field = static_cast<UIEditCtrl*>(this->m_fields[index]);
field->disabled = 1;
field->Invalidate();
field->SetText("");
}
for (auto it = this->m_rows.begin(); it != this->m_rows.end(); ++it) {
it->first->SetDisabled(0);
it->first->Invalidate();
it->second->SetDisabled(0);
it->second->Invalidate();
it->first->Enable(1);
it->second->Enable(1);
}
} else {
for (auto it = this->m_rows.begin(); it != this->m_rows.end(); ++it) {
it->first->SetDisabled(1);
it->first->Invalidate();
it->second->SetDisabled(1);
it->second->Invalidate();
it->first->Enable(0);
it->second->Enable(0);
}
for (int index = 0; index < this->m_visibleRows; ++index) {
UIEditCtrl* field = static_cast<UIEditCtrl*>(this->m_fields[index]);
field->disabled = 0;
field->Invalidate();
if (sender == this->m_tabs[2]) {
field->SetText(this->m_names[index].c_str());
} else if (sender == this->m_tabs[3]) {
if (index == 0) {
field->SetText(this->m_target.c_str());
} else {
field->SetText("");
}
}
}
}
break;
}
case 345:
if (this->m_mode == 2 || this->m_mode == 3) {
this->m_namesValid = this->ValidateNames(1);
this->m_targetValid = this->ValidateTarget(1);
if (this->m_namesValid == true && this->m_targetValid == true) {
PACKET_CZ_MACRO_REPORT_HEADER header;
header.packetType = 0xBDA;
strncpy_s(header.target, sizeof(header.target), this->m_target.c_str(), _TRUNCATE);
header.count = static_cast<std::uint8_t>(this->m_nameCount);
const int length = this->m_nameCount * 16 + sizeof(header);
header.type = 6;
char buffer[2048];
std::memset(buffer + sizeof(header), 0, sizeof(buffer) - sizeof(header));
if (length > sizeof(buffer)) {
break;
}
header.packetLength = static_cast<std::uint16_t>(length);
std::memcpy(buffer, &header, sizeof(header));
for (int index = 0; index < this->m_nameCount; ++index) {
if (!this->m_names[index].empty()) {
char name[16];
strncpy_s(name, sizeof(name), (this->m_names[index] + ".gat").c_str(), _TRUNCATE);
memcpy_s(buffer + sizeof(header) + index * 16, 16, name, sizeof(name));
}
}
GetRagConnection().Send(length, buffer);
}
} else {
std::vector<int> accounts;
for (auto it = this->m_entries.begin(); it != this->m_entries.end(); ++it) {
if (std::find(accounts.begin(), accounts.end(), it->id) == accounts.end()) {
accounts.push_back(it->id);
}
}
const int result = reinterpret_cast<WindowDialogs*>(&g_windowMgr)
->Confirm(FormatOwnedString(LookupMessage(2876), accounts.size()).c_str(), 2, false, false, 0, "Message", 280, 120, 0);
if (result != 188) {
for (auto it = accounts.begin(); it != accounts.end(); ++it) {
PACKET_CZ_MACRO_REPORT_ACCOUNT packet;
packet.packetType = 0xA56;
packet.accountId = *it;
GetRagConnection().Send(reinterpret_cast<const PacketLengths&>(GetRagConnection()).FixedLength(packet.packetType), &packet);
}
this->m_entries.clear();
for (auto it = this->m_rows.begin(); it != this->m_rows.end(); ++it) {
it->first->SetDisabled(1);
it->first->Invalidate();
this->m_removedRows.push_back(it->first);
it->second->SetDisabled(1);
it->second->Invalidate();
this->m_removedRows.push_back(it->second);
}
this->m_rows.clear();
}
}
break;
}
break;
case 7:
case 9:
case 10: {
const int previous = this->m_firstRow;
if (message == 9) {
this->m_firstRow = previous - this->m_visibleRows + 1;
} else if (message == 10) {
this->m_firstRow = previous + (this->m_visibleRows - 1);
} else {
this->m_firstRow = previous + argument1;
}
if (previous != this->m_firstRow) {
this->UpdateScrollBar();
}
return this->m_firstRow - previous;
}
case 34: {
this->m_state = reinterpret_cast<MacroReporterState*>(argument1);
if (!reinterpret_cast<MacroReporterWndInfo*>(this->m_state)->IsValid()) {
reinterpret_cast<MacroReporterWndInfo*>(this->m_state)->Reset();
}
this->Resize(this->m_state->width, this->m_state->height);
this->Move(this->m_state->x, this->m_state->y);
this->unknown_010C = this->m_state->unknown_0011;
static_cast<UICheckBox*>(this->unknown_00D4)->SetChecked(this->unknown_010C);
this->m_entries.clear();
for (unsigned int index = 0; index < this->m_state->entries.size(); ++index) {
const MacroReporterEntry& entry = this->m_state->entries[index];
this->m_entries.push_back(MacroReporterEntry(entry.name, entry.id, entry.unknown_001C));
this->sub_7EF430(entry.id, entry.name);
}
this->UpdateScrollBar();
break;
}
case 98: {
auto entry = this->m_entries.begin();
for (; entry != this->m_entries.end(); ++entry) {
if (argument1 == entry->id) {
break;
}
}
if (entry == this->m_entries.end()) {
break;
}
unsigned int row = 0;
for (; row < this->m_rows.size(); ++row) {
if (sender == this->m_rows[row].second) {
break;
}
}
if (!g_windowMgr.CloseWindow(287)) {
UIMacroUserInfoWnd* info = static_cast<UIMacroUserInfoWnd*>(g_windowMgr.EnsureWindow(287));
info->Move(this->geometry.x + 15, this->geometry.y + row * 22 + 78);
const unsigned short job = entry->unknown_001C;
std::string name = entry->name;
info->m_name = name;
info->m_message = g_session.GetJobName(job, -1);
info->Invalidate();
}
break;
}
}
return this->UIFrameWnd::SendMsg(sender, message, argument1, argument2, argument3, argument4);
}