fzeet 0.6.1 → 0.6.2
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/examples/UIRibbon/ApplicationModes.dll +0 -0
- data/examples/UIRibbon/ApplicationModes.rb +40 -0
- data/examples/UIRibbon/ApplicationModes.rbw +14 -0
- data/examples/UIRibbon/ApplicationModes.xml +83 -0
- data/examples/UIRibbon/Color.rbw +1 -1
- data/examples/UIRibbon/Control/Button.dll +0 -0
- data/examples/UIRibbon/Control/Button.rb +9 -5
- data/examples/UIRibbon/Control/Button.rbw +3 -1
- data/examples/UIRibbon/Control/Button.xml +6 -0
- data/examples/UIRibbon/Control/ColorPicker.dll +0 -0
- data/examples/UIRibbon/Control/ColorPicker.rb +55 -0
- data/examples/UIRibbon/Control/ColorPicker.rbw +91 -0
- data/examples/UIRibbon/Control/ColorPicker.xml +131 -0
- data/examples/UIRibbon/Control/ComboBox.dll +0 -0
- data/examples/UIRibbon/Control/ComboBox.rb +23 -0
- data/examples/UIRibbon/Control/ComboBox.rbw +56 -0
- data/examples/UIRibbon/Control/ComboBox.xml +75 -0
- data/examples/UIRibbon/Control/FontControl.dll +0 -0
- data/examples/UIRibbon/Control/FontControl.rb +34 -0
- data/examples/UIRibbon/Control/FontControl.rbw +83 -0
- data/examples/UIRibbon/Control/FontControl.xml +96 -0
- data/examples/UIRibbon/Control/Gallery.dll +0 -0
- data/examples/UIRibbon/Control/Gallery.rb +55 -0
- data/examples/UIRibbon/Control/Gallery.rbw +124 -0
- data/examples/UIRibbon/Control/Gallery.xml +132 -0
- data/examples/UIRibbon/Control/Spinner.dll +0 -0
- data/examples/UIRibbon/Control/Spinner.rb +14 -0
- data/examples/UIRibbon/Control/Spinner.rbw +27 -0
- data/examples/UIRibbon/Control/Spinner.xml +37 -0
- data/examples/UIRibbon/Size.rbw +1 -1
- data/examples/UIRibbon/TabGroup.dll +0 -0
- data/examples/UIRibbon/TabGroup.rb +12 -0
- data/examples/UIRibbon/TabGroup.rbw +23 -0
- data/examples/UIRibbon/TabGroup.xml +42 -0
- data/examples/UIRibbon/Viewer.rbw +1 -1
- data/examples/res/applications-graphics-big.bmp +0 -0
- data/examples/res/applications-graphics-small.bmp +0 -0
- data/examples/res/applications-graphics.bmp +0 -0
- data/examples/res/document-print-big.bmp +0 -0
- data/examples/res/document-print-preview-big.bmp +0 -0
- data/examples/res/document-print-preview-small.bmp +0 -0
- data/examples/res/document-print-preview.bmp +0 -0
- data/examples/res/document-print-small.bmp +0 -0
- data/examples/res/document-print.bmp +0 -0
- data/examples/res/go-bottom-big.bmp +0 -0
- data/examples/res/go-bottom-small.bmp +0 -0
- data/examples/res/go-bottom.bmp +0 -0
- data/examples/res/preferences-desktop-font-big.bmp +0 -0
- data/examples/res/preferences-desktop-font-small.bmp +0 -0
- data/examples/res/preferences-desktop-font.bmp +0 -0
- data/examples/res/process-stop-big.bmp +0 -0
- data/examples/res/process-stop-small.bmp +0 -0
- data/examples/res/process-stop.bmp +0 -0
- data/lib/fzeet/Application.rb +6 -1
- data/lib/fzeet/Common.rb +17 -0
- data/lib/fzeet/Dialog/ShellFileDialog.rb +8 -48
- data/lib/fzeet/UIRibbon.rb +174 -7
- data/lib/fzeet/windows/com.rb +2 -0
- data/lib/fzeet/windows/common.rb +47 -6
- data/lib/fzeet/windows/gdi.rb +8 -0
- data/lib/fzeet/windows/kernel.rb +2 -0
- data/lib/fzeet/windows/ole.rb +34 -0
- data/lib/fzeet/windows/propsys.rb +7 -1
- data/lib/fzeet/windows/shell/Common.rb +44 -0
- data/lib/fzeet/windows/shlwapi.rb +10 -0
- data/lib/fzeet/windows/uiribbon.rb +15 -0
- data/lib/fzeet/windows.rb +1 -0
- metadata +51 -8
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            <?xml version='1.0' encoding='utf-8' ?>
         | 
| 2 | 
            +
            <Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
         | 
| 3 | 
            +
            	<Application.Commands>
         | 
| 4 | 
            +
            <Command Name='cmdAppMenu' />
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            <Command Name='cmdQAT' />
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            <Command Name='cmdTab1' LabelTitle='Tab1' />
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            <Command Name='cmdTabGroup1' LabelTitle='TabGroup1' />
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            <Command Name='cmdTabGroup1Tab1' LabelTitle='Tab1' />
         | 
| 13 | 
            +
            <Command Name='cmdTabGroup1Tab2' LabelTitle='Tab2' />
         | 
| 14 | 
            +
            	</Application.Commands>
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            	<Application.Views>
         | 
