我有以下代碼,如果我給無效參數(雖然,顯然不工作),但是每當我給出準確的參數,ruby段錯誤。我傾向於認爲這是我的代碼和/或ruby實際調用此API函數的能力的問題,但我想要更多的輸入。我試過Win32API
和DL::Importer
,結果相同。有什麼辦法讓這個工作?如何從Ruby調用CreateWindowEx?
對於好奇,there's full background available here,包括在不同分支上嘗試使用Win32API
和DL::Importer
。在這兩種情況下,您都在尋找examples/windows-test
。
編輯:我已經設法讓RegisterClassEx
工作,但這仍然沒有幫助。紅寶石正悄然崩潰在CreateWindowEx
。
下面給出這樣的輸出:
的WndProc:4293787656
的hInstance:4194304
輸入RegisterClassEx
窗口類:49795
輸入CreateWindowEx
編輯2:我正在進行的代碼已經增長了一點點,以待粘貼它全部進入SE。如果你想要所有的背景,你可以在上面的鏈接中看到它。儘管如此,我仍試圖保持所有相關內容。
class Windows
def initialize
puts "wndproc: #{Win32::User32::WNDPROC}"
hInstance = Win32::Kernel32::GetModuleHandle(DL::NULL)
puts "hInstance: #{hInstance}"
puts "Entering RegisterClassEx"
@window_class_struct = Win32::User32::WNDCLASSEX.malloc
@window_class_struct.cbSize = Win32::User32::WNDCLASSEX.size
@window_class_struct.style = Win32::User32::CS_HREDRAW | Win32::User32::CS_VREDRAW
@window_class_struct.lpfnWndProc = Win32::User32::WNDPROC
@window_class_struct.cbClsExtra = 0
@window_class_struct.cbWndExtra = 0
@window_class_struct.hInstance = hInstance
@window_class_struct.hIcon = 0
@window_class_struct.hCursor = 0
@window_class_struct.hbrBackground = Win32::User32::COLOR_WINDOWFRAME
@window_class_struct.lpszMenuName = DL::NULL
@window_class_struct.lpszClassName = 'ruby-skype'
@window_class_struct.hIconSm = 0
p @window_class_struct
@window_class = Win32::User32::RegisterClassEx(@window_class_struct.to_i)
puts "Window Class: #{@window_class}"
puts "Entering CreateWindowEx"
@window = Win32::User32::CreateWindowEx(0, 'ruby-skype', 'ruby-skype', Win32::User32::WS_OVERLAPPEDWINDOW,
0, 0, 200, 200, DL::NULL, DL::NULL, DL::NULL)
puts "Exited CreateWindowEx"
p @window
end
module Win32
module Types
def included(m)
m.module_eval {
include ::DL::Win32Types
# @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx
typealias('HBRUSH', 'HANDLE')
typealias('HCURSOR', 'HANDLE')
typealias('HICON', 'HANDLE')
typealias('HMENU', 'HANDLE')
typealias('HMODULE', 'HANDLE')
typealias('LPCTSTR', 'unsigned char *')
typealias('LPVOID', 'void *')
typealias('WNDPROC', 'void *') # Actually a function pointer
typealias('WNDCLASSEX', 'void *') # struct
}
end
module_function :included
end
module User32
extend DL
extend DL::Importer
dlload 'user32'
include Types
extern 'HWND CreateWindowEx(DWORD, LPCTSTR, LPCTSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE)'
WNDPROC = set_callback DL::TYPE_LONG, 4 do |window_handle, message_id, wParam, lParam|
puts "WM: #{message_id}"
end
end
end
end
Windows.new
嗯,你告訴窗戶不創建一個窗口。 CreateWindowEx的第二個參數是要創建的窗口的類名。對於預定義的控件(Windows),這可能是按鈕,編輯等...如果你想創建一個父窗口,你需要首先用RegisterWindowEx創建一個原子,然後將其作爲類名 – Gunner
@Gunner:是我今天晚上的第一次嘗試,但如果是這樣,那麼爲什麼班級名稱在API文檔中作爲可選字段呈現? –
因爲我們正在談論MS的文檔編寫者,他們似乎犯了很多錯誤/遺漏。無論如何,您應該檢查API調用的返回。 CreateWindowEx在錯誤時返回NULL,當它發生時,調用GetLastError來獲取原因 – Gunner