至急!windowsプログラミングのウィンドウにメニューを付ける方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
まるべる

至急!windowsプログラミングのウィンドウにメニューを付ける方法

#1

投稿記事 by まるべる » 13年前

1] 質問文
 [1.1]ウィンドウにメニューバーを付けたいです。これは学校の課題です。

 [1.2]

本文

コード:

//ex6_1.cpp
//簡単なメニューを実装したプログラム
//ビルド前にリソースエディタでメニューを作成すること。
//メニューID=MYMENU 「終了」ID=IDM_END 「ヘルプ」ID=IDM_HELP とする。
//「ファイル」はpopup=true、それ以外はpopup=faulse とする。

#include <windows.h>
#include "resource.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);

TCHAR szClassName[] = TEXT("ex6_1");	//ウィンドウクラス


int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
				   LPSTR lpsCmdLine, int nCmdShow)
{
	MSG msg;
	BOOL bRet;
	
	if (!InitApp(hCurInst))
		return FALSE;
	if (!InitInstance(hCurInst, nCmdShow)) 
		return FALSE;
	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
		if (bRet == -1) {
			break;
		} else {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return (int)msg.wParam;
}

//ウィンドウ・クラスの登録

ATOM InitApp(HINSTANCE hInst)
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;	//プロシージャ名
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInst;//インスタンス
	wc.hIcon = (HICON)LoadImage(NULL,
		MAKEINTRESOURCE(IDI_APPLICATION),
		IMAGE_ICON,
		0,
		0,
		LR_DEFAULTSIZE | LR_SHARED);
	wc.hCursor = (HCURSOR)LoadImage(NULL,
		MAKEINTRESOURCE(IDC_ARROW),
		IMAGE_CURSOR,
		0,
		0,
		LR_DEFAULTSIZE | LR_SHARED);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName = TEXT("MYMENU");	//メニュー名(IDR_MENUなどのときはMAKEINTRESOURCEを使うことに注意)
	wc.lpszClassName = szClassName;
	wc.hIconSm = (HICON)LoadImage(NULL,
		MAKEINTRESOURCE(IDI_APPLICATION),
		IMAGE_ICON,
		0,
		0,
		LR_DEFAULTSIZE | LR_SHARED);

	return (RegisterClassEx(&wc));
}

//ウィンドウの生成

BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
{
	HWND hWnd;

	hWnd = CreateWindow(szClassName,
			TEXT("メニューのあるプログラム"), //タイトルバーにこの名前が表示されます
			WS_OVERLAPPEDWINDOW, //ウィンドウの種類
			CW_USEDEFAULT,	//X座標
			CW_USEDEFAULT,	//Y座標
			CW_USEDEFAULT,	//幅
			CW_USEDEFAULT,	//高さ
			NULL, //親ウィンドウのハンドル、親を作るときはNULL
			NULL, //メニューハンドル、クラスメニューを使うときはNULL
			hInst, //インスタンスハンドル
			NULL);
	if (!hWnd)
		return FALSE;
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	return TRUE;
}

//ウィンドウプロシージャ

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	int id;

	switch (msg) {
		case WM_COMMAND:
			switch (LOWORD(wp)) {
				case IDM_END://メニューの「終了」を選択したときに行う処理
					SendMessage(hWnd, WM_CLOSE, 0, 0);//プログラムを終了する
					break;
				case IDM_HELP://メニューの「ヘルプ」を選択したときに行う処理
					//メッセージボックスを表示する
					MessageBox(hWnd, 
						TEXT("Kanto Gakuin Univ. 2011\nメニューサンプル"), 
						TEXT("about"), 
						MB_OK);
					break;
				default:
					return (DefWindowProc(hWnd, msg, wp, lp));
			}
			break;
		case WM_CLOSE:
			id = MessageBox(hWnd,
				TEXT("終了してもよろしいですか"),
				TEXT("確認"),
				MB_YESNO | MB_ICONQUESTION);
			if (id == IDYES)
				DestroyWindow(hWnd);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return (DefWindowProc(hWnd, msg, wp, lp));
	}
	return 0;
}
ヘッダーファイル

