19.控件(一)

1.控件

  系统已经定义窗口类型,相应窗口的处理函数等都已经由系统定义完成。例如编辑框、按钮等。

2.控件创建

  不需要注册,直接使用CreateWindow/Ex创建该类窗口。

  控件创建时,每个控件都具有一个ID。

3.控件消息

  程序和控件之间的交互都是用过消息完成的。

  控件的窗口消息:

    我们想获取控件的消息或设置控件的状态,程序可以通过SendMessage向控件发送消息(调用控件的处理函数)。

  控件的通知消息:

    控件有相应的事件发生后,会向所有的父窗口(的窗口处理函数)发生通知消息(WM_COMMAND),父窗口根据通知消息的ID做相应处理。

 4.静态框

  (1)相关信息

     静态框常用语显示文字和图标等,窗口类名称“STATIC“

     文字静态框 - 显示文字

     图标静态框 - 显示图标,设置SS_ICON/SS_BITMAP

  (2)使用

     a.创建

       CreateWindow/CreateWindowEx

       风格:图标静态框使用SS_ICON/SS_BITMAP风格

       如果创建图标静态框,那么窗口的名称要设置成图标ID,例如:CreateWindowEx(0, "STATIC", "#101", ... );

     b.窗口消息

       SendMessage发送到控件即可。

     c.通知消息

       需要在创建时增加SS_NOTIFY风格。通知消息通过WM_COMMAND消息传递。

       wPARAM:LOWORD - 菜单项、加速键、控件ID

                  HIWORD - 对于菜单项,为0

                         对于加速键,为1

                                                  对于控件,是Notify-Code

       lPARAM:对于菜单项、加速键为NULL

                                 对于控件,为控件窗口句柄

  相关代码:

#include "stdafx.h"

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

void OnCreate(HWND hWnd)
{
    //静态框添加SS_NOTIFY风格才会发出WM_COMMAND消息
    //占用菜单参数作为控件ID
    CreateWindowEx(0, "STATIC", "hello txt", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 100, 100, 200, 30,
        hWnd, (HMENU)1001, g_hInstance, NULL);  

    CreateWindowEx(0, "STATIC", "#129", WS_CHILD | WS_VISIBLE | SS_ICON | SS_NOTIFY,
        350, 100, 0, 0, hWnd, (HMENU)1002, g_hInstance, NULL);
}
void OnCommand(HWND hWnd, WPARAM wParam)
{
    switch (LOWORD(wParam))
    {
    case 1001:
        if (STN_CLICKED == HIWORD(wParam))
        {
            MessageBox(hWnd, "点击文字静态框", "Info", MB_OK);
        }
        break;
    case 1002:
        if (STN_DBLCLK == HIWORD(wParam))
        {
            MessageBox(hWnd, "双击图标静态框", "Info", MB_OK);
        }
        break;
    case ID_REDCROSS:
        {
            HICON hRedCross = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON1));
            HWND hStatic = GetDlgItem(hWnd, 1001);
            SendMessage(hStatic, STM_SETICON, (WPARAM)hRedCross, 0);
        }
        break;
    case ID_BLUECROSS:
        {
            HICON hBlueCross = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON2));
            HWND hStatic = GetDlgItem(hWnd, 1002);
            SendMessage(hStatic, STM_SETICON, (WPARAM)hBlueCross, 0);
        }
        break;
    }
}
//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
        OnCommand(hWnd, wParam);
        break;
    case WM_CREATE:
        OnCreate(hWnd);  //在WM_CREATE消息中创建子窗口
        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);
    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()
{
    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)相关信息

     根据按钮的方格,分为4类:

       下压式按钮:BS_PUSHBUTTON / BS_DEFPUSHBUTTON

       分组框:BS_GROUPBOX

       复选框:BS_CHECKEDBOX / BS_AUTOCHECKEDBOX

                               BS_3STATE / BS_AUTO3STATE

       单选框:BS_RADIOBUTTON / BS_AUTORADIOBUTTON

  (2)下压式按钮

     创建按钮

     窗口消息

     通知消息,通知码BN_CLICKED

  (3)分组框

     用于界面上的控件分组显示,提高界面友好性

  (4)复选框

     a.风格和创建

       BS_CHECKBOX - 点击选择时,需要自己维护选择状态

       BS_AUTOCHECKBOX - 点击选择时,系统自动维护选择状态

     b.窗口消息

       获取和设置选择状态:

         BM_SETCHECK:wPARAM - 具体状态

                                                  lPARAM - 没用,必须为0

         BM_GETCHECK:wPARAM/lPARAM - 都没有用,必须为0

         复选框当前状态通过SendMessage函数的返回值获取

     c.通知消息

       BN_CLICKED - 按钮被点击

  (5)单选框

     a.风格和创建

       BS_RADIOBUTTON - 自己维护状态

       BS_AUTORADIOBUTTON - 系统自动维护状态

     b.窗口消息

       获取和设置选择状态

         BM_SETCHECK

         BM_GETCHECK

         每组单选框中只能同时有一个被选择

     c.通知消息

       BN_CLICKED

     d.其他

       单选框分组,可以使用WS_GROUP风格分组。从当前具有WS_GROUP风格的单选框,

       到下一个单选框之前,为一组单选框。

  相关代码: 

