C++Builder XE8でモバイルアプリケーションのassets\internal フォルダ(内部フォルダ)に配置したファイルを読み込むには

C++Builder XE8でモバイルアプリケーションのassets\internalフォルダ(内部フォルダ)に配置したファイルを読み込む方法を紹介します。

assets\internalフォルダ(内部フォルダ)にファイルを配置する

メニューの「プロジェクト」→「配置」を選択します。

10

「すべての構成 – すべてのプラットフォーム」を選択します。

11

「ファイルの追加」ボタンを押します。

12

追加するファイルを選択して、ファイルを登録します。

追加したファイルのリモートパスを編集して「assets\internal\」に書き換えます。

13

ファイルを読み込む

assets\internalフォルダに配置したファイルのディレクトリは、System::Ioutils::TPath::GetDocumentsPath()で取得できます。

#include <System.IOUtils.hpp>

UnicodeString path = System::Ioutils::TPath::Combine(
    System::Ioutils::TPath::GetDocumentsPath(), 
    L"save_256_h.png");

サンプルアプリケーション

次のサンプルアプリケーションでは、assets\internalフォルダに配置した画像ファイルを読み込んで、表示します。

フォームにボタンコンポーネント(TButton)とイメージコンポーネント(TImage)を配置します。

08

assets\internalフォルダに画像ファイルを配置します。

ボタンのOnClickイベントを記述します。

void __fastcall TForm2::Button1Click(TObject *Sender)
{
  UnicodeString path = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), L"save_256_h.png");
  TBitmap* Bitmap = new TBitmap(path);

  Image1->Bitmap->Assign(Bitmap);
  delete Bitmap;
}

Androidで実行したところ

04

05

iOSシミュレータで実行したところ

06

07

C++Builder XE8でFiremonkeyアプリケーションでクリップボードに文字列をコピーする

C++Builder XE8でFiremonkeyアプリケーションでクリップボードに文字列をコピーする方法を紹介します。

クリップボードを使用するには、IFMXClipboardServiceインターフェースを使用します。

アプリケーションを実行しているプラットフォームがIFMXClipboardServiceを利用可能かどうかを調べます。

if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXClipboardService)))
{
  //IFMXClipboardServiceが利用な可能なとき
}

IFMXClipboardServiceが利用可能であれば、IFMXClipboardServiceのインスタンスを取得します。

_di_IFMXClipboardService ClipboardService = TPlatformServices::Current->GetPlatformService(__uuidof(IFMXClipboardService));

クリップボードに文字列をコピーするには、IFMXClipboardServiceのSetClipboardメソッドを使用します。

ClipboardService->SetClipboard(TValue::From(Memo1->Text));

クリップボードに文字列をコピーするコードは次のようになります。

#include <FMX.Platform.hpp>


if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXClipboardService)))
{
  _di_IFMXClipboardService ClipboardService = TPlatformServices::Current->GetPlatformService(__uuidof(IFMXClipboardService));
  ClipboardService->SetClipboard(TValue::From("コピーする文字列"));
}

次のサンプルアプリケーションでは、アプリケーションを実行しているプラットフォームで利用できるディレクトリのパスを取得して、クリップボードにコピーします。

フォームにボタンコンポーネント(TButton)とメモコンポーネント(TMemo)を配置します。

03

フォームのOnCreateイベントと、ボタンのOnClickイベントを記述します。

#include <fmx.h>
#pragma hdrstop

