「.NET Compact Framework」のソフトを作るDelphi2006ユーザーが増えてくれること願いつつ、私が試行錯誤している事をここに書いていきます。
ただいま「コンポ同士の繋がりが消える」という致命的なバグにより試行錯誤を休止中です(泣)。
ダウンロードはこちらのサイトでも行えます、こちらが正式ページなのでよろしくです^^
●ドルドのゲームアイランド(ドルドマイページ本家)
http://www.geocities.jp/doldomn/
先にしときましょう、そうしないと以後に入れる事になるビルドヘルパーが誤動作します。
ここは特に問題なし。
あれ?
-DCF_Oosterkamp
が
-DCF_Pluimers
に変わってる!
「ConvertCAB.bat」を使ってやる方法は.NET Compact Framework 1.0 SP3 インストール パッケージ のページでダウンロードできる中から「netcf.core.ppc3.ARM.cab」 (=.NET CF のインストレーションファイル) に含まれるすべてのファイルを解凍してバッチを実行するのだが、見事にファイル名が違っていて失敗!!
仕方ないので「ConvertGAC.bat」を使う方法を行う。 まずはPoketPC(私はW-ZERO3[es]から)のWindowsフォルダにある「GAC_」が付いている すべてのDLLを、PC上の適当なフォルダにコピーして、いざバッチを実行すると「ファイルがありません」と出る…??? う、このファイル、システム属性と非表示属性が付いてる(;;)
attrib -h -s (ファイル名)
で解除できるみたいなので「Setattrib.bat」というバッチファイルを作る
ついでに「ConvertCAB.bat」も置いておきます
CEエミュレータなるものがあって、それが使えるらしいんだけどいまいちピンとこない。
まぁ設定で「ActiveSync」選んでおけば実機(W-ZERO3[es])の直下にコピーされて勝手に動くから、これでいいかな。
.NET Compact Frameworkで使えないコンポーネントを貼ったり、使えないプロパティを設定したりするとたちどころに不安定。 何度もトライ&エラーしてても不安定になる、突然コンパイル通らなくなるとか(;;) Delphiの再起動で直ったり、Windowsの再起動しないと直らなかったり、わけわからんのです。
「プロジェクト名.bdsproj」のファイル内の下でFalseになっている2箇所を両方Trueにします
※突然なるので詳細は不明…
<CompactFramework_UseDefaultDeploy>False</CompactFramework_UseDefaultDeploy>
<CompactFramework>False</CompactFramework>
↓
<CompactFramework_UseDefaultDeploy>True</CompactFramework_UseDefaultDeploy>
<CompactFramework>True</CompactFramework>
procedure frmMain.Button2_Click(sender: System.Object; e: System.EventArgs); var sr: TSearchRec; WkMasterFileName: string; WkCopyFileName: string; begin if Borland.Vcl.SysUtils.FindFirst('\My Documents\マイ ピクチャ\*.jpg', FaAnyFile, sr) = 0 then begin repeat ListBox1.Items.Add(sr.Name); until Borland.Vcl.SysUtils.FindNext(sr) <> 0; Borland.Vcl.SysUtils.FindClose(sr); end; end;
「\My Documents\マイ ピクチャ\」フォルダには「img227.jpg」「img228.jpg」「img229.jpg」のファイルがあるのですが、ListBoxに表示された内容はなんと「g227.jpg」「g228.jpg」「g229.jpg」となぜか前2バイトが抜けたものが並びます。
調べていくと、さらに内部の関数「FildFirstFile」まで同じくファイル名の頭2バイトが無い状態で取り出されてしまう模様。
そもそも、Delphi2006が、.NET Compact Frameworkに対してのVCLが未サポートらしいです…偶然動いただけらしい(汗)
結局、.NETライブラリである「Directory.GetFiles」関数を使って解決しました。
「.NET Compact Framework 1.0」ではレジストリはAPI使わないと駄目らしい。
「.NET Compact Framework 2.0」はクラスあるのに~…って愚痴っても仕方ないので、どれをUSESすればAPI使えるか調べる。
されどWebページを検索しても何処にも見つからず(;;)シクシク
仕方ないので「C:\Program Files\Borland\BDS\4.0\lib\cf」のファイルを見て、カンで「Borland.VclCF.Windows」をUSESに入れる。
APIである「RegOpenKeyEx」が使えるようになった…当たり・・・かな???
一応コンパイルは通るけど、正しいっていう根拠がどこにも無いのが恐ろしい…。
とりあえずやりたい事は「HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory」の「Folder」キーの文字列を取りたいだけなのだが…値は「miniSDカード」と返ってくるはず。
ところが、返ってくる文字列がしこたまおかしい!!1バイトごとに途中でNULLが入ってる文字列になってる。
これじゃあ文字途中で切れじゃうじゃない~なんだろなこれ…
色々調べるとこういう場合は「PlatformStringOf関数」を通さないと駄目らしい。
さらにこの関数、ヘルプを見ると「末尾の NULL 文字を追加したり削除しないことに注意してください」との事で、何故か後にNULL文字が2つ付いている状態で渡してくるものだから、それを削る処理も入れないと以後文字連結できなくなるというさらにハマリが(;;)
procedure frmMain.Button1_Click(sender: System.Object; e: System.EventArgs); var WkHKEY: HKEY; WkType, WkSize: Cardinal; WkGetValue: array of Byte; WkValue: string; begin try if RegOpenKeyEx(HKEY_LOCAL_MACHINE, 'System\StorageManager\Profiles\SDMemory', 0, KEY_EXECUTE, WkHKEY) <> ERROR_SUCCESS then begin //キーが無いので終了 Exit; end; try WkSize := 256; SetLength(WkGetValue, WkSize); RegQueryValueExW(WkHKEY, 'Folder', nil, WkType, WkGetValue, WkSize); SetLength(WkGetValue, WkSize); WkValue := ''; if WkType = REG_SZ then begin //PlatformStringOf関数を通さないと //まともな文字列に変換されない WkValue := PlatformStringOf(WkGetValue); //後に何故か#0が2つ付いているため、 //以後の文字列連結がおかしなるのを防ぐのに後1バイト削除 WkValue := Copy(WkValue, 1, Length(WkValue) - 1); end; //デバッグ System.Windows.Forms.MessageBox.Show(WkValue); finally RegCloseKey(WkHKEY); end; except //SDメモリのフォルダ名取得失敗 Exit; end; end;
以上でなんとかメッセージボックスで表示するサンプルコードが完成しました。
.NET Compact Framework用じゃないですが、APIによるレジストリの取得方法の参考にしたページです。
●Tips: レジストリの使い方
[http://www.kt.rim.or.jp/~yuta/prog/win32/Registry/index.html]
「ToolBar」を使うのは罠で、これだとボタン名が付けられません。
「MainMenu」を使うのが正解、ただし他のオブジェクトを移動したりすると「MainManu」に繋がっているはずの「MenuItem」郡のリンクが全て外れてしまう(InitializeComponentからその記述が消える)という現象が起きる為、その部分だけ自分で書いておく必要がある。
//フォームのLoadイベントに書いておくと良い procedure frmMain.frmMain_Load(sender: System.Object; e: System.EventArgs); begin //この記述がInitializeComponentから勝手に消えるため自分で書く(;;) //MainMenu1の子分はMenuItem1・MenuItem2 Self.MainMenu1.MenuItems.AddRange( TArrayOfSystem_Windows_Forms_MenuItem.Create(Self.MenuItem1, Self.MenuItem2)); //MenuItem2の子分はMenuItem3・MenuItem4 Self.MenuItem2.MenuItems.Add(Self.MenuItem3); Self.MenuItem2.MenuItems.Add(Self.MenuItem4); end;
作った「MenuItem」は「MainMenu」でメニューを登録する度に無尽蔵に増えていくため、いつのまにやら余計なMenuItemを作っている可能性がある。
以下のように「MenuItem」が増えていくため、いらない「MenuItem」はコード上から手作業で削除する必要がある。
type frmMain = class(System.Windows.Forms.Form) {$REGION 'Designer Managed Code'} strict private /// <summary> /// Required designer variable. /// </summary> ~中略~ MenuItem1: System.Windows.Forms.MenuItem; //生成されるコード MenuItem2: System.Windows.Forms.MenuItem; //生成されるコード MenuItem3: System.Windows.Forms.MenuItem; //生成されるコード MenuItem4: System.Windows.Forms.MenuItem; //生成されるコード ~中略~ procedure frmMain.InitializeComponent; begin Self.FileMoveButton := System.Windows.Forms.Button.Create; Self.FileListBox := System.Windows.Forms.ListBox.Create; Self.FileMoveProgressBar := System.Windows.Forms.ProgressBar.Create; Self.Button1 := System.Windows.Forms.Button.Create; Self.Label1 := System.Windows.Forms.Label.Create; Self.MainMenu1 := System.Windows.Forms.MainMenu.Create; Self.MenuItem1 := System.Windows.Forms.MenuItem.Create; //生成されるコード Self.MenuItem2 := System.Windows.Forms.MenuItem.Create; //生成されるコード Self.MenuItem3 := System.Windows.Forms.MenuItem.Create; //生成されるコード Self.MenuItem4 := System.Windows.Forms.MenuItem.Create; //生成されるコード Self.SuspendLayout; ~中略~ // // MenuItem1 // Self.MenuItem1.Index := -1; //生成されるコード Self.MenuItem1.Text := 'ファイル移動'; //生成されるコード Include(Self.MenuItem1.Click, Self.MenuItem1_Click); //生成されるコード // // MenuItem2 // Self.MenuItem2.Index := -1; //生成されるコード Self.MenuItem2.Text := 'メニュー';//生成されるコード // // MenuItem3 // Self.MenuItem3.Index := -1; //生成されるコード Self.MenuItem3.Text := 'オプション(&0)'; //生成されるコード // // MenuItem4 // Self.MenuItem4.Index := -1; //生成されるコード Self.MenuItem4.Text := '終了(&X)'; //生成されるコード Include(Self.MenuItem4.Click, Self.MenuItem4_Click); //生成されるコード
例えばパネルの上にボタンとか置いたりしても、いつのまにか外れます。
置いた直後はInitializeComponentにその記述はあるんですけどねぇ…他のオブジェクトを移動したりするだけでその記述だけ消えるんですよね。
このバグがある限りは、もうデザインがマウスでぱぱっと出来ないことを意味するので、ちょっとやってられません(泣)致命的です。
仕方ないので、Delphi2006で.NET Compact Frameworkを作る試みはここで一時休止しようと思います。
Delphi2007 for .NET の.NET Compact Frameworkフル対応を期待して…。