brukeropus.control.dde
1# Python DDE interface by David Naylor, http://code.activestate.com/recipes/577654-dde-client/ 2# Slightly modified to work with python 3 and streamline the code a bit 3# I do not understand how this works, just use it for sending/recieving DDE communication through OPUS 4 5from ctypes import POINTER, WINFUNCTYPE, c_char_p, c_void_p, c_int, c_ulong, c_char_p, byref, windll, create_string_buffer 6from ctypes.wintypes import BOOL, DWORD, BYTE, INT, LPCWSTR, UINT, ULONG, HWND, MSG 7 8# DECLARE_HANDLE(name) typedef void *name; 9HCONV = c_void_p # = DECLARE_HANDLE(HCONV) 10HDDEDATA = c_void_p # = DECLARE_HANDLE(HDDEDATA) 11HSZ = c_void_p # = DECLARE_HANDLE(HSZ) 12LPBYTE = c_char_p # POINTER(BYTE) 13LPDWORD = POINTER(DWORD) 14LPSTR = c_char_p 15ULONG_PTR = c_ulong 16 17# See windows/ddeml.h for declaration of struct CONVCONTEXT 18PCONVCONTEXT = c_void_p 19 20DMLERR_NO_ERROR = 0 21 22# Predefined Clipboard Formats 23CF_TEXT = 1 24CF_BITMAP = 2 25CF_METAFILEPICT = 3 26CF_SYLK = 4 27CF_DIF = 5 28CF_TIFF = 6 29CF_OEMTEXT = 7 30CF_DIB = 8 31CF_PALETTE = 9 32CF_PENDATA = 10 33CF_RIFF = 11 34CF_WAVE = 12 35CF_UNICODETEXT = 13 36CF_ENHMETAFILE = 14 37CF_HDROP = 15 38CF_LOCALE = 16 39CF_DIBV5 = 17 40CF_MAX = 18 41 42DDE_FACK = 0x8000 43DDE_FBUSY = 0x4000 44DDE_FDEFERUPD = 0x4000 45DDE_FACKREQ = 0x8000 46DDE_FRELEASE = 0x2000 47DDE_FREQUESTED = 0x1000 48DDE_FAPPSTATUS = 0x00FF 49DDE_FNOTPROCESSED = 0x0000 50 51DDE_FACKRESERVED = (~(DDE_FACK | DDE_FBUSY | DDE_FAPPSTATUS)) 52DDE_FADVRESERVED = (~(DDE_FACKREQ | DDE_FDEFERUPD)) 53DDE_FDATRESERVED = (~(DDE_FACKREQ | DDE_FRELEASE | DDE_FREQUESTED)) 54DDE_FPOKRESERVED = (~(DDE_FRELEASE)) 55 56XTYPF_NOBLOCK = 0x0002 57XTYPF_NODATA = 0x0004 58XTYPF_ACKREQ = 0x0008 59 60XCLASS_MASK = 0xFC00 61XCLASS_BOOL = 0x1000 62XCLASS_DATA = 0x2000 63XCLASS_FLAGS = 0x4000 64XCLASS_NOTIFICATION = 0x8000 65 66XTYP_ERROR = (0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 67XTYP_ADVDATA = (0x0010 | XCLASS_FLAGS) 68XTYP_ADVREQ = (0x0020 | XCLASS_DATA | XTYPF_NOBLOCK) 69XTYP_ADVSTART = (0x0030 | XCLASS_BOOL) 70XTYP_ADVSTOP = (0x0040 | XCLASS_NOTIFICATION) 71XTYP_EXECUTE = (0x0050 | XCLASS_FLAGS) 72XTYP_CONNECT = (0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK) 73XTYP_CONNECT_CONFIRM = (0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 74XTYP_XACT_COMPLETE = (0x0080 | XCLASS_NOTIFICATION ) 75XTYP_POKE = (0x0090 | XCLASS_FLAGS) 76XTYP_REGISTER = (0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) 77XTYP_REQUEST = (0x00B0 | XCLASS_DATA ) 78XTYP_DISCONNECT = (0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) 79XTYP_UNREGISTER = (0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) 80XTYP_WILDCONNECT = (0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK) 81XTYP_MONITOR = (0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 82 83XTYP_MASK = 0x00F0 84XTYP_SHIFT = 4 85 86TIMEOUT_ASYNC = 0xFFFFFFFF 87 88def get_winfunc(libname, funcname, restype=None, argtypes=(), _libcache={}): 89 """Retrieve a function from a library, and set the data types.""" 90 if libname not in _libcache: 91 _libcache[libname] = windll.LoadLibrary(libname) 92 func = getattr(_libcache[libname], funcname) 93 func.argtypes = argtypes 94 func.restype = restype 95 96 return func 97 98 99DDECALLBACK = WINFUNCTYPE(HDDEDATA, UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, 100 ULONG_PTR, ULONG_PTR) 101 102class DDE(object): 103 """Object containing all the DDE functions""" 104 AccessData = get_winfunc("user32", "DdeAccessData", LPBYTE, (HDDEDATA, LPDWORD)) 105 ClientTransaction = get_winfunc("user32", "DdeClientTransaction", HDDEDATA, (LPBYTE, DWORD, HCONV, HSZ, UINT, UINT, DWORD, LPDWORD)) 106 Connect = get_winfunc("user32", "DdeConnect", HCONV, (DWORD, HSZ, HSZ, PCONVCONTEXT)) 107 CreateStringHandle = get_winfunc("user32", "DdeCreateStringHandleW", HSZ, (DWORD, LPCWSTR, UINT)) 108 Disconnect = get_winfunc("user32", "DdeDisconnect", BOOL, (HCONV,)) 109 GetLastError = get_winfunc("user32", "DdeGetLastError", UINT, (DWORD,)) 110 Initialize = get_winfunc("user32", "DdeInitializeW", UINT, (LPDWORD, DDECALLBACK, DWORD, DWORD)) 111 FreeDataHandle = get_winfunc("user32", "DdeFreeDataHandle", BOOL, (HDDEDATA,)) 112 FreeStringHandle = get_winfunc("user32", "DdeFreeStringHandle", BOOL, (DWORD, HSZ)) 113 QueryString = get_winfunc("user32", "DdeQueryStringA", DWORD, (DWORD, HSZ, LPSTR, DWORD, c_int)) 114 UnaccessData = get_winfunc("user32", "DdeUnaccessData", BOOL, (HDDEDATA,)) 115 Uninitialize = get_winfunc("user32", "DdeUninitialize", BOOL, (DWORD,)) 116 117class DDEError(RuntimeError): 118 """Exception raise when a DDE errpr occures.""" 119 def __init__(self, msg, idInst=None): 120 if idInst is None: 121 RuntimeError.__init__(self, msg) 122 else: 123 RuntimeError.__init__(self, "%s (err=%s)" % (msg, hex(DDE.GetLastError(idInst)))) 124 125class DDEClient(object): 126 """The DDEClient class. 127 128 Use this class to create and manage a connection to a service/topic. To get 129 classbacks subclass DDEClient and overwrite callback.""" 130 131 def __init__(self, service, topic): 132 """Create a connection to a service/topic.""" 133 self._idInst = DWORD(0) 134 self._hConv = HCONV() 135 136 self._callback = DDECALLBACK(self._callback) 137 res = DDE.Initialize(byref(self._idInst), self._callback, 0x00000010, 0) 138 if res != DMLERR_NO_ERROR: 139 raise DDEError("Unable to register with DDEML (err=%s)" % hex(res)) 140 141 hszService = DDE.CreateStringHandle(self._idInst, service, 1200) 142 hszTopic = DDE.CreateStringHandle(self._idInst, topic, 1200) 143 self._hConv = DDE.Connect(self._idInst, hszService, hszTopic, PCONVCONTEXT()) 144 DDE.FreeStringHandle(self._idInst, hszTopic) 145 DDE.FreeStringHandle(self._idInst, hszService) 146 if not self._hConv: 147 raise DDEError("Unable to establish a conversation with server", self._idInst) 148 149 def __del__(self): 150 """Cleanup any active connections.""" 151 if self._hConv: 152 DDE.Disconnect(self._hConv) 153 if self._idInst: 154 DDE.Uninitialize(self._idInst) 155 156 def advise(self, item, stop=False): 157 """Request updates when DDE data changes.""" 158 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 159 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_ADVSTOP if stop else XTYP_ADVSTART, TIMEOUT_ASYNC, LPDWORD()) 160 DDE.FreeStringHandle(self._idInst, hszItem) 161 if not hDdeData: 162 raise DDEError("Unable to %s advise" % ("stop" if stop else "start"), self._idInst) 163 DDE.FreeDataHandle(hDdeData) 164 165 def execute(self, command, timeout=5000): 166 """Execute a DDE command.""" 167 pData = c_char_p(command) 168 cbData = DWORD(len(command) + 1) 169 hDdeData = DDE.ClientTransaction(pData, cbData, self._hConv, HSZ(), CF_TEXT, XTYP_EXECUTE, timeout, LPDWORD()) 170 if not hDdeData: 171 raise DDEError("Unable to send command", self._idInst) 172 DDE.FreeDataHandle(hDdeData) 173 174 def request(self, item, timeout=5000): 175 """Request data from DDE service.""" 176 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 177 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_REQUEST, timeout, LPDWORD()) 178 DDE.FreeStringHandle(self._idInst, hszItem) 179 if not hDdeData: 180 raise DDEError("Unable to request item", self._idInst) 181 182 if timeout != TIMEOUT_ASYNC: 183 pdwSize = DWORD(0) 184 pData = DDE.AccessData(hDdeData, byref(pdwSize)) 185 if not pData: 186 DDE.FreeDataHandle(hDdeData) 187 raise DDEError("Unable to access data", self._idInst) 188 # TODO: use pdwSize 189 DDE.UnaccessData(hDdeData) 190 DDE.FreeDataHandle(hDdeData) 191 return pData 192 193 def callback(self, value, item=None): 194 """Calback function for advice.""" 195 print("%s: %s" % (item, value)) 196 197 def _callback(self, wType, uFmt, hConv, hsz1, hsz2, hDdeData, dwData1, dwData2): 198 dwSize = DWORD(0) 199 pData = DDE.AccessData(hDdeData, byref(dwSize)) 200 if pData: 201 item = create_string_buffer('\000' * 128) 202 DDE.QueryString(self._idInst, hsz2, item, 128, 1004) 203 self.callback(pData, item.value) 204 DDE.UnaccessData(hDdeData) 205 return DDE_FACK 206 return 0 207 208def WinMSGLoop(): 209 """Run the main windows message loop.""" 210 LPMSG = POINTER(MSG) 211 LRESULT = c_ulong 212 GetMessage = get_winfunc("user32", "GetMessageW", BOOL, (LPMSG, HWND, UINT, UINT)) 213 TranslateMessage = get_winfunc("user32", "TranslateMessage", BOOL, (LPMSG,)) 214 # restype = LRESULT 215 DispatchMessage = get_winfunc("user32", "DispatchMessageW", LRESULT, (LPMSG,)) 216 217 msg = MSG() 218 lpmsg = byref(msg) 219 while GetMessage(lpmsg, HWND(), 0, 0) > 0: 220 TranslateMessage(lpmsg) 221 DispatchMessage(lpmsg) 222 223if __name__ == "__main__": 224 # ------------------------------------------ 225 # Test with Excel 226 # open workbook and enter something in Sheet 1, R1C1 227 dde = DDEClient("Excel", "Sheet1") 228 print(dde.request("R1C1").decode('ASCII')) 229 230 # ------------------------------------------ 231 # Test with OPUS 232 # make sure OPUS software is open 233 dde = DDEClient("Opus", "System") 234 print(dde.request("GET_VERSION_EXTENDED"))
HCONV =
<class 'ctypes.c_void_p'>
HDDEDATA =
<class 'ctypes.c_void_p'>
HSZ =
<class 'ctypes.c_void_p'>
LPBYTE =
<class 'ctypes.c_char_p'>
LPDWORD =
<class 'ctypes.wintypes.LP_c_ulong'>
LPSTR =
<class 'ctypes.c_char_p'>
ULONG_PTR =
<class 'ctypes.c_ulong'>
PCONVCONTEXT =
<class 'ctypes.c_void_p'>
DMLERR_NO_ERROR =
0
CF_TEXT =
1
CF_BITMAP =
2
CF_METAFILEPICT =
3
CF_SYLK =
4
CF_DIF =
5
CF_TIFF =
6
CF_OEMTEXT =
7
CF_DIB =
8
CF_PALETTE =
9
CF_PENDATA =
10
CF_RIFF =
11
CF_WAVE =
12
CF_UNICODETEXT =
13
CF_ENHMETAFILE =
14
CF_HDROP =
15
CF_LOCALE =
16
CF_DIBV5 =
17
CF_MAX =
18
DDE_FACK =
32768
DDE_FBUSY =
16384
DDE_FDEFERUPD =
16384
DDE_FACKREQ =
32768
DDE_FRELEASE =
8192
DDE_FREQUESTED =
4096
DDE_FAPPSTATUS =
255
DDE_FNOTPROCESSED =
0
DDE_FACKRESERVED =
-49408
DDE_FADVRESERVED =
-49153
DDE_FDATRESERVED =
-45057
DDE_FPOKRESERVED =
-8193
XTYPF_NOBLOCK =
2
XTYPF_NODATA =
4
XTYPF_ACKREQ =
8
XCLASS_MASK =
64512
XCLASS_BOOL =
4096
XCLASS_DATA =
8192
XCLASS_FLAGS =
16384
XCLASS_NOTIFICATION =
32768
XTYP_ERROR =
32770
XTYP_ADVDATA =
16400
XTYP_ADVREQ =
8226
XTYP_ADVSTART =
4144
XTYP_ADVSTOP =
32832
XTYP_EXECUTE =
16464
XTYP_CONNECT =
4194
XTYP_CONNECT_CONFIRM =
32882
XTYP_XACT_COMPLETE =
32896
XTYP_POKE =
16528
XTYP_REGISTER =
32930
XTYP_REQUEST =
8368
XTYP_DISCONNECT =
32962
XTYP_UNREGISTER =
32978
XTYP_WILDCONNECT =
8418
XTYP_MONITOR =
33010
XTYP_MASK =
240
XTYP_SHIFT =
4
TIMEOUT_ASYNC =
4294967295
def
get_winfunc( libname, funcname, restype=None, argtypes=(), _libcache={'user32': <WinDLL 'user32', handle 7ff8c01c0000>}):
89def get_winfunc(libname, funcname, restype=None, argtypes=(), _libcache={}): 90 """Retrieve a function from a library, and set the data types.""" 91 if libname not in _libcache: 92 _libcache[libname] = windll.LoadLibrary(libname) 93 func = getattr(_libcache[libname], funcname) 94 func.argtypes = argtypes 95 func.restype = restype 96 97 return func
Retrieve a function from a library, and set the data types.
DDECALLBACK =
<class 'ctypes.WINFUNCTYPE.<locals>.WinFunctionType'>
class
DDE:
103class DDE(object): 104 """Object containing all the DDE functions""" 105 AccessData = get_winfunc("user32", "DdeAccessData", LPBYTE, (HDDEDATA, LPDWORD)) 106 ClientTransaction = get_winfunc("user32", "DdeClientTransaction", HDDEDATA, (LPBYTE, DWORD, HCONV, HSZ, UINT, UINT, DWORD, LPDWORD)) 107 Connect = get_winfunc("user32", "DdeConnect", HCONV, (DWORD, HSZ, HSZ, PCONVCONTEXT)) 108 CreateStringHandle = get_winfunc("user32", "DdeCreateStringHandleW", HSZ, (DWORD, LPCWSTR, UINT)) 109 Disconnect = get_winfunc("user32", "DdeDisconnect", BOOL, (HCONV,)) 110 GetLastError = get_winfunc("user32", "DdeGetLastError", UINT, (DWORD,)) 111 Initialize = get_winfunc("user32", "DdeInitializeW", UINT, (LPDWORD, DDECALLBACK, DWORD, DWORD)) 112 FreeDataHandle = get_winfunc("user32", "DdeFreeDataHandle", BOOL, (HDDEDATA,)) 113 FreeStringHandle = get_winfunc("user32", "DdeFreeStringHandle", BOOL, (DWORD, HSZ)) 114 QueryString = get_winfunc("user32", "DdeQueryStringA", DWORD, (DWORD, HSZ, LPSTR, DWORD, c_int)) 115 UnaccessData = get_winfunc("user32", "DdeUnaccessData", BOOL, (HDDEDATA,)) 116 Uninitialize = get_winfunc("user32", "DdeUninitialize", BOOL, (DWORD,))
Object containing all the DDE functions
class
DDEError(builtins.RuntimeError):
118class DDEError(RuntimeError): 119 """Exception raise when a DDE errpr occures.""" 120 def __init__(self, msg, idInst=None): 121 if idInst is None: 122 RuntimeError.__init__(self, msg) 123 else: 124 RuntimeError.__init__(self, "%s (err=%s)" % (msg, hex(DDE.GetLastError(idInst))))
Exception raise when a DDE errpr occures.
Inherited Members
- builtins.BaseException
- with_traceback
- args
class
DDEClient:
126class DDEClient(object): 127 """The DDEClient class. 128 129 Use this class to create and manage a connection to a service/topic. To get 130 classbacks subclass DDEClient and overwrite callback.""" 131 132 def __init__(self, service, topic): 133 """Create a connection to a service/topic.""" 134 self._idInst = DWORD(0) 135 self._hConv = HCONV() 136 137 self._callback = DDECALLBACK(self._callback) 138 res = DDE.Initialize(byref(self._idInst), self._callback, 0x00000010, 0) 139 if res != DMLERR_NO_ERROR: 140 raise DDEError("Unable to register with DDEML (err=%s)" % hex(res)) 141 142 hszService = DDE.CreateStringHandle(self._idInst, service, 1200) 143 hszTopic = DDE.CreateStringHandle(self._idInst, topic, 1200) 144 self._hConv = DDE.Connect(self._idInst, hszService, hszTopic, PCONVCONTEXT()) 145 DDE.FreeStringHandle(self._idInst, hszTopic) 146 DDE.FreeStringHandle(self._idInst, hszService) 147 if not self._hConv: 148 raise DDEError("Unable to establish a conversation with server", self._idInst) 149 150 def __del__(self): 151 """Cleanup any active connections.""" 152 if self._hConv: 153 DDE.Disconnect(self._hConv) 154 if self._idInst: 155 DDE.Uninitialize(self._idInst) 156 157 def advise(self, item, stop=False): 158 """Request updates when DDE data changes.""" 159 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 160 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_ADVSTOP if stop else XTYP_ADVSTART, TIMEOUT_ASYNC, LPDWORD()) 161 DDE.FreeStringHandle(self._idInst, hszItem) 162 if not hDdeData: 163 raise DDEError("Unable to %s advise" % ("stop" if stop else "start"), self._idInst) 164 DDE.FreeDataHandle(hDdeData) 165 166 def execute(self, command, timeout=5000): 167 """Execute a DDE command.""" 168 pData = c_char_p(command) 169 cbData = DWORD(len(command) + 1) 170 hDdeData = DDE.ClientTransaction(pData, cbData, self._hConv, HSZ(), CF_TEXT, XTYP_EXECUTE, timeout, LPDWORD()) 171 if not hDdeData: 172 raise DDEError("Unable to send command", self._idInst) 173 DDE.FreeDataHandle(hDdeData) 174 175 def request(self, item, timeout=5000): 176 """Request data from DDE service.""" 177 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 178 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_REQUEST, timeout, LPDWORD()) 179 DDE.FreeStringHandle(self._idInst, hszItem) 180 if not hDdeData: 181 raise DDEError("Unable to request item", self._idInst) 182 183 if timeout != TIMEOUT_ASYNC: 184 pdwSize = DWORD(0) 185 pData = DDE.AccessData(hDdeData, byref(pdwSize)) 186 if not pData: 187 DDE.FreeDataHandle(hDdeData) 188 raise DDEError("Unable to access data", self._idInst) 189 # TODO: use pdwSize 190 DDE.UnaccessData(hDdeData) 191 DDE.FreeDataHandle(hDdeData) 192 return pData 193 194 def callback(self, value, item=None): 195 """Calback function for advice.""" 196 print("%s: %s" % (item, value)) 197 198 def _callback(self, wType, uFmt, hConv, hsz1, hsz2, hDdeData, dwData1, dwData2): 199 dwSize = DWORD(0) 200 pData = DDE.AccessData(hDdeData, byref(dwSize)) 201 if pData: 202 item = create_string_buffer('\000' * 128) 203 DDE.QueryString(self._idInst, hsz2, item, 128, 1004) 204 self.callback(pData, item.value) 205 DDE.UnaccessData(hDdeData) 206 return DDE_FACK 207 return 0
The DDEClient class.
Use this class to create and manage a connection to a service/topic. To get classbacks subclass DDEClient and overwrite callback.
DDEClient(service, topic)
132 def __init__(self, service, topic): 133 """Create a connection to a service/topic.""" 134 self._idInst = DWORD(0) 135 self._hConv = HCONV() 136 137 self._callback = DDECALLBACK(self._callback) 138 res = DDE.Initialize(byref(self._idInst), self._callback, 0x00000010, 0) 139 if res != DMLERR_NO_ERROR: 140 raise DDEError("Unable to register with DDEML (err=%s)" % hex(res)) 141 142 hszService = DDE.CreateStringHandle(self._idInst, service, 1200) 143 hszTopic = DDE.CreateStringHandle(self._idInst, topic, 1200) 144 self._hConv = DDE.Connect(self._idInst, hszService, hszTopic, PCONVCONTEXT()) 145 DDE.FreeStringHandle(self._idInst, hszTopic) 146 DDE.FreeStringHandle(self._idInst, hszService) 147 if not self._hConv: 148 raise DDEError("Unable to establish a conversation with server", self._idInst)
Create a connection to a service/topic.
def
advise(self, item, stop=False):
157 def advise(self, item, stop=False): 158 """Request updates when DDE data changes.""" 159 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 160 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_ADVSTOP if stop else XTYP_ADVSTART, TIMEOUT_ASYNC, LPDWORD()) 161 DDE.FreeStringHandle(self._idInst, hszItem) 162 if not hDdeData: 163 raise DDEError("Unable to %s advise" % ("stop" if stop else "start"), self._idInst) 164 DDE.FreeDataHandle(hDdeData)
Request updates when DDE data changes.
def
execute(self, command, timeout=5000):
166 def execute(self, command, timeout=5000): 167 """Execute a DDE command.""" 168 pData = c_char_p(command) 169 cbData = DWORD(len(command) + 1) 170 hDdeData = DDE.ClientTransaction(pData, cbData, self._hConv, HSZ(), CF_TEXT, XTYP_EXECUTE, timeout, LPDWORD()) 171 if not hDdeData: 172 raise DDEError("Unable to send command", self._idInst) 173 DDE.FreeDataHandle(hDdeData)
Execute a DDE command.
def
request(self, item, timeout=5000):
175 def request(self, item, timeout=5000): 176 """Request data from DDE service.""" 177 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 178 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_REQUEST, timeout, LPDWORD()) 179 DDE.FreeStringHandle(self._idInst, hszItem) 180 if not hDdeData: 181 raise DDEError("Unable to request item", self._idInst) 182 183 if timeout != TIMEOUT_ASYNC: 184 pdwSize = DWORD(0) 185 pData = DDE.AccessData(hDdeData, byref(pdwSize)) 186 if not pData: 187 DDE.FreeDataHandle(hDdeData) 188 raise DDEError("Unable to access data", self._idInst) 189 # TODO: use pdwSize 190 DDE.UnaccessData(hDdeData) 191 DDE.FreeDataHandle(hDdeData) 192 return pData
Request data from DDE service.
def
WinMSGLoop():
209def WinMSGLoop(): 210 """Run the main windows message loop.""" 211 LPMSG = POINTER(MSG) 212 LRESULT = c_ulong 213 GetMessage = get_winfunc("user32", "GetMessageW", BOOL, (LPMSG, HWND, UINT, UINT)) 214 TranslateMessage = get_winfunc("user32", "TranslateMessage", BOOL, (LPMSG,)) 215 # restype = LRESULT 216 DispatchMessage = get_winfunc("user32", "DispatchMessageW", LRESULT, (LPMSG,)) 217 218 msg = MSG() 219 lpmsg = byref(msg) 220 while GetMessage(lpmsg, HWND(), 0, 0) > 0: 221 TranslateMessage(lpmsg) 222 DispatchMessage(lpmsg)
Run the main windows message loop.