Project1

标题: 关于win32api的createwindow的问题 [打印本页]

作者: proudmor    时间: 2020-2-16 14:52
标题: 关于win32api的createwindow的问题
我使用这个@CreateWindow=Win32API.new("user32","CreateWindow",['p','p','l','i','i','i','i','l','l','l','p'],'l')
但是报错了,CreateWindow or CreateWindowA,似乎是参数的问题。
这些参数应该写些什么,对于可能出问题的第1、2、3、11我都试过p,l,i,v都不行,但没有试过所有排列组合(11p4那么多),除了4、5、6、7能确定是i,8、9、10大概是l,1、2大概是p其他应该是什么?
作者: proudmor    时间: 2020-2-16 14:54
最疑惑的是3,dword在ruby的win32api调用中是什么类型,是不是p,l,i,v以外的类型,我试过d不行。
作者: SixRC    时间: 2020-2-16 19:55
本帖最后由 SixRC 于 2020-2-16 20:01 编辑

首先 CreateWindow 并非这个api的真名 大多数api都分 A(ansi) 和 W(unicode) 两个版本
用哪个版本要基于你传入参数是什么编码的 纯英文就用A 因为 RM 好像是 utf-8 和 ansi 在英文区域不冲突的
然后这个api有点特殊。。
"CreateWindow is implemented as a call to the CreateWindowEx function, as shown below."
C 代码复制
  1. #define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
  2. CreateWindowExA(0L, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
  3.  
  4. #define CreateWindowW(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
  5. CreateWindowExW(0L, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
  6.  
  7. #ifdef UNICODE
  8. #define CreateWindow  CreateWindowW
  9. #else
  10. #define CreateWindow  CreateWindowA
  11. #endif

所以其实你需要调用的是 CreateWindowExA
其实Win32API 能否取到api只和api名字是否正确有关  后面的和传参相关 不对程序可能崩掉
然后看参数
CreateWindowExA
RM是32位的 32位传参 int 就是 long  DWORD 是 unsigned long 用 L 吧(其实 l 也没事的)
句柄 HANDLE 是 void* 其实也是 l
l的意义是原值传入 p的意义是把ruby字符串的地址传入
也可以都写 l 字符串传入 [str].pack("p").unpack("l")[0] 就行
所以我们有 依次 LppLllllllll
RUBY 代码复制
  1. c=Win32API.new("user32","CreateWindowExA","LppLllllllll","l")
  2. p c.call(0,"Button","hi",0x10000000 | 0x00040000,400,400,250,150,0,0,0x400000,0)

假如有些参数需要指向结构体 你需要利用ruby字符串来建构它 会稍微麻烦一点
大概就是这样
作者: proudmor    时间: 2020-2-16 22:44
SixRC 发表于 2020-2-16 19:55
首先 CreateWindow 并非这个api的真名 大多数api都分 A(ansi) 和 W(unicode) 两个版本
用哪个版本要基于你 ...

强啊大神。
作者: proudmor    时间: 2020-2-16 23:19
继续请教大神,我想要的是可输入中文的文本框
中文显示,是在哪个地方表示一下utf-8之类的吗,好像rpgmaker和菜鸟驿站上的不大一样。
获取输入的内容,GetWindowText怎么获取的是标题。
销毁窗口,destroywindow是什么情况,是不是不是这个,怎么会和Enum什么的扯上关系,大概查了下销毁窗口和消息队列有关?
作者: proudmor    时间: 2020-2-17 19:11
现在获取输入的内容和销毁窗口搞定了,就剩中文显示的问题了。
作者: SixRC    时间: 2020-2-17 19:59
本帖最后由 SixRC 于 2020-2-17 20:09 编辑
proudmor 发表于 2020-2-17 19:11
现在获取输入的内容和销毁窗口搞定了,就剩中文显示的问题了。


昨天没看到 点评一下我 或者 @一下我吧...不然我不知道你回了啊啊
RM默认应该是utf-8编码
所以对于A版本的函数 你需要用
MultiByteToWideChar 把字符串转换成unicode 再用
WideCharToMultiByte 转成 ansi
第一个参数代码页你需要写常数 不能写CP_ACP 你应该懂的
缓存区域你可以 buf = "0" * size
size通过上面的函数返回
具体看函数说明
对于转换到unicode 需要 buf = "0" * size * 2
具体看函数说明 要看仔细
看他返回的单位是 字节数 还是 字数
我给你写个例子

RUBY 代码复制
  1. MultiByteToWideChar = Win32API.new("kernel32","MultiByteToWideChar","llplpl","l")
  2. WideCharToMultiByte = Win32API.new("kernel32","WideCharToMultiByte","llplplll","l")
  3. UTF8 = 0xFDE9
  4. CPACP = 0
  5. def utf8ToAnsi(str)
  6.   len = MultiByteToWideChar.call(UTF8, 0, str, -1, "", 0)
  7.   buf = "00" * len
  8.   MultiByteToWideChar.call(UTF8, 0, str, -1, buf, len)
  9.   len = WideCharToMultiByte.call(CPACP, 0, buf, -1, "", 0, 0, 0)
  10.   retbuf = "0" * len
  11.   WideCharToMultiByte.call(CPACP, 0, buf, -1, retbuf, len, 0, 0)
  12.   retbuf
  13. end
  14.  
  15. title = utf8ToAnsi("测试")
  16. c=Win32API.new("user32","CreateWindowExA","LppLllllllll","l")
  17. p c.call(0,"Button",title,0x10000000 | 0x00040000,400,400,250,150,0,0,0x400000,0)


你改改就能用了
作者: proudmor    时间: 2020-2-18 17:33
SixRC 发表于 2020-2-17 19:59
昨天没看到 点评一下我 或者 @一下我吧...不然我不知道你回了啊啊
RM默认应该是utf-8编码
所以对于A版本 ...

太感谢了。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1