開源軟體《M8圍棋譜》v0.8.8 首次登陸魅族軟體中心,免費發布,技術總結

來源:互聯網
上載者:User

  今日(2010/7/22),本人(liigo)開發的C/C++開源軟體《M8圍棋譜》v0.8.8 首次登陸魅族軟體中心,免費發布。本文主要針對“如何滿足魅族軟體中心對軟體的各項要求”作一些技術總結。

  眾所周知,魅族對發布在軟體中心的軟體有詳細的要求、嚴格的審核,工作人員甚至幫你測試尋找BUG,細緻入微,熱心而且周到,工作效率也挺高,周六都在加班工作。在《M8圍棋譜(v0.8.8)》申請進入魅族軟體中心之前,我逐條對照《魅族手機應用軟體審核標準1.2》,自我審核並修改了部分內容,後來有幾經周折按照魅族軟體中心工作人員的反饋,修改了另外部分內容。總結一下,此次為登陸魅族軟體中心,大概修改了一下內容:

  軟體必須單一實例運行;

  必須設定標題列文本;

  軟體在系統工作管理員中的顯示文本必須與軟體名稱一致;

  通過USB串連電腦時軟體必須退出,且不彈出任何提示;

  軟體啟動、退出、切換視窗時必須有動畫效果;

  軟體在英文系統下運行不能有中文亂碼;

  如果軟體有播放聲音的功能,必須允許使用者通過音量鍵(物理按鍵)調節聲音,必須有選項可以關閉聲音;

總體來說,它的審核有點過分瑣碎、過分嚴格,有些細節在編碼實現上有過分複雜(這是SDK設計不夠友好)。

 

  軟體必須單一實例運行,我是通過建立系統全域Event對象實現的,與官方範例程式碼稍有區別:

//應MStore要求,必須單一實例運行<br />m_eventHandle = CreateEvent(NULL, FALSE, FALSE, L"Global//M8WeiqiPu_by_liigo");<br />if(m_eventHandle && GetLastError() == ERROR_ALREADY_EXISTS)<br />{<br />HWND hWnd = FindWindowW(NULL, M8_WEIQIPU);<br />if(hWnd)<br />{<br />SetForegroundWindow(hWnd);<br />SetActiveWindow(hWnd);<br />::ShowWindow(hWnd, SW_SHOWNORMAL);<br />::UpdateWindow(hWnd);<br />}<br />PostQuitMessage(0);<br />return FALSE;<br />}<br />else<br />SetWindowText(M8_WEIQIPU);

  上面的代碼中,首先建立全域Event對象,如果發現同名對象已存在,說明本軟體已經有一個執行個體在運行,通過WinCE API函數FindWindow()找到主視窗並啟用它,然後退出當前進程。

 

  軟體在系統工作管理員中的顯示文本必須與軟體名稱一致。文檔中似乎沒有提到系統工作管理員中的顯示文本取自何處,我總結得知,如果通過WinCE API函數SetWindowText()設定了主視窗標題列文本,則顯示該文本,否則顯示軟體EXE檔案名稱(無路徑)。所以要滿足此條要求,只需設定標題列文本為軟體中文名稱即可。

 

  通過USB串連電腦時軟體必須退出,且不彈出任何提示。這個實現起來稍微有一點麻煩,但是也簡單,SDK文檔有相關說明。首先要定義一個類成員 int m_usbNotifyMsg,在視窗初始化時(OnInitDialog)對其賦值:m_usbNotifyMsg = RegisterUsbNotifyMsg();,即通過調用MZ SDK 函數RegisterUsbNotifyMsg()擷取“USB串連相關的”訊息值。然後,在CMzWnd::MzDefWndProc()方法中處理USB串連訊息,主要代碼如下:

virtual LRESULT MzDefWndProc(UINT message, WPARAM wParam, LPARAM lParam)<br />{<br />if( message == m_usbNotifyMsg) //應MStore要求:USB串連時靜默退出程式<br />{<br />if(wParam == USB_MASSSTORAGE_ATTACH)<br />{<br />Quit();<br />}<br />}<br />…………

 

  軟體啟動、退出、切換視窗時必須有動畫效果。主要是 CMzWnd::AnimateWindow(MZ_ANIMTYPE_ZOOM_IN, true) 此類代碼調用,SDK文檔中有範例程式碼,簡單。

 

  軟體在英文系統下運行不能有中文亂碼。M8圍棋譜軟體需要讀取GB編碼的SGF棋譜檔案,我(liigo)自行開發的SGF解析器解析出來的文本都是GB編碼(char*),而軟體本身是UNICODE的,中間需要進行編碼轉換。我原來使用C庫函數 mbstowcs() 轉換編碼,後來被魅族軟體中心測試人員發現,在軟體運行在英文系統下時,此舉會造成中文顯示亂碼。我分析後估計是locale的原因,事先調用C庫函數setlocale()設定為中文locale應該就能解決吧?然後又發現WinCE下的C運行庫似乎沒有setlocale()函數。於是放棄這個思路,改用WinCE API函數MultiByteToWideChar()進行編碼轉換(GB2312->UCS2LE),主要代碼如下:

//確保在英文系統下也能轉換SGF檔案中的中文字元到Unicode<br />static int cncharsToWChar(const char* cnchars, WCHAR* wchars_buffer, int wchar_buffer_size)<br />{<br />if(wchars_buffer == NULL)<br />return MultiByteToWideChar(936 /*gb2312*/, 0, cnchars, -1, NULL, 0);<br />else<br />return MultiByteToWideChar(936 /*gb2312*/, 0, cnchars, -1, wchars_buffer, wchar_buffer_size);<br />}

 

  如果軟體有播放聲音的功能,必須允許使用者通過音量鍵(物理按鍵)調節聲音,必須有選項可以關閉聲音。我原來是調用WinCE API函數PlaySound()播放WAVE檔案的,如此一來不好處理音量大小的控制。後來選擇調用MZ SDK提供的COM介面IPlayerCore_Play,首先是相關COM對象的初始化(基本上是引用SDK文檔中的範例程式碼,相當繁瑣):

#include <IMzSysFile.h><br />#include <IPlayerCore.h><br />#include <IPlayerCore_IID.h><br />#include <PlayerCore_GUID.h><br />IPlayerCore_Play* m_pPlayCore;<br />IMzSysFile* m_pSysFile;<br />//初始化聲音播放組件<br />m_pSysFile = NULL;<br />m_pPlayCore = NULL;<br />if(SUCCEEDED( CoCreateInstance(CLSID_PlayerCore, NULL, CLSCTX_INPROC_SERVER, IID_MZ_SysFile, (void **)&m_pSysFile)))<br />{<br />m_pSysFile->SetParentWnd(m_hWnd);<br />if( !SUCCEEDED(m_pSysFile->QueryInterface( IID_PlayerCore_Play, (void**)&m_pPlayCore)) )<br />{<br />m_pSysFile->Release();<br />m_pSysFile = NULL;<br />}<br />//m_pPlayCore->SetNotify(m_hWnd, WM_USER + 15);<br />}

  欲播放音樂檔案時,先調用 m_pSysFile->SetName(m_luoziSoundFile),然後調用 m_pPlayCore->OpenFile(),然後調用 m_pPlayCore->Play(),當然,Play()之前可以調用 m_pPlayCore->SetVolume(m_soundVolume) 設定音量:

m_pSysFile->SetName(m_luoziSoundFile);<br />m_pPlayCore->OpenFile();<br />m_pPlayCore->SetVolume(m_soundVolume);<br />m_pPlayCore->Play();

 

  接下來要處理使用者按下音樂鍵(物理按鍵)的訊息了,以便增減音量。方法與處理USB串連事件大致相同(代碼之繁瑣有過之而無不及):

int m_allkeyEventMsg;<br />int m_soundVolume;<br />RegisterShellMessage(m_hWnd, WM_MZSH_ALL_KEY_EVENT);<br />m_allkeyEventMsg = GetShellNotifyMsg_AllKeyEvent();<br />virtual LRESULT MzDefWndProc(UINT message, WPARAM wParam, LPARAM lParam)<br />{<br />if(message == m_allkeyEventMsg) //應MStore要求:音量鍵調節聲音<br />{<br />int key = LOWORD(wParam); //WPARAM_KEY_EVENT_***<br />if(key == WPARAM_KEY_EVENT_CLICK_VOLUP)<br />{<br />m_soundVolume += 7; //與按下音量鍵時的系統音量變化幅度保持基本一致<br />if(m_soundVolume > 100) m_soundVolume = 100;<br />m_skin.SetSoundVolume(m_soundVolume);<br />}<br />else if(key == WPARAM_KEY_EVENT_CLICK_VOLDOWN)<br />{<br />m_soundVolume -= 7;<br />if(m_soundVolume < 0) m_soundVolume = 0;<br />m_skin.SetSoundVolume(m_soundVolume);<br />}<br />}<br />…………

 

  實現響應音樂鍵調節音量的過程中,有個細節我處理的不夠理想,即,沒有找到擷取當前音量的方法。使用者按“上音量鍵”我增加音量,使用者按“下音量鍵”我減小音量,可是音量的初始值是什麼呢?一直沒找到方法讀取,只好暫時以當前系統來電鈴聲音量替代。目前的效果不是很好:使用者按音樂鍵時,系統會自動彈出一個音量大小進度顯示框,而它顯示的值有時明顯不能跟我軟體中的音量一致起來。歸根結底還是沒有取得音量初始值。鬱悶。如果系統改進一下介面,在使用者按下音樂鍵時,直接返回給我音量值多好。

 

  總體的感覺,MZ SDK 的 API 介面設計不是非常友好,有些地方使用起來相當繁瑣。是不是我易語言代碼寫多了,再不願寫又臭又長的代碼?我倒是很期待Android SDK,想象中Google設計的API應該相當OK吧?無論如何,《M8圍棋譜》進入魅族軟體中心,還是值得慶祝的。順便也祝願魅族軟體中心發展的越來越好。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.