.NET(Mobile) コントロールのIMEモードを設定する

WindowsアプリであればテキストボックスのImeModeプロパティがありますが
CompactFrameworkのテキストボックスにはImeModeプロパティがありません。

CompactFrameworkのテキストボックスのImeModeを設定するにはAPIを使用します。
Imports System.Runtime.InteropServices

Public Class Form1

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call SetImeMode(Me.TextBox1, ImeMode.HIRAGANA)
End Sub

Public Enum ImeMode
NOCONTROL = 0
OFF = 1
[ON] = 2
DISABLE = 3
HIRAGANA = 4
KATAKANA = 5
KATAKANAHALF = 6
ALPHAFULL = 7
ALPHA = 8
End Enum

Private Const ALPHANUMERIC As Int32 = &H0   '半角英数
Private Const NATIVE As Int32 = &H1         '直接入力
Private Const KATAKANA As Int32 = &H2       'カタカナ
Private Const FULLSHAPE As Int32 = &H8      '全角
Private Const ROMAN As Int32 = &H10

 _
Private Shared Function ImmGetContext(ByVal hWnd As IntPtr) As IntPtr
End Function

 _
Private Shared Function ImmReleaseContext(ByVal hWnd As IntPtr) As Boolean
End Function

 _
Private Shared Function ImmSetConversionStatus(ByVal hIMC As IntPtr, ByVal fdwConversion As Int32, ByVal fdwSentence As Int32) As Boolean
End Function

 _
Private Shared Function ImmSetOpenStatus(ByVal hIMC As IntPtr, ByVal fOpen As Int32) As Boolean
End Function

 _
Private Shared Function ImmAssociateContext(ByVal hWnd As IntPtr, ByVal hIMC As Int32) As Int32
End Function


Private Sub SetImeMode(ByVal ctrl As Control, ByVal mode As ImeMode)
Dim himc As IntPtr = ImmGetContext(ctrl.Handle)

Try
Select Case mode
Case ImeMode.DISABLE
ImmAssociateContext(himc, 0)

Case ImeMode.OFF
ImmAssociateContext(himc, 1)
ImmSetOpenStatus(himc, 0)

Case ImeMode.ON
ImmAssociateContext(himc, 1)
ImmSetOpenStatus(himc, 1)

Case Else

ImmAssociateContext(himc, 1)
ImmSetOpenStatus(himc, 1)

Dim dwConversion As Int32

Select Case mode
Case ImeMode.HIRAGANA
dwConversion = NATIVE Or FULLSHAPE Or ROMAN
Case ImeMode.KATAKANA
dwConversion = NATIVE Or FULLSHAPE Or KATAKANA Or ROMAN
Case ImeMode.KATAKANAHALF
dwConversion = NATIVE Or KATAKANA Or ROMAN
Case ImeMode.ALPHAFULL
dwConversion = FULLSHAPE Or ALPHANUMERIC
Case ImeMode.ALPHA
dwConversion = ALPHANUMERIC
End Select
ImmSetConversionStatus(himc, dwConversion, 0)



End Select
Finally
ImmReleaseContext(ctrl.Handle)
End Try

End Sub


End Class

.NET(Mobile) アプリのメモリ使用量について

CompactFrameworkアプリでフォームを開いたり閉じたりしていると、メモリ使用量がどんどん増えていきます。

Microsofrフィードバックによると
Inherits Componentしているコントロール(Timer、ToolTipなど)を使用する際に.Netが自動生成するコードが
CompactFrameworkでは自動生成されないためフォームの参照が解放されず、ガーベッジに収集されないらしいのです。

具体的にはCompactFrameworkのMainMenuコントロールはInherits Componentされているにもかかわらず、Desiner.vbでcomponentsに追加されずfinalizaで解放されないということです。
このコードの★部分が本来ならmainMenu1 = New System.Windows.Forms.Mainmenu(components)となる。
 _
Partial Public Class Form1
Inherits System.Windows.Forms.Form

'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
 _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub

'Windows フォーム デザイナで必要です。
Private components As System.ComponentModel.IContainer
Private mainMenu1 As System.Windows.Forms.MainMenu

