2003-12-07 12:59:34 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2005-01-06 13:58:04 +00:00
|
|
|
/* $Id$
|
2003-12-07 12:59:34 +00:00
|
|
|
*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: Window classes
|
|
|
|
* FILE: subsys/win32k/ntuser/class.c
|
|
|
|
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
|
|
* REVISION HISTORY:
|
|
|
|
* 06-06-2001 CSH Created
|
|
|
|
*/
|
2003-12-07 16:54:44 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright 1993 Martin Ayotte
|
|
|
|
* Copyright 1994 Alexandre Julliard
|
|
|
|
* Copyright 1997 Morten Welinder
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2003-12-07 12:59:34 +00:00
|
|
|
/* INCLUDES ******************************************************************/
|
2005-06-29 07:09:25 +00:00
|
|
|
|
2004-05-10 17:07:20 +00:00
|
|
|
#include <w32k.h>
|
2003-12-07 12:59:34 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
InitAcceleratorImpl(VOID)
|
|
|
|
{
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
CleanupAcceleratorImpl(VOID)
|
|
|
|
{
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
STDCALL
|
|
|
|
NtUserCopyAcceleratorTable(
|
|
|
|
HACCEL Table,
|
|
|
|
LPACCEL Entries,
|
|
|
|
int EntriesCount)
|
|
|
|
{
|
2003-12-07 14:21:00 +00:00
|
|
|
PWINSTATION_OBJECT WindowStation;
|
|
|
|
PACCELERATOR_TABLE AcceleratorTable;
|
|
|
|
NTSTATUS Status;
|
|
|
|
int Ret;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-07 14:21:00 +00:00
|
|
|
Status = IntValidateWindowStationHandle(NtUserGetProcessWindowStation(),
|
|
|
|
UserMode,
|
|
|
|
0,
|
|
|
|
&WindowStation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(STATUS_ACCESS_DENIED);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-07 14:21:00 +00:00
|
|
|
Status = ObmReferenceObjectByHandle(WindowStation->HandleTable,
|
|
|
|
Table,
|
|
|
|
otAcceleratorTable,
|
|
|
|
(PVOID*)&AcceleratorTable);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-07 14:21:00 +00:00
|
|
|
if(Entries)
|
|
|
|
{
|
2003-12-07 17:22:13 +00:00
|
|
|
Ret = min(EntriesCount, AcceleratorTable->Count);
|
2003-12-07 14:21:00 +00:00
|
|
|
Status = MmCopyToCaller(Entries, AcceleratorTable->Table, Ret * sizeof(ACCEL));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ObmDereferenceObject(AcceleratorTable);
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Ret = AcceleratorTable->Count;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-07 14:21:00 +00:00
|
|
|
ObmDereferenceObject(AcceleratorTable);
|
|
|
|
ObDereferenceObject(WindowStation);
|
2003-12-07 12:59:34 +00:00
|
|
|
|
2003-12-07 14:21:00 +00:00
|
|
|
return Ret;
|
2003-12-07 12:59:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HACCEL
|
|
|
|
STDCALL
|
|
|
|
NtUserCreateAcceleratorTable(
|
|
|
|
LPACCEL Entries,
|
|
|
|
SIZE_T EntriesCount)
|
|
|
|
{
|
|
|
|
PWINSTATION_OBJECT WindowStation;
|
|
|
|
PACCELERATOR_TABLE AcceleratorTable;
|
|
|
|
NTSTATUS Status;
|
|
|
|
HACCEL Handle;
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d)\n",
|
2003-12-07 12:59:34 +00:00
|
|
|
Entries, EntriesCount);
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(NtUserGetProcessWindowStation(),
|
|
|
|
UserMode,
|
|
|
|
0,
|
|
|
|
&WindowStation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(STATUS_ACCESS_DENIED);
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT1("E1\n");
|
2003-12-07 12:59:34 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
AcceleratorTable = ObmCreateObject(
|
|
|
|
WindowStation->HandleTable,
|
|
|
|
(PHANDLE)&Handle,
|
|
|
|
otAcceleratorTable,
|
|
|
|
sizeof(ACCELERATOR_TABLE));
|
|
|
|
if (AcceleratorTable == NULL)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
SetLastNtError(STATUS_NO_MEMORY);
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT1("E2\n");
|
2003-12-07 12:59:34 +00:00
|
|
|
return (HACCEL) 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
AcceleratorTable->Count = EntriesCount;
|
|
|
|
if (AcceleratorTable->Count > 0)
|
|
|
|
{
|
2004-02-19 21:12:11 +00:00
|
|
|
AcceleratorTable->Table = ExAllocatePoolWithTag(PagedPool, EntriesCount * sizeof(ACCEL), TAG_ACCEL);
|
2003-12-07 12:59:34 +00:00
|
|
|
if (AcceleratorTable->Table == NULL)
|
|
|
|
{
|
|
|
|
ObmCloseHandle(WindowStation->HandleTable, Handle);
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
SetLastNtError(Status);
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT1("E3\n");
|
2003-12-07 12:59:34 +00:00
|
|
|
return (HACCEL) 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = MmCopyFromCaller(AcceleratorTable->Table, Entries, EntriesCount * sizeof(ACCEL));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ExFreePool(AcceleratorTable->Table);
|
|
|
|
ObmCloseHandle(WindowStation->HandleTable, Handle);
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
SetLastNtError(Status);
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT1("E4\n");
|
2003-12-07 12:59:34 +00:00
|
|
|
return (HACCEL) 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
|
|
|
|
/* FIXME: Save HandleTable in a list somewhere so we can clean it up again */
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d) = %x end\n",
|
2003-12-07 12:59:34 +00:00
|
|
|
Entries, EntriesCount, Handle);
|
|
|
|
|
|
|
|
return (HACCEL) Handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
|
|
|
NtUserDestroyAcceleratorTable(
|
|
|
|
HACCEL Table)
|
|
|
|
{
|
|
|
|
PWINSTATION_OBJECT WindowStation;
|
|
|
|
PACCELERATOR_TABLE AcceleratorTable;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* FIXME: If the handle table is from a call to LoadAcceleratorTable, decrement it's
|
|
|
|
usage count (and return TRUE).
|
|
|
|
FIXME: Destroy only tables created using CreateAcceleratorTable.
|
|
|
|
*/
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("NtUserDestroyAcceleratorTable(Table %x)\n",
|
2003-12-07 12:59:34 +00:00
|
|
|
Table);
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(NtUserGetProcessWindowStation(),
|
|
|
|
UserMode,
|
|
|
|
0,
|
|
|
|
&WindowStation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(STATUS_ACCESS_DENIED);
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT1("E1\n");
|
2003-12-07 12:59:34 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ObmReferenceObjectByHandle(WindowStation->HandleTable,
|
|
|
|
Table,
|
|
|
|
otAcceleratorTable,
|
|
|
|
(PVOID*)&AcceleratorTable);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2003-12-07 16:54:44 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
2003-12-07 12:59:34 +00:00
|
|
|
ObDereferenceObject(WindowStation);
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT1("E2\n");
|
2003-12-07 12:59:34 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-12-07 16:54:44 +00:00
|
|
|
ObmCloseHandle(WindowStation->HandleTable, Table);
|
|
|
|
|
2003-12-07 12:59:34 +00:00
|
|
|
if (AcceleratorTable->Table != NULL)
|
|
|
|
{
|
|
|
|
ExFreePool(AcceleratorTable->Table);
|
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("NtUserDestroyAcceleratorTable(Table %x)\n",
|
2003-12-07 12:59:34 +00:00
|
|
|
Table);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2003-12-07 16:54:44 +00:00
|
|
|
static BOOLEAN
|
|
|
|
IntTranslateAccelerator(HWND hWnd,
|
|
|
|
UINT message,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam,
|
|
|
|
BYTE fVirt,
|
|
|
|
WORD key,
|
|
|
|
WORD cmd)
|
|
|
|
{
|
|
|
|
UINT mesg = 0;
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("IntTranslateAccelerator(hWnd %x, message %x, wParam %x, lParam %x, fVirt %d, key %x, cmd %x)\n",
|
2003-12-07 16:54:44 +00:00
|
|
|
hWnd, message, wParam, lParam, fVirt, key, cmd);
|
|
|
|
|
|
|
|
if (wParam != key)
|
|
|
|
{
|
2003-12-29 23:28:46 +00:00
|
|
|
DPRINT("T0\n");
|
2003-12-07 16:54:44 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (message == WM_CHAR)
|
|
|
|
{
|
|
|
|
if (!(fVirt & FALT) && !(fVirt & FVIRTKEY))
|
|
|
|
{
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("found accel for WM_CHAR: ('%c')\n", wParam & 0xff);
|
2003-12-07 16:54:44 +00:00
|
|
|
goto found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((fVirt & FVIRTKEY) > 0)
|
|
|
|
{
|
|
|
|
INT mask = 0;
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("found accel for virt_key %04x (scan %04x)\n",
|
2003-12-07 16:54:44 +00:00
|
|
|
wParam, 0xff & HIWORD(lParam));
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("NtUserGetKeyState(VK_SHIFT) = 0x%x\n",
|
2003-12-07 16:54:44 +00:00
|
|
|
NtUserGetKeyState(VK_SHIFT));
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("NtUserGetKeyState(VK_CONTROL) = 0x%x\n",
|
2003-12-07 16:54:44 +00:00
|
|
|
NtUserGetKeyState(VK_CONTROL));
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("NtUserGetKeyState(VK_MENU) = 0x%x\n",
|
2003-12-07 16:54:44 +00:00
|
|
|
NtUserGetKeyState(VK_MENU));
|
|
|
|
|
|
|
|
if (NtUserGetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
|
|
|
|
if (NtUserGetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
|
|
|
|
if (NtUserGetKeyState(VK_MENU) & 0x8000) mask |= FALT;
|
|
|
|
if (mask == (fVirt & (FSHIFT | FCONTROL | FALT))) goto found;
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("but incorrect SHIFT/CTRL/ALT-state\n");
|
2003-12-07 16:54:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(lParam & 0x01000000)) /* no special_key */
|
|
|
|
{
|
|
|
|
if ((fVirt & FALT) && (lParam & 0x20000000))
|
|
|
|
{ /* ^^ ALT pressed */
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("found accel for Alt-%c\n", wParam & 0xff);
|
2003-12-07 16:54:44 +00:00
|
|
|
goto found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("IntTranslateAccelerator(hWnd %x, message %x, wParam %x, lParam %x, fVirt %d, key %x, cmd %x) = FALSE\n",
|
2003-12-07 16:54:44 +00:00
|
|
|
hWnd, message, wParam, lParam, fVirt, key, cmd);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
found:
|
|
|
|
if (message == WM_KEYUP || message == WM_SYSKEYUP)
|
|
|
|
mesg = 1;
|
|
|
|
else if (IntGetCaptureWindow())
|
|
|
|
mesg = 2;
|
|
|
|
else if (!IntIsWindowVisible(hWnd)) /* FIXME: WINE IsWindowEnabled == IntIsWindowVisible? */
|
|
|
|
mesg = 3;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
HMENU hMenu, hSubMenu, hSysMenu;
|
|
|
|
UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos;
|
|
|
|
|
|
|
|
hMenu = (NtUserGetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? 0 : GetMenu(hWnd);
|
|
|
|
hSysMenu = get_win_sys_menu(hWnd);
|
|
|
|
|
|
|
|
/* find menu item and ask application to initialize it */
|
|
|
|
/* 1. in the system menu */
|
|
|
|
hSubMenu = hSysMenu;
|
|
|
|
nPos = cmd;
|
|
|
|
if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
|
|
|
|
{
|
2003-12-26 22:52:12 +00:00
|
|
|
IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L);
|
2003-12-07 16:54:44 +00:00
|
|
|
if(hSubMenu != hSysMenu)
|
|
|
|
{
|
|
|
|
nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu);
|
|
|
|
TRACE_(accel)("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos);
|
2003-12-26 22:52:12 +00:00
|
|
|
IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE));
|
2003-12-07 16:54:44 +00:00
|
|
|
}
|
|
|
|
uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND);
|
|
|
|
}
|
|
|
|
else /* 2. in the window's menu */
|
|
|
|
{
|
|
|
|
hSubMenu = hMenu;
|
|
|
|
nPos = cmd;
|
|
|
|
if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
|
|
|
|
{
|
2003-12-26 22:52:12 +00:00
|
|
|
IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L);
|
2003-12-07 16:54:44 +00:00
|
|
|
if(hSubMenu != hMenu)
|
|
|
|
{
|
|
|
|
nPos = MENU_FindSubMenu(&hMenu, hSubMenu);
|
|
|
|
TRACE_(accel)("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos);
|
2003-12-26 22:52:12 +00:00
|
|
|
IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE));
|
2003-12-07 16:54:44 +00:00
|
|
|
}
|
|
|
|
uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uSysStat != (UINT)-1)
|
|
|
|
{
|
|
|
|
if (uSysStat & (MF_DISABLED|MF_GRAYED))
|
|
|
|
mesg=4;
|
|
|
|
else
|
|
|
|
mesg=WM_SYSCOMMAND;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (uStat != (UINT)-1)
|
|
|
|
{
|
|
|
|
if (IsIconic(hWnd))
|
|
|
|
mesg=5;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (uStat & (MF_DISABLED|MF_GRAYED))
|
|
|
|
mesg=6;
|
|
|
|
else
|
|
|
|
mesg=WM_COMMAND;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mesg=WM_COMMAND;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
DPRINT1("menu search not implemented");
|
|
|
|
mesg = WM_COMMAND;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mesg == WM_COMMAND)
|
|
|
|
{
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT(", sending WM_COMMAND, wParam=%0x\n", 0x10000 | cmd);
|
2003-12-26 22:52:12 +00:00
|
|
|
IntSendMessage(hWnd, mesg, 0x10000 | cmd, 0L);
|
2003-12-07 16:54:44 +00:00
|
|
|
}
|
|
|
|
else if (mesg == WM_SYSCOMMAND)
|
|
|
|
{
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT(", sending WM_SYSCOMMAND, wParam=%0x\n", cmd);
|
2003-12-26 22:52:12 +00:00
|
|
|
IntSendMessage(hWnd, mesg, cmd, 0x00010000L);
|
2003-12-07 16:54:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* some reasons for NOT sending the WM_{SYS}COMMAND message:
|
|
|
|
* #0: unknown (please report!)
|
|
|
|
* #1: for WM_KEYUP,WM_SYSKEYUP
|
|
|
|
* #2: mouse is captured
|
|
|
|
* #3: window is disabled
|
|
|
|
* #4: it's a disabled system menu option
|
|
|
|
* #5: it's a menu option, but window is iconic
|
|
|
|
* #6: it's a menu option, but disabled
|
|
|
|
*/
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT(", but won't send WM_{SYS}COMMAND, reason is #%d\n", mesg);
|
2003-12-07 16:54:44 +00:00
|
|
|
if (mesg == 0)
|
|
|
|
{
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT1(" unknown reason - please report!");
|
2003-12-07 16:54:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-12-14 11:36:43 +00:00
|
|
|
DPRINT("IntTranslateAccelerator(hWnd %x, message %x, wParam %x, lParam %x, fVirt %d, key %x, cmd %x) = TRUE\n",
|
2003-12-07 16:54:44 +00:00
|
|
|
hWnd, message, wParam, lParam, fVirt, key, cmd);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2003-12-07 12:59:34 +00:00
|
|
|
int
|
|
|
|
STDCALL
|
|
|
|
NtUserTranslateAccelerator(
|
2004-11-13 01:52:56 +00:00
|
|
|
HWND hWnd,
|
2003-12-07 12:59:34 +00:00
|
|
|
HACCEL Table,
|
|
|
|
LPMSG Message)
|
|
|
|
{
|
2003-12-07 16:54:44 +00:00
|
|
|
PWINSTATION_OBJECT WindowStation;
|
|
|
|
PACCELERATOR_TABLE AcceleratorTable;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG i;
|
|
|
|
|
2004-11-13 01:52:56 +00:00
|
|
|
DPRINT("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p)\n",
|
|
|
|
hWnd, Table, Message);
|
|
|
|
|
|
|
|
if (hWnd == NULL)
|
|
|
|
return 0;
|
2003-12-07 16:54:44 +00:00
|
|
|
|
|
|
|
if (Message == NULL)
|
|
|
|
{
|
|
|
|
SetLastNtError(STATUS_INVALID_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Table == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((Message->message != WM_KEYDOWN) &&
|
|
|
|
(Message->message != WM_SYSKEYDOWN) &&
|
2004-11-13 01:52:56 +00:00
|
|
|
(Message->message != WM_SYSCHAR) &&
|
2003-12-07 16:54:44 +00:00
|
|
|
(Message->message != WM_CHAR))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(NtUserGetProcessWindowStation(),
|
|
|
|
UserMode,
|
|
|
|
0,
|
|
|
|
&WindowStation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(STATUS_ACCESS_DENIED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ObmReferenceObjectByHandle(WindowStation->HandleTable,
|
|
|
|
Table,
|
|
|
|
otAcceleratorTable,
|
|
|
|
(PVOID*)&AcceleratorTable);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Associate AcceleratorTable with the current thread */
|
|
|
|
|
|
|
|
for (i = 0; i < AcceleratorTable->Count; i++)
|
|
|
|
{
|
2004-11-13 01:52:56 +00:00
|
|
|
if (IntTranslateAccelerator(hWnd, Message->message, Message->wParam, Message->lParam,
|
2003-12-07 16:54:44 +00:00
|
|
|
AcceleratorTable->Table[i].fVirt, AcceleratorTable->Table[i].key,
|
|
|
|
AcceleratorTable->Table[i].cmd))
|
2004-02-02 15:16:53 +00:00
|
|
|
{
|
|
|
|
ObDereferenceObject(WindowStation);
|
2004-11-13 01:52:56 +00:00
|
|
|
DPRINT("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i end\n",
|
|
|
|
hWnd, Table, Message, 1);
|
2003-12-07 16:54:44 +00:00
|
|
|
return 1;
|
2004-02-02 15:16:53 +00:00
|
|
|
}
|
|
|
|
if (((AcceleratorTable->Table[i].fVirt & 0x80) > 0))
|
|
|
|
{
|
2003-12-07 16:54:44 +00:00
|
|
|
break;
|
2004-02-02 15:16:53 +00:00
|
|
|
}
|
2003-12-07 16:54:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(WindowStation);
|
|
|
|
|
2004-11-13 01:52:56 +00:00
|
|
|
DPRINT("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i end\n",
|
|
|
|
hWnd, Table, Message, 0);
|
2003-12-07 12:59:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|