みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Windowsプログラミングでの質問です

よろしくお願いします。
windowsのプログラミングを、『猫でもわかるwindowsプログラミング弟2版』と言う本を参考にしながら、C言語で作っています。
2ヶ月ほどがんばってみたのですがどうしてもうまく行きません。
手順です、
1、空のウィンドウを作りメニューバーを作成。
2、メニューに『ファイルと、オプションタブを作る』
3、オプションタブに、ダイアログボックスを『開くと、閉じる』タブ
  を作る。
4、『開く』タブをクリックすると、名前を入力するためのダイアログ  ボックスを開く。
と言うプログラムなのですが、作成されたウィンドウから⇒オプションタブ⇒開くをクリックしても、ダイアログボックスが表示されません。
リソースファイルや、ヘッダファイルを開いて、参考にしている本と比べてみたのですが、ほとんど変わっていません。自分では原因が発見できないのですが、詳しい方、ご指摘をお願いします。
5、気になる所では、ソース中で、ウィンドウプロシージャの記述で、
 else文に{}が無いので、そこをいじってみたのですが、うまく行きま せんでした。

  case WM_PAINT: //描画処理
if(strcmp(szName, "")==0)
strcpy(szBuf, "まだ名前の入力はありません");
else
wsprintf(szBuf, "入力された名前は%sさんです",
szName);
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 10, 10, szBuf, (int)strlen(szBuf));
EndPaint(hWnd, &ps);
break;
ご指導よろしくお願いします。
 

投稿日時 - 2007-08-13 15:38:49

QNo.3251741

困ってます

質問者が選んだベストアンサー

★本当に文字列ですか?
・『MYDIALOG』も『MYMENU』も『MYACCEL』も記号定数ですけど。
 文字列の意味が分かっていない気がします。
 リソースの
>MYDIALOG DIALOG DISCARDABLE 0, 0, 270, 180
>MYMENU MENU DISCARDABLE
>MYACCEL ACCELERATORS DISCARDABLE
 ↑
 この3つは記号定数で ID を指定しています。
 もし文字列なら
 "MYDIALOG" DIALOG DISCARDABLE 0, 0, 270, 180
 "MYMENU" MENU DISCARDABLE
 "MYACCEL" ACCELERATORS DISCARDABLE
 とするか "Resmenu.h" ファイルで
 #define MYDIALOG "MYDIALOG"
 #define MYMENU "MYMENU"
 #define MYACCEL "MYACCEL"
 となっていないといけない。
 でもそのような定義していない気がします。ここ確認。
・今回は ID を記号定数の MYDIALOG、MYMENU、MYACCEL で指定しています。きっと。多分。
 だからソースにも記号定数で指定しないとダイアログ、メニュー、アクセラレータの全てが
 正しく識別されません。→表示されない。など。
・よって次のように修正して再コンパイルして下さい。
 (1)WinMain() 関数内にある
  修正前⇒hAccel = LoadAccelerators( hCurInst, "MYACCEL" );
  修正後⇒hAccel = LoadAccelerators( hCurInst, MAKEINTRESOURCE(MYACCEL) );
 (2)InitApp() 関数内にある
  修正前⇒wc.lpszMenuName = "MYMENU"; //メニュー名 ウィンドウクラスにメニュー名を登録
  修正後⇒wc.lpszMenuName = MAKEINTRESOURCE(MYMENU); //メニュー名 ウィンドウクラスにメニュー名を登録
 (3)WndProc() 関数内にある
  修正前⇒hDlg = CreateDialog( hInst, "MYDLG", hWnd, (DLGPROC)MyDlgProc );
  修正後⇒hDlg = CreateDialog( hInst, MAKEINTRESOURCE(MYDLG), hWnd, (DLGPROC)MyDlgProc );
 上記の3つを修正して下さい。
・ちなみに MAKEINTRESOURCE() マクロは記号定数を文字列ポインタに変換するマクロです。
 これを使って下さい。
・以上。結果報告を待っています。

投稿日時 - 2007-08-14 16:33:48

補足

