2010/09/14

Publish Your WxWidget Program


Publish Your wxWidget Program

初入wxWidget時,是使用wxDev-C++當作開發編譯環境,後來不經意的使用了VS2005的環境,便開始愛上cl.exe那麼飛快編譯速度、Visual Studio良好Debug環境。

但最近在發行wxWidget程式(Release Version)時,在其他未安裝Visual Studio的電腦上無法執行的問題,將錯誤訊息google過後發現是編譯參數/MD的關係,將/MD改成/MT便行(在project屬性頁的組態屬性-->C/C++-->程式碼產生裡)。

改完重編後,又發生
------ 已啟動全部重新生成: 項目: WxWidgetsWizardTest, 配置: Debug Win32 ------
正在刪除項目「WxWidgetsWizardTest」(配置「Debug|Win32」)的中間文件和輸出文件
正在編譯...
WxWidgetsWizardTestFrm.cpp
正在編譯...
WxWidgetsWizardTestApp.cpp
正在編譯資源清單...
正在鏈接...
MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: _free 已經在 LIBCMT.lib(free.obj) 中定義
MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) 已經在 LIBCMT.lib(typinfo.obj) 中定義
MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) 已經在 LIBCMT.lib(typinfo.obj) 中定義
LINK : warning LNK4098: 默認庫「LIBCMT」與其他庫的使用衝突;請使用 /NODEFAULTLIB:library
LINK : warning LNK4098: 默認庫「MSVCRTD」與其他庫的使用衝突;請使用 /NODEFAULTLIB:library
LINK : warning LNK4098: 默認庫「LIBCMTD」與其他庫的使用衝突;請使用 /NODEFAULTLIB:library
D:\WxWidgetsWizardTest\Debug\WxWidgetsWizardTest.exe : fatal error LNK1169: 找到一個或多個多重定義的符號
生成日誌保存在「file://d:\WxWidgetsWizardTest\WxWidgetsWizardTest\Debug\BuildLog.htm」
WxWidgetsWizardTest - 4 個錯誤,3 個警告
========== 全部重新生成: 0 已成功, 1 已失敗, 0 已跳過 ==========
所以我又去google這個錯誤,發現是library部分也要以維持一致性,順手將C:\wxWidgets-2.9.0\build\msw\wx_vc8.sln打開後,並將所有的/MD改成/MT,重編後便OK了。

若還是有遇到問題,不彷注意一下自己連結的library裡,是否有用到debug的版本,library及程式編譯參數最好一模一樣,這樣碰到的問題會較少。

2010/08/26

wxWidget 初學

wxWidget 初學

(廣告: 最近有人有case要外包嗎? 最近非常缺, 有要外包的, 請email給我)

最近有人問起:「我想學C++ UI programming,我該學那套好?」可以用C++來寫UI的frameworks很多,如果是我推薦,我一定會選擇我最熟悉的[wxWidget]。

師父引入門,修行靠自己。對於初學者最好從一個好用的IDE開始,wxWidget唯一(誤)可用的IDE是[wxDev-C++],要使用它來開發,基本上就是抓下來安裝好就可以開始玩了。其他的IDE可以參考[wxWiki]的[Tools]頁面,裡頭有介紹不少工具可用。

在玩IDE的途中,一定會需要參考到那些物件及函式可用,這部分可到[Reference Manual]一探一二。若需要有一整套完整的介紹可參考這本書[Cross-Platform GUI Programming with WxWidget],網路上可找到電子版的。

再進階一點,自己重編整個wxWidget library是少不了的,你可以在[Download]頁面,找到適合你的版本。以Windows + Visual Studio 2005重編也很容易,先將[wxAll]抓下來,解壓縮,用VS2005開,再按建置就完成了。

需要範例可在source code的sample資料匣下找到。





2010/08/25

Build Your Own Fedora and Ubuntu

Build Your Own Fedora and Ubuntu

最近因為公司稍閒, 便開始為了未來準備及興趣,逐漸將目前的工作平台移著Linux上。適逄剛好有人問我如何製作自己的Fedora,所以記載一下工作實錄。

Compile Fedora 13 and Ubuntu 10.04 kernel


Build Your Own Fedora and Ubuntu

Fedora可用[Revisor]這個工具來製作,大制上圖型介面一步步往下走就可製作出光碟在/svr底下。唯獨2個小地方要修正,否則會出現」anaconda error code 1」的錯誤訊息:
  • Copy /usr/lib/revisor/scripts/F12-buildinstall to /usr/lib/revisor/scripts/F13-buildinstall
  • Comment out two sections of 「anaconda-updates」 and 「anaconda-updats-source」 in /etc/revisor/conf.d/revisor-f13-i386.conf

Ubuntu可用[Reconstructor],連結內圖文並茂。

2010/05/09

舒跑杯路跑

5/2 去參加了舒跑杯的路跑,這是3年慢跑生涯的milestone吧。

