[KERNEL32-CONSRV]

- Implement ConsoleMenuControl; see http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php for more information.
- Implement SetConsoleMenuClose; see http://www.mail-archive.com/harbour@harbour-project.org/msg27509.html (or http://harbour-devel.1590103.n2.nabble.com/Question-about-hb-gt-win-CtrlHandler-usage-td4670862i20.html ) for more information.

[CONSRV]
Remove two unneeded DPRINTs.

svn path=/trunk/; revision=59112
This commit is contained in:
Hermès Bélusca-Maïto 2013-05-30 00:50:03 +00:00
parent 72eb8769a6
commit 8765fbb397
11 changed files with 249 additions and 49 deletions

View file

@ -240,17 +240,29 @@ IntCheckForConsoleFileName(IN LPCWSTR pszName,
/*
* @unimplemented (Undocumented)
* @implemented (Undocumented)
* @note See http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php
*/
BOOL
HMENU
WINAPI
ConsoleMenuControl(HANDLE hConsole,
DWORD Unknown1,
DWORD Unknown2)
ConsoleMenuControl(HANDLE hConsoleOutput,
DWORD dwCmdIdLow,
DWORD dwCmdIdHigh)
{
DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_MENUCONTROL MenuControlRequest = &ApiMessage.Data.MenuControlRequest;
MenuControlRequest->OutputHandle = hConsoleOutput;
MenuControlRequest->dwCmdIdLow = dwCmdIdLow;
MenuControlRequest->dwCmdIdHigh = dwCmdIdHigh;
MenuControlRequest->hMenu = NULL;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepMenuControl),
sizeof(CONSOLE_MENUCONTROL));
return MenuControlRequest->hMenu;
}
@ -654,15 +666,29 @@ SetConsoleMaximumWindowSize(DWORD Unknown0,
/*
* @unimplemented (Undocumented)
* @implemented (Undocumented)
*/
BOOL
WINAPI
SetConsoleMenuClose(DWORD Unknown0)
SetConsoleMenuClose(BOOL bEnable)
{
DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &ApiMessage.Data.SetMenuCloseRequest;
SetMenuCloseRequest->Enable = bEnable;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMenuClose),
sizeof(CONSOLE_SETMENUCLOSE));
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
return TRUE;
}

View file

@ -451,6 +451,12 @@ BOOL WINAPI SetConsoleTextAttribute(_In_ HANDLE, _In_ WORD);
BOOL WINAPI SetConsoleTitleA(_In_ LPCSTR);
BOOL WINAPI SetConsoleTitleW(_In_ LPCWSTR);
BOOL WINAPI SetConsoleWindowInfo(_In_ HANDLE, _In_ BOOL, _In_ const SMALL_RECT*);
/* Undocumented, see http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php */
HMENU WINAPI ConsoleMenuControl(_In_ HANDLE, _In_ DWORD, _In_ DWORD);
/* Undocumented */
BOOL WINAPI SetConsoleMenuClose(_In_ BOOL);
BOOL WINAPI WriteConsoleA(HANDLE,CONST VOID*,DWORD,LPDWORD,LPVOID);
BOOL WINAPI WriteConsoleW(HANDLE,CONST VOID*,DWORD,LPDWORD,LPVOID);

View file