'メモ: 以下のプロシージャは Windows フォーム デザイナで必要です。
'Windows フォーム デザイナを使用して変更できます。  
'コード エディタを使って変更しないでください。
 _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container
'★本来ならmainMenu1 = New System.Windows.Forms.Mainmenu(components)
mainMenu1 = New System.Windows.Forms.Mainmenu()
Me.Menu = mainMenu1
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi
Me.Text = "Form1"
Me.AutoScroll = True
End Sub
End Class



しかし、それでもメモリは増え続けていきます・・・・


ダイアログフォームを起動し、ダイアログフォームを閉じる処理を1000回行い100回ごとにメモリ使用量を計測する処理を
以下の7種類のコードで試してみました。

コード1
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Using句を使用します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Using frm As New Form2
frm.ShowDialog()
End Using
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード2
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Using句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Using frm As New Form2
frm.ShowDialog()
End Using
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード3
Form3を起動し、Form3のActivatedでForm3を閉じます。
Form3にはmainMenuコントロールを1つ配置しています。
Form3のmainMenuコントロールはmainMenu1 = New System.Windows.Forms.Mainmenu(components)とします。
Using句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Using frm As New Form3
frm.ShowDialog()
End Using
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード4
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Try~finally句を使用します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form2
Try
frm.ShowDialog()
Finally
frm.Dispose()
End Try
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード5
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Try~finally句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form2
Try
frm.ShowDialog()
Finally
frm.Dispose()
End Try
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード6
Form2を起動し、Form2のActivatedでForm2を閉じます。
Form2にはmainMenuコントロールを1つ配置しています。
Try~finally句を使用します。
Form2にNothingを設定します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form2
Try
frm.ShowDialog()
Finally
frm.Dispose()
frm = Nothing
End Try
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next


コード7
Form3を起動し、Form3のActivatedでForm3を閉じます。
Form3にはmainMenuコントロールを1つ配置しています。
Form3のmainMenuコントロールはmainMenu1 = New System.Windows.Forms.Mainmenu(components)とします。
Try~finally句を使用します。
GC.Collectを1回実行します。
Me.ListBox1.Items.Add("開始" & " : " & GC.GetTotalMemory(False))
For i As Int32 = 1 To 1000
Dim frm As New Form3
Try
frm.ShowDialog()
Finally
frm.Dispose()
End Try
GC.Collect()
If i Mod 100 = 0 Then
Me.ListBox1.Items.Add(i.ToString & " : " & GC.GetTotalMemory(False))
End If
Next




コード1、コード4はメモリ使用量はほぼ同じですが、他のコードと比べGC.Collectを実行していないので、最もメモリ使用量が高いです。
コード6以外のその他のコードはメモリ使用量はほぼ同じです。
圧倒的にメモリ使用量が少なく、メモリ増加量も少ないのがコード6でした。

う~ん・・・?ナゼ?

Java パスを指定して画像を読み込む

Sample1.jpgをデスクトップから読み込み、Frameに描画します。

画像を読み込むにはAWTのToolkitクラスに用意されているgetImageメソッドを使用します。
Toolkitは AWTの世界と現実のウィンドウシステムとの間の橋渡しをするクラスです。
このクラスは抽象クラスになっていて、まずgetDefaultToolkitメソッドでデフォルトインスタンスを取得します。
package graphicsSample;

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

public class ImageSample extends Frame {

private static final long serialVersionUID = 1L;
//イメージ
Image img = null;  //  @jve:decl-index=0:

/**
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
new ImageSample();
}

/**
* This is the default constructor
*/
public ImageSample() {
initialize();
}

/**
* This method initializes this
* 
* @return void
*/
private void initialize() {
this.setSize(500, 500);
this.setTitle("Frame");

//イメージを読み込みます。
img = Toolkit.getDefaultToolkit().getImage("C:/Users/UserName/Desktop/Sample1.jpg");

this.setVisible(true);

}

@Override
public void paint(Graphics g) {
// TODO 自動生成されたメソッド・スタブ
//super.paint(g);
//イメージを描画します。
g.drawImage(img,50,50,this);
}
}  //  @jve:decl-index=0:visual-constraint="18,7"



