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

このQ&Aのポイント
  • Windowsプログラミングでの質問です。作成したプログラムのウィンドウからオプションタブをクリックしてもダイアログボックスが表示されません。
  • ソース中のウィンドウプロシージャの記述に問題があるかもしれません。else文に{}がないため、修正してみましたがうまく動作しませんでした。
  • 詳しい方にご指摘をお願いします。リソースファイルやヘッダファイルを確認しましたが、参考書とほぼ同じです。原因を見つけることができません。
回答を見る
  • ベストアンサー

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; ご指導よろしくお願いします。  

noname#220054
noname#220054

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.8

★本当に文字列ですか? ・『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() マクロは記号定数を文字列ポインタに変換するマクロです。  これを使って下さい。 ・以上。結果報告を待っています。

noname#220054
質問者

お礼

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

noname#220054
質問者

補足

結果報告が後れて済みませんでした。 ご指摘の箇所を編集しなおして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)  

その他の回答 (7)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.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" も一緒に確認して下さい。文字列か、記号定数かを。 ・以上。確認報告を待っています。

noname#220054
質問者

補足

お手数をおかけします。ご指摘の所を確認しました。 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               }                                                                                       

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

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

noname#220054
質問者

補足

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

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.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つを使って貼り付けて。  貼り付けるときタブ文字を全角空白に置換してくれると見やすいです。  待っています。 ・以上。

noname#220054
質問者

お礼

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; } 次が貼り付けられません。 

noname#220054
質問者

補足

回答有難うございます。 ご指摘の、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; }

回答No.4

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

noname#220054
質問者

お礼

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

回答No.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); }

noname#220054
質問者

補足

アドバイス有難うございます。 参考にしている『猫でもわかる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に変更すればいいのでしょうか、今から試してみます。 判断ミスや指摘する所がありましたらアドバイスをお願いします。 それから、今、画面が変になってしまっています(質問当初の画面が表示されない)読みずらかったらすみません。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

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

noname#220054
質問者

お礼

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

noname#220054
質問者

補足

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

回答No.1

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

noname#220054
質問者

補足

回答有難うございます。 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、宣言の部分、ウィンドウクラスの登録、ウィンドウの生成の部分は、省いてあります。 お手数をおかけします。

