win 0.1.2 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.9
data/lib/win/dde.rb CHANGED
@@ -10,15 +10,53 @@ module Win
10
10
  # Windows ANSI codepage:
11
11
  CP_WINANSI = 1004
12
12
 
13
- #
13
+ # DDE name service afCmd commands used by DdeNameService function:
14
+
15
+ # Registers the service name.
16
+
14
17
  DNS_REGISTER = 1
18
+ # Unregisters the service name. If the hsz1 parameter is 0L, ALL service names registered by the server will be
19
+ # unregistered.
15
20
  DNS_UNREGISTER = 2
21
+ # Turns on service name initiation filtering. The filter prevents a server from receiving
22
+ # XTYP_CONNECT transactions for service names it has not registered. This is the default
23
+ # setting for this filter. If a server application does not register any service names,
24
+ # the application cannot receive XTYP_WILDCONNECT transactions.
25
+ DNS_FILTERON = 4
26
+ # Turns off service name initiation filtering. If this flag is specified, the server
27
+ # receives an XTYP_CONNECT transaction whenever another DDE application calls the
28
+ # DdeConnect function, regardless of the service name.
29
+ DNS_FILTEROFF = 8
16
30
 
31
+ # Transaction types:
32
+
33
+ # A client uses the XTYP_CONNECT transaction to establish a conversation. A DDE server callback function,
34
+ # DdeCallback, receives this transaction when a client specifies a service name that the server supports
35
+ # (and a topic name that is not NULL) in a call to the DdeConnect function.
17
36
  XTYP_CONNECT = 0x60
18
37
  XTYP_DISCONNECT = 0xC0
38
+
39
+ # A client uses the XTYP_POKE transaction to send unsolicited data to the server. DDE server callback function,
40
+ # DdeCallback, receives this transaction when a client specifies XTYP_POKE in the DdeClientTransaction function.
19
41
  XTYP_POKE = 0x90
20
42
  XTYP_ERROR = 0x00
21
43
 
44
+ # Transaction confirmations:
45
+
46
+ # Transaction confirmation
47
+ DDE_FACK = 0x8000
48
+ # Server is too busy to process transaction
49
+ DDE_FBUSY = 0x4000
50
+ DDE_FDEFERUPD = 0x4000
51
+ DDE_FACKREQ = 0x8000
52
+ DDE_FRELEASE = 0x2000
53
+ DDE_FREQUESTED = 0x1000
54
+ DDE_FAPPSTATUS = 0x00ff
55
+ # Transaction rejected
56
+ DDE_FNOTPROCESSED = 0
57
+
58
+ # DdeInitialize afCmd flaggs:
59
+
22
60
  # Registers the application as a standard (nonmonitoring) DDEML application.
23
61
  APPCLASS_STANDARD = 0
24
62
  # Makes it possible for the application to monitor DDE activity in the system.
@@ -87,14 +125,41 @@ module Win
87
125
  MF_CONV = 0x40000000
88
126
  # ?
89
127
  MF_MASK = 0xFF000000
128
+
129
+ # Error codes:
130
+
90
131
  # Returned if DDE Init successful
91
132
  DMLERR_NO_ERROR = 0x00
92
- # Returned if DDE Init failed due to wrong DLL usage
133
+ # An application initialized as APPCLASS_MONITOR has attempted to perform a Dynamic Data Exchange (DDE) transaction,
134
+ # or an application initialized as APPCMD_CLIENTONLY has attempted to perform server transactions.
93
135
  DMLERR_DLL_USAGE = 0x4004
94
- # Returned if DDE Init failed due to invalid params
136
+ # DMLERR_INVALIDPARAMETER A parameter failed to be validated by the DDEML. Some of the possible causes follow:
137
+ # - The application used a data handle initialized with a different item name handle than was required by the
138
+ # transaction.
139
+ # - The application used a data handle that was initialized with a different clipboard data format than was
140
+ # required by the transaction.
141
+ # - The application used a client-side conversation handle with a server-side function or vice versa.
142
+ # - The application used a freed data handle or string handle.
143
+ # - More than one instance of the application used the same object.
95
144
  DMLERR_INVALIDPARAMETER = 0x4006
96
- # Returned if DDE Init failed due to system error
145
+ # DMLERR_SYS_ERROR An internal error has occurred in the DDEML.
97
146
  DMLERR_SYS_ERROR = 0x400f
147
+ # DMLERR_ADVACKTIMEOUT A request for a synchronous advise transaction has timed out.
148
+ # DMLERR_BUSY The response to the transaction caused the DDE_FBUSY flag to be set.
149
+ # DMLERR_DATAACKTIMEOUT A request for a synchronous data transaction has timed out.
150
+ # DMLERR_DLL_NOT_INITIALIZED A DDEML function was called without first calling the DdeInitialize function, or an invalid instance identifier was passed to a DDEML function.
151
+ # DMLERR_DLL_USAGE
152
+ # DMLERR_EXECACKTIMEOUT A request for a synchronous execute transaction has timed out.
153
+ # DMLERR_LOW_MEMORY A DDEML application has created a prolonged race condition (in which the server application outruns the client), causing large amounts of memory to be consumed.
154
+ # DMLERR_MEMORY_ERROR A memory allocation has failed.
155
+ # DMLERR_NO_CONV_ESTABLISHED A client's attempt to establish a conversation has failed.
156
+ # DMLERR_NOTPROCESSED A transaction has failed.
157
+ # DMLERR_POKEACKTIMEOUT A request for a synchronous poke transaction has timed out.
158
+ # DMLERR_POSTMSG_FAILED An internal call to the PostMessage function has failed.
159
+ # DMLERR_REENTRANCY An application instance with a synchronous transaction already in progress attempted to initiate another synchronous transaction, or the DdeEnableCallback function was called from within a DDEML callback function.
160
+ # DMLERR_SERVER_DIED A server-side transaction was attempted on a conversation terminated by the client, or the server terminated before completing a transaction.
161
+ # DMLERR_UNADVACKTIMEOUT A request to end an advise transaction has timed out.
162
+ # DMLERR_UNFOUND_QUEUE_ID An invalid transaction identifier was passed to a DDEML function. Once the application has returned from an XTYP_XACT_COMPLETE callback, the transaction identifier for that callback function is no longer valid.
98
163
 
99
164
  ##
100
165
  # The RegisterClipboardFormat function registers a new clipboard format.
@@ -116,7 +181,7 @@ module Win
116
181
  # form of an HGLOBAL value.
