Windows SDK」タグアーカイブ

Aero の TextOut

唐突に気がついたのだが…
以前 WPF の描写について

※ボタンを押して文字を描写した
※アプリの上に他のウインドを被せた
※そのウインドをどかしたら文字が消えていた

なんて初心者が必ず迷う事柄はもう二度と起こらないんだし。

と書いてしまったが、よく考えたら Aero 自体も DirectX 描写だ。
もしかして?と思って実験。

20080309.JPG

を Aero で動かして左クリックで文字を描写して上にウインドを被せる。
どかしたら…やっぱりコレでは描写が消えなくなっていたのね。

ウインドをリサイズすると当然のように消えるのは変わっていない。
正確に書くとリサイズでは WM_PAINT が飛んでくる。

WPF は何をしようが消えない、うーややこしいぞ。
つーか WPF では Paint イベントなんて定義が無いので消えたら困る。

文字を表示する
かの赤坂氏の解説も今は通じなくなってしまっているわな。
なんか何を今更という感じですが Vista って本当に困った OS です。

Windows徹底理解

WPF も魅力なのだが現行アプリもやらねば。
とりあえず今年は C++ をメインに少しづつ .NET でいく。

Windows API の本で役に立った本も紹介しておく。

2004年発行のムックだけど今でもたまに手に取っている。
やっぱりプレミアが…って定価 ¥2095 なのでそんなに付いていない。

コレを買ったのは BCC で DLL の作り方が書いてあったから。
VC++ Exp が無償で手に入る時代に今更 BCC は勧めませんが。
当時は C++ のコンパイルを BCC でやっていたのでまあ。

まあそれはそれで役に立ったわけですが、この本は凄かった。
その名の通り Windows はどうやって動いているかで始まっている。

NTFS の仕組みとか IO とか割り込みとかキューとか etc…
それも簡潔ながら図解付きで解りやすく解説されている。
実はなんとなくしか解っていなかったが本当に勉強になった。

そして基本ウインドの項目は衝撃だった。
アプリケーションは自分でメッセージをキューに取りに行っているのね。

while (GetMessage(&msg, NULL, 0, 0))

の部分で、あぁだからこの関数が必要なんだと。
そんなことも知らずにプログラミングをしていた自分を恥じた。
たったソレだけのことを知った事による影響は大きかった。

それを解説してくれる本にそれまで出会わなかった事が不思議だ。
まあそれを隠しているデルヒャァ屋だったというのもあるが。
WPF なんかも隠す方向なんだよねぇ、チト気になる。

脱線はこれくらいにして。
ファイルアクセスやメモリ管理なんかの解説も当然あるわけで。
これらもなんとなくしか解っていなかった事をこの本で改めて知った。

実は UNICODE アプリが作れるようになったのもこの本のおかげだ。
そしてフォントはふぉんとに奥が深かった(我ながらつまらん…)

ようするに API の解説ではなく Windows の解説本なのだが、
どうやって Windows が動いているのかを知って得たモノは大きい。
API というか SDK でプログラムをしようという人は必見。

Vista が出た時代だけど API 関数はほぼ同一なので問題無し。
てゆーか本当に基本の基本しか書いていない、それがよい。

でもさすがに古いムックなので代替があればイイんだけど…
見つけたらまた紹介するね。

Flash 再生

VS2008 の使い勝手を調べるのに試しに Flash 再生をば。
新規でまず普通に Win32プロジェクトを適当な名前で作り stdafx.h に…

なんじゃこの targetver.h っつーのは、分離する必要があるのか?
ココを弄くるとリビルドしなきゃいけないのでややこしくなるだけだと思うが。
まあそれはよくて。

#pragma comment(lib,”Atl.lib”)
// TODO: プログラムに必要な追加ヘッダーをここで参照してください。
#include <atlbase.h>
#import <C:\\Windows\\System32\\Macromed\\Flash\\Flash9d.ocx> named_guids raw_interfaces_only

を追加、ocx の名前は私はこうなっていたけどどうなんだろう?

と書いていたトコで Ctrl+C が急にまったく使えなくなってしまい困った。
再起動しようとすると更新アイコンが、こんなにコッソリ更新すんなボケ!
VS2008 では使えなくなったかと思ったヤン、まあそれはよくて。

ソース先頭にお約束を記述
using namespace ShockwaveFlashObjects;

ShockwaveFlash オブジェクトのポインタを用意しておく。
IShockwaveFlash *pSwf;

んでもって下記のコードを追加してビルド、完成。
swf ファイルは自分で用意してパス指定してね。

atl01

だけどコレだけじゃ atl が使えないので
C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.ATL
に atl90.dll があるので生成された exe と同じフォルダに放り込む。
それだけで swf は再生可能。

