鏑矢の憂鬱2000年9月前半
透明1ドットイメージ
 
2000/09/01 (Fri)
・今日はお休みです〜。
 
・余談。隠れたウィンドウのキャプチャはやっぱ無理な気がする……。
透明1ドットイメージ
 
2000/09/02 (Sat)
・今日はお便りを紹介。
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは。先日ウインドウのキャプチャについて質問した者です。
 
> 隠れたウィンドウのキャプチャはやっぱ無理な気がする……。
 
 うーん、やはりそうですかね。「メモリ上のどっかにあるはず !」と色々試してみたのですが、結局まだできてません。他の方法で対処してみます。
 
 ここは普通の掲示板と違って、できない場合でも試した方法などをお返事いただけるので、すごく嬉しいです。ありがとうございました。また質問するかと思いますが、よろしくお願いします。
透明1ドットイメージ
透明1ドットイメージ
 
・ありがとうです〜。ここは掲示板みたいな無味簡素なのじゃなく、ラジオ番組のノリでいこうと思ってます。キャプチャリングだけど、ベクターさんで公開されてるキャプチャリングアプリってこんだけあるんですよねー。この中のを片っ端から調べて、もし「隠れたウィンドウのでもキャプチャリングできる」のがあれば……。まーでも、逆にひとつもなければ、それができれば当たるかもしんないとも言える。でもかなり難しそう……。
 
・でわまたっ!
透明1ドットイメージ
 
2000/09/03 (Sun)
・今日はお休み。
透明1ドットイメージ
 
2000/09/04 (Mon)
・今日はお便り紹介。では今日のお便りっ!
 
透明1ドットイメージ
透明1ドットイメージ
 VC初心者のものですが質問があります
 windowsでフォルダにパスワードによるロックをかけたいのですがどのようにしたらいいのでしょうか?
 シェルエクステンションを使うのでしょうかそれとも、常駐型のプログラムでフォルダのアクセスを監視するのでしょうか?よろしくお願いします。
透明1ドットイメージ
透明1ドットイメージ
 
・どうもですー。さて、これは結構大変なんじゃないかなー。まず、正攻法じゃ無理だと思うです。「フォルダ内のファイル一覧の列挙」は FindFirstFile() とかを呼び出すことで取得できます。ってことは、この関数が呼ばれたことをチェックできないと、監視することは不可能だと思うです。 FindFirstChangeNotification() で監視しても、実行を阻止することはできないし。
 
・いくつか制限のある方法としては、まず WinNT と Win2000 ならセキュリティ機能を使うこと。でも権限の関係でできる範囲限られるだろうし、確か個別にパスワード設定するとかゆーことはできないんだよね……実は NT 系はあんまり詳しくない(汗)。それにこれだと Win9x じゃ使えないしね。
 
・かなり難しいけど、 FindFirstFile() が呼び出されるのを監視する方法はなくはないんです。 DLL のすり替えをするとか、 DDK を使ってファイルまわりのフックを掛けるとか。でも難易度が爆発的に上がると思うし、 OS によってかなり変わってくるし、現実的な解決法じゃないですね。
 
・手抜き大爆発でいけば、エクスプローラーだけを監視しておいて、目標のフォルダが開かれたらそのエクスプローラーを操作してひとつ前のフォルダに移動させちゃうとか。もちろんエクスプローラーでしか機能しないし、「今表示してるフォルダ」を認識するのとかも結構面倒かなー。
 
・ちょっと毛色違うけど現実的だと思うのは、フォルダ内を圧縮しちゃってその圧縮ファイルに置き換えちゃうこと。圧縮ファイル内にあるファイルやフォルダへのアクセスには専用のアプリを使用するようにして、パスワードがないと入れないようにする。シェルエクステンションをフル活用すれば、エクスプローラー内に組み込むこともできるかもしんない。ただこれだと、もちろん FindFirstFile() とかじゃアクセスできなくなっちゃうけどね。
 
・……って、「VC初心者」じゃえらいきついのばっかですな(汗)。実際の所、かなり難しいと思うです。これも、実際に実現してるアプリがあったら誰か教えてねん、それどうやってるのか調べてみるから。って、これは調べるの大変か……。
 