| 17 | 
            +
            		<Ribbon>
         | 
| 18 | 
            +
            			<Ribbon.ApplicationMenu>
         | 
| 19 | 
            +
            <ApplicationMenu CommandName='cmdAppMenu'>
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            </ApplicationMenu>
         | 
| 22 | 
            +
            			</Ribbon.ApplicationMenu>
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            			<Ribbon.QuickAccessToolbar>
         | 
| 25 | 
            +
            <QuickAccessToolbar CommandName='cmdQAT'>
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            </QuickAccessToolbar>
         | 
| 28 | 
            +
            			</Ribbon.QuickAccessToolbar>
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            			<Ribbon.Tabs>
         | 
| 31 | 
            +
            <Tab CommandName='cmdTab1' />
         | 
| 32 | 
            +
            			</Ribbon.Tabs>
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            			<Ribbon.ContextualTabs>
         | 
| 35 | 
            +
            <TabGroup CommandName='cmdTabGroup1'>
         | 
| 36 | 
            +
            	<Tab CommandName='cmdTabGroup1Tab1' />
         | 
| 37 | 
            +
            	<Tab CommandName='cmdTabGroup1Tab2' />
         | 
| 38 | 
            +
            </TabGroup>
         | 
| 39 | 
            +
            			</Ribbon.ContextualTabs>
         | 
| 40 | 
            +
            		</Ribbon>
         | 
| 41 | 
            +
            	</Application.Views>
         | 
| 42 | 
            +
            </Application>
         | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
    
        data/lib/fzeet/Application.rb
    CHANGED
    
    | @@ -12,10 +12,15 @@ module Fzeet | |
| 12 12 | 
             
            		@accelerators = []
         | 
| 13 13 | 
             
            		@dialogs = []
         | 
| 14 14 | 
             
            		@images = {}
         | 
| 15 | 
            +
            		Fzeet.using(ScreenDC.new) { |dc|
         | 
| 16 | 
            +
            			@devcaps = {
         | 
| 17 | 
            +
            				logpixelsy: Windows.GetDeviceCaps(dc.handle, Windows::LOGPIXELSY)
         | 
| 18 | 
            +
            			}
         | 
| 19 | 
            +
            		}
         | 
| 15 20 |  | 
| 16 21 | 
             
            		class << self
         | 
| 17 22 | 
             
            			attr_accessor :name, :version, :authors, :quitWhenMainWindowCloses
         | 
| 18 | 
            -
            			attr_reader :window, :accelerators, :dialogs, :images
         | 
| 23 | 
            +
            			attr_reader :window, :accelerators, :dialogs, :images, :devcaps
         | 
| 19 24 | 
             
            		end
         | 
| 20 25 |  | 
| 21 26 | 
             
            		def self.window=(window)
         | 
    
        data/lib/fzeet/Common.rb
    CHANGED
    
    | @@ -153,6 +153,10 @@ module Fzeet | |
| 153 153 | 
             
            		def rb; Point.new(self[:right], self[:bottom]) end
         | 
| 154 154 | 
             
            	end
         | 
| 155 155 |  | 
| 156 | 
            +
            	class LOGFONT
         | 
| 157 | 
            +
            		include Toggle
         | 
| 158 | 
            +
            	end
         | 
| 159 | 
            +
             | 
| 156 160 | 
             
            	class Message < Windows::MSG
         | 
| 157 161 | 
             
            		def get!(window = nil, msgFilterMin = 0, msgFilterMax = 0)
         | 
| 158 162 | 
             
            			Windows.DetonateLastError(-1, :GetMessage, self, window && window.handle, msgFilterMin, msgFilterMax) != 0
         | 
| @@ -299,6 +303,9 @@ module Fzeet | |
| 299 303 | 
             
            		def color; Windows.GetTextColor(@handle) end
         | 
| 300 304 | 
             
            		def color=(color) Windows.SetTextColor(@handle, color) end
         | 
| 301 305 |  | 
| 306 | 
            +
            		def background; Windows.GetBkColor(@handle) end
         | 
| 307 | 
            +
            		def background=(background) Windows.SetBkColor(@handle, background) end
         | 
| 308 | 
            +
             | 
| 302 309 | 
             
            		def fillRect(rect, brush) Windows.DetonateLastError(0, :FillRect, @handle, rect, brush.handle); self end
         | 
| 303 310 |  | 
| 304 311 | 
             
            		def text(text, rect, flags = 0) Windows.DetonateLastError(0, :DrawText, @handle, text, -1, rect, Fzeet.flags(flags, :dt_)); self end
         | 
| @@ -328,4 +335,14 @@ module Fzeet | |
| 328 335 |  | 
| 329 336 | 
             
            		def dispose; Windows.ReleaseDC(@window.handle, @handle); detach end
         | 
| 330 337 | 
             
            	end
         | 
| 338 | 
            +
             | 
| 339 | 
            +
            	class ScreenDC < Handle
         | 
| 340 | 
            +
            		include DCMethods
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            		def initialize
         | 
| 343 | 
            +
            			@handle = Windows.DetonateLastError(FFI::Pointer::NULL, :GetDC, nil); attach
         | 
| 344 | 
            +
            		end
         | 
| 345 | 
            +
             | 
| 346 | 
            +
            		def dispose; Windows.ReleaseDC(nil, @handle); detach end
         | 
| 347 | 
            +
            	end
         | 