コード:

#define IDR_MYMENU                     101
#define IDM_END                        104
#define IDM_HELP                       105
リソースファイル

コード:

#include <windows.h>
#include "resource.h"

#include <windows.h>
#include "resource.h"

IDR_MYMENU MENU DISCARDABLE 
BEGIN
    POPUP "ファイル(&F)"
    BEGIN
        MENUITEM "開く(&O)", IDM_FILEOPEN
        POPUP "新規作成(&N)"
        BEGIN
            MENUITEM "フォルダ(&F)", IDM_MAKEFOLDER
        END
        MENUITEM SEPARATOR
        MENUITEM "終了(&X)", IDM_END
    END
    MENUITEM "情報(&I)", IDM_HELP
END

 [1.3] エラーはありません。ウィンドウは表示されるのですがメニューバーが表示されません
 [1.4] ソースコードの間違えの場所、またリソースファイルの仕組み

[2] 環境  
 [2.1] windowsXP
 [2.2] VC++ 2008EE

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 至急!windowsプログラミングのウィンドウにメニューを付ける方法

#2

投稿記事 by みけCAT » 13年前

コード:

wc.lpszMenuName = TEXT("MYMENU");   //メニュー名(IDR_MENUなどのときはMAKEINTRESOURCEを使うことに注意)
自分で書いていますよね?
というわけでこうしたらどうなりますか?

コード:

wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 至急!windowsプログラミングのウィンドウにメニューを付ける方法

#3

投稿記事 by みけCAT » 13年前

そもそもIDM_FILEOPENとIDM_MAKEFOLDERの定義が見つからないので、エラーが出ると思います。
というかDev-C++4.9.9.2でコンパイルしたら出ました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

まるべる

Re: 至急!windowsプログラミングのウィンドウにメニューを付ける方法

#4

投稿記事 by まるべる » 13年前

みけCATさん

丁寧にありがとうございます。
このソースは学校での例題に私がネットで参考にしたものをあわせたソースなので意味の分からないものになっていました。。。すいません!
メニューバーに関しては無事に表示できましたので自己解決しました!回答していただいたのに申し訳ないです。

厚かましいのですがその先の課題でまた詰まってしまいました。

課題内容は

作成してきたタイマープログラムに「タイマー操作」というメニュー項目をもつメニューを追加しなさい。

「タイマー操作」の下にダイアログボックス表示のための項目を設け、その項目をクリックするとダイアログボックスが表示されるようにしなさい。

また、そのダイアログボックスで「OK」ボタンを押すと、カウントを開始するようにしなさい。

というものです

現在のソースが

本文

コード:

#include <windows.h>
#include "resource.h"
#define ID_MYTIMER 100 //タイマID

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
HFONT MyCreateFont(int, DWORD, LPCTSTR);

TCHAR szClassName[] = TEXT("ktimer");	//ウィンドウクラス
HINSTANCE hInst;

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
				   LPSTR lpsCmdLine, int nCmdShow)
{
	MSG msg;
	BOOL bRet;
	
	hInst = hCurInst; //インスタンスハンドルをグローバル変数にコピー
	if (!InitApp(hCurInst))
		return FALSE;
	if (!InitInstance(hCurInst, nCmdShow)) 
		return FALSE;
	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
		if (bRet == -1) {
			break;
		} else {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return (int)msg.wParam;
}

//ウィンドウ・クラスの登録

ATOM InitApp(HINSTANCE hInst)
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
	wc.lpfnWndProc = WndProc;	//プロシージャ名
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInst;//インスタンス
	wc.hIcon = (HICON)LoadImage(NULL,
		MAKEINTRESOURCE(IDI_APPLICATION),
		IMAGE_ICON,
		0,
		0,
		LR_DEFAULTSIZE | LR_SHARED);
	wc.hCursor = (HCURSOR)LoadImage(NULL,
		MAKEINTRESOURCE(IDC_ARROW),
		IMAGE_CURSOR,
		0,
		0,
		LR_DEFAULTSIZE | LR_SHARED);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName = TEXT("MYMENU");	//メニュー名
	wc.lpszClassName = szClassName;
	wc.hIconSm = (HICON)LoadImage(NULL,
		MAKEINTRESOURCE(IDI_APPLICATION),
		IMAGE_ICON,
		0,
		0,
		LR_DEFAULTSIZE | LR_SHARED);

	return (RegisterClassEx(&wc));
}

