类似qq魔法表情播放器的实现

来源:互联网 发布:淘宝如何设置降价宝贝 编辑:程序博客网 时间:2024/03/29 05:28
    qq魔法表情播放器应该是一个dynamic ole object host之类的东东,其能播放swf之类的文件,并且播放时是没有窗体的,这让人看起来感觉很酷,下面简单的讲一下其实现。
    首先利用flash.ocx写一个透明显示flash的控件,这个可以参考http://www.codeguru.com/cpp/com-tech/activex/com/article.php/c12229/#more关于写透明flash控件的。
    然后在该透明flash控件上添上相关的有用的设置,大家可以添加自己想要的功能,我讲下我添加的功能和实现步骤。
    1.用vs2008(推荐vs 6.0,我是没有安装)创建个Win32的项目,然后向项目添加下载的透明flash控件FlashWnd.cpp和FlashWnd.h文件。
    2.因为要无窗体显示透明的flash,可以在主窗体创建后并不显示,然后创建相应的CFlashWnd。
  1. int APIENTRY _tWinMain(HINSTANCE hInstance,
  2.                      HINSTANCE hPrevInstance,
  3.                      LPTSTR    lpCmdLine,
  4.                      int       nCmdShow)
  5. {
  6.     UNREFERENCED_PARAMETER(hPrevInstance);
  7.     UNREFERENCED_PARAMETER(lpCmdLine);
  8.     // TODO: 在此放置代码。
  9.     MSG msg;
  10.     HACCEL hAccelTable;
  11.     // 初始化全局字符串
  12.     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  13.     LoadString(hInstance, IDC_MAGICFLASH, szWindowClass, MAX_LOADSTRING);
  14.     MyRegisterClass(hInstance);
  15.     // 执行应用程序初始化:
  16.     if (!InitInstance (hInstance, nCmdShow))
  17.     {
  18.         return FALSE;
  19.     }
  20.     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MAGICFLASH));
  21.     OleInitialize(NULL);   
  22.    
  23.    //创建相应的显示透明flash的控件窗口
  24.     g_flashWnd = new CFlashWnd;
  25.     g_flashWnd->Create(ShockwaveFlashObjects::CLSID_ShockwaveFlash,
  26.         WS_EX_LAYERED, WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS,
  27.         g_hWnd, g_hInst);
  28.     
  29.     // 主消息循环:
  30.     while (GetMessage(&msg, NULL, 0, 0))
  31.     {
  32.         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  33.         {
  34.             TranslateMessage(&msg);
  35.             DispatchMessage(&msg);
  36.         }
  37.     }
  38.     delete g_flashWnd;
  39.     OleUninitialize();
  40.     return (int) msg.wParam;
  41. }
    3.因为隐藏了主窗口,所以要用透明显示Flash的控件来交互,如加载flash、退出程序,这里可以通过修改FlashWnd.h中的COleContainerWnd窗口的回调函数来实现
  1. OLECONTAINER(LRESULT)::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2. {
  3.     int wmId, wmEvent;
  4.     switch (uMsg)
  5.     {
  6.     case WM_COMMAND:
  7.         {
  8.             wmId    = LOWORD(wParam);
  9.             wmEvent = HIWORD(wParam);
  10.             // 分析菜单选择:
  11.             switch (wmId)
  12.             {
  13.             case ID_RIGHTMENU_LOAD:
  14.                 {
  15.                     //加载Flash,显示打开文件对话框
  16.                     OPENFILENAME   ofn;   
  17.                     memset(&ofn, 0, sizeof(OPENFILENAME)); 
  18.                     memset(szFile, 0, sizeof(szFile));
  19.                     ofn.lStructSize = sizeof(OPENFILENAME);   
  20.                     ofn.hwndOwner = m_hWnd;   
  21.                     ofn.lpstrFile = szFile;   
  22.                     ofn.nMaxFile = MAX_PATH;   
  23.                     ofn.lpstrFilter = TEXT("SWF Files (*.swf)/0*.swf/0");   
  24.                     ofn.lpstrDefExt = TEXT("swf");   
  25.                     ofn.lpstrTitle = TEXT("打开SWF文件");   
  26.                     ofn.nFilterIndex = 1;   
  27.                     ofn.lpstrFileTitle = NULL;   
  28.                     ofn.nMaxFileTitle = 0;   
  29.                     ofn.lpstrInitialDir = NULL;   
  30.                     if(GetSaveFileName(&ofn))   
  31.                     {   
  32.                         WritePrivateProfileString(L"Magic Flash", L"File", szFile, L"MagicFlash.ini");
  33.                         m_bGetRect = FALSE;
  34.                         m_uSize = ID_RIGHTMENU_NORMAL;
  35.                         OnAfterShowingContent();
  36.                     }
  37.                 }
  38.                 
  39.                 break;
  40.             //设置播放Flash的质量,这里采用多态实现,SetQuality为一虚函数,在CFlashWnd中实现
  41.             case ID_RIGHTMENU_LOW:
  42.             case ID_RIGHTMENU_MID:
  43.             case ID_RIGHTMENU_HIGH:
  44.                 m_uQuality = wmId;
  45.                 SetQuality(m_uQuality);
  46.                 break;
  47.             //设置播放flash的大小
  48.             case ID_RIGHTMENU_QUARTER:
  49.             case ID_RIGHTMENU_HALF:
  50.             case ID_RIGHTMENU_THREE_QUARTER:
  51.             case ID_RIGHTMENU_NORMAL:
  52.             case ID_RIGHTMENU_DOUBLE:
  53.                 {
  54.                     if(!m_bGetRect)
  55.                     {
  56.                         RECT rt;
  57.                         GetWindowRect(hWnd, &rt);
  58.                         m_uNormalHeight = rt.bottom - rt.top;
  59.                         m_uNormalWidth = rt.right - rt.left;
  60.                         m_bGetRect = TRUE;
  61.                     }
  62.                     m_uSize = wmId;
  63.                     SetSize(hWnd, m_uSize);
  64.                 }
  65.                 break;
  66.             //弹出About窗口,并把消息发给主窗口
  67.             case ID_RIGHTMENU_ABOUT:
  68.                 SendMessage(m_hWndParent, WM_COMMAND, IDM_ABOUT, NULL);
  69.                 break;
  70.             //设置是否最前显示
  71.             case ID_RIGHTMENU_TOP:
  72.                 m_bTopCheck = !m_bTopCheck; 
  73.                 if(m_bTopCheck)
  74.                 {
  75.                     SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  76.                 }
  77.                 else
  78.                 {
  79.                     SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  80.                 }
  81.                 break;
  82.             //退出消息,发送给主窗口
  83.             case ID_RIGHTMENU_EXIT:
  84.                 PostQuitMessage(0);
  85.                 SendMessage(m_hWndParent, WM_DESTROY, wParam, lParam);
  86.                 break;
  87.             default:
  88.                 return DefWindowProc(hWnd, uMsg, wParam, lParam);
  89.             }
  90.         }
  91.         break;
  92.     case WM_CREATE:
  93.         {
  94.             LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
  95.             SetWindowLong(hWnd, GWL_USERDATA, (long)lpcs->lpCreateParams);
  96.             return 0;
  97.         }
  98.         break;
  99.     case WM_PAINT:
  100.         {
  101.             if (!m_bTransparent)
  102.             {
  103.                 PAINTSTRUCT ps;
  104.                 HDC hdc = ::BeginPaint(GetHWND(), &ps);
  105.                 Draw(hdc, &ps.rcPaint, ps.fErase);
  106.                 ::EndPaint(GetHWND(), &ps);
  107.                 return 0;
  108.             }
  109.         }
  110.         break;
  111.     case WM_NCHITTEST:
  112.         {
  113.             int x = LOWORD(lParam), y = HIWORD(lParam);
  114.             if (m_lpO && m_lpViewObjectEx)
  115.             {
  116.                 IViewObjectEx *lpV = m_lpViewObjectEx;
  117.                 POINT p = {x, y};
  118.                 DWORD dwRes;
  119.                 RECT rTotal;
  120.                 GetWindowRect(GetHWND(), &rTotal);
  121.                 HRESULT hr = lpV->QueryHitPoint(DVASPECT_CONTENT, &rTotal, p, 1, &dwRes);
  122.                 if (hr == S_OK)
  123.                 {
  124.                     if (dwRes == HITRESULT_OUTSIDE)
  125.                         return HTTRANSPARENT;
  126.                     else
  127.                         return HTCLIENT;
  128.                 }
  129.             }
  130.         }
  131.         break;
  132.     case WM_LBUTTONDOWN:
  133.         SendMessage(m_hWnd, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
  134.         break;
  135.     case WM_LBUTTONUP:
  136.         SendMessage(m_hWnd, WM_NCLBUTTONUP, HTCAPTION, lParam);
  137.         break;
  138.     case WM_SIZE:
  139.         {
  140.             HRESULT hr;
  141.             RECT rPos;
  142.             GetClientRect(GetHWND(), &rPos);
  143.             RECT rClip = rPos;
  144.             if (m_lpInPlaceObjWindowless)
  145.                 hr = m_lpInPlaceObjWindowless->SetObjectRects(&rPos, &rClip);
  146.             else if (m_lpInPlaceObj)
  147.                 hr = m_lpInPlaceObj->SetObjectRects(&rPos, &rClip);
  148.             return 0;
  149.         }
  150.         break;
  151.     //弹出相应的右键菜单
  152.     case WM_RBUTTONDOWN:
  153.         {
  154.             POINT curPos;                      
  155.             GetCursorPos(&curPos);
  156.             HMENU popMenu,rightMenu;
  157.             rightMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDR_MENU_RIGHT_POP));
  158.             popMenu = GetSubMenu(rightMenu, 0);
  159.             if(m_bTopCheck)
  160.             {
  161.                 CheckMenuItem(popMenu, ID_RIGHTMENU_TOP, MF_BYCOMMAND | MF_CHECKED);
  162.             }
  163.             CheckMenuItem(popMenu, m_uQuality, MF_BYCOMMAND | MF_CHECKED);
  164.             CheckMenuItem(popMenu, m_uSize, MF_BYCOMMAND | MF_CHECKED);
  165.             TrackPopupMenu(popMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,curPos.x,curPos.y,0, hWnd, NULL);
  166.             DestroyMenu(popMenu);
  167.             DestroyMenu(rightMenu);
  168.         }
  169.         break;
  170.     }
  171.     if (m_lpInPlaceObjWindowless)
  172.     {
  173.         if (uMsg == WM_MOUSEMOVE || /*uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP ||*/ uMsg == WM_LBUTTONDBLCLK
  174.             || uMsg == WM_RBUTTONUP || uMsg == WM_RBUTTONDBLCLK
  175.             || uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP || uMsg == WM_MBUTTONDBLCLK
  176.             || uMsg == WM_MOUSEWHEEL 
  177.             || uMsg == WM_KEYDOWN || uMsg == WM_KEYUP || uMsg == WM_CHAR
  178.             || uMsg == WM_SETCURSOR
  179.             )
  180.         {
  181.             HRESULT hr;
  182.             LRESULT res;
  183.             hr = m_lpInPlaceObjWindowless->OnWindowMessage(uMsg, wParam, lParam, &res);
  184.             if (hr == S_OK)
  185.                 return res;
  186.         }
  187.     }
  188.     return DefWindowProc(hWnd, uMsg, wParam, lParam);
  189. }
    4.主窗口的回调函数,与透明显示flash要相关的交互

  1. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  2. {
  3.     int wmId, wmEvent;
  4.     PAINTSTRUCT ps;
  5.     HDC hdc;
  6.     
  7.     UINT WM_TASKBARCREATED;
  8.     // 不要修改TaskbarCreated,这是系统任务栏自定义的消息
  9.     WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
  10.     switch (message)
  11.     {
  12.     case WM_CREATE:
  13.         {
  14.             //添加相应的系统托盘
  15.             nid.cbSize = sizeof(nid);
  16.             nid.hWnd = hWnd;
  17.             nid.uID = 0;
  18.             nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
  19.             nid.uCallbackMessage = WM_USER;
  20.             nid.hIcon = g_hIcon;
  21.             nid.dwState = NIS_SHAREDICON;
  22.             nid.uTimeout = 5000;
  23.             nid.dwInfoFlags = NIIF_INFO;   
  24.             lstrcpy(nid.szTip, L"MagicFlash");
  25.             lstrcpy(nid.szInfoTitle, L"MagicFlash");
  26.             lstrcpy(nid.szInfo, L"未加载Flash");
  27.             Shell_NotifyIcon(NIM_ADD, &nid);
  28.         }
  29.         break;
  30.     case WM_USER:
  31.         {
  32.             if (lParam == WM_LBUTTONDBLCLK)
  33.             {
  34.                 SetForegroundWindow(g_flashWnd->m_hWnd);
  35.             }
  36.             if (lParam == WM_RBUTTONDOWN)
  37.             {
  38.                 SetForegroundWindow(hWnd);
  39.                 SendMessage(g_flashWnd->m_hWnd, WM_RBUTTONDOWN, wParam, lParam);
  40.             }
  41.         }
  42.         break;
  43.     case WM_COMMAND:
  44.         wmId    = LOWORD(wParam);
  45.         wmEvent = HIWORD(wParam);
  46.         // 分析菜单选择:
  47.         switch (wmId)
  48.         {
  49.         case IDM_ABOUT:
  50.             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), g_flashWnd->m_hWnd, About);
  51.             break;
  52.         case IDM_EXIT:
  53.             DestroyWindow(hWnd);
  54.             break;
  55.         default:
  56.             return DefWindowProc(hWnd, message, wParam, lParam);
  57.         }
  58.         break;
  59.     case WM_PAINT:
  60.         hdc = BeginPaint(hWnd, &ps);
  61.         // TODO: 在此添加任意绘图代码...
  62.         EndPaint(hWnd, &ps);
  63.         break;
  64.     case WM_DESTROY:
  65.         Shell_NotifyIcon(NIM_DELETE, &nid);
  66.         PostQuitMessage(0);
  67.         break;
  68.     default:
  69.         if(message == WM_TASKBARCREATED)
  70.         {
  71.             SendMessage(hWnd, WM_CREATE, wParam, lParam);
  72.             break;
  73.         }
  74.         return DefWindowProc(hWnd, message, wParam, lParam);
  75.     }
  76.     return 0;
  77. }
    这样无窗体的可以显示透明flash的播放器就实现了,运行截图


相关源代码(上传不了附件,就搁到资源上了),下载页面
原创粉丝点击