00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
00017
00018
00019
00020
00021
00022 int ItemContainingSubMenu(
00023
PMENU pmainMenu,
00024 ULONG_PTR wID)
00025 {
00026
int i;
00027
PITEM pItem;
00028
00029
if ((i = pmainMenu->
cItems - 1) == -1)
00030
return -1;
00031
00032 pItem = &pmainMenu->
rgItems[i];
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
while (i >= 0)
00046 {
00047
if (pItem->
spSubMenu ==
NULL)
00048 {
00049
00050
00051
00052
if (pItem->
wID == wID)
00053
break;
00054 }
00055
else
00056 {
00057
00058
00059
00060
if (pItem->
spSubMenu == (
PMENU)wID)
00061
break;
00062
00063
00064
00065
00066
00067
if (
ItemContainingSubMenu(pItem->
spSubMenu, wID) != -1)
00068
break;
00069 }
00070
00071 i--;
00072 pItem--;
00073 }
00074
00075
return i;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 int UT_FindTopLevelMenuIndex(
00087
PMENU pMenu,
00088 UINT cmd)
00089 {
00090
PMENU pMenuItemIsOn;
00091
PITEM pItem;
00092
00093
00094
00095
00096 pItem =
MNLookUpItem(pMenu, cmd,
FALSE, &pMenuItemIsOn);
00097
if ((pItem ==
NULL) || (pItem->
spSubMenu !=
NULL))
00098
return(-1);
00099
00100
00101
00102
00103
00104
00105
return ItemContainingSubMenu(pMenu,
00106 pMenuItemIsOn != pMenu ? (ULONG_PTR)pMenuItemIsOn : cmd);
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 BOOL xxxHiliteMenuItem(
00118
PWND pwnd,
00119
PMENU pMenu,
00120 UINT cmd,
00121 UINT flags)
00122 {
00123
00124
if (!(flags & MF_BYPOSITION))
00125 cmd = (
UINT)
UT_FindTopLevelMenuIndex(pMenu, cmd);
00126
00127
if (!
TestMF(pMenu,
MFISPOPUP))
00128
xxxMNRecomputeBarIfNeeded(pwnd, pMenu);
00129
00130
xxxMNInvertItem(
NULL, pMenu, cmd, pwnd, (flags & MF_HILITE));
00131
00132
return TRUE;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 #define TA_DISABLED 1
00144
00145 UINT xxxTA_AccelerateMenu(
00146
PWND pwnd,
00147
PMENU pMenu,
00148 UINT cmd,
00149 HMENU *phmenuInit)
00150 {
00151
int i;
00152
PITEM pItem;
00153
BOOL fDisabledTop;
00154
BOOL fDisabled;
00155
UINT rgfItem;
00156
PMENU pMenuItemIsOn;
00157
00158
CheckLock(pwnd);
00159
CheckLock(pMenu);
00160
00161 rgfItem = 0;
00162
if (pMenu !=
NULL) {
00163
if ((i =
UT_FindTopLevelMenuIndex(pMenu, cmd)) != -1) {
00164
00165
00166
00167
00168 rgfItem = 2;
00169
00170
xxxSendMessage(pwnd, WM_INITMENU, (WPARAM)
PtoHq(pMenu), 0
L);
00171
if ((
UINT)i >= pMenu->cItems)
00172
return 0;
00173
00174 pItem = &pMenu->rgItems[i];
00175
if (pItem->
spSubMenu !=
NULL) {
00176 *phmenuInit =
PtoHq(pItem->
spSubMenu);
00177
xxxSendMessage(pwnd, WM_INITMENUPOPUP, (WPARAM)*phmenuInit,
00178 (
DWORD)i);
00179
if ((
UINT)i >= pMenu->cItems)
00180
return 0;
00181 fDisabledTop =
TestMFS(pItem,MFS_GRAYED);
00182 }
else {
00183 fDisabledTop =
FALSE;
00184 }
00185
00186 pItem =
MNLookUpItem(pMenu, cmd,
FALSE, &pMenuItemIsOn);
00187
00188
00189
00190
00191
00192
if (pItem ==
NULL) {
00193 rgfItem = 0;
00194 }
else {
00195 fDisabled =
TestMFS(pItem,MFS_GRAYED);
00196
00197
00198
00199
00200
if (fDisabled || fDisabledTop)
00201 rgfItem |=
TA_DISABLED;
00202 }
00203 }
00204 }
00205
00206
return rgfItem;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 HANDLE
APIENTRY _CreateAcceleratorTable(
00218 LPACCEL ccxpaccel,
00219
int cbAccel)
00220 {
00221
LPACCELTABLE pat;
00222
int size;
00223
00224 size = cbAccel +
sizeof(
ACCELTABLE) -
sizeof(ACCEL);
00225
00226 pat = (
LPACCELTABLE)
HMAllocObject(
PtiCurrent(),
NULL,
TYPE_ACCELTABLE, size);
00227
if (pat ==
NULL)
00228
return NULL;
00229
00230
try {
00231 RtlCopyMemory(pat->
accel, ccxpaccel, cbAccel);
00232 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00233
HMFreeObject(pat);
00234
return NULL;
00235 }
00236
00237 pat->
cAccel = cbAccel /
sizeof(ACCEL);
00238 pat->
accel[pat->
cAccel - 1].fVirt |=
FLASTKEY;
00239
00240
return pat;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 int xxxTranslateAccelerator(
00252
PWND pwnd,
00253
LPACCELTABLE pat,
00254 LPMSG lpMsg)
00255 {
00256
UINT cmd;
00257
BOOL fVirt;
00258
PMENU pMenu;
00259
BOOL fFound;
00260
UINT flags;
00261
UINT keystate;
00262
UINT message;
00263
UINT rgfItem;
00264
BOOL fDisabled;
00265
BOOL fSystemMenu;
00266 LPACCEL paccel;
00267
TL tlpMenu;
00268
int vkAlt, vkCtrl;
00269 HMENU hmenuInit =
NULL;
00270
00271
CheckLock(pwnd);
00272
CheckLock(pat);
00273
00274
if (
gfInNumpadHexInput &
NUMPAD_HEXMODE_HL) {
00275
return FALSE;
00276 }
00277
00278 paccel = pat->
accel;
00279
00280 fFound =
FALSE;
00281
00282 message =
SystoChar(lpMsg->message, lpMsg->lParam);
00283
00284
switch (message) {
00285
case WM_KEYDOWN:
00286
case WM_SYSKEYDOWN:
00287 fVirt =
TRUE;
00288
break;
00289
00290
case WM_CHAR:
00291
case WM_SYSCHAR:
00292 fVirt =
FALSE;
00293
break;
00294
00295
default:
00296
return FALSE;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 keystate = 0;
00309 UserAssert(
PtiCurrent()->spklActive !=
NULL);
00310
if (
PtiCurrent()->spklActive &&
00311 (
PtiCurrent()->spklActive->spkf->pKbdTbl->fLocaleFlags & KLLF_ALTGR) &&
00312 (
_GetKeyState(VK_RMENU) & 0x8000)) {
00313
00314
00315
00316
00317 vkCtrl = VK_RCONTROL;
00318 vkAlt = VK_LMENU;
00319 }
else {
00320
00321
00322
00323
00324 vkAlt = VK_MENU;
00325 vkCtrl = VK_CONTROL;
00326 }
00327
00328
if (
_GetKeyState(vkCtrl) & 0x8000) {
00329 keystate |= FCONTROL;
00330 }
00331
if (
_GetKeyState(vkAlt) & 0x8000) {
00332 keystate |= FALT;
00333 }
00334
if (
_GetKeyState(VK_SHIFT) & 0x8000) {
00335 keystate |= FSHIFT;
00336 }
00337
00338
do
00339 {
00340 flags = paccel->fVirt;
00341
if ( (
DWORD)paccel->key != lpMsg->wParam ||
00342 ((fVirt != 0) != ((flags & FVIRTKEY) != 0))) {
00343
goto Next;
00344 }
00345
00346
if (fVirt && ((keystate & (FSHIFT | FCONTROL)) != (flags & (FSHIFT | FCONTROL)))) {
00347
goto Next;
00348 }
00349
00350
if ((keystate & FALT) != (flags & FALT)) {
00351
goto Next;
00352 }
00353
00354 fFound =
TRUE;
00355 fSystemMenu = 0;
00356 rgfItem = 0;
00357
00358 cmd = paccel->cmd;
00359
if (cmd != 0) {
00360
00361
00362
00363
00364
00365
00366 pMenu = pwnd->
spmenu;
00367 rgfItem = 0;
00368
00369
if (!
TestWF(pwnd,
WFCHILD)) {
00370
ThreadLock(pMenu, &tlpMenu);
00371 rgfItem =
xxxTA_AccelerateMenu(pwnd, pMenu, cmd, &hmenuInit);
00372
ThreadUnlock(&tlpMenu);
00373 }
00374
00375
if (
TestWF(pwnd,
WFCHILD) || rgfItem == 0) {
00376 UserAssert(hmenuInit ==
NULL);
00377 pMenu = pwnd->
spmenuSys;
00378
if (pMenu ==
NULL &&
TestWF(pwnd,
WFSYSMENU)) {
00379
00380
00381
00382
00383 pMenu = pwnd->
head.rpdesk->spmenuSys;
00384
if (pMenu ==
NULL) {
00385 pMenu =
xxxLoadSysDesktopMenu (&pwnd->
head.rpdesk->spmenuSys,
ID_SYSMENU);
00386 }
00387
ThreadLock(pMenu, &tlpMenu);
00388
00389
00390
00391
xxxSetSysMenu(pwnd);
00392 }
else {
00393
ThreadLock(pMenu, &tlpMenu);
00394 }
00395
00396
if ((rgfItem =
xxxTA_AccelerateMenu(pwnd, pMenu, cmd, &hmenuInit)) != 0) {
00397 fSystemMenu =
TRUE;
00398 }
00399
ThreadUnlock(&tlpMenu);
00400 }
00401 }
00402
00403 fDisabled =
TestWF(pwnd,
WFDISABLED);
00404
00405
00406
00407
00408
00409
00410
00411
00412
if (!(rgfItem &
TA_DISABLED) &&
00413 !(rgfItem &&
TestWF(pwnd,
WFICONIC) && !fSystemMenu)) {
00414
if (!(rgfItem != 0 && (
PtiCurrent()->pq->spwndCapture !=
NULL ||
00415 fDisabled))) {
00416
00417
if (fSystemMenu) {
00418
xxxSendMessage(pwnd, WM_SYSCOMMAND, cmd, 0x00010000L);
00419 }
else {
00420
xxxSendMessage(pwnd, WM_COMMAND, MAKELONG(cmd, 1), 0);
00421 }
00422
00423
00424
00425
00426 flags =
FLASTKEY;
00427 }
00428 }
00429
00430
00431
00432
00433
if (hmenuInit !=
NULL) {
00434
xxxSendMessage(pwnd, WM_UNINITMENUPOPUP, (WPARAM)hmenuInit, 0);
00435 hmenuInit =
NULL;
00436 }
00437
00438 Next:
00439 paccel++;
00440
00441 }
while (!(flags &
FLASTKEY) && !fFound);
00442
00443
00444
return fFound;
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 UINT SystoChar(
00462 UINT message,
00463 LPARAM lParam)
00464 {
00465
if (
CheckMsgFilter(message, WM_SYSKEYDOWN, WM_SYSDEADCHAR) &&
00466 !(HIWORD(lParam) &
SYS_ALTERNATE))
00467
return (message - (WM_SYSKEYDOWN - WM_KEYDOWN));
00468
00469
return message;
00470 }