13.资源

1.资源的使用

  (1)资源相关

     资源脚本文件:*.rc文件

     编译器:RC.exe

2.菜单资源的使用

  (1)添加菜单资源

  (2)加载菜单资源

     在注册时设置菜单资源

     加载菜单资源,设置到窗口

     HMENU LoadMenu( HINSTANCE  hInstance,

                                          LPCTSTR      lpMenuName);

     CreateWindow/CreateWindowEx

     SetMenu

3.图标资源ICON的使用

  (1)添加图标资源

     注意图标的大小,一个图标文件中可以有多个大小不同的图标。

  (2)加载

     HICON LoadIcon( HINSTANCE  hInstance,

                                       LPCTSTR      lpIconName);

     成功返回HICON句柄。

  (3)设置

     注册窗口类和WM_SETICON消息时,设置icon图标。

  (4)绘制

     DrawIcon - 在窗口客户区中绘制一个图标

     //在窗口中绘制一个.ico为后缀的图片

     BOOL DrawIcon( HDC     hDc,      //绘图设备句柄

                                       int       x,          //水平坐标

                                       int       y,          //垂直坐标

                                       HICON  hIcon);  //图标句柄

4.光标资源的使用  

  (1)添加光标资源

     光标的大小默认是32x32像素,每个光标有HotSpot,是鼠标的当前热点。

  (2)使用资源

     HCURSOR LoadCursor( HINSTANCE  hInstance,

                                                LPCTSTR      lpCursorName);

     在注册窗口时,设置光标

     HCURSOR SetCursor(HCURSOR hCursor);

  (3)光标的使用

     WM_SETCURSOR消息,在不捕获光标的前提下,鼠标移动就产生。

       wPARAM: 当前光标句柄

       lPARAM:LOWORD - 鼠标活动区域(Hit-Test code),HTCLIENT/HTCAPTION

                    HIWORD - 消息ID

  相关示例代码: 

#include "stdafx.h"

HINSTANCE g_hInstance = 0;  //接收当前程序实例句柄

void OnCommand(HWND hWnd, WPARAM wParam)
{
    switch (LOWORD(wParam))
    {
    case ID_NEW:
        MessageBox(hWnd, "新建被点击", "Info", MB_OK);
        break;
    case ID_EXIT:
        MessageBox(hWnd, "退出被点击", "Info", MB_OK);
        break;
    case ID_ABOUT:
        MessageBox(hWnd, "关于被点击", "Info", MB_OK);
        break;
    }
}
void OnPaint(HWND hWnd)
{
    PAINTSTRUCT ps = { 0 };
    HDC hdc = BeginPaint(hWnd, &ps);
    HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON1));
    DrawIcon(hdc, 100, 100, hIcon);
    EndPaint(hWnd, &ps);
}

