#include <windows.h>
#include "resource.h"
//#include <tchar.h>
char szClassName[] ="dialog02"; //ウィンドウクラス
//POINTS start,end,old_end;
HINSTANCE hInst; //インスタンスハンドル
HWND hDlg; //モードレスダイアログボックスのハンドル
char szName[32]; //ダイアログボックスから入力された文字列
HWND hMain;
//ダイアログプロシージャ
BOOL CALLBACK MyDlgProc(HWND hDlg,UINT msg, WPARAM wp, LPARAM lp)
{
static HWND hParent;
// static char szName[32]; //ダイアログボックスから入力された文字列
switch(msg){
case WM_INITDIALOG:
hParent = GetParent(hDlg);
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 IDC_CLEAR:
SetDlgItemText(hDlg,IDC_EDIT1,"");
return TRUE;
case IDC_CLOSE:
DestroyWindow(hDlg);
return TRUE;
}
return FALSE;
case WM_CLOSE:
DestroyWindow(hDlg);
return TRUE;
}
return FALSE;
}
void DrawRect(HWND hWnd,POINTS beg,POINTS end)
{
HDC hdc;
hdc = GetDC(hWnd);
SetROP2(hdc,R2_NOT);
MoveToEx(hdc,beg.x,beg.y,NULL);
LineTo(hdc,end.x,beg.y);
LineTo(hdc,end.x,beg.y);
LineTo(hdc,end.x,end.y);
LineTo(hdc,beg.x,end.y);
LineTo(hdc,beg.x,beg.y);
LineTo(hdc,end.x,end.y);
return;
}
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp)
{
char szBuf[64];
HDC hdc;
// static BOOL bDraw;
int kakunin;
static HMENU hMenu;
PAINTSTRUCT ps;
// static char szName[32]; //ダイアログボックスから入力された文字列
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_COMMAND:
switch(LOWORD(wp)){
case IDM_END:
SendMessage(hWnd,WM_CLOSE,0,0);
break;
case IDM_HELP:
MessageBox(hWnd,
"Copyright(C)2004 Y.Kumei\nメニュー",
"about",MB_OK);
break;
case IDM_DLG:
hDlg = CreateDialog(hInst,"MYDLG",hWnd,(DLGPROC)MyDlgProc);
ShowWindow(hDlg,SW_NORMAL);
//DialogBoxParam(hInst,"MYDLG",hWnd,(DLGPROC)MyDlgProc,(LPARAM)IDC_EDIT1);
break;
case IDM_CLOSEDLG:
DestroyWindow(hDlg);
break;
}
case WM_PAINT:
if(strcmp(szName,"")==0)
//strcpy(szBuf,"まだ名前の入力はありません"); //警告表示が出るから
strcpy_s(szBuf,"まだ名前の入力はありません");
else
wsprintf(szBuf,"入力された氏名は%sさんです",
szName);
hdc=BeginPaint(hWnd,&ps);
TextOut(hdc, 10, 10, szBuf,(int)strlen(szBuf));
EndPaint(hWnd,&ps);
break;
case WM_RBUTTONDOWN:
kakunin = MessageBox(hWnd,"終了しますか?","終了確認",MB_YESNO);
if(kakunin == IDYES){
DestroyWindow(hWnd);
}
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;
}
//ウィンドウクラスの登録
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,
//タイトルバーにこの名前が表示されます
"猫でもわかるダイアログボックス",
WS_OVERLAPPEDWINDOW, //ウィンドウの種類
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
CW_USEDEFAULT,//CW_USEDEFAULT, //幅
CW_USEDEFAULT,//CW_USEDEFAULT, //高さ
NULL, //親ウィンドウのハンドル、親を作る時は、NULL
NULL, //メニューハンドル、クラスメニュー
//使う時は、NULL
hInst, //インスタンスハンドル
NULL);
if(!hWnd)
return FALSE;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
hMain = hWnd;
return TRUE;
}
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){
// MessageBox(NULL,"GetMessageエラー","Error",MB_OK);
break;
}else{
if(!hDlg || !IsDialogMessage(hDlg,&msg)){
if(!TranslateAccelerator(hMain,hAccel,&msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
return (int)msg.wParam;
}
ダイアログボックス上のエディットコントロールなどに入力れたデータをメインウィンドウで利用したい場合、グローバル変数を利用しなくてはなりません。これでは、グローバル変数うがどんどん増えてしまいます。これを解決する方法としてDialogBoxParamを使用しますと記載しています。
ネットでいろいろ見えていますがコーディング方法がわからないのでご教授頂ければ幸いです。
C言語ですか(質問)。C++を使うとDLGとそれが扱うデータをひとくくりにして
寿命をコントロールしやすいのでDialogBoxParam()を使う場面はだいぶ減ります。
詳しくは解説しませんが、
1.DialogBoxParam()の、第5引数に任意の32bit値を渡す。
2.受け取り側の当該DLGのコールバックは、
WM_INITDIALOGの時のLPARAMに、先の32bit値を受け取ることができる。
3.当たり前だが、この32bit値はある構造を持つデータのポインタでもOK。
という仕組みです。以上の事から、以下の制限があります。
4.受け渡すデータ(構造体のポインタなど)の寿命は、
受け取り側のDLGの寿命より長くなくてはならない。
つまり、ローカルな変数など、スコープを抜けると
なくなっちゃうような物を渡してはだめなわけですね。
以上の仕組みを疑似的コードにすると
// 主データ構造
typedef struct DATA_MAIN{
int data1;
int data2;
}DATA_MAIN;
DATA_MAIN DataMain;// 主データのインスタンス
// 主ウインドウコールバック
WndProc(...){
:
DialogBoxParam( hInst,"MYDLG",hWnd,
(DLGPROC)MyDlgProc, (LPARAM)&DataMain);
:
}
// DLG のコールバック
MyDlgProc(HWND hDlg,UINT msg, WPARAM wp, LPARAM lp){
static DATA_MAIN * pDatatMain_for_DLG;
switch( msg){
case WM_INITDIALOG:
// 主データのポインタを取得
pDatatMain_for_DLG = ( DATA_MAIN *)lp;
// Editにデータを設定
SetDlgItemInt(hDlg,ID_EDIT1,pDatatMain_for_DLG->data1, TRUE);
break;
case IDOK:
// Editの設定値を取得し、主データに戻す
pDatatMain_for_DLG->data1
= GetDlgItemInt(hDlg,ID_EDIT1,NULL,TRUE);
EndDialog(...);
break;
}
}