一个win32程序如何使用自定义图标?

纹枰老妖 2015-11-10 05:27:36
我用vs2013写了一个win32程序,下面是源代码:
#include <Windows.h>
#define WINDOW_WIDTH 800 //为窗口宽度定义的宏,方便在此处修改窗口
#define WINDOW_HEIGHT 600 //为窗口高度定义的宏
#define WINDOW_TITLE L"【致我们的游戏开发梦想】程序核心框架" //为窗口标题定义的宏

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//【1】窗口设计四部曲之一:开始设计一个完整的窗口类
WNDCLASSEX wndClass = { 0 };
wndClass.cbSize = sizeof(wndClass); //设置结构体的字节大小
wndClass.style = CS_HREDRAW | CS_VREDRAW; //设置窗口样式
wndClass.lpfnWndProc = WndProc; //设置指向窗口过程处理函数的指针
wndClass.cbClsExtra = 0; //窗口类的附加内存,取0就可以了
wndClass.cbWndExtra = 0; //窗口的附加内存,同样取0
wndClass.hInstance = hInstance; //指定包含窗口过程的程序的实例句柄
wndClass.hIcon = (HICON)::LoadImage(NULL, L"icon1.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); //本地加载自定义icon图标
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); //指定窗口类的光标句柄
wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); //为hbrbackground成员指定一个灰色画刷句柄
wndClass.lpszMenuName = NULL; //用一个以空终止的字符串,指定菜单资源的名字
wndClass.lpszClassName = L"ForTheDreamOfGameDevelop"; //用一个以空终止的字符串,指定窗口类的名字


//【2】窗口创建四部曲之二,注册窗口类
if (!RegisterClassEx(&wndClass)) return -1;


//【3】窗口创建四部曲之三:正式创建窗口
HWND hwnd = CreateWindow(L"ForTheDreamOfGameDevelop", WINDOW_TITLE, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);

//【4】窗口创建四部曲之四:窗口的移动、更新与显示
MoveWindow(hwnd, 250, 80, WINDOW_WIDTH, WINDOW_HEIGHT, true); //窗口显示时的位置,左上角位于 250、80处
ShowWindow(hwnd, nShowCmd); //调用showwindow函数来显示窗口
UpdateWindow(hwnd);


//【5】消息循环过程
MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
if (PeekMessage( &msg,0,0,0,PM_REMOVE )) //查看应用程序消息队列,有消息时将队列中的消息派发出去
{
TranslateMessage(&msg); //将虚拟键消息转换为字符消息
DispatchMessage(&msg); //分发一个消息给窗口程序
}
}


//【6】窗口的注销
UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance);


return 0;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
ValidateRect(hwnd, NULL);
break;
case WM_KEYDOWN:
if (wParam==VK_ESCAPE)
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}

return 0;
}


然后我在工程资源那里添加了一个自定义的图标,如图:

可为什么最后运行的结果是:
...全文
766 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
纹枰老妖 2015-12-01
  • 打赏
  • 举报
回复
引用 25 楼 SXJIAKE 的回复:
[quote=引用 24 楼 wenpinglaoyao 的回复:] [quote=引用 23 楼 SXJIAKE 的回复:] 目测楼主不适合搞 Windows 编程,资源文件 rc 或 res 都不知道。 这么多人说了这么多,最后居然是“直接加载本地文件”的帖子得分…… 以后你干脆对话框也从本地加载得了……
惭愧,本人笨点。。。 之所以让11楼的朋友得分最多,是因为貌似他对这个问题耗费的心血最多,这点让我颇为感动。 最后我诚挚的对您说声真对不起!您的指点竟然没有得分,这不应该,也确实是我的大意疏忽。。。[/quote]这不能怪你,或许你还没看明白而已,其他很多人也提到了资源。资源文件这个你是必须要了解的,否则你根本没法开始 Windows 编程。[/quote] 嗯,确实还没弄明白,本人只会写一些控制台的小程序,可视化的编程一窍不通。比如贪吃蛇,程序算法我可以很容易搞出来,但如何让它生龙活虎的表现出来,我却一筹莫展。 我会努力的,谢谢您的指点,再有缘的话,一定会加倍补偿您的热心!!!
「已注销」 2015-11-30
  • 打赏
  • 举报
回复
目测楼主不适合搞 Windows 编程,资源文件 rc 或 res 都不知道。 这么多人说了这么多,最后居然是“直接加载本地文件”的帖子得分…… 以后你干脆对话框也从本地加载得了……
「已注销」 2015-11-30
  • 打赏
  • 举报
回复
引用 24 楼 wenpinglaoyao 的回复:
[quote=引用 23 楼 SXJIAKE 的回复:] 目测楼主不适合搞 Windows 编程,资源文件 rc 或 res 都不知道。 这么多人说了这么多,最后居然是“直接加载本地文件”的帖子得分…… 以后你干脆对话框也从本地加载得了……
惭愧,本人笨点。。。 之所以让11楼的朋友得分最多,是因为貌似他对这个问题耗费的心血最多,这点让我颇为感动。 最后我诚挚的对您说声真对不起!您的指点竟然没有得分,这不应该,也确实是我的大意疏忽。。。[/quote]这不能怪你,或许你还没看明白而已,其他很多人也提到了资源。资源文件这个你是必须要了解的,否则你根本没法开始 Windows 编程。
纹枰老妖 2015-11-30
  • 打赏
  • 举报
回复
引用 23 楼 SXJIAKE 的回复:
目测楼主不适合搞 Windows 编程,资源文件 rc 或 res 都不知道。 这么多人说了这么多,最后居然是“直接加载本地文件”的帖子得分…… 以后你干脆对话框也从本地加载得了……
惭愧,本人笨点。。。 之所以让11楼的朋友得分最多,是因为貌似他对这个问题耗费的心血最多,这点让我颇为感动。 最后我诚挚的对您说声真对不起!您的指点竟然没有得分,这不应该,也确实是我的大意疏忽。。。
纹枰老妖 2015-11-29
  • 打赏
  • 举报
回复
引用 21 楼 lsq19871207 的回复:
[quote=引用 20 楼 wenpinglaoyao 的回复:] [quote=引用 19 楼 lsq19871207 的回复:] [quote=引用 18 楼 wenpinglaoyao 的回复:] 谢谢您的回复。我马上结贴。新建res文件夹的时候,需要加什么后缀吗?
文件夹名有后缀吗?[/quote] 好吧,是我傻冒了。。。 按照您在11楼的指点步骤,我照做之后程序编译错误,错误提示是找不到标识符,错误定位在【for (i = lstrlen(__szWorkingDir__); i>0 && __szWorkingDir__[i] != _T('\\'); __szWorkingDir__[i--] = 0);】这一句,就是里面那个【 _T 】,编译器说找不到它的标识符,是不是我忘了包含什么头文件啊?[/quote] 你是猴子起来的逗比吗..... 看样子你肯定不懂什么是字符集的概念,下去自己学习吧 在#include <windows.h>后面加上#include <tchar.h> 顺便把工程配置属性——>常规 右边栏中的“字符集”设置为“使用 Unicode 字符集” 当然,你不设置,就使用多字符集也是可以的[/quote] 好吧,谢谢您的热心回复!祝生活愉快。
信阳毛尖 2015-11-28
  • 打赏
  • 举报
回复
引用 20 楼 wenpinglaoyao 的回复:
[quote=引用 19 楼 lsq19871207 的回复:] [quote=引用 18 楼 wenpinglaoyao 的回复:] 谢谢您的回复。我马上结贴。新建res文件夹的时候,需要加什么后缀吗?
文件夹名有后缀吗?[/quote] 好吧,是我傻冒了。。。 按照您在11楼的指点步骤,我照做之后程序编译错误,错误提示是找不到标识符,错误定位在【for (i = lstrlen(__szWorkingDir__); i>0 && __szWorkingDir__[i] != _T('\\'); __szWorkingDir__[i--] = 0);】这一句,就是里面那个【 _T 】,编译器说找不到它的标识符,是不是我忘了包含什么头文件啊?[/quote] 你是猴子起来的逗比吗..... 看样子你肯定不懂什么是字符集的概念,下去自己学习吧 在#include <windows.h>后面加上#include <tchar.h> 顺便把工程配置属性——>常规 右边栏中的“字符集”设置为“使用 Unicode 字符集” 当然,你不设置,就使用多字符集也是可以的
纹枰老妖 2015-11-28
  • 打赏
  • 举报
