2009年12月9日 星期三

(VB入門篇)VB2008 四、語法簡介下(函數\Sub\Class關鍵字\Event Handle)

函數


假設有一多項式f(x)=x^2+3x+2,設定x=1,則f(1)=6, f(2)=12。程式中函數的跟其作用類似,給定值,並回傳處理過的資料,例如VB內建好的Math.Sqrt(81)會傳回9 [開根號的函數]。

使用範例如下:
Dim A As Integer=9

Dim B As Integer=Math.Sqrt(A)+2

則最後B等於5

不過,函數不一定只能給一個值,例如Math.Pow(2,3)是2的3次方,

而且也不一定要給值,例如Rnd()傳回隨機亂數,且0≦Rnd()<1。

在後面敘述中我們給函數的值稱之為引數或者參數

除了內建的函數之外,我們當然也要自己寫自己的函數囉

寫法是這樣的:
Function 函數名稱(ByVal 引數1 As 引數1型態, ByVal 引數2 As 引數2型態, ....) As 傳回值的型態

(程式碼)

Return 要傳回的值

End Function

舉個例子:
Function MyFunc(ByVal VX As Integer)

Dim V2 As Integer =VX*VX

Return V2+3*VX+2

End Function

以上程式碼讓MyFunc(1)傳回6的數字MyFunc(2)傳回12

Sub


Sub的意義跟函數很像,但是它是沒有產生值的函數,只是執行特定區塊的程式碼。

而寫法是這樣的:
Sub SUB的名稱(ByVal 引數1 As 引數1型態, ByVal 引數2 As 引數2型態, .........)

(程式碼)

End Sub

主要的意義是用來簡化重複的程式碼、或者當「觸發事件」的反應程式碼。

舉例:
Sub ShowName(ByVal Name As String, ByVal SayHi As Boolean)

If SayHi Then

MsgBox("Hello, " + Name)

Else

MsgBox(Name)

End If

End Sub

單行程式碼:ShowName("Aethur",True)會顯示一對話方塊"Hello, Aethur"

函數與Sub的擺放位置


在VB中並不支援在函數裡擺函數或Sub,同樣的Sub裡面也不能包函數以及Sub

所以像是
Sub A1(ByVal V As Integer)

Sub B2(ByVal Q As Integer)

Q=Q*6

End Sub

V=V*2

End Sub

是錯的!函數擺錯地方是初學常見的錯請小心=3=

正確擺放方式是
Sub A1(ByVal V As Integer)

V=V*2

End Sub

Sub B2(ByVal Q As Integer)

Q=Q*6

End Sub

ByVal跟ByRef


以上函數之類的舉例用的都是ByVal,但是VB裡面還有個ByRef可以當作引數的開頭,它跟ByVal有什麼差別呢?先看看下面的程式碼:
Sub A1(ByVal V As Integer)

V=V*2

MsgBox("Wow" & V)

End Sub

Sub A2(ByRef V As Integer)

V=V*2

MsgBox("Wow" & V)

End Sub

假設我們執行:

V=3

A1(V)

MsgBox("Out" & V)

結果會是Wow6跟Out3




而假設我們執行:

V=3

A2(V)

MsgBox("Out" & V)

結果會是Wow6跟Out6
簡單來講,如果用ByVal,則函數裡對該引數的賦值在函數/Sub之外無效。

而如果用ByRef,則函數理對該引數的賦值在函數/Sub之外有效。

Class跟Public與Private


很明顯的,在VB中設計程式時常常冒出一些Public Class、Public Sub之類另人不明白的東西,

Class,類別,表示一種「東西」,這是物件導向的部分往後才討論。而Public和Private之類的在未動到Class之前幾乎是沒有差別的,這裡也不予討論,只是先講這不是奇怪的字詞而已。

Event Handle


Event Handle,觸發事件的偵聽,通常都是由程式自動產生的Private Sub XXX,然後自己填程式碼。Event Handle的功能在於事件發生後,系統會呼叫之。如:表單關閉、滑鼠移動都是事件,而自動產生Private Sub的方式是屬性視窗中的閃電,或者點兩下控制項。

