win32、VC++2005でresource.h内のコントロール色変更がうまくいかない

このQ&Aのポイント
  • win32、VC++2005で開発しております。resource.h内でコントロールの色を変更しようとした際に他のコントロールの色も変化してしまいました。Excelで一括変更する方法を試したが、コントロールの色が散らばってしまいました。
  • resource.hのID名は変更せずに複数のダイアログ画面を作成しているため、IDの重複が問題となっています。各画面ごとにIDを束ねることで見やすさを追求しています。
  • プログラム初心者のため、コントロールが膨大で見づらい状況です。見やすくするための方法やプログラムコーディングの基準についてアドバイスを求めています。
回答を見る
  • ベストアンサー

resource.h

win32、VC++2005で開発しております。 resource.h内の#defineで切ってあるIDの番号が重なっていたため 各コントロールの色を変更しようとすると同時に他のコントロールの色も変化してしまいました。 かなりのコントロール量だったのでExcelで開いて一気にインクリメントして再ロードするとコントロールの色が散らばってしまいました・・・ この方法はまずかったでしょうか? 色の変更は case WM_CTLCOLORSTATIC : i = GetWindowLong( (HWND)lParam, GWL_ID ); hdc = BeginPaint(hDlg, &ps); if ( i == IDC_ICHI_S ) { //位置出し SetTextColor( (HDC)wParam, RGB( 255, 255, 255 ) ); SetBkColor( (HDC)wParam, RGB( 0, 0, 255 ) ); return (LRESULT)CreateSolidBrush( RGB( 0, 0, 255 )); } if ( i == IDC_NIN_S ) { //任意(未知)の器械点セット SetTextColor( (HDC)wParam, RGB( 255, 255, 255 ) ); SetBkColor( (HDC)wParam, RGB( 0, 128, 0 ) ); return (LRESULT)CreateSolidBrush( RGB( 0, 128, 0 )); } EndPaint(hDlg, &ps); こんな感じでやってます。 resource.hのID名は変更してませんのでダイアログはちゃんと開きます。 resource.hの#defineの値は自動で割り振られたと思いますが、ダイアログ画面を複数書いて値が重複するのは変だと思いますがどうなんですか? また、見やすいように各画面ごとにIDを束ねようとしてるのですが普通なことでしょうか? プログラムコーディングの基準?常識?がよくわからないのでお願いします。 コントロールも膨大になってきて見ずらいです。 通常はどのように見やすくするのでしょうか? プログラム初心者なので分かり易い指摘でお願いします。

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

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

★アドバイス ・致命的な間違いを指摘します。  WM_CTLCOLORSTATIC 内で BeginPaint、EndPaint は使ってはいけません。  その代わりに wParam を HDC にキャストすればデバイスコンテキストの  ハンドルがもらえます。分かっていますよね。  それなのに BeginPaint、EndPaint を記述しているのはおかしいです。 >ダイアログ画面を複数書いて値が重複するのは変だと思いますがどうなんですか?  ↑  思いません。  ダイアログAでボタン1があった場合 IDC_BUTTON1 を使います。  ダイアログBでもボタン1があった場合 IDC_BUTTON1 を使います。  IDC_BUTTON1 がダイアログで重複していても問題ないですし、変とも思いません。  ただし、タブコントロールなどに使うダイアログをコントロールとした場合は  各画面ごとに ID を束ねるようにしたり、重複しないようにします。  これはタブコントロールやプロパティシートのダイアログ・プロシージャを  1つに共通化したいために重複をしないためです。  (あまりにもコントロールの数が多い場合はダイアログ毎にプロシージャを用意します) ・リソースIDの値を変更した場合はリビルドしないといけません。  上手くリビルドできない場合は *.obj、*.exe などのファイルを削除してから  ビルド(コンパイル)を行います。ファイルを複数に分割している場合はこのようにします。

glee_sss
質問者

お礼

