前序
該章是在上一章的基礎上繼續完善代碼,先來看看我們上一章做到哪了
那麼我們接下來要先給控件加上圖標(不然太醜了),然後先實現雙擊進入目錄(爲了做到簡單些,我這裏的不會去做位圖按鈕來實現返回功能,而是直接在工具箱中添加一個按鈕來響應返回上級目錄的功能),不會做位圖按鈕的請查閱我之前的博客。
實現
1、因爲我們要給控件中添加磁盤跟文件的圖標,那麼我們的圖標哪裏來呢?當然是從我們的系統中獲取的了,因而我們需要在頭文件中添加CImageList類型指針來存儲這些圖標。而我們將獲取圖標的代碼寫到構造函數裏或初始化函數裏(OnInitDialog()),代碼實現如下(這裏我們在OnInitDialog函數裏面添加):
BOOL CLocalFileSysDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 將“關於...”菜單項添加到系統菜單中。
// IDM_ABOUTBOX 必須在系統命令範圍內。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
// 執行此操作
SetIcon(m_hIcon, TRUE); // 設置大圖標
SetIcon(m_hIcon, FALSE); // 設置小圖標
// TODO: 在此添加額外的初始化代碼
// 獲取文件圖標
SHFILEINFO sfi;
// 捲圖標
HIMAGELIST hImageList;
// 加載系統圖標列表
hImageList = (HIMAGELIST)SHGetFileInfo(
NULL,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_LARGEICON | SHGFI_SYSICONINDEX
);
m_ImageList_Large = CImageList::FromHandle(hImageList);
// 加載系統小圖標列表
hImageList = (HIMAGELIST)SHGetFileInfo(
NULL,
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SMALLICON | SHGFI_SYSICONINDEX
);
m_ImageList_Small = CImageList::FromHandle(hImageList);
InitLocalDiskDriverList();
m_local_list.SetImageList(m_ImageList_Large, LVSIL_NORMAL);
m_local_list.SetImageList(m_ImageList_Small, LVSIL_SMALL);
return TRUE; // 除非將焦點設置到控件,否則返回 TRUE
}
而上面的m_local_list.SetImageList則是在我們的控件中使用圖標。這裏代碼添加完了,我們再來運行下我們的項目,是不是發現我們的磁盤前面已經有圖標了,效果如下:
2、接着我們來實現雙擊鼠標左鍵進入磁盤/文件目錄的函數。我在這裏都是直接手動添加這些消息處理函數,如果你覺得麻煩你也可以在對話框中右鍵添加消息響應函數,這種方式MFC會自動幫你在對應的地方加上代碼,不過我不大喜歡。
我們來到頭文件LocalFileSysDlg.h下在類中添加雙擊左鍵的函數
afx_msg VOID OnNMDblclkListLocal(NMHDR *pNMHDR, LRESULT *pResult); // 響應鼠標雙擊事件函數
然後在LocalFileSysDlg.cpp中找到 BEGIN_MESSAGE_MAP,如下:
BEGIN_MESSAGE_MAP(CLocalFileSysDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CLocalFileSysDlg::OnNMDblclkListLocal)
END_MESSAGE_MAP()
其中ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CLocalFileSysDlg::OnNMDblclkListLocal)是我剛添加到這裏的,讓函數跟控件綁定起來。
最後我們來實現這個函數體:
VOID CLocalFileSysDlg::OnNMDblclkListLocal(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知處理程序代碼
if (m_local_list.GetSelectedCount() == 0 ||
m_local_list.GetItemData(m_local_list.GetSelectionMark()) != 1)
return;
MessageBox("雙擊了");
*pResult = 0;
}
函數體裏面我做了個判斷,就是只能在雙擊控件中的某一行才能往下執行,如果是雙擊空白處則是不執行的。可以看看效果如何。
效果圖:
爲了不讓一節的內容太長,剩下的內容我在下節繼續講解,主要是雙擊進目錄,然後添加個按鈕返回上一級。