2009年12月8日 星期二

(VB入門篇)VB2008 四、語法簡介中(條件和迴圈)

If


If如果把它翻做如果,則一切都很容易明白=D
If A = B Then

MsgBox("OK")

End If

以上程式碼表示如果A等於B則執行MsgBox("OK")

從進階的角度來講,IfThen 之間會有一串運算式,如果這運算式的結果不是0也不是False,就會執行ThenEnd If之間的程式碼。

結論:
If 運算式 Then

(程式碼)

End If

Else


簡單來說,當If的運算式為False或0的時候會執行ElseEnd If之間的程式碼。
If A = B Then

MsgBox("OK")

Else

MsgBox("Not OK")

End If

以上程式碼表示如果A等於B則執行MsgBox("OK"),如果A不等於B,則執行MsgBox("Not OK")

結論:
If 運算式 Then

(程式碼)

Else

(程式碼)

End If

Else If


If的運算式為False或0的時候會判斷Else IfThen之間的運算式,如果該運算式是True或者1,則執行Else If ... Then End之間的程式碼。
If A = B Then

MsgBox("OK")

Else If A>B Then

MsgBox("BIGGER THAN")

End If

以上程式碼表示如果A等於B則執行MsgBox("OK"),如果A不等於B,可是A>B,則執行MsgBox("BIGGER THAN")

If A = B Then

MsgBox("OK")

Else If A>B Then

MsgBox("BIGGER THAN")

Else

MsgBox("SMALLER THAN")

End If

以上程式碼表示如果A等於B則執行MsgBox("OK"),如果A不等於B,可是A>B,則執行MsgBox("BIGGER THAN"),再不然,就會執行MsgBox("SMALLER THAN")

結論:


If 運算式 Then

(程式碼)

Else If 運算式 Then

(程式碼)

End If



For


關於迴圈,直接從語法上來好了。

範例程式碼:
Dim i As Integer = 0

For i = 0 To 3

MsgBox("OK" & i)

Next

嗯,如果要簡單說的話就是讓i從0加到3,期間執行ToNext之間的程式碼(範例內是MsgBox)

以上這段程式碼是這樣執行的:
i=0

MsgBox("OK" & i)

i=i+1

MsgBox("OK" & i)

i=i+1

MsgBox("OK" & i)

i=i+1

MsgBox("OK" & i)

因為i=3, 結束迴圈

最後i=3,符合最後條件所以結束迴圈。

關於i=i+1這段,+1是由省略變形而來的
Dim i As Integer = 0

For i = 0 To 3 Step 1

MsgBox("OK" & i)

Next

這段跟前述程式碼是等價的,產生的結果一樣。

但是:
Dim i As Integer = 0

For i = 0 To 3 Step 2

MsgBox("OK" & i)

Next

的結果不同,流程是
i=0

MsgBox("OK" & i)

i=i+2

MsgBox("OK" & i)

因為i>3,結束迴圈

結論:
For 變數名稱 = 初始值 To 結束值

(程式碼)

Next

或者:
For 變數名稱 = 初始值 To 結束值 Step 遞增值

(程式碼)

Next

變形:
For 變數名稱 As Integer = 初始值 To 結束值

(程式碼)

Next

變形可以省去前面變數名稱的宣告,直接在FOR裡宣告

While


While超易懂,結論:
While 運算式

(程式碼)

End While

當運算式結果是True或者是1,程式碼會不斷執行,直到運算式=0或者False

另一種表達方式是:
Do

(程式碼)

While 運算式

(VB入門篇)VB2008 四、語法簡介上(宣告,資料型態,賦值)

首先我要你背幾個單字,或者看過有印象比較好。
Integer 整數 / String 字串 / Array 陣列 / Dim 宣告 / If 如果 / Else 其他 / For 向 / Sub 子程式 / Function 函數 (這裡的中文並非單字的唯一解釋,而是這些單字在程式碼裡的通常意義)

