1 回答

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個(gè)贊
package main
/*
#cgo LDFLAGS: -lgdi32
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <windows.h>
HDC *hdcArr;
int count;
BOOL CALLBACK EnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
int i;
for (i = 0; i < (_msize(hdcArr) / sizeof(HDC)); i++) {
if (hdcArr[i] == NULL) {
hdcArr[i] = CreateCompatibleDC(hdcMonitor);
break;
}
}
return TRUE;
}
void Init() {
count = GetSystemMetrics(SM_CMONITORS);
hdcArr = (HDC*)malloc(sizeof(HDC) * count);
memset(hdcArr, 0, sizeof(HDC) * count);
}
*/
import "C"
import (
"fmt"
"reflect"
"unsafe"
"github.com/JamesHovious/w32"
)
func main() {
C.Init()
hdc := w32.GetDC(0)
w32.EnumDisplayMonitors(hdc, nil, reflect.ValueOf(C.EnumProc).Pointer(), 0)
w32.ReleaseDC(0, hdc)
t := (*[256]w32.HDC)(unsafe.Pointer(C.hdcArr))[:C.count:C.count]
for _, dc := range t {
cx := w32.GetDeviceCaps(dc, w32.HORZRES)
fmt.Println(cx)
w32.DeleteDC(dc)
}
C.free(unsafe.Pointer(C.hdcArr))
}
對(duì)您來說理解這一點(diǎn)非常重要,指向 C 數(shù)組的指針只是一個(gè)內(nèi)存地址,沒有任何有關(guān)大小的信息(因此您的 t 數(shù)組為空)。這就是為什么你必須先把它轉(zhuǎn)換成一個(gè)大數(shù)組(*[256]w32.HDC),然后再把它切成合適的大小[:C.count:C.count]
這就是為什么我創(chuàng)建了count一個(gè)全局變量。
您遇到的另一個(gè)問題是傳遞給的 hdc 句柄EnumProc僅在回調(diào)中有效。要使它們?cè)诨卣{(diào)范圍之外永久可用,您必須調(diào)用CreateCompatibleDC(hdcMonitor);.
要將此功能與 cgo 一起使用,您必須通過以下方式包含 lib gdi32#cgo LDFLAGS: -lgdi32
一旦你用完這些 DC,你必須再次釋放它們w32.DeleteDC(dc)
也不要忘記釋放你的 malloced 數(shù)組C.free(unsafe.Pointer(C.hdcArr))
我的建議:每當(dāng)您使用 WinApi 時(shí),請(qǐng)仔細(xì)閱讀 msdn 文檔。這需要一些時(shí)間,但可以為您省去很多麻煩
您也可以在沒有 cgo 的情況下完全在 golang 中執(zhí)行此操作:
package main
import (
"fmt"
"syscall"
"github.com/JamesHovious/w32"
)
func EnumProc(hMonitor w32.HMONITOR, hdcMonitor w32.HDC, lprcMonitor *w32.RECT, dwData w32.LPARAM) uintptr {
fmt.Println(w32.GetDeviceCaps(hdcMonitor, w32.HORZRES))
return w32.TRUE
}
func main() {
hdc := w32.GetDC(0)
w32.EnumDisplayMonitors(hdc, nil, syscall.NewCallback(EnumProc), 0)
w32.ReleaseDC(0, hdc)
}
甚至更平滑:
func EnumProc(hMonitor w32.HMONITOR, hdcMonitor w32.HDC, lprcMonitor *w32.RECT, dwData w32.LPARAM) uintptr {
horzres := lprcMonitor.Right - lprcMonitor.Left
fmt.Println(horzres)
return w32.TRUE
}
func main() {
w32.EnumDisplayMonitors(nil, nil, syscall.NewCallback(EnumProc), 0)
}
- 1 回答
- 0 關(guān)注
- 124 瀏覽
添加回答
舉報(bào)