//ウィンドウの生成

BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
{
	HWND hWnd;

	hWnd = CreateWindow(szClassName,
			TEXT("モーダルダイアログボックスを表示する"), //タイトルバーにこの名前が表示されます
			WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, //ウィンドウの種類
			CW_USEDEFAULT,	//X座標
			CW_USEDEFAULT,	//Y座標
			300, //幅
			100,	//高さ
			NULL, //親ウィンドウのハンドル、親を作るときはNULL
			NULL, //メニューハンドル、クラスメニューを使うときはNULL
			hInst, //インスタンスハンドル
			NULL);
	if (!hWnd)
		return FALSE;
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	return TRUE;
}

//ウィンドウプロシージャ

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	int id;
	HDC hdc;
	PAINTSTRUCT ps;
	static TCHAR szTime[64];
	SYSTEMTIME st;
	HFONT hFont2;
	static int start_time;//起動時の時刻を秒に変換
	static int settei_time = 20;//タイマの設定時間
	int now_time;
	int nokori;
	static BOOL f_timer = FALSE;

	switch (msg) {
		case WM_CREATE:
			//start_time = GetTickCount();
			//SetTimer(hWnd, ID_MYTIMER, 500, NULL);
			break;

		case WM_COMMAND:
			switch (LOWORD(wp)){
				case IDM_START:
					start_time = GetTickCount();
					SetTimer(hWnd, ID_MYTIMER, 500, NULL);
					f_timer = TRUE;

				break;

				case IDM_END:
					if(f_timer){
						if (KillTimer(hWnd, ID_MYTIMER) == 0) {
							MessageBox(hWnd, 
							TEXT("KillTimer Error!"), 
							TEXT("Error"), 
							MB_OK | MB_ICONEXCLAMATION);
						}
					f_timer = FALSE;
					wsprintf(szTime, TEXT("終了"));
					InvalidateRect(hWnd , NULL , TRUE);
					}

				break;

				case IDM_DLG:
					//ダイアログボックスの呼び出し(hInstはグローバル変数)
					DialogBox(hInst, TEXT("MYDLG"), hWnd, (DLGPROC)MyDlgProc); 
					break;
				case IDM_ABOUT:
					MessageBox(hWnd,
						TEXT("2011 Kanto Gakuin Univ."),
						TEXT("About"),
						MB_OK);
					break;

				default:
					return (DefWindowProc(hWnd, msg, wp, lp));

			}

			break;


		case WM_CHAR:

			if (wp == VK_SPACE){
				start_time = GetTickCount();
				SetTimer(hWnd, ID_MYTIMER, 500, NULL);

			}

			break;

		case WM_TIMER:
			//関係ないタイマーイベントはDefWindowProcに任せる
			if (wp != ID_MYTIMER)
				return (DefWindowProc(hWnd, msg, wp, lp));

			now_time = (int)((GetTickCount() - start_time) / 1000 + 0.5);
			nokori = settei_time - now_time;

				if(nokori >= 0)
					wsprintf(szTime, TEXT("%02d"), nokori);
				else
					wsprintf(szTime, TEXT("終了"));
			//クライアント領域全体を更新
			InvalidateRect(hWnd, NULL, TRUE);

			break;
		case WM_LBUTTONDBLCLK:
			SendMessage(hWnd, WM_CLOSE, 0, 0);
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			hFont2 = MyCreateFont(30, SHIFTJIS_CHARSET, TEXT("MS ゴシック"));
			SelectObject(hdc, hFont2);
			SetTextColor(hdc, RGB(0, 0, 255));
			TextOut(hdc, 10, 20, szTime, lstrlen(szTime));
			DeleteObject(hFont2);
			EndPaint(hWnd, &ps);
			break;
		case WM_CLOSE:
			id = MessageBox(hWnd,
				TEXT("終了してもよろしいですか"),
				TEXT("確認"),
				MB_YESNO | MB_ICONQUESTION);
			if (id == IDYES) {
				if(f_timer){
					if (KillTimer(hWnd, ID_MYTIMER) == 0) {
						MessageBox(hWnd, 
							TEXT("KillTimer Error!"), 
							TEXT("Error"), 
							MB_OK | MB_ICONEXCLAMATION);
					}
					f_timer = FALSE;
				}
				DestroyWindow(hWnd);
			}
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return (DefWindowProc(hWnd, msg, wp, lp));
	}
	return 0;
}