Java AWT 図形を描画する

AWTで図形を描画してみます。

AWTのコンポーネントの描画はすべてJavaで行われているわけではなく、WindowsであればWIN32APIを使用しているため、
ButtonクラスのpaintメソッドをオーバーライドしてもButtonのデザインを変更することはできません。
AWTではGUIの表示を変更することができません。
※Swingではすべての描画がJavaで行われいるので、GUIの表示を変更することが可能です。


AWTの描画の仕組みは、コンポーネントで再描画の要求があるとrepaint、Update、Paintの順に描画メソッドが呼び出されていきます。

FrameクラスのpaintメソッドをオーバーライドしてFrameに図形を描画してみます。
paintメソッドの引数Graphicsクラスには下記のような描画メソッドが用意されています。

drawRect(横位置, 縦位置, 横幅, 縦幅)枠線のみの四角を描画します。
fillRect(横位置, 縦位置, 横幅, 縦幅)塗りつぶした資格を描画します。
drawOval(横位置, 縦位置, 横幅, 縦幅)枠線のみの円を描画します。
fillOval(横位置, 縦位置, 横幅, 縦幅)塗りつぶした円を描画します。
drawLine(開始横位置,開始縦位置, 終了横位置, 終了縦位置)直線を描画します。
drawRoundRect(横位置, 縦位置, 横幅, 縦幅, 丸みの横幅, 丸みの縦幅)枠線のみの角が丸い四角を描画します。
fillRoundRect(横位置, 縦位置, 横幅, 縦幅, 丸みの横幅, 丸みの縦幅)塗りつぶした角が丸い四角を描画します。
draw3DRect(横位置, 縦位置, 横幅, 縦幅, boolean)枠線が立体的な四角を描画します。第5引数のboolean型には凸であればtrue。凹であればfalse。
drawArc(横位置, 縦位置, 横幅, 縦幅, 開始角度, 描画角度)円弧を描画します。開始角度、描画角度はは3時の位置を0として、反時計周りに算出した円弧の角度を指定します。
fillArc(横位置, 縦位置, 横幅, 縦幅, 開始角度, 描画角度)扇型を描画します。開始角度、描画角度はは3時の位置を0として、反時計周りに算出した円弧の角度を指定します。
drawPolyLine(int配列1, int配列2, int配列3)開いた多角形の線分を描画します。
drawPolygon(int配列1, int配列2, int配列3)
drawPolygon(Polygon)
閉じた多角形の線分を描画します。
fillPolygon(int配列1, int配列2, int配列3)
fillPolygon(polygon)
閉じた多角形を塗りつぶして描画します。



VisualEditorを利用してFrameを作成します。
ソースコードの「extends Frame」にカーソルを置いた状態で
eclipseメニューの「ソース」より「メソッドのオーバーライド/実装」を選択します。
起動した画面より「Container」の「paint(Graphics)」をチェックONにし「OK」ボタンをクリックします。



ソースコードのPaintメソッドに描画コードを記述します。
package graphicsSample;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Polygon;