117
182
  #
118
183
  # :call-seq:
119
- # register_clipboard_format( format_name )
184
+ # format_id = register_clipboard_format( format_name )
120
185
  #
121
186
  function :RegisterClipboardFormat, [:pointer], :uint, zeronil: true
122
187
 
@@ -135,7 +200,22 @@ module Win
135
200
  # - XCLASS_BOOL - A DDE callback function should return TRUE or FALSE when it finishes processing a
136
201
  # transaction that belongs to this class. The XCLASS_BOOL class consists of the following types:
137
202
  # - XTYP_ADVSTART
138
- # - XTYP_CONNECT
203
+ # - *XTYP_CONNECT*: A client uses the XTYP_CONNECT transaction to establish a conversation.
204
+ # hsz1:: Handle to the topic name.
205
+ # hsz2:: Handle to the service name.
206
+ # dwData1:: Pointer to a CONVCONTEXT structure that contains context information for the conversation.
207
+ # If the client is not a Dynamic Data Exchange Management Library (DDEML) application,
208
+ # this parameter is 0.
209
+ # dwData2:: Specifies whether the client is the same application instance as the server. If the
210
+ # parameter is 1, the client is the same instance. If the parameter is 0, the client
211
+ # is a different instance.
212
+ # *Returns*:: A server callback function should return TRUE to allow the client to establish a
213
+ # conversation on the specified service name and topic name pair, or the function
214
+ # should return FALSE to deny the conversation. If the callback function returns TRUE
215
+ # and a conversation is successfully established, the system passes the conversation
216
+ # handle to the server by issuing an XTYP_CONNECT_CONFIRM transaction to the server's
217
+ # callback function (unless the server specified the CBF_SKIP_CONNECT_CONFIRMS flag
218
+ # in the DdeInitialize function).
139
219
  # - XCLASS_DATA - A DDE callback function should return a DDE handle, the CBR_BLOCK return code, or
140
220
  # NULL when it finishes processing a transaction that belongs to this class. The XCLASS_DATA
141
221
  # transaction class consists of the following types:
@@ -147,7 +227,15 @@ module Win
147
227
  # class consists of the following types:
148
228
  # - XTYP_ADVDATA
149
229
  # - XTYP_EXECUTE
150
- # - XTYP_POKE
230
+ # - *XTYP_POKE*: A client uses the XTYP_POKE transaction to send unsolicited data to the server.
231
+ # uFmt:: Specifies the format of the data sent from the server.
232
+ # hconv:: Handle to the conversation.
233
+ # hsz1:: Handle to the topic name.
234
+ # hsz2:: Handle to the item name.
235
+ # hdata:: Handle to the data that the client is sending to the server.
236
+ # *Returns*:: A server callback function should return the DDE_FACK flag if it processes this
237
+ # transaction, the DDE_FBUSY flag if it is too busy to process this transaction,
238
+ # or the DDE_FNOTPROCESSED flag if it rejects this transaction.
151
239
  # - XCLASS_NOTIFICATION - The transaction types that belong to this class are for notification purposes
152
240
  # only. The return value from the callback function is ignored. The XCLASS_NOTIFICATION transaction
153
241
  # class consists of the following types:
@@ -217,6 +305,11 @@ module Win
217
305
  # - DMLERR_INVALIDPARAMETER
218
306
  # - DMLERR_SYS_ERROR
219
307
  # ---
308
+ # <b> Enhanced API accepts only 2 parameters (get rid of reserved hsz2):
309
+ # instance_id:: (optional) Application instance identifier. At initialization, this parameter should be 0, nil
310
+ # or omitted altogether. If it is nonzero/non-nil, reinitialization of the DDEML is implied.
311
+ # cmd(afCmd):: obligatory set of flags
312
+ # ---
220
313
  # *Remarks*:
221
314
  # - An application that uses multiple instances of the DDEML must not pass DDEML objects between instances.
222
315
  # - A DDE monitoring application should not attempt to perform DDE operations (establish conversations,
@@ -231,19 +324,38 @@ module Win
231
324
  # value for the iCodePage member of the CONVCONTEXT structure (CP_WINANSI or CP_WINUNICODE).
232
325
  #
233
326
  # :call-seq:
234
- # instance_id, status = dde_initialize( instance_id = 0, cmd )
327
+ # instance_id, status = dde_initialize( [instance_id = 0], cmd )
235
328
  # {|type, format, hconv, hsz1, hsz2, hdata, data1, data2| your dde_callback block}
236
329
  #
237
- function :DdeInitialize, [:pointer, :DdeCallback, :DWORD, :DWORD], :uint,
330
+ function :DdeInitialize, [:pointer, :DdeCallback, :uint32, :uint32], :uint,
238
331
  &->(api, old_id=0, cmd, &block){
239
332
  raise ArgumentError, 'No callback block' unless block
240
- id = FFI::MemoryPointer.new(:long)
241
- id.write_long(old_id)
333
+ old_id = 0 unless old_id
334
+ id = FFI::MemoryPointer.new(:long).write_long(old_id)
242
335
  status = api.call(id, block, cmd, 0)
243
336
  id = status == 0 ? id.read_long() : nil
244
337
  [id, status] }
245
338
  # weird lambda literal instead of block is needed because RDoc goes crazy if block is attached to meta-definition
246
339
 
340
+ ##
341
+ # The DdeUninitialize function frees all Dynamic Data Exchange Management Library (DDEML) resources associated
342
+ # with the calling application.
343
+ #
344
+ # [*Syntax*] BOOL DdeUninitialize( DWORD idInst);
345
+ #
346
+ # idInst:: [in] Specifies the application instance identifier obtained by a previous call to the DdeInitialize.
347
+ # *Returns*:: If the function succeeds, the return value is nonzero.
348
+ # If the function fails, the return value is zero.
349
+ # ---
350
+ # *Remarks*
351
+ # DdeUninitialize terminates any conversations currently open for the application.
352
+ #
353
+ # :call-seq:
354
+ # success = dde_uninitialize( instance_id )
355
+ #
356
+ function :DdeUninitialize, [:uint32], :int, boolean: true
357
+
358
+
247
359
  ##
248
360
  # The DdeCreateStringHandle function creates a handle that identifies the specified string.
249
361
  # A Dynamic Data Exchange (DDE) client or server application can pass the string handle as a
@@ -265,6 +377,8 @@ module Win
265
377
  # The DdeGetLastError function can be used to get the error code, which can be one of the