//ダイアログプロシージャ
BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
	switch (msg) {
		case WM_COMMAND:
			switch (LOWORD(wp)) {
				case IDOK:
					EndDialog(hDlg, IDOK);
					return TRUE;
				case IDCANCEL:
					EndDialog(hDlg, IDCANCEL);
					return TRUE;
			}
			return FALSE;
	}
	return FALSE;
}

HFONT MyCreateFont(int nHeight, DWORD dwCharSet, LPCTSTR lpName)
{
	return(	CreateFont(nHeight, 0, 0, 0,
				FW_DONTCARE,
				FALSE, FALSE, FALSE,
				dwCharSet,
				OUT_DEFAULT_PRECIS,
				CLIP_DEFAULT_PRECIS,
				DEFAULT_QUALITY,
				DEFAULT_PITCH | FF_DONTCARE,
				lpName));
}
ヘッダー

コード:

#define IDR_MENU1                       101
#define ID_40001                        40001
#define ID_40002                        40002
#define IDM_START                       40003
#define IDM_END                         40004
#define IDM_DLG							40006
#define IDM_ABOUT						40007

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        102
#define _APS_NEXT_COMMAND_VALUE         40005
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
リソースファイル

コード:

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
//#include "afxres.h"
#include <windows.h>
#define IDC_STATIC -1

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// 日本語 resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
#ifdef _WIN32
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
#pragma code_page(932)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

MYMENU MENU 
BEGIN
    POPUP "タイマー"
    BEGIN
        MENUITEM "開始",                          IDM_START
        MENUITEM "終了",                          IDM_END
    END
    POPUP "オプション"
    BEGIN
	MENUITEM "ダイアログボックスの表示"	  IDM_DLG
    END
    POPUP "ヘルプ"
    BEGIN
	MENUITEM "About"			  IDM_ABOUT
    END
END

#endif    // 日本語 resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED
ウインドウ、メニューバーは表示できるのですがダイアログボックスを立ち上げることが出来ません。
おそらくリソースファイルでのダイアログボックスの作成が出来ていない為だと思っています。
VC++2008EEなのでリソースエディターを使うことが出来ません。
ご助言、訂正などよろしくお願い致します。

とりむ~

Re: 至急!windowsプログラミングのウィンドウにメニューを付ける方法

#5

投稿記事 by とりむ~ » 13年前

初投稿になります。

リソーススクリプトにダイアログボックスに関することが
書かれていないようなので、表示がされないのは
それが原因でしょうか。(動作未確認です・・)

スクリプトの書き方については、
猫でもわかるプログラミングサイトの- WindowsSDK編第1部内に
ダイアログについて書かれているものがありますので
そちらを参考にされてはいかがでしょうか。

閉鎖

“C言語何でも質問掲示板” へ戻る