devcamp 20 A3.ppt [互換モード] -...

52
17 Th Developer Camp A3Delphi/C++Builderテクニカルセッション 「アンドキュメンテッド(?) VCL 逆引きVCL新機能 A3Delphi/C++Builderテクニカルセッション 逆引きVCL新機能株式会社 エスプリフォート 筑木真志 筑木真志 1

Transcript of devcamp 20 A3.ppt [互換モード] -...

Page 1: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

【A3】Delphi/C++Builderテクニカルセッション

「アンドキュメンテッド(?) VCL 逆引きVCL新機能 」

【A3】Delphi/C++Builderテクニカルセッション

~逆引きVCL新機能~」

株式会社 エスプリフォート

筑木真志筑木真志

1

Page 2: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

自己紹介

• 名前:筑木 真志 (ちくぎ しんじ)– 多分、同姓同名はいません

– 「流しのプログラマ」としてJavaやっています

– でも、ホームグラウンドはC++のつもり

2

Page 3: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

株式会社エスプリフォートについて

• URL: http://www.esprit-fort.co.jp/• 次代をともに創造するシステムインテグレーター

– 基幹/情報システム

– Webシステム/モバイルシステム開発

– データベースソリューション開発

– 制御アプリケーション開発

• 社是社是

– 高い技術レベルをもってIT技術を利用し、卓越した価値創造企業を目指します。

– 共存共栄の精神を持ち、イノベーションにより未来の創造をします。

3

Page 4: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

アジェンダ

• 文字列処理あれこれ文 列処 あ

• ファイル処理あれこれ

• GUI関連のあれこれ• GUI関連のあれこれ

• まとめ・Q&A

4

Page 5: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

何故「アンドキュメンテッド(?)」なのか

• リリースノートにクラス名だけ追加されている

– 製品リリース後のヘルプに反映されていない

– あっても、クラス名とかメソッド名だけで概要がないあ 、 ラ 名 名 概要

– 製品アップデートのリリースノートにさりげなく記述されていたり

– コンポーネント名でググるとホワイトペーパーが見つかる

– Delphi2009 HANDBOOKで解説されているp• いくつかネタを拝借しています

• ロードマップに「ドキュメントの整備」があるのはお約束

– Wiki化で徐々に改善

– Help Updateによる反映

5

p p よる反映

Page 6: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

文字列処理あれこれ文字列処理あれこれその1:1 その文字列を構築する

1

6

Page 7: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

文字列を能率良く構築する

• TStringBuilderクラス– http://docwiki.embarcadero.com/VCL/ja/SysUtils.TStringBuilder– 文字列を構築するユーティリティクラス

J のj l St i B ild に相当• Javaのjava.lang.StringBuilderに相当

• .NET FrameworkのSystem.Text.StringBuilderに相当

– 単純に文字列を「+」で連結するとその分インスタンスが生成され非– 単純に文字列を「+」で連結するとその分インスタンスが生成され非能率

– Appendメソッドで文字列を「構築」

– AppendFormatメソッドで書式化も可能

• 戻り値は「自分自身」なので、連続してコールできる

• いわゆる「メソッドチェ ン」• いわゆる「メソッドチェーン」

– ToStringメソッドで「構築」した文字列を取得

7

Page 8: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コードサンプル(Delphi)

procedure TForm1.Button1Click(Sender: TObject);var

sb : TStringBuilder;sb : TStringBuilder;x, y : Double;

beginsb := TStringBuilder.Create;x := 123 456;x := 123.456;y := 789.123;

// 出⼒ログ⽂字列を⽣成するsb Append(DateTimeToStr(Now))sb.Append(DateTimeToStr(Now))

.Append(' [Info]')

.Append(' AreaName = ')

.Append(Edit1.Text)AppendFormat(' Point = (%9 3f %9 3f) ' [x y]).AppendFormat(  Point = (%9.3f, %9.3f)  , [x, y])

.Append(' ShopCount = ')

.Append(Memo1.Lines.Count);

// TMemoに出⼒// TMemoに出⼒Memo1.Lines.Add(sb.ToString);// IDEのデバッグウィンドウに出⼒OutputDebugString(PWideChar(sb.ToString));

end;

8

end;

Page 9: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コードサンプル(C++Builder)

