アプリ版:「スタンプのみでお礼する」機能のリリースについて

現在 VC9にて、IME入力を取得するプログラムを書いています。

そのプログラムには、エディットボックスなどが
なく、普通のウィンドウに対してImmGetContext()を行い、
現在の入力状況を取得しています。
ここで問題なのですが、この状態で実行すると、ウィンドウの左上に
変換中の文字が見えてしまいます。これを見えなくさせようと思い、
ImmDisableIMEを呼ぶと当然ながら、IMEからのメッセージは
なくなってしまいます。

要点は
・変換中の文字を見せることなく
・IMEの編集状況を取得するにはどうしたらよいか?
です。

環境はVC9、XP sp3になります。
よろしくお願いします。

A 回答 (4件)

変換中の文字が見えないと、文字入力しているユーザが困るんじゃ?


と言う気がしますが、

確か、拙者の記憶だと、IMEの変換入力中の文字列を表示する位置を
変更するAPIがあったと思います。

デスクトップの外などに変換入力位置を飛ばしてしまうどうでしょう。

この回答への補足

返答ありがとうございます。
説明不足でしたね。
これはフルスクリーンゲーム中でのキーボード入力を
取得する部分になります。
>IMEの変換入力中の文字列を表示する位置を変更するAPI
調べてみました。ImmSetCompositionWindowですかね?
やり方が不味いのか、これでは上手くいきませんでした。
同様にImmSetCompositionWindowも試してみましたが、
上手くいきません。

補足日時:2009/02/11 19:41
    • good
    • 0

ちと、記憶を頼りに調べてみました。



動作確認していないので、うまく行くかわかりませんが、

SetCaretPos()とか使えませんか?

後、「キャレット」などで、ウェブ検索すると、何か参考になるページが見つかるかもしれません。

この回答への補足

ありがとうございます。
しかし、やはり上手くいきませんね。
画像つきのほうが解りやすいと思ったので、上げました。
http://www.dotup.org/uploda/www.dotup.org3267.jpg
このように、エディットボックスなどがないまっさらなウィンドウ
上で入力すると出るタイプのものです。
教えて頂いたSetCaretPosを利用しても、位置は変わらず、
HideCaretを利用しても表示は消えませんでした。
う~ん。

補足日時:2009/02/11 21:22
    • good
    • 0

IMEの入力位置を移動するサンプル作ってみました。


imm.h使うの結構久しぶりなので、てこずりました。
テストとかしてませんので、バグあると思います。
参考にどうぞ。

----------------------------------------------------------------------
/*
* test_SetCaret.cxx
*
* Created on: 2009/02/11
* Author: yanch
*/
#define STRICT

#include <cstdio>
#include <windows.h>
#include <imm.h>

#define MEM_CLEAR(x)  ::ZeroMemory(&x,sizeof(x))
#define CLASS_NAME    TEXT("SAMPLE")
#define WINDOW_NAME  TEXT("test_SetCaret")

HWND  hMainWnd;

LRESULT  CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT onKillFocus( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT onSetFocus( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

/*=============================================================================
=============================================================================*/
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd )
{
  MSG  msg;
  HRESULT hRet;
  
  WNDCLASSEX wcex;

  MEM_CLEAR( wcex );
  wcex.cbSize = sizeof( WNDCLASSEX );
  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = (WNDPROC)::MainWndProc;
  wcex.hInstance = hInst;
  wcex.hIcon = ::LoadIcon( 0, IDI_APPLICATION );
  wcex.hCursor = ::LoadCursor( 0, IDC_ARROW );
  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);
  wcex.lpszClassName = CLASS_NAME;

  hRet = ::RegisterClassEx( &wcex );
  if ( !hRet ) return 0;

  hMainWnd = ::CreateWindowEx(
    0,
    CLASS_NAME,
    WINDOW_NAME,
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    0,
    0,
    hInst,
    0
    );
  if ( !hMainWnd )
    return 0;

  ::ShowWindow( hMainWnd, nShowCmd );
  ::UpdateWindow( hMainWnd );
  
  while ( ::GetMessage( &msg, 0, 0, 0 ) )
  {
    ::TranslateMessage( &msg );
    ::DispatchMessage( &msg );
  }

  return msg.wParam;
}

/*=============================================================================
=============================================================================*/
LRESULT  CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  switch ( uMsg )
  {
  case WM_KILLFOCUS:
    return onKillFocus( hWnd, uMsg, wParam, lParam );
  case WM_SETFOCUS:
    return onSetFocus( hWnd, uMsg, wParam, lParam );
  case WM_DESTROY:
    ::PostQuitMessage( 0 );
    return 0;
  }
  return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
}


LRESULT onKillFocus( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  ::HideCaret(hWnd);
  ::DestroyCaret();
  return 0;
}
LRESULT onSetFocus( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  int nNewPosX = 100;
  int nNewPosY = 100;
  
  ::CreateCaret(hWnd, NULL, 10, 10);
  ::SetCaretPos(nNewPosX, nNewPosY);
  HIMC hImc = ::ImmGetContext(hWnd);
  if (hImc)
  {
    COMPOSITIONFORM cpf;
    cpf.dwStyle = CFS_POINT;
    cpf.ptCurrentPos.x = nNewPosX;
    cpf.ptCurrentPos.y = nNewPosY;
    ImmSetCompositionWindow(hImc, &cpf);
    ImmReleaseContext(hWnd, hImc);
  }
  
  return 0;
}

// [EOF:test_SetCaret.cxx]
----------------------------------------------------------------------
    • good
    • 0

よくゲームでは


IMEの候補リストウインドウを含めて自前で描画しますが
質問者さんが行おうとしている処理と関係があると思います。

DirectX SDKについてくるサンプルソースで
CustomUIというものがありますが、
これは日本語入力部分の表示をDirectXを使って独自に描画しているので参考になると思います。
http://msdn.microsoft.com/ja-jp/directx/default. …
(DirectXに関係なく自前で描画出来ます。)

具体的にどうしてるかというと
WM_IME_SETCONTEXTを受け取ったときに
lParam = 0;とするとIME関連の表示が行われなくなります。
後はWM_IME~のメッセージ(WM_IME_STARTCOMPOSITION 、WM_IME_COMPOSITION、WM_IME_ENDCOMPOSITION、WM_IME_NOTIFY)
に必要な処理をしてやれば
お望みの動作が可能かと思います。

この回答への補足

おお、ありがとうございます!!!
まさしく自分がやりたかったことです。
ちょっとESPを要求するような書き方でしたね。すいません。

#CustomUIのサンプルは、新旧のSDKの設定がこんがらがって
#しまっていて、ビルドできずに、「ひとまず自力でやってみる」
#という方針でやっていました。

補足日時:2009/02/12 20:33
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!