結果報告が後れて済みませんでした。
ご指摘の箇所を編集しなおしてMAKEしてみたのですが、エラーが出てしまいました。
『BCCでの文字列の指定のしかた』を改めて確認したところ、ダブルクォーティーションはつけなくても良いことが確認できました。
そこで、リソースエディタでの、ダイアログの部分をよく確認した所、設定ミスがあるのを見つけることが出来ました。
いろいろとアドバイスをしていただいたおかげで、『よく確認する』と言うことが大事なことが分かりました。
(確認のポイントがまだ未熟でした。)
ただ、まだ問題が残っています。
ダイアログボックスが表示されたのはいいのですが、
1、『OK』ボタンを押しても、ダイアログボックスが閉じない。
2、『キャンセル』ボタンを押した後で、『終了』ボタンを押して終了しても、入力した文字が表示される。
3、メニューのオプションにある『ダイアログを閉じる』が、グレーダ  ウンしたままで、変化しない。等が残っていますが、サンプルを確  認しながら、修正してみます。どうしても原因が分からない時は、  改めて質問しますので見かけましたら、アドバイスをお願いします。
  いつも、多くのアドバイス、ご指摘有難うございます。

こちらが、MAKEINTRESOURCE() マクロを使ってMAKEした結果です。

> D:\borland\bcc55\Bin\make.exe -fRelease\menu.mak -B TARGET
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
bcc32 -W -3 -O2 -w- -AT -pc -H- -k -b -nRelease -c D:\menu\menu\daialog.txt.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
D:\menu\menu\daialog.txt.cpp:
brc32 -r -foRelease\menu.res D:\menu\menu\menu.rc
Borland Resource Compiler Version 5.40
Copyright (c) 1990, 1999 Inprise Corporation. All rights reserved.

Error menu.rc 11 43: Bad character in source input     
** error 20018 ** deleting Release\menu.res       //エラーの意味はまだ分かりません。


Make End !! (Elapsed time 0:00.797)




 

投稿日時 - 2007-08-15 22:34:58

お礼

たくさんのアドバイス、有難うございました。
まだ問題は残っていますが、取りあえず、ダイアログボックスが表示できるようになりました。
残っている問題点を、今までのアドバイス、ご指摘と照らし合わせてみます。
力不足のため、どうしても一人で解決できない時は、改めて質問したいと思います。
見かけましたら、アドバイス、ご指導をお願いします。

投稿日時 - 2007-08-17 20:09:18

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(8)

ANo.7

★確認のアドバイス
>例えば、配列や、ポインタ、構造体、その他の文、を使って自分でプログラムを作ることは出来ません。
 ↑
 まだ使いこなせてはいないようですね。
 windows プログラムでは構造体がいっぱい出てきますので。
>そのソースの内容について確認しながらの学習です。
 ↑
 頑張って下さいね。
 確認しながらが大事ですから。確認が。
>あと、『タブ文字を全角空白に置換』の意味、方法が分からないのでそのまま貼り付けます。
 ↑
 Cソースのインデントとしてタブ文字使っていますよね。普通。
 ここの質問、補足、お礼なのに貼り付けると連続するタブやスペースが1つのスペースに
 変換されてしまうのです。そこでインデントのタブ文字だけは全角空白文字に変換して
 貼り付けると『空白文字』として見やすくなると言いたかったのです。それだけの意味。
・確認したいのですがモードレス・ダイアログの ID は次のどちらですか?
 (1)文字列の "MYDLG" ですか。
 (2)resource.h で記号定数として MYDLG ですか。
 つまりダイアログ・リソースの記述が
 (1)"MYDLG" DIALOGEX 0, 0, 幅, 高さ
 (2)MYDLG DIALOGEX 0, 0, 幅, 高さ
 のどちら。
 もしも(2)の記号定数で記述しているのなら CreateDialog() の第2引数には記号定数として MYDLG を
 指定しないとダイアログが表示されません。また逆の場合も同じでリソースに文字列として ID を
 記述しているのに CreateDialog() の第2引数に記号定数として MYDLG を指定した場合もダイアログが
 表示されなくなります。よって文字列なら文字列、記号定数なら記号定数で指定します。
・あとリソースの『DS_MODALFRAME』スタイルはモードレス・ダイアログの表示とは
 まったく関係がありません。

その他:
・ダイアログ・プロシージャで
>GetDlgItemText( hDlg, IDC_EDIT1, szName, (int)sizeof(szName)-1 );
 ↑
 となっていますが sizeof(szName) で良いですよ。1 引かなくても。
 GetDlgItemText( hDlg, IDC_EDIT1, szName, (int)sizeof(szName) );
