diff -u -N -r ReactOS-0.3.11-old/dll/win32/user32/windows/messagebox.c ReactOS-0.3.11/dll/win32/user32/windows/messagebox.c --- ReactOS-0.3.11-old/dll/win32/user32/windows/messagebox.c Mon Mar 29 21:08:52 2010 +++ ReactOS-0.3.11/dll/win32/user32/windows/messagebox.c Sat Apr 3 22:52:41 2010 @@ -72,17 +72,200 @@ int nButtons; LONG *Btns; UINT Timeout; + WNDPROC ButtonOldProcs[MSGBOXEX_MAXBTNS]; } MSGBOXINFO, *PMSGBOXINFO; /* INTERNAL FUNCTIONS ********************************************************/ +static VOID copy_msgbox_in_text(HWND hwnd, PMSGBOXINFO mbi) +{ + HWND hwndText; + int i, j, k; + int cch, cchTitle, cchText, cchLines, cchButtons, cchButton; + LPWSTR psz, pszTitle, pszText; + HGLOBAL hGlobal; + WCHAR szButton[32]; + LPWSTR pch; + static const WCHAR szLine[30] = + {'-','-','-','-','-','-','-','-','-','-','-','-','-','-','-', + '-','-','-','-','-','-','-','-','-','-','-','-','\r','\n',0}; + + cchTitle = GetWindowTextLengthW(hwnd) + 1; + hwndText = GetDlgItem(hwnd, MSGBOX_IDTEXT); + cchText = GetWindowTextLengthW(hwndText) + 1; + cchLines = 4 * 29; + cchButtons = 3 * (32 + 3); + + pszTitle = (LPWSTR) RtlAllocateHeap(GetProcessHeap(), 0, cchTitle * sizeof(WCHAR)); + if (pszTitle == NULL) + return; + pszText = (LPWSTR) RtlAllocateHeap(GetProcessHeap(), 0, cchText * sizeof(WCHAR)); + if (pszText == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, pszTitle); + return; + } + if (GetWindowTextW(hwnd, pszTitle, cchTitle) == 0 || + GetWindowTextW(hwndText, pszText, cchText) == 0) + { + RtlFreeHeap(GetProcessHeap(), 0, pszTitle); + RtlFreeHeap(GetProcessHeap(), 0, pszText); + return; + } + + pch = pszText; + while(*pch) + { + if (*pch == L'\n') + cchText++; + pch++; + } + + cch = cchTitle + 2 + cchText + cchLines + cchButtons + 2 + 1; + hGlobal = GlobalAlloc(GMEM_SHARE | GHND, cch * sizeof(WCHAR)); + if (hGlobal == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, pszTitle); + RtlFreeHeap(GetProcessHeap(), 0, pszText); + return; + } + + psz = (LPWSTR) GlobalLock(hGlobal); + if (psz == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, pszTitle); + RtlFreeHeap(GetProcessHeap(), 0, pszText); + GlobalFree(hGlobal); + return; + } + + strcpyW(psz, szLine); + strcatW(psz, pszTitle); + strcatW(psz, L"\r\n"); + strcatW(psz, szLine); + j = strlenW(psz); + /* convert \n to \r\n */ + for(i = 0; i < cchText; i++) + { + if (pszText[i] == L'\n') + psz[j++] = L'\r'; + psz[j++] = pszText[i]; + } + psz[j] = 0; + strcatW(psz, szLine); + + for(i = 0; i < mbi->nButtons; i++) + { + GetDlgItemTextW(hwnd, mbi->Btns[i], szButton, 32); + cchButton = strlenW(szButton); + j = strlenW(psz); + /* skip '&' */ + for(k = 0; k < cchButton; k++) + { + if (szButton[k] == L'&') + continue; + psz[j++] = szButton[k]; + } + psz[j] = 0; + strcatW(psz, L" "); + } + strcatW(psz, L"\r\n"); + strcatW(psz, szLine); + GlobalUnlock(hGlobal); + + if (OpenClipboard(hwnd)) + { + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, hGlobal); + CloseClipboard(); + } + else + { + GlobalFree(hGlobal); + } + RtlFreeHeap(GetProcessHeap(), 0, pszTitle); + RtlFreeHeap(GetProcessHeap(), 0, pszText); +} + +static LRESULT CALLBACK Button0Proc( HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam ) +{ + PMSGBOXINFO mbi; + HWND owner; + mbi = (PMSGBOXINFO)GetPropW(owner, L"ROS_MSGBOX"); + switch(message) + { + case WM_KEYDOWN: + owner = GetWindow(hwnd, GW_OWNER); + if (wParam == L'C' && GetAsyncKeyState(VK_CONTROL) < 0 && + GetAsyncKeyState(VK_MENU) >= 0) + { + copy_msgbox_in_text(owner, mbi); + break; + } + /* FALL THRU */ + + default: + return CallWindowProc(mbi->ButtonOldProcs[0], hwnd, message, wParam, lParam); + } + return 0; +} + +static LRESULT CALLBACK Button1Proc( HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam ) +{ + PMSGBOXINFO mbi; + HWND owner; + mbi = (PMSGBOXINFO)GetPropW(owner, L"ROS_MSGBOX"); + switch(message) + { + case WM_KEYDOWN: + owner = GetWindow(hwnd, GW_OWNER); + if (wParam == L'C' && GetAsyncKeyState(VK_CONTROL) < 0 && + GetAsyncKeyState(VK_MENU) >= 0) + { + copy_msgbox_in_text(owner, mbi); + break; + } + /* FALL THRU */ + + default: + return CallWindowProc(mbi->ButtonOldProcs[1], hwnd, message, wParam, lParam); + } + return 0; +} + +static LRESULT CALLBACK Button2Proc( HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam ) +{ + PMSGBOXINFO mbi; + HWND owner; + mbi = (PMSGBOXINFO)GetPropW(owner, L"ROS_MSGBOX"); + switch(message) + { + case WM_KEYDOWN: + owner = GetWindow(hwnd, GW_OWNER); + if (wParam == L'C' && GetAsyncKeyState(VK_CONTROL) < 0 && + GetAsyncKeyState(VK_MENU) >= 0) + { + copy_msgbox_in_text(owner, mbi); + break; + } + /* FALL THRU */ + + default: + return CallWindowProc(mbi->ButtonOldProcs[2], hwnd, message, wParam, lParam); + } + return 0; +} + static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { int i; PMSGBOXINFO mbi; HELPINFO hi; - HWND owner; + HWND owner, button; switch(message) { case WM_INITDIALOG: @@ -110,6 +293,19 @@ SetFocus(GetDlgItem(hwnd, mbi->DefBtn)); if(mbi->Timeout && (mbi->Timeout != (UINT)-1)) SetTimer(hwnd, 0, mbi->Timeout, NULL); + i = 0; + button = GetDlgItem(hwnd, mbi->Btns[i]); + mbi->ButtonOldProcs[i++] = (WNDPROC)SetWindowLongPtrW(button, GWLP_WNDPROC, (LONG_PTR)Button0Proc); + if (i < mbi->nButtons) + { + button = GetDlgItem(hwnd, mbi->Btns[i]); + mbi->ButtonOldProcs[i++] = (WNDPROC)SetWindowLongPtrW(button, GWLP_WNDPROC, (LONG_PTR)Button1Proc); + if (i < mbi->nButtons) + { + button = GetDlgItem(hwnd, mbi->Btns[i]); + mbi->ButtonOldProcs[i] = (WNDPROC)SetWindowLongPtrW(button, GWLP_WNDPROC, (LONG_PTR)Button2Proc); + } + } } return 0;