31 1月 2008

Skype4Com in BCB

Skype4Com在BCB中實現有兩種方法
  1. 一種是廣為人知的透過Variant去控制Com的物件
  2. 另一種是使用BCB強大的功能,將Skype4Com.dll解析後,直接使用其中的class
以下將各給一個例子,去取得「好友清單」的列表,再把它列到Memo元件中。


法1 : 透過Variant去控制Com的物件
// Prepare Setp :
// 1. Add a Memo to the Form1
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Memo1->Clear();

//Create a Skype Com object
Variant oSkype;
oSkype = Variant::CreateObject("Skype4COM.Skype");
// test if Skype is running, if not, start it;
if( !oSkype.OlePropertyGet("Client").OlePropertyGet("IsRunning") )
oSkype.OlePropertyGet("Client").OleFunction("Start");

// Connect to Skype via API
oSkype.OleFunction("Attach");

// Get all firends
Variant friends = oSkype.OlePropertyGet("Friends");
int count = friends.OlePropertyGet( "Count" );
Memo1->Lines->Add( "User Count : "+IntToStr(count) );

// Add to Memo
for( int i=1 ; i<=count ; i++ )//start index from 1 !!!
Memo1->Lines->Add( friends.OlePropertyGet("Item", i).OlePropertyGet("Handle") );
}
//---------------------------------------------------------------------------



法2 :

  1. 下載Skype4Com Releas,解壓縮出Skype4Com.dll
  2. 打開BCB,點選Component -> Import ActiveX Control -> Add Skype4Com.dll -> Install
  3. 至元件列表中,點選「ActiveX」,看看有沒有出現「Skype」這個Icon,有的話,就是成功了
  4. 拉一個Skype元件下來,即可使用TSkype這個class了
  5. 切記:Skype4Com.dll的位置不能改變,否則BCB會出錯
// Prepare step :
// 1. Add a Skype to Form
// 2. Add a Memo to Form
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Skype = new TSkype(Owner);
Skype->Attach(5,false);

// test if Skype is running, if not, start it;
if( !Skype->Client->IsRunning )
Skype->Client->Start(false,false);
// 1st parameter - start Skype in minimized state
// 2nd parameter - show splash screen

// Get the count of Friends
int count = Skype->Friends->get_Count();
Memo1->Lines->Add( IntToStr(count) );

// Add Friend list to Memo
for( int i=1 ; i<count ; i++ )// start index from 1 !!!
Memo1->Lines->Add( Skype->Friends->get_Item(i)->get_Handle() );

}
//---------------------------------------------------------------------------
延伸閱讀:

Skype API 的另一種應用 - Skype4Com

  Skype4Com - 意思就是Skype for Com,是將Skype API包成一個Com的Object,讓任何支援Com/ActiveX元件的語言所使用(如:Visual Studio, Delphi, BCB, VB, PHP, ... ),但是只限於Windows平台上。

  之前的文章介紹過的Skype API,是透過Windows Message去存取Skype的行為。但是這樣子的處理下,有些行為變得比較不直觀,比如,我想得到所有的友人清單,在自己撰寫的一個Function中,下Command : 「Search Friends」,卻必須在另一個Function : WndProc()中才能得到Skype回應的Message,這樣子的寫法會讓程式變得很支離破碎。
  而使用Skype4Com就沒有這樣子的困擾了,當你Create出一個Skype的Com物件後,就可以直接存取它裡面的一些變數值。所以就程式的觀點而言,Skype4Com是比較優的!!!


