1

我正在尝试使用带有 FFI gem 的 Ruby 更改 Windows 7 桌面中图标的位置。

到目前为止,“管理桌面图标”拥有我想要的大部分内容,但它对我不起作用。

这篇文章曾经使用LVA_ALIGNLEFT过,但我知道我需要LVS_ALIGNLEFT根据“ LVM_ARRANGE message ”来使用。

require 'ffi'

module Win32
  extend FFI::Library
  ffi_lib 'user32'
  ffi_convention :stdcall

  enum :lvm, [:LVM_GETITEMCOUNT, 4100,
              :LVM_ARRANGE, 4118,
              :LVM_SETITEMPOSITION, 4111]

  enum :parameter, [:GW_CHILD, 5,
                    :LVS_ALIGNLEFT, 2048 ]

  # Uses C Function to find the window handle(HWND) of a window with the specified text, in this case 'ProgMan'
  attach_function :findWindow, 
    :FindWindowA,[ :string, :parameter ], :int

  # Gets passed in window's child window 
  attach_function :getChildWindow,
    :GetWindow, [ :int, :parameter], :int

  # Sends a message to the passed in window  
  attach_function :sendMessage,
    :SendMessageA, [ :int, :lvm, :parameter, :long], :int
end

# Finds Windows handle for FolderView, SysListView32 which is the icon list
DesktopHandle = Win32.findWindow('ProgMan', 0)
DesktopHandle = Win32.getChildWindow(DesktopHandle, :GW_CHILD)
DesktopHandle = Win32.getChildWindow(DesktopHandle, :GW_CHILD)

# Aligns icons left?
Win32.sendMessage(DesktopHandle, :LVM_ARRANGE, :LVS_ALIGNLEFT, 0)

Win32.sendMessage(DesktopHandle, :LVM_ARRANGE, :LVS_ALIGNLEFT, 0)应该左对齐图标但什么都不做。

我曾经Win32.sendMessage(DesktopHandle, :LVM_GETITEMCOUNT, 0, 0)确保我有正确的句柄,这确实输出了我拥有的相同数量的图标。

我从“ LVM_* defs ”中获取了我的大部分值。

我只是不确定为什么这不起作用。

编辑:看起来左对齐实际上正在工作我只是没有意识到它在做什么,我认为使用这个命令应该将我所有的图标移动到我的屏幕左侧,但是这个命令只会改变对齐方式!当您左对齐某些内容或将某些内容居中时,Microsoft word 中的 IE 会改变文本的样式。

现在我需要得到改变图标位置的实际部分来工作:

for (int i=0; i<200; i++)
  SendMessage(DesktopHandle, LVM_SETITEMPOSITION, 0, MAKELPARAM(10, i));

我仍在寻找的唯一部分是如何MAKELPARAM(10, I)在 ruby​​ 中完成该部分,我想我可能想使用 Ruby 的 array#pack,但我不确定如何去做。

更新:原来我的 LVM 值的来源不是我需要的,而是我使用了“ List-View Messages ”中的值。(我更新了我的数字,所以上面的内容很好)

我还为 MAKELPARAM()找到了“ Ruby Class: Object ”。

def MAKELPARAM(w1,w2)
  return (w2<<16) | w1
end

这移动了我的一个图标Win32.sendMessage(DesktopHandle, :LVM_SETITEMPOSITION, 0, makeLPARAM(10, 1))

4

1 回答 1

1

原来我在我的发送消息中发送了错误的值。

计算图标数量的代码,然后将一个图标移动到某个 x、y 位置(这会将列表中的第一个图标移动到左上角位置,在我的情况下,我什么都没有。

require 'ffi'

module Win32
  extend FFI::Library
  ffi_lib 'user32'
  ffi_convention :stdcall

  enum :lvm, [:LVM_GETITEMCOUNT, 4100,
          :LVM_DELETEALLITEMS, 4105,
          :LVM_GETNEXTITEM, 4108,
          :LVM_SETITEMPOSITION, 4111,
          :LVM_GETITEMPOSITION, 4112,
          :LVM_ARRANGE, 4118,
          :LVM_UPDATE, 4138,
          :LVM_GETITEMTEXTA, 4141,
          :LVM_SETITEMTEXTA, 4142 ]

  enum :parameter, [:GW_CHILD, 5,
                    :LVS_ALIGNLEFT, 2048 ]

  # Uses C Function to find the window handle(HWND) of a window with the specified text, in this case 'ProgMan'
  attach_function :findWindow, 
    :FindWindowA,[ :string, :parameter ], :int

  # Gets passed in window handle's child window 
  attach_function :getChildWindow,
    :GetWindow, [ :ulong, :parameter], :int

  # Sends a message to the passed in window  
  attach_function :sendMessage,
    :SendMessageA, [ :ulong, :lvm, :parameter, :long], :int

end # end of Win32

def makeLPARAM(w1, w2)
  return (w2<<16) | w1
end

# Finds Windows handle for FolderView, SysListView32 which is the icon list
DesktopHandle = Win32.findWindow('ProgMan', 0)
DesktopHandle = Win32.getChildWindow(DesktopHandle, :GW_CHILD)
DesktopHandle = Win32.getChildWindow(DesktopHandle, :GW_CHILD)

# Gets count of icons on desktop
Win32.sendMessage(DesktopHandle, :LVM_GETITEMCOUNT, 0, 0)

# Moves the first icon in the list to the top leftmost position on the screen
Win32.sendMessage(DesktopHandle, :LVM_SETITEMPOSITION, 0, makeLPARAM(10, 1))

这比我想象的要困难得多!尽管很多都没有正确的价值观,但有人能指出我应该首先寻找价值观的地方吗?

于 2013-04-04T13:42:03.830 回答