這次因為太晚報名,只能報到3KM的休閒組,但我跟我女友還是偷偷跑去參加了9KM組。當天早上我們不到5點就起床了,5:40到市政府,先做暖身,準時6點開始跑。

9KM的路程大約是由台北市政府延著仁愛路,大概在台大醫學院那折返再跑回來。我平常不管在跑步機或是運動場從來沒有跑超過7KM,沒想到這次9KM的路程跑起來還算輕鬆,跑出來的成績也算不算,9KM花58分鐘。這可能的原因很多,我猜最大的原因是風景一直變不會太無聊,跑起來也就特別有力。

這次跑完的感覺十分良好,我想下次有機會還會繼續參加其他路跑 :)

附上照片一張 [20100502_舒跑杯路跑]


打造自己的VIM: 源碼追蹤 call tree (CCTree)

CCTree 是一個對於VIM使用者很方便的追蹤源碼工具。它主要提供2種功能,一是根據輸入的Symbol (函式名)產生所有呼叫到此symbol的函式名列表;或是根據輸入產生此symbol所有呼叫到的函式樹狀圖。

安裝此plugin的方式十分簡單,只需將CCTree.vim移至vim/plugin/底下便行。

在使用CCTree之前,請先產生cscope.out,若有不清楚的朋友們,可參考小弟之前的文章[源碼追蹤 ctags+cscope及預覽視窗SrcExpl]。在產生完後首先需下CCTreeLoadDB讀取cscope.out,這需要一些時間,接著就能開始使用CCTree了。CCTree使用上只有4個快速鍵,如下



舉例來說,我在LoadBmpImage下按下<C-\><,在VIM的左邊的window,便會顯示有2個函式呼叫它,如下圖:


若是在LoadBmpImage下按下<C-\>>在VIM的左邊的window,便會顯示有LoadBmpImage呼叫了多少函式,如下圖:


2010/04/14

透過SendMessage控制功能表項

前幾天有朋友問我怎麼在Windows中控制Windows Media Player的播放、停止等功能,可以做到此目的的方法有很多種,其中用Spy++及SendMessage可以輕易達成。我這裡稍微簡述一下方法,詳細流程可以參考[Interoperating with Windows Media Player using P/Invoke and C# - CodeProject]。

目的


為了方便說明,我改以控制PCMan中我的最愛其中之一的連結來說明。如下圖被框起來的功能表項。




手段


使用SendMessage摸擬功能表項被按下的動作。其中SendMessage的參數如下:


第一個參數可以透過FindWindow來找到,第二個參數因為是按功能表項所以必定是WM_COMMAND,第三及第四個參數較難取得,但我們可以透過Vistual Studio內附的Spy++來監視PCMan的WM_COMMAND訊息來取得。

首先打開Spy++並按下Ctrl-M,並用下圖紅框1的東東拖到PCMan選到正確視窗,如下圖紅框2。



接著按到訊息的Tab,選WM_COMMAND如下圖。




最後在PCMan內去按下[我的最愛]->[台大批踢踢實業坊],此時在Spy++內便會出現下圖訊息,按下右鍵選[屬性]後便能取得wParam及lParam。



在SendMessage四個參數都備齊後,我寫了一支程式去做SendMessage。底下是程式結果,其中程式的4個參數分別為Program ClassName、Event、wParam和lParam。



執行後ptt便會在PCMan中被打開了。MessageControl的源碼如下:

 1 // MessageControl.cpp : 定義主控台應用程式的進入點。
 2 //
 3
 4 #include "stdafx.h"
 5 #include <stdlib.h>
 6 #include <Windows.h>
 7
 8 struct EventMappingTable_t {
 9     LPCWSTR Name;
10     UINT Code;
11 } g_eventMapping[] = {
12     {_T("WM_COMMNOTIFY"), 0x0044}
13 };
14
15 int _tmain(int argc, _TCHAR* argv[])
16 {
17     if (argc != 5) {
18         fprintf(stderr"Usage: %S ClassName Event WPARAM LPARAM\n", argv[0]);
19         return -1;
20     }
21
22     HWND hWnd = FindWindow(argv[1], NULL);
23     if (hWnd == NULL) {
24         fprintf(stderr"Cannot find window: %S\n", argv[1]);
25         return -2;
26     }
27
28     WPARAM wParam;
29     LPARAM lParam;
30     UINT eventID = 0;
31     UINT i;
32     for (i = 0; i < sizeof(g_eventMapping)/sizeof(EventMappingTable_t); ++i) {
33         if (_wcsicmp(g_eventMapping[i].Name, argv[2]) == 0) {
34             eventID = g_eventMapping[i].Code;
35             break;
36         }
37     }
38     if (i >= sizeof(g_eventMapping)/sizeof(EventMappingTable_t)) {
39         fprintf(stderr"Cannot Event: %S\n", argv[2]);
40         return -3;
41     }
42
43     wParam = wcstol(argv[3], NULL16);
44     lParam = wcstol(argv[4], NULL16);
45     SendMessage(hWnd, eventID, wParam, lParam);
46     return 0;
47 }
48