266
378
  # following values: DMLERR_NO_ERROR, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
267
379
  # ---
380
+ # <b> Enhanced (snake_case) API makes code_page param optional and returns *nil* if handle creation fails. </b>
381
+ # ---
268
382
  # *Remarks*: The value of a string handle is not related to the case of the string it identifies.
269
383
  # When an application either creates a string handle or receives one in the callback function
270
384
  # and then uses the DdeKeepStringHandle function to keep it, the application must free that string
@@ -274,7 +388,219 @@ module Win
274
388
  # :call-seq:
275
389
  # string_handle = dde_create_string_handle( instance_id, string, code_page_id )
276
390
  #
277
- function :DdeCreateStringHandle, [:DWORD, :pointer, :int], :HSZ, zeronil: true
391
+ function :DdeCreateStringHandle, [:uint32, :pointer, :int], :ulong, zeronil: true,
392
+ &->(api, instance_id, string, code_page=CP_WINANSI){ api.call(instance_id, string, code_page) }
393
+
394
+ ##
395
+ # The DdeFreeStringHandle function frees a string handle in the calling application.
396
+ #
397
+ # [*Syntax*] BOOL DdeFreeStringHandle( DWORD idInst, HSZ hsz );
398
+ #
399
+ # idInst:: [in] Specifies the application instance identifier obtained by a previous call to the DdeInitialize.
400
+ # hsz:: [in, out] Handle to the string handle to be freed. This handle must have been created by a previous call
401
+ # to the DdeCreateStringHandle function.
402
+ # *Returns*:: If the function succeeds, the return value is nonzero. If the function fails, it is zero.
403
+ # ---
404
+ # <b> Enhanced snake_case API returns boolean true/false as a success indicator. </b>
405
+ # ---
406
+ # *Remarks*:
407
+ # An application can free string handles it creates with DdeCreateStringHandle but should not free those that
408
+ # the system passed to the application's Dynamic Data Exchange (DDE) callback function or those returned in the
409
+ # CONVINFO structure by the DdeQueryConvInfo function.
410
+ #
411
+ # :call-seq:
412
+ # success = dde_free_string_handle( instance_id, string_handle )
413
+ #
414
+ function :DdeFreeStringHandle, [:uint32, :ulong], :int, boolean: true
415
+
416
+ ##
417
+ # The DdeQueryString function copies text associated with a string handle into a buffer.
418
+ #
419
+ # [*Syntax*] DWORD DdeQueryString( DWORD idInst, HSZ hsz, LPTSTR psz, DWORD cchMax, int iCodePage);
420
+ #
421
+ # idInst:: [in] Specifies the application instance identifier obtained by a previous call to the DdeInitialize.
422
+ # hsz:: [in] Handle to the string to copy. This handle must have been created by a previous call to the
423
+ # DdeCreateStringHandle function.
424
+ # psz:: [in, out] Pointer to a buffer that receives the string. To obtain the length of the string, this parameter
425
+ # should be set to NULL.
426
+ # cchMax:: [in] Specifies the length, in TCHARs, of the buffer pointed to by the psz parameter. For the ANSI
427
+ # version of the function, this is the number of bytes; for the Unicode version, this is the number of
428
+ # characters. If the string is longer than ( cchMax– 1), it will be truncated. If the psz parameter is
429
+ # set to NULL, this parameter is ignored.
430
+ # iCodePage:: [in] Code page used to render the string. This value should be either CP_WINANSI or CP_WINUNICODE.
431
+ #
432
+ # *Returns*:: If the psz parameter specified a valid pointer, the return value is the length, in TCHARs, of the
433
+ # returned text (not including the terminating null character). If the psz parameter specified a NULL
434
+ # pointer, the return value is the length of the text associated with the hsz parameter (not including
435
+ # the terminating null character). If an error occurs, the return value is 0L.
436
+ # ---
437
+ # <b> Enhanced (snake_case) API makes all args optional except for first (dde instance id), and returns nil if
438
+ # the function was unsuccessful.</b>
439
+ # ---
440
+ # *Remarks*
441
+ # - The string returned in the buffer is always null-terminated. If the string is longer than ( cchMax– 1),
442
+ # only the first ( cchMax– 1) characters of the string are copied.
443
+ # - If the psz parameter is NULL, the DdeQueryString function obtains the length, in bytes, of the string
444
+ # associated with the string handle. The length does not include the terminating null character.
445
+ #
446
+ # :call-seq:
447
+ # string = dde_query_string( instance_id, handle, [code_page = CP_WINANSI ] )
448
+ #
449
+ function :DdeQueryString, [:uint32, :ulong, :pointer, :uint32, :int], :uint32,
450
+ &->(api, instance_id, handle, code_page = CP_WINANSI){
451
+ buffer = FFI::MemoryPointer.new :char, 1024
452
+ num_chars = api.call(instance_id, handle, buffer, buffer.size, code_page)
453
+ num_chars == 0 ? nil : buffer.get_bytes(0, num_chars) }
454
+
455
+ ##
456
+ # The DdeNameService function registers or unregisters the service names a Dynamic Data Exchange (DDE) server
457
+ # supports. This function causes the system to send XTYP_REGISTER or XTYP_UNREGISTER transactions to other running
458
+ # Dynamic Data Exchange Management Library (DDEML) client applications.
459
+ #
460
+ # [*Syntax*] HDDEDATA DdeNameService( DWORD idInst, UINT hsz1, UINT hsz2, UINT afCmd );
461
+ #
462
+ # idInst:: [in] Specifies the application instance identifier obtained by a previous call to the DdeInitialize.
463
+ # hsz1:: [in] Handle to the string that specifies the service name the server is registering or unregistering.
464
+ # An application that is unregistering all of its service names should set this parameter to 0L.
465
+ # hsz2:: Reserved; should be set to 0L.
466
+ # afCmd:: [in] Specifies the service name options. This parameter can be one of the following values.
467
+ # DNS_REGISTER:: Registers the service name.
468
+ # DNS_UNREGISTER:: Unregisters the service name. If the hsz1 parameter is 0L,
469
+ # all service names registered by the server will be unregistered.
470
+ # DNS_FILTERON:: Turns on service name initiation filtering. The filter prevents a server from receiving
471
+ # XTYP_CONNECT transactions for service names it has not registered. This is the default
472
+ # setting for this filter. If a server application does not register any service names,
473
+ # the application cannot receive XTYP_WILDCONNECT transactions.
474
+ # DNS_FILTEROFF:: Turns off service name initiation filtering. If this flag is specified, the server
475
+ # receives an XTYP_CONNECT transaction whenever another DDE application calls the
476
+ # DdeConnect function, regardless of the service name.
477
+ # *Returns*:: If the function succeeds, it returns nonzero (*true* in snake_case method). For CamelCase, that
478
+ # value is not really HDDEDATA value, but merely a Boolean indicator of success. The function is
479
+ # typed HDDEDATA to allow for future expansion of the function and more sophisticated returns.
480
+ # If the function fails, the return value is 0L (*false* in snake_case method). The DdeGetLastError
481
+ # function can be used to get the error code, which can be one of the following:
482
+ # - DMLERR_DLL_NOT_INITIALIZED
483
+ # - DMLERR_DLL_USAGE
484
+ # - DMLERR_INVALIDPARAMETER
485
+ # - DMLERR_NO_ERROR
486
+ # ---
487
+ # <b> Enhanced API accepts only 3 parameters (get rid of reserved hsz2) and returns boolean true/false. </b>
488
+ # ---
489
+ # *Remarks*:
490
+ # The service name identified by the hsz1 parameter should be a base name (that is, the name should contain no
491
+ # instance-specific information). The system generates an instance-specific name and sends it along with the
492
+ # base name during the XTYP_REGISTER and XTYP_UNREGISTER transactions. The receiving applications can then
493
+ # connect to the specific application instance.
494
+ #
495
+ # :call-seq:
496
+ # success = dde_name_service( instance_id, string_handle, cmd )
497
+ #
498
+ function :DdeNameService, [:uint32, :ulong, :ulong, :uint], :ulong,
499
+ &->(api, id, string_handle, cmd){ api.call(id, string_handle, 0, cmd) != 0 }
500
+ # weird lambda literal instead of block is needed because RDoc goes crazy if block is attached to meta-definition
501
+
502
+ ##
503
+ # The DdeGetData function copies data from the specified Dynamic Data Exchange (DDE) object to the specified
504
+ # local buffer.
505
+ #
506
+ # [*Syntax*] DWORD DdeGetData( HDDEDATA hData, LPBYTE pDst, DWORD cbMax, DWORD cbOff );
507
+ #
508
+ # hData:: [in] Handle to the DDE object that contains the data to copy.
509
+ # pDst:: [out] Pointer to the buffer that receives the data. If this parameter is NULL, the DdeGetData
510
+ # function returns the amount of data, in bytes, that would be copied to the buffer.
511
+ # cbMax:: [in] Specifies the maximum amount of data, in bytes, to copy to the buffer pointed to by the pDst
512
+ # parameter. Typically, this parameter specifies the length of the buffer pointed to by pDst.
513
+ # cbOff:: [in] Specifies an offset within the DDE object. Data is copied from the object beginning at this offset.
514
+ #
515
+ # *Returns*:: If the pDst parameter points to a buffer, return value is the size, in bytes, of the memory object
516
+ # associated with the data handle or the size specified in the cbMax parameter, whichever is lower.
517
+ # If the pDst parameter is NULL, the return value is the size, in bytes, of the memory object
518
+ # associated with the data handle.
519
+ # The DdeGetLastError function can be used to get the error code, which can be one of the following:
520
+ # - DMLERR_DLL_NOT_INITIALIZED
521
+ # - DMLERR_INVALIDPARAMETER
522
+ # - DMLERR_NO_ERROR
523
+ # ---
524
+ # <b> Enhanced (snake_case) API accepts only data handle, and optionally max and offset (no need to pre-allocate
525
+ # buffer). It returns buffer with copied DDE data (FFI::MemoryPointer) or nil for failure. DDE data length is
526
+ # determined internally, no need to call function twice (first time with nil buffer just to determine length).</b>
527
+ # ---
528
+ #
529
+ # :call-seq:
530
+ # buffer, success = dde_get_data( data_handle, [max = infinite, offset = 0] )
531
+ #
532
+ function :DdeGetData, [:ulong, :pointer, :uint32, :uint32], :uint,
533
+ &->(api, data_handle, max=1073741823, offset=0){ # max is maximum DWORD Fixnum
534
+ length = api.call(data_handle, nil, 0, 0) # determining data set length
535
+ if length != 0
536
+ copy_length = length < max ? length : max
537
+ buffer = FFI::MemoryPointer.new(:char, offset + copy_length)
538
+ length = api.call(data_handle, buffer, copy_length, offset)
539
+ end
540
+ length != 0 ? buffer: nil }
541
+ # weird lambda literal instead of block is needed because RDoc goes crazy if block is attached to meta-definition
542
+
543
+ ##
544
+ # DdeConnect function establishes a conversation with a server application that supports the specified service
545
+ # name and topic name pair. If more than one such server exists, the system selects only one.
546
+ #
547
+ # [*Syntax*] HCONV DdeConnect( DWORD idInst, HSZ hszService, HSZ hszTopic, PCONVCONTEXT pCC );
548
+ #
549
+ # idInst:: [in] Specifies the application instance identifier obtained by a previous call to the DdeInitialize.
550
+ # hszService:: [in] Handle to the string that specifies the service name of the server application with which
551
+ # a conversation is to be established. This handle must have been created by a previous call to
552
+ # the DdeCreateStringHandle function. If this parameter is 0L, a conversation is established with
553
+ # any available server.
554
+ # hszTopic:: [in] Handle to the string that specifies the name of the topic on which a conversation is to be
555
+ # established. This handle must have been created by a previous call to DdeCreateStringHandle.
556
+ # If this parameter is 0L, a conversation on any topic supported by the selected server is established.
557
+ # pCC:: [in] Pointer to the CONVCONTEXT structure that contains conversation context information. If this
558
+ # parameter is NULL, the server receives the default CONVCONTEXT structure during the XTYP_CONNECT
559
+ # or XTYP_WILDCONNECT transaction.
560
+ # *Returns*:: If the function succeeds, the return value is the handle to the established conversation.
561
+ # If the function fails, the return value is 0L. The DdeGetLastError function can be used to get
562
+ # the error code, which can be one of the following values:
563
+ # - DMLERR_DLL_NOT_INITIALIZED
564
+ # - DMLERR_INVALIDPARAMETER
565
+ # - DMLERR_NO_CONV_ESTABLISHED
566
+ # - DMLERR_NO_ERROR
567
+ # ---
568
+ # <b> Enhanced (snake_case) API makes all args optional except for first (dde instance id), and returns nil if
569
+ # the function was unsuccessful.</b>
570
+ # ---
571
+ # *Remarks*
572
+ # - The client application cannot make assumptions regarding the server selected. If an instance-specific name
573
+ # is specified in the hszService parameter, a conversation is established with only the specified instance.
574
+ # Instance-specific service names are passed to an application's Dynamic Data Exchange (DDE) callback function
575
+ # during the XTYP_REGISTER and XTYP_UNREGISTER transactions.
576
+ # - All members of the default CONVCONTEXT structure are set to zero except cb, which specifies the size of the
577
+ # structure, and iCodePage, which specifies CP_WINANSI (the default code page) or CP_WINUNICODE, depending on
578
+ # whether the ANSI or Unicode version of the DdeInitialize function was called by the client application.
579
+ #
580
+ # :call-seq:
581
+ # conversation_handle = dde_connect( instance_id, [service = nil, topic = nil, context = nil] )
582
+ #
583
+ function :DdeConnect, [:uint32, :ulong, :ulong, :pointer], :ulong, zeronil: true,
584
+ &->(api, instance_id, service = nil, topic = nil, context = nil){
585
+ api.call(instance_id, service, topic, context) }
586
+
587
+ ##
588
+ # The DdeGetLastError function retrieves the most recent error code set by the failure of a Dynamic Data Exchange
589
+ # Management Library (DDEML) function and resets the error code to DMLERR_NO_ERROR.
590
+ #
591
+ # [*Syntax*] UINT DdeGetLastError( DWORD idInst );
592
+ #
593
+ # idInst:: [in] Specifies the application instance identifier obtained by a previous call to the DdeInitialize.
594
+ #
595
+ # *Returns*:: If the function succeeds, the return value is the last error code, which can be one of the following:
596
+ # DMLERR_ADVACKTIMEOUT, DMLERR_EXECACKTIMEOUT, DMLERR_INVALIDPARAMETER, DMLERR_LOW_MEMORY, DMLERR_MEMORY_ERROR,
597
+ # DMLERR_NO_CONV_ESTABLISHED, DMLERR_NOTPROCESSED, DMLERR_POKEACKTIMEOUT, DMLERR_POSTMSG_FAILED, DMLERR_REENTRANCY,
598
+ # DMLERR_SERVER_DIED, DMLERR_SYS_ERROR, DMLERR_UNADVACKTIMEOUT, DMLERR_UNFOUND_QUEUE_ID
599
+ #
600
+ # :call-seq:
601
+ # string = dde_get_last_error( instance_id )
602
+ #
603
+ function :DdeGetLastError, [:uint32], :int, zeronil: true
278
604
 