程式,一套自動執行的指令。你要他幹嘛,他就跟著你做。表達的好,你想要的程式就可以順著你的意去執行!

流程對,邏輯對,語法對,才能產生你自己的程式。以下為語法簡介。

一、宣告式(基本)


宣告的目的是為了幫欲儲存的資料安排記憶體空間。

VB裡宣告式很簡單:

Dim 變數名稱 As 資料型態

變形式(以後說明): Dim 變數名稱 As New 資料型態

範例:Dim Num As Integer

非變形式的宣告後面可加預設值,如:

[code lang="vb"]Dim Num As Integer = 123[/code]

二、資料型態(基本)


一般程式語言都有整數、小數、字元、字串等資料型態,VB也不例外,資料型態是什麼?就是資料的類型咩=3=

1.Integer(長整數)表示大整數,範圍大約在正負21億,是最常應用的資料型態之一,你知道的,數位生活離不開數字。

2.Short(短整數)表示小整數,範圍大約在正負32700,適用小範圍的數字,例如便利商店商品價錢(最好是有五位數價錢的商品=口=)。

3.Single(單精度浮點數)用來儲存大約7位的小數+整數位(如:123.4567),例如成績平均用Single大概就夠了(在別的程式語言中,Single被叫做Float)。

4.Double(雙精度浮點數)用來儲存大約14~15位的小數+整數位(如:0.1234567891234),比較精密的數字就要用DOUBLE去算了。

※Float跟Double能儲存的範圍有爭議,這裡取大概

5.Char(字元)用來表示一個"字",如'A', 'B', 'C', 'D'都是一個字元,而'你', '我', '他'也都是一個字元,標點符號如","也是一個字元。

6.String(字串)則是表示按照順序排列的字元,是連續的字元,如同字元串起來般,所以叫做字串,通常拿來存放句子。

※字串是在句子前後加雙引號「"」,字元是在字的前後加單引號「'」來表示,如Dim Str As String="Happy Birthday"

7.Boolean(布林值)只能存放兩種數值,0跟1,0表示false,1表示true,true表示"真",false表示"假",看後篇你就知道意思了。

其他資料型態會在後篇提到。

三、賦值


賦值非常的簡單,

如 A=1+2 就是把1+2的結果存到A。

因此賦值的表示方式是

變數名稱=運算式

四、運算式


運算式跟賦值一樣好懂,1+2是運算式,3*5是運算式,5*6/3也是運算式,分別產生3,15,10的運算結果。

不同於數學的是,如<, >, =, <=, >=等符號也可以當作運算符號,不過產生的不是數字,而是布林值

例如5>3,是真的,所以產生的結果是1(True)。而5<3並不成立,所以產生的結果是0(False)。

5=5,是真的,產生的結果是1,而7=49/7也是真的,結果也是1,但是7=6是明顯矛盾的,所以結果是0。

第三、四點的總結範例:
A=1+2

B=3+7

C=A*B

則A,B,C最後各是3,10,30

(VB入門篇)VB2008 一、下載&安裝

VB2008 Express下載與安裝說明:

步驟:

1.進入http://www.microsoft.com/express/vb/Default.aspx

2.選取Traditional Chinese 並按Download



3.下載結束後開啟並執行

※Express Edition 常見問題:

Q.是否比一般版少了很多功能?

Ans.輔助功能應該是少了一些,不過程式碼方面沒有任何限制,一般版寫得出來,Express也寫得出來。

Q.Visual Studio?

Ans.Visual Studio可以整合多種程式語言的專案, 包含VC++, C#, VB. 通常要錢!

Q.SQL 200x Express?

Ans.如果你需要進行網路伺服器相關的專案才需安裝,不然的話MS SQL閒置擺著確實有點浪費記憶體空間。至於那是做什麼的,那個是資料庫系統之一。

2009年7月20日 星期一

Yahoo即時通的通訊協定 YMSG Protocol

