アプリ版:「スタンプのみでお礼する」機能のリリースについて

いつも皆様、お世話になっております。
一つ教えてください。

解像度が変わるとエディット・コントロールの位置がずれるのですが、
ずばりクリックした行にエディット・コントロールを張り付かせたいです。

EditCellShow 関数は、セルを↑↓←→で移動した場合 や リストコントロールをスクロールした時などに呼び出されます。

(最後にクリックした行、列は、正しく拾えているものとします。)
(そして、workRow、workColumnに代入されます。)

例えば、1280 × 800 ピクセル (Windows Vista 32bit)では、以下のコードで正常に動作します。
1920 × 1080 ピクセル (Windows7 64bit)では、上にずれます。

もし解像度の問題でなければすみません、でも他のXPマシンや Windows7 マシンでも正常に動作しました。


void CFileListCreatorDlg::EditCellShow(int workRow,int workColumn)
{
  if (m_xvChkEditCellMode == TRUE){
    CFileListCreatorDlg::StatusStringSet(_T("ファイル名 や 備考欄 の 編集モードになりました (セルをクリックするか、クリック後 矢印キーで素早く移動、Enterで確定)"),0,FALSE);
    //StatusStringSet()関数は、ステータス文字を画面上部に表示し、警告音を鳴らすユーザー関数
  }

  ::ShowWindow(::GetDlgItem(m_hWnd,IDC_EDIT_Item),SW_HIDE);
  ::ShowWindow(::GetDlgItem(m_hWnd,IDC_STATIC_Arrow),SW_HIDE);//追加2011.10.08
  ::SetWindowText(::GetDlgItem(m_hWnd,IDC_EDIT_Item),_T(""));

  //m_xcListは、IDC_LISTの変数名

  m_xcList.SetItemState(workRow, // フォーカス&非選択状態にしたいアイテムのインデックス
  !LVIS_FOCUSED | !LVIS_SELECTED, // 状態
  LVIS_FOCUSED | LVIS_SELECTED); // マスク
  //UpdateWindow();

HWND hWnd1 = ::GetDlgItem (m_hWnd,IDC_LIST);
RECT rect;

  int nItem;
  int nSubItem;

  //何回も代入していますが、特に意味はありません、参考サイトのまま ソースコードを使いたかったので、それに合わせました。
nItem = workRow;
nSubItem = workColumn;

  LastSelectedRow = nItem;
  LastSelectedColumn = nSubItem;

  ////0:ファイル重複識別ナンバー 1:通し番号 2:フルパス 3:ファイル名 4:おおよそのデータサイズ 5:データサイズ 6:修正日 7:修正時間 8:備考欄 9:書式情報
  if((nSubItem == 0 || nSubItem == -1 || nItem == -1) || (nSubItem != 3 && nSubItem != 8)){ //2011.09.22変更
    //ファイル名と備考欄のみ編集可能に、他のカラムがクリックされた場合は、ファイル名編集欄に移動
    nSubItem = 3;
    LastSelectedColumn = nSubItem;
  }


  CFileListCreatorDlg::m_xcList.EnsureVisible(nItem, FALSE);

  CString str = m_xcList.GetItemText(nItem,nSubItem);


  ListView_GetSubItemRect(hWnd1,nItem,nSubItem,LVIR_BOUNDS,&rect);

  if(nItem != -1)
    ::SetWindowPos(::GetDlgItem(m_hWnd,IDC_EDIT_Item),
    HWND_TOP,rect.left + (18),rect.top + 4 + ( 16*5+2 ), //追加2011.09.22 //(18)と( 16*5+2 )は、帳尻あわせ //HWND_TOPは、IDC_LISTのTOPを取っているのか?
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));
  ::SetWindowText(::GetDlgItem(m_hWnd,IDC_EDIT_Item),str);

  ::SetWindowPos(::GetDlgItem(m_hWnd,IDC_STATIC_Arrow),//追加2011.10.08
    HWND_TOP,rect.left + (18) -17 ,rect.top + 4 + ( 16*5+2 ), //追加2011.09.22 //(18)と( 16*5+2 )は、帳尻あわせ //HWND_TOPは、IDC_LISTのTOPを取っているのか?
17,
12 ,NULL);
  ::ShowWindow(::GetDlgItem(m_hWnd,IDC_STATIC_Arrow),SW_SHOW);//追加2011.10.08
}