回复
引用 19 楼 lsq19871207 的回复:
[quote=引用 18 楼 wenpinglaoyao 的回复:] 谢谢您的回复。我马上结贴。新建res文件夹的时候,需要加什么后缀吗?
文件夹名有后缀吗?[/quote] 好吧,是我傻冒了。。。 按照您在11楼的指点步骤,我照做之后程序编译错误,错误提示是找不到标识符,错误定位在【for (i = lstrlen(__szWorkingDir__); i>0 && __szWorkingDir__[i] != _T('\\'); __szWorkingDir__[i--] = 0);】这一句,就是里面那个【 _T 】,编译器说找不到它的标识符,是不是我忘了包含什么头文件啊?
信阳毛尖 2015-11-27
  • 打赏
  • 举报
回复
引用 18 楼 wenpinglaoyao 的回复:
谢谢您的回复。我马上结贴。新建res文件夹的时候,需要加什么后缀吗?
文件夹名有后缀吗?
纹枰老妖 2015-11-27
  • 打赏
  • 举报
回复
谢谢您的回复。我马上结贴。新建res文件夹的时候,需要加什么后缀吗?
信阳毛尖 2015-11-27
  • 打赏
  • 举报
回复
引用 15 楼 wenpinglaoyao 的回复:
[quote=引用 10 楼 lsq19871207 的回复:] 你如果使用了LR_LOADFROMFILE标识,那么第二个参数就是文件所在的路径,你直接写个icon.ico,它到哪儿找去啊??
大哥我最后的问题:比如您用您的vs创建了一个空项目的win32工程,里面的代码就是我帖子里的源代码。然后您F5运行会生成一个程序框架,但您对框架里面的图标不满意,于是您想换成一个自定义的图标,比如您电脑里的一张自拍照,您会怎么做??[/quote] 在工程的输出目录(Debug/Release)目录下新建一个res文件夹,把icon.ico文件拷贝到res目录下 剩下的请见我11L说的 这样做的目的是为了通用性,不要加载到.rc里面去,通过资源ID来加载。给你举一种情况吧: 目前我对这个icon.ico很满意,编译好了,运行起来给测试妹子看,嘚瑟吧唧的,结果妹子说你的程序图标太TM丑了,客户肯定不喜欢,必须得改掉 不一会儿配合你修改的UI的妹子发了一个xxoo.ico文件给你,你就该吧: 1、如果通过文件名来加载,那么你需要做的简直太TM少了,把xxoo.ico文件的文件名改成icon.ico并拷贝到应用程序目录下的res目录中替换掉原来的icon.ico文件,双击exe运行看看如何,直接打包,发布测试 2、如果是通过资源ID来修改,你就哭吧,先打开VS,再打开工程,把xxoo.ico拷贝到工程目录,添加资源,修改rc文件中的资源与ID对应关系.......... F7,F5,再release编译、打包、发布测试。。。。 要是你,你选哪个? 总之,要学会做一名偷懒的程序猿,善于偷懒
纹枰老妖 2015-11-27
  • 打赏
  • 举报
回复
引用 13 楼 fhw_bin_dl 的回复:
wndClass.hIconSm = (HICON)::LoadImage(...);
按照您的提示,我把那个wndClass.hIcon改成了wndClass.hIconSm,然后运行程序后,还是没有达到我期望的效果。顺带多问一句:那个hIconSm和hIcon有什么不同?
纹枰老妖 2015-11-27
  • 打赏
  • 举报