以下的網址可參考:
  1. Skype官網上 Skype4Com的說明
  2. Skype4Com的元件說明
  3. Skype4Com的Example (包含VB, C++, C#, Delphi)
  4. Skype4Com 1.0.28.2 Release下載 (包含Skype4Com.dll, Skype4Com Windows說明檔)

延伸閱讀:

20 1月 2008

Netlimit IP Switcher 1.21 release 發佈

Netlimit IP Switcher
1.21 Release Note

-1. 自動更換IP程式
-2. 可設定流量上限
-3. 可選擇網卡更換IP
-4. 多國語言
-5. 下次執行時 可設定自動開始


Netlimit IP Switcher
1.21 Change Log

- Fixed : 修正無法正常切換IP的問題

下載連結

18 1月 2008

Netlimit IP Switcher 1.2 release 發佈

Netlimit IP Switcher
1.2 Release Note

-1. Automate Switcher your IP.
-2. Set the net limit.
-3. You can choice the interface adapter to change IP.
-4. Multi-Language.
-5. You can set it auto-run when you start it next time.

-------------------------------------
Netlimit IP Switcher
1.2 Change Log

- Add : 使用者可選擇處理哪一張網路介面卡.
- Add : 支援多國語言(中文、英文) ... testing...

下載連結

09 1月 2008

[Lex] flex如何結合c++的code

我在之前的文章介紹過Lex的基本用法了,flex是用來處理Token Analysis的好工具,原本的.l檔在flex compile過後,會變成lex.yy.c,再用gcc compile後,就可以成為執行檔了。所以一般在寫入.l檔時,都是使用c的library。不過有時候想使用c++的std library時,也是有方法可以達成的!以下介紹兩個方法供參考。

1. 偷吃步 簡易法
 在.l檔直接include c++ std library,用flex產生lex.yy.c後,再用g++去compile即可。

2. c++達人 完全物件法
 flex提供了一個Lex的c++版,.l檔的寫法完全class物件化,因此用了這種方法,並不能與之前的寫法相容喔。
 使用方法有兩種:
 a. 在.l檔裡,檔案開頭加上%option c++
 b. flex指令加上-+
 而flex compile過後的檔案是lex.yy.cc,而非lex.yy.c。而且會幫你自動include FlexLexer.h檔。檔案裡頭宣告了兩個class:FlexLexer和yyFlexLexer,FlexLexer是一個interface,是給yyFlexLexer繼承的,原本用到的lex c function,全部都被包進class yyFlexLexer裡,所以,在使用時,必須先宣告一個yyFlexLexer物件來使用,原本c的yyin不見了,所以要指定input、output的來源必須透過yyFlexLexer的constructor來指定(預設是stdin & stdout),下面會給個範例可以讀檔當input。

 將c++版的class yyFlexLexer裡面的function與原本的c版的lex做簡單的比較:
 const char * YYText()
   回傳目前match的token字串,與c版的yytext相同。
 int YYLeng()
   回傳目前match的token字串長度,與c版的yyleng相同。
 int lineno() const
   回傳目前parser到的是文件中的第幾行(若要使用,記得寫入%option yylineno)

以下有個簡單完整的例子,是用c++版的Flex寫的,可以parser出文件中的number, name, string:

%option noyywrap
%{
using std::cout;
int mylineno = 0;
%}

string \"[^\n"]+\"
ws [ \t]+
alpha [A-Za-z]
dig [0-9]
name ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])*
num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)?
num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)?
number {num1}|{num2}

%%


{ws} ;/* skip blanks and tabs */
{number} cout << "number " << YYText() << '\n';
\n mylineno++;
{name} cout << "name " << YYText() << '\n';
{string} cout << "string " << YYText() << '\n';


%%
#include <fstream>
int main( int argc, char **argv )
{
std::ifstream input;
FlexLexer* lexer;

++argv, --argc;
//--- File input ---//
if ( argc > 0 ){
input.open(argv[0]);
lexer = new yyFlexLexer( &input, &std::cout );
}
//--- Stdin ---//
else{
lexer = new yyFlexLexer;
}

while( lexer->yylex() != 0 );
return 0;
}

compile的指令:
flex -+ xxx.l
g++ lex.yy.cc -o myoutput

參考文章:FreeBSD flex

03 1月 2008

[Linux] 搜尋資料夾底下 檔案內部文字

find "path name" -name "file name" -exec grep -H "search content" {} \;

find原本是用「檔案名稱」來搜尋在哪些地方有這些檔案,將這些路徑結果餵給grep後,就可以拿來搜尋檔案內部的文字片段。

Ex:
find ./kernel -name "*.c" -exec grep -H "main" {} \;
以上這段指令,是要搜尋./kernel底下所有的.c檔,內容含有"main"的地方。

find的參數:
  -name 要搜尋哪些檔名
  -exec utility name [argument...{} \;
    搜尋出的檔名 交給哪個執行檔(utility name)處理
    {} 會被find搜尋後的檔名路徑名稱所取代
    \; 代表exec的參數到此為止

grep的參數:
  -H 列出搜尋到的檔案名稱路徑