void __fastcall TForm1::Button1Click(TObject *Sender){

std::unique ptr<TStringBuilder> sb(new TStringBuilder());std::unique_ptr<TStringBuilder> sb(new TStringBuilder());double x = 123.456;double y = 789.123;

// 出⼒ログ⽂字列を⽣成する

注意:Appendメソッドにワイド文字列リテラルを

渡すと、暗黙的型変換の優先順位により// 出⼒ログ⽂字列を⽣成するsb‐>Append(DateTimeToStr(Now()))

‐>Append(" [Info]")‐>Append(" AreaName = ")>Append(Edit1 >Text)

渡すと、暗黙的型変換の優先順位によりboolにキャストされる。

× Append(L"AreaName = ")‐>Append(Edit1‐>Text)‐>AppendFormat(" Point = (%9.3f, %9.3f) ", ARRAYOFCONST((x, y)))‐>Append(" ShopCount = ")‐>Append(Memo1‐>Lines‐>Count);

// TMemoに出⼒Memo1‐>Lines‐>Add(sb‐>ToString());

// IDEのデバッグウィンドウに出⼒// IDEのデバッグウィンドウに出⼒OutputDebugString(sb‐>ToString().w_str());

}

9

Page 10: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

文字列処理あれこれ文字列処理あれこれその2:2 その正規表現

2

10

Page 11: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

正規表現を使う

• 正規表現とは、文字列の集合を一つの文字列で表現す規表 表る方法の一つである。

– Wikipediaより引用

• 「メタ文字」によって文字の集合を表現する

• 「メタ文字」は文字だけではなく、位置も表現するメタ文字」は文字だけではなく、位置も表現する

メタ文字 意味

. 任意の1文字

[] []内にある任意の1文字

¥w 単語を構成する任意の1文字

^ 行の先頭^ 行の先頭

* 直前の表現の0回以上の繰り返し

¥b 単語の境界

11

Page 12: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

Delphi/C++Builderで使用可能な正規表現エンジン

• 標準で使用可能

– TRegex (XE以降)

– boost::regex / std::tr1::regex (C++Builderのみ)g g ( )

• サードパーティー製

– SkRegExpSkRegExp– 鬼車

– BREGEXP DLLBREGEXP.DLL– など

• エンジンによって挙動が変わるので注意!!メタ文字の種類 Unicodeの扱いなど

12

– メタ文字の種類、Unicodeの扱いなど

Page 13: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

正規表現を使う

• TRegExクラスg クラ– http://docwiki.embarcadero.com/VCL/ja/RegularExpressions.TR

egEx

ド– Matchesメソッドでマッチ• 戻り値は、マッチ部分のコレクション(TMatchCollection型)

TR E はオブジ クトを生成して次々とマ チさせること– TRegExはオブジェクトを生成して次々とマッチさせることも可能

13

Page 14: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コードサンプル

procedure TForm1.btnMatchClick(Sender: TObject);varreg : TRegEx;match: TMatchCollection;m: TMatch;

beginbegin

// 正規表現reg := TRegEx.Create(edtPattern.Text);

// 正規表現がマッチするか?match := reg.Matches(edtText.Text);

// 結果をListBoxに表⽰lstMatched.Clear;for m in match do beginl h d dd( l )lstMatched.Items.Add(m.Value);

end;end;

14

Page 15: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

日本語ハッシュタグにマッチする正規表現

• Twitterのハッシュタグが日本語に対応

– http://blog.jp.twitter.com/2011/07/blog-post.html

• 条件

– #(ハッシュマーク) で始まる#(ハッシュマ ク) で始まる

– 半角、全角のどちらでも可

– 英数字 ひらがな カタカナ 漢字 ハングルおよびキリ– 英数字、ひらがな、カタカナ、漢字、ハングルおよびキリル文字

– ハッシュタグの前後には空白または句読点ッシ タグの前後には空白または句読点

– 記号や絵文字は使用不可

15

Page 16: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

日本語ハッシュタグにマッチする正規表現

• VCLにおける注意点

– 文字コードはUTF-16– 全角と半角の違い角 半角 違

– 濁音・半濁音と合成文字(「ガ」/「カ」+「゛」/「カ」+「゙」)

• Unicode正規化が必要

