| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /******************************************************************************
- *
- * FILE
- * $Archive: /Commando/Code/wwui/IMECandidate.cpp $
- *
- * DESCRIPTION
- *
- * PROGRAMMER
- * $Author: Denzil_l $
- *
- * VERSION INFO
- * $Revision: 4 $
- * $Modtime: 1/12/02 9:43p $
- *
- ******************************************************************************/
- #include "IMECandidate.h"
- #include "WWDebug.h"
- namespace IME {
- /******************************************************************************
- *
- * NAME
- * IMECandidate::IMECandidate
- *
- * DESCRIPTION
- * Default constructor
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- IMECandidate::IMECandidate() :
- mCandidateSize(0),
- mCandidates(NULL)
- {
- Close();
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::~IMECandidate
- *
- * DESCRIPTION
- * Destructor
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- IMECandidate::~IMECandidate()
- {
- if (mCandidates)
- {
- delete[] mCandidates;
- }
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::Open
- *
- * DESCRIPTION
- *
- * INPUTS
- * Index - Candidate Index ID
- * HWND - Window IME is associated with
- * CodePage - Code page for current input mode.
- * Unicode - If true, process IME as unicode; if false, process as MBCS
- * StartFrom1 - If true, candidates should be displayed starting from 1
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void IMECandidate::Open(int id, HWND hwnd, UINT codepage, bool unicode, bool startFrom1)
- {
- mIndex = id;
- mHWND = hwnd;
- mCodePage = codepage;
- mUseUnicode = unicode;
- mStartFrom1 = startFrom1;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::Read
- *
- * DESCRIPTION
- * Read the candidate list from IMM
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void IMECandidate::Read(void)
- {
- HIMC imc = ImmGetContext(mHWND);
- if (imc)
- {
- DWORD size = 0;
- // Get the size of the candidate list
- if (mUseUnicode)
- {
- size = ImmGetCandidateListW(imc, mIndex, NULL, 0);
- }
- else
- {
- size = ImmGetCandidateList(imc, mIndex, NULL, 0);
- }
- // Allocate space to hold candidates
- if ((mCandidates == NULL) || (size > mCandidateSize))
- {
- // Free the existing candidate buffer
- if (mCandidates != NULL)
- {
- delete[] mCandidates;
- }
- // Allocate a new buffer to hold the candidates
- mCandidates = (CANDIDATELIST*)(new unsigned char[size]);
- mCandidateSize = size;
- }
- if (mCandidates != NULL)
- {
- if (mUseUnicode)
- {
- ImmGetCandidateListW(imc, mIndex, mCandidates, mCandidateSize);
- }
- else
- {
- ImmGetCandidateList(imc, mIndex, mCandidates, mCandidateSize);
- }
- WWDEBUG_SAY(("IMECandidate: Index %d, Style %08lX, Selection %d, PageStart %d, PageSize %d, Count %d\n",
- mIndex, GetStyle(), GetSelection(), GetPageStart(), GetPageSize(), GetCount()));
- }
- ImmReleaseContext(mHWND, imc);
- }
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::Close
- *
- * DESCRIPTION
- * Close the candidate.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void IMECandidate::Close(void)
- {
- mIndex = -1;
- mHWND = NULL;
- mCodePage = CP_ACP;
- mUseUnicode = true;
- mStartFrom1 = true;
- if (mCandidates)
- {
- memset(mCandidates, 0, sizeof(CANDIDATELIST));
- }
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::IsValid
- *
- * DESCRIPTION
- * Check if the candidate data is valid.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * True if valid
- *
- ******************************************************************************/
- bool IMECandidate::IsValid(void) const
- {
- return ((-1 != mIndex) && (mCandidates != NULL));
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::GetIndex
- *
- * DESCRIPTION
- * Get the candidate index ID
- *
- * INPUTS
- * NONE
- *
- * RESULT
- * Candidate index ID
- *
- ******************************************************************************/
- int IMECandidate::GetIndex(void) const
- {
- return mIndex;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::GetStyle
- *
- * DESCRIPTION
- *
- * INPUTS
- * NONE
- *
- * RESULT
- *
- ******************************************************************************/
- unsigned long IMECandidate::GetStyle(void) const
- {
- WWASSERT(mCandidates != NULL);
- return mCandidates->dwStyle;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::GetPageStart
- *
- * DESCRIPTION
- *
- * INPUTS
- *
- * RESULT
- *
- ******************************************************************************/
- unsigned long IMECandidate::GetPageStart(void) const
- {
- WWASSERT(mCandidates != NULL);
- return mCandidates->dwPageStart;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::SetPageStart
- *
- * DESCRIPTION
- *
- * INPUTS
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void IMECandidate::SetPageStart(unsigned long start)
- {
- WWASSERT((start >=0) && (start < GetCount()));
- if ((start >=0) && (start < GetCount()))
- {
- HIMC imc = ImmGetContext(mHWND);
- if (imc)
- {
- // The IMM documentation says that the candidate list index must
- // be in the range of 0 - 3 for NI_SETCANDIDATE_PAGESTART
- WWASSERT((mIndex >= 0 && mIndex <= 3) && "IMM parameter error");
- ImmNotifyIME(imc, NI_SETCANDIDATE_PAGESTART, mIndex, start);
- ImmReleaseContext(mHWND, imc);
- }
- }
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::GetPageSize
- *
- * DESCRIPTION
- * Get the number of candidates per page.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- *
- ******************************************************************************/
- unsigned long IMECandidate::GetPageSize(void) const
- {
- WWASSERT(mCandidates != NULL);
- return mCandidates->dwPageSize;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::GetCount
- *
- * DESCRIPTION
- * Get the total number of candidates.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- *
- ******************************************************************************/
- // Get the number of candidates in the list.
- unsigned long IMECandidate::GetCount(void) const
- {
- if (mCandidates)
- {
- return mCandidates->dwCount;
- }
- return 0;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::GetSelection
- *
- * DESCRIPTION
- * Get the index of the currently selected candidate.
- *
- * INPUTS
- * NONE
- *
- * RESULT
- *
- ******************************************************************************/
- unsigned long IMECandidate::GetSelection(void) const
- {
- WWASSERT(mCandidates != NULL);
- return mCandidates->dwSelection;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::IsStartFrom1
- *
- * DESCRIPTION
- * Check if the candidates should be listed as starting from 1 or 0
- *
- * INPUTS
- * NONE
- *
- * RESULT
- *
- ******************************************************************************/
- bool IMECandidate::IsStartFrom1(void) const
- {
- return mStartFrom1;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::GetCandidate
- *
- * DESCRIPTION
- * Get a candidate string.
- *
- * INPUTS
- * Index of the candidate string to get.
- *
- * RESULT
- * String
- *
- ******************************************************************************/
- const wchar_t* IMECandidate::GetCandidate(unsigned long index)
- {
- if (index < GetCount())
- {
- // For the IME_CAND_CODE style, the candidate list has a special structure
- // depending on the value of the dwCount member. If dwCount is 1, the dwOffset
- // member contains a single DBCS character rather than an offset, and no
- // candidate string is provided. If the dwCount member is greater than 1,
- // the dwOffset member contains valid offsets, and the candidate strings are
- // text representations of individual DBCS character values in hexadecimal notation.
- if ((IME_CAND_CODE == GetStyle()) && (1 == GetCount()))
- {
- unsigned long dbcs = mCandidates->dwOffset[0];
- // If this char has a lead byte then it is double byte. Swap the bytes
- // for generate string order
- if (dbcs & 0xFF00)
- {
- dbcs = (((dbcs & 0xFF) << 8) | (dbcs >> 8));
- }
- // Convert char to unicode
- MultiByteToWideChar(mCodePage, 0, (const char*)&dbcs, -1, mTempString, 1);
- mTempString[1] = 0;
- return mTempString;
- }
- DWORD offset = mCandidates->dwOffset[index];
- const char* candString = ((const char*)mCandidates + offset);
- if (mUseUnicode)
- {
- return ((const wchar_t*)candString);
- }
- MultiByteToWideChar(mCodePage, 0, candString, -1, mTempString, (sizeof(mTempString) / sizeof(wchar_t)));
- mTempString[(sizeof(mTempString) / sizeof(wchar_t)) - 1] = 0;
- return mTempString;
- }
-
- return NULL;
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::SelectCandidate
- *
- * DESCRIPTION
- * Select a string in the candidate list.
- *
- * INPUTS
- * Index of candidate string to select.
- *
- * RESULT
- * NONE
- *
- ******************************************************************************/
- void IMECandidate::SelectCandidate(unsigned long selection)
- {
- HIMC imc = ImmGetContext(mHWND);
- if (imc)
- {
- ImmNotifyIME(imc, NI_SELECTCANDIDATESTR, mIndex, selection);
- ImmNotifyIME(imc, NI_CLOSECANDIDATE, mIndex, 0);
- ImmReleaseContext(mHWND, imc);
- }
- }
- /******************************************************************************
- *
- * NAME
- * IMECandidate::SetView
- *
- * DESCRIPTION
- *
- * INPUTS
- * Top - Index of top candidate.
- * Bottom - Index of bottom candidate.
- *
- * RESULT
- *
- ******************************************************************************/
- void IMECandidate::SetView(unsigned long topIndex, unsigned long bottomIndex)
- {
- HIMC imc = ImmGetContext(mHWND);
- if (imc)
- {
- ImmNotifyIME(imc, NI_SETCANDIDATE_PAGESIZE, mIndex, (bottomIndex - topIndex) + 1);
- ImmNotifyIME(imc, NI_SETCANDIDATE_PAGESTART, mIndex, topIndex);
- ImmReleaseContext(mHWND, imc);
- }
- }
-
- } // namespace IME
|