- PR -

dataGridのセルにフリガナを自動入力できます

投稿者投稿内容
ZEN73
常連さん
会議室デビュー日: 2003/03/10
投稿数: 43
投稿日時: 2004-10-17 18:07
dataGridのセルに入力した名前のフリガナを右隣のセルに自動的に入力させたいのですが,思い通りのふりがなにならなくて困っています。
 @山田⇒ヤマダヤマダ
  小山田⇒オヤマダオヤマダオヤマダ
  畠⇒ハタ というように表示されてしまいます。
 A<山田⇒ヤマダヤマダ>となっているところで,[BackSpaceキー]
を,押したときには⇒オヤマダオヤマダオヤマダオヤマダオヤマダオヤマダ となります。
対策として
 @には,lPBufの内容をどこかの時点で開放するのかなと思ってますが
  どのようにしたらよいのかわかりません。
 Aには,[BackSpaceキー]の押し下げに対処するコードを書けばいいと思ってますが
  これはなんとか対処できそうですが,これで大丈夫かなと思ってます。

どなたか,対処の方法を教えてください。お願いします。
(textBoxのTextChangeイベントでも同じ現象になります)

コード:
#!/usr/bin/perl 


namespace DataGrid_Furigana
{
 public class Form1 : System.Windows.Forms.Form
 {
  public string Furigana;
  const int GCS_RESURTREADSTR = 0x0200;

  [DllImport("imm32.dll")]
  static extern IntPtr ImmGetContext(IntPtr hWnd);
  [DllImport("imm32.dll")]
  static extern int ImmGetCompositionString(
   IntPtr hIMC, int dwIndex, StringBuilder lpBuf, int dwBufLen);
  [DllImport("imm32.dll")]
  static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);

  static void Main()
  {
    Application.Run(new Form1());
  }

  private void SeitoNum_KeyPress(object sender,
      System.Windows.Forms.KeyPressEventArgs e)
  {
    string str="";
    int iCol = dataGrid1.CurrentCell.ColumnNumber;
    int iRow = dataGrid1.CurrentCell.RowNumber;
    IntPtr himc = ImmGetContext(dataGrid1.Handle);

     if(himc == IntPtr.Zero)
{
return;
}
try
{
int dwSize = ImmGetCompositionString(himc, GCS_RESURTREADSTR,
null, 0);
StringBuilder lpBuf = new StringBuilder(dwSize);
ImmGetCompositionString(himc, GCS_RESURTREADSTR, lpBuf, dwSize);

lpBuf.Length = dwSize;
str = lpBuf.ToString();
dataGrid1[iRow,iCol+1]=Furigana + str;
Furigana = dataGrid1[iRow,iCol+1].ToString();
}
finally
{
ImmReleaseContext(dataGrid1.Handle, himc);
}
}
private void Form1_Load(object sender, System.EventArgs e)
{
this.dataGridTextBoxColumn1.TextBox.KeyPress
+= new KeyPressEventHandler(this.SeitoNum_KeyPress);
}
}
}



 


[ メッセージ編集済み 編集者: ZEN73 編集日時 2004-10-22 10:05 ]

[ メッセージ編集済み 編集者: ZEN73 編集日時 2004-10-22 10:24 ]
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-10-17 21:02
諸農です。

引用:

 1.山田⇒ヤマダヤマダ
  小山田⇒オヤマダオヤマダオヤマダ
  畠⇒ハタ というように表示されてしまいます。



KeyPressイベントが変換文字単位で発生しているからではないでしょうか?

引用:

 A<山田⇒ヤマダヤマダ>となっているところで,[BackSpaceキー]
を,押したときには⇒オヤマダオヤマダオヤマダオヤマダオヤマダオヤマダ となります。



「ヤマダ」なのに「オヤマダ」になるんですか?
これは変ですね。
バッファのクリアが変なのかな。

引用:

対策として
 1.には,lPBufの内容をどこかの時点で開放するのかなと思ってますが



WM_IME_COMPOSITIONのメッセージを受け取ることで変換確定を知ることが
出来ますので、DataGridTextBoxの拡張版をDataGridにセットしてみては
いかがでしょうか。
拡張版TextBoxはこちらが参考になると思います。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=7712&forum=7

#丸数字を変えました。



