Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

491 lines
13 KiB

  1. #include "msgina.h"
  2. #include <shellapi.h>
  3. typedef struct
  4. {
  5. HKL dwHkl;
  6. HICON hIcon;
  7. } LAYOUTINFO, *PLAYOUTINFO;
  8. typedef struct
  9. {
  10. HKL hklLast;
  11. PLAYOUTINFO pLayoutInfo;
  12. UINT uNumLayouts;
  13. } USERLAYOUTINFO, *PUSERLAYOUTINFO;
  14. HICON
  15. CreateLangIdIcon(
  16. WORD LangId);
  17. int
  18. CreateIconList(
  19. PLAYOUTINFO pLayoutInfo,
  20. HKL hkl,
  21. UINT uLangs);
  22. HICON
  23. GetIconFromHkl(
  24. PLAYOUTINFO pLayoutInfo,
  25. HKL hkl,
  26. UINT uLangs);
  27. USERLAYOUTINFO UserLayoutInfo[2];
  28. typedef BOOL (WINAPI *LPFNIMMGETIMEFILENAME)(HKL, LPTSTR, UINT);
  29. LPFNIMMGETIMEFILENAME pfnImmGetImeFileName = NULL;
  30. TCHAR szImm32DLL[] = TEXT("imm32.dll");
  31. typedef UINT (WINAPI *PFNEXTRACTICONEXW)(LPCWSTR lpszFile, int nIconIndex, HICON FAR *phiconLarge, HICON FAR *phiconSmall, UINT nIcons);
  32. /***************************************************************************\
  33. * FUNCTION: CreateLangIdIcon
  34. *
  35. * PURPOSE: Create an icon that displays the first two letters of the
  36. * supplied language ID.
  37. *
  38. * RETURNS: Icon that shows displays Language ID.
  39. *
  40. * HISTORY:
  41. *
  42. * 04-17-98 ShanXu Borrowed from internat.exe
  43. *
  44. \***************************************************************************/
  45. HICON
  46. CreateLangIdIcon(
  47. WORD langID
  48. )
  49. {
  50. HBITMAP hbmColour = NULL;
  51. HBITMAP hbmMono;
  52. HBITMAP hbmOld;
  53. HICON hicon = NULL;
  54. ICONINFO ii;
  55. RECT rc;
  56. DWORD rgbText;
  57. DWORD rgbBk = 0;
  58. HDC hdc = NULL;
  59. HDC hdcScreen;
  60. LOGFONT lf;
  61. HFONT hfont;
  62. HFONT hfontOld;
  63. TCHAR szData[20];
  64. UINT cxSmIcon, cySmIcon;
  65. cxSmIcon = GetSystemMetrics(SM_CXSMICON);
  66. cySmIcon = GetSystemMetrics(SM_CYSMICON);
  67. //
  68. // Get the indicator by using the first 2 characters of the
  69. // abbreviated language name.
  70. //
  71. if (GetLocaleInfo( MAKELCID(langID, SORT_DEFAULT),
  72. LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
  73. szData,
  74. sizeof(szData) / sizeof(szData[0]) ))
  75. {
  76. //
  77. // Only use the first two characters.
  78. //
  79. szData[2] = TEXT('\0');
  80. }
  81. else
  82. {
  83. //
  84. // Id wasn't found. Use question marks.
  85. //
  86. szData[0] = TEXT('?');
  87. szData[1] = TEXT('?');
  88. szData[2] = TEXT('\0');
  89. }
  90. if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0))
  91. {
  92. #if (1) //DSIE: Bug 351507
  93. if (hdcScreen = GetDC(NULL))
  94. {
  95. double dScaleY = GetDeviceCaps(hdcScreen, LOGPIXELSY) / 96.0f;
  96. lf.lfHeight = (int) (lf.lfHeight * dScaleY); // Scale the height based on the system DPI.
  97. ReleaseDC(NULL, hdcScreen);
  98. }
  99. #endif
  100. if ((hfont = CreateFontIndirect(&lf)))
  101. {
  102. hdcScreen = GetDC(NULL);
  103. if ( hdcScreen )
  104. {
  105. hdc = CreateCompatibleDC(hdcScreen);
  106. hbmColour = CreateCompatibleBitmap(hdcScreen, cxSmIcon, cySmIcon);
  107. ReleaseDC(NULL, hdcScreen);
  108. }
  109. if (hbmColour && hdc)
  110. {
  111. hbmMono = CreateBitmap(cxSmIcon, cySmIcon, 1, 1, NULL);
  112. if (hbmMono)
  113. {
  114. hbmOld = SelectObject(hdc, hbmColour);
  115. rc.left = 0;
  116. rc.top = 0;
  117. rc.right = cxSmIcon;
  118. rc.bottom = cySmIcon;
  119. rgbBk = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
  120. rgbText = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  121. ExtTextOut( hdc,
  122. rc.left,
  123. rc.top,
  124. ETO_OPAQUE,
  125. &rc,
  126. TEXT(""),
  127. 0,
  128. NULL );
  129. SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
  130. hfontOld = SelectObject(hdc, hfont);
  131. DrawText( hdc,
  132. szData,
  133. 2,
  134. &rc,
  135. DT_CENTER | DT_VCENTER | DT_SINGLELINE );
  136. #ifdef USE_MIRRORING
  137. {
  138. DWORD dwLayout;
  139. GetProcessDefaultLayout(&dwLayout);
  140. if (dwLayout & LAYOUT_RTL)
  141. {
  142. MirrorBitmapInDC(hdc, hbmColour);
  143. }
  144. }
  145. #endif
  146. SelectObject(hdc, hbmMono);
  147. PatBlt(hdc, 0, 0, cxSmIcon, cySmIcon, BLACKNESS);
  148. SelectObject(hdc, hbmOld);
  149. ii.fIcon = TRUE;
  150. ii.xHotspot = 0;
  151. ii.yHotspot = 0;
  152. ii.hbmColor = hbmColour;
  153. ii.hbmMask = hbmMono;
  154. hicon = CreateIconIndirect(&ii);
  155. DeleteObject(hbmMono);
  156. SelectObject(hdc, hfontOld);
  157. }
  158. DeleteObject(hbmColour);
  159. DeleteDC(hdc);
  160. }
  161. DeleteObject(hfont);
  162. }
  163. }
  164. return (hicon);
  165. }
  166. /***************************************************************************\
  167. * FUNCTION: CreateIconList
  168. *
  169. * PURPOSE: Create the table that contains the relationship between an hkl
  170. * and an icon.
  171. *
  172. * RETURNS: Index of the current hkl in the table.
  173. *
  174. * HISTORY:
  175. *
  176. * 04-17-98 ShanXu Created
  177. *
  178. \***************************************************************************/
  179. int
  180. CreateIconList(
  181. PLAYOUTINFO pLayoutInfo,
  182. HKL hklCur,
  183. UINT uLangs)
  184. {
  185. HKL *pLanguages;
  186. UINT uCount;
  187. int nCurIndex = -1;
  188. pLanguages = (HKL *)LocalAlloc(LPTR, uLangs * sizeof(HKL));
  189. if (!pLanguages)
  190. {
  191. return -1;
  192. }
  193. GetKeyboardLayoutList(uLangs, (HKL *)pLanguages);
  194. for (uCount = 0; uCount < uLangs; uCount++)
  195. {
  196. pLayoutInfo[uCount].dwHkl = pLanguages[uCount];
  197. if (pLanguages[uCount] == hklCur)
  198. {
  199. nCurIndex = uCount;
  200. }
  201. if ((HIWORD(pLanguages[uCount]) & 0xf000) == 0xe000)
  202. {
  203. WCHAR szIMEFile[32]; // assume long filename up to 32 byte
  204. if (!pfnImmGetImeFileName)
  205. {
  206. HMODULE hMod;
  207. hMod = GetModuleHandle(szImm32DLL);
  208. if (hMod)
  209. {
  210. pfnImmGetImeFileName = (LPFNIMMGETIMEFILENAME)
  211. GetProcAddress(
  212. hMod,
  213. "ImmGetIMEFileNameW");
  214. }
  215. }
  216. if (pfnImmGetImeFileName &&
  217. (*pfnImmGetImeFileName) (pLanguages[uCount],
  218. szIMEFile,
  219. sizeof(szIMEFile) ))
  220. {
  221. HINSTANCE hInstShell32;
  222. PFNEXTRACTICONEXW pfnExtractIconExW;
  223. hInstShell32 = LoadLibrary (TEXT("shell32.dll"));
  224. if (hInstShell32)
  225. {
  226. pfnExtractIconExW = (PFNEXTRACTICONEXW) GetProcAddress (hInstShell32,
  227. "ExtractIconExW");
  228. if (pfnExtractIconExW)
  229. {
  230. //
  231. // First one of the file.
  232. //
  233. pfnExtractIconExW(
  234. szIMEFile,
  235. 0,
  236. NULL,
  237. &pLayoutInfo[uCount].hIcon,
  238. 1);
  239. }
  240. FreeLibrary (hInstShell32);
  241. }
  242. continue;
  243. }
  244. }
  245. //
  246. // for non-ime layout
  247. //
  248. pLayoutInfo[uCount].hIcon = CreateLangIdIcon(LOWORD(pLanguages[uCount]));
  249. }
  250. LocalFree(pLanguages);
  251. return nCurIndex;
  252. }
  253. /***************************************************************************\
  254. * FUNCTION: GetIconFromHkl
  255. *
  256. * PURPOSE: Find the icon in our table that has a matching hkl
  257. * with the supplied hkl. Create the table if it does not
  258. * exist.
  259. *
  260. * RETURNS: Icon of the macthing hkl.
  261. *
  262. * HISTORY:
  263. *
  264. * 04-17-98 ShanXu Created
  265. *
  266. \***************************************************************************/
  267. HICON
  268. GetIconFromHkl(
  269. PLAYOUTINFO pLayoutInfo,
  270. HKL hkl,
  271. UINT uLangs)
  272. {
  273. UINT uCount;
  274. int nIndex = -1;
  275. if (pLayoutInfo[0].dwHkl == 0)
  276. {
  277. //
  278. // Icon/hkl list no exsists yet. Create it.
  279. //
  280. nIndex = CreateIconList(pLayoutInfo, hkl, uLangs);
  281. }
  282. else
  283. {
  284. //
  285. // Find the icon with a matching hkl
  286. //
  287. for (uCount = 0; uCount < uLangs; uCount++)
  288. {
  289. if (pLayoutInfo[uCount].dwHkl == hkl)
  290. {
  291. nIndex = uCount;
  292. break;
  293. }
  294. }
  295. }
  296. if (nIndex == -1)
  297. {
  298. return NULL;
  299. }
  300. return ( pLayoutInfo[nIndex].hIcon);
  301. }
  302. /***************************************************************************\
  303. * FUNCTION: DisplayLanguageIcon
  304. *
  305. * PURPOSE: Displays the icon of the currently selected hkl in the
  306. * dlg window.
  307. *
  308. * RETURNS: TRUE - The icon is displayed.
  309. * FALSE - No icon displayed.
  310. *
  311. * HISTORY:
  312. *
  313. * 04-17-98 ShanXu Created
  314. *
  315. \***************************************************************************/
  316. BOOL
  317. DisplayLanguageIcon(
  318. HWND hwnd,
  319. LAYOUT_USER LayoutUser,
  320. HKL hkl)
  321. {
  322. HICON hIconLayout;
  323. UINT uLangs;
  324. PLAYOUTINFO pLayout;
  325. uLangs = GetKeyboardLayoutList(0, NULL);
  326. if (uLangs < 2)
  327. {
  328. return FALSE;
  329. }
  330. pLayout = UserLayoutInfo[LayoutUser].pLayoutInfo;
  331. if (!pLayout)
  332. {
  333. pLayout = (PLAYOUTINFO)LocalAlloc(LPTR, uLangs * sizeof(LAYOUTINFO));
  334. if (!pLayout)
  335. {
  336. return FALSE;
  337. }
  338. UserLayoutInfo[LayoutUser].pLayoutInfo = pLayout;
  339. UserLayoutInfo[LayoutUser].uNumLayouts = uLangs;
  340. }
  341. hIconLayout = GetIconFromHkl(
  342. pLayout,
  343. hkl,
  344. uLangs);
  345. if (!hIconLayout)
  346. {
  347. return FALSE;
  348. }
  349. SendMessage(
  350. GetDlgItem(hwnd, IDD_KBLAYOUT_ICON),
  351. STM_SETICON,
  352. (WPARAM)hIconLayout,
  353. 0 );
  354. UserLayoutInfo[LayoutUser].hklLast = hkl;
  355. SetTimer(hwnd, TIMER_MYLANGUAGECHECK, 500, NULL);
  356. return TRUE;
  357. }
  358. /***************************************************************************\
  359. * FUNCTION: FreeLayoutInfo
  360. *
  361. * PURPOSE: Delete the icon/hkl table and destroy all icons.
  362. *
  363. * RETURNS: -
  364. *
  365. * HISTORY:
  366. *
  367. * 04-17-98 ShanXu Created
  368. *
  369. \***************************************************************************/
  370. void
  371. FreeLayoutInfo(
  372. LAYOUT_USER LayoutUser)
  373. {
  374. UINT uLangs;
  375. UINT uCount;
  376. PLAYOUTINFO pLayoutInfo;
  377. pLayoutInfo = UserLayoutInfo[LayoutUser].pLayoutInfo;
  378. if (!pLayoutInfo)
  379. {
  380. return;
  381. }
  382. uLangs = UserLayoutInfo[LayoutUser].uNumLayouts;
  383. for (uCount = 0; uCount < uLangs; uCount++)
  384. {
  385. DestroyIcon (pLayoutInfo[uCount].hIcon);
  386. }
  387. LocalFree(pLayoutInfo);
  388. UserLayoutInfo[LayoutUser].pLayoutInfo = NULL;
  389. UserLayoutInfo[LayoutUser].uNumLayouts = 0;
  390. return;
  391. }
  392. /***************************************************************************\
  393. * FUNCTION: LayoutCheckHandler
  394. *
  395. * PURPOSE: Handle layout check. Set appropriate icon if there is
  396. * a change in keyboard layout.
  397. *
  398. * RETURNS: -
  399. *
  400. * HISTORY:
  401. *
  402. * 04-22-98 ShanXu Created
  403. *
  404. \***************************************************************************/
  405. void
  406. LayoutCheckHandler(
  407. HWND hwnd,
  408. LAYOUT_USER LayoutUser)
  409. {
  410. HKL hklCurrent;
  411. KillTimer(hwnd, TIMER_MYLANGUAGECHECK);
  412. hklCurrent = GetKeyboardLayout(0);
  413. if (hklCurrent != UserLayoutInfo[LayoutUser].hklLast)
  414. {
  415. DisplayLanguageIcon(
  416. hwnd,
  417. LayoutUser,
  418. hklCurrent);
  419. }else{
  420. SetTimer(hwnd, TIMER_MYLANGUAGECHECK, 500, NULL);
  421. }
  422. }