@ -64,7 +64,7 @@ typedef enum _CONSRV_API_NUMBER
// ConsolepVDMOperation,
// ConsolepSetCursor,
// ConsolepShowCursor,
// ConsolepMenuControl,
ConsolepMenuControl,
// ConsolepSetPalette,
ConsolepSetDisplayMode,
// ConsolepRegisterVDM,
@ -85,7 +85,7 @@ typedef enum _CONSRV_API_NUMBER
ConsolepGetCP,
ConsolepSetCP,
// ConsolepSetKeyShortcuts,
// ConsolepSetMenuClose,
ConsolepSetMenuClose,
// ConsolepNotifyLastClose,
ConsolepGenerateCtrlEvent,
// ConsolepGetKeyboardLayoutName,
@ -469,6 +469,19 @@ typedef struct
COORD Size;
} CONSOLE_GETLARGESTWINDOWSIZE, *PCONSOLE_GETLARGESTWINDOWSIZE;
typedef struct
{
HANDLE OutputHandle;
DWORD dwCmdIdLow;
DWORD dwCmdIdHigh;
HMENU hMenu;
} CONSOLE_MENUCONTROL, *PCONSOLE_MENUCONTROL;
typedef struct
{
BOOL Enable;
} CONSOLE_SETMENUCLOSE, *PCONSOLE_SETMENUCLOSE;
typedef struct
{
HANDLE OutputHandle;
@ -479,12 +492,12 @@ typedef struct
typedef struct
{
HWND WindowHandle;
HWND WindowHandle;
} CONSOLE_GETWINDOW, *PCONSOLE_GETWINDOW;
typedef struct
{
HICON WindowIcon;
HICON WindowIcon;
} CONSOLE_SETICON, *PCONSOLE_SETICON;
@ -637,6 +650,8 @@ typedef struct _CONSOLE_API_MESSAGE
CONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest;
CONSOLE_GETSETCONSOLETITLE TitleRequest;
CONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest;
CONSOLE_MENUCONTROL MenuControlRequest;
CONSOLE_SETMENUCLOSE SetMenuCloseRequest;
CONSOLE_SETWINDOWINFO SetWindowInfoRequest;
CONSOLE_GETWINDOW GetWindowRequest;
CONSOLE_SETICON SetIconRequest;

View file

@ -54,6 +54,8 @@ CSR_API(SrvSetConsoleHardwareState);
CSR_API(SrvGetConsoleDisplayMode);
CSR_API(SrvSetConsoleDisplayMode);
CSR_API(SrvGetLargestConsoleWindowSize);
CSR_API(SrvConsoleMenuControl);
CSR_API(SrvSetConsoleMenuClose);
CSR_API(SrvSetConsoleWindowInfo);
CSR_API(SrvGetConsoleWindow);
CSR_API(SrvSetConsoleIcon);

View file

@ -40,5 +40,9 @@
(Console)->TermIFace.Vtbl->GetDisplayMode(Console)
#define ConioSetDisplayMode(Console, NewMode) \
(Console)->TermIFace.Vtbl->SetDisplayMode((Console), (NewMode))
#define ConioMenuControl(Console, CmdIdLow, CmdIdHigh) \
(Console)->TermIFace.Vtbl->MenuControl((Console), (CmdIdLow), (CmdIdHigh))
#define ConioSetMenuClose(Console, Enable) \
(Console)->TermIFace.Vtbl->SetMenuClose((Console), (Enable))
/* EOF */

View file

@ -1339,11 +1339,7 @@ CSR_API(SrvGetConsoleDisplayMode)
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get console handle in SrvGetConsoleDisplayMode\n");
return Status;
}
if (!NT_SUCCESS(Status)) return Status;
GetDisplayModeRequest->DisplayMode = ConioGetDisplayMode(Console);
@ -1363,11 +1359,7 @@ CSR_API(SrvSetConsoleDisplayMode)
&Buff,
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get console handle in SrvSetConsoleDisplayMode\n");
return Status;
}
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
@ -1406,6 +1398,47 @@ CSR_API(SrvGetLargestConsoleWindowSize)
return STATUS_SUCCESS;
}
CSR_API(SrvConsoleMenuControl)
{
NTSTATUS Status;
PCONSOLE_MENUCONTROL MenuControlRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.MenuControlRequest;
PCONSOLE Console;
PCONSOLE_SCREEN_BUFFER Buff;
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
MenuControlRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
MenuControlRequest->hMenu = ConioMenuControl(Console,
MenuControlRequest->dwCmdIdLow,
MenuControlRequest->dwCmdIdHigh);
ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_SUCCESS;
}
CSR_API(SrvSetConsoleMenuClose)
{
NTSTATUS Status;
BOOL Success;
PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetMenuCloseRequest;
PCONSOLE Console;
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Success = ConioSetMenuClose(Console, SetMenuCloseRequest->Enable);
ConSrvReleaseConsole(Console, TRUE);
return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
}
CSR_API(SrvSetConsoleWindowInfo)
{
NTSTATUS Status;

View file

@ -48,6 +48,11 @@ typedef struct _GUI_CONSOLE_DATA
HICON hIcon; /* Handle to the console's icon (big) */
HICON hIconSm; /* Handle to the console's icon (small) */
BOOL IgnoreNextMouseSignal; /* Used in cases where we don't want to treat a mouse signal */
BOOL IsCloseButtonEnabled; /* TRUE if the Close button and the corresponding system menu item are enabled, FALSE otherwise */
UINT cmdIdLow ; /* Lowest menu id of the user-reserved menu id range */
UINT cmdIdHigh; /* Highest menu id of the user-reserved menu id range */
// COLORREF Colors[16];
// PVOID ScreenBuffer; /* Hardware screen buffer */

View file

@ -83,21 +83,21 @@ typedef struct _GUICONSOLE_MENUITEM
static const GUICONSOLE_MENUITEM GuiConsoleEditMenuItems[] =
{
{ IDS_MARK, NULL, ID_SYSTEM_EDIT_MARK },
{ IDS_COPY, NULL, ID_SYSTEM_EDIT_COPY },
{ IDS_PASTE, NULL, ID_SYSTEM_EDIT_PASTE },
{ IDS_SELECTALL, NULL, ID_SYSTEM_EDIT_SELECTALL },
{ IDS_SCROLL, NULL, ID_SYSTEM_EDIT_SCROLL },
{ IDS_FIND, NULL, ID_SYSTEM_EDIT_FIND },
{ IDS_MARK, NULL, ID_SYSTEM_EDIT_MARK },
{ IDS_COPY, NULL, ID_SYSTEM_EDIT_COPY },
{ IDS_PASTE, NULL, ID_SYSTEM_EDIT_PASTE },
{ IDS_SELECTALL, NULL, ID_SYSTEM_EDIT_SELECTALL },
{ IDS_SCROLL, NULL, ID_SYSTEM_EDIT_SCROLL },
{ IDS_FIND, NULL, ID_SYSTEM_EDIT_FIND },
{ 0, NULL, 0 } /* End of list */
};
static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems[] =
{
{ IDS_EDIT, GuiConsoleEditMenuItems, 0 },
{ IDS_DEFAULTS, NULL, ID_SYSTEM_DEFAULTS },
{ IDS_PROPERTIES, NULL, ID_SYSTEM_PROPERTIES },
{ IDS_EDIT, GuiConsoleEditMenuItems, 0 },
{ IDS_DEFAULTS, NULL, ID_SYSTEM_DEFAULTS },
{ IDS_PROPERTIES, NULL, ID_SYSTEM_PROPERTIES },
{ 0, NULL, 0 } /* End of list */
};
@ -186,8 +186,7 @@ GuiConsoleAppendMenuItems(HMENU hMenu,
static VOID
GuiConsoleCreateSysMenu(HWND hWnd)
{
HMENU hMenu;
hMenu = GetSystemMenu(hWnd, FALSE);
HMENU hMenu = GetSystemMenu(hWnd, FALSE);
if (hMenu != NULL)
{
GuiConsoleAppendMenuItems(hMenu, GuiConsoleMainMenuItems);
@ -195,6 +194,16 @@ GuiConsoleCreateSysMenu(HWND hWnd)
}
}
static VOID
GuiSendMenuEvent(PCONSOLE Console, UINT CmdId)
{
INPUT_RECORD er;
er.EventType = MENU_EVENT;
er.Event.MenuEvent.dwCommandId = CmdId;
ConioProcessInputEvent(Console, &er);
}
static VOID
GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData);
@ -222,6 +231,18 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM
}
ActiveBuffer = Console->ActiveBuffer;
/*
* In case the selected menu item belongs to the user-reserved menu id range,
* send to him a menu event and return directly. The user must handle those
* reserved menu commands...
*/
if (GuiData->cmdIdLow <= (UINT)wParam && (UINT)wParam <= GuiData->cmdIdHigh)
{
GuiSendMenuEvent(Console, (UINT)wParam);
goto Unlock_Quit;
}
/* ... otherwise, perform actions. */
switch (wParam)
{
case ID_SYSTEM_EDIT_MARK:
@ -284,8 +305,8 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM
break;
}
Unlock_Quit:
LeaveCriticalSection(&Console->Lock);
Quit:
if (!Ret)
Ret = DefWindowProcW(GuiData->hWindow, WM_SYSCOMMAND, wParam, lParam);
@ -1570,9 +1591,11 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (GuiData == NULL) return 0;
/*
* Each helper function which needs the console
* has to validate and lock it.
* Just retrieve a pointer to the console in case somebody needs it.
* It is not NULL because it was checked in GuiGetGuiData.
* Each helper function which needs the console has to validate and lock it.
*/
Console = GuiData->Console;
/* We have a console, start message dispatching */
switch (msg)
@ -1683,6 +1706,36 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
}
case WM_INITMENU:
{
HMENU hMenu = (HMENU)wParam;
if (hMenu != NULL)
{
/* Enables or disables the Close menu item */
EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | (GuiData->IsCloseButtonEnabled ? MF_ENABLED : MF_GRAYED));
}
if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
GuiSendMenuEvent(Console, WM_INITMENU);
LeaveCriticalSection(&Console->Lock);
}
break;
}
case WM_MENUSELECT:
{
if (HIWORD(wParam) == 0xFFFF) // Allow all the menu flags
{
if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
GuiSendMenuEvent(Console, WM_MENUSELECT);
LeaveCriticalSection(&Console->Lock);
}
}
break;
}
case WM_COMMAND:
case WM_SYSCOMMAND:
{
@ -1693,7 +1746,6 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_SETFOCUS:
case WM_KILLFOCUS:
{
Console = GuiData->Console; // Not NULL because checked in GuiGetGuiData.
if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
INPUT_RECORD er;
@ -1730,7 +1782,6 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
case PM_APPLY_CONSOLE_INFO:
{
Console = GuiData->Console; // Not NULL because checked in GuiGetGuiData.
if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
GuiApplyUserSettings(GuiData, (HANDLE)wParam, (BOOL)lParam);
@ -2322,6 +2373,37 @@ GuiSetDisplayMode(PCONSOLE Console, ULONG NewMode)
return TRUE;
}
static HMENU WINAPI
GuiMenuControl(PCONSOLE Console, UINT cmdIdLow, UINT cmdIdHigh)
{
PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data;
GuiData->cmdIdLow = cmdIdLow ;
GuiData->cmdIdHigh = cmdIdHigh;
return GetSystemMenu(GuiData->hWindow, FALSE);
}
static BOOL WINAPI
GuiSetMenuClose(PCONSOLE Console, BOOL Enable)
{
/*
* NOTE: See http://www.mail-archive.com/harbour@harbour-project.org/msg27509.html
* or http://harbour-devel.1590103.n2.nabble.com/Question-about-hb-gt-win-CtrlHandler-usage-td4670862i20.html
* for more information.
*/
PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data;
HMENU hSysMenu = GetSystemMenu(GuiData->hWindow, FALSE);
if (hSysMenu == NULL) return FALSE;
GuiData->IsCloseButtonEnabled = Enable;
EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | (Enable ? MF_ENABLED : MF_GRAYED));
return TRUE;
}
static FRONTEND_VTBL GuiVtbl =
{
GuiCleanupConsole,
@ -2338,6 +2420,8 @@ static FRONTEND_VTBL GuiVtbl =
GuiGetLargestConsoleWindowSize,
GuiGetDisplayMode,
GuiSetDisplayMode,
GuiMenuControl,
GuiSetMenuClose,
};
NTSTATUS FASTCALL
@ -2460,6 +2544,12 @@ GuiInitConsole(PCONSOLE Console,
}
}
/* Close button and the corresponding system menu item are enabled by default */
GuiData->IsCloseButtonEnabled = TRUE;
/* There is no user-reserved menu id range by default */
GuiData->cmdIdLow = GuiData->cmdIdHigh = 0;
/*
* We need to wait until the GUI has been fully initialized
* to retrieve custom settings i.e. WindowSize etc...

View file

@ -643,6 +643,18 @@ TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode)
return TRUE;
}
static HMENU WINAPI
TuiMenuControl(PCONSOLE Console, UINT cmdIdLow, UINT cmdIdHigh)
{
return NULL;
}
static BOOL WINAPI
TuiSetMenuClose(PCONSOLE Console, BOOL Enable)
{
return FALSE;
}
static FRONTEND_VTBL TuiVtbl =
{
TuiCleanupConsole,
@ -659,6 +671,8 @@ static FRONTEND_VTBL TuiVtbl =
TuiGetLargestConsoleWindowSize,
TuiGetDisplayMode,
TuiSetDisplayMode,
TuiMenuControl,
TuiSetMenuClose,
};
NTSTATUS FASTCALL

View file

@ -218,6 +218,11 @@ typedef struct _FRONTEND_VTBL
ULONG (WINAPI *GetDisplayMode)(struct _CONSOLE* Console);
BOOL (WINAPI *SetDisplayMode)(struct _CONSOLE* Console,
ULONG NewMode);
HMENU (WINAPI *MenuControl)(struct _CONSOLE* Console,
UINT cmdIdLow,
UINT cmdIdHigh);
BOOL (WINAPI *SetMenuClose)(struct _CONSOLE* Console,
BOOL Enable);
#if 0 // Possible future front-end interface
BOOL (WINAPI *GetFrontEndProperty)(struct _CONSOLE* Console,

View file

@ -74,7 +74,7 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber - CONSRV_FIR
// SrvVDMConsoleOperation,
// SrvSetConsoleCursor,
// SrvShowConsoleCursor,
// SrvConsoleMenuControl,
SrvConsoleMenuControl,
// SrvSetConsolePalette,
SrvSetConsoleDisplayMode,
// SrvRegisterConsoleVDM,
@ -95,7 +95,7 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber - CONSRV_FIR
SrvGetConsoleCP,
SrvSetConsoleCP,
// SrvSetConsoleKeyShortcuts,
// SrvSetConsoleMenuClose,
SrvSetConsoleMenuClose,
// SrvConsoleNotifyLastClose,
SrvGenerateConsoleCtrlEvent,
// SrvGetConsoleKeyboardLayoutName,
@ -165,7 +165,7 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber - CONSRV_FIRST_API
// FALSE, // SrvVDMConsoleOperation,
// FALSE, // SrvSetConsoleCursor,
// FALSE, // SrvShowConsoleCursor,
// FALSE, // SrvConsoleMenuControl,
FALSE, // SrvConsoleMenuControl,
// FALSE, // SrvSetConsolePalette,
FALSE, // SrvSetConsoleDisplayMode,
// FALSE, // SrvRegisterConsoleVDM,
@ -186,7 +186,7 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber - CONSRV_FIRST_API
FALSE, // SrvGetConsoleCP,
FALSE, // SrvSetConsoleCP,
// FALSE, // SrvSetConsoleKeyShortcuts,
// FALSE, // SrvSetConsoleMenuClose,
FALSE, // SrvSetConsoleMenuClose,
// FALSE, // SrvConsoleNotifyLastClose,
FALSE, // SrvGenerateConsoleCtrlEvent,
// FALSE, // SrvGetConsoleKeyboardLayoutName,
@ -256,7 +256,7 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER]
// "VDMConsoleOperation",
// "SetConsoleCursor",
// "ShowConsoleCursor",
// "ConsoleMenuControl",
"ConsoleMenuControl",
// "SetConsolePalette",
"SetConsoleDisplayMode",
// "RegisterConsoleVDM",
@ -277,7 +277,7 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER]
"GetConsoleCP",
"SetConsoleCP",
// "SetConsoleKeyShortcuts",
// "SetConsoleMenuClose",
"SetConsoleMenuClose",
// "ConsoleNotifyLastClose",
"GenerateConsoleCtrlEvent",
// "GetConsoleKeyboardLayoutName",