轉自https://www.cnblogs.com/birdwawe/articles/2507771.html
先說多線程:
方法 1 : CreateThread
不用多說,萬變不離其宗,這是 Win32 內創建線程的唯一系統方法,以下介紹的多線程創建方式雖然不直
接接觸這個 Win32 APi,但系統也是通過他創建的。
方法 2 : TimerSetEvent
這個函數是 Win32 系統的一個高精度計時器函數,通過調用這個函數,系統會創建一個新的線程,讓Timer
回調函數中的代碼運行在這個新線程中。
方法 3 : SHCreateThread
很多人應該沒見過這個函數,這是 shlwapi.dll 的一個導出函數,這個函數看字面也能理解是個創建多線
程的函數,而且。。。 他是基於對象操作的多線程函數,也就是說他能夠穩定的運行一些用上面2種方法創
建,但不能穩定運行的代碼。至少這個函數在 IDE 的環境下表現的中規中矩! 使用方法可查 API-GUIDE
方法 4 : 想起來了, CreateRemoteThread
創建遠程線程,經測試一點也不穩定,根本沒法說下去了,還不如直接調用 CreateThread
但,做為一種線程的創建方法,還是希望能夠熟悉一下,如果不用VB寫代碼,要寫跨進程線程,這是一個簡單易
行的辦法,否則只能繼續SetWindowHook了,熟悉匯編指令的還可以遠程分配內存寫硬編碼執行
方法 5 : 簡單說下 ActiveX 方式的多線程
論壇里面有用這種方法實現的穩定多線程,代碼雖好,但我卻不會用,在倡導綠色軟件的今天,為了一個多線
程,而注冊表里面又要多點xx,不好。。而且卸載麻煩。 用 ActiveX 創建線程與其他方式創建的線程最重
要的地方要主義,任何VB函數的調用最好都建立在新線程中新初始化的對象基礎上執行,不要跨對象調用,
而 ActiveX 的安全線程本身也正是利用了這點,不知道研究 ActiveX 的老大們有沒注意,利用他特性實
現的多線程,是初始化的一個新的線程,而這個線程中初始化的對象則是整個工程。很大的資源浪費,而且有
時候還不好控制,不是你想要的效果。總之一句話,新線程中要自己初始化新的對象而且最好不要用實例繼承
方法 6 : 我的想法
記得以前 CSDN 中有人做過一個代碼,通過函數地址抓取函數內的機器碼,如果能夠知道VB何時已將代碼進
行了機器碼的轉換,然后抓取這些代碼放到數組中執行,那應該是非常穩定的。這純屬娛樂的想法,雖然能夠
實現,但有點過分了,除非是 VB 多線程的狂熱者,否則我想不該花太多力氣研究這個。
方法 7 : 異步
論壇中很多人問,timer控件的事件中代碼是怎么運行的。其實這就是異步,對於單核CPU多線程的執行方式
與異步簡直無異。而最重要的是,VB 中用異步實現代碼執行是安全的。其實異步從大家開始Win GUI編程時
就開始接觸了。例如窗體的消息循環中就經常會以異步的方式執行,1個消息正在執行的時候,另外的消息又
被執行了,也許這樣說會覺得有些亂,稍侯解釋。這個帖子內容要說的內容就完了,下一個帖子里面有個我
忘了什么時候寫的代碼,以那個代碼為例,介紹應用異步。
==========================================================================
微軟官方給出的方案在MSDN里面有說,就是使用ActiveX EXE那種"單元線程模型".
我也曾經試過,的確可以實現"多線程",只是由於要多一個EXE,比較麻煩,后來就沒有深入了.
結果一次無意中在VBGOOD中看到一段代碼,才打通了一個關節:為什么不直接使用ActiveX EXE寫程序呢?!
那段代碼里面,是直接使用這種工程類型,然后在工程內使用CreateObject來生成一個新對象,這樣的話,新的對象就工作於一個單元線程內了.
其實這個我也知道,可是就沒有想到在ActiveX EXE內部使用
看來思路真的不如人.....還要多多學習,多多積累.
ActiveX EXE工程設置為"獨立啟動"后,貌似只能從Sub Main里進行初始化.
而每個對象的建立,都會調用一次這個過程,因此這個過程需要一次性運行.
但是MSDN里說得很清楚,在單元線程模型里面,全局變量的范圍只能是本單元,因此不能使用設置全局變量來完成這個過程的一次運行邏輯.
原代碼里使用了GetProp等方式,感覺不是很好,於是作了一下改進,使用事件對象來完成此工作.
Sub Main相關代碼如下:

Dim hEvent As Long
Sub Main() If GetEventHandle = 0 Then '由於每個新對象的建立,都要執行Main()過程,因此使用事件對象來進行判斷. hEvent = CreateEvent(0&, False, False, MyEvent) '在單元線程下,模塊里的全局變量已經沒有用了. frmMain.Show End If End Sub Private Function GetEventHandle() As Long GetEventHandle = OpenEvent(EVENT_ALL_ACCESS, False, MyEvent) Call CloseHandle(GetEventHandle) End Function Public Function Quit() Call CloseHandle(hEvent) End Function
由於事件對象是系統范圍的,因此可以比較完美的完成這個工作.
同時事件對象在進程消失后,會自動釋放,也方便:)
示例代碼可以生成一個新的單元線程,並在這個線程里面顯示一個窗體,窗體進行一個大循環.
循環內沒有放入DoEvents函數,因此會造成循環所在窗體無響應.
而此時主窗體不受影響.
對象間可以通過一般的調用與事件來進行通訊.
完整的代碼,在此下載: 點擊下載此文件
**************************改一下,添加一個簡單測試例子***********************
0. 用第三方多線程專業控件ThreadFactory.exe,
1. VBA實現多線程