・あとダイアログを作成している部分で
>hDlg = CreateDialog( hInst, "MYDLG", hWnd, (DLGPROC)MyDlgProc );
 としていますが hDlg が NULL のときに代入して NULL 以外の場合はダイアログを
 2度以上は作成させないようにします。ここにも注意。
 2つ以上のモードレス・ダイアログを作成するならダイアログのウインドウハンドルを
 配列などで全て管理して下さい。そして WinMain() のメッセージ・ループですべての
 ダイアログのウインドウハンドルに対して IsDialogMessage() で調べる必要があります。
・今回は恐らくダイアログの ID の文字列か、記号定数かの違いで表示されないのではと思います。
 文字列なら文字列、記号定数なら記号定数で CreateDialog() 関数の引数に渡して下さい。
 一致させないと正しくは表示されません。それも全く表示されないため原因不明に思えます。
 ID の指定を確認して下さい。→記号定数の場合は MAKEINTRESOURCE(MYDLG) と指定。
 ※メニューの "MYMENU" も一緒に確認して下さい。文字列か、記号定数かを。
・以上。確認報告を待っています。

投稿日時 - 2007-08-14 12:05:49

補足

お手数をおかけします。ご指摘の所を確認しました。
1、モードレスダイアログのIDは、文字列で『MYDIALOG』として作りました。
2、メニューについても、『MYMENU』とし、アクセラレータは、『MYACCEL』として作りました。
リソースファイルを貼り付けますので、気の付いた所がありましたら、ご指摘をお願いします
//-----------------------------------------
// BCCForm Ver 2.41
// An Easy Resource Editor for BCC
// Copyright (c) February 2002 by ysama
//-----------------------------------------
#include"Resmenu.h"
//----------------------------------
// ダイアログ (MYDIALOG)
//----------------------------------
MYDIALOG DIALOG DISCARDABLE 0, 0, 270, 180           EXSTYLE WS_EX_DLGMODALFRAME                  STYLE WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU |WS_MINIMIZEBOX | DS_SETFONT                  CAPTION "モードレスダイアログbox"               FONT 8, "MS 明朝"
    CONTROL "", IDC_EDIT1, "EDIT", WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | ES_AUTOHSCROLL | ES_READONLY | ES_LEFT, 48, 55, 186, 15, WS_EX_DLGMODALFRAME
 CONTROL "OK", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_NOTIFY, 18, 129, 66, 18
         CONTROL "クリア", IDCANCEL, "BUTTON", WS_CHILD | WS_VISIBLE |BS_DEFPUSHBUTTON | BS_NOTIFY, 111, 130, 79, 18
 CONTROL "閉じる", IDC_CLOSE, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_NOTIFY, 205, 129, 54, 19         CONTROL "名前を入力してください", IDC_STATIC, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 42, 18, 156, 15      
}                              
//-------------------------
// メニュー(MYMENU)                    
//-------------------------
MYMENU MENU DISCARDABLE
{
POPUP "ファイル(&F)"                     {
MENUITEM "終了(&X)", IDM_END                
}
POPUP "オプション(&O)"
{
MENUITEM "ダイアログ表示(&D)\tF5", IDM_DLG
MENUITEM "ダイアログを閉じる(&C)\tF6", IDM_CLOSEDLG     
}
}                              
//--------------------------------
// アクセラレーター (MYACCEL)       
//--------------------------------
MYACCEL ACCELERATORS DISCARDABLE            
{                               
VK_F5, IDA_OPT1, VIRTKEY, NOINVERT              
VK_F6, IDA_OPT2, VIRTKEY, NOINVERT              
}                                                                                       

投稿日時 - 2007-08-14 14:30:04

ANo.6

★追記。
・ダイアログを CreateDialog() で作っています。
 WinMain() のメッセージループでちゃんと IsDialogMessage() を使っていますか?
 CreateDialog() で作ったのはモードレス・ダイアログですよ。
 普通の『モーダル・ダイアログ』はマクロ関数の DialogBox() を使います。
 本当に『モードレス・ダイアログ』でいいのですか?
・以上。参考に。

投稿日時 - 2007-08-14 07:26:39

補足

回答有難うございます。
ご指摘の所なのですが、使用している本では、『モードレスダイアログボックスなのに、スタイルに、DS_MODALFRAMEを使っていますが、モードレスダイアログボックスのリソースは、モーダルダイアログボックスのそれと同じでよい』と解説してあります。ソースでもそうなっていました。
力のある人は、スタイルを変更してください。となっていますが、私にはまだ無理なので、サンプルどおりに作っています。

投稿日時 - 2007-08-14 08:33:29