・でわまたっ!
透明1ドットイメージ
 
2000/09/05 (Tue)
・今日はプログラミング辞書書いてました。とりあえず「ごめんなさい」が多いんで、ごめんなさいの掲載はやめる方向に持ってこうかなーとか思ってます。たとえば「送ったのに載ってない場合はかぶゆ〜で」みたいに。っていうのも、最近単語じゃないのが多いんです(汗)。「なんたらの方法を教えて」とか。
 
・プログラミング辞書のヒット数が爆発的なこともあって、なかなか調整とか難しい状況かもしんない。就職したら更新するの大変になるし、その前に、プログラミング関係のコンテンツをどっかに売却しようかなぁ。でもよー考えると、あのコンテンツにどんな価値があるんだろう(爆)。
 
・でわまたっ!
透明1ドットイメージ
 
2000/09/06 (Wed)
・うおー、誰か __RPC_FAR がどこで #define されてるか教えてくで〜!! ぷらとわで LPCTSTR の解説するときに必要なんです〜。「あ、 __RPC_FAR は空白と同じだから」『なんで?』なんでだろう……。 Windef.h かと思ったら違うし。
 
・あ、今みつけた(爆)。 Rpc.h にあった。全文検索してあまりにも大量に引っかかりすぎてたんで最初の方に見つかったのが消えてた(汗)。ってゆーか __RPC_FAR って単語なんだから真っ先に Rpc.h 見るべきだったな……。ま、こーゆーふーにログとして書くことでそーゆーことに気付いて、だから見つかったんだってことで。
 
・というわけで今日のお便り。今日は質問が4つ入ってたんで、ひとつずつ回答していくことにしましょう。ではひとつめの質問。
 
透明1ドットイメージ
透明1ドットイメージ
 質問1
 
 コンソールで、画像処理(直にメモリアクセス、API使わない)を行うプログラムを書きました。  その結果(確認のみ)を、Windowに表示したいと思っています。
 DIB なので HBITMAP の取得は簡単にできます。
 ウィンドウをコンソールから作成する方法を教えて頂けませんか。
 Borland C++ Compiler (free) でも動作させたいので、SDKでお願いします。
(メイン環境はWin2000,VisualC++6 sp4)
透明1ドットイメージ
透明1ドットイメージ
 
・コンソールからもフツーにウィンドウは作成できます。注意点としてはインスタンスハンドルは GetModuleHandle() で取得するってこと。あとはCodianの「"Hello World!"から始めよう!?」と同じ方法でOK。とりあえずこんな感じのコードでテストしてみました。かなり手抜き(汗)。
 
#include <windows.h>

// ウィンドウプロシージャ。
LRESULT CALLBACK WndProc
		( HWND p_hWnd, UINT p_uiMsg
		, WPARAM wParam, LPARAM lParam )
{
	switch( p_uiMsg )
	{
	case WM_DESTROY:	//×ボタンが押されたとき。
		PostQuitMessage( 0 );
		return 0;
	}

	return DefWindowProc( p_hWnd, p_uiMsg, wParam, lParam );
}

// メイン。
void StartWindow()
{
	HINSTANCE p_hInstance = (HINSTANCE)GetModuleHandle( NULL );
	WNDCLASS	stWndClass;	//ウィンドウクラスです。

	stWndClass.style
		 = CS_BYTEALIGNWINDOW | CS_HREDRAW | CS_VREDRAW;
	stWndClass.lpfnWndProc = WndProc;
	stWndClass.cbClsExtra = 0;
	stWndClass.cbWndExtra = 0;
	stWndClass.hInstance = p_hInstance;
	stWndClass.hIcon = LoadIcon( NULL, IDI_EXCLAMATION );
	stWndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
	stWndClass.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
	stWndClass.lpszMenuName = NULL;
	stWndClass.lpszClassName = "MAWndClass";
	RegisterClass( &stWndClass );

	HWND	hWnd;	//ウィンドウハンドルです。
	hWnd = CreateWindow
			( "MAWndClass", "てすと"
			, WS_OVERLAPPEDWINDOW
			, CW_USEDEFAULT, 0, CW_USEDEFAULT
			, 0, NULL, NULL, p_hInstance, NULL );
	ShowWindow( hWnd, SW_SHOW );
	UpdateWindow( hWnd );

	MSG	stMsg;
	while( GetMessage( &stMsg, NULL, 0, 0 ) )
	{
		TranslateMessage( &stMsg );
		DispatchMessage( &stMsg );
	}
}
	
 
・ BCC でのテストはしてないけど、たぶん大丈夫でしょう。基本的にコンソールアプリでもウィンドウズの機能はすべて使えるから、 API のみでの作成に慣れてるんならそんなに大変じゃないと思うです。では次の質問。
 
