win 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -22,15 +22,15 @@ preferably not turning your code base into an ugly spaghetty of CamelCase calls,
22
22
  String/Array pack/unpack gymnastics, buffer/pointer allocations, extracting return
23
23
  values from [in/out] parameters and checking return codes for 0.
24
24
 
25
- You have several options at this point. You can use either 'win32-api' or 'ffi' libraries
25
+ You have several options at this point. You can use 'win32-api' or 'ffi' libraries
26
26
  to connect your ruby code to Windows API and manually define wrapper methods for
27
27
  needed function calls. This is definitely a valid approach, even if it is a bit
28
- low-level one: you'll still have to handle (somewhat) gory details of callback
29
- announcement, argument preparation, mimicking pointers with Strings (or declaring
30
- pointers explicitly with FFI) and other stuff (like manually defining about a gazillion
31
- obscure Windows constants). As an example, consider the amount of code needed to complete
32
- a task as simple as getting unicode title text for the window that you already have handle
33
- for (using win32-api):
28
+ low-level one: you'll have to handle (somewhat) gory details of callback announcement,
29
+ argument preparation, mimicking pointers with Strings or declaring pointers explicitly
30
+ with FFI and other stuff (like manually defining about a gazillion obscure Windows
31
+ constants). As an example, consider the amount of code needed to complete a task as
32
+ simple as getting unicode title text for the window that you already have handle for
33
+ (using win32-api):
34
34
 
35
35
  api = Win32::API.new( 'GetWindowTextW', ['L', 'P', 'I'], 'L', 'user32' )
36
36
  buffer = "\x00" * 1024 # I just hope it will be enough...
@@ -60,22 +60,21 @@ As an alternative, you can use 'windows-pr' (pure ruby) library that gives you l
60
60
  Windows functions pre-defined and sectioned into modules, declares Windows constants and
61
61
  adds some other niceties. Unfortunately this library works only with MRI (not JRuby or
62
62
  other Ruby implementations), and still lacks Ruby look-and-feel for declared functions.
63
- It helps you to cut some of the declaration slack:
63
+ It helps you to cut some of the declaration slack though:
64
64
 
65
- num_chars = GetWindowTextW(window_handle, buffer ="\x00" * 1024 , buffer.size)
66
- title = if num_chars == 0
65
+ title = if GetWindowTextW(window_handle, buffer ="\x00" * 1024 , buffer.size) == 0
67
66
  nil
68
67
  else
69
68
  buffer.force_encoding('utf-16LE').encode('utf-8').rstrip
70
69
  end
71
70
 
72
- But still, does not it look like TOO MUCH code for something that should (ideally) look like this:
71
+ But still it seems like TOO MUCH code for something that should (ideally) look like this:
73
72
 
74
73
  title = window_text_w(window_handle)
75
74
 
76
75
  This is an idea behind this library - make Windows API functions easier to use and feel more
77
76
  natural inside Ruby code. Following the principle of least surprise, we define wrapper methods that:
78
- * Have Rubyesque names (minimized? instead of IsMinimized, etc)
77
+ * Have meaningful Rubyesque names (iconic? and minimized? instead of IsIconic, etc)
79
78
  * Require minimum arguments with sensible defaults
80
79
  * Return appropriate values explicitly (several return values if necessary)
81
80
  * Have sensible returns (false/true instead of 0/nonzero for test functions, nil if find function fails, etc)
@@ -103,7 +102,7 @@ and code blocks to give you reusable API wrapper methods with the exact behavior
103
102
  == REQUIREMENTS:
104
103
 
105
104
  Only works with Ruby 1.9 compatible implementations since it uses some of the most recent features
106
- (block arguments given to block, etc...)
105
+ (block arguments given to block, etc...).
107
106
 
108
107
  == FEATURES/PROBLEMS:
109
108
 
