实现go-dde 服务端

master
15128022404 2 years ago
parent d6deeebed3
commit 1a77b3c28b

@ -22,11 +22,7 @@ func DDERequest(idInst DWORD, hConv HCONV, hszItem HSZ, sDesc string) string {
if hData == 0 { if hData == 0 {
return "Request failed" return "Request failed"
} else { } else {
size := ddeml.DdeGetData(hData, nil, 0, 0) return DDEGetMessage(hData)
var str BYTE
ddeml.DdeGetData(hData, &str, size, 0)
buffer := (*[MAX_BUFFER_SIZE]byte)(unsafe.Pointer(&str))[:size-1]
return string(buffer)
} }
} }
func DDEPoke(idInst DWORD, hConv HCONV, hszItem HSZ, szData string) { 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) UINT(XTYP_POKE), 3000, nil)
C.free(unsafe.Pointer(cs)) 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)
}

@ -112,4 +112,10 @@ var (
DdeKeepStringHandle func(Inst DWORD, S HSZ) BOOL DdeKeepStringHandle func(Inst DWORD, S HSZ) BOOL
DdeCmpStringHandles func(S1 HSZ, S2 HSZ) int 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
) )

@ -1,7 +1,6 @@
package ddeml package ddeml
import ( import (
"fmt"
. "go-dde/types" . "go-dde/types"
"syscall" "syscall"
"unsafe" "unsafe"
@ -15,14 +14,11 @@ func init() {
Cmd DWORD, Cmd DWORD,
Res DWORD) UINT { Res DWORD) UINT {
proc := user32.MustFindProc("DdeInitializeW") proc := user32.MustFindProc("DdeInitializeW")
res, _, err := proc.Call( res, _, _ := proc.Call(
uintptr(unsafe.Pointer(Inst)), uintptr(unsafe.Pointer(Inst)),
syscall.NewCallback(Callback), syscall.NewCallback(Callback),
uintptr(Cmd), uintptr(Cmd),
0) 0)
if err != nil {
fmt.Print(err.Error())
}
return UINT(res) return UINT(res)
} }
DdeUninitialize = func(Inst DWORD) BOOL { DdeUninitialize = func(Inst DWORD) BOOL {
@ -276,4 +272,21 @@ func init() {
uintptr(S2)) uintptr(S2))
return int(res) 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)
}
} }

@ -8,24 +8,61 @@ import (
"time" "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 { switch wType {
case XTYP_CONNECT: 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: 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: 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: 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: 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: default:
return 0 res = HDDEDATA(NULL)
} }
return 0 return int(res)
} }
var callbacks FNCALLBACK = func( var callbacks FNCALLBACK = func(
@ -43,6 +80,8 @@ var callbacks FNCALLBACK = func(
var idInst DWORD = 0 var idInst DWORD = 0
var szApp VString = "Server" var szApp VString = "Server"
var szTopic VString = "MyTopic" var szTopic VString = "MyTopic"
var g_hszAppName HSZ
var g_hszTopicName HSZ
var items []VString = []VString{"MyItem0", "MyItem1", "MyItem2", "MyItem3", "MyItem4", "MyItem5", "MyItem6"} var items []VString = []VString{"MyItem0", "MyItem1", "MyItem2", "MyItem3", "MyItem4", "MyItem5", "MyItem6"}
var hszItem []HSZ = make([]HSZ, len(items)) var hszItem []HSZ = make([]HSZ, len(items))
@ -81,6 +120,41 @@ func runClient() {
ddeml.DdeUninitialize(idInst) 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() { func main() {
runClient() //runClient()
runServer()
} }

@ -81,6 +81,14 @@ var (
CP_WINANSI = 1004 CP_WINANSI = 1004
CP_WINUNICODE = 1200 CP_WINUNICODE = 1200
DNS_REGISTER = 0x0001
DNS_UNREGISTER = 0x0002
DNS_FILTERON = 0x0004
DNS_FILTEROFF = 0x0008
NULL = 0
FALSE = 0
TRUE = 1
) )
type ( type (
@ -333,3 +341,18 @@ type CONVINFO struct {
Wnd HWND Wnd HWND
WndPartner 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

Loading…
Cancel
Save