class Fzeet::BasicWindow

Constants

DialogProc
FrameProc
MDIChildProc
Prefix
WindowClass
WindowProc

Attributes

client[R]
parent[R]
ribbon[R]

Public Class Methods

[](name, opts = {}) click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 686
def self.[](name, opts = {})
        Class.new(self) {
                const_set(:WindowClass, Fzeet::WindowClass.new(self::WindowClass, name, opts))
        }
end
crackMessage(hwnd, uMsg, wParam, lParam) click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 692
def self.crackMessage(hwnd, uMsg, wParam, lParam)
        window = @@instances[hwnd.to_i]

        args = {
                hwnd: hwnd,
                uMsg: uMsg,
                wParam: wParam,
                lParam: lParam,
                result: (window.kind_of?(Dialog)) ? 1 : 0,
                window: window,
                sender: window
        }

        case uMsg
        when Windows::WM_CREATE
                args[:cs] = Windows::CREATESTRUCT.new(FFI::Pointer.new(lParam))
        when Windows::WM_NCCREATE
                args[:result] = 1
                args[:cs] = Windows::CREATESTRUCT.new(FFI::Pointer.new(lParam))
        when Windows::WM_COMMAND
                args[:command], args[:notification], args[:hctl] = Windows.LOWORD(wParam), Windows.HIWORD(wParam), FFI::Pointer.new(lParam)
                args[:sender] = @@instances[args[:hctl].to_i] unless args[:hctl].null?
        when Windows::WM_NOTIFY
                args[:nmh] = Windows::NMHDR.new(FFI::Pointer.new(lParam))
                args[:command], args[:notification], args[:hctl] = args[:nmh][:idFrom], args[:nmh][:code], args[:nmh][:hwndFrom]
                (args[:sender] = @@instances[args[:hctl].to_i]).class.crackNotification(args)
        when \
                Windows::WM_MOUSEMOVE,
                Windows::WM_LBUTTONDOWN, Windows::WM_LBUTTONUP, Windows::WM_LBUTTONDBLCLK,
                Windows::WM_RBUTTONDOWN, Windows::WM_RBUTTONUP, Windows::WM_RBUTTONDBLCLK,
                Windows::WM_MBUTTONDOWN, Windows::WM_MBUTTONUP, Windows::WM_MBUTTONDBLCLK,
                Windows::WM_CONTEXTMENU

                args[:x], args[:y] = Windows.GET_X_LPARAM(lParam), Windows.GET_Y_LPARAM(lParam)

                if uMsg == Windows::WM_CONTEXTMENU && args[:x] == -1
                        Windows.DetonateLastError(0, :GetCursorPos, pt = Point.new)

                        args[:keyboard], args[:x], args[:y] = true, pt[:x], pt[:y]
                end
        end

        args
end
new(opts = {}) { |self, _opts| ... } click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 737
def initialize(opts = {})
        _opts = {
                xstyle: [],
                caption: Application.name,
                style: [],
                x: Windows::CW_USEDEFAULT,
                y: Windows::CW_USEDEFAULT,
                width: Windows::CW_USEDEFAULT,
                height: Windows::CW_USEDEFAULT,
                parent: nil,
                menu: nil,
                position: [],
                anchor: nil
        }
        badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
        _opts.merge!(opts)

        yield self, _opts if block_given?

        _opts[:xstyle] = Fzeet.flags(_opts[:xstyle], *self.class::Prefix[:xstyle])
        _opts[:caption] = _opts[:caption].to_s
        _opts[:style] = Fzeet.flags(_opts[:style], *self.class::Prefix[:style])
        _opts[:x], _opts[:y], _opts[:width], _opts[:height] = _opts[:position] unless _opts[:position].empty?

        @messages ||= {}
        @commands ||= {}
        @notifies ||= {}

        @processed = [0, 0]

        @handle = Windows.CreateWindowEx(
                _opts[:xstyle],  self.class::WindowClass.name, _opts[:caption], _opts[:style],
                _opts[:x], _opts[:y], _opts[:width], _opts[:height],
                _opts[:parent] && _opts[:parent].handle, nil, Windows.GetModuleHandle(nil), FFI::Pointer.new(object_id)
        )

        if @handle.null?
                raise "CreateWindowEx failed (last error #{Windows.GetLastError()})." unless [
                        [Windows::WM_NCCREATE, 0], [Windows::WM_CREATE, -1],
                        [Windows::WM_DESTROY, 0], [Windows::WM_NCDESTROY, 0]
                ].include?(@processed)
        else
                @parent = _opts[:parent]
                self.menu = _opts[:menu] if _opts[:menu]

                on(:destroy) {
                        menu.rdetach if self.menu

                        eachChild(&:dispose)
                }

                case _opts[:anchor]
                when :ltr
                        @parent.on(:size) { |args|
                                self.position = @parent.rect.tap { |r| r[:bottom] = _opts[:height] }.to_a

                                args[:result] = nil if @parent.class == MDIChild
                        }
                when :lrb
                        @parent.on(:size) { |args|
                                self.position = @parent.rect.tap { |r| r[:top] = r[:bottom] - _opts[:height]; r[:bottom] = _opts[:height] }.to_a

                                args[:result] = nil if @parent.class == MDIChild
                        }
                when :ltrb
                        @parent.on(:size) { |args|
                                self.position = @parent.rect.to_a

                                args[:result] = nil if @parent.class == MDIChild
                        }
                else raise ArgumentError, "Bad anchor spec: #{_opts[:anchor]}."
                end if _opts[:anchor] && @parent
        end
