From 1a77b3c28be5ffcb2fce2d6c7c2041f8bf9eab0a Mon Sep 17 00:00:00 2001 From: 15128022404 <1421485150@qq.com> Date: Tue, 18 Oct 2022 12:13:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0go-dde=20=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dde/dde.go | 19 +++++++--- ddeml/ddeml.go | 6 ++++ ddeml/ddeml_impl.go | 23 +++++++++--- main.go | 86 +++++++++++++++++++++++++++++++++++++++++---- types/types.go | 23 ++++++++++++ 5 files changed, 141 insertions(+), 16 deletions(-) diff --git a/dde/dde.go b/dde/dde.go index 1b6aa8f..8049f26 100644 --- a/dde/dde.go +++ b/dde/dde.go @@ -22,11 +22,7 @@ func DDERequest(idInst DWORD, hConv HCONV, hszItem HSZ, sDesc string) string { if hData == 0 { return "Request failed" } else { - size := ddeml.DdeGetData(hData, nil, 0, 0) - var str BYTE - ddeml.DdeGetData(hData, &str, size, 0) - buffer := (*[MAX_BUFFER_SIZE]byte)(unsafe.Pointer(&str))[:size-1] - return string(buffer) + return DDEGetMessage(hData) } } func DDEPoke(idInst DWORD, hConv HCONV, hszItem HSZ, szData string) { @@ -37,3 +33,16 @@ func DDEPoke(idInst DWORD, hConv HCONV, hszItem HSZ, szData string) { UINT(XTYP_POKE), 3000, nil) C.free(unsafe.Pointer(cs)) } +func DDESendMessage(Inst DWORD, Src string, Item HSZ, Fmt UINT) HDDEDATA { + cs := C.CString(Src) + hdata := ddeml.DdeCreateDataHandle(Inst, (*BYTE)(unsafe.Pointer(cs)), DWORD(len(Src)+1), 0, Item, Fmt, 0) + C.free(unsafe.Pointer(cs)) + return hdata +} +func DDEGetMessage(hData HDDEDATA) string { + size := ddeml.DdeGetData(hData, nil, 0, 0) + var str BYTE + ddeml.DdeGetData(hData, &str, size, 0) + buffer := (*[MAX_BUFFER_SIZE]byte)(unsafe.Pointer(&str))[:size-1] + return string(buffer) +} diff --git a/ddeml/ddeml.go b/ddeml/ddeml.go index bd6d030..a818542 100644 --- a/ddeml/ddeml.go +++ b/ddeml/ddeml.go @@ -112,4 +112,10 @@ var ( DdeKeepStringHandle func(Inst DWORD, S HSZ) BOOL DdeCmpStringHandles func(S1 HSZ, S2 HSZ) int + + GetMessage func(lpMsg LPMSG, hWnd HWND, wMsgFilterMin UINT, wMsgFilterMax UINT) BOOL + + TranslateMessage func(lpMsg LPMSG) BOOL + + DispatchMessage func(lpMsg LPMSG) BOOL ) diff --git a/ddeml/ddeml_impl.go b/ddeml/ddeml_impl.go index a96e996..bd98a5b 100644 --- a/ddeml/ddeml_impl.go +++ b/ddeml/ddeml_impl.go @@ -1,7 +1,6 @@ package ddeml import ( - "fmt" . "go-dde/types" "syscall" "unsafe" @@ -15,14 +14,11 @@ func init() { Cmd DWORD, Res DWORD) UINT { proc := user32.MustFindProc("DdeInitializeW") - res, _, err := proc.Call( + res, _, _ := proc.Call( uintptr(unsafe.Pointer(Inst)), syscall.NewCallback(Callback), uintptr(Cmd), 0) - if err != nil { - fmt.Print(err.Error()) - } return UINT(res) } DdeUninitialize = func(Inst DWORD) BOOL { @@ -276,4 +272,21 @@ func init() { uintptr(S2)) return int(res) } + + GetMessage = func(lpMsg LPMSG, hWnd HWND, wMsgFilterMin UINT, wMsgFilterMax UINT) BOOL { + proc := user32.MustFindProc("GetMessageW") + res, _, _ := proc.Call(uintptr(unsafe.Pointer(lpMsg)), + uintptr(hWnd), uintptr(wMsgFilterMin), uintptr(wMsgFilterMax)) + return BOOL(res) + } + TranslateMessage = func(lpMsg LPMSG) BOOL { + proc := user32.MustFindProc("TranslateMessage") + res, _, _ := proc.Call(uintptr(unsafe.Pointer(lpMsg))) + return BOOL(res) + } + DispatchMessage = func(lpMsg LPMSG) BOOL { + proc := user32.MustFindProc("DispatchMessageW") + res, _, _ := proc.Call(uintptr(unsafe.Pointer(lpMsg))) + return BOOL(res) + } } diff --git a/main.go b/main.go index 4b8302b..4874cc1 100644 --- a/main.go +++ b/main.go @@ -8,24 +8,61 @@ import ( "time" ) -func DdeCallback(wType int, wFmt int, hConv uintptr, hsz1 uintptr, hsz2 uintptr, hData uintptr, dwData1 int64, dwData2 int64) int { +func isHSZItem(hsz2 uintptr) HSZ { + for i := 0; i < len(items); i++ { + if ddeml.DdeCmpStringHandles(HSZ(hsz2), hszItem[i]) <= 0 { + return hszItem[i] + } + } + return 0 +} + +func DdeCallback(wType int, wFmt int, hConv uintptr, hsz1 uintptr, hsz2 uintptr, hData HDDEDATA, dwData1 int64, dwData2 int64) int { + selectItem := isHSZItem(hsz2) + var res HDDEDATA switch wType { case XTYP_CONNECT: //接受客户端链接; - return 0 //接受客户端链接 + if ddeml.DdeCmpStringHandles(HSZ(hsz1), g_hszTopicName) <= 0 && + ddeml.DdeCmpStringHandles(HSZ(hsz2), g_hszAppName) <= 0 { + res = HDDEDATA(TRUE) + } else { + res = HDDEDATA(FALSE) //接受客户端链接 + } case XTYP_ADVSTART: //客户端启动咨询循环。 - return 0 //接受客户端链接 + if ddeml.DdeCmpStringHandles(HSZ(hsz1), g_hszTopicName) <= 0 && + ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 { + res = HDDEDATA(TRUE) + } else { + res = HDDEDATA(FALSE) //接受客户端链接 + } case XTYP_ADVREQ: + if ddeml.DdeCmpStringHandles(HSZ(hsz1), g_hszTopicName) <= 0 && + ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 { + res = dde.DDESendMessage(idInst, "XTYP_ADVREQ", selectItem, UINT(wFmt)) + } //广播数据; case XTYP_REQUEST: + if ddeml.DdeCmpStringHandles(HSZ(hsz1), g_hszTopicName) <= 0 && + ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 { + res = dde.DDESendMessage(idInst, "XTYP_REQUEST", selectItem, UINT(wFmt)) + } //数据请求; case XTYP_POKE: + if ddeml.DdeCmpStringHandles(HSZ(hsz1), g_hszTopicName) <= 0 && + ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 { + message := dde.DDEGetMessage(hData) + fmt.Printf("message: %v\n", message) + res = HDDEDATA(DDE_FACK) + } + case XTYP_DISCONNECT: + fmt.Println("Disconnect notification received from server") //接受客户端发送的数据; default: - return 0 + res = HDDEDATA(NULL) } - return 0 + return int(res) } var callbacks FNCALLBACK = func( @@ -43,6 +80,8 @@ var callbacks FNCALLBACK = func( var idInst DWORD = 0 var szApp VString = "Server" var szTopic VString = "MyTopic" +var g_hszAppName HSZ +var g_hszTopicName HSZ var items []VString = []VString{"MyItem0", "MyItem1", "MyItem2", "MyItem3", "MyItem4", "MyItem5", "MyItem6"} var hszItem []HSZ = make([]HSZ, len(items)) @@ -81,6 +120,41 @@ func runClient() { ddeml.DdeUninitialize(idInst) } +func runServer() { + iReturn := ddeml.DdeInitialize(&idInst, DdeCallback, DWORD(APPCLASS_STANDARD), 0) + if int(iReturn) != DMLERR_NO_ERROR { + fmt.Printf("DDE Initialization Failed") + } + g_hszAppName = ddeml.DdeCreateStringHandle(idInst, szApp, 0) + + g_hszTopicName = ddeml.DdeCreateStringHandle(idInst, szTopic, 0) + for i := 0; i < len(items); i++ { + hszItem[i] = ddeml.DdeCreateStringHandle(idInst, items[i], 0) + } + sever := ddeml.DdeNameService(idInst, g_hszAppName, 0, UINT(DNS_REGISTER)) + defer func() { + ddeml.DdeFreeStringHandle(idInst, g_hszAppName) + ddeml.DdeFreeStringHandle(idInst, g_hszTopicName) + fmt.Printf("服务端关闭") + ddeml.DdeNameService(idInst, g_hszAppName, 0, UINT(DNS_UNREGISTER)) + ddeml.DdeUninitialize(idInst) + }() + if int(sever) < 1 { + fmt.Printf("DdeNameService() failed!") + } + fmt.Printf("服务端开启") + for { + //do something + var msg TagMSG + if int(ddeml.GetMessage(&msg, 0, 0, 0)) <= 0 { + break + } + ddeml.TranslateMessage(&msg) + ddeml.DispatchMessage(&msg) + } + +} func main() { - runClient() + //runClient() + runServer() } diff --git a/types/types.go b/types/types.go index 69725e3..89892b2 100644 --- a/types/types.go +++ b/types/types.go @@ -81,6 +81,14 @@ var ( CP_WINANSI = 1004 CP_WINUNICODE = 1200 + + DNS_REGISTER = 0x0001 + DNS_UNREGISTER = 0x0002 + DNS_FILTERON = 0x0004 + DNS_FILTEROFF = 0x0008 + NULL = 0 + FALSE = 0 + TRUE = 1 ) type ( @@ -333,3 +341,18 @@ type CONVINFO struct { Wnd HWND WndPartner HWND } +type TagPOINT struct { + X LONG + Y LONG +} + +type TagMSG struct { + Hwnd HWND + Message UINT + WParam WPARAM + LParam LPARAM + Time DWORD + Pt TagPOINT +} + +type LPMSG *TagMSG