279
605
  end
280
606
  end
data/lib/win/gui/input.rb CHANGED
@@ -251,7 +251,7 @@ module Win
251
251
  # Y:: [in] Specifies the new y-coordinate of the cursor, in screen coordinates.
252
252
  #
253
253
  # *Returns*:: Nonzero(*true*) if successful or zero(*false*) otherwise. To get extended error information,
254
- # call GetLastError. Enhanced to return true/false instead of nonzero/zero
254
+ # call GetLastError. Enhanced to return true/false instead of nonzero/zero
255
255
  # ---
256
256
  # *Remarks*: The cursor is a shared resource. A window should move the cursor only when the cursor is in the
257
257
  # window's client area. The calling process must have WINSTA_WRITEATTRIBUTES access to the window station.
@@ -235,7 +235,7 @@ module Win
235
235
  # App-specific (non-reserved) messages above this one (WM_App+1, etc...)
236
236
  WM_APP = 0x8000
237
237
 
238
- # Sys Commands:
238
+ # Sys Commands:
239
239
 
240
240
  #
241
241
  SC_SIZE = 0xF000
@@ -259,26 +259,67 @@ module Win
259
259
  SC_MONITORPOWER = 0xF170
260
260
  SC_CONTEXTHELP = 0xF180
261
261
 
