Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dmmnem.c

Go to the documentation of this file.
00001 /***************************************************************************\ 00002 * 00003 * DMMNEM.C - 00004 * 00005 * Copyright (c) 1985 - 1999, Microsoft Corporation 00006 * 00007 * Mnemonic Character Processing Routines 00008 * 00009 * ??-???-???? mikeke Ported from Win 3.0 sources 00010 * 12-Feb-1991 mikeke Added Revalidation code 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 /***************************************************************************\ 00017 * FindMnemChar 00018 * 00019 * Returns: 0x00 if no matching char, 00020 * 0x01 if menmonic char is matching, 00021 * 0x80 if first char is matching 00022 * 00023 * History: 00024 * 11-18-90 JimA Created. 00025 \***************************************************************************/ 00026 00027 int FindMnemChar( 00028 LPWSTR lpstr, 00029 WCHAR ch, 00030 BOOL fFirst, 00031 BOOL fPrefix) 00032 { 00033 WCHAR chc; 00034 WCHAR chnext; 00035 WCHAR chFirst; 00036 00037 while (*lpstr == TEXT(' ')) 00038 lpstr++; 00039 00040 ch = (WCHAR)(ULONG_PTR)CharLowerW((LPWSTR)ULongToPtr( (DWORD)(UTCHAR)ch )); 00041 chFirst = (WCHAR)(ULONG_PTR)CharLowerW((LPWSTR)ULongToPtr( (DWORD)(UTCHAR)(*lpstr) )); 00042 00043 #ifdef FE_SB // FindMnemChar() 00044 // 00045 // HIRO: LATER: CH_ENGLISHPREFIX is obsolete, so entire FE_SB can be removed ? 00046 // 00047 if (fPrefix) { 00048 SHORT wvch, xvkey; 00049 // 00050 // get OEM-dependent virtual key code 00051 // 00052 if ((wvch = VkKeyScanW(ch)) != -1) 00053 wvch &= 0x00FF; 00054 00055 while (chc = *lpstr++) { 00056 // 00057 // This should think about KOREA & TAIWAN case. But probably OK. 00058 // 00059 if ((chc == CH_PREFIX) || (chc == CH_ENGLISHPREFIX)) { 00060 chnext = (WCHAR)(ULONG_PTR)CharLowerW((LPWSTR)ULongToPtr( (DWORD)(UTCHAR)*lpstr )); 00061 00062 if (chnext == CH_PREFIX) 00063 lpstr++; 00064 else if (chnext == ch) 00065 return(0x01); 00066 else { 00067 // 00068 // Compare should be done with virtual key in Kanji menu mode 00069 // in order to accept Digit shortcut key and save English 00070 // windows applications! 00071 // 00072 xvkey = VkKeyScanW(chnext); 00073 if (xvkey != 0xFFFF && ((xvkey & 0x00FF) == wvch)) 00074 return(0x01); 00075 else 00076 return(0x00); 00077 } 00078 } 00079 } 00080 } 00081 #else 00082 if (fPrefix) { 00083 while (chc = *lpstr++) { 00084 if (((WCHAR)CharLower((LPWSTR)(DWORD)(UTCHAR)chc) == CH_PREFIX)) { 00085 chnext = (WCHAR)CharLowerW((LPWSTR)(DWORD)(UTCHAR)*lpstr); 00086 00087 if (chnext == CH_PREFIX) 00088 lpstr++; 00089 else if (chnext == ch) 00090 return 0x01; 00091 else { 00092 return 0x00; 00093 } 00094 } 00095 } 00096 } 00097 #endif // FE_SB 00098 00099 if (fFirst && (ch == chFirst)) 00100 return 0x80; 00101 00102 return 0x00; 00103 } 00104 00105 00106 /***************************************************************************\ 00107 * xxxFindNextMnem 00108 * 00109 * This function returns NULL if no control with the specified mnemonic 00110 * can be found. 00111 * 00112 * History: 00113 \***************************************************************************/ 00114 00115 PWND xxxGNM_FindNextMnem( 00116 PWND pwndDlg, 00117 PWND pwnd, 00118 WCHAR ch) 00119 { 00120 PWND pwndStart; 00121 PWND pwndT; 00122 WCHAR rgchText[256]; 00123 int i = 0; 00124 TL tlpwndStart; 00125 TL tlpwnd; 00126 DWORD dwDlgCode; 00127 00128 CheckLock(pwndDlg); 00129 CheckLock(pwnd); 00130 00131 /* 00132 * Check if we are in a group box so we can find local mnemonics. 00133 */ 00134 00135 pwndStart = _GetChildControl(pwndDlg, pwnd); 00136 ThreadLock(pwndStart, &tlpwndStart); 00137 00138 while (TRUE) { 00139 00140 pwndT = _GetNextDlgGroupItem(pwndDlg, pwndStart, FALSE); 00141 00142 ThreadUnlock(&tlpwndStart); 00143 00144 i++; 00145 if (pwndT == NULL || pwndT == pwnd || i > 60) { 00146 00147 /* 00148 * If we have returned to our starting window or if we have gone 00149 * through 60 iterations, let's exit. There are no local mnemonics 00150 * that match. We have to check for 60 iterations (or so) because 00151 * we run into problems with WS_GROUP not being properly defined in 00152 * rc files that we never reach this same starting window again.... 00153 */ 00154 break; 00155 } 00156 00157 pwndStart = pwndT; 00158 00159 /* 00160 * Only check for matching mnemonic if control doesn't want characters 00161 * and control isn't a static control with SS_NOPREFIX 00162 */ 00163 ThreadLock(pwndStart, &tlpwndStart); 00164 00165 dwDlgCode = (DWORD)SendMessage(HWq(pwndT), WM_GETDLGCODE, 0, 0L); 00166 if (!(dwDlgCode & DLGC_WANTCHARS) && 00167 (!(dwDlgCode & DLGC_STATIC) || !(pwndT->style & SS_NOPREFIX))) { 00168 GetWindowText(HWq(pwndT), rgchText, sizeof(rgchText)/sizeof(WCHAR)); 00169 if (FindMnemChar(rgchText, ch, FALSE, TRUE) != 0) { 00170 ThreadUnlock(&tlpwndStart); 00171 return pwndT; 00172 } 00173 } 00174 } 00175 00176 pwnd = pwndStart = _GetChildControl(pwndDlg, pwnd); 00177 00178 ThreadLock(pwnd, &tlpwnd); 00179 while (TRUE) { 00180 00181 /* 00182 * Start with next so we see multiples of same mnemonic. 00183 */ 00184 pwnd = _NextControl(pwndDlg, pwnd, TRUE); 00185 00186 ThreadUnlock(&tlpwnd); 00187 ThreadLock(pwnd, &tlpwnd); 00188 00189 00190 00191 /* 00192 * Only check for matching mnemonic if control doesn't want characters 00193 * and control isn't a static control with SS_NOPREFIX 00194 */ 00195 dwDlgCode = (DWORD)SendMessage(HW(pwnd), WM_GETDLGCODE, 0, 0L); 00196 if (!(dwDlgCode & DLGC_WANTCHARS) && 00197 (!(dwDlgCode & DLGC_STATIC) || !(pwnd->style & SS_NOPREFIX))) { 00198 GetWindowText(HW(pwnd), rgchText, sizeof(rgchText)/sizeof(WCHAR)); 00199 if (FindMnemChar(rgchText, ch, FALSE, TRUE) != 0) 00200 break; 00201 } 00202 00203 if (pwnd == pwndStart) { 00204 pwnd = NULL; 00205 break; 00206 } 00207 } 00208 ThreadUnlock(&tlpwnd); 00209 00210 return pwnd; 00211 } 00212 00213 /***************************************************************************\ 00214 * xxxGotoNextMnem 00215 * 00216 * History: 00217 \***************************************************************************/ 00218 00219 PWND xxxGotoNextMnem( 00220 PWND pwndDlg, 00221 PWND pwnd, 00222 WCHAR ch) 00223 { 00224 UINT code; 00225 PWND pwndFirstFound = NULL; 00226 int count = 0; 00227 TL tlpwnd; 00228 PWND pwndT; 00229 HWND hwnd; 00230 00231 CheckLock(pwndDlg); 00232 CheckLock(pwnd); 00233 00234 ThreadLock(pwnd, &tlpwnd); 00235 00236 /* 00237 * Loop for a long time but not long enough so we hang... 00238 */ 00239 while (count < 256 * 2) { 00240 00241 /* 00242 * If the dialog box doesn't has the mnemonic specified, return NULL. 00243 */ 00244 if ((pwnd = xxxGNM_FindNextMnem(pwndDlg, pwnd, ch)) == NULL) { 00245 ThreadUnlock(&tlpwnd); 00246 return NULL; 00247 } 00248 hwnd = HWq(pwnd); 00249 00250 ThreadUnlock(&tlpwnd); 00251 ThreadLock(pwnd, &tlpwnd); 00252 00253 code = (UINT)SendMessage(hwnd, WM_GETDLGCODE, 0, 0L); 00254 00255 /* 00256 * If a non-disabled static item, then jump ahead to nearest tabstop. 00257 */ 00258 if (code & DLGC_STATIC && !TestWF(pwnd, WFDISABLED)) { 00259 pwndT = _GetNextDlgTabItem(pwndDlg, pwnd, FALSE); 00260 00261 /* 00262 * If there is no other tab item, keep looking 00263 */ 00264 if (pwndT == NULL) 00265 continue; 00266 pwnd = pwndT; 00267 hwnd = HWq(pwnd); 00268 00269 ThreadUnlock(&tlpwnd); 00270 ThreadLock(pwnd, &tlpwnd); 00271 00272 /* 00273 * I suppose we should do a getdlgcode here, but who is going to 00274 * label a button with a static control? The setup guys, that's 00275 * who... Also, generally useful for ownerdraw buttons which are 00276 * labeled with a static text item. 00277 */ 00278 code = (UINT)SendMessage(hwnd, WM_GETDLGCODE, 0, 0L); 00279 } 00280 00281 if (!TestWF(pwnd, WFDISABLED)) { 00282 00283 /* 00284 * Is it a Pushbutton? 00285 */ 00286 if (!(code & DLGC_BUTTON)) { 00287 00288 /* 00289 * No, simply give it the focus. 00290 */ 00291 DlgSetFocus(hwnd); 00292 } else { 00293 00294 /* 00295 * Yes, click it, but don't give it the focus. 00296 */ 00297 if ((code & DLGC_DEFPUSHBUTTON) || (code & DLGC_UNDEFPUSHBUTTON)) { 00298 00299 /* 00300 * Flash the button. 00301 */ 00302 SendMessage(hwnd, BM_SETSTATE, TRUE, 0L); 00303 00304 /* 00305 * Delay 00306 */ 00307 #ifdef LATER 00308 // JimA - 2/19/92 00309 // There oughta be a better way of doing this... 00310 for (i = 0; i < 10000; i++) 00311 ; 00312 #else 00313 Sleep(1); 00314 #endif 00315 00316 /* 00317 * Un-Flash it. 00318 */ 00319 SendMessage(hwnd, BM_SETSTATE, FALSE, 0L); 00320 00321 /* 00322 * Send the WM_COMMAND message. 00323 */ 00324 pwndT = REBASEPWND(pwnd, spwndParent); 00325 SendMessage(HW(pwndT), WM_COMMAND, 00326 MAKELONG(PTR_TO_ID(pwnd->spmenu), BN_CLICKED), (LPARAM)hwnd); 00327 ThreadUnlock(&tlpwnd); 00328 return (PWND)1; 00329 } else { 00330 00331 /* 00332 * Because BM_CLICK processing will result in BN_CLICK msg, 00333 * xxxSetFocus must be prevented from sending the same msg; 00334 * Otherwise, it will notify parent twice! 00335 * Fix for Bug #3024 -- SANKAR -- 09-22-89 -- 00336 */ 00337 BOOL fIsNTButton; 00338 PBUTN pbutn; 00339 00340 fIsNTButton = (pwnd->fnid == FNID_BUTTON); 00341 if (fIsNTButton) { 00342 pbutn = ((PBUTNWND)pwnd)->pbutn; 00343 BUTTONSTATE(pbutn) |= BST_DONTCLICK; 00344 } else { 00345 RIPMSG0(RIP_WARNING, "xxxGotoNextMnem: fnid != FNID_BUTTON"); 00346 } 00347 00348 DlgSetFocus(hwnd); 00349 00350 if (fIsNTButton) { 00351 BUTTONSTATE(pbutn) &= ~BST_DONTCLICK; 00352 } 00353 00354 /* 00355 * Send click message if button has a UNIQUE mnemonic 00356 */ 00357 if (xxxGNM_FindNextMnem(pwndDlg, pwnd, ch) == pwnd) { 00358 SendMessage(hwnd, BM_CLICK, TRUE, 0L); 00359 } 00360 } 00361 } 00362 00363 ThreadUnlock(&tlpwnd); 00364 return pwnd; 00365 } else { 00366 00367 /* 00368 * Stop if we've looped back to the first item we checked 00369 */ 00370 if (pwnd == pwndFirstFound) { 00371 ThreadUnlock(&tlpwnd); 00372 return NULL; 00373 } 00374 00375 if (pwndFirstFound == NULL) 00376 pwndFirstFound = pwnd; 00377 } 00378 00379 count++; 00380 00381 } /* Loop for a long time */ 00382 00383 ThreadUnlock(&tlpwnd); 00384 return NULL; 00385 }

Generated on Sat May 15 19:39:46 2004 for test by doxygen 1.3.7