Skip to content

Commit 72066a3

Browse files
committed
分发兼容:配置路径 AppData 回退 + QuickView DPI 感知 + 崩溃日志 + 窗口尺寸适配
- qlens_config.ini 读写:exe 旁可写(便携)→ %APPDATA%/QLens/(Program Files 只读兼容) - QuickView 加 Per-Monitor V2 DPI 感知(高分屏清晰) - QuickView 崩溃日志改 %APPDATA%/QLens/(原绝对路径 E:/PYTHON/...) - Manager 默认窗口尺寸改屏幕可用区 80%(不再固定 1400x900)
1 parent b838f31 commit 72066a3

4 files changed

Lines changed: 74 additions & 10 deletions

File tree

‎src/manager/ManagerWindow.cpp‎

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <QUrl>
1313
#include <QFile>
1414
#include <QTimer>
15+
#include <QScreen>
1516
#include <QApplication>
1617
#include <QVBoxLayout>
1718
#include <QHBoxLayout>
@@ -47,7 +48,16 @@ static QString picturesFolder()
4748

4849
ManagerWindow::ManagerWindow(QWidget *parent) : QMainWindow(parent) {
4950
setWindowTitle(QString::fromWCharArray(I18n::Get(L"QLens 管理器")));
50-
resize(1400, 900);
51+
// 默认尺寸:屏幕可用区 80%(分发兼容小屏/高 DPI),最大化为常态
52+
{
53+
QScreen *scr = screen();
54+
if (scr) {
55+
QSize avail = scr->availableGeometry().size();
56+
resize(avail.width() * 4 / 5, avail.height() * 4 / 5);
57+
} else {
58+
resize(1280, 800);
59+
}
60+
}
5161
setDockNestingEnabled(true);
5262

5363
// 数据层(文件夹绑定在 loadFolder 时切换)
@@ -225,11 +235,11 @@ ManagerWindow::ManagerWindow(QWidget *parent) : QMainWindow(parent) {
225235
QAction *zhAct = langMenu->addAction(tr("中文"));
226236
QAction *enAct = langMenu->addAction(tr("English"));
227237
zhAct->setCheckable(true); enAct->setCheckable(true);
228-
// 当前语言勾选标识(读 qlens_config.ini)
238+
// 当前语言勾选标识(读 qlens_config.ini——分发兼容路径)
229239
{
230-
QString iniPath = QCoreApplication::applicationDirPath() + "/qlens_config.ini";
240+
std::wstring iniPath = I18n::ConfigIniPath(false);
231241
wchar_t lang[16] = {};
232-
GetPrivateProfileStringW(L"General", L"language", L"", lang, 16, (LPCWSTR)iniPath.utf16());
242+
GetPrivateProfileStringW(L"General", L"language", L"", lang, 16, iniPath.c_str());
233243
bool en = (_wcsicmp(lang, L"en") == 0 || _wcsicmp(lang, L"English") == 0);
234244
zhAct->setChecked(!en);
235245
enAct->setChecked(en);
@@ -477,9 +487,9 @@ bool ManagerWindow::eventFilter(QObject *obj, QEvent *event) {
477487
// 切换界面语言(写 qlens_config.ini;重启生效——i18n 启动时加载)
478488
void ManagerWindow::setLanguage(const QString &lang)
479489
{
480-
QString iniPath = QCoreApplication::applicationDirPath() + "/qlens_config.ini";
490+
std::wstring iniPath = I18n::ConfigIniPath(true); // 分发兼容:exe 旁可写 → AppData
481491
WritePrivateProfileStringW(L"General", L"language",
482-
(LPCWSTR)lang.utf16(), (LPCWSTR)iniPath.utf16());
492+
(LPCWSTR)lang.utf16(), iniPath.c_str());
483493
QMessageBox::information(this, T(L"设置"), T(L"语言已更改,重启后生效。"));
484494
}
485495

‎src/quickview/i18n.cpp‎

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,38 @@ const wchar_t *Get(const wchar_t *zh)
9797

9898
void Clear() { g_map.clear(); }
9999

100+
// 配置文件路径(分发兼容:exe 旁只读时落到 AppData)
101+
std::wstring ConfigIniPath(bool forWrite)
102+
{
103+
wchar_t exeDir[MAX_PATH];
104+
GetModuleFileNameW(nullptr, exeDir, MAX_PATH);
105+
wchar_t *sl = wcsrchr(exeDir, L'\\');
106+
if (sl) *sl = 0;
107+
std::wstring exeIni = std::wstring(exeDir) + L"\\qlens_config.ini";
108+
109+
if (forWrite) {
110+
// 写:exe 旁可写 → 便携(绿色);否则 %APPDATA%/QLens/
111+
HANDLE h = CreateFileW(exeIni.c_str(), GENERIC_WRITE, 0, nullptr,
112+
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
113+
if (h != INVALID_HANDLE_VALUE) { CloseHandle(h); return exeIni; }
114+
wchar_t app[MAX_PATH];
115+
if (GetEnvironmentVariableW(L"APPDATA", app, MAX_PATH) && app[0]) {
116+
std::wstring dir = std::wstring(app) + L"\\QLens";
117+
CreateDirectoryW(dir.c_str(), nullptr);
118+
return dir + L"\\qlens_config.ini";
119+
}
120+
return exeIni;
121+
}
122+
// 读:exe 旁 → %APPDATA%/QLens/
123+
if (GetFileAttributesW(exeIni.c_str()) != INVALID_FILE_ATTRIBUTES) return exeIni;
124+
wchar_t app[MAX_PATH];
125+
if (GetEnvironmentVariableW(L"APPDATA", app, MAX_PATH) && app[0]) {
126+
std::wstring dir = std::wstring(app) + L"\\QLens";
127+
return dir + L"\\qlens_config.ini";
128+
}
129+
return exeIni;
130+
}
131+
100132
// 从配置/系统语言加载对应 .po(language/<code>/<app>.po)
101133
// 优先级:qlens_config.ini 的 language(Manager Settings 写)→ 系统 UI 语言
102134
// 代码:zh=中文(默认) en=English;系统语言无匹配 → 中文
@@ -111,9 +143,8 @@ bool LoadForApp(const wchar_t *appName)
111143
// 1) 配置优先(Manager Settings 写)
112144
wchar_t lang[64] = {};
113145
{
114-
wchar_t iniPath[MAX_PATH];
115-
swprintf_s(iniPath, MAX_PATH, L"%s\\qlens_config.ini", exeDir);
116-
GetPrivateProfileStringW(L"General", L"language", L"", lang, 64, iniPath);
146+
std::wstring iniPath = ConfigIniPath(false);
147+
GetPrivateProfileStringW(L"General", L"language", L"", lang, 64, iniPath.c_str());
117148
}
118149
// 2) 无配置 → 系统 UI 语言
119150
if (!lang[0]) {

‎src/quickview/i18n.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ bool LoadForApp(const wchar_t *appName);
1515
const wchar_t *Get(const wchar_t *zh);
1616
// 卸载/清空(释放)
1717
void Clear();
18+
// 配置文件路径(分发兼容):
19+
// forWrite=false 读:exe 旁 qlens_config.ini → %APPDATA%/QLens/
20+
// forWrite=true 写:exe 旁可写(便携/绿色)→ 否则 %APPDATA%/QLens/
21+
std::wstring ConfigIniPath(bool forWrite);
1822
}

‎src/quickview/main.cpp‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,19 @@ void RegisterFileAssociations();
1515

1616
static LONG WINAPI CrashFilter(EXCEPTION_POINTERS *ep)
1717
{
18-
FILE *f = fopen("E:/PYTHON/qlens/build-qv/crash.log", "a");
18+
// 崩溃日志写到 %APPDATA%/QLens/(exe 目录可能只读——分发兼容)
19+
wchar_t logPath[MAX_PATH];
20+
if (GetEnvironmentVariableW(L"APPDATA", logPath, MAX_PATH) && logPath[0]) {
21+
wcscat_s(logPath, MAX_PATH, L"\\QLens");
22+
CreateDirectoryW(logPath, nullptr);
23+
wcscat_s(logPath, MAX_PATH, L"\\crash.log");
24+
} else {
25+
GetModuleFileNameW(nullptr, logPath, MAX_PATH);
26+
wchar_t *sl = wcsrchr(logPath, L'\\');
27+
if (sl) wcscpy_s(sl + 1, MAX_PATH - (sl - logPath), L"crash.log");
28+
}
29+
FILE *f = nullptr;
30+
_wfopen_s(&f, logPath, L"a");
1931
if (f) {
2032
fprintf(f, "CRASH code=0x%08lX at=%p\n",
2133
(unsigned long)ep->ExceptionRecord->ExceptionCode,
@@ -27,6 +39,13 @@ static LONG WINAPI CrashFilter(EXCEPTION_POINTERS *ep)
2739

2840
int WINAPI wWinMain(HINSTANCE hi, HINSTANCE, PWSTR pCmdLine, int)
2941
{
42+
// 高 DPI 感知(Win10 1703+ Per-Monitor V2)——分发到高分屏不模糊/不错位
43+
HMODULE user32 = GetModuleHandleW(L"user32.dll");
44+
if (user32) {
45+
typedef BOOL(WINAPI *SetDpiCtxFn)(DPI_AWARENESS_CONTEXT);
46+
auto fn = (SetDpiCtxFn)GetProcAddress(user32, "SetProcessDpiAwarenessContext");
47+
if (fn) fn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
48+
}
3049
SetUnhandledExceptionFilter(CrashFilter);
3150
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
3251
WNDCLASSW wc = {};

0 commit comments

Comments
 (0)