ANo.5

★親ウインドウのプロシージャに原因がありそうだ。
・ざっと読んだところ次のような構造になっているのですよね。
 
 親ウインドウ(ここにメニューなどの処理)
 └ダイアログ(このプロシージャをNo.1さんの補足に貼り付けた)
 
>windowsのプログラミングを、『猫でもわかるwindowsプログラミング弟2版』と言う本を
>参考にしながら、C言語で作っています。
>2ヶ月ほどがんばってみたのですがどうしてもうまく行きません。
 ↑
 windows プログラムの前に C 言語はどの程度理解していますか?
 (1)配列、ポインタ
 (2)構造体、共用体、ビットフィールド
 (3)その他
 ↑
 3つとも完全に理解して使いこなせていますか?
・あと『空のプロジェクト』から始めていますか?
 Win32API+SDK(非MFC)のようですけどダイアログの呼び出し部分やリソースの設定によっては
 ダイアログが表示されないことがあります。空のウインドウは正常に作成されて表示はされて
 いるようですね。多分。
・そうなると
 (1)親ウインドウの WM_COMMAND メッセージから正しくダイアログが呼べるかを調査。
 (2)その後、メニュー項目を選択したら WM_COMMAND メッセージでキャッチでき MessageBox() が
  ちゃんと表示できるか調査。
 1つずつ原因を突き止めたほうが良いです。
・とりあえず WinMain() 部分からすべてのソースを『補足』と『お礼』の2つを使って貼り付けて。
 貼り付けるときタブ文字を全角空白に置換してくれると見やすいです。
 待っています。
・以上。

投稿日時 - 2007-08-14 07:15:48

補足

回答有難うございます。
ご指摘の、C言語の理解度なのですが、『配列、ポインタ、構造体、共用体』については、記述の仕方、文体の構造、などが大体分かる程度です。例えば、配列や、ポインタ、構造体、その他の文、を使って自分でプログラムを作ることは出来ません。サンプルのプログラムをコーディングして、無事実行できたものをプリントアウトし、そのソースの内容について確認しながらの学習です。
また、今回の質問のは、BCCdeveloperで作成しました。
あと、『タブ文字を全角空白に置換』の意味、方法が分からないのでそのまま貼り付けます。
すみません。

/*モードレスダイアログボックス、タブを押すとその順にアクティブなコントロールが移動 */

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

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

char szClassName[] = "dialog"; //ウィンドウクラス

HINSTANCE hInst;
HWND hMain;
HWND hDlg;
char szName[32];


int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
LPSTR lpsCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
HACCEL hAccel; //アクセラレータの変数

hInst = hCurInst; //インスタンスハンドルをグローバル変数にコピー

if(!InitApp(hCurInst))
return FALSE;
if(!InitInstance(hCurInst, nCmdShow))
return FALSE;

hAccel = LoadAccelerators(hCurInst, "MYACCEL");

while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
if(bRet == -1){
break;
}else{
if(!hDlg || !IsDialogMessage(hDlg, &msg)){
if(!TranslateAccelerator(hMain, hAccel, &msg)){


TranslateMessage(&msg);
DispatchMessage(&msg);
}
} //WinMain以外の関数で、インスタンスハンドルを参照したいので、
//グローバル変数にコピーしている
}
}
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 = NULL;
wc.hCursor = (HCURSOR)LoadImage(NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR, 0, 0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "MYMENU"; //メニュー名 ウィンドウクラスにメニュー名を登録
wc.lpszClassName = (LPCSTR)szClassName;//ウィンドウクラスの名前を記述
wc.hIconSm = NULL;

return (RegisterClassEx(&wc));
}
//ウィンドウの生成

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

hWnd = CreateWindow(szClassName, "モードレスダイアログbox",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //y座標
CW_USEDEFAULT, //幅
CW_USEDEFAULT, //高さ
NULL, //親ウィンドウのハンドル
NULL, //メニューハンドル
hInst, //インスタンスハンドル
NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
hMain = hWnd;
return TRUE;
}

投稿日時 - 2007-08-14 09:33:39

お礼

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
static HMENU hMenu;
char szBuf[64];
HDC hdc;
PAINTSTRUCT ps;