| 331 348 | 
             
            end
         | 
| @@ -10,78 +10,38 @@ module Fzeet | |
| 10 10 | 
             
            			result
         | 
| 11 11 | 
             
            		end
         | 
| 12 12 |  | 
| 13 | 
            -
            		def  | 
| 14 | 
            -
            			result = nil
         | 
| 15 | 
            -
             | 
| 13 | 
            +
            		def item
         | 
| 16 14 | 
             
            			FFI::MemoryPointer.new(:pointer) { |psi|
         | 
| 17 15 | 
             
            				next unless GetResult(psi) == Windows::S_OK
         | 
| 18 16 |  | 
| 19 17 | 
             
            				si = Windows::ShellItem.new(psi.read_pointer)
         | 
| 20 18 |  | 
| 21 19 | 
             
            				begin
         | 
| 22 | 
            -
            					 | 
| 23 | 
            -
            						next unless si.GetDisplayName(Windows::SIGDN_FILESYSPATH, pwcs) == Windows::S_OK
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            						wcs = pwcs.read_pointer
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            						begin
         | 
| 28 | 
            -
            							result = Windows.WCSTOMBS(wcs)
         | 
| 29 | 
            -
            						ensure
         | 
| 30 | 
            -
            							Windows.CoTaskMemFree(wcs)
         | 
| 31 | 
            -
            						end
         | 
| 32 | 
            -
            					}
         | 
| 20 | 
            +
            					yield si
         | 
| 33 21 | 
             
            				ensure
         | 
| 34 22 | 
             
            					si.Release
         | 
| 35 23 | 
             
            				end
         | 
| 36 24 | 
             
            			}
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            			result
         | 
| 39 25 | 
             
            		end
         | 
| 40 26 |  | 
| 41 | 
            -
            		def  | 
| 42 | 
            -
            			result = []
         | 
| 43 | 
            -
             | 
| 27 | 
            +
            		def items
         | 
| 44 28 | 
             
            			FFI::MemoryPointer.new(:pointer) { |psia|
         | 
| 45 29 | 
             
            				next unless GetResults(psia) == Windows::S_OK
         | 
| 46 30 |  | 
| 47 31 | 
             
            				sia = Windows::ShellItemArray.new(psia.read_pointer)
         | 
| 48 32 |  | 
| 49 33 | 
             
            				begin
         | 
| 50 | 
            -
            					 | 
| 51 | 
            -
            						next unless sia.GetCount(pc) == Windows::S_OK
         | 
| 52 | 
            -
             | 
| 53 | 
            -
            						pc.read_long.times { |i|
         | 
| 54 | 
            -
            							FFI::MemoryPointer.new(:pointer) { |psi|
         | 
| 55 | 
            -
            								next unless sia.GetItemAt(i, psi) == Windows::S_OK
         | 
| 56 | 
            -
             | 
| 57 | 
            -
            								si = Windows::ShellItem.new(psi.read_pointer)
         | 
| 58 | 
            -
             | 
| 59 | 
            -
            								begin
         | 
| 60 | 
            -
            									FFI::MemoryPointer.new(:pointer) { |pwcs|
         | 
| 61 | 
            -
            										next unless si.GetDisplayName(Windows::SIGDN_FILESYSPATH, pwcs) == Windows::S_OK
         | 
| 62 | 
            -
             | 
| 63 | 
            -
            										wcs = pwcs.read_pointer
         | 
| 64 | 
            -
             | 
| 65 | 
            -
            										begin
         | 
| 66 | 
            -
            											result << Windows.WCSTOMBS(wcs)
         | 
| 67 | 
            -
            										ensure
         | 
| 68 | 
            -
            											Windows.CoTaskMemFree(wcs)
         | 
| 69 | 
            -
            										end
         | 
| 70 | 
            -
            									}
         | 
| 71 | 
            -
            								ensure
         | 
| 72 | 
            -
            									si.Release
         | 
| 73 | 
            -
            								end
         | 
| 74 | 
            -
            							}
         | 
| 75 | 
            -
            						}
         | 
| 76 | 
            -
            					}
         | 
| 34 | 
            +
            					yield sia
         | 
| 77 35 | 
             
            				ensure
         | 
| 78 36 | 
             
            					sia.Release
         | 
| 79 37 | 
             
            				end
         | 
| 80 38 | 
             
            			}
         | 
| 81 | 
            -
             | 
| 82 | 
            -
            			result
         | 
| 83 39 | 
             
            		end
         | 
| 84 40 |  | 
| 41 | 
            +
            		def path; item { |si| return si.path } end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            		def paths; items { |sia| return sia.map(&:path) } end
         | 
| 44 | 
            +
             | 
| 85 45 | 
             
            		def show(window = Application.window)
         | 
| 86 46 | 
             
            			DialogResult.new((Show(window.handle) == Windows::S_OK) ? Windows::IDOK : Windows::IDCANCEL)
         | 
| 87 47 | 
             
            		end
         | 
    
        data/lib/fzeet/UIRibbon.rb
    CHANGED
    
    | @@ -7,6 +7,38 @@ module Fzeet | |
| 7 7 |  | 
| 8 8 | 
             
            			prop(*args)
         | 
| 9 9 | 
             
            		end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            		def update(from)
         | 
| 12 | 
            +
            			case from
         | 
| 13 | 
            +
            			when Windows::LOGFONT
         | 
