2010年まであと1日

昨日の早朝、急に吐き気をもよおし、それから腹痛。また腸が詰まってしまったか・・・。ベッドで軽い腹痛を覚えつつ、気分が悪い状態で丸一日。

つぅことで、年末バタバタしている中、ベッドの中でiPodでyoutubeにアップされているバラエティ番組の動画を見つつ、過ごすはめになりました。

来年はちょっといろいろ周りの環境や状況が変わるので、今までのように好き勝手にできないかもしれない。持病を気にしつつ、僕のポリシー、

「がんばらず、テキトーに生きていこう」

はそのままです。

年の瀬に

1月にやる手術のための術前検査に呼ばれ、行ってきました。
いつもは渋滞する道路も、今日が仕事納めの日なんでしょうか、少なめ。

外科で受付~採血・採尿~心電図~肺活量測定~レントゲン で第一部終了。ここまで1時間ちょっと。
第二部は麻酔科受診。これが長い。異様に待たされる。待合室人いっぱい。2時間半ぐらい待ってやっと受診。5分ほどで終了(__;) こんなん書類だけ見て判断すればいいんでわ?対面で行う意味なし。決まり(マニュアル)だからしょうがないんだけど・・・。

結局、9時に行って、終わったのが13時30分・・・。あとは入院日を電話で知らせてくれるそうで・・・まだいつなのか分からず。

エアロのガラス効果

Windows Vistaに全く興味がなかったわけでもないですが、メインのPCをWindows7にしたことだし・・・ということで、ほとんど何の知識もないWindows Aeroですが、ちょっと勉強がてらいじってみました。

Aeroの最大の特徴は、やはり、ウィンドウフレームにも適用されているガラス効果でしょう。各ウィンドウとガラス効果などのAero効果をデスクトップ上のウィンドウとして表示できるように合成・管理しているのが、DWM(Desktop Window Manager)ということだそうです。

クライアント向けのWindowsで、NT4からXPまでのウィンドウマネージャなどの大部分はカーネルモードで動作していたと思います。これは純粋にパフォーマンス向上のためと思いますが、Vista以降ではドライバモデルが変更され、iその一部がユーザーモードで動作するようになりました。本来のNTの思想に戻ったといえます。ビデオカードをはじめとするハードウェア自体の性能向上のおかげでしょうね・・・。

このDWM、タスクマネージャで確認するとVistaと7では、明らかにメモリ使用量が違っています。詳しくは知りませんが、なんらかの改良が施されているんだと思います。

で、DWMに関連するAPIでネットを検索しても、SDKプログラマの興味がないのか、関心がないのか、C/C++ WindowsSDKで利用できるまとまった情報(コード)が少ないです。使ってみました、という記事はいっぱい出るんですが、詳細な記事が見つからず。MSDNのAPI説明見てもいまいち分からないし・・・。

まぁ、だけど利用できるAPIは限られていて、DWMに関連するAPIで最も簡単に利用できるのが、DwmExtendFrameIntoClientAreaというAPIです。
これは、ウィンドウフレームに適用されているガラス効果をクライアントエリアに拡張するAPIなんですが、使い方は至って簡単です。ガラス効果をどれだけクライアント側に食い込ませるかをMARGINS構造体にセットして、それをウィンドウハンドルとともに渡せばOKです。

//{左,右,上,下}という風になります。
//下記例だと、上部20ピクセルが拡張されます。
MARGINS margins = {0,0,20,0};
DwmExtendFrameIntoClientArea(hWnd,&margins);

//ちなみに、以下のように-1をセットすると、クライアント領域すべてがガラス効果の影響受けます。
MARGINS margins = {-1};

※dwmapi.hのインクルードと、dwmapi.libのリンクが必要です。

MARGINS margins={-1};としたときのガラス効果