262
+ ##
262
263
  function :BroadcastSystemMessage, 'LPIIL', 'L'
264
+
265
+ ##
263
266
  function :DefWindowProc, 'LLLL', 'L'
267
+
268
+ ##
264
269
  function :DispatchMessage, 'P', 'L'
270
+
271
+ ##
265
272
  function :GetInputState, 'V', 'B'
273
+
274
+ ##
266
275
  function :GetMessage, 'PLII', 'B'
276
+
277
+ ##
267
278
  function :GetMessageExtraInfo, 'V', 'L'
279
+
280
+ ##
268
281
  function :GetMessagePos, 'V', 'L'
282
+
283
+ ##
269
284
  function :GetMessageTime, 'V', 'L'
285
+
286
+ ##
270
287
  function :GetQueueStatus, 'I', 'L'
288
+
289
+ ##
271
290
  function :InSendMessage, 'V', 'B'
291
+
292
+ ##
272
293
  function :InSendMessageEx, 'L', 'L'
294
+
295
+ ##
273
296
  function :PeekMessage, 'PLIII', 'B'
297
+
298
+ ##
274
299
  function :PostQuitMessage, 'I', 'V'
300
+
301
+ ##
275
302
  function :PostThreadMessage, 'LILL', 'B'
303
+
304
+ ##
276
305
  function :RegisterWindowMessage, 'P', 'I'
306
+
307
+ ##
277
308
  function :ReplyMessage, 'L', 'B'
309
+
310
+ ##
278
311
  function :SendMessageTimeout, 'LILLIIP', 'L'
312
+
313
+ ##
279
314
  function :SendNotifyMessage, 'LILLIIP', 'L'
315
+
316
+ ##
280
317
  function :SetMessageExtraInfo, 'L', 'L'
318
+
319
+ ##
281
320
  function :TranslateMessage, 'P', 'B'
321
+
322
+ ##
282
323
  function :WaitMessage, 'V', 'B'
283
324
 
284
325
  ##
@@ -296,7 +337,7 @@ module Win
296
337
  # lResult:: [in] Specifies the result of the message processing. This value depends on the message.
297
338
  #
298
339
  # :call-seq:
299
- # SendAsyncProc callback block: {|handle, msg, w_param, l_param| your code }
340
+ # SendAsyncProc callback block: {|handle, msg, data, l_result| your callbackcode }
300
341
  #
301
342
  callback :SendAsyncProc, [:long, :uint, :ulong, :ulong, :long], :void
302
343
 
@@ -334,7 +375,11 @@ module Win
334
375
  # - The callback function is called only when the thread that called SendMessageCallback also calls GetMessage,
