9控件按钮

通过WIN32 绘图,画出各种控件,如下:

注意:按钮的本质是窗口。换句话说,以上说显示的都是窗口,button,radio,checked box等都是一个窗口。

 

窗口函数原型:

CreateWindowExA(0, lpClassName, lpWindowName, dwStyle, x, y,

nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)

 

全部控件都可以利用CreateWindowExA()实现,以下几点请注意:

1.lpClassName:”BUTTON”,使用系统内部的类

2.dwStyle:要定义主窗口的风格、按钮的风格,WS_CHILD|WS_VISIBLE这两个必要的

3.hMenu:菜单句柄,如果要通过按钮实现其他操作,因此必须一个消息队列,可以通过hMenu进入消息循环。

 

可以看出,在例子中使用了许多控件ID,那么如何使ID不重复并有意义?

步骤:打开资源视图-》找到.rc(如下图)-》右击-》资源符号。

利用资源符号可以各种控件的ID,并其值由系统分配。

Checked box 与 AutoChecked box的区别:

Checked box必须要自己书写消息循环,由hMenu为入口。

AutoChecked box 创建后可以直接使用,不需要书写消息循环。

同理,AutoRadio与Radio也是如此。

 

 

关于checked box详解:

         case IDM_CHECKEDBOX:

                            if(HIWORD(wParam)==BN_CLICKED)

                            {

                                     switch(SendMessage((HWND)lParam,BM_GETCHECK,0,0))

                                     {

                                     case BST_CHECKED:

                                     SendMessage((HWND)lParam,BM_SETCHECK,BST_UNCHECKED,0);

                                               break;

                                     case BST_UNCHECKED:

                                     SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);

                                               break;

                                     }

                            }

                            break;

注意点:

1.HIWORD(wParam) 存放该控件是否被点击了。

2.因为每一个控件都是一个窗口,所以SendMessage()的窗口句柄是(HWND)lParam,不是hWnd,而hWnd是我们的主窗口,不是控件。

3.通过SendMessage((HWND)lParam,BM_GETCHECK,0,0),BM_GETCHECK返回控件的点击情况,

再进一步选择,若是不选中,则变成选中状态。

 

关于checked box详解:

CreateWindowEx(0,"button","RADIOBUTTON1",WS_CHILD|WS_VISIBLE|BS_RADIOBUTTON|WS_GROUP,point.x,point.y+dwSize*5,dwWidth,dwHeight,hWnd,(HMENU)IDC_RADIO1,hInst,0);

         CreateWindowEx(0,"button","RADIOBUTTON2",WS_CHILD|WS_VISIBLE|BS_RADIOBUTTON,point.x,point.y+dwSize*6,dwWidth,dwHeight,hWnd,(HMENU)IDC_RADIO2,hInst,0);

                  

 

case IDC_RADIO1:

                            if(HIWORD(wParam)==BN_CLICKED)

                            {

                                     SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);

                                     SendMessage(GetDlgItem(hWnd,IDC_RADIO2),BM_SETCHECK,BST_UNCHECKED,0);

                            }

                            break;

case IDC_RADIO2:

                            if(HIWORD(wParam)==BN_CLICKED)

                            {

                                     SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);

                                     SendMessage(GetDlgItem(hWnd,IDC_RADIO1),BM_SETCHECK,BST_UNCHECKED,0);

                            }

                            break;

 

创建radio button时,要注意第一radio的风格必须加上WS_GROUP,意思为与以下的radio都是都是一组的。

 

消息循环函数与checked box类似,若选择了radio1,则将radio1变成选中状态,radio2变成不选中状态。

比较 :

SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);

SendMessage(GetDlgItem(hWnd,IDC_RADIO1),BM_SETCHECK,BST_UNCHECKED,0);

因为点击了radio1,lParam里面携带了当前radio1的窗口句柄,但是没有radio2的窗口句柄,所以要通过windows API 函数GetDlgItem()来获取。(参数解析,获取某一窗口的某一控件id的句柄。)

 

3 state的详解:

CreateWindowEx(0,"button","3state",WS_CHILD|WS_VISIBLE|BS_3STATE,point.x+dwWidth+dwSize,point.y,dwWidth,dwHeight,hWnd,(HMENU)IDC_3STATE,hInst,0);

 

                   case IDC_3STATE:

                            if(HIWORD(wParam)==BN_CLICKED)

                            {

                                     switch(SendMessage(HWND(lParam),BM_GETCHECK,0,0))

                                     {

                                     case BST_CHECKED:

                                               SendMessage((HWND)lParam,BM_SETCHECK,BST_INDETERMINATE,0);

                                               break;

                                     case BST_INDETERMINATE:

                                               SendMessage((HWND)lParam,BM_SETCHECK,BST_UNCHECKED,0);

                                               break;

                                     case BST_UNCHECKED:

                                               SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);

                                               break;

                                     }

                            }

                            break;

 

该控件有三种状态,选中、没选中、虚选中。实现原理与以上解析的控件类似。也是有auto3state。

