2007年12月16日日曜日

C++/CLIと#include <Windows.h>

もっと根本的な問題#define MessageBox MessageBoxWとSystem::Windows::Forms::MessageBoxの名前がぶつかる問題とか解決してほしいなぁ。
と書いたけど、一応現時点での対策も書いておきます。
#include <Windows.h>
...
#pragma push_macro("MessageBox")
#undef MessageBox
MessageBox::Show( "message", "caption" );
#pragma pop_macro("MessageBox")
です。でも面倒くさい…。

VS2008の変更点: C++

VS2008を使い始めて気がついた点をあげていきます。今回はC++について。

まず/Wp64(64 ビット移植性の問題の検出)のサポートがなくなっています。VS2005の1代でつぶれました。せっかく警告たとしても、Win32では無理やりcastするのが正しいときが多々あり、警告の意味が薄れてしまうからでしょうか。更にはx64コンパイラも用意されていますし、x64プロセッサもクライアントPCにまで出回ってきて、実機でテストしなさい、ってことかもしれません。

新しくSTL/CLRライブラリとC++マーシャリングライブラリが増えています。STL/CLRは本当はVS2005に入るはずだったとか間に合わなかったとかだそうで? C++/CLIは個人的にはC#で書ききれないWin32 nativeな部分のマーシャリング?に使うものという位置づけで、STLの出番はちょっと少ないです。JITで最適化していく.NETでSTL/CLRのコンパイル時インライン展開の最適化はどうなんでしょう?
もう一つのC++マーシャリングはまぁ、今まで必要になった人が書いていたものをあらかじめ用意しましたよ、程度で。こちらもgenericではなくtemplateで書かれているのでコンパイル時にインライン展開されます。
マーシャリングはうれしいけど、もっと根本的な問題#define MessageBox MessageBoxWとSystem::Windows::Forms::MessageBoxの名前がぶつかる問題とか解決してほしいなぁ。

今回なくなったライブラリとしてはATL ServerとATL_MIN_CRT関連。obsolateではなくきれいさっぱり削除されています。ATL Serverは使っていませんでしたがATL_MIN_CRT関連は使っていたのでちょっと痛手。もちろん#ifdefで分けていたので、ファイルサイズが大きくなる程度ですが、気分的に。
一応

Visual C++ 2008では、ATL_MIN_CRTが定義されているかどうかに関係なく、ATLプロジェクトのCRTに対する依存はすべて最小限に抑えられます。
と書かれていますが、この説明に意味はなく、ソースを見る限り「リンカが選択的にリンクしますよ」程度のことでした。

