• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:解像度が変わるとEditコントロールの位置がずれる)

解像度が変わるとEditコントロールの位置がずれる

redfox63の回答

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

WND_TOPは座標とは無関係です これはウィンドウの表示の高さ(重なり具合)を決定します 表示する座標付近のコントロールより(Z軸での)上に表示させるためです ListViewの矩形領域をGetWindowRectで取得して ScreenToClientでクライアント座標に変換した時のtopを足してやればいいと思いますよ // ListViewの領域取得 ::GetwindowRect( ::GetDlgItem( m_hWnd, IDC_LIST ), &rect1 ); // ダイアログの領域取得 ::GetwindowRect( m_hWnd, &rect2 ); // ダイアログのクライアント座標に変換 this->ScrenToClient( &rect1 ); this->ScrenToClient( &rect2 ); int x = rect1.left - rect2.left; としておいて ::SetWindowPos(::GetDlgItem(m_hWnd,IDC_STATIC_Arrow),     HWND_TOP,rect.left + x,          rect.top + rect1.top + 2,          17,          12 ,NULL); といった具合で出来ると思いますよ

psychang
質問者

お礼

助かりました。ありがとうございました。

psychang
質問者

補足

  // ▼ここから教えて頂いた部分▼ //Get the Rectange of the listControl ListView_GetSubItemRect(hWnd1,nItem, nSubItem,LVIR_BOUNDS,&rect);   CString str = m_xcList.GetItemText(nItem,nSubItem); //現在のセルの文字を取得   RECT rect1;   RECT rect2;   // ListViewの領域取得   ::GetWindowRect( ::GetDlgItem( m_hWnd, IDC_LIST ), &rect1 ); //wを大文字にしました。あげ足とりですみません。   // ダイアログの領域取得   ::GetWindowRect( m_hWnd, &rect2 );   // ダイアログのクライアント座標に変換   this->ScreenToClient( &rect1 ); //Scren → Screen に直しました、すべて記憶で打ってる所が凄いです!   this->ScreenToClient( &rect2 );   int x = rect1.left - rect2.left; if(nItem != -1) ::SetWindowPos(::GetDlgItem(m_hWnd,IDC_EDIT_Item),     //HWND_TOP,rect.left+x,rect.top+4,//変更前     HWND_TOP,rect.left + x,       rect.top + rect1.top + 2, rect.right-rect.left - 3, rect.bottom-rect.top -1,NULL); ::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT_Item),SW_SHOW); ::SetFocus(::GetDlgItem(m_hWnd,IDC_EDIT_Item)); //Set the listItem text in the EditBox ::SetWindowText(::GetDlgItem(m_hWnd,IDC_EDIT_Item),str);   if(nItem != -1)   ::SetWindowPos(::GetDlgItem(m_hWnd,IDC_STATIC_Arrow),     HWND_TOP,rect.left + x - 17,       rect.top + rect1.top + 4,           17,           12 ,NULL);   ::ShowWindow(::GetDlgItem(m_hWnd,IDC_STATIC_Arrow),SW_SHOW);//追加2011.10.08   // ▲ここまで教えて頂いた部分▲   void CFileListCreatorDlg::OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult) 関数内でも同じような処理をしているのですが、青色の矢印アイコンの上にグリッド線を描画してしまいます。なんとか、直してみます。   BOOL CFileListCreatorDlg::PreTranslateMessage(MSG* pMsg) 内の WM_LBUTTONUP とかでできるかも知れません。上下左右の矢印キーによる移動の時は、問題なしです。XPでは完全に自分が望む機能ができました。Vistaでは欠けます。   XP→Vista→7 と解像度が上がると、少しずつ表示位置の不具合が出てきます。   ただ、欠ける現象は、Vistaのみでした。不思議です。   横幅も合わせたり、色々してたので、御礼が遅くなってすみません。      ほぼ解決ですが、今回は、横幅に関しては、付け焼刃で作ってしまいました。横幅固定で。時間があるときに、各セルの幅を%で作ってみます。 ■DrawTextでの描画(過去ログ) http://oshiete.goo.ne.jp/qa/5022902.html >この方式の弱点は 2回のDrawTextを実行するといった点です > 一度目は DT_CENTER | DT_CALCRECT ... 領域計算 > 二度目は DT_CENTER ... こちらで実際に描画 > になりますす これも使ったほうがいいですね。 ご回答ありがとうございました!