同样通过SendMessage(HWND(lParam),BM_GETCHECK,0,0),来获取当前控件的状态,再经过选择,进入下一级状态。

 

源代码:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static POINT point;
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    point.x=4,point.y=4;
    DWORD dwSize=50;
    static DWORD dwWidth=150,dwHeight=40;
    switch (message)
    {
    case WM_CREATE:
//普通按钮
        CreateWindowEx(0,"BUTTON","Push Button",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,point.x,point.y,dwWidth,dwHeight,hWnd,(HMENU)IDM_PUSHBUTTON,hInst,0);
        CreateWindowEx(0,"button","DEFAULT BUTTON",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,point.x,point.y+dwSize*1,dwWidth,dwHeight,hWnd,0,hInst,0);
//组合框
        CreateWindowEx(0,"button","GROUP BOX",WS_CHILD|WS_VISIBLE|BS_GROUPBOX,point.x,point.y+dwSize*2,dwWidth+50,dwHeight,hWnd,0,hInst,0);        
//选择框
        CreateWindowEx(0,"button","CHECKED BOX",WS_CHILD|WS_VISIBLE|BS_CHECKBOX,point.x,point.y+dwSize*3,dwWidth,dwHeight,hWnd,(HMENU)IDM_CHECKEDBOX,hInst,0);
        
//自动选择框,不需要写菜单消息循环
        CreateWindowEx(0,"button","AUTOCHECKED BOX",WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,point.x,point.y+dwSize*4,dwWidth,dwHeight,hWnd,0,hInst,0);
        
//选择按钮
        CreateWindowEx(0,"button","RADIOBUTTON1",WS_CHILD|WS_VISIBLE|BS_RADIOBUTTON|WS_GROUP,point.x,point.y+dwSize*5,dwWidth,dwHeight,hWnd,(HMENU)IDC_RADIO1,hInst,0);
    CreateWindowEx(0,"button","RADIOBUTTON2",WS_CHILD|WS_VISIBLE|BS_RADIOBUTTON,point.x,point.y+dwSize*6,dwWidth,dwHeight,hWnd,(HMENU)IDC_RADIO2,hInst,0);
        
//自动选择按钮
    CreateWindowEx(0,"button","AUTORADIO1",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,point.x,point.y+dwSize*7,dwWidth,dwHeight,hWnd,NULL,hInst,0);
    CreateWindowEx(0,"button","AUTORADIO2",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,point.x,point.y+dwSize*8,dwWidth,dwHeight,hWnd,NULL,hInst,0);    
        
//3 state
    CreateWindowEx(0,"button","3state",WS_CHILD|WS_VISIBLE|BS_3STATE,point.x+dwWidth+dwSize,point.y,dwWidth,dwHeight,hWnd,(HMENU)IDC_3STATE,hInst,0);
        CreateWindowEx(0,"button","auto3state",WS_CHILD|WS_VISIBLE|BS_AUTO3STATE,point.x+dwWidth+dwSize,point.y+dwSize,dwWidth,dwHeight,hWnd,NULL,hInst,0);    
//push like
        CreateWindowEx(0,"button","push like",WS_CHILD|WS_VISIBLE|BS_PUSHLIKE,point.x+dwWidth+dwSize,point.y+dwSize*3,dwWidth,dwHeight,hWnd,NULL,hInst,0);    
        break;

    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_PUSHBUTTON:
            MessageBox(hWnd,"测试 ","提醒",MB_OK);
            break;
        case IDM_CHECKEDBOX:
            if(HIWORD(wParam)==BN_CLICKED)
            {
                switch(SendMessage((HWND)lParam,BM_GETCHECK,0,0))
                {
                case BST_CHECKED:
                SendMessage((HWND)lParam,BM_SETCHECK,BST_UNCHECKED,0);
                    break;
                case BST_UNCHECKED:
                SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);
                    break;
                }
            }
            break;
        case IDC_RADIO1:
            if(HIWORD(wParam)==BN_CLICKED)
            {
                SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);
                SendMessage(GetDlgItem(hWnd,IDC_RADIO2),BM_SETCHECK,BST_UNCHECKED,0);
            }
            break;
        case IDC_RADIO2:
            if(HIWORD(wParam)==BN_CLICKED)
            {
                SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);
                SendMessage(GetDlgItem(hWnd,IDC_RADIO1),BM_SETCHECK,BST_UNCHECKED,0);
            }
            break;
        case IDC_3STATE:
            if(HIWORD(wParam)==BN_CLICKED)
            {
                switch(SendMessage(HWND(lParam),BM_GETCHECK,0,0))
                {
                case BST_CHECKED:
                    SendMessage((HWND)lParam,BM_SETCHECK,BST_INDETERMINATE,0);
                    break;
                case BST_INDETERMINATE:
                    SendMessage((HWND)lParam,BM_SETCHECK,BST_UNCHECKED,0);
                    break;
                case BST_UNCHECKED:
                    SendMessage((HWND)lParam,BM_SETCHECK,BST_CHECKED,0);
                    break;
                }
            }
            break;
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            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:45  gd_沐辰  阅读(259)  评论(0编辑  收藏  举报