Windows API隨手筆記<一>:Commond Control 用法及實踐記錄

来源:互联网 发布:数据库建模谁来做 编辑:程序博客网 时间:2024/04/29 06:45

為了實踐工程數學中,傅立葉變換用於音頻處理的技術,在Matlab的作法早已了然於心,但不用他人數學庫、不用C++自己幹一個算法實作出來

就是不痛快。

因此,特地去翻了翻Windows關於音訊處理的流程以及方法,貌似現在windows關於多媒體處理的技術現在都用Microsoft Media Foundation來實踐了。

快速理解該技術架構後,開始查找相關資源並進行理解,沒想到MSDN上的相關範例竟然有不少函式是被deprecated的,真差點沒被氣死。

這裡有坑,因此在此提醒各位看官。


花了不少時間後才終於在windows7SDK中找到"合適"範例代碼。SDK範例代碼現在可以從GITHUB直接下載,連結網址。

Microsoft Media Foundation 的MFPlayer範例中,有段特殊的代碼是之前沒看過的。

    // Initialize the common control library.    INITCOMMONCONTROLSEX icc;    icc.dwSize = sizeof(icc);    icc.dwICC = ICC_STANDARD_CLASSES | ICC_BAR_CLASSES;    if (!InitCommonControlsEx(&icc))    {        MessageBox(NULL, L"InitCommonControlsEx failed.", NULL, MB_ICONSTOP);        CoUninitialize();        return 0;    }
之後一查,原來windows還有為一些特別控件進行動態函示庫包裝,能讓人快速調用。

這裡來做些展示。


像這種下載動畫:



或是像這種菜單欄


心動不?以前像這種控件都是自己手刻的,不然就是要套用其他人的庫,現在才知道Windows有這麼好用的庫,

真是相見恨晚。

迫不及待想快速掌握用法了。

先來附上一的Msdn關於 common control的連結:https://msdn.microsoft.com/zh-tw/library/windows/desktop/bb775493(v=vs.85).aspx

接著就跟以前一樣,直接從閱讀代碼來學習它的用法。

以下也是筆者一邊看代碼,一邊學習並記錄。



這是連結所需要的庫,及頭文件。

#include <commctrl.h>#pragma comment(lib, "comctl32.lib")



這是程序進入點,其中 IDD_MAINDIALOG是主視窗樣板資源,DialogProc是該視窗回調函數。

int APIENTRY wWinMain(HINSTANCE hInstance,                      HINSTANCE hPrevInstance,                      LPWSTR    lpCmdLine,                      int       nCmdShow){    g_hInst = hInstance;    return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, DialogProc);}



這是 DialogProc實現,用於對各類信息進行轉發,由上到下分別是初始化窗口信息,及菜單欄信息、窗口關閉信息。

HANDLE_MSG其實是個宏,宏定義長得像這樣:

#define HANDLE_MSG(hwnd, message, fn)    \

    case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))

就是做了一層信息轉發。

INT_PTR CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    switch (message)    {        // Handle the WM_INITDIALOG message in OnInitDialog        HANDLE_MSG (hWnd, WM_INITDIALOG, OnInitDialog);        // Handle the WM_COMMAND message in OnCommand        HANDLE_MSG (hWnd, WM_COMMAND, OnCommand);        // Handle the WM_CLOSE message in OnClose        HANDLE_MSG (hWnd, WM_CLOSE, OnClose);    default:        return FALSE;    }    return 0;}


OnInitDialog 進去發現只有return true;

而OnCommand長得像以下代碼,針對類型按鈕的回調函數




void OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify){    switch (id)    {    case IDC_BUTTON_ANIMATION:        {            HWND hDlg = CreateDialog(g_hInst,                 MAKEINTRESOURCE(IDD_ANIMATIONDIALOG),                 hWnd, AnimationDlgProc);            if (hDlg)            {                ShowWindow(hDlg, SW_SHOW);            }        }        break;    case IDC_BUTTON_COMBOBOXEX:        {            HWND hDlg = CreateDialog(g_hInst,                 MAKEINTRESOURCE(IDD_COMBOBOXEXDIALOG),                 hWnd, ComboBoxExDlgProc);            if (hDlg)            {                ShowWindow(hDlg, SW_SHOW);            }        }        break;    case IDC_BUTTON_DATETIMEPICK:        {            HWND hDlg = CreateDialog(g_hInst,                 MAKEINTRESOURCE(IDD_DATETIMEPICKDIALOG),                 hWnd, DateTimePickDlgProc);            if (hDlg)            {                ShowWindow(hDlg, SW_SHOW);            }        }        break;.....省略.....

IDC_BUTTON_ANIMATION進去後可以看見在貼文章下載動畫。

CreateDialog是依造資源項創建視窗,而重點在於AnimationDlgProc 這個回調函數。




AnimationDlgProc其實又是一層消息轉發函數。

INT_PTR CALLBACK AnimationDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    switch (message)    {        // Handle the WM_INITDIALOG message in OnInitAnimationDialog        HANDLE_MSG (hWnd, WM_INITDIALOG, OnInitAnimationDialog);        // Handle the WM_CLOSE message in OnClose        HANDLE_MSG (hWnd, WM_CLOSE, OnClose);    default:        return FALSE;// Let system deal with msg    }    return 0;}

這總算是真正實現代碼的位置了,當子窗口生成時會自動執行以下代碼。

BOOL OnInitAnimationDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam){    // Load and register animation control class.    INITCOMMONCONTROLSEX iccx = { sizeof(iccx) };    iccx.dwICC = ICC_ANIMATE_CLASS;    if (!InitCommonControlsEx(&iccx))    {        return FALSE;    }    // Create the animation control.    RECT rc = { 20, 20, 280, 60 };//在子窗口中又創建控件window用於跑動畫    HWND hAnimate = CreateWindowEx(0, ANIMATE_CLASS, 0,         ACS_TIMER | ACS_AUTOPLAY | ACS_TRANSPARENT | WS_CHILD | WS_VISIBLE,         rc.left, rc.top, rc.right, rc.bottom,         hWnd, reinterpret_cast<HMENU>(IDC_ANIMATION), g_hInst, 0);    if (hAnimate == NULL)    {        return FALSE;    }    // Open the AVI clip and display its first frame in the animation control.    if (0 == SendMessage(hAnimate, ACM_OPEN, static_cast<WPARAM>(0),         reinterpret_cast<LPARAM>(MAKEINTRESOURCE(IDR_UPLOAD_AVI))))    {        return FALSE;    }    // Plays the AVI clip in the animation control.    if (0 == SendMessage(hAnimate, ACM_PLAY, static_cast<WPARAM>(-1),         MAKELONG(/*from frame*/0, /*to frame*/-1)))    {        return FALSE;    }    return TRUE;}

其中,在Create window時,ANIMATE_CLASS及後面不曾見過的Style宣告在在我們一開始引入的頭文件裡

SendMessage(hAnimate, ACM_OPEN, static_cast<WPARAM>(0),         reinterpret_cast<LPARAM>(MAKEINTRESOURCE(IDR_UPLOAD_AVI))
發現了一件不得了的事,原來剛剛的實踐,只有完成動畫播放器而已,真正的動畫資源還是要自己引入的,

如本次中,為IDR_UPLOAD_AVI。


還有其他common control範例,可以直接參考連結:https://code.msdn.microsoft.com/windowsapps/CppWindowsCommonControls-9ea0de64

而我自己看完這一系列api後,打算自己時做一個相似的效果,來加深印象。
在範例的最末尾發現他給的參考連結:https://msdn.microsoft.com/en-us/library/bb761881.aspx













0 0
原创粉丝点击