天天看點

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

“依米魔法郵箱”開發筆記

軟體用MFC開發而成,具體有以下功能、特色:

  • 文檔加密解密
  • 儲存自定義字尾的檔案(*.yimi)
  • 打開自定義字尾的檔案(*.yimi)
  • 改變視窗背景色
  • 改變視窗形狀
  • 改變光标圖案
  • 生成動态自定義軟體圖示

效果圖如下

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

功能實作方法

我所選的是MFC基本對話框類型的應用程式,布局如下:

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

文檔加密解密

加密核心代碼:

//加密
    char str;
    for(int i = ; i < m_strContent.GetLength(); i++)
    {
        str = m_strContent.GetAt(i);
        str = str+i;
        m_strContent.SetAt(i, str);
    }
           

解密核心代碼:

//判斷是否是.yimi檔案
    if(dlg.GetFileExt()=="yimi")//是.yimi檔案,則解密
    {//解密
        char str;
        for(int i = ; i < m_strContent.GetLength(); i++)
        {
            str = m_strContent.GetAt(i);
            str = str-i;
            m_strContent.SetAt(i, str);
        }

        UpdateData(FALSE);//更新資料
    }
           

具體請參見下面的“儲存與打開自定義字尾的檔案”。

儲存自定義字尾的檔案(*.yimi)

為編輯框空間關聯Value類型的CString變量m_strContent;

為頂部靜态文本關聯Value類型的CString變量m_strTitle;

為“另存為”按鈕添加BN_CLICKED消息映射,并添加映射函數,代碼如下(包括儲存檔案、頂部顯示檔案相關資訊和對*.yimi類型的檔案進行加密處理):

void CMyDlg::OnButtonSave() 
{
    CFile file;
    CString filter;
    //“依米魔法檔案(*.yimi)”即檔案類型選擇項,“*.yimi”即要求顯示的類型檔案
    filter = "依米魔法檔案(*.yimi)|*.yimi||";
    //第一個參數為TRUE時為“打開檔案”對話框;為FALSE時為“另存為”對話框。
    CFileDialog dlg(FALSE, filter, NULL, OFN_HIDEREADONLY, filter);
    if(dlg.DoModal()!=IDOK) return;
    //要寫CFile::modeCreate,若無該檔案則建立;要寫CFile::modeWrite,若已有該同名檔案則重寫覆寫
    if(!file.Open(dlg.GetPathName(), CFile::modeCreate|CFile::modeWrite))
    {
        AfxMessageBox(dlg.GetPathName() + "儲存失敗╮(╯▽╰)╭");
        return;
    }
    UpdateData();

    //靜态文本
    CString strFileName = dlg.GetPathName();
    CFileStatus status;
    if(!CFile::GetStatus(strFileName, status))
    {
        MessageBox("該檔案不存在!");
        return;
    }
    //為頂端靜态文本設定為以下格式的内容:檔案路徑全名[年-月-日, 位元組數]
    m_strTitle.Format("%s[%s, %ld位元組]", strFileName,
        status.m_ctime.Format("%Y-%m-%d"), status.m_size);
    UpdateData(FALSE);

    //加密
    char str;
    for(int i = ; i < m_strContent.GetLength(); i++)
    {
        str = m_strContent.GetAt(i);
        str = str+i;
        m_strContent.SetAt(i, str);
    }

    //文檔儲存
    file.Write(m_strContent, m_strContent.GetLength());
    file.Close();

}
           

打開自定義字尾的檔案(*.yimi)

為“打開”按鈕添加BN_CLICKED消息映射,并添加映射函數,代碼如下(包括打開檔案、頂部顯示檔案相關資訊和對*.yimi類型的檔案進行解密)

void CMyDlg::OnButtonOpen() 
{
    CString filter;
    //“依米魔法檔案(*.yimi)”即檔案類型選擇項,“*.yimi”即要求顯示的類型檔案
    filter = "依米魔法檔案(*.yimi)|*.yimi|(*.*)|*.*||";
    //第一個參數為TRUE時為“打開檔案”對話框;為FALSE時為“另存為”對話框。
    CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);
    if(dlg.DoModal()!=IDOK) return;
    //靜态文本
    CString strFileName = dlg.GetPathName();
    CFileStatus status;
    if(!CFile::GetStatus(strFileName, status))
    {
        MessageBox("該檔案不存在!");
        return;
    }

    //為頂端靜态文本設定為以下格式的内容:檔案路徑全名[年-月-日, 位元組數]
    m_strTitle.Format("%s[%s, %ld位元組]", strFileName,
        status.m_ctime.Format("%Y-%m-%d"), status.m_size);
    UpdateData(FALSE);//更新資料

    //打開檔案,并讀取資料
    m_strContent.Empty();   //清空内容
    CFile theFile;
    if(!theFile.Open(strFileName, CFile::modeRead))
    {
        MessageBox("該檔案無法打開!");
        return;
    }
    char szBuffer[];
    UINT nActual = ;
    while(nActual = theFile.Read(szBuffer, sizeof(szBuffer)))
    {
        CString str(szBuffer, nActual);
        m_strContent = m_strContent + str;
    }
    theFile.Close();

    //判斷是否是.yimi檔案
    if(dlg.GetFileExt()=="yimi")//是.yimi檔案,則解密
    {//解密
        char str;
        for(int i = ; i < m_strContent.GetLength(); i++)
        {
            str = m_strContent.GetAt(i);
            str = str-i;
            m_strContent.SetAt(i, str);
        }

        UpdateData(FALSE);//更新資料
    }
} 
           

改變視窗背景色

