资源文件
图标、光标、字符串、菜单、快捷键和对话框资源,位图资源等等都属于资源文件。
资源脚本文件:.rc文件。资源ID管理:resourse.h文件。
添加资源大概流程:先新建一种资源,然后取一个ID,利用MAKEINTRESOURCE这个函数可以将数字类型的资源ID转换成字符传形式。在注册类或者创建窗口的时候添加,前者是该类创建的所有窗口生效,后者是单个窗口生效。
菜单资源
wce.lpszMenuName = MAKEINTRESOURCE(ID);//注册时候添加
//createwindow函数的倒数第四个参数
//HMENU hMenu, // menu handle or child identifier,菜单句柄
/***************
从硬盘加载资源到本进程内存。
HMENU LoadMenu(
HINSTANCE hInstance, // handle to module,模块句柄,为了找到进程内存。
LPCTSTR lpMenuName // menu name or resource identifier,字符串形式ID
);
****************/
HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(ID));
CreateWindow(...,hMenu,...);
图标资源
图标资源可以定义大小,一个图标文件里面可以有多个不同大小的图标。一般后缀是.ico。
窗口类注册的时候:
//LoadIcon的参数和LoadMenu一样。
wce.hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(ID1));
wce.hIconSm = LoadIcon(g_hInst, MAKEINTRESOURCE(ID2));
//上面的叫大图标,表示在窗口切换ALT+TAB的时候显示。
//下面的叫小图标,在窗口的标题栏显示。
动态修改图标:发送WM_SETICON消息,然后系统会自动处理。
SendMessage(
(HWND) hWnd, // handle to destination window
WM_SETICON, // message to send
(WPARAM) wParam, // icon type,图标类型,是大是小,ICON_BIG,ICON_SMALL。
(LPARAM) lParam // handle to icon (HICON),图标句柄,需要强转下。
);
画图标:
BOOL DrawIcon(
HDC hDC, // handle to DC
int X, // x-coordinate of upper-left corner
int Y, // y-coordinate of upper-left corner
HICON hIcon // handle to icon
);
//在WM_PAINT里面处理即可
光标资源
大小默认是32*32像素。光标比较特殊的地方在于会和系统有部分冲突,比如实时修改。
其次系统为光标提供了很多种默认的样子,具体的看LoadCursor在MSDN的介绍。
还有就是光标一般和鼠标位置一起使用。
//注册的时候,默认是在窗口客户区生效。
wce.hCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_CURSOR1));
//加载:
HCURSOR LoadCursor(
HINSTANCE hInstance, // handle to application instance
LPCTSTR lpCursorName // name or resource identifier
);
//如果hInstance为空,则获取系统默认的HCURSOR
//修改:
HCURSOR SetCursor(
HCURSOR hCursor // handle to cursor
);
//传入目标图标句柄,返回原来的图标句柄,方便来回更换。
动态修改光标:
case WM_SETCURSOR:
if( TRUE == OnSetCursor(hWnd, nMsg,wParam, lParam ))
return 0;
/***************
WM_SETCURSOR:
WPARAM:当前使用的光标句柄。
LPARAM:低八位,鼠标的范围,HTCLIENT表示客户区,HTCAPTION表示标题栏。
高八位,当前鼠标消息ID
***************/
BOOL OnSetCursor( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
{
int nHitTest = LOWORD( lParam );
if( HTCLIENT != nHitTest )
return FALSE;
//获得窗口的客户区
RECT rcClient = { 0 };
GetClientRect( hWnd, &rcClient );
//获得当前光标的位置
POINT ptPos = { 0 };
GetCursorPos( &ptPos );
ScreenToClient( hWnd, &ptPos );
//根据位置加载光标
HCURSOR hCursor = NULL;
if( ptPos.x < rcClient.right/2 )
{
if( ptPos.y < rcClient.bottom/2 )
{
hCursor = LoadCursor( NULL, IDC_SIZEALL );
}
else
{
hCursor = LoadCursor( NULL, IDC_CROSS );
}
}
else
{
if( ptPos.y < rcClient.bottom/2 )
{
hCursor = LoadCursor( NULL, IDC_WAIT );
}
else
{
hCursor = LoadCursor( NULL, IDC_UPARROW );
}
}
// 设置光标
SetCursor( hCursor );
return TRUE;
}
字符串资源
字符串资源就是一个字符串表,和一个小型的数据库很类似。如果不想通过文件传递,可以通过这个,但是考虑到代码的可改型,一般都选择从文件读取。
int LoadString(
HINSTANCE hInstance, // handle to resource module
UINT uID, // resource identifier
LPTSTR lpBuffer, // resource buffer
int nBufferMax // size of buffer
);
CHAR szText[260] = { 0 };
LoadString( g_hInst, IDS_MAIN, szText, 260 );
快捷键资源
快捷键是有个表的,每个ID对应一个快捷键处理。
//加载:
HACCEL LoadAccelerators(
HINSTANCE hInstance, // handle to module
LPCTSTR lpTableName // accelerator table name,快捷键表
);
处理快捷键消息是在消息处理里面:
TranslateAccelerator检测消息是否是WM_KEYDOWN/WM_SYSKEYDOWN。获取按键状态,然后在快捷键表里面找,找到了ID则发送WM_COMMAND消息。
//加载快捷键表
HACCEL hAccel = LoadAccelerators(g_hInst, MAKEINTRESOURCE(IDR_ACCEL));
//消息循环
MSG msg = { 0 };
while( GetMessage( &msg, NULL, 0, 0 ) )
{
// 增加快捷键的消息处理
if( !TranslateAccelerator( hWnd, hAccel, &msg ) )//如果是快捷键,返回非0
{
//字符消息处理
TranslateMessage( &msg );
//消息派发
DispatchMessage( &msg );
}
}
//消息处理函数里面
void OnCommand( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
{
int nCmdID = LOWORD( wParam );
switch( nCmdID )
{
case ID_NEW:
//WM_COMMOND里面,WPARAM的高八位,为1表示快捷键,0表示菜单;低八位为命令ID。
if(HIWORD(wParam) == 0){菜单消息}
else if(HIWORD(wParam) == 1){快捷键消息}
break;
case YOUR_ID://自己的消息ID则不会冲突。
//添加自己的处理。
break;
}
}