YAHOO即時通的通訊協定叫做YMSG,會用Wireshark的人可以找找看。
...寫YAHOO機器人的時候,很想抱怨,
怎麼都沒半篇"中文"的文章介紹YMSG呢?
我這裡簡單介紹一下好了(雖然說我很不會介紹東西)。
<正文開始>
I.幾乎即時通每個封包(不管是送出去還是丟進來)都有以下格式:
※備註:以下標示的陣列全都是byte陣列
YMSG封包的內容依序是:
  1. 開頭都是YMSG, 以陣列表示是 {'Y','M','S','G'},
    轉成十六進制就是 0x59 0x4D 0x53 0x47 [共佔4個位元組]
  2. 接下來是版本號{0,16} [共佔2個位元組]
  3. 然後是兩個0 {0,0} [共佔2個位元組]
  4. 接著是以Short表示的"Yahoo Data"(後面會提)的長度 [共佔2個位元組]
  5. 以Short表示的Service常數 [共佔2個位元組]
  6. 以Int 32表示的Status常數 [共佔4個位元組]
  7. 以Int 32表示的SessionID [共佔4個位元組]
  8. 最後就是"Yahoo Data" [不定]
II.YahooData的組成
 Yahoo Data基本上是用字串表示的,而資料則是用Key跟Value的方法表示,並用{0xc0 , 0x80}兩個連續位元分隔。
 舉個例比較明白(以".."暫時表示0xc0跟0x80),例如傳送聊天訊息的封包裡面的DATA就像這樣:"0..twlupus..1..twlupus..5..nickwinwin..14..Hello world.."。這個DATA可以看成是:
  • [0]twlupus
  • [1]twlupus
  • [5]nickwinwin
  • [14]Hello world
 組合而成的。
 然而有時候key會重複,這點需要注意=ˇ=,結尾時也要放0xC0,0x80喔
III.登入與驗證
 YMSG能拿來幹嘛?當然是拿來模擬即時通啦!要模擬即時通,當然要先學會登入。
 登入的動作分為:
  1. Client->Server
    [封包內容]YMSG參數:Service=SERVICE_AUTH , Status=99 , SessionID=0
    Yahoo Data(請參考第二部份轉換):[1]你的帳號
    你或許會有疑問,封包要傳到哪去?我個人是連線到76.13.15.41:5050
  2. Server->Client
  3. 這裡"讀到"的SessionID要在後面用到,請記得取出。
    [封包內容]Yahoo Data:[94]神秘驗證碼
  4. 下載1網頁"https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=&login=" + 你的帳號 + "&passwd=" + 你的密碼 + "&chal=" + 神秘驗證碼

  5. 第3步取得的網頁內容,如果密碼正確的話,網頁內容會像是"0\r\nymsgr=XXXXXXXXXXXXX",取出ymsgr

  6. 下載第2個網頁"https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=&token=" + ymsgr

  7. 同第3步,但這次不是從內容中取出ymsgr而是crumb

  8. 對「crumb+""+神秘驗證碼」進行MD5加密取得byte陣列

  9. 然後用Base64加密byte陣列,並用分別用".", "_", "-"取代"+", "/", "=",加密後的字串我稱之為AUTHCODE

  10. 第5步的網頁中還有兩個資料,分別是Y跟T,也請取出

  11. Client->Server
    [封包內容]YMSG參數:Service=SERVICE_AUTHRESP , Status=99 , SessionID
    Yahoo Data:[0]你的帳號[1]你的帳號[277]Y的資料[278]T的資料 [307]AUTHCODE的資料[244]2097087[2]你的帳號

  12. 如果以上無誤,應該已經正確登入了

  13. (顯示上線)這裡應該在登入後暫停個一秒左右才進行動作。

  14. Client->Server
    [封包內容]YMSG參數:Service=198 , Status=0 , SessionID
    Yahoo Data:[10]99[19]狀態訊息[97]1
  15. 恭喜你,如果你看懂的話你現在應該是登入的了

