2007年6月20日水曜日

ウィンドウの生成

ウィンドウを作る手順。
1、WNDCLASSEX構造体にデータを設定する
2、RegisterClassEx関数でクラスを登録する
3、CreateWindowEx関数でウィンドウを生成

CreateWindowEx関数でRegisterClassEx関数で登録した
WNDCLASSEX構造体の情報をもとにウィンドウを生成します

CreateWindowEx関数
http://msdn2.microsoft.com/en-us/library/aa930455.aspx

HWND CreateWindowEx( //戻り値 ウィンドウハンドル
DWORD dwExStyle, // ウィンドウの拡張スタイル
LPCTSTR lpClassName, // 生成するウィンドウクラスの名前
LPCTSTR lpWindowName, // ウィンドウの名前(タイトルバーに表示されます)
DWORD dwStyle, // ウィンドウスタイル
int x, // ウィンドウを表示する X座標
int y, // ウィンドウを表示する Y座標
int nWidth, // ウィンドウの幅
int nHeight, // ウィンドウの高さ
HWND hWndParent, // 親ウィンドウハンドル
HMENU hMenu, // メニューハンドル
HINSTANCE hInstance, // 実行exeのインスタンスハンドル
LPVOID lpParam // 生成時のメッセージで渡す引数
);

CreateWindowEx関数のリンク先に
拡張スタイルとスタイルの渡すべき値(Define定義されているもの)の一覧が
載っていますのでそれを参考にしてスタイルを指定します

次回簡単な例でものっけよ

仮想関数(virtual)

テストプログラム作成したので貼り付けとこっと
C++のメンバメソッドにvirtual付けたときと付けない時の動作確認
C言語には無い概念…これめっちゃ便利やね。
一応関数ポインタを使えばC言語でも作れるんやけどめんどい!

--------------

#include

class Base {
public:
Base(){};
virtual ~Base(){};
void print();
virtual void vprint();
};

void Base::print()
{
printf("Base printf \n");
}
void Base::vprint()
{
printf("Base virtual printf \n");
}

class Foo :public Base {
public:
Foo(){};
virtual ~Foo(){};
void print();
virtual void vprint();
};

void Foo::print()
{
printf("Foo printf \n");
}
void Foo::vprint()
{
printf("Foo virtual printf \n");
}

int main (void) {
Foo* instanceFoo = new Foo();
Base* instanceBase = (Base*)instanceFoo;
printf("instance Foo\n");
instanceFoo->print();
instanceFoo->vprint();
printf("instance Base\n");
instanceBase->print();
instanceBase->vprint();
return 0;
}

--------------

2007年6月14日木曜日

ウィンドウクラスの登録

ウィンドウを作る手順。
1、WNDCLASSEX構造体にデータを設定する
2、RegisterClassEx関数でクラスを登録する
3、CreateWindowEx関数でウィンドウを生成

今回は
2、RegisterClassEx関数でクラスを登録する
です

RegisterClassEx関数について
http://msdn2.microsoft.com/en-us/library/ms633587.aspx
ATOM RegisterClassEx(
CONST WNDCLASSEX *lpwcx // ウィンドウクラスのポインタ
);
RegisterClassExに登録する前に WNDCLASSEX の各値を設定しておかないと
失敗する。戻り値に0(ゼロ)が戻ってきた時が失敗した時である
その場合は WNDCLASSEX で設定したウィンドウを生成することが出来ない

RegisterClassExで登録した WNDCLASSEX のデータは
アプリケーションを終了するまで削除されない

よって一度登録しておくと、登録したWNDCLASSEXのデータで
何度もウィンドウを生成することができる

完全なメモになってしまったや
まっいいかw

2007年6月13日水曜日

実行ファイルパス取得(C言語)

過去の投稿で.NETでの実行ファイルパスの取得方法を記述しました
http://mzs184.blogspot.com/2007/02/blog-post_21.html
今回はC言語での実行ファイルパスを取得する方法を紹介します。

といってもいたって単純です
main 関数の引数として渡ってきているのそれを取り出すだけです
----
int main (int argc, char* argv[]);
----
argv[0] に実行ファイルパス(絶対パス)が格納されています

main関数の args, argv については別のサイトで詳しく調べて下さい
面倒だーって人は以下のソースをコンパイルして出来上がった exe に
ファイルをドロップしたりコマンドプロンプトで引数をつけて実行してみてください
いろいろわかるでしょう。
-----
#include <stdio.h>

int main (int argc, char* argv[]) {
int i = 0;
for (i = 0; i < argc;++i) {
printf("%s\n", argv[i]);
}
printf("press any key");
getchar();
return (1);
}

----

今日はwinapiはちょっと休憩^^;

2007年6月10日日曜日

ウィンドウを生成するのに必要な構造体(WNDCLASSEX)

ウィンドウを作る手順。
1、WNDCLASSEX構造体にデータを設定する
2、RegisterClassEx関数でクラスを登録する
3、CreateWindowEx関数でウィンドウを生成
こんだけw

