• ベストアンサー

オプションウィンドウ作成について

オプションウィンドウ作成について質問です。 メインのウィンドウがあって、 オプションをクリックするとオプションウィンドウが 開くというものを作りたいのですが、 どうすれば出来るのでしょうか? ちなみに、実行ファイルは1つにしたいので、 別のプロジェクトは作らないようにしたいです。 開発環境 XP Visual Studio 2005 C、C++

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

  • ベストアンサー
回答No.4

 こんばんは。補足頂きました。  ダイアログリソースが無いから開かないのでしょう。リソーススクリプト無しでプロパティシートを使うのは自殺行為の様なものです。  非常に厄介なモノなので、リソーススクリプトは使った方が無難です。 #include<windows.h> #include<tchar.h> #include"resource.h" #pragma comment(lib, "comctl32.lib") static HPROPSHEETPAGE s_hPage[2] = {NULL, NULL}; /*必須ではない //プロパティシートコールバック int CALLBACK PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) { switch(uMsg) { case PSCB_INITIALIZED : break; case PSCB_PRECREATE : break; } return 0; } //プロパティシートページコールバック UINT CALLBACK PropSheetPageProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp) { const LPNMHDR pnmh = (LPNMHDR)ppsp->lParam; switch(uMsg) { case WM_NOTIFY: if(pnmh->code == PSN_QUERYCANCEL) { } return FALSE; } return FALSE; } */ //プロパティダイアログ const PROPSHEETHEADER InitPropHDR(HWND hParent, HINSTANCE hInst, LPCTSTR pszTitle, HPROPSHEETPAGE phpage[], INT nPages, PFNPROPSHEETCALLBACK pfnCallback = NULL) { PROPSHEETHEADER psh = {sizeof(PROPSHEETHEADER)}; psh.dwFlags = PSH_DEFAULT | PSH_PROPTITLE;// | PSH_MODELESS; psh.dwFlags |= pfnCallback != NULL ? PSH_USECALLBACK : 0; psh.hwndParent = hParent; psh.hInstance = hInst; psh.pfnCallback = pfnCallback;//無くてもよい psh.pszCaption = pszTitle;//プロパティダイアログのタイトル psh.phpage = phpage;//ページハンドル配列の先頭 psh.nPages = nPages;//ページの個数 return psh; } //プロパティシートページ const PROPSHEETPAGE InitPropPage(HINSTANCE hInst, LPCTSTR pszTitle, UINT uiDialogID, UINT uiIconID, DLGPROC pfnDlgProc, LPFNPSPCALLBACK pfnCallback = NULL, LPARAM lParam = 0) { PROPSHEETPAGE psp = {sizeof(PROPSHEETPAGE)}; psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEICONID; psp.dwFlags |= pfnCallback != NULL ? PSP_USECALLBACK : 0; psp.pszTitle = pszTitle;//ページのタイトル psp.pszIcon = MAKEINTRESOURCE(uiIconID);//アイコンのID psp.pszTemplate = MAKEINTRESOURCE(uiDialogID);//ダイアログのID psp.hInstance = hInst; psp.pfnDlgProc = pfnDlgProc;//ダイアログプロシージャ psp.pfnCallback = pfnCallback;//無くてもよい psp.lParam = lParam;//無くてもよい return psp; } //ダイアログ1 INT WINAPI DlgProc1(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 0; } //ダイアログ2 INT WINAPI DlgProc2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 0; } //設定ウィンドウを開く static void InitPage(HWND hParent, HPROPSHEETPAGE ahPage[], int count) { HINSTANCE hInstance = ::GetModuleHandle(NULL); LPCTSTR aTitles[2] = {TEXT("Dialog1"), TEXT("Dialog2")}; UINT auiIconID[2] = {0, 0}; UINT auiDlgID[2] = {IDD_DIALOG1, IDD_DIALOG2}; DLGPROC aProc[2] = {::DlgProc1, ::DlgProc2}; for(int i = 0; i < count; ++i) { PROPSHEETPAGE page = ::InitPropPage(hInstance, aTitles[i], auiDlgID[i], auiIconID[i], aProc[i]); ahPage[i] = ::CreatePropertySheetPage(&page); } } //ウィンドウクラス登録 static ATOM Regist(LPCTSTR szClassName, WNDPROC wndProc) { WNDCLASSEX wndclass = {sizeof(wndclass)}; wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szClassName; wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); wndclass.hInstance = ::GetModuleHandle(NULL); wndclass.style = 0; wndclass.lpfnWndProc = wndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; return ::RegisterClassEx(&wndclass); } //ウィンドウを作成して開く static HWND OpenWindow(LPCTSTR szClassName, LPCTSTR szTitleName, INT w, INT h) { HINSTANCE hInst = ::GetModuleHandle(NULL); HWND hWnd = ::CreateWindowEx(WS_EX_TOOLWINDOW, szClassName, szTitleName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT, w, h, NULL, NULL, hInst, NULL); return hWnd; } //開いた static LRESULT OnCreate(HWND hWnd) { return 0; } //xボタン static LRESULT OnClose(HWND hWnd) { ::DestroyWindow(hWnd); return 0; } //ウィンドウが無くなる static LRESULT OnDestroy(HWND hWnd) { ::PostQuitMessage(0); return 0; } //左クリック static LRESULT OnLButtonDown(HWND hWnd) { ::InitPage(hWnd, s_hPage, 2); PROPSHEETHEADER header = ::InitPropHDR(hWnd, ::GetModuleHandle(NULL), TEXT("hello world"), s_hPage, 2); HWND hWndSheet = (HWND)::PropertySheet(&header); //消してはいけない // for(int i = 0; i < 2; ++i) // ::DestroyPropertySheetPage(s_hPage[i]); return 0; } LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE: return ::OnCreate(hWnd); case WM_CLOSE: return ::OnClose(hWnd); case WM_DESTROY: return ::OnDestroy(hWnd); case WM_LBUTTONDOWN: return ::OnLButtonDown(hWnd); } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, LPSTR lpCmdLine, int nShowCmd) { MSG msg; const TCHAR tstrClassName[] = TEXT("test resize frame"); const TCHAR tstrTitleName[] = TEXT("title"); //初期化 ::InitCommonControls(); //ウィンドウクラスの登録 ::Regist(tstrClassName, &::WndProc); //ウィンドウを作成して開く HWND hWnd = ::OpenWindow(tstrClassName, tstrTitleName, 800, 600); //ウィンドウの表示 ::ShowWindow(hWnd, SW_SHOW); //メッセージ回転 while(::GetMessage(&msg, NULL, 0, 0) == TRUE) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } //終了 return msg.wParam; }

noname#154655
質問者

お礼

出来ました。 リソーススクリプトが無かったから出来なかっただけだったんですね。 リソーススクリプト無しでは難しいんですか。 ですけど出来てよかったです。 ソースまで付けて頂きありがとうございます。

その他の回答 (3)

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

ソースコードを掲載してもらうと早いです。 あとは、丸写しのプログラムを作ってみて動作を確認後に動かないプログラムと差を確認しましょう。動く見本があるんだから、そんなに難しい問題ではないはずですよ。

noname#154655
質問者

お礼

補足欄をすでに使っているのでこちらに書かせていただきます。 紹介して頂いたサイトのプログラムをそのまま使って動かしてみました。 そしたら、同じようにウィンドウは出るのですが、 すぐに消えました。 サイトを見る限りでは、リソースファイルを使うようなのですが、 リソースファイルを作っていないのですが、 それが原因なのでしょうか? ちなみに、サイトのプログラムをそのまま使おうとしたら エラーが出たので、「#pragma comment(lib, "comctl32.lib") 」 を入れました。 リソースファイルは使わないようにしたいのですが、 どうすればいいのでしょうか?

noname#154655
質問者

補足

ソースコード全てだと長いので一部だけ載せます。 不足がありましたら追加で書きます。 LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { switch (*message) { case WM_CREATE : return (main_window->WindowCreate(&hwnd, &message, &wparam, &lparam)); case WM_NCRBUTTONDOWN : return (main_window->WindowRightClick(&hwnd, &message, &wparam, &lparam)); default : return (main_window->Else(&hwnd, &message, &wparam, &lparam)); } return (DefWindowProc(hwnd, message, wparam, lparam)); } LRESULT MainWindow::WindowCreate(HWND *hwnd, UINT *message, WPARAM *wparam, LPARAM *lparam) { InitCommonControls(); return (0); } LRESULT MainWindow::WindowRightClick(HWND *hwnd, UINT *message, WPARAM *wparam, LPARAM *lparam) { PROPSHEETPAGE psp; PROPSHEETHEADER psh; HPROPSHEETPAGE hPsp[2]; psp.dwSize = sizeof (PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT; psp.pszIcon = TEXT("PAGEICON"); psp.pszIcon = NULL; psp.hInstance = (HINSTANCE)GetWindowLong(*hwnd , GWL_HINSTANCE); psp.pszTemplate = TEXT("Page1"); psp.pfnDlgProc = (DLGPROC) PageProc1; hPsp[0] = CreatePropertySheetPage(&psp); psp.pszTemplate = TEXT("Page2"); psp.pfnDlgProc = (DLGPROC) PageProc2; hPsp[1] = CreatePropertySheetPage(&psp); psh.dwSize = sizeof (PROPSHEETHEADER); psh.dwFlags = PSH_DEFAULT; psh.hwndParent = *hwnd; psh.hIcon = LoadIcon(NULL , IDI_ASTERISK); psh.pszCaption = "TITLE"; psh.nPages = 2; psh.phpage = hPsp; PropertySheet(&psh); return (0); } LRESULT MainWindow::Else(HWND *hwnd, UINT *message, WPARAM *wparam, LPARAM *lparam) { return (DefWindowProc(*hwnd, *message, *wparam, *lparam)); } BOOL CALLBACK PageProc1(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { return (FALSE); } BOOL CALLBACK PageProc2(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { return (FALSE); } http://wisdom.sakura.ne.jp/system/winapi/common/common12.html​ を参考にしました。 一応、丸写しのプログラムで試してみようと思います。

回答No.2

 こんばんは。  ページが複数あるウィンドウを開きたいのであれば、ウィンドウプロシージャ内でオプションがクリックされた時に、プロパティシート等を作成すれば良いのではないでしょうか。  http://wisdom.sakura.ne.jp/system/winapi/common/common12.html

noname#154655
質問者

補足

表示はされたのですが、すぐに消えてしまいます。 追加した部分は、「WM_RBUTTONUP」の所に書いてある部分と、 「InitCommonControls();」です。 他に何か追加しないといけないものはあるのでしょうか? それとも、戻り値に問題があるのでしょうか? プロパティシートのコールバック関数に 行くと思うのですが行きませんでした。 どういう原因があるのでしょうか?

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

MFCならダイアログクラスを新規に追加するだけ。 WindowsAPIなら、このあたりを参考に。 http://www.kumei.ne.jp/c_lang/sdk/sdk_67.htm 少し複雑すぎるかもしれませんが。

noname#154655
質問者

お礼

2回目の回答のお礼の欄が使っているのでこちらに書かせていただきます。 出来ました。 リソーススクリプトを作っていなかったから出来なかっただけでした。 ありがとうございました。

noname#154655
質問者

補足

WindowsAPIを使用しています。 必要そうな所は追加して表示はされたのですが、 すぐに消えてしまいます。 何が原因か調べようとしたのですが分かりませんでした。 何か原因があるのでしょうか?