void OnSetCursor(HWND hWnd, WPARAM wParam)
{
    RECT rc = { 0 };
    GetClientRect(hWnd, &rc);//获取窗口的边界信息(客户区坐标系)
    POINT pt = { 0 };
    GetCursorPos(&pt);//获取光标的位置(屏幕坐标系)
    ScreenToClient(hWnd, &pt);//将屏幕坐标系坐标转换成窗口客户区坐标
    HCURSOR hCross = LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
    HCURSOR hBall = LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_CURSOR2));
    if (pt.x <= rc.right / 2)
    {        
        SetCursor(hCross);
    }
    else
    {       
        SetCursor(hBall);
    }
    
}
//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_SETCURSOR:
        /*
        if(LOWORD(lParam) ==  HTCLIENT)
        {
            HCURSOR hBall = LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_CURSOR2));
            SetCursor(hBall);
            return 0;
        }*/
        OnSetCursor(hWnd, wParam);
        return 0;
        break;
    case WM_PAINT:
        OnPaint(hWnd);
        break;
    case WM_COMMAND:
        OnCommand(hWnd, wParam);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
{
    WNDCLASSEX wce = { 0 };

    wce.cbSize        = sizeof(wce);
    wce.cbClsExtra    = 200;
    wce.cbClsExtra    = 200;
    wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wce.hCursor       = LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
    wce.hIcon         = NULL;  //LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON1));
    wce.hIconSm       = NULL;  //LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON2));
    wce.hInstance     = g_hInstance;
    wce.lpfnWndProc   = wndProc;
    wce.lpszClassName = lpClassName;
    wce.lpszMenuName  = NULL;  //MAKEINTRESOURCE(IDR_MENU1); //将数字形式的资源ID转换成字符串形式的资源ID
    wce.style         = CS_HREDRAW | CS_VREDRAW;

    ATOM nAtom = RegisterClassEx(&wce);
    if (0 == nAtom)
    {
        return FALSE;
    }
    return TRUE;
}
//创建主窗口
HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName)
{
    HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MENU1));

    HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW,
        400, 100, 600, 400, NULL, hMenu, g_hInstance, NULL);
    
    HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON1));
    SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);

    return hWnd;
}
//显示窗口
void Display(HWND hWnd)
{
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
}
//消息循环
void Message()
{
    MSG nMsg = { 0 };
    while (GetMessage(&nMsg, NULL, 0, 0))
    {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    g_hInstance = hInstance;
    Register("Main", WndProc);
    HWND hWnd = CreateMainWindow("Main", "window");
    Display(hWnd);
    Message();

    return 0;
}
View Code

5.字符串资源

  (1)添加字符串资源

     添加字符串表,在表中添加字符串。

  (2)字符串资源的使用

     int LoadString( HINSTANCE   hInstance,      //进程句柄

                                    UINT             hID,               //字符串ID

                                    LPTSTR         lpBuffer,         //存放字符串的buffer

                                    int                nBufferMax);   //buff长度

     成功返回字符串长度,失败返回0。 

6.加速键资源

  (1)添加

     添加加速键表,增加命令ID对应的加速键

  (2)使用

     a.加载加速键表

       HACCEL LoadAccelerators( HINSTANCE  hInstance,

                                                          LPCTSTR      lpTableName);

       返回加速键句柄

     b.翻译加速键

        int TranslateAccelerator( HWND    hWnd,        //处理消息的窗口句柄

                                                          HACCEL  hAccTable,  //加速键句柄

                                                          LPMSG    lpMsg);      //消息指针

        如果是加速键,发出WM_COMMAND消息,返回非零。

     c.在WM_COMMAND中处理消息

        wPARAM:HIWORD - 1表示加速键,0表示菜单

                                      LOWORD - 命令ID

        lPARAM:NULL

  (3)TranslateAccelerator处理过程

     TranslateAccelerator(hWNd, hAccel, &nMsg)

     {

       //1.检测是否是WM_KEYDOWN/WM_SYSKEYDOWN消息

       if (nMsg.message != WM_KEYDOWN && nMsg.message != WM_SYSKEYDOWN)

       {

         return 0;

       }

       //2.根据按键状态,从HACCEL中查找对应命令ID,发出WM_COMMAND消息

       通过nMsg.wParam(虚拟键码),可以获知哪个按键被按下(CTRL+M)。

       拿着CTRL+M到hAccel(加速键表)中匹配查找。

       if (没找到)

       {

         return 0;

       }

       else

       {

         PostMessage(nMsg.hWnd, WM_COMMAND, 加速键命令ID和1, NULL);

         return 非零;

       }

     }

  字符和加速键相关示例代码:

#include "stdafx.h"

HINSTANCE g_hInstance = 0;  //接收当前程序实例句柄

void OnCommand(HWND hWnd, WPARAM wParam)
{
    switch (LOWORD(wParam))
    {
    case ID_NEW:
        MessageBox(hWnd, "新建被点击", "Info", MB_OK);
        break;
    }
}
//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
        OnCommand(hWnd, wParam);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
{
    WNDCLASSEX wce = { 0 };

    wce.cbSize = sizeof(wce);
    wce.cbClsExtra = 200;
    wce.cbClsExtra = 200;
    wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wce.hCursor = NULL;
    wce.hIcon = NULL;
    wce.hIconSm = NULL;
    wce.hInstance = g_hInstance;
    wce.lpfnWndProc = wndProc;
    wce.lpszClassName = lpClassName;
    wce.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);//NULL;
    wce.style = CS_HREDRAW | CS_VREDRAW;

    ATOM nAtom = RegisterClassEx(&wce);
    if (0 == nAtom)
    {
        return FALSE;
    }
    return TRUE;
}
//创建主窗口
HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName)
{
    HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, g_hInstance, NULL);
    return hWnd;
}
//显示窗口
void Display(HWND hWnd)
{
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
}
//消息循环
void Message()
{
    HACCEL hAccel = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
    MSG nMsg = { 0 };
    while (GetMessage(&nMsg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(nMsg.hwnd, hAccel, &nMsg)) //不是加速键
        {
            TranslateMessage(&nMsg);
            DispatchMessage(&nMsg);
        }
    }
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    g_hInstance = hInstance;
    Register("Main", WndProc);
    char szTitle[256] = { 0 };
    LoadString(hInstance, IDS_WND, szTitle, 256);
    HWND hWnd = CreateMainWindow("Main", szTitle);
    Display(hWnd);
    Message();

    return 0;
}
View Code

    

原文地址:https://www.cnblogs.com/csqtech/p/5617473.html