ついでにATLのソースをVS2005とVS2008で比較してみたところ、気づいたことが2点ありました。VS2005ではATL_MIN_CRTの影響なのかセキュリティ強化されたCRTを使わないバージョンが存在しましたが、VS2008ではセキュリティ強化されたCRTが強制的に使われます。おかげでガンガンにCRTを使います。
もう1点、なぜかVS2008でも_MTを見ています。VS2005以降、シングルスレッドCRTライブラリが削除されてマルチスレッドCRTライブラリしか存在しないわけですが、ATLは_MTを見てシングルスレッド動作も意識しています。…でもATL_MIN_CRTが廃止されたためにマルチスレッドCRTライブラリが必須なはずですが f(^^;

2007年12月15日土曜日

Visual Studio Team System 2008 Team Suite

VS2008の続報です。Visual Studio Team System 2008 Team Suite日本語版が12/14にリリースされていました。国内での販売は2008/02/01からだそうです。
ところで、.NET Framework 2.0 SP1日本語 Language Packや.NET Framework 3.0SP1はどうなってることやら。インストールして詳しく調べることにします。

2007年12月3日月曜日

ダイアログの表示のされ方(2)

ダイアログの表示のされ方(1)の続きです。
ダイアログには、タイトルバーがあり各種ボタンが並びますが、これまた制御がややこしいため調査しました。
ボタンの場合、表示されているかどうかの他に、動作するかどうかもあります。簡単な話に聞こえますが、表示されていなくてもマウス操作やショートカットキーで動作することもあるため、独立して調査する必要があります。

// ControlBoxが表示される条件
Form.ControlBox == true && Form.ShowIcon == true &&
( Form.FormBorderStyle == FormBorderStyle.FixedSingle || Form.FormBorderStyle == FormBorderStyle.Fixed3D ||
Form.FormBorderStyle == FormBorderStyle.Sizable ||
Form.FormBorderStyle == FormBorderStyle.FixedDialog && Form.Icon != null );

// ControlBoxが動作する条件
Form.ControlBox == true && Form.FormBorderStyle != FormBorderStyle.None;
アイコンが表示されていなくても、Alt+Spaceで動作します。最初からかなりややこしい条件で、泣けました。
// HelpButtonが表示される条件、及び動作する条件
Form.HelpButton == true && Form.ControlBox == true && Form.MinimizeBox == false && Form.MaximizeBox == false &&
( Form.FormBorderStyle == FormBorderStyle.FixedSingle || Form.FormBorderStyle == FormBorderStyle.Fixed3D ||
Form.FormBorderStyle == FormBorderStyle.FixedDialog || Form.FormBorderStyle == FormBorderStyle.Sizable );
Shift+F1については確認できていません。今やヘルプボタンはマイナーな存在になりつつあるため、気にする必要はないかもしれませんね。
// MinimizeBoxが表示される条件、及びMaximizeBoxが表示される条件
( Form.MinimizeBox == true || Form.MaximizeBox == true ) && Form.ControlBox == true &&
( Form.FormBorderStyle == FormBorderStyle.FixedSingle || Form.FormBorderStyle == FormBorderStyle.Fixed3D ||
Form.FormBorderStyle == FormBorderStyle.FixedDialog || Form.FormBorderStyle == FormBorderStyle.Sizable );

// MinimizeBoxが動作する条件
Form.MinimizeBox == true && Form.ControlBox == true &&
( Form.FormBorderStyle == FormBorderStyle.FixedSingle || Form.FormBorderStyle == FormBorderStyle.Fixed3D ||
Form.FormBorderStyle == FormBorderStyle.FixedDialog || Form.FormBorderStyle == FormBorderStyle.Sizable );

// MaximizeBoxが動作する条件
Form.MaximizeBox == true && Form.FormBorderStyle != FormBorderStyle.None;
最小化ボタン・最大化ボタンどちらかが有効になっているときに表示されます。最小化のショートカットを知らないため、見えていて有効になっているとき動作するとしました。最大化に関してはタイトルバーのダブルクリックを含めています。
// CloseBoxが表示される条件
Form.ControlBox == true && Form.FormBorderStyle != FormBorderStyle.None;

// CloseBoxが動作する条件
true;
ControlBoxプロパティそのものでした。Alt+F4は絶えず有効でした。

…疲れました。

2007年12月2日日曜日

ダイアログの表示のされ方(1)

タイトルは何の変哲もないものになってしまいました。
Windowsでは、ダイアログを出すとき、タスクバーに表示されるか・Alt+TABのリストに並ぶか・タスクマネージャに表示されるか、それぞれ制御できるようです。ところが.NET Frameworkには直接的に制御できるのはShowInTaskbarというプロパティぐらいしかなく、制御しづらい上にわかりにくいです。
そこでひたすらパターンを組み合わせてどのように表示されるかまとめてみました。とはいえ、総当たり表を見てもパターンが多すぎてわかりづらいので、逆引き形式で並べてみます。

// タスクバーに表示される条件
Form.ShowInTaskbar == true;

// 3D Flipに表示される条件
Form.ShowInTaskbar == true;

// Alt+Tabに表示される条件
Form.ShowInTaskBar == true ||
Form.FormBorderStyle != FormBorderStyle.FixedToolWindow && Form.FormBorderStyle != FormBorderStyle.SizableToolWindow;

// タスクマネージャに表示される条件
Form.FormBorderStyle != FormBorderStyle.FixedToolWindow && Form.FormBorderStyle != FormBorderStyle.SizableToolWindow;

だんだん、関係ないパラメータに依存してきていることがわかりました。

さらに、タスクバー・Alt+Tab・タスクマネージャにはダイアログアイコンが表示されます。表示されるアイコン自体は共通したものでしたが、アイコンの選択のされ方には微妙な違いがありました。
if( Form.ShowIcon == true && Form.Icon != null )
TheIcon = Form.Icon;
else if( Form.ShowIcon == true && Form.Icon == null && Form.FormBorderStyle != FormBorderStyle.FixedDialog )
TheIcon = Form.ParentForm.Icon;
else
TheIcon = null;

この式でTheIconに値が設定されないときはタスクバーなりタスクマネージャなりのデフォルトが使われる模様?
こうもややこしいと困りますね。