| 14 | 
            +
            				uiprop(:FontProperties_Family, Windows::PROPVARIANT[:wstring, from.face])
         | 
| 15 | 
            +
            				uiprop(:FontProperties_Size, Windows::PROPVARIANT[:decimal, from.size.round])
         | 
| 16 | 
            +
            				uiprop(:FontProperties_Bold, Windows::PROPVARIANT[:uint, (from.bold?) ? 2 : 1])
         | 
| 17 | 
            +
            				uiprop(:FontProperties_Italic, Windows::PROPVARIANT[:uint, (from.italic?) ? 2 : 1])
         | 
| 18 | 
            +
            				uiprop(:FontProperties_Underline, Windows::PROPVARIANT[:uint, (from.underline?) ? 2 : 1])
         | 
| 19 | 
            +
            				uiprop(:FontProperties_Strikethrough, Windows::PROPVARIANT[:uint, (from.strikeout?) ? 2 : 1])
         | 
| 20 | 
            +
            			else raise ArgumentError
         | 
| 21 | 
            +
            			end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            			self
         | 
| 24 | 
            +
            		end
         | 
| 25 | 
            +
            	end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            	class Windows::UISimplePropertySet
         | 
| 28 | 
            +
            		def get(k) Windows::PROPVARIANT.new.tap { |v| GetValue(k, v) } end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            		def prop(*args)
         | 
| 31 | 
            +
            			case args.length
         | 
| 32 | 
            +
            			when 1; get(*args)
         | 
| 33 | 
            +
            			else raise ArgumentError
         | 
| 34 | 
            +
            			end
         | 
| 35 | 
            +
            		end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            		def uiprop(*args)
         | 
| 38 | 
            +
            			args[0] = Windows.const_get("UI_PKEY_#{args[0]}")
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            			prop(*args)
         | 
| 41 | 
            +
            		end
         | 
| 10 42 | 
             
            	end
         | 
| 11 43 |  | 
| 12 44 | 
             
            	class UIRibbon
         | 
| @@ -102,11 +134,63 @@ module Fzeet | |
| 102 134 | 
             
            			}
         | 
| 103 135 | 
             
            		end
         | 
| 104 136 |  | 
| 105 | 
            -
            		 | 
| 137 | 
            +
            		class GalleryItem < Windows::UISimplePropertySetCallback
         | 
| 138 | 
            +
            			def initialize(label, categoryId = 0, image = nil)
         | 
| 139 | 
            +
            				@label, @categoryId, @image = label, categoryId, image
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            				super()
         | 
| 142 | 
            +
            			end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            			attr_reader :label, :categoryId, :image
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            			def GetValue(pkey, pvalue)
         | 
| 147 | 
            +
            				key, value = Windows::PROPERTYKEY.new(pkey), Windows::PROPVARIANT.new(pvalue)
         | 
| 148 | 
            +
             | 
| 149 | 
            +
            				case key
         | 
| 150 | 
            +
            				when Windows::UI_PKEY_CategoryId
         | 
| 151 | 
            +
            					value.uint = @categoryId; Windows::S_OK
         | 
| 152 | 
            +
            				when Windows::UI_PKEY_Label
         | 
| 153 | 
            +
            					value.wstring = @label; Windows::S_OK
         | 
| 154 | 
            +
            				when Windows::UI_PKEY_ItemImage
         | 
| 155 | 
            +
            					FFI::MemoryPointer.new(:pointer) { |punk|
         | 
| 156 | 
            +
            						Windows::UIImageFromBitmap.new.CreateImage(PARGB32.new(@image).handle, Windows::UI_OWNERSHIP_TRANSFER, punk)
         | 
| 157 | 
            +
             | 
| 158 | 
            +
            						unk = Windows::Unknown.new(punk.read_pointer)
         | 
| 159 | 
            +
            						value.unknown = unk
         | 
| 160 | 
            +
            						unk.Release
         | 
| 161 | 
            +
            					}
         | 
| 162 | 
            +
             | 
| 163 | 
            +
            					Windows::S_OK
         | 
| 164 | 
            +
            				else
         | 
| 165 | 
            +
            					Windows::E_NOTIMPL
         | 
| 166 | 
            +
            				end
         | 
| 167 | 
            +
            			end
         | 
| 168 | 
            +
            		end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
            		def initialize(_window, opts = {})
         | 
| 171 | 
            +
            			handlers = {}
         | 
| 172 | 
            +
             | 
| 173 | 
            +
            			opts.delete_if { |k, v|
         | 
| 174 | 
            +
            				next false unless v.kind_of?(Proc)
         | 
| 175 | 
            +
             | 
| 176 | 
            +
            				handlers[k] = v; true
         | 
| 177 | 
            +
            			}
         | 
| 178 | 
            +
             | 
| 179 | 
            +
            			_opts = {
         | 
| 180 | 
            +
            				name: Application.name,
         | 
| 181 | 
            +
            				resname: 'APPLICATION_RIBBON'
         | 
| 182 | 
            +
            			}
         | 
| 183 | 
            +
            			badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
         | 
| 184 | 
            +
            			_opts.merge!(opts)
         | 
| 185 | 
            +
             | 
| 106 186 | 
             
            			@creates = []
         | 
| 107 187 | 
             
            			@destroys = []
         | 
| 108 188 | 
             
            			@sizes = []
         | 
| 109 189 | 
             
            			@executesAllVerbs = {}
         | 
