今年も残すところあと一ヶ月になってしまいました。
ラス1! 早いです。 光陰矢のごとしです。
なんと言いますか、なにもしないまま今年も終わっていくという思いしかありません。
ただ今年は新たにこのブログを始めたことで、もっと早くからブログやっていればよかったなという思いが沸いてきたので更になにか新たなことにトライしてみるのもいいかなと思っています。
今年も残すところあと一ヶ月になってしまいました。
ラス1! 早いです。 光陰矢のごとしです。
なんと言いますか、なにもしないまま今年も終わっていくという思いしかありません。
ただ今年は新たにこのブログを始めたことで、もっと早くからブログやっていればよかったなという思いが沸いてきたので更になにか新たなことにトライしてみるのもいいかなと思っています。
わたしは携帯電話を持ったことがないので携帯のあの小っこい窓からサイトを見てなにが面白いのかすごく不思議というか使いづらいだろうなとしか思わないんですよね。
そんなわたしですが以前に携帯サイトを作る羽目になったことがあってそのときは表示確認用に渡された携帯の操作がさっぱりわからなくて面倒な操作説明書読むところから苦労しましたよ。。。
それでサイト作りのときは携帯各社のブラウザ仕様のあまりの違いに打ちのめされました。
まず使えるタグが各社独自のHTML仕様やらで大変な目に遭ったのをうっすらと覚えています。(嫌な記憶なので脳が記憶を隔離してる?)
画像もほとんど使えなかったし1ページの文字数制限もきつかったなぁ。。
クッキーとJavaScriptはNG。文字コードはシフトJISというのは各社共通ではっきり決まってたのでこういうのは却って楽な要素だったと思います。
で、久しぶりに携帯サイト開発の現状がどうなってるのか見てみたら以前よりはマシになってるような感じでした。
現状の主流は「XHTML Mobile Profile 1.0」という仕様のタグを使うのが無難なようです。
<table>タグは今も使わないほうがいいようですね。つまり背景色などはCSSで行うことになります。
画像に関しては「gif」と「jpg」なら最近の機種は対応してるということらしい。。
クッキーとJavaScriptは使える機種も少しだけ出ているようではあるけどこれじゃ使うメリットがない。
最近の携帯サイトにはQRコードがかなり広まっているらしい。
ついでにRSSも完備できているほうがいいらしい。
そうそう携帯と言えば絵文字ね。絵文字に割り当てられた文字コードがまた携帯各社でバラバラでひどい目に遭った記憶がよみがえってきた。
もう携帯電話は見るのも嫌だ。悪夢を見そうで嫌だ!
たまにはMinGWもやらねばということで、
MinGWは「#include <windows.h>」とやるだけで「Win32API」を使えるように作られているので、プログラミングの情報は豊富にあります。
「Win32API 入門 」などのキーワードで検索すれば解説ページがたくさんヒットします。
と、、、知った風に書いてしまいましたが実はWin32API等を使ったウィンドウズソフト作成はあまりやったことがないので私自身もっと勉強しないといけません。
ただ、豊富なAPI群が用意されているのでパズルのように組み合わせればそう難しくなさそうなのがウィンドウズプログラムといった感じです。
ウィンドウを伴うプログラムでは、コンパイル時に-mwindowsオプションを付けないと以下のようなリンケージエラーが出ますのでご注意を。
■リソースを使ったメニュー作成(menu.rc)
メニューバー作成方法は前回書きましたが、もっと分かり易そうなものをコチラ で見つけましたので今回はこの方法を利用して書きます。
}
POPUP "編集" {
MENUITEM "切り取り" , 40007
MENUITEM "コピー" , 40008
MENUITEM "貼り付け" , 40009
}
POPUP "表\示" {
MENUITEM "ツールバー" , 40010
MENUITEM SEPARATOR
MENUITEM "ソース" , 40011
}
POPUP "ヘルプ" {
MENUITEM "ヘルプ" , 40012
MENUITEM SEPARATOR
MENUITEM "バージョン情報" , 40013
}
}
上記リソースの「WIN_MENU」という部分を、次に挙げるwin.cソースコードのLoadMenu()関数の第2引数と合わせることで取り込まれるようになります。
■メイン処理(win.c)
VisualC++で動作確認されたコチラ のWin32API解説ページを参考にちょっとだけメニュー部分を改変して書いてみました。
// 定数
#define WINDOW_WIDTH (400) // ウィンドウの幅
#define WINDOW_HEIGHT (300) // ウィンドウの高さ
#define WINDOW_X ((GetSystemMetrics( SM_CXSCREEN ) - WINDOW_WIDTH ) / 2)
#define WINDOW_Y ((GetSystemMetrics( SM_CYSCREEN ) - WINDOW_HEIGHT ) / 2)
// プロトタイプ宣言
HWND Create(HINSTANCE hInst);
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
// 開始位置
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd)
{
HWND hWnd;
MSG msg;
// ウィンドウを作成する
hWnd = Create( hInst );
if( hWnd == NULL )
{
MessageBox( NULL, _T("ウィンドウの作成に失敗しました"), _T("エラー"), MB_OK );
return 1;
}
// ウィンドウを表示する
ShowWindow( hWnd, SW_SHOW );
UpdateWindow( hWnd );
// メッセージループ
while( 1 )
{
BOOL ret = GetMessage( &msg, NULL, 0, 0 ); // メッセージを取得する
if( ret == 0 || ret == -1 )
{
// アプリケーションを終了させるメッセージが来ていたら、
// あるいは GetMessage() が失敗したら( -1 が返されたら )、ループを抜ける
break;
}
else
{
// メッセージを処理する
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
return 0;
}
// ウィンドウを作成する
HWND Create(HINSTANCE hInst)
{
WNDCLASSEX wc;
// ウィンドウクラスの情報を設定
wc.cbSize = sizeof(wc); // 構造体サイズ
wc.style = CS_HREDRAW | CS_VREDRAW; // スタイル
wc.lpfnWndProc = WndProc; // ウィンドウプロシージャ
wc.cbClsExtra = 0; // 拡張情報1
wc.cbWndExtra = 0; // 拡張情報2
wc.hInstance = hInst; // インスタンスハンドル
wc.hIcon = (HICON)LoadImage( // アイコン
NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON,
0, 0, LR_DEFAULTSIZE | LR_SHARED
);
wc.hIconSm = wc.hIcon; // 子アイコン
wc.hCursor = (HCURSOR)LoadImage( // マウスカーソル
NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR,
0, 0, LR_DEFAULTSIZE | LR_SHARED
);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // ウィンドウ背景
wc.lpszMenuName = NULL; // メニュー名
wc.lpszClassName = _T("Default Class Name");// ウィンドウクラス名
// ウィンドウクラスを登録する
if( RegisterClassEx( &wc ) == 0 ){ return NULL; }
// ウィンドウを作成する
return CreateWindow(
wc.lpszClassName, // ウィンドウクラス名
_T("Sample Program"), // タイトルバーに表示する文字列
WS_OVERLAPPEDWINDOW, // ウィンドウの種類
WINDOW_X, // ウィンドウを表示する位置(X座標)
WINDOW_Y, // ウィンドウを表示する位置(Y座標)
WINDOW_WIDTH, // ウィンドウの幅
WINDOW_HEIGHT, // ウィンドウの高さ
NULL, // 親ウィンドウのウィンドウハンドル
NULL, // メニューハンドル
hInst, // インスタンスハンドル
NULL // その他の作成データ
);
}
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
static HMENU hMenu;
int wmId;
switch( msg )
{
case WM_CREATE: // ウィンドウが作られたとき
// メニューリソースをロードする
hMenu = LoadMenu( NULL, _T("WIN_MENU") );
// ウィンドウにメニューリソースを割り当てる
SetMenu( hWnd, hMenu );
return 0;
case WM_COMMAND:
wmId= LOWORD(wp);
switch (wmId){
case 40006: DestroyWindow(hWnd);
break;
default: ;
}
break;
case WM_CLOSE: // ウィンドウが閉じられるとき
// ウィンドウからメニューバーを削除
SetMenu( hWnd, NULL );
// メニューバーリソースを破棄する
DestroyMenu( hMenu );
hMenu = NULL;
break; // ウィンドウを閉じる処理はDefWindowProc()に任せる
case WM_DESTROY: // ウィンドウが破棄されるとき
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, msg, wp, lp );
}
■Makefile作成
Makefileを使わずに、先にリソースをオブジェクトファイルに(リソースコンパイラとCのコンパイラは別なので)して、
% windres menu.rc menu.o
最終的にCのソースをオブジェクトファイルにしたものと先のオブジェクトファイルをリンクさせて実行ファイルを作り出すということを手打ちですることもできます。
% gcc win.c menu.o -mwindows -o win.exe
が、もっと大規模になることを見据えてMakefileを作って
% make
で済ませるようにしておくことは意義があります。
%.o: %.c
$(CC) $(CFLAGS) -o $@ -c $<
.PHONY : all
all: $(PROG)
$(PROG): $(OBJS) $(WINDRES)
$(CC) $(OBJS) $(WINDRES) $(LDFLAGS) -o $@
$(WINDRES): $(RC)
windres $(RC) $(WINDRES)
.PHONY : clean
clean:
$(RM) $(OBJS) $(WINDRES)
■コンパイル作業
DOS窓を起動させて、「make」または「make all」と打ち込みコンパイル実行させます。
C:\Users\Administrator\Desktop\cwin>make
gcc -Wall -O3 -o win.o -c win.c
gcc win.o menu.o -mwindows -o win.exe
C:\Users\Administrator\Desktop\cwin>
■ウィンドウ画像
今回は前回と比べて扱うファイル数も少なく済んでスッキリした感じになりました。