2009年10月27日火曜日

日記ちゃん

 父上が突然無線ルータを買ってきて「今すぐ設定して使えるようにしろ、このウジ虫!」
というので、適当にセッティングした。ほぼデフォルト設定。

 ところが自分のノートPCの無線は壊れて機能しない上に、外付けHDD等の関係で移動も出来ず、またiPhoneや携帯ゲーム機も存在しない。父上もPCを1ヶ月に1回程度しか使わないので、無線の恩恵にほとんどあやかれない悲惨な状況になってる。ののしられ損である。なきたい。

2009年10月25日日曜日

日記ちゃん

 バニラオイルとバニラエッセンスって何が違うんだろうと売り場で悩んだことがある。そのときはよくわからないから購入は次回にしようと見送ったのだけど、そのとき分かったことはバニラエッセンスよりバニラオイルのほうが高いということだけだった。値段が2倍ぐらい違う。
 今日になってふと思い出したのでググって見たら、どうやらバニラエッセンスのほうが熱に弱く、加熱すると香りが飛びやすいらしい。熱を加えるお菓子なんかにはバニラオイルを使おう、というお話。熱を加えないお菓子って何があったっけとすぐには思いつかないけど。あー、アイスがあるか。
 バニラの風味の主要成分にバニリンってのがあるらしい。まんまだ。バニリンのインパクトはすごいな、たぶんこの先一生忘れないと思うわ。バニリン。バニリン。

[参考]

バニラ - Wikipedia
http://ja.wikipedia.org/wiki/%E3%83%90%E3%83%8B%E3%83%A9

2009年10月14日水曜日

クリップボード関係のウィンドウメッセージ

 CF_DIBからデータ抜き出すのに疲れたよ。
ところがCF_DIBがくるときは大抵CF_BITMAPも来てるんでCF_BITMAPで事足りるうえに、CF_BITMAPはとくに加工せずにそのまま描画できちゃうから、CF_BITMAPだけでいいんじゃないかと妥協したくなる。


休憩だ……っ!


 画像ソフトからコピーを行ったときに、どういうデータでクリップボードにセットされるのか調べてた。
・Microsoft (R) ペイント ver 5.1
 CF_BITMAP(2), CF_METAFILEPICT(3), CF_DIB(8), CF_ENHMETAFILE(14), CF_MAX(17)
・プリントスクリーン
 CF_BITMAP(2), CF_DIB(8), CF_MAX(17)
・PictBear ver2.0
 [背景]CF_BITMAP(2), CF_DIB(8), CF_MAX(17)
 [レイヤー]送られてこない
・AzPainter2 ver2.05
 [コピー]送られてこない
 [他へ出力→クリップボード]CF_BITMAP(2), CF_DIB(8), CF_MAX(17)
・Microsoft (R) Office Excel 2003
 [画像データを選択しコピーしたとき]CF_METAFILEPICT(3), CF_ENHMETAFILE(14)

おまけ
・エクスプローラでファイルをコピー
 CF_HDROP(15)
・InternetExplorerにて画像を右クリック→コピー
 CF_BITMAP(2), CF_DIB(8), CF_HDROP(15), CF_MAX(17)

といったような感じ。
 レイヤー関係はクリップボードを使わないみたいだが、だから不便なんだよ。32bitにしてAlphaColorを0にでもすればいいんじゃないかと思わんでもないが、そんな簡単な問題でもないんだろうな。
 Officeに関しては、クリップボード関係を調べてたら一例で乗ってたので実験がてら。


 ところでCF_MAXってなんじょい?


#if(WINVER >= 0x0500)
#define CF_MAX 18
#elif(WINVER >= 0x0400)
#define CF_MAX 17
#else
#define CF_MAX 15
#endif


 とWinUser.hにあり、値がまちまちのようだ。結局なんのパラメータ?

2009年10月9日金曜日

&&より&のほうが速いか?

 trueが1になることを意識して最適化しようと思うとどうすればいいのかとアセンブラとにらめっこしていたが、


for (int i=0; i<100; ++i)
{
  num += (((i & 3)==0) && (num<100))!=0 ? 1 : 0;
}


と


for (int i=0; i<100; ++i)
{
  num += (((i & 3)==0) & (num<100))!=0 ? 1 : 0;
}


では、後者のほうが高速になると思われる。前者にはjgeとjmp,jiが含まれるが、後者にはjiしかない(forの分かと思う)。



 ほかに


for (int i=0; i<100; ++i)
{
  num += (((i & 3)==0) & (num<100)) ? 1 : 0;
}


と


for (int i=0; i<100; ++i)
{
  num += ((i & 3) == 0) & (num < 100);
}


だと、後者のほうが数命令少ないため、おそらく高速。実際、1億回回して時間を計ると後者が200ms程度速かった。

コンパイラ: VisualC++ 2005 Express Edition
CPU: Intel(R) Pentium(R) M processor 1400MHz
速度優先(/O2)で最適化してコンパイルした。


 よっぽどコアな部分のプログラムでもない限り意識する必要はないかと。速度が重要ならアルゴリズムを見直すほうが効果がある。