IV.發送訊息和接收訊息

     
  1. 發送部分:
    Client->Server
    [封包內容]YMSG參數:Service=SERVICE_MESSAGE , Status=0 , SessionID
    Yahoo Data:[0]你的帳號[1]你的帳號[5]對方帳號[14]訊息

  2.  
  3. 接收部分:
    Server->Client
    [封包內容]YMSG參數:Service=SERVICE_MESSAGE , Status=0 , SessionID
    Yahoo Data:[4]對方帳號[14]訊息


V.附錄

    C#在登錄與驗證那邊,實作7、8步的方法:
    //要記得using System.Security.Cryptography;
    private string GetAuthCode(string Crumb, string Challenge) {//Challenge就是神祕驗證碼
    string Crypt = string.Join(string.Empty, new string[] { Crumb, Challenge });
    byte[] Hash = HashAlgorithm.Create("MD5").ComputeHash(Encoding.Default.GetBytes(Crypt));
    string Auth =
    Convert.ToBase64String(Hash).Replace("+", ".").Replace("/", "_").Replace("=", "-");
    return Auth;
    }
    好啦,剩下是商業機密XDD,可以自己爬英文文章或者爬點PIDGIN的原始檔也不錯。

2009年7月6日 星期一

C# 腳本直譯器

腦袋沒動會生鏽,
以前就曾想自己寫一個腳本執行器看看,昨天就用C#寫了個非常陽春的版本。

程式碼在gitHub

範例程式下載

陽春是沒辦法的ˊˇˋ 畢竟只用了數小時=口=++
一般來講C#可以直接用內建的CodeDom庫去編譯腳本(如果沒特殊需要真的就用CodeDom就好),但這裡我用的是自己寫的直譯器。


這個直譯器可以用的邏輯式有:
for(i=0;i<5;i=i+1){
}
while(i<5){
}
if(i>=6){
}
之類的(sorry沒有else),全部都要按照格式一步一步來(沒時間寫偽編譯啊)
變數不用宣告,宣告陣列只需要 "陣列名稱=[];"
嗯,差不多就是這樣了

如果糟糕的程式碼很榮幸的被用到您的程式上,希望但不強制您放上本站的網址xDD

2009年6月20日 星期六

Pidgin (即時通 - Yahoo Messenger -YM ) 不能登入問題

資料來源:http://stuff.techwhack.com/6804-yahoo-messenger-pidgin

解決方法:
用記事本開啟:"C:\WINDOWS\system32\drivers\etc\hosts"
最下面添加一行:
66.163.181.170 scs.msg.yahoo.com

重開Pidgin, OK :)

2009年5月15日 星期五

VB.net 表單淡入淡出+縮放特效

測試用。

很懶所以打很少,請各位客倌研究一下吧XD
VB程式碼
方法:
1.匯入模組(把程式碼貼到新模組.vb)
2.叫出新FORM的時候:
Dim F As New Form()
Dim FADE As New FadeControl(F)
FADE.ShowForm()

成員方法:
Public Sub ShowForm() '淡入視窗
Public Sub HideForm() '淡出視窗
事件
Public Event Hided(ByVal sender As Object) '完全隱藏時
Public Event Shown(ByVal sender As Object) '完全顯示時

2009年3月2日 星期一

C#多人聊天室

網友問了這個程式,然後網路又沒好範例,他看的書又很囧...
當作練習C#重寫了個,還可以運行耶囧~
把程式碼貼上來:
類別檔,隨便開一個類別cs放進去
介面檔案(兩個,請記得拉卷軸)

要更改的部分:
namespace名稱記得改成你的專案名稱~

ChatClient部分,
Sock.Connect("59.127.188.199", 8250);
要改成連線的IP和Port

ChatServer的Port也可以改

2009年2月28日 星期六

ChatFun MSN機器人(即時通機器人) v0.1 [開放原始碼]

CHATFUN用的MSN通訊協定已經過時了,
 建議用新版的AMSNBOT



