[日記]

創作同人誌万歳!~コミティアに行ってきた / 2005-08-29 (月)

久しぶりにコミティアに行ってきました.前回,2001年9月開催のコミティア57以来2回目なのですが,サークル数が2000と倍以上になっていて,前回の感覚でブースを回っていたら時間が足りなくなってしまいました.

久しぶりに参加して思ったことはコミケなどみたいに表紙だけ立派でページ数も中身も薄い本が結構見受けられたことです.前回参加したときは地味ながら密度の濃い本が集まっていた印象があったのでこれは残念でした.

しかしありがたいことに今回もすてきな同人誌に出会えました(今回誘ってくれた友人は残念ながら出会えなかったのですが).続き物なので次回作が待ち遠しいですが買ったのが第3集なのでまずは既刊本の入手ですね.

[ ツッコミの受付は終了しています ]
この記事のリンク元 | 1 |

[日記]

プラネタリウムを見てきた / 2005-08-29 (月)

9/5 再度訂正 9/3 重大な誤りがあったので訂正

友人に誘われて,プラネタリウムを見に行きました.

プラネタリウムは幼い頃に学習図鑑でその存在を知っていたものの,実際に見るのは初めて.(上京して以来ずっと東京にいるんだから見に行けば良かったのにね)

実際に見に行って,図鑑で見たのとほぼ同じ形の投影機(?)と対面.その顕微鏡を巨大怪獣にしたようないかついフォルムの実物にちょっと感動(笑).

上映が始まり,満天の星空が現れると見入ってしまいました.本物の満天の星空は子供の頃に海と山で見たきりだったので懐かしくもありました.

星座の解説では夏なのでまず夏の第三角形が.ベガとアルタイルの名前が出てくるとJリーグのファンとしてはどうしてもベガルタ仙台のことを考えてしまいます.ベガルタ(VEGALTA)という名前はベガ(Vega)とアルタイル(Altair)に由来しているのです.どうしてベガとアルタイルなのかはベガが織姫星,アルタイルが彦星で,仙台といえば…ということです.さらに大三角形のもう一つの恒星ははくちょう座のアルビレオ.Jリーグにはこの星を名前の由来にしているクラブもあったりします.

「ベガルタ仙台対アルビレックス新潟の対戦カードは夏の大三角ダービーだったんだよ!!」「な,なんだってー???」 …それはともかく,夏の第三角形を構成する3つの星を完璧に記憶できたことは確かです.

9/3訂正 夏の大三角形のもうひとつははくちょう座のデネブです!間違えて覚えていました,大嘘書いてごめんなさい.ちなみにアルビレオははくちょう座のうち白鳥のしっぽ(9/5訂正)に位置する星です.『アルビレオ』と聞いた瞬間に私の思考が止まってしまったようです.

プラネタリウムでみた満天の星空はとっても綺麗だったのですが,今度は久々にリアルの満天の星空も見たくなってきました.

[ ツッコミの受付は終了しています ]
1: イカデビル (09/17 15:14)
正確にはくちばし(笑)
今度、本物を見に行こうね。
秋の中頃までは何とか、大三角形も見れるはず・・・東京からでも可

[delphi]

Delphi:ボーダーのないフォームを最大化して起動する場合の注意点 / 2005-08-05 (金)

問題点

フォームのBorderStyleがbsNoneのとき,設計時にWindowsStateをwsMaximizedすると 実行時に最大化を解除してもWidthとHeightで指定したサイズにならない.

対策

設計時はフォームを最大化せず,実行中最初にフォームを表すときに最大化するとこの問題を回避できます.

type
  TForm1 = class(TForm)
    (※中略)
  private
    FFormInitialized: boolean;
    (※中略)
  end;

procedure TForm1.FormShow(Sender: TObject);
begin
  if not FFormInitialized then
  begin
    WindowsState := wsMaximized;
    FFormInitialized := True;
  end;
end;
ただしこの場合,Positionの値はpoDesignedとなり,最大化を解除すると,
  1. PositionがpoDefault,poDefaultPosOnlyの場合はフォームの左上座標画面の左上に来てしまう.
    このため,タスクバーなどのアプリケーションバーが画面の上又は左に存在するとフォームの一部又は全部が隠れてしまう
  2. それ以外の場合は常に設計時にLeft, Topで指定した座標に表示される.
    poScreenCenter等の指定は無視されてしまう.

この対策は自分で表示位置を修正するしかないようです.

アプリケーションバーと重なっているかどうかを調べる方法

アプリケーションバーについてひとつひとつ調べる必要はありません.SystemParametersInfo APIでアプリケーションバーを除いた領域(ここでは作業領域と呼びます)を簡単に取得できるからです.現在のフォーム領域がこの領域をはみ出ているかどうかを調べれば判定できます.