2009年10月7日水曜日

c++ではtrueは1

boolをfloatに暗黙の型変換?
http://sumishiro.blogspot.com/2009/08/boolfloat.html


 以前こんなことを書いたが考えてみれば、bool -> int -> floatで変換されたと思えばどうということはないな。クラスでこんな一足飛びな型変換ができちゃうのかなと少し試してみたが、再現できなかった。一足飛びな型変換は出来ないのかもしれない。

 また


C++言語仕様では、boolはintに変換でき、false→0/true→1 となっています。

--- ISO/IEC FDIS 14882:1998(E) ---

4.5 - Integral promotions [conv.prom]
...
-4- An rvalue of type bool can be converted to an rvalue of type int,
with false becoming zero and true becoming one.


true/falseは、1/0と保障されている?
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200504/05040024.txt
より引用。
 とあり、trueはc++では1らしい。


#include <cstdio>
#include <cstring>
int main()
{
bool b;
std::memset( &b, 2, sizeof(b) );
if ( b == true ) std::printf("b == true\n");
if ( b == 2 ) std::printf("b == 2\n");
return 0;
}


output:

b == true
b == 2

2009年10月6日火曜日

311号

http://cid-8cd7cf5ea9fbca55.skydrive.live.com/self.aspx/Public/music/no%20name311.ogg
2.3MB

製作時間:2時間程度
ツール:ピストンコラージュ ver0.9.1.4
音源:デフォルトの

 地味にテンションが高いが、これといって主張もしないので「何を表現したいんだ!」といらいらする、そんな曲に仕上がりました。うーん。

2009年9月30日水曜日

アクティブなウィンドウのハンドルからファイルパス取得

 以前ちょっと話題に出した「Manic Time」が面白かったため、似たような機能を作ってみたい! ってことでちょちょいと調べてみた。


●アクティブなウィンドウのタイトルを取得する
 GetForegroundWindowって便利な関数があるのでそれで一発。ウィンドウハンドルが得られるからあとはGetWindowTextするだけ。簡単。

GetForegroundWindow 関数
http://msdn.microsoft.com/ja-jp/library/cc364732.aspx

GetWindowText 関数
http://msdn.microsoft.com/ja-jp/library/cc364815.aspx



●ウィンドウハンドルからファイルパス取得
 「Manic Time」にはプログラム別に色分けして表示する機能があるので、プログラムでユニークな情報が必要そう。「Manic Time」ではどうしているのか知らないけれど、ファイルパスでどうにかできそうなのでファイル名を取得する。ウィンドウハンドルだけからファイルパスを直接取得する関数がないので、いくらか段階を踏む必要がある。

GetWindowThreadProcessIdでプロセスIDを取得
↓
OpenProcessでプロセスハンドルを取得
↓
EnumProcessModulesでモジュールハンドルを取得
↓
GetModuleFileNameExでファイルパスを取得

 といった流れ。GetModuleFileNameExでプロセスとモジュールのハンドルが必要になるので適当にデータを取ってくる。作業。

GetWindowThreadProcessId 関数
http://msdn.microsoft.com/ja-jp/library/cc364779.aspx

OpenProcess 関数
http://msdn.microsoft.com/ja-jp/library/cc429278.aspx

EnumProcessModules 関数
http://msdn.microsoft.com/ja-jp/library/cc429387.aspx

GetModuleFileNameEx 関数
http://msdn.microsoft.com/ja-jp/library/cc429403.aspx


●サンプル

#include <windows.h>
#include <cstdio>
 
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
 
 
bool getWindowFileName( HWND hWnd, LPSTR lpFileName, DWORD nSize )
{
  DWORD processID;
  GetWindowThreadProcessId( hWnd, &processID );
  HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID );
  bool ret = false;
  if ( hProcess )
  {
    HMODULE hModule;
    DWORD cbReturned;
    if ( EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbReturned ) )
    {
      ret = 0 != GetModuleFileNameEx( hProcess, hModule, lpFileName, nSize );
    }
    CloseHandle( hProcess );
  }
 
  return ret;
}
 
int main()
{
  for (;;)
  {
    HWND hWnd = GetForegroundWindow();
 
    TCHAR title[ 1024 ];
    ZeroMemory( title, sizeof(title) );
    GetWindowText( hWnd, title, sizeof(title)/sizeof(*title) );
 
    TCHAR fileName[ 1024 ];
    ZeroMemory( fileName, sizeof(fileName) );
    getWindowFileName( hWnd, fileName, sizeof(fileName)/sizeof(*fileName) );
 
    std::printf("%s [%s]\n", title, fileName );
    Sleep( 1000 );
  }
}



●ほか
 あとは収集したデータをグラフィカルに表示すればOKといったところだろうけど、そこが一番面倒くさい。

 以下のサイトを参考にしました。感謝。
Win32 API でアプリケーションを列挙する方法
http://support.microsoft.com/default.aspx?scid=kb;ja;175030

