喫茶XRAYトップページ


[10776] 最近起きた珍現象返信 削除
2017/2/9 (木) 23:36:21 Konnoya
こんばんは!
以下の簡単なサンプルプログラムを組んでみました。
これを実行すると、不思議な事にTPanelのべベル線が透明になってしまいます。
条件としては、FormのCreate時でパネルを生成、BevelKindをフラットにする。
かつ、パネルを重ね合わせた時だけこの現象が起きます。
パネルを重ね会わなければこの現象は起きません。

[開発環境1]
OS:Windows7
Delphi:Delphi XE8
[開発環境2]
OS:Windows7
Delphi:RAD Studio 10.1 Berlin Starter

[VCL]コード
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;

const
  PANEL_NUM = 5;

type
  TForm1 = class(TForm)
    procedure FormCreate ( Sender : TObject );
    procedure FormDestroy( Sender : TObject );
    procedure WMNCHITTEST( var Msg : TWMNCHITTEST ); Message WM_NCHITTEST;
  private
    { Private 宣言 }
    PanelList : Array of TPanel;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate( Sender : TObject );

var
  lc1 : Integer;

begin
  // フォームの設定(設計時)
  // Self.BorderStyle は bsNone;
  // Self.Position    は poScreenCenter;

  SetLength( PanelList, PANEL_NUM );

  for lc1 := Low( PanelList ) to High( PanelList ) do
  begin
    PanelList[ lc1 ]             := TPanel.Create( Self );
    PanelList[ lc1 ].Name        := 'Panel' + lc1.ToString;
    PanelList[ lc1 ].Parent      := Self;
    PanelList[ lc1 ].BevelInner  := bvNone;
    PanelList[ lc1 ].BevelKind   := bkFlat;
    PanelList[ lc1 ].BevelOuter  := bvNone;
    PanelList[ lc1 ].ShowCaption := FALSE;
    PanelList[ lc1 ].Width       := 51;                 // ←ワザとパネルが1ドット重なる様に+1
    PanelList[ lc1 ].Height      := 50;
    PanelList[ lc1 ].Left        := 50 + ( lc1 * 50 );
    PanelList[ lc1 ].Top         := 50;
    PanelList[ lc1 ].Visible     := TRUE;
  end;
end;

procedure TForm1.FormDestroy( Sender : TObject );

var
  lc1 : Integer;

begin
  for lc1 := Low( PanelList ) to High( PanelList ) do
  begin
    PanelList[ lc1 ].DisposeOf;
  end;
end;

procedure TForm1.WMNCHITTEST( var Msg : TWMNCHITTEST );

var
  Pos :TPoint;

begin
  GetCursorPos( Pos );
  Pos := ScreenToClient( Pos );

  if Pos.Y < 32 then
    Msg.Result := HTCAPTION
  else
    Msg.Result := HTCLIENT;
  end;

end.

フォームのBorderStyleがbsNoneなので、
WM_NCHITTESTでフォームの上32ドットでウインドウを動かせる様にしてあります。