関連するQ&A

  • スクロールバーコントロールについて質問があります

    作成手順 1) IDC_SCROLLBAR1として、リソースエディタで適当な位置に配置 2) 右クリック 「変数の追加」で、コントロール変数の追加 CForm1View に、 CScrollBar m_sbHorz; として、追加される 3) CForm1View::InitialUpdate() で、 // スクロールバーの設定 this->m_sbHorz.SetParent(this); HWND hWndSb; GetDlgItem(IDC_SCROLLBAR1, &hWndSb); ::ShowWindow( hWndSb, SW_SHOW ); CRect rectSb; ::GetClientRect( hWndSb, &rectSb ); 4) CForm1View::OnDraw() で、 HWND hWndSb; GetDlgItem(IDC_SCROLLBAR1, &hWndSb); ::SetScrollRange( hWndSb, SB_CTL, this->m_ScMinVal, this->m_ScMaxVal, FALSE ); ::SetScrollPos( hWndSb, SB_CTL, this->m_ScPos, TRUE ); ::ShowWindow( hWndSb, SW_SHOW ); ※ m_ScMinVal: 最小値、m_ScMaxVal = 最大値、m_ScPos=現在値 の変数 5) CFomr1View::OnSize()で、 // FormViewのScrollBarを表示させない SetScrollSizes( MM_TEXT, CSize(cx,cy) ); CWnd::OnSize(nType, cx, cy ); // スクロールバーの位置調整 HWND hWndSb; GetDlgItem(IDC_SCROLLBAR1, &hWndSb); ::GetClientRect( hWndSb, &rect ); ::MoveWindow( hWndSb, 0, cy, cx, rect.Height(), FALSE ); ::SetScrollPos( hWndSb, SB_CTL, this->m_ScPos, TRUE ); 6) CFomr1View::OnHScroll() で、 HWND hWndSb; GetDlgItem(IDC_SCROLLBAR1, &hWndSb); ::SetScrollPos( hWndSb, SB_CTL, this->m_ScPos, TRUE ); とやると、スクロールバーが表示されません。 何かアドバイスいただけませんか? また、今、スクロールバーの表示位置調整や、ScrollPosのセットなんかを Win32API関数使ってますが、MFCで(というか、CScrollBar m_sbHorz; を使って) できないものなのでしょうか? よろしくお願いします。

  • 1と表示させたいが12と表示される

    windows XP VC++.net 2003です。 よろしくお願いします。 症状は毎回コピーアンドペーストでプログラムを書くよりも 関数化してソースをきれいにしようと思い BOOL ButtonNumber (int bNumber,HWND hWnd) { long z; char sBuff[100]; char number[100]; wsprintf(number,"%d",bNumber); z = GetWindowText(GetDlgItem(hWnd,IDC_EDIT1),sBuff,99); if(z == 0){ SetWindowText(GetDlgItem(hWnd,IDC_EDIT1),number); return TRUE; } if(z == 10){ //桁数が多すぎる警告メッセージ MessageBox(NULL,"桁数が多すぎます。","警告",MB_OK); return TRUE; } z = atol(sBuff); wsprintf(sBuff,"%d1",z); SetWindowText(GetDlgItem(hWnd,IDC_EDIT1),sBuff); return TRUE; } という関数を作りました。 numberに1という数字が入っていてエディットボックスに1と表示されるはずなのですが12と表示されてしまいます。 ためしにnumberに12と入れてみると表示されるのが122 123と入力すると1232と表示されてしまいます。 SetWindowText(GetDlgItem(hWnd,IDC_EDIT1),number); どこも間違っていないように思いますが・・なんででしょう・・ 関数化せずmainに直接書き込んでいけば正常に1と表示されます・ switch (LOWORD(wParam)) { case IDC_BUTTON1: ButtonNumber(1,hWnd); case IDC_BUTTON2: a = GetWindowText(GetDlgItem(hWnd,IDC_EDIT1),sBuff,99); if(a == 0){ SetWindowText(GetDlgItem(hWnd,IDC_EDIT1),"2"); return TRUE; } if(a == 10){ //桁数が多すぎる警告メッセージ MessageBox(NULL,"桁数が多すぎます。","警告",MB_OK); return TRUE; } a = atol(sBuff); wsprintf(sBuff,"%d2",a); SetWindowText(GetDlgItem(hWnd,IDC_EDIT1),sBuff); return TRUE; この場合BUTTON1は12と意図しない表示をしますが BUTTON2はちゃんと2と表示されます。 非常に困っていますよろしくお願いします。

  • VCでグループボックスを不可視にするには?

    VC++6.0で開発を行っております。 初心者です。 非常に単純な質問なんですが、 明確な回答がなかなか見つからないため 質問させていただきます。 プログラム上でグループボックスの可視/不可視を 制御したいのですが、コードはどうなるのでしょうか? (リソースファイルのデフォルトは可視) ラジオボタンの場合は調べたところ以下の様にすれば いいことが分かりましたがグループボックスの場合が 見つかりません。よろしくお願い致します。 GetDlgItem(IDC_RADIO1)->ShowWindow(SW_SHOW); 下記の様にすればできるといいのですが・・・ GetDlgItem(IDC_FRMTYPE1)->ShowWindow(SW_SHOW);

  • 猫でも 20章

    LRESULTはlong型、DWORDはmsdnより、「32 ビットの符号なし整数、またはセグメント アドレスとそれに関連するオフセット」、SendMessageは返り値はLRESULT型。それで、猫でもわかるプログラミング20章(http://www.kumei.ne.jp/c_lang/sdk/sdk_20.htm)、の上のほうにリスト等の情報を取得するのに、 int getDlg(HWND hDlgWnd) { GetWindowText(GetDlgItem(hDlgWnd, IDC_EDIT1), edit_str, sizeof(edit_str)); ScrPos = GetScrollPos(GetDlgItem(hDlgWnd, IDC_SCROLL1), SB_CTL); ListNo = (int)(DWORD)SendMessage(GetDlgItem(hDlgWnd, IDC_LIST1), LB_GETCURSEL, 0L, 0L); ComboNo = (int)(DWORD)SendMessage(GetDlgItem(hDlgWnd, IDC_COMBO1), CB_GETCURSEL, 0L, 0L); return 0; } とあるのですが、SendMessageを(int)(DWORD)とキャストしているのはなぜなんでしょうか。(int)ではダメですか?

  • ウィンドウハンドルの取得方法について

    よろしくお願いします。 WIN98 VC++6.0 MFC にて 色々勉強しておりますが、今だにウィンドウハンドルの取得方法が良く分かりません。 SDKのサンプルを見ると、なるほどそうするのか。と思いますが、MFCになると分からなくなります。 たとえば、 ウィザードのデフォルトに従いダイアログベースでのプロジェクトを作成し、ボタン1と2を配置します。 以下のコードでボタン1を非表示にできます。 void CPppDlg::OnButton2() { CWnd* pButton1 = GetDlgItem (IDC_BUTTON1); pButton1->ShowWindow(SW_HIDE); } このコードにおいて、 1.SDKの BOOL ShowWindow( HWND hWnd, // handle to window int nCmdShow // show state of window ); を用いて引数が2個の形式に書きかえることは可能でしょうか? 2.可能であれば、具体的にはどう記述すれば良いのでしょうか?

  • MFCタブコントロールのグラデーション描画

    現在、VC++2010・MFC環境でMFCのタブコントロールのウィンドウ部(?)をグラデーション描画にしたいと考えています。 完成予想としては、Excelのメニュー(?)みたいな感じでグラデーションがかかるような感じにしたいのですが、現在、グラデーションの描画は何とか(たぶん無理やり)できましたが、タブを切替たり、ダイアログ自体が非アクティブ/アクティブを繰り返すとちらついてしまいます。 ソースは以下のようになっています。 ----------------------------------------------------------------- void CTabGradDlg::OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult) { // TODO: ここにコントロール通知ハンドラー コードを追加します。 int sel = m_xcTab.GetCurSel(); m_edit1.ShowWindow(SW_HIDE); m_edit2.ShowWindow(SW_HIDE); m_button1.ShowWindow(SW_HIDE); m_button2.ShowWindow(SW_HIDE); switch(sel) { case 0: m_edit1.ShowWindow(SW_SHOW); m_button1.ShowWindow(SW_SHOW); break; case 1: m_edit2.ShowWindow(SW_SHOW); m_button2.ShowWindow(SW_SHOW); break; } Invalidate(); *pResult = 0; } void CTabGradDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CDialogEx::OnActivate(nState, pWndOther, bMinimized); // TODO: ここにメッセージ ハンドラー コードを追加します。 switch( nState ) { case WA_INACTIVE : // 非アクティブ break; case WA_ACTIVE : // (マウスをクリックする以外の方法) アクティブ case WA_CLICKACTIVE : // (マウス クリック)アクティブ Invalidate(); break; } } ----------------------------------------------------------------- Invalidate();が原因でちらついていることまでは分かっているのですが、 なぜちらつくのか?ということと、対処方法もしくは別の方法はないのか? 別の方法があればどういったことなのか?ということが知りたいです。 初心者(小学生並み)にもわかるように教えていただければ幸いです。 宜しくお願いします。

  • VC++2010 GDIオブジェクトの解放方法

    現在、VC++2010 MFCでアプリケーションを作成しています。 処理している内容は、ADボードから電圧値をもらい、それをエディットボックスに表示する処理ですが、タスクマネージャなどでみるとGDIオブジェクトが増加していき、9999になるとアプリケーションがフリーズしてしまいます。調べたところ、解放するプログラムが必要みたいですが、解放方法が分かりませんでしたので質問させていただきました。最初にエディットボックスのレイアウトを変更する処理をしています。 以下が今回のプログラムとなっております。 CFont* m_pFont;  CFont* m_pFont;m_pFont = new CFont; m_pFont->CreatePointFont(200,""); ((CEdit *)GetDlgItem(IDC_EDIT1))->SetFont(m_pFont); ((CEdit *)GetDlgItem(IDC_EDIT2))->SetFont(m_pFont); ((CEdit *)GetDlgItem(IDC_EDIT3))->SetFont(m_pFont); ((CEdit *)GetDlgItem(IDC_EDIT4))->SetFont(m_pFont); ((CEdit *)GetDlgItem(IDC_EDIT5))->SetFont(m_pFont); ((CEdit *)GetDlgItem(IDC_EDIT6))->SetFont(m_pFont); DeleteObject(m_pFont); SetTimer(1,1000,NULL); 以下が毎秒処理となっております。 void Power_Noise::OnTimer(UINT_PTR nIDEvent) { m_nRet = m_pADControl->AD_In_Out(m_AD1,m_AD2,m_AD3,m_AD4,m_AD5,m_AD6); if(m_nRet == FALSE){ MessageBox("失敗"); KillTimer(1); } UpdateData(TRUE); m_xvEditVolt[0] = m_AD1; m_xvEditVolt[1] = m_AD2; m_xvEditVolt[2] = m_AD3; m_xvEditVolt[3] = m_AD4; m_xvEditVolt[4] = m_AD5; m_xvEditVolt[5] = m_AD6; UpdateData(FALSE); }

  • MFCのエディットボックスの値をスピンボタン

    エディットボックスの値をスピンボタンの初期値にしたく、 下記コーディングにしたのですが CString Item; m_Spin->SetPos(((CEdit*)GetDlgItem(IDC_EDIT1))->GetWindowText(Item)); SetPos' : 1 番目の引数を 'void' から 'int' に変換できません。 とのエラーになります。 どのように変更したらよいかお教えください。

  • リストビュー:先頭行のアイテム番号取得

    リストビューコントロールで、 最上位に表示されているアイテムの番号を取得したく、 以下のような関数を作ったのですがうまくいきません。 リストビューの0番目のアイテムが先頭行に表示されていると、正しい値が取得できるのですが、 それ以外だと、取得すべき値より1小さい値が返されてしまいます。 どこがまずいか、または別の方法があれば、 ご教授ください。 [関数] int GetTopItemNum(HWND hDlg){ HWND hList = GetDlgItem(hDlg, IDC_INFOTABLE); RECT r; LVHITTESTINFO lvhti; ListView_GetItemRect (hList, 0, &r,LVIR_BOUNDS) // カーソルサイズ取得 lvhti.pt.x = (r.right-r.left)/2; lvhti.pt.y = (r.bottom-r.top)/2; // 中心取得 lvhti.flags = LVHT_ONITEMLABEL; ListView_HitTest (hList, &lvhti);// 表示先頭行でヒットテスト return lvhti.iItem; // 先頭行のアイテム番号取得 }

  • ダイアログの領域全てをエデイトボックスが占めるプログラム

    お世話になります。 現在ダイアログにエディトボックス(IDC_EDIT1)を1つおいて、このエディトボックスがダイアログの全体を占める様なプログラムを作成しています。 以下のようなプログラムでは、サイズ変更をした時に初めてダイアログ内にエディトボックスが動的に占めるのですが、これをプログラムを起動したときから既にエディトボックスがダイアログの全体を占めている状態にしたいのですが、どのようにすればよいでしょうか? 開発環境はVC++ 6.0 MFC WindXPです。 ご教示よろしくお願いします。 プログラム: void CxxxDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください CRect rect; CWnd* pEdit = GetDlgItem( IDC_EDIT1 ); GetClientRect(&rect); if( pEdit != NULL ) { rect=CRect(0,0,cx,cy); pEdit->MoveWindow( &rect, TRUE ); } }