335
376
  # PeekMessage, or WaitMessage.
336
377
  #
337
- function :SendMessageCallback, [:long, :uint, :uint, :long, :SendAsyncProc, :ulong], :bool
378
+ # :call-seq:
379
+ # success = send_message_callback(handle, msg, w_param, l_param, data)
380
+ # {|handle, msg, data, l_result| callback code }
381
+ #
382
+ function :SendMessageCallback, [:long, :uint, :uint, :long, :SendAsyncProc, :ulong], :int, boolean: true
338
383
 
339
384
  ##
340
385
  # The PostMessage function places (posts) a message in the message queue associated with the thread that
@@ -343,14 +388,14 @@ module Win
343
388
  #
344
389
  # [*Syntax*] BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
345
390
  #
346
- # handle:: [in] Handle to the window whose window procedure will receive the message. If this parameter is
391
+ # hWnd:: [in] Handle to the window whose window procedure will receive the message. If this parameter is
347
392
  # HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or
348
393
  # invisible unowned windows, overlapped windows, and pop-up windows; but the message is not posted to
349
394
  # child windows. If it is NULL, the function behaves like a call to PostThreadMessage()
350
395
  # with the dwThreadId parameter set to the identifier of the current thread.
351
- # msg:: [in] Specifies the message to be posted.
352
- # w_param:: [in] Specifies additional message-specific information.
353
- # l_param:: [in] Specifies additional message-specific information.
396
+ # Msg:: [in] Specifies the message to be posted.
397
+ # wParam:: [in] Specifies additional message-specific information.
398
+ # lParam:: [in] Specifies additional message-specific information.
354
399
  #
355
400
  # *Returns*:: Nonzero if the function succeeds, zero if it fails. For extended error info, call GetLastError.
356
401
  # ---
@@ -371,10 +416,50 @@ module Win
371
416
  #:call-seq:
372
417
  # success = post_message(handle, msg, w_param, l_param)
373
418
  #
374
- function :PostMessage, [:ulong, :uint, :long, :uint], :bool
375
-
376
- function :SendMessage, 'LLLP', 'L'
419
+ function :PostMessage, [:ulong, :uint, :long, :uint], :int, boolean: true
377
420
 
421
+ ##
422
+ # The SendMessage function sends the specified message to a window or windows. It calls the window procedure for
423
+ # the specified window and does not return until the window procedure has processed the message.
424
+ #
425
+ # To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a
426
+ # message to a thread's message queue and return immediately, use the PostMessage or PostThreadMessage function.
427
+ #
428
+ #
429
+ # [*Syntax*] LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
430
+ #
431
+ # hWnd:: [in] Handle to the window whose window procedure will receive the message. If this parameter is
432
+ # HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or
433
+ # invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to
434
+ # child windows.
435
+ # Microsoft Windows Vista and later. Message sending is subject to User Interface Privilege Isolation
436
+ # (UIPI). The thread of a process can send messages only to message queues of threads in processes of
437
+ # lesser or equal integrity level.
438
+ # Msg:: [in] Specifies the message to be sent.
439
+ # wParam:: [in] Specifies additional message-specific information.
440
+ # lParam:: [in/out?] Specifies additional message-specific information.
441
+ #
442
+ # *Return*:: The return value specifies the result of the message processing; it depends on the message sent.
443
+ # ---
444
+ # *Remarks*:
445
+ # - Microsoft Windows Vista and later. When a message is blocked by UIPI the last error, retrieved with
446
+ # GetLastError, is set to 5 (access denied).
447
+ # - Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function
448
+ # to obtain a unique message for inter-application communication.
449
+ # - The system only does marshalling for system messages (those in the range 0 to (WM_USER-1)). To send other
450
+ # messages (those >= WM_USER) to another process, you must do custom marshalling.
451
+ # - If the specified window was created by the calling thread, the window procedure is called immediately as
452
+ # a subroutine. If the specified window was created by a different thread, the system switches to that thread
453
+ # and calls the appropriate window procedure. Messages sent between threads are processed only when the
454
+ # receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread
455
+ # processes the message. However, the sending thread will process incoming nonqueued messages while waiting
456
+ # for its message to be processed. To prevent this, use SendMessageTimeout with SMTO_BLOCK set. For more
457
+ # information on nonqueued messages, see Nonqueued Messages.
458
+ #
459
+ #:call-seq:
460
+ # send_message(handle, msg, w_param, l_param)
461
+ #
462
+ function :SendMessage, [:ulong, :uint, :long, :pointer], :int # LPARAM different from PostMessage!
378
463
 
379
464
  end
380
465
  end
@@ -394,8 +394,7 @@ module Win
394
394
  function :GetWindowThreadProcessId, [:ulong, :pointer], :long,
395
395
  &->(api, *args) {
396
396
  namespace.enforce_count( args, api.prototype, -1)
397
- process = FFI::MemoryPointer.new(:long)
398
- process.write_long(1)
397
+ process = FFI::MemoryPointer.new(:long).write_long(1)
399
398
  thread = api.call(args.first, process)
400
399
  thread == 0 ? [nil, nil] : [thread, process.read_long()] }
401
400
  # weird lambda literal instead of normal block is needed because current version of RDoc
@@ -429,7 +428,7 @@ module Win
429
428
  &->(api, *args) {
430
429
  namespace.enforce_count( args, api.prototype, -1)
431
430
  rect = FFI::MemoryPointer.new(:long, 4)
432
- rect.write_array_of_long([0, 0, 0, 0])
431
+ #rect.write_array_of_long([0, 0, 0, 0])
433
432
  res = api.call args.first, rect
434
433
  res == 0 ? [nil, nil, nil, nil] : rect.read_array_of_long(4) }
435
434
  # weird lambda literal instead of normal block is needed because current version of RDoc
data/lib/win/library.rb CHANGED
@@ -75,7 +75,7 @@ module Win
75
75
  c: :char, # 8-bit character (byte)
76
76
  # :int8 – 8-bit signed integer
77
77
  # :uint8 – 8-bit unsigned integer
78
- S: :ushort, # – 16-bit unsigned integer (Win32API: used for string)
78
+ S: :ushort, # – 16-bit unsigned integer (Win32/API: S used for string params)
79
79
  s: :short, # – 16-bit signed integer
80
80
  # :uint16 – 16-bit unsigned integer
81
81
  # :int16 – 16-bit signed integer