回答ありがとうございます。 ほとんどが何処かのサイトから参考にして書いたのですが、 確かにHDCにキャストしてあるのにおかしいですね。 リビルドすればうまく行きました。 > (あまりにもコントロールの数が多い場合はダイアログ毎にプロシージャを用意します) プロシージャを分ける場合はファイルも別にするのが普通なんですか? 別にしないと結局コードが長くて見ずらいですよね?

関連するQ&A

  • エディットコントロール入力時の背景色変更について

    Win32 APIについて質問です。(前回質問させてもらった続きです) Microsoft Visual Studio .NET 2002、XP、API 2つのエディットコントロール(hEdit_DatDelay、hEdit_DatDelay2) のことなんですが、2つのエディットコントロールは、「0」を入力し フォーカスを外すと、メッセージを表示し、背景色を赤色表示する。 その後「0」以外の値を入力しフォーカスを外すと、背景色が元の 白色に戻る仕様を予定しています。 次のコードのように作成すると、両方のエディットコントロールで、 「0」を入力しフォーカスを外すとメッセージは表示しますが、 背景色は白色のままとなります。 (3)、(4)の行をコメントアウトすると「hEdit_DatDelay」のみ赤色と なります。 (1)~(4)のあたりが何か問題があるのではと思っているのですが、 お手上げ状態です。 ご存じの方すいませんがご教授の程よろしくお願いします。 //・・・ switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId) { //・・・ case IDC_DAT_DELAY: //一つ目のエディットコントロール switch (wmEvent) { case EN_KILLFOCUS: GetWindowText(hEdit_DatDelay , DatDelay , 4); DatDelay_int = atoi(DatDelay); if(DatDelay_int == 0) { Bck_Red = 1; MessageBox(hWnd, (PCTSTR)Text, _T("ftp"), MB_OK); SetFocus(hEdit_DatDelay); break; }else{ Bck_Red = 3; //(1) InvalidateRect(hEdit_DatDelay, NULL, TRUE); //(2) break; } break ; } break; case IDC_DAT_DELAY2://二つ目のエディットコントロール switch (wmEvent) { case EN_KILLFOCUS: GetWindowText(hEdit_DatDelay2 , DatDelay2 , 4); DatDelay_int2 = atoi(DatDelay2); if(DatDelay_int2 == 0) { Bck_Red = 2; MessageBox(hWnd, (PCTSTR)Text, _T("ftp"), MB_OK); SetFocus(hEdit_DatDelay2); break; }else{ Bck_Red = 4; //(3) InvalidateRect(hEdit_DatDelay2, NULL, TRUE); //(4) break; } break ; } break; //・・・ case WM_INITDIALOG: //ブラシの作成 RedBrush = CreateSolidBrush(RGB(255,0,0));// 赤ブラシ ClearBrush = (HBRUSH)GetStockObject( NULL_BRUSH );//透明 break; case WM_CTLCOLOREDIT: { switch(Bck_Red) { case 1: if ((HWND)lParam == GetDlgItem(hWnd, IDC_DAT_DELAY)) { SetBkColor((HDC)wParam, RGB(255,0,0)); //背景を赤色 return (LRESULT)RedBrush; } break; case 2: if ((HWND)lParam == GetDlgItem(hWnd, IDC_DAT_DELAY2)) { SetBkColor((HDC)wParam, RGB(255,0,0)); //背景を赤色 return (LRESULT)RedBrush; } break; case 3: SetBkColor( (HDC)wParam, GetSysColor( COLOR_WINDOW ) ); return (LRESULT)ClearBrush; break; case 4: SetBkColor( (HDC)wParam, GetSysColor( COLOR_WINDOW ) ); return (LRESULT)ClearBrush; break; default: break; } } break;

  • resource.hに残る不要な#define

    VC++6.0でコントロールを作りプロパティからIDを変更するとresource.hに初期の宣言が残ります。 コントロールが多いと#defineが列挙され 見にくいのですが無視しても構わないのでしょうか? また100個近くあるチェックボックスの初期状態を保持しておく方法で何かいい方法はありませんか? iniファイルかレジストリか、どう格納するのが良いか知りたいです。

  • エディットボックス

    VC++、APIでwindowsプログラムを書いています。ダイアログボックスで質問があります。 case WM_INITDIALOG: SetDlgItemText(hDlg, IDC_EDIT1, "0"); return TRUE; で読み取り専用エディットボックス内に初期値を書き case WM_CTLCOLORSTATIC: { HDC hdc = (HDC)wParam ; SetTextColor( hdc, RGB( 255, 255, 255)) ;// 白色 SetBkMode(hdc, TRANSPARENT); // 背景を透過 return (BOOL)(HBRUSH)GetStockObject(NULL_BRUSH) ; } でダイアログボックス内のスタティックテキストと読み取り専用エディットボックスの背景を同時に透過させているのですが、エディットボックス内の文字を void ddd( HWND hDlg, int xxx) { char ttt[100]; sprintf(ttt,"%d",xxx); SetDlgItemText(hDlg, IDC_EDIT1, ttt); return ; } で書き換えると古いテキストが残ったように表示されます(背景に色を指定すれば古いテキストは残らない)。 うまく表示させるにはどういった方法があるでしょうか? ご存知の方、よろしくお願いします。 ちなみにダイアログボックスにはビットマップが貼ってあります。

  • win32プログラム

    以下のコードで 1、CreateSolidBrush()で色設定しつつ 2、SelectObject()で、前のブラシのハンドルを受け取り 3、DeleteObject()で前の色を削除。     これらを一つの文で行っているんですか?  これらの記述は、一般的な方法ですか?  ブラシ(CreateSolidBrush()など)特に削除しなくても、  プログラム 出来る気がしますが、  削除しないと何か問題はありますか?  教えてください。 SelectObject ( hdc,CreateSolidBrush( RGB( 255,0,255))); Polygon(hdc,a,6); DeleteObject( SelectObject( hdc, CreateSolidBrush(RGB(55,77,33)))); PolyPolygon(hdc,b,d,2); DeleteObject( SelectObject(hdc, GetStockObject(WHITE_BRUSH)));

  • コントロールの色の変更

    初歩的な質問で申し訳ありません。 色々なHPを徘徊して調べているのですが、どうしてもうまくいきません。 コードはメッセージループに次のように記述しています。 --------------------------------------------------------- case WM_CTLCOLORBTN:   // 白色のブラシハンドルを返す   return (LRESULT)GetStockObject(WHITE_PEN); case WM_CTLCOLORSTATIC:   SetTextColor((HDC)wParam, RGB(255, 255, 255));   // 黒色のブラシハンドルを返す   return (LRESULT)GetStockObject(BLACK_PEN); --------------------------------------------------------- これでボタンは白、スタティックは黒地に白文字で表示されると思ったのですが、 ボタンは色が何も変わらず、スタティックは文字の周りを囲むように黒くなり、 肝心の文字の地は白のままでした。 解決策を知っている方、どうか教えていただけませんか? ちなみに、MFCは諸事情により使用できません。

  • リストビューに色はつかない?

    CreateWindowEx を使ったリストビュー(WC_LISTVIEW) についてなんですが、 マクロの、ListView_InsertItem (hList, &item) で、リストに追加しますよね。 その際、カラーはできないのでしょうか。 例えば、一行おきに色を変えるとか・・・ SetTextColor(hdc, RGB(0, 255, 0)) とか SendMessage(hList, WM_SETFONT, (WPARAM)hFont, 0) とかいろいろ 見たり試したりしたのですが、無理なんでしょうか。

  • SelectObjectについて

    SelectObject関数で例えば、 hbrush=SelectObject(hdc,CreatesolidBrush(RGB(0,0,0,)); Rectangle(hdc,0,0,100,100); SelectObject(hdc,hbrush); でやる場合、なぜ、SelectObject(hdc,hbrush);で前の色に戻るはずなのに 戻らないのでしょうか?この意味はあるのでしょうか? 環境はVC++2005です。

  • BCC5.5とBCCFormを使用し、実行ファイルを作成したが、実行できません。

    当方、只今C言語でWin32APIを呼び出し、Windowsアプリを開発中です。 そこで質問なのですが、以下の手順で作業した場合、抽出される実行ファイルが実行できません。 どなたかお分かりになる方、助言の方よろしくお願いします。 1.名前、住所をリッチテキストに入力し、OKボタンを押下後、メッセージボックス  にて”○○さんの住所は○○です”と表示されるソースコードを"bcc32 -W source.cpp"でコンパイル。 2.BCCFormで作成したリソースファイルを"brc32 dialog.rc source.exe"で結合。 3.source.exeを実行するが、動作しない。 ちなみに環境はWindowsXPSP3です。 下記にまず、ソースコードを表示します。 /* ソース */ /* ファイル名 source.cpp */ #if 1 /* ダイアログボックスを出す */ #include <windows.h> #include "Resdialog.h" BOOL CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { DialogBox(hCurInst, "MYDLG", NULL, (DLGPROC)MyDlgProc); return 0; } BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { char szBuf[128], szBuf1[64], szBuf2[64]; switch(msg){ case WM_COMMAND: switch (LOWORD(wp)){ case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE; case IDOK: GetDlgItemText(hDlg, IDC_RICHEDIT102, szBuf1, (int)sizeof(szBuf1)); GetDlgItemText(hDlg, IDC_RICHEDIT103, szBuf2, (int)sizeof(szBuf2)); wsprintf(szBuf, "あなたの住所は%sで、氏名は%sです", szBuf1, szBuf2); MessageBox(hDlg, szBuf, "ダイアログボックス", MB_OK); return TRUE; } return FALSE; } return FALSE; } #endif そして、リソーススクリプトです。 /* リソーススクリプト */ /* ファイル名 dialog.rc */ //----------------------------------------- // BCCForm Ver 2.41 // An Easy Resource Editor for BCC // Copyright (c) February 2002 by ysama //----------------------------------------- #include "Resdialog.h" //---------------------------------- // ダイアログ (MYDLG) //---------------------------------- MYDLG DIALOG DISCARDABLE 0, 0, 270, 117 EXSTYLE WS_EX_DLGMODALFRAME STYLE WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT CAPTION "Form" FONT 8, "MS 明朝" { CONTROL "名前", IDC_LABEL100, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 10, 10, 46, 18 CONTROL "住所", IDC_LABEL101, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 10, 41, 47, 17 CONTROL "", IDC_RICHEDIT102, "RICHEDIT", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 88, 8, 159, 25 CONTROL "", IDC_RICHEDIT103, "RICHEDIT", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 88, 40, 160, 24 CONTROL "OK", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 49, 85, 61, 18 CONTROL "Cancell", IDCANCELL, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 165, 84, 56, 18 } そして、リソースヘッダです。 /* リソースヘッダ */ /* ファイル名Resdialog.h */ //----------------------------------------- // BCCForm Ver 2.41 // Header File for Resource Script File // Copyright (c) February 2002 by ysama //----------------------------------------- //--------------------- // ダイアログリソース //--------------------- // ダイアログ MYDLG #define IDC_LABEL100 100 #define IDC_LABEL101 101 #define IDC_RICHEDIT102 102 #define IDC_RICHEDIT103 103 #define IDCANCELL 105 //--------------------- // メニューリソース //--------------------- //--------------------- // イメージリソース //--------------------- //--------------------- // ストリングテーブル //--------------------- //-------------------- // アクセラレーター //-------------------- //------------------ // ヴァージョン情報 //------------------ 上記のようになってます。 どうかご教授の方、宜しくお願いします。

  • BCC5.5でコンパイル、BCCFormで作成した実行ファイルが実行できません。

    当方、只今C言語でWin32APIを呼び出し、Windowsアプリを開発中です。 そこで質問なのですが、以下の手順で作業した場合、抽出される実行ファイルが実行できません。 どなたかお分かりになる方、助言の方よろしくお願いします。 1.名前、住所をリッチテキストに入力し、OKボタンを押下後、メッセージボックス  にて”○○さんの住所は○○です”と表示されるソースコードを"bcc32 -W source.cpp"でコンパイル。 2.BCCFormで作成したリソースファイルを"brc32 dialog.rc source.exe"で結合。 3.source.exeを実行するが、動作しない。 ちなみに環境はWindowsXPSP3です。 下記にまず、ソースコードを表示します。 /* ソース */ /* ファイル名 source.cpp */ #if 1 /* ダイアログボックスを出す */ #include <windows.h> #include "Resdialog.h" BOOL CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { DialogBox(hCurInst, "MYDLG", NULL, (DLGPROC)MyDlgProc); return 0; } BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { char szBuf[128], szBuf1[64], szBuf2[64]; switch(msg){ case WM_COMMAND: switch (LOWORD(wp)){ case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE; case IDOK: GetDlgItemText(hDlg, IDC_RICHEDIT102, szBuf1, (int)sizeof(szBuf1)); GetDlgItemText(hDlg, IDC_RICHEDIT103, szBuf2, (int)sizeof(szBuf2)); wsprintf(szBuf, "あなたの住所は%sで、氏名は%sです", szBuf1, szBuf2); MessageBox(hDlg, szBuf, "ダイアログボックス", MB_OK); return TRUE; } return FALSE; } return FALSE; } #endif そして、リソーススクリプトです。 /* リソーススクリプト */ /* ファイル名 dialog.rc */ //----------------------------------------- // BCCForm Ver 2.41 // An Easy Resource Editor for BCC // Copyright (c) February 2002 by ysama //----------------------------------------- #include "Resdialog.h" //---------------------------------- // ダイアログ (MYDLG) //---------------------------------- MYDLG DIALOG DISCARDABLE 0, 0, 270, 117 EXSTYLE WS_EX_DLGMODALFRAME STYLE WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT CAPTION "Form" FONT 8, "MS 明朝" { CONTROL "名前", IDC_LABEL100, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 10, 10, 46, 18 CONTROL "住所", IDC_LABEL101, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 10, 41, 47, 17 CONTROL "", IDC_RICHEDIT102, "RICHEDIT", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 88, 8, 159, 25 CONTROL "", IDC_RICHEDIT103, "RICHEDIT", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 88, 40, 160, 24 CONTROL "OK", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 49, 85, 61, 18 CONTROL "Cancell", IDCANCELL, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 165, 84, 56, 18 } そして、リソースヘッダです。 /* リソースヘッダ */ /* ファイル名Resdialog.h */ //----------------------------------------- // BCCForm Ver 2.41 // Header File for Resource Script File // Copyright (c) February 2002 by ysama //----------------------------------------- //--------------------- // ダイアログリソース //--------------------- // ダイアログ MYDLG #define IDC_LABEL100 100 #define IDC_LABEL101 101 #define IDC_RICHEDIT102 102 #define IDC_RICHEDIT103 103 #define IDCANCELL 105 //--------------------- // メニューリソース //--------------------- //--------------------- // イメージリソース //--------------------- //--------------------- // ストリングテーブル //--------------------- //-------------------- // アクセラレーター //--------------------

  • なぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?

    #define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc") #define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc") #define STRCOMMAND TEXT("ボタンが押されました") HWND hButton1; LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam; HDC hDC; if(nCode==HC_ACTION) { hDC = GetDC(pcwpRetStruct->hwnd); switch(pcwpRetStruct->message) { case WM_COMMAND: TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND)); break; case WM_RBUTTONDOWN: TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON)); break; } ReleaseDC(pcwpRetStruct->hwnd, hDC); } return CallNextHookEx(NULL, nCode, wParam, lParam); } LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HHOOK hHook; HDC hDC; switch(uMsg) { case WM_DESTROY: UnhookWindowsHookEx(hHook); PostQuitMessage(0); return 0; case WM_CREATE: hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() ); if(!hHook) MessageBox(NULL, "hooking failed", NULL, MB_OK); hButton1 = CreateWindow( "BUTTON", "hButton1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 40, 100, 20, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL ); return 0; case WM_LBUTTONDOWN: hDC = GetDC(hWnd); TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON)); ReleaseDC(hWnd, hDC); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

専門家に質問してみよう