Ignore:
Timestamp:
Feb 21, 2000, 3:25:23 PM (26 years ago)
Author:
sandervl
Message:

Ported Wine accelerator apis

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/winaccel.cpp

    r2803 r2846  
    1 /* $Id: winaccel.cpp,v 1.6 2000-02-16 14:28:25 sandervl Exp $ */
     1/* $Id: winaccel.cpp,v 1.7 2000-02-21 14:25:23 sandervl Exp $ */
    22/*
    33 * Win32 accelerator key functions for OS/2
    44 *
    5  * Copyright 1999 Bart van Leeuwen
    6  *
     5 * Based on Wine: (windows\input.c; loader\resource.c) (20000130)
     6 * Copyright 1993 Bob Amstadt
     7 * Copyright 1996 Albrecht Kleine
     8 * Copyright 1997 David Faure
     9 * Copyright 1998 Morten Welinder
     10 * Copyright 1998 Ulrich Weigand
     11 * Copyright 1993 Robert J. Amstadt
     12 * Copyright 1995 Alexandre Julliard
    713 *
    814 * Project Odin Software License can be found in LICENSE.TXT
     
    1117#include <os2win.h>
    1218#include <misc.h>
    13 #include <win32wbase.h>
    14 #include <winaccel.h>
    15 
    16 #define DBG_LOCALLOG    DBG_winaccel
     19#include <heapstring.h>
     20#include "win32wbase.h"
     21#include "win32wmdiclient.h"
     22#include <win\winnls.h>
     23
     24#define DBG_LOCALLOG    DBG_winaccel
    1725#include "dbglocal.h"
    1826
    19 /*****************************************************************************
    20  * Name      : HACCEL WIN32API LoadAcceleratorsA
    21  * Purpose   : Load accelerator resource and return handle to it
    22  * Parameters: HINSTANCE hinst, LPCSTR lpszAcc
    23  * Variables :
    24  * Result    : Global Handle of resource
    25  * Remark    : see code
    26  * Status    : OK
    27  *
    28  * Author    : Bart van Leeuwen  [Sun, 1998/12/26 17:01]
    29  *****************************************************************************/
    30 HACCEL WIN32API LoadAcceleratorsA(HINSTANCE hinst, LPCSTR lpszAcc)
    31 {
    32  HACCEL rc;
    33 
    34     rc = (HACCEL)FindResourceA(hinst, lpszAcc, RT_ACCELERATORA);
    35 
    36     dprintf(("LoadAcceleratorsA returned %d\n", rc));
    37     return(rc);
    38 }
    39 /*****************************************************************************
    40  * Name      : HACCEL WIN32API LoadAcceleratorsW
    41  * Purpose   : Load accelerator resource and return handle to it
    42  * Parameters: HINSTANCE hinst, LPCSTR lpszAcc
    43  * Variables :
    44  * Result    : Global Handle of resource
    45  * Remark    : see code
    46  * Status    : OK
    47  *
    48  * Author    : Bart van Leeuwen  [Sun, 1998/12/26 17:01]
    49  *****************************************************************************/
    50 
    51 HACCEL WIN32API LoadAcceleratorsW(HINSTANCE hinst, LPCWSTR lpszAccel)
    52 {
    53  HACCEL rc;
    54 
    55     rc = (HACCEL)FindResourceW(hinst, lpszAccel, RT_ACCELERATORW);
    56 
    57 
    58     dprintf(("LoadAcceleratorsW returned %d\n", rc));
    59     return(rc);
    60 }
    61 //******************************************************************************
    62 //******************************************************************************
    63 BOOL WIN32API DestroyAcceleratorTable( HACCEL haccel)
    64 {
    65  Win32Resource *winres;
    66 
    67     dprintf(("DestroyAcceleratorTable %x\n", haccel));
    68     winres = (Win32Resource *)haccel;
    69     delete winres;
    70     return TRUE;
     27/**********************************************************************
     28 *           KBD_translate_accelerator
     29 *
     30 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP  -messages
     31 */
     32static BOOL KBD_translate_accelerator(HWND hWnd,LPMSG msg,
     33                                      BYTE fVirt,WORD key,WORD cmd)
     34{
     35    BOOL sendmsg = FALSE;
     36
     37    if(msg->wParam == key)
     38    {
     39        if (msg->message == WM_CHAR) {
     40            if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
     41            {
     42                dprintf(("TranslateAccelerator: found accel for WM_CHAR: ('%c')\n", msg->wParam&0xff));
     43                sendmsg=TRUE;
     44            }
     45        }
     46        else
     47        {
     48            if(fVirt & FVIRTKEY) {
     49                INT mask = 0;
     50                if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
     51                if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
     52                if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT;
     53
     54                if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
     55                        sendmsg=TRUE;
     56                else    dprintf(("TranslateAccelerator: but incorrect SHIFT/CTRL/ALT-state %x != %x", mask, fVirt));
     57            }
     58            else
     59            {
     60                if (!(msg->lParam & 0x01000000))  /* no special_key */
     61                {
     62                    if ((fVirt & FALT) && (msg->lParam & 0x20000000))
     63                    {                                                   /* ^^ ALT pressed */
     64                        dprintf(("TranslateAccelerator: found accel for Alt-%c\n", msg->wParam&0xff));
     65                        sendmsg=TRUE;
     66                    }
     67                }
     68            }
     69        }
     70
     71        if (sendmsg)      /* found an accelerator, but send a message... ? */
     72        {
     73            INT  iSysStat,iStat,mesg=0;
     74            HMENU hMenu;
     75
     76            if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) {
     77                mesg=1;
     78            }
     79            else
     80                if (GetCapture())
     81                    mesg=2;
     82                else
     83                if (!IsWindowEnabled(hWnd))
     84                    mesg=3;
     85                else
     86                {
     87                   Win32BaseWindow *window;
     88
     89                    window = Win32BaseWindow::GetWindowFromHandle(hWnd);
     90                    if(!window) {
     91                        return FALSE; //should never happen! (already checked)
     92                    }
     93
     94                    hMenu = (window->getStyle() & WS_CHILD) ? 0 : (HMENU)window->GetMenu();
     95
     96                    iSysStat = (window->GetSysMenu()) ? GetMenuState(GetSubMenu(window->GetSysMenu(), 0),
     97                                                                     cmd, MF_BYCOMMAND) : -1 ;
     98                    iStat = (hMenu) ? GetMenuState(hMenu, cmd, MF_BYCOMMAND) : -1 ;
     99
     100                    if (iSysStat!=-1)
     101                    {
     102                        if (iSysStat & (MF_DISABLED|MF_GRAYED))
     103                            mesg=4;
     104                        else
     105                            mesg=WM_SYSCOMMAND;
     106                    }
     107                    else
     108                    {
     109                        if (iStat!=-1)
     110                        {
     111                            if (IsIconic(hWnd)) {
     112                                mesg=5;
     113                            }
     114                            else
     115                            {
     116                                if (iStat & (MF_DISABLED|MF_GRAYED))
     117                                    mesg=6;
     118                                else
     119                                    mesg=WM_COMMAND;
     120                            }
     121                        }
     122                        else
     123                            mesg=WM_COMMAND;
     124                    }
     125                }
     126                if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
     127                {
     128                    SendMessageA(hWnd, mesg, cmd, 0x00010000L);
     129                }
     130                else
     131                {
     132                    /*  some reasons for NOT sending the WM_{SYS}COMMAND message:
     133                     *   #0: unknown (please report!)
     134                     *   #1: for WM_KEYUP,WM_SYSKEYUP
     135                     *   #2: mouse is captured
     136                     *   #3: window is disabled
     137                     *   #4: it's a disabled system menu option
     138                     *   #5: it's a menu option, but window is iconic
     139                     *   #6: it's a menu option, but disabled
     140                     */
     141                    if(mesg==0)
     142                            dprintf(("ERROR: unknown reason - please report!"));
     143                    else    dprintf(("but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg));
     144
     145                }
     146                return TRUE;
     147            }
     148            dprintf(("TranslateAccelerator: not match for %x %x %x", fVirt, key, cmd));
     149    }
     150    return FALSE;
    71151}
    72152/*****************************************************************************
     
    79159 * Remark    : if a accelerator is found it is not neccesarely executed
    80160 *             depends on window stat
    81  * Status    : finished but not fully tested
    82  *
    83  * Author    : Bart van Leeuwen  [Sun, 1998/12/26 17:01]
     161 *
    84162 *****************************************************************************/
    85 int WIN32API TranslateAcceleratorA(HWND hwnd, HACCEL haccel, LPMSG lpmsg)
    86 {
    87  Win32BaseWindow *window,*parentWindow,*childWindow;
    88  LPWINACCEL lpAccelTbl;
    89  WINACCEL tmpAccel;
    90  HACCEL temp2;
    91  HGLOBAL GlobHandle;
    92  HWND hwndMenu,parent,child,msgHwnd;
    93  int i,keyMask;
    94  INT16 menuStat;
    95  BOOL sendMessage;
    96 
    97 
    98     //bvl: check if messages come from keyboard
    99     if ((lpmsg->message != WM_KEYDOWN &&
    100          lpmsg->message != WM_SYSKEYDOWN))
    101          {
    102            //dprintf(("TranslateAcceleratorA called by invalid message"));
    103            SetLastError(ERROR_SUCCESS);
    104            return FALSE;
    105          }
    106 
    107     window = Win32BaseWindow::GetWindowFromHandle(lpmsg->hwnd);
    108 
    109     if(!window)
    110     {
    111       dprintf(("TranslateAcceleratorA, window %x not found", hwnd));
    112       SetLastError(ERROR_INVALID_WINDOW_HANDLE);
    113       return FALSE;
    114     }
    115 
    116     //bvl: Get memory pointer here
    117     GlobHandle = LoadResource(NULL,haccel);
    118     lpAccelTbl = (LPWINACCEL) LockResource(GlobHandle);
    119 
    120     keyMask=0;
    121     if(GetKeyState(VK_SHIFT) & 0x8000) keyMask |= FSHIFT;
    122     if(GetKeyState(VK_CONTROL) & 0x8000) keyMask |= FCONTROL;
    123     if(GetKeyState(VK_MENU) & 0x8000) keyMask |= FALT;
    124 
    125     i=0;
     163INT WINAPI TranslateAcceleratorA(HWND hWnd, HACCEL hAccel, LPMSG msg)
     164{
     165    /* YES, Accel16! */
     166    LPACCEL lpAccelTbl;
     167    Win32BaseWindow *window;
     168    int i;
     169
     170    SetLastError(ERROR_SUCCESS);
     171    if (msg == NULL)
     172    {
     173          dprintf(("TranslateAcceleratorAmsg null; should hang here to be win compatible"));
     174          SetLastError(ERROR_INVALID_PARAMETER);
     175          return 0;
     176    }
     177    if (!hAccel || !(lpAccelTbl = (LPACCEL)GlobalLock(hAccel)))
     178    {
     179          dprintf(("TranslateAcceleratorA: invalid accel handle=%x", hAccel));
     180          SetLastError(ERROR_INVALID_PARAMETER);
     181          return 0;
     182    }
     183    window = Win32BaseWindow::GetWindowFromHandle(hWnd);
     184    if(!window) {
     185          dprintf(("TranslateAccelerator, window %x not found", hWnd));
     186          SetLastError(ERROR_INVALID_WINDOW_HANDLE);
     187          return 0;
     188    }
     189    if ((msg->message != WM_KEYDOWN &&
     190         msg->message != WM_KEYUP &&
     191         msg->message != WM_SYSKEYDOWN &&
     192         msg->message != WM_SYSKEYUP &&
     193         msg->message != WM_CHAR))
     194    {
     195          return 0;
     196    }
     197
     198/*    TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x,"
     199      "msg->hwnd=%04x, msg->message=%04x, wParam=%08x, lParam=%lx\n",
     200      hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); */
     201
     202    i = 0;
    126203    do
    127204    {
    128        if ((lpAccelTbl[i].key == lpmsg->wParam)&&(keyMask == (lpAccelTbl[i].fVirt &
    129            (FSHIFT | FCONTROL | FALT))))
     205        if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
     206                                      lpAccelTbl[i].key,lpAccelTbl[i].cmd))
    130207        {
    131          //bvl: Accelerator found
    132          dprintf(("Accelerator found for command: %X",lpAccelTbl[i].cmd));
    133          //bvl: this is not right, check control and win stat
    134          // SendMessageA(hwnd,WM_COMMAND,lpAccelTbl[i].cmd,0x00010000L);
    135 
    136          sendMessage = FALSE;
    137 
    138          if (window->isFrameWindow())
    139            {
    140             if ( !window->IsIconic() )
    141              {
    142               //bvl: this is a frame window so just use that menuhandle
    143               hwndMenu = window->GetMenu();
    144               if ( hwndMenu == NULL )
    145                {
    146                 //bvl: window does not have a menu so command isn't a menu
    147                 dprintf(("framenomenu"));
    148                 sendMessage = TRUE;
    149                }
    150                else
    151                {
    152                 //bvl: get menuitem  status
    153                 menuStat = GetMenuState(hwndMenu,lpAccelTbl[i++].cmd,MF_BYCOMMAND);
    154                 //bvl: -1 means no menu Item
    155                 if( !menuStat == -1)
    156                  {
    157                   if( menuStat  & !(MF_DISABLED|MF_GRAYED) )
    158                    {
    159                      //bvl: its a menu item and its enabled
    160                      dprintf(("framemenu"));
    161                      sendMessage = TRUE;
    162                    }
    163                    else
    164                    {
    165                     //bvl: its a menu Item but disabled
    166                     sendMessage = FALSE;
    167                    }
    168                  }
    169                  else
    170                  {
    171                   //bvl: the message is probably not a menu msg so process it
    172                   dprintf(("framemenunoitem"));
    173                   sendMessage = TRUE;
    174                  }
    175                }
    176              }
    177            }
    178            else
    179            {
    180               //bvl: the message is probably not a menu msg so process it
    181               dprintf(("noframe"));
    182               sendMessage = TRUE;
    183            }
    184 
    185          if ( sendMessage )
    186          {
    187           //bvl: previous checks indicated that command can be send.
    188           SendMessageA(hwnd,WM_COMMAND,lpAccelTbl[i].cmd,0x00010000L);
    189           return TRUE;
    190 
    191          }
    192         }
    193 
    194     } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
    195 
    196     SetLastError(ERROR_SUCCESS);
    197     return FALSE;
    198 }
    199 /*****************************************************************************
    200  * Name      : int WIN32API TranslateAcceleratorA
    201  * Remark    : See TranslateAcceleratorA
    202  * Status    : finished but not fully tested
    203  *
    204  * Author    : Bart van Leeuwen  [Sun, 1998/12/26 17:01]
    205  *****************************************************************************/
    206 
    207 int WIN32API TranslateAcceleratorW( HWND hwnd, HACCEL hAccel, LPMSG lpMsg)
    208 {
    209     return TranslateAcceleratorA(hwnd, hAccel, lpMsg);
     208            return 1;
     209        }
     210    }
     211    while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
     212
     213//    WARN_(accel)("couldn't translate accelerator key\n");
     214    return 0;
    210215}
    211216//******************************************************************************
    212217//******************************************************************************
    213 BOOL WIN32API TranslateMDISysAccel( HWND arg1, LPMSG  arg2)
    214 {
    215 #ifdef DEBUG
    216 ////    WriteLog("USER32:  TranslateMDISysAccel\n");
    217 #endif
    218     return O32_TranslateMDISysAccel(arg1, arg2);
    219 }
    220 //******************************************************************************
    221 //******************************************************************************
    222 HACCEL WIN32API CreateAcceleratorTableA( LPACCEL arg1, int  arg2)
    223 {
    224 #ifdef DEBUG
    225     WriteLog("USER32:  CreateAcceleratorTableA\n");
    226 #endif
    227     return O32_CreateAcceleratorTable(arg1, arg2);
    228 }
    229 //******************************************************************************
    230 //******************************************************************************
    231 HACCEL WIN32API CreateAcceleratorTableW( LPACCEL arg1, int  arg2)
    232 {
    233 #ifdef DEBUG
    234     WriteLog("USER32:  CreateAcceleratorTableW\n");
    235 #endif
    236     // NOTE: This will not work as is (needs UNICODE support)
    237     return O32_CreateAcceleratorTable(arg1, arg2);
    238 }
    239 //******************************************************************************
    240 //******************************************************************************
    241 int WIN32API CopyAcceleratorTableA(HACCEL hAccelSrc, LPACCEL lpAccelDest,
    242                       int cAccelEntries)
    243 {
    244 #ifdef DEBUG
    245   WriteLog("USER32:  CopyAcceleratorTableA, not implemented\n");
    246 #endif
    247   return(0);
    248 }
    249 //******************************************************************************
    250 //TODO:
    251 //******************************************************************************
    252 int WIN32API CopyAcceleratorTableW(HACCEL hAccelSrc, LPACCEL lpAccelDest,
    253                       int cAccelEntries)
    254 {
    255 #ifdef DEBUG
    256   WriteLog("USER32:  CopyAcceleratorTableW, not implemented\n");
    257 #endif
    258   return(0);
    259 }
    260 //******************************************************************************
    261 //******************************************************************************
     218BOOL WIN32API TranslateMDISysAccel(HWND hwndClient, LPMSG msg)
     219{
     220    SetLastError(ERROR_SUCCESS);
     221
     222    if(IsWindow(hwndClient) && (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN))
     223    {
     224        Win32MDIClientWindow *clientWnd;
     225        Win32MDIChildWindow  *mdichild;
     226        HWND                  hwndChild;
     227
     228        clientWnd = (Win32MDIClientWindow *)Win32BaseWindow::GetWindowFromHandle(hwndClient);
     229        if(!clientWnd) {
     230            dprintf(("TranslateMDISysAccel window %x not found", hwndClient));
     231            SetLastError(ERROR_INVALID_WINDOW_HANDLE);
     232            return FALSE;
     233        }
     234
     235        mdichild = clientWnd->getActiveChild();
     236        if(!mdichild) {
     237            dprintf(("TranslateMDISysAccel NO active MDI child!!"));
     238            return FALSE;
     239        }
     240        hwndChild = mdichild->getWindowHandle();
     241
     242        if(IsWindow(hwndChild) && !(GetWindowLongA(hwndChild,GWL_STYLE) & WS_DISABLED) )
     243            {
     244            WPARAM      wParam = 0;
     245
     246                /* translate if the Ctrl key is down and Alt not. */
     247                if( (GetKeyState(VK_CONTROL) & 0x8000) &&
     248                    !(GetKeyState(VK_MENU) & 0x8000))
     249                {
     250                        switch( msg->wParam )
     251                        {
     252                        case VK_F6:
     253                        case VK_TAB:
     254                                wParam = ( GetKeyState(VK_SHIFT) & 0x8000 )
     255                                                ? SC_NEXTWINDOW : SC_PREVWINDOW;
     256                                break;
     257                        case VK_F4:
     258                        case VK_RBUTTON:
     259                                wParam = SC_CLOSE;
     260                                break;
     261                        default:
     262                                return 0;
     263                        }
     264                    SendMessageA(hwndChild, WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam);
     265                    return 1;
     266                }
     267            }
     268    }
     269    return 0; /* failure */
     270}
     271/**********************************************************************
     272 *                      LoadAccelerators32W     [USER.177]
     273 * The image layout seems to look like this (not 100% sure):
     274 * 00:  BYTE    type            type of accelerator
     275 * 01:  BYTE    pad             (to WORD boundary)
     276 * 02:  WORD    event
     277 * 04:  WORD    IDval           
     278 * 06:  WORD    pad             (to DWORD boundary)
     279 */
     280HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance,LPCWSTR lpTableName)
     281{
     282    HRSRC hRsrc;
     283    HACCEL hMem,hRetval=0;
     284    DWORD size;
     285
     286    if (!(hRsrc = FindResourceW( instance, lpTableName, RT_ACCELERATORW )))
     287    {
     288        dprintf(("LoadAcceleratorsW couldn't find accelerator table resource %x %x", instance, lpTableName));
     289        return 0;
     290    }
     291    else {
     292        hMem = LoadResource( instance, hRsrc );
     293        size = SizeofResource( instance, hRsrc );
     294        if(size >= sizeof(PE_ACCEL))
     295        {
     296                LPPE_ACCEL accel_table = (LPPE_ACCEL) hMem;
     297                LPACCEL accel;
     298                int i,nrofaccells = size/sizeof(PE_ACCEL);
     299
     300                hRetval = GlobalAlloc(0,sizeof(ACCEL)*nrofaccells);
     301                accel   = (LPACCEL)GlobalLock(hRetval);
     302       
     303                for (i=0;i<nrofaccells;i++) {
     304                        accel[i].fVirt = accel_table[i].fVirt;
     305                        accel[i].key = accel_table[i].key;
     306                        accel[i].cmd = accel_table[i].cmd;
     307                }
     308                accel[i-1].fVirt |= 0x80;
     309        }
     310    }
     311    dprintf(("LoadAcceleratorsW returned %x %x %x\n", instance, lpTableName, hRetval));
     312    return hRetval;
     313}
     314
     315HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName)
     316{
     317        LPWSTR   uni;
     318        HACCEL result;
     319        if (HIWORD(lpTableName))
     320                uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
     321        else
     322                uni = (LPWSTR)lpTableName;
     323        result = LoadAcceleratorsW(instance,uni);
     324        if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
     325        return result;
     326}
     327
     328/**********************************************************************
     329 *             CopyAcceleratorTable32A   (USER32.58)
     330 */
     331INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT entries)
     332{
     333  return CopyAcceleratorTableW(src, dst, entries);
     334}
     335
     336/**********************************************************************
     337 *             CopyAcceleratorTable32W   (USER32.59)
     338 *
     339 * By mortene@pvv.org 980321
     340 */
     341INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst, INT entries)
     342{
     343  int i,xsize;
     344  LPACCEL accel = (LPACCEL)GlobalLock(src);
     345  BOOL done = FALSE;
     346
     347  /* Do parameter checking to avoid the explosions and the screaming
     348     as far as possible. */
     349  if((dst && (entries < 1)) || (src == (HACCEL)NULL) || !accel)
     350  {
     351        dprintf(("CopyAcceleratorTableW: Application sent invalid parameters (%p %p %d).\n", (LPVOID)src, (LPVOID)dst, entries));
     352        SetLastError(ERROR_INVALID_PARAMETER);
     353        return 0;
     354  }
     355  xsize = GlobalSize(src)/sizeof(ACCEL);
     356  if (xsize>entries) entries=xsize;
     357
     358  i=0;
     359  while(!done) {
     360    /* Spit out some debugging information. */
     361//    TRACE_(accel)("accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
     362//        i, accel[i].fVirt, accel[i].key, accel[i].cmd);
     363
     364    /* Copy data to the destination structure array (if dst == NULL,
     365       we're just supposed to count the number of entries). */
     366    if(dst) {
     367        dst[i].fVirt = accel[i].fVirt;
     368        dst[i].key = accel[i].key;
     369        dst[i].cmd = accel[i].cmd;
     370
     371        /* Check if we've reached the end of the application supplied
     372           accelerator table. */
     373        if(i+1 == entries) {
     374                /* Turn off the high order bit, just in case. */
     375                dst[i].fVirt &= 0x7f;
     376                done = TRUE;
     377        }
     378    }
     379
     380    /* The highest order bit seems to mark the end of the accelerator
     381       resource table, but not always. Use GlobalSize() check too. */
     382    if((accel[i].fVirt & 0x80) != 0) done = TRUE;
     383
     384    i++;
     385  }
     386
     387  return i;
     388}
     389
     390/*********************************************************************
     391 *                    CreateAcceleratorTable   (USER32.64)
     392 *
     393 * By mortene@pvv.org 980321
     394 */
     395HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT cEntries)
     396{
     397  HACCEL        hAccel;
     398  LPACCEL       accel;
     399  int           i;
     400
     401  /* Do parameter checking just in case someone's trying to be
     402     funny. */
     403  if(cEntries < 1) {
     404        dprintf(("CreateAcceleratorTableA: Application sent invalid parameters (%p %d).\n", lpaccel, cEntries));
     405        SetLastError(ERROR_INVALID_PARAMETER);
     406        return NULL;
     407  }
     408  dprintf(("FIXME: CreateAcceleratorTableA: should check that the accelerator descriptions are valid return NULL and SetLastError() if not"));
     409
     410  /* Allocate memory and copy the table. */
     411  hAccel = GlobalAlloc(0,cEntries*sizeof(ACCEL));
     412
     413  if(!hAccel) {
     414        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     415        return (HACCEL)NULL;
     416  }
     417  accel = (LPACCEL)GlobalLock(hAccel);
     418  for (i=0;i<cEntries;i++) {
     419            accel[i].fVirt = lpaccel[i].fVirt;
     420            accel[i].key = lpaccel[i].key;
     421            accel[i].cmd = lpaccel[i].cmd;
     422  }
     423  /* Set the end-of-table terminator. */
     424  accel[cEntries-1].fVirt |= 0x80;
     425
     426  dprintf(("CreateAcceleratorTableA %x %x returned %x\n", lpaccel, cEntries, hAccel));
     427  return hAccel;
     428}
     429
     430/*********************************************************************
     431 *                    CreateAcceleratorTableW   (USER32.64)
     432 *
     433 *
     434 */
     435HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT cEntries)
     436{
     437  HACCEL        hAccel;
     438  LPACCEL       accel;
     439  int           i;
     440  char          ckey;
     441
     442  /* Do parameter checking just in case someone's trying to be
     443     funny. */
     444  if(cEntries < 1) {
     445        dprintf(("CreateAcceleratorTableW: Application sent invalid parameters (%p %d).\n", lpaccel, cEntries));
     446        SetLastError(ERROR_INVALID_PARAMETER);
     447        return NULL;
     448  }
     449  dprintf(("FIXME: CreateAcceleratorTableW: should check that the accelerator descriptions are valid return NULL and SetLastError() if not"));
     450
     451  /* Allocate memory and copy the table. */
     452  hAccel = GlobalAlloc(0,cEntries*sizeof(ACCEL));
     453
     454  if(!hAccel) {
     455        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     456        return (HACCEL)NULL;
     457  }
     458  accel = (LPACCEL)GlobalLock(hAccel);
     459
     460  for (i=0;i<cEntries;i++) {
     461       accel[i].fVirt = lpaccel[i].fVirt;
     462       if( !(accel[i].fVirt & FVIRTKEY) ) {
     463            ckey = (char) lpaccel[i].key;
     464            MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &ckey, 1, &accel[i].key, 1);
     465       }
     466       else  accel[i].key = lpaccel[i].key;
     467       accel[i].cmd = lpaccel[i].cmd;
     468  }
     469
     470  /* Set the end-of-table terminator. */
     471  accel[cEntries-1].fVirt |= 0x80;
     472
     473  dprintf(("CreateAcceleratorTableW %x %x returned %x\n", lpaccel, cEntries, hAccel));
     474  return hAccel;
     475}
     476
     477/******************************************************************************
     478 * DestroyAcceleratorTable [USER32.130]
     479 * Destroys an accelerator table
     480 *
     481 * NOTES
     482 *    By mortene@pvv.org 980321
     483 *
     484 * PARAMS
     485 *    handle [I] Handle to accelerator table
     486 *
     487 * RETURNS STD
     488 */
     489BOOL WINAPI DestroyAcceleratorTable( HACCEL handle )
     490{
     491    return GlobalFree(handle);
     492}
     493
Note: See TracChangeset for help on using the changeset viewer.