Golang可以做界面嗎?
說(shuō)起界面,這是一道坎,有人或許會(huì)說(shuō),GO為什么要寫(xiě)界面UI呢,這本來(lái)不是GO擅長(zhǎng)的部分,也不是GO該干的事情,這句話(huà)我就不愛(ài)聽(tīng)了。
舉個(gè)列子,比如我們用GO語(yǔ)言寫(xiě)個(gè)服務(wù)器,這個(gè)服務(wù)器就是用作直播視頻聊天的服務(wù)器,它的功能包含直播房間在線(xiàn)列表人員,當(dāng)然GO語(yǔ)言設(shè)計(jì)的時(shí)候,服務(wù)器記錄了在線(xiàn)列表的 userId、roomId、token、level、ip、chatConent等等。比如我們要監(jiān)視某個(gè)房間的人員列表,看他是否用協(xié)議刷了人氣,其實(shí)就是統(tǒng)計(jì)一個(gè)IP上有多少帳號(hào),或者監(jiān)控房間里面是否有機(jī)器人在發(fā)言,并隨時(shí)封禁它,或者統(tǒng)計(jì)在線(xiàn)直播列表的人數(shù)等等,我們用命令行是能夠操作上述的東西,但是這么多的動(dòng)作你能記得住那么多的命令嗎?
而且上述那么多的東西顯示在黑色框子里面,眼睛看久了不累嗎?一旦命令行用錯(cuò)了,承擔(dān)起后果嗎?
在命令行里面去選擇一個(gè)用戶(hù)或者房間那是一件多么痛苦的事情啊。
而且這些后臺(tái)管理員又不是技術(shù)人員,很可能會(huì)出錯(cuò)。
因此界面是必須有的。
GO語(yǔ)言中選擇界面是一件糾結(jié)的事情,github上面GO-UI要么項(xiàng)目幾年沒(méi)人更新了,要么簡(jiǎn)單的功能讓人不多看一眼。
比如 谷歌自帶gxui已經(jīng)死掉了,goqt的下載一大堆的東西去配置,go-gtk配置也麻煩,而且功能也是簡(jiǎn)單。
假如在linux下,我建議還是選擇后面的兩個(gè),那是沒(méi)得選擇的選擇。
在WINODWS 目前推薦https://github.com/lxn/walk 這個(gè)東西,目前在GITHUB上最新的版本是需要GO1.8去構(gòu)建的,否則百分百會(huì)出錯(cuò)。
下載下來(lái)看下demo
有復(fù)制粘帖、數(shù)據(jù)綁定、圖片顯示、webkit、繪圖、listbox、托盤(pán)、tab、滑動(dòng)條、拖動(dòng)文件、進(jìn)度條、按鈕、選擇框、單選框等等。功能挺全面的,可以去實(shí)驗(yàn)下。
先來(lái)了解下句柄,什么叫做句柄?句柄可以說(shuō)是windows上集合所有打開(kāi)了的界面程序上的控件ID一樣,代表了唯一身份,其實(shí)底層還是指針,每次打開(kāi)程序,句柄由系統(tǒng)隨機(jī)分配命名,不存在兩個(gè)句柄是一樣的。句柄包含了窗口句柄和控件句柄。
walk下載下來(lái)的包這么小,而且編譯出來(lái)的程序也這么小,那就肯定是調(diào)用了WINDOWS內(nèi)置的一些com組件和active控件,這些東西存在于DLL中,一般位于在system32目錄下或者程序運(yùn)行的當(dāng)前目錄下,像QT5這些不是調(diào)用window內(nèi)置的,因此QT編譯出來(lái)的程序是找不到控件句柄的。比如QQ、YY、迅雷這些軟件是找不到控件的句柄的,只能找到窗口句柄,因?yàn)檫@些控件是DX畫(huà)出來(lái)了。
句柄是一個(gè)類(lèi)似整數(shù)一樣的數(shù)值。
在windows設(shè)計(jì)不同語(yǔ)言的交互的時(shí)候,dll文件是一條逃不過(guò)去的坑,先來(lái)看下C/C++、GO的類(lèi)型不同的定義
Win32 C/C++ golang 字符對(duì)照表
WIN32類(lèi)型 C/C++ 類(lèi)型 GO 類(lèi)型
HANDLE void * uintptr
BYTE unsigned char uint8, byte
SHORT short int16
WORD unsigned short uint16
INT int int32, int
UINT unsigned int uint32
LONG long int32
BOOL int int
DWORD unsigned long uint32
ULONG unsigned long uint32
CHAR char byte
WCHAR wchar_t uint16
LPSTR utf8/char * *byte
LPCSTR const utf8/char * *byte, syscall.StringBytePtr(), xc.UTF8PtrToSting()
LPWSTR wchar_t * *uint16
LPCWSTR const wchar_t * *uint16, syscall.StringToUTF16Ptr()
FLOAT float float32
DOUBLE double float64
LONGLONG __int64 int64
DWORD64 unsigned __int64 uint64