用MFC ClassWizard向導為CMyDlg類添加WM_CTLCOLOR消息映射,并添加以下代碼:

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    COLORREF color = RGB(, , );//天藍色
    m_Brush.Detach();
    m_Brush.CreateSolidBrush(color);
    pDC->SetBkColor(color);

//  return hbr; //隻編輯框有背景顔色

    return (HBRUSH)m_Brush;//整個窗體的背景色
}
           

改變視窗形狀

在ResourceView中添加Bitmap資源,ID設為IDB_BITMAP_DLG。注意,白色為将來可顯示的窗體部分,其他色均為透明顯示,所繪制的Bitmap圖形大小應與窗體實際大小一緻。

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記
MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

繪制如圖:

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

然後在BOOL CMyDlg::OnInitDialog()函數的return TRUE;語句前添加如下代碼:

//異形窗體
    COLORREF TransColor=RGB(,,);//白色為顯示的部分  
    CBitmap cBitmap;  
    cBitmap.LoadBitmap(IDB_BITMAP_DLG);//加載描述視窗形狀的BMP圖檔  
    CDC* pDC=this->GetDC();  
    CDC memDC;  
    memDC.CreateCompatibleDC(pDC);//建立與傳入DC相容的臨時DC  
    CBitmap *pOldMemBmp=NULL;  
    pOldMemBmp=memDC.SelectObject(&cBitmap);//将位圖選入臨時DC,友善對圖檔在控件環境中進行操作  
    static CRgn wndRgn;  
    wndRgn.CreateRectRgn(,,,);//建立總的窗體區域,初始region為0  
    BITMAP bit;  
    cBitmap.GetBitmap (&bit);//取得位圖參數,這裡要用到位圖的長和寬  
    int y;  
    CRgn rgnTemp; //儲存臨時region  
    for(y=;y<=bit.bmHeight ;y++)  
    {  
        int iX = ;  
        do  
        {  
            //跳過透明色找到下一個非透明色的點.  
            while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) != TransColor)  
                iX++;  
            //記住這個起始點  
            int iLeftX = iX;  
            //尋找下個透明色的點  
            while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) == TransColor)  
                ++iX;  
            //建立一個包含起點與重點間高為1像素的臨時“region”  
            rgnTemp.CreateRectRgn(iLeftX, y, iX, y+);  
            //合并到主"region".  
            wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR);  
            //删除臨時"region",否則下次建立時和出錯  
            rgnTemp.DeleteObject();  
        }while(iX<bit.bmWidth);  
    }  
    this->SetWindowRgn(wndRgn,TRUE);  
    memDC.DeleteDC(); 
           

具體請參見

MFC異形視窗-多邊形視窗-根據圖檔自定義視窗形狀-CRgn

最終效果如圖:

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

改變光标圖案

在ResourceView的Cursor下繪制一個光标資源,ID預設為IDC_CURSOR1。單擊“建立裝置圖像”按鈕建立裝置圖像 單擊“自定義”按鈕設定好大小顔色後按“确定”。注意:很重要的一點,接下來要在“裝置”選項中選擇系統原來預設已有的“單色[32*32]”,然後選擇“圖像”菜單的“删除裝置圖像”指令。這樣才能把我們自定義的光标正常使用。

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

接下來,為CMyDlg類添加HCURSOR類型的成員變量m_hCursor,并為CMyDlg類添加WM_SETCURSOR的消息映射函數,代碼如下:

BOOL CMyDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
    if(nHitTest == HTCAPTION)
    {
        m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);
        SetCursor(m_hCursor);
    }else if(nHitTest == HTCLIENT)
    {
        m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);
        SetCursor(m_hCursor);
    }
    return true;
}
           

生成動态自定義軟體圖示

在ResourceView的Icon下添加若幹圖示資源,如下:

MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記
MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記
MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記
MFC——“依米魔法郵箱”開發筆記“依米魔法郵箱”開發筆記

為CMyDlg添加成員函數ChangeIcon(UINT nIconID),代碼如下:

void CMyDlg::ChangeIcon(UINT nIconID)
{
    HICON hIconNew = AfxGetApp()->LoadIcon(nIconID);
    HICON hIconOld = (HICON)GetClassLong(m_hWnd, GCL_HICON);
    if(hIconNew!=hIconOld)
    {
        DestroyIcon(hIconOld);
        SetClassLong(m_hWnd, GCL_HICON, (long)hIconNew);
        RedrawWindow();
    }
}
           

接下來,要實作動畫效果,即軟體圖示不斷變化,需要用到計時器。

在BOOL CMyDlg::OnInitDialog()中添加計時器設定代碼:

其中第一個參數指定改計時器辨別值,任寫一個非零數字即可;第二個參數表示調用計時器的時間間隔,此處為以500毫秒的時間為間隔更換圖示,進而實作動畫效果;第三個參數是一個回調函數指針,一般設為NULL即可。

接下來,為CMyDlg添加WM_TIMER的消息映射函數,代碼如下:

void CMyDlg::OnTimer(UINT nIDEvent) 
{
    if(nIDEvent==)
    {//改圖示,nIDEvent即SetTimer函數的第一個參數——計時器辨別值
        static int icons[] = {IDI_ICON1, IDI_ICON2, IDI_ICON3, IDI_ICON4};//圖示
        static int index = ;
        ChangeIcon(icons[index]);
        index++;
        if(index>) index = ;  
    }

    CDialog::OnTimer(nIDEvent);
}
           

接下來,為CMyDlg添加WM_DESTROY的消息映射函數,代碼如下:

void CMyDlg::OnDestroy() 
{
    CDialog::OnDestroy();
    KillTimer();   
}
           

OK,可以運作看結果啦~

源碼及程式下載下傳

下載下傳源碼及程式