2011年11月7日 星期一

使用 VC++ 2010 Express 編譯 Chromium Embedded Framework (CEF) @ Windows 7 64-Bit

前一陣子接觸了 Webkit 和 Chromium 後,開始萌生一些小點子,雖然這些點子還滿粗淺的,但還是試看看吧。第一步則是要使用 Chromium Embedded Framework (CEF),並且嘗試編譯一下。


至於什麼是 CEF 呢?簡單說就是一個 library,讓你很容易在視窗程式中使用瀏覽器元件,若是以 mobile app 環境上,大概是 UIWebView @ iOS 和 WebView @ Android 吧。由於打算以免費的編譯環境,因此採用 VC Express 版本,設定上需要小小動一下。


編譯環境:


VC++ 2010 Express
VC++ 2010 Express SP1 
Windows Driver Kit Version 7.1.0


程式碼:


cef_binary_r306_windows.zip (42.0 MB)


設定:



  1. 開啟 cefclient2010.sln 檔

  2. [工具]->[設定]->[專家設定] && [檢視]->[屬性管理]-> 隨便一個 Project -> Debug | Win32 -> Microsoft.Cpp.Win32.user -> VC++ 目錄

    • Include 目錄

      • C:\WinDDK\7600.16385.1\inc\atl71

      • C:\WinDDK\7600.16385.1\inc\mfc42



    • 程式庫目錄

      • C:\WinDDK\7600.16385.1\lib\ATL\i386

      • C:\WinDDK\7600.16385.1\lib\Mfc\i386





  3. 設定 atldef.h 

    • C:\WinDDK\7600.16385.1\inc\atl71\atldef.h

    • 註解 //#error Do not define _SECURE_ATL.



  4. 設定 cefclient 專案

    • 屬性 -> 連結器 -> 輸入 -> 其他相依性 -> 增加 atlthunk.lib 即可




如此一來,即可編譯成功。唯一的缺陷是有警告訊息:


2>atlsd.lib(stdafx.obj) : warning LNK4078: 發現多個 'ATL' 區段有不同的屬性 (40301040)
2>clientplugin.obj : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>plugin_test.obj : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(atltrace.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(externs.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(atldebugapi.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(atlbase.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(atlfuncs.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(stdafx.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(allocate.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)
2>atlsd.lib(atltracemodulemanager.obj) : warning LNK4254: 區段 'ATL' (50000040) 以不同的屬性合併到 '.rdata' (40000040)


雖然網路上有查到相關解法(屬性 -> 一般 -> ATL 用法 -> 選擇"動態連結 ATL"或"靜態連結 ATL"),但測試的情況並沒有完全清除訊息,因此就先不管他了。接著有空慢慢以這個 cefclient2010.sln 當作基底,修改成想要的東西好了 :D


cefclient_win.cpp


2011年11月4日 星期五

解決 PPS (PPStream) 之網路緩慢、常駐程式問題 @ Windows 7 64Bit

msconfig


打從學生時代,雖然聽過 PPS 上頭有多豐富的影集、電影,但基於版權合法,我都不曾使用 XD 並且因為學校的大水管,使得計中常常接到某某公司寄來的警告信,不外乎又是哪個學生用 P2P 軟體 :P 談到 P2P 也讓我回想起台灣 FOX 也都熄燈了呢。只是,對那些住在外頭的人來說,PPS 依舊是大家的好朋友 XDD 之前幫忙修電腦,發現網路奇慢無比,連 GMail 都上不去,仔細確認後,就是 PPS 搞的鬼 XD 據說 PPSAP.exe 負責把下載過的影片上傳出去。


解決方法:開啟 Windows 工作管理員,把 PPSAP.exe 關掉後,果真一切恢復正常啦。


只是從開機後,又會出現,因此,正確的解法還必須使用 msconfig ,在啟動區把 PPS 加速器關掉,這樣開機就不會執行了。


2011年10月23日 星期日

想想十年後想要變成什麼樣的人吧!

客運


參加家族聚會,又一次含糊地回答別人我的工作在幹嘛,說真的連我的家人也不太懂 :P 我想,我的工作內容或能力,大概是練習成為一位具現化系吧 XD 我不會跟別人說我是專門搞後端或是前端的開發人員,我只會很輕描淡寫地說,我是在做整合性服務的研發人員。回顧這幾年的變化,學生時期從一位熱愛搞 SA 活動的,慢慢地走向自以為是嵌入式,接著又跳到網際網路應用服務,然後網路上的東西日新月異,不會就學,並不侷限在某個領域或技術,剛好很符合我的個性,我不會想要用一招通吃,另類的中庸之道吧?


最近隔壁同事要役畢了,也選擇要離開換個環境,我分享了一些福利好的公司,但他一口回絕,他只想要可以去練功的公司!漸漸地,我發現自己的想法開始比較不會受人影響,不曉得這是不是成老頑固的第一步?


每個人的生活、條件都不一樣,不需要時時跟著別人的腳步,更需好好地思考,十年後,到底想要變成什麼樣的人,當下得選擇將會越來越清晰了。


2011年10月7日 星期五

替 Webkit 送 Patch

Webkit Bugzilla
Webkit Bugzilla:https://bugs.webkit.org/


幾個月前收到一個任務,要替 Webkit 送幾個 patch,當下覺得很興奮,但是時間不夠用,拖了幾個月後,我才正是嘗試。目前我只做了一個簡單的部分,替某個 patch 建立正確的 test cases,這部分不需要寫程式的。現在就先把這些過程筆記一下,或許哪天也可以學 J大神用 commit log 來介紹自己了(誤)


首先,想要替 Webkit 貢獻者,必須先確認該功能還沒被實作或是有某些 bugs,例如 HTML5 眾多的 CSS3 功能等,另外則是在 Webkit Bugzilla 搜尋一下。關於某個未實作的功能,最好的驗證方式是去查看目前 webkit svn 裡頭的 LayoutTests 的東西,這邊 Webkit 可是分成非常多的 platform 的,光 chromium 就還可以分 win/linux/mac 等版本。


http://trac.webkit.org/browser/trunk/LayoutTests/platform/


接著就照 Webkit 官網的介紹,去取得程式碼、安裝開發環境,最後再把它編譯起來。如此一來,至少完成編譯的動作,接著才進入開發階段。


開發完成時,一樣編譯好,可以透過自製或是上述 LayoutTests 的測資


測資來源:http://trac.webkit.org/browser/trunk/LayoutTests 


測資結果(win):http://trac.webkit.org/browser/trunk/LayoutTests/platform/win


當功能一切完善後,就可以到 Webkit Bugzilla 貢獻程式,甚至自己發佈新問題或需求,接著自己再解掉。


在上傳 patch 之前,是必須通過 Webkit framework 的驗證,驗證方式可透過 WebKit/Tools/Scripts/run-webkit-tests 查看更改的程式是否能通過 test cases:


驗證 LayoutTests/folder1/folder2 裡的測資


$ ./Tools/Scripts/run-webkit-tests -v folder1/folder2


建立 pixel results ,有網頁可以查看兩者在瀏覽器顯示的樣貌


$ ./Tools/Scripts/run-webkit-tests -v -p folder1/folder2


如果原先的 test cases 本來就不對了,那這時候就是把你產出的測資拿去覆蓋掉原本即可。


當工作一切完善後,接著才正式進入送 patch 階段,在送出 patch 前,須產生 Changelog 筆記一下,接著驗證自己產生的東西是否符合 Webkit coding style:


$ cd Webkit
$ ./Tools/Scripts/prepare-ChangeLog --name "Your Name" --email "Your Email Address"
  Running status to find changed, added, or removed files.
  Reviewing diff to determine which lines changed.
  Extracting affected function names from source files.
  Change author: Your Name <Your Email Address>.
  Running 'svn update' to update ChangeLog files.
    At revision xxxxx.
    At revision xxxxx.
  Editing the Source/folder/ChangeLog file.
  Editing the LayoutTests/ChangeLog file.
-- Please remember to include a detailed description in your ChangeLog entry. --

-- See <http://webkit.org/coding/contributing.html> for more info --


編寫完 ChangeLog 後,再用 check-webkit-style 驗證(包括ChangeLog):


$ cd Webkit
$ ./Tools/Scripts/check-webkit-style
...
Total erros found: 0 in # files


一切都備妥後,就可以正式在 Webkit Bugzilla 上傳 patch 了,上傳時會有表單要填寫:


patch_bugzilla


首先是上傳的檔案不能超過 2MB,不然就要切開成多個 patch 或是給一個 url 讓它測;接著給上簡短一句話的描述;最後,則是 Flags 要設定,若要被人審核,那 review 那邊要標 ? ,而希望通過 review 後可以自動進入 trunk ,那就要用 ? 標記 commit-queue 囉。可以用滑鼠移到下拉式選單,將有提示字句可以再多多了解。


最後,就是等待審核者來處理及相互互動囉,順利的話,就可以完成貢獻啦。


2011年10月3日 星期一

[Python] 使用 Django 架構,提供強制下載檔案的 CGI 服務

周邊有人有需求,希望 CGI 能夠提供強制下載的功能,這我以前寫過 PHP,知道很容易透過用 header() 來送出資訊,請瀏覽器直接下載檔案,但改成 Django 我又不會了。翻了以前的筆記,順便看到以前的筆記:[Python] 使用 Django 提供檔案下載的 CGI 服務,溫習了一下。


至於此篇解法如下:


@ views.py

from django import http
from django.http import HttpResponse
from django.core.servers.basehttp import FileWrapper
import os
import mimetypes

def DemoFileDownload(request):
file_path = '/data/cat.jpg'
file_name = 'name_for_download.jpg'
response = HttpResponse(FileWrapper( file(file_path) ),mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=%s' % file_name 
response['Content-Type'] = mimetypes.guess_type(file_path)
response['Content-Length'] = os.path.getsize(file_path)
return response