このページの情報は、私のパソコン利用環境で、少なくとも1度は実行などしたものを記載していますが、
このページの情報を利用して損害などが生じても、私(このWEBページの作成者、programtips)は一切責任は負いません。
脅すわけではないですが、IME作成(というより作成したIMEを利用するために)はWindowsのレジストリを変更する必要もあり、
パソコンが動作不安定になったり、動かなくなったりする可能性が通常より高い点にはご注意ください。
エミューレーターや、OSのリカバリが問題ないパソコンが用意できれば、安全と思います。
もっとも、私もほかの用途などでも使っているパソコンを利用していますけれども。
またVisualStudio2015のインストールされた64ビット版Windows10パソコンを前提にしています。
簡単な漢字変換機能を持ったIMEプロジェクトを作成しました。
それを公開することは、公開することという点では簡単なのですが、
マイクロソフトのサンプルを延長して作成したものなので、
そのまま全部公開すると問題があるかもしれないという危惧があります。
また、マイクロソフトのサンプルのまま残っている部分を全部置き換えるということも考えたのですが、
それはこれから、いろいろ試してみようという人にとっては障害が増えることになるかもしれないという危惧と、手間がかかるという事情があります。
そこで、今回は、SDK7.1のサンプルtsfmarkをベースに、なるべく変更箇所を減らしたうえで、その追加変更部分という形で、公開したいと思います。
そのため、まずもとになるtsfmarkをビルドできるプロジェクトを、1回目のWindows10+VisualStudio2015でIMEを作成(1)サンプルコードをコンパイルして利用するを参考にして作成してください。
変更点として、モジュール定義ファイルの名称はmark.defになります。
次に、ソースコードを変更します。
globals.hの15行目、 #include"msctf.h"の次に、以下の4行を追加挿入します。
#include <string>
using namespace std;
extern string currentCompositionInputs;
extern int currentConversionCount;
mark.h の97行目、HRESULT _HandleReturn(TfEditCookie ec, ITfContext *pContext);の次に、以下の1行を追加挿入します。
HRESULT _HandleSpace(TfEditCookie ec, ITfContext *pContext);
compose.cpp の110行目、 pCompositionEditSession->Release(); の次 }の前に、以下の2行を追加挿入します。
currentCompositionInputs = "";
currentConversionCount = 0;
keys.cpp 10行目 #include"editsess.h"の次に、以下の5行を追加挿入します。
#include <vector>
#include <atlstr.h>
using namespace std;
string currentCompositionInputs;
int currentConversionCount;
keys.cpp 127行目 hr=S_OK;//・・・ の次に、以下の2行を追加挿入します。
string temp = { (char)((WCHAR)wParam|32) };
currentCompositionInputs = currentCompositionInputs + temp;
keys.cpp 312行目 case VK_SPACE:の次 return S_OK;の行を以下の1行のように変更します。
return _pMark->_HandleSpace(ec, _pContext);
keys.cpp ファイル末尾に以下のように、44行追加します。
vector<CStringW> wordMatching(string word)
{
vector<CStringW> words;
if ((string)"odori" == word)
{
words.push_back((CStringW)"踊り");
words.push_back((CStringW)"おどり");
}
else if ((string)"ooi" == word)
{
words.push_back((CStringW)"多い");
words.push_back((CStringW)"覆い");
words.push_back((CStringW)"大井");
}
return words;
}
HRESULT CMarkTextService::_HandleSpace(TfEditCookie ec, ITfContext *pContext)
{
ITfRange *pRangeComposition;
_pComposition->GetRange(&pRangeComposition);
if (pRangeComposition == NULL)
{
return S_FALSE;
}
vector<CStringW> words = wordMatching(currentCompositionInputs);
if (words.size() != 0)
{
pRangeComposition->SetText(ec, 0, (LPCWSTR)words[currentConversionCount%words.size()], words[currentConversionCount%words.size()].GetLength());
this->_SetCompositionDisplayAttributes(ec);
currentConversionCount++;
}
pRangeComposition->Release();
return S_OK;
}
変更点は以上7箇所のみですが、keys.cppファイルは変更箇所が複数あり、一つ目を変更すると、行がずれていくので気を付けてください。
ソースコードの変更が終了したら、1回目を参考にして、コンパイルして、regsvr32で、DLLを登録し、メモ帳を開いた上で、今回作成したIME(名前はMarkTextServide)をIMEに選択してください。
そして言語バーのメニューから 「Start/End Composition」を選択します。
この状態でキー入力すると、下線付き赤字でキー入力が表示されますが、「ooi」と入力します。
ここでスぺ^-スキーを1回押すと、「多い」と変換されます。
また、もう1回スペースキーを押すと、「覆い」と変換されます。
また、もう1回スペースキーを押すと、「大井」と変換されます。
さらに、スペースキーを押すとまた「多い」に戻ります。
他には、変更したソースコードを見ればわかると思いますが、「odori」でも変換できます。
wordMatchingのところを変更すれば、変換できる単語は増えるので、増やしてみてもよいでしょう。
では以上で、終了ですので、DLLを忘れずに、「regsvr32 /u」で登録解除します。
2016/08/16追記
上記では、直接変換の処理をしてしまいましたが
変換の処理などは、ITFCandidateListを継承したクラスで行うのが標準のようです
sdkサンプルの中のwinui\input\tsf\textservice\textservice-step06-3も参考にしてください。
ただ私のところではITFCandidateListを利用しなくても今のところ支障が見当らないようにおもいます
ご意見、ご質問などは下記掲示板にお願いします。
作成2016/08/10、追記2016/08/16、
(c)2016 programtips