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

imemenu.c File Reference

#include "precomp.h"

Go to the source code of this file.

Classes

struct  _IMEMENU_BMP_HEADER
struct  IMEMENU_ITEM
struct  IMEMENU_HEADER

Defines

#define D(x)
#define IME_MENU_FILE_NAME   L"ImmMenuInfo"
#define IME_MENU_MAXMEM   (128 * 1024)
#define CONVTO_OFFSET(x)   ((x) = (LPVOID)((x) ? ((LPBYTE)(x) - offset) : NULL))
#define CONVTO_PTR(x)   ((x) = (LPVOID)((x) ? ((LPBYTE)(x) + offset) : NULL))
#define CHK_OFFSET(x)
#define CHK_PTR(x)
#define DumpBytes(a, b)

Typedefs

typedef _IMEMENU_BMP_HEADER IMEMENU_BMP_HEADER

Functions

void ConvertImeMenuItemInfoAtoW (LPIMEMENUITEMINFOA lpA, LPIMEMENUITEMINFOW lpW, int nCP, BOOL copyBmp)
void ConvertImeMenuItemInfoWtoA (LPIMEMENUITEMINFOW lpW, LPIMEMENUITEMINFOA lpA, int nCP)
IMEMENU_BMP_HEADERSaveBitmapToMemory (HDC hDC, HBITMAP hBmp, IMEMENU_BMP_HEADER *lpBH, IMEMENU_HEADER *pHeader)
IMEMENU_BMP_HEADERDecompileBitmap (IMEMENU_HEADER *pHeader, HBITMAP hBitmap)
LRESULT ImmPutImeMenuItemsIntoMappedFile (HIMC hImc)
HBITMAP InternalImeMenuCreateBitmap (IMEMENU_BMP_HEADER *lpBH)
DWORD ImmGetImeMenuItemsInterProcess (HIMC hImc, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOW lpParentMenu, LPIMEMENUITEMINFOW lpMenu, DWORD dwSize)
DWORD ImmGetImeMenuItemsWorker (HIMC hIMC, DWORD dwFlags, DWORD dwType, LPVOID lpImeParentMenu, LPVOID lpImeMenu, DWORD dwSize, BOOL bAnsiOrigin)
DWORD WINAPI ImmGetImeMenuItemsA (HIMC hIMC, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOA lpImeParentMenu, LPIMEMENUITEMINFOA lpImeMenu, DWORD dwSize)
DWORD WINAPI ImmGetImeMenuItemsW (HIMC hIMC, DWORD dwFlags, DWORD dwType, LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu, DWORD dwSize)


Define Documentation

#define CHK_OFFSET  ) 
 

Definition at line 82 of file imemenu.c.

Referenced by ImmPutImeMenuItemsIntoMappedFile().

#define CHK_PTR  ) 
 

Value:

if ((x) != NULL) { \ if ((LPVOID)(x) < (LPVOID)pHeader || (LPBYTE)(x) > (LPBYTE)pHeader + pHeader->dwMemSize) { \ goto cleanup; \ } \ }

Definition at line 83 of file imemenu.c.

Referenced by DecompileBitmap(), ImmGetImeMenuItemsInterProcess(), and ImmPutImeMenuItemsIntoMappedFile().

#define CONVTO_OFFSET  )     ((x) = (LPVOID)((x) ? ((LPBYTE)(x) - offset) : NULL))
 

Definition at line 68 of file imemenu.c.

Referenced by ImmGetImeMenuItemsInterProcess(), and ImmPutImeMenuItemsIntoMappedFile().

#define CONVTO_PTR  )     ((x) = (LPVOID)((x) ? ((LPBYTE)(x) + offset) : NULL))
 

Definition at line 69 of file imemenu.c.

Referenced by ImmGetImeMenuItemsInterProcess(), and ImmPutImeMenuItemsIntoMappedFile().

#define D  ) 
 

Definition at line 17 of file imemenu.c.

Referenced by ImmIsUIMessageWorker(), and ImmPutImeMenuItemsIntoMappedFile().

#define DumpBytes a,
 ) 
 

Definition at line 155 of file imemenu.c.

Referenced by SaveBitmapToMemory().

#define IME_MENU_FILE_NAME   L"ImmMenuInfo"
 

Definition at line 20 of file imemenu.c.

Referenced by ImmGetImeMenuItemsInterProcess(), and ImmPutImeMenuItemsIntoMappedFile().

#define IME_MENU_MAXMEM   (128 * 1024)
 

Definition at line 21 of file imemenu.c.

Referenced by ImmGetImeMenuItemsInterProcess().


Typedef Documentation

typedef struct _IMEMENU_BMP_HEADER IMEMENU_BMP_HEADER
 


Function Documentation

void ConvertImeMenuItemInfoAtoW LPIMEMENUITEMINFOA  lpA,
LPIMEMENUITEMINFOW  lpW,
int  nCP,
BOOL  copyBmp
 

Definition at line 90 of file imemenu.c.

References L.

Referenced by ImmGetImeMenuItemsWorker().

00091 { 00092 int i; 00093 00094 lpW->cbSize = lpA->cbSize; 00095 lpW->fType = lpA->fType; 00096 lpW->fState = lpA->fState; 00097 lpW->wID = lpA->wID; 00098 if (copyBmp) { 00099 lpW->hbmpChecked = lpA->hbmpChecked; 00100 lpW->hbmpUnchecked = lpA->hbmpUnchecked; 00101 lpW->hbmpItem = lpA->hbmpItem; 00102 } 00103 lpW->dwItemData = lpA->dwItemData; 00104 00105 i = MultiByteToWideChar(nCP, 00106 0, 00107 lpA->szString, 00108 lstrlenA(lpA->szString), 00109 lpW->szString, 00110 IMEMENUITEM_STRING_SIZE); 00111 00112 lpW->szString[i] = L'\0'; 00113 }