atl02

コードギャーは気にしないでくだされ、手元にコレしか無かっただけです。

flv の再生は読み込んだ swf から ActionScript とかで読み込んで再生させる。
というわけで Flash 作成ツールが必要なのね、、、、、

WS_EX_COMPOSITED は使えない

あけおめ(一応)

あー!なんじゃこの拡張スタイルはっつーの。
Wバッファリングを自動でやってくれるスタイルなんだが。
Aero で使ってみたら問題が無かったので当ててみたら…

クラシック表示
VMR の動画がまったく見えない。
他の部分が余計にチラツク

XP
アルファブレンドを掛けた GDI+ 表示がまったく見えない。
VMR の動画もやっぱりまったく見えない。
その見えない動画の上ではメニューさえも消える…

そういえば自力でやったら似たようになったのでヤメたんだっけ…
とにかく GDI+ や DirectX を使う人は絶対にこのスタイルを含めないで。

とにかくこの環境全部のつじつまを合わせると方法が限定されて困るわな。

???の人に簡単な解説をすると。

XP までの画面表示は1つの画面領域を全部のアプリが共有していました。
だからウインドを移動すると下のウインドが真っ白になっているのが見える。
ソレ毎に WM_PAINT が飛んできて、せっせと再描写が行われます。

しかしビデオカードが大半を処理してくれるので気にならなかった。
GetDC 関数で得られる HDC は実は完全に見せかけです。

Vista のクラシック表示は同じ方法で描写されます。
しかし GDI 処理が全部ソフトウエア処理に変更になりました。
そのため描写処理は目を覆いたくなるくらい遅くなってしまいました。

Vista を重いと言う人の大半はコレを言っているような…
クラシック表示のほうが軽いって考える思いこみって怖いね。

Aero 環境は Desktop Window Manager (DWM) が一括管理します。
アプリケーションごとに画面領域を本当に確保しておき合成して描写します。
おかげで背景のウインドさえスケスケに見えるなんてワザが可能。

と、聞いただけでは「重くなりそう…」と感じるのですが
その仕組みのおかげで上に被さっているウインドが移動しただけで
WM_PAINT が飛んできて再描写なんて事は無くなってしまいました。
トータルで描写処理が軽くなっています、頭がいい人が考えたのね。

Aero で表示がおかしくなるアプリは WM_PAINT の処理がおかしい。
○isual Studio とか ○onoha とか。

おまけに Vista ではオーバーレイが廃止されている。
だから動画のスクリーンショットも普通に可能になってもーた。
つーことで Cinema も VMR というワケワカなモンに移行したわけで。

とにかく。
描写処理が Aero、クラシック表示、XP で全部違うのよ。
従来の方法で描写しているかぎりは何も問題がないわけですが、
DirectX や GDI+ でアルファブレンドを使うとこうなってしまう。
両方使っている Cinema は…さて、色々試して勉強だ。

正月からこんなネタ…

アルファブレンドの制御

クラシックてか Windows 2000 スタイルでの動作チェック。

シークバーがチラツキすぎる…だめだこりゃ。

まあWバッファリングが上手くいかんのでチラツクのは解っているんだが。
アルファを掛けているとバッファの転送で背景が消えないんで一度フラッシュしてるし。
クラシック表示だと露骨に見えるようになるのか、コレは困った。

なんとかならんかとあーでもねぇこーでもねぇとやって今日が終わるよぉ!
InvalidateRect の第三引数を TRUE にすれば普通なら消えるはずなのに…
以前の描写部分を転送前に消す、もしくは転送したら消えるようにするには…
いくら探しても古くさい情報しか見つからない!方法は絶対にあるはずだ!

GDIPlus に関する情報の少なさは悲しいね。
C++ で行う情報は皆無に近いので C# で探して自力変換するしかないし。
…それって逆だろ!と憤りを感じてもしょーがない。
まあ他言語からの変換なんて元デルヒャァユーザーはいつものことだったし。

半日探してやっとこんなのを見つけた。

方法 : 複合モードを使用してアルファ ブレンドを制御する

んーブレンド制御を行ったら透過部分も塗りつぶしにならんかな?
とも思ったけどやってみにゃ解らない、藁にもすがる気持ちでやってみる。
まあつまり

g.Clear(Color::Black); //チラつくけど背景消去方法が他にない

とやっていたトコを

g.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);

に書き換えるだけなんだが。

さてどうなるか…あっさり解決…
せっかく GDI+ が用意してくれている方法を知らないって悲しいなぁ。
まあ現場のおっさんなんだからこんなもんさ。

そんなこんなで今日も進まない。