| 190 | 
            +
            			@executesExecute = {}
         | 
| 191 | 
            +
            			@executesPreview = {}
         | 
| 192 | 
            +
            			@executesCancelPreview = {}
         | 
| 193 | 
            +
            			@updatesAllKeys = {}
         | 
| 110 194 |  | 
| 111 195 | 
             
            			@window = _window
         | 
| 112 196 |  | 
| @@ -124,6 +208,7 @@ module Fzeet | |
| 124 208 | 
             
            				attr_reader :ribbon
         | 
| 125 209 |  | 
| 126 210 | 
             
            				def Execute(*args) ribbon.execute(*args); Windows::S_OK end
         | 
| 211 | 
            +
            				def UpdateProperty(*args) ribbon.update(*args); Windows::S_OK end
         | 
| 127 212 | 
             
            			end
         | 
| 128 213 |  | 
| 129 214 | 
             
            			@uia = Windows::UIApplication.new
         | 
| @@ -183,10 +268,18 @@ module Fzeet | |
| 183 268 | 
             
            				def OnCreateUICommand(*args) uich.QueryInterface(uich.class::IID, args[-1]); Windows::S_OK end
         | 
| 184 269 | 
             
            			end
         | 
| 185 270 |  | 
| 271 | 
            +
            			@hdll = Windows.LoadRibbonDll(_opts[:name])
         | 
| 272 | 
            +
             | 
| 273 | 
            +
            			handlers.each { |k, v|
         | 
| 274 | 
            +
            				k[1] = Object.const_get(k[1]) if k.length > 1
         | 
| 275 | 
            +
             | 
| 276 | 
            +
            				on(*k, &v)
         | 
| 277 | 
            +
            			}
         | 
| 278 | 
            +
             | 
| 186 279 | 
             
            			@uif = Windows::UIFramework.new
         | 
| 187 280 |  | 
| 188 281 | 
             
            			uif.Initialize(window.handle, uia)
         | 
