2016-01-22 61 views
2

我有一個CListCtrl,我在單元格上顯示文本框以允許用戶編輯單元格的文本。MFC CListCtrl在單元格上顯示文本框供用戶編輯

這是有效的,但我不認爲文本框會根據用戶窗口設置停留在不同UI樣式的正確位置。

有誰知道一種可靠的方法來將文本框窗口置於用戶單擊的單元格上嗎?這是我現在使用的代碼。我不關心添加值爲16的文本框的右側。我只想要一個可靠的方法來獲取文本框左側和頂部的位置。

void FilesDialog::OnNMClickFiles(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
    LPNMITEMACTIVATE temp = (LPNMITEMACTIVATE)pNMHDR; 
    //get the row number 
    nItem = temp->iItem; 
    //get the column number 
    nSubItem = temp->iSubItem; 
    if (nSubItem == 0 || nSubItem == -1 || nItem == -1) 
    { 
     *pResult = 0; 
     return; 
    } 
    //Retrieve the text of the selected subItem from the list 
    CString str = GetItemText(filesList.m_hWnd, nItem, nSubItem); 
    CRect rectList, rectDlg, rectCl; 
    CRect rectItem; 
    // Get the rectangle of the selected sub-item. 
    ListView_GetSubItemRect(filesList.m_hWnd, temp->iItem, temp->iSubItem, LVIR_BOUNDS, &rectItem); 
    //Get the Rectange of the listControl 
    ::GetWindowRect(temp->hdr.hwndFrom, &rectList); 
    //Get the Rectange of the Dialog 
    ::GetWindowRect(this->m_hWnd, &rectDlg); 
    GetClientRect(&rectCl); 
    //this->ScreenToClient(&rectCl); 
    int subY = rectDlg.Height() - rectCl.Height() - 5; 
    int lft = rectItem.left + rectList.left - rectDlg.left + 1; 
    int tp = rectItem.top + rectList.top - rectDlg.top - subY; 
    // When an item is cut off by the window on the right 
    // side, resize the text box so that the right side 
    // is at the edge of the list control. 
    int rtEdge = rectDlg.right - (rectDlg.right - rectCl.right); 
    int subWdth = 0; 
    if (lft + rectItem.Width() - 2 > rtEdge) 
    { 
     // 16 is just an arbitrary value that seems to work. 
     subWdth = 16 + (lft + rectItem.Width() - 2) - rtEdge; 
    } 
    // Move the edit box window over the cell. 
    editText.MoveWindow(lft, tp, rectItem.Width() - 2 - subWdth, rectItem.Height() - 1, true); 
    //Set the list Item text in the edit box. 
    ::SetWindowText(editText.m_hWnd, str); 
    // Show the edit box and set focus to it. 
    ::ShowWindow(editText.m_hWnd, SW_SHOW); 
    ::SetFocus(editText.m_hWnd); 

    *pResult = 0; 

} 

謝謝。

回答

1

它取決於如何創建editText。如果editText父是ListView控件,例如:

editText.Create(WS_CHILD, CRect(0, 0, 1, 1), &filesList, 1); 

那麼就沒有必要調整任何東西,只需使用rectItem的是:

void FilesDialog::OnNMClickFiles(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
    LPNMITEMACTIVATE temp = (LPNMITEMACTIVATE)pNMHDR; 
    if (temp->iSubItem == 0 || temp->iSubItem == -1 || temp->iItem == -1) 
    { 
     *pResult = 0; 
     return; 
    } 

    CString str = filesList.GetItemText(temp->iItem, temp->iSubItem); 

    CRect rectItem; 
    filesList.GetSubItemRect(temp->iItem, temp->iSubItem, LVIR_BOUNDS, rectItem); 

    editText.SetWindowText(str); 
    editText.MoveWindow(rectItem, 1); 
    editText.ShowWindow(SW_SHOW); 

    *pResult = 0; 
} 

如果另一方面editText的parent不是ListView控件,那麼編輯框不會相對於ListView定位它自己,因此它的位置必須進行調整。

例如,如果editTextDoDataExchange初始化然後偏移rectItem如下:

POINT p = { 0 }; 
filesList.MapWindowPoints(this, &p, 1); 
rectItem.OffsetRect(p.x, p.y); 
... 
editText.MoveWindow(rectItem, 1); 
+0

感謝。這工作正常。非常感激。 –

相關問題