重なっている場合に重ならないように移動する方法

単純に左にはみ出ていればその分右に移動,上にはみ出ていればその分下に移動.右と下も同様です.ただし左右又は上下ともにはみ出ている場合,つまりフォームの幅や高さが作業領域の幅や高さより大きい場合は幅や高さを縮めるか片方だけ適用します.以下にコードを晒します(※このコードでは幅や高さの縮小はしていません).

コード

※宣言部

function CenterRectOfRect(const aRect, MotherRect: TRect): TRect; 
function DesktopWorkRect: TRect; 
function WidthOfRect(const aRect: TRect): integer; 
function HeightOfRect(const aRect: TRect): integer; 
procedure MoveFormToPosition(Form: TCustomForm; Position: TPosition = poDesigned); 

※実装部

{★指定された領域と同じサイズで別の領域の中央になる領域を返します.}
function CenterRectOfRect(const aRect, MotherRect: TRect): TRect;
begin
  Result.Left := MotherRect.Left + (WidthOfRect(MotherRect) - WidthOfRect(aRect)) div 2;
  Result.Right := aRect.Right + (Result.Left - aRect.Left);
  Result.Top := MotherRect.Top + (HeightOfRect(MotherRect) - HeightOfRect(aRect)) div 2;
  Result.Bottom := aRect.Bottom + (Result.Top - aRect.Top);
end;

{★アプリケーションバーを除いた領域を返す
 (※マルチモニターの場合はプライマリモニターの領域を返します)}
function DesktopWorkRect: TRect;
begin
  Windows.SystemParametersInfo(SPI_GETWORKAREA, 0, @Result, 0)
end;

{★領域の幅を返す.}
function WidthOfRect(const aRect: TRect): integer;
begin
  Result := abs(aRect.Right - aRect.Left);
end;

{★領域の高さを返す.}
function HeightOfRect(const aRect: TRect): integer;
begin
  Result := abs(aRect.Bottom - aRect.Top);
end;

{★フォームの位置をPositionで指定した場所に移動します.}
procedure MoveFormToPosition(Form: TCustomForm; Position: TPosition);
var
  aDesktopWorkRect, aBoundsRect: TRect;
  NeedToMoveOffsetX, NeedToMoveOffsetY: integer;
begin
  aDesktopWorkRect := DesktopWorkRect;
  aBoundsRect := Form.BoundsRect;

  case Position of
  poDefault, poDefaultPosOnly:
    begin
      { クライアント領域からはみ出しているなら収まるように移動します.}
      if aBoundsRect.Left < aDesktopWorkRect.Left then
        NeedToMoveOffsetX := aDesktopWorkRect.Left - aBoundsRect.Left
      else if aBoundsRect.Right > aDesktopWorkRect.Right then
        NeedToMoveOffsetX := aDesktopWorkRect.Right - aBoundsRect.Right
      else
        NeedToMoveOffsetX := 0;

      if aBoundsRect.Top < aDesktopWorkRect.Top then
        NeedToMoveOffsetY := aDesktopWorkRect.Top - aBoundsRect.Top
      else if aBoundsRect.Bottom > aDesktopWorkRect.Bottom then
        NeedToMoveOffsetY := aDesktopWorkRect.Bottom - aBoundsRect.Bottom
      else
        NeedToMoveOffsetY := 0;

      if (NeedToMoveOffsetX <> 0) or (NeedToMoveOffsetY <> 0) then
      begin
        Windows.OffsetRect(aBoundsRect, NeedToMoveOffsetX , NeedToMoveOffsetY);
        Form.BoundsRect := aBoundsRect;
      end;
    end;
  poScreenCenter:
    Form.BoundsRect := CenterRectOfRect(aBoundsRect, Bounds(0, 0, Screen.Width, Screen.Height));
  poDesktopCenter:
    Form.BoundsRect := CenterRectOfRect(aBoundsRect, DesktopWorkRect);
  poMainFormCenter:
    if Form <> Application.MainForm then
      Form.BoundsRect := CenterRectOfRect(aBoundsRect, Application.MainForm.BoundsRect)
    else
      MoveFormToPosition(Form, poScreenCenter);
  poOwnerFormCenter:
    if Form.Owner is TCustomForm then
      Form.BoundsRect := CenterRectOfRect(aBoundsRect, (Form.Owner as TCustomForm).BoundsRect)
    else
      MoveFormToPosition(Form, poMainFormCenter);
  end;
end;

使い方の例

procedure TForm1.FormShow(Sender: TObject);
begin
  MoveFormToPosition(Form, poDefaultPosOnly);
end;