| 189 | 
            -
            			uif.LoadUI(@hdll | 
| 282 | 
            +
            			uif.LoadUI(@hdll, "#{_opts[:resname]}\0".encode('utf-16le'))
         | 
| 190 283 |  | 
| 191 284 | 
             
            			window.on(:destroy) {
         | 
| 192 285 | 
             
            				uich.Release
         | 
| @@ -203,15 +296,28 @@ module Fzeet | |
| 203 296 | 
             
            			args = {
         | 
| 204 297 | 
             
            				commandId: commandId,
         | 
| 205 298 | 
             
            				verb: verb,
         | 
| 206 | 
            -
            				key: key,
         | 
| 207 | 
            -
            				value: value,
         | 
| 208 | 
            -
            				props: props,
         | 
| 299 | 
            +
            				key: (key.null?) ? nil : Windows::PROPERTYKEY.new(key),
         | 
| 300 | 
            +
            				value: (value.null?) ? nil : Windows::PROPVARIANT.new(value),
         | 
| 301 | 
            +
            				props: (props.null?) ? nil : Windows::UISimplePropertySet.new(props),
         | 
| 209 302 | 
             
            				ribbon: self,
         | 
| 210 303 | 
             
            				sender: Command.new(self, commandId)
         | 
| 211 304 | 
             
            			}
         | 
| 212 305 |  | 
| 213 | 
            -
            			 | 
| 214 | 
            -
            				 | 
| 306 | 
            +
            			(handlers = @executesAllVerbs[commandId]) and handlers.each { |handler|
         | 
| 307 | 
            +
            				(handler.arity == 0) ? handler.call : handler.call(args)
         | 
| 308 | 
            +
            			}
         | 
| 309 | 
            +
             | 
| 310 | 
            +
            			case verb
         | 
| 311 | 
            +
            			when Windows::UI_EXECUTIONVERB_EXECUTE
         | 
| 312 | 
            +
            				(handlers = @executesExecute[commandId]) and handlers.each { |handler|
         | 
| 313 | 
            +
            					(handler.arity == 0) ? handler.call : handler.call(args)
         | 
| 314 | 
            +
            				}
         | 
| 315 | 
            +
            			when Windows::UI_EXECUTIONVERB_PREVIEW
         | 
| 316 | 
            +
            				(handlers = @executesPreview[commandId]) and handlers.each { |handler|
         | 
| 317 | 
            +
            					(handler.arity == 0) ? handler.call : handler.call(args)
         | 
| 318 | 
            +
            				}
         | 
| 319 | 
            +
            			when Windows::UI_EXECUTIONVERB_CANCELPREVIEW
         | 
| 320 | 
            +
            				(handlers = @executesCancelPreview[commandId]) and handlers.each { |handler|
         | 
| 215 321 | 
             
            					(handler.arity == 0) ? handler.call : handler.call(args)
         | 
| 216 322 | 
             
            				}
         | 
| 217 323 | 
             
            			end
         | 
| @@ -223,6 +329,33 @@ module Fzeet | |
| 223 329 | 
             
            			self
         | 
| 224 330 | 
             
            		end
         | 
| 225 331 |  | 
| 332 | 
            +
            		def update(commandId, key, value, newValue)
         | 
| 333 | 
            +
            			args = {
         | 
| 334 | 
            +
            				commandId: commandId,
         | 
| 335 | 
            +
            				key: (key.null?) ? nil : Windows::PROPERTYKEY.new(key),
         | 
| 336 | 
            +
            				value: (value.null?) ? nil : Windows::PROPVARIANT.new(value),
         | 
| 337 | 
            +
            				newValue: (newValue.null?) ? nil : Windows::PROPVARIANT.new(newValue),
         | 
| 338 | 
            +
            				ribbon: self,
         | 
| 339 | 
            +
            				sender: Command.new(self, commandId)
         | 
| 340 | 
            +
            			}
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            			(handlers = @updatesAllKeys[commandId]) and handlers.each { |handler|
         | 
| 343 | 
            +
            				(handler.arity == 0) ? handler.call : handler.call(args)
         | 
| 344 | 
            +
            			}
         | 
| 345 | 
            +
             | 
| 346 | 
            +
            			self
         | 
| 347 | 
            +
            		rescue
         | 
| 348 | 
            +
            			Fzeet.message %Q{#{$!}\n\n#{$!.backtrace.join("\n")}}, icon: :error
         | 
| 349 | 
            +
             | 
| 350 | 
            +
            			self
         | 
| 351 | 
            +
            		end
         | 
| 352 | 
            +
             | 
| 353 | 
            +
            		def invalidate(commandId, flags = Windows::UI_INVALIDATIONS_ALLPROPERTIES, key = nil)
         | 
| 354 | 
            +
            			@uif.InvalidateUICommand(commandId, flags, key)
         | 
| 355 | 
            +
             | 
| 356 | 
            +
            			self
         | 
| 357 | 
            +
            		end
         | 
| 358 | 
            +
             | 
| 226 359 | 
             
            		def on(*args, &block)
         | 
| 227 360 | 
             
            			case args.size
         | 
| 228 361 | 
             
            			when 1
         | 
| @@ -233,12 +366,46 @@ module Fzeet | |
| 233 366 | 
             
            				when Integer; (@executesAllVerbs[args[0]] ||= []) << block
         | 
| 234 367 | 
             
            				else raise ArgumentError
         | 
| 235 368 | 
             
            				end
         | 
| 369 | 
            +
            			when 2
         | 
| 370 | 
            +
            				case args[0]
         | 
| 371 | 
            +
            				when /^execute$/i; (@executesExecute[args[1]] ||= []) << block
         | 
| 372 | 
            +
            				when /^preview$/i; (@executesPreview[args[1]] ||= []) << block
         | 
| 373 | 
            +
            				when /^cancelpreview$/i; (@executesCancelPreview[args[1]] ||= []) << block
         | 
| 374 | 
            +
            				when /^update$/i; (@updatesAllKeys[args[1]] ||= []) << block
         | 
| 375 | 
            +
            				else raise ArgumentError
         | 
| 376 | 
            +
            				end
         | 
| 236 377 | 
             
            			else raise ArgumentError
         | 
| 237 378 | 
             
            			end
         | 
| 238 379 |  | 
| 239 380 | 
             
            			self
         | 
| 240 381 | 
             
            		end
         | 
| 241 382 |  | 
| 383 | 
            +
            		def fontPropsUpdate(args)
         | 
| 384 | 
            +
            			return self unless args[:key] == Windows::UI_PKEY_FontProperties
         | 
| 385 | 
            +
             | 
| 386 | 
            +
            			args[:value].unknown { |current|
         | 
| 387 | 
            +
            				current.QueryInstance(Windows::PropertyStore) { |ps|
         | 
| 388 | 
            +
            					yield ps
         | 
| 389 | 
            +
             | 
| 390 | 
            +
            					args[:newValue].unknown = current
         | 
| 391 | 
            +
            				}
         | 
| 392 | 
            +
            			}
         | 
| 393 | 
            +
             | 
| 394 | 
            +
            			self
         | 
| 395 | 
            +
            		end
         | 
| 396 | 
            +
             | 
| 397 | 
            +
            		def fontPropsChanged(args)
         | 
| 398 | 
            +
            			return self unless args[:key] == Windows::UI_PKEY_FontProperties
         | 
| 399 | 
            +
             | 
| 400 | 
            +
            			args[:props].uiprop(:FontProperties_ChangedProperties).unknown { |changed|
         | 
| 401 | 
            +
            				changed.QueryInstance(Windows::PropertyStore) { |ps|
         | 
| 402 | 
            +
            					yield ps
         | 
| 403 | 
            +
            				}
         | 
| 404 | 
            +
            			}
         | 
| 405 | 
            +
             | 
| 406 | 
            +
            			self
         | 
| 407 | 
            +
            		end
         | 
| 408 | 
            +
             | 
| 242 409 | 
             
            		def contextualUI(id, x, y)
         | 
| 243 410 | 
             
            			uif.UseInstance(Windows::UIContextualUI, :GetView, id) { |view|
         | 
| 244 411 | 
             
            				view.ShowAtLocation(x, y)
         | 
    
        data/lib/fzeet/windows/com.rb
    CHANGED
    
    
    
        data/lib/fzeet/windows/common.rb
    CHANGED
    
    | @@ -87,13 +87,17 @@ module Fzeet | |
| 87 87 | 
             
            		def GET_Y_LPARAM(l) ((w = HIWORD(l)) > 0x7fff) ? w - 0x1_0000 : w end
         | 
| 88 88 |  | 
| 89 89 | 
             
            		def LPWSTR(s)
         | 
| 90 | 
            -
            			FFI::MemoryPointer.new(:uchar, (s.length + 2) * 2) | 
| 91 | 
            -
            				"#{s}\0".encode('utf-16le').each_byte.with_index { |b, i|
         | 
| 92 | 
            -
            					p.put_char(i, b)
         | 
| 90 | 
            +
            			p = FFI::MemoryPointer.new(:uchar, (s.length + 2) * 2)
         | 
| 93 91 |  | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
            			 | 
| 92 | 
            +
            			"#{s}\0".encode('utf-16le').each_byte.with_index { |b, i| p.put_char(i, b) }
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            			begin
         | 
| 95 | 
            +
            				yield p; return nil
         | 
| 96 | 
            +
            			ensure
         | 
| 97 | 
            +
            				p.free
         | 
| 98 | 
            +
            			end if block_given?
         | 
| 99 | 
            +
             | 
| 100 | 
            +
            			p
         | 
| 97 101 | 
             
            		end
         | 
| 98 102 |  | 
| 99 103 | 
             
            		def WCSTOMBS(p)
         | 
| @@ -172,6 +176,43 @@ module Fzeet | |
| 172 176 | 
             
            				:lfQuality, :uchar,
         | 
| 173 177 | 
             
            				:lfPitchAndFamily, :uchar,
         | 
| 174 178 | 
             
            				:lfFaceName, [:char, 32]
         | 
| 179 | 
            +
             | 
| 180 | 
            +
            			def face; self[:lfFaceName].to_s end
         | 
| 181 | 
            +
            			def face=(face) self[:lfFaceName] = face end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
            			def size; -Rational(self[:lfHeight] * 72, Application.devcaps[:logpixelsy]) end
         | 
| 184 | 
            +
            			def size=(size) self[:lfHeight] = -Windows.MulDiv((size * 10).to_i, Application.devcaps[:logpixelsy], 720) end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
            			def bold?; self[:lfWeight] >= 700 end
         | 
| 187 | 
            +
            			def bold=(bold) self[:lfWeight] = (bold) ? 700 : 0 end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
            			def italic?; self[:lfItalic] == 1 end
         | 
| 190 | 
            +
            			def italic=(italic) self[:lfItalic] = (italic) ? 1 : 0 end
         | 
| 191 | 
            +
             | 
| 192 | 
            +
            			def underline?; self[:lfUnderline] == 1 end
         | 
| 193 | 
            +
            			def underline=(underline) self[:lfUnderline] = (underline) ? 1 : 0 end
         | 
| 194 | 
            +
             | 
| 195 | 
            +
            			def strikeout?; self[:lfStrikeOut] == 1 end
         | 
| 196 | 
            +
            			def strikeout=(strikeout) self[:lfStrikeOut] = (strikeout) ? 1 : 0 end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
            			def update(from)
         | 
| 199 | 
            +
            				case from
         | 
| 200 | 
            +
            				when PropertyStore
         | 
| 201 | 
            +
            					from.each { |k, v|
         | 
| 202 | 
            +
            						case k
         | 
| 203 | 
            +
            						when UI_PKEY_FontProperties_Family; self.face = v.wstring
         | 
| 204 | 
            +
            						when UI_PKEY_FontProperties_Size; self.size = v.decimal.to_f
         | 
| 205 | 
            +
            						when UI_PKEY_FontProperties_Bold; self.bold = v.uint == 2
         | 
| 206 | 
            +
            						when UI_PKEY_FontProperties_Italic; self.italic = v.uint == 2
         | 
| 207 | 
            +
            						when UI_PKEY_FontProperties_Underline; self.underline = v.uint == 2
         | 
| 208 | 
            +
            						when UI_PKEY_FontProperties_Strikethrough; self.strikeout = v.uint == 2
         | 
| 209 | 
            +
            						end
         | 
| 210 | 
            +
            					}
         | 
| 211 | 
            +
            				else raise ArgumentError
         | 
| 212 | 
            +
            				end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
            				self
         | 
| 215 | 
            +
            			end
         | 
| 175 216 | 
             
            		end
         | 
| 176 217 |  | 
| 177 218 | 
             
            		class SYSTEMTIME < FFI::Struct
         | 
    
        data/lib/fzeet/windows/gdi.rb
    CHANGED
    
    | @@ -13,6 +13,11 @@ module Fzeet | |
| 13 13 | 
             
            		module_function \
         | 
| 14 14 | 
             
            			:GetRValue, :GetGValue, :GetBValue, :RGB
         | 
| 15 15 |  | 
| 16 | 
            +
            		LOGPIXELSX = 88
         | 
| 17 | 
            +
            		LOGPIXELSY = 90
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            		attach_function :GetDeviceCaps, [:pointer, :int], :int
         | 
| 20 | 
            +
             | 
| 16 21 | 
             
            		DEFAULT_GUI_FONT = 17
         | 
| 17 22 |  | 
| 18 23 | 
             
            		attach_function :GetStockObject, [:int], :pointer
         | 
| @@ -46,6 +51,9 @@ module Fzeet | |
| 46 51 | 
             
            		attach_function :GetTextColor, [:pointer], :ulong
         | 
| 47 52 | 
             
            		attach_function :SetTextColor, [:pointer, :ulong], :ulong
         | 
| 48 53 |  | 
| 54 | 
            +
            		attach_function :GetBkColor, [:pointer], :ulong
         | 
| 55 | 
            +
            		attach_function :SetBkColor, [:pointer, :ulong], :ulong
         | 
| 56 | 
            +
             | 
| 49 57 | 
             
            		attach_function :MoveToEx, [:pointer, :int, :int, :pointer], :int
         | 
| 50 58 | 
             
            		attach_function :LineTo, [:pointer, :int, :int], :int
         | 
| 51 59 | 
             
            	end
         | 
    
        data/lib/fzeet/windows/kernel.rb
    CHANGED
    
    
    
        data/lib/fzeet/windows/ole.rb
    CHANGED
    
    | @@ -85,6 +85,8 @@ module Fzeet | |
| 85 85 | 
             
            					key[:pid] = type
         | 
| 86 86 | 
             
            				}
         | 
| 87 87 | 
             
            			end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            			def ==(other) Windows.memcmp(other, self, size) == 0 end
         | 
| 88 90 | 
             
            		end
         | 
| 89 91 |  | 
| 90 92 | 
             
            		class LARGE_INTEGER < FFI::Union
         | 
| @@ -246,6 +248,38 @@ module Fzeet | |
| 246 248 |  | 
| 247 249 | 
             
            			def uint; raise 'Wrong type tag.' unless self[:vt] == VT_UI4; self[:uintVal] end
         | 
| 248 250 | 
             
            			def uint=(uint) self[:vt] = VT_UI4; self[:uintVal] = uint end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
            			def unknown
         | 
| 253 | 
            +
            				raise 'Wrong type tag.' unless self[:vt] == VT_UNKNOWN
         | 
| 254 | 
            +
             | 
| 255 | 
            +
            				yield Unknown.new(self[:punkVal])
         | 
| 256 | 
            +
            			ensure
         | 
| 257 | 
            +
            				Windows.PropVariantClear(self)
         | 
| 258 | 
            +
            			end
         | 
| 259 | 
            +
             | 
| 260 | 
            +
            			def unknown=(unknown) self[:vt] = VT_UNKNOWN; self[:punkVal] = unknown.pointer; unknown.AddRef end
         | 
| 261 | 
            +
             | 
| 262 | 
            +
            			def wstring; raise 'Wrong type tag.' unless self[:vt] == VT_LPWSTR; Windows.WCSTOMBS(self[:pwszVal]) end
         | 
| 263 | 
            +
             | 
| 264 | 
            +
            			def wstring=(string)
         | 
| 265 | 
            +
            				self[:vt] = VT_LPWSTR
         | 
| 266 | 
            +
             | 
| 267 | 
            +
            				FFI::MemoryPointer.new(:pointer) { |p|
         | 
| 268 | 
            +
            					Windows.DetonateHresult(:SHStrDup, string, p)
         | 
| 269 | 
            +
             | 
| 270 | 
            +
            					self[:pwszVal] = p.read_pointer
         | 
| 271 | 
            +
            				}
         | 
| 272 | 
            +
            			end
         | 
| 273 | 
            +
             | 
| 274 | 
            +
            			def decimal
         | 
| 275 | 
            +
            				raise 'Wrong type tag.' unless self[:vt] == VT_DECIMAL
         | 
| 276 | 
            +
             | 
| 277 | 
            +
            				Rational(self[:decVal][:Lo64], 10 ** self[:decVal][:scale]) + self[:decVal][:Hi32]
         | 
| 278 | 
            +
            			end
         | 
| 279 | 
            +
             | 
| 280 | 
            +
            			def decimal=(decimal) self[:vt] = VT_DECIMAL; self[:decVal][:Lo64] = decimal end
         | 
| 249 281 | 
             
            		end
         | 
| 282 | 
            +
             | 
| 283 | 
            +
            		attach_function :PropVariantClear, [:pointer], :long
         | 
| 250 284 | 
             
            	end
         | 
| 251 285 | 
             
            end
         | 
| @@ -18,10 +18,14 @@ module Fzeet | |
| 18 18 | 
             
            		PropertyStore = COM::Instance[IPropertyStore]
         | 
| 19 19 |  | 
| 20 20 | 
             
            		class PropertyStore
         | 
| 21 | 
            -
            			 | 
| 21 | 
            +
            			include Enumerable
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            			def count; FFI::MemoryPointer.new(:ulong) { |pc| GetCount(pc); return pc.get_ulong(0) } end
         | 
| 22 24 | 
             
            			alias :size :count
         | 
| 23 25 | 
             
            			alias :length :count
         | 
| 24 26 |  | 
| 27 | 
            +
            			def key(i) PROPERTYKEY.new.tap { |k| GetAt(i, k) } end
         | 
| 28 | 
            +
             | 
| 25 29 | 
             
            			# superclass.superclass is FFI::Struct, so do NOT touch [] and []=
         | 
| 26 30 | 
             
            			def get(k) PROPVARIANT.new.tap { |v| GetValue(k, v) } end
         | 
| 27 31 | 
             
            			def set(k, v) SetValue(k, v); self end
         | 
| @@ -35,6 +39,8 @@ module Fzeet | |
| 35 39 | 
             
            			end
         | 
| 36 40 |  | 
| 37 41 | 
             
            			def commit; Commit(); self end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            			def each; length.times { |i| v = get(k = key(i)); yield k, v }; self end
         | 
| 38 44 | 
             
            		end
         | 
| 39 45 | 
             
            	end
         | 
| 40 46 | 
             
            end
         |