程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> MFC客戶端開發記錄

MFC客戶端開發記錄

編輯:C++入門知識

      最近在寫一個MFC程序,感覺MFC發展了很多年,應該是趨於完善的;具體表現在:相關的文檔比較全,相關功能的Demo可以很方便的google到。因此,在MFC上做一些基本功能應該是沒問題的。

MFC文檔

        MSDN上的文檔也比較全,相關的文檔參考:MFC Reference,Controls (MFC)。本文中,提到的一些功能,並不只和MFC相關。既然用到了,就記在一起,方便查詢。


功能


托盤圖標

        在windows右下角的托盤中,顯示圖標。此功能比較常見,參考代碼如下:
[cpp]
NOTIFYICONDATAW   m_IconData; 
 
m_IconData.cbSize = sizeof(NOTIFYICONDATAW); 
m_IconData.uCallbackMessage = m_messageId; // Try icon的消息ID  
m_IconData.dwInfoFlags = NIIF_INFO; 
m_IconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 設定圖標接受的消息  
m_IconData.uID = ID_TRAY_ICON; // 用來區分的icon的ID  
m_IconData.hWnd = hWnd; // 接受消息的窗口  
m_IconData.hIcon = m_hIconOffLine; // IDI_TRAY是在資源文件中定義的ICON的ID,可在資源sheet中用自帶工具生成。  
CMsg info(IDS_TRAY_VERSION); 
wcscpy(m_IconData.szTip, info); 
 
Shell_NotifyIcon(NIM_ADD, &m_IconData); 

    NOTIFYICONDATAW   m_IconData;

    m_IconData.cbSize = sizeof(NOTIFYICONDATAW);
    m_IconData.uCallbackMessage = m_messageId; // Try icon的消息ID
    m_IconData.dwInfoFlags = NIIF_INFO;
    m_IconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 設定圖標接受的消息
    m_IconData.uID = ID_TRAY_ICON; // 用來區分的icon的ID
    m_IconData.hWnd = hWnd; // 接受消息的窗口
    m_IconData.hIcon = m_hIconOffLine; // IDI_TRAY是在資源文件中定義的ICON的ID,可在資源sheet中用自帶工具生成。
    CMsg info(IDS_TRAY_VERSION);
    wcscpy(m_IconData.szTip, info);

    Shell_NotifyIcon(NIM_ADD, &m_IconData);        更多細節可以參考:NOTIFYICONDATA structure,Shell_NotifyIcon function。


多語言

        多語言的一種簡單的實現方式是:定義一個DLL工程,除了創建一份新的rc文件外,加入所有的其它資源文件,修改rc文件中的字符串。然後,采用下面的方式加載到運行的程序中:

[cpp]
m_hInsChs = LoadLibrary(_T("LangChs.dll")); // LangChs.dll為某個語言對應的dll。  
AfxSetResourceHandle(m_hInsChs); 

    m_hInsChs = LoadLibrary(_T("LangChs.dll")); // LangChs.dll為某個語言對應的dll。
    AfxSetResourceHandle(m_hInsChs);        可以參考文章《Internationalization and Multiple Language Support》,其中包含了一個可運行、測試的Demo。


屬性頁對話框
        MFC中,屬性頁面對話框,可以用來制作配置頁面和向導頁面。與它相關聯的類為:CPropertySheet和CPropertyPage。定義屬性頁對話框和普通的對話框差不多,此處不贅述。

        若想要修改屬性頁對話框的一些屬性,可以參考文章《Hacking the CPropertySheet》。
        顯示屬性頁對話框,可以參考一下語句:
[cpp]
if (!m_initializeDialog.m_hWnd) { // 判斷對話框是否創建。  
    m_initializeDialog.SetWizardMode(); // 切換到向導模式  
    m_initializeDialog.Create(); // 創建並顯示  
} else { 
    m_initializeDialog.SetForegroundWindow(); // 若已創建,則顯示出來  

    if (!m_initializeDialog.m_hWnd) { // 判斷對話框是否創建。
        m_initializeDialog.SetWizardMode(); // 切換到向導模式
        m_initializeDialog.Create(); // 創建並顯示
    } else {
        m_initializeDialog.SetForegroundWindow(); // 若已創建,則顯示出來
    }

保持文件夾

        所謂保持文件夾,就是將文件夾控制在程序中,防止用戶在程序外進行刪除等操作。可以參考下面的代碼:
[cpp]
HANDLE hDir = CreateFileW(dirpath,  
                          GENERIC_READ,  
                          FILE_SHARE_READ | FILE_SHARE_WRITE,  
                          NULL,  
                          OPEN_EXISTING,  
                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,  
                          NULL); 

    HANDLE hDir = CreateFileW(dirpath,
                              GENERIC_READ,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
                              NULL);        細節可參考文檔:CreateFile function。

 

帶顏色的靜態文本框

        具體參考文章《Using colors in CEdit and CStatic》,此文使用了一個類繼承並擴展了CStatic控件的功能。


超鏈接

        MFC中,有超鏈接控件,感覺不大好用,於是找了個基於CStatic的自定義控件的文章《Hyperlink control》。若要使用此控件,可能需要對它的源碼略作修改。


選擇文件夾對話框

        直接參考文章《CFolderDialog - Selecting Folders》即可,它裡面對Windows的API進行了封裝,具體細節參考源碼。


MD5轉碼

        采用文章《Use Windows Crypto API to calculate a MD5 string》內的方案即可。不過這個是非Unicode編碼的,使用的時候需要注意。


附加控制台

        這個功能是指在MFC程序起來的時候,彈出控制台打印,一般用來調試。此部分參考下面語句:
[cpp]
int hCrt; 
FILE *hf; 
// 創建一個新的控制台  
AllocConsole();  
// 綁定到標准輸出  
hCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT); 
hf = _fdopen( hCrt, "w" ); 
// 替換標准輸出stdout,讓printf可用  
m_stdoutOld = *stdout; 
*stdout = *hf; 
// 清空輸出緩存  
setvbuf( stdout, NULL, _IONBF, 0 ); 
// 測試  
printf("my console is running from printf\n"); 
std::cout << "my console is running from std::cout" << std::endl; 

    int hCrt;
    FILE *hf;
    // 創建一個新的控制台
    AllocConsole();
    // 綁定到標准輸出
    hCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
    hf = _fdopen( hCrt, "w" );
    // 替換標准輸出stdout,讓printf可用
    m_stdoutOld = *stdout;
    *stdout = *hf;
    // 清空輸出緩存
    setvbuf( stdout, NULL, _IONBF, 0 );
    // 測試
    printf("my console is running from printf\n");
    std::cout << "my console is running from std::cout" << std::endl;

回調
        MFC中,難免要用到回調機制,直接采用庫sigslot即可,該庫只有一個頭文件。具體用法參考《libjingle源碼分析之一:Signal機制》。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved