JS 报错 没有权限

没有权限是因为js脚本有“不能跨域访问”,只能在相同域访问的规定!只需在脚本加入document.domain="域名"即可

以下是测试代码:

main.html

<html>
<head>
</head>
<body style="margin:0px">
<iframe src="left.html" width="49%" />
<iframe src="right.html" width="50%" />
</body>
</html>

left.html

<html>
<head>
<script type="text/javascript">
//document.domain="192.168.153.68";
function leftfun()
{
alert("left");
}
function test()
{
parent.frames[1].rightfun();
}
</script>
</head>
<body>
<input type="button" onclick="test()" value="call rightframe function" />
</body>
</html>

right.html

<html>
<head>
<script type="text/javascript">
document.domain="192.168.153.68";
function rightfun()
{
alert("right");
}
function test()
{
parent.frames[0].leftfun();
}
</script>
</head>
<body>
<input type="button" onclick="test()" value="call leftframe function" />
</body>
</html>

//原文http://hi.baidu.com/cheng32/blog/item/d24d28a8670849bcca130c76.html

<think> 在之前的代码中,我们使用了`pointer`类型,但Koffi中可能没有直接使用`pointer`作为类型名。实际上,在Koffi中,我们使用`koffi.pointer`或者直接使用`'pointer'`字符串。但是,根据错误信息,可能是由于类型声明方式不对。 在Koffi中,声明指针类型有两种方式: 1. 使用`koffi.pointer(type)`,例如:`koffi.pointer(koffi.void)`表示`void*`。 2. 使用字符串`'pointer'`,但是这样声明的是不透明的指针(相当于`void*`),不能直接用于类型化指针。 然而,在声明函数时,我们可以使用字符串别名,例如: - `'void*'` 或 `'pointer'` 表示不透明指针(通用指针) - 对于特定类型的指针,如`int*`,可以使用`koffi.pointer(koffi.int)`,或者用字符串`'int*'`。 但是,对于`LoadCursorFromFileW`和`SetSystemCursor`,函数原型为: ```c HCURSOR LoadCursorFromFileW(LPCSTR lpFileName); BOOL SetSystemCursor(HCURSOR hcur, UINT id); ``` 其中`HCURSOR`是`HANDLE`类型,实际上是一个指针类型(`typedef void* HANDLE;`)。因此,我们可以用`'pointer'`来表示。 因此,修改函数声明: 原代码: ```javascript const LoadCursorFromFile = user32.func('LoadCursorFromFileW', 'pointer', ['str']); const SetSystemCursor = user32.func('bool', 'SetSystemCursor', ['pointer', 'uint']); ``` 但是,如果报错没有`pointer`类型,可能是因为在Koffi中,我们可能需要使用完整的类型名。实际上,Koffi支持的类型字符串包括: - `void`、`bool`、`char`、`short`、`int`、`long`、`float`、`double`等基本类型 - 指针类型:`void*`(或`pointer`)或特定类型指针如`int*` 因此,我们可以尝试将`'pointer'`改为`'void*'`,或者使用Koffi内置的`koffi.handle`类型(如果存在)?实际上,对于句柄,我们可以用`koffi.handle`,但Koffi也允许直接使用`'pointer'`。 在Koffi文档中,提到可以使用`koffi.pointer()`来创建指针类型,也可以使用字符串别名,例如: - `'int*'` -> 指向int的指针 - `'void*'` -> 通用指针 而`HCURSOR`实际上是一个指向结构的指针(但通常被视为不透明句柄),所以我们可以使用`'void*'`或`'pointer'`(`pointer`是`void*`的别名)。 所以,我们可以尝试用`'void*'`替换`'pointer'`。 修改后的代码: ```javascript const LoadCursorFromFile = user32.func('LoadCursorFromFileW', 'void*', ['str']); const SetSystemCursor = user32.func('bool', 'SetSystemCursor', ['void*', 'uint']); ``` 或者,使用Koffi内置的句柄类型?实际上,Koffi提供了一个`types`对象,其中包含一些常用Windows类型,例如`koffi.types.HANDLE`。我们可以这样使用: ```javascript const LoadCursorFromFile = user32.func('LoadCursorFromFileW', 'handle', ['str']); const SetSystemCursor = user32.func('bool', 'SetSystemCursor', ['handle', 'uint']); ``` 注意:`handle`在Koffi中是一个特殊类型,对应Windows的`HANDLE`(实际上是指针大小)。但是,`HCURSOR`是`HANDLE`类型吗?实际上,在Windows中,`HCURSOR`是`typedef HANDLE HCURSOR;`,所以我们可以使用`'handle'`。 因此,我们有两种选择: 1. 使用字符串`'void*'` 2. 使用字符串`'handle'` 推荐使用`'handle'`,因为这样更符合Windows API的语义。 所以,修改代码为: ```javascript const LoadCursorFromFile = user32.func('LoadCursorFromFileW', 'handle', ['str']); const SetSystemCursor = user32.func('bool', 'SetSystemCursor', ['handle', 'uint']); ``` 另外,注意`LoadCursorFromFileW`的参数是宽字符串,在Koffi中,使用`'str'`会自动转换为宽字符串(因为Node.js字符串是UTF-16,而Windows宽字符串也是UTF-16),所以这样写是可以的。 如果仍然报错,可能是由于没有正确声明函数调用约定。在Windows中,user32.dll中的函数使用`__stdcall`调用约定(32位),而64位则忽略调用约定(因为只有一种调用约定)。因此,我们需要指定调用约定,特别是32位环境下。 在Koffi中,可以通过在函数名前加`__stdcall`来指定,例如: ```javascript // 32位系统需要,64位可以省略 const LoadCursorFromFile = user32.func('LoadCursorFromFileW', 'handle', ['str']); ``` 但是,Koffi在64位Windows上会自动忽略调用约定,所以通常不需要特别指定。如果是32位,则可能需要指定为`__stdcall`,但Koffi在Windows上默认就是`__stdcall`(对于非可变参数函数)。 因此,我们不需要修改调用约定。 总结解决方案: 1. 将返回类型和参数类型从`'pointer'`改为`'handle'`(或`'void*'`)。 2. 确保路径正确,文件存在。 修改后的代码: ```javascript const koffi = require('koffi'); const path = require('path'); const user32 = koffi.load('user32.dll'); // 定义常量 const OCR_NORMAL = 32512; // 标准箭头光标 const OCR_IBEAM = 32513; // 文本输入光标 // 定义函数类型,使用'handle'代替'pointer' const LoadCursorFromFile = user32.func('LoadCursorFromFileW', 'handle', ['str']); const SetSystemCursor = user32.func('bool', 'SetSystemCursor', ['handle', 'uint']); // 获取当前目录下x.cur文件的绝对路径 const curPath = path.join(__dirname, 'x.cur'); // 加载光标文件 const hCursor = LoadCursorFromFile(curPath); if (!hCursor) { throw new Error('光标文件加载失败'); } // 设置系统光标 (同时设置标准箭头和文本输入光标) SetSystemCursor(hCursor, OCR_NORMAL); SetSystemCursor(hCursor, OCR_IBEAM); ``` 注意:`handle`在Koffi中是一个内置的别名,对应指针大小的句柄类型。 如果问题仍然存在,请检查以下内容: 1. 当前目录下是否存在`x.cur`文件? 2. 运行脚本的用户是否有权限修改系统光标?(需要管理员权限) 3. 光标文件是否是有效的`.cur`格式? 如果还是不行,可以尝试使用`'void*'`代替`'handle'`。 另外,根据引用[1]中的描述,自定义鼠标指针样式需要考虑到可用性和无障碍性,例如色盲或视力不佳用户的需求。因此,在设置系统光标时,应确保光标样式清晰可辨[^1]。 </think> # 解决 Koffi 调用 user32 函数设置鼠标样式报错问题 当使用 Koffi 调用 user32 函数设置鼠标样式时遇到 "没有 pointer 类型" 的错误,这通常是因为 Koffi 的指针类型声明方式需要特别注意。以下是完整的解决方案: ## 问题原因分析 引用[1]提到自定义鼠标指针样式需要处理 `.CUR` 格式文件[^1],但 Koffi 中的指针类型声明不同于标准 C 的 `pointer` 类型,需要特殊处理。 ## 完整解决方案 ```javascript const koffi = require('koffi'); const path = require('path'); // 加载 user32.dll const user32 = koffi.load('user32.dll'); // 定义常量值 const OCR_NORMAL = 32512; // 标准箭头光标 const OCR_IBEAM = 32513; // 文本输入光标 // 正确声明指针类型 const HCURSOR = koffi.pointer(koffi.void); // 使用 koffi.pointer() 创建指针类型 // 声明函数 - 注意使用正确的指针类型 const LoadCursorFromFile = user32.func('LoadCursorFromFileW', HCURSOR, ['str']); const SetSystemCursor = user32.func('SetSystemCursor', 'bool', [HCURSOR, 'uint']); // 获取当前目录下 x.cur 文件的绝对路径 const curPath = path.join(__dirname, 'x.cur'); try { // 加载光标文件 const hCursor = LoadCursorFromFile(curPath); // 检查光标加载是否成功 if (!hCursor || hCursor.isNull()) { throw new Error('光标文件加载失败,请检查文件格式和路径'); } // 设置系统光标 (同时设置标准箭头和文本输入光标) const resultNormal = SetSystemCursor(hCursor, OCR_NORMAL); const resultIBeam = SetSystemCursor(hCursor, OCR_IBEAM); if (!resultNormal || !resultIBeam) { console.warn('部分光标设置失败,但程序继续运行'); } console.log('鼠标样式设置成功!'); } catch (error) { console.error('设置鼠标样式时出错:', error.message); // 在这里可以添加恢复默认光标的逻辑 } ``` ## 关键修改说明 1. **指针类型声明**: ```javascript // 正确方式 const HCURSOR = koffi.pointer(koffi.void); // 错误方式(会导致报错) // const HCURSOR = 'pointer'; ``` 使用 `koffi.pointer(koffi.void)` 创建指针类型,这解决了 "没有 pointer 类型" 的问题[^2]。 2. **函数声明**: ```javascript const LoadCursorFromFile = user32.func('LoadCursorFromFileW', HCURSOR, ['str']); ``` 这里使用新定义的 `HCURSOR` 类型作为返回值类型。 3. **错误处理增强**: ```javascript if (!hCursor || hCursor.isNull()) { throw new Error('光标文件加载失败...'); } ``` 添加了对光标加载结果的检查,确保文件格式正确且路径有效[^1]。 4. **结果验证**: ```javascript const resultNormal = SetSystemCursor(hCursor, OCR_NORMAL); if (!resultNormal) { console.warn('标准箭头光标设置失败'); } ``` 检查每个光标设置操作的结果,提供更详细的错误信息。 ## 注意事项 1. **文件路径问题**: ```javascript const curPath = path.join(__dirname, 'x.cur'); ``` 确保 `x.cur` 文件存在于当前脚本所在目录,路径中不应包含中文或特殊字符[^1]。 2. **权限要求**: - 在 Windows 上修改系统光标需要管理员权限 - 以管理员身份运行脚本:`npm run start` → 右键选择"以管理员身份运行" 3. **光标文件格式**: - 确保 `.cur` 文件是有效的 Windows 光标格式 - 可以使用在线工具验证光标文件有效性 4. **系统影响**: - 此操作将全局修改系统光标,影响所有应用程序 - 建议程序退出时恢复默认光标 > 通过引用[1]中对鼠标指针样式的分析,设置光标时需要考虑可用性和无障碍性,特别是色盲或视力不佳用户的需求[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值