回复
引用 10 楼 lsq19871207 的回复:
你如果使用了LR_LOADFROMFILE标识,那么第二个参数就是文件所在的路径,你直接写个icon.ico,它到哪儿找去啊??
大哥我最后的问题:比如您用您的vs创建了一个空项目的win32工程,里面的代码就是我帖子里的源代码。然后您F5运行会生成一个程序框架,但您对框架里面的图标不满意,于是您想换成一个自定义的图标,比如您电脑里的一张自拍照,您会怎么做??
「已注销」 2015-11-26
  • 打赏
  • 举报
回复
资源应该是以 rc 文件形式存在,ico 是 rc 中的资源之一,并且具有一个唯一的名字或 id。LoadImage 不是传 icon.ico 的名字,而是传那个“唯一的名字或 id”,且不能有 LR_LOADFROMFILE。
信阳毛尖 2015-11-25
  • 打赏
  • 举报
回复
比如你当前是debug模式,你在你的debug目录下新建一个res文件夹,把icon.ico文件拷贝到res目录下:

TCHAR __szWorkingDir__[MAX_PATH] = {0};   //存放当前工作目录
HINSTANCE hAppIns = GetModuleHandle(NULL);
GetModuleFileName(hAppIns,__szWorkingDir__,MAX_PATH);
int i = 0;
for(i=lstrlen(__szWorkingDir__);i>0&&__szWorkingDir__[i]!=_T('\\');__szWorkingDir__[i--]=0);

TCHAR szIconPath[MAX_PATH] = {0};
wsprintf(szIconPath,_T("%sres\\%s"),__szWorkingDir__,_T("icon.ico"));
wndClass.hIcon = (HICON)::LoadImage(hInstance, szIconPath, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
信阳毛尖 2015-11-25
  • 打赏
  • 举报
回复
你如果使用了LR_LOADFROMFILE标识,那么第二个参数就是文件所在的路径,你直接写个icon.ico,它到哪儿找去啊??
fhw217 2015-11-25
  • 打赏
  • 举报
回复
wndClass.hIconSm = (HICON)::LoadImage(...);
worldy 2015-11-25
  • 打赏
  • 举报
回复
引用 8 楼 wenpinglaoyao 的回复:
[quote=引用 7 楼 iswjh 的回复:] wndClass.hIcon=LoadImage(hInstance 第一个参数要改成模块句柄
按照您的提示,我把第19行的代码改成【 wndClass.hIcon = (HICON)::LoadImage(hInstance, L"icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); 】形式,但还是不能随心所欲的使用我想用的图标,特别说明一下,我想用的图标指的是我随便截的图,不过把后缀改成【 .ico 】而已。 最后,谢谢您的热心!![/quote] 不可以,必须将裁图转换为icon格式
纹枰老妖 2015-11-25
  • 打赏
  • 举报
回复
引用 9 楼 worldy 的回复:
[quote=引用 8 楼 wenpinglaoyao 的回复:] [quote=引用 7 楼 iswjh 的回复:] wndClass.hIcon=LoadImage(hInstance 第一个参数要改成模块句柄
按照您的提示,我把第19行的代码改成【 wndClass.hIcon = (HICON)::LoadImage(hInstance, L"icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); 】形式,但还是不能随心所欲的使用我想用的图标,特别说明一下,我想用的图标指的是我随便截的图,不过把后缀改成【 .ico 】而已。 最后,谢谢您的热心!![/quote] 不可以,必须将裁图转换为icon格式[/quote] 也就是说,单纯的更改一下后缀名并没有效果,对吗?
纹枰老妖 2015-11-24
  • 打赏
  • 举报
回复
引用 7 楼 iswjh 的回复:
wndClass.hIcon=LoadImage(hInstance 第一个参数要改成模块句柄
按照您的提示,我把第19行的代码改成【 wndClass.hIcon = (HICON)::LoadImage(hInstance, L"icon.ico", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); 】形式,但还是不能随心所欲的使用我想用的图标,特别说明一下,我想用的图标指的是我随便截的图,不过把后缀改成【 .ico 】而已。 最后,谢谢您的热心!!
iswjh 2015-11-23
  • 打赏
  • 举报
回复
wndClass.hIcon=LoadImage(hInstance 第一个参数要改成模块句柄
加载更多回复(6)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