#1
by yaya » 4年前
mingw 付属の C コンパイラである gcc で
ウィンドウを表示し、時間の経過と共に線が伸びていくようなアニメーションっぽい
動きを描画したいと考えています。
定期で発生する Windows メッセージを見つける事ができず
switch 文の default の部分に X 座標を増やすような処理を
追記しました。
この状態でウィンドウの上でマウスカーソルを動かすと
Windows メッセージが発生してくれるようで、
線が伸びて描画されます。
しかし希望する動作としては、マウスカーソルを動かさなくても
X 座標が増え、線が伸びてほしいです。
どの部分を修正すべきでしょうか?
コード:
/*
マウスカーソルをカチャカチャ動かすと線が伸びる (2)
windres menu.rc menu.o
gcc window.c menu.o -mwindows -o menu.exe
*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;
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 = LoadIcon(NULL, IDI_APPLICATION); // アイコン
wc.hIconSm = wc.hIcon; // 子アイコン
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // マスカーソル
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // ウィンドウ背景
wc.lpszMenuName = NULL; // メニュー名
wc.lpszClassName = "fooWindowClass"; // ウィンドウクラス名
if(RegisterClassEx(&wc) == 0){ return 1; }
hWnd = CreateWindow(
wc.lpszClassName, // ウィンドウクラス名
"Sample Window", // タイトルバーに表示する文字列
WS_OVERLAPPEDWINDOW, // ウィンドウの種類
CW_USEDEFAULT, // ウィンドウを表示するX座標
CW_USEDEFAULT, // ウィンドウを表示するY座標
CW_USEDEFAULT, // ウィンドウ幅
CW_USEDEFAULT, // ウィンドウ高さ
NULL, // 親ウィンドウのウィンドウハンドル
NULL, // メニューハンドル
hInst, // インスタンスハンドル
NULL // その他の作成データ
);
if(hWnd == NULL){ return 1; }
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while(1) {
BOOL ret = GetMessage(&msg, NULL, 0, 0);
if(ret == 0 || ret == -1) {
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
static HMENU hMenu;
int wmId;
HDC hdc; // added
PAINTSTRUCT ps; // added
static int cnt=0;
static unsigned short int x = 0 , y = 0;
switch(msg) {
case WM_CREATE: // ウィンドウが作成されたら
hMenu = LoadMenu(NULL, "WIN_MENU"); // メニューリソースをロード
SetMenu(hWnd, hMenu); // ウィンドウにメニューリソース割り当て
return 0;
case WM_COMMAND: // メニューが選択されたら
wmId = LOWORD(wp);
switch (wmId) {
case 40001: MessageBox(NULL, "開く", "メッセージ", MB_OK);
break;
case 40002: MessageBox(NULL, "保存", "メッセージ", MB_OK);
break;
case 40003: DestroyWindow(hWnd); // 終了
break;
case 40004: MessageBox(NULL, "切り取り", "メッセージ", MB_OK);
break;
case 40005: MessageBox(NULL, "コピー", "メッセージ", MB_OK);
break;
case 40006: MessageBox(NULL, "貼\り付け", "メッセージ", MB_OK);
break;
case 40007: MessageBox(NULL, "ツールバー", "メッセージ", MB_OK);
break;
case 40008: MessageBox(NULL, "イ", "メッセージ", MB_OK);
break;
case 40009: MessageBox(NULL, "ロ", "メッセージ", MB_OK);
break;
case 40010: MessageBox(NULL, "ハ", "メッセージ", MB_OK);
break;
case 40011: MessageBox(NULL, "ソ\ース", "メッセージ", MB_OK);
break;
case 40012: MessageBox(NULL, "ヘルプ", "メッセージ", MB_OK);
break;
case 40013: MessageBox(NULL, "ver1.00", "バージョン情報", MB_OK);
break;
}
break;
case WM_CLOSE: // ウィンドウが閉じられるとき
SetMenu(hWnd, NULL); // ウィンドウからメニュー削除
DestroyMenu(hMenu); // メニューバーリソース破棄
hMenu = NULL;
break; // ウィンドウを閉じる処理はDefWindowProc()に任せる
case WM_DESTROY: // ウィンドウが破棄されたら
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
MoveToEx(hdc, 50, 50, NULL); // (50, 50) まで移動
LineTo(hdc, x,50);
EndPaint(hWnd, &ps);
return 0;
case WM_LBUTTONDOWN:
return 0;
default:
if(cnt==20)
{
x=x+10;
InvalidateRect(hWnd , NULL , TRUE);
cnt=0;
}
cnt++;
}
return DefWindowProc(hWnd, msg, wp, lp);
}
menu.rc
コード:
WIN_MENU MENU{
POPUP "ファイル"{
MENUITEM "開く", 40001
MENUITEM SEPARATOR
MENUITEM "保存", 40002
MENUITEM SEPARATOR
MENUITEM "終了", 40003
}
POPUP "編集"{
MENUITEM "切り取り", 40004
MENUITEM "コピー", 40005
MENUITEM "貼\り付け", 40006
}
POPUP "表\示"{
MENUITEM "ツールバー", 40007
MENUITEM SEPARATOR
POPUP"サブメニュー"{
MENUITEM "「イ」を表\示", 40008
MENUITEM "「ロ」を表\示", 40009
MENUITEM "「ハ」を表\示", 40010
}
MENUITEM "ソ\ース", 40011
}
POPUP "ヘルプ"{
MENUITEM "ヘルプ", 40012
MENUITEM SEPARATOR
MENUITEM "バージョン情報", 40013
}
}
mingw 付属の C コンパイラである gcc で
ウィンドウを表示し、時間の経過と共に線が伸びていくようなアニメーションっぽい
動きを描画したいと考えています。
定期で発生する Windows メッセージを見つける事ができず
switch 文の default の部分に X 座標を増やすような処理を
追記しました。
この状態でウィンドウの上でマウスカーソルを動かすと
Windows メッセージが発生してくれるようで、
線が伸びて描画されます。
しかし希望する動作としては、マウスカーソルを動かさなくても
X 座標が増え、線が伸びてほしいです。
どの部分を修正すべきでしょうか?
[code]
/*
マウスカーソルをカチャカチャ動かすと線が伸びる (2)
windres menu.rc menu.o
gcc window.c menu.o -mwindows -o menu.exe
*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;
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 = LoadIcon(NULL, IDI_APPLICATION); // アイコン
wc.hIconSm = wc.hIcon; // 子アイコン
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // マスカーソル
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // ウィンドウ背景
wc.lpszMenuName = NULL; // メニュー名
wc.lpszClassName = "fooWindowClass"; // ウィンドウクラス名
if(RegisterClassEx(&wc) == 0){ return 1; }
hWnd = CreateWindow(
wc.lpszClassName, // ウィンドウクラス名
"Sample Window", // タイトルバーに表示する文字列
WS_OVERLAPPEDWINDOW, // ウィンドウの種類
CW_USEDEFAULT, // ウィンドウを表示するX座標
CW_USEDEFAULT, // ウィンドウを表示するY座標
CW_USEDEFAULT, // ウィンドウ幅
CW_USEDEFAULT, // ウィンドウ高さ
NULL, // 親ウィンドウのウィンドウハンドル
NULL, // メニューハンドル
hInst, // インスタンスハンドル
NULL // その他の作成データ
);
if(hWnd == NULL){ return 1; }
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while(1) {
BOOL ret = GetMessage(&msg, NULL, 0, 0);
if(ret == 0 || ret == -1) {
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
static HMENU hMenu;
int wmId;
HDC hdc; // added
PAINTSTRUCT ps; // added
static int cnt=0;
static unsigned short int x = 0 , y = 0;
switch(msg) {
case WM_CREATE: // ウィンドウが作成されたら
hMenu = LoadMenu(NULL, "WIN_MENU"); // メニューリソースをロード
SetMenu(hWnd, hMenu); // ウィンドウにメニューリソース割り当て
return 0;
case WM_COMMAND: // メニューが選択されたら
wmId = LOWORD(wp);
switch (wmId) {
case 40001: MessageBox(NULL, "開く", "メッセージ", MB_OK);
break;
case 40002: MessageBox(NULL, "保存", "メッセージ", MB_OK);
break;
case 40003: DestroyWindow(hWnd); // 終了
break;
case 40004: MessageBox(NULL, "切り取り", "メッセージ", MB_OK);
break;
case 40005: MessageBox(NULL, "コピー", "メッセージ", MB_OK);
break;
case 40006: MessageBox(NULL, "貼\り付け", "メッセージ", MB_OK);
break;
case 40007: MessageBox(NULL, "ツールバー", "メッセージ", MB_OK);
break;
case 40008: MessageBox(NULL, "イ", "メッセージ", MB_OK);
break;
case 40009: MessageBox(NULL, "ロ", "メッセージ", MB_OK);
break;
case 40010: MessageBox(NULL, "ハ", "メッセージ", MB_OK);
break;
case 40011: MessageBox(NULL, "ソ\ース", "メッセージ", MB_OK);
break;
case 40012: MessageBox(NULL, "ヘルプ", "メッセージ", MB_OK);
break;
case 40013: MessageBox(NULL, "ver1.00", "バージョン情報", MB_OK);
break;
}
break;
case WM_CLOSE: // ウィンドウが閉じられるとき
SetMenu(hWnd, NULL); // ウィンドウからメニュー削除
DestroyMenu(hMenu); // メニューバーリソース破棄
hMenu = NULL;
break; // ウィンドウを閉じる処理はDefWindowProc()に任せる
case WM_DESTROY: // ウィンドウが破棄されたら
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
MoveToEx(hdc, 50, 50, NULL); // (50, 50) まで移動
LineTo(hdc, x,50);
EndPaint(hWnd, &ps);
return 0;
case WM_LBUTTONDOWN:
return 0;
default:
if(cnt==20)
{
x=x+10;
InvalidateRect(hWnd , NULL , TRUE);
cnt=0;
}
cnt++;
}
return DefWindowProc(hWnd, msg, wp, lp);
}
[/code]
menu.rc
[code]
WIN_MENU MENU{
POPUP "ファイル"{
MENUITEM "開く", 40001
MENUITEM SEPARATOR
MENUITEM "保存", 40002
MENUITEM SEPARATOR
MENUITEM "終了", 40003
}
POPUP "編集"{
MENUITEM "切り取り", 40004
MENUITEM "コピー", 40005
MENUITEM "貼\り付け", 40006
}
POPUP "表\示"{
MENUITEM "ツールバー", 40007
MENUITEM SEPARATOR
POPUP"サブメニュー"{
MENUITEM "「イ」を表\示", 40008
MENUITEM "「ロ」を表\示", 40009
MENUITEM "「ハ」を表\示", 40010
}
MENUITEM "ソ\ース", 40011
}
POPUP "ヘルプ"{
MENUITEM "ヘルプ", 40012
MENUITEM SEPARATOR
MENUITEM "バージョン情報", 40013
}
}
[/code]