Windows API 函数 LoadIcon的使用

LoadIcon函数用于加载应用程序或系统中的图标资源。参数包括模块实例句柄和图标资源名或标识符。在使用系统预定义图标时,hInstance需设为NULL。文章通过代码示例展示了如何在C++中加载标准图标和自定义图标,以及在MFC中使用LoadIcon和LoadStandardIcon函数的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LoadIcon的使用

 函数原型:

 HICON WINAPI LoadIcon ( HINSTANCE hInstance, LPCTSTR lpIconName );

参数

1.hInstance类型:HINSTANCE

图标资源所在模块的实例句柄。如果是标准图标,此参数必须为NULL。


2.lpIconName类型:LPCTSTR
图标资源名或资源标识符,资源标识符由16位组成,在低16位,高16位为0。宏 MAKEINTRESOURCE 可以将资源标识符强制转换成参数的资源名类型。如果使用预定义的图标,需要将hInstance参数设置成NULL,并且lpIconName值必须是以下之一:

宏名宏值意义
IDI_APPLICATIONMAKEINTRESOURCE(32512)默认应用程序图标
IDI_ASTERISKMAKEINTRESOURCE(32516)星状图标,同 IDI_INFORMATION
IDI_ERRORMAKEINTRESOURCE(32513)手型图标
IDI_EXCLAMATIONMAKEINTRESOURCE(32515)感叹号状图标,同 IDI_WARNING
IDI_HANDMAKEINTRESOURCE(32513)手型图标,同 IDI_ERROR
IDI_INFORMATIONMAKEINTRESOURCE(32516)星状图标
IDI_QUESTIONMAKEINTRESOURCE(32514)问号图标
IDI_SHIELDMAKEINTRESOURCE(32518)安全防护罩图标
IDI_WARNINGMAKEINTRESOURCE(32515)感叹号状图标
IDI_WINLOGOMAKEINTRESOURCE(32517)默认应用程序图标(Windows 2000 为Windows Logo图标)

返回值

类型:HICON

如果成功,返回最近一次加载的图标句柄。
如果失败,返回NULL。

 

注意:

1、使用系统预定义图标,必须第一个参数设置为NULL.

在初始化时,我们可以这样使用:

wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;

相应的显示:

 

2、另外,我们也可以使用自定义的图标:

用到MAKEINTRESOURCE宏(这个宏是把一个数字类型 转换成 指针类型的宏, 原因是有的资源是用序号定义的,而不是字符串.)

wndclass.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1)) ;

 

在VS2012下的Resource View下的项目添加ICO文件,它会生成ID号,默认的IDI_ICON1.

3、常用的形式

3.1 在CWinApp中封装有该成员函数,有2种:

HICON LoadIcon( LPCTSTR lpszResourceName ) const;

HICON LoadIcon( UINT nIDResource ) const;

所以如果添加了资源,ID 为IDI_ICON1,调用时直接:

AfxGetApp()->LoadIcon(IDI_ICON1);

但是这种方法并不能加载系统预定义图标,在CWinApp中还有个装载图标的函数:

HICON LoadStandardIcon( LPCTSTR lpszIconName ) const;

如:

AfxGetApp()->LoadStandardIcon(IDI_QUESTION);

3.2 当然在MFC中可以调用全局函数加载图标,但是如果要装载自己添加的图标资源,要注意下面几种写法:

LoadIcon(AfxGetApp()->m_hInstance,(LPCTSTR)IDI_ICON1);

LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(ICON1));

LoadIcon(AfxGetInstanceHandle(),,MAKEINTRESOURCE(ICON1));

以上都是正确的.

