15菜单、热键、光标

系统菜单

如图,这是系统给出的菜单,也可以通过资源视图-》Menu进行修改。

通过结构体WNDCLASSEX wcex 进行加载:

wcex.lpszMenuName      = MAKEINTRESOURCE(IDC_MENUDEMO2);

 

菜单的互斥

点击某一菜单,其他菜单变成不可选择。

利用EnablemenuItem() 处理,有以下两种方式:

1.EnableMenuItem(hMenu,2,MF_GRAYED|MF_BYPOSITION);

通过菜单的相对位置进行设置,选择后整个菜单栏都会变灰。如上图位置,“描图”为0,“颜色”为1,“帮助为3”。。。。

注意:若第二参数使用相对位置,那么第三个参数必须使用MF_BYPOSITION。MF_GRAYED灰度化,使2位置变灰,不可选择。

 

2.EnableMenuItem(hMenu,IDM_ABOUT,MF_GRAYED|MF_BYCOMMAND);

通过对应的菜单选项的ID进行设置,此方法可以单独设置某一选择或多个选择,不是整一个菜单栏都不可选择。

注意:若第二参数使用ID,那么第三个参数必须使用MF_ BYCOMMAND。

 

菜单的勾选

点击某一菜单选项后,其前面出现选中状态。

通过WM_INITMENUPOPUP:响应消息,及函数CheckMenuItem()。

case WM_INITMENUPOPUP:

                   if(uFlat==IDM_POINT)

                            CheckMenuItem(hMenu,IDM_POINT,MF_BYCOMMAND|MF_CHECKED);

                   else

                            CheckMenuItem(hMenu,IDM_POINT,MF_BYCOMMAND|MF_UNCHECKED);

uFlat为临时变量,判断是否被选中。

CheckMenuItem(hMenu,IDM_POINT,MF_BYCOMMAND|MF_UNCHECKED);

MF_UNCHECKED 不选中。

MF_CHECKED 选中

 

自定义菜单(右键菜单)

方法与上面的相同,在资源菜单中新建菜单,获取相应的ID。

1.加载菜单

hMyMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1));

2.设置,并显示本地菜单

         case WM_CONTEXTMENU:

                   point.x=LOWORD(lParam);

              point.y=HIWORD(lParam);       TrackPopupMenu(GetSubMenu(hMyMenu,0),TPM_LEFTALIGN|TPM_VCENTERALIGN,point.x,point.y,0,hWnd,0);

 

WM_CONTEXTMENU:相应本地菜单消息。

lParam 携带光标的坐标。

GetSubMenu(hMyMenu,0),获取本地菜单hMyMenu的下一栏。

如图,GetSubMenu将会显示2 3 4 5,不将显示1。

也可以通过GetMenu()来获取系统菜单,再将系统菜单设为本地菜单。

 

热键,或称快捷键。

如何利用WIN32已有的资源进行热键操作?

步骤:

1.在资源视图中找到Accelerator,出现如下图:

2.设置想要的按键,作为相应按钮。可以以下两个地方设置:

第一:

 

第二:

 

解析:ID,需要产生相应的控件ID,可以是系统按钮、自拟控件的ID。修饰符,有Ctrl、Alt、Shift,当我们按下某字母键时,是否需要这三个键来组合,才会响应。(True,需要。False,不需要)Key,按下哪个键去响应控件。Type,推荐使用VIRTKEY。

3.保存,运行程序,就会修改成功。

 

光标

有时需要修改鼠标的光标,或是在不用的区域显示不同的光标。

 

步骤:

1.在资源视图->Icon,添加和设定自己光标。

2.加载光标,有两个方法:

1.wcex.hIcon= LoadIcon(hInstance, IDI_ICON1);

利用WNDCLASSEX wcexd的结构体属性,进行直接加载。

  2.通过消息响应WM_SETCURSOR加载,调用函数SetCursor()。

hCursor1=LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR1));

hCursor2=LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR2));

case WM_SETCURSOR:

                   if(LOWORD(lParam)==HTCLIENT)

                            SetCursor(hCursor1);

                   else if(LOWORD(lParam)==HTCAPTION)

                            SetCursor(hCursor2);

                   break;

lParam:携带了当前光标的坐标。

HTCLIENT:代表窗口的客户区。

HTCAPTION:代表标题栏

区别:第一种方法加载简便,一次性加载,不需要每次响应。第二方法可以多样化,如上所示,可以在客户区使用一种光标,在标题栏使用另外一种光标。

另外,也可以加载动态光标,或其他文件中、桌面的光标。利用函数LoadCursorFromFile()

,参数为光标所在的路径。

 

图标

修改程序中的大图标(桌面任务栏)和小图标(程序的标题栏最左边)

 

 

方式1:通过WNDCLASSEX wcex结构体进行修改

