# win.image 库模块帮助文档

<details>  <summary>必读</summary>  <p>

## 管理位图/图标句柄的生命周期 <a id="handle-lifecycle" href="#handle-lifecycle">&#x23;</a>

1. 加载图像/图标时指定 `0x8000/*_LR_SHARED*/` 选项。返回句柄全局有效，只管创建不管释放。在进程退出时由系统自动释放。

	同一文件重复以 _LR_SHARED 选项加载时也会返回不同的位图/图标句柄。
	因此要避免用这种方式频繁自内存创建 _LR_SHARED 图像或句柄。。

2. 使用原生句柄（数据类型为 `pointer`）自行管理图标的生命周期。谁创建谁释放。

3. 使用 gcdata 创建托管句柄（数据类型为 `cdata` ），由 aardio 自动管理图标句柄的生命周期。变量存活图标就有效，变量被回收则自动释放句柄。

	`win.image.loadIconFromFile(iconPathOrData,true)` 会返回托管句柄（参数 @2 指定为 true） 。

	将一个普通图标句柄 `hIcon` （数据类型为 `pointer` 的原生指针）转换为托管指针的关键代码如下：

    ```aardio 
    /*
    返回 cdata 类型托管指针，
    元表 hIcon@ 设置为参数指定的表对象。
    */
    var gcIcon = gcdata(
        //_topointer 可以是指针或返回指针的函数
        _topointer = hIcon; //在 API 函数或结构体中自动转换为指针值
        _gc = function(){
            // hIcon 被回收时自动调用 _gc 指定的析构函数
            ::DestroyIcon(owner); //owner 自动转换为元属性 _topointer 返回的指针值
        } 
    );
    ```

    返回的托管指针 hIcon 负责管理绑定图标句柄的生命周期，托管指针被回收时会自动调用析构函数并执行  `::DestroyIcon(hIcon)` 释放自身。
    因此不能再手动调用  `::DestroyIcon(gcIcon)` （这会导致错误地重复释放操作）。

    托管指针/句柄在传入支持原生类型的 API 函数或 aardio 函数时会自动解包为普通指针，在一般使用时与普通指针没有区别。 

    参考：[托管指针](https://www.aardio.com/zh-cn/docs/language-reference/datatype/datatype.html#cdata)

4. 使用 win.form 对象自动管理图标句柄

	实际上在 aardio 开发中使用 GDI 位图并不多见。
	大多时候我们使用 gdip.bitmap 或者 com.picture 处理图像，一般无需自行处理资源释放问题。

	而控件图标基本都已经被更简洁的文字图标替代（例如 fonts.fontAwesome ）。
	但设置窗体本身的图标（主要显示在窗口标题栏与系统任务栏）却必须指定图标句柄（加载自 *.ico 文件）。

	图标句柄的生命周期管理非常复杂，但 win.form 的 setIcon 方法封装并简化了这些操作。

	最简单的用法：

	```aardio 
	winform.afterDpiChanged = function(scaleX,scaleY,origScaleX,origScaleY){ 
		winform.setIcon("/example.ico")
	}
	```

	窗口初始化或系统 DPI 缩放时会自动调用 winform.afterDpiChanged 。
	winform.setIcon 的参数如果是图标文件路径时（必须是硬盘存在的文件，不能是内嵌资源文件），
	aardio 会自动选择合适的分辨率，并加载合适的小图标、大图标，并自动管理加载的图标句柄（不用时自动释放）。
	这让一切事情都变得很简单。

	直接指定图标句柄的格式如下：
	`winform.setIcon(hSmall,hBig,gc)`

	如果参数 @gc 为 true，winform 会负责自动释放传入的图标句柄。
	如果参数 @hSmall,@hBig 是托管句柄并且 @gc 为 true，那么 winform 仅添加与解除引用（不会执行 ::DestroyIcon ）。
	这种托管句柄的图标可以安全地用于多个窗口。

	但如果 @hSmall,@hBig 是普通图标句柄且参数 @gc 为 true，
	则 winform 在释放图标时会对图标执行 ::DestroyIcon 调用。
	因此不能将普通图标句柄用 winform.setIcon 指定到多个窗口，并且将参数  @gc 为 true 。

	对于使用 _LR_SHARED 选项加载的共享图标，
	也不能将参数 @gc 设为 true，共享图标由系统在进程退出时释放。

 要注意在现代界面开发主要使用更方便的字体图标，
 需要用到原生 icon 图标的场景并不多见，因此不必要把简单的事搞复很复杂。

</p></details>

## win.image 成员列表 <a id="win.image" href="#win.image">&#x23;</a>

### win.image.createAniCursor(动画光标数据) <a id="win.image.createAniCursor" href="#win.image.createAniCursor">&#x23;</a>
自内存加载 *.ani 格式的动画光标。  
参数也可以是文件、或资源文件路径

### win.image.createIcon <a id="win.image.createIcon" href="#win.image.createIcon">&#x23;</a>
在图标数据中加载指定像素的图标,失败返回空值

### win.image.createIcon(图标数据,是否图标,最小分辨率,最大位宽,选项) <a id="win.image.createIcon" href="#win.image.createIcon">&#x23;</a>
自内存创建图标，失败返回空值。  
图标数据:也可以是路径,或资源文件路径,  
是否图标:可省略,默认为 true ,载入光标请指定为 false ,仅支持单色光标  
最小分辨率:可省略,如果不匹配则取最接近的图标。  
最大位宽:可省略,默认值为32位  
选项:保留参数,不必指定  

如果选项不指定_LR_SHARED，返回的句柄不再使用时必须调用 ::DestroyIcon销毁

### win.image.createSharedIcon(图标数据,是否图标,最小分辨率,最大位宽) <a id="win.image.createSharedIcon" href="#win.image.createSharedIcon">&#x23;</a>
自内存创建共享图标，失败返回空值。  
图标数据:也可以是路径,或资源文件路径,  
是否图标:可省略,默认为 true ,载入光标请指定为 false ,仅支持单色光标  
最小分辨率:可省略,如果不匹配则取最接近的图标。  
最大位宽:可省略,默认值为32位  
选项:保留参数,不必指定  

返回的句柄句柄系统管理，不能自行调用 ::DestroyIcon 销毁。  
图标全局有效，进程退出时自动释放。  
注意不能大量创建这种图标（无法提前释放）。  
同一文件多次创建共享图标也会返回不同的句柄。

### win.image.extractIcon(EXE文件路径,图标索引,是否自动释放) <a id="win.image.extractIcon" href="#win.image.extractIcon">&#x23;</a>
索引默认为 1,如果为 0,则返回图标总数,  
参数二默认为true

### win.image.getIcon(窗口对象或句柄,是否大图标) <a id="win.image.getIcon" href="#win.image.getIcon">&#x23;</a>
获取窗口图标句柄。  
返回的句柄不应被释放，共享图标返回空值

### win.image.loadCursor(请输入资源名,模块句柄) <a id="win.image.loadCursor" href="#win.image.loadCursor">&#x23;</a>
自光标资源载入光标（鼠标指针）,  
返回句柄无需释放

### win.image.loadCursorFromFile(位图路径) <a id="win.image.loadCursorFromFile" href="#win.image.loadCursorFromFile">&#x23;</a>
自参数 @1 指定的文件路径载入光标（鼠标指针），  
支持 aardio 内嵌资源文件路径。

### win.image.loadIcon(请输入资源名,模块句柄) <a id="win.image.loadIcon" href="#win.image.loadIcon">&#x23;</a>
自图标资源载入图标，  
返回句柄无需释放

### win.image.loadIconFromFile <a id="win.image.loadIconFromFile" href="#win.image.loadIconFromFile">&#x23;</a>
自参数图标文件（支持内嵌资源文件）或内存数据加载图标。  
可选指定一个或多个分辨率。

### win.image.loadIconFromFile(iconPathOrData,flags,size,size2,...) <a id="win.image.loadIconFromFile" href="#win.image.loadIconFromFile">&#x23;</a>
加载一个或多个图标。  
- 参数 @iconPathOrData 可指定图标内存数据（string/buffer/string.builder）  
或文件路径（支持内嵌资源路径）  
- 参数 @flags 可用数值指定选项，例如指定 `0x8000/*_LR_SHARED*/`返回共享图标句柄。  
如果 @flags 恒等为 true 则返回托管指针（负责自动释放图标）。  
- 可选可选增加一个或多个参数指定图标大小（已处理浮点误差，不要加 0.5），  
指定多个分辨率则返回多个图标句柄。  
失败返回 null 。

### win.image.loadImage(请输入资源名,模块句柄) <a id="win.image.loadImage" href="#win.image.loadImage">&#x23;</a>
自位图资源载入位图，n返回句柄无需释放

### win.image.loadImageFromFile(位图路径,是否自动释放) <a id="win.image.loadImageFromFile" href="#win.image.loadImageFromFile">&#x23;</a>
自参数 @1 指定的文件路径载入位图，  
支持 aardio 内嵌资源文件路径。  
参数 @2 默认为 true

### win.image.loadSharedIconFromFile(iconPathOrData,size,size2,...) <a id="win.image.loadSharedIconFromFile" href="#win.image.loadSharedIconFromFile">&#x23;</a>
加载一个或多个共享图标。  
等价于调用 win.image.loadIconFromFile 并将 flags 参数指定为  `0x8000/*_LR_SHARED*/`。  
- 参数 @iconPathOrData 可指定图标内存数据（string/buffer/string.builder）  
或文件路径（支持内嵌资源路径）  
- 可选可选增加一个或多个参数指定图标大小（已处理浮点误差，不要加 0.5），  
指定多个分辨率则返回多个图标句柄。  
失败返回 null 。  

同一文件重复以 _LR_SHARED 选项加载时也会返回不同的位图/图标句柄

### win.image.queryIconFromResource(图标数据,是否图标,回调函数,选项) <a id="win.image.queryIconFromResource" href="#win.image.queryIconFromResource">&#x23;</a>

```aardio
win.image.queryIconFromResource(/*图标数据或路径*/,true,  

	function(count,index,width,height,bpp,colorCount,planes){  
		if ( width == 48 & bpp == 32 ) {    
			return true;  
		}  
	}  
)
```

### win.image.setIcon(窗口句柄,图标句柄,是否大图标) <a id="win.image.setIcon" href="#win.image.setIcon">&#x23;</a>
设置窗口图标。  
此函数设置的图标窗口不会负责自动释放。  

参数 @3 设为 true 仅设置大图标,设为 false 仅设置小图标  
如果替换了小图标,返回值为窗口原来的小图标  
如果替换了大图标,返回值为窗口原来的大图标  

设置 aardio 窗口的图标请改用 win.form 对象的 setIcon 方法（支持自动选择分辨率，自动释放图标）。