_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
ZEN73
常連さん
会議室デビュー日: 2003/03/10
投稿数: 43
投稿日時: 2004-10-18 05:23
善浪です。
諸農さんの早速のアドバイス,ありがとうございます。
(以前にも,いろいろと教えていただき,感謝しています)

引用:-------------------------------------------------------
「ヤマダ」なのに「オヤマダ」になるんですか?
これは変ですね。
バッファのクリアが変なのかな。
-------------------------------------------------------------
これは,「ヤマダヤマダヤマダヤマダ」のまちがいでした。


引用:-------------------------------------------------------
KeyPressイベントが変換文字単位で発生しているからではないでしょうか?

WM_IME_COMPOSITIONのメッセージを受け取ることで変換確定を知ることが
出来ますので、DataGridTextBoxの拡張版をDataGridにセットしてみては
いかがでしょうか。
拡張版TextBoxはこちらが参考になると思います。

Public class TextBoxEx :TextBox
-------------------------------------------------------------
拡張版dataGridのクラスにするには,
  ア: Public class dataGridEx : dataGrid
イ: Public class dataGridTextBoxEx : dataGridTextBox
どうするのかぁ?
ともかくも早速試してみます。



ZEN73
常連さん
会議室デビュー日: 2003/03/10
投稿数: 43
投稿日時: 2004-10-18 19:48
善浪です。
諸能さんの引用-------------------------------------------
WM_IME_COMPOSITIONのメッセージを受け取ることで変換確定を知ることが
出来ますので、DataGridTextBoxの拡張版をDataGridにセットしてみては
いかがでしょうか。
拡張版TextBoxはこちらが参考になると思います。

Public class TextBoxEx :TextBox
{
・・・・・・・・・・・・・・・
}
private void Form1_load
{
TextBoxEx tb = new TextBoxEx();

tb.CompositionEvent +=
new TextBoxEx.CompositionEventHandler(this.CompoEvent);
this.Controls.Add(tb);
}
-------------------------------------------------------------
いろいろと,試しては見たのですが,お手上げです。
何がわからないかというと,DataGridの
---------------------
|氏名|フリガナ|番号|
---------------------
|   |     |  |
--↑-----------------
ここでイベントを発生させる「イベントハンドラの設定」
   の方法がわからないのです。
 上の例では,新たに配置するTextBoxのイベントになっていますので…。
 どなたか,お教え願います。

  




[/quote]
とっと
大ベテラン
会議室デビュー日: 2004/03/25
投稿数: 197
投稿日時: 2004-10-19 08:33
引用:

ZEN73さんの書き込み (2004-10-18 19:48) より:

-------------------------------------------------------------
いろいろと,試しては見たのですが,お手上げです。
何がわからないかというと,DataGridの
---------------------
|氏名|フリガナ|番号|
---------------------
|   |     |  |
--↑-----------------
ここでイベントを発生させる「イベントハンドラの設定」
   の方法がわからないのです。
 上の例では,新たに配置するTextBoxのイベントになっていますので…。
 どなたか,お教え願います。



おはようございます。

VBで申し訳ないですが、僕の場合、

Dim oleDa As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter
Dim dtSet As DataSet
Dim dtTable As DataTable = New DataTable

 〜 データ取得 〜
oleDa.Fill(dtSet, "AAA")
dtTable = dtSet.Tables("AAA")

でDataTable設定後に

'DataTableに検証イベントを追加
AddHandler dtTable.ColumnChanging, AddressOf Sub_ColumnChanging

と、イベントを追加しています。(数種類のイベントがあるようです。)

実際の処理は
Private Sub Sub_ColumnChanging(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs)

Select Case e.Column.ColumnName

Case "(列名A)"

If CType(e.ProposedValue, Integer) > 0 Then

e.Row.Item("列名B") = DBNull.Value

End If

End Select

End Sub

この例では各セルの値によって別のセルの内容を書き換える場合、そのセルの値の変化によって新たなイベントが発生してしまう場合があるので、処理の最初に一旦イベントを削除して最後に元に戻す処理が必要になります。


