实现go-dde 服务端
This commit is contained in:
parent
d6deeebed3
commit
1a77b3c28b
19
dde/dde.go
19
dde/dde.go
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
88
main.go
88
main.go
@ -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 main() {
|
func runServer() {
|
||||||
runClient()
|
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()
|
||||||
|
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…
x
Reference in New Issue
Block a user