2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: frontends/gui/conwnd.c
5 * PURPOSE: GUI Console Window Class
6 * PROGRAMMERS: Gé van Geldorp
9 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
12 /* INCLUDES *******************************************************************/
25 /* GLOBALS ********************************************************************/
27 // #define PM_CREATE_CONSOLE (WM_APP + 1)
28 // #define PM_DESTROY_CONSOLE (WM_APP + 2)
31 #define CONGUI_MIN_WIDTH 10
32 #define CONGUI_MIN_HEIGHT 10
33 #define CONGUI_UPDATE_TIME 0
34 #define CONGUI_UPDATE_TIMER 1
36 #define CURSOR_BLINK_TIME 500
39 /**************************************************************\
40 \** Define the Console Leader Process for the console window **/
41 #define GWLP_CONWND_ALLOC (2 * sizeof(LONG_PTR))
42 #define GWLP_CONSOLE_LEADER_PID 0
43 #define GWLP_CONSOLE_LEADER_TID 4
46 SetConWndConsoleLeaderCID(IN PGUI_CONSOLE_DATA GuiData
)
48 PCONSOLE_PROCESS_DATA ProcessData
;
49 CLIENT_ID ConsoleLeaderCID
;
51 ProcessData
= CONTAINING_RECORD(GuiData
->Console
->ProcessList
.Blink
,
54 ConsoleLeaderCID
= ProcessData
->Process
->ClientId
;
55 SetWindowLongPtrW(GuiData
->hWindow
, GWLP_CONSOLE_LEADER_PID
,
56 (LONG_PTR
)(ConsoleLeaderCID
.UniqueProcess
));
57 SetWindowLongPtrW(GuiData
->hWindow
, GWLP_CONSOLE_LEADER_TID
,
58 (LONG_PTR
)(ConsoleLeaderCID
.UniqueThread
));
60 /**************************************************************/
62 HICON ghDefaultIcon
= NULL
;
63 HICON ghDefaultIconSm
= NULL
;
64 HCURSOR ghDefaultCursor
= NULL
;
66 typedef struct _GUICONSOLE_MENUITEM
69 const struct _GUICONSOLE_MENUITEM
*SubMenu
;
71 } GUICONSOLE_MENUITEM
, *PGUICONSOLE_MENUITEM
;
73 static const GUICONSOLE_MENUITEM GuiConsoleEditMenuItems
[] =
75 { IDS_MARK
, NULL
, ID_SYSTEM_EDIT_MARK
},
76 { IDS_COPY
, NULL
, ID_SYSTEM_EDIT_COPY
},
77 { IDS_PASTE
, NULL
, ID_SYSTEM_EDIT_PASTE
},
78 { IDS_SELECTALL
, NULL
, ID_SYSTEM_EDIT_SELECTALL
},
79 { IDS_SCROLL
, NULL
, ID_SYSTEM_EDIT_SCROLL
},
80 { IDS_FIND
, NULL
, ID_SYSTEM_EDIT_FIND
},
82 { 0, NULL
, 0 } /* End of list */
85 static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems
[] =
87 { IDS_EDIT
, GuiConsoleEditMenuItems
, 0 },
88 { IDS_DEFAULTS
, NULL
, ID_SYSTEM_DEFAULTS
},
89 { IDS_PROPERTIES
, NULL
, ID_SYSTEM_PROPERTIES
},
91 { 0, NULL
, 0 } /* End of list */
95 * Default 16-color palette for foreground and background
96 * (corresponding flags in comments).
98 const COLORREF s_Colors
[16] =
100 RGB(0, 0, 0), // (Black)
101 RGB(0, 0, 128), // BLUE
102 RGB(0, 128, 0), // GREEN
103 RGB(0, 128, 128), // BLUE | GREEN
104 RGB(128, 0, 0), // RED
105 RGB(128, 0, 128), // BLUE | RED
106 RGB(128, 128, 0), // GREEN | RED
107 RGB(192, 192, 192), // BLUE | GREEN | RED
109 RGB(128, 128, 128), // (Grey) INTENSITY
110 RGB(0, 0, 255), // BLUE | INTENSITY
111 RGB(0, 255, 0), // GREEN | INTENSITY
112 RGB(0, 255, 255), // BLUE | GREEN | INTENSITY
113 RGB(255, 0, 0), // RED | INTENSITY
114 RGB(255, 0, 255), // BLUE | RED | INTENSITY
115 RGB(255, 255, 0), // GREEN | RED | INTENSITY
116 RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY
119 /* FUNCTIONS ******************************************************************/
121 static LRESULT CALLBACK
122 ConWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
125 RegisterConWndClass(IN HINSTANCE hInstance
)
127 WNDCLASSEXW WndClass
;
130 ghDefaultIcon
= LoadImageW(hInstance
,
131 MAKEINTRESOURCEW(IDI_TERMINAL
),
133 GetSystemMetrics(SM_CXICON
),
134 GetSystemMetrics(SM_CYICON
),
136 ghDefaultIconSm
= LoadImageW(hInstance
,
137 MAKEINTRESOURCEW(IDI_TERMINAL
),
139 GetSystemMetrics(SM_CXSMICON
),
140 GetSystemMetrics(SM_CYSMICON
),
142 ghDefaultCursor
= LoadCursorW(NULL
, IDC_ARROW
);
144 WndClass
.cbSize
= sizeof(WNDCLASSEXW
);
145 WndClass
.lpszClassName
= GUI_CONWND_CLASS
;
146 WndClass
.lpfnWndProc
= ConWndProc
;
147 WndClass
.style
= CS_DBLCLKS
/* | CS_HREDRAW | CS_VREDRAW */;
148 WndClass
.hInstance
= hInstance
;
149 WndClass
.hIcon
= ghDefaultIcon
;
150 WndClass
.hIconSm
= ghDefaultIconSm
;
151 WndClass
.hCursor
= ghDefaultCursor
;
152 WndClass
.hbrBackground
= (HBRUSH
)GetStockObject(BLACK_BRUSH
); // The color of a terminal when it is switched off.
153 WndClass
.lpszMenuName
= NULL
;
154 WndClass
.cbClsExtra
= 0;
155 WndClass
.cbWndExtra
= GWLP_CONWND_ALLOC
;
157 WndClassAtom
= RegisterClassExW(&WndClass
);
158 if (WndClassAtom
== 0)
160 DPRINT1("Failed to register GUI console class\n");
164 NtUserConsoleControl(GuiConsoleWndClassAtom
, &WndClassAtom
, sizeof(ATOM
));
167 return (WndClassAtom
!= 0);
171 UnRegisterConWndClass(HINSTANCE hInstance
)
173 return !!UnregisterClassW(GUI_CONWND_CLASS
, hInstance
);
179 GetScreenBufferSizeUnits(IN PCONSOLE_SCREEN_BUFFER Buffer
,
180 IN PGUI_CONSOLE_DATA GuiData
,
182 OUT PUINT HeightUnit
)
184 if (Buffer
== NULL
|| GuiData
== NULL
||
185 WidthUnit
== NULL
|| HeightUnit
== NULL
)
190 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
192 *WidthUnit
= GuiData
->CharWidth
;
193 *HeightUnit
= GuiData
->CharHeight
;
195 else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
203 GuiConsoleAppendMenuItems(HMENU hMenu
,
204 const GUICONSOLE_MENUITEM
*Items
)
207 WCHAR szMenuString
[255];
212 if (Items
[i
].uID
!= (UINT
)-1)
214 if (LoadStringW(ConSrvDllInstance
,
217 sizeof(szMenuString
) / sizeof(szMenuString
[0])) > 0)
219 if (Items
[i
].SubMenu
!= NULL
)
221 hSubMenu
= CreatePopupMenu();
222 if (hSubMenu
!= NULL
)
224 GuiConsoleAppendMenuItems(hSubMenu
,
227 if (!AppendMenuW(hMenu
,
228 MF_STRING
| MF_POPUP
,
232 DestroyMenu(hSubMenu
);
253 } while (!(Items
[i
].uID
== 0 && Items
[i
].SubMenu
== NULL
&& Items
[i
].wCmdID
== 0));
257 GuiConsoleCreateSysMenu(HWND hWnd
)
259 HMENU hMenu
= GetSystemMenu(hWnd
, FALSE
);
262 GuiConsoleAppendMenuItems(hMenu
, GuiConsoleMainMenuItems
);
268 GuiSendMenuEvent(PCONSOLE Console
, UINT CmdId
)
272 er
.EventType
= MENU_EVENT
;
273 er
.Event
.MenuEvent
.dwCommandId
= CmdId
;
275 DPRINT("Menu item ID: %d\n", CmdId
);
276 ConioProcessInputEvent(Console
, &er
);
280 GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData
);
282 GuiConsolePaste(PGUI_CONSOLE_DATA GuiData
);
284 GuiConsoleUpdateSelection(PCONSOLE Console
, PCOORD coord
);
286 GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData
, DWORD WidthUnit
, DWORD HeightUnit
);
289 GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData
, WPARAM wParam
, LPARAM lParam
)
292 PCONSOLE Console
= GuiData
->Console
;
293 PCONSOLE_SCREEN_BUFFER ActiveBuffer
;
295 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
300 ActiveBuffer
= GuiData
->ActiveBuffer
;
303 * In case the selected menu item belongs to the user-reserved menu id range,
304 * send to him a menu event and return directly. The user must handle those
305 * reserved menu commands...
307 if (GuiData
->CmdIdLow
<= (UINT
)wParam
&& (UINT
)wParam
<= GuiData
->CmdIdHigh
)
309 GuiSendMenuEvent(Console
, (UINT
)wParam
);
313 /* ... otherwise, perform actions. */
316 case ID_SYSTEM_EDIT_MARK
:
318 /* Clear the old selection */
319 // GuiConsoleUpdateSelection(Console, NULL);
320 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
322 /* Restart a new selection */
323 Console
->dwSelectionCursor
.X
= ActiveBuffer
->ViewOrigin
.X
;
324 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ViewOrigin
.Y
;
325 Console
->Selection
.dwSelectionAnchor
= Console
->dwSelectionCursor
;
326 GuiConsoleUpdateSelection(Console
, &Console
->Selection
.dwSelectionAnchor
);
331 case ID_SYSTEM_EDIT_COPY
:
332 GuiConsoleCopy(GuiData
);
335 case ID_SYSTEM_EDIT_PASTE
:
336 GuiConsolePaste(GuiData
);
339 case ID_SYSTEM_EDIT_SELECTALL
:
341 /* Clear the old selection */
342 // GuiConsoleUpdateSelection(Console, NULL);
343 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
346 * The selection area extends to the whole screen buffer's width.
348 Console
->Selection
.dwSelectionAnchor
.X
= 0;
349 Console
->Selection
.dwSelectionAnchor
.Y
= 0;
350 Console
->dwSelectionCursor
.X
= ActiveBuffer
->ScreenBufferSize
.X
- 1;
353 * Determine whether the selection must extend to just some part
354 * (for text-mode screen buffers) or to all of the screen buffer's
355 * height (for graphics ones).
357 if (GetType(ActiveBuffer
) == TEXTMODE_BUFFER
)
360 * We select all the characters from the first line
361 * to the line where the cursor is positioned.
363 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->CursorPosition
.Y
;
365 else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */
368 * We select all the screen buffer area.
370 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ScreenBufferSize
.Y
- 1;
373 /* Restart a new selection */
374 Console
->Selection
.dwFlags
|= CONSOLE_MOUSE_SELECTION
;
375 GuiConsoleUpdateSelection(Console
, &Console
->dwSelectionCursor
);
380 case ID_SYSTEM_EDIT_SCROLL
:
381 DPRINT1("Scrolling is not handled yet\n");
384 case ID_SYSTEM_EDIT_FIND
:
385 DPRINT1("Finding is not handled yet\n");
388 case ID_SYSTEM_DEFAULTS
:
389 GuiConsoleShowConsoleProperties(GuiData
, TRUE
);
392 case ID_SYSTEM_PROPERTIES
:
393 GuiConsoleShowConsoleProperties(GuiData
, FALSE
);
402 LeaveCriticalSection(&Console
->Lock
);
405 Ret
= DefWindowProcW(GuiData
->hWindow
, WM_SYSCOMMAND
, wParam
, lParam
);
410 static PGUI_CONSOLE_DATA
411 GuiGetGuiData(HWND hWnd
)
413 /* This function ensures that the console pointer is not NULL */
414 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
415 return ( ((GuiData
== NULL
) || (GuiData
->hWindow
== hWnd
&& GuiData
->Console
!= NULL
)) ? GuiData
: NULL
);
419 GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData
, DWORD WidthUnit
, DWORD HeightUnit
)
421 PCONSOLE_SCREEN_BUFFER Buff
= GuiData
->ActiveBuffer
;
426 Width
= Buff
->ViewSize
.X
* WidthUnit
+
427 2 * (GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXEDGE
));
428 Height
= Buff
->ViewSize
.Y
* HeightUnit
+
429 2 * (GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYEDGE
)) + GetSystemMetrics(SM_CYCAPTION
);
431 /* Set scrollbar sizes */
432 sInfo
.cbSize
= sizeof(SCROLLINFO
);
433 sInfo
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
435 if (Buff
->ScreenBufferSize
.Y
> Buff
->ViewSize
.Y
)
437 sInfo
.nMax
= Buff
->ScreenBufferSize
.Y
- 1;
438 sInfo
.nPage
= Buff
->ViewSize
.Y
;
439 sInfo
.nPos
= Buff
->ViewOrigin
.Y
;
440 SetScrollInfo(GuiData
->hWindow
, SB_VERT
, &sInfo
, TRUE
);
441 Width
+= GetSystemMetrics(SM_CXVSCROLL
);
442 ShowScrollBar(GuiData
->hWindow
, SB_VERT
, TRUE
);
446 ShowScrollBar(GuiData
->hWindow
, SB_VERT
, FALSE
);
449 if (Buff
->ScreenBufferSize
.X
> Buff
->ViewSize
.X
)
451 sInfo
.nMax
= Buff
->ScreenBufferSize
.X
- 1;
452 sInfo
.nPage
= Buff
->ViewSize
.X
;
453 sInfo
.nPos
= Buff
->ViewOrigin
.X
;
454 SetScrollInfo(GuiData
->hWindow
, SB_HORZ
, &sInfo
, TRUE
);
455 Height
+= GetSystemMetrics(SM_CYHSCROLL
);
456 ShowScrollBar(GuiData
->hWindow
, SB_HORZ
, TRUE
);
460 ShowScrollBar(GuiData
->hWindow
, SB_HORZ
, FALSE
);
463 /* Resize the window */
464 SetWindowPos(GuiData
->hWindow
, NULL
, 0, 0, Width
, Height
,
465 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOCOPYBITS
);
466 // NOTE: The SWP_NOCOPYBITS flag can be replaced by a subsequent call
467 // to: InvalidateRect(GuiData->hWindow, NULL, TRUE);
471 GuiConsoleHandleNcCreate(HWND hWnd
, LPCREATESTRUCTW Create
)
473 PGUI_CONSOLE_DATA GuiData
= (PGUI_CONSOLE_DATA
)Create
->lpCreateParams
;
480 DPRINT("GuiConsoleHandleNcCreate\n");
484 DPRINT1("GuiConsoleNcCreate: No GUI data\n");
488 Console
= GuiData
->Console
;
490 GuiData
->hWindow
= hWnd
;
492 GuiData
->Font
= CreateFontW(LOWORD(GuiData
->GuiInfo
.FontSize
),
493 0, // HIWORD(GuiData->GuiInfo.FontSize),
496 GuiData
->GuiInfo
.FontWeight
,
503 NONANTIALIASED_QUALITY
,
504 FIXED_PITCH
| GuiData
->GuiInfo
.FontFamily
/* FF_DONTCARE */,
505 GuiData
->GuiInfo
.FaceName
);
507 if (NULL
== GuiData
->Font
)
509 DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
510 GuiData
->hWindow
= NULL
;
511 SetEvent(GuiData
->hGuiInitEvent
);
514 hDC
= GetDC(GuiData
->hWindow
);
517 DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
518 DeleteObject(GuiData
->Font
);
519 GuiData
->hWindow
= NULL
;
520 SetEvent(GuiData
->hGuiInitEvent
);
523 OldFont
= SelectObject(hDC
, GuiData
->Font
);
526 DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
527 ReleaseDC(GuiData
->hWindow
, hDC
);
528 DeleteObject(GuiData
->Font
);
529 GuiData
->hWindow
= NULL
;
530 SetEvent(GuiData
->hGuiInitEvent
);
533 if (!GetTextMetricsW(hDC
, &Metrics
))
535 DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
536 SelectObject(hDC
, OldFont
);
537 ReleaseDC(GuiData
->hWindow
, hDC
);
538 DeleteObject(GuiData
->Font
);
539 GuiData
->hWindow
= NULL
;
540 SetEvent(GuiData
->hGuiInitEvent
);
543 GuiData
->CharWidth
= Metrics
.tmMaxCharWidth
;
544 GuiData
->CharHeight
= Metrics
.tmHeight
+ Metrics
.tmExternalLeading
;
546 /* Measure real char width more precisely if possible. */
547 if (GetTextExtentPoint32W(hDC
, L
"R", 1, &CharSize
))
548 GuiData
->CharWidth
= CharSize
.cx
;
550 SelectObject(hDC
, OldFont
);
552 ReleaseDC(GuiData
->hWindow
, hDC
);
554 /* Initialize the terminal framebuffer */
555 GuiData
->hMemDC
= CreateCompatibleDC(NULL
);
556 GuiData
->hBitmap
= NULL
;
557 GuiData
->hSysPalette
= NULL
; /* Original system palette */
559 // FIXME: Keep these instructions here ? ///////////////////////////////////
560 Console
->ActiveBuffer
->CursorBlinkOn
= TRUE
;
561 Console
->ActiveBuffer
->ForceCursorOff
= FALSE
;
562 ////////////////////////////////////////////////////////////////////////////
564 SetWindowLongPtrW(GuiData
->hWindow
, GWLP_USERDATA
, (DWORD_PTR
)GuiData
);
566 SetTimer(GuiData
->hWindow
, CONGUI_UPDATE_TIMER
, CONGUI_UPDATE_TIME
, NULL
);
567 GuiConsoleCreateSysMenu(GuiData
->hWindow
);
569 DPRINT("GuiConsoleHandleNcCreate - setting start event\n");
570 SetEvent(GuiData
->hGuiInitEvent
);
572 return (BOOL
)DefWindowProcW(GuiData
->hWindow
, WM_NCCREATE
, 0, (LPARAM
)Create
);
576 SmallRectToRect(PGUI_CONSOLE_DATA GuiData
, PRECT Rect
, PSMALL_RECT SmallRect
)
578 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
579 UINT WidthUnit
, HeightUnit
;
581 GetScreenBufferSizeUnits(Buffer
, GuiData
, &WidthUnit
, &HeightUnit
);
583 Rect
->left
= (SmallRect
->Left
- Buffer
->ViewOrigin
.X
) * WidthUnit
;
584 Rect
->top
= (SmallRect
->Top
- Buffer
->ViewOrigin
.Y
) * HeightUnit
;
585 Rect
->right
= (SmallRect
->Right
+ 1 - Buffer
->ViewOrigin
.X
) * WidthUnit
;
586 Rect
->bottom
= (SmallRect
->Bottom
+ 1 - Buffer
->ViewOrigin
.Y
) * HeightUnit
;
590 GuiConsoleUpdateSelection(PCONSOLE Console
, PCOORD coord
)
592 PGUI_CONSOLE_DATA GuiData
= Console
->TermIFace
.Data
;
595 SmallRectToRect(GuiData
, &oldRect
, &Console
->Selection
.srSelection
);
602 /* Exchange left/top with right/bottom if required */
603 rc
.Left
= min(Console
->Selection
.dwSelectionAnchor
.X
, coord
->X
);
604 rc
.Top
= min(Console
->Selection
.dwSelectionAnchor
.Y
, coord
->Y
);
605 rc
.Right
= max(Console
->Selection
.dwSelectionAnchor
.X
, coord
->X
);
606 rc
.Bottom
= max(Console
->Selection
.dwSelectionAnchor
.Y
, coord
->Y
);
608 SmallRectToRect(GuiData
, &newRect
, &rc
);
610 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
612 if (memcmp(&rc
, &Console
->Selection
.srSelection
, sizeof(SMALL_RECT
)) != 0)
616 /* Calculate the region that needs to be updated */
617 if ((rgn1
= CreateRectRgnIndirect(&oldRect
)))
619 if ((rgn2
= CreateRectRgnIndirect(&newRect
)))
621 if (CombineRgn(rgn1
, rgn2
, rgn1
, RGN_XOR
) != ERROR
)
623 InvalidateRgn(GuiData
->hWindow
, rgn1
, FALSE
);
633 InvalidateRect(GuiData
->hWindow
, &newRect
, FALSE
);
636 Console
->Selection
.dwFlags
|= CONSOLE_SELECTION_NOT_EMPTY
;
637 Console
->Selection
.srSelection
= rc
;
638 Console
->dwSelectionCursor
= *coord
;
640 if ((Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) == 0)
642 LPWSTR SelectionType
, WindowTitle
= NULL
;
645 /* Clear the old selection */
646 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
648 InvalidateRect(GuiData
->hWindow
, &oldRect
, FALSE
);
651 if (Console
->Selection
.dwFlags
& CONSOLE_MOUSE_SELECTION
)
653 SelectionType
= L
"Selection - ";
657 SelectionType
= L
"Mark - ";
660 Length
= Console
->Title
.Length
+ wcslen(SelectionType
) + 1;
661 WindowTitle
= ConsoleAllocHeap(0, Length
* sizeof(WCHAR
));
662 wcscpy(WindowTitle
, SelectionType
);
663 wcscat(WindowTitle
, Console
->Title
.Buffer
);
664 SetWindowText(GuiData
->hWindow
, WindowTitle
);
665 ConsoleFreeHeap(WindowTitle
);
667 Console
->Selection
.dwFlags
|= CONSOLE_SELECTION_IN_PROGRESS
;
668 ConioPause(Console
, PAUSED_FROM_SELECTION
);
673 /* Clear the selection */
674 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
676 InvalidateRect(GuiData
->hWindow
, &oldRect
, FALSE
);
679 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
680 ConioUnpause(Console
, PAUSED_FROM_SELECTION
);
682 SetWindowText(GuiData
->hWindow
, Console
->Title
.Buffer
);
688 GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer
,
689 PGUI_CONSOLE_DATA GuiData
,
691 PRECT rcFramebuffer
);
693 GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer
,
694 PGUI_CONSOLE_DATA GuiData
,
696 PRECT rcFramebuffer
);
699 GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData
)
702 PCONSOLE Console
= GuiData
->Console
;
703 PCONSOLE_SCREEN_BUFFER ActiveBuffer
;
707 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
712 ActiveBuffer
= GuiData
->ActiveBuffer
;
714 BeginPaint(GuiData
->hWindow
, &ps
);
715 if (ps
.hdc
!= NULL
&&
716 ps
.rcPaint
.left
< ps
.rcPaint
.right
&&
717 ps
.rcPaint
.top
< ps
.rcPaint
.bottom
)
719 EnterCriticalSection(&GuiData
->Lock
);
721 /* Compose the current screen-buffer on-memory */
722 if (GetType(ActiveBuffer
) == TEXTMODE_BUFFER
)
724 GuiPaintTextModeBuffer((PTEXTMODE_SCREEN_BUFFER
)ActiveBuffer
,
725 GuiData
, &ps
.rcPaint
, &rcPaint
);
727 else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */
729 GuiPaintGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER
)ActiveBuffer
,
730 GuiData
, &ps
.rcPaint
, &rcPaint
);
733 /* Send it to screen */
737 rcPaint
.right
- rcPaint
.left
,
738 rcPaint
.bottom
- rcPaint
.top
,
744 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
)
746 SmallRectToRect(GuiData
, &rcPaint
, &Console
->Selection
.srSelection
);
748 /* Invert the selection */
749 if (IntersectRect(&rcPaint
, &ps
.rcPaint
, &rcPaint
))
751 InvertRect(ps
.hdc
, &rcPaint
);
755 LeaveCriticalSection(&GuiData
->Lock
);
757 EndPaint(GuiData
->hWindow
, &ps
);
761 LeaveCriticalSection(&Console
->Lock
);
763 DefWindowProcW(GuiData
->hWindow
, WM_PAINT
, 0, 0);
769 IsSystemKey(WORD VirtualKeyCode
)
771 switch (VirtualKeyCode
)
773 /* From MSDN, "Virtual-Key Codes" */
792 GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
794 PCONSOLE Console
= GuiData
->Console
;
795 PCONSOLE_SCREEN_BUFFER ActiveBuffer
;
797 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
799 ActiveBuffer
= GuiData
->ActiveBuffer
;
801 if (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
)
803 WORD VirtualKeyCode
= LOWORD(wParam
);
805 if (msg
!= WM_KEYDOWN
) goto Quit
;
807 if (VirtualKeyCode
== VK_RETURN
)
809 /* Copy (and clear) selection if ENTER is pressed */
810 GuiConsoleCopy(GuiData
);
813 else if ( VirtualKeyCode
== VK_ESCAPE
||
814 (VirtualKeyCode
== 'C' && GetKeyState(VK_CONTROL
) & 0x8000) )
816 /* Cancel selection if ESC or Ctrl-C are pressed */
817 GuiConsoleUpdateSelection(Console
, NULL
);
821 if ((Console
->Selection
.dwFlags
& CONSOLE_MOUSE_SELECTION
) == 0)
823 /* Keyboard selection mode */
824 BOOL Interpreted
= FALSE
;
825 BOOL MajPressed
= (GetKeyState(VK_SHIFT
) & 0x8000);
827 switch (VirtualKeyCode
)
832 if (Console
->dwSelectionCursor
.X
> 0)
833 Console
->dwSelectionCursor
.X
--;
841 if (Console
->dwSelectionCursor
.X
< ActiveBuffer
->ScreenBufferSize
.X
- 1)
842 Console
->dwSelectionCursor
.X
++;
850 if (Console
->dwSelectionCursor
.Y
> 0)
851 Console
->dwSelectionCursor
.Y
--;
859 if (Console
->dwSelectionCursor
.Y
< ActiveBuffer
->ScreenBufferSize
.Y
- 1)
860 Console
->dwSelectionCursor
.Y
++;
868 Console
->dwSelectionCursor
.X
= 0;
869 Console
->dwSelectionCursor
.Y
= 0;
876 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ScreenBufferSize
.Y
- 1;
883 Console
->dwSelectionCursor
.Y
-= ActiveBuffer
->ViewSize
.Y
;
884 if (Console
->dwSelectionCursor
.Y
< 0)
885 Console
->dwSelectionCursor
.Y
= 0;
893 Console
->dwSelectionCursor
.Y
+= ActiveBuffer
->ViewSize
.Y
;
894 if (Console
->dwSelectionCursor
.Y
>= ActiveBuffer
->ScreenBufferSize
.Y
)
895 Console
->dwSelectionCursor
.Y
= ActiveBuffer
->ScreenBufferSize
.Y
- 1;
907 Console
->Selection
.dwSelectionAnchor
= Console
->dwSelectionCursor
;
909 GuiConsoleUpdateSelection(Console
, &Console
->dwSelectionCursor
);
911 else if (!IsSystemKey(VirtualKeyCode
))
913 /* Emit an error beep sound */
914 SendNotifyMessage(GuiData
->hWindow
, PM_CONSOLE_BEEP
, 0, 0);
921 /* Mouse selection mode */
923 if (!IsSystemKey(VirtualKeyCode
))
925 /* Clear the selection and send the key into the input buffer */
926 GuiConsoleUpdateSelection(Console
, NULL
);
935 if ((Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) == 0)
939 Message
.hwnd
= GuiData
->hWindow
;
940 Message
.message
= msg
;
941 Message
.wParam
= wParam
;
942 Message
.lParam
= lParam
;
944 ConioProcessKey(Console
, &Message
);
948 LeaveCriticalSection(&Console
->Lock
);
952 // FIXME: Remove after fixing GuiConsoleHandleTimer
954 GuiInvalidateCell(IN OUT PFRONTEND This
, SHORT x
, SHORT y
);
957 GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData
)
959 PCONSOLE Console
= GuiData
->Console
;
960 PCONSOLE_SCREEN_BUFFER Buff
;
962 SetTimer(GuiData
->hWindow
, CONGUI_UPDATE_TIMER
, CURSOR_BLINK_TIME
, NULL
);
964 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
966 Buff
= GuiData
->ActiveBuffer
;
968 if (GetType(Buff
) == TEXTMODE_BUFFER
)
970 GuiInvalidateCell(&Console
->TermIFace
, Buff
->CursorPosition
.X
, Buff
->CursorPosition
.Y
);
971 Buff
->CursorBlinkOn
= !Buff
->CursorBlinkOn
;
973 if ((GuiData
->OldCursor
.x
!= Buff
->CursorPosition
.X
) ||
974 (GuiData
->OldCursor
.y
!= Buff
->CursorPosition
.Y
))
977 int OldScrollX
= -1, OldScrollY
= -1;
978 int NewScrollX
= -1, NewScrollY
= -1;
980 xScroll
.cbSize
= sizeof(SCROLLINFO
);
981 xScroll
.fMask
= SIF_POS
;
982 // Capture the original position of the scroll bars and save them.
983 if (GetScrollInfo(GuiData
->hWindow
, SB_HORZ
, &xScroll
)) OldScrollX
= xScroll
.nPos
;
984 if (GetScrollInfo(GuiData
->hWindow
, SB_VERT
, &xScroll
)) OldScrollY
= xScroll
.nPos
;
986 // If we successfully got the info for the horizontal scrollbar
989 if ((Buff
->CursorPosition
.X
< Buff
->ViewOrigin
.X
) ||
990 (Buff
->CursorPosition
.X
>= (Buff
->ViewOrigin
.X
+ Buff
->ViewSize
.X
)))
992 // Handle the horizontal scroll bar
993 if (Buff
->CursorPosition
.X
>= Buff
->ViewSize
.X
)
994 NewScrollX
= Buff
->CursorPosition
.X
- Buff
->ViewSize
.X
+ 1;
1000 NewScrollX
= OldScrollX
;
1003 // If we successfully got the info for the vertical scrollbar
1004 if (OldScrollY
>= 0)
1006 if ((Buff
->CursorPosition
.Y
< Buff
->ViewOrigin
.Y
) ||
1007 (Buff
->CursorPosition
.Y
>= (Buff
->ViewOrigin
.Y
+ Buff
->ViewSize
.Y
)))
1009 // Handle the vertical scroll bar
1010 if (Buff
->CursorPosition
.Y
>= Buff
->ViewSize
.Y
)
1011 NewScrollY
= Buff
->CursorPosition
.Y
- Buff
->ViewSize
.Y
+ 1;
1017 NewScrollY
= OldScrollY
;
1021 // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area
1022 // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar
1023 // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling)
1024 // and their associated scrollbar is left alone.
1025 if ((OldScrollX
!= NewScrollX
) || (OldScrollY
!= NewScrollY
))
1027 Buff
->ViewOrigin
.X
= NewScrollX
;
1028 Buff
->ViewOrigin
.Y
= NewScrollY
;
1029 ScrollWindowEx(GuiData
->hWindow
,
1030 (OldScrollX
- NewScrollX
) * GuiData
->CharWidth
,
1031 (OldScrollY
- NewScrollY
) * GuiData
->CharHeight
,
1037 if (NewScrollX
>= 0)
1039 xScroll
.nPos
= NewScrollX
;
1040 SetScrollInfo(GuiData
->hWindow
, SB_HORZ
, &xScroll
, TRUE
);
1042 if (NewScrollY
>= 0)
1044 xScroll
.nPos
= NewScrollY
;
1045 SetScrollInfo(GuiData
->hWindow
, SB_VERT
, &xScroll
, TRUE
);
1047 UpdateWindow(GuiData
->hWindow
);
1048 // InvalidateRect(GuiData->hWindow, NULL, FALSE);
1049 GuiData
->OldCursor
.x
= Buff
->CursorPosition
.X
;
1050 GuiData
->OldCursor
.y
= Buff
->CursorPosition
.Y
;
1054 else /* if (GetType(Buff) == GRAPHICS_BUFFER) */
1058 LeaveCriticalSection(&Console
->Lock
);
1062 GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData
)
1064 PCONSOLE Console
= GuiData
->Console
;
1066 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
1069 // TODO: Prompt for termination ? (Warn the user about possible apps running in this console)
1072 * FIXME: Windows will wait up to 5 seconds for the thread to exit.
1073 * We shouldn't wait here, though, since the console lock is entered.
1074 * A copy of the thread list probably needs to be made.
1076 ConDrvConsoleProcessCtrlEvent(Console
, 0, CTRL_CLOSE_EVENT
);
1078 LeaveCriticalSection(&Console
->Lock
);
1083 GuiConsoleHandleNcDestroy(HWND hWnd
)
1085 PGUI_CONSOLE_DATA GuiData
= GuiGetGuiData(hWnd
);
1087 KillTimer(hWnd
, CONGUI_UPDATE_TIMER
);
1088 GetSystemMenu(hWnd
, TRUE
);
1092 /* Free the terminal framebuffer */
1093 if (GuiData
->hMemDC
) DeleteDC(GuiData
->hMemDC
);
1094 if (GuiData
->hBitmap
) DeleteObject(GuiData
->hBitmap
);
1095 // if (GuiData->hSysPalette) DeleteObject(GuiData->hSysPalette);
1096 if (GuiData
->Font
) DeleteObject(GuiData
->Font
);
1099 /* Free the GuiData registration */
1100 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (DWORD_PTR
)NULL
);
1102 return DefWindowProcW(hWnd
, WM_NCDESTROY
, 0, 0);
1106 PointToCoord(PGUI_CONSOLE_DATA GuiData
, LPARAM lParam
)
1108 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1110 UINT WidthUnit
, HeightUnit
;
1112 GetScreenBufferSizeUnits(Buffer
, GuiData
, &WidthUnit
, &HeightUnit
);
1114 Coord
.X
= Buffer
->ViewOrigin
.X
+ ((SHORT
)LOWORD(lParam
) / (int)WidthUnit
);
1115 Coord
.Y
= Buffer
->ViewOrigin
.Y
+ ((SHORT
)HIWORD(lParam
) / (int)HeightUnit
);
1117 /* Clip coordinate to ensure it's inside buffer */
1120 else if (Coord
.X
>= Buffer
->ScreenBufferSize
.X
)
1121 Coord
.X
= Buffer
->ScreenBufferSize
.X
- 1;
1125 else if (Coord
.Y
>= Buffer
->ScreenBufferSize
.Y
)
1126 Coord
.Y
= Buffer
->ScreenBufferSize
.Y
- 1;
1132 GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1135 PCONSOLE Console
= GuiData
->Console
;
1137 if (GuiData
->IgnoreNextMouseSignal
)
1139 if (msg
!= WM_LBUTTONDOWN
&&
1140 msg
!= WM_MBUTTONDOWN
&&
1141 msg
!= WM_RBUTTONDOWN
&&
1142 msg
!= WM_MOUSEMOVE
)
1145 * If this mouse signal is not a button-down action or a move,
1146 * then it is the last signal being ignored.
1148 GuiData
->IgnoreNextMouseSignal
= FALSE
;
1153 * This mouse signal is a button-down action or a move.
1154 * Ignore it and perform default action.
1161 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
1167 if ( (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) ||
1168 (Console
->QuickEdit
) )
1172 case WM_LBUTTONDOWN
:
1174 /* Clear the old selection */
1175 // GuiConsoleUpdateSelection(Console, NULL);
1176 Console
->Selection
.dwFlags
= CONSOLE_NO_SELECTION
;
1178 /* Restart a new selection */
1179 Console
->Selection
.dwSelectionAnchor
= PointToCoord(GuiData
, lParam
);
1180 SetCapture(GuiData
->hWindow
);
1181 Console
->Selection
.dwFlags
|= CONSOLE_MOUSE_SELECTION
| CONSOLE_MOUSE_DOWN
;
1182 GuiConsoleUpdateSelection(Console
, &Console
->Selection
.dwSelectionAnchor
);
1191 if (!(Console
->Selection
.dwFlags
& CONSOLE_MOUSE_DOWN
)) break;
1193 // c = PointToCoord(GuiData, lParam);
1194 Console
->Selection
.dwFlags
&= ~CONSOLE_MOUSE_DOWN
;
1195 // GuiConsoleUpdateSelection(Console, &c);
1201 case WM_LBUTTONDBLCLK
:
1203 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1205 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
1207 #ifdef IS_WHITESPACE
1208 #undef IS_WHITESPACE
1210 #define IS_WHITESPACE(c) \
1211 ((c) == L'\0' || (c) == L' ' || (c) == L'\t' || (c) == L'\r' || (c) == L'\n')
1213 PTEXTMODE_SCREEN_BUFFER TextBuffer
= (PTEXTMODE_SCREEN_BUFFER
)Buffer
;
1215 PCHAR_INFO ptrL
, ptrR
;
1217 /* Starting point */
1218 cL
= cR
= PointToCoord(GuiData
, lParam
);
1219 ptrL
= ptrR
= ConioCoordToPointer(TextBuffer
, cL
.X
, cL
.Y
);
1221 /* Enlarge the selection by checking for whitespace */
1222 while ((0 < cL
.X
) && !IS_WHITESPACE(ptrL
->Char
.UnicodeChar
)
1223 && !IS_WHITESPACE((ptrL
-1)->Char
.UnicodeChar
))
1228 while ((cR
.X
< TextBuffer
->ScreenBufferSize
.X
- 1) &&
1229 !IS_WHITESPACE(ptrR
->Char
.UnicodeChar
) &&
1230 !IS_WHITESPACE((ptrR
+1)->Char
.UnicodeChar
))
1237 * Update the selection started with the single
1238 * left-click that preceded this double-click.
1240 Console
->Selection
.dwSelectionAnchor
= cL
;
1241 Console
->dwSelectionCursor
= cR
;
1243 Console
->Selection
.dwFlags
|= CONSOLE_MOUSE_SELECTION
| CONSOLE_MOUSE_DOWN
;
1244 GuiConsoleUpdateSelection(Console
, &Console
->dwSelectionCursor
);
1246 /* Ignore the next mouse move signal */
1247 GuiData
->IgnoreNextMouseSignal
= TRUE
;
1253 case WM_RBUTTONDOWN
:
1254 case WM_RBUTTONDBLCLK
:
1256 if (!(Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
))
1258 GuiConsolePaste(GuiData
);
1262 GuiConsoleCopy(GuiData
);
1265 /* Ignore the next mouse move signal */
1266 GuiData
->IgnoreNextMouseSignal
= TRUE
;
1274 if (!(wParam
& MK_LBUTTON
)) break;
1275 if (!(Console
->Selection
.dwFlags
& CONSOLE_MOUSE_DOWN
)) break;
1277 c
= PointToCoord(GuiData
, lParam
); /* TODO: Scroll buffer to bring c into view */
1278 GuiConsoleUpdateSelection(Console
, &c
);
1284 Err
= FALSE
; // TRUE;
1288 else if (Console
->InputBuffer
.Mode
& ENABLE_MOUSE_INPUT
)
1291 WORD wKeyState
= GET_KEYSTATE_WPARAM(wParam
);
1292 DWORD dwButtonState
= 0;
1293 DWORD dwControlKeyState
= 0;
1294 DWORD dwEventFlags
= 0;
1298 case WM_LBUTTONDOWN
:
1299 SetCapture(GuiData
->hWindow
);
1300 dwButtonState
= FROM_LEFT_1ST_BUTTON_PRESSED
;
1304 case WM_MBUTTONDOWN
:
1305 SetCapture(GuiData
->hWindow
);
1306 dwButtonState
= FROM_LEFT_2ND_BUTTON_PRESSED
;
1310 case WM_RBUTTONDOWN
:
1311 SetCapture(GuiData
->hWindow
);
1312 dwButtonState
= RIGHTMOST_BUTTON_PRESSED
;
1334 case WM_LBUTTONDBLCLK
:
1335 dwButtonState
= FROM_LEFT_1ST_BUTTON_PRESSED
;
1336 dwEventFlags
= DOUBLE_CLICK
;
1339 case WM_MBUTTONDBLCLK
:
1340 dwButtonState
= FROM_LEFT_2ND_BUTTON_PRESSED
;
1341 dwEventFlags
= DOUBLE_CLICK
;
1344 case WM_RBUTTONDBLCLK
:
1345 dwButtonState
= RIGHTMOST_BUTTON_PRESSED
;
1346 dwEventFlags
= DOUBLE_CLICK
;
1351 dwEventFlags
= MOUSE_MOVED
;
1355 dwButtonState
= GET_WHEEL_DELTA_WPARAM(wParam
) << 16;
1356 dwEventFlags
= MOUSE_WHEELED
;
1359 case WM_MOUSEHWHEEL
:
1360 dwButtonState
= GET_WHEEL_DELTA_WPARAM(wParam
) << 16;
1361 dwEventFlags
= MOUSE_HWHEELED
;
1371 if (wKeyState
& MK_LBUTTON
)
1372 dwButtonState
|= FROM_LEFT_1ST_BUTTON_PRESSED
;
1373 if (wKeyState
& MK_MBUTTON
)
1374 dwButtonState
|= FROM_LEFT_2ND_BUTTON_PRESSED
;
1375 if (wKeyState
& MK_RBUTTON
)
1376 dwButtonState
|= RIGHTMOST_BUTTON_PRESSED
;
1378 if (GetKeyState(VK_RMENU
) & 0x8000)
1379 dwControlKeyState
|= RIGHT_ALT_PRESSED
;
1380 if (GetKeyState(VK_LMENU
) & 0x8000)
1381 dwControlKeyState
|= LEFT_ALT_PRESSED
;
1382 if (GetKeyState(VK_RCONTROL
) & 0x8000)
1383 dwControlKeyState
|= RIGHT_CTRL_PRESSED
;
1384 if (GetKeyState(VK_LCONTROL
) & 0x8000)
1385 dwControlKeyState
|= LEFT_CTRL_PRESSED
;
1386 if (GetKeyState(VK_SHIFT
) & 0x8000)
1387 dwControlKeyState
|= SHIFT_PRESSED
;
1388 if (GetKeyState(VK_NUMLOCK
) & 0x0001)
1389 dwControlKeyState
|= NUMLOCK_ON
;
1390 if (GetKeyState(VK_SCROLL
) & 0x0001)
1391 dwControlKeyState
|= SCROLLLOCK_ON
;
1392 if (GetKeyState(VK_CAPITAL
) & 0x0001)
1393 dwControlKeyState
|= CAPSLOCK_ON
;
1394 /* See WM_CHAR MSDN documentation for instance */
1395 if (lParam
& 0x01000000)
1396 dwControlKeyState
|= ENHANCED_KEY
;
1398 er
.EventType
= MOUSE_EVENT
;
1399 er
.Event
.MouseEvent
.dwMousePosition
= PointToCoord(GuiData
, lParam
);
1400 er
.Event
.MouseEvent
.dwButtonState
= dwButtonState
;
1401 er
.Event
.MouseEvent
.dwControlKeyState
= dwControlKeyState
;
1402 er
.Event
.MouseEvent
.dwEventFlags
= dwEventFlags
;
1404 ConioProcessInputEvent(Console
, &er
);
1412 LeaveCriticalSection(&Console
->Lock
);
1416 return DefWindowProcW(GuiData
->hWindow
, msg
, wParam
, lParam
);
1422 GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer
,
1423 PGUI_CONSOLE_DATA GuiData
);
1425 GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer
,
1426 PGUI_CONSOLE_DATA GuiData
);
1429 GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData
)
1431 PCONSOLE Console
= GuiData
->Console
;
1433 if (OpenClipboard(GuiData
->hWindow
) == TRUE
)
1435 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1437 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
1439 GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER
)Buffer
, GuiData
);
1441 else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
1443 GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER
)Buffer
, GuiData
);
1449 /* Clear the selection */
1450 GuiConsoleUpdateSelection(Console
, NULL
);
1454 GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer
,
1455 PGUI_CONSOLE_DATA GuiData
);
1457 GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer
,
1458 PGUI_CONSOLE_DATA GuiData
);
1461 GuiConsolePaste(PGUI_CONSOLE_DATA GuiData
)
1463 if (OpenClipboard(GuiData
->hWindow
) == TRUE
)
1465 PCONSOLE_SCREEN_BUFFER Buffer
= GuiData
->ActiveBuffer
;
1467 if (GetType(Buffer
) == TEXTMODE_BUFFER
)
1469 GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER
)Buffer
, GuiData
);
1471 else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
1473 GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER
)Buffer
, GuiData
);
1481 GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData
, PMINMAXINFO minMaxInfo
)
1483 PCONSOLE Console
= GuiData
->Console
;
1484 PCONSOLE_SCREEN_BUFFER ActiveBuffer
;
1486 UINT WidthUnit
, HeightUnit
;
1488 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
1490 ActiveBuffer
= GuiData
->ActiveBuffer
;
1492 GetScreenBufferSizeUnits(ActiveBuffer
, GuiData
, &WidthUnit
, &HeightUnit
);
1494 windx
= CONGUI_MIN_WIDTH
* WidthUnit
+ 2 * (GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXEDGE
));
1495 windy
= CONGUI_MIN_HEIGHT
* HeightUnit
+ 2 * (GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYEDGE
)) + GetSystemMetrics(SM_CYCAPTION
);
1497 minMaxInfo
->ptMinTrackSize
.x
= windx
;
1498 minMaxInfo
->ptMinTrackSize
.y
= windy
;
1500 windx
= (ActiveBuffer
->ScreenBufferSize
.X
) * WidthUnit
+ 2 * (GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXEDGE
));
1501 windy
= (ActiveBuffer
->ScreenBufferSize
.Y
) * HeightUnit
+ 2 * (GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYEDGE
)) + GetSystemMetrics(SM_CYCAPTION
);
1503 if (ActiveBuffer
->ViewSize
.X
< ActiveBuffer
->ScreenBufferSize
.X
) windy
+= GetSystemMetrics(SM_CYHSCROLL
); // window currently has a horizontal scrollbar
1504 if (ActiveBuffer
->ViewSize
.Y
< ActiveBuffer
->ScreenBufferSize
.Y
) windx
+= GetSystemMetrics(SM_CXVSCROLL
); // window currently has a vertical scrollbar
1506 minMaxInfo
->ptMaxTrackSize
.x
= windx
;
1507 minMaxInfo
->ptMaxTrackSize
.y
= windy
;
1509 LeaveCriticalSection(&Console
->Lock
);
1513 GuiConsoleResize(PGUI_CONSOLE_DATA GuiData
, WPARAM wParam
, LPARAM lParam
)
1515 PCONSOLE Console
= GuiData
->Console
;
1517 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return;
1519 if ((GuiData
->WindowSizeLock
== FALSE
) &&
1520 (wParam
== SIZE_RESTORED
|| wParam
== SIZE_MAXIMIZED
|| wParam
== SIZE_MINIMIZED
))
1522 PCONSOLE_SCREEN_BUFFER Buff
= GuiData
->ActiveBuffer
;
1523 DWORD windx
, windy
, charx
, chary
;
1524 UINT WidthUnit
, HeightUnit
;
1526 GetScreenBufferSizeUnits(Buff
, GuiData
, &WidthUnit
, &HeightUnit
);
1528 GuiData
->WindowSizeLock
= TRUE
;
1530 windx
= LOWORD(lParam
);
1531 windy
= HIWORD(lParam
);
1533 // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar)
1534 if (Buff
->ViewSize
.X
< Buff
->ScreenBufferSize
.X
) windy
+= GetSystemMetrics(SM_CYHSCROLL
); // window currently has a horizontal scrollbar
1535 if (Buff
->ViewSize
.Y
< Buff
->ScreenBufferSize
.Y
) windx
+= GetSystemMetrics(SM_CXVSCROLL
); // window currently has a vertical scrollbar
1537 charx
= windx
/ (int)WidthUnit
;
1538 chary
= windy
/ (int)HeightUnit
;
1540 // Character alignment (round size up or down)
1541 if ((windx
% WidthUnit
) >= (WidthUnit
/ 2)) ++charx
;
1542 if ((windy
% HeightUnit
) >= (HeightUnit
/ 2)) ++chary
;
1544 // Compensate for added scroll bars in new window
1545 if (charx
< Buff
->ScreenBufferSize
.X
) windy
-= GetSystemMetrics(SM_CYHSCROLL
); // new window will have a horizontal scroll bar
1546 if (chary
< Buff
->ScreenBufferSize
.Y
) windx
-= GetSystemMetrics(SM_CXVSCROLL
); // new window will have a vertical scroll bar
1548 charx
= windx
/ (int)WidthUnit
;
1549 chary
= windy
/ (int)HeightUnit
;
1551 // Character alignment (round size up or down)
1552 if ((windx
% WidthUnit
) >= (WidthUnit
/ 2)) ++charx
;
1553 if ((windy
% HeightUnit
) >= (HeightUnit
/ 2)) ++chary
;
1556 if ((charx
!= Buff
->ViewSize
.X
) || (chary
!= Buff
->ViewSize
.Y
))
1558 Buff
->ViewSize
.X
= (charx
<= Buff
->ScreenBufferSize
.X
) ? charx
: Buff
->ScreenBufferSize
.X
;
1559 Buff
->ViewSize
.Y
= (chary
<= Buff
->ScreenBufferSize
.Y
) ? chary
: Buff
->ScreenBufferSize
.Y
;
1562 GuiConsoleResizeWindow(GuiData
, WidthUnit
, HeightUnit
);
1564 // Adjust the start of the visible area if we are attempting to show nonexistent areas
1565 if ((Buff
->ScreenBufferSize
.X
- Buff
->ViewOrigin
.X
) < Buff
->ViewSize
.X
) Buff
->ViewOrigin
.X
= Buff
->ScreenBufferSize
.X
- Buff
->ViewSize
.X
;
1566 if ((Buff
->ScreenBufferSize
.Y
- Buff
->ViewOrigin
.Y
) < Buff
->ViewSize
.Y
) Buff
->ViewOrigin
.Y
= Buff
->ScreenBufferSize
.Y
- Buff
->ViewSize
.Y
;
1567 InvalidateRect(GuiData
->hWindow
, NULL
, TRUE
);
1569 GuiData
->WindowSizeLock
= FALSE
;
1572 LeaveCriticalSection(&Console
->Lock
);
1576 // HACK: This functionality is standard for general scrollbars. Don't add it by hand.
1580 GuiConsoleHandleScrollbarMenu(VOID)
1584 hMenu = CreatePopupMenu();
1587 DPRINT("CreatePopupMenu failed\n");
1591 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE);
1592 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
1593 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP);
1594 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM);
1595 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
1596 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP);
1597 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN);
1598 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
1599 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP);
1600 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN);
1605 GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData
, UINT uMsg
, WPARAM wParam
)
1607 PCONSOLE Console
= GuiData
->Console
;
1608 PCONSOLE_SCREEN_BUFFER Buff
;
1611 int old_pos
, Maximum
;
1614 if (!ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
)) return 0;
1616 Buff
= GuiData
->ActiveBuffer
;
1618 if (uMsg
== WM_HSCROLL
)
1621 Maximum
= Buff
->ScreenBufferSize
.X
- Buff
->ViewSize
.X
;
1622 pShowXY
= &Buff
->ViewOrigin
.X
;
1627 Maximum
= Buff
->ScreenBufferSize
.Y
- Buff
->ViewSize
.Y
;
1628 pShowXY
= &Buff
->ViewOrigin
.Y
;
1631 /* set scrollbar sizes */
1632 sInfo
.cbSize
= sizeof(SCROLLINFO
);
1633 sInfo
.fMask
= SIF_RANGE
| SIF_POS
| SIF_PAGE
| SIF_TRACKPOS
;
1635 if (!GetScrollInfo(GuiData
->hWindow
, fnBar
, &sInfo
)) goto Quit
;
1637 old_pos
= sInfo
.nPos
;
1639 switch (LOWORD(wParam
))
1650 sInfo
.nPos
-= sInfo
.nPage
;
1654 sInfo
.nPos
+= sInfo
.nPage
;
1658 sInfo
.nPos
= sInfo
.nTrackPos
;
1659 ConioPause(Console
, PAUSED_FROM_SCROLLBAR
);
1662 case SB_THUMBPOSITION
:
1663 ConioUnpause(Console
, PAUSED_FROM_SCROLLBAR
);
1667 sInfo
.nPos
= sInfo
.nMin
;
1671 sInfo
.nPos
= sInfo
.nMax
;
1678 sInfo
.nPos
= max(sInfo
.nPos
, 0);
1679 sInfo
.nPos
= min(sInfo
.nPos
, Maximum
);
1681 if (old_pos
!= sInfo
.nPos
)
1683 USHORT OldX
= Buff
->ViewOrigin
.X
;
1684 USHORT OldY
= Buff
->ViewOrigin
.Y
;
1685 UINT WidthUnit
, HeightUnit
;
1687 *pShowXY
= sInfo
.nPos
;
1689 GetScreenBufferSizeUnits(Buff
, GuiData
, &WidthUnit
, &HeightUnit
);
1691 ScrollWindowEx(GuiData
->hWindow
,
1692 (OldX
- Buff
->ViewOrigin
.X
) * WidthUnit
,
1693 (OldY
- Buff
->ViewOrigin
.Y
) * HeightUnit
,
1700 sInfo
.fMask
= SIF_POS
;
1701 SetScrollInfo(GuiData
->hWindow
, fnBar
, &sInfo
, TRUE
);
1703 UpdateWindow(GuiData
->hWindow
);
1704 // InvalidateRect(GuiData->hWindow, NULL, FALSE);
1708 LeaveCriticalSection(&Console
->Lock
);
1714 EnterFullScreen(PGUI_CONSOLE_DATA GuiData
);
1716 LeaveFullScreen(PGUI_CONSOLE_DATA GuiData
);
1718 SwitchFullScreen(PGUI_CONSOLE_DATA GuiData
, BOOL FullScreen
);
1720 GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData
);
1722 static LRESULT CALLBACK
1723 ConWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1726 PGUI_CONSOLE_DATA GuiData
= NULL
;
1727 PCONSOLE Console
= NULL
;
1730 * - If it's the first time we create a window for the terminal,
1731 * just initialize it and return.
1733 * - If we are destroying the window, just do it and return.
1735 if (msg
== WM_NCCREATE
)
1737 return (LRESULT
)GuiConsoleHandleNcCreate(hWnd
, (LPCREATESTRUCTW
)lParam
);
1739 else if (msg
== WM_NCDESTROY
)
1741 return GuiConsoleHandleNcDestroy(hWnd
);
1745 * Now the terminal window is initialized.
1746 * Get the terminal data via the window's data.
1747 * If there is no data, just go away.
1749 GuiData
= GuiGetGuiData(hWnd
);
1750 if (GuiData
== NULL
) return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
1752 // TEMPORARY HACK until all of the functions can deal with a NULL GuiData->ActiveBuffer ...
1753 if (GuiData
->ActiveBuffer
== NULL
) return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
1756 * Just retrieve a pointer to the console in case somebody needs it.
1757 * It is not NULL because it was checked in GuiGetGuiData.
1758 * Each helper function which needs the console has to validate and lock it.
1760 Console
= GuiData
->Console
;
1762 /* We have a console, start message dispatching */
1767 WORD ActivationState
= LOWORD(wParam
);
1769 DPRINT1("WM_ACTIVATE - ActivationState = %d\n");
1771 if ( ActivationState
== WA_ACTIVE
||
1772 ActivationState
== WA_CLICKACTIVE
)
1774 if (GuiData
->GuiInfo
.FullScreen
)
1776 EnterFullScreen(GuiData
);
1777 // // PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
1778 // SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
1781 else // if (ActivationState == WA_INACTIVE)
1783 if (GuiData
->GuiInfo
.FullScreen
)
1785 SendMessageW(GuiData
->hWindow
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
1786 LeaveFullScreen(GuiData
);
1787 // // PostMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
1788 // SendMessageW(GuiData->hWindow, WM_SYSCOMMAND, SC_MINIMIZE, 0);
1793 * When we are in QuickEdit mode, ignore the next mouse signal
1794 * when we are going to be enabled again via the mouse, in order
1795 * to prevent e.g. an erroneous right-click from the user which
1796 * would have as an effect to paste some unwanted text...
1798 if (Console
->QuickEdit
&& (ActivationState
== WA_CLICKACTIVE
))
1799 GuiData
->IgnoreNextMouseSignal
= TRUE
;
1805 if (GuiConsoleHandleClose(GuiData
)) goto Default
;
1809 GuiConsoleHandlePaint(GuiData
);
1813 GuiConsoleHandleTimer(GuiData
);
1816 case WM_PALETTECHANGED
:
1818 PCONSOLE_SCREEN_BUFFER ActiveBuffer
= GuiData
->ActiveBuffer
;
1820 DPRINT("WM_PALETTECHANGED called\n");
1823 * Protects against infinite loops:
1824 * "... A window that receives this message must not realize
1825 * its palette, unless it determines that wParam does not contain
1826 * its own window handle." (WM_PALETTECHANGED description - MSDN)
1828 * This message is sent to all windows, including the one that
1829 * changed the system palette and caused this message to be sent.
1830 * The wParam of this message contains the handle of the window
1831 * that caused the system palette to change. To avoid an infinite
1832 * loop, care must be taken to check that the wParam of this message
1833 * does not match the window's handle.
1835 if ((HWND
)wParam
== hWnd
) break;
1837 DPRINT("WM_PALETTECHANGED ok\n");
1839 // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
1840 if (ActiveBuffer
->PaletteHandle
)
1842 DPRINT("WM_PALETTECHANGED changing palette\n");
1844 /* Specify the use of the system palette for the framebuffer */
1845 SetSystemPaletteUse(GuiData
->hMemDC
, ActiveBuffer
->PaletteUsage
);
1847 /* Realize the (logical) palette */
1848 RealizePalette(GuiData
->hMemDC
);
1851 DPRINT("WM_PALETTECHANGED quit\n");
1863 case WM_SYSDEADCHAR
:
1865 /* Detect Alt-Enter presses and switch back and forth to fullscreen mode */
1866 if (msg
== WM_SYSKEYDOWN
&& (HIWORD(lParam
) & KF_ALTDOWN
) && wParam
== VK_RETURN
)
1868 /* Switch only at first Alt-Enter press, and ignore subsequent key repetitions */
1869 if ((HIWORD(lParam
) & (KF_UP
| KF_REPEAT
)) != KF_REPEAT
)
1870 GuiConsoleSwitchFullScreen(GuiData
);
1875 GuiConsoleHandleKey(GuiData
, msg
, wParam
, lParam
);
1882 * The message was sent because we are manually triggering a change.
1883 * Check whether the mouse is indeed present on this console window
1884 * and take appropriate decisions.
1886 if (wParam
== -1 && lParam
== -1)
1891 /* Get the placement of the mouse */
1892 GetCursorPos(&mouseCoords
);
1894 /* On which window is placed the mouse ? */
1895 hWndHit
= WindowFromPoint(mouseCoords
);
1897 /* It's our window. Perform the hit-test to be used later on. */
1898 if (hWndHit
== hWnd
)
1900 wParam
= (WPARAM
)hWnd
;
1901 lParam
= DefWindowProcW(hWndHit
, WM_NCHITTEST
, 0,
1902 MAKELPARAM(mouseCoords
.x
, mouseCoords
.y
));
1906 /* Set the mouse cursor only when we are in the client area */
1907 if ((HWND
)wParam
== hWnd
&& LOWORD(lParam
) == HTCLIENT
)
1909 if (GuiData
->MouseCursorRefCount
>= 0)
1911 /* Show the cursor */
1912 SetCursor(GuiData
->hCursor
);
1916 /* Hide the cursor if the reference count is negative */
1927 case WM_LBUTTONDOWN
:
1928 case WM_MBUTTONDOWN
:
1929 case WM_RBUTTONDOWN
:
1933 case WM_LBUTTONDBLCLK
:
1934 case WM_MBUTTONDBLCLK
:
1935 case WM_RBUTTONDBLCLK
:
1938 case WM_MOUSEHWHEEL
:
1940 Result
= GuiConsoleHandleMouse(GuiData
, msg
, wParam
, lParam
);
1947 Result
= GuiConsoleHandleScroll(GuiData
, msg
, wParam
);
1951 case WM_NCRBUTTONDOWN
:
1953 DPRINT1("WM_NCRBUTTONDOWN\n");
1955 * HACK: !! Because, when we deal with WM_RBUTTON* and we do not
1956 * call after that DefWindowProc, on ReactOS, right-clicks on the
1957 * (non-client) application title-bar does not display the system
1958 * menu and does not trigger a WM_NCRBUTTONUP message too.
1959 * See: http://git.reactos.org/?p=reactos.git;a=blob;f=reactos/win32ss/user/user32/windows/defwnd.c;hb=332bc8f482f40fd05ab510f78276576719fbfba8#l1103
1960 * and line 1135 too.
1963 if (DefWindowProcW(hWnd
, WM_NCHITTEST
, 0, lParam
) == HTCAPTION
)
1965 /* Call DefWindowProcW with the WM_CONTEXTMENU message */
1966 msg
= WM_CONTEXTMENU
;
1971 // case WM_NCRBUTTONUP:
1972 // DPRINT1("WM_NCRBUTTONUP\n");
1975 case WM_CONTEXTMENU
:
1977 if (DefWindowProcW(hWnd
/*GuiData->hWindow*/, WM_NCHITTEST
, 0, lParam
) == HTCLIENT
)
1979 HMENU hMenu
= CreatePopupMenu();
1982 GuiConsoleAppendMenuItems(hMenu
, GuiConsoleEditMenuItems
);
1983 TrackPopupMenuEx(hMenu
,
1985 GET_X_LPARAM(lParam
),
1986 GET_Y_LPARAM(lParam
),
2001 HMENU hMenu
= (HMENU
)wParam
;
2004 /* Enable or disable the Close menu item */
2005 EnableMenuItem(hMenu
, SC_CLOSE
, MF_BYCOMMAND
|
2006 (GuiData
->IsCloseButtonEnabled
? MF_ENABLED
: MF_GRAYED
));
2008 /* Enable or disable the Copy and Paste items */
2009 EnableMenuItem(hMenu
, ID_SYSTEM_EDIT_COPY
, MF_BYCOMMAND
|
2010 ((Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) &&
2011 (Console
->Selection
.dwFlags
& CONSOLE_SELECTION_NOT_EMPTY
) ? MF_ENABLED
: MF_GRAYED
));
2012 // FIXME: Following whether the active screen buffer is text-mode
2013 // or graphics-mode, search for CF_UNICODETEXT or CF_BITMAP formats.
2014 EnableMenuItem(hMenu
, ID_SYSTEM_EDIT_PASTE
, MF_BYCOMMAND
|
2015 (!(Console
->Selection
.dwFlags
& CONSOLE_SELECTION_IN_PROGRESS
) &&
2016 IsClipboardFormatAvailable(CF_UNICODETEXT
) ? MF_ENABLED
: MF_GRAYED
));
2019 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2021 GuiSendMenuEvent(Console
, WM_INITMENU
);
2022 LeaveCriticalSection(&Console
->Lock
);
2029 if (HIWORD(wParam
) == 0xFFFF) // Allow all the menu flags
2031 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2033 GuiSendMenuEvent(Console
, WM_MENUSELECT
);
2034 LeaveCriticalSection(&Console
->Lock
);
2043 Result
= GuiConsoleHandleSysMenuCommand(GuiData
, wParam
, lParam
);
2050 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2052 BOOL SetFocus
= (msg
== WM_SETFOCUS
);
2055 er
.EventType
= FOCUS_EVENT
;
2056 er
.Event
.FocusEvent
.bSetFocus
= SetFocus
;
2057 ConioProcessInputEvent(Console
, &er
);
2060 DPRINT1("TODO: Create console caret\n");
2062 DPRINT1("TODO: Destroy console caret\n");
2064 LeaveCriticalSection(&Console
->Lock
);
2069 case WM_GETMINMAXINFO
:
2070 GuiConsoleGetMinMaxInfo(GuiData
, (PMINMAXINFO
)lParam
);
2075 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2077 // TODO: Simplify the code.
2078 // See: GuiConsoleNotifyWndProc() PM_CREATE_CONSOLE.
2082 /* Retrieve our real position */
2083 GetWindowRect(GuiData
->hWindow
, &rcWnd
);
2084 GuiData
->GuiInfo
.WindowOrigin
.x
= rcWnd
.left
;
2085 GuiData
->GuiInfo
.WindowOrigin
.y
= rcWnd
.top
;
2087 LeaveCriticalSection(&Console
->Lock
);
2093 GuiConsoleResize(GuiData
, wParam
, lParam
);
2096 case PM_RESIZE_TERMINAL
:
2098 PCONSOLE_SCREEN_BUFFER Buff
= GuiData
->ActiveBuffer
;
2102 DWORD Width
, Height
;
2103 UINT WidthUnit
, HeightUnit
;
2105 GetScreenBufferSizeUnits(Buff
, GuiData
, &WidthUnit
, &HeightUnit
);
2107 Width
= Buff
->ScreenBufferSize
.X
* WidthUnit
;
2108 Height
= Buff
->ScreenBufferSize
.Y
* HeightUnit
;
2110 /* Recreate the framebuffer */
2111 hDC
= GetDC(GuiData
->hWindow
);
2112 hnew
= CreateCompatibleBitmap(hDC
, Width
, Height
);
2113 ReleaseDC(GuiData
->hWindow
, hDC
);
2114 hold
= SelectObject(GuiData
->hMemDC
, hnew
);
2115 if (GuiData
->hBitmap
)
2117 if (hold
== GuiData
->hBitmap
) DeleteObject(GuiData
->hBitmap
);
2119 GuiData
->hBitmap
= hnew
;
2121 /* Resize the window to the user's values */
2122 GuiData
->WindowSizeLock
= TRUE
;
2123 GuiConsoleResizeWindow(GuiData
, WidthUnit
, HeightUnit
);
2124 GuiData
->WindowSizeLock
= FALSE
;
2128 case PM_APPLY_CONSOLE_INFO
:
2130 if (ConDrvValidateConsoleUnsafe(Console
, CONSOLE_RUNNING
, TRUE
))
2132 GuiApplyUserSettings(GuiData
, (HANDLE
)wParam
, (BOOL
)lParam
);
2133 LeaveCriticalSection(&Console
->Lock
);
2138 case PM_CONSOLE_BEEP
:
2139 DPRINT1("Beep !!\n");
2143 // case PM_CONSOLE_SET_TITLE:
2144 // SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer);
2148 Result
= DefWindowProcW(hWnd
, msg
, wParam
, lParam
);