# Double Buffer Architecture Research v7
## Focus: Resize / Maximize / Minimize 邊界情境

---

## Resize 完整流程

```
使用者拖曳視窗邊框
  ↓
WM_ENTERSIZEMOVE
  ├─ pWVT->bAlreadySizing = TRUE
  ↓
WM_SIZE (重複多次)
  ├─ hb_gt_wvt_FitRows / hb_gt_wvt_FitSize
  │   ├─ 重新計算 ROWS/COLS
  │   ├─ 重新建立字型（hFont）
  │   ├─ PTEXTSIZE.x/y 更新
  │   ├─ g_nCellW/g_nCellH 由下次 PaintText 更新
  │   └─ InvalidateRect(hWnd, NULL, TRUE)  ← 全視窗 dirty
  ↓
WM_EXITSIZEMOVE
  ├─ pWVT->bAlreadySizing = FALSE
  ↓
WM_PAINT
  ├─ s_bInsidePaint = 1
  ├─ g_bSharedPaint = 1
  ├─ PaintText:
  │   ├─ GetClientRect → 新大小
  │   ├─ s_hdcPaintBuf 大小不符 → DeleteDC + 重建
  │   ├─ 新 buffer 內容：空（未初始化）
  │   ├─ BitBlt(新 buffer ← screen) ← 螢幕有舊尺寸的殘留
  │   ├─ TextOut → 新 buffer（新尺寸的 ASCII）
  │   ├─ 跳過 BitBlt（g_bSharedPaint=1）
  │   ├─ g_hPaintBuf = 新 buffer
  │   └─ EndPaint
  │
  ├─ ScanAndDrawUda:
  │   ├─ g_nCellW/g_nCellH 已由 PaintText 更新
  │   ├─ hdcDraw = g_hPaintBuf（新 buffer）
  │   ├─ s_hdcDblBuf 大小不符 → 重建（但 v4 不用它）
  │   ├─ DrawUDA → g_hPaintBuf
  │   ├─ BitBlt g_hPaintBuf → screen ← 新尺寸的完整畫面
  │   └─ Caret 重建（新位置）
  ↓
結果：一次乾淨的 resize，新 buffer 有完整內容
```

## 問題點

### 1. 新 buffer 的初始 capture（舊螢幕內容）
- 新 buffer 建立後第一次 capture 取自螢幕
- 螢幕仍顯示舊尺寸的內容（WM_SIZE 後尚未重繪）
- capture 取得的是**舊尺寸內容在新尺寸座標上**
- **但**：PaintText 接著 TextOut 所有 dirty rows（全螢幕 dirty）
- TextOut 覆蓋了所有 cell → 舊內容被完全覆蓋
- **結論：不是問題**（全螢幕 dirty = 全部重繪）

### 2. g_nCellW/g_nCellH 更新時機
- FitSize 更新 PTEXTSIZE.x/y
- PaintText 匯出 g_nCellW = PTEXTSIZE.x（line 3257）
- ScanAndDrawUda 讀取 g_nCellW（line 43）
- **順序正確**：PaintText 先執行 → 更新 g_nCellW → ScanAndDrawUda 後讀取

### 3. 多次 WM_SIZE 期間的 WM_PAINT
- bAlreadySizing=TRUE 時，PaintText 使用 cached brush 填充 margin
- 每次 WM_SIZE 觸發 InvalidateRect → WM_PAINT → 重建 buffer
- 頻繁的 DeleteDC/CreateDC 可能慢
- **但**：s_bInsidePaint 防止重入，一次只處理一個 WM_PAINT

### 4. Maximize → Restore 順序
- Maximize: WM_SIZE → 新大小（全螢幕）→ buffer 重建
- Restore: WM_SIZE → 原大小 → buffer 再重建
- MarginLeft/MarginTop 在 maximize 時 > 0，restore 時 = 0
- g_nMarginLeft 由 PaintText 更新 → ScanAndDrawUda 讀取
- **順序正確**

## 結論

**Resize 行為在 v4 下是安全的。** 全螢幕 dirty 保證所有 cell 被重繪。buffer 重建後第一次 capture 雖取得舊內容，但被 TextOut 完全覆蓋。