wcex.hIcon                = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SMALL));

wcex.hIconSm          = LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_ICON1));

第一个wcex.hIcon为大图标。

第二个wcex.hIconSm 为小图标。

MAKEINTRESOURCE():为预定义,将ID转换成对应的字符串。

 

方法2:

通过函数进行修改。

hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1));

PostMessage(hWnd,WM_SETICON,ICON_BIG,(LPARAM)hIcon);

 

利用PostMessage()发送设置光标的消息.

第三个参数必须为ICON_BIG,或是ICON_SMALL.

 

 

 

部分源码:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    HMENU hMenu=GetMenu(hWnd);
    static HMENU hMyMenu;
    static HCURSOR hCursor1,hCursor2;
    static UINT uFlat=0;
    static POINT point;
    static HICON hIcon;
    switch (message)
    {
    case WM_CREATE:
        hCursor1=LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR1));
        hCursor2=LoadCursor(hInst,MAKEINTRESOURCE(IDC_CURSOR2));
        hMyMenu=LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1));
        hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1));
        break;
        //设置光标。分任务栏和客户区
    case WM_SETCURSOR:
        //判断当前光标位置
        if(LOWORD(lParam)==HTCLIENT)
            SetCursor(hCursor1);
        else if(LOWORD(lParam)==HTCAPTION)
            SetCursor(hCursor2);
        break;
    case WM_CONTEXTMENU:
        //获取当前光标位置
        point.x=LOWORD(lParam);
        point.y=HIWORD(lParam);
    TrackPopupMenu(GetSubMenu(hMyMenu,0),TPM_LEFTALIGN|TPM_VCENTERALIGN,point.x,point.y,0,hWnd,0);
    case WM_INITMENUPOPUP:
        if(uFlat==IDM_POINT)
            CheckMenuItem(hMenu,IDM_POINT,MF_BYCOMMAND|MF_CHECKED);
        else
            CheckMenuItem(hMenu,IDM_POINT,MF_BYCOMMAND|MF_UNCHECKED);
        if(uFlat==IDM_RECT)
            CheckMenuItem(hMenu,IDM_RECT,MF_BYCOMMAND|MF_CHECKED);
        else
            CheckMenuItem(hMenu,IDM_RECT,MF_BYCOMMAND|MF_UNCHECKED);
        if(uFlat==IDM_TRAG)
            CheckMenuItem(hMenu,IDM_TRAG,MF_BYCOMMAND|MF_CHECKED);
        else
            CheckMenuItem(hMenu,IDM_TRAG,MF_BYCOMMAND|MF_UNCHECKED);
        if(uFlat==IDM_CIRCLE)
            CheckMenuItem(hMenu,IDM_CIRCLE,MF_BYCOMMAND|MF_CHECKED);
        else
            CheckMenuItem(hMenu,IDM_CIRCLE,MF_BYCOMMAND|MF_UNCHECKED);
        break;
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        uFlat=wmId;
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_POINT:
            //MessageBox(hWnd,"dsd","ds",MB_OK);
            EnableMenuItem(hMenu,1,MF_GRAYED|MF_BYPOSITION);
            EnableMenuItem(hMenu,2,MF_GRAYED|MF_BYPOSITION);
            uFlat=IDM_POINT;
            DrawMenuBar(hWnd);
            break;
        case IDM_RECT:
            EnableMenuItem(hMenu,IDM_GREEN,MF_GRAYED|MF_BYCOMMAND);
            EnableMenuItem(hMenu,IDM_ABOUT,MF_GRAYED|MF_BYCOMMAND);
            uFlat=IDM_RECT;
            DrawMenuBar(hWnd);
            break;
        case IDM_TRAG:
            EnableMenuItem(hMenu,1,MF_GRAYED|MF_BYPOSITION);
            EnableMenuItem(hMenu,2,MF_ENABLED|MF_BYPOSITION);
            DrawMenuBar(hWnd);
            uFlat=IDM_TRAG;
            break;
        case IDM_CIRCLE:
            EnableMenuItem(hMenu,1,MF_ENABLED|MF_BYPOSITION);
            EnableMenuItem(hMenu,2,MF_ENABLED|MF_BYPOSITION);
            uFlat=IDM_CIRCLE;
            DrawMenuBar(hWnd);
            break;
        case IDM_ELLPSE:
            break;
        case IDM_SQUIRE:
            break;
        case IDM_RED:
            PostMessage(NULL,WM_SETICON,ICON_BIG,(LPARAM)hIcon);
            break;
        case WM_SETICON:
            MessageBox(NULL,"d","dd",MB_OK);
            break;
        case IDM_BLUE:
            break;
        case IDM_YELLOW:
            break;
        case IDM_GREEN:
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

posted @ 2017-09-03 21:54  gd_沐辰  阅读(365)  评论(0编辑  收藏  举报