ファイル名を取得するには
http://hpcgi1.nifty.com/MADIA/Vcbbs/wwwlng.cgi?print+200504/05040053.txt

 
 
/** 11-06-05 */
 hProcessを閉じ忘れていたのを修正

2009年9月27日日曜日

ノートPCのファン清掃

 最近、ウギギギギっギャンゴギャンゴッとPCのファンが鳴いてたので分解して埃の除去を行った。
参考にしたサイトは以下

サーマルセンサーエラー|caraldo.net | MT Blog
http://blog.caraldo.net/2007/09/post_9.php


MG50G~MG50シリーズ分解のページ
http://sakurapapa.hp.infoseek.co.jp/MG50G1.htm


 だいぶ静かになったが、まだちょっとうるさい。起動時にサーマルセンサーエラーが出なくなったのでよしとする。ねじが一本あまったが、それもまあよしとする。


/***/


 まる一日経過したが、気が付いてみればファンが回らなくなってた。なんか静かだと思ったよ。CPUを使っていないときのHDD温度は50℃前後、CPUをしばらく使うと55℃ぐらいになる。60℃を超えるとHDDが死ぬというからそこそこキテると思われるが、どうしたものかな。

 とりあえず、割り箸で すのこ的なものを作ってPCの下に敷いておいたが、どれだけの効果が期待できるのかは不明。うかつにCPUをつかうエロゲが出来なくなったが、かえってよかったかもしれない。
 うちわでぱたぱたしてたら45℃まで下がった。分解したときに知ったけど、キーボードの裏側に薄く広い金属板があって、それで熱を分散してるみたい。だから全体を冷やすように風を当ててもそれなりに冷えるようだ。そこらへんノートPC様々といったところ。しかし扇ぐの面倒だな、このままでは左手がむきむきになってしまう。

/***/

 普通に扇風機をそばに置いた。手が冷える冷える。

2009年9月25日金曜日

ドラッグ&ドロップ + [Alt+Tab]

画像処理でボコーダーエフェクト - Radium Software
http://d.hatena.ne.jp/KZR/20090925/p2

 を見ていて、操作に驚いた。ファイルをドラッグしたまま[alt+tab]でウィンドウをトップに表示し、ドロップしていた。その発想はなかった!

 ドラッグ&ドロップは誰でも良く使うんじゃないかと思う。画像編集ソフトに画像ファイルをドロップして開くとか、メディアプレイヤーに音楽ファイルをドロップしてリストに追加するとか。
 Alt+Tabは使わない人も中にはいるかもしれない。[alt]キーをおしながら[tab]キーを押すと、ウィンドウ選択画面が出てきて、選んだウィンドウをトップに表示することができるショートカット。[alt]をおしながら[tab]で次のウィンドウ、[alt]をおしながら[shift+tab]で前のウィンドウを選択できる。

 自分は今までどうしていたかというと、
・ファイルをドラッグしたままタスクバーにカーソルを移動。
・ドロップ先ウィンドウ名の上でしばらく待機するとそのウィンドウがトップに表示される
・ドロップ
ってな感じ。ドラッグしたままタスクバーで待機ってのも普通しない動作だと思うが、対応しているWindowsもすごい。おそらくXp以降でのみ可能。

2009年9月24日木曜日

大胸筋強制サポーター

 ゲームパッド部分のプログラムを見直してみてる。


↑入りっぱなし状態になってしまって
ゲームできない・・・


って書き込みが某所にあって気になってたので。

 今のところ詳細な原因不明だけど、スティックの中央値を0x8000に固定してるのが原因かなと踏んでる。ちょっと調べなおしてみたところ(wXmax-wXmin)/2あたりを中央値としたほうがよさげ。そこからスティックの遊び値を計算に入れればOKっぽい。
 自分の環境ではwXmaxは65535, wXminは0なので中央値は(0xFFFF - 0x0000)/2 = 0x7FFFで、1しか差がないので問題ないといえばない。

 joyGetThreshold 関数
http://msdn.microsoft.com/ja-jp/library/cc410477.aspx

の解説に、


移動しきい値は、デバイスをキャプチャしたウィンドウに WM_JOYMOVE メッセージが送信される前に、ジョイスティックを動かさなければならない距離です。しきい値の初期値は 0 です。


とあり、キャプチャして使用している場合にのみ使う関数のような気がする。いままで遊び値を取得するのに使っていたが大きな間違いで、おそらく自分で設定しない限りは0が帰るんじゃないかと。遊びを取得する関数がないかと探してみたが見つからない。ないのかな? 

 それはそれとして、メモリの無駄遣いがひどいので修正じゃ!

 ゲームパッドのパラメータ取得には以下の関数を使用しています。
joyGetPosEx
joyGetThreshold
joyGetNumDevs
joyGetDevCaps
 検索助長なのか検索妨害なのか微妙なところ。DirectX使わなくてパッドを使用可能に出来るから、みんなゲーム作るときは組み込んでね、というおはなしじゃったんじゃ。結構「パッドが使えれば」って書き込みを某所でよく見るので。