data/spec/spec_helper.rb CHANGED
@@ -12,17 +12,21 @@ module ClassMacros
12
12
  # wrapper for it method that extracts description from example source code, such as:
13
13
  # spec { use{ function(arg1 = 4, arg2 = 'string') }}
14
14
  def spec &block
15
- if RUBY_PLATFORM =~ /java/
16
- it 'not able to extract description', &block
17
- else
18
- it description_from(*block.source_location), &block
19
- end
15
+ it description_from(caller[0]), &block # it description_from(*block.source_location), &block
16
+ #do lambda(&block).should_not raise_error end
20
17
  end
21
18
 
22
- # reads description line from source file and drops external brackets (like its{}, use{}
23
- def description_from(file, line)
19
+ # reads description line from source file and drops external brackets like its{}, use{}
20
+ # accepts as arguments either file name and line or call stack member (caller[0])
21
+ def description_from(*args)
22
+ case args.size
23
+ when 1
24
+ file, line = args.first.scan(/\A(.*?):(\d+)/).first
25
+ when 2
26
+ file, line = args
27
+ end
24
28
  File.open(file) do |f|
25
- f.lines.to_a[line-1].gsub( /(spec.*?{)|(use.*?{)|}/, '' ).strip
29
+ f.lines.to_a[line.to_i-1].gsub( /(spec.*?{)|(use.*?{)|}/, '' ).strip
26
30
  end
27
31
  end
28
32
  end
@@ -32,6 +36,7 @@ module InstanceMacros
32
36
  def use
33
37
  lambda{yield}.should_not raise_error
34
38
  end
39
+
35
40
  def any_block
36
41
  lambda{|*args| args}
37
42
  end
@@ -40,6 +45,12 @@ end
40
45
  Spec::Runner.configure do |config|
41
46
  config.extend(ClassMacros)
42
47
  config.include(InstanceMacros)
48
+
49
+ class << Spec::ExampleGroup
50
+ # def spoc &block
51
+ # it description_from(caller[0]), &block
52
+ # end
53
+ end
43
54
  end
44
55
 
45
56
  module WinTest
data/spec/win/dde_spec.rb CHANGED
@@ -13,6 +13,14 @@ module WinDDETest
13
13
  ->{}
14
14
  end
15
15
 
16
+ def zero_id
17
+ FFI::MemoryPointer.new(:long).write_long(0)
18
+ end
19
+
20
+ def buffer
21
+ FFI::MemoryPointer.new(:char, 1024)
22
+ end
23
+
16
24
  describe Win::DDE, ' contains a set of pre-defined Windows API functions' do
17
25
  describe 'register_clipboard_format' do
18
26
  spec{ use{ RegisterClipboardFormat(format_name = "XlTable") }}
@@ -36,10 +44,25 @@ module WinDDETest
36
44
  end
37
45
 
38
46
  describe 'dde_initialize' do
39
- spec{ use{ status = DdeInitialize( id = [0].pack('L'), dde_callback, dde_cmd, unused = 0)}}
40
- spec{ use{ id, status = dde_initialize( id = 0, dde_cmd) do|*args| end }}
47
+ spec{ use{ status = DdeInitialize( zero_id, dde_callback, dde_cmd, unused = 0)}}
48
+ spec{ use{ id, status = dde_initialize( instance_id = 0, dde_cmd) do|*args|
49
+ end }}
50
+
51
+ it 'with zero instance_id, returns integer id and DMLERR_NO_ERROR if initialization successful' do
52
+ id, status = dde_initialize(0, APPCLASS_STANDARD) {|*args| }
53
+ id.should be_an Integer
54
+ id.should_not == 0
55
+ status.should == DMLERR_NO_ERROR
56
+ end
57
+
58
+ it 'with nil instance_id, returns integer id and DMLERR_NO_ERROR if initialization successful' do
59
+ id, status = dde_initialize(nil, APPCLASS_STANDARD) {|*args| }
60
+ id.should be_an Integer
61
+ id.should_not == 0
62
+ status.should == DMLERR_NO_ERROR
63
+ end
41
64
 
42
- it 'returns integer id and 0 if initialization successful' do
65
+ it 'with omitted instance_id, returns integer id and DMLERR_NO_ERROR if initialization successful' do
43
66
  id, status = dde_initialize(APPCLASS_STANDARD) {|*args| }
44
67
  id.should be_an Integer
45
68
  id.should_not == 0
@@ -58,12 +81,153 @@ module WinDDETest
58
81
  status.should == DMLERR_NO_ERROR
59
82
  new_id.should == id
60
83
  end
84
+ end
85
+
86
+ context 'after initialization:' do
87
+ before(:each) {@instance_id, status = dde_initialize(APPCLASS_STANDARD) {|*args| }}
88
+ after(:each) {dde_uninitialize(@instance_id)}
89
+
90
+ describe '#dde_uninitialize' do
91
+
92
+ spec{ use{ status = DdeUninitialize( @instance_id ) }}
93
+ spec{ use{ id, status = dde_uninitialize( @instance_id) }}
94
+
95
+ it 'returns true if uninitialization successful' do
96
+ res = dde_uninitialize(@instance_id)
97
+ res.should == true
98
+ end
99
+
100
+ it 'returns false if initialization unsuccessful' do
101
+ res = dde_uninitialize(12345)
102
+ res.should == false
103
+ end
104
+ end
105
+
106
+ describe '#dde_create_string_handle' do
107
+ spec{ use{ string_handle = DdeCreateStringHandle(instance_id=0, string='Any String', code_page_id=CP_WINANSI) }}
108
+ spec{ use{ string_handle = dde_create_string_handle(instance_id=0, string='Any String', code_page_id=CP_WINANSI)}}
109
+
110
+ it 'returns nonzero Integer handle to a string (passable to other DDEML functions)' do
111
+ string_handle = dde_create_string_handle(@instance_id, 'My String', CP_WINANSI)
112
+ string_handle.should be_an Integer
113
+ string_handle.should_not == 0
114
+ end
115
+
116
+ it 'creates handle even if code_page is omitted' do
117
+ string_handle = dde_create_string_handle(@instance_id, 'My String')
118
+ string_handle.should be_an Integer
119
+ string_handle.should_not == 0
120
+ end
121
+
122
+ it 'creating two handles for the SAME string (inside one instance) USUALLY returns same handle' do
123
+ string_handle1 = dde_create_string_handle(@instance_id, 'My String')
124
+ 10.times do
125
+ string_handle2 = dde_create_string_handle(@instance_id, 'My String')
126
+ string_handle1.should == string_handle2
127
+ end
128
+ end
129
+
130
+ it 'returns nil if unable to register handle to a string' do
131
+ string_handle = dde_create_string_handle(@instance_id, "", CP_WINANSI)
132
+ string_handle.should == nil
133
+ end
134
+
135
+ end
136
+
137
+ context "with dde string handle to 'My String':" do
138
+ before(:each) {@string_handle = dde_create_string_handle(@instance_id, 'My String', CP_WINANSI)}
139
+ after(:each) {dde_free_string_handle(@instance_id, @string_handle)}
140
+
141
+ describe '#dde_query_string' do
142
+
143
+ spec{ use{ string = DdeQueryString(@instance_id, @string_handle, buffer, buffer.size, code_page=CP_WINANSI)}}
144
+ spec{ use{ string = dde_query_string(@instance_id, @string_handle, code_page=CP_WINANSI )}}
145
+
146
+ it 'retrieves string that given string handle refers to' do
147
+ string = dde_query_string(@instance_id, @string_handle)
148
+ string.should == 'My String'
149
+ end
150
+
151
+ it 'retrieves string even if code_page is omitted' do
152
+ string = dde_query_string(@instance_id, @string_handle)
153
+ string.should == 'My String'
154
+ end
155
+
156
+ it 'returns nil attempting to retrieve invalid handle' do
157
+ string = dde_query_string(@instance_id, 12345)
158
+ string.should == nil
159
+ end
160
+ end
161
+
162
+ describe '#dde_free_string_handle' do
163
+
164
+ spec{ use{ success = DdeFreeStringHandle( @instance_id, @string_handle)}}
165
+ spec{ use{ success = dde_free_string_handle( @instance_id, @string_handle )}}
166
+
167
+ it 'returns true when freeing string handle registered with DDEML' do
168
+ res = dde_free_string_handle(@instance_id, @string_handle)
169
+ res.should == true
170
+ end
171
+
172
+ it 'returns false attempting to free unregistered handle' do
173
+ res = dde_free_string_handle(@instance_id, 12345)
174
+ res.should == false
175
+ end
176
+ end
177
+
178
+ describe '#dde_name_service' do
179
+ spec{ use{ success = dde_name_service(@instance_id, @string_handle, cmd=DNS_UNREGISTER ) }}
180
+ spec{ use{ success = DdeNameService(@instance_id, @string_handle, reserved=0, cmd=DNS_UNREGISTER) }}
181
+
182
+ it 'registers or unregisters the service names that DDE server supports' do
183
+
184
+ success = dde_name_service( @instance_id, @string_handle, DNS_REGISTER )
185
+ success.should == true
186
+
187
+ success = dde_name_service( @instance_id, @string_handle, DNS_UNREGISTER )
188
+ success.should == true
189
+ end
190
+ end
191
+
192
+ describe '#dde_get_last_error' do
193
+ spec{ use{ error_code = DdeGetLastError( @instance_id) }}
194
+ spec{ use{ error_code = dde_get_last_error( @instance_id) }}
195
+
196
+ it 'original API returns DMLERR_NO_ERROR if there is no last DDE error for given app instance' do
197
+ DdeGetLastError( @instance_id).should == DMLERR_NO_ERROR
198
+ end
199
+
200
+ it 'snake_case API returns nil if there is no last DDE error for given app instance' do
201
+ dde_get_last_error( @instance_id).should == nil
202
+ end
203
+
204
+ it 'returns error code of last DDE error for given app instance' do
205
+ dde_name_service( @instance_id, 1234, DNS_REGISTER )
206
+ dde_get_last_error( @instance_id).should == DMLERR_INVALIDPARAMETER
207
+ end
208
+ end
209
+
210
+ end
211
+
212
+ describe '#dde_get_data' do
213
+ spec{ use{ buffer, success = dde_get_data( data_handle = 123, max = 1073741823, offset = 0) }}
214
+ spec{ use{ length = DdeGetData( data_handle = 123, nil, 0, 0) }} # returns dde data set length
215
+ spec{ use{ length = DdeGetData( data_handle = 123, FFI::MemoryPointer.new(:char, 1024), max = 1024, offset = 0) }}
216
+
217
+ it 'original API returns 0 if trying to address invalid dde data handle' do
218
+ DdeGetData( data_handle = 123, nil, 0, 0).should == 0
219
+ end
220
+
221
+ it 'snake_case API returns nil if trying to address invalid dde data handle' do
222
+ dde_get_data( data_handle = 123, 3741823, 0).should == nil
223
+ end
61
224
 
62
- it 'returns nil if not able to initialize' do
63
- pending
64
- register_clipboard_format("").should == nil
65
225
  end
226
+
227
+ describe '#dde_connect' do
228
+ it 'connects to existing DDE server'
229
+ end
230
+
66
231
  end
67
232
  end
68
233
  end
69
-
@@ -10,6 +10,7 @@ module WinGuiMessageTest
10
10
  describe Win::Gui::Message do
11
11
 
12
12
  describe '#post_message' do
13
+ spec{ use{ success = PostMessage(handle = 0, msg = 0, w_param = 0, l_param = 0) }}
13
14
  spec{ use{ success = post_message(handle = 0, msg = 0, w_param = 0, l_param = 0) }}
14
15
 
15
16
  it 'places (posts) a message in the message queue associated with the thread that created the specified window'
@@ -17,6 +18,7 @@ module WinGuiMessageTest
17
18
  end
18
19
 
19
20
  describe '#send_message' do
21
+ spec{ use{ success = SendMessage(handle = 0, msg = 0, w_param = 1024, l_param = "\x0"*1024) }}
20
22
  spec{ use{ success = send_message(handle = 0, msg = 0, w_param = 1024, l_param = "\x0"*1024) }}
21
23
  # handle (L) - Handle to the window whose window procedure is to receive the message. The following values have special meanings.
22
24
  # HWND_BROADCAST - The message is posted to all top-level windows in the system, including disabled or invisible unowned windows,
data/win.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{win}
8
- s.version = "0.1.2"
8
+ s.version = "0.1.9"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["arvicco"]
12
- s.date = %q{2010-02-16}
12
+ s.date = %q{2010-02-19}
13
13
  s.description = %q{Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI }
14
14
  s.email = %q{arvitallian@gmail.com}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - arvicco
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-16 00:00:00 +03:00
12
+ date: 2010-02-19 00:00:00 +03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency