MFC製作本地文件系統(二)

前序

該章是在上一章的基礎上繼續完善代碼,先來看看我們上一章做到哪了
這裏寫圖片描述

那麼我們接下來要先給控件加上圖標(不然太醜了),然後先實現雙擊進入目錄(爲了做到簡單些,我這裏的不會去做位圖按鈕來實現返回功能,而是直接在工具箱中添加一個按鈕來響應返回上級目錄的功能),不會做位圖按鈕的請查閱我之前的博客。

實現

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;
}

函數體裏面我做了個判斷,就是只能在雙擊控件中的某一行才能往下執行,如果是雙擊空白處則是不執行的。可以看看效果如何。
效果圖:
這裏寫圖片描述
爲了不讓一節的內容太長,剩下的內容我在下節繼續講解,主要是雙擊進目錄,然後添加個按鈕返回上一級。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章