23rd developer camp -...

Post on 07-Sep-2019

2 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

プレゼンテーション資料

TRACK B

第23回 エンバカデロ・デベロッパーキャンプ

2012年9月4日(火)

UDX GALLELY NEXT(東京/秋葉原)

Program

10:00~11:00

【A1】 Delphiテクニカルセッション

「Delphi 2009 Handbook以降の Delphi言語

新機能」

スピーカー:

福士 光

東洋テクニカルシステム株式会社 システム開発部

15 年来の Delphi ユーザ。

Delphi-ML(http://www.freeml.com/delphi-users)や公式フォーラム

に生息しています。

【B1】 C++テクニカルセッション

「業務で使える!C++実践ワンポイントテクニック」

スピーカー:

服部 励起

アナハイムエンジニアリング株式会社 代表取締役

Delphi 1.0γ 版(Windows 3.1) や Borland C++(MS-DOS)を使って業

務系システム開発を始め、1990 年代はメーリングリスト等で積

極的に普及活動を行なっていました。最近では株式会社フ ルネ

スの専属講師として、Delphi や C++ Builder の研修講師を務めつ

つ、iOS や Android のアプリ開発も行っています。

11:15~12:15

【A2】 HTML5テクニカルセッション

「HTML5アプリ開発入門」

スピーカー:

高橋 智宏

エンバカデロ・テクノロジーズ エヴァンジェリスト

Java、Delphi、C++など幅広いプログラミング言語の知識と

CORBA や J2EE をはじめとするシステム開発に関するコンサル

ティングサービス提供の豊富な経験を持つ。技術力に裏付けら

れたそのサービスには定評がある

【B2】 Delphiテクニカルセッション

「見た目で楽しい Delphiプログラミング」

スピーカー:

細川 淳

株式会社シリアルゲームズ 取締役・シニアエンジニア

PostPet V3 Windows 版の開発に関わるなど、主にエンターテイン

メント/コミュニケーション系ソフトウェアの開発を行う。高

校時代に Turbo Pascal に触れたばっかりに、今では立派な?

Delphi 使いに。VM やスクリプト言語全盛の中、ネイティブ・ア

プリケーションの復権を目指し活動し つつも、最近は Android

のプログラムを書いたりもしています。

13:30~14:30

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

「RAD Studio XE3の概要」

スピーカー:

デビッド・インターシモーネ

エンバカデロ・テクノロジーズ チーフエヴァンジェリスト

David I (デビッドアイ)の愛称で知られるデビッド・インターシモーネは、エンバカデロ・テクノ

ロジーズのチーフエヴァンジェリストとして、エンバカデロ・テクノロジーズをリードしています。

1985 年プロダクト・サービス・ディレクターとしてボーランドに参画以来、言語・ツールの研究お

よび開発に従事。ボーランド入社以前は、Softsel Computer Products Inc.(現 Merisel)のプロダクト・

サービス・ディレクターとして活躍していました。2008 年、エンバカデロ・テクノロジーズによる

CodeGear 事業本部の買収により、同社に移籍し、現在に至ります。カリフォルニア州立ポリテクニ

ック大学サン・ルイス・オビスポ校でコンピュータサイエンス学士号を取得しています。

配布資料あり

配布資料あり

配布資料あり

配布資料あり

14:45~15:45

【A4】 Delphiテクニカルセッション

「Delphi+IntraWeb+FastReportによるWeb、モバ

イル、タブレットアプリ開発」

スピーカー:

山本 悟

株式会社ドリームハイブ 代表取締役 IT コンサルタント

職業、IT コンサルタント。メンドウクサイを IT の力でラクチンに

変えるプロフェッショナルです。 1978 年東京都目黒区生まれ。

母はデザイナー、父は写真家。大学卒業後、就職せずに株式会社

ドリームハイブを設立、今年 11 期目を迎えました。多くの企業様

から 相談を受ける「課題を IT で解決するプロ」として、700 回

を超えるセミナー講演や、多数のサービスを提供しています。

【B4】 C++Builderテクニカルセッション

「 FireMonkey クロス開発テクニカルエッセンス -

アニメーションデータ作成ツール開発事例から」

スピーカー:

橋本 孔明

株式会社ウェブテクノロジ R&D 1部

弊社デスクトップアプリケーション全般の開発に携わっている

ほか、さまざまなプラットフォームおよび開発環境の技術検証

の担当も行っています。

16:00~17:00

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

「RAD Studio XE3の新機能」

スピーカー:

デビッド・インターシモーネ

エンバカデロ・テクノロジーズ チーフエヴァンジェリスト

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

「 FireMonkeyモバイル/タブレットアプリ開発」

スピーカー:

高橋 智宏

エンバカデロ・テクノロジーズ エヴァンジェリスト

J

17:15~18:15

【G6】 ライトニングトーク

「共有!みんなの開発事例、開発経験、テクニック」

司会:

はやし つとむ

アナハイムテクノロジー株式会社 代表取締役

本日のセッション資料の最新版ならびに配布資料に含まれないプレゼンテーション資料については、

後日 Embarcadero Developer Network日本語版(http://edn.embarcadero.com/jp) からダウンロードいただけます。

配布資料あり

配布資料あり

配布資料あり

「業務で使える!C++実践ワンポイントテクニック」 4

1

17Th

Developer Camp

「業務で使える!

C++実践ワンポイントテクニック」

アナハイムエンジニアリング株式会社

代表取締役

服部励起

【B1】テクニカルセッション

2

17Th

Developer Camp

エンジニアとして「都市伝説!?」1

5

B1

3

近頃!?の見たり聞いたり

• 「周りの技術レベルが低い」

• 「改修よりスクラップアンドビルドが効率的」

• 「オブジェクト指向だから開発工数が削減できる」

• 「アジャイル開発なので各種標準化は不要」

• 「ソースコードレビューは不要(出来ない)」

• 「ドキュメントよりもソースコードが重要」

• 「インデントが無いソースコードの方が読み易い」

• 「コピペしただけなので、バグは作成元に責任があり私では無い」

プロフェッショナルの仕事では無い

4

それなら私がやるしか・・・ (;´∀`)

• 技術指向より業務指向

– ハイテクニック依存は属人的になりやすい

– 組織全体としての効率化とそのテクニック中心

• プロフェッショナルとは何か?

– ソフトウェア品質特性

– 特に保守について

• C++言語特性を再確認

– 業務的視点から見たメリットとデメリット

「業務で使える!C++実践ワンポイントテクニック」 6

5

17Th

Developer Camp

集団開発技術として「業務指向開発!?」2

6

技術指向と業務指向

• 技術指向とは

– 理解できる人のみ理解できれば良い

– 華麗なテクニックや最新ライブラリ等を駆使

– 自分が頑張って勉強したので、他人も同様の努力を要求

– コメントは極力少ない傾向

• 業務指向とは

– 組織としての最大の効果を常に考える

– 技術レベルは、8割が理解できるレベルで統一

– 他人がソースを読むことを常に念頭に

– 仕様変更を念頭にクラス設計を

7

B1

7

業務指向の効果とは

• 技術指向の罠は、属人化

– 担当した仕事の保守は、概ね元担当者へ(会社側は新たな仕事を担当させられない事に)

– 属人的ソースコードの行方はスクラップアンドビルド(スクラップアンドビルドの非効率工数は誰が支払う?)

– 但し、ソフトウェア寿命がワンオフなら話は別

• 業務指向では他人に任せられる点

– 面倒な保守は新人等に担当させたい

– 転職時にも面倒な引き継ぎ期間の短縮

– 特に複雑な部分をブラックボックス化する等の柔軟性も

8

17Th

Developer Camp

プロフェッショナルとして「期待される特性」3

「業務で使える!C++実践ワンポイントテクニック」 8

9

ソフトウェア品質特性(ISO9126)

• 機能性:要求通り実装されている等

• 信頼性:バグが少ない等

• 使用性:使い易い等のUX

• 効率性:レスポンス等

• 保守性:保守する場合の対応等

• 移植性:環境変更時の対応等

• セキュリティ:機能性の一部

要件定義に記載

非機能要件と呼ばれる内容!

10

Note. 移植性の補足

• 移植性の構成要素

– 環境適応性

• インストール先変更しても問題が発生しない

– 設置性

• インストールのしやすさ等

– 共存性

• 複数のソフトウェア同士で、共存することによる問題点回避

– 置換性

• ソフトウェアの依存度や他ライブラリバージョン依存の回避

ソフトウェアアーキテクチャでの対応

9

B1

11

Note. 保守の重要性

• ソフトウェア目標寿命まで運用できること

• 保守工数がソフトウェアライフサイクルの大半を占める

– 氷山に例えられることも

• 氷山は海上は全体の10%

海面下は90%

• 初期開発工数は10%で、保守工数は90%

– 保守工数を削減し利益へ貢献

• 経営環境が迅速に変化しているため、ソフトウェア保守に時間を割くことが難しくなっている

参照: http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Iceberg.jpg

Created by Uwe Kils (iceberg) and User:Wiska Bodo (sky).

12

Note. 保守の重要性

• オブジェクト指向技術

– 保守工数の削減に利用を主眼に置き、開発工数削減を狙うと失敗する危険性が高い

• クラス設計や構成等は十二分に検討

• ソースコードに対する技術不足

– 他人のソースコードを読み、理解し、推測できる技術が特に重要

– 優れたオープンソースを読む訓練は役に立つ

「業務で使える!C++実践ワンポイントテクニック」 10

13

保守性の構成要素に対応するテクニック

• 解析性

– コーディング規約全般、命名規約、コメント規約

– 標準化運用ルール※リバースエンジニアリングツールを過信してはダメ

• 変更容易性

– コーディング規約全般、クラス設計標準

– 各種ドキュメント

• 試験性

– ソフトウェア変更標準

– ユニットテスト

14

17Th

Developer Camp

C++の言語特性4

11

B1

15

マルチパラダイムプログラミング言語

• 構造化プログラミング

– 階層的に抽象化されたプログラム記述形式

• 命令型(手続き型)プログラミング

– プロシージャ、ルーチン、サブルーチン、メソッド(グローバル関数・変数)

• オブジェクト指向プログラミング

– オブジェクトの集まりとしてプログラムを構成(C++標準)

• ジェネリックプログラミング

– データ形式に依存しないプログラミング方式(C++テンプレート機能)

16

マルチパラダイムプログラミング言語

• マクロ

– テンプレートはマクロの発展系

– C++では問題点も多いと指摘されることも

• 演算子のオーバーロード

– 演算子を別の処理にコンパイル時に置き換える

– iostreamでは普通に使われている「<<」等

「業務で使える!C++実践ワンポイントテクニック」 12

17

C++の歴史

規格制定日 C++ 標準規格 非公式名称

1998年9月1日 ISO/IEC 14882:1998 C++98

2003年10月16日 ISO/IEC 14882:2003 C++03

2007年11月15日 ISO/IEC TR 19768:2007 C++TR1

2011年9月1日 ISO/IEC 14882:2011 C++11

• 言語仕様が変遷しており、今後も変更される

• 関数型プログラミングも今後取り込む予定

• 恐らく前方互換性を持たせるため、旧規格で作成しても問題は無い

• 保守業務を考えると最新技術仕様を取り込む場合には注意が必要

18

17Th

Developer Camp

実践ワンポイント「標準化編」5

13

B1

19

1.クラス定義

• 1つの物理ソースファイルに、複数のクラス定義を実装するのを是か非か

– 関連性が維持できるクラス定義は統合するべき。但し、担当者が分散するケースが散見されるなら敢えて1

ファイルを1クラスにするのも一考

class HogeBase {protected:

virtual int Get() = 0;virtual void Set(int st) = 0;

public:HogeBase();~HogeBase();

};

class HogeData : private HogeBase {public:

int Get();void Set(int st);

};

仮想クラスを多用する場合には1クラスの方が見通しが良い

【コーディング標準】

20

2.メソッド行数制限と行内桁数制限

• メンバ関数行数制限

– 最大でも200~250行

– それ以上は分割する。但し、初期化処理は例外とする

• 1行内の桁数制限

– ディスプレイサイズで決定すれば良いのかなと・・・

– 個人的には160~180桁

※昔は80桁以内か以上で論争がありましたねぇ。

【コーディング標準】

「業務で使える!C++実践ワンポイントテクニック」 14

21

3.カプセル化方針

• 内部変数のpublic公開について

– 異論はあるが、内部変数をpublic公開は禁止

– getter/setterメンバ関数(アクセッサ)を利用するべき

– 全てのクラス内定義は、privateで作成すると便利

– クラスデフォルトはprivateだが全て記述するべき

【コーディング標準】

class HogeBase {private:

int st;protected:

virtual int Get() = 0;virtual void Set(int st) = 0;

public:HogeBase();~HogeBase();

};

DBデータを扱うクラスも、継承してメソッドをpublicで公開する

と、仕様変更時の柔軟性が上がる。

22

4.継承方針

• 多重継承の禁止

– 混乱と仕様変更時の柔軟性に影響

• 基底クラスを使い、継承を利用して公開する仕様も検討してはどうでしょう?

【コーディング標準】

//基底クラス定義class Calc_Base {public:

Calc_Base();~Calc_Base();

};// 計算クラスを継承して加算クラスを作成class Calc_Add : private Calc_Base {public:

int Opereation(int data1, int data2);};// 計算クラスを継承して減算クラスを作成class Calc_Sub : private Calc_Base {public:

int Opereation(int data1, int data2);};

継承階層が深くなり過ぎないように注意する必要はあります。

15

B1

23

5.コンストラクタとデストラクタ

• 使用しない場合でも定義だけはコーディング

– 修正が必要となった場合に楽

• 継承時の実行順番は重要!

– ①スーパークラスのコンストラクタ②サブクラスのコンストラクタ③サブクラスのデストラクタ

④スーパークラスのデストラクタ

【コーディング標準】

24

6.パラメタ設計方針

• 大きく分類して2種類

– getter/setterメンバ関数は欲しい結果をreturnで受け取る

– returnで受け取るのは、メンバ関数が動作したbool情報とし、結果値は別メンバ関数経由で返却

• getter/setter系メンバ関数

– 結果情報を直接returnで返却する方式

【コーディング標準】

class CalcAdd : private CalcBase {public:

int Opereation(int data1, int data2);};

int CalcAdd::Opereation(int data1, int data2) {return data1 + data2;

}

「業務で使える!C++実践ワンポイントテクニック」 16

25

6.パラメタ設計方針

• returnでbool値(int値も可)で動作状態判別系

– メンバ関数が正常に動作したのかをreturnで通知し、その時メンバ関数が行なったデータは別メンバ関数(getter)で行う

【コーディング標準】

class hoge {private:

DB_EmpData data;public:

hoge();~hoge();bool getEmployee(int empNumber); //社員情報の取得メンバ関数DB_EmpData getEmpData(); //取得した社員データ提供メンバ関数

};

26

7.構造体・共用体

• C++ではクラスで代用できるため、コーディング標準的には積極的には使用しない方向で

• C言語開発経験者が多いプロジェクト等ではC++でも利用されている可能性も

【コーディング標準】

struct hoge {protected:

int a;public:

hoge();int getA() {return a;}

};struct hoge2 : public hoge {private:

int b;public:

hoge2();int getB() {return b;}

};

17

B1

27

8.演算子のオーバーロード

• 一般的には極力控えた方が、保守性に貢献するものと想定します。

– 演算子のオーバーロードを自由自在に操れる人は少数

– 属人的になりやすいため敬遠することが賢明

• 演算子としか見えないため、オーバーロードされていると気が付きにくい。

– きちんと管理されていれば、利用することは吝かではない

【コーディング標準】

28

9.マクロの扱い

• マクロとは

– コンパイラがソースコードをコンパイルする直前に、プリプロセッサで実行される命令群

– スコープがプロジェクト全体

– コンパイラに近い言語と言え、習熟している人は少ない

• 基本的にマクロ使用は最低限度に抑え、保守性を向上させる方針を推奨

– 関数形式マクロを使うならテンプレート化を検討

【コーディング標準】

オブジェクト形式マクロ文法#define [マクロ名] [置換文字列]

関数形式マクロ文法#define [マクロ名](引数リスト) [置換文字列]

「業務で使える!C++実践ワンポイントテクニック」 18

29

10.テンプレート

• テンプレートのメリット

– マクロより型安全

• テンプレートのデメリット

– 移植性が低い

– エラーメッセージが分かり辛い

– 実行ファイルが大きくなる危険性もある

• テンプレートの使用は、テンプレート関数までとし複雑になりやすいテンプレートクラスは避ける

• 特に実行時デバッグでは分かり辛いため、デバッグ効率性かも極単機能で分り易いものだけに限定

【コーディング標準】

30

10.テンプレート

例)

【コーディング標準】

template <class X> int operation(X *obj, int data1, int data2) {return obj->Operation(data1, data2);

}

void __fastcall TMyCalc::bt_equClick(TObject *Sender){

int ans;switch(calc_kind) {

case C_add: {CalcOpe_Add obj;ans = operation(obj, data1.Get(), data2.Get());break;

}case C_sub: {

CalcOpe_Sub obj;ans = operation(obj, data1.Get(), data2.Get());break;

}}Panel1->Caption = IntToStr(ans);

19

B1

31

11.define, const, typedef

• defineはマクロのため、コンパイル時に置き換え

• constは修飾子のため、全てに使用可

• typedefは変数の型を独自に定義

• マジックナンバーはdefineかconstで定義しておく

– constは型を指定できるため、こちらを推奨

– スコープはdefineは全体。constはソース定義範囲。

【コーディング標準】

const int MAX_ARRAY_SIZE = 3000;

#define MAX_ARRAY_SIZE 3000

typedef int myInt16; //myInt16という型を定義#define myInt16 int //typedefと同じ効果を持つ

32

12.constメンバ関数

• メンバ関数に付与することで、その関数内でメンバ変数の値を変更しない

– getterメンバ関数等で使うと非常に便利

class constClass{

int i_test;const int MAX_SIZE;mutable int m_test; //mutableを使うとconst中でも変更可だが・・・

public:constClass() : MAX_SIZE(10) {} //コンストラクタで初期化int getMaxSize() const { //constメンバ関数

m_test = 3;// i_test = 10; コンパイルエラー// MAX_SIZE = 20; コンパイルエラー

return(MAX_SIZE);}

};

【コーディング標準】

「業務で使える!C++実践ワンポイントテクニック」 20

33

12.各種命名規約

• 組織等で分り易い記述形式にし、変数からメソッド、クラス名、例外エラークラス等ざっくりとでも決定

• ハンガリアン記法

– データ属性を小文字の接頭語として使用

• キャメル記法

– 単語の区切りを大文字を利用する

// ハンガリアン記法int iCount;char cName[10];

// キャメル記法std::string lastName; //ローワーキャメルケースstd::string FirstName; //アッパーキャメルケース

34

13.コメント規約

• ファイルコメント

– .cppや.hファイルの先頭に、作成者やファイルの概要や名前、修正履歴等を記入(ドキュメントの不備等に対応させる目的)

• クラス・メソッドコメント

– クラス定義部と各メソッド実装部に、簡単でも目的

– 実装でトラブルがあった場合、トラブル内容等を簡易に記述する

• 実装コメント

– 例外処理や、規約違反している場合の詳細説明、実装に苦労した内容等を詳細に記載

21

B1

35

17Th

Developer Camp

実践ワンポイント「ツール編」6

36

1.ユニットテストの活用

• テストプロジェクトの追加

「業務で使える!C++実践ワンポイントテクニック」 22

37

1.ユニットテストの活用

• テストケースの追加

38

2.GExpertsの活用

• GExperts

– 機能が多すぎで分かりません。 (^^;;

– Editor Experts

• エディタの補完を行ってくれます

– Grep Results/Grep Search

• プロジェクト全体のGrepも出来ます

– Procedure List

• 今開いているファイル内の関数一覧

http://www.gexperts.org/

23

B2

1

17Th

Developer Camp

「見た目で楽しい Delphi プログラ

ミング」

会社名 株式会社シリアルゲームズ

名前 細川 淳

【B2】Delphi テクニカルセッション

2

アジェンダ

• VCL / FireMonkey のスタイルの触りを紹介します

• VCL スタイル

– TStyleManager

• FireMonkey スタイル

– TStyleBook

「見た目で楽しい Delphi プログラミング」 24

3

17Th

Developer Camp

VCL スタイル1

4

VCL スタイル

• Delphi XE 以前– TThemeServices

• OS が提供する「テーマ」を利用するクラス

• Windows XP Style (Luna など)に対応するために追加されました

• ※XE2 以降でも依然として利用可能

• Delphi XE2 以降– TStyleManager

• VCL / FireMoneky に新しく追加された「スタイル」を利用するクラス

• スタイルを利用すると、OS のビジュアル(見た目)から解放されます

→特にマルチプラットフォームである FireMonkey において重要

25

B2

5

VCL スタイルの一番簡単な使い方

好きなスタイルにチェックを入れる

※スタイルを1個でも追加すると120[KB]程

ファイルサイズが増加し、スタイル一個につきファイルサイズが40~60[KB]増加する

デフォルトのスタイルを選ぶ

たったこれだけ!

6

17Th

Developer Camp

VCL スタイルを適用する

デモンストレーション

「見た目で楽しい Delphi プログラミング」 26

7

17Th

Developer Camp

VCL スタイルをプログラムから使う1

8

VCL スタイル - TStyleManager

• TStyleManager.TrySetStyle

– スタイルを設定するメソッド

– とりあえずこのメソッドさえ知っていればスタイルの適用は可能

procedure TForm1.Button1Click(Sender: TObject);beginTStyleManager.TrySetStyle('Amakrits'); // スタイルの名前

end;

27

B2

9

VCL スタイル - TStyleManager

• TStyleManager.StyleNames

– 使用可能なスタイルを返すメソッド

procedure TForm1.Button2Click(Sender: TObject);varStyleName: String;

beginfor StyleName in TStyleManager.StyleNames doListBox1.Items.Add(StyleName);

end;

procedure TForm1.Button3Click(Sender: TObject);begin// SetStyle は内部で TrySetStyle を呼び出し、失敗すると例外をあげるif (ListBox1.ItemIndex > -1) thenTStyleManager.SetStyle(ListBox1.Items[ListBox1.ItemIndex]);

end;

名前をリストアップして、それを適用します

10

17Th

Developer Camp

VCL スタイルをプログラムから適用する

デモンストレーション

「見た目で楽しい Delphi プログラミング」 28

11

17Th

Developer Camp

VCL スタイルを自分で作ってみる1

12

VCL スタイル - VCL スタイルデザイナ

自分でスタイルを作成する場合、VCL スタイルデザイナを使います。

29

B2

13

VCL スタイル - VCL スタイルデザイナ

• スタイルは基本的に各部分部分を表す画像で提供されます

– ゲームのように一枚の画像からパーツを切り出して使います

• 設定項目が多い!

– 自分のスタイルをゼロから作ろうと思っても挫折します

– 既存のスタイルを修正していくと良いでしょう

14

VCL スタイル - VCL スタイルデザイナ

一枚の画像に全ての構成要素をいれます

選択部分が反映されています

「見た目で楽しい Delphi プログラミング」 30

15

VCL スタイル - VCL スタイルデザイナ

スタイルデザイナ上で確認できます

16

17Th

Developer Camp

VCL スタイルスタイルデザイナの

デモ

31

B2

17

VCL スタイル - 自作スタイルの使い方

まず Object のトップのプロパティを設定しておきます

Name プロパティがスタイルの名前になります

18

VCL スタイル - 自作スタイルの使い方

• TStyleManager.LoadFromFile

– スタイルファイルを読み込むメソッド

procedure TForm1.Button2Click(Sender: TObject);beginTStyleManager.LoadFromFile('C:¥Temp¥TestStyle.vsf');TStyleManager.TrySetStyle('TestStyle'); //スタイルデザイナで設定した名前

end;

「見た目で楽しい Delphi プログラミング」 32

19

procedure TForm1.Button2Click(Sender: TObject);varStyleInfo: TStyleInfo;

beginif (TStyleManager.IsValidStyle('C:¥Temp¥TestStyle.vsf', StyleInfo))

thenwith StyleInfo doShowMessage(

Name + sLineBreak +Author + sLineBreak +AuthorEMail + sLineBreak +AuthorURL + sLineBreak +Version

);end;

VCL スタイル - 自作スタイルの使い方

• TStyleManager.IsValidStyle

– スタイルファイルの正当性チェック&スタイル情報取得

実行結果

20

17Th

Developer Camp

VCL スタイルスタイルファイル読み込みデモ

33

B2

21

17Th

Developer Camp

VCL スタイルを使用するコントロールの作成1

22

VCL スタイル - コントロールの作成

一番単純な方法は Paint メソッドや WM_NCPAINT, WM_PAINT に応えて自分で実装します。

procedure TForm1.PaintBox1Paint(Sender: TObject);varDC: HDC;R: TRect;

beginDC := PaintBox1.Canvas.Handle;R := PaintBox1.ClientRect;

StyleServices.DrawElement(DC,StyleServices.GetElementDetails(tbPushButtonNormal),R);

StyleServices.DrawText(DC,StyleServices.GetElementDetails(tbPushButtonNormal),'TEST CAPTION',R,TTextFormatFlags(DT_CENTER or DT_VCENTER or DT_SINGLELINE),StyleServices.GetStyleFontColor(sfButtonTextNormal));

end;

ノーマル状態のボタンを描画する例

「見た目で楽しい Delphi プログラミング」 34

23

VCL スタイル - コントロールの作成

• 一般的に、VCLスタイルの描画は TStyleHook を使います。

– TStyleHook とは TStyleManager から呼び出されコントロールの描画を担います。

– WM_PAINT やWM_NCPAINT などを「フック」して、それらの応答をコントロールに変わって実行します。

– ただし、OS 標準スタイル時の描画には使われません

• 標準のスタイル時は、従来と同様に、コンポーネントのPaint メソッドなどで処理されます。

24

VCL スタイル - TStyleHook の実例

unit uTestControl;

interface

usesWinapi.Windows, Vcl.Controls, Vcl.ExtCtrls, Vcl.Graphics, Vcl.Themes;

typeTTestControl = class(TPanel)privateclass constructor Create; // クラスコンストラクタは initialization に追加するのと同じ

end;

implementation

typeTTestControlStyleHook = class(TStyleHook)protectedprocedure Paint(Canvas: TCanvas); override;

publicconstructor Create(iWinControl: TWinControl); override;

end;

35

B2

25

VCL スタイル - TStyleHook の実例

{ TTestControl }

class constructor TTestControl.Create;begin// StyleHook とコントロールを結び付けますTCustomStyleEngine.RegisterStyleHook(TTestControl, TTestControlStyleHook);

end;

{ TTestControlStyleHook }

constructor TTestControlStyleHook.Create(iWinControl: TWinControl);begininherited;

OverridePaint := True; // Paint メソッドをフックしますよ、という意味end;

procedure TTestControlStyleHook.Paint(Canvas: TCanvas);begin// TTestControl の Paint の代わりにこちらが呼ばれる(ノーマル状態のボタンを描画する例と同様のため中略)

end;

end.

26

VCL スタイル - TStyleHook の実例

TTestControl が継承している TPanel の標準の見た目が描画される

TTestControlStyleHook がスタイルに応じた見た目を描画する

Windows 標準時

VCL スタイル適用時

「見た目で楽しい Delphi プログラミング」 36

27

17Th

Developer Camp

VCL スタイルTStyleHook

デモ

28

17Th

Developer Camp

FireMonkey スタイル1

37

B2

29

FireMonkey スタイル

• FireMonkey のスタイルは VCL スタイルとはまったく異なります。

– 個々のコントロールがスタイルを持っている

• TStyledControl を継承したコントロール

• 個別に設定できる

– スタイルは TStyleBook で管理される

• TStyleBook で定義済みのスタイルリソースを読み込むとスタイルを一括で変更できる

30

FireMonkey スタイル

• 一番簡単な使用方法は…

– Form に TStyleBook コンポーネントを貼る

– TStyleBook コンポーネントの「Resource」プロパティをクリックしてスタイルエディタを開く

– スタイルエディタから定義済みスタイルを読み込む

– 「適用して終了」を押す

「見た目で楽しい Delphi プログラミング」 38

31

FireMonkey スタイル 簡単な設定方法

スタイルエディタを開く

定義済みスタイルを開く

32

FireMonkey スタイル - コンポーネント毎

• 個々のコンポーネントごとに編集する方法は…

– コンポーネントを右クリックして

– 「カスタムスタイルの編集」「デフォルトスタイルの編集」のどちらかを選ぶ

– スタイルエディタが開く

– 「適用して終了」を押す

※個々のコンポーネントのスタイルを編集すると、自動的にTStyleBook コンポーネントのインスタンスが生成される

39

B2

33

FireMonkey スタイル - コンポーネント毎

スタイルエディタを開く

スタイルの要素のプロパティはオブジェクトインスペクタに表示され編集可能

34

FireMonkey スタイル - コンポーネント毎の例

• フォーカス時に使われる TGlowEffect の色を変えてみる

GlowEffect の色

GlowEffect が発動するトリガーほかにも IsMouseOver などがある

GlowColor を「Crimson」($DC143C)

に変更

「見た目で楽しい Delphi プログラミング」 40

35

FireMonkey スタイル - StyleLookup

• コンポーネントの StyleLookup プロパティを設定するとデフォルトのスタイルを変更できます。

– StyleLookup プロパティは、このコントロールが使うスタイルの名前です。

– このプロパティが設定されると FindStyleResource メソッドによって適切なスタイルが設定されます。

36

FireMonkey スタイル - StyleLookup

• TPanel の StyleLookup を変更して見た目をボタンのようにしてみます。

41

B2

37

17Th

Developer Camp

FireMonkey スタイルデモ

38

17Th

Developer Camp

FireMonkey スタイルそのほか1

「見た目で楽しい Delphi プログラミング」 42

39

FireMonkey スタイル

• スタイルの個々の要素をプログラムから変更することができます(本当は)

• 現状では小細工しないと変更できません

– Delphi XE2 Update4 で確認(QC100275 既に Closed)

– これについては、EDN TeamJapan の高橋さんのブログ記事が詳しいです• http://blogs.embarcadero.com/teamj/2011/11/11/2589/

FireMonkeyのコンポーネントのFindStyleResourceメソッドを呼び出して、スタイルにアクセスしようとしますが、なぜかnil(見つからなかったということ)が返ってきてしまいます。

この問題(現象)はQualityCentralにも報告されたのですが、トップレベルのスタイルの場合、親クラスである「TStyleControlクラスのprotectedなメンバであるFResourceLink」にアクセスする必要がある(As Designed, 仕様)という結果になりました。

上記記事より引用

40

17Th

Developer Camp

付録:UI 設計の指針1

43

B2

41

UI 設計の指針

• VCL / FireMonkey スタイルを利用することで OS の見た目から解放されます。

• しかし、OS の UI から解放されるわけでありません。そのため OS で提供されている一般的な操作が犠牲になる場合があります。

– 例として

• Flash (Air)

– Win / Mac / Linux で動作するが、一般化のためにコンテキストメニューが廃止されている

• Unitiy

– Android / iOS などで動作するが、一般化のために「戻るボタン」によるActivity 遷移がサポートされていない

• FireMonkey の場合は特に OS の提供する UX の犠牲を最小限にとどめる必要があります。

• VCL はWindows アプリケーションとなりますが、見た目が自由になったからといって、独自すぎる UI を提供すべきではありません。

42

UI 設計の指針 - 一般的論としての UI

• 視線は左から右、上から下に流れる

視線の流れ

←ここには視線が最後にたどり着く

左上から見ていって、途中に問題がない事を確認していくので、UI の右下に「OK」や「確認」といったボタンがある

このコンテキストで一般的な動作は右側にイリーガルな操作は左側に。

上記原則に反するが、Windows はMacOS との類似を避けるためにOK ボタンを左にしたFireMonkey の場合は、MacOS に合わせるか、Windows に合わせるかはメインターゲットによる。もしくは、プログラムで動的に変更する

参考として Android は 2.x までは左側、3.x からは右側に変更されている

「見た目で楽しい Delphi プログラミング」 44

43

UI 設計の指針 - 一般的論としての UI

• 視覚効果は感覚に合わせる– グレーアウトされていれば押せない

• MouseOver で凹むボタンなど言語道断

– 感覚としてボタンは押されると凹むもの

– 曖昧なアイコンは使わない

グレーアウトされているボタンは押せない。

マウスオーバーするとグレーが解除されたり、ポップアップしたりして押せる事をアピールする変な動作がウェブにあふれていますが、間違い。

このアイコンをクリックすると起きるアクションは?・音がOFFになる・音がONになるどっち?

44

UI 設計の指針 - 一般的論としての UI

• その UI で正しいかどうか考慮する

– TComboBox と ListBox

– TLabel と TImage

– TMainMenu と TPopupMenu

– etc.

都道府県の選択の場合、どの UI が正解だと思いますか?

45

B2

45

UI 設計の指針 - その他の事

ターゲット層 ターゲットデバイス ターゲット UI

ターゲット UI はターゲット層で決まる

色覚異常への対応

それぞれが判別可能か?

ユーザビリティテスト

独りよがりな UI になっていないか?

46

17Th

Developer Camp

質疑応答1

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 46

1

17Th

Developer Camp

「FireMonkeyクロス開発テクニカルエッセンス - アニメーションデー

タ作成ツール開発事例から」

株式会社ウェブテクノロジ

R&Dグループ

橋本孔明(Yoshiaki Hashimoto)

【B4】 C++Builderテクニカルセッション

2

はじめに

本日はご来場いただきありがとうございます

47

B4

3

自己紹介

橋本孔明(はしもと よしあき) hashimoto@webtech.co.jp

‒ 経歴• 勘違いからPC入門と同時にプログラミング入門

• 中高生時代、VC++、Delphiなどいろいろな環境でオンラインソフトを作っていたことがきっかけで入社

‒ 現在• Windows・Mac・スマートフォンなどなんでも手がける

• プロダクト開発のほか、各種プラットフォームおよび開発環境の調査や導入決定などにも携わる

• 基本的にC++屋(STL/Boost/C++11などを多用)

‒ その他

• 趣味人間(鉄道、釣り、アクアリウムとか)

4

会社紹介 - 株式会社ウェブテクノロジ

各種製品・サービスの企画・開発・販売・サポート– 画像最適化ツール『OPTPiX imésta』ゲーム業界国内シェア100%

– スプライトアニメーション作成ツール『SpriteStudio』

– 携帯電話向け画像最適化ASP『OPTPicture』

– 絵を描かずにマンガが作成できる『コミPo!』

受託開発– 大手電機メーカー向けデータ放送用画像変換モジュール

– 大手コンテンツプロバイダ向け高機能画像変換システムの提供

– 大手光学機器メーカー複合機内蔵PDF生成用減色モジュールの提供

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 48

5

アジェンダ

1. ソーシャル開発におけるプラットフォームの変遷

2. 「SpriteStudio」の紹介

3. クロスプラットフォーム開発環境の模索

4. C++Builder XE2&FireMonkeyとの出会い

5. FireMonkey苦労話(今回のメイン)

6. まとめ

6

17Th

Developer Camp

ソーシャル開発におけるプラットフォームの変遷1

49

B4

7

ソーシャル開発環境の変遷

‒ ソーシャルゲーム:iOSデバイス、Androidデバイスなどで動作するゲームの呼称

• 必ずしもネットワーク要素を含まない

‒ 従来、ゲームプログラム開発はWindows環境が主流

‒ iOSの台頭により、MacOS X上での開発が必須に

‒ MacOS X上ではAndroid開発(Eclipse)も行える

‒ すべてをMac上で済ませるベンダーが増えた

‒ 開発ツール類のMac対応要望が増加

8

17Th

Developer Camp

「SpriteStudio」の紹介2

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 50

9

SpriteStudioとは(1)

SpriteStudio(スプライトスタジオ)は、汎用的なアニメーションデータ作成ツールです。

for Designers for Programmers for All Developers

•ドラッグ&ドロップなど直感的な操作で、アニメーションデータの作成が可能に

•タイムチャートとグラフでアニメーションデータを視覚的に管理

•動きを付ける作業をデザイナに任せることにより、負担が軽減

•SDKを使って、アニメーションデータのコンバータにも簡単に作成可能

•SpriteStudioが、アニメーションの開発効率を向上させる!

ドラッグ&ドロップなどの簡単な操作

キーフレーム方式で楽に編集

タイムチャートによる視覚的な管理

動きを組み合わせるシーン編集モード

ソフトがなくても確認できるビューア

SpriteStudio SDK

トラッキングモードによるキーフレーム化

「イベントデータ」の編集と管理

http://www.webtech.co.jp/spritestudio/

10

SpriteStudioとは(2)

‒ スプライトアニメーション編集ツール

‒ 著名コンシューマーゲーム、ソーシャルゲーム等での採用事例多数

51

B4

11

SpriteStudioとは(3)

‒ リリース中のバージョンはWindows専用

• VC++、ネイティブC++およびWin32 APIで開発

‒ MacOS Xにて、仮想環境上のWindowsによる動作も可能だが…

‒ Mac版の要望を多数頂戴

‒ 開発決定

12

17Th

Developer Camp

デモンストレーション

SpriteStudio

開発途上版

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 52

13

17Th

Developer Camp

クロスプラットフォーム開発環境の模索3

14

要件定義

‒ MacOS XとWindowsのGUIの違いを吸収したい

• メニューバー位置などはOSネイティブに合わせたい

‒ OSネイティブではなく、ダークグレーベースの外観としたい

• 他のデザイナー向けプロフェッショナルツールでも導入事例が多い(Adobe CS6、3Dツールなど)

• 見た目が良いというだけではなく、デザイナーの長時間利用に耐え、目に優しい色遣いとなっている

‒ プロフェッショナルユースに耐えうるUX設計

‒ 社内ツールや簡単なフリーソフトなどとは違います

53

B4

15

クロスプラットフォーム開発環境の模索

いくつかの候補を調査

‒ C/C++&ネイティブAPI

‒ Mono

‒ Qt

‒ wxWidgets

‒ C++Builder XE2

※主観がかなり入っています

16

C/C++&ネイティブAPI

○ UIはそれぞれのプラットフォームに合わせて細かく設計可能

○ 確実な開発環境(VC++/Xcode)の存在

× 標準コントロールのみを使用していると「古くさい」UI

になる(特にWindows)

× 標準コントロールのカスタマイズが難しく、なんでもかんでも自作していく羽目に

• 昔は実際にやっていましたが…

× MacOS Xネイティブ開発技術の習得

• ただしiOS学習である程度のObjective-Cの知識有り

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 54

17

Mono

C#および.NETを用いたクロス対応開発環境

IDEとしてMonoDevelopを使用

○ C#でRAD風の開発が可能(Windows Forms)

○ .NET(Windows Forms)開発知識が転用可能

× .NETの最新潮流であるWPFは使用できない

× UIがOSネイティブに準じてカスタマイズしにくい

× 中間コードで出力されることによるソフトウェアプロテクトへの不安

18

クロス対応GUIフレームワーク

C++で記述可能なGUIフレームワーク

(Qt、wxWidgetsなど)

○ C++やネイティブAPIが使用できる

× 商用サポートを受けるためにはライセンス料金が高額だったり、そもそもサポートが無かったり

× 他はネイティブと同じデメリット

× 日本語情報の不足(微妙に不安)

× 試そうとしたがビルド環境構築(OSX)で挫折

55

B4

19

C++Builder XE2

実は当初候補に入っておらず、他のダメ出しをした

後で存在を思い出し、検討を開始

○ C++で開発可能

○ 昔のVCLの知識が役立つ?

○ Windows上で同時開発し、MacOS Xプログラムのデバッグがリモートで可能

○ 柔軟なGUI設計が可能

× Mac開発の実績がいまいち不明

20

17Th

Developer Camp

C++Builder XE2&FireMonkey

との出会い4

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 56

21

試用版でFireMonkeyプラットフォームを学習

‒ Delphi/C++Builderの知識はVer6くらいで止まっていた&かなり忘れていた

‒ 久々に起動したC++Builderはすっかり変わって…

‒ FireMonkeyプラットフォームはVCLの面影がなんとなく残っていた

‒ スタイル編集により、GUI要素の外観カスタマイズが自在→これはいけそう

22

早速開発に着手

‒ アプリケーションの性格上、いきなりOpenGLの導入など高度な要素から挑戦

• 後から「無理」と判明すると困る

‒ 買って数日でランタイムライブラリの内部を覗いたりする羽目に…

• C++Builder単体より、ランタイムソースの付いているRAD Studioを持っていた方がよさそう

‒ ランタイムはDelphi製

‒ 忘れかけていたDelphi言語知識をなんとか思い出す

57

B4

23

17Th

Developer Camp

FireMonkey

苦労話(今回のメイン)

5

24

注意事項

‒ 基礎知識的なものは省略します

‒ 独自調査に基づく項目が多く含まれます

‒ 他開発環境(VC++)からの移行も重視しています

‒ 弊社の開発スタイルの都合に合わせるための対策も含まれます

• 実際には別の解決策があったり、公式には他の方法が推奨されている可能性があります

‒ XE3になると解消する問題もありそうです

‒ WindowsをWin、MacOS XをOSXと省略

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 58

25

17Th

Developer Camp

C++環境レベルでの違い

26

C++環境レベルでの違い(1)

• ビルド分けしたい場合

– #ifdef __APPLE__ でOSXを識別

– #ifdef _WIN32(#ifdef _WINDOWS) でWinを識別

– Winのx64では_WIN64が加わります(_WIN32も存在)

• CRT関数の違い

– Windowsで使われるwcscpy_s()などがOSXには無い

• OSXはPOSIX準拠+α 程度のCRT関数しか無い

• VC++などで書いたコードの移植時に注意

• 汎用処理はRTLの機能か、STL・Boostに頼る

59

B4

27

C++環境レベルでの違い(2)

• Win32構造化例外はOSXにはありません

– アクセス違反などはシグナルハンドラで捕まえます

– 他コンパイラでtry-catchを流用していたコードも注意

• Boostの一部機能が使えない(XE3で解消?)

– OSXではスタティックライブラリを要するBoostコンポーネントの大半が使用不可能(ヘルプに記載はあったが…)

– serialization、filesystemなど

• 文字列リテラルの文字コード

– Windowsはシステム依存、OSXは基本的にUTF-8

– この問題は深いので各自研究してください

28

C++環境レベルでの違い(3)

wchar_tの違い(公式でも解説されている)

‒ Winでは2bytes、OSXでは4bytes

‒ UnicodeString(String)型、WideChar型はどちらのOSでも2bytesベース

‒ このためOSXではwchar_tを使用するCRT関数・std::wstring・Boostなどへのアクセスが不便

‒ UnicodeStringからstd::wstringへの変換関数を自前で用意しました(ただし重そう)

‒ テンプレートにWideCharを適用した型を自分で定義して使う方法もある

‒ std::basic_string、boost::basic_formatなど

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 60

29

コードサンプル

inline std::wstring wstring_from_UnicodeString(const UnicodeString& str)

{#ifdef __APPLE__

return(wchar_t*)PUCS4Chars(

UnicodeStringToUCS4String(str));#else // 手抜き。将来のiOSやAndroidを考えると非推奨

return str.w_str();#endif}

30

C++環境レベルでの違い(4)

L”hello” と u”hello” と _D(”hello”)

‒ L”hello”はWinで2バイト文字、OSXでは4バイト文字

• 厳密にはwchar_tの配列(環境ごとにサイズ可変)

‒ u”hello”はOSXでも2バイト

• 厳密にはchar16_tの配列(C++11で導入)

• char16の名の通り、どんな環境でも「最低」2バイト

• 大文字のU””にするとchar32_t

‒ _D(”hello”)にするとどちらでも2バイト

• UnicodeStringに渡すならとりあえずこれがいいらしい

• マクロなので何かあっても後で再定義すればいい

61

B4

31

17Th

Developer Camp

OSネイティブAPI

の呼び出し

32

OSネイティブAPIの呼び出し

‒ FireMonkeyだけでも結構なものは作れる

‒ 細かいユーザーインターフェースの改良にはどうしてもネイティブAPIのサポートが必要となる

‒ SpriteStudioの場合、アニメーション再生にOpenGLが必要となった

‒ OSXのネイティブAPIはObjective-Cだが…?

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 62

33

OSネイティブAPIの呼び出し:Windows

‒ 大半がただの関数なのであまり難しくない(必要なヘッダをincludeして呼ぶだけ)

‒ ハンドルの取得方法さえわかれば大丈夫

#include <FMX.Platform.Win.hpp>

FmxHandleToHWND(this->Handle); // TForm*からHWND(HMENU)(pMenu->Handle); // TMenuItem*からHMENU

34

OSネイティブAPIの呼び出し:MacOS X

‒ Cocoa API:Objective-Cの知識が必要

‒ ランタイムが、Objective-CクラスをC++クラス(イン

ターフェース)として呼び出せる高度なラッパーを提供している

‒ Delphi向けのためC++での記述方法がかなり特殊

‒ 私もまだ完全理解には至っていません

‒ 公式の説明が見あたらない…

‒ Carbon APIなら簡単です

• Win32 APIと同じくC関数呼び出し方式

• 最新のOS機能には非対応

63

B4

35

コードサンプル

// 必要となるヘッダ#include <FMX.Platform.Mac.hpp>#include <Macapi.Foundation.hpp>#include <Macapi.AppKit.hpp>

// TForm*からNSWindowを得る// Cocoaクラス名に接頭辞_di_が付くものとTが付くものがあり役割も分かれる_di_NSWindow wnd =

TNSWindow::Wrap(_di_ILocalObject(FmxHandleToObjC(pForm->Handle))->GetObjectID());

// 自アプリのNSBundleを得る(クラスメソッド呼び出し)// 生のObjCクラスポインタはWrapしてラッパクラス(スマートポインタ)化するVoid* pMainBundle = TNSBundle::OCClass->mainBundle();_di_NSBundle bundle = TNSBundle::Wrap(pMainBundle);

// 得られたNSWindowインスタンスのメソッドを呼んでみる// NSString生成にはRTL提供のNSSTR関数が利用可能// [wnd setTitle: @”Hello World”]; ObjCの記法wnd->setTitle(NSSTR(_D(”Hello World”))); // C++同等に呼べる

36

コードサンプル

// TForm*からNSViewを得るTObject* pObj =

_interfaceToObjectCast<TObject>(FmxHandleToObjC(this->Handle));

if(pObj){

boost::scoped_ptr<TRttiContext> pRttiContext(new TRttiContext);TRttiType* pRttiType = pRttiContext->GetType(pObj->ClassType());if(pRttiType){

TRttiProperty* pRttiProperty = pRttiType->GetProperty("View");if(pRttiProperty){

_di_NSView view = pRttiProperty->GetValue(pObj).AsInterface();return view;

}}

}

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 64

37

17Th

Developer Camp

OSごとのメニューの違い

38

OSごとのメニューの違い

‒ 結構マニアックな内容に

‒ しかし、メニューはアプリケーションGUIの基本中の基本

‒ 中規模以上のアプリケーションを開発するには、メニューを柔軟に制御する必要はどうしても出てくる

‒ GUI要素でOSネイティブなのは基本的にメニューだけ(それ以外のコントロールはFireMonkey経由)

‒ 以上の理由により、複雑になりがちですが、ちょっと詳しくまとめてみました

65

B4

39

OSごとのメニューの違い - Windows

ショートカットキーとアクセラレータが別の概念となっている

40

OSごとのメニューの違い – MacOS X(1/2)

Windowsでいう「ショートカットキー」が無く、

「アクセラレータ」相当を「ショートカット」と呼称

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 66

41

OSごとのメニューの違い – MacOS X(2/2)

「アプリケーションメニュー」の存在

Windowsでいうところの「システムメニュー」

「ツール」「ヘルプ」などの内容に相当

42

OSごとのメニューの違い – その他

‒ メニュー配置の「常識」の違い

• OSXでは「終了」は「ファイル」の中ではない

• バージョン情報や環境設定はアプリケーションメニューに入っている

‒ 同じ内容でも微妙に表現が違う

• Win:切り取り・コピー・貼り付け

• OSX:カット・コピー・ペースト

‒ ショートカット文字列の有無

‒ Ctrlキー vs. Commandキー

67

B4

43

OSごとのメニューの違い – 解決策

‒ フォーム上に別々のTMenuBarを作っておき、OSごとに割り付けすることで、ある程度解決可能

‒ しかし、今後の変更やローカライズを考えるとフォーム上のアイテムでの個別管理はわずらわしい

‒ そこで、メニュー内容をXML化しリソースに格納

• 属性としてWindows用・MacOS X用などのフラグを追加

• ショートカットもOS別に指定可能とした

• これをRTLのTXMLDocumentで読み込み、TMenuBar/TMenuItemを構築するライブラリを開発

44

メニュー定義用XMLサンプル(抜粋)

<!-- Commandにコマンド文字列(イベントハンドラ関数に渡される)を指定する --><!-- WinShortcutでWindowsショートカットキーのアルファベットを指定する --><!-- Accelにアクセラレータキーのキーコンビネーションを文字列で指定する --><!-- 一般的な流儀に沿い、WinでCtrl+●、MacでCmd+●をアクセラレータにする(核キーが同じ)場合、Accelアトリビュートに「Def+」と書いて共通化できる --><Item Name="新規作成" Command="New" WinShortcut="N" Accel="Def+N" />

<!-- セパレータを作る場合はこのように指定する --><Item Name="-" />

<!-- WinとMacで名称を分けることもできる。Win用にショートカット文字列を入れてしまう(WinShortcut省略)ことも可能 --><!-- アクセラレータキーをWinとMacで別々に定義(または片方だけ定義)したい場合、WinAccelとMacAccelを両方定義することで分けられる --><!-- OpenDlg=1とすると項目名の後に「...」を付与する --><Item WinName="開く(&amp;O)" MacName="開く" Command="Open" WinAccel="Ctrl+O"

MacAccel="Cmd+O" OpenDlg="1" /><Item Name="上書き保存" Command="Save" WinShortcut="S" Accel="Def+S" />

<!-- Winのみで表示したい場合はMacHide=1、逆はWinHide=1とする --><Item Name="-" MacHide="1" /><Item Name="Applicationの終了" Command="Exit" WinShortcut="X“ MacHide="1" />

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 68

45

OSネイティブメニューへの対応

• 作ったTMenuBarをOSネイティブのメニューに設定する方法

– 構築完了してから UseOSMenu() メソッドを呼べばOK

– UseOSMenu()してからアイテム追加しても反映されない

• OSXアプリケーションメニューに設定する方法

– 別のTMenuBarを構築し、Application->ApplicationMenuItems

に代入する

46

OSごとのメニューの違い – 実装してみたが

‒ Winでは特に問題無く動作…した?(後述)

‒ OSXでトラブル発生

• XMLのCommandの内容をTMenuItemのTagStringに格納し、共通のOnClickハンドラから読み取って識別しようとした

• TMenuItemのOnClickに指定したメソッドで、Sender引数をTMenuItem*にキャストして使用したところアクセス違反

• ランタイムライブラリのソースコードを漁ったり検索したり

• QCにて既知不具合と判明• http://qc.embarcadero.com/wc/qcmain.aspx?d=105091

69

B4

47

コードサンプル

void __fastcall MenuLoader::MenuItemClick (TObject *Sender)

{pMenuItem = (TMenuItem*)(Sender);ProcessCommand(pMenuItem->TagString); // Error on OSX

}

48

コードサンプル

#include <FMX.Platform.Mac.hpp>#include <Macapi.Foundation.hpp>#include <Macapi.AppKit.hpp>

TMenuItem* pMenuItem;#ifdef __APPLE__

// パラメータクラスが誤って渡されているので、同じメモリモデルのクラスに// 無理矢理キャストして中身を取り出す(暫定対応)class TFMXOSMenuItem : public TOCLocal{public:

TMenuItem* FMXMenuItem;};TFMXOSMenuItem* pOSXMenuItem = (TFMXOSMenuItem*)Sender;pMenuItem = pOSXMenuItem->FMXMenuItem;

#else

pMenuItem = static_cast<TMenuItem*>(Sender);

#endif

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 70

49

OSXショートカットキーの対応

「環境設定」に[Cmd+,]を指定したい

‒ TextToShortcut("Cmd+,"); が動かない

‒ TextToShortcutはアルファベット程度しか対応していないらしい

‒ TextToShortcut同等品を自作して差し替え(今回のプロジェクトに対応できる程度の簡素なもの)

50

メニュー項目の有効無効・チェック対応

‒ TMenuItemのEnabledやIsCheckedを変更しても正常に反映されない場合がある(Win・OSXとも)

‒ さらに、はっきり確認できていないが、OSXでIsCheckedを変更すると、メモリ破壊か何かが起こって他のところにトラブルを招く模様?

‒ これらに対応するにはOSネイティブ処理を呼ぶ必要がある

‒ このほかツールバーボタンとの共用などもあり、総合的な管理クラスを設計して使っています

71

B4

51

メニュー項目の有効無効・チェック対応:OSX

‒ チェック対応• TMenuItemからCocoaのNSMenuItemオブジェクトを得て、setState(NSOnState または NSOffState)メソッドを呼ぶ

‒無効化対応• 次のコードサンプル参照

• ややこしいです

• 今覚えなくても「なんとかなる」と記憶しておいてください

52

コードサンプル

// TMenuItemからNSMenuItemを得るstatic _di_NSMenuItem GetNSMenuItem(TMenuItem* pMenuItem){

_di_NSMenuItem item;if(pMenuItem->Handle){

item = TNSMenuItem::Wrap(_di_ILocalObject(FmxHandleToObjC(pMenuItem->Handle))

->GetObjectID());}return item;

}

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 72

53

コードサンプル(続き)

// メニューアイテムを無効にする場合TMenuItem* pMenuItem = (TMenuItem取得);_di_NSMenuItem item = GetNSMenuItem(pMenuItem);class_addMethod(object_getClass(item->target()),

sel_getUid("validateMenuItem:"), &validateMenuItem, "C@:@");

item->setEnabled(false);

// 無効化対応のためのチェックメソッド用関数static BYTE validateMenuItem(void* pthis, SEL cmdsel,

void* sender){

_di_NSMenuItem item = TNSMenuItem::Wrap(sender);return item->isEnabled() ? 1 : 0;

}

54

メニュー項目の有効無効・チェック対応:Win

‒ チェック対応

• TMenuItemのIsCheckedを変更するだけで対応可能(ネイティブ対応不要)

‒ 無効化対応

• 次のコードサンプル参照

• Windows APIを直接使用します

• OSXほどややこしくないです

73

B4

55

コードサンプル

// メニューアイテムを無効にする場合TMenuItem* pMenuItem = (TMenuItem取得);

MENUITEMINFO mii;

ZeroMemory(&mii, sizeof(mii));mii.cbSize = sizeof(mii);mii.fMask = MIIM_STATE;mii.fState = MFS_GRAYED; //有効化ならMFS_ENABLED

SetMenuItemInfo((HMENU)pMenuItem->Handle,(UINT_PTR)pMenuItem, FALSE, &mii);

56

メニュー:その他

‒ ツールバー等とも連携できる、アクションリストが欲しい

• XE3でサポート予定らしい?

• 現状では自作した

• 前述の不具合なども治っているといいのですが

‒ メニュー項目へのビットマップ表示ができない

• OSXでは使わないがWindowsでは標準的

• これもネイティブコードを使えば可能

• XP以前とVista(+AeroGlass)以降で扱いが異なる

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 74

57

17Th

Developer Camp

その他Tips

58

その他Tips(1)

GPUアクセラレーションをオフにする

‒ SpriteStudioのようにフォーム内のコントロールが多いとかえって遅くなるようです

‒ OpenGLとも動作が衝突するのでオフにします

‒ FMXMain()の最初でGlobalUseDirect2D = false;

とすればオフにできます(Winのみ)

‒ OSXでは方法が無いようです(けっこう重い)

75

B4

59

その他Tips(2)

コントロールフォーカスエフェクトをオフにする

‒ デフォルトではフォーカスを得たコントロールの周囲にぼかしエフェクトが付きます

‒ これがかなり重い

‒ FMXMain()の最初でGlobalDisableFocusEffect = true;

とすればオフにできます

60

その他Tips(3)

OSXでdynamic_castがおかしい

‒ 複数のコントロールからイベントハンドラを共有している場合など、Senderを当該コントロールの型にdynamic_castして判定したいことがある

‒ OSXで使ったら落ちた

‒ 自分でnewしたもの同士だと問題ない

‒ ランタイムが生成したインスタンスがRTTIに対応できていない?

‒ static_castし、Tagで識別するなどして対応

「FireMonkey クロス開発テクニカルエッセンス - アニメーションデータ作成ツール開発事例から」 76

61

コードサンプル

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

TForm* pForm = dynamic_cast<TForm*>(Sender);if(pForm){

pForm->Caption = _D("Hello World");}

}

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

if(dynamic_cast<TButton*>(Sender)){

// ボタンだった場合の処理}else if(dynamic_cast<TMenuItem*>(Sender)){

// メニュー項目だった場合の処理}

}

62

その他Tips(4)

OSXでのアプリケーション終了の挙動

‒ OSXアプリはウィンドウを閉じただけでは終了しない

‒ OnCloseイベントでメインウィンドウを隠しておき、OSから通知を受けたら再表示する

‒ アプリケーションメニューの「終了」で完全終了

‒ 詳しくは前回のDevCamp資料にあった、ような…

77

B4

63

その他Tips(5)

その他

‒ ダイアログボックスでのボタンの順序

• GUIデザインはオリジナルで作っても、こういうところは慣れが出るので標準からあまり弄らないほうがいい

‒ IDEおよびエディタの動作

• 謎のコンパイルエラー・リンクエラーが出たら再起動

• 外部でソース編集する場合は齟齬に注意

65

まとめ

‒ 一部愚痴っぽくなってしまった感もありますが、C++Builder XE2のクロスプラットフォーム対応は間違いなくすばらしいものです

‒ クロス開発で「一番大変な部分」の大半がFireMonkeyによって片付けられます

‒ プロフェッショナルユースに耐えるアプリケーション開発を行うためには、デベロッパー側での工夫や調整も必要です

‒ XE3での改良にも期待します

「FireMonkey モバイル/タブレットアプリ開発」 78

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

FireMonkeyモバイル/タブレットアプリ開発

エンバカデロ・テクノロジーズエヴァンジェリスト高橋智宏ttakahashi@embarcadero.com

1

アジェンダ

• FireMonkeyカスタムコンポーネントの基礎

• TMS Pack for FireMonkey

• FireMonkey iOSアプリ開発テクニック

• DataSnapモバイルコネクタ

• モバイル/タブレット向けWebアプリ

• Delphi XE3, C++Builder XE3

2

79

B5

FireMonkeyカスタムコンポーネントの基礎

• Delphi XE2

• C++Builder XE2

• FireMonkey iOS– Xcode 側に.pasをコピー

3

TMS Pack for FireMonkey

• http://www.tmssoftware.com/site/tmsfmxpack.asp

• Delphi XE2, C++Builder XE2, FireMonkey iOS をサポート

• 注意:トライアル版には FireMonkey iOS は含まれない

4

「FireMonkey モバイル/タブレットアプリ開発」 80

FireMonkey iOSアプリ開発

• 現時点で必要な環境

– Delphi XE2 Update 4 Hotfix 1

• Windows OS上で開発

– OS X SnowLeopard(10.6)

• Xcode 3.2.6 ~ Xcode 4.2

– OS X Lion(10.7)

• Xcode 4.2.1 + Xcode 4.4.1

– OS X Mountain Lion(10.8) は不可

• ただし…

5

FireMonkey iOSアプリ開発テクニック

• iPhone,iPadの種類&バージョン判別

– シミュレータ or 実機

• キーボードの表示・非表示に適応させる

• 画面の回転を検知

• TCP/IPクライアント

– CFSocket

– コールバック関数の呼び出し規約は

mwpascal (MetroWerks Pascal Calling Convention)

• NSThreadの利用とGUIの更新

• iOSアプリのフォルダ(パス)は?

– ExtractFilePath(ParamStr(0))

6

81

B5

DataSnapモバイルコネクタ

• DataSnapサーバー

– Delphi XE2 Enterprise Edition以上が必要

• FireMonkey iOS向けモバイルコネクタ

– freepascal_ios42

– freepascal_ios50

– 3点ほど不具合がありますので、.pasの修正が必要• 日本語パラメータの文字化け

– http://qc.embarcadero.com/wc/qcmain.aspx?d=103021

• メモリ(参照カウント)エラー

– http://qc.embarcadero.com/wc/qcmain.aspx?d=104296

• NSURLConnectionの使用法の誤り

– http://qc.embarcadero.com/wc/qcmain.aspx?d=104368

7

iPhoneシミュレータの注意点• 予め、ターミナルからiPhoneシミュレータのプロセスを

UTF-8で起動しておく(日本語などの文字化け対策)

– QC#101418

• http://qc.embarcadero.com/wc/qcmain.aspx?d=101418

$ export LANG=ja_JP.UTF-8

$ cd /Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone¥

Simulator.app/Contents/MacOS

$ ./iPhone¥ Simulator

• Xcodeでビルドして起動!!

8

「FireMonkey モバイル/タブレットアプリ開発」 82

モバイル/タブレット向けWebアプリ

• FireMonkeyとは直接関係ないですが…– Webアプリのほうが良い(楽だ)と考えている開発者向け

– Windows 8, iPhone, iPad, Android, BlackBerry, WP etc…

• IWCGjQuery が凄い!! – ポルトガルのCentralGest社が最近リリースしました

• http://www.cgdevtools.com/

– IWCGjQuery Suite for IntraWeb

• 主にデスクトップWebブラウザ向け

• http://www.cgdevtools.com/?skill=iwcgjquery-suite

– IWCGjQuery Mobile Suite for IntraWeb

• スマホ & タブレットWebブラウザ向け

• http://www.cgdevtools.com/skill/iwcgjquery-mobile-suite/

– Delphi 2007 ~ Delphi XE2

– C++Builder 2007 ~ C++Builder XE2

– IntraWeb 10.0.23 ~ IntraWeb 12.2.4 9

Delphi XE3, C++Builder XE3

• FireMonkey 2.0 でMetropolis UI スタイル

• FireMonkey 2.0 でタッチ&ジェスチャー

• InterBase XE3 ToGo Edition

• dbExpress driver for SQLite3

10

83

B5

Thank You

11

www.embarcadero.com/jp 〒102-0072 東京都千代田区飯田橋 4-7-1 ロックビレイビル 8F TEL 03-4577-4520 FAX 03-6843-0961

top related