質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1322閲覧

ダイアログボックスのテキストを親ウィンドウで表示したい

daiking

総合スコア19

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/01/21 07:03

編集2020/01/21 14:15

現在windows apiを勉強中のものです。
やりたいことは

1,登録ボタンを押す
2,テキストエディットが出てくる
3,体重を入力
4,描写ボタンを押す
5,記録した体重が親ウィンドウに表示される(現在の体重は00です)

というような簡単なものを作ろうとしています。自力で4番まではできました。しかし、5を実装しようとすると値を変数に登録していく中で型の違いに悩まされうまくできません。

ダイアログボックス内に記録した体重を表示させることはできました。しかし、親ウィンドウに表示できません。

答えはお答えしていただかなくて結構なのでこんな感じにやるよみたいなアドバイスをいただきたいです。

環境はVisualStudioの最新版です

C

1//source.cpp 2#include <windows.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include <tchar.h> 7 8#include "resource.h" 9 10 11#define BUTTON_ID1 0 12 13// グローバル変数: 14TCHAR szBuf_edit1[1024]; 15 16// このコード モジュールに含まれる関数の宣言を転送します: 17LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM); 18 19LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 20 21char edit_str[256]; 22 23 24int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 25 PSTR lpCmdLine, int nCmdShow) 26{ 27 28 HWND hwnd; 29 MSG msg; 30 WNDCLASS winc; 31 32 winc.style = CS_HREDRAW | CS_VREDRAW; 33 winc.lpfnWndProc = WndProc; 34 winc.cbClsExtra = winc.cbWndExtra = 0; 35 winc.hInstance = hInstance; 36 winc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 37 winc.hCursor = LoadCursor(NULL, IDC_ARROW); 38 winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 39 winc.lpszMenuName = NULL; 40 winc.lpszClassName = TEXT("KITTY"); 41 42 if (!RegisterClass(&winc)) return -1; 43 44 hwnd = CreateWindow( 45 TEXT("KITTY"), TEXT("体重管理アプリ"), 46 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 47 CW_USEDEFAULT, CW_USEDEFAULT, 48 CW_USEDEFAULT, CW_USEDEFAULT, 49 NULL, NULL, hInstance, NULL 50 ); 51 52 CreateWindow( 53 TEXT("BUTTON"), TEXT("記録する"), 54 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 55 0, 0, 100, 50, 56 hwnd, (HMENU)BUTTON_ID1, hInstance, NULL 57 ); 58 59 if (hwnd == NULL) return -1; 60 while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); 61 return msg.wParam; 62} 63 64LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { 65 66 switch (msg) { 67 case WM_DESTROY: 68 PostQuitMessage(0); 69 return 0; 70 71 case WM_COMMAND: 72 73 switch (LOWORD(wp)) { 74 case BUTTON_ID1: 75 DialogBox((HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE), "DIALOG_BOX", hwnd, (DLGPROC)DialogProc); 76 } 77 return 0; 78 79 80 } 81 return DefWindowProc(hwnd, msg, wp, lp); 82} 83 84LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { 85 switch (msg) { 86 87 case WM_CLOSE: 88 EndDialog(hwnd, IDOK); 89 break; 90 case WM_COMMAND: 91 switch(LOWORD(wp)){ 92 case IDC_BUTTON1: 93 GetDlgItemText(hwnd, IDC_EDIT1, 94 (LPTSTR)szBuf_edit1, (int)sizeof(szBuf_edit1)); 95 SetDlgItemText(hwnd, IDC_STATIC1, (LPCTSTR)szBuf_edit1); 96 } 97 break; 98 } 99 return FALSE; 100} 101 102 103

//resource.rc

DIALOG_BOX DIALOG 0, 0, 170, 62
FONT 9, "MS UI Gothic"
CAPTION "ダイアログ"
BEGIN
EDITTEXT IDC_EDIT1, 2, 2, 166, 13, ES_AUTOHSCROLL
PUSHBUTTON "描写", IDC_BUTTON1, 132, 17, 26, 13
LTEXT "", IDC_STATIC1, 4, 40, 114, 8
END

resource.h

define IDC_EDIT1 1001
define IDC_BUTTON1 1002
define IDC_STATIC1 1003
ifndef IDC_STATIC
define IDC_STATIC -1

endif

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takabosoft

2020/01/21 09:02

> 5を実装しようとすると値を変数に登録していく中で型の違いに悩まされうまくできません。 その試したコードとエラーを載せてください。 また、ソースの整形がうまくいっていないので、質問記事を編集してください。
dodox86

2020/01/21 09:59 編集

ソースの整形を切に願います。。。(#defineなどのプリプロセッサマクロ部分がマークダウンで見出しになってしまっています)
daiking

2020/01/21 14:10

すみません。すぐに変えます。
guest

回答1

0

ベストアンサー

「型の違いでうまくいかない」と言われているのは恐らく、TCHAR szBuf_edit1[]char型の混在、プロジェクトの設定でのUnicode文字セットとマルチバイト文字セットのビルドに関してGetDlgItemTextSetDlgItemTextの使い方で混乱されていることを指しているのだと思いました。Windows APIにはUnicode文字(ワイド文字)とAnsi文字(≒マルチバイト文字)用で分かれているAPIがあります。GetDlgItemTextなどもそうで、これはGetDlgItemTextWGetDlgItemTextAと分かれます。GetDlgItemTextは実際にはマクロで、Unicodeビルドのマルチバイト文字セットのビルドで自動的にそれぞれのAPIに変換されます。

本質問の主旨が単に「うまく変換できない」と言うことなのであれば、下記のコードのように修正すればWndProcDlgProcでグローバル変数TCHAR szBuf_edit1[]を共有できます。(コード中の"NOTE:"のコメントを参考にしてください)

C++

1#include <windows.h> 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#include <tchar.h> 6 7#include "resource.h" 8 9#define BUTTON_ID1 0 10 11// グローバル変数: 12// NOTE1: 念の為'\0'で初期化しておく 13TCHAR szBuf_edit1[1024] = { _T('\0') }; 14 15LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM); 16 17LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 18 19// NOTE2: 使わないので消しておく 20//char edit_str[256]; 21 22int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 23 PSTR lpCmdLine, int nCmdShow) 24{ 25 HWND hwnd; 26 MSG msg; 27 WNDCLASS winc; 28 29 winc.style = CS_HREDRAW | CS_VREDRAW; 30 winc.lpfnWndProc = WndProc; 31 winc.cbClsExtra = winc.cbWndExtra = 0; 32 winc.hInstance = hInstance; 33 winc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 34 winc.hCursor = LoadCursor(NULL, IDC_ARROW); 35 winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 36 winc.lpszMenuName = NULL; 37 winc.lpszClassName = TEXT("KITTY"); 38 39 if (!RegisterClass(&winc)) return -1; 40 41 hwnd = CreateWindow( 42 TEXT("KITTY"), TEXT("体重管理アプリ"), 43 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 44 CW_USEDEFAULT, CW_USEDEFAULT, 45 CW_USEDEFAULT, CW_USEDEFAULT, 46 NULL, NULL, hInstance, NULL 47 ); 48 49 CreateWindow( 50 TEXT("BUTTON"), TEXT("記録する"), 51 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 52 0, 0, 100, 50, 53 hwnd, (HMENU)BUTTON_ID1, hInstance, NULL 54 ); 55 56 if (hwnd == NULL) return -1; 57 while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); 58 return msg.wParam; 59} 60 61LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { 62 63 switch (msg) { 64 case WM_DESTROY: 65 PostQuitMessage(0); 66 return 0; 67 68 case WM_COMMAND: 69 70 switch (LOWORD(wp)) { 71 case BUTTON_ID1: 72 // NOTE3: 73 // Unicodeビルドでもマルチバイト文字ビルドでも使えるよう、_T()マクロを使用する 74 //DialogBox((HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE), "DIALOG_BOX", hwnd, (DLGPROC)DialogProc); 75 DialogBox((HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE), _T("DIALOG_BOX"), hwnd, (DLGPROC)DialogProc); 76 } 77 return 0; 78 } 79 80 return DefWindowProc(hwnd, msg, wp, lp); 81} 82 83LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { 84 switch (msg) { 85 86 case WM_CLOSE: 87 EndDialog(hwnd, IDOK); 88 break; 89 case WM_COMMAND: 90 switch (LOWORD(wp)) { 91 case IDC_BUTTON1: 92 // NOTE4: 93 // キャストする必要は無い 94 //GetDlgItemText(hwnd, IDC_EDIT1, 95 // (LPTSTR)szBuf_edit1, (int)sizeof(szBuf_edit1)); 96 //SetDlgItemText(hwnd, IDC_STATIC1, (LPCTSTR)szBuf_edit1); 97 98 // NOTE5: 99 // GetDlgItemTextの第4引数は「バイト数」ではなく「文字数」なので、 100 // UNICODEビルド用に文字数に変換しておく 101 GetDlgItemText(hwnd, IDC_EDIT1, 102 szBuf_edit1, sizeof(szBuf_edit1) / sizeof(szBuf_edit1[0])); 103 SetDlgItemText(hwnd, IDC_STATIC1, szBuf_edit1); 104 } 105 break; 106 } 107 return FALSE; 108}

ただ、今のままではグローバル変数に保存できるだけです。例えば"DIALOG_BOX"ダイアログでボタンを押したときにメインウィンドウにリアルタイムに文字表示をしたい、とのような要件なのであれば、ダイアログボックスのボタン押下と同時にPostMessageSendMessageでメインウィンドウに通知し、メインウィンドウ側ではダイアログボックスを閉じることなく、そのメッセージの受信タイミングで描画する、とのようなこともできます。TCHAR szBuf_edit1[]のようなグローバル変数名をもろに使いたくないのであれば、DialogBoxParamでダイアログボックスを作成するようにし、独自の構造体のアドレスをそのパラメーターに渡すなどすれば良いでしょう。

投稿2020/01/21 09:55

dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/01/21 10:08

質問の主旨とは違うのでコメントのみですが、DlgProc、ダイアログプロシージャでは本来は自分でメッセージを処理した場合は、TRUEを返します。つまり、WM_COMMANDを処理したら return TRUEとすべきでしょう。ダイアログプロシージャの関数シグニチャはウィンドウプロシージャとは少し違っていて、本来はINT_PTR Dlgproc(HWND Arg1,UINT Arg2,WPARAM Arg3,LPARAM Arg4 )です。(大差ないですけど)
daiking

2020/01/21 14:29

回答ありがとうございます。なるほどこのようにすれば型の違いに悩まされないのですね。型をしっかりと理解していないのでもう一度勉強しなおそうと思います。 質問の件に戻るのですが、PostMessageでWM_PAINTをWndProcに渡して TextOut()で表示しようと思っているのですがこの方法だと表示されませんでした。該当するソースを載せます。 case WM_PAINT: hdc = BeginPaint(hwnd, &ps); TextOut(hdc, 100, 100, szBuf_edit1, strlen(szBuf_edit1)); EndPaint(hwnd, &ps); SendMessage(hwnd, WM_PAINT, 0, 0);をIDC_BUTTONの最後に書きました。 ちなみにpsはWndProc内に定義されています。
dodox86

2020/01/21 16:04 編集

WM_PAINTメッセージを直接送っても描画はできません。WM_PAINTは、Windows自身が送るもので、そういう場合は何らかのタイミングでInvalidateRectでウィンドウの無効領域を人為的に生成し、WM_PAINTが自然に発生するようにします。そのタイミングを通知するためにダイアログボックスのボタンを押下したときにSendMessageやPostMessageを使う訳ですが、簡易にWM_COMMANDを使うとか、WM_APPをもとに独自メッセージを定義して通知するようにします。WM_APPをもとにした独自メッセージにするなら #define WM_APPTEST (WM_APP+10) // +10は深い意味は無いです。WM_APPのリファレンス参照のこと ...DlgProcで // ボタン押下時、親であるメインウィンドウにWM_APPTESTをポスト。 // ※SendMessageだとよりリアルタイム感がある。 PostMessage(GetParent(hwnd), WM_APPTEST, 0, 0); return 0; ...WndProcで case WM_APPTEST: // 「文字列の更新があった」と認識する RECT rect; GetClientRect(hwnd, &rect); InvalidateRect(hwnd, &rect); // クライアント領域を無効化 UpdateWindow(hwnd); // こうすると、即、WM_PAINTが自分に送られる。 return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); TextOut(hdc, 100, 100, szBuf_edit1, strlen(szBuf_edit1)); EndPaint(hwnd, &ps); return 0; などとなります。ちなみにTCHARの文字列なら、strlenより_tcslenの方が適切です。
daiking

2020/01/22 05:37

やりたいことがやっとできるようになりました。WM_PAINTのことなど参考になりました。本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問