Fix 05: Remove g_lastLoadedText poisoning bug; add live session archiving via FinalizeSession
This commit is contained in:
@@ -0,0 +1,317 @@
|
|||||||
|
# Fix 05 — New transcriptions never reach history (+ live session archiving)
|
||||||
|
|
||||||
|
**Builds on:** Fix-03/04 (popup history list — those are fine and unchanged).
|
||||||
|
**Files touched:** `src/main.cpp` only. `history.h` already has everything we need.
|
||||||
|
**Estimated effort:** 30–45 minutes including testing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Root cause — one line poisons every archive path
|
||||||
|
|
||||||
|
History files are only ever written by `ArchiveSession()`, which is called from three
|
||||||
|
places, all guarded the same way:
|
||||||
|
|
||||||
|
| Where | Guard |
|
||||||
|
|---|---|
|
||||||
|
| Clear button (`OnClick` → `WK::Clear`) | `if (!cur.empty() && cur != g_lastLoadedText)` |
|
||||||
|
| Picking a history entry (`WM_APP_SELECT` → `ID_SEL_HISTORY`) | same |
|
||||||
|
| App exit (`WM_DESTROY`) | same |
|
||||||
|
|
||||||
|
`g_lastLoadedText` exists for ONE purpose: it remembers text that was loaded **FROM**
|
||||||
|
history, so that flipping between entries doesn't re-archive an unmodified copy and
|
||||||
|
create duplicates. It is supposed to be set in exactly one place — the history-load
|
||||||
|
handler.
|
||||||
|
|
||||||
|
But look at `WM_APP_RESULT` (the handler that runs when a transcription finishes).
|
||||||
|
After inserting the new text into the transcript box it does:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
UpdatePlaceholder(hWnd);
|
||||||
|
g_lastLoadedText = GetEditText(hWnd); // ← THE BUG
|
||||||
|
SetClipboardTextUtf8(hWnd, *res);
|
||||||
|
```
|
||||||
|
|
||||||
|
That line stamps the freshly-transcribed text as "this came from history". From that
|
||||||
|
moment, `cur == g_lastLoadedText` is true, so:
|
||||||
|
|
||||||
|
- **Clear** skips the archive — but still shows the (now lying) "Saved to history" status;
|
||||||
|
- **loading another history entry** silently discards the current transcription;
|
||||||
|
- **exiting the app** discards it too.
|
||||||
|
|
||||||
|
Net effect: exactly what you reported — no new transcription ever lands in `history\`.
|
||||||
|
You can confirm the diagnosis before fixing: transcribe → **manually type one extra
|
||||||
|
character** in the box → press Clear → the entry DOES appear (the edit makes
|
||||||
|
`cur != g_lastLoadedText` again).
|
||||||
|
|
||||||
|
## 2. Second problem — sessions only archived at boundaries the user rarely hits
|
||||||
|
|
||||||
|
Even with that line deleted, a session is only archived on Clear / entry-switch / exit.
|
||||||
|
The real dictation workflow is: hotkey → speak → auto-paste → keep working, app lives in
|
||||||
|
the tray. Clear is optional, exit is rare. So history would still feel "missing" most of
|
||||||
|
the time, and a crash would lose the whole session.
|
||||||
|
|
||||||
|
**Fix: live session archiving.** Every successful transcription immediately writes the
|
||||||
|
session's history file:
|
||||||
|
|
||||||
|
- the **first** clip of a session **creates** a new timestamped file (via the existing
|
||||||
|
`ArchiveSession`, which already returns the path it wrote);
|
||||||
|
- every **subsequent** clip **rewrites that same file** with the full transcript —
|
||||||
|
one file per session, never duplicates;
|
||||||
|
- Clear / entry-switch / exit just *finalize* the session (capture any manual edits made
|
||||||
|
after the last clip, then start a fresh session).
|
||||||
|
|
||||||
|
Result: open the History popup right after dictating and the session is already there,
|
||||||
|
at the top, kept current as you append. Crash-safe for free.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Step 1 — Add the session-path global
|
||||||
|
|
||||||
|
In `src/main.cpp`, find:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::vector<HistoryEntry> g_history;
|
||||||
|
std::wstring g_lastLoadedText;
|
||||||
|
```
|
||||||
|
|
||||||
|
Add one line below them:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::vector<HistoryEntry> g_history;
|
||||||
|
std::wstring g_lastLoadedText;
|
||||||
|
std::wstring g_sessionPath; // history file backing the CURRENT session ("" = none yet)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Do NOT delete `g_lastLoadedText`** — it still guards against re-archiving an
|
||||||
|
unmodified entry that was loaded from history (Step 4 below still uses it).
|
||||||
|
|
||||||
|
## 4. Step 2 — Add two small helpers
|
||||||
|
|
||||||
|
Paste these **immediately above** `void OnClick(HWND hWnd, WK kind)` (right after the
|
||||||
|
`SelectsRowFullWidthAnchor()` helper from Fix-04):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// True if the string contains anything that isn't whitespace.
|
||||||
|
static bool HasInk(const std::wstring& s) {
|
||||||
|
for (wchar_t c : s) if (!iswspace(c)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End the current session: make sure whatever is in the transcript box is in
|
||||||
|
// history (including manual edits made after the last clip), then reset the
|
||||||
|
// session so the next transcription starts a new history file.
|
||||||
|
// Returns true if the session is saved in history.
|
||||||
|
static bool FinalizeSession(HWND hWnd) {
|
||||||
|
std::wstring cur = GetEditText(hWnd);
|
||||||
|
bool saved = false;
|
||||||
|
if (!g_sessionPath.empty()) {
|
||||||
|
// Live archiving already created the file; just capture any edits
|
||||||
|
// the user made after the last transcription.
|
||||||
|
if (HasInk(cur)) WriteFileUtf8(g_sessionPath, cur);
|
||||||
|
saved = true;
|
||||||
|
} else if (HasInk(cur) && cur != g_lastLoadedText) {
|
||||||
|
// Text that was typed (never transcribed) — archive it once.
|
||||||
|
// The g_lastLoadedText guard stops unmodified loaded entries
|
||||||
|
// from being archived a second time.
|
||||||
|
saved = !ArchiveSession(cur).empty();
|
||||||
|
}
|
||||||
|
g_sessionPath.clear();
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
(`WriteFileUtf8` and `ArchiveSession` are both `inline` in `history.h`, which
|
||||||
|
`main.cpp` already includes — nothing to add there.)
|
||||||
|
|
||||||
|
## 5. Step 3 — Fix `WM_APP_RESULT` (delete the bug, add live archiving)
|
||||||
|
|
||||||
|
In `WndProc`'s `WM_APP_RESULT` case, find these four lines:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
SendMessageW(hEdit, EM_SCROLLCARET, 0, 0);
|
||||||
|
UpdatePlaceholder(hWnd);
|
||||||
|
g_lastLoadedText = GetEditText(hWnd);
|
||||||
|
SetClipboardTextUtf8(hWnd, *res);
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
SendMessageW(hEdit, EM_SCROLLCARET, 0, 0);
|
||||||
|
UpdatePlaceholder(hWnd);
|
||||||
|
{
|
||||||
|
// Live-archive: keep this session's history file current.
|
||||||
|
// First clip creates the file; later clips rewrite it.
|
||||||
|
std::wstring all = GetEditText(hWnd);
|
||||||
|
if (g_sessionPath.empty()) g_sessionPath = ArchiveSession(all);
|
||||||
|
else WriteFileUtf8(g_sessionPath, all);
|
||||||
|
}
|
||||||
|
SetClipboardTextUtf8(hWnd, *res);
|
||||||
|
```
|
||||||
|
|
||||||
|
Two things happened here — make sure both did:
|
||||||
|
|
||||||
|
1. `g_lastLoadedText = GetEditText(hWnd);` is **GONE**. This is the actual bug fix.
|
||||||
|
Do not move it somewhere else; it must only ever be assigned in the history-load
|
||||||
|
handler (Step 5b) and cleared on Clear.
|
||||||
|
2. The live-archive block was added in its place.
|
||||||
|
|
||||||
|
## 6. Step 4 — Route the three session boundaries through `FinalizeSession`
|
||||||
|
|
||||||
|
### 4a. Clear button — `OnClick`, `case WK::Clear`
|
||||||
|
|
||||||
|
Find:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
case WK::Clear: {
|
||||||
|
std::wstring cur = GetEditText(hWnd);
|
||||||
|
if (!cur.empty() && cur != g_lastLoadedText)
|
||||||
|
ArchiveSession(cur);
|
||||||
|
g_history = LoadHistoryIndex();
|
||||||
|
g_lastLoadedText.clear();
|
||||||
|
g_editDirty = false;
|
||||||
|
SetDlgItemText(hWnd, ID_EDIT_TEXT, L"");
|
||||||
|
UpdatePlaceholder(hWnd);
|
||||||
|
SetStatus(hWnd, L"Saved to history");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
case WK::Clear: {
|
||||||
|
bool saved = FinalizeSession(hWnd);
|
||||||
|
g_history = LoadHistoryIndex();
|
||||||
|
g_lastLoadedText.clear();
|
||||||
|
g_editDirty = false;
|
||||||
|
SetDlgItemText(hWnd, ID_EDIT_TEXT, L"");
|
||||||
|
UpdatePlaceholder(hWnd);
|
||||||
|
SetStatus(hWnd, saved ? L"Saved to history" : L"Cleared");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
(Bonus fix: the status no longer claims "Saved to history" when nothing was saved —
|
||||||
|
clearing an empty box now honestly says "Cleared".)
|
||||||
|
|
||||||
|
### 4b. Picking a history entry — `WM_APP_SELECT`, the `ID_SEL_HISTORY` branch
|
||||||
|
|
||||||
|
Find:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
} else if (ctrlId == ID_SEL_HISTORY && idx >= 0 && idx < (int)g_history.size()) {
|
||||||
|
std::wstring cur = GetEditText(hWnd);
|
||||||
|
if (!cur.empty() && cur != g_lastLoadedText)
|
||||||
|
ArchiveSession(cur);
|
||||||
|
std::wstring text = ReadFileUtf8(g_history[idx].path);
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace the first three body lines with one call (the rest of the branch stays):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
} else if (ctrlId == ID_SEL_HISTORY && idx >= 0 && idx < (int)g_history.size()) {
|
||||||
|
FinalizeSession(hWnd); // save the in-progress session before swapping
|
||||||
|
std::wstring text = ReadFileUtf8(g_history[idx].path);
|
||||||
|
```
|
||||||
|
|
||||||
|
Leave `g_lastLoadedText = text;` and everything after it in this branch exactly as it
|
||||||
|
is — this is the ONE place `g_lastLoadedText` is supposed to be assigned.
|
||||||
|
|
||||||
|
Note: loading an entry does NOT make it the live session (`FinalizeSession` cleared
|
||||||
|
`g_sessionPath`). If you dictate on top of a loaded entry, the next clip archives the
|
||||||
|
combined text as a **new** file — old history entries are never mutated.
|
||||||
|
|
||||||
|
### 4c. App exit — `WM_DESTROY`
|
||||||
|
|
||||||
|
Find:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
case WM_DESTROY: {
|
||||||
|
std::wstring cur = GetEditText(hWnd);
|
||||||
|
if (!cur.empty() && cur != g_lastLoadedText) ArchiveSession(cur);
|
||||||
|
PersistNow();
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
case WM_DESTROY: {
|
||||||
|
FinalizeSession(hWnd);
|
||||||
|
PersistNow();
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4d. Legacy hidden Clear button — `WM_COMMAND`, `case ID_BTN_CLEAR`
|
||||||
|
|
||||||
|
This branch belongs to a hidden legacy child button and never fires, but update it to
|
||||||
|
match 4a anyway so the two Clear paths can't drift apart:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
case ID_BTN_CLEAR: {
|
||||||
|
bool saved = FinalizeSession(hWnd);
|
||||||
|
g_history = LoadHistoryIndex();
|
||||||
|
g_lastLoadedText.clear();
|
||||||
|
g_editDirty = false;
|
||||||
|
SetDlgItemText(hWnd, ID_EDIT_TEXT, L"");
|
||||||
|
UpdatePlaceholder(hWnd);
|
||||||
|
SetStatus(hWnd, saved ? L"Saved to history" : L"Cleared");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. How the pieces behave now (mental model for the dev)
|
||||||
|
|
||||||
|
```
|
||||||
|
record clip 1 ──► WM_APP_RESULT ──► ArchiveSession(text) → creates 2026-06-11_HHMMSS.txt, g_sessionPath = that file
|
||||||
|
record clip 2 ──► WM_APP_RESULT ──► WriteFileUtf8(sessionPath) → same file rewritten with full text
|
||||||
|
edit by hand ──► (nothing yet — captured at the next clip or at finalize)
|
||||||
|
Clear / pick entry / exit ──► FinalizeSession → final write incl. edits, g_sessionPath = ""
|
||||||
|
next clip ──► new session file
|
||||||
|
```
|
||||||
|
|
||||||
|
- One file per session. Appending clips never creates duplicates.
|
||||||
|
- Cancelled clips / "No speech detected" change nothing (the result is empty, so the
|
||||||
|
live-archive block isn't reached).
|
||||||
|
- The session file keeps its creation timestamp/filename while it grows — it sorts in
|
||||||
|
the popup by when the session *started*. That's intended.
|
||||||
|
- `ArchiveSession` already refuses whitespace-only text and prunes to 100 files; both
|
||||||
|
behaviors are reused untouched.
|
||||||
|
|
||||||
|
## 8. Build & test checklist
|
||||||
|
|
||||||
|
1. **The headline fix:** launch with an empty box → dictate one clip → open History
|
||||||
|
(no Clear!) → the new session is the top entry with the right preview.
|
||||||
|
2. **Appending:** dictate a second clip → open History → still ONE entry for this
|
||||||
|
session, now containing both clips. No duplicate rows.
|
||||||
|
3. **Clear:** press Clear → "Saved to history" → box empties → dictate again → History
|
||||||
|
now shows TWO entries (old session + new session).
|
||||||
|
4. **Clear with empty box:** status says "Cleared" and no empty file appears in `history\`.
|
||||||
|
5. **Exit:** dictate → edit a word by hand → Exit via tray → relaunch → the entry
|
||||||
|
contains the hand-edit.
|
||||||
|
6. **Switching:** dictate → open History → pick an older entry → the in-progress
|
||||||
|
session was saved (visible in the list) and the older text loads.
|
||||||
|
7. **No duplicate on unmodified load:** load an entry, change nothing, press Clear →
|
||||||
|
no new file is created (status "Cleared"); the entry appears once in the list.
|
||||||
|
8. **Dictating onto a loaded entry:** load an entry → dictate → a NEW combined entry is
|
||||||
|
created; the original old file is unchanged.
|
||||||
|
9. **Typed-only session:** type text manually without dictating → Clear → archived once.
|
||||||
|
10. **Cancel:** record → hotkey again mid-transcription to cancel → no history file.
|
||||||
|
11. **Diagnosis confirmation (optional, before applying the fix):** on the OLD build,
|
||||||
|
transcribe → type one character → Clear → entry appears. That proves the
|
||||||
|
`g_lastLoadedText` poisoning was the culprit.
|
||||||
|
|
||||||
|
## 9. Do NOT touch
|
||||||
|
|
||||||
|
- `history.h` — `ArchiveSession`, `WriteFileUtf8`, `PruneHistory`, `LoadHistoryIndex`
|
||||||
|
all unchanged.
|
||||||
|
- The popup code from Fix-03/04 (`PopupProc`, `ShowSelectPopup`,
|
||||||
|
`SelectsRowFullWidthAnchor`) — unchanged.
|
||||||
|
- `g_lastLoadedText` — keep it; it is still assigned in the history-load branch and
|
||||||
|
cleared on Clear. Just never assign it anywhere else (that was the bug).
|
||||||
|
- `g_editDirty` — currently informational only; leave as is.
|
||||||
+30
-14
@@ -144,6 +144,7 @@ DWORD g_insStart = 0, g_insEnd = 0;
|
|||||||
REAL g_statsTopY = 0;
|
REAL g_statsTopY = 0;
|
||||||
std::vector<HistoryEntry> g_history;
|
std::vector<HistoryEntry> g_history;
|
||||||
std::wstring g_lastLoadedText;
|
std::wstring g_lastLoadedText;
|
||||||
|
std::wstring g_sessionPath;
|
||||||
#define ID_SEL_HISTORY 1019
|
#define ID_SEL_HISTORY 1019
|
||||||
enum class View { Main, Settings };
|
enum class View { Main, Settings };
|
||||||
View g_view = View::Main;
|
View g_view = View::Main;
|
||||||
@@ -1130,6 +1131,24 @@ static RectF SelectsRowFullWidthAnchor() {
|
|||||||
return RectF(a.X, b.Y, (b.X + b.Width) - a.X, b.Height);
|
return RectF(a.X, b.Y, (b.X + b.Width) - a.X, b.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool HasInk(const std::wstring& s) {
|
||||||
|
for (wchar_t c : s) if (!iswspace(c)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FinalizeSession(HWND hWnd) {
|
||||||
|
std::wstring cur = GetEditText(hWnd);
|
||||||
|
bool saved = false;
|
||||||
|
if (!g_sessionPath.empty()) {
|
||||||
|
if (HasInk(cur)) WriteFileUtf8(g_sessionPath, cur);
|
||||||
|
saved = true;
|
||||||
|
} else if (HasInk(cur) && cur != g_lastLoadedText) {
|
||||||
|
saved = !ArchiveSession(cur).empty();
|
||||||
|
}
|
||||||
|
g_sessionPath.clear();
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
void OnClick(HWND hWnd, WK kind) {
|
void OnClick(HWND hWnd, WK kind) {
|
||||||
if (!g_modelLoaded.load() && kind != WK::RecordHero && kind != WK::Clear
|
if (!g_modelLoaded.load() && kind != WK::RecordHero && kind != WK::Clear
|
||||||
&& kind != WK::Copy && kind != WK::Paste && kind != WK::Pin
|
&& kind != WK::Copy && kind != WK::Paste && kind != WK::Pin
|
||||||
@@ -1161,15 +1180,13 @@ void OnClick(HWND hWnd, WK kind) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WK::Clear: {
|
case WK::Clear: {
|
||||||
std::wstring cur = GetEditText(hWnd);
|
bool saved = FinalizeSession(hWnd);
|
||||||
if (!cur.empty() && cur != g_lastLoadedText)
|
|
||||||
ArchiveSession(cur);
|
|
||||||
g_history = LoadHistoryIndex();
|
g_history = LoadHistoryIndex();
|
||||||
g_lastLoadedText.clear();
|
g_lastLoadedText.clear();
|
||||||
g_editDirty = false;
|
g_editDirty = false;
|
||||||
SetDlgItemText(hWnd, ID_EDIT_TEXT, L"");
|
SetDlgItemText(hWnd, ID_EDIT_TEXT, L"");
|
||||||
UpdatePlaceholder(hWnd);
|
UpdatePlaceholder(hWnd);
|
||||||
SetStatus(hWnd, L"Saved to history");
|
SetStatus(hWnd, saved ? L"Saved to history" : L"Cleared");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WK::Pin:
|
case WK::Pin:
|
||||||
@@ -1667,7 +1684,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
SendMessageW(hEdit, EM_REPLACESEL, TRUE, (LPARAM)ins.c_str());
|
SendMessageW(hEdit, EM_REPLACESEL, TRUE, (LPARAM)ins.c_str());
|
||||||
SendMessageW(hEdit, EM_SCROLLCARET, 0, 0);
|
SendMessageW(hEdit, EM_SCROLLCARET, 0, 0);
|
||||||
UpdatePlaceholder(hWnd);
|
UpdatePlaceholder(hWnd);
|
||||||
g_lastLoadedText = GetEditText(hWnd);
|
{
|
||||||
|
std::wstring all = GetEditText(hWnd);
|
||||||
|
if (g_sessionPath.empty()) g_sessionPath = ArchiveSession(all);
|
||||||
|
else WriteFileUtf8(g_sessionPath, all);
|
||||||
|
}
|
||||||
|
|
||||||
SetClipboardTextUtf8(hWnd, *res);
|
SetClipboardTextUtf8(hWnd, *res);
|
||||||
|
|
||||||
@@ -1736,9 +1757,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
InvalidateRect(GetDlgItem(hWnd, ID_SEL_MODEL), nullptr, FALSE);
|
InvalidateRect(GetDlgItem(hWnd, ID_SEL_MODEL), nullptr, FALSE);
|
||||||
PersistNow();
|
PersistNow();
|
||||||
} else if (ctrlId == ID_SEL_HISTORY && idx >= 0 && idx < (int)g_history.size()) {
|
} else if (ctrlId == ID_SEL_HISTORY && idx >= 0 && idx < (int)g_history.size()) {
|
||||||
std::wstring cur = GetEditText(hWnd);
|
FinalizeSession(hWnd);
|
||||||
if (!cur.empty() && cur != g_lastLoadedText)
|
|
||||||
ArchiveSession(cur);
|
|
||||||
std::wstring text = ReadFileUtf8(g_history[idx].path);
|
std::wstring text = ReadFileUtf8(g_history[idx].path);
|
||||||
SetWindowTextW(GetDlgItem(hWnd, ID_EDIT_TEXT), text.c_str());
|
SetWindowTextW(GetDlgItem(hWnd, ID_EDIT_TEXT), text.c_str());
|
||||||
g_lastLoadedText = text;
|
g_lastLoadedText = text;
|
||||||
@@ -1782,15 +1801,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
PostMessage(hWnd, WM_HOTKEY, HK_TOGGLE, 0);
|
PostMessage(hWnd, WM_HOTKEY, HK_TOGGLE, 0);
|
||||||
break;
|
break;
|
||||||
case ID_BTN_CLEAR: {
|
case ID_BTN_CLEAR: {
|
||||||
std::wstring cur = GetEditText(hWnd);
|
bool saved = FinalizeSession(hWnd);
|
||||||
if (!cur.empty() && cur != g_lastLoadedText)
|
|
||||||
ArchiveSession(cur);
|
|
||||||
g_history = LoadHistoryIndex();
|
g_history = LoadHistoryIndex();
|
||||||
g_lastLoadedText.clear();
|
g_lastLoadedText.clear();
|
||||||
g_editDirty = false;
|
g_editDirty = false;
|
||||||
SetDlgItemText(hWnd, ID_EDIT_TEXT, L"");
|
SetDlgItemText(hWnd, ID_EDIT_TEXT, L"");
|
||||||
UpdatePlaceholder(hWnd);
|
UpdatePlaceholder(hWnd);
|
||||||
SetStatus(hWnd, L"Saved to history");
|
SetStatus(hWnd, saved ? L"Saved to history" : L"Cleared");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_BTN_PIN:
|
case ID_BTN_PIN:
|
||||||
@@ -1844,8 +1861,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case WM_DESTROY: {
|
case WM_DESTROY: {
|
||||||
std::wstring cur = GetEditText(hWnd);
|
FinalizeSession(hWnd);
|
||||||
if (!cur.empty() && cur != g_lastLoadedText) ArchiveSession(cur);
|
|
||||||
PersistNow();
|
PersistNow();
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user