透明1ドットイメージ
透明1ドットイメージ
 質問2
 
 過去に、linux の gcc -lstdc で、
 
#include <limits>
 
 が、無いとエラーが出てnumeric_limits を使えなかった記憶があります。
 処理とインターフェイスを明確に分けてプログラムを書き、処理部分では環境依存しないようにしたいのですが、これは、C++標準ではないのでしょうか?
透明1ドットイメージ
透明1ドットイメージ
 
・ちゃんと標準 C++ ライブラリに含まれてます。ただそれがどのくらい「古い」のかに寄るかも。もしかしたら limits のない時代とかあったのかもしんない。 STL のグループに含まれているものじゃないし。少なくとも今は大丈夫なはずなんで、その古い linux でコンパイルする必要がないんなら、使っちゃって大丈夫だと思うです。では次の質問。
 
透明1ドットイメージ
透明1ドットイメージ
 質問3
 
 VisualC++で、メンバテンプレート関数を宣言の外実装する方法はありますか?
 現在、メンバテンプレート関数が長く&数が多く見通しが悪くなっています。
 
template<class _Ta>
class	Tsample
{
public:
	template<class __Tdata>
	void	func(const __Tdata& _Data);
	{
		.......
	}
};
	
 
 これを、
 
template<class _Ta>
class	Tsample
{
public:
	template<class __Tdata>
	void	func(const __Tdata& _Data);
};

template<class _Ta>
template<class _Tdata>
void	Tsample<_Ta>::func(const __Tdata& _Data);
{
	.......
}
	
 
 こんな感じにしたい。
透明1ドットイメージ
透明1ドットイメージ
 
・これは無理なんです(泣)。 VC6 はメンバテンプレートに完全対応してないんで、コンパイルできないんです。 gcc ならできるんですけど。 VC7 もすぐには出ないし、どうしたもんかな……。では最後。
 
透明1ドットイメージ
透明1ドットイメージ
 質問4
 
 VisualC のエディタのみを起動することはできますか?
 インテリセンス(?)を使いたい。
透明1ドットイメージ
透明1ドットイメージ
 
・うんうん、わてもそれしたいです。でも無理っぽいです(泣)。とりあえず VC 立ち上げて、なんかテキトーにワークスペース開いて、んで目的のソースファイルを開いてエディタとして使うとインテリセンスとかばっちり使えるんでそーゆーふーに使うのがいいんじゃないかなー。わては gcc をツールとして登録したりしてちょっと便利にしてます(6月19日参照)。
 
・でわまたっ!
透明1ドットイメージ
 
2000/09/07 (Thu)
・今日もお便り紹介!
 
透明1ドットイメージ
透明1ドットイメージ
 usoです。
 友達に聞かれた事を聞きたいんですけど^^;
 ちょっとプログラミングの話ではないんですが、VCで、クラスとか構造体の名前を書いた後、そのメンバを続けて書こうとするとき、勝手に列挙されて出てくる機能ありますよね?なんていう名前の機能かわからないんですが。それで、自分で作ったクラスとかでも出てくると思うんですけど、なんか出てこない場合もあって、あれってどういう条件で出てくるんだろう?って聞かれて、よくわかんなかったんですけど^^;
 ここで質問するべき事ではないかもしれませんが、もしご存知でしたらご教授くださいませませ。
透明1ドットイメージ
透明1ドットイメージ
 
・どうもですー。その機能は、昨日の質問にもあった「インテリセンス」っていう機能です。普通の変数か参照ならピリオドを打ったときに、ポインタなら参照演算子( -> )を打ち込んだ時に、そのクラスが持つメンバ全部がアルファベット順に表示されます。表が消えたときでも、 Ctrl+Space (正確には Complete Word 機能)でまた表が表示されます。この機能、ローカル変数とかを途中まで書いてこれ押すとそのあと補完してくれたりして便利です。
 
