优化dde,创建结构体对象方法集成
This commit is contained in:
parent
1a77b3c28b
commit
07d3998111
201
dde/dde.go
201
dde/dde.go
@ -7,16 +7,213 @@ package dde
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
ddeml "go-dde/ddeml"
|
ddeml "go-dde/ddeml"
|
||||||
. "go-dde/types"
|
. "go-dde/types"
|
||||||
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MAX_BUFFER_SIZE = 16
|
MAX_BUFFER_SIZE = 2147483647
|
||||||
)
|
)
|
||||||
|
|
||||||
func DDERequest(idInst DWORD, hConv HCONV, hszItem HSZ, sDesc string) string {
|
type DdeMeta struct {
|
||||||
|
IdInst DWORD //全局句柄
|
||||||
|
HConv HCONV //会话句柄
|
||||||
|
Callback FNCALLBACK //回调函数
|
||||||
|
AppName VString //服务名称
|
||||||
|
TopicName VString //主题名称
|
||||||
|
Items []VString //单元项目字符串数组
|
||||||
|
HszApp HSZ //服务字符串句柄
|
||||||
|
HszTopic HSZ //主题字符串句柄
|
||||||
|
HszItem []HSZ //单元项目字符串句柄数组
|
||||||
|
}
|
||||||
|
type DdeClient struct {
|
||||||
|
DdeMeta
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DdeClient) Run() bool {
|
||||||
|
var cmd DWORD = DWORD(APPCLASS_STANDARD | APPCMD_CLIENTONLY)
|
||||||
|
var res DWORD = 0
|
||||||
|
if c.Callback == nil {
|
||||||
|
c.Callback = c.MetaCallBackfunc
|
||||||
|
}
|
||||||
|
iReturn := ddeml.DdeInitialize(&c.IdInst, c.Callback, cmd, res)
|
||||||
|
if int(iReturn) != DMLERR_NO_ERROR {
|
||||||
|
fmt.Printf("DDE Initialization Failed")
|
||||||
|
}
|
||||||
|
c.HszApp = ddeml.DdeCreateStringHandle(c.IdInst, c.AppName, 0)
|
||||||
|
c.HszTopic = ddeml.DdeCreateStringHandle(c.IdInst, c.TopicName, 0)
|
||||||
|
c.HszItem = make([]HSZ, len(c.Items))
|
||||||
|
for i := 0; i < len(c.Items); i++ {
|
||||||
|
c.HszItem[i] = ddeml.DdeCreateStringHandle(c.IdInst, c.Items[i], 0)
|
||||||
|
}
|
||||||
|
c.HConv = ddeml.DdeConnect(c.IdInst, c.HszApp, c.HszTopic, nil)
|
||||||
|
if c.HConv == HCONV(NULL) {
|
||||||
|
fmt.Printf("DDE Connection Failed.\n")
|
||||||
|
time.Sleep(2e9) //2e9 相当于2秒
|
||||||
|
c.DestoryClient()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DdeClient) DestoryClient() {
|
||||||
|
ddeml.DdeFreeStringHandle(c.IdInst, c.HszApp)
|
||||||
|
ddeml.DdeFreeStringHandle(c.IdInst, c.HszTopic)
|
||||||
|
for i := 0; i < len(c.Items); i++ {
|
||||||
|
ddeml.DdeFreeStringHandle(c.IdInst, c.HszItem[i])
|
||||||
|
}
|
||||||
|
fmt.Printf("客户端关闭")
|
||||||
|
ddeml.DdeDisconnect(c.HConv)
|
||||||
|
ddeml.DdeUninitialize(c.IdInst)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DdeServer struct {
|
||||||
|
DdeMeta
|
||||||
|
close bool //服务状态
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DdeServer) RunServer() bool {
|
||||||
|
if c.Callback == nil {
|
||||||
|
c.Callback = c.MetaCallBackfunc
|
||||||
|
}
|
||||||
|
iReturn := ddeml.DdeInitialize(&c.IdInst, c.Callback, DWORD(APPCLASS_STANDARD), 0)
|
||||||
|
if int(iReturn) != DMLERR_NO_ERROR {
|
||||||
|
fmt.Printf("DDE Initialization Failed")
|
||||||
|
}
|
||||||
|
c.HszApp = ddeml.DdeCreateStringHandle(c.IdInst, c.AppName, 0)
|
||||||
|
c.HszTopic = ddeml.DdeCreateStringHandle(c.IdInst, c.TopicName, 0)
|
||||||
|
c.HszItem = make([]HSZ, len(c.Items))
|
||||||
|
for i := 0; i < len(c.Items); i++ {
|
||||||
|
c.HszItem[i] = ddeml.DdeCreateStringHandle(c.IdInst, c.Items[i], 0)
|
||||||
|
}
|
||||||
|
sever := ddeml.DdeNameService(c.IdInst, c.HszApp, 0, UINT(DNS_REGISTER))
|
||||||
|
defer c.DestoryServer()
|
||||||
|
if int(sever) != TRUE {
|
||||||
|
fmt.Printf("DdeNameService() failed!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c.close = false
|
||||||
|
fmt.Printf("服务端开启")
|
||||||
|
for {
|
||||||
|
//do something
|
||||||
|
var msg TagMSG
|
||||||
|
if int(ddeml.GetMessage(&msg, 0, 0, 0)) <= 0 {
|
||||||
|
if c.close {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ddeml.TranslateMessage(&msg)
|
||||||
|
ddeml.DispatchMessage(&msg)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DdeServer) DestoryServer() {
|
||||||
|
c.close = true
|
||||||
|
ddeml.DdeFreeStringHandle(c.IdInst, c.HszApp)
|
||||||
|
ddeml.DdeFreeStringHandle(c.IdInst, c.HszTopic)
|
||||||
|
for i := 0; i < len(c.Items); i++ {
|
||||||
|
ddeml.DdeFreeStringHandle(c.IdInst, c.HszItem[i])
|
||||||
|
}
|
||||||
|
fmt.Printf("服务端关闭")
|
||||||
|
ddeml.DdeNameService(c.IdInst, c.HszApp, 0, UINT(DNS_UNREGISTER))
|
||||||
|
ddeml.DdeUninitialize(c.IdInst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DdeServer) IsHSZItem(hsz2 HSZ) HSZ {
|
||||||
|
for i := 0; i < len(c.Items); i++ {
|
||||||
|
if ddeml.DdeCmpStringHandles(HSZ(hsz2), c.HszItem[i]) <= 0 {
|
||||||
|
return c.HszItem[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DdeMeta) MetaCallBackfunc(wType UINT, wFmt UINT, hConv HCONV, hsz1 HSZ, hsz2 HSZ, hData HDDEDATA, dwData1 ULONG_PTR, dwData2 ULONG_PTR) HDDEDATA {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func (c *DdeServer) MetaCallBackfunc(wType UINT, wFmt UINT, hConv HCONV, hsz1 HSZ, hsz2 HSZ, hData HDDEDATA, dwData1 ULONG_PTR, dwData2 ULONG_PTR) HDDEDATA {
|
||||||
|
selectItem := c.IsHSZItem(hsz2)
|
||||||
|
var res HDDEDATA
|
||||||
|
switch wType {
|
||||||
|
case XTYP_CONNECT:
|
||||||
|
//接受客户端链接;
|
||||||
|
if ddeml.DdeCmpStringHandles(HSZ(hsz1), c.HszTopic) <= 0 &&
|
||||||
|
ddeml.DdeCmpStringHandles(HSZ(hsz2), c.HszApp) <= 0 {
|
||||||
|
res = HDDEDATA(TRUE)
|
||||||
|
} else {
|
||||||
|
res = HDDEDATA(FALSE) //接受客户端链接
|
||||||
|
}
|
||||||
|
case XTYP_ADVSTART:
|
||||||
|
//客户端启动咨询循环。
|
||||||
|
if ddeml.DdeCmpStringHandles(HSZ(hsz1), c.HszTopic) <= 0 &&
|
||||||
|
ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 {
|
||||||
|
res = HDDEDATA(TRUE)
|
||||||
|
} else {
|
||||||
|
res = HDDEDATA(FALSE) //接受客户端链接
|
||||||
|
}
|
||||||
|
case XTYP_ADVREQ:
|
||||||
|
if ddeml.DdeCmpStringHandles(HSZ(hsz1), c.HszTopic) <= 0 &&
|
||||||
|
ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 {
|
||||||
|
res = c.SendMessage("XTYP_ADVREQ", selectItem, UINT(wFmt))
|
||||||
|
}
|
||||||
|
//广播数据;
|
||||||
|
case XTYP_REQUEST:
|
||||||
|
if ddeml.DdeCmpStringHandles(HSZ(hsz1), c.HszTopic) <= 0 &&
|
||||||
|
ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 {
|
||||||
|
res = c.SendMessage("XTYP_REQUEST哈哈", selectItem, UINT(wFmt))
|
||||||
|
}
|
||||||
|
//数据请求;
|
||||||
|
case XTYP_POKE:
|
||||||
|
if ddeml.DdeCmpStringHandles(HSZ(hsz1), c.HszTopic) <= 0 &&
|
||||||
|
ddeml.DdeCmpStringHandles(HSZ(hsz2), selectItem) <= 0 {
|
||||||
|
message := c.GetMessage(hData)
|
||||||
|
fmt.Printf("message: %v\n", message)
|
||||||
|
res = HDDEDATA(DDE_FACK)
|
||||||
|
}
|
||||||
|
case XTYP_DISCONNECT:
|
||||||
|
fmt.Println("Disconnect notification received from server")
|
||||||
|
//接受客户端发送的数据;
|
||||||
|
default:
|
||||||
|
res = HDDEDATA(NULL)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
func (c *DdeMeta) Request(hszItem HSZ) string {
|
||||||
|
hData := ddeml.DdeClientTransaction(nil, 0, c.HConv, hszItem, UINT(CF_TEXT),
|
||||||
|
UINT(XTYP_REQUEST), 5000, nil)
|
||||||
|
if hData == 0 {
|
||||||
|
return "Request failed"
|
||||||
|
} else {
|
||||||
|
return DDEGetMessage(hData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c *DdeMeta) Poke(hszItem HSZ, szData string) {
|
||||||
|
cs := C.CString(szData)
|
||||||
|
ddeml.DdeClientTransaction((*BYTE)(unsafe.Pointer(cs)),
|
||||||
|
DWORD(len(szData)+1),
|
||||||
|
c.HConv, hszItem, UINT(CF_TEXT),
|
||||||
|
UINT(XTYP_POKE), 3000, nil)
|
||||||
|
C.free(unsafe.Pointer(cs))
|
||||||
|
}
|
||||||
|
func (c *DdeMeta) SendMessage(Src string, Item HSZ, Fmt UINT) HDDEDATA {
|
||||||
|
cs := C.CString(Src)
|
||||||
|
hdata := ddeml.DdeCreateDataHandle(c.IdInst, (*BYTE)(unsafe.Pointer(cs)), DWORD(len(Src)+1), 0, Item, Fmt, 0)
|
||||||
|
C.free(unsafe.Pointer(cs))
|
||||||
|
return hdata
|
||||||
|
}
|
||||||
|
func (c *DdeMeta) GetMessage(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DDERequest(idInst DWORD, hConv HCONV, hszItem HSZ) string {
|
||||||
hData := ddeml.DdeClientTransaction(nil, 0, hConv, hszItem, UINT(CF_TEXT),
|
hData := ddeml.DdeClientTransaction(nil, 0, hConv, hszItem, UINT(CF_TEXT),
|
||||||
UINT(XTYP_REQUEST), 5000, nil)
|
UINT(XTYP_REQUEST), 5000, nil)
|
||||||
if hData == 0 {
|
if hData == 0 {
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
DdeInitialize func(
|
DdeInitialize func(
|
||||||
Inst *DWORD,
|
Inst *DWORD,
|
||||||
Callback any,
|
Callback FNCALLBACK, //any
|
||||||
Cmd DWORD,
|
Cmd DWORD,
|
||||||
Res DWORD) UINT
|
Res DWORD) UINT
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ func init() {
|
|||||||
user32 := syscall.MustLoadDLL("user32")
|
user32 := syscall.MustLoadDLL("user32")
|
||||||
DdeInitialize = func(
|
DdeInitialize = func(
|
||||||
Inst *DWORD,
|
Inst *DWORD,
|
||||||
Callback any,
|
Callback FNCALLBACK, //any
|
||||||
Cmd DWORD,
|
Cmd DWORD,
|
||||||
Res DWORD) UINT {
|
Res DWORD) UINT {
|
||||||
proc := user32.MustFindProc("DdeInitializeW")
|
proc := user32.MustFindProc("DdeInitializeW")
|
||||||
|
145
demo/demo.go
Normal file
145
demo/demo.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package demo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go-dde/dde"
|
||||||
|
"go-dde/ddeml"
|
||||||
|
. "go-dde/types"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isHSZItem(hsz2 HSZ) HSZ {
|
||||||
|
for i := 0; i < len(items); i++ {
|
||||||
|
if ddeml.DdeCmpStringHandles(HSZ(hsz2), hszItem[i]) <= 0 {
|
||||||
|
return hszItem[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func DdeCallback(wType UINT, wFmt UINT, hConv HCONV, hsz1 HSZ, hsz2 HSZ, hData HDDEDATA, dwData1 ULONG_PTR, dwData2 ULONG_PTR) HDDEDATA {
|
||||||
|
selectItem := isHSZItem(hsz2)
|
||||||
|
var res HDDEDATA
|
||||||
|
switch wType {
|
||||||
|
case XTYP_CONNECT:
|
||||||
|
//接受客户端链接;
|
||||||
|
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:
|
||||||
|
//客户端启动咨询循环。
|
||||||
|
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:
|
||||||
|
res = HDDEDATA(NULL)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
//var callbacks FNCALLBACK = DdeCallback
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
func runClient() {
|
||||||
|
var cmd DWORD = DWORD(APPCLASS_STANDARD | APPCMD_CLIENTONLY)
|
||||||
|
var res DWORD = 0
|
||||||
|
iReturn := ddeml.DdeInitialize(&idInst, DdeCallback, cmd, res)
|
||||||
|
if iReturn != UINT(DMLERR_NO_ERROR) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if int(iReturn) != DMLERR_NO_ERROR {
|
||||||
|
fmt.Printf("DDE Initialization Failed")
|
||||||
|
}
|
||||||
|
var hConv HCONV // 会话句柄
|
||||||
|
hszApp := ddeml.DdeCreateStringHandle(idInst, szApp, 0)
|
||||||
|
hszTopic := ddeml.DdeCreateStringHandle(idInst, szTopic, 0)
|
||||||
|
for i := 0; i < len(items); i++ {
|
||||||
|
hszItem[i] = ddeml.DdeCreateStringHandle(idInst, items[i], 0)
|
||||||
|
}
|
||||||
|
hConv = ddeml.DdeConnect(idInst, hszApp, hszTopic, nil)
|
||||||
|
ddeml.DdeFreeStringHandle(idInst, hszApp)
|
||||||
|
ddeml.DdeFreeStringHandle(idInst, hszTopic)
|
||||||
|
if hConv == 0 {
|
||||||
|
fmt.Printf("DDE Connection Failed.\n")
|
||||||
|
time.Sleep(2e9) //2e9 相当于2秒
|
||||||
|
ddeml.DdeUninitialize(idInst)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(items); i++ {
|
||||||
|
data := dde.DDERequest(idInst, hConv, hszItem[i])
|
||||||
|
fmt.Printf("data: %v\n", data)
|
||||||
|
dde.DDEPoke(idInst, hConv, hszItem[i], data)
|
||||||
|
time.Sleep(1e9)
|
||||||
|
}
|
||||||
|
fmt.Printf("客户端关闭")
|
||||||
|
ddeml.DdeDisconnect(hConv)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
154
main.go
154
main.go
@ -3,158 +3,34 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go-dde/dde"
|
"go-dde/dde"
|
||||||
"go-dde/ddeml"
|
|
||||||
. "go-dde/types"
|
. "go-dde/types"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
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:
|
|
||||||
//接受客户端链接;
|
|
||||||
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:
|
|
||||||
//客户端启动咨询循环。
|
|
||||||
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:
|
|
||||||
res = HDDEDATA(NULL)
|
|
||||||
}
|
|
||||||
return int(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
var callbacks FNCALLBACK = func(
|
|
||||||
Type UINT,
|
|
||||||
Fmt UINT,
|
|
||||||
Conv HCONV,
|
|
||||||
Sz1 HSZ,
|
|
||||||
Sz2 HSZ,
|
|
||||||
Data HDDEDATA,
|
|
||||||
Data1 ULONG_PTR,
|
|
||||||
Data2 ULONG_PTR) HDDEDATA {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
func runClient() {
|
func runClient() {
|
||||||
var cmd DWORD = DWORD(APPCLASS_STANDARD | APPCMD_CLIENTONLY)
|
ddecli := dde.DdeClient{}
|
||||||
var res DWORD = 0
|
ddecli.AppName = "Server"
|
||||||
iReturn := ddeml.DdeInitialize(&idInst, DdeCallback, cmd, res)
|
ddecli.TopicName = "MyTopic"
|
||||||
if iReturn != UINT(DMLERR_NO_ERROR) {
|
ddecli.Items = []VString{"MyItem0", "MyItem1", "MyItem2", "MyItem3", "MyItem4", "MyItem5", "MyItem6"}
|
||||||
|
ddecli.Run()
|
||||||
}
|
for i := 0; i < len(ddecli.Items); i++ {
|
||||||
if int(iReturn) != DMLERR_NO_ERROR {
|
data := ddecli.Request(ddecli.HszItem[i])
|
||||||
fmt.Printf("DDE Initialization Failed")
|
|
||||||
}
|
|
||||||
var hConv HCONV // 会话句柄
|
|
||||||
hszApp := ddeml.DdeCreateStringHandle(idInst, szApp, 0)
|
|
||||||
hszTopic := ddeml.DdeCreateStringHandle(idInst, szTopic, 0)
|
|
||||||
for i := 0; i < len(items); i++ {
|
|
||||||
hszItem[i] = ddeml.DdeCreateStringHandle(idInst, items[i], 0)
|
|
||||||
}
|
|
||||||
hConv = ddeml.DdeConnect(idInst, hszApp, hszTopic, nil)
|
|
||||||
ddeml.DdeFreeStringHandle(idInst, hszApp)
|
|
||||||
ddeml.DdeFreeStringHandle(idInst, hszTopic)
|
|
||||||
if hConv == 0 {
|
|
||||||
fmt.Printf("DDE Connection Failed.\n")
|
|
||||||
time.Sleep(2e9) //2e9 相当于2秒
|
|
||||||
ddeml.DdeUninitialize(idInst)
|
|
||||||
}
|
|
||||||
for i := 0; i < len(items); i++ {
|
|
||||||
data := dde.DDERequest(idInst, hConv, hszItem[i], "请求到服务端数据: ")
|
|
||||||
fmt.Printf("data: %v\n", data)
|
fmt.Printf("data: %v\n", data)
|
||||||
dde.DDEPoke(idInst, hConv, hszItem[i], data)
|
ddecli.Poke(ddecli.HszItem[i], data)
|
||||||
time.Sleep(1e9)
|
time.Sleep(1e9)
|
||||||
}
|
}
|
||||||
fmt.Printf("客户端关闭")
|
|
||||||
ddeml.DdeDisconnect(hConv)
|
|
||||||
ddeml.DdeUninitialize(idInst)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runServer() {
|
func runServer() {
|
||||||
iReturn := ddeml.DdeInitialize(&idInst, DdeCallback, DWORD(APPCLASS_STANDARD), 0)
|
ddeser := dde.DdeServer{}
|
||||||
if int(iReturn) != DMLERR_NO_ERROR {
|
ddeser.AppName = "Server"
|
||||||
fmt.Printf("DDE Initialization Failed")
|
ddeser.TopicName = "MyTopic"
|
||||||
}
|
ddeser.Items = []VString{"MyItem0", "MyItem1", "MyItem2", "MyItem3", "MyItem4", "MyItem5", "MyItem6"}
|
||||||
g_hszAppName = ddeml.DdeCreateStringHandle(idInst, szApp, 0)
|
defer ddeser.DestoryServer()
|
||||||
|
ddeser.RunServer()
|
||||||
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()
|
runServer()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,25 +54,25 @@ var (
|
|||||||
XCLASS_FLAGS = 0x4000
|
XCLASS_FLAGS = 0x4000
|
||||||
XCLASS_NOTIFICATION = 0x8000
|
XCLASS_NOTIFICATION = 0x8000
|
||||||
|
|
||||||
XTYP_ERROR = 0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
XTYP_ERROR = UINT(0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK)
|
||||||
XTYP_ADVDATA = 0x0010 | XCLASS_FLAGS
|
XTYP_ADVDATA = UINT(0x0010 | XCLASS_FLAGS)
|
||||||
XTYP_ADVREQ = 0x0020 | XCLASS_DATA | XTYPF_NOBLOCK
|
XTYP_ADVREQ = UINT(0x0020 | XCLASS_DATA | XTYPF_NOBLOCK)
|
||||||
XTYP_ADVSTART = 0x0030 | XCLASS_BOOL
|
XTYP_ADVSTART = UINT(0x0030 | XCLASS_BOOL)
|
||||||
XTYP_ADVSTOP = 0x0040 | XCLASS_NOTIFICATION
|
XTYP_ADVSTOP = UINT(0x0040 | XCLASS_NOTIFICATION)
|
||||||
XTYP_EXECUTE = 0x0050 | XCLASS_FLAGS
|
XTYP_EXECUTE = UINT(0x0050 | XCLASS_FLAGS)
|
||||||
XTYP_CONNECT = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK
|
XTYP_CONNECT = UINT(0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK)
|
||||||
XTYP_CONNECT_CONFIRM = 0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
XTYP_CONNECT_CONFIRM = UINT(0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK)
|
||||||
XTYP_XACT_COMPLETE = 0x0080 | XCLASS_NOTIFICATION
|
XTYP_XACT_COMPLETE = UINT(0x0080 | XCLASS_NOTIFICATION)
|
||||||
XTYP_POKE = 0x0090 | XCLASS_FLAGS
|
XTYP_POKE = UINT(0x0090 | XCLASS_FLAGS)
|
||||||
XTYP_REGISTER = 0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
XTYP_REGISTER = UINT(0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK)
|
||||||
XTYP_REQUEST = 0x00B0 | XCLASS_DATA
|
XTYP_REQUEST = UINT(0x00B0 | XCLASS_DATA)
|
||||||
XTYP_DISCONNECT = 0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
XTYP_DISCONNECT = UINT(0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK)
|
||||||
XTYP_UNREGISTER = 0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
XTYP_UNREGISTER = UINT(0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK)
|
||||||
XTYP_WILDCONNECT = 0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK
|
XTYP_WILDCONNECT = UINT(0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK)
|
||||||
XTYP_MONITOR = 0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
XTYP_MONITOR = UINT(0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK)
|
||||||
|
|
||||||
XTYP_MASK = 0x00F0
|
XTYP_MASK = UINT(0x00F0)
|
||||||
XTYP_SHIFT = 4
|
XTYP_SHIFT = UINT(4)
|
||||||
|
|
||||||
TIMEOUT_ASYNC = 0xFFFFFFFF
|
TIMEOUT_ASYNC = 0xFFFFFFFF
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ type (
|
|||||||
HCRYPTPROV ULONG_PTR
|
HCRYPTPROV ULONG_PTR
|
||||||
HCURSOR HANDLE
|
HCURSOR HANDLE
|
||||||
HDC HANDLE
|
HDC HANDLE
|
||||||
HDDEDATA HANDLE
|
HDDEDATA int
|
||||||
HDESK HANDLE
|
HDESK HANDLE
|
||||||
HDEVNOTIFY HANDLE
|
HDEVNOTIFY HANDLE
|
||||||
HDPA HANDLE
|
HDPA HANDLE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user