end

Public Instance Methods

dispose() click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 814
def dispose; Windows.DestroyWindow(@handle) end
on(*args, &block) click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 888
def on(*args, &block)
        args[0] =~ /^draw$/ and
                return onMessage(:paint) { |_args| paint { |dc| dc.select(*args[1..-1]) {
                        case block.arity
                        when 0; block.call
                        when 1; block.call(dc)
                        else block.call(dc, _args)
                        end
                }}}

        case args.length
        when 1; onMessage(*args, &block)
        when 2, 3
                case Fzeet.constant(args.shift, :wm_)
                when Windows::WM_COMMAND; onCommand(*args, &block)
                when Windows::WM_NOTIFY; onNotify(*args, &block)
                else raise ArgumentError
                end
        else raise ArgumentError
        end
end
onCommand(cmd, notification = :all, &block) click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 870
def onCommand(cmd, notification = :all, &block)
        notification = Fzeet.constant(notification, *self[cmd].class::Prefix[:notification]) unless
                notification.kind_of?(Integer) || notification == :all

        (((@commands ||= {})[Command[cmd]] ||= {})[notification] ||= []) << block

        self
end
onMessage(msg, &block) click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 864
def onMessage(msg, &block)
        ((@messages ||= {})[Fzeet.constant(msg, :wm_)] ||= []) << block

        self
end
onNotify(cmd, notification = :all, &block) click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 879
def onNotify(cmd, notification = :all, &block)
        notification = Fzeet.constant(notification, *self[cmd].class::Prefix[:notification]) unless
                notification.kind_of?(Integer) || notification == :all

        (((@notifies ||= {})[Command[cmd]] ||= {})[notification] ||= []) << block

        self
end
stubNotImplementedCommands() click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 910
def stubNotImplementedCommands
        Command.instance_variable_get(:@ids).each { |command, id|
                next if @commands.find { |_id, handlers| _id == id }

                on(:command, id) { message "Not Implemented (#{command})", icon: :warning }
        }

        self
end
windowProc(hwnd, uMsg, wParam, lParam) click to toggle source
# File lib/fzeet/windows/user/Window/Common.rb, line 816
def windowProc(hwnd, uMsg, wParam, lParam)
        args, result = nil, nil

        if (handlers = @messages[uMsg])
                args ||= self.class.crackMessage(hwnd, uMsg, wParam, lParam)

                handlers.each { |handler|
                        (handler.arity == 0) ? handler.call : handler.call(args)

                        result = args[:result]; @processed[0], @processed[1] = uMsg, result
                }
        end

        if uMsg == Windows::WM_COMMAND && (handlers = @commands[Windows.LOWORD(wParam)])
                args ||= self.class.crackMessage(hwnd, uMsg, wParam, lParam)

                handlers[:all].each { |handler|
                        (handler.arity == 0) ? handler.call : handler.call(args)

                        result = args[:result]; @processed[0], @processed[1] = uMsg, result
                } if handlers[:all]

                handlers[Windows.HIWORD(wParam)].each { |handler|
                        (handler.arity == 0) ? handler.call : handler.call(args)

                        result = args[:result]; @processed[0], @processed[1] = uMsg, result
                } if handlers[Windows.HIWORD(wParam)]
        end

        if uMsg == Windows::WM_NOTIFY && (handlers = @notifies[(nmh = Windows::NMHDR.new(FFI::Pointer.new(lParam)))[:idFrom]])
                args ||= self.class.crackMessage(hwnd, uMsg, wParam, lParam)

                handlers[:all].each { |handler|
                        (handler.arity == 0) ? handler.call : handler.call(args)

                        result = args[:result]; @processed[0], @processed[1] = uMsg, result
                } if handlers[:all]

                handlers[nmh[:code]].each { |handler|
                        (handler.arity == 0) ? handler.call : handler.call(args)

                        result = args[:result]; @processed[0], @processed[1] = uMsg, result
                } if handlers[nmh[:code]]
        end

        result
end