<think>好的,我现在需要帮用户把之前提供的Vue组件代码封装成一个可复用的Composable,也就是Vue 3中的use函数。用户给出的代码已经实现了动态加载图标的功能,但现在是希望将其封装成use函数,方便在其他组件中复用。 首先,我需要理解用户提供的代码结构。原代码中,他们导入了defineAsyncComponent和ref,以及所有图标。然后定义了一个校验函数isValidIcon,用来检查传入的图标名是否有效。接着是loadIcon函数,根据图标名动态加载对应的组件,如果无效则加载默认图标。最后通过computed属性currentIcon来返回加载的组件。 现在要将其封装成use函数,通常Vue 3的Composable是以use开头的函数,比如useIconLoader。这个函数应该接收参数,比如后台传递的图标名称,然后返回相关的响应式变量和方法。 首先,我需要确定这个Composable需要接收哪些参数。从原代码看,主要需要的是backendIconName,这可能是一个ref或者字符串。不过考虑到响应式,应该接受一个ref作为参数,或者内部自己创建。 接下来,封装校验函数。原来的isValidIcon是检查传入的名称是否在AllIcons的键中。这部分可以保留在Composable内部,作为辅助函数。 然后,动态加载图标的逻辑也需要封装进去。loadIcon函数需要处理动态导入,并且返回一个异步组件。这部分可以移动到Composable内部,可能作为一个内部函数。 原代码中的currentIcon是一个computed属性,根据backendIconName.value动态加载图标。在Composable中,可能需要将其作为返回值的一部分,让组件可以访问到当前图标组件。 另外,错误处理也需要考虑,比如加载失败时使用默认图标。原代码中已经在loadIcon里处理了,可能需要保留这部分逻辑。 还需要考虑类型校验,比如确保传入的图标名称是有效的,但原代码已经通过isValidIcon实现了。 然后,思考如何将上述逻辑组织成一个use函数函数的结构可能是这样的: 1. 导入必要的Vue API和图标库。 2. 定义useIconLoader函数,接收backendIconName参数。 3. 在函数内部定义isValidIcon。 4. 定义loadIcon方法,处理动态加载。 5. 使用computed来根据backendIconName的变化更新当前图标。 6. 返回currentIcon或者其他必要的值。 另外,是否需要让外部可以访问到校验函数?或者是否需要提供手动重新加载的方法?这取决于用户的需求,但原代码中没有提到,可能暂时不需要。 可能的实现步骤: - 创建useIconLoader.js文件,导出useIconLoader函数。 - 函数内部导入AllIcons和defineAsyncComponent。 - 接收一个iconName的ref作为参数。 - 创建isValidIcon函数。 - 定义loadIcon函数,处理动态导入。 - 创建currentIcon的computed属性,依赖iconName的变化。 - 返回currentIcon,以便组件中使用。 然后,在组件中使用时,只需要调用useIconLoader,传入backendIconName的ref,然后绑定到组件上。 另外,需要注意路径是否正确。原代码中的动态导入路径是@vicons/ionicons5/es/${name},需要确保在封装后路径依然正确。可能需要保持这个路径,或者允许用户配置路径,但原代码中没有提到,所以暂时保持原样。 错误处理方面,原代码在loadIcon中如果发现无效名称,会加载默认图标。这里需要确保默认图标的路径正确,或者在Composable中允许用户自定义默认图标路径。但根据原代码,暂时保持默认路径为'./DefaultIcon.vue',可能需要用户自己确保该组件存在,或者提供选项参数。 另外,在Composable中是否需要处理异步加载的状态,比如加载中或加载错误?原代码中使用了Suspense,但在封装后,可能需要让用户自己处理,或者在Composable中返回加载状态。不过原示例中没有提到,可能暂时不考虑,保持简单。 最后,测试这个Composable是否正常工作,确保当iconName变化时,currentIcon能正确更新,并加载对应的图标。 总结步骤: 1. 创建useIconLoader函数,接收iconName的ref。 2. 在函数内部导入所有图标,并定义校验函数。 3. 定义动态加载函数,处理有效性和路径。 4. 创建computed属性,返回异步组件。 5. 返回currentIcon供组件使用。</think>--- ### **Composable 封装实现** 以下是将原有逻辑封装为 Vue 3 Composable 的完整方案: ```typescript // useDynamicIcon.ts import { defineAsyncComponent, computed, type Ref } from 'vue' import * as AllIcons from '@vicons/ionicons5' interface IconLoaderOptions { fallbackComponent?: string // 可配置的备用组件路径 enablePreCheck?: boolean // 是否启用预校验 } export function useDynamicIcon( iconName: Ref<string>, options: IconLoaderOptions = { fallbackComponent: './DefaultIcon.vue', enablePreCheck: true } ) { // 校验逻辑复用 const isValidIcon = (name: string) => Object.keys(AllIcons).includes(name) // 核心加载器 const loadIcon = (name: string) => { if (options.enablePreCheck && !isValidIcon(name)) { console.error(`[IconLoader] Invalid icon name: ${name}`) return defineAsyncComponent(() => import(options.fallbackComponent!)) } return defineAsyncComponent(() => import(`@vicons/ionicons5/es/${name}`) .then(module => ({ default: module[name] || module.default })) .catch(() => import(options.fallbackComponent!)) ) } // 响应式图标引用 const currentIcon = computed(() => loadIcon(iconName.value)) return { currentIcon, isValidIcon // 暴露校验方法供外部使用 } } ``` --- ### **使用示例** 在 Vue 组件中的调用方式: ```vue <script setup lang="ts"> import { ref } from 'vue' import { useDynamicIcon } from './useDynamicIcon' const backendIconName = ref('WineOutline') // 来自后台的图标名称 const { currentIcon } = useDynamicIcon(backendIconName, { fallbackComponent: './assets/MyFallbackIcon.vue' }) </script> <template> <component :is="currentIcon" class="icon-style" /> </template> ``` --- ### **进阶功能扩展** #### **1. 类型增强** 创建类型声明文件 `iconTypes.d.ts`: ```typescript // 自动生成所有可用图标名称类型 type IonIcons = keyof typeof import('@vicons/ionicons5') declare const __ALL_ICON_NAMES: IonIcons[] ``` #### **2. 缓存机制** ```typescript // 在 Composable 中添加缓存逻辑 const iconCache = new Map<string, Component>() const loadIconWithCache = (name: string) => { if (iconCache.has(name)) { return iconCache.get(name)! } const component = loadIcon(name) iconCache.set(name, component) return component } ``` --- ### **工程化配置** #### **vite.config.ts 优化** ```typescript export default defineConfig({ resolve: { alias: { '@icons': path.resolve(__dirname, './src/assets/icons') } }, build: { rollupOptions: { output: { manualChunks(id) { if (id.includes('@vicons/ionicons5')) { return 'ionicons' } } } } } }) ``` --- ### **性能监控(示例)** ```typescript // 添加性能追踪 const startLoadTime = Date.now() performance.mark('icon-load-start') return defineAsyncComponent({ loader: () => import(`@vicons/ionicons5/es/${name}`), delay: 200, timeout: 3000, onError: (error) => { console.error(`[IconLoader] Load failed: ${error}`) }, onLoad: () => { performance.measure('icon-load-duration', 'icon-load-start') } }) ``` --- ### **实现原理图示** ```mermaid graph TD A[后台传递图标名称] --> B{校验有效性} B -->|有效| C[动态加载对应图标] B -->|无效| D[加载备用图标] C --> E[缓存组件实例] D --> F[返回备用组件] E --> G[响应式更新视图] F --> G ``` --- ### **最佳实践建议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值