public class GraphicsSample01 extends Frame {

private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics g) {
// TODO 自動生成されたメソッド・スタブ
//super.paint(g);

g.setColor(Color.red);
//枠線のみの四角形を描画します。
g.drawRect(50,50,50,50);
//塗りつぶした四角形を描画します。
g.fillRect(120, 50, 50, 50);

g.setColor(Color.blue);
//枠線のみの円を描画します。
g.drawOval(50,120,50,50);
//塗りつぶした円を描画します。
g.fillOval(120, 120, 50, 50);

g.setColor(Color.black);
//直線を描画します。
g.drawLine(50, 190, 150, 190);

g.setColor(Color.orange);
//枠線のみの角の丸い四角を描画します。
g.drawRoundRect(50, 260, 50, 50, 20,20);
//塗りつぶした角の丸い四角を描画します。
g.fillRoundRect(120, 260, 50, 50, 20,20);

g.setColor(Color.lightGray);
//枠線が浮き出した四角を描画します。
g.fill3DRect(50, 330, 50, 50, true);
//枠線がへこんだ四角を描画します。
g.fill3DRect(120, 330, 50, 50, false);

g.setColor(Color.magenta );
//円弧を描画します。
g.drawArc(50, 400, 50, 50, 0, -90);
//扇型を描画します。
g.fillArc(120, 400, 50, 50, 0, -90);

g.setColor(Color.cyan);
//(50,470)、(100,520)、(150,470)、(200,520)の4点を結ぶ折れ線を描画します。
int p = 4;
int[] x = {50,100,150,200};
int[] y = {470,520,470,520};
g.drawPolyline(x, y, p);

//(50,590),(100,640),(150,590),(200,640)の4点を結ぶ多角形を描画します。
Polygon pol1 = new Polygon();
pol1.npoints = 4;
pol1.xpoints = new int[]{50,100,150,200};
pol1.ypoints = new int[]{590,640,590,640};
g.drawPolygon(pol1);

//(50,650),(100,700),(150,650),(200,700)の4点を結ぶ塗りつぶした多角形を描画します。
Polygon pol2 = new Polygon();
pol2.npoints = 4;
pol2.xpoints = new int[]{50,100,150,200};
pol2.ypoints = new int[]{590,640,590,640};
g.fillPolygon(pol2);
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
new GraphicsSample01();
}

/**
* This is the default constructor
*/
public GraphicsSample01() {
super();
initialize();
}

/**
* This method initializes this
* 
* @return void
*/
private void initialize() {
this.setSize(300, 700);
this.setTitle("Frame");

this.setVisible(true);
}

}


Java VisualEditorの利用

VEプロジェクトを作ります。

eclipseの「ファイル」メニュー「新規」より「その他」を選択します。
起動した画面より「Java」の「ビジュアル・クラス」を選択します。



以下のような画面が起動しますので、以下の設定を行います。
名前:クラス名を入力します。
スタイル:ベースとなるクラスを指定します。今回はAWTのフレームを選択します。
作成するメソッド・スタブの選択:
 public static void main(String[] args)をチェックON
 継承された抽象メソッドをチェックON


画面の右端の▽マークでパレットウインドウよりコントロールを選択肢Frameにドラッグします。
コントロールのプロパティは、プロパティウィンドウで設定します。


ボタンをFrameにドラッグします。
ボタンを選択し右クリックメニューの「イベント」の「actionPerformed」クリックすると
ActionListenerが無名クラスを使って組み込まれます。

Java 実行可能Javaアーカイブを作る

eclipseの「ファイル」メニューより「エクスポート」を選択します。
起動したウィンドウから「JARファイル」を選択し「次へ」をクリックします。



起動した画面で「エクスポートするリソースの選択」と「エクスポート先の選択」を行い、後はデフォルトのままにしておきます。



この画面はデフォルトのままにしておきます。



この画面では「アプリケーションのエントリー・ポイントのクラスを指定」で
参照ボタンをクリックして、選択可能なクラスの一覧が表示されるので、メインクラスを選択します。



「エクスポート先の選択」で指定したファイル名.jarファイルが作成されます。

Java VisualEditor1.4のインストール

GUIのデザインをビジュアルエディタを使用して作成できる Visual Editor をインストールします。

eclipseを起動し、ヘルプの「ソフトウェアの更新」をクリックします。
「ソフトウェア更新およびアドオン」画面が起動しますので
「サイトの追加」ボタンをクリックし「http://update.soyatec.org/Ganymede/ve/1.4」を追加します。


追加したサイトのチェックボックスをONにし「インストールボタンをクリック」します。

画面に従ってインストールが完了すると再起動を勧めるメッセージが表示されますので、
eclipseを再起動します。

ヘルプの「Eclipseプラットフォームについて」をクリックし、開いた画面の「プラグインの詳細」ボタンをクリックします。


プラグイン名に「Visual Editor」が表示されていれば、インストール完了です。