#include "Unit2.h"
#include <System.IOUtils.hpp>
#include <FMX.Platform.hpp>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormCreate(TObject *Sender)
{
  Memo1->Lines->Add("System::Ioutils::TPath::GetLibraryPath="+System::Ioutils::TPath::GetLibraryPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetDocumentsPath="+System::Ioutils::TPath::GetDocumentsPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetHomePath="+System::Ioutils::TPath::GetHomePath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedAlarmsPath="+System::Ioutils::TPath::GetSharedAlarmsPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetPublicPath="+System::Ioutils::TPath::GetPublicPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedDocumentsPath="+System::Ioutils::TPath::GetSharedDocumentsPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetDownloadsPath="+System::Ioutils::TPath::GetDownloadsPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetMoviesPath="+System::Ioutils::TPath::GetMoviesPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetMusicPath="+System::Ioutils::TPath::GetMusicPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetPicturesPath="+System::Ioutils::TPath::GetPicturesPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetRingtonesPath="+System::Ioutils::TPath::GetRingtonesPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedDownloadsPath="+System::Ioutils::TPath::GetSharedDownloadsPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedMoviesPath="+System::Ioutils::TPath::GetSharedMoviesPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedMusicPath="+System::Ioutils::TPath::GetSharedMusicPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedCameraPath="+System::Ioutils::TPath::GetSharedCameraPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedPicturesPath="+System::Ioutils::TPath::GetSharedPicturesPath());
  Memo1->Lines->Add("System::Ioutils::TPath::GetSharedRingtonesPath="+System::Ioutils::TPath::GetSharedRingtonesPath());
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
  Memo1->SelectAll();

  if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXClipboardService)))
  {
    _di_IFMXClipboardService ClipboardService = TPlatformServices::Current->GetPlatformService(__uuidof(IFMXClipboardService));
    ClipboardService->SetClipboard(TValue::From(Memo1->Text));
  }
}
//---------------------------------------------------------------------------

RAD Studio XE8のGetItでライブラリをインストールしてみる

RAD Studio XE8のGetItでBoostをインストールしてみました。

メニューの「ツール」→「GetIt…」を選択します。

01

GetItのウィンドウが表示されます。

02

「Boost 1.39 1.55」の「インストール」ボタンを押します。

03

ライセンスの画面が表示されます。

04

「すべて同意する」をクリックすると、インストーラのダウンロードが始まります。

05

ダウンロードが完了すると、インストーラが起動します。

06

見覚えのある画面が表示されます。

07

インストールするファイルのダウンロードが始まります。
かなり時間がかかりました。

08

09

10

11

コンポーネントのパスなどが追加されるため、RAD Studioの再起動が必要です。

12

13

再びGitItを開くと、インストール済みのライブラリはボタンが「インストール」から「アンインストール」に変わっていました。

14

Delphi XE7/C++Builder XE7のGlyFXアイコンの場所

Delphi XE7/C++Builder XE7のGlyFXのアイコンは、次の場所にあります。

C:\Program Files (x86)\Embarcadero\Studio\15.0\Images\GlyFX\glyFX.zip

Google+のDelphi/C++Builder関連のコミュニティのメモ

Google+のDelphi/C++Builder関連のコミュニティのメモ

日本語

英語

Delphi/C++ Builderの不正なBMPファイルの脆弱性を修正するファイル

Delphi XE7/C++Builder XE7以前のバージョンに、BMPファイルの処理にバッファオーバーフローの脆弱性が見つかりました。
(JVNVU#97910946: Embarcadero Delphi と C++Builder の VCL にバッファオーバーフローの脆弱性)

各バージョンの修正方法は次の通り

RAD Studio XE7(Delphi XE7/C++Builder XE7)でOS Xアプリケーションを作成するための設定

RAD Studio XE7(Delphi XE7/C++Builder XE7)でOS Xアプリケーションを作成するための設定手順です。

使用した環境は次の通り

  • RAD Studio XE7
  • MAC OS X 10.9.4

システムの構成

Windows上で動作するRAD Studio(Delphi/C++Builder)はMAC上で動作するPAServerと通信して、PAServerとOS Xアプリケーションが通信します。

RAD Studio ←→ PAServer ←→ OS Xアプリケーション

このため、OS Xアプリケーションを作成するには、MACにPAServerをインストールして、実行しておく必要があります。

MACにXcodeをインストールする

App StoreからXcodeをインストールします。

MACにPAServerをインストールする

PAServerをダウンロードします。

RAD Studio XE7(Delphi XE7/C++Builder XE7)用のPAServerは次のURLからダウンロードします。

2015年5月30日追記。
XE7用PAServer Update1が次のURLからダウンロードできます。

ダウンロードが完了したら、インストーラを実行して、インストールします。

001

002

003

004

005

PAServerを起動する

Macのファインダで、PAServer 15.0.appを起動します。

010

011

012

013

接続プロファイルを追加する

XE7のメニューから「ツール」→「オプション」を選択します。

021

オプション画面が表示されます。

「環境オプション」→「接続プロファイル マネージャ」を選択します。

022

「追加」ボタンを押します。

023

プロファイル情報画面が表示されます。

024

「プロファイル名」を入力して「次へ」ボタンを押します。

025

「リモートマシン(IPアドレスまたはマシン名)」欄に、MACのIPアドレスを入力します。

026

「接続テスト」ボタンを押して、接続できることを確認します。

027

「終了」ボタンを押します。

028

MACのIPアドレスを確認するには

(1)「アップルメニュー」→「システム環境設定」→「ネットワーク」

MACのIPアドレスを確認するには、「アップルメニュー」→「システム環境設定」→「ネットワーク」→を選択します。

051

052

ネットワーク画面が表示されます。

有線接続の場合は「Ethernet」を、無線接続の場合は「Wi-Fi」を選択します。

IPアドレスが表示されます。

053

(2)PAServerで「i」コマンド

PAServerを起動したら、「i」キー+Enterキーを押します。

IPアドレスが表示されます。

Copyright (c) 2009-2014 Embarcadero Technologies, Inc.

接続プロファイル パスワード <パスワードがない場合はただ Enter キーを押す>: 

デバッグをサポートする権限を取得しています...成功

Platform Assistant Server をポート 64211 で起動します

? を入力すると使用可能なコマンドが表示されます
>?
q - サーバーを停止する
c - すべてのクライアントを出力する
p - ポート番号を出力する
i - 使用可能な IP アドレスを出力します
s - スクラッチ ディレクトリを出力する
g - ログイン パスファイルを生成します
v - 詳細表示モードの切り替え
r - すべての子プロセスをリセットして終了します
>i
192.168.0.5
192.168.0.7
192.168.65.1
192.168.147.1

SDKを追加する

オプション画面の「SDKマネージャ」を選択します。

041

「追加」ボタンを押します。

042

「新規SDKの追加」画面が表示されます。

043

「プラットフォームの選択」プルダウンメニューから「」を選択します。

044

「SDKバージョンの選択」プルダウンメニューが自動的に設定されます。
必要に応じて、SDKバージョンを選択します。

「OK」ボタンを押して、SDKを追加します。

045

046

MACアプリケーションを作成する

メニューから「新規作成」→「マルチデバイス アプリケーション」を選択します。

031

「空のアプリケーション」を選択します。

032

プロジェクトが作成されます。

033

プロジェクトマネージャの「ターゲットプラットフォーム」から「OS X」を選択します。

035

アプリケーションを実行します。

036

MACでアプリケーションが実行されました。

037

第2回 RAD Studio勉強会@Osaka

とあるデータベースアプリケーションのバージョンアップの歴史(注意:実際には存在しません。)

Windowsアプリケーション

Win

Windowsアプリケーションでは、撮影した写真や位置情報を登録するのが大変でした。

モバイルアプリケーション

Mobile

モバイルアプリケーションにすると、スマートフォンについているカメラやGPSを使って、写真や位置情報の登録が簡単になりました。
ですが、文字入力が大変でした。

Windowsアプリケーションとモバイルアプリケーションのハイブリット

ApplicationTethering

スマートフォンのカメラやGPSで写真や位置情報をとり、Wi-FiやBluetoothでパソコンに送って、登録します。
文字入力はパソコンで行います。

パソコンの得意なことはパソコンで、スマートフォンが得意なことはスマートフォンで。

アプリケーションテザリングのすすめ

Delphi/C++Builderならアプリケーションテザリングでデバイスの連携がとても簡単です。

勉強会では、スマートフォンのカメラで撮った写真やGPSの位置情報を、Windowsアプリケションに送る方法を説明します。

C++Builder XE6でAndroidスマートフォンの電話番号などの端末情報を取得するには

C++Builder XE6でAndroidスマートフォンの電話番号などの端末情報を取得するサンプルアプリケーションです。

FireMonkeyモバイルアプリケーションを作成します。

フォームにボタンコンポーネント(TButton)とメモコンポーネント(TMemo)を配置します。

JTelephonyManager01

ボタンコンポーネントのクリックイベントを記述します。

#include <Androidapi.Helpers.hpp>
#include <Androidapi.JNI.JavaTypes.hpp>
#include <Androidapi.JNI.GraphicsContentViewText.hpp>
#include <Androidapi.JNIBridge.hpp>
#include <Androidapi.JNI.Telephony.hpp>
#include <FMX.Helpers.Android.hpp>

void __fastcall TForm1::Button1Click(TObject *Sender) {
    _di_JObject TelephonyServiceNative = SharedActivityContext()->getSystemService(TJContext::JavaClass->TELEPHONY_SERVICE);
    _di_JTelephonyManager TelephonyManager = TJTelephonyManager::Wrap(((_di_ILocalObject)TelephonyServiceNative)>GetObjectID());

    Memo1->Lines->BeginUpdate();
    try {
        Memo1->Lines->Add(L"電話番号");
        Memo1->Lines->Add(JStringToString(TelephonyManager->getLine1Number()));
        Memo1->Lines->Add(L"デバイスID");
        Memo1->Lines->Add(JStringToString(TelephonyManager->getDeviceId()));
        Memo1->Lines->Add(L"SIMの国コード");
        Memo1->Lines->Add(JStringToString(TelephonyManager->getSimCountryIso()));
        Memo1->Lines->Add(L"MCC+MNC (mobile country code + mobile network code)");
        Memo1->Lines->Add(JStringToString(TelephonyManager->getSimOperator()));
        Memo1->Lines->Add(L"サービスプロバイダの名前");
        Memo1->Lines->Add(JStringToString(TelephonyManager->getSimOperatorName()));
        Memo1->Lines->Add(L"SIMのシリアル番号");
        Memo1->Lines->Add(JStringToString(TelephonyManager->getSimSerialNumber()));
        Memo1->Lines->Add(L"ボイスメールナンバー");
        Memo1->Lines->Add(JStringToString(TelephonyManager->getVoiceMailNumber()));
        Memo1->Lines->Add(L"SIMの状態");
        const int SimState = TelephonyManager->getSimState();
        if (SimState == TJTelephonyManager::JavaClass->SIM_STATE_UNKNOWN)
            Memo1->Lines->Add(L"SIM_STATE_UNKNOWN");
        if (SimState == TJTelephonyManager::JavaClass->SIM_STATE_ABSENT)
            Memo1->Lines->Add(L"SIM_STATE_ABSENT");
        if (SimState == TJTelephonyManager::JavaClass->SIM_STATE_PIN_REQUIRED)
            Memo1->Lines->Add(L"SIM_STATE_PIN_REQUIRED");
        if (SimState == TJTelephonyManager::JavaClass->SIM_STATE_NETWORK_LOCKED)
            Memo1->Lines->Add(L"SIM_STATE_NETWORK_LOCKED");
        if (SimState == TJTelephonyManager::JavaClass->SIM_STATE_READY)
            Memo1->Lines->Add(L"SIM_STATE_READY");
    }
    __finally {
        Memo1->Lines->EndUpdate();
    }
}

アプリケーションを実行し、ボタンをクリックします。

メモコンポーネントに端末情報が表示されます。

AFSoft さんの記事を読みやすくする HTML ファイル

Delphi/C++Builderには大量のコンポーネントが用意されています。
たくさんありすぎで、すべてのコンポーネントを把握するのは困難です。
使ったことのないコンポーネントもたくさんあります。

AFSoftさんのサイトでは、VCL/FireMonkeyのたくさんのコンポーネントを画面キャプチャ付きで説明されています。
AFSoftさんの記事を読んで、コンポーネントの概略を知るだけでも、開発効率はぐっと上がると思います。
斜め読みでもいいので、一度目を通しておくといいかもしれません。

Delphi Forumトピック: ごくごく基本的な VCL の使い方AFSoftさんの記事を読みやすくするHTMLファイルが公開されています。

AFsoft

このHTMLファイルでは、VCLとFireMonkeyのコンポーネントがカテゴリ別に整理されています。
目的のコンポーネントを見つけやすくなっていて、知りたいコンポーネントの解説記事が読みやすっくなっています。
興味のあるカテゴリーから読んでみてはいかがでしょうか。