data/Rakefile CHANGED
@@ -5,11 +5,12 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "win"
8
- gem.summary = %Q{A collection of Windows functions predefined for you using FFI}
9
- gem.description = %Q{A collection of Windows functions predefined for you using FFI}
8
+ gem.summary = %Q{A collection of pre-defined Windows API functions with Rubyesque interfaces}
9
+ gem.description = %Q{A collection of pre-defined Windows API functions with Rubyesque interfaces}
10
10
  gem.email = "arvitallian@gmail.com"
11
11
  gem.homepage = "http://github.com/arvicco/win"
12
12
  gem.authors = ["arvicco"]
13
+ gem.add_dependency "ffi", ">= 0.6.0"
13
14
  gem.add_development_dependency "rspec", ">= 1.2.9"
14
15
  gem.add_development_dependency "cucumber", ">= 0"
15
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.6
data/lib/win/dde.rb ADDED
@@ -0,0 +1,223 @@
1
+ require 'win/library'
2
+
3
+ module Win
4
+
5
+ # Includes functions related to DDE exchange protocol in Windows
6
+ #
7
+ module DDE
8
+ include Win::Library
9
+
10
+ # Windows ANSI codepage:
11
+ CP_WINANSI = 1004
12
+
13
+ #
14
+ DNS_REGISTER = 1
15
+ DNS_UNREGISTER = 2
16
+
17
+ XTYP_CONNECT = 0x60
18
+ XTYP_DISCONNECT = 0xC0
19
+ XTYP_POKE = 0x90
20
+ XTYP_ERROR = 0x00
21
+
22
+ # Registers the application as a standard (nonmonitoring) DDEML application.
23
+ APPCLASS_STANDARD = 0
24
+ # Makes it possible for the application to monitor DDE activity in the system.
25
+ # This flag is for use by DDE monitoring applications. The application specifies the types of DDE
26
+ # activity to monitor by combining one or more monitor flags with the APPCLASS_MONITOR flag.
27
+ APPCLASS_MONITOR = 0x00000001
28
+ # ?
29
+ APPCLASS_MASK = 0x0000000F
30
+ # Prevents the application from becoming a server in a DDE conversation. The application can only be a client.
31
+ # This flag reduces consumption of resources by the DDEML. It includes the CBF_FAIL_ALLSVRXACTIONS flag.
32
+ APPCMD_CLIENTONLY = 0x00000010
33
+ # Prevents the DDEML from sending XTYP_CONNECT and XTYP_WILDCONNECT transactions to the application until
34
+ # the application has created its string handles and registered its service names or has turned off filtering
35
+ # by a subsequent call to the DdeNameService or DdeInitialize function. This flag is always in effect when an
36
+ # application calls DdeInitialize for the first time, regardless of whether the application specifies the flag.
37
+ # On subsequent calls to DdeInitialize, not specifying this flag turns off the application's service-name
38
+ # filters, but specifying it turns on the application's service name filters.
39
+ APPCMD_FILTERINITS = 0x00000020
40
+ # ?
41
+ APPCMD_MASK = 0x00000FF0
42
+ # Prevents the callback function from receiving XTYP_CONNECT transactions from the application's own instance.
43
+ # This flag prevents an application from establishing a DDE conversation with its own instance. An application
44
+ # should use this flag if it needs to communicate with other instances of itself but not with itself.
45
+ CBF_FAIL_SELFCONNECTIONS = 0x00001000
46
+ # Prevents the callback function from receiving XTYP_CONNECT and XTYP_WILDCONNECT.
47
+ CBF_FAIL_CONNECTIONS = 0x00002000
48
+ # Prevents the callback function from receiving XTYP_ADVSTART and XTYP_ADVSTOP transactions. The system returns
49
+ # DDE_FNOTPROCESSED to each client that sends an XTYP_ADVSTART or XTYP_ADVSTOP transaction to the server.
50
+ CBF_FAIL_ADVISES = 0x00004000
51
+ # Prevents the callback function from receiving XTYP_EXECUTE transactions. The system returns DDE_FNOTPROCESSED
52
+ # to a client that sends an XTYP_EXECUTE transaction to the server.
53
+ CBF_FAIL_EXECUTES = 0x00008000
54
+ # Prevents the callback function from receiving XTYP_POKE transactions. The system returns DDE_FNOTPROCESSED
55
+ # to a client that sends an XTYP_POKE transaction to the server.
56
+ CBF_FAIL_POKES = 0x00010000
57
+ # Prevents the callback function from receiving XTYP_REQUEST transactions. The system returns DDE_FNOTPROCESSED
58
+ # to a client that sends an XTYP_REQUEST transaction to the server.
59
+ CBF_FAIL_REQUESTS = 0x00020000
60
+ # Prevents the callback function from receiving server transactions. The system returns DDE_FNOTPROCESSED to each
61
+ # client that sends a transaction to this application. This flag is equivalent to combining all CBF_FAIL_ flags.
62
+ CBF_FAIL_ALLSVRXACTIONS = 0x0003f000
63
+ # Prevents the callback function from receiving XTYP_CONNECT_CONFIRM.
64
+ CBF_SKIP_CONNECT_CONFIRMS = 0x00040000
65
+ # Prevents the callback function from receiving XTYP_REGISTER notifications.
66
+ CBF_SKIP_REGISTRATIONS = 0x00080000
67
+ # Prevents the callback function from receiving XTYP_UNREGISTER notifications.
68
+ CBF_SKIP_UNREGISTRATIONS = 0x00100000
69
+ # Prevents the callback function from receiving XTYP_DISCONNECT notifications.
70
+ CBF_SKIP_DISCONNECTS = 0x00200000
71
+ # Prevents the callback function from receiving any notifications. Equivalent to combining all CBF_SKIP_ flags.
72
+ CBF_SKIP_ALLNOTIFICATIONS = 0x003c0000
73
+ # Notifies the callback function whenever a DDE application creates, frees, or increments the usage count of
74
+ # a string handle or whenever a string handle is freed as a result of a call to the DdeUninitialize function.
75
+ MF_HSZ_INFO = 0x01000000
76
+ # Notifies the callback function whenever the system or an application sends a DDE message.
77
+ MF_SENDMSGS = 0x02000000
78
+ # Notifies the callback function whenever the system or an application posts a DDE message.
79
+ MF_POSTMSGS = 0x04000000
80
+ # Notifies the callback function whenever a transaction is sent to any DDE callback function in the system.
81
+ MF_CALLBACKS = 0x08000000
82
+ # Notifies the callback function whenever a DDE error occurs.
83
+ MF_ERRORS = 0x10000000
84
+ # Notifies the callback function whenever an advise loop is started or ended.
85
+ MF_LINKS = 0x20000000
86
+ # Notifies the callback function whenever a conversation is established or terminated.
87
+ MF_CONV = 0x40000000
88
+ # ?
89
+ MF_MASK = 0xFF000000
90
+ # Returned if DDE Init successful
91
+ DMLERR_NO_ERROR = 0x00
92
+ # Returned if DDE Init failed due to wrong DLL usage
93
+ DMLERR_DLL_USAGE = 0x4004
94
+ # Returned if DDE Init failed due to invalid params
95
+ DMLERR_INVALIDPARAMETER = 0x4006
96
+ # Returned if DDE Init failed due to system error
97
+ DMLERR_SYS_ERROR = 0x400f
98
+
99
+ ##
100
+ # The RegisterClipboardFormat function registers a new clipboard format.
101
+ # This format can then be used as a valid clipboard format.
102
+ #
103
+ # Syntax: UINT RegisterClipboardFormat( LPCTSTR lpszFormat )
104
+ #
105
+ # Params:
106
+ # format_name (P) - [in] Pointer to a null-terminated string that names the new format.
107
+ #
108
+ # Returns: (I) or nil
109
+ # If the function succeeds, the return value identifies the registered clipboard format.
110
+ # If the function fails, the return value is nil(not zero). For error information, call GetLastError.
111
+ #
112
+ # Remarks:
113
+ # If a registered format with the specified name already exists, a new format is not registered and the
114
+ # return value identifies the existing format. This enables more than one application to copy and paste
115
+ # data using the same registered clipboard format. Note that the comparison is case-insensitive.
116
+ # Registered clipboard formats are identified by values in the range 0xC000 through 0xFFFF.
117
+ # When registered clipboard formats are placed on or retrieved from the clipboard, they must be in the
118
+ # form of an HGLOBAL value.
119
+ #
120
+ # :call-seq:
121
+ # register_clipboard_format( format_name )
122
+ #
123
+ function 'RegisterClipboardFormat', 'P', 'I', zeronil: true
124
+
125
+ # Procedure that calls (DdeInitialize) function expecting a DdeCallback. Runtime block is converted
126
+ # into Dde callback and registered with DdeInitialize. Returns DDE init status and DDE instance id.
127
+ #
128
+ return_id_status = ->(api, id=0, cmd, &block){
129
+ raise ArgumentError, 'No callback block' unless block
130
+
131
+ status = api.call(id = [id].pack('L'), block, cmd, 0)
132
+ id = status == 0 ? id.unpack('L').first : nil
133
+ [id, status] }
134
+
135
+ # DdeCallabck declaration
136
+ # MSDN syntax: HDDEDATA CALLBACK DdeCallback( UINT uType, UINT uFmt, HCONV hconv, HDDEDATA hsz1, HDDEDATA hsz2,
137
+ # HDDEDATA hdata, HDDEDATA dwData1, HDDEDATA dwData2);
138
+ callback :dde_callback, [:uint, :uint, :HCONV, :HDDEDATA, :HDDEDATA, :HDDEDATA, :HDDEDATA, :HDDEDATA], :HDDEDATA
139
+
140
+ ##
141
+ # The DdeInitialize function registers an application with the Dynamic Data Exchange Management Library (DDEML).
142
+ # An application must call this function before calling any other DDEML function.
143
+ #
144
+ # Syntax: UINT DdeInitialize( LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes );
145
+ #
146
+ # Params:
147
+ # pidInst (P) - [in, out] Pointer to the application instance identifier.
148
+ # At initialization, this parameter should point to 0. If the function succeeds, this parameter points to
149
+ # the instance identifier for the application. This value should be passed as the idInst parameter in all
150
+ # other DDEML functions that require it. If an application uses multiple instances of the DDEML dynamic-link
151
+ # library (DLL), the application should provide a different callback function for each instance.
152
+ # If pidInst points to a nonzero value, reinitialization of the DDEML is implied. In this case, pidInst must
153
+ # point to a valid application-instance identifier.
154
+ # pfnCallback (K) - [in] Pointer to the application-defined Dynamic Data Exchange (DDE) callback function.
155
+ # This function processes DDE transactions sent by the system. For more information, see the DdeCallback.
156
+ # afCmd (L) - [in] Specifies a set of APPCMD_, CBF_, and MF_ flags. The APPCMD_ flags provide special
157
+ # instructions to DdeInitialize. The CBF_ flags specify filters that prevent specific types of transactions
158
+ # from reaching the callback function. The MF_ flags specify the types of DDE activity that a DDE monitoring
159
+ # application monitors. Using these flags enhances the performance of a DDE application by eliminating
160
+ # unnecessary calls to the callback function. This parameter can be one or more of the following values:
161
+ # APPCLASS_MONITOR, APPCLASS_STANDARD, APPCMD_CLIENTONLY, APPCMD_FILTERINITS,
162
+ # CBF_FAIL_ALLSVRXACTIONS, CBF_FAIL_ADVISES, CBF_FAIL_CONNECTIONS, CBF_FAIL_EXECUTES, CBF_FAIL_POKES
163
+ # CBF_FAIL_REQUESTS, CBF_FAIL_SELFCONNECTIONS, CBF_SKIP_ALLNOTIFICATIONS, CBF_SKIP_CONNECT_CONFIRMS
164
+ # CBF_SKIP_DISCONNECTS, CBF_SKIP_REGISTRATIONS, CBF_SKIP_UNREGISTRATIONS
165
+ # MF_CALLBACKS, MF_CONV, MF_ERRORS, MF_HSZ_INFO, MF_LINKS, MF_POSTMSGS, MF_SENDMSGS
166
+ # ulRes (L) - Reserved; must be set to zero.
167
+ #
168
+ # Return Value:
169
+ # If the function succeeds, the return value is DMLERR_NO_ERROR.
170
+ # If the function fails, the return value is one of the following values:
171
+ # DMLERR_DLL_USAGE
172
+ # DMLERR_INVALIDPARAMETER
173
+ # DMLERR_SYS_ERROR
174
+ #
175
+ # Remarks:
176
+ # An application that uses multiple instances of the DDEML must not pass DDEML objects between instances.
177
+ # A DDE monitoring application should not attempt to perform DDE operations (establish conversations,
178
+ # issue transactions, and so on) within the context of the same application instance. A synchronous
179
+ # transaction fails with a DMLERR_REENTRANCY error if any instance of the same task has a synchronous
180
+ # transaction already in progress. The CBF_FAIL_ALLSVRXACTIONS flag causes the DDEML to filter all server
181
+ # transactions and can be changed by a subsequent call to DdeInitialize. The APPCMD_CLIENTONLY flag prevents
182
+ # the DDEML from creating key resources for the server and cannot be changed by a subsequent call to
183
+ # DdeInitialize. There is an ANSI version and a Unicode version of DdeInitialize. The version called
184
+ # determines the type of the window procedures used to control DDE conversations (ANSI or Unicode),
185
+ # and the default value for the iCodePage member of the CONVCONTEXT structure (CP_WINANSI or CP_WINUNICODE).
186
+ #
187
+ # :call-seq:
188
+ # id_inst, status = dde_initialize( id_inst = 0, cmd ) {|callback args| callback block}
189
+ #
190
+ function 'DdeInitialize', [:pointer, :dde_callback, :DWORD, :DWORD], :uint, &return_id_status
191
+
192
+ ##
193
+ # The DdeCreateStringHandle function creates a handle that identifies the specified string.
194
+ # A Dynamic Data Exchange (DDE) client or server application can pass the string handle as a
195
+ # parameter to other Dynamic Data Exchange Management Library (DDEML) functions.
196
+ #
197
+ # Syntax: HSZ DdeCreateStringHandle( DWORD idInst, LPTSTR psz, int iCodePage );
198
+ #
199
+ # Parameters:
200
+ # idInst (L) - [in] Specifies the application instance identifier obtained by a previous call to the
201
+ # DdeInitialize function.
202
+ # psz (P) - [in] Pointer to a buffer that contains the null-terminated string for which a handle
203
+ # is to be created. This string can be up to 255 characters. The reason for this limit is that
204
+ # DDEML string management functions are implemented using global atoms.
205
+ # iCodePage (I) - [in] Specifies the code page used to render the string. This value should be either
206
+ # CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode
207
+ # version of DdeInitialize was called by the client application.
208
+ #
209
+ # Return Value (L) or nil: If the function succeeds, the return value is a string handle.
210
+ # If the function fails, the return value is 0(changed to nil in enhanced version).
211
+ # The DdeGetLastError function can be used to get the error code, which can be one of the following values:
212
+ #DMLERR_NO_ERROR, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
213
+ #
214
+ # Remarks: The value of a string handle is not related to the case of the string it identifies.
215
+ # When an application either creates a string handle or receives one in the callback function
216
+ # and then uses the DdeKeepStringHandle function to keep it, the application must free that string
217
+ # handle when it is no longer needed. An instance-specific string handle cannot be mapped from string
218
+ # handle to string and back to string handle.
219
+ #
220
+ function 'DdeCreateStringHandle', [:DWORD, :pointer, :int], :HSZ
221
+
222
+ end
223
+ end