想写个界面,之前试过Qt、Dear ImGui各写了一个但不太理想,
Qt(布局有点麻烦,没学qml)
Dear ImGui(多语言支持不友好)
看到aardio写界面很方便,但不知道该怎么入手…
main.hpp(文末有全部代码的附件)
#include <windows.h>
#include <fstream>
#include <iostream>
#include <cstring>
#include <tchar.h>
#include <vector>
#include <locale>
#include <codecvt>
#include <string>
#include <atlconv.h>
#define NTAC_MAGIC 0x4341544E
#define NTAC_NAME_LEN 40
#define NTAC_IP_LEN 15
#define NTAC_USERNAME_LEN 30
#define NTAC_PASSWORD_LEN 30
#define NTAC_APN_LEN 30
#define NTAC_HOMEPAGE_LEN 512
#define NTAC_MAX_NUM 0xFFFF
#define NTAC_PROXY_LEN 128
#define NTAC_VER 1
typedef struct _NTAC_FILE_HEAD_T
{
DWORD magic;
WORD version;
WORD nCount;
_NTAC_FILE_HEAD_T()
{
memset(this, 0, sizeof(_NTAC_FILE_HEAD_T));
}
} NTAC_FILE_HEAD_T;
typedef struct _NTAC_T
{
DWORD active_flag; // only used by tools
WORD reserved;
WORD mcc; // mcc country code, 一般都是3位
WORD mnc; // mnc network code
WORD port; // 代理服务器端口号 默认80
BYTE access_type; // 连接类型:0 表示wap1.2(WSP), 1表示wap2.0(HTTP)//如果选择Wap1.2,port默认变为9201 , 默认2.0
BYTE access_option; // 存取选项,0:可编辑;1:只读
BYTE auth_type; // 鉴定类型0:PAP; 1:CHAP; 2:PAP+CHAP; 3:NONE//uint8
BYTE account_type; // 帐户类型0:浏览器,1:MMS,2:JAVA,3:DCD // uint8
WCHAR name[NTAC_NAME_LEN + 1]; // 连接名称 最大28
WCHAR gateway[NTAC_PROXY_LEN + 1]; // 代理服务器IP地址 默认0.0.0.0 最大128
WCHAR dns1[NTAC_IP_LEN + 1]; // 首选dns 默认0.0.0.0 最大15
WCHAR dns2[NTAC_IP_LEN + 1]; // 备选dns 默认0.0.0.0 最大15
WCHAR username[NTAC_USERNAME_LEN + 1]; // 用户名 最大30
WCHAR password[NTAC_PASSWORD_LEN + 1]; // 密码 最大30
WCHAR apn[NTAC_APN_LEN + 1]; // 接入点名称 最大30
WCHAR homepage[NTAC_HOMEPAGE_LEN + 1]; // 主页地址 最大512
_NTAC_T()
{
Init();
}
void Init()
{
memset(this, 0, sizeof(_NTAC_T));
active_flag = 0;
mcc = 0;
mnc = 0;
port = 80;
access_type = 1;
access_option = 0;
auth_type = 0;
account_type = 0;
wcscpy_s(gateway, NTAC_PROXY_LEN + 1, L"0.0.0.0");
wcscpy_s(dns1, NTAC_IP_LEN + 1, L"0.0.0.0");
wcscpy_s(dns2, NTAC_IP_LEN + 1, L"0.0.0.0");
}
} NTAC_T;
typedef enum
{
MN_PAP = 0,
MN_CHAP = 1
} MN_PCO_AUTH_TYPE_E;
typedef enum
{
MMICONNECTION_ACCOUNT_BROWSER,
MMICONNECTION_ACCOUNT_MMS,
MMICONNECTION_ACCOUNT_JAVA,
MMICONNECTION_ACCOUNT_DCD,
MMICONNECTION_ACCOUNT_MAX,
} MMICONNECTION_ACCOUNT_TYPE_E;
typedef enum
{
E_OK = 0,
E_INIT_XLS_ERR,
E_OPEN_XLS_ERR,
E_OPEN_SHEET_ERR,
E_READ_ROW_ERR,
E_INVALID_XLS_ERR,
E_DEC_XLS_ERR,
E_Count
} NAPASE_STATUS;
BOOL EncodeString(LPBYTE &pBuf, LPBYTE pEnd, WCHAR *pString, BOOL bUnicode = FALSE);
BOOL EncodeNTAC(LPBYTE &pBuf, DWORD &dwSize);
BOOL ExportNTACFile(const std::string &filePath);
BOOL ParseNtacSheet(const std::string &filePath);
BOOL DecodeXlsx2Ntac(xlnt::worksheet &ws);
main.cpp
#include "./xlnt/xlnt.hpp"
#include "main.hpp"
std::vector<NTAC_T> m_vNTAC;
NTAC_FILE_HEAD_T m_tHead;
std::wstring ConvertA2W(const std::string &str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(str);
}
VOID Clear()
{
memset(&m_tHead, 0, sizeof(m_tHead));
m_tHead.version = NTAC_VER;
m_vNTAC.clear();
}
BOOL EncodeString(LPBYTE &pBuf, LPBYTE pEnd, WCHAR *pString, BOOL bUnicode /*=FALSE*/)
{
USES_CONVERSION;
WORD wLen = (WORD)(wcslen(pString) + 1);
if (bUnicode)
{
wLen *= 2;
}
WORD wSize = (WORD)(((wLen + 3 + 2) / 4) * 4 - 2); // not include size itself, but calc align with it
if (pBuf + wSize + 2 > pEnd) // Check if there is enough space
{
return FALSE;
}
*(WORD *)pBuf = wSize;
pBuf += 2;
if (bUnicode)
{
for (WORD i = 0; i < (wLen / 2); i++)
{
*(WORD *)(pBuf + i * 2) = pString[i];
}
}
else
{
if (pBuf + wSize > pEnd) // Check if there is enough space
{
return FALSE;
}
strcpy_s((char *)pBuf, wSize, W2A(pString));
}
pBuf += wSize;
return TRUE;
}
BOOL EncodeNTAC(LPBYTE &pBuf, DWORD &dwSize)
{
pBuf = NULL;
dwSize = 0;
DWORD dwMaxSize = (sizeof(NTAC_T) + sizeof(DWORD)) * m_tHead.nCount + 8;
pBuf = new BYTE[dwMaxSize];
memset(pBuf, 0, dwMaxSize);
LPBYTE pCur = pBuf;
*(DWORD *)pCur = NTAC_MAGIC;
pCur += 4;
WORD ver = m_tHead.version;
*(WORD *)pCur = ver;
pCur += 2;
*(WORD *)(pCur) = m_tHead.nCount;
pCur += 2;
DWORD *pOffset = (DWORD *)pCur;
pCur += m_tHead.nCount * 4;
DWORD dwOffset = static_cast<DWORD>(pCur - pBuf);
for (UINT i = 0; i < m_vNTAC.size(); i++)
{
if (m_vNTAC[i].active_flag)
{
*pOffset = dwOffset;
pCur = pBuf + dwOffset;
*(WORD *)pCur = m_vNTAC[i].reserved;
pCur += 2;
*(WORD *)pCur = m_vNTAC[i].mcc;
pCur += 2;
*(WORD *)pCur = m_vNTAC[i].mnc;
pCur += 2;
*(WORD *)pCur = m_vNTAC[i].port;
pCur += 2;
memcpy(pCur, &m_vNTAC[i].access_type, 4);
pCur += 4;
LPBYTE pEnd = pBuf + dwMaxSize;
EncodeString(pCur, pEnd, m_vNTAC[i].name, TRUE);
EncodeString(pCur, pEnd, m_vNTAC[i].gateway, FALSE);
EncodeString(pCur, pEnd, m_vNTAC[i].dns1, FALSE);
EncodeString(pCur, pEnd, m_vNTAC[i].dns2, FALSE);
EncodeString(pCur, pEnd, m_vNTAC[i].username, FALSE);
EncodeString(pCur, pEnd, m_vNTAC[i].password, FALSE);
EncodeString(pCur, pEnd, m_vNTAC[i].apn, FALSE);
EncodeString(pCur, pEnd, m_vNTAC[i].homepage, FALSE);
dwOffset = static_cast<DWORD>(pCur - pBuf);
pOffset++;
}
}
dwSize = static_cast<DWORD>(pCur - pBuf);
return TRUE;
}
BOOL ExportNTACFile(const std::string &filePath)
{
// 写入到新的ntac文件
FILE *pFile;
LPBYTE pBuf = NULL;
DWORD dwSize = 0;
EncodeNTAC(pBuf, dwSize);
errno_t err = _tfopen_s(&pFile, _T(filePath.c_str()), _T("wb"));
if (err != 0) {
std::cout << _T("File open file!") << std::endl;
return 0;
}
if (pFile != NULL)
{
DWORD dwWrite = static_cast<DWORD>(fwrite(pBuf, 1, dwSize, pFile));
fclose(pFile);
}
delete[] pBuf;
pBuf = NULL;
return 1;
}
int StringToInt(const std::string &str)
{
try
{
return std::stoi(str);
}
catch (std::invalid_argument &)
{
return 0; // 或者返回你认为合适的默认值
}
}
BOOL ParseNtacSheet(const std::string &filePath)
{
try
{
xlnt::workbook wb;
wb.load(filePath);
for (auto ws : wb)
{
if (ws.title() == "NTAC")
{
if (!DecodeXlsx2Ntac(ws))
{
return FALSE;
}
}
}
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what() << std::endl;
return FALSE;
}
return TRUE;
}
BOOL DecodeXlsx2Ntac(xlnt::worksheet &ws)
{
try
{
m_tHead.magic = NTAC_MAGIC;
m_tHead.version = 1;
m_tHead.nCount = static_cast<WORD>(ws.rows().length() - 1); // Subtract 1 for the header row
bool isFirstRow = true;
for (auto row : ws.rows(false))
{
if (isFirstRow)
{
isFirstRow = false;
continue;
}
NTAC_T ntac;
ntac.Init();
ntac.active_flag = TRUE;
ntac.reserved = StringToInt(row[15].to_string());
ntac.mcc = StringToInt(row[1].to_string());
ntac.mnc = StringToInt(row[2].to_string());
ntac.port = StringToInt(row[8].to_string());
ntac.access_type = StringToInt(row[5].to_string());
ntac.access_option = StringToInt(row[6].to_string());
ntac.auth_type = StringToInt(row[14].to_string());
ntac.account_type = StringToInt(row[3].to_string());
wcscpy_s(ntac.name, sizeof(ntac.name) / sizeof(WCHAR), ConvertA2W(row[0].to_string()).c_str());
wcscpy_s(ntac.gateway, sizeof(ntac.gateway) / sizeof(WCHAR), ConvertA2W(row[7].to_string()).c_str());
wcscpy_s(ntac.dns1, sizeof(ntac.dns1) / sizeof(WCHAR), ConvertA2W(row[11].to_string()).c_str());
wcscpy_s(ntac.dns2, sizeof(ntac.dns2) / sizeof(WCHAR), ConvertA2W(row[12].to_string()).c_str());
wcscpy_s(ntac.username, sizeof(ntac.username) / sizeof(WCHAR), ConvertA2W(row[9].to_string()).c_str());
wcscpy_s(ntac.password, sizeof(ntac.password) / sizeof(WCHAR), ConvertA2W(row[10].to_string()).c_str());
wcscpy_s(ntac.apn, sizeof(ntac.apn) / sizeof(WCHAR), ConvertA2W(row[4].to_string()).c_str());
wcscpy_s(ntac.homepage, sizeof(ntac.homepage) / sizeof(WCHAR), ConvertA2W(row[13].to_string()).c_str());
m_vNTAC.push_back(ntac);
}
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what() << std::endl;
return FALSE;
}
return TRUE;
}
int main()
{
// 读取xlsx文件,写入m_vNTAC
if (!ParseNtacSheet("../../input.xlsx"))
{
std::cout << _T("parse NTAC sheet failed!") << std::endl;
return 0;
}
// 将m_vNTAC导出为ntac文件
if (!ExportNTACFile("output.ntac"))
{
return 0;
}
return 0;
}
20231202104807260-cpp.zip
zip文件
28.0M
没有回复内容