void ConvertImeMenuItemInfoWtoA LPIMEMENUITEMINFOW  lpW,
LPIMEMENUITEMINFOA  lpA,
int  nCP
 

Definition at line 115 of file imemenu.c.

References BOOL, and NULL.

Referenced by ImmGetImeMenuItemsWorker().

00116 { 00117 int i; 00118 BOOL bUDC; 00119 00120 lpA->cbSize = lpW->cbSize; 00121 lpA->fType = lpW->fType; 00122 lpA->fState = lpW->fState; 00123 lpA->wID = lpW->wID; 00124 lpA->hbmpChecked = lpW->hbmpChecked; 00125 lpA->hbmpUnchecked = lpW->hbmpUnchecked; 00126 lpA->dwItemData = lpW->dwItemData; 00127 lpA->hbmpItem = lpW->hbmpItem; 00128 00129 00130 i = WideCharToMultiByte(nCP, 00131 0, 00132 lpW->szString, 00133 wcslen(lpW->szString), 00134 lpA->szString, 00135 IMEMENUITEM_STRING_SIZE, 00136 (LPSTR)NULL, 00137 &bUDC); 00138 00139 lpA->szString[i] = '\0'; 00140 }

IMEMENU_BMP_HEADER* DecompileBitmap IMEMENU_HEADER pHeader,
HBITMAP  hBitmap
 

Definition at line 254 of file imemenu.c.

References CHK_PTR, GetDC, GetDesktopWindow(), _IMEMENU_BMP_HEADER::hBitmap, IMEMENU_HEADER::lpBmp, IMEMENU_HEADER::lpBmpNext, _IMEMENU_BMP_HEADER::lpNext, NULL, ReleaseDC(), and SaveBitmapToMemory().

Referenced by ImmPutImeMenuItemsIntoMappedFile().