• 詳細は過去のデベロッパーキャンプの資料を参照!– 漢字・仮名にマッチするメタ文字

メタ文字 意味 TRegex boost::regex

¥w 単語構成文字 × ○

¥x{hex} 16進数指定(任意長) ○ ○

¥uhex Unicodeコードポイント(16進数4桁) × ×

¥p{prop} Unicodeプロパティ × ×

16

p{p p} Unicodeプ ティ

Page 17: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

日本語ハッシュタグにマッチする正規表現

procedure TForm1.Button1Click(Sender: TObject);var

m : TMatchCollection;本当は、• テキストの正規化;

I : Integer;begin

m := TRegEx.Matches(Edit1.Text,'(#|¥x{FF03})' + // ハッシュマーク'([¥w ' + // 英数字+アンダースコア

• テキストの正規化• 先読みと戻り読みで前後の空白チェック• ハングルとキリル文字のチェックが必要

([¥w_ +  // 英数字+アンダ スコア'¥x{3041}‐¥x{3094}¥x{3099}‐¥x{309C}¥x{30A1}‐¥x{30FA}¥x{30FC}' + // ひらがな・カタカナ'¥x{3400}‐¥x{D7FF}' + // 漢字‘¥x{FF10}‐¥x{FF19}¥x{FF20}‐¥x{FF3A}¥x{FF41}‐¥x{FF5A}¥x{FF66}‐¥x{FF9F}]+)’);  // 全⾓形・半⾓形

);

Memo1.Clear;if m.Count > 0 then

for I := 0 to m.Count ‐ 1 do beginMemo1.Lines.Add(m.Item[I].Value);( [ ] )

endelse

ShowMessage('ハッシュタグはありません');end;

17

Page 18: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

フ イル処理あれこれファイル処理あれこれその1:3 そのファイル名・パス名処理

3

18

Page 19: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

ファイル名、パス名の処理

• SysUtilsユニットで定義されていたファイル、パス名処理関連の関数が整理され、IOUtilsユニットで再定義

• http://docwiki.embarcadero.com/VCL/ja/IOUtils– TDirectoryクラス: ディレクトリ操作関数

ク 操作関数– TFileクラス : ファイル操作関数

– TPathクラス: パス操作関数

• SysUtilsユニットで定義されていた関数は使用可能

• 全てのパス関連の関数が整理されたわけではない• 全てのパス関連の関数が整理されたわけではない– 例)IncludeTrailingPathDelimiter

19

Page 20: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

パス名関連処理の比較1:拡張子を変更する

• IOUtils.TPath.ChangeExtension関数– http://docwiki.embarcadero.com/VCL/ja/IOUtils.TPath.ChangeEx

tension拡張子を変更する– 拡張子を変更する

– SysUtils.ChangeFileExtと使い方は同じ

– 拡張子にピリオドが無くても自動的に付加してくれる拡張子 リオ 無く も自動的 付加し くれる

procedure TForm1.Button2Click(Sender: TObject);begin

edtRes lt1 Te t : ChangeFileE t(edtFileName Te t edtE t Te t);edtResult1.Text := ChangeFileExt(edtFileName.Text, edtExt.Text);edtResult2.Text := TPath.ChangeExtension(edtFileName.Text, edtExt.Text);

end;

20

Page 21: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

パス名関連処理の比較2:ファイルの検索

• TDirectory.GetFiles関数

– http://docwiki.embarcadero.com/VCL/ja/IOUtils.TDirectory.GetFiles

/ / C 代替関数– FindFirst / FindNext / FindCloseの代替関数

– ワイルドカード、再帰検索も可能procedure TForm1.Button1Click(Sender: TObject);procedure TForm1.Button1Click(Sender: TObject);var

Dir, f: string;Root: WideString;Files: TStringDynArray;

beginDir := GetMyDocumentsPath(CSIDL_PERSONAL);

ダ だif SelectDirectory('フォルダを選択してください。', Root, Dir, [sdNewUI]) thenEdit1.Text := Dir;

// ファイルを検索Files := TDirectory.GetFiles(Edit1.Text, '*.pas', TSearchOption.soAllDirectories);

// ファイル情報を取得// ファイル情報を取得with Memo1 do begin

Clear;Lines.BeginUpdate;for f in Files do Lines.Add(f);Lines.EndUpdate;

end;

21

end;end;

Page 22: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

IOUtilsユニットで再定義された関数の例

• ファイル名の取得

– SysUtils.ExtractFileName → TPath.GetFileName– http://docwiki.embarcadero.com/VCL/ja/IOUtils.TPath.GetFileNa

me

• ファイルの有無

– SysUtils.FileExists → TFile.Exists– http://docwiki.embarcadero.com/VCL/ja/IOUtils.TFile.Exists

• フォルダの作成

– SysUtils.CreateDir → TDirectory.CreateDirectory– http://docwiki.embarcadero.com/VCL/ja/IOUtils.TDirectory.Create

Directory22

Directory

Page 23: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

フ イル処理あれこれファイル処理あれこれその2:4 そのエンコーディング判定

4

23

Page 24: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

TEncoding.GetBufferEncodingの問題

• GetBufferEncodingはBOMを必要とするg• BOM無しUTF-8をDefaultとして解釈してしまう。

// エンコーディングを判別して、TEncodigを取得(?)//  ンコ ディングを判別して、TEncodigを取得(?)enc := nil;ms.Position := 0;res := TEncoding.GetBufferEncoding(ms.Memory, enc);

24

Page 25: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

エンコーディングの自動判別

• エンコーディング判別ライブラリは外部のを使用

– mlang.dll• Windows標準

• BOM無しUTF-8を正しく判別しない場合がある

– Universalchardet• Mozillaのエンコーディング判別部分をDLL化• http://www.void.in/wiki/Universalchardet

– EncodeDetect• http://www.watercolor-city.net/ct_delphi/delphi_tiburon/

25

Page 26: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

Universalchardet.dllを使用する

• DLLの関数を参照するユニットunit universalchardet;

interface

typechardet_t = Pointer;

constCHARDET MAX ENCODING NAME = 64;CHARDET_MAX_ENCODING_NAME = 64;

function chardet_create(var pdet: chardet_t): integer;stdcall; external 'universalchardet.dll' name '_chardet_create';

procedure chardet_destroy(det: chardet_t);stdcall; external 'universalchardet.dll' name '_chardet_destroy';

( )function chardet_handle_data(det: chardet_t; const data: PAnsiChar; len: Cardinal): integer;stdcall; external 'universalchardet.dll' name '_chardet_handle_data';

function chardet_data_end(det: chardet_t): integer;stdcall; external 'universalchardet.dll' name '_chardet_data_end';

function chardet reset(det: chardet t): integer;_ ( _ ) g ;stdcall; external 'universalchardet.dll' name '_chardet_reset';

function chardet_get_charset(det: chardet_t; namebuf: PAnsiChar; buflen: Cardinal): integer;stdcall; external 'universalchardet.dll' name '_chardet_get_charset';

implementationend

26

end.

Page 27: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

Universalchardet.dllを使用する

• chardet_handle_data関数でエンコーディングを判別_ _– バッファとして、TMemoryStream.Memoryプロパティがそのまま使用できる。

• chardet get charset関数でエンコーディング名を取得_g _

• TEncoding.GetEncoding関数で、エンコーディング名TEncoding.GetEncoding関数で、 ンコ ディング名からTEncodingを取得する

• 本当は、EUC-JP(CP51932)とCP21932の処理が必要

– 今回は省略

27

今回は省略

Page 28: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コードサンプル

procedure TForm1.Button1Click(Sender: TObject);varms: TMemoryStream;enc: TEncoding;encname: array[0..CHARDET_MAX_ENCODING_NAME] of AnsiChar;det: chardet t;det: chardet_t;res: Integer;

beginms := TMemoryStream.Create;

// ファイルをストリームへ読み込むIdHTTP1.Get('http://www.yahoo.co.jp', ms);

// universalchardet.dllでエンコーディングの判別det := nil;chardet_create(det);

h d h dl d (d i )res := chardet_handle_data(det, ms.Memory, ms.Size);chardet_data_end(det);

28

Page 29: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コードサンプル(続き)

// エンコーディング名の取得chardet_get_charset(det, encname, CHARDET_MAX_ENCODING_NAME);chardet_destroy(det);

// エンコーディング名からTEncodigを取得// エンコ ディング名からTEncodigを取得enc := nil;tryenc := TEncoding.GetEncoding(encname);

excepton EEncodingError doenc := TEncoding.Default;

end;end;

// オフセットをストリームの先頭にms.Position := 0;

i d ( )Memo1.Lines.LoadFromStream(ms, enc);ms.Free;

end;

29

end;

Page 30: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

ストリームI/Oの注意

• TStrings.LoadFromStreamのように、ストリームから読gみ込むときは、必ず、Positionプロパティを0にして、ストリームの先頭にする

// オフセットをストリームの先頭にms.Position := 0;;Memo1.Lines.LoadFromStream(ms, enc);ms.Free;

30

Page 31: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

GUI関連のあれこれGUI関連のあれこれその1:5 そのリストビュー

5

31

Page 32: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

リスト ビューのグルーピング

• リスト ビューのグルーピングはVista以降でサポート

• TListView.Groupsプロパティ

– ヘッダ、フッタ、サブタイトルッダ、フッタ、サブタイトル

– イメージの指定

– グループ毎にアイテムを表示/非表示グル プ毎にアイテムを表示/非表示

– タイトルの表示のみXPでサポート

• http://docwiki embarcadero com/VCL/ja/ComCtrls TL• http://docwiki.embarcadero.com/VCL/ja/ComCtrls.TListView

32

Page 33: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

TListGroupクラスの主なプロパティ

Headerプロパティ:TitleImageプロパティ:TListView.GroupHeaderImagesのインデックス

eade プ ティグループヘッダのタイトル

Subtitleプロパティ:グループヘッダのサブタイトルFooterプロパティ:

グループ化されたLIstViewItemの下部に表示するテキスト

33

下部に表示するテキスト

Page 34: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

リスト ビューのグルーピング

• TListView.GroupViewプロパティをTrueにするp

• TListView.Groups.Addメソッドでグループヘッダを追加

34

Page 35: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

リスト ビューのグルーピング

procedure TForm1.Button1Click(Sender: TObject);varGr: TListGroup;Item: TListItem;

beginGr := ListView1.Groups.Add(); // グループヘッダを追加Gr :  ListView1.Groups.Add(); // グル プヘッダを追加with Gr do beginGroupID := ListView1.Groups.NextGroupID;  // 「次」のグループIDを取得Header := 'Header' + IntToStr(GroupID);

( )Footer := 'Footer' + IntToStr(GroupID);DisplayName := 'DisplayName' + IntToStr(GroupID);Subtitle := 'Subtitle' + IntToStr(GroupID);TitleImage := GroupID mod ImageList1.Count;TitleImage :  GroupID mod ImageList1.Count;State := [lgsNormal, lgsCollapsible];

end;end;

35

Page 36: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

GUI関連のあれこれGUI関連のあれこれその2:6 そのバルーンヒント

6

36

Page 37: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

TBalloonHintを動的に表示する

• TBalloonHintコンポーネントを使って、任意の位置にヒントを表示する

• http://docwiki.embarcadero.com/VCL/ja/Controls.TBp jalloonHint

• ヘルプの表示はShowHintメソッドを使用する

– 指定する座標はスクリーン座標指定する座標はスクリ ン座標

– フォームの座標ではない

37

Page 38: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コードサンプル

procedure TForm1.Button1Click(Sender: TObject);begin

BalloonHint1 Title := 'ヒントのタイトル';BalloonHint1.Title :=  ヒントのタイトル ;BalloonHint1.Description := 'バルーンヒントを表⽰してみる。';BalloonHint1.HideAfter := 2000;

BalloonHint1 ShowHint(BalloonHint1.ShowHint(Button1.ClientToScreen(CenterPoint(Button1.ClientRect)));

end;

void __fastcall TForm1::Button1Click(TObject *Sender){

BalloonHint1‐>Title =  T("ヒントのタイトル");a oo t > t e _ ( ヒントのタイトル );BalloonHint1‐>Description = _T("バルーンヒントを表⽰してみる。");BalloonHint1‐>HideAfter = 2000;

BalloonHint1‐>ShowHint(BalloonHint1 >ShowHint(Button1‐>ClientToScreen(Button1‐>ClientRect.CenterPoint()));

}

38

Page 39: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

バルーンヒントを使う上での注意

• TBalloonHintは動的に生成しないでフォームに貼る

• ShowHintメソッドはヒントを表示したらすぐに終了するShowHintメソッドはヒントを表示したらすぐに終了する

– HideAfterで指定した値の間は停止する訳ではない

• TApplicationEvent.OnShowHintイベントが発生しない

QC#70888– QC#70888

39

Page 40: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

GUI関連のあれこれGUI関連のあれこれその3:7 そのコントロールの自動配置

7

40

Page 41: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コントロールを自動的にレイアウトする

• コントロールの位置・サイズはピクセル単位

• TForm.OnResizeイベントなどで位置・サイズを再計算

41

Page 42: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コントロールを自動的にレイアウトする

• コンポーネントの位置・サイズを自動計算するパネル

– TGridPanel• コンポーネントを格子状に配置

• http://docwiki.embarcadero.com/VCL/ja/ExtCtrls.TGridPanel

– TFlowPanel• コンポーネントを縦方向・横方向に配置

• http://docwiki.embarcadero.com/VCL/ja/ExtCtrls.TFlowPanel

42

Page 43: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コントロールを格子状にレイアウトする

• TGridPanelをフォームにドロップ

• ColumnCollection/RowCollectionでパネル内部の配置を決定する

• SizeStyleプロパティ : グリッドサイズの単位

– ssAbsolute : ピクセル単位

– ssAuto : 自動計算

– ssPercent : 割合(パーセント単位)V l プロパティ グリ ドサイズ• Valueプロパティ: グリッドサイズ

43

Page 44: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コントロールを格子状にレイアウトする

• ColumnCollection/RowCollectionの調整

– オブジェクトインスペクタのは少々使いづらいので、エディタで値を直接編集する

ColumnCollection = <item

Value = 50.000000000000000000endenditem

Value = 50.000000000000000000enditem

d>

• 注意:C++Builderではヘッダファイルが破壊される

end>

注意:C Builderでは ッダファイルが破壊される(QC#81162)ので、ヘッダファイルの末尾にダミーのコメント行を追加しておく。

44

Page 45: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コントロールを格子状にレイアウトする

• コントロールをGridPanel上にドロップすると、ControlCollectionプロパティにコントロールが追加される

45

Page 46: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コントロールを格子状にレイアウトする

• コントロールのサイズを調整する

– ControlCollectionプロパティでサイズを調整

– TControlItem型のコレクション

• TControlItemの主なプロパティTControlItemの主なプロパティ

– Columnプロパティ:配置するセルの横座標

– Rowプロパティ:配置するセルの縦座標Rowプロパティ:配置するセルの縦座標

– ColumnSpanプロパティ:セルの横サイズ

– RowSpanプロパティ:セルの縦サイズ– RowSpanプロパティ:セルの縦サイズ

– Controlプロパティ:配置するコントロール

46

Page 47: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

コントロールを格子状にレイアウトする

• 本文

– 本文

• 本文

フォームをリサイズしても、コントロールは自動的に配置さントロ ルは自動的に配置される

47

Page 48: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

まとめ8 ま め8

48

Page 49: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

アンドキュメンテッド(?)に如何にして対処するか?

• まずdocwikiを参照する!!– docwikiは随時更新しています。– http://docwiki.embarcadero.com/RADStudio/ja/Main_Page

• 試してみる

• ググるググる

• RTLのソースコードを読む

– “Use the Source Luke ”の原則Use the Source, Luke. の原則

• QCに投稿

投稿は英語だけど Google翻訳とかでOK– 投稿は英語だけど、Google翻訳とかでOK。

49

Page 50: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

アフターフォローとか

• 今日のアフターフォローは以下で行います

– 自分のBlog:http://d.hatena.ne.jp/A7M/– Twitterハッシュタグ: #dcamp jpp_jp– Twitter ID : A7M3J

50

Page 51: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

17Th

Developer Camp

Q & AQ &

51

Page 52: devcamp 20 A3.ppt [互換モード] - edn.embarcadero.comedn.embarcadero.com/.../Webseminar1109_Chkugi_PPT.pdf · 自己紹介 • 名前:筑木真志(ちくぎしんじ) – 多分、同姓同名はいません

後に

ご清聴ありがとうございました!!ご清聴ありがとうございました!!<( )><(_ _)>

52