関連するQ&A

  • エラー Run-Time Check Failure #2 - Stack around the variable 'ps' was corrupted.

    五目並べのプログラムを作っているのですが、 下記2のサブルーチンを出る時に 下記1のようなランタイムエラーが どうしても出てしまいます。 原因が分からなく自分の力ではどうにもできないので、 どなたかアドバイスよろしくお願い致します。        記1 Run-Time Check Failure #2 - Stack around the variable 'ps' was corrupted.        記2 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id, x, y; static int nTe = 0; PAINTSTRUCT ps; HDC hdc; char szBuf[64], szSashite[16]; static HMENU hMenu; switch (msg) { case WM_CREATE: hMenu = GetMenu(hWnd); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); MyMakeBan(hdc); MyStoneDraw(hdc); if (bSente) strcpy_s(szSashite, "先手●"); else strcpy_s(szSashite, "後手○"); wsprintf((LPWSTR)szBuf, TEXT("差し手 = %s"), szSashite); TextOut(hdc, 30, SHUI + KANKAKU * 14 + 30, (LPCWSTR)szBuf, strlen(szBuf)); wsprintf((LPWSTR)szBuf, TEXT("第 %02d 手終了 現在 %02d 手目待ち"), nTe, nTe + 1); TextOut(hdc, 30, SHUI + KANKAKU * 14 + 50, (LPCWSTR)szBuf, strlen(szBuf)); EndPaint(hWnd, &ps); break;

  • 猫でもわかるWindowsプログラミングの5.2タイピングソフトのプログラムについて

    猫でもわかるWindowsプログラミング第3版の5.2タイピングソフトのプログラムなのですが、 本のプログラムをそのまま書くと、タイプミス!の分岐にはいらないんですが、これは本が間違ってるんでしょうか? 付属のCD-ROMのプログラム(本の方とは少し違う)は正しく動いているようですが、 本に書いてある方がなぜ上手くいかないのかが理解できません。 もし本が間違えているなら、どこが間違っているのか教えていただけると助かります。 下のコードは本に書いてあった方のウィンドウプロージャ部を写したものです。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; MMTIME mm; switch (msg) { case WM_CREATE: srand((unsigned)time(NULL)); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 0, 0, szMondai, lstrlen(szMondai)); TextOut(hdc, 0, 40, szInput, lstrlen(szInput)); if(bSeikai) SetTextColor(hdc, RGB(0,0,0)); else SetTextColor(hdc, RGB(255,0,0)); TextOut(hdc,0,80,szCheck,lstrlen(szCheck)); EndPaint(hWnd, &ps); break; case WM_CHAR: if(wp == VK_SPACE && !bStart) { bStart = TRUE; TypeStart(hWnd); break; } if(bStart == FALSE) return DefWindowProc(hWnd, msg, wp, lp); if(wp == VK_ESCAPE) { lstrcpy(szMondai, TEXT("")); lstrcpy(szInput, TEXT("")); lstrcpy(szCheck, TEXT("")); InvalidateRect(hWnd, NULL, TRUE); bStart = FALSE; break; } wsprintf(szInput, TEXT("あなたの入力=\"%c\""), (int)wp); if(szMondai[6] == szInput[14]) { bSeikai = TRUE; mm.wType = TIME_MS; timeGetSystemTime(&mm, sizeof(MMTIME)); dwEnd = mm.u.ms; wsprintf(szCheck, TEXT("反応時間[%dミリ秒]"), dwEnd - dwStart); TypeStart(hWnd); } else { bSeikai = FALSE; MessageBeep(MB_OK); lstrcpy(szCheck, TEXT("タイプミス!")); } InvalidateRect(hWnd, NULL, TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp,lp)); } return 0; } int TypeStart(HWND hWnd) { int n; MMTIME mm; n = rand() % 26; wsprintf(szMondai, TEXT("問題=\"%c\""), 'a' + n); mm.wType = TIME_MS; timeGetSystemTime(&mm, sizeof(MMTIME)); dwStart = mm.u.ms; InvalidateRect(hWnd, NULL, TRUE); return 0; }

  • Windowsプログラミングでのテキスト保存について

    Windowsプログラミングでのテキスト保存について WindowsAPIを使ってプログラミングをしているのですがコントロールに入力されたテキストを 保存するときにWindows付属のメモ帳のように保存ダイアログボックス上で保存文字コードを 選択できるようにしたいのですがやり方わかる人いましたらどうか教えてください。お願いします。

  • windowsプログラミング

    "猫でもわかるwindowsプログラミング"を読みながらWin32 APIを勉強しているのですが、なかなかうまくいかないところがあります。 モードレスダイアログボックスを表示してコントロールも問題なく行えているのですが、ダイアログボックスのウィンドウについている赤い閉じるボタンが反応を返しません。 自分で作った閉じるボタンでは正常に閉じるのですが、ウィンドウの閉じるボタンを押しても閉じません… ダイアログボックスのボタン類のIDと同様にウィンドウについている閉じるボタンにもIDは存在するのかと思ったのですが、resource.hを見ても書かれていないのでなさそうですね… メインウィンドウであればWM_CLOSEメッセージが送られてきますが、この場合も何かしらのメッセージが送られてきているのでしょうか? Windows7 , Visual Studio 2010 , C言語で書いています。

  • フォントの指定 猫でもわかるwindowsプログラミングより

    猫でもわかるwindowsプログラミングの本で勉強している学生なんですが、第2章の2.4フォントの指定のところでプログラムを打ち込んでコンパイルしたのですがなぜか識別子が見つかりませんというエラーがでてコンパイルできません。どなたかわかる方お願いします。 一応プログラム(CALLBACK関数と論理フォント作成の関数のみ)↓ //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){ static HFONT hFont1, hFont2, hFont3; PAINTSTRUCT ps; HDC hdc; char *szName1 = "○○"; char *szName2 = "▲▲"; switch (msg) { case WM_CREATE: hFont1 = MyCreateFont(40, SHIFTJIS_CHARSET, "HG行書体"); hFont2 = MyCreateFont(40, ANSI_CHARSET, "Fraktur JS"); hFont3 = MyCreateFont(40, SHIFTJIS_CHARSET, "MS 明朝"); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); SelectObject(hdc, hFont1); TextOut(hdc, 0, 0, (LPCTSTR)szName1, (int)strlen(szName1)); SelectObject(hdc, hFont2); TextOut(hdc, 0, 60, (LPCTSTR)szName2, (int)strlen(szName2)); SelectObject(hdc, hFont3); TextOut(hdc, 0, 120, (LPCTSTR)szName1, (int)strlen(szName1)); EndPaint(hWnd, &ps); break; case WM_DESTROY: DeleteObject(hFont1); DeleteObject(hFont2); DeleteObject(hFont3); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } //論理フォントの作成 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)); } エラー内容↓ MyCreateFontの識別子が見つかりません。 論理フォントの関数のFALSEの値が構文エラーで参照できない。

  • SDKでウィンドウの中央に文字列を表示させる方法

    ウィンドウの中央に文字列sを表示させる方法を教えて下さい。 /********************************** WM_PAINTで TCHAR s[80]; HDC hDC; PAINTSTRUCT ps; RECT rc; GetClientRect(hWnd, &rc); hDC = BeginPaint(hWnd, &ps); TextOut(hDC, rc.right / 2, rc.bottom / 2, tcDayTime, lstrlen(s)); EndPaint(hWnd, &ps); return FALSE; ***********************************/ GetClientRect(hWnd, &rc);でウィンドウのサイズを取得し、 TextOutの第2、第3引数で ウィンドウ幅/2、ウィンドウ高さ/2 としていますが、これだと中央から表示されてしまいます。 できれば、ウィンドウのサイズを変更してもウィンドウの中央に表示させたいです。 #VC ++ 6.0 & Win98 & SDK で作成してます。

  • SetWindowText関数について

    プログラミング初心者です。 WINAPI32を用いて、プログラミングに励んでいます。 リソース機能を用いて、親ウインドウのメニューバーからダイアログという形で子ウインドウを開けるようなプログラムを作りました。さらにその子ウインドウ上に、エディットボックスのコントロールを作りました。 例えばそのエディットボックスのIDがIDC_EDIT1なのですが、 子ウインドウを開いた時にすでにそのエディットボックスに数値が入力されているようにしたいのです。 そこで、ダイアログが開かれた時に流れる WM_INITDIALOGのメッセージがきたときに、SetWindowText関数を使えばよいのかな?と思ったのですが、このようなとき第一パラメータにはどのような数値をいれたらエディットボックスに文字列を代入できますか?? IDC-EDIT1といれたら、Struct HWNDに変換してくださいというエラーがでました。 どなたかご教授よろしくお願いいたします。

  • LPTSTR型の変数に文字を格納

    LPTSTR型の変数に文字を格納 現在C言語でWindowsプログラミングを学習しています。 LPTSTR 型の変数にキーボードから入力されて1文字づつ格納したいのですが、 下記のコードであればうまくいきません。 自分がTCHARやLPTSTRのことを根本から理解できていないのが原因だと思うのですが。 LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { static LPTSTR buffer; HDC hdc; PAINTSTRUCT ps; switch(msg){ case WM_CHRAR: *buffer++=(TCHAR)wp; InvalidateRect(hWnd,NULL,TRUE); return 0; case WM_PRINT: hdc=BeginPaint(hWnd,&ps); DrawText(hdc,buffer,-1,&rc,DT_WORDBREAK); EndPaint(hWnd,&ps); return 0; ・ ・ ・ ・

  • Windowsプログラミング

    識別子が無効ですといわれて困ってます。一応打ち込んだものを乗せておきます。VisualC++2008でやりました。 // sample01.cpp #include<windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTACE); BOOL InitInstance(HINSTANCE); TCHAR szClassName[] = TEXT("sample01"); // ウィンドウクラス 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) { MessageBox(NULL, TEXT("GetMessageエラー"), TEXT("Error"), MB_OK); break; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } } // ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndPrec; // プロシージャ名 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 = NULL; // メニュー名 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("猫でもわかるWindowsプログラミング"), 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, UNIT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } 長いですがよろしくお願いします。 return 0; }

  • OpenGLでウィンドウハンドルの取得

    コンソールアプリで作ることが前提です。 glut関数で作成したウィンドウのハンドルを取得し、その画面上に文字を表示しようとTextOutやDrawTextやらを使ってみたんですが、背景色しか表示されません。DrawTextの戻り値が18だったので成功していると思うのですが。どこがおかしいのかご指摘をお願いします。 #include<stdio.h> #include<windows.h> #include<GL/glut.h> HWND hwnd; void display(){ glClearColor(0.5,0.5,0.5,1); glClear(GL_COLOR_BUFFER_BIT); hwnd=GetActiveWindow(); PAINTSTRUCT ps; HDC hdc; RECT rect; LPCSTR str = TEXT("あああ"); GetClientRect(hwnd, &rect); hdc = BeginPaint(hwnd, &ps); SetRect( &rect, 10, 10, 100, 100); TextOut(hdc, 10, 10, str, lstrlen(str));    DrawText(hdc, TEXT("あああ"), -1, &rect,DT_CENTER); EndPaint(hwnd, &ps); glFlush(); } int main(int argc,char **argv){ glutInit(&argc,argv); glutInitWindowSize(640,480); glutCreateWindow("aaa"); glutDisplayFunc(display); glutMainLoop(); return(0); }

専門家に質問してみよう