switch (msg){
case WM_CREATE:
hMenu = GetMenu(hWnd); //メニューハンドルの取得
break;

case WM_INITMENU:
if(IsWindow(hDlg)){ //以下メニューの初期化

EnableMenuItem(hMenu, IDM_DLG,
MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hMenu, IDM_CLOSEDLG,
MF_BYCOMMAND | MF_ENABLED);
}else{
EnableMenuItem(hMenu, IDM_DLG,
MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(hMenu, IDM_CLOSEDLG,
MF_BYCOMMAND | MF_GRAYED);
}
DrawMenuBar(hWnd);
break;

case WM_PAINT: //描画処理
if(strcmp(szName, "")==0)
strcpy(szBuf, "まだ名前の入力はありません");
else
wsprintf(szBuf, "入力された名前は%sさんです",
szName);
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 10, 10, szBuf, (int)strlen(szBuf));
EndPaint(hWnd, &ps);
break;

case WM_COMMAND:
switch (LOWORD(wp)){

case IDM_END: //FormではEXITのため変更
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;

case IDM_DLG:
hDlg = CreateDialog(hInst, "MYDLG",
hWnd, (DLGPROC)MyDlgProc);
ShowWindow(hDlg, SW_NORMAL);
break;

case IDM_CLOSEDLG:
DestroyWindow(hDlg);
break;

}
break;

case WM_CLOSE:
if (IsWindow(hDlg)){
MessageBox(hWnd, "ダイアログを破棄します",
"破棄", MB_OK);
DestroyWindow(hDlg);
}
DestroyWindow(hWnd);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}
次が貼り付けられません。 

投稿日時 - 2007-08-14 09:58:29

ANo.4

すみません。私の勘違いでした。
ANo.3のソースや補足には問題ないですね。
示していただいたソースをもう少し調べてみます。

投稿日時 - 2007-08-14 00:45:21

お礼

お手数をおかけします。
まだ問題は残っていますが、取りあえずダイアログボックスの表示は、できるようになりました。
一時、締め切りたいと思います。
残っている問題が解決できない時は、改めて質問したいと思っています。
見かけましたらアドバイスをお願いします。

投稿日時 - 2007-08-17 20:03:33

ANo.3

たくさんのソースを貼ってくれましたが、関係があるのはこの部分だけです。
何の処理か分かりますか?