臨時想用C#或VB.net開發MSN機器人,
上網找到MSNPSharp這個程式庫,是DotMSN的新版本。
修改一般手動聊天的範例後變成了機器人。
我現在都用foxbot@livemail.tw測試最新版,不怕他上上下下的就加吧XD
基本上這隻玩意兒根本沒有任何智慧可言,純粹是死板化的輸入和輸出而已喔~。
這機器人是用VB.net做的,不過改C#也可以~請善用轉換器。
[目前功能]
1.計算式子---可以求值,如:2*2
2.可以改變字體顏色
3.簡繁轉換
4.個人資料設定
5.判斷星座(沒用的感覺XD)
6.RSS訂閱
7.使用者教話功能
教話A+B
使用者輸入A,電腦會回答B
藍藍路~A+B,把B這個訊息洗掉
8.自動新增好友(含YAHOO)
[下載連結]
VB2008程式原始碼
Chatfun執行檔
[截圖]
MSN機器人

2009年1月29日 星期四

Openfast Alpha 熱鍵快速啟動華麗版

雖然比起PCMAN大的版本還嫌不穩定,但是已經可以到實用的程度了,

跟四年前的KeyOpen版本比起來,現在電腦速度快多了,自然可以用更炫的特效啦。

要用這個記憶體我建議至少要512MB- -,最近換記憶體到3.25GB所以這種小程式就隨我玩了。

如果是熱鍵快速啟動的使用者,想問這個玩意兒跟KeyOpen差在哪裡:

1.Skin可以自訂(支援半透明ARGB的PNG)

2.淡入淡出特效

3.懶人用的自動完成

4.穩定度不明=A=|||

5.你記憶體要夠撐..

[測試環境]

CPU:Intel x86 P4 3.2Ghz

System:Windows XP SP3 + .Net framework3.5

記憶體:3.25GB

顯示卡:256MB

>>結果:順的很

[下載連結]
Hinet 載點
RS載點

[截圖]

2009年1月28日 星期三

VB.Net C# 不顯示在Alt+Tab

網路上的版本似乎都不太令人滿意的說=w=


VB.net版本,前兩句要放在類別或模組的地方,最後一句要放在Form_Load或Form_Shown事件裡
Public Declare Auto Function SetWindowLong Lib "User32.Dll" (ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
Public Declare Auto Function GetWindowLong Lib "User32.Dll" (ByVal hWnd As System.IntPtr, ByVal nIndex As Integer) As Integer

SetWindowLong(Me.Handle, -20, GetWindowLong(Me.Handle, -20) Or &H80 And Not &H40000)


C#版本,同上:

[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

SetWindowLong(this.Handle, -20, GetWindowLong(this.Handle, -20) | 0x80 & !0x40000);

小小關鍵字?(C# VB.net VB 2005 VB2008 不顯示在Alt+Tab清單|Alt+Tab不顯示)

2009年1月18日 星期日

VB.net檔案傳輸|C#檔案傳輸

久違的程式POST( C#傳檔 / VB.net VB2005 VB2008傳檔 ),

心血來潮寫完=A=,
網路上也沒夠強大的程式碼,
Socket本身的BeginSendfile則沒有進度說明,
因此下面這個,
有進度Event(ProgressChanged),也有完成Event(ProgressFinished)

函式都註解的很清楚,所以我就不多打了~

VB.net程式碼(已測試)

C#程式碼(未測試)


使用範例:

(對指定IP進行檔案傳送,當然對方也要開著本程式才行)

(Form1上有一條進度列、一個文字框、一個按鈕)

Public Class Form1
Public F As New FileServer(Me)
Private Dia As New OpenFileDialog()
Private Sub Prog1(ByVal sender As TransferTask, ByVal P As Integer)
ProgressBar1.Value = P
End Sub
Public Sub Fin(ByVal sender As TransferTask, ByVal [Error] As Boolean)
Button1.Enabled = True
MsgBox("檔案傳送成功 " & Not [Error])
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Not Dia.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
Button1.Enabled = False
BeginTransFile(Dia.FileName, "C:\" & My.Computer.FileSystem.GetFileInfo(Dia.FileName).Name, TextBox1.Text, AddressOf Fin, AddressOf Prog1)
End If
End Sub
End Class