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.

511 lines
16 KiB

  1. //------------------------------------------------------------------------
  2. //
  3. // imemenu.cpp
  4. //
  5. //------------------------------------------------------------------------
  6. #include "private.h"
  7. #include "resource.h"
  8. #include "globals.h"
  9. #include "imemenu.h"
  10. #define GetpMyMenuItem(pMenu) ((PMYMENUITEM)((LPBYTE)pMenu + sizeof(MENULIST)))
  11. typedef DWORD (WINAPI *PFNIMMGETIMEMENUITEMS)(HIMC, DWORD, DWORD, LPIMEMENUITEMINFO, LPIMEMENUITEMINFO, DWORD);
  12. // since I don't have the memphis lib, do a load library
  13. static const TCHAR c_szImmLib[] = TEXT("IMM32");
  14. static const TCHAR c_szImmGetImeMenuItems[] = TEXT("ImmGetImeMenuItemsA");
  15. PFNIMMGETIMEMENUITEMS g_pfnImmGetImeMenuItems = NULL;
  16. //
  17. // Max and Min number of MYMENUITEM if our shared heap.
  18. //
  19. /**********************************************************************/
  20. /* */
  21. /* GetImeMenuProc() */
  22. /* */
  23. /**********************************************************************/
  24. BOOL CWin32ImeMenu::GetImeMenuProp()
  25. {
  26. if (g_pfnImmGetImeMenuItems)
  27. return TRUE;
  28. if (IsOnFE() || IsOnNT5())
  29. {
  30. HINSTANCE hInstImm;
  31. hInstImm = GetSystemModuleHandle(c_szImmLib);
  32. if (hInstImm)
  33. g_pfnImmGetImeMenuItems = (PFNIMMGETIMEMENUITEMS)GetProcAddress(hInstImm, c_szImmGetImeMenuItems);
  34. }
  35. return g_pfnImmGetImeMenuItems ? TRUE : FALSE;
  36. }
  37. /**********************************************************************/
  38. /* */
  39. /* AddMenuList() */
  40. /* */
  41. /**********************************************************************/
  42. BOOL CWin32ImeMenu::AddMenuList(PMENULIST pMenu)
  43. {
  44. PMENULIST pMenuPrev, pMenuNext;
  45. if (!_pMenuHdr)
  46. {
  47. if ((_pMenuHdr = (PMENULIST)cicMemAllocClear(sizeof(MENULIST))) == NULL)
  48. return FALSE;
  49. _pMenuHdr->pPrev = _pMenuHdr;
  50. _pMenuHdr->pNext = _pMenuHdr;
  51. }
  52. pMenuPrev = _pMenuHdr->pPrev;
  53. pMenuNext = pMenuPrev->pNext;
  54. pMenu->pNext = pMenuPrev->pNext;
  55. pMenu->pPrev = pMenuNext->pPrev;
  56. pMenuPrev->pNext = pMenu;
  57. pMenuNext->pPrev = pMenu;
  58. _nMenuList++;
  59. return TRUE;
  60. }
  61. /**********************************************************************/
  62. /* */
  63. /* DeleteMenuList() */
  64. /* */
  65. /**********************************************************************/
  66. void CWin32ImeMenu::DeleteMenuList(PMENULIST pMenu)
  67. {
  68. PMENULIST pMenuPrev, pMenuNext;
  69. if (pMenu == _pMenuHdr) {
  70. #ifdef DEBUG
  71. OutputDebugString("DeleteMenu: should not delete header");
  72. #endif
  73. return;
  74. }
  75. pMenuPrev = pMenu->pPrev;
  76. pMenuNext = pMenu->pNext;
  77. pMenuPrev->pNext = pMenu->pNext;
  78. pMenuNext->pPrev = pMenu->pPrev;
  79. _nMenuList--;
  80. if (_nMenuList < 0)
  81. {
  82. #ifdef DEBUG
  83. OutputDebugString("DeleteMenu: _nMenuList is zero");
  84. #endif
  85. _nMenuList = 0;
  86. }
  87. cicMemFree(pMenu);
  88. }
  89. /**********************************************************************/
  90. /* */
  91. /* DeleteAllMenuList() */
  92. /* */
  93. /**********************************************************************/
  94. void CWin32ImeMenu::DeleteAllMenuList()
  95. {
  96. PMENULIST pMenu, pMenuNext;
  97. if (!_pMenuHdr)
  98. return;
  99. pMenu = _pMenuHdr->pNext;
  100. if (pMenu == _pMenuHdr)
  101. return;
  102. while (pMenu != _pMenuHdr)
  103. {
  104. pMenuNext = pMenu->pNext;
  105. DeleteMenuList(pMenu);
  106. pMenu = pMenuNext;
  107. }
  108. if (_nMenuList > 0)
  109. {
  110. #ifdef DEBUG
  111. OutputDebugString("DeleteAllMenu: _nMenuList is not zero");
  112. #endif
  113. _nMenuList = 0;
  114. }
  115. return;
  116. }
  117. /**********************************************************************/
  118. /* */
  119. /* AllocMenuList() */
  120. /* */
  121. /**********************************************************************/
  122. PMENULIST CWin32ImeMenu::AllocMenuList(DWORD dwNum)
  123. {
  124. PMENULIST pMenu;
  125. pMenu = (PMENULIST)cicMemAllocClear(sizeof(MENULIST) + sizeof(MYMENUITEM) * dwNum);
  126. if (pMenu)
  127. {
  128. AddMenuList(pMenu);
  129. pMenu->dwNum = dwNum;
  130. }
  131. return pMenu;
  132. }
  133. /**********************************************************************/
  134. /* */
  135. /* SetMyMenuItem() */
  136. /* */
  137. /**********************************************************************/
  138. void CWin32ImeMenu::SetMyMenuItem(HWND hWnd, HIMC hIMC, LPIMEMENUITEMINFO lpIme, BOOL fRight, PMYMENUITEM pMyMenuItem)
  139. {
  140. FillMemory((PVOID)pMyMenuItem, sizeof(MYMENUITEM), 0);
  141. pMyMenuItem->imii = *lpIme;
  142. if (lpIme->fType & IMFT_SUBMENU)
  143. {
  144. //
  145. // If lpIme has SubMenu, we need to create another MENULIST.
  146. //
  147. pMyMenuItem->pmlSubMenu = CreateImeMenu(hWnd, hIMC, lpIme, fRight);
  148. }
  149. pMyMenuItem->nMenuID = IDM_CUSTOM_MENU_START + _nMenuCnt;
  150. }
  151. /**********************************************************************/
  152. /* */
  153. /* CreateImeMenu() */
  154. /* */
  155. /**********************************************************************/
  156. PMENULIST CWin32ImeMenu::CreateImeMenu(HWND hWnd, HIMC hIMC, LPIMEMENUITEMINFO lpImeParentMenu, BOOL fRight)
  157. {
  158. DWORD dwSize, dwNum, dwI;
  159. LPIMEMENUITEMINFO lpImeMenu;
  160. PMENULIST pMenu;
  161. PMYMENUITEM pMyMenuItem;
  162. if (!GetImeMenuProp())
  163. return NULL;
  164. dwNum = g_pfnImmGetImeMenuItems(hIMC, fRight ? IGIMIF_RIGHTMENU : 0,
  165. IGIMII_CMODE |
  166. IGIMII_SMODE |
  167. IGIMII_CONFIGURE |
  168. IGIMII_TOOLS |
  169. IGIMII_HELP |
  170. IGIMII_OTHER,
  171. lpImeParentMenu, NULL, 0);
  172. if (!dwNum)
  173. return 0;
  174. pMenu = AllocMenuList(dwNum);
  175. if (!pMenu)
  176. return 0;
  177. pMyMenuItem = GetpMyMenuItem(pMenu);
  178. dwSize = dwNum * sizeof(IMEMENUITEMINFO);
  179. lpImeMenu = (LPIMEMENUITEMINFO)GlobalAlloc(GPTR, dwSize);
  180. if (!lpImeMenu)
  181. return 0;
  182. dwNum = g_pfnImmGetImeMenuItems(hIMC, fRight ? IGIMIF_RIGHTMENU : 0,
  183. IGIMII_CMODE |
  184. IGIMII_SMODE |
  185. IGIMII_CONFIGURE |
  186. IGIMII_TOOLS |
  187. IGIMII_HELP |
  188. IGIMII_OTHER,
  189. lpImeParentMenu, lpImeMenu, dwSize);
  190. // Setup this MENULIST.
  191. for (dwI = 0 ; dwI < dwNum; dwI++)
  192. {
  193. SetMyMenuItem(hWnd, hIMC, lpImeMenu + dwI, fRight, pMyMenuItem + dwI);
  194. _nMenuCnt++;
  195. }
  196. GlobalFree((HANDLE)lpImeMenu);
  197. return pMenu;
  198. }
  199. /**********************************************************************/
  200. /* */
  201. /* GetIMEMenu() */
  202. /* */
  203. /**********************************************************************/
  204. BOOL CWin32ImeMenu::GetIMEMenu(HWND hWnd, HIMC hIMC, BOOL fRight)
  205. {
  206. // Init sequent number.
  207. _nMenuCnt = 0;
  208. CreateImeMenu(hWnd, hIMC, NULL, fRight);
  209. return TRUE;
  210. }
  211. /**********************************************************************/
  212. /* */
  213. /* FillMenuItemInfo() */
  214. /* */
  215. /**********************************************************************/
  216. void CWin32ImeMenu::FillMenuItemInfo(LPMENUITEMINFO lpmii, PMYMENUITEM pMyMenuItem, BOOL fRight)
  217. {
  218. FillMemory((PVOID)lpmii, sizeof(MENUITEMINFO), 0);
  219. lpmii->cbSize = sizeof(MENUITEMINFO);
  220. lpmii->fMask = 0;
  221. // Set fType;
  222. if (pMyMenuItem->imii.fType)
  223. {
  224. if (IsOnNT5())
  225. lpmii->fMask |= MIIM_FTYPE;
  226. else
  227. lpmii->fMask |= MIIM_TYPE;
  228. lpmii->fType = 0;
  229. if (pMyMenuItem->imii.fType & IMFT_RADIOCHECK)
  230. lpmii->fType |= MFT_RADIOCHECK;
  231. if (pMyMenuItem->imii.fType & IMFT_SEPARATOR)
  232. lpmii->fType |= MFT_SEPARATOR;
  233. }
  234. lpmii->fMask |= MIIM_ID;
  235. lpmii->wID = pMyMenuItem->nMenuID;
  236. if (pMyMenuItem->imii.fType & IMFT_SUBMENU)
  237. {
  238. //
  239. // If lpIme has SubMenu, we need to create another Popup Menu.
  240. //
  241. lpmii->fMask |= MIIM_SUBMENU;
  242. lpmii->hSubMenu = CreatePopupMenu();
  243. BuildIMEMenuItems(lpmii->hSubMenu, pMyMenuItem->pmlSubMenu, fRight);
  244. }
  245. lpmii->fMask |= MIIM_STATE;
  246. lpmii->fState = pMyMenuItem->imii.fState;
  247. if (pMyMenuItem->imii.hbmpChecked && pMyMenuItem->imii.hbmpUnchecked)
  248. {
  249. lpmii->fMask |= MIIM_CHECKMARKS;
  250. lpmii->hbmpChecked = pMyMenuItem->imii.hbmpChecked;
  251. lpmii->hbmpUnchecked = pMyMenuItem->imii.hbmpUnchecked;
  252. }
  253. lpmii->fMask |= MIIM_DATA;
  254. lpmii->dwItemData = pMyMenuItem->imii.dwItemData;
  255. if (pMyMenuItem->imii.hbmpItem)
  256. {
  257. lpmii->fMask |= MIIM_BITMAP;
  258. lpmii->hbmpItem = pMyMenuItem->imii.hbmpItem;
  259. }
  260. if (lstrlen(pMyMenuItem->imii.szString))
  261. {
  262. lpmii->fMask |= MIIM_STRING;
  263. lpmii->dwTypeData = pMyMenuItem->imii.szString;
  264. lpmii->cch = lstrlen(pMyMenuItem->imii.szString);
  265. }
  266. }
  267. /**********************************************************************/
  268. /* */
  269. /* GetDefaultImeMenuItem() */
  270. /* */
  271. /**********************************************************************/
  272. int CWin32ImeMenu::GetDefaultImeMenuItem()
  273. {
  274. PMENULIST pMenu;
  275. DWORD dwI;
  276. PMYMENUITEM pMyMenuItem;
  277. if (!_pMenuHdr)
  278. return 0;
  279. pMenu = _pMenuHdr->pNext;
  280. if (pMenu == _pMenuHdr)
  281. return 0;
  282. if (!pMenu->dwNum)
  283. return 0;
  284. pMyMenuItem = GetpMyMenuItem(pMenu);
  285. for (dwI = 0 ; dwI < pMenu->dwNum; dwI++)
  286. {
  287. if (pMyMenuItem->imii.fState & IMFS_DEFAULT)
  288. return pMyMenuItem->imii.wID;
  289. pMyMenuItem++;
  290. }
  291. return 0;
  292. }
  293. /**********************************************************************/
  294. /* */
  295. /* BuildIMEMenuItems() */
  296. /* */
  297. /**********************************************************************/
  298. BOOL CWin32ImeMenu::BuildIMEMenuItems(HMENU hMenu, PMENULIST pMenu, BOOL fRight)
  299. {
  300. DWORD dwI;
  301. MENUITEMINFO mii;
  302. PMYMENUITEM pMyMenuItem;
  303. if (!pMenu || !pMenu->dwNum)
  304. return FALSE;
  305. pMyMenuItem = GetpMyMenuItem(pMenu);
  306. for (dwI = 0 ; dwI < pMenu->dwNum; dwI++)
  307. {
  308. FillMenuItemInfo(&mii, pMyMenuItem + dwI, fRight);
  309. InsertMenuItem(hMenu, dwI, TRUE, (MENUITEMINFO *)&mii);
  310. }
  311. return TRUE;
  312. }
  313. /**********************************************************************/
  314. /* */
  315. /* BuildIMEMenu() */
  316. /* */
  317. /**********************************************************************/
  318. BOOL CWin32ImeMenu::BuildIMEMenu(HMENU hMenu, BOOL fRight)
  319. {
  320. PMENULIST pMenu;
  321. if (!_pMenuHdr)
  322. return FALSE;
  323. pMenu = _pMenuHdr->pNext;
  324. if (pMenu == _pMenuHdr)
  325. return FALSE;
  326. return BuildIMEMenuItems(hMenu, pMenu, fRight);
  327. }
  328. /**********************************************************************/
  329. /* */
  330. /* GetIMEMenuItemID() */
  331. /* */
  332. /**********************************************************************/
  333. UINT CWin32ImeMenu::GetIMEMenuItemID(int nMenuID)
  334. {
  335. DWORD dwI;
  336. PMENULIST pMenu, pMenuNext;
  337. PMYMENUITEM pMyMenuItem;
  338. UINT uRet = 0;
  339. if (!_pMenuHdr)
  340. goto Exit;
  341. pMenu = _pMenuHdr->pNext;
  342. if (pMenu == _pMenuHdr)
  343. goto Exit;
  344. while (pMenu != _pMenuHdr)
  345. {
  346. pMenuNext = pMenu->pNext;
  347. pMyMenuItem = GetpMyMenuItem(pMenu);
  348. for (dwI = 0; dwI < pMenu->dwNum; dwI ++)
  349. {
  350. if (pMyMenuItem->nMenuID == nMenuID)
  351. {
  352. uRet = pMyMenuItem->imii.wID;
  353. goto Exit;
  354. }
  355. pMyMenuItem++;
  356. }
  357. pMenu = pMenuNext;
  358. }
  359. Exit:
  360. return uRet;
  361. }
  362. /**********************************************************************/
  363. /* */
  364. /* GetIMEMenuItemData() */
  365. /* */
  366. /**********************************************************************/
  367. DWORD CWin32ImeMenu::GetIMEMenuItemData(int nImeMenuID)
  368. {
  369. DWORD dwI;
  370. PMENULIST pMenu, pMenuNext;
  371. PMYMENUITEM pMyMenuItem;
  372. DWORD dwRet = 0;
  373. if (!_pMenuHdr)
  374. goto Exit;
  375. pMenu = _pMenuHdr->pNext;
  376. if (pMenu == _pMenuHdr)
  377. goto Exit;
  378. while (pMenu != _pMenuHdr)
  379. {
  380. pMenuNext = pMenu->pNext;
  381. pMyMenuItem = GetpMyMenuItem(pMenu);
  382. for (dwI = 0; dwI < pMenu->dwNum; dwI ++)
  383. {
  384. if (pMyMenuItem->imii.wID == (UINT)nImeMenuID)
  385. {
  386. dwRet = pMyMenuItem->imii.dwItemData;
  387. goto Exit;
  388. }
  389. pMyMenuItem++;
  390. }
  391. pMenu = pMenuNext;
  392. }
  393. Exit:
  394. return dwRet;
  395. }
  396. /**********************************************************************/
  397. /* */
  398. /* DestroyIMEMenu() */
  399. /* */
  400. /**********************************************************************/
  401. void CWin32ImeMenu::DestroyIMEMenu()
  402. {
  403. DeleteAllMenuList();
  404. }