Commit c9174ca4 authored by captainwong's avatar captainwong

update

parent c024947b
#pragma once
#include "qt_global.h"
#include <system_error>
#include <QString>
JLIBQT_NAMESPACE_BEGIN
//! 获取错误码文字描述
inline QString ecString(const std::error_code& ec) {
return QString::fromLocal8Bit(ec.message().data());
}
//! 获取错误码文字描述(带有错误目录)
inline QString ecStringWithCategory(const std::error_code& ec) {
return QString::fromLocal8Bit(ec.category().name()) + ": " + QString::fromLocal8Bit(ec.message().data());
}
#define BREAK_IF_QUERY_FAILED(ec_type) if (!ok) { \
ec = ec_type; \
MYQCRITICAL << ecStringWithCategory(ec) << "\n" << query.lastError(); \
break; \
}
enum class DatabaseErrorCode {
OpenDbFailed = 1,
CreateDbTableFailed,
QueryDbFailed,
};
JLIBQT_NAMESPACE_END
#define ENABLE_ENUM_AS_ERROR_CODE(type) \
namespace std { \
template <> struct is_error_code_enum<type> : true_type {}; \
std::error_code make_error_code(type); \
}
ENABLE_ENUM_AS_ERROR_CODE(JLIBQT_NAMESPACE DatabaseErrorCode)
std::error_code std::make_error_code(JLIBQT_NAMESPACE DatabaseErrorCode ec);
#pragma once
#include "qt_global.h"
#include <system_error>
#include <QString>
JLIBQT_NAMESPACE_BEGIN
//! 获取错误码文字描述
inline QString ecString(const std::error_code& ec) {
return QString::fromLocal8Bit(ec.message().data());
}
//! 获取错误码文字描述(带有错误目录)
inline QString ecStringWithCategory(const std::error_code& ec) {
return QString::fromLocal8Bit(ec.category().name()) + ": " + QString::fromLocal8Bit(ec.message().data());
}
#define BREAK_IF_QUERY_FAILED(ec_type) if (!ok) { \
ec = ec_type; \
MYQCRITICAL << ecStringWithCategory(ec) << "\n" << query.lastError(); \
break; \
}
enum class DatabaseErrorCode {
OpenDbFailed = 1,
CreateDbTableFailed,
QueryDbFailed,
};
JLIBQT_NAMESPACE_END
#define ENABLE_ENUM_AS_ERROR_CODE(type) \
namespace std { \
template <> struct is_error_code_enum<type> : true_type {}; \
std::error_code make_error_code(type); \
}
ENABLE_ENUM_AS_ERROR_CODE(JLIBQT_NAMESPACE DatabaseErrorCode)
std::error_code std::make_error_code(JLIBQT_NAMESPACE DatabaseErrorCode ec);
#pragma once
#include <QDebug>
#include <QDateTime>
#ifdef _WIN32
#include <Windows.h>
#endif //_WIN32
#define JLIBQT_QDEBUG_FILE_LINE_STREAM "[" << __FUNCTION__ << __LINE__ << "]: "
#define JLIBQT_QDEBUG_FILE_LINE_VALUE (QString("[") + __FUNCTION__ + " " + QString::number(__LINE__) + "]: ")
#define MYQDEBUG qDebug() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO qInfo() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN qWarning() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL qCritical() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG_NOQUOTE qDebug().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO_NOQUOTE qInfo().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN_NOQUOTE qWarning().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL_NOQUOTE qCritical().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG2 qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO2 qInfo() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN2 qWarning() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL2 qCritical() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG2_NOQUOTE qDebug().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO2_NOQUOTE qInfo().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN2_NOQUOTE qWarning().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL2_NOQUOTE qCritical().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
//! 弹窗报告行号开关
// #define JLIBQT_SHOW_LINE 0
//! 当行号大于下方定义的值时,弹窗报告行号,否则忽略。可在多个cpp文件分别定义不同的值。
// #define JLIBQT_SHOW_MSGBOX_AFTER_LINE 1
#if JLIBQT_SHOW_LINE
#ifdef JLIBQT_SHOW_MSGBOX_AFTER_LINE
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); }
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); }
#else
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); }
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); }
#endif
#else
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title)
#endif
#pragma once
#include <QDebug>
#include <QDateTime>
#ifdef _WIN32
#include <Windows.h>
#endif //_WIN32
#define JLIBQT_QDEBUG_FILE_LINE_STREAM "[" << __FUNCTION__ << __LINE__ << "]: "
#define JLIBQT_QDEBUG_FILE_LINE_VALUE (QString("[") + __FUNCTION__ + " " + QString::number(__LINE__) + "]: ")
#define MYQDEBUG qDebug() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO qInfo() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN qWarning() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL qCritical() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG_NOQUOTE qDebug().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO_NOQUOTE qInfo().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN_NOQUOTE qWarning().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL_NOQUOTE qCritical().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG2 qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO2 qInfo() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN2 qWarning() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL2 qCritical() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG2_NOQUOTE qDebug().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO2_NOQUOTE qInfo().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN2_NOQUOTE qWarning().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL2_NOQUOTE qCritical().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
//! 弹窗报告行号开关
// #define JLIBQT_SHOW_LINE 0
//! 当行号大于下方定义的值时,弹窗报告行号,否则忽略。可在多个cpp文件分别定义不同的值。
// #define JLIBQT_SHOW_MSGBOX_AFTER_LINE 1
#if JLIBQT_SHOW_LINE
#ifdef JLIBQT_SHOW_MSGBOX_AFTER_LINE
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); }
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); }
#else
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); }
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); }
#endif
#else
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title)
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#pragma once
#include "../base/config.h"
#include <ShlObj.h>
#include <string>
#include <algorithm>
namespace jlib {
namespace win32 {
inline std::wstring getExePath() {
wchar_t path[1024] = { 0 }; ::GetModuleFileNameW(nullptr, path, 1024); return path;
}
inline std::string getExePathA() {
char path[1024] = { 0 }; ::GetModuleFileNameA(nullptr, path, 1024); return path;
}
inline std::wstring getFolder(const std::wstring& path) {
auto pos = path.find_last_of(L"\\/"); return pos != path.npos ? path.substr(0, pos) : path;
}
inline std::string getFolder(const std::string& path) {
auto pos = path.find_last_of("\\/"); return pos != path.npos ? path.substr(0, pos) : path;
}
inline std::wstring getExeFolderPath() { return getFolder(getExePath()); }
inline std::string getExeFolderPathA() { return getFolder(getExePathA()); }
static constexpr const wchar_t* DEFAULT_PATH_FILTERW = L"\\/:*?\"<>| ";
static constexpr const char* DEFAULT_PATH_FILTER = "\\/:*?\"<>| ";
inline std::wstring integrateFileName(const std::wstring& name, const std::wstring& filter = DEFAULT_PATH_FILTERW, wchar_t replace_by = L'_') {
auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret;
}
inline std::string integrateFileName(const std::string& name, const std::string& filter = DEFAULT_PATH_FILTER, char replace_by = '_') {
auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret;
}
inline std::wstring getSpecialFolder(int csidl) {
wchar_t path[MAX_PATH] = { 0 };
return ::SHGetSpecialFolderPathW(nullptr, path, csidl, false) ? std::wstring(path) : std::wstring();
}
inline std::string getSpecialFolderA(int csidl) {
char path[MAX_PATH] = { 0 };
return ::SHGetSpecialFolderPathA(nullptr, path, csidl, false) ? std::string(path) : std::string();
}
/**
* @brief 获取%APPDATA%路径,一般用于存储程序配置文件
* @note 一般xp的结果为: C:\Documents and Setting\[UserName]\Application Data
* @note 一般vista及以上的结果为:C:\Users\[UserName]\AppData\Roaming
*/
inline std::wstring getAppDataPath() { return getSpecialFolder(CSIDL_APPDATA); }
inline std::string getAppDataPathA() { return getSpecialFolderA(CSIDL_APPDATA); }
inline std::wstring getTempPath() { wchar_t path[MAX_PATH] = { 0 }; ::GetTempPathW(MAX_PATH, path); return path; }
inline std::string getTempPathA() { char path[MAX_PATH] = { 0 }; ::GetTempPathA(MAX_PATH, path); return path; }
inline std::wstring getMyDocumentsPath() { return getSpecialFolder(CSIDL_MYDOCUMENTS); }
inline std::string getMyDocumentsPathA() { return getSpecialFolderA(CSIDL_MYDOCUMENTS); }
inline std::wstring getTempFileName(const std::wstring& folder, const std::wstring& pre) {
wchar_t path[MAX_PATH] = { 0 };
UINT ret = ::GetTempFileNameW(folder.c_str(), pre.c_str(), 0, path);
if (ret != 0) { return path; } return std::wstring();
}
inline std::string getTempFileName(const std::string& folder, const std::string& pre) {
char path[MAX_PATH] = { 0 };
UINT ret = ::GetTempFileNameA(folder.c_str(), pre.c_str(), 0, path);
if (ret != 0) { return path; } return std::string();
}
inline std::wstring getTempFileName(const std::wstring& pre = L"JLIB") {
return getTempFileName(getTempPath(), pre);
}
inline std::string getTempFileNameA(const std::string& pre = "JLIB") {
return getTempFileName(getTempPathA(), pre);
}
inline bool folderExists(const std::wstring& folderPath) {
DWORD dwAttrib = ::GetFileAttributesW(folderPath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool folderExists(const std::string& folderPath) {
DWORD dwAttrib = ::GetFileAttributesA(folderPath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool fileExists(const std::wstring& filePath) {
DWORD dwAttrib = ::GetFileAttributesW(filePath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool fileExists(const std::string& filePath) {
DWORD dwAttrib = ::GetFileAttributesA(filePath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool createDirectory(const std::wstring& path) {
return ::CreateDirectoryW(path.data(), nullptr) ? true : false;
}
inline bool createDirectory(const std::string& path) {
return ::CreateDirectoryA(path.data(), nullptr) ? true : false;
}
//! 应用程序典型路径辅助
//struct PathHelper {
//
//
//};
}
}
#pragma once
#include "../base/config.h"
#include <ShlObj.h>
#include <string>
#include <algorithm>
namespace jlib {
namespace win32 {
inline std::wstring getExePath() {
wchar_t path[1024] = { 0 }; ::GetModuleFileNameW(nullptr, path, 1024); return path;
}
inline std::string getExePathA() {
char path[1024] = { 0 }; ::GetModuleFileNameA(nullptr, path, 1024); return path;
}
inline std::wstring getFolder(const std::wstring& path) {
auto pos = path.find_last_of(L"\\/"); return pos != path.npos ? path.substr(0, pos) : path;
}
inline std::string getFolder(const std::string& path) {
auto pos = path.find_last_of("\\/"); return pos != path.npos ? path.substr(0, pos) : path;
}
inline std::wstring getExeFolderPath() { return getFolder(getExePath()); }
inline std::string getExeFolderPathA() { return getFolder(getExePathA()); }
static constexpr const wchar_t* DEFAULT_PATH_FILTERW = L"\\/:*?\"<>| ";
static constexpr const char* DEFAULT_PATH_FILTER = "\\/:*?\"<>| ";
inline std::wstring integrateFileName(const std::wstring& name, const std::wstring& filter = DEFAULT_PATH_FILTERW, wchar_t replace_by = L'_') {
auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret;
}
inline std::string integrateFileName(const std::string& name, const std::string& filter = DEFAULT_PATH_FILTER, char replace_by = '_') {
auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret;
}
inline std::wstring getSpecialFolder(int csidl) {
wchar_t path[MAX_PATH] = { 0 };
return ::SHGetSpecialFolderPathW(nullptr, path, csidl, false) ? std::wstring(path) : std::wstring();
}
inline std::string getSpecialFolderA(int csidl) {
char path[MAX_PATH] = { 0 };
return ::SHGetSpecialFolderPathA(nullptr, path, csidl, false) ? std::string(path) : std::string();
}
/**
* @brief 获取%APPDATA%路径,一般用于存储程序配置文件
* @note 一般xp的结果为: C:\Documents and Setting\[UserName]\Application Data
* @note 一般vista及以上的结果为:C:\Users\[UserName]\AppData\Roaming
*/
inline std::wstring getAppDataPath() { return getSpecialFolder(CSIDL_APPDATA); }
inline std::string getAppDataPathA() { return getSpecialFolderA(CSIDL_APPDATA); }
inline std::wstring getTempPath() { wchar_t path[MAX_PATH] = { 0 }; ::GetTempPathW(MAX_PATH, path); return path; }
inline std::string getTempPathA() { char path[MAX_PATH] = { 0 }; ::GetTempPathA(MAX_PATH, path); return path; }
inline std::wstring getMyDocumentsPath() { return getSpecialFolder(CSIDL_MYDOCUMENTS); }
inline std::string getMyDocumentsPathA() { return getSpecialFolderA(CSIDL_MYDOCUMENTS); }
inline std::wstring getTempFileName(const std::wstring& folder, const std::wstring& pre) {
wchar_t path[MAX_PATH] = { 0 };
UINT ret = ::GetTempFileNameW(folder.c_str(), pre.c_str(), 0, path);
if (ret != 0) { return path; } return std::wstring();
}
inline std::string getTempFileName(const std::string& folder, const std::string& pre) {
char path[MAX_PATH] = { 0 };
UINT ret = ::GetTempFileNameA(folder.c_str(), pre.c_str(), 0, path);
if (ret != 0) { return path; } return std::string();
}
inline std::wstring getTempFileName(const std::wstring& pre = L"JLIB") {
return getTempFileName(getTempPath(), pre);
}
inline std::string getTempFileNameA(const std::string& pre = "JLIB") {
return getTempFileName(getTempPathA(), pre);
}
inline bool folderExists(const std::wstring& folderPath) {
DWORD dwAttrib = ::GetFileAttributesW(folderPath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool folderExists(const std::string& folderPath) {
DWORD dwAttrib = ::GetFileAttributesA(folderPath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool fileExists(const std::wstring& filePath) {
DWORD dwAttrib = ::GetFileAttributesW(filePath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool fileExists(const std::string& filePath) {
DWORD dwAttrib = ::GetFileAttributesA(filePath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
inline bool createDirectory(const std::wstring& path) {
return ::CreateDirectoryW(path.data(), nullptr) ? true : false;
}
inline bool createDirectory(const std::string& path) {
return ::CreateDirectoryA(path.data(), nullptr) ? true : false;
}
//! 应用程序典型路径辅助
//struct PathHelper {
//
//
//};
}
}
This diff is collapsed.
#pragma once
#include <Windows.h>
#include <vector>
namespace jlib
{
namespace win32
{
inline long width(::LPCRECT rc) {
return rc->right - rc->left;
}
inline long height(::LPCRECT rc) {
return rc->bottom - rc->top;
}
inline void deflateRect(::LPRECT rc, int l, int t, int r, int b) {
rc->left += l;
rc->top += t;
rc->right -= r;
rc->bottom -= b;
}
inline void inflateRect(::LPRECT rc, int l, int t, int r, int b) {
rc->left -= l;
rc->top -= t;
rc->right += r;
rc->bottom += b;
}
//! 将矩形平均分割成 n 份,间距 2*gap, n 必须是平方数 x^2, x={1,2,3...}
inline std::vector<::RECT> splitRect(::LPCRECT rc, int n, int gap = 50) {
std::vector<::RECT> v;
for (int i = 0; i < n; i++) {
v.push_back(*rc);
}
double l = sqrt(n);
int line = int(l);
int col_step = (int)(width(rc) / line);
int row_step = (int)(height(rc) / line);
for (int i = 0; i < n; i++) {
v[i].left = rc->left + (i % line) * col_step;
v[i].right = v[i].left + col_step;
v[i].top = rc->top + (i / line) * row_step;
v[i].bottom = v[i].top + row_step;
deflateRect(&v[i], gap, gap, gap, gap);
}
return v;
};
//! 将矩形水平平均分割为 n 份矩形, 当 hgap == -1 时,分割出的矩形与源矩形保持比例
inline std::vector<::RECT> split_rect_horizontal(::LPCRECT rc, int n, int wgap = 50, int hgap = -1) {
std::vector<::RECT> v;
int w = (width(rc) - (n + 1) * wgap) / n;
if (hgap == -1) {
double ratio = (rc->right - rc->left) * 1.0 / (rc->bottom - rc->top);
int h = static_cast<int>(w / ratio);
hgap = (height(rc) - h) / 2;
}
for (int i = 0; i < n; i++) {
::RECT r = *rc;
r.left += i * w + (i + 1) * wgap;
r.right = r.left + w;
r.top = rc->top + hgap;
r.bottom = rc->bottom - hgap;
v.push_back(r);
}
return v;
}
/**
* @brief 从矩形内获取六边形顶点
* @param rc 矩形
* @param spliter 六边形的边长是矩形边长的 1/spliter
* @note rc's width / spliter = (rc's width - hexagon's side length) / 2
* @return 六边形的六个顶点坐标,从上边左侧点顺时针排列
*/
inline std::vector<::POINT> getHexagonVertexesFromRect(::LPCRECT rc, float spliter = 3.0) {
if (!rc) { return std::vector<::POINT>(); }
if (spliter == 0.0) { spliter = 3.0; }
std::vector<::POINT> v;
auto w = rc->right - rc->left;
auto h = rc->bottom - rc->top;
auto ww = static_cast<int>(w / spliter);
auto hh = static_cast<int>(h / spliter);
::POINT pt;
pt.x = rc->left;
pt.y = rc->top + hh;
v.push_back(pt);
pt.x = rc->left + ww;
pt.y = rc->top;
v.push_back(pt);
pt.x = rc->right - ww;
v.push_back(pt);
pt.x = rc->right;
pt.y = rc->top + hh;
v.push_back(pt);
pt.y = rc->bottom - hh;
v.push_back(pt);
pt.x = rc->right - ww;
pt.y = rc->bottom;
v.push_back(pt);
pt.x = rc->left + ww;
v.push_back(pt);
pt.x = rc->left;
pt.y = rc->bottom - hh;
v.push_back(pt);
return v;
}
}
}
#pragma once
#include <Windows.h>
#include <vector>
namespace jlib
{
namespace win32
{
inline long width(::LPCRECT rc) {
return rc->right - rc->left;
}
inline long height(::LPCRECT rc) {
return rc->bottom - rc->top;
}
inline void deflateRect(::LPRECT rc, int l, int t, int r, int b) {
rc->left += l;
rc->top += t;
rc->right -= r;
rc->bottom -= b;
}
inline void inflateRect(::LPRECT rc, int l, int t, int r, int b) {
rc->left -= l;
rc->top -= t;
rc->right += r;
rc->bottom += b;
}
//! 将矩形平均分割成 n 份,间距 2*gap, n 必须是平方数 x^2, x={1,2,3...}
inline std::vector<::RECT> splitRect(::LPCRECT rc, int n, int gap = 50) {
std::vector<::RECT> v;
for (int i = 0; i < n; i++) {
v.push_back(*rc);
}
double l = sqrt(n);
int line = int(l);
int col_step = (int)(width(rc) / line);
int row_step = (int)(height(rc) / line);
for (int i = 0; i < n; i++) {
v[i].left = rc->left + (i % line) * col_step;
v[i].right = v[i].left + col_step;
v[i].top = rc->top + (i / line) * row_step;
v[i].bottom = v[i].top + row_step;
deflateRect(&v[i], gap, gap, gap, gap);
}
return v;
};
//! 将矩形水平平均分割为 n 份矩形, 当 hgap == -1 时,分割出的矩形与源矩形保持比例
inline std::vector<::RECT> split_rect_horizontal(::LPCRECT rc, int n, int wgap = 50, int hgap = -1) {
std::vector<::RECT> v;
int w = (width(rc) - (n + 1) * wgap) / n;
if (hgap == -1) {
double ratio = (rc->right - rc->left) * 1.0 / (rc->bottom - rc->top);
int h = static_cast<int>(w / ratio);
hgap = (height(rc) - h) / 2;
}
for (int i = 0; i < n; i++) {
::RECT r = *rc;
r.left += i * w + (i + 1) * wgap;
r.right = r.left + w;
r.top = rc->top + hgap;
r.bottom = rc->bottom - hgap;
v.push_back(r);
}
return v;
}
/**
* @brief 从矩形内获取六边形顶点
* @param rc 矩形
* @param spliter 六边形的边长是矩形边长的 1/spliter
* @note rc's width / spliter = (rc's width - hexagon's side length) / 2
* @return 六边形的六个顶点坐标,从上边左侧点顺时针排列
*/
inline std::vector<::POINT> getHexagonVertexesFromRect(::LPCRECT rc, float spliter = 3.0) {
if (!rc) { return std::vector<::POINT>(); }
if (spliter == 0.0) { spliter = 3.0; }
std::vector<::POINT> v;
auto w = rc->right - rc->left;
auto h = rc->bottom - rc->top;
auto ww = static_cast<int>(w / spliter);
auto hh = static_cast<int>(h / spliter);
::POINT pt;
pt.x = rc->left;
pt.y = rc->top + hh;
v.push_back(pt);
pt.x = rc->left + ww;
pt.y = rc->top;
v.push_back(pt);
pt.x = rc->right - ww;
v.push_back(pt);
pt.x = rc->right;
pt.y = rc->top + hh;
v.push_back(pt);
pt.y = rc->bottom - hh;
v.push_back(pt);
pt.x = rc->right - ww;
pt.y = rc->bottom;
v.push_back(pt);
pt.x = rc->left + ww;
v.push_back(pt);
pt.x = rc->left;
pt.y = rc->bottom - hh;
v.push_back(pt);
return v;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment