• ベストアンサー

ダイアログボックスで指定したサイズどおり表示されない

ダイアログボックスで指定したサイズがメイン上では約2倍の大きさになって表示されてしまい、困っています。 メニューリソースは以下のとおりです。 MYDLG DIALOG DISCARDABLE 25, 50, 100, 150 STYLE WS_VISIBLE | WS_CHILD | DS_CONTROL CAPTION "Dialog" FONT 9, "MS Pゴシック" BEGIN END WndProc内にダイアログを貼り付けています。 if(hDlgWnd) break; hDlgWnd = CreateDialog((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),"MYDLG",hWnd,DialogProc); それが実際にウィンドウを開くとダイアログがだいたいですが(50,115,200,340)のように表示されてしまいます。 VC++ Ver.6.0です。コンパイラ等の問題でしょうか。 ご存知の方、宜しくお願いします。

  • aakey
  • お礼率46% (14/30)

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

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

★コンパイラ等の問題ではありません。 ・もともとダイアログのサイズはピクセル数での指定ではないのです。  この基本を知らないと今回の質問が出てくるようですね。  ダイアログは『ダイアログ・ベース単位』でサイズが決まります。  これはダイアログに設定されているフォントの高さなどから変化するのです。  次のリンクを読んで下さい。  http://wisdom.sakura.ne.jp/system/winapi/win32/win84.html→『ダイアログ』  かなり最初の方に >ただし、ダイアログで指定する座標、サイズはピクセルではないので注意してください >ダイアログの場合、座標系は文字サイズを基準としているのです  という事が書かれています。 解決策: ・CreateDialog() でダイアログを作成したときにダイアログの WM_INITDIALOG で  ウインドウのサイズをピクセル値で設定しなおす処理を行います。  つまりは  case WM_INITDIALOG:   SetWindowPos( hDlg, NULL, 25, 50, 100, 150, (SWP_NOZORDER|SWP_NOOWNERZORDER) );   return TRUE;  という記述を追加します。  重要なのは SetWindowPos() 関数でウインドウの位置とサイズをピクセル値で  設定することです。 ・以上。『ダイアログ・ベース単位』と『ピクセル値』は違います。注意。

参考URL:
http://wisdom.sakura.ne.jp/system/winapi/win32/win84.html
aakey
質問者

お礼

ありがとうございます。解決いたしました。 サイトはAPIを書くうえで参考にしていましたが、ダイアログに関する記述は見落としていたようです。 大変勉強になりました。

その他の回答 (1)

  • noocyte
  • ベストアンサー率58% (171/291)
回答No.1

リソースファイル内のダイアログの座標は画素単位じゃなくて, 「ダイアログテンプレート単位」だということはご存知ですか? http://www5d.biglobe.ne.jp/~noocyte/Programming/Windows/WindowsTips.html#DialogUnits → ダイアログの座標系 (ダイアログテンプレート単位とダイアログベース単位)

aakey
質問者

お礼

回答ありがとうございます。 大変参考になりました。

関連するQ&A

  • Type name expected エラーがでます。

    こんにちは。 非常に短い 次のコードで、 Type name expected エラーが出ます。 何か悪いのでしょうか。 コンパイラは、bcc55 (ボーランドのコマンドライン用の 無償のコンパイラです)。 #include <windows.h> #include "dialog1.h" BOOL CALLBACK dialogProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE h,HINSTANCE,LPSTR,int) { DialogBox(h,"DIALOG1",HWND_DESKTOP,(DLGPROC)dialogProc); return 0; } BOOL CALLBACK dialogProc(HWND hw,UINT msg,WPARAM wp,LPALAM lp){ return FALSE; } 何か分かる人がいましたら、 よろしくお願いします。 dialog1.cpp-------------------------------------- #include <windows.h> #include "dialog1.h" DIALOG1 DIALOG 100,100,200,80 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "FIRST DIALOG" FONT 10,"system" { DEFPUSHBUTTON "BEEP",ID_0,25,10,50,15 PUSHBUTTON "EXIT",ID_1,25,30,50,15 } dialog1.h----------------------------- #define ID_0 100 #define ID_1 101

  • ダイアログ内の文字列取得

    開発環境  Xp Home Edtion Microsoft Visual C++ 2008 Express Edition ダイアログのテキストボックスに入力された文字列を取得し、それをデバッグに表示するプログラムを作ろうとしています。 ですが、デバッグに表示されないのです。どのようにしたら良いでしょうか? リソースファイル IDM_SETTING DIALOG DISCARDABLE 0, 0, 154, 115 STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU FONT 16 , "MS Shell Dlg" STYLE WS_CAPTION | WS_BORDER | WS_SYSMENU CAPTION "設定画面" BEGIN EDITTEXT IDC_XS,35,15,40,14,ES_AUTOHSCROLL PUSHBUTTON "OK", IDOK,10,0,50,14,WS_GROUP END cppファイル HWND hnd; LPTSTR Lptdtr10; LPCSTR dsLPCSTR10; Lptdtr10 = (char*)malloc(32768); GetDlgItemText(hnd, IDC_XS , Lptdtr10, sizeof(Lptdtr10)); dsLPCSTR10 = (LPCSTR) Lptdtr10; char *ree; ree=(char*)dsLPCSTR10; String^ data=gcnew String(ree); System::Diagnostics::Debug::WriteLine(data); //ここで表示する

  • WindowsAPIの、ウインドウの表示非表示

    WindowsAPIのCreateWindowEx関数で作った 例えば第一引数が WS_EX_TOOLWINDOW|WS_EX_TOPMOST で第四引数が WS_SYSMENU | WS_VSCROLL | WS_SIZEBOX のウインドウを、何かのアクションがあったときいったん非表示にしてから、また何かのアクションがあった時に表示させるには、どのような物を使うのがベストなのでしょうか? プロシージャ内(HWNDはhw)で一例として(…?)試しに以下だけのものでやってみると long lStyle = GetWindowLong(hw, GWL_STYLE); lStyle = ~WS_VISIBLE; SetWindowLong(hw, GWL_STYLE, lStyle); 確かに非表示扱いにはなるようなのですが、これだけではスクリーンは再描画されず、再描画されるには人為的に別ウインドウを移動したりしないといけません。 おそらく「何かによって再描画させられれば」出来ると思うのですが それはどうすれば実現できるのでしょうか? また、これより もっと「こっちの方がいい」といった方法はありますでしょうか?

  • ハンドルからインスタンス?を取得したいのですが

    CreateWindowExを使いたいのですが 途中でインスタンス?(でいいのかな?)を指定するところが あるのですがどうしていいか困っています。 GetWindowLong(HWND,GWL_HINSTANCE); でとれるのかな?と思うのですが 返す値がLongです インスタンスにキャストすることなどできるのでしょうか? どのようにしたらいいのでしょうか? インスタンス自身もあまり意味が....... よろしくお願いいたします

  • ダイアログボックスのボタンコントロールのフォーカスについて

    ダイアログボックスのボタンコントロールのフォーカスについて 教えて下さい。  モーダルダイアログにボタン「OK」を一つ貼り付けて それを「標準のボタン」(BS_DEFPUSHBUTTON)として作成したのですが ダイアログ表示直後は下画像(1)のようになってエンターキーを押しても 反応しません。何度かカーソルキーを押すとようやく(2)のように ボタンに枠線がついてエンターで押せるようになるのですが ダイアログ表示直後に(2)のようにするにはどうするべきでしょうか? ダイアログのコールバック・プロシージャ(WM_INITDIALOG部分でボタン作成) LRESULT CALLBACK SettingWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){ switch (msg){ case WM_INITDIALOG: CreateWindowEx(0x00000000,"BUTTON","OK", WS_CHILD |WS_VISIBLE| WS_TABSTOP | BS_DEFPUSHBUTTON, 16,16,80,21,hWnd,(HMENU)IDOK,GetModuleHandle(0),0); return TRUE; } return FALSE; }

  • EDIT 作成時のちらつき防止について

    Enterキーを押下された時に画面にEDITBOXを表示し、 再度Enterキーを押下されたらEDITBOXを消す。 という処理を行っているのですが、表示する時も消す時も画面のちらつきが発生します。 このちらつきを防ぐにはどうしたらいいでしょうか? Enterキーが押されたときに、毎回、CreateWindowし、SetWindowLongでWNDPROCを設定しています。 mainWndProc関数の一部 mHwEnter = CreateWindow("EDIT", "ここに入力", WS_CHILD | WS_VISIBLE | WS_BORDER, 173, 380, 12 * 16, 16, mHwMain, NULL, hInst, NULL); mainWndProc = (WNDPROC)GetWindowLong(mHwEnter, GWL_WNDPROC); SetWindowLong(mHwEnter, GWL_WNDPROC, (LONG)WndProcEnter); 再度Enterキーが押されたとき ウインドウを破棄しています。 WndProcEnter関数の一部 SetWindowLong (mHwEnter, GWL_WNDPROC, (LONG)mainWndProc); DestroyWindow (mHwEnter); mHwEnter = NULL; EDITの表示、消去の仕方はWebで調べたのですが、間違っていたらご指摘お願いします。 また、メイン(親)画面は20FPSくらいで描画し続けています。MFCやDirectXは使用していません。 ちらつき防止のわかる方がいたら回答お願いします。

  • WNDPROC をクラスのメンバにもちたいです

    ツリーコントロールをクラスにラップしたいのですが、 クラス内のメンバで WNDPROC PrevProc; とすると、 error C2597: 静的でないメンバ 'TreeControlClass::PrevProc' への参照が正しくありません。 というエラーが表示されます。 どうにかできないでしょうか? クラスの外に変数宣言するしかダメでしょうか? よろしくお願いします。 Visual C++.NETで開発 #include<Commctrl.h> class TreeControlClass { private: HWND TreeWnd; WNDPROC PrevProc; public: void WindowCreate(HWND ParentWnd,RECT Rect) { DWORD Style; Style=WS_VISIBLE|WS_CHILD|WS_BORDER|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT; int x,y,width,height; x=Rect.left; y=Rect.top; width=Rect.right-Rect.left; height=Rect.bottom-Rect.top; TreeWnd=CreateWindow(WC_TREEVIEW,"",Style,x,y,width,height,ParentWnd,NULL,NULL,NULL); PrevProc=(WNDPROC)GetWindowLong(TreeWnd,GWL_WNDPROC); SetWindowLong(TreeWnd,GWL_WNDPROC,(LONG)TreeProc); return; } void WindowDestroy() { SetWindowLong(TreeWnd,GWL_WNDPROC,(LONG)PrevProc); DestroyWindow(TreeWnd); return; } static LRESULT CALLBACK int TreeProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { default: return (CallWindowProc(PrevProc, hWnd, message, wParam, lParam)); } } };

  • VC++コンソールアプリでのインスタンスハンドルの取得

    VC++コンソールアプリでのインスタンスハンドルの取得 VC++コンソールアプリケーションでインスタンスハンドルを取得しようとしているのですが、 HINSTANCE hi = (HINSTANCE)GetWindowLong(HWND_DESKTOP, GWL_HINSTANCE); を実行すると、NULLが戻ってきます。 どこかまずい部分があるのでしょうか。 なお、第一引数のウィンドウハンドルは不明なため、 いくつかのWebサイトに習い、HWND_DESKTOPを指定しました。

  • ダイアログ表示後に1回だけ実行

    ダイアログベースのプログラムで、ダイアログを表示後にメッセージボックスを表示しようとして、下のプログラムのようにしたのですがダイアログが表示される前にメッセージボックスが表示されてしまいます。 ダイアログが表示された直後に1回だけ表示されるようにするにはどうすればいいですか? #include<Windows.h> #include "resource.h" HINSTANCE hinst; INT_PTR CALLBACK dlgproc(HWND,UINT,WPARAM,LPARAM); int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { hinst=hInstance; DialogBox(hinst,TEXT("mydlgmain"),NULL,dlgproc); } INT_PTR CALLBACK dlgproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) { TCHAR moji[]=TEXT("ダイアログ表示"); switch(msg) { case WM_INITDIALOG: MessageBox(hwnd,moji,TEXT(""),MB_OK); return(INT_PTR)TRUE; case WM_CLOSE: EndDialog(hwnd,LOWORD(wp)); return (INT_PTR)TRUE; } return(INT_PTR)FALSE; } --- 実行環境 --- Microsoft Visual C++ 2010 Express WIN32 ユニコードビルド C言語

  • ダイアログを閉じるとメモリー消費が増える

    メインウインドーに例えばA、Bという2個のモーダルダイアログを開くようにしていますが、Aのみで開いたり閉じたりするとメモリー消費が200kバイトづつ毎回増えてしまいます。 しかし、最初にBを一回開いて閉じておけば、その後は何回Aを開いてもメモリーは増えません。 また、メモリーの増えるタイミングはAのダイアログを開いた時ではなく閉じた時点で増えます。 解決策を教えてください。 //子ウィンドー作成 hwDialog_o = CreateWindowEx(0, "CDialog", "", WS_OVERLAPPED| WS_SYSMENU| WS_CAPTION| WS_BORDER| WS_VISIBLE| WS_CLIPCHILDREN| WS_EX_TOPMOST,//WS_CLIPCHILDRENでチラツキ防止 i, j, 660, 180, NULL, NULL, h_Inst, NULL); ShowWindow(hwDialog_o, nWinMode); UpdateWindow(hwDialog_o); // メインウインドウを無効化してモーダルに EnableWindow(hwnd,FALSE); ・ ・   色々と処理 ・ // メインウインドウを有効にしてモーダル解除 EnableWindow(hwnd,TRUE); BringWindowToTop(hwnd); return;

専門家に質問してみよう