00255 { 00256 IMEMENU_BMP_HEADER* pBmp = pHeader->lpBmp; 00257 HDC hDC; 00258 00259 // first search handled bitmap 00260 while (pBmp) { 00261 if (pBmp->hBitmap == hBitmap) { 00262 // if hBitmap is already de-compiled, return it 00263 return pBmp; 00264 } 00265 pBmp = pBmp->lpNext; 00266 } 00267 00268 // not yet allocated, so prepare memory buffer 00269 pBmp = pHeader->lpBmpNext; 00270 UserAssert(pBmp != NULL); 00271 CHK_PTR(pBmp); 00272 if (pBmp == NULL) { 00273 RIPMSG1(RIP_WARNING, "DecompileBitmap: pBmp == NULL in L%d", __LINE__); 00274 return NULL; 00275 } 00276 00277 // use desktop's DC 00278 hDC = GetDC(GetDesktopWindow()); 00279 if (hDC == NULL) { 00280 RIPMSG1(RIP_WARNING, "DecompileBitmap: hDC == NULL in L%d", __LINE__); 00281 return NULL; 00282 } 00283 00284 // 00285 // decompile hBitmap 00286 // 00287 pBmp->lpNext = pHeader->lpBmp; 00288 pHeader->lpBmpNext = SaveBitmapToMemory(hDC, hBitmap, pBmp, pHeader); 00289 if (pHeader->lpBmpNext == NULL) { 00290 RIPMSG1(RIP_WARNING, "DecompileBitmap: pHeader->lpBmpNext == NULL in L%d", __LINE__); 00291 // error case. restore bmp link, then returns NULL 00292 pHeader->lpBmpNext = pBmp; 00293 pHeader->lpBmp = pBmp->lpNext; 00294 pBmp = NULL; 00295 goto cleanup; 00296 } 00297 00298 // if succeeded, mark this BITMAP_HEADER with hBitmap 00299 pBmp->hBitmap = hBitmap; 00300 00301 // 00302 // put this BITMAP_HEADER in linked list 00303 // 00304 pHeader->lpBmp = pBmp; 00305 00306 cleanup: 00307 if (hDC) 00308 ReleaseDC(GetDesktopWindow(), hDC); 00309 return pBmp; 00310 }

DWORD WINAPI ImmGetImeMenuItemsA HIMC  hIMC,
DWORD  dwFlags,
DWORD  dwType,
LPIMEMENUITEMINFOA  lpImeParentMenu,
LPIMEMENUITEMINFOA  lpImeMenu,
DWORD  dwSize
 

Definition at line 953 of file imemenu.c.

References dwFlags, DWORD, ImmGetImeMenuItemsWorker(), LPVOID, and TRUE.

00960 { 00961 return ImmGetImeMenuItemsWorker(hIMC, dwFlags, dwType, 00962 (LPVOID)lpImeParentMenu, 00963 (LPVOID)lpImeMenu, dwSize, TRUE /* ANSI origin */); 00964 }

DWORD ImmGetImeMenuItemsInterProcess HIMC  hImc,
DWORD  dwFlags,
DWORD  dwType,
LPIMEMENUITEMINFOW  lpParentMenu,
LPIMEMENUITEMINFOW  lpMenu,
DWORD  dwSize
 

Definition at line 560 of file imemenu.c.

References IMEMENU_ITEM::cbSize, CHK_PTR, CONVTO_OFFSET, CONVTO_PTR, dwFlags, DWORD, gcsImeDpi, _IMEMENU_BMP_HEADER::hBitmap, IME_MENU_FILE_NAME, IME_MENU_MAXMEM, InputContextDefaultImeWindow, InternalImeMenuCreateBitmap(), IsWindow(), IMEMENU_ITEM::lpBmpChecked, IMEMENU_ITEM::lpBmpItem, IMEMENU_ITEM::lpBmpUnchecked, _IMEMENU_BMP_HEADER::lpNext, LPVOID, NtUserQueryInputContext(), NULL, _IMEMENU_BMP_HEADER::pBits, and SendMessage().

Referenced by ImmGetImeMenuItemsWorker().

00566 { 00567 HWND hwnd; 00568 HANDLE hMemFile = NULL; 00569 DWORD dwRet = 0; 00570 LPBYTE lpMap = NULL; 00571 IMEMENU_HEADER* pHeader; 00572 IMEMENU_ITEM* pMenuItem; 00573 IMEMENU_BMP_HEADER* pBmpHeader; 00574 DWORD i; 00575 ULONG_PTR offset; 00576 00577 // Get default IME window 00578 // 00579 // Note: We do not consider user created HIMC here, because this inter-process call is intended to 00580 // support only internat.exe, and this message is passed as just a kick to IMM's def WinProc. 00581 hwnd = (HWND)NtUserQueryInputContext(hImc, InputContextDefaultImeWindow); 00582 if (hwnd == NULL || !IsWindow(hwnd)) { 00583 RIPMSG1(RIP_WARNING, "ImmGetImeMenuItemsInterProcess: hwnd(%lx) is not a valid window.", hwnd); 00584 return 0; 00585 } 00586 00587 RtlEnterCriticalSection(&gcsImeDpi); 00588 00589 // first, create memory mapped file 00590 hMemFile = CreateFileMapping((HANDLE)~0, NULL, PAGE_READWRITE, 00591 0, IME_MENU_MAXMEM, IME_MENU_FILE_NAME); 00592 if (hMemFile == NULL) { 00593 RIPMSG0(RIP_WARNING, "ImmGetImeMenuItemsInterProcess: cannot allocate memory mapped file."); 00594 goto cleanup; 00595 } 00596 // then get a view of the mapped file 00597 lpMap = (LPBYTE)MapViewOfFile(hMemFile, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); 00598 if (lpMap == NULL) { 00599 RIPMSG0(RIP_WARNING, "ImmGetImeMenuItemsInterProcess: cannot map view of memory mapped file."); 00600 goto cleanup; 00601 } 00602 00603 // 00604 // shared buffer (memory mapped file) initialization 00605 // 00606 pHeader = (IMEMENU_HEADER*)lpMap; 00607 RtlZeroMemory(pHeader, sizeof *pHeader); 00608 pHeader->dwVersion = 1; 00609 pHeader->dwMemSize = IME_MENU_MAXMEM; 00610 pHeader->dwSize = dwSize / sizeof(IMEMENUITEMINFOW); // CAUTION: dwSize could be 0. 00611 RIPMSG1(RIP_WARNING, "ImmGetImeMenuItemsInterProcess: pHeader->dwSize=%ld", pHeader->dwSize); 00612 pHeader->dwFlags = dwFlags; 00613 pHeader->dwType = dwType; 00614 00615 // 00616 // 1) dwSize != 0 and lpMenu != NULL means, caller requests the given buffer filled 00617 // 2) if lpParentMenu is passed, we need to put its information in shared buffer 00618 // 00619 if ((dwSize && lpMenu) || lpParentMenu) { 00620 // if parent menu is specified, copy it here 00621 if (lpParentMenu) { 00622 IMEMENU_ITEM* pPMenu = 00623 pHeader->lpImeParentMenu = (IMEMENU_ITEM*)&pHeader[1]; 00624 00625 RtlCopyMemory(pPMenu, lpParentMenu, sizeof(IMEMENUITEMINFOW)); 00626 00627 // by design, IME will receive NULL hbmpItem in parent menu. 00628 // there is no way to guarantee the same hbmpItem is returned, thus NULL is passed. 00629 pPMenu->lpBmpChecked = pPMenu->lpBmpUnchecked = pPMenu->lpBmpItem = NULL; 00630 pHeader->lpImeMenu = pHeader->lpImeParentMenu + 1; 00631 } 00632 else { 00633 pHeader->lpImeParentMenu = NULL; 00634 pHeader->lpImeMenu = (LPVOID)&pHeader[1]; 00635 } 00636 // convert pointer to offset 00637 offset = (ULONG_PTR)lpMap; 00638 CONVTO_OFFSET(pHeader->lpImeParentMenu); 00639 CONVTO_OFFSET(pHeader->lpImeMenu); 00640 } 00641 00642 00643 00644 00646 if (!SendMessage(hwnd, WM_IME_SYSTEM, IMS_GETIMEMENU, (LPARAM)hImc)) { 00647 // if it fails 00648 goto cleanup; 00649 } 00651 00652 // NOTE: dwSize is maximum index of menu array. not a total byte size of array. 00653 dwSize = pHeader->dwSize; 00654 00655 if (lpMenu) { 00657 // convert offset to pointer 00659 pMenuItem = CONVTO_PTR(pHeader->lpImeMenu); 00660 CHK_PTR(pMenuItem); 00661 // NOTE: we don't have to handle parent menu 00662 00663 // 00664 // pointers to BITMAP_HEADER in each menu structure 00665 // 00666 for (i = 0; i < dwSize; ++i, ++pMenuItem) { 00667 CONVTO_PTR(pMenuItem->lpBmpChecked); 00668 CONVTO_PTR(pMenuItem->lpBmpUnchecked); 00669 CONVTO_PTR(pMenuItem->lpBmpItem); 00670 // 00671 // check the pointers 00672 // 00673 CHK_PTR(pMenuItem->lpBmpChecked); 00674 CHK_PTR(pMenuItem->lpBmpUnchecked); 00675 CHK_PTR(pMenuItem->lpBmpItem); 00676 } 00677 00678 // 00679 // pointer to first BITMAP_HEADER 00680 // 00681 pBmpHeader = CONVTO_PTR(pHeader->lpBmp); 00682 00683 // 00684 // each BITMAP_HEADER 00685 // 00686 while (pBmpHeader) { 00687 pBmpHeader->hBitmap = NULL; // clear 00688 // pBits 00689 CONVTO_PTR(pBmpHeader->pBits); 00690 CHK_PTR(pBmpHeader->pBits); 00691 00692 // next BITMAP_HEADER 00693 pBmpHeader = CONVTO_PTR(pBmpHeader->lpNext); 00694 CHK_PTR(pBmpHeader); 00695 } 00696 00697 // 00698 // copy back the results 00699 // 00700 pMenuItem = pHeader->lpImeMenu; 00701 for (i = 0; i < dwSize; ++i, ++pMenuItem, ++lpMenu) { 00702 lpMenu->cbSize = pMenuItem->cbSize; 00703 lpMenu->fType = pMenuItem->fType; 00704 lpMenu->fState = pMenuItem->fState; 00705 lpMenu->wID = pMenuItem->wID; 00706 lpMenu->dwItemData = pMenuItem->dwItemData; 00707 wcscpy(lpMenu->szString, pMenuItem->szString); 00708 00709 // Create bitmap from memory buffer 00710 // hbmp will be NULL if no bmp is specified. 00711 if (pMenuItem->lpBmpChecked) { 00712 lpMenu->hbmpChecked = InternalImeMenuCreateBitmap(pMenuItem->lpBmpChecked); 00713 } 00714 else { 00715 lpMenu->hbmpChecked = NULL; 00716 } 00717 if (pMenuItem->lpBmpUnchecked) { 00718 lpMenu->hbmpUnchecked = InternalImeMenuCreateBitmap(pMenuItem->lpBmpUnchecked); 00719 } 00720 else { 00721 lpMenu->hbmpUnchecked = NULL; 00722 } 00723 if (pMenuItem->lpBmpItem) { 00724 lpMenu->hbmpItem = InternalImeMenuCreateBitmap(pMenuItem->lpBmpItem); 00725 } 00726 else { 00727 lpMenu->hbmpItem = NULL; 00728 } 00729 } 00730 } 00731 00732 00733 cleanup: 00734 if (lpMap) { 00735 UnmapViewOfFile(lpMap); 00736 } 00737 RtlLeaveCriticalSection(&gcsImeDpi); 00738 // destroy memory mapped file 00739 if (hMemFile) { 00740 CloseHandle(hMemFile); 00741 } 00742 00743 return dwSize; 00744 }

DWORD WINAPI ImmGetImeMenuItemsW HIMC  hIMC,
DWORD  dwFlags,
DWORD  dwType,
LPIMEMENUITEMINFOW  lpImeParentMenu,
LPIMEMENUITEMINFOW  lpImeMenu,
DWORD  dwSize
 

Definition at line 967 of file imemenu.c.

References dwFlags, DWORD, FALSE, ImmGetImeMenuItemsWorker(), and LPVOID.

Referenced by ImmPutImeMenuItemsIntoMappedFile().

00974 { 00975 return ImmGetImeMenuItemsWorker(hIMC, dwFlags, dwType, 00976 (LPVOID)lpImeParentMenu, 00977 (LPVOID)lpImeMenu, dwSize, FALSE /* UNICODE origin */); 00978 }

DWORD ImmGetImeMenuItemsWorker HIMC  hIMC,
DWORD  dwFlags,
DWORD  dwType,
LPVOID  lpImeParentMenu,
LPVOID  lpImeMenu,
DWORD  dwSize,
BOOL  bAnsiOrigin
 

Definition at line 759 of file imemenu.c.

References BOOL, ConvertImeMenuItemInfoAtoW(), ConvertImeMenuItemInfoWtoA(), tagIMEDPI::dwCodePage, dwFlags, DWORD, GetCurrentProcessId, GetInputContextProcess, GetInputContextThread, GetKeyboardLayout(), tagIMEDPI::_tagImeFunctions::ImeGetImeMenuItems, ImmGetImeMenuItemsInterProcess(), ImmLocalAlloc(), ImmLocalFree, ImmLockIMC(), ImmLockImeDpi(), ImmUnlockIMC(), ImmUnlockImeDpi(), IsAnsiIMC(), LPVOID, NULL, tagIMEDPI::pfn, TRACE, and TRUE.

Referenced by ImmGetImeMenuItemsA(), and ImmGetImeMenuItemsW().

00766 { 00767 BOOL bAnsiIme = IsAnsiIMC(hIMC); 00768 DWORD dwRet = 0; 00769 LPINPUTCONTEXT lpInputContext; 00770 DWORD dwThreadId; 00771 PIMEDPI pImeDpi = NULL; 00772 LPVOID lpImePTemp = lpImeParentMenu; // keeps parent menu 00773 LPVOID lpImeTemp = lpImeMenu; // points menu buffer 00774 IMEMENUITEMINFOA imiiParentA; 00775 IMEMENUITEMINFOW imiiParentW; 00776 00777 // 00778 // check if the call will be inter process 00779 // 00780 { 00781 DWORD dwProcessId = GetInputContextProcess(hIMC); 00782 if (dwProcessId == 0) { 00783 RIPMSG0(RIP_WARNING, "ImmGetImeMenuItemsWorker: dwProcessId == 0"); 00784 return 0; 00785 } 00786 if (dwProcessId != GetCurrentProcessId()) { 00787 // 00788 // going to call another process' IME 00789 // 00790 TRACE(("ImmGetImeMenuItemsWorker: Inter process.\n")); 00791 if (bAnsiOrigin) { 00792 // 00793 // this inter-process thing is only allowed to internat.exe or equivalent 00794 // 00795 RIPMSG0(RIP_WARNING, "ImmGetImeMenuItemsWorker: interprocess getmenu is not allowed for ANSI caller."); 00796 return 0; 00797 } 00798 return ImmGetImeMenuItemsInterProcess(hIMC, dwFlags, dwType, lpImeParentMenu, 00799 lpImeMenu, dwSize); 00800 } 00801 } 00802 00803 // 00804 // within process 00805 // 00806 00807 if (hIMC == NULL || (lpInputContext = ImmLockIMC(hIMC)) == NULL) { 00808 RIPMSG2(RIP_WARNING, "ImmGetImeMenuItemsWorker: illegal hIMC(%#lx) in L%d", hIMC, __LINE__); 00809 return 0; 00810 } 00811 00812 dwThreadId = GetInputContextThread(hIMC); 00813 if (dwThreadId == 0) { 00814 RIPMSG1(RIP_WARNING, "ImmGetImeMenuItemsWorker: dwThreadId = 0 in L%d", __LINE__); 00815 goto cleanup; 00816 } 00817 if ((pImeDpi = ImmLockImeDpi(GetKeyboardLayout(dwThreadId))) == NULL) { 00818 RIPMSG1(RIP_WARNING, "ImmGetImeMenuItemWorker: pImeDpi == NULL in L%d.", __LINE__); 00819 goto cleanup; 00820 } 00821 00822 #if 0 // NT: we don't keep version info in ImeDpi 00823 if (pImeDpi->dwWinVersion <= IMEVER_0310) { 00824 RIPMSG1(RIP_WARNING, "GetImeMenuItems: OldIME does not support this. %lx", hIMC); 00825 goto cleanup; 00826 } 00827 #endif 00828 00829 // 00830 // if IME does not support IME Menu, do nothing 00831 // 00832 if (pImeDpi->pfn.ImeGetImeMenuItems) { 00833 LPVOID lpNewBuf = NULL; 00834 00835 TRACE(("ImmGetImeMenuItemsWorker: IME has menu callback.\n")); 00836 00837 if (bAnsiIme != bAnsiOrigin) { 00838 // 00839 // we need A/W translation before calling IME 00840 // 00841 if (bAnsiOrigin) { 00842 // ANSI API and UNICODE IME. 00843 // A to W conversion needed here 00844 if (lpImeParentMenu) { 00845 // parent menu is specified. need conversion 00846 lpImePTemp = (LPVOID)&imiiParentW; 00847 ConvertImeMenuItemInfoAtoW((LPIMEMENUITEMINFOA)lpImeParentMenu, 00848 (LPIMEMENUITEMINFOW)lpImePTemp, 00849 CP_ACP, TRUE); // ANSI app, UNICODE IME: let's use CP_ACP 00850 } 00851 if (lpImeMenu) { 00852 // allocate memory block for temporary storage 00853 DWORD dwNumBuffer = dwSize / sizeof(IMEMENUITEMINFOA); 00854 dwSize = dwNumBuffer * sizeof(IMEMENUITEMINFOW); 00855 if (dwSize == 0) { 00856 RIPMSG0(RIP_WARNING, "ImmGetImeMenuItemsWorker: (AtoW) dwSize is 0."); 00857 goto cleanup; 00858 } 00859 lpImeTemp = lpNewBuf = ImmLocalAlloc(0, dwSize); 00860 TRACE(("ImmGetImeMenuItemsWorker: for UNICODE IME memory allocated %d bytes. lpNewBuf=%#x\n", dwSize, lpNewBuf)); 00861 if (lpNewBuf == NULL) { 00862 RIPMSG1(RIP_WARNING, "ImmGetImeMenuItemsWorker: cannot alloc lpNewBuf in L%d", __LINE__); 00863 goto cleanup; 00864 } 00865 } 00866 } 00867 else { 00868 // UNICODE API and ANSI IME. 00869 // W to A conversion needed here 00870 if (lpImeParentMenu) { 00871 // parent menu is speicified. need conversion 00872 lpImePTemp = (LPVOID)&imiiParentA; 00873 ConvertImeMenuItemInfoWtoA((LPIMEMENUITEMINFOW)lpImeParentMenu, 00874 (LPIMEMENUITEMINFOA)lpImePTemp, 00875 pImeDpi->dwCodePage); // Note: hopefully in the future, this can be changed to IMECodePage(pImeDpi) 00876 } 00877 if (lpImeMenu) { 00878 // allocate memory block for temporary storage 00879 DWORD dwNumBuffer = dwSize / sizeof(IMEMENUITEMINFOW); 00880 dwSize = dwNumBuffer / sizeof(IMEMENUITEMINFOA); 00881 if (dwSize == 0) { 00882 RIPMSG0(RIP_WARNING, "ImmGetImeMenuItemsWorker: (WtoA) dwSize is 0."); 00883 goto cleanup; 00884 } 00885 lpImeTemp = lpNewBuf = ImmLocalAlloc(0, dwSize); 00886 RIPMSG2(RIP_WARNING, "ImmGetImeMenuItemsWorker: for ANSI IME memory allocated %d bytes. lpNewBuf=%#x", dwSize, lpNewBuf); 00887 if (lpNewBuf == NULL) { 00888 RIPMSG1(RIP_WARNING, "ImmGetImeMenuItemsWorker: cannot alloc lpNewBuf in L%d", __LINE__); 00889 goto cleanup; 00890 } 00891 } 00892 } 00893 } 00894 00896 dwRet = pImeDpi->pfn.ImeGetImeMenuItems(hIMC, dwFlags, dwType, lpImePTemp, lpImeTemp, dwSize); 00898 00899 // 00900 // back-conversion needed if: 00901 // 1) IME returns menus, and 00902 // 2) A/W is different between caller and IME, and 00903 // 3) caller wants the buffer to be filled 00904 // 00905 if (dwRet && bAnsiIme != bAnsiOrigin && lpImeTemp) { 00906 if (bAnsiOrigin) { 00907 // ANSI API and UNICODE IME. 00908 // W to A conversion needed here 00909 LPIMEMENUITEMINFOW lpW = (LPIMEMENUITEMINFOW)lpImeTemp; 00910 LPIMEMENUITEMINFOA lpA = (LPIMEMENUITEMINFOA)lpImeMenu; 00911 DWORD i; 00912 00913 for (i = 0; i < dwRet; ++i) { 00914 ConvertImeMenuItemInfoWtoA((LPIMEMENUITEMINFOW)lpW++, 00915 (LPIMEMENUITEMINFOA)lpA++, 00916 CP_ACP); // ANSI app and UNICODE IME: let's use CP_ACP 00917 } 00918 } 00919 else { 00920 // UNICODE API and ANSI IME. 00921 // A to W conversion needed here 00922 LPIMEMENUITEMINFOA lpA = (LPIMEMENUITEMINFOA)lpImeTemp; 00923 LPIMEMENUITEMINFOW lpW = (LPIMEMENUITEMINFOW)lpImeMenu; 00924 DWORD i; 00925 00926 for (i = 0; i < dwSize; i++) { 00927 ConvertImeMenuItemInfoAtoW((LPIMEMENUITEMINFOA)lpA++, 00928 (LPIMEMENUITEMINFOW)lpW++, 00929 pImeDpi->dwCodePage, // Note: hopefully in the future, this can be changed to IMECodePage(pImeDpi) 00930 TRUE); // copy hbitmap also 00931 } 00932 } 00933 } 00934 00935 // free temporary buffer if we've allocated it 00936 if (lpNewBuf) 00937 ImmLocalFree(lpNewBuf); 00938 } // end if IME has menu callback 00939 00940 cleanup: 00941 if (pImeDpi) { 00942 ImmUnlockImeDpi(pImeDpi); 00943 } 00944 00945 if (hIMC != NULL) { 00946 ImmUnlockIMC(hIMC); 00947 } 00948 00949 return dwRet; 00950 }

LRESULT ImmPutImeMenuItemsIntoMappedFile HIMC  hImc  ) 
 

Definition at line 325 of file imemenu.c.

References CHK_OFFSET, CHK_PTR, CONVTO_OFFSET, CONVTO_PTR, D, DecompileBitmap(), IMEMENU_HEADER::dwFlags, DWORD, IMEMENU_HEADER::dwSize, IMEMENU_HEADER::dwType, IMEMENU_HEADER::dwVersion, FALSE, IME_MENU_FILE_NAME, ImmGetImeMenuItemsW(), ImmLocalAlloc(), ImmLocalFree, L, IMEMENU_HEADER::lpBmp, IMEMENU_ITEM::lpBmpChecked, IMEMENU_ITEM::lpBmpItem, IMEMENU_HEADER::lpBmpNext, IMEMENU_ITEM::lpBmpUnchecked, IMEMENU_HEADER::lpImeMenu, IMEMENU_HEADER::lpImeParentMenu, _IMEMENU_BMP_HEADER::lpNext, LPVOID, NULL, _IMEMENU_BMP_HEADER::pBits, and TRACE.

Referenced by _InitializeImmEntryTable().

00326 { 00327 HANDLE hMap = NULL; 00328 LPVOID lpMap = NULL; 00329 IMEMENU_HEADER* pHeader; 00330 LPIMEMENUITEMINFO lpBuf = NULL; 00331 IMEMENU_ITEM* pMenu; 00332 IMEMENU_BMP_HEADER* pBmp; 00333 LRESULT lRet = 0; 00334 ULONG_PTR offset; 00335 DWORD i; 00336 00337 // Open memory mapped file 00338 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, IME_MENU_FILE_NAME); 00339 if (hMap == NULL) { 00340 RIPMSG0(RIP_WARNING, "ImmPutImeMenuItemsIntoMappedFile: cannot open mapped file."); 00341 return 0L; 00342 } 00343 00344 // Map entire view of the file into the process memory space 00345 lpMap = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 00346 if (lpMap == NULL) { 00347 RIPMSG0(RIP_WARNING, "ImmPutImeMenuItemsIntoMappedFile: cannot map view of file."); 00348 goto cleanup; 00349 // I wish if I could use C++... 00350 } 00351 00352 pHeader = (IMEMENU_HEADER*)lpMap; 00353 00355 // Version check 00357 if (pHeader->dwVersion != 1) { 00358 RIPMSG1(RIP_WARNING, "ImmPutImeMenuItemsIntoMappedFile: dwVersion(%d) does not match.", 00359 pHeader->dwVersion); 00360 goto cleanup; 00361 } 00362 00364 // convert offset to pointer 00365 offset = (ULONG_PTR)pHeader; 00366 CONVTO_PTR(pHeader->lpImeParentMenu); 00367 CHK_PTR(pHeader->lpImeParentMenu); 00368 pMenu = CONVTO_PTR(pHeader->lpImeMenu); 00369 CHK_PTR(pHeader->lpImeMenu); 00370 if (pHeader->dwSize) { 00371 UserAssert(pHeader->lpImeMenu); // if dwSize is specified, we need real buffer here 00372 lpBuf = ImmLocalAlloc(HEAP_ZERO_MEMORY, pHeader->dwSize * sizeof(IMEMENUITEMINFOW)); 00373 if (lpBuf == NULL) { 00374 RIPMSG0(RIP_WARNING, "ImmPutImeMenuItemsIntoMappedFile: not enough memory for receiver's buffer."); 00375 goto cleanup; 00376 } 00377 } 00378 00379 00380 // preparation 00381 #if DBG 00382 if (pHeader->lpImeParentMenu) { 00383 UserAssert(!pHeader->lpImeParentMenu->lpBmpChecked && 00384 !pHeader->lpImeParentMenu->lpBmpUnchecked && 00385 !pHeader->lpImeParentMenu->lpBmpItem); 00386 } 00387 #endif 00388 00390 // Get IME menus 00391 pHeader->dwSize = ImmGetImeMenuItemsW(hImc, pHeader->dwFlags, pHeader->dwType, 00392 (LPIMEMENUITEMINFOW)pHeader->lpImeParentMenu, lpBuf, 00393 pHeader->dwSize * sizeof(IMEMENUITEMINFOW)); 00394 // now, pHeader->dwSize contains number of menu items rather than byte size 00395 if (pHeader->dwSize == 0) { 00396 goto cleanup; 00397 } 00399 00400 // 00401 // Copy back the information 00402 // 00403 // if lpBuf != NULL, we need to copy back information 00404 // 00405 if (lpBuf) { 00406 LPIMEMENUITEMINFO lpMenuW = lpBuf; 00407 00408 pHeader->lpBmp = NULL; 00409 // lpBmpNext will point first possible memory for bmp de-compile 00410 pHeader->lpBmpNext = (LPVOID)((LPBYTE)pHeader + (pHeader->dwSize + 1) * sizeof(IMEMENUITEMINFOW)); 00411 00412 // copy menuinfo 00413 for (i = 0; i < pHeader->dwSize; ++i, ++pMenu, ++lpMenuW) { 00414 RtlCopyMemory(pMenu, lpMenuW, sizeof *lpMenuW); 00415 // decompile hbitmap 00416 if (lpMenuW->hbmpChecked) { 00417 if ((pMenu->lpBmpChecked = DecompileBitmap(pHeader, lpMenuW->hbmpChecked)) == NULL) { 00418 RIPMSG1(RIP_WARNING, "ImmPutImeMenuItemsIntoMappedFile: DecompileBitmap Failed in L%d", __LINE__); 00419 goto cleanup; 00420 } 00421 } 00422 if (lpMenuW->hbmpUnchecked) { 00423 if ((pMenu->lpBmpUnchecked = DecompileBitmap(pHeader, lpMenuW->hbmpUnchecked)) == NULL) { 00424 RIPMSG1(RIP_WARNING, "ImmPutImeMenuItemsIntoMappedFile: DecompileBitmap Failed in L%d", __LINE__); 00425 goto cleanup; 00426 } 00427 } 00428 if (lpMenuW->hbmpItem) { 00429 if ((pMenu->lpBmpItem = DecompileBitmap(pHeader, lpMenuW->hbmpItem)) == NULL) { 00430 RIPMSG1(RIP_WARNING, "ImmPutImeMenuItemsIntoMappedFile: DecompileBitmap Failed in L%d", __LINE__); 00431 goto cleanup; 00432 } 00433 } 00434 } 00435 00437 // 00438 // convert pointer to offset 00439 // 00440 00441 pMenu = pHeader->lpImeMenu; 00442 CONVTO_OFFSET(pHeader->lpImeMenu); 00443 // no need to convert parent menu, so let it be NULL 00444 D(pHeader->lpImeParentMenu = NULL); 00445 00446 // pointer to BITMAP_HEADER in each menu 00447 for (i = 0; i < pHeader->dwSize; ++i, ++pMenu) { 00448 TRACE(("ImmPutImeMenuItemsIntoMappedFile: convertiong '%S'\n", pMenu->szString)); 00449 CONVTO_OFFSET(pMenu->lpBmpChecked); 00450 CONVTO_OFFSET(pMenu->lpBmpUnchecked); 00451 TRACE(("ImmPutImeMenuItemsIntoMappedFile: before conversion (%#lx)\n", pMenu->lpBmpItem)); 00452 CONVTO_OFFSET(pMenu->lpBmpItem); 00453 TRACE(("ImmPutImeMenuItemsIntoMappedFile: after conversion (%#lx)\n", pMenu->lpBmpItem)); 00454 00455 // check them 00456 CHK_OFFSET(pMenu->lpBmpChecked); 00457 CHK_OFFSET(pMenu->lpBmpChecked); 00458 CHK_OFFSET(pMenu->lpBmpItem); 00459 } 00460 00461 // 00462 // first pointer to BITMAP_HEADER linked list 00463 // 00464 pBmp = pHeader->lpBmp; 00465 CONVTO_OFFSET(pHeader->lpBmp); 00466 CHK_OFFSET(pHeader->lpBmp); 00467 // pHeader->lpBmpNext will not be used, so let it be NULL 00468 D(pHeader->lpBmpNext = NULL); 00469 00470 // 00471 // pointers in BITMAP_HEADER linked list 00472 // 00473 while (pBmp) { 00474 IMEMENU_BMP_HEADER* ptBmp = pBmp->lpNext; 00475 CONVTO_OFFSET(pBmp->pBits); 00476 CONVTO_OFFSET(pBmp->lpNext); 00477 CHK_OFFSET(pBmp->lpNext); 00478 pBmp = ptBmp; 00479 } 00480 // 00481 // pointer conversion finished 00482 // 00484 } // end if (lpBuf) 00485 00486 // 00487 // everything went OK 00488 // 00489 lRet = 1; 00490 00491 cleanup: 00492 if (lpBuf) 00493 ImmLocalFree(lpBuf); 00494 if (lpMap) 00495 UnmapViewOfFile(lpMap); 00496 if (hMap) 00497 CloseHandle(hMap); 00498 return lRet; 00499 }

HBITMAP InternalImeMenuCreateBitmap IMEMENU_BMP_HEADER lpBH  ) 
 

Definition at line 508 of file imemenu.c.

References _IMEMENU_BMP_HEADER::bmi, DWORD, GetDC, GetDesktopWindow(), _IMEMENU_BMP_HEADER::hBitmap, NULL, _IMEMENU_BMP_HEADER::pBits, ReleaseDC(), and TRACE.

Referenced by ImmGetImeMenuItemsInterProcess().

00509 { 00510 HDC hDC; 00511 00512 if (lpBH == NULL) { 00513 RIPMSG1(RIP_WARNING, "InternalImeMenuCreateBitmap: lpBH == NULL in L%d", __LINE__); 00514 return NULL; 00515 } 00516 if (lpBH->pBits == NULL) { 00517 RIPMSG1(RIP_WARNING, "InternalImeMenuCreateBitmap: lpBH->pBits == NULL in L%d", __LINE__); 00518 return NULL; 00519 } 00520 00521 if (lpBH->hBitmap) { 00522 TRACE(("InternalImeMenuCreateBitmap: lpBH->hBitmap != NULL. will return it.\n")); 00523 return lpBH->hBitmap; 00524 } 00525 00526 if (hDC = GetDC(GetDesktopWindow())) { 00527 HDC hMyDC = CreateCompatibleDC(hDC); 00528 if (hMyDC) { 00529 // (select palette) needed ? 00530 lpBH->hBitmap = CreateDIBitmap(hDC, &lpBH->bmi.bmiHeader, CBM_INIT, 00531 lpBH->pBits, &lpBH->bmi, DIB_RGB_COLORS); 00532 if (lpBH->hBitmap == NULL) { 00533 DWORD dwErr = GetLastError(); 00534 RIPMSG1(RIP_WARNING, "InternalImeMenuCreateBitmap: CreateDIBitmap Failed. Last error=%#x\n", dwErr); 00535 } 00536 DeleteDC(hMyDC); 00537 } 00538 else { 00539 RIPMSG0(RIP_WARNING, "InternalImeMenuCreateBitmap: CreateCompatibleDC failed."); 00540 } 00541 00542 ReleaseDC(GetDesktopWindow(), hDC); 00543 } 00544 else { 00545 RIPMSG0(RIP_WARNING, "InternalImeMenuCreateBitmap: couldn't get Desktop DC."); 00546 } 00547 return lpBH->hBitmap; 00548 }

IMEMENU_BMP_HEADER* SaveBitmapToMemory HDC  hDC,
HBITMAP  hBmp,
IMEMENU_BMP_HEADER lpBH,
IMEMENU_HEADER pHeader
 

Definition at line 161 of file imemenu.c.

References _IMEMENU_BMP_HEADER::bmi, DumpBytes, IMEMENU_HEADER::dwMemSize, DWORD, FALSE, NULL, and _IMEMENU_BMP_HEADER::pBits.

Referenced by DecompileBitmap().

00162 { 00163 HBITMAP hTmpBmp, hBmpOld; 00164 IMEMENU_BMP_HEADER* lpNext = NULL; 00165 PBITMAPINFO pbmi = &lpBH->bmi; 00166 ULONG sizBMI; 00167 00168 00169 if (!hBmp) { 00170 RIPMSG0(RIP_WARNING, "SaveBitmapToMemory: hBmp == NULL"); 00171 return NULL; 00172 } 00173 UserAssert(lpBH != NULL); 00174 00175 // 00176 // Let the graphics engine to retrieve the dimension of the bitmap for us 00177 // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO 00178 // if BitCount != 0, color table will be retrieved 00179 // 00180 pbmi->bmiHeader.biSize = sizeof pbmi->bmiHeader; 00181 pbmi->bmiHeader.biBitCount = 0; // don't get the color table 00182 if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)NULL, pbmi, DIB_RGB_COLORS)) == 0) { 00183 RIPMSG0(RIP_WARNING, "SaveBitmapToMemory: failed to GetDIBits(NULL)"); 00184 return NULL; 00185 } 00186 00187 00188 // 00189 // Note: 24 bits per pixel has no color table. So, we don't have to 00190 // allocate memory for retrieving that. Otherwise, we do. 00191 // 00192 switch (pbmi->bmiHeader.biBitCount) { 00193 case 24: // has color table 00194 sizBMI = sizeof(BITMAPINFOHEADER); 00195 break; 00196 case 16: 00197 case 32: 00198 sizBMI = sizeof(BITMAPINFOHEADER) + sizeof(DWORD) * 3; 00199 break; 00200 default: 00201 sizBMI = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << pbmi->bmiHeader.biBitCount); 00202 break; 00203 00204 } 00205 00206 // 00207 // check if the buffer has enough space to put bitmap 00208 // 00209 if ((LPBYTE)pHeader + pHeader->dwMemSize < (LPBYTE)lpBH + sizeof lpBH + sizBMI + pbmi->bmiHeader.biSizeImage) { 00210 RIPMSG0(RIP_WARNING, "SaveBitmapToMemory: size of bmp image(s) exceed limit "); 00211 return FALSE; 00212 } 00213 00214 // 00215 // Now that we know the size of the image, let pBits point the given buffer 00216 // 00217 lpBH->pBits = (LPBYTE)pbmi + sizBMI; 00218 00219 // 00220 // Bitmap can't be selected into a DC when calling GetDIBits 00221 // Assume that the hDC is the DC where the bitmap would have been selected 00222 // if indeed it has been selected 00223 // 00224 if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) { 00225 hBmpOld = SelectObject(hDC, hTmpBmp); 00226 if (GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)lpBH->pBits, pbmi, DIB_RGB_COLORS) == 0){ 00227 SelectObject(hDC, hBmpOld); 00228 RIPMSG0(RIP_WARNING, "SaveBitmapToMemory: GetDIBits() failed."); 00229 return NULL; 00230 } 00231 lpNext = (IMEMENU_BMP_HEADER*)((LPBYTE)pbmi + sizBMI + pbmi->bmiHeader.biSizeImage); 00232 00233 DumpBytes((LPBYTE)pbmi, sizeof *pbmi); 00234 } else { 00235 RIPMSG0(RIP_WARNING, "SaveBitmapToMemory: CreateCompatibleBitmap() failed."); 00236 return NULL; 00237 } 00238 00239 SelectObject(hDC, hBmpOld); 00240 DeleteObject(hTmpBmp); 00241 return lpNext; 00242 }


Generated on Sat May 15 19:44:09 2004 for test by doxygen 1.3.7