Index: win32ss/user/user32/windows/dialog.c =================================================================== --- win32ss/user/user32/windows/dialog.c (revision 56438) +++ win32ss/user/user32/windows/dialog.c (working copy) @@ -579,6 +579,18 @@ if (!IsWindow( hwnd )) return 0; break; } + + /* + * If the user is pressing Ctrl+C, send a WM_COPY message. + * TODO: Is there another way to check if the Dialog it's a MessageBox?. + */ + if( msg.message == WM_KEYDOWN && GetPropW(hwnd, L"ROS_MSGBOX") != NULL && + GetForegroundWindow() == hwnd ) + { + if( msg.wParam == L'C' && GetKeyState(VK_CONTROL) < 0 ) + SendMessageW( hwnd, WM_COPY, 0, 0); + } + if (!IsWindow( hwnd )) return 0; if (!(dlgInfo->flags & DF_END) && !IsDialogMessageW( hwnd, &msg)) { Index: win32ss/user/user32/windows/messagebox.c =================================================================== --- win32ss/user/user32/windows/messagebox.c (revision 56438) +++ win32ss/user/user32/windows/messagebox.c (working copy) @@ -76,6 +76,114 @@ /* INTERNAL FUNCTIONS ********************************************************/ +static VOID MessageBoxTextToClipboard(HWND DialogWindow) +{ + HWND hwndText; + PMSGBOXINFO mbi; + int cchTotal, cchTitle, cchText, cchButton, i, n, cchBuffer; + LPWSTR pszBuffer, pszBufferPos, pMessageBoxText, pszTitle, pszText, pszButton; + WCHAR szButton[MSGBOXEX_MAXBTNSTR]; + HGLOBAL hGlobal; + + static const WCHAR szLine[30] = + {'-','-','-','-','-','-','-','-','-','-','-','-','-','-','-', + '-','-','-','-','-','-','-','-','-','-','-','-','\r','\n', 0}; + + mbi = (PMSGBOXINFO)GetPropW(DialogWindow, L"ROS_MSGBOX"); + hwndText = GetDlgItem(DialogWindow, MSGBOX_IDTEXT); + cchTitle = GetWindowTextLengthW(DialogWindow) + 1; + cchText = GetWindowTextLengthW(hwndText) + 1; + + if(!mbi) + return; + + pMessageBoxText = (LPWSTR)RtlAllocateHeap(GetProcessHeap(), 0, (cchTitle + cchText) * sizeof(WCHAR)); + + if(pMessageBoxText == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, pMessageBoxText); + return; + } + + pszTitle = pMessageBoxText; + pszText = pMessageBoxText + cchTitle; + + + + if(GetWindowTextW(DialogWindow, pszTitle, cchTitle) == 0 || + GetWindowTextW(hwndText, pszText, cchText) == 0) + { + RtlFreeHeap(GetProcessHeap(), 0, pMessageBoxText); + return; + } + + /* + * Calculate the total buffer size. + */ + cchTotal = 6 + cchTitle + cchText + (lstrlenW(szLine) * 4) + (mbi->nButtons * MSGBOXEX_MAXBTNSTR + 3); + + hGlobal = GlobalAlloc(GHND, cchTotal * sizeof(WCHAR)); + + pszBuffer = (LPWSTR)GlobalLock(hGlobal); + + if(pszBuffer == NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, pMessageBoxText); + GlobalFree(hGlobal); + return; + } + + /* + * First format title and text. + * ------------------ + * Title + * ------------------ + * Text + * ------------------ + */ + cchBuffer = wsprintfW(pszBuffer, L"%s%s\r\n%s%s\r\n%s", szLine, pszTitle, szLine, pszText, szLine); + pszBufferPos = pszBuffer + cchBuffer; + + for(i = 0; i < mbi->nButtons; i++) + { + GetDlgItemTextW(DialogWindow, mbi->Btns[i], szButton, MSGBOXEX_MAXBTNSTR); + + cchButton = strlenW(szButton); + pszButton = szButton; + + /* Skip '&' character. */ + if(szButton[0] == '&') + { + pszButton = pszButton + 1; + cchButton = cchButton - 1; + } + + for(n = 0; n < cchButton; n++) + *(pszBufferPos++) = pszButton[n]; + + /* Add spaces. */ + *(pszBufferPos++) = L' '; + *(pszBufferPos++) = L' '; + *(pszBufferPos++) = L' '; + } + + wsprintfW(pszBufferPos, L"\r\n%s", szLine); + + GlobalUnlock(hGlobal); + + if(OpenClipboard(DialogWindow)) + { + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, hGlobal); + CloseClipboard(); + } + else + { + GlobalFree(hGlobal); + } + RtlFreeHeap(GetProcessHeap(), 0, pMessageBoxText); +} + static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { @@ -139,6 +247,10 @@ return 0; } return 0; + + case WM_COPY: + MessageBoxTextToClipboard(hwnd); + return 0; case WM_HELP: mbi = (PMSGBOXINFO)GetPropW(hwnd, L"ROS_MSGBOX");