なんで透明になっちゃうんだよ〜といいつつ悩んでしまいました。
解決できたのですが、どうして発生するのかは不明。
ご存知の方がいましたらお教え下さい(汗
[開発環境1] と [開発環境2] のどちらでも発生したので、これってWindowsの問題かな?


[10777] Re:最近起きた珍現象返信 削除
2017/2/10 (金) 10:07:13 Mr.XRAY
▼ Konnoyaさん

> これを実行すると、不思議な事にTPanelのべベル線が透明になってしまいます。
> 条件としては、FormのCreate時でパネルを生成、BevelKindをフラットにする。
> かつ、パネルを重ね合わせた時だけこの現象が起きます。
> パネルを重ね会わなければこの現象は起きません。


これは仕様だと思います.
bkNone にすれば隣接して並べて表示した時に,境界線を非表示にできる,
という解釈ではどうでしょうか ?

オンラインヘルプにも,
『多様な効果を作成できます。目的の外観を得るために,さまざまな組み合わせ
を試してください。』
と書いてありますから... (^^;

下の図は,bkNone と bkFlat の時を確認したものです.
2 番目は,確認しやすいように拡大してみました.


[10778] Re2:最近起きた珍現象返信 削除
2017/2/10 (金) 10:20:38 Mr.XRAY
> bkNone にすれば隣接して並べて表示した時に,境界線を非表示にできる,
> という解釈ではどうでしょうか ?


こういうのは,プログラムに限らず,社会生活,人生では
一般的にあることでしょう.

他のアプリを操作したい,という人もいれば,
他のアプリから操作されたくない,という人もいます.

なんで線が消えるんだよ ! と言う人もいれば,
隣合わせにしたのに,なんで線が消えないんだよ !
という人もいかるかも知れません,ってね.
ホホホッ.

いわゆる価値的命題といったところでしょうか.


[10779] Re2:最近起きた珍現象返信 削除
2017/2/10 (金) 12:17:12 Mr.XRAY
> これは仕様だと思います.
> bkNone にすれば隣接して並べて表示した時に,境界線を非表示にできる,
> という解釈ではどうでしょうか ?


BevelOuter  := bvNone; にした場合です.
最初のは,TPanel の上にコントロールを載せる時によく使う手です.
TPanel の境界を見せなくする方法です.
これが今回問題とした現象ということになると思います.



[10780] Re3:最近起きた珍現象返信 削除
2017/2/10 (金) 14:38:51 Mr.XRAY
> 最初のは,TPanel の上にコントロールを載せる時によく使う手です.
> TPanel の境界を見せなくする方法です.


サンプルプログラム集で使っているのは下図のような設定が多いです.
TPanel を使用しない場合は,TMemo の Align を alBottom にして,
Anchors プロパティのメンバの値を全てチェックする方法にしています.



[10781] Re3:最近起きた珍現象返信 削除
2017/2/10 (金) 19:36:21 Konnoya
▼ Mr.XRAYさん
> > これは仕様だと思います.
> > bkNone にすれば隣接して並べて表示した時に,境界線を非表示にできる,
> > という解釈ではどうでしょうか ?
>
> BevelOuter  := bvNone; にした場合です.
> 最初のは,TPanel の上にコントロールを載せる時によく使う手です.
> TPanel の境界を見せなくする方法です.
> これが今回問題とした現象ということになると思います.


こんばんは!XRAY様、色々教えて下さりありがとうございます。
掲示板に書き込みたかったのですが、帰宅してからという事もあり、
返事が遅くなってすみません(汗

私の稚拙な文章で伝わらせたい事がなかなか伝わっておらず、
あるいは、XRAY様の環境ではそのような現象が発生しないのか判りませんが、
今回、発生した現象というのは、動的に生成したパネルのべベル線が
フォームを通り越して(また下手な説明)デスクトップの背景が見えるというものです。

FormCreateの時に生成したパネルで、パネル矩形が重なると、
重ねられたパネルのべベル線がフォームの後ろの背景になるという事でして(汗
なかなか文章では伝わりにくいので画像を貼りました。
1枚目がべベル線が透けてしまう状態です。(パネルが重なっている)

>こういうのは,プログラムに限らず,社会生活,人生では
>一般的にあることでしょう.


仰る通りです。
こんな事になったよ〜って事を書いたのです(汗

対策としては、FormCreate時に生成しないという方法を取りました。


[10782] Re4:最近起きた珍現象返信 削除
2017/2/10 (金) 19:53:56 Konnoya
なんでこの様な配置のパネルを?と思われるでしょうけども、
カレンダーみたいなやつを作っていました。
カレンダーといっても、月火水木金土日と1週間毎に改行されている物ではなくて、
横に1ヶ月分日にちが並ぶ様な感じの物(汗
パネルを1ドット重ねたのはフレーム線を2ドットにしたくない為、
1ドット重ねて表示するという仕様にしました。

お騒がせしてみません^^;


[10784] Re4:最近起きた珍現象返信 削除
2017/2/10 (金) 19:59:58 Mr.XRAY
▼ Konnoyaさん

> FormCreateの時に生成したパネルで、パネル矩形が重なると、
> 重ねられたパネルのべベル線がフォームの後ろの背景になるという事でして(汗
> なかなか文章では伝わりにくいので画像を貼りました。
> 1枚目がべベル線が透けてしまう状態です。(パネルが重なっている)


ギョエ ! そうことでしたか.失礼しました.
う〜む,それは.... 分かりません !
なんだべ ?


[10785] Re5:最近起きた珍現象返信 削除
2017/2/10 (金) 20:14:38 Konnoya
> ギョエ ! そうことでしたか.失礼しました.
> う〜む,それは.... 分かりません !
> なんだべ ?


重ならなければ通常色で描画されます。
ちなみに会社のPC 3台+自宅PC 1台(全てWIndows7)で試したので
謎ですがこれも仕様だと思う事にしています(汗
各PCのグラボはバラバラです。
※ Intelチップセット、GeForce等。

逆にこれを利用して何かできないかと思ったりしてますw

[10786] Re5:最近起きた珍現象返信 削除
2017/2/10 (金) 20:17:05 Mr.XRAY
> > FormCreateの時に生成したパネルで、パネル矩形が重なると、
> > 重ねられたパネルのべベル線がフォームの後ろの背景になるという事でして(汗
> > なかなか文章では伝わりにくいので画像を貼りました。
> > 1枚目がべベル線が透けてしまう状態です。(パネルが重なっている)


これって,フォームの BorderStyle が bsSizeable たと発生しないみたいですね.
bsNone だと見事に発生します.


[10787] Re6:最近起きた珍現象返信 削除
2017/2/10 (金) 20:32:02 Mr.XRAY
> これって,フォームの BorderStyle が bsSizeable たと発生しないみたいですね.
> bsNone だと見事に発生します.


フォームの BorderStyle を bsSizeable にして BorderStyle を
CreateParams で設定してみたらどうでしょう ?
こちらでは透過しなくなりました.
動作確認は Windows 7 U64(SP1) + Delphi 10.1 Berlin Stater です.

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  Params.Style := WS_POPUP;
end;

推測ですが,この現象はおそらく Windows Vista で実装された
フレームウィンドウの影響ではないかと思います.
フォームのボーダースタイルの設定の時期,タイミングによって変わるのではと.



[10788] Re7:最近起きた珍現象返信 削除
2017/2/10 (金) 20:48:39 Mr.XRAY
> フォームの BorderStyle を bsSizeable にして BorderStyle を
> CreateParams で設定してみたらどうでしょう ?


最初のコードのまま実行すると,以下の図のようになります.



[10789] Re8:最近起きた珍現象返信 削除
2017/2/10 (金) 21:05:39 Mr.XRAY
ちなみに,フォームの枠のデザインの設定の参考です.

[18_実行時にフォームのスタイルを変更  -  フレーム枠のないウィンドウ ]
http://mrxray.on.coocan.jp/Delphi/plSamples/127_FormSystemMenuETC.htm#18


[10790] Re8:最近起きた珍現象返信 削除
2017/2/10 (金) 21:15:14 Konnoya
▼ Mr.XRAYさん
> > フォームの BorderStyle を bsSizeable にして BorderStyle を
> > CreateParams で設定してみたらどうでしょう ?
>
> 最初のコードのまま実行すると,以下の図のようになります.


おお〜その様な方法で回避できると…。
あんなに頭を抱えていたのにもう解決策を見出すとは、さすがXRAY様ですね。
まるで曇り空で頭痛に見舞われ、ナ○ンエースを飲んだ後の様な爽快感が^^

Form.BorderStyle が bsNone の時だけ起こるレアなケースですが、
一応、今後は自作クラスでTPanelを継承して作っているカスタムクラスのチェックも
やろうかなと思っています。
TPanelは何かと便利なんですよ^^;

有難う御座いました。

[10791] Re9:最近起きた珍現象返信 削除
2017/2/10 (金) 21:24:15 Mr.XRAY
▼ Konnoyaさん

> あんなに頭を抱えていたのにもう解決策を見出すとは、さすがXRAY様ですね。

どうだ !! 参ったか,なんちゃって...  ホホホッ
これだけの特急記事だと,
サンプルプログラム集の記事だったら,誤字脱字だらけですね.ハハハッ

> TPanelは何かと便利なんですよ^^;

御意 !! TPanel はやたら使いますからね.

ところで東京地方のみなさん.
午後 10 時から NHK E テレでモーガンフリーマンやります.
えっ ? そんなの興味ない ? あっそう...

http://www4.nhk.or.jp/P3452/

INCM/CMT
Cyclamen v3.82