win 0.1.2 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
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