mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-17 21:03:19 +08:00
fix: dynamic sizing of InfoboxLng
This commit is contained in:
parent
e1643773ec
commit
fe1b2630d7
107
src/Dialogs.c
107
src/Dialogs.c
@ -187,6 +187,8 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam,
|
||||
//SendMessage(GetDlgItem(hwnd, IDC_INFOBOXTEXT), EM_SETTABSTOPS, 3, (LPARAM)tabStopDist);
|
||||
|
||||
// --- Dynamic dialog sizing: shrink for short text, grow proportionally (W & H) for long text ---
|
||||
// Always inserts ~one line of breathing room between message text and buttons; reclaims that
|
||||
// band when the checkbox is hidden and the template puts it between text and buttons.
|
||||
{
|
||||
HWND const hWndText = GetDlgItem(hwnd, IDC_INFOBOXTEXT);
|
||||
|
||||
@ -195,6 +197,7 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam,
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&rcText, 2);
|
||||
int const origTextWidth = rcText.right - rcText.left;
|
||||
int const origTextHeight = rcText.bottom - rcText.top;
|
||||
int const textBottomY = rcText.top + origTextHeight;
|
||||
|
||||
RECT rcDlg;
|
||||
GetWindowRect(hwnd, &rcDlg);
|
||||
@ -255,47 +258,99 @@ static INT_PTR CALLBACK _InfoBoxLngDlgProc(HWND hwnd, UINT umsg, WPARAM wParam,
|
||||
int deltaX = targetWidth - origTextWidth;
|
||||
int deltaY = targetHeight - origTextHeight;
|
||||
|
||||
int extraGap = lineHeight; // one blank line between text and buttons
|
||||
|
||||
// Probe template positions of buttons and checkbox so we can detect
|
||||
// INFOBOX4-style layouts where the checkbox sits between text and buttons,
|
||||
// and reclaim that band when the checkbox is hidden.
|
||||
int const buttonIDs[] = { IDOK, IDYES, IDNO, IDCANCEL, IDABORT, IDRETRY,
|
||||
IDIGNORE, IDTRYAGAIN, IDCONTINUE, IDCLOSE };
|
||||
int buttonTopTpl = INT_MAX;
|
||||
for (int i = 0; i < COUNTOF(buttonIDs); ++i) {
|
||||
HWND const h = GetDlgItem(hwnd, buttonIDs[i]);
|
||||
if (h) {
|
||||
RECT r;
|
||||
GetWindowRect(h, &r);
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&r, 2);
|
||||
if (r.top < buttonTopTpl) buttonTopTpl = r.top;
|
||||
}
|
||||
}
|
||||
|
||||
int checkboxTopTpl = INT_MAX, checkboxBottomTpl = INT_MAX;
|
||||
HWND const hChkProbe = GetDlgItem(hwnd, IDC_INFOBOXCHECK);
|
||||
if (hChkProbe) {
|
||||
RECT r;
|
||||
GetWindowRect(hChkProbe, &r);
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&r, 2);
|
||||
checkboxTopTpl = r.top;
|
||||
checkboxBottomTpl = r.bottom;
|
||||
}
|
||||
|
||||
bool const checkboxInGapZone = (buttonTopTpl != INT_MAX) &&
|
||||
(checkboxTopTpl > textBottomY) &&
|
||||
(checkboxBottomTpl <= buttonTopTpl);
|
||||
int vReclaim = 0;
|
||||
if (lpMsgBox->bDisableCheckBox && checkboxInGapZone) {
|
||||
vReclaim = (buttonTopTpl - textBottomY) - extraGap;
|
||||
if (vReclaim < 0) vReclaim = 0;
|
||||
}
|
||||
|
||||
if (origDlgWidth + deltaX > maxDlgWidth) {
|
||||
deltaX = maxDlgWidth - origDlgWidth;
|
||||
}
|
||||
if (origDlgHeight + deltaY > maxDlgHeight) {
|
||||
deltaY = maxDlgHeight - origDlgHeight;
|
||||
int netExtra = extraGap - vReclaim;
|
||||
if (origDlgHeight + deltaY + netExtra > maxDlgHeight) {
|
||||
int overflow = (origDlgHeight + deltaY + netExtra) - maxDlgHeight;
|
||||
int const gapShrink = min(overflow, extraGap);
|
||||
extraGap -= gapShrink;
|
||||
overflow -= gapShrink;
|
||||
if (overflow > 0) {
|
||||
deltaY -= overflow;
|
||||
}
|
||||
netExtra = extraGap - vReclaim;
|
||||
}
|
||||
|
||||
if (deltaX != 0 || deltaY != 0) {
|
||||
SetWindowPos(hWndText, NULL, 0, 0,
|
||||
origTextWidth + deltaX,
|
||||
origTextHeight + deltaY,
|
||||
SWP_NOMOVE | SWP_NOZORDER);
|
||||
// Resize text region.
|
||||
SetWindowPos(hWndText, NULL, 0, 0,
|
||||
origTextWidth + deltaX,
|
||||
origTextHeight + deltaY,
|
||||
SWP_NOMOVE | SWP_NOZORDER);
|
||||
|
||||
// Buttons: shift right by deltaX (right-anchored as a group) and down by deltaY.
|
||||
int const buttonIDs[] = { IDOK, IDYES, IDNO, IDCANCEL, IDABORT, IDRETRY,
|
||||
IDIGNORE, IDTRYAGAIN, IDCONTINUE, IDCLOSE };
|
||||
for (int i = 0; i < COUNTOF(buttonIDs); ++i) {
|
||||
HWND hCtl = GetDlgItem(hwnd, buttonIDs[i]);
|
||||
if (hCtl) {
|
||||
RECT rc;
|
||||
GetWindowRect(hCtl, &rc);
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&rc, 2);
|
||||
SetWindowPos(hCtl, NULL, rc.left + deltaX, rc.top + deltaY, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER);
|
||||
}
|
||||
// Buttons: shift right by deltaX (right-anchored), and down by
|
||||
// (deltaY + extraGap - vReclaim) for any control whose template top is
|
||||
// at or below the text region (controls above the text bottom keep deltaY only).
|
||||
for (int i = 0; i < COUNTOF(buttonIDs); ++i) {
|
||||
HWND const hCtl = GetDlgItem(hwnd, buttonIDs[i]);
|
||||
if (hCtl) {
|
||||
RECT rc;
|
||||
GetWindowRect(hCtl, &rc);
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&rc, 2);
|
||||
int const yShift = (rc.top >= textBottomY)
|
||||
? (deltaY + extraGap - vReclaim)
|
||||
: deltaY;
|
||||
SetWindowPos(hCtl, NULL, rc.left + deltaX, rc.top + yShift, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER);
|
||||
}
|
||||
// Checkbox: left-anchored, shift only by deltaY.
|
||||
}
|
||||
// Checkbox: left-anchored. Skip when hidden — vReclaim already collapsed its band.
|
||||
if (!lpMsgBox->bDisableCheckBox) {
|
||||
HWND const hChk = GetDlgItem(hwnd, IDC_INFOBOXCHECK);
|
||||
if (hChk) {
|
||||
RECT rc;
|
||||
GetWindowRect(hChk, &rc);
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&rc, 2);
|
||||
SetWindowPos(hChk, NULL, rc.left, rc.top + deltaY, 0, 0,
|
||||
int const yShift = (rc.top >= textBottomY)
|
||||
? (deltaY + extraGap - vReclaim)
|
||||
: deltaY;
|
||||
SetWindowPos(hChk, NULL, rc.left, rc.top + yShift, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER);
|
||||
}
|
||||
|
||||
SetWindowPos(hwnd, NULL, 0, 0,
|
||||
origDlgWidth + deltaX,
|
||||
origDlgHeight + deltaY,
|
||||
SWP_NOMOVE | SWP_NOZORDER);
|
||||
}
|
||||
|
||||
SetWindowPos(hwnd, NULL, 0, 0,
|
||||
origDlgWidth + deltaX,
|
||||
origDlgHeight + deltaY + netExtra,
|
||||
SWP_NOMOVE | SWP_NOZORDER);
|
||||
}
|
||||
|
||||
SetDlgItemText(hwnd, IDC_INFOBOXTEXT, lpMsgBox->lpstrMessage);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user