if(IsWindow(hDlg)){ //以下メニューの初期化
EnableMenuItem(hMenu, IDM_DLG, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hMenu, IDM_CLOSEDLG, MF_BYCOMMAND | MF_ENABLED);
}else{
EnableMenuItem(hMenu, IDM_DLG, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(hMenu, IDM_CLOSEDLG, MF_BYCOMMAND | MF_GRAYED);
}

投稿日時 - 2007-08-13 20:23:33

補足

アドバイス有難うございます。
参考にしている『猫でもわかるwindowsプログラミング第2版』を良く調べてみました。IsWindow(hDlg ) 関数 指定したウィンドウハンドルが有効かどうかを調べる

EnableMenuItem関数 メニュウ項目を使用可能、不可能にする。

第一引数に、メニューハンドルを指定   hMenu
第二引数に、対象となるメニュー項目   IDM_DLG
第三引数に、メニュー項目の指定方法と、メニューの状態    MF_BYCOMMAND | MF_GRAYED

MF_BYCOMMAND は、メニュー項目をIDで指定する。
MF_GRAYEDは、 メニュー項目をグレイアウトして使用不可にする
MF_ENABLEDは、 メニュー項目を使用可能にする

if文で IsWindow関数なら EnableMenuItem(hMenu, IDM_DLG, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hMenu, IDM_CLOSEDLG, MF_BYCOMMAND | MF_ENABLED); を実行

違っていたら、EnableMenuItem(hMenu, IDM_DLG, MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(hMenu, IDM_CLOSEDLG, MF_BYCOMMAND | MF_GRAYED);
}  を実行
と解釈しました、
ダイアログボックスが表示できないのは、EnableMenuItem(hMenu, IDM_DLG, MF_BYCOMMAND | MF_GRAYED);
の所のMF_GRAYEDの部分をMF_ENABLEDに変更すればいいのでしょうか、今から試してみます。
判断ミスや指摘する所がありましたらアドバイスをお願いします。
それから、今、画面が変になってしまっています(質問当初の画面が表示されない)読みずらかったらすみません。

投稿日時 - 2007-08-13 22:37:21

ANo.2

zwi

サイト「猫でもわかるプログラミング」のページで同じところはありますでしょうか?
http://www.kumei.ne.jp/c_lang/
質問の内容とこのサイトの内容で同じ所があれば教えてください。今の説明のままだと良く分かりません。

投稿日時 - 2007-08-13 17:00:15

補足

回答有難うございます。
『BCCでプログラムを作ろう』の第8章に、『猫でもわかるプログラミング第2版』では、第10章を少し加えてあります。
1、メニューバーに、ファイル、オプションタブ、が表示
2、オプションタブには、『ダイアログを開く、と ダイアログを閉じる』タブがあリ、それぞれにアクセラレータキー、F5と、F6がつきます。
1、ファイルを開くから、ダイアログが表示され、エディットコントロールに、名前を入力するようになっています。
2、プッシュボタンは、OK,クリア、閉じる の3つがあり、名前を入力してから、OKを押すと、『○○さんですね』と確認して終了します。
3、makeして出来たウィンドウでは、画面に『まだ名前の入力がありません』と表示されていて、ダイアログを開くタブで、ダイアログが表示されるのですが、ここの所がうまく行きません。
お手数をおかけしますが、よろしくお願いします。

投稿日時 - 2007-08-13 18:39:56

お礼

回答有難うございます。
まだ問題は残っていますが、取りあえずダイアログボックスの表示は、
できるようになりました。
残っている問題が解決できない時には、改めて質問をします、もし見かけましたらアドバイスをお願いします。

投稿日時 - 2007-08-17 19:58:36

ANo.1

描画処理のソースしかないですね。
ソースを見ないとなんとも言えません。
開くをクリックするとどこが呼ばれるか分かりますか?

投稿日時 - 2007-08-13 15:54:16

補足

回答有難うございます。
1、開くをクリックすると、名前を入力するためのダイアログボックスが呼ばれます。
ソースを全文記述すると、『文字数オーバー』となってしまうので、途中からの表示です。
//ウィンドウプロシージャ

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
static HMENU hMenu;
char szBuf[64];
HDC hdc;
PAINTSTRUCT ps;

switch (msg){
case WM_CREATE:
hMenu = GetMenu(hWnd); //メニューハンドルの取得
break;

case WM_INITMENU:
if(IsWindow(hDlg)){ //以下メニューの初期化

EnableMenuItem(hMenu, IDM_DLG,
MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hMenu, IDM_CLOSEDLG,
MF_BYCOMMAND | MF_ENABLED);
}else{
EnableMenuItem(hMenu, IDM_DLG,
MF_BYCOMMAND | MF_ENABLED);
EnableMenuItem(hMenu, IDM_CLOSEDLG,
MF_BYCOMMAND | MF_GRAYED);
}
DrawMenuBar(hWnd);
break;

case WM_PAINT: //描画処理
if(strcmp(szName, "")==0)
strcpy(szBuf, "まだ名前の入力はありません");
else
wsprintf(szBuf, "入力された名前は%sさんです",
szName);
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 10, 10, szBuf, (int)strlen(szBuf));
EndPaint(hWnd, &ps);
break;

case WM_COMMAND:
switch (LOWORD(wp)){

case IDM_END: //FormではEXITのため変更
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;

case IDM_DLG:
hDlg = CreateDialog(hInst, "MYDLG",
hWnd, (DLGPROC)MyDlgProc);
ShowWindow(hDlg, SW_NORMAL);
break;

case IDM_CLOSEDLG:
DestroyWindow(hDlg);
break;

}
break;

case WM_CLOSE:
if (IsWindow(hDlg)){
MessageBox(hWnd, "ダイアログを破棄します",
"破棄", MB_OK);
DestroyWindow(hDlg);
}
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)
{
static HWND hParent;

switch (msg){
case WM_INITDIALOG:
hParent = GetParent(hDlg); //親Windowのハンドルを取得
return TRUE;

case WM_COMMAND:
switch (LOWORD(wp)){

case IDOK:
GetDlgItemText(hDlg, IDC_EDIT1, szName,
(int)sizeof(szName)-1);
InvalidateRect(hParent, NULL, TRUE);
return TRUE;

case IDCANCEL:
SetDlgItemText(hDlg, IDC_EDIT1, "");
return TRUE;

case IDC_CLOSE:
DestroyWindow(hDlg);
return TRUE;
}
return FALSE;
}
return FALSE;
}
2、宣言の部分、ウィンドウクラスの登録、ウィンドウの生成の部分は、省いてあります。
お手数をおかけします。

投稿日時 - 2007-08-13 18:06:57

あなたにオススメの質問