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

為了實踐工程數學中,傅立葉變換用於音頻處理的技術,在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













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值