mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 09:50:02 +00:00
allow selecting text with the mouse in gui consoles
svn path=/trunk/; revision=10304
This commit is contained in:
parent
c9f548f45a
commit
b6a9c73c88
1 changed files with 231 additions and 1 deletions
|
@ -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);
|
||||
}
|
||||
|
@ -325,6 +410,12 @@ GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
Message.message = msg;
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue