00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <os2win.h>
00018 #include <misc.h>
00019 #include <heapstring.h>
00020 #include "win32wbase.h"
00021 #include <win\winnls.h>
00022
00023 #define DBG_LOCALLOG DBG_winaccel
00024 #include "dbglocal.h"
00025
00026
00027
00028
00029
00030
00031 static BOOL KBD_translate_accelerator(HWND hWnd,LPMSG msg,
00032 BYTE fVirt,WORD key,WORD cmd)
00033 {
00034 BOOL sendmsg = FALSE;
00035
00036 if(msg->wParam == key)
00037 {
00038 if (msg->message == WM_CHAR) {
00039 if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
00040 {
00041 dprintf(("TranslateAccelerator: found accel for WM_CHAR: ('%c')\n", msg->wParam&0xff));
00042 sendmsg=TRUE;
00043 }
00044 }
00045 else
00046 {
00047 if(fVirt & FVIRTKEY) {
00048 INT mask = 0;
00049 if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
00050 if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
00051 if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT;
00052
00053 if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
00054 sendmsg=TRUE;
00055 else dprintf(("TranslateAccelerator: but incorrect SHIFT/CTRL/ALT-state %x != %x", mask, fVirt));
00056 }
00057 else
00058 {
00059 if (!(msg->lParam & 0x01000000))
00060 {
00061 if ((fVirt & FALT) && (msg->lParam & 0x20000000))
00062 {
00063 dprintf(("TranslateAccelerator: found accel for Alt-%c\n", msg->wParam&0xff));
00064 sendmsg=TRUE;
00065 }
00066 }
00067 }
00068 }
00069
00070 if (sendmsg)
00071 {
00072 INT iSysStat,iStat,mesg=0;
00073 HMENU hMenu;
00074
00075 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) {
00076 mesg=1;
00077 }
00078 else
00079 if (GetCapture())
00080 mesg=2;
00081 else
00082 if (!IsWindowEnabled(hWnd))
00083 mesg=3;
00084 else
00085 {
00086 Win32BaseWindow *window;
00087
00088 window = Win32BaseWindow::GetWindowFromHandle(hWnd);
00089 if(!window) {
00090 return FALSE;
00091 }
00092
00093 hMenu = GetMenu(hWnd);
00094
00095 iSysStat = (window->GetSysMenu()) ? GetMenuState(GetSubMenu(window->GetSysMenu(), 0),
00096 cmd, MF_BYCOMMAND) : -1 ;
00097 iStat = (hMenu) ? GetMenuState(hMenu, cmd, MF_BYCOMMAND) : -1 ;
00098
00099 if (iSysStat!=-1)
00100 {
00101 if (iSysStat & (MF_DISABLED|MF_GRAYED))
00102 mesg=4;
00103 else
00104 mesg=WM_SYSCOMMAND;
00105 }
00106 else
00107 {
00108 if (iStat!=-1)
00109 {
00110 if (IsIconic(hWnd)) {
00111 mesg=5;
00112 }
00113 else
00114 {
00115 if (iStat & (MF_DISABLED|MF_GRAYED))
00116 mesg=6;
00117 else
00118 mesg=WM_COMMAND;
00119 }
00120 }
00121 else
00122 mesg=WM_COMMAND;
00123 }
00124 RELEASE_WNDOBJ(window);
00125 }
00126 if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
00127 {
00128 SendMessageA(hWnd, mesg, cmd, 0x00010000L);
00129 }
00130 else
00131 {
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 if(mesg==0)
00142 dprintf(("ERROR: unknown reason - please report!"));
00143 else dprintf(("but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg));
00144
00145 }
00146 return TRUE;
00147 }
00148 dprintf(("TranslateAccelerator: not match for %x %x %x", fVirt, key, cmd));
00149 }
00150 return FALSE;
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 INT WINAPI TranslateAcceleratorA(HWND hWnd, HACCEL hAccel, LPMSG msg)
00164 {
00165
00166 LPACCEL lpAccelTbl;
00167 int i;
00168
00169 SetLastError(ERROR_SUCCESS);
00170 if (msg == NULL)
00171 {
00172 dprintf(("TranslateAcceleratorAmsg null; should hang here to be win compatible"));
00173 SetLastError(ERROR_INVALID_PARAMETER);
00174 return 0;
00175 }
00176 if (!hAccel || !(lpAccelTbl = (LPACCEL)GlobalLock(hAccel)))
00177 {
00178 dprintf(("TranslateAcceleratorA: invalid accel handle=%x", hAccel));
00179 SetLastError(ERROR_INVALID_PARAMETER);
00180 return 0;
00181 }
00182 if(!IsWindow(hWnd)) {
00183 dprintf(("TranslateAccelerator, window %x not found", hWnd));
00184 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
00185 return 0;
00186 }
00187 if ((msg->message != WM_KEYDOWN &&
00188 msg->message != WM_KEYUP &&
00189 msg->message != WM_SYSKEYDOWN &&
00190 msg->message != WM_SYSKEYUP &&
00191 msg->message != WM_CHAR))
00192 {
00193 return 0;
00194 }
00195
00196
00197
00198
00199
00200 i = 0;
00201 do
00202 {
00203 if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
00204 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
00205 {
00206 return 1;
00207 }
00208 }
00209 while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
00210
00211
00212 return 0;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance,LPCWSTR lpTableName)
00224 {
00225 HRSRC hRsrc;
00226 HACCEL hMem,hRetval=0;
00227 DWORD size;
00228
00229 if (!(hRsrc = FindResourceW( instance, lpTableName, RT_ACCELERATORW )))
00230 {
00231 dprintf(("LoadAcceleratorsW couldn't find accelerator table resource %x %x", instance, lpTableName));
00232 return 0;
00233 }
00234 else {
00235 hMem = LoadResource( instance, hRsrc );
00236 size = SizeofResource( instance, hRsrc );
00237 if(size >= sizeof(PE_ACCEL))
00238 {
00239 LPPE_ACCEL accel_table = (LPPE_ACCEL) hMem;
00240 LPACCEL accel;
00241 int i,nrofaccells = size/sizeof(PE_ACCEL);
00242
00243 hRetval = GlobalAlloc(0,sizeof(ACCEL)*nrofaccells);
00244 accel = (LPACCEL)GlobalLock(hRetval);
00245
00246 for (i=0;i<nrofaccells;i++) {
00247 accel[i].fVirt = accel_table[i].fVirt;
00248 accel[i].key = accel_table[i].key;
00249 accel[i].cmd = accel_table[i].cmd;
00250 }
00251 accel[i-1].fVirt |= 0x80;
00252 }
00253 }
00254 dprintf(("LoadAcceleratorsW returned %x %x %x\n", instance, lpTableName, hRetval));
00255 return hRetval;
00256 }
00257
00258 HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName)
00259 {
00260 LPWSTR uni;
00261 HACCEL result;
00262 if (HIWORD(lpTableName))
00263 uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
00264 else
00265 uni = (LPWSTR)lpTableName;
00266 result = LoadAcceleratorsW(instance,uni);
00267 if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
00268 return result;
00269 }
00270
00271
00272
00273
00274 INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT entries)
00275 {
00276 return CopyAcceleratorTableW(src, dst, entries);
00277 }
00278
00279
00280
00281
00282
00283
00284 INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst, INT entries)
00285 {
00286 int i,xsize;
00287 LPACCEL accel = (LPACCEL)GlobalLock(src);
00288 BOOL done = FALSE;
00289
00290
00291
00292 if((dst && (entries < 1)) || (src == (HACCEL)NULL) || !accel)
00293 {
00294 dprintf(("CopyAcceleratorTableW: Application sent invalid parameters (%p %p %d).\n", (LPVOID)src, (LPVOID)dst, entries));
00295 SetLastError(ERROR_INVALID_PARAMETER);
00296 return 0;
00297 }
00298 xsize = GlobalSize(src)/sizeof(ACCEL);
00299 if (xsize>entries) entries=xsize;
00300
00301 i=0;
00302 while(!done) {
00303
00304
00305
00306
00307
00308
00309 if(dst) {
00310 dst[i].fVirt = accel[i].fVirt;
00311 dst[i].key = accel[i].key;
00312 dst[i].cmd = accel[i].cmd;
00313
00314
00315
00316 if(i+1 == entries) {
00317
00318 dst[i].fVirt &= 0x7f;
00319 done = TRUE;
00320 }
00321 }
00322
00323
00324
00325 if((accel[i].fVirt & 0x80) != 0) done = TRUE;
00326
00327 i++;
00328 }
00329
00330 return i;
00331 }
00332
00333
00334
00335
00336
00337
00338 HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT cEntries)
00339 {
00340 HACCEL hAccel;
00341 LPACCEL accel;
00342 int i;
00343
00344
00345
00346 if(cEntries < 1) {
00347 dprintf(("CreateAcceleratorTableA: Application sent invalid parameters (%p %d).\n", lpaccel, cEntries));
00348 SetLastError(ERROR_INVALID_PARAMETER);
00349 return NULL;
00350 }
00351 dprintf(("FIXME: CreateAcceleratorTableA: should check that the accelerator descriptions are valid return NULL and SetLastError() if not"));
00352
00353
00354 hAccel = GlobalAlloc(0,cEntries*sizeof(ACCEL));
00355
00356 if(!hAccel) {
00357 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00358 return (HACCEL)NULL;
00359 }
00360 accel = (LPACCEL)GlobalLock(hAccel);
00361 for (i=0;i<cEntries;i++) {
00362 accel[i].fVirt = lpaccel[i].fVirt;
00363 accel[i].key = lpaccel[i].key;
00364 accel[i].cmd = lpaccel[i].cmd;
00365 }
00366
00367 accel[cEntries-1].fVirt |= 0x80;
00368
00369 dprintf(("CreateAcceleratorTableA %x %x returned %x\n", lpaccel, cEntries, hAccel));
00370 return hAccel;
00371 }
00372
00373
00374
00375
00376
00377
00378 HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT cEntries)
00379 {
00380 HACCEL hAccel;
00381 LPACCEL accel;
00382 int i;
00383 char ckey;
00384
00385
00386
00387 if(cEntries < 1) {
00388 dprintf(("CreateAcceleratorTableW: Application sent invalid parameters (%p %d).\n", lpaccel, cEntries));
00389 SetLastError(ERROR_INVALID_PARAMETER);
00390 return NULL;
00391 }
00392 dprintf(("FIXME: CreateAcceleratorTableW: should check that the accelerator descriptions are valid return NULL and SetLastError() if not"));
00393
00394
00395 hAccel = GlobalAlloc(0,cEntries*sizeof(ACCEL));
00396
00397 if(!hAccel) {
00398 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00399 return (HACCEL)NULL;
00400 }
00401 accel = (LPACCEL)GlobalLock(hAccel);
00402
00403 for (i=0;i<cEntries;i++) {
00404 accel[i].fVirt = lpaccel[i].fVirt;
00405 if( !(accel[i].fVirt & FVIRTKEY) ) {
00406 ckey = (char) lpaccel[i].key;
00407 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &ckey, 1, &accel[i].key, 1);
00408 }
00409 else accel[i].key = lpaccel[i].key;
00410 accel[i].cmd = lpaccel[i].cmd;
00411 }
00412
00413
00414 accel[cEntries-1].fVirt |= 0x80;
00415
00416 dprintf(("CreateAcceleratorTableW %x %x returned %x\n", lpaccel, cEntries, hAccel));
00417 return hAccel;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 BOOL WINAPI DestroyAcceleratorTable( HACCEL handle )
00433 {
00434 return GlobalFree(handle);
00435 }
00436