/* INCLUDES *******************************************************************/
#include <consrv.h>
-
+#include <intrin.h>
#include <windowsx.h>
#define NDEBUG
PCONSOLE_PROCESS_DATA ProcessData;
CLIENT_ID ConsoleLeaderCID;
- ProcessData = ConDrvGetConsoleLeaderProcess(GuiData->Console);
+ ProcessData = ConSrvGetConsoleLeaderProcess(GuiData->Console);
ConsoleLeaderCID = ProcessData->Process->ClientId;
SetWindowLongPtrW(GuiData->hWindow, GWLP_CONSOLE_LEADER_PID,
(LONG_PTR)(ConsoleLeaderCID.UniqueProcess));
} while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
}
-static VOID
+//static
+VOID
CreateSysMenu(HWND hWnd)
{
+ MENUITEMINFOW mii;
+ WCHAR szMenuStringBack[255];
+ WCHAR *ptrTab;
HMENU hMenu = GetSystemMenu(hWnd, FALSE);
if (hMenu != NULL)
{
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING;
+ mii.dwTypeData = szMenuStringBack;
+ mii.cch = sizeof(szMenuStringBack)/sizeof(WCHAR);
+
+ GetMenuItemInfoW(hMenu, SC_CLOSE, FALSE, &mii);
+
+ ptrTab = wcschr(szMenuStringBack, '\t');
+ if (ptrTab)
+ {
+ *ptrTab = '\0';
+ mii.cch = wcslen(szMenuStringBack);
+
+ SetMenuItemInfoW(hMenu, SC_CLOSE, FALSE, &mii);
+ }
+
AppendMenuItems(hMenu, GuiConsoleMainMenuItems);
DrawMenuBar(hWnd);
}
static VOID
Paste(PGUI_CONSOLE_DATA GuiData);
static VOID
-UpdateSelection(PGUI_CONSOLE_DATA GuiData, PCOORD coord);
+UpdateSelection(PGUI_CONSOLE_DATA GuiData,
+ PCOORD SelectionAnchor OPTIONAL,
+ PCOORD coord);
static VOID
Mark(PGUI_CONSOLE_DATA GuiData)
PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
/* Clear the old selection */
- // UpdateSelection(GuiData, NULL);
GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION;
/* Restart a new selection */
- GuiData->dwSelectionCursor.X = ActiveBuffer->ViewOrigin.X;
- GuiData->dwSelectionCursor.Y = ActiveBuffer->ViewOrigin.Y;
- GuiData->Selection.dwSelectionAnchor = GuiData->dwSelectionCursor;
- UpdateSelection(GuiData, &GuiData->Selection.dwSelectionAnchor);
+ GuiData->dwSelectionCursor = ActiveBuffer->ViewOrigin;
+ UpdateSelection(GuiData,
+ &GuiData->dwSelectionCursor,
+ &GuiData->dwSelectionCursor);
}
static VOID
SelectAll(PGUI_CONSOLE_DATA GuiData)
{
PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
+ COORD SelectionAnchor;
/* Clear the old selection */
- // UpdateSelection(GuiData, NULL);
GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION;
/*
* The selection area extends to the whole screen buffer's width.
*/
- GuiData->Selection.dwSelectionAnchor.X = 0;
- GuiData->Selection.dwSelectionAnchor.Y = 0;
+ SelectionAnchor.X = SelectionAnchor.Y = 0;
GuiData->dwSelectionCursor.X = ActiveBuffer->ScreenBufferSize.X - 1;
/*
/* Restart a new selection */
GuiData->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION;
- UpdateSelection(GuiData, &GuiData->dwSelectionCursor);
+ UpdateSelection(GuiData, &SelectionAnchor, &GuiData->dwSelectionCursor);
}
static LRESULT
SetWindowLongPtrW(GuiData->hWindow, GWLP_USERDATA, (DWORD_PTR)GuiData);
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
- CreateSysMenu(GuiData->hWindow);
+ // FIXME: HACK: Potential HACK for CORE-8129; see revision 63595.
+ //CreateSysMenu(GuiData->hWindow);
DPRINT("OnNcCreate - setting start event\n");
SetEvent(GuiData->hGuiInitEvent);
static VOID
OnActivate(PGUI_CONSOLE_DATA GuiData, WPARAM wParam)
{
- PCONSOLE Console = GuiData->Console;
WORD ActivationState = LOWORD(wParam);
DPRINT1("WM_ACTIVATE - ActivationState = %d\n");
}
/*
- * When we are in QuickEdit mode, ignore the next mouse signal
- * when we are going to be enabled again via the mouse, in order
- * to prevent e.g. an erroneous right-click from the user which
- * would have as an effect to paste some unwanted text...
+ * Ignore the next mouse signal when we are going to be enabled again via
+ * the mouse, in order to prevent, e.g. when we are in Edit mode, erroneous
+ * mouse actions from the user that could spoil text selection or copy/pastes.
*/
- if (Console->QuickEdit && (ActivationState == WA_CLICKACTIVE))
+ if (ActivationState == WA_CLICKACTIVE)
GuiData->IgnoreNextMouseSignal = TRUE;
}
Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ViewOrigin.Y) * HeightUnit;
}
+VOID
+GetSelectionBeginEnd(PCOORD Begin, PCOORD End,
+ PCOORD SelectionAnchor,
+ PSMALL_RECT SmallRect)
+{
+ if (Begin == NULL || End == NULL) return;
+
+ *Begin = *SelectionAnchor;
+ End->X = (SelectionAnchor->X == SmallRect->Left) ? SmallRect->Right
+ /* Case X != Left, must be == Right */ : SmallRect->Left;
+ End->Y = (SelectionAnchor->Y == SmallRect->Top ) ? SmallRect->Bottom
+ /* Case Y != Top, must be == Bottom */ : SmallRect->Top;
+
+ /* Exchange Begin / End if Begin > End lexicographically */
+ if (Begin->Y > End->Y || (Begin->Y == End->Y && Begin->X > End->X))
+ {
+ End->X = _InterlockedExchange16(&Begin->X, End->X);
+ End->Y = _InterlockedExchange16(&Begin->Y, End->Y);
+ }
+}
+
+static HRGN
+CreateSelectionRgn(PGUI_CONSOLE_DATA GuiData,
+ BOOL LineSelection,
+ PCOORD SelectionAnchor,
+ PSMALL_RECT SmallRect)
+{
+ if (!LineSelection)
+ {
+ RECT rect;
+ SmallRectToRect(GuiData, &rect, SmallRect);
+ return CreateRectRgnIndirect(&rect);
+ }
+ else
+ {
+ HRGN SelRgn;
+ COORD Begin, End;
+
+ GetSelectionBeginEnd(&Begin, &End, SelectionAnchor, SmallRect);
+
+ if (Begin.Y == End.Y)
+ {
+ SMALL_RECT sr;
+ RECT r ;
+
+ sr.Left = Begin.X;
+ sr.Top = Begin.Y;
+ sr.Right = End.X;
+ sr.Bottom = End.Y;
+
+ // Debug thingie to see whether I can put this corner case
+ // together with the previous one.
+ if (SmallRect->Left != sr.Left ||
+ SmallRect->Top != sr.Top ||
+ SmallRect->Right != sr.Right ||
+ SmallRect->Bottom != sr.Bottom)
+ {
+ DPRINT1("\n"
+ "SmallRect = (%d, %d, %d, %d)\n"
+ "sr = (%d, %d, %d, %d)\n"
+ "\n",
+ SmallRect->Left, SmallRect->Top, SmallRect->Right, SmallRect->Bottom,
+ sr.Left, sr.Top, sr.Right, sr.Bottom);
+ }
+
+ SmallRectToRect(GuiData, &r, &sr);
+ SelRgn = CreateRectRgnIndirect(&r);
+ }
+ else
+ {
+ PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
+
+ HRGN rg1, rg2, rg3;
+ SMALL_RECT sr1, sr2, sr3;
+ RECT r1 , r2 , r3 ;
+
+ sr1.Left = Begin.X;
+ sr1.Top = Begin.Y;
+ sr1.Right = ActiveBuffer->ScreenBufferSize.X - 1;
+ sr1.Bottom = Begin.Y;
+
+ sr2.Left = 0;
+ sr2.Top = Begin.Y + 1;
+ sr2.Right = ActiveBuffer->ScreenBufferSize.X - 1;
+ sr2.Bottom = End.Y - 1;
+
+ sr3.Left = 0;
+ sr3.Top = End.Y;
+ sr3.Right = End.X;
+ sr3.Bottom = End.Y;
+
+ SmallRectToRect(GuiData, &r1, &sr1);
+ SmallRectToRect(GuiData, &r2, &sr2);
+ SmallRectToRect(GuiData, &r3, &sr3);
+
+ rg1 = CreateRectRgnIndirect(&r1);
+ rg2 = CreateRectRgnIndirect(&r2);
+ rg3 = CreateRectRgnIndirect(&r3);
+
+ CombineRgn(rg1, rg1, rg2, RGN_XOR);
+ CombineRgn(rg1, rg1, rg3, RGN_XOR);
+ DeleteObject(rg3);
+ DeleteObject(rg2);
+
+ SelRgn = rg1;
+ }
+
+ return SelRgn;
+ }
+}
+
+static VOID
+PaintSelectionRect(PGUI_CONSOLE_DATA GuiData, PPAINTSTRUCT pps)
+{
+ HRGN rgnPaint = CreateRectRgnIndirect(&pps->rcPaint);
+ HRGN rgnSel = CreateSelectionRgn(GuiData, GuiData->LineSelection,
+ &GuiData->Selection.dwSelectionAnchor,
+ &GuiData->Selection.srSelection);
+
+ /* Invert the selection */
+
+ int ErrorCode = CombineRgn(rgnPaint, rgnPaint, rgnSel, RGN_AND);
+ if (ErrorCode != ERROR && ErrorCode != NULLREGION)
+ {
+ InvertRgn(pps->hdc, rgnPaint);
+ }
+
+ DeleteObject(rgnSel);
+ DeleteObject(rgnPaint);
+}
+
static VOID
-UpdateSelection(PGUI_CONSOLE_DATA GuiData, PCOORD coord)
+UpdateSelection(PGUI_CONSOLE_DATA GuiData,
+ PCOORD SelectionAnchor OPTIONAL,
+ PCOORD coord)
{
PCONSOLE Console = GuiData->Console;
- RECT oldRect;
+ HRGN oldRgn = CreateSelectionRgn(GuiData, GuiData->LineSelection,
+ &GuiData->Selection.dwSelectionAnchor,
+ &GuiData->Selection.srSelection);
- SmallRectToRect(GuiData, &oldRect, &GuiData->Selection.srSelection);
+ /* Update the anchor if needed (use the old one if NULL) */
+ if (SelectionAnchor)
+ GuiData->Selection.dwSelectionAnchor = *SelectionAnchor;
if (coord != NULL)
{
- RECT newRect;
SMALL_RECT rc;
+ HRGN newRgn;
+
+ /*
+ * Pressing the Control key while selecting text, allows us to enter
+ * into line-selection mode, the selection mode of *nix terminals.
+ */
+ BOOL OldLineSel = GuiData->LineSelection;
+ GuiData->LineSelection = !!(GetKeyState(VK_CONTROL) & 0x8000);
/* Exchange left/top with right/bottom if required */
rc.Left = min(GuiData->Selection.dwSelectionAnchor.X, coord->X);
rc.Right = max(GuiData->Selection.dwSelectionAnchor.X, coord->X);
rc.Bottom = max(GuiData->Selection.dwSelectionAnchor.Y, coord->Y);
- SmallRectToRect(GuiData, &newRect, &rc);
+ newRgn = CreateSelectionRgn(GuiData, GuiData->LineSelection,
+ &GuiData->Selection.dwSelectionAnchor,
+ &rc);
if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
{
- if (memcmp(&rc, &GuiData->Selection.srSelection, sizeof(SMALL_RECT)) != 0)
+ if (OldLineSel != GuiData->LineSelection ||
+ memcmp(&rc, &GuiData->Selection.srSelection, sizeof(SMALL_RECT)) != 0)
{
- HRGN rgn1, rgn2;
-
/* Calculate the region that needs to be updated */
- if ((rgn1 = CreateRectRgnIndirect(&oldRect)))
+ if (oldRgn && newRgn && CombineRgn(newRgn, newRgn, oldRgn, RGN_XOR) != ERROR)
{
- if ((rgn2 = CreateRectRgnIndirect(&newRect)))
- {
- if (CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
- {
- InvalidateRgn(GuiData->hWindow, rgn1, FALSE);
- }
- DeleteObject(rgn2);
- }
- DeleteObject(rgn1);
+ InvalidateRgn(GuiData->hWindow, newRgn, FALSE);
}
}
}
else
{
- InvalidateRect(GuiData->hWindow, &newRect, FALSE);
+ InvalidateRgn(GuiData->hWindow, newRgn, FALSE);
}
+ DeleteObject(newRgn);
+
GuiData->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY;
GuiData->Selection.srSelection = rc;
GuiData->dwSelectionCursor = *coord;
if ((GuiData->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) == 0)
{
- LPWSTR SelectionType, WindowTitle = NULL;
- SIZE_T Length = 0;
+ LPWSTR SelTypeStr = NULL , WindowTitle = NULL;
+ SIZE_T SelTypeStrLength = 0, Length = 0;
/* Clear the old selection */
if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
{
- InvalidateRect(GuiData->hWindow, &oldRect, FALSE);
+ InvalidateRgn(GuiData->hWindow, oldRgn, FALSE);
}
- if (GuiData->Selection.dwFlags & CONSOLE_MOUSE_SELECTION)
- {
- SelectionType = L"Selection - ";
- }
- else
+ /*
+ * When passing a zero-length buffer size, LoadString(...) returns
+ * a read-only pointer buffer to the program's resource string.
+ */
+ SelTypeStrLength =
+ LoadStringW(ConSrvDllInstance,
+ (GuiData->Selection.dwFlags & CONSOLE_MOUSE_SELECTION)
+ ? IDS_SELECT_TITLE : IDS_MARK_TITLE,
+ (LPWSTR)&SelTypeStr, 0);
+
+ /*
+ * Prepend the selection type string to the current console title
+ * if we succeeded in retrieving a valid localized string.
+ */
+ if (SelTypeStr)
{
- SelectionType = L"Mark - ";
- }
+ // 3 for " - " and 1 for NULL
+ Length = Console->Title.Length + (SelTypeStrLength + 3 + 1) * sizeof(WCHAR);
+ WindowTitle = ConsoleAllocHeap(0, Length);
+
+ wcsncpy(WindowTitle, SelTypeStr, SelTypeStrLength);
+ WindowTitle[SelTypeStrLength] = L'\0';
+ wcscat(WindowTitle, L" - ");
+ wcscat(WindowTitle, Console->Title.Buffer);
- Length = Console->Title.Length + wcslen(SelectionType) + 1;
- WindowTitle = ConsoleAllocHeap(0, Length * sizeof(WCHAR));
- wcscpy(WindowTitle, SelectionType);
- wcscat(WindowTitle, Console->Title.Buffer);
- SetWindowText(GuiData->hWindow, WindowTitle);
- ConsoleFreeHeap(WindowTitle);
+ SetWindowText(GuiData->hWindow, WindowTitle);
+ ConsoleFreeHeap(WindowTitle);
+ }
GuiData->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS;
ConioPause(Console, PAUSED_FROM_SELECTION);
/* Clear the selection */
if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
{
- InvalidateRect(GuiData->hWindow, &oldRect, FALSE);
+ InvalidateRgn(GuiData->hWindow, oldRgn, FALSE);
}
GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION;
ConioUnpause(Console, PAUSED_FROM_SELECTION);
+ /* Restore the console title */
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
}
+
+ DeleteObject(oldRgn);
}
rcPaint.top,
SRCCOPY);
+ /* Draw the selection region if needed */
if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
{
- SmallRectToRect(GuiData, &rcPaint, &GuiData->Selection.srSelection);
-
- /* Invert the selection */
- if (IntersectRect(&rcPaint, &ps.rcPaint, &rcPaint))
- {
- InvertRect(ps.hdc, &rcPaint);
- }
+ PaintSelectionRect(GuiData, &ps);
}
LeaveCriticalSection(&GuiData->Lock);
goto Quit;
}
else if ( VirtualKeyCode == VK_ESCAPE ||
- (VirtualKeyCode == 'C' && GetKeyState(VK_CONTROL) & 0x8000) )
+ (VirtualKeyCode == 'C' && (GetKeyState(VK_CONTROL) & 0x8000)) )
{
/* Cancel selection if ESC or Ctrl-C are pressed */
- UpdateSelection(GuiData, NULL);
+ UpdateSelection(GuiData, NULL, NULL);
goto Quit;
}
{
/* Keyboard selection mode */
BOOL Interpreted = FALSE;
- BOOL MajPressed = (GetKeyState(VK_SHIFT) & 0x8000);
+ BOOL MajPressed = !!(GetKeyState(VK_SHIFT) & 0x8000);
switch (VirtualKeyCode)
{
if (Interpreted)
{
- if (!MajPressed)
- GuiData->Selection.dwSelectionAnchor = GuiData->dwSelectionCursor;
-
- UpdateSelection(GuiData, &GuiData->dwSelectionCursor);
+ UpdateSelection(GuiData,
+ !MajPressed ? &GuiData->dwSelectionCursor : NULL,
+ &GuiData->dwSelectionCursor);
}
else if (!IsSystemKey(VirtualKeyCode))
{
if (!IsSystemKey(VirtualKeyCode))
{
/* Clear the selection and send the key into the input buffer */
- UpdateSelection(GuiData, NULL);
+ UpdateSelection(GuiData, NULL, NULL);
}
else
{
* We shouldn't wait here, though, since the console lock is entered.
* A copy of the thread list probably needs to be made.
*/
- ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
+ ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
LeaveCriticalSection(&Console->Lock);
return FALSE;
BOOL Err = FALSE;
PCONSOLE Console = GuiData->Console;
+ // FIXME: It's here that we need to check whether we has focus or not
+ // and whether we are in edit mode or not, to know if we need to deal
+ // with the mouse, or not.
+
if (GuiData->IgnoreNextMouseSignal)
{
if (msg != WM_LBUTTONDOWN &&
msg != WM_MBUTTONDOWN &&
- msg != WM_RBUTTONDOWN &&
- msg != WM_MOUSEMOVE)
+ msg != WM_RBUTTONDOWN)
{
/*
- * If this mouse signal is not a button-down action or a move,
+ * If this mouse signal is not a button-down action
* then it is the last signal being ignored.
*/
GuiData->IgnoreNextMouseSignal = FALSE;
else
{
/*
- * This mouse signal is a button-down action or a move.
+ * This mouse signal is a button-down action.
* Ignore it and perform default action.
*/
Err = TRUE;
case WM_LBUTTONDOWN:
{
/* Clear the old selection */
- // UpdateSelection(GuiData, NULL);
GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION;
/* Restart a new selection */
- GuiData->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam);
+ GuiData->dwSelectionCursor = PointToCoord(GuiData, lParam);
SetCapture(GuiData->hWindow);
GuiData->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
- UpdateSelection(GuiData, &GuiData->Selection.dwSelectionAnchor);
+ UpdateSelection(GuiData,
+ &GuiData->dwSelectionCursor,
+ &GuiData->dwSelectionCursor);
break;
}
case WM_LBUTTONUP:
{
- // COORD c;
-
if (!(GuiData->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break;
- // c = PointToCoord(GuiData, lParam);
+ // GuiData->dwSelectionCursor = PointToCoord(GuiData, lParam);
GuiData->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
- // UpdateSelection(GuiData, &c);
+ // UpdateSelection(GuiData, NULL, &GuiData->dwSelectionCursor);
ReleaseCapture();
break;
if (GetType(Buffer) == TEXTMODE_BUFFER)
{
-#ifdef IS_WHITESPACE
-#undef IS_WHITESPACE
-#endif
-#define IS_WHITESPACE(c) \
+#define IS_WORD_SEP(c) \
((c) == L'\0' || (c) == L' ' || (c) == L'\t' || (c) == L'\r' || (c) == L'\n')
PTEXTMODE_SCREEN_BUFFER TextBuffer = (PTEXTMODE_SCREEN_BUFFER)Buffer;
ptrL = ptrR = ConioCoordToPointer(TextBuffer, cL.X, cL.Y);
/* Enlarge the selection by checking for whitespace */
- while ((0 < cL.X) && !IS_WHITESPACE(ptrL->Char.UnicodeChar)
- && !IS_WHITESPACE((ptrL-1)->Char.UnicodeChar))
+ while ((0 < cL.X) && !IS_WORD_SEP(ptrL->Char.UnicodeChar)
+ && !IS_WORD_SEP((ptrL-1)->Char.UnicodeChar))
{
--cL.X;
--ptrL;
}
while ((cR.X < TextBuffer->ScreenBufferSize.X - 1) &&
- !IS_WHITESPACE(ptrR->Char.UnicodeChar) &&
- !IS_WHITESPACE((ptrR+1)->Char.UnicodeChar))
+ !IS_WORD_SEP(ptrR->Char.UnicodeChar) &&
+ !IS_WORD_SEP((ptrR+1)->Char.UnicodeChar))
{
++cR.X;
++ptrR;
* Update the selection started with the single
* left-click that preceded this double-click.
*/
- GuiData->Selection.dwSelectionAnchor = cL;
- GuiData->dwSelectionCursor = cR;
-
GuiData->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
- UpdateSelection(GuiData, &GuiData->dwSelectionCursor);
+ UpdateSelection(GuiData, &cL, &cR);
/* Ignore the next mouse move signal */
GuiData->IgnoreNextMouseSignal = TRUE;
case WM_MOUSEMOVE:
{
- COORD c;
-
if (!(wParam & MK_LBUTTON)) break;
if (!(GuiData->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break;
- c = PointToCoord(GuiData, lParam); /* TODO: Scroll buffer to bring c into view */
- UpdateSelection(GuiData, &c);
+ // TODO: Scroll buffer to bring SelectionCursor into view
+ GuiData->dwSelectionCursor = PointToCoord(GuiData, lParam);
+ UpdateSelection(GuiData, NULL, &GuiData->dwSelectionCursor);
break;
}
break;
}
+ /*
+ * HACK FOR CORE-8394: Ignore the next mouse move signal
+ * just after mouse down click actions.
+ */
+ switch (msg)
+ {
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ GuiData->IgnoreNextMouseSignal = TRUE;
+ default:
+ break;
+ }
+
if (!Err)
{
if (wKeyState & MK_LBUTTON)
}
/* Clear the selection */
- UpdateSelection(GuiData, NULL);
+ UpdateSelection(GuiData, NULL, NULL);
}
VOID
// HACK: This functionality is standard for general scrollbars. Don't add it by hand.
VOID
-FASTCALL
GuiConsoleHandleScrollbarMenu(VOID)
{
HMENU hMenu;
break;
}
+ /* Detect Alt-Esc/Space/Tab presses defer to DefWindowProc */
+ if ( (HIWORD(lParam) & KF_ALTDOWN) && (wParam == VK_ESCAPE || wParam == VK_SPACE || wParam == VK_TAB))
+ {
+ return DefWindowProcW(hWnd, msg, wParam, lParam);
+ }
OnKey(GuiData, msg, wParam, lParam);
break;