279 lines
8.0 KiB
C++
279 lines
8.0 KiB
C++
|
#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;
|
||
|
}
|