参考サイト: http://www.codeproject.com/KB/list/editing_subit …
(主に、項番10を参考にしました。)

画像を初めて添付しますが、文字が小さいなどの不具合があったら、すみません。
(画像は帳尻あわせをして、正常に動いている時のものです。)

「解像度が変わるとEditコントロールの位」の質問画像

A 回答 (2件)

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);
といった具合で出来ると思いますよ

この回答への補足

  // ▼ここから教えて頂いた部分▼

//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 ... こちらで実際に描画
> になりますす

これも使ったほうがいいですね。

ご回答ありがとうございました!

補足日時:2011/11/10 18:22
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/11/12 00:54

特にディスプレイの解像度と、そのファイルの「標準」スタイルのフォントサイズから影響を受けます。

(「標準」スタイルのフォントサイズと印刷結果の縦横比との間に比例関係はないようです)
例えば、解像度が 96dpi の場合は「標準」スタイルのフォントサイズが11ポイントの方が、10ポイントや9ポイントのときよりも変化が小さくなります。解像度が 120dpi の場合は「標準」スタイルのフォントサイズが9ポイントの方が、10ポイントや11ポイントのときよりも変化が小さくなります。

グラフシートではオブジェクトは指定した大きさで印刷できるようです。

今後編集する必要がない場合や、セルに合わせてサイズ変更する必要がない場合は、コピーして拡張メタファイルとして貼り付けると、指定した大きさで印刷できるようになります。

[挿入]-[オブジェクト] でMicrosoft Word 図 や Microsoft Draw などのオブジェクトを作成し、その中にオートシェイプを作成する方法も有効です。(ただし、挿入後に Excel の操作で図の大きさを変更すると指定した大きさでは印刷されません。シート上の図の大きさの倍率は必ず100%にして、大きさの変更はオブジェクトを編集するアプリケーション側で行うようにします。また、図の書式設定で「セルに合わせて移動やサイズ変更をしない」または「セルに合わせて移動するがサイズ変更はしない」を設定する必要があります)

この回答への補足

>解像度が 96dpi の場合は「標準」スタイルのフォントサイズが11ポイントの方が、10ポイントや9ポイントのときよりも変化が小さくなります。
>解像度が 120dpi の場合は「標準」スタイルのフォントサイズが9ポイントの方が、10ポイントや11ポイントのときよりも変化が小さくなります。

難しいんですね。

今回の問題は、Windows7マシンを新調していなければ、全く気が付かなかったかもしれません。


■モニタの物理解像度を得る(Win32API)
http://oshiete.goo.ne.jp/qa/6417189.html

上の過去ログも参考になるかもしれませんね。

Excel と連携する事もできるのですね。Excel 版の同じ機能のVBAも作っているので、連携できれば面白そうです。ただし、余談ですが、エクセル2007、2010になってから、互換モードでも実行となってしまい、処理が重く、実用に耐えなくなってしまいました(>_<")

VBAのソースコードはそのままで、2007以上にネイティブ?にできるのでしょうか?拡張子は変わるでしょうが、、、ちょっとカテゴリ違いですがυ

印刷は、HTMLに出力して、IE任せですが、自分でも作ってみるつもりです!

アドバイスありがとうございましたm(_ _)m

補足日時:2011/11/10 18:40
    • good
    • 0
この回答へのお礼

ありがとうございました。今後の参考にさせていただきます。

お礼日時:2011/11/12 00:55

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!