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使わなくてパッドを使用可能に出来るから、みんなゲーム作るときは組み込んでね、というおはなしじゃったんじゃ。結構「パッドが使えれば」って書き込みを某所でよく見るので。

2009年9月20日日曜日

事故怖い怖い


 すごい見覚えのある風景に思わず。
免許とっても車乗らない自分まじ賢いと思わざるを得ない。

2009年9月15日火曜日

ローカル変数のメモリ配置?


#include <stdio.h>
 
int main()
{
  int num = 0x00737569;
  int num2 = 0x61726144;
  printf("%s\n", (char*)&num2 );
  printf("%p, %p\n", (void*)&num, (void*)&num2 );
  return 0;
}

 というようなプログラムを実行したところgcc4.1.2では

Daraius
0xbfa284e8, 0xbfa284e4

 と、出力されたが、VisualC++2005EE(Debug)では

Daraフフフフフフフフius
0012FF4C, 0012FF40

 と表示された。Releaseだとgcc4.1.2と同じ結果になった。

 普通こんな使い方はしなけど面白半分にテストしてみたら自分の予想とは違った結果になった。
宣言した順番とは逆方向にメモリが確保されているのに「うん?」と思ったが、スタック構造なのを考えると納得はいく。構造体のイメージでいると「やっちゃったよ!」てな事態になるかもしれない。
 VC(debug)だと、intにもかかわらず12byteもの領域があるらしい。オプションの設定かなんかでそうなってるんだろうけど、Debugでは動くけどReleaseでは動かないなんて事態が容易に想像できるのが泣ける。


#include <stdio.h>
 
struct Block
{
  int num;
  int num2;
};
 
int main()
{
  struct Block b;
  b.num = 0x61726144;
  b.num2 = 0x00737569;
 
  printf("%s\n", (char*)&b.num );
  printf("%p, %p\n", (void*)&b.num, (void*)&b.num2 );
  return 0;
}

 を実行すると、gccでもVC(debug)でも同一の結果になった。「プログラミング言語C 第2版」の付録A8.3に構造体のメンバーは、宣言の順序に増えていくアドレスをもつ。とあるので、メモリ配置に関しては信用できる。intが4byteとは限らないし、char*に変換したときに[0]44,[1]61,[2]72,[3]61となるとも(おそらく)限らないので、結局環境依存だけど。

 いままで、ノリと勘だけでやってたから、知らんことばっかりじゃ。

2009年9月9日水曜日

立体的だと感じるには? 実験2

 前回に引き続き、オブジェクト配置後に回転させた。前回はオブジェクトを直接回転させてたんだけど、今回は視点のほうを回転させた。けれど結果に違いが出なかったというか、メタセコだと視点を動かしてるのに影の位置が変わらないらしい。仕様?


■実験1
 多重スクロールではないが、近くのものは早く、遠くのものは遅くを基本に、回転なしで。FCとかみたいな表現がもっとも立体感の出せる表現方法なのではないか? と、思ったため実験。
 結構ゲームでも似たいような表現をよく見るため新鮮さはないが、水平飛行すればだいたいこうなるのでしかたのない部分も。シンプルながら面白い。


送信者 生産がす

■実験2
 情報量が少ないのかと思い、むやみやたらとオブジェクトを増やして回転させたら、ぐちゃぐちゃしてよくわからなくなった例。
 ただ、画像上のほうの位置があまり変わらないオブジェクトに注視すると、動きの激しい部分との対比でちょと立体的に見える。
*この画像だけうまくアップできなかったので直接リンク貼る。



■実験3
 前回のとかわらないが、視点を動かしているにもかかわらず、影の位置が変わってないのにここでようやく気づく。



■実験4
 実験1、2から、情報量をほどほどにし、近くと遠くにオブジェクトを置いて回転させた。
 なかなか立体的だと感じる。どうも回転していることを確認できる範囲が広いほど立体的と感じるような気がする。オブジェクトが多すぎると、遠くのものが隠れて見えなくなるので立体感が減るのではないだろうか。見えないものはないと同じ。動きを確認できる範囲が縮小して小さい範囲だけが動いているように見えるとか、そんな感じか。
 遠くが見えていればいいので、チリのような小さいものを漂わせて立体感をだす演出はかなり効果的だと思われる。

2009年9月6日日曜日

日記ちゃん

 バニラエッセンスを買ったので、フレンチトーストに作る際使用してみた。ふんわりと甘い香りがして美味! ナイフとフォークで食べたのですげえ優雅な感じに。

 ついでに新しい歯磨き粉を買った。ピーチ味のやつ。歯磨きも優雅!

 最近マウスがいかれてきてて、クリックするとダブルクリックに化ける。ホイールクリック利かないとひどい状況になってる。無線が便利すぎてはずすわけにもいかず。近いうちに買い換えたい。
 ちなみに、クリックがダブルクリックになるような現象のことをチャタリング(Wikipedia)というらしい。この先、生きててこの単語を使うことはまずあるまい。