#include "stdafx.h"


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


void OnCreate(HWND hWnd)
{
    CreateWindowEx(0, "BUTTON", "OK", WS_CHILD|WS_VISIBLE |BS_PUSHBUTTON,
        50, 50, 100, 40, hWnd, (HMENU)1001, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "GroupBox", WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
        30, 30, 300, 450, hWnd, (HMENU)1002, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "CheckBox", WS_VISIBLE|WS_CHILD|BS_CHECKBOX,
        50, 100, 200, 30, hWnd, (HMENU)1003, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "AutoCheckBox", WS_VISIBLE|WS_CHILD|BS_AUTOCHECKBOX,
        50, 140, 200, 30, hWnd, (HMENU)1004, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "3State", WS_VISIBLE|WS_CHILD|BS_3STATE,
        50, 180, 200, 30, hWnd, (HMENU)1005, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "Auto3State", WS_VISIBLE|WS_CHILD|BS_AUTO3STATE,
        50, 220, 200, 30, hWnd, (HMENU)1006, g_hInstance, NULL);
    //从当前具有WS_GROUP风格的单选框开始到下一个具有该风格的单选框之前为一组
    CreateWindowEx(0, "BUTTON", "A 奔波儿霸", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
        50, 260, 200, 20, hWnd, (HMENU)1007, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "B 霸波尔奔", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
        50, 300, 200, 20, hWnd, (HMENU)1008, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "C 喜洋洋", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
        50, 340, 200, 20, hWnd, (HMENU)1009, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "D 灰太狼", WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
        50, 380, 200, 20, hWnd, (HMENU)1010, g_hInstance, NULL);
    CreateWindowEx(0, "BUTTON", "多态按钮", WS_VISIBLE|WS_CHILD|BS_AUTOCHECKBOX|BS_PUSHLIKE,
        50, 420, 200, 20, hWnd, (HMENU)1011, g_hInstance, NULL);
}
void OnCommand(HWND hWnd, WPARAM wParam)
{
    switch (LOWORD(wParam))
    {
    case 1005:
        if (BN_CLICKED == HIWORD(wParam))
        {
            HWND h3State = GetDlgItem(hWnd, 1005);
            LRESULT nRet = SendMessage(h3State, BM_GETCHECK, 0, 0);
            if (BST_CHECKED == nRet)
            {
                SendMessage(h3State, BM_SETCHECK, BST_INDETERMINATE, 0);                    
            }
            else if (BST_INDETERMINATE == nRet)
            {
                SendMessage(h3State, BM_SETCHECK, BST_UNCHECKED, 0);
            }
            else
            {
                SendMessage(h3State, BM_SETCHECK, BST_CHECKED, 0);
            }
        }
        break;
    case 1003:
        if (BN_CLICKED == HIWORD(wParam))
        {
            HWND hCheck = GetDlgItem(hWnd, 1003);
            LRESULT nRet = SendMessage(hCheck, BM_GETCHECK, 0, 0);
            if (BST_CHECKED == nRet)
            {
                SendMessage(hCheck, BM_SETCHECK, BST_UNCHECKED, 0);
            }
            else
            {
                SendMessage(hCheck, BM_SETCHECK, BST_CHECKED, 0);
            }
        }
        break;
    case 1001:
        if (BN_CLICKED == HIWORD(wParam))
        {
            MessageBox(hWnd, "点击OK", "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_CREATE:
        OnCreate(hWnd);
        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 = 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()
{
    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

  运行结果:

   

 

posted @ 2016-07-05 10:18  甩锅侠  阅读(254)  评论(0编辑  收藏  举报