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

//------------------------------------------------------------------------
//
// imemenu.cpp
//
//------------------------------------------------------------------------
#include "private.h"
#include "resource.h"
#include "globals.h"
#include "imemenu.h"
#define GetpMyMenuItem(pMenu) ((PMYMENUITEM)((LPBYTE)pMenu + sizeof(MENULIST)))
typedef DWORD (WINAPI *PFNIMMGETIMEMENUITEMS)(HIMC, DWORD, DWORD, LPIMEMENUITEMINFO, LPIMEMENUITEMINFO, DWORD);
// since I don't have the memphis lib, do a load library
static const TCHAR c_szImmLib[] = TEXT("IMM32");
static const TCHAR c_szImmGetImeMenuItems[] = TEXT("ImmGetImeMenuItemsA");
PFNIMMGETIMEMENUITEMS g_pfnImmGetImeMenuItems = NULL;
//
// Max and Min number of MYMENUITEM if our shared heap.
//
/**********************************************************************/
/* */
/* GetImeMenuProc() */
/* */
/**********************************************************************/
BOOL CWin32ImeMenu::GetImeMenuProp()
{
if (g_pfnImmGetImeMenuItems)
return TRUE;
if (IsOnFE() || IsOnNT5())
{
HINSTANCE hInstImm;
hInstImm = GetSystemModuleHandle(c_szImmLib);
if (hInstImm)
g_pfnImmGetImeMenuItems = (PFNIMMGETIMEMENUITEMS)GetProcAddress(hInstImm, c_szImmGetImeMenuItems);
}
return g_pfnImmGetImeMenuItems ? TRUE : FALSE;
}
/**********************************************************************/
/* */
/* AddMenuList() */
/* */
/**********************************************************************/
BOOL CWin32ImeMenu::AddMenuList(PMENULIST pMenu)
{
PMENULIST pMenuPrev, pMenuNext;
if (!_pMenuHdr)
{
if ((_pMenuHdr = (PMENULIST)cicMemAllocClear(sizeof(MENULIST))) == NULL)
return FALSE;
_pMenuHdr->pPrev = _pMenuHdr;
_pMenuHdr->pNext = _pMenuHdr;
}
pMenuPrev = _pMenuHdr->pPrev;
pMenuNext = pMenuPrev->pNext;
pMenu->pNext = pMenuPrev->pNext;
pMenu->pPrev = pMenuNext->pPrev;
pMenuPrev->pNext = pMenu;
pMenuNext->pPrev = pMenu;
_nMenuList++;
return TRUE;
}
/**********************************************************************/
/* */
/* DeleteMenuList() */
/* */
/**********************************************************************/
void CWin32ImeMenu::DeleteMenuList(PMENULIST pMenu)
{
PMENULIST pMenuPrev, pMenuNext;
if (pMenu == _pMenuHdr) {
#ifdef DEBUG
OutputDebugString("DeleteMenu: should not delete header");
#endif
return;
}
pMenuPrev = pMenu->pPrev;
pMenuNext = pMenu->pNext;
pMenuPrev->pNext = pMenu->pNext;
pMenuNext->pPrev = pMenu->pPrev;
_nMenuList--;
if (_nMenuList < 0)
{
#ifdef DEBUG
OutputDebugString("DeleteMenu: _nMenuList is zero");
#endif
_nMenuList = 0;
}
cicMemFree(pMenu);
}
/**********************************************************************/
/* */
/* DeleteAllMenuList() */
/* */
/**********************************************************************/
void CWin32ImeMenu::DeleteAllMenuList()
{
PMENULIST pMenu, pMenuNext;
if (!_pMenuHdr)
return;
pMenu = _pMenuHdr->pNext;
if (pMenu == _pMenuHdr)
return;
while (pMenu != _pMenuHdr)
{
pMenuNext = pMenu->pNext;
DeleteMenuList(pMenu);
pMenu = pMenuNext;
}
if (_nMenuList > 0)
{
#ifdef DEBUG
OutputDebugString("DeleteAllMenu: _nMenuList is not zero");
#endif
_nMenuList = 0;
}
return;
}
/**********************************************************************/
/* */
/* AllocMenuList() */
/* */
/**********************************************************************/
PMENULIST CWin32ImeMenu::AllocMenuList(DWORD dwNum)
{
PMENULIST pMenu;
pMenu = (PMENULIST)cicMemAllocClear(sizeof(MENULIST) + sizeof(MYMENUITEM) * dwNum);
if (pMenu)
{
AddMenuList(pMenu);
pMenu->dwNum = dwNum;
}
return pMenu;
}
/**********************************************************************/
/* */
/* SetMyMenuItem() */
/* */
/**********************************************************************/
void CWin32ImeMenu::SetMyMenuItem(HWND hWnd, HIMC hIMC, LPIMEMENUITEMINFO lpIme, BOOL fRight, PMYMENUITEM pMyMenuItem)
{
FillMemory((PVOID)pMyMenuItem, sizeof(MYMENUITEM), 0);
pMyMenuItem->imii = *lpIme;
if (lpIme->fType & IMFT_SUBMENU)
{
//
// If lpIme has SubMenu, we need to create another MENULIST.
//
pMyMenuItem->pmlSubMenu = CreateImeMenu(hWnd, hIMC, lpIme, fRight);
}
pMyMenuItem->nMenuID = IDM_CUSTOM_MENU_START + _nMenuCnt;
}
/**********************************************************************/
/* */
/* CreateImeMenu() */
/* */
/**********************************************************************/
PMENULIST CWin32ImeMenu::CreateImeMenu(HWND hWnd, HIMC hIMC, LPIMEMENUITEMINFO lpImeParentMenu, BOOL fRight)
{
DWORD dwSize, dwNum, dwI;
LPIMEMENUITEMINFO lpImeMenu;
PMENULIST pMenu;
PMYMENUITEM pMyMenuItem;
if (!GetImeMenuProp())
return NULL;
dwNum = g_pfnImmGetImeMenuItems(hIMC, fRight ? IGIMIF_RIGHTMENU : 0,
IGIMII_CMODE |
IGIMII_SMODE |
IGIMII_CONFIGURE |
IGIMII_TOOLS |
IGIMII_HELP |
IGIMII_OTHER,
lpImeParentMenu, NULL, 0);
if (!dwNum)
return 0;
pMenu = AllocMenuList(dwNum);
if (!pMenu)
return 0;
pMyMenuItem = GetpMyMenuItem(pMenu);
dwSize = dwNum * sizeof(IMEMENUITEMINFO);
lpImeMenu = (LPIMEMENUITEMINFO)GlobalAlloc(GPTR, dwSize);
if (!lpImeMenu)
return 0;
dwNum = g_pfnImmGetImeMenuItems(hIMC, fRight ? IGIMIF_RIGHTMENU : 0,
IGIMII_CMODE |
IGIMII_SMODE |
IGIMII_CONFIGURE |
IGIMII_TOOLS |
IGIMII_HELP |
IGIMII_OTHER,
lpImeParentMenu, lpImeMenu, dwSize);
// Setup this MENULIST.
for (dwI = 0 ; dwI < dwNum; dwI++)
{
SetMyMenuItem(hWnd, hIMC, lpImeMenu + dwI, fRight, pMyMenuItem + dwI);
_nMenuCnt++;
}
GlobalFree((HANDLE)lpImeMenu);
return pMenu;
}
/**********************************************************************/
/* */
/* GetIMEMenu() */
/* */
/**********************************************************************/
BOOL CWin32ImeMenu::GetIMEMenu(HWND hWnd, HIMC hIMC, BOOL fRight)
{
// Init sequent number.
_nMenuCnt = 0;
CreateImeMenu(hWnd, hIMC, NULL, fRight);
return TRUE;
}
/**********************************************************************/
/* */
/* FillMenuItemInfo() */
/* */
/**********************************************************************/
void CWin32ImeMenu::FillMenuItemInfo(LPMENUITEMINFO lpmii, PMYMENUITEM pMyMenuItem, BOOL fRight)
{
FillMemory((PVOID)lpmii, sizeof(MENUITEMINFO), 0);
lpmii->cbSize = sizeof(MENUITEMINFO);
lpmii->fMask = 0;
// Set fType;
if (pMyMenuItem->imii.fType)
{
if (IsOnNT5())
lpmii->fMask |= MIIM_FTYPE;
else
lpmii->fMask |= MIIM_TYPE;
lpmii->fType = 0;
if (pMyMenuItem->imii.fType & IMFT_RADIOCHECK)
lpmii->fType |= MFT_RADIOCHECK;
if (pMyMenuItem->imii.fType & IMFT_SEPARATOR)
lpmii->fType |= MFT_SEPARATOR;
}
lpmii->fMask |= MIIM_ID;
lpmii->wID = pMyMenuItem->nMenuID;
if (pMyMenuItem->imii.fType & IMFT_SUBMENU)
{
//
// If lpIme has SubMenu, we need to create another Popup Menu.
//
lpmii->fMask |= MIIM_SUBMENU;
lpmii->hSubMenu = CreatePopupMenu();
BuildIMEMenuItems(lpmii->hSubMenu, pMyMenuItem->pmlSubMenu, fRight);
}
lpmii->fMask |= MIIM_STATE;
lpmii->fState = pMyMenuItem->imii.fState;
if (pMyMenuItem->imii.hbmpChecked && pMyMenuItem->imii.hbmpUnchecked)
{
lpmii->fMask |= MIIM_CHECKMARKS;
lpmii->hbmpChecked = pMyMenuItem->imii.hbmpChecked;
lpmii->hbmpUnchecked = pMyMenuItem->imii.hbmpUnchecked;
}
lpmii->fMask |= MIIM_DATA;
lpmii->dwItemData = pMyMenuItem->imii.dwItemData;
if (pMyMenuItem->imii.hbmpItem)
{
lpmii->fMask |= MIIM_BITMAP;
lpmii->hbmpItem = pMyMenuItem->imii.hbmpItem;
}
if (lstrlen(pMyMenuItem->imii.szString))
{
lpmii->fMask |= MIIM_STRING;
lpmii->dwTypeData = pMyMenuItem->imii.szString;
lpmii->cch = lstrlen(pMyMenuItem->imii.szString);
}
}
/**********************************************************************/
/* */
/* GetDefaultImeMenuItem() */
/* */
/**********************************************************************/
int CWin32ImeMenu::GetDefaultImeMenuItem()
{
PMENULIST pMenu;
DWORD dwI;
PMYMENUITEM pMyMenuItem;
if (!_pMenuHdr)
return 0;
pMenu = _pMenuHdr->pNext;
if (pMenu == _pMenuHdr)
return 0;
if (!pMenu->dwNum)
return 0;
pMyMenuItem = GetpMyMenuItem(pMenu);
for (dwI = 0 ; dwI < pMenu->dwNum; dwI++)
{
if (pMyMenuItem->imii.fState & IMFS_DEFAULT)
return pMyMenuItem->imii.wID;
pMyMenuItem++;
}
return 0;
}
/**********************************************************************/
/* */
/* BuildIMEMenuItems() */
/* */
/**********************************************************************/
BOOL CWin32ImeMenu::BuildIMEMenuItems(HMENU hMenu, PMENULIST pMenu, BOOL fRight)
{
DWORD dwI;
MENUITEMINFO mii;
PMYMENUITEM pMyMenuItem;
if (!pMenu || !pMenu->dwNum)
return FALSE;
pMyMenuItem = GetpMyMenuItem(pMenu);
for (dwI = 0 ; dwI < pMenu->dwNum; dwI++)
{
FillMenuItemInfo(&mii, pMyMenuItem + dwI, fRight);
InsertMenuItem(hMenu, dwI, TRUE, (MENUITEMINFO *)&mii);
}
return TRUE;
}
/**********************************************************************/
/* */
/* BuildIMEMenu() */
/* */
/**********************************************************************/
BOOL CWin32ImeMenu::BuildIMEMenu(HMENU hMenu, BOOL fRight)
{
PMENULIST pMenu;
if (!_pMenuHdr)
return FALSE;
pMenu = _pMenuHdr->pNext;
if (pMenu == _pMenuHdr)
return FALSE;
return BuildIMEMenuItems(hMenu, pMenu, fRight);
}
/**********************************************************************/
/* */
/* GetIMEMenuItemID() */
/* */
/**********************************************************************/
UINT CWin32ImeMenu::GetIMEMenuItemID(int nMenuID)
{
DWORD dwI;
PMENULIST pMenu, pMenuNext;
PMYMENUITEM pMyMenuItem;
UINT uRet = 0;
if (!_pMenuHdr)
goto Exit;
pMenu = _pMenuHdr->pNext;
if (pMenu == _pMenuHdr)
goto Exit;
while (pMenu != _pMenuHdr)
{
pMenuNext = pMenu->pNext;
pMyMenuItem = GetpMyMenuItem(pMenu);
for (dwI = 0; dwI < pMenu->dwNum; dwI ++)
{
if (pMyMenuItem->nMenuID == nMenuID)
{
uRet = pMyMenuItem->imii.wID;
goto Exit;
}
pMyMenuItem++;
}
pMenu = pMenuNext;
}
Exit:
return uRet;
}
/**********************************************************************/
/* */
/* GetIMEMenuItemData() */
/* */
/**********************************************************************/
DWORD CWin32ImeMenu::GetIMEMenuItemData(int nImeMenuID)
{
DWORD dwI;
PMENULIST pMenu, pMenuNext;
PMYMENUITEM pMyMenuItem;
DWORD dwRet = 0;
if (!_pMenuHdr)
goto Exit;
pMenu = _pMenuHdr->pNext;
if (pMenu == _pMenuHdr)
goto Exit;
while (pMenu != _pMenuHdr)
{
pMenuNext = pMenu->pNext;
pMyMenuItem = GetpMyMenuItem(pMenu);
for (dwI = 0; dwI < pMenu->dwNum; dwI ++)
{
if (pMyMenuItem->imii.wID == (UINT)nImeMenuID)
{
dwRet = pMyMenuItem->imii.dwItemData;
goto Exit;
}
pMyMenuItem++;
}
pMenu = pMenuNext;
}
Exit:
return dwRet;
}
/**********************************************************************/
/* */
/* DestroyIMEMenu() */
/* */
/**********************************************************************/
void CWin32ImeMenu::DestroyIMEMenu()
{
DeleteAllMenuList();
}