allow selecting text with the mouse in gui consoles

svn path=/trunk/; revision=10304
This commit is contained in:
Thomas Bluemel 2004-07-28 22:28:50 +00:00
parent c9f548f45a
commit b6a9c73c88

View file

@ -1,4 +1,4 @@
/* $Id: guiconsole.c,v 1.15 2004/07/03 17:17:05 hbirr Exp $
/* $Id: guiconsole.c,v 1.16 2004/07/28 22:28:50 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -32,6 +32,8 @@ typedef struct GUI_CONSOLE_DATA_TAG
CRITICAL_SECTION Lock;
HDC MemoryDC;
HBITMAP MemoryBitmap;
RECT Selection;
POINT SelectionStart;
} GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
#ifndef WM_APP
@ -134,6 +136,8 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
GuiData->CursorBlinkOn = TRUE;
GuiData->ForceCursorOff = FALSE;
GuiData->Selection.left = -1;
Console->PrivateData = GuiData;
SetWindowLongW(hWnd, GWL_USERDATA, (LONG) Console);
@ -181,6 +185,71 @@ GuiConsoleGetLogicalCursorPos(PCSRSS_SCREEN_BUFFER Buff, ULONG *CursorX, ULONG *
}
}
static VOID FASTCALL
GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData)
{
RECT oldRect = GuiData->Selection;
if(rc != NULL)
{
RECT changeRect = *rc;
GuiData->Selection = *rc;
changeRect.left *= GuiData->CharWidth;
changeRect.top *= GuiData->CharHeight;
changeRect.right *= GuiData->CharWidth;
changeRect.bottom *= GuiData->CharHeight;
if(rc->left != oldRect.left ||
rc->top != oldRect.top ||
rc->right != oldRect.right ||
rc->bottom != oldRect.bottom)
{
if(oldRect.left != -1)
{
HRGN rgn1, rgn2;
oldRect.left *= GuiData->CharWidth;
oldRect.top *= GuiData->CharHeight;
oldRect.right *= GuiData->CharWidth;
oldRect.bottom *= GuiData->CharHeight;
/* calculate the region that needs to be updated */
if((rgn1 = CreateRectRgnIndirect(&oldRect)))
{
if((rgn2 = CreateRectRgnIndirect(&changeRect)))
{
if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
{
InvalidateRgn(hWnd, rgn1, FALSE);
}
DeleteObject(rgn2);
}
DeleteObject(rgn1);
}
}
else
{
InvalidateRect(hWnd, &changeRect, FALSE);
}
}
}
else if(oldRect.left != -1)
{
/* clear the selection */
GuiData->Selection.left = -1;
oldRect.left *= GuiData->CharWidth;
oldRect.top *= GuiData->CharHeight;
oldRect.right *= GuiData->CharWidth;
oldRect.bottom *= GuiData->CharHeight;
InvalidateRect(hWnd, &oldRect, FALSE);
}
}
VOID FASTCALL
GuiConsoleUpdateBitmap(HWND hWnd, RECT rc)
{
@ -303,6 +372,22 @@ GuiConsoleHandlePaint(HWND hWnd)
Ps.rcPaint.right - Ps.rcPaint.left + 1,
Ps.rcPaint.bottom - Ps.rcPaint.top + 1, GuiData->MemoryDC,
Ps.rcPaint.left, Ps.rcPaint.top, SRCCOPY);
if (GuiData->Selection.left != -1)
{
RECT rc = GuiData->Selection;
rc.left *= GuiData->CharWidth;
rc.top *= GuiData->CharHeight;
rc.right *= GuiData->CharWidth;
rc.bottom *= GuiData->CharHeight;
if (IntersectRect(&rc, &Ps.rcPaint, &rc))
{
PatBlt(Dc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, DSTINVERT);
}
}
EndPaint (hWnd, &Ps);
LeaveCriticalSection(&GuiData->Lock);
}
@ -326,6 +411,12 @@ GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Message.wParam = wParam;
Message.lParam = lParam;
if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
{
/* clear the selection */
GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
}
ConioProcessKey(&Message, Console, FALSE);
}
@ -525,6 +616,133 @@ GuiConsoleHandleNcDestroy(HWND hWnd)
HeapFree(Win32CsrApiHeap, 0, GuiData);
}
static VOID FASTCALL
GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
POINTS pt;
RECT rc;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL) return;
pt = MAKEPOINTS(lParam);
rc.left = pt.x / GuiData->CharWidth;
rc.top = pt.y / GuiData->CharHeight;
rc.right = rc.left + 1;
rc.bottom = rc.top + 1;
GuiData->SelectionStart.x = rc.left;
GuiData->SelectionStart.y = rc.top;
SetCapture(hWnd);
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
}
static VOID FASTCALL
GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
RECT rc;
POINTS pt;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL) return;
if (GuiData->Selection.left == -1) return;
pt = MAKEPOINTS(lParam);
rc.left = GuiData->SelectionStart.x;
rc.top = GuiData->SelectionStart.y;
rc.right = (pt.x >= 0 ? (pt.x + GuiData->CharWidth - 1) / GuiData->CharWidth : 0);
rc.bottom = (pt.y >= 0 ? (pt.y + GuiData->CharHeight - 1) / GuiData->CharHeight : 0);
/* exchange left/top with right/bottom if required */
if(rc.left >= rc.right)
{
LONG tmp;
tmp = rc.left;
rc.left = max(rc.right - 1, 0);
rc.right = tmp + 1;
}
if(rc.top >= rc.bottom)
{
LONG tmp;
tmp = rc.top;
rc.top = max(rc.bottom - 1, 0);
rc.bottom = tmp + 1;
}
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
ReleaseCapture();
}
static VOID FASTCALL
GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
RECT rc;
POINTS pt;
if (!(wParam & MK_LBUTTON)) return;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL) return;
pt = MAKEPOINTS(lParam);
rc.left = GuiData->SelectionStart.x;
rc.top = GuiData->SelectionStart.y;
rc.right = (pt.x >= 0 ? (pt.x + GuiData->CharWidth - 1) / GuiData->CharWidth : 0);
rc.bottom = (pt.y >= 0 ? (pt.y + GuiData->CharHeight - 1) / GuiData->CharHeight : 0);
/* exchange left/top with right/bottom if required */
if(rc.left >= rc.right)
{
LONG tmp;
tmp = rc.left;
rc.left = max(rc.right - 1, 0);
rc.right = tmp + 1;
}
if(rc.top >= rc.bottom)
{
LONG tmp;
tmp = rc.top;
rc.top = max(rc.bottom - 1, 0);
rc.bottom = tmp + 1;
}
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
}
static VOID FASTCALL
GuiConsoleRightMouseDown(HWND hWnd)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL) return;
if (GuiData->Selection.left == -1)
{
/* FIXME - paste text from clipboard */
}
else
{
/* FIXME - copy selection to clipboard */
GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
}
}
static LRESULT CALLBACK
GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
@ -559,6 +777,18 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
GuiConsoleHandleNcDestroy(hWnd);
Result = 0;
break;
case WM_LBUTTONDOWN:
GuiConsoleLeftMouseDown(hWnd, lParam);
break;
case WM_LBUTTONUP:
GuiConsoleLeftMouseUp(hWnd, lParam);
break;
case WM_RBUTTONDOWN:
GuiConsoleRightMouseDown(hWnd);
break;
case WM_MOUSEMOVE:
GuiConsoleMouseMove(hWnd, wParam, lParam);
break;
default:
Result = DefWindowProcW(hWnd, msg, wParam, lParam);
break;