このようにAPI自体はカンタンに利用できる反面、C/C++とWindowsSDKのみで組んで行くには相当めんどくさい処理が必要になります。

  1. 単純にボタンやエディットなどのコントロールを配置すると、悲惨なことになる。
  2. ガラス効果上に黒い文字を描画すると、黒い文字が透明になっちゃう(^^;;;
  3. ガラス効果にしたクライアント領域部分は、別途常に黒く塗りつぶさないといけない。
    (要するに、拡張した部分の背景色の再描画処理を別途記述しなければならないかと・・・)
  4. DWMのデスクトップコンポジションが有効か無効かを判別してそれぞれに対する処理を行う必要がある。

などなど・・・

ガラス効果上に配置した黒く塗りつぶしたGDIアイテムは、全部透明になってしまいます(テキストとかメニューの文字とか)。要するに、色値が0x00000000(要するに黒色)の部分がガラス効果として透明なるっちゅーわけだから、当たり前と言えば当たり前ですが・・・。COLORREF型の先頭1バイトを255にすればいいのか?よくわかんないです。
これの解決方法としては、コントロールをオーナードローで描画するか、GDI+ライブラリを使用する、という選択肢がMSDNで紹介されていました。が、子コントロールの色を全部修正するなんて、メンドーだし、他の解決方法があるのかもしれません。
そのうちガラス効果関連処理をラップしたC/C++のクラスライブラリがそのうち出るかもしれないし、でないかもしれないし、すでに出ているのかも・・・。C#の情報は結構あるんですけどね・・・。

ダイアログをリソースファイルで定義してDialogBox() APIで表示させているようなプログラムの場合、最低限以下のようなウィンドウメッセージを捕まえて背景を別途処理しないといけない。

・WM_INITDIALOG
デスクトップコンポジションが有効なら、DwmExtendFrameIntoClientAreaを実行。

・WM_ERASEBKGND
ガラス効果を適用しても、ダイアログの背景用描画ブラシで上書きされてしまうので、ガラス効果を拡張した部分は黒色で、それ以外はダイアログの背景色で背景を塗りつぶす。

・WM_DWMCOMPOSITIONCHANGED
デスクトップコンポジションが有効になったり、無効になったりすると、飛んでくるので、これを捕まえて適切な処理を行う。
注意しなければならないのは、デスクトップコンポジションが有効になったらその都度、DwmExtendFrameIntoClientAreaをコールする必要があること。

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  //上部20ピクセルを拡張
  MARGINS margins = {0,0,20,0};
  RECT rect = {0};
  BOOL fDwmEnabled = FALSE;
  HBRUSH hBrush = NULL;
  LONG oldBottom = 0;

  switch(message)
  {
  case WM_INITDIALOG:
    DwmIsCompositionEnabled(&fDwmEnabled);
    if(fDwmEnabled)
      DwmExtendFrameIntoClientArea(hDlg,&margins);
    return (INT_PTR)TRUE;

  case WM_ERASEBKGND:
    DwmIsCompositionEnabled(&fDwmEnabled);
    GetClipBox((HDC)wParam,&rect);

    //デスクトップコンポジションの有効・無効によって背景に使用するブラシを決定
    hBrush = fDwmEnabled ? (HBRUSH)GetStockObject(BLACK_BRUSH) : GetSysColorBrush(COLOR_BTNFACE);

    //クライアント領域の上部20ピクセル(ガラス効果)の背景を描画
    oldBottom = rect.bottom;
    rect.bottom = rect.top + 20;
    FillRect((HDC)wParam,&rect,hBrush);
    
    //クライアント領域の残りの下部の背景を描画
    hBrush = GetSysColorBrush(COLOR_BTNFACE);
    rect.top += 20;
    rect.bottom = oldBottom;
    FillRect((HDC)wParam,&rect,hBrush);

    return (INT_PTR)TRUE;

  case WM_DWMCOMPOSITIONCHANGED:
    DwmIsCompositionEnabled(&fDwmEnabled);
    if(fDwmEnabled)
      DwmExtendFrameIntoClientArea(hDlg,&margins);
    return (INT_PTR)0;

  case WM_COMMAND:
      //ダイアログ上のコントロールへの応答処理など
      if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
          EndDialog(hDlg, LOWORD(wParam));
          return (INT_PTR)TRUE;
        }
      break;
  }
  return (INT_PTR)FALSE;
}

ということで、なんとかかんとか、思ったように表示できました・・・。

ガラス効果2

なんか、久しぶりにGUIなAPI触ると、何がどうだったか・・・忘却の彼方へ・・・(ーー;

同窓会報賛助金って?

よく届きます。相当運営費が厳しいんでしょう。

時期が悪いよ・・・。

さすがに、小学校、中学校からはないんですが、大学と高校からは頻繁です。1万円もしないので、別に払ってもいいんですが・・・正直、同窓会の運営実体分かんないし、しかも、徴収先は、知らない会社だし・・・。

今回は、高校から同窓会報とともに振込用紙が届きました。どうしましょ?(^^;

会報見ると、僕が所属してた部(クラブ)のホームページ(というかブログかな)ができたみたいで、部室とか懐かしいす(^^

nephew

じっとしてないのでピントがあってないけど。結構前のもの。

眼鏡をしているのが怖いのか、僕が部屋に入ると急に大人しくなります(__;) もうすぐ1才。誕生日いつだっけ(^^;;;

I wish you a Merry Christmas!

ポイントの有効期限

寒いっっっっっっスねぇ~~~~~~~。暖冬じゃなかったのか????

先日、ETCマイレージサービスのポイント残高のお知らせ、なる圧着ハガキが届きました。

それによると、2010年3月31日で有効期限が切れるポイント数があるので、還元額(無料通行分)への交換してね、ということなんですけどね・・・・、あまり高速道を使わない(1ヶ月に多くて1~2回程度)のでポイント溜まらない。

ポイント交換は、どんなサービスでも、「○○○ポイントから×××単位で交換」という消費者にとって至極都合の悪い条件があるのが多い。ETCもそう。有効期限がくるので早くポイント交換しろ、と言われても、この極悪条件(^^;;;のおかげで、ポイント交換できません。

要するに、もっと金使え、ということなんだな。デフレ・デフレであり得ないほどモノの値段は下がっているのに、公共サービスの料金はデフレになんないっすねぇ~・・・。

来年2月ぐらいまで会社休む予定なので、その間は、貯金を食いつぶしている状態なんですが・・・まぁ、親と同居している分、ラクと言えばラクなんですが・・・会社の方も気を遣ってくれているのか、家でできる仕事を少しですが回してくれています。自由に時間が使えるので、こっちの方が効率が上がったりします(^^ゞ

今年もあと10日程になりましたねぇ。