Author: gschneider Date: Thu Apr 28 19:59:16 2011 New Revision: 51481
URL: http://svn.reactos.org/svn/reactos?rev=51481&view=rev Log: [win32csr] Implement routines to allow copy, paste and select all on console windows See issue #4068 for more details.
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] Thu Apr 28 19:59:16 2011 @@ -1371,6 +1371,109 @@ }
static VOID +GuiConsoleCopy(HWND hWnd, PCSRSS_CONSOLE Console) +{ + if (OpenClipboard(hWnd) == TRUE) + { + HANDLE hData; + PBYTE ptr; + LPSTR data, dstPos; + ULONG selWidth, selHeight; + ULONG xPos, yPos, size; + + selWidth = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1; + selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1; + DPRINT("Selection is (%d|%d) to (%d|%d)\n", + Console->Selection.srSelection.Left, + Console->Selection.srSelection.Top, + Console->Selection.srSelection.Right, + Console->Selection.srSelection.Bottom); + + /* Basic size for one line and termination */ + size = selWidth + 1; + if (selHeight > 0) + { + /* Multiple line selections have to get \r\n appended */ + size += ((selWidth + 2) * (selHeight - 1)); + } + + /* Allocate memory, it will be passed to the system and may not be freed here */ + hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size); + if (hData == NULL) + { + CloseClipboard(); + return; + } + data = GlobalLock(hData); + if (data == NULL) + { + CloseClipboard(); + return; + } + + DPRINT("Copying %dx%d selection\n", selWidth, selHeight); + dstPos = data; + + for (yPos = 0; yPos < selHeight; yPos++) + { + ptr = ConioCoordToPointer(Console->ActiveBuffer, + Console->Selection.srSelection.Left, + yPos + Console->Selection.srSelection.Top); + /* Copy only the characters, leave attributes alone */ + for (xPos = 0; xPos < selWidth; xPos++) + { + dstPos[xPos] = ptr[xPos * 2]; + } + dstPos += selWidth; + if (yPos != (selHeight - 1)) + { + strcat(data, "\r\n"); + dstPos += 2; + } + } + + DPRINT("Setting data <%s> to clipboard\n", data); + GlobalUnlock(hData); + + EmptyClipboard(); + SetClipboardData(CF_TEXT, hData); + CloseClipboard(); + } +} + +static VOID +GuiConsolePaste(HWND hWnd, PCSRSS_CONSOLE Console) +{ + if (OpenClipboard(hWnd) == TRUE) + { + HANDLE hData; + LPSTR str; + size_t len; + + hData = GetClipboardData(CF_TEXT); + if (hData == NULL) + { + CloseClipboard(); + return; + } + + str = GlobalLock(hData); + if (str == NULL) + { + CloseClipboard(); + return; + } + DPRINT("Got data <%s> from clipboard\n", str); + len = strlen(str); + + ConioWriteConsole(Console, Console->ActiveBuffer, str, len, TRUE); + + GlobalUnlock(hData); + CloseClipboard(); + } +} + +static VOID GuiConsoleRightMouseDown(HWND hWnd) { PCSRSS_CONSOLE Console; @@ -1381,12 +1484,13 @@
if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)) { - /* FIXME - paste text from clipboard */ + GuiConsolePaste(hWnd, Console); } else { - /* FIXME - copy selection to clipboard */ - + GuiConsoleCopy(hWnd, Console); + + /* Clear the selection */ GuiConsoleUpdateSelection(Console, NULL); }
@@ -1466,18 +1570,41 @@ CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); } static LRESULT -GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData) +GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { LRESULT Ret = TRUE; + PCSRSS_CONSOLE Console; + PGUI_CONSOLE_DATA GuiData; + COORD bottomRight = { 0, 0 }; + + GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
switch(wParam) { case ID_SYSTEM_EDIT_MARK: + DPRINT1("Marking not handled yet\n"); + break; + case ID_SYSTEM_EDIT_COPY: + GuiConsoleCopy(hWnd, Console); + break; + case ID_SYSTEM_EDIT_PASTE: + GuiConsolePaste(hWnd, Console); + break; + case ID_SYSTEM_EDIT_SELECTALL: + bottomRight.X = Console->Size.X - 1; + bottomRight.Y = Console->Size.Y - 1; + GuiConsoleUpdateSelection(Console, &bottomRight); + break; + case ID_SYSTEM_EDIT_SCROLL: + DPRINT1("Scrolling is not handled yet\n"); + break; + case ID_SYSTEM_EDIT_FIND: + DPRINT1("Finding is not handled yet\n"); break;
case ID_SYSTEM_DEFAULTS: @@ -1895,7 +2022,7 @@ GuiConsoleMouseMove(hWnd, wParam, lParam); break; case WM_SYSCOMMAND: - Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData); + Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam); break; case WM_HSCROLL: case WM_VSCROLL: