XE2でVCLスタイルをDLLのフォームに適用する方法について

解決


クロ  2013-03-29 19:54:26  No: 44157  IP: 192.*.*.*

XE2でアプリケーションを作成しています。
MDIアプリケーションで複数のDLLからMDIChildのフォームを呼び出しています。

この時、メインとなるプロジェクトに対してVCLスタイルを変更できるようにしてみましたが、呼び出すフォームにはVCLスタイルが適用されません。

適用する方法を教えていただきたいのですが・・・
よろしくお願いします

編集 削除
DEKO  2013-03-29 22:55:31  No: 44158  IP: 192.*.*.*

> MDIアプリケーションで複数のDLLからMDIChildのフォームを呼び出しています。

子フォームは DLL 側にあるのですから、
VCL スタイルが適用されなくても仕方ない気がします。

# DLL にスタイルをリソースとして埋め込むしかないと思います。

編集 削除
Mr.XRAY  2013-03-30 14:59:59  No: 44159  IP: 192.*.*.*

># DLL にスタイルをリソースとして埋め込むしかないと思います。

ですよね.
VCL スタイルの設定はプロジェクトごとですから.DLL は別のプロジェクトです.

で,やってみました.Delphi XE2 に添付されている Amethyst Kamri でやってみました.
この VCL スタイルのファイル名は AmethystKamri.vsf です.
ところが,以下のコードで,LoadFromResouce が nil となってしまいます.
リソースは,[プロジェクト] [リソースと画像] で追加しています.

  if FindResource(HInstance, 'Resource_1', RT_RCDATA) <> 0 then begin
    if TStyleManager.LoadFromResource(HInstance, 'Resource_1', RT_RCDATA) <> nil then begin
      TStyleManager.SetStyle('Amethyst Kamri');
    end;
  end;

そこで,Delphi XE2 の新規にプロジェクトを作成し,
この VCL スタイルを設定して保存し,コンパイルしてみました.
作成された Project1.dproj を見てみると,以下の記述がありました.
これが VCL スタイルの設定のようです.

<VCL_Custom_Styles>&quot;Amethyst Kamri|VCLSTYLE|$(PUBLIC)\Documents\RAD Studio\9.0\Styles\AmethystKamri.vsf&quot;</VCL_Custom_Styles>

そこで,DLL のプロジェクトを新規に作成し,今回のテストでは,TestDll.dpr としました.
上のファイルに相当するのは,TestDll.dproj となります.
これを開いて,上と同じコードを追加してみました.
追加したのは,2 行目です.場所がわかりやすいように,他のも書いておきました.
AmethystKamri.vsf というファイルは,ここに書いてあるフォルダにコピーしてテストしています.

<PropertyGroup Condition="'$(Base)'!=''">
  <VCL_Custom_Styles>&quot;Amethyst Kamri|VCLSTYLE|D:\000\AmethystKamri.vsf&quot;</VCL_Custom_Styles>
  <VerInfo_Locale>1041</VerInfo_Locale>
  <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
  <DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
  <DCC_E>false</DCC_E>
  <DCC_F>false</DCC_F>
  
上の 1 行を追加した上で,
Dll 内のフォームを生成するイベントで次のコードを実行します.
Dll 内のフォームの名前が DllForm の場合です.

procedure TDllForm.FormCreate(Sender: TObject);
begin
  TStyleManager.TrySetStyle('Amethyst Kamri');
end;

Windows 7 U64(SP1) + Delphi XE2(UP4) で動作確認しました.

実際問題として,DLL という別のファイルを作成するアプリなのだから,
ファイルから読み込んでも,いいんじゃないかとも思んですが.

編集 削除
Mr.XRAY  2013-03-30 15:10:01  No: 44160  IP: 192.*.*.*

失礼 !

TStyleManager の使用には,uses に Vcl.Themes が必要です.

編集 削除
Mr.XRAY  2013-03-30 15:14:33  No: 44161  IP: 192.*.*.*

もうひとつ.
もしかししたら LoadFromResource の使用方法が間違っているのかも知れません.
提示した方法がベターということではありませんので,あしからず.

LoadFromResource も uses に Vcl.Themes が必要です.

編集 削除
Mr.XRAY  2013-03-31 05:38:51  No: 44162  IP: 192.*.*.*

>もしかしたら LoadFromResource の使用方法が間違っているのかも知れません.

もしかしたら,とやってみました.
以下のコードで,リソースから読み出せるようです.多分 OK でしょう ?
uses に  Vcl.Themes, VCL.Styles が必要です.

var
  StyleHandle : TStyleManager.TStyleServicesHandle;
begin
  //リソースからVCLスタイルの情報を取得してセット
  if TStyleManager.TryLoadFromResource(HInstance,
                                       'Resource_2',
                                       'VCLSTYLE',
                                       StyleHandle) then begin
    if StyleHandle <> nil then begin
      TStyleManager.SetStyle(StyleHandle);
    end;
  end;

リソースの追加は,[プロジェクト] [リソースと画像] から,VCL スタイルを選択します.
この時,以下のように,リソースタイプは,VCLSTYLE と手動で入力します.
DLL のプロジェクトの再構築あるいはビルドをお忘れなく.
  
[DLL 内で表示するフォームに VCL スタイルを適用する] 
http://mrxray.on.coocan.jp/Others/DLLwithForm_VCLStyle.htm#03

編集 削除
Mr.XRAY  2013-03-31 05:42:04  No: 44163  IP: 192.*.*.*

またリンクの最後に空白が入ってしまいました.ここです.
http://mrxray.on.coocan.jp/Others/DLLwithForm_VCLStyle.htm#03

編集 削除
KHE00221  2013-03-31 23:16:00  No: 44164  IP: 192.*.*.*

1. JCLフォームアプリケーションを作成する
2. 使用したいカスタムスタイルを指定する
3. 保存する (.RES を作成する)
4. そのプロジェクト(.DPR)を使用して DLL を作成する

var
  Vcl.Themes,
  Vcl.Styles;

TStyleManager.TrySetStyle('Amakrits');で
でテーマ適用

編集 削除
クロ  2013-04-01 16:49:40  No: 44165  IP: 192.*.*.*

お返事が遅くなり申し訳ありません。
皆様ありがとうございました。

Mr.XRAY様、ホームページにまで掲載していただき本当にありがとうございます。
かなり求めているものに近づいてきました。

最後にもう一点なのですが・・・。
例えば、
①親フォームでVCLスタイルを変更できるようする
②子フォームをDLLで用意する。
③この状態で実行して、子フォームを呼び出し後、親フォームでVCLスタイルを変更したら子フォームも変更させる

ということをする場合、親フォームでVCLスタイルを変更したらDLLでリソース読み直すみたいなことをしないとでしょうか・・・?

編集 削除
Mr.XRAY  2013-04-01 17:42:16  No: 44166  IP: 192.*.*.*

>親フォームでVCLスタイルを変更したらDLLでリソース読み直すみたいな

当然ですね,前に書いてある通り,VCL スタイルはプロジェクト単位の設定ですから.

DLL のリソースにも,その分だけスタイルのリソースを用意しておくこになると思います.
    
実行時の VCL スタイルの変更はあまりお勧めできません.
以下を参考にしてください.一番下の方の文章です.
前のレスの記事の中にもリンクしてありますので,すでにお読みになっているこことは
思いますが,念のため.

[VCL スタイル (Delphi XE2 以降)]
http://ht-deko.minim.ne.jp/tech074.html

掲載記事を書き変えました.
DLL でフォームを表示するコードがあまりにも,それだけという感じでしたので,
少しは後で参考になるようにしました.
http://mrxray.on.coocan.jp/Others/DLLwithForm_VCLStyle.htm
        

それと,○囲み数字は,「機種依存文字」あるいは「インターネット使用禁止文字」というものです.
インターネット上では(メールもインターネット経由です),使わない方が無難です.
以下のスレッド参照

https://www.petitmonte.com/bbs/answers?question_id=7928

編集 削除
Mr.XRAY  2013-04-01 17:50:08  No: 44167  IP: 192.*.*.*

>掲載記事を書き変えました.

これは クロ さんにというわけではなく,
前のサンプルをダウンロードしてしまった方へということです.

編集 削除
クロ  2013-04-02 19:17:39  No: 44168  IP: 192.*.*.*

Mr.XRAY様ありがとうございます。
おっっしゃる通り、実行時のVCLスタイルの変更は避けて進もうと思います。

掲載記事も大変参考になりました。ありがとうございます。

○囲み文字の件、大変失礼いたしました。
以後気を付けます。

VCLスタイルの変更に関しましては、設定する場所を設けて、アプリケーション再起動で適用されるという仕様で進めていこうと考えています。
お答えいただいた皆様、本当にありがとうございました。

編集 削除
Mr.XRAY  2013-04-05 07:59:13  No: 44169  IP: 192.*.*.*

>実行時の VCL スタイルの変更はあまりお勧めできません.

いくつかのスタイルで,ちょっとやってみました.
中には,スタイルを変更しても問題なさそうなのもありますが,
やはり,コントロールの再生成をしてしまうのもありますね.

残念ですが,そのスタイルによるようです.

編集 削除