00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
int xxxClientFindMnemChar(
00017 PUNICODE_STRING pstrSrc,
00018 WCHAR ch,
00019 BOOL fFirst,
00020 BOOL fPrefix);
00021
00022
00023 #define CMDSWITCH 1
00024 #define CMDQUERY 2
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 UINT MNFindNextValidItem(
00035
PMENU pMenu,
00036
int i,
00037
int dir,
00038 UINT flags)
00039 {
00040
int iStart;
00041
BOOL cont =
TRUE;
00042
int cItems = pMenu->
cItems;
00043
PITEM pItem;
00044
00045
if ((i < 0) && (dir > 0))
00046
00047 i = iStart = cItems;
00048
else if ((i >= cItems) && (
dir < 0))
00049
00050 i = iStart = -1;
00051
else
00052 iStart = i;
00053
00054
if (!cItems)
00055
return(
MFMWFP_NOITEM);
00056
00057
00058
00059
00060
if ( ( i == 0 ) && ( cItems == 1 ) && (
dir > 0 ) )
00061 {
00062
dir = 0;
00063
goto artsquickndirtybugfix;
00064 }
00065
00066
00067
00068
00069
while (
TRUE) {
00070 i +=
dir;
00071
00072
if ((i == iStart) || (
dir == 0))
00073
00074
return MFMWFP_NOITEM;
00075
00076
00077
if (i >= cItems) {
00078 i = -1;
00079
continue;
00080 }
00081
else if (i < 0) {
00082 i = cItems;
00083
continue;
00084 }
00085
00086 artsquickndirtybugfix:
00087 pItem = pMenu->
rgItems + i;
00088
00089
00090
if (
TestMFT(pItem, MFT_SEPARATOR)) {
00091
00092
00093
00094
00095
00096
if (!(flags &
MNF_DONTSKIPSEPARATORS)) {
00097
continue;
00098 }
00099 }
else if ((pItem->
hbmp >= HBMMENU_MBARFIRST) && (pItem->
hbmp <= HBMMENU_MBARLAST)) {
00100
00101
00102
00103
continue;
00104 }
00105
00106
00107
return(i);
00108 }
00109
00110
00111
00112
00113 UserAssert(
FALSE);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 UINT MNFindItemInColumn(
00125
PMENU pMenu,
00126 UINT idxB,
00127
int dir,
00128 BOOL fRoot)
00129 {
00130
int dxMin;
00131
int dyMin;
00132
int dxMax;
00133
int dyMax;
00134
int xB;
00135
int yB;
00136
UINT idxE;
00137
UINT idxR;
00138
UINT cItems;
00139
PITEM pItem;
00140
00141 cItems = pMenu->
cItems;
00142 idxR =
MFMWFP_NOITEM;
00143 idxE =
MNFindNextValidItem(pMenu,
MFMWFP_NOITEM,
dir, 0);
00144
if (idxE == -1)
00145
goto End;
00146
00147 dxMin = dyMin = 20000;
00148
00149
if (idxB >= pMenu->
cItems)
00150
return idxR;
00151
00152 pItem = &pMenu->
rgItems[idxB];
00153 xB = pItem->
xItem;
00154 yB = pItem->
yItem;
00155
00156
while (cItems-- > 0 &&
00157 (idxB =
MNFindNextValidItem(pMenu, idxB,
dir, 0)) != idxE) {
00158 pItem = &pMenu->
rgItems[idxB];
00159 dxMax = xB - pItem->
xItem;
00160 dyMax = yB - pItem->
yItem;
00161
00162
if (dxMax < 0)
00163 dxMax = (-dxMax);
00164
if (dyMax < 0)
00165 dyMax = (-dyMax);
00166
00167
00168
00169
00170
00171
00172
00173
if ((dyMax < dyMin) && (fRoot || dxMax) && dxMax <= dxMin) {
00174 dxMin = dxMax;
00175 dyMin = dyMax;
00176 idxR = idxB;
00177 }
00178 }
00179
00180
End:
00181
return idxR;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 UINT xxxMNFindChar(
00194
PMENU pMenu,
00195 UINT ch,
00196
int idxC,
00197 LPINT lpr)
00198 {
00199
int idxFirst =
MFMWFP_NOITEM;
00200
int idxB;
00201
int idxF;
00202
int rT;
00203 LPWSTR lpstr;
00204
PITEM pItem;
00205
00206
if (ch == 0)
00207
return 0;
00208
00209
00210
00211
00212 idxF =
MFMWFP_NOITEM;
00213 rT = 0;
00214 idxB = idxC;
00215
00216
if (idxB < 0)
00217
00218 idxB =
MNFindNextValidItem(pMenu, pMenu->
cItems,
MFMWFP_NOITEM,
MNF_DONTSKIPSEPARATORS);
00219
00220
do {
00221
INT idxPrev;
00222
00223 idxPrev = idxC;
00224 idxC =
MNFindNextValidItem(pMenu, idxC, 1,
MNF_DONTSKIPSEPARATORS);
00225
if (idxC ==
MFMWFP_NOITEM || idxC == idxFirst)
00226
break;
00227
if (idxFirst ==
MFMWFP_NOITEM)
00228 idxFirst = idxC;
00229
00230 pItem = &pMenu->
rgItems[idxC];
00231
00232
if (pItem->
lpstr !=
NULL) {
00233
if (pItem->
cch != 0) {
00234 UNICODE_STRING strMnem;
00235
00236 lpstr =
TextPointer(pItem->
lpstr);
00237
if (*lpstr ==
CH_HELPPREFIX) {
00238
00239
00240
00241
00242
00243 lpstr++;
00244 }
00245
00246
RtlInitUnicodeString(&strMnem, lpstr);
00247
if (((rT = (
UINT)
xxxClientFindMnemChar(&strMnem,
00248 (WCHAR)ch,
TRUE,
TRUE)) == 0x0080) &&
00249 (idxF ==
MFMWFP_NOITEM))
00250 idxF = idxC;
00251 }
00252 }
00253
if (idxC == idxPrev) {
00254
break;
00255 }
00256 }
while (rT != 1 && idxB != idxC);
00257
00258 *lpr = rT;
00259
00260
if (rT == 1)
00261
return idxC;
00262
00263
return idxF;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 void xxxMNKeyFilter(
00291
PPOPUPMENU ppopupMenu,
00292
PMENUSTATE pMenuState,
00293 UINT ch)
00294 {
00295
BOOL fLocalInsideMenuLoop = pMenuState->
fInsideMenuLoop;
00296
00297
if (pMenuState->
fButtonDown) {
00298
00299
00300
00301
00302
return;
00303 }
00304
00305
if (!pMenuState->
fInsideMenuLoop) {
00306
00307
00308
00309
00310
if (!
xxxMNStartMenu(ppopupMenu,
KEYBDHOLD)) {
00311
return;
00312 }
00313 pMenuState->
fInsideMenuLoop =
TRUE;
00314 }
00315
00316
00317
switch (ch) {
00318
case 0:
00319
00320
00321
00322
00323
00324
00325
00326
xxxMNSelectItem(ppopupMenu, pMenuState, 0);
00327
break;
00328
00329
case MENUCHILDSYSMENU:
00330
if (!
TestwndChild(ppopupMenu->
spwndNotify)) {
00331
00332
00333
00334
00335
00336
00337
goto MenuCharHandler;
00338 }
00339
00340
00341
00342
00343
00344
case MENUSYSMENU:
00345
if (!
TestWF(ppopupMenu->
spwndNotify,
WFSYSMENU)) {
00346
xxxMessageBeep(0);
00347
goto MenuCancel;
00348 }
00349
00350
00351
00352
00353
xxxMNCloseHierarchy(ppopupMenu, pMenuState);
00354
if (!ppopupMenu->
fIsSysMenu && ppopupMenu->
spmenuAlternate)
00355
xxxMNSwitchToAlternateMenu(ppopupMenu);
00356
if (!ppopupMenu->
fIsSysMenu) {
00357
00358
00359
00360
goto MenuCancel;
00361 }
00362
00363
MNPositionSysMenu(ppopupMenu->
spwndPopupMenu, ppopupMenu->
spmenu);
00364
xxxMNSelectItem(ppopupMenu, pMenuState, 0);
00365
xxxMNOpenHierarchy(ppopupMenu, pMenuState);
00366 ppopupMenu->
fToggle =
FALSE;
00367
break;
00368
00369
00370
default:
00371
00372
00373
00374
00375
00376
00377
00378
00379 MenuCharHandler:
00380
xxxMNChar(ppopupMenu, pMenuState, ch);
00381
if (ppopupMenu->
posSelectedItem ==
MFMWFP_NOITEM) {
00382
00383
00384
00385
goto MenuCancel;
00386 }
00387
break;
00388 }
00389
00390
if (!fLocalInsideMenuLoop && pMenuState->
fInsideMenuLoop) {
00391
xxxMNLoop(ppopupMenu, pMenuState, 0,
FALSE);
00392 }
00393
00394
return;
00395
00396
00397 MenuCancel:
00398 pMenuState->
fModelessMenu =
FALSE;
00399
if (!ppopupMenu->
fInCancel) {
00400
xxxMNDismiss(pMenuState);
00401 }
00402 UserAssert(!pMenuState->
fInsideMenuLoop && !pMenuState->
fMenuStarted);
00403
return;
00404 }