・で、このメンバ表とかが出るときと出ないときっていうのの条件、わても分かんないです(汗)。いきなり出なくなることあるし、インテリセンス機能が効く「範囲」がどうも分からないし。読み込んでいるヘッダーファイルってわけでもないみたいなんですよねー。とりあえずクラステンプレートのメンバは表示されないみたいです。 STL 使いとしてはちょっと悲しい(泣)。
 
・ちなみにこういう質問好き(爆)。答えてて楽しいかもしんない。ネットワークとかデータベースとか来たら、もーけんもほろろモードになっちゃいますよ……。
 
・でわまたっ!
透明1ドットイメージ
 
2000/09/08 (Fri)
・ここ最近お便り多くてうれしいです〜。では今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは。  
 あのう、1 月号(?)の K-ta さんの質問とソックリで申し訳ないんですが、よろしければ教えてやっていただけませんでしょうか。
 
 今、特定のアプリケーションを起動させないようにする常駐プログラムを書いています。とりあえずは何も起動させないプログラムを作ってみようと、以下のようなフックプロシージャを書いてみたのですが、うまくいかないんです。
 
LRESULT CALLBACK CHook::CallWndProc
    (int nCode, WPARAM wParam, LPARAM lParam)
{
    if( nCode < 0 ){
        return ::CallNextHookEx( m_hHook, nCode, wParam, lParam );
    }

    if( ((CWPSTRUCT*)lParam)->message == WM_CREATE ){
            ((CWPSTRUCT*)lParam)->message = WM_NULL;
    }
    return ::CallNextHookEx( m_hHook, nCode, wParam, lParam );
}
	
 
 CallWndProc ではダメなのかと思い、GetMsgProc でやってみても同じでした。
 どこがいけないんでしょうか ?
透明1ドットイメージ
透明1ドットイメージ
 
・どうもですー。とりあえず気になった点がいくつか。まず、 CallWndProc() はちょっと無理です。 MSDN の CallWndProc() のページにも書いてあるけど、このフックプロシージャではメッセージの修正ができないんです。だから他の種類のフックにしないと。あと、 GetMsgProc() は、 MSDN によると「メッセージキュー」にあるものしか拾えないんで、 WM_CREATE は拾えないのかもしんない。
 
・実は、ウィンドウの生成を検出するフックがあるんです。 SetWindowsHook() に WH_CBT 渡してセットするフック( CBTProc() がそのフックプロシージャ )がそれです。これだと「処理の中断」が簡単にできるっぽいんで、これを使うのが一番いいんじゃないかなと思います。試したことはないけど(汗)。
 
・あと、理論上はフック掛けなくても実現できるかも。「特定のアプリ」の判断がウィンドウクラスとかなら、タイマーで定期的に全ウィンドウをチェックして、「特定のアプリ」のウィンドウがあったら WM_CLOSE 送る、とかっていう方法も。あ、でもこれじゃちょっとだけウィンドウが表示されちゃうからダメか。
 
・でわまたっ!
透明1ドットイメージ
 
2000/09/09 (Sat)
・今日はお休み〜。
透明1ドットイメージ
 
2000/09/10 (Sun)
・今日もお休みだす。
透明1ドットイメージ
 
2000/09/11 (Mon)
・まずはお知らせから。明日から15日(金)夕方までゼミ合宿に行ってくるんで、明日から14日の分まで、この日記はお休みします。お便り送られても返事できないからご注意。では今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは。先日フックについて質問した者です。
 
 CBTProc を使ったらできました ! ありがとうございました。
 
 そしてまた質問なんですけど・・・スミマセン。
 
 今度は特定のアプリケーション(ここでは Internet Explorer)を起動させないようにしようとしたのですが、うまくいかないんです。以下がコードです。
 
const CString strIE = "IEXPLORE.EXE";

LRESULT CALLBACK CIEHook::CBTProc
    (int nCode, WPARAM wParam, LPARAM lParam)
{
    if( nCode < 0 ){
        return ::CallNextHookEx( m_hHook, nCode, wParam, lParam );
    }

    if( nCode == HCBT_CREATEWND ){
        CBT_CREATEWND* pCbtCW = (CBT_CREATEWND*)lParam;
        HMODULE hMod = (HMODULE)(pCbtCW->lpcs->hInstance);
        char szExePath[MAX_PATH];
        ::ZeroMemory(szExePath, sizeof(szExePath));
        ::GetModuleFileName(hMod, szExePath, MAX_PATH);
        CString strExe(szExePath);
        if( strExe.Right(strIE.GetLength()) == strIE ){
            return 1;
        }
    }

    return ::CallNextHookEx( m_hHook, nCode, wParam, lParam );
}
	
 
 ゴチャゴチャしてますけど、モジュールハンドルからパスを取ってきて、EXE 名を判定してます。これで IE であることは判定できているようなのですが、IE が起動してしまうんです。(CBTProc のヘルプによると、0 以外の値を返すとウインドウが破棄されるそうです。)なぜでしょうか・・・。
 
 ちなみに IE の判定をなくして、ただ 0 以外の値を返すと、何も起動されなくなります。
透明1ドットイメージ
透明1ドットイメージ
 
・この前のうまくいったみたいですね、良かったです。さて今回の件だけど、環境によるかもしれないんだけど、うちの Win98 + IE4 だと、 IEXPLORE.EXE が起動しなかったです。 Spy++ とかで見てみると、 IE のプロセスは EXPLORER.EXE 、つまりフォルダやエクスプローラーと同じみたいです。
 
・なんで、 判別はクラス名でした方がいいかも。 IE のクラス名は IEFrame 、フォルダのクラス名は CabinetWClass 、エクスプローラーのクラス名は ExploreWClass なんで。でも IEFrame って、なんかよく使われてそうな気もするなー(汗)。ウィンドウ名に「 - Microsoft Internet Explorer」が入っているかどうかも調べるといいかも。ちなみにウィンドウ名の最後に[オフライン作業]とか付くことあるから注意。
 
・あといくつか気になったこと。 CString の == 演算子は大文字小文字の区別をするから、上の例だとうまくいかない場合とかありそう。区別しない場合には CString::CompareNoCase() を使った方がいいかもしんない。これを使う場合には、一致したときに0が返ってくるから注意。 あと、最後の CallNextHookEx() って呼ぶべきなのかなー、戻り値の意味が他のフックプロシージャと違うからなぁ。これはどうすべきか、わてにも分からないです。
 
・ちなみに、今回の追試をするときに、うっかり TRACE() を使ってはまってしまった(汗)。 TRACE() って、システムフックのときには働かないんですよね。なんで「なぜにローカルフックになるのー?」と迷ってしまった。 MessageBox() 使ったり、ファイルに書き込むのが楽かもしんない。ファイルの方は同期処理とか大変か。テスト中、死ぬほどフリーズしまくって10回は強制リセットしたし、システムフックのデバッグは大変です……。はっ、ってゆーか Win2000 ならこーゆーことならんのか?(汗)
 
・でわまたっ!
透明1ドットイメージ
 
2000/09/12 - 14 (Tue - Thu)
作者ゼミ合宿のため休載
透明1ドットイメージ
 
2000/09/15 (Fri)
・ただいまー。さて、ちょっと質問があったんで、 STL & iostream 入門の再放送についてアナウンスします。
 
・まず、今行ってる本放送は、今月27日に最終回を迎えます。で、そのまま何事もなく、10月4日(水)に #01 が配信されます(爆)。つまり今、本放送を購読登録している方で、10月から再放送も読みたいという方は、購読登録を解除せずにそのままのんびり待っていれば、ちゃんと再放送も送られてくる、ということになります。
 
・再放送の内容は、広告部分を除いてほぼ本放送と同じ。ただ、再放送はまぐまぐさんの方にバックナンバーとして残しておきます。なんで、再放送についてはそんなに神経をとがらせなくてもOK。また、時間的余裕があれば、ホームページ化していくつもり。イラスト入りにしたりするから、さらに分かりやすくなるはず。
 
・でわまたっ!
 
 
(C)KAB-studio 2000 ALL RIGHTS RESERVED.