Windows programming (8) - Win32 API -			2001.May

1. 最初のWin32 API
 さて。Windowsらしい動きをするプログラムを1つ。MessageBox() APIです。
 こいつは結構、機能豊富なので色々試すとおもしろいです。

#include <windows.h>
 
int main(void)
{
    MessageBox(NULL, "Console", "1st Win32", 0);
    return 0;
}

 で、こいつにはちょっと問題あります。気付きました?
 そう。実行するとDOS窓が必ず出るんですね。出ないようにするには:

#include <windows.h>
 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow)
{
    MessageBox(NULL, "Windows", "2nd Win32", 0);
    return 0;
}

 って、ちゃんとコンパイルやリンクできました?
 リンクする時にGUIだぞ。という指定しないとダメっすよ?

 そうです。コンソールプログラムの場合はANSI Cな書き方そのままなんですが、
 GUIプログラムの場合はちょっと変えないとだめなんですね。

 main()がある場合、コンソールプログラム。
 WinMain()がある場合、GUIプログラム。

 というようにソース(リンクオプションも)を変える必要があるんです。

 #glutとか使う場合はmain()があるGUIプログラムとしてリンクするんだけど、
  そーゆーのは特例
 #UNICODE版の場合、更にちょっと違うけど、あっしん家にはNT/2K/CEはないんで
   パス

 さて。GUI版の引数ですが……。
 hInstance	: 実行ファイルへの手がかり。ただしここで出した程度のプログラム
		 では無用の長物
 hPrevInstance	: 自分自身が複数起動していた時、より以前に実行してた奴への
		 手がかり。なんだけど、それはWin16での話。Win32では意味なし。
		 常にNULL。
 lpCmdLine	: コマンドラインの引数。でもね、_argc/_argvとかも使えたり
		 するんだよね(処理系によっては__argc/__argvの場合も……)
 nCmdShow	: アイコン状態で起動しろ、とか、最大化で起動しろ。とかOSが
		 指示してくる。でも、とりあえず無視してOKOK

 このプログラム、APIの動作確認とか色々するのに便利なので、雛形として
 とっておいて使い回すと便利よ。ちなみに。

 例えばこんなん作ってみたりとか。

#include <windows.h>
#include <process.h>
 
#define TITLE "thread"
#define WAITTIME 5  // sec
 
void thread(void* arg)
{
    MessageBox(NULL, "hoge", arg, 0);
    _endthread();
}
 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow)
{
    HWND hWnd;
 
    _beginthread(thread, 0, TITLE);
 
    Sleep(WAITTIME * 1000);
    hWnd = FindWindow("#32770", TITLE);
    if (hWnd!=NULL) SendMessage(hWnd, IDCANCEL, 0, 0);
    return 0;
}
 
/* eof */

 って、5秒で自動的に消えるMessageBox()ちゃんですぅ(はーと)

 #「(はーと)」はやめろ。気色悪いから>わし

 いや、説明読んでもいまいちなAPIはこーやって試すのが吉。っちゅー訳ですよ。

 後、APIENTRYってのは、WinMain()への引数の渡し方とか、関数呼び出しの作法を
 指定するものだけど、当面はそういうもんだと思って*黙って書く*で良いと思うぞ。

 う〜む。BC++の場合、コンパイル時に-D__MT__として、マルチスレッド関数を有効に
 しないとダメですね。
 それとリンク時もマルチスレッドライブラリをリンクしないとダメ。

 あっしの作ったcc.batのユーザだったら、こうすればOK
 cc -O -D__MT__ thread -w cw32mti.lib

 #う〜む。cc.batのbccんとこ、デフォルトでマルチスレッドにすべきかな?

 ちなみに「#32770」ってのは、クラスを指定してないダイアログのデフォルトの
 値のようです。「$Generic_Dialog」とかにして欲しかった。とか思うのは私だけ?

(EOF)