ZEN73
常連さん
会議室デビュー日: 2003/03/10
投稿数: 43
投稿日時: 2004-10-19 21:58
善浪です。
自分のしたいことをきちんと説明するべきでした。
諸農さん,とっとさん,申し訳ありません。
コード--------------------------------------------
lpBuf.Length = dwSize;
str = lpBuf.ToString();
dataGrid1[iRow,iCol+1] = str;
--------------------------------------------------
上のコードでは,ちゃんとフリガナが表示されます。
   善浪⇒ゼンナミ
しかし,姓に続けて名前を入力すると,名前だけが
表示されてしまいます。
   善浪太郎⇒タロウ
《これを改善したいのです》
それで,次のようなコードを書いて先に書いたような
結果になってしまった,ということなのです。
コード--------------------------------------------
lpBuf.Length = dwSize;
str = lpBuf.ToString();
dataGrid1[iRow,iCol+1]=Furigana + str;
Furigana = dataGrid1[iRow,iCol+1].ToString();
-------------------------------------------------

DataGridのイベントは,いろいろ調べているのですが,
KyePressイベントがこの場合に使える唯一のイベント
と思い込んでしまっています。

アドバイスお待ちしています。

[ メッセージ編集済み 編集者: ZEN73 編集日時 2004-10-19 22:22 ]
とっと
大ベテラン
会議室デビュー日: 2004/03/25
投稿数: 197
投稿日時: 2004-10-19 22:43
こんばんわ。

ふと、自分がVB6.0でInputManでやってた頃を思い出してみましたが・・。

逆ではダメですか?

ふりがなを先に入力するとか・・
ZEN73
常連さん
会議室デビュー日: 2003/03/10
投稿数: 43
投稿日時: 2004-10-22 10:00
善浪です。
 KeyPressイベントに変えて,KeyDownイベントにしてみたら思い通りにフリガナを表示できるようになりました。Furiganaを配列にして氏名の削除に対応するなど,改良すべき点が多々ありますが,これで一応は使えるんじゃないかと思ってます。
 改良についての情報をお待ちしています。

コード:
#!/usr/bin/perl 
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;

namespace DataGrid_Furigana
{
  public class Form1 : System.Windows.Forms.Form
  {
    public string Furigana = "";
    const int GCS_RESURTREADSTR = 0x0200;

    [DllImport("imm32.dll")]
    static extern IntPtr ImmGetContext(IntPtr hWnd);
    [DllImport("imm32.dll")]
    static extern int ImmGetCompositionString(
		IntPtr hIMC, int dwIndex, StringBuilder lpBuf, int dwBufLen);
    [DllImport("imm32.dll")]
    static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
    ………
    private void InitializeComponent()
    {
      …
      this.dataGrid1.CurrentCellChanged += new System.EventHandler(
                                           this.dataGrid1_CurrentCellChanged);
      this.Load += new System.EventHandler(this.Form1_Load);
    }

    static void Main() 
    {
      Application.Run(new Form1());
    }

    private void SeitoNum_KeyDown(
			   object sender, System.Windows.Forms.KeyEventArgs e)
    {
      string tmpStr;
      int iCol = dataGrid1.CurrentCell.ColumnNumber;
      int iRow = dataGrid1.CurrentCell.RowNumber;
      IntPtr himc = ImmGetContext(dataGrid1.Handle);

      if(himc == IntPtr.Zero 
                           || e.KeyCode == Keys.Back || e.KeyCode ==Keys.Left)
      {
        return;
      }
      try
      {
        int dwSize = ImmGetCompositionString(himc, GCS_RESURTREADSTR, null, 0);
        StringBuilder lpBuf = new StringBuilder(dwSize);
        ImmGetCompositionString(himc, GCS_RESURTREADSTR, lpBuf, dwSize);
        lpBuf.Length = dwSize;
        tmpStr = lpBuf.ToString();
        Furigana += tmpStr;
        dataGrid1[iRow,iCol+1]= Furigana ;
      }
      finally
      {
        ImmReleaseContext(dataGrid1.Handle, himc);
      }
    }

    private void dataGrid1_CurrentCellChanged(
                                             object sender, System.EventArgs e)
    {
      Furigana = "";
    }

    private void Form1_Load(object sender, System.EventArgs e)
    {
      this.dataGridTextBoxColumn1.TextBox.KeyDown 
                                 += new KeyEventHandler(this.SeitoNum_KeyDown);
    }
  }
}


スキルアップ/キャリアアップ(JOB@IT)