今回は「1、WNDCLASSEX構造体にデータを設定する」の構造体について知る
MSDNを参照(http://msdn2.microsoft.com/en-us/library/ms633577.aspx)

英語で書いてあるのを訳せば終わりなんやけどね~。
ちょこっと記述してみた。
typedef struct {
UINT cbSize; //クラスのサイズを設定WNDCLASSとを識別するために必要
UINT style; // ウィンドウのスタイルを設定
WNDPROC lpfnWndProc; //メッセージを処理する関数を登録する
int cbClsExtra; // この構造体に付加する領域のbyteサイズ
int cbWndExtra; // ウィンドウのインスタンスに付加する領域のbyteサイズ
HINSTANCE hInstance; // 実行ファイルのインスタンスハンドル
HICON hIcon; // ウィンドウのアイコンのハンドル
HCURSOR hCursor; // ウィンドウ内のマウスカーソルのハンドル
HBRUSH hbrBackground; // ウィンドウ領域の背景色を塗りつぶすブラシのハンドル
LPCTSTR lpszMenuName; // ウィンドウに表示するメニューの名前
LPCTSTR lpszClassName; // ウィンドクラスの名前、生成する時に使う
HICON hIconSm; // 小さいアイコン
} WNDCLASSEX

ん~ハンドルが沢山あるな…
おいおい詳しくわかってくるやろ

2007年6月8日金曜日

WinMainのWINAPIというおまじないについて

前回の投稿(http://mzs184.blogspot.com/2007/06/mainwinmain.html)で

int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow);

のWINAPIってなんなんやろ~って疑問として残ってましたが、
windef.h内で以下のように定義されていました。

#define WINAPI __stdcall

__stdcallってなんやねん!って調べてたら。
関数の呼び出し規約とかいうものらしい

ここがすごいわかりやすかったので紹介
http://arton.no-ip.info/collabo/backyard/?StdDeclCDecl
-----紹介したサイトの抜粋です
__stdcallは、WIN32 APIの呼び出し規約で、スタックの解放を呼ばれた側が行い(したがって、varargは使用不可)、__cdeclは、スタックの解放を呼ぶ側が行う(したがって、varargを使用可能)。
----
実際にアセンブリコードとの混合モードで解説してあるので
すんごいわかりやすかった!

WINAPIというおまじないはこれで解決っと

2007年6月5日火曜日

mainじゃなくてWinMainなんやね!

仕事で.NET2.0を使ってるんですが、
もうちょと詳しくウィンドウアプリケーションを知っておこうと
C言語にてwindowを作ってみる。
もちろんコンパイラはMinGWのgccコンパイラです。
過去の日記でインストールした時にwinapi関連のライブラリも
インストールできているのでそのまま使います。

で…ネットを検索しまくって
こんなヘッダーをインクルードして。
#include <windows.h>

こんな関数がエントリーポイントになっていると知る。
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow);

そして、意味不明な大文字の型が…
WINAPI 良くわかりません。とりあえずおまじないと思って書いておく
HINSTANCE:void*をtypedefしたやつやった。
     「インスタンスハンドル」やねんて
PSTR:strっていうぐらいやから文字列の型「wchar*」or「char*」をtypedefしたもの
   UNICODEを使えるか使えないかで場合分けしてある

んで各引数の説明
HINSTANCE hInstance
:実行したプログラムを識別するためのもの

HINSTANCE hPrevInstance
:すんごい昔に多重起動を確認するために使われていた今はNULLしか入ってこない

PSTR szCmdLine
:コマンドラインで実行した時の引数、今までも同じものあったからこれは大丈夫かな

int iCmdShow
:ウィンドウの初期表示方法です ウィンドウを生成する時に使うそうな…


以下のコードを書いて簡単に呼び出してみた
メッセージボックスが表示されておしまい。
-------
#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
MessageBox (NULL, TEXT("text"), TEXT("caption"), MB_OK);
return 0;
}

-------

TEXT()はマクロでUNICODE対応の場合は文字列の先頭に「L」を付ける

例TEXT("text")
 ⇒UNICODE対応 ⇒ L"text"
 ⇒UNICODE非対応 ⇒ "text"

まだウィンドウは作成できず…

2007年6月4日月曜日

ゴミ箱のパス

ゴミ箱のファイルパスを探してこられるかたが多いようなので
調べてみた。

ごみ箱は以下フォルダ内にありました
C:\RECYCLER

但しシステムファイルを表示するように設定していないと目視で確認できません。

WindowsXP Homeの環境です
システムファイルの表示方法は
「ツール」「フォルダオプション」の表示タブで
「保護されたオペレーティングシステムファイルを表示しない(推奨)」と
「すべてのファイルとフォルダを表示する」の二つにチェックを入れる
これでシステムのファイルかつ隠しフォルダであるC:\RECYCLER
を目で確認できると思います。

2007年6月1日金曜日

フォルダをダブルクリックすると検索ウィンドウが開くように…

フォルダオプションを弄ってたら
フォルダをダブルクリックすると検索ウィンドウが開くように…
右クリックから「開く」ではちゃんとフォルダを開いてくれるのに!!

ってことで調べてみた。
レジストリを弄らないと直らないみたいorz
レジストリを触ると何が起こるかわからないので自己責任のもとで触ってください。

「ファイル名を指定して実行」 から regedit を起動
・HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell
・(既定) を右クリック「修正」でデータに none と記入して「OK」をクリックします

同じようにドライバをダブルクリックで検索ウィンドウが開く場合は
フォルダの場合と同じように
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Drive\shellの(既定)のデータを none に修正します

ラベル