diff options
Diffstat (limited to 'Src/Plugins/Library/ml_disc/questionwnd.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_disc/questionwnd.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_disc/questionwnd.cpp b/Src/Plugins/Library/ml_disc/questionwnd.cpp new file mode 100644 index 00000000..66071eea --- /dev/null +++ b/Src/Plugins/Library/ml_disc/questionwnd.cpp @@ -0,0 +1,279 @@ +#include "main.h" +#include "./copyfiles.h" +#include "./copyinternal.h" +#include "./resource.h" +#include "../nu/trace.h" +#include <shlwapi.h> +#include <strsafe.h> + + +#define QUESTIONBOX_PROP TEXT("QUESTIONBOX") +#define GetQuestionBox(__hdlg) ((QUESTIONBOX*)GetProp((__hdlg), QUESTIONBOX_PROP)) + + +#define GetResolvedString(__pszText, __pszBuffer, __chhBufferMax)\ + (IS_INTRESOURCE(__pszText) ? WASABI_API_LNGSTRINGW_BUF((UINT)(UINT_PTR)(__pszText), (__pszBuffer), (__chhBufferMax)) : (__pszText)) + +static INT_PTR CALLBACK CopyQuestion_DialogProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR MLDisc_ShowQuestionBox(QUESTIONBOX *pQuestionBox) +{ + if (!pQuestionBox) return IDCANCEL; + return WASABI_API_DIALOGBOXPARAMW(IDD_FILECOPY_QUESTION, pQuestionBox->hParent, CopyQuestion_DialogProc, (LPARAM)pQuestionBox); +} + +static BOOL FindPrefferedSizeEx(HDC hdc, LPCTSTR pszText, LPCTSTR pszNewLine, SIZE *pSize) +{ + if (!pSize) return FALSE; + pSize->cx = 0; pSize->cy = 0; + if (!hdc || !pszText || !pszNewLine) return FALSE; + LPCTSTR pszBlock = pszText; + LPCTSTR pszCursor = pszBlock; + INT cchSep = lstrlenW(pszNewLine); + INT matched = 0; + for(;;) + { + if (*pszCursor) + { + if (*pszCursor == pszNewLine[matched]) matched++; + else matched = 0; + pszCursor++; + } + if (matched == cchSep || TEXT('\0') == *pszCursor) + { + SIZE sz; + + INT l = (INT)(size_t)((pszCursor - pszBlock) - matched); + if (l > 0) + { + if (!GetTextExtentPoint32(hdc, pszBlock, l, &sz)) return FALSE; + } + else + { + if (!GetTextExtentPoint32(hdc, TEXT("\n"), 1, &sz)) return FALSE; + sz.cx = 0; + } + + if (pSize->cx < sz.cx) pSize->cx= sz.cx; + pSize->cy += sz.cy; + + if (TEXT('\0') == *pszCursor) break; + else + { + matched = 0; + pszBlock = pszCursor; + } + } + } + return TRUE; +} + +static BOOL FindPrefferedSize(HWND hwnd, LPCTSTR pszText, LPCTSTR pszNewLine, SIZE *pSize) +{ + HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_PARENTCLIP); + if (!hdc) return FALSE; + HFONT hf, hfo; + hf = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0L); + if (NULL == hf) hf = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + hfo = (NULL != hf) ? (HFONT)SelectObject(hdc, hf) : NULL; + + BOOL br = FindPrefferedSizeEx(hdc, pszText, pszNewLine, pSize); + + if (hfo) SelectObject(hdc, hfo); + ReleaseDC(hwnd, hdc); + + return br; +} + +static INT_PTR CopyQuestion_OnInitDialog(HWND hdlg, HWND hFocus, QUESTIONBOX *pqb) +{ + if (!pqb) return FALSE; + SetProp(hdlg, QUESTIONBOX_PROP, pqb); + + HWND hctrl; + TCHAR szBuffer[2048] = {0}; + LONG messageLeft = 0; + + if (NULL != pqb->pszTitle) SetWindowText(hdlg, GetResolvedString(pqb->pszTitle, szBuffer, ARRAYSIZE(szBuffer))); + + if (NULL != pqb->pszBtnOkText) SetDlgItemText(hdlg, IDOK, GetResolvedString(pqb->pszBtnOkText, szBuffer, ARRAYSIZE(szBuffer))); + if (NULL != pqb->pszBtnCancelText) SetDlgItemText(hdlg, IDCANCEL, GetResolvedString(pqb->pszBtnCancelText, szBuffer, ARRAYSIZE(szBuffer))); + + if (NULL != (hctrl = GetDlgItem(hdlg, IDC_BTN_EXTRA1))) + { + ShowWindow(hctrl, (QBF_SHOW_EXTRA_BUTTON & pqb->uFlags) ? SW_SHOWNA : SW_HIDE); + if (NULL != pqb->pszBtnExtraText) SetWindowText(hctrl, GetResolvedString(pqb->pszBtnExtraText, szBuffer, ARRAYSIZE(szBuffer))); + } + + + if (NULL != (hctrl = GetDlgItem(hdlg, IDC_PIC_ICON))) + { + HICON hIcon = NULL; + if (NULL != pqb->pszIcon) + { + hIcon = LoadIcon(WASABI_API_LNG_HINST, pqb->pszIcon); + if (NULL == hIcon) hIcon = LoadIcon(WASABI_API_ORIG_HINST, pqb->pszIcon); + if (NULL == hIcon) hIcon = LoadIcon(NULL, pqb->pszIcon); + } + SendMessage(hctrl, STM_SETICON, (WPARAM)hIcon, 0L); + ShowWindow(hctrl, (hIcon) ? SW_SHOWNA : SW_HIDE); + RECT rw; + GetWindowRect(hctrl, &rw); + MapWindowPoints(HWND_DESKTOP, hdlg, (POINT*)&rw, 2); + messageLeft = (hIcon) ? (rw.right + 24) : rw.left; + } + + INT shiftRight = 0, shiftBottom = 0; + + if (NULL != (hctrl = GetDlgItem(hdlg, IDC_LBL_MESSAGE))) + { + RECT rw; + SIZE textSize = { 0, 0 }; + LPCTSTR pszText = (NULL != pqb->pszMessage) ? GetResolvedString(pqb->pszMessage, szBuffer, ARRAYSIZE(szBuffer)) : NULL; + if (pszText) + { + FindPrefferedSize(hctrl, pszText, TEXT("\n"), &textSize); + textSize.cx += 8; textSize.cy += 4; + } + SetWindowText(hctrl, pszText); + GetWindowRect(hctrl, &rw); + MapWindowPoints(HWND_DESKTOP, hdlg, (POINT*)&rw, 2); + rw.left = messageLeft; + shiftRight = (rw.left + textSize.cx) - rw.right; + if (shiftRight < 0) shiftRight = 0; + shiftBottom = textSize.cy - (rw.bottom - rw.top); + if (shiftBottom < 0) shiftBottom = 0; + SetWindowPos(hctrl, NULL, rw.left, rw.top, (rw.right - rw.left) + shiftRight, (rw.bottom - rw.top) + shiftBottom, SWP_NOACTIVATE | SWP_NOZORDER); + } + + if (NULL != (hctrl = GetDlgItem(hdlg, IDC_CHECKBOX1))) + { + + if (NULL != pqb->pszCheckboxText) SetWindowText(hctrl, GetResolvedString(pqb->pszCheckboxText, szBuffer, ARRAYSIZE(szBuffer))); + SendMessage(hctrl, BM_SETCHECK, (pqb->checkboxChecked) ? BST_CHECKED : BST_UNCHECKED, 0L); + + RECT rw; + GetWindowRect(hctrl, &rw); + + if (0 == (QBF_SHOW_CHECKBOX & pqb->uFlags)) + { + shiftBottom -= (rw.bottom - rw.top); + ShowWindow(hctrl, SW_HIDE); + } + else if (shiftRight || shiftBottom) + { + MapWindowPoints(HWND_DESKTOP, hdlg, (POINT*)&rw, 2); + SetWindowPos(hctrl, NULL, rw.left, rw.top + shiftBottom, + (rw.right - rw.bottom) + shiftRight, (rw.bottom - rw.top), SWP_NOACTIVATE | SWP_NOZORDER); + ShowWindow(hctrl, SW_SHOWNA); + } + } + + if (shiftRight || shiftBottom) + { + RECT rw; + INT idList[] = {IDC_BTN_EXTRA1, IDOK, IDCANCEL, }; + for (int i = 0; i < ARRAYSIZE(idList); i++) + { + if (NULL != (hctrl = GetDlgItem(hdlg, idList[i]))) + { + GetWindowRect(hctrl, &rw); + MapWindowPoints(HWND_DESKTOP, hdlg, (POINT*)&rw, 2); + SetWindowPos(hctrl, NULL, rw.left + shiftRight, rw.top + shiftBottom, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + } + + } + + HWND hParent = GetParent(hdlg); + if (hParent) + { + RECT rw, rc; + GetClientRect(hParent, &rc); + GetWindowRect(hdlg, &rw); + rw.right += shiftRight; + rw.bottom += shiftBottom; + + SetWindowPos(hdlg, NULL, + rw.left + ((rc.right - rc.left) - (rw.right - rw.left))/2, + rw.top + ((rc.bottom - rc.top) - (rw.bottom - rw.top))/2, + rw.right - rw.left, rw.bottom - rw.top, SWP_NOACTIVATE | SWP_NOZORDER); + } + + SendMessage(hdlg, DM_REPOSITION, 0, 0L); + return FALSE; +} + +static void CopyQuestion_OnDestroy(HWND hdlg) +{ + QUESTIONBOX *pqb = GetQuestionBox(hdlg); + if (pqb) + { + pqb->checkboxChecked = (BST_CHECKED == IsDlgButtonChecked(hdlg, IDC_CHECKBOX1)); + } + RemoveProp(hdlg, QUESTIONBOX_PROP); +} + +static void CopyQuestion_OnCommand(HWND hdlg, INT ctrlId, INT eventId, HWND hctrl) +{ + switch(ctrlId) + { + case IDOK: + case IDCANCEL: + EndDialog(hdlg, ctrlId); + break; + case IDC_BTN_EXTRA1: + if (BN_CLICKED == eventId) EndDialog(hdlg, ctrlId); + break; + } +} +#define IDT_POSTSHOW 1985 +#define DELAY_POSTSHOW 0 + +static void CALLBACK CopyQuestion_OnPostShowElapsed(HWND hdlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + QUESTIONBOX *pqb = GetQuestionBox(hdlg); + KillTimer(hdlg, idEvent); + if (!pqb) return; + + if (QBF_FLASH & pqb->uFlags) + { + FLASHWINFO flash = { sizeof(FLASHWINFO), }; + flash.hwnd = hdlg; + flash.dwFlags = FLASHW_ALL; + flash.uCount = 2; + flash.dwTimeout = 300; + FlashWindowEx(&flash); + } + + if (QBF_BEEP & pqb->uFlags) MessageBeep(pqb->uBeepType); + + if ((QBF_SETFOREGROUND | QBF_TOPMOST) & pqb->uFlags) + { + SetForegroundWindow(hdlg); + SetWindowPos(hdlg, (QBF_SETFOREGROUND & pqb->uFlags) ? HWND_TOP : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + } + + + + + +} +static void CopyQuestion_OnShowWindow(HWND hdlg, BOOL bShow, UINT nStatus) +{ + if (bShow) + { + SetTimer(hdlg, IDT_POSTSHOW, DELAY_POSTSHOW, CopyQuestion_OnPostShowElapsed); + } +} + +static INT_PTR CALLBACK CopyQuestion_DialogProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: return CopyQuestion_OnInitDialog(hdlg, (HWND)wParam, (QUESTIONBOX*)lParam); + case WM_DESTROY: CopyQuestion_OnDestroy(hdlg); break; + case WM_COMMAND: CopyQuestion_OnCommand(hdlg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); break; + case WM_SHOWWINDOW: CopyQuestion_OnShowWindow(hdlg, (BOOL)wParam, (UINT)lParam); break; + } + return 0; +}
\ No newline at end of file |