Windows SDK 教程(三) 一些细节以及动态创建控件

茵蒂克丝

资源编辑器一些小細節

1.如何指定窗口標題

找到窗口的属性面板,在【caption】处可以修改

2.如何設置窗口出現的位置

找到窗口的属性面板,在【位置】下可以设置【center】为【true】则能让窗口居中显示,x 和 y 则是窗口出现的横纵坐标。(横纵坐标起点为屏幕左上角)

3.如何添加圖片

在对话框的编辑界面,打开工具箱的面板,先在资源视图处添加一张图片资源(注意要是位图 *.bmp 格式),找到【pictrue control】拖到对话框上,接着打开【pictrue control】的属性面板,设置【Type】为【bitmap】接着到【Image】处,选择刚刚添加的图片ID即可。

4.如何設置菜單

在资源视图出添加【Menu】资源类型,双击可以编辑菜单项的文字,也可以右键【属性】在属性面板上编辑【caption】,顶级菜单项的ID不可编辑。触发事件的方式与前几件的按钮等类似。注意菜单编辑好了之后,要到对话框【属性面板】的【Menu】选项中添加。

5.如何设置窗口图标

如果用模板创建要用到 SendMessage, 将在后几讲中介绍

动态创建控件

动态创建窗口

#include <windows.h>
 
// 5. 窗口过程处理
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;  // 更多详细都可以去百度的 http://baike.baidu.com/view/1750396.htm
    HWND hwnd;
    MSG Msg;
    char text[30];
 
    const char szClassName[] = "myWindowClass";
 
    // 1. 设置注册窗口结构体
    wc.cbSize        = sizeof(WNDCLASSEX);              // 注册窗口结构体的大小
    wc.style         = 0;                               // 窗口的样式
    wc.lpfnWndProc   = WndProc;                         // 指向窗口处理过程的函数指针
    wc.cbClsExtra    = 0;                               // 指定紧跟在窗口类结构后的附加字节数
    wc.cbWndExtra    = 0;                               // 指定紧跟在窗口事例后的附加字节数
    wc.hInstance     = hInstance;                       // 本模块的实例句柄
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);     // 光标的句柄
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);        // 背景画刷的句柄
    wc.lpszMenuName  = NULL;                            // 指向菜单的指针
    wc.lpszClassName = szClassName;                     // 注册窗口的类名
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标
 
    // 2. 使用【窗口结构体】注册窗口
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
 
    // 3. 创建窗口
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,       // 窗口的扩展风格
        szClassName,            // 控件的类名
        TEXT("窗口标题"),       // 指向窗口名称的指针
        WS_OVERLAPPEDWINDOW,    // 窗口风格
        CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高
        NULL,                   // 父窗口的句柄
        NULL,                   // 菜单的句柄
        hInstance,              // 应用程序实例的句柄
        NULL                    // 指向窗口的创建数据
        );
 
    if(hwnd == NULL)
    {
        MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
 
    // 4. 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
 
    // 6. 消息循环
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

wc.lpszClassName 本质上确实是指向类名称的指针,不过博主没睡好,大清早又重录了一遍,录视频的时候再看到这种容易让人误会的说法就爆了粗口,这个意外 XD

动态创建BUTTON

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    switch(msg)
    {
    case WM_CREATE:
        // 动态创建button
        CreateWindowEx(
                0,              // 拓展样式
                "BUTTON",       // 创建的控件的类名
                "我的按钮",     // 控件显示的文字
                WS_CHILD | WS_VISIBLE,  // 控件的样式
                0, 0,           // 空间出现的 x y 坐标
                100, 30,        // 控件的宽高
                hwnd,           // 父窗口的句柄
                NULL,           // ID
                hgInstance,     // 当前实例的句柄
                NULL            // 传递给控件的参数 默认是NULL
            );
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

处理动态 BUTTON 的点击

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    switch(msg)
    {
    case WM_CREATE:
        // 动态创建button
        CreateWindowEx(
                0,              // 拓展样式
                "BUTTON",       // 创建的控件的类名
                "我的按钮",     // 控件显示的文字
                WS_CHILD | WS_VISIBLE,  // 控件的样式
                0, 0,           // 空间出现的 x y 坐标
                100, 30,        // 控件的宽高
                hwnd,           // 父窗口的句柄
                (HMENU)1234,    // ID
                hgInstance,     // 当前实例的句柄
                NULL            // 传递给控件的参数 默认是NULL
            );
        break;

    case WM_COMMAND:
        switch(wParam)
        {
        case 1234:
            echo("按钮被按下");
            break;
        }
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

动态创建 EDIT

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    switch(msg)
    {
    case WM_CREATE:
        CreateWindowEx(
                0,
                "EDIT",
                "",
                WS_CHILD | WS_VISIBLE,
                0, 50,
                100, 30,
                hwnd,
                NULL,
                hgInstance,
                NULL
            );
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

获取动态 EDIT 中的文字并显示

#include <windows.h>

#define IDC_BUTTON_1 1234

HINSTANCE hgInstance;

void echo(LPSTR str)
{
    MessageBox(NULL, str, TEXT("提示信息"), MB_OK);
}

// 5. 窗口过程处理
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    char text[50];
    switch(msg)
    {
    case WM_CREATE:
        // 动态创建 BUTTON
        CreateWindowEx(
                0,              // 拓展样式
                "BUTTON",       // 创建的控件的类名
                "我的按钮",     // 控件显示的文字
                WS_CHILD | WS_VISIBLE,  // 控件的样式
                0, 0,           // 空间出现的 x y 坐标
                100, 30,        // 控件的宽高
                hwnd,           // 父窗口的句柄
                (HMENU)IDC_BUTTON_1,    // ID
                hgInstance,     // 当前实例的句柄
                NULL            // 传递给控件的参数 默认是NULL
            );

        // 动态创建 EDIT 控件
        CreateWindowEx(
                0,
                "EDIT",
                "",
                WS_CHILD | WS_VISIBLE,
                0, 50,
                100, 30,
                hwnd,
                (HMENU)1000,
                hgInstance,
                NULL
            );
        break;

    case WM_COMMAND:
        switch(wParam)
        {
        // 当按钮被点击
        case IDC_BUTTON_1:
            // 获取Edit 控件中的字符串
            GetDlgItemText(hwnd, 1000, text, sizeof(text));
            // 输出字符串
            echo(text);
            break;
        }
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;  // 更多详细都可以去百度的 http://baike.baidu.com/view/1750396.htm
    HWND hwnd;
    MSG Msg;
    char text[30];

    const char szClassName[] = "myWindowClass";

    // 1. 设置注册窗口结构体
    wc.cbSize        = sizeof(WNDCLASSEX);              // 注册窗口结构体的大小
    wc.style         = 0;                               // 窗口的样式
    wc.lpfnWndProc   = WndProc;                         // 窗口处理过程的函数指针
    wc.cbClsExtra    = 0;                               // 指定紧跟在窗口类结构后的附加字节数
    wc.cbWndExtra    = 0;                               // 指定紧跟在窗口事例后的附加字节数
    wc.hInstance     = hInstance;                       // 本模块的实例句柄
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);     // 光标的句柄
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+2);        // 背景画刷的句柄
    wc.lpszMenuName  = NULL;                            // 指向菜单的指针
    wc.lpszClassName = szClassName;                     // 注册窗口的类名
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标

    // 2. 使用【窗口结构体】注册窗口
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 3. 创建窗口
    hwnd = CreateWindowEx(
        0,                      // 窗口的扩展风格
        szClassName,            // 注册的类名
        TEXT("窗口标题"),       // 指向窗口名称的指针
        WS_OVERLAPPEDWINDOW,    // 窗口风格
        CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高
        NULL,                   // 父窗口的句柄
        NULL,                   // 菜单的句柄
        hInstance,              // 应用程序实例的句柄
        NULL                    // 指向窗口的创建数据
        );

    hgInstance = hInstance;

    if(hwnd == NULL)
    {
        MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 4. 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 6. 消息循环
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

文章索引百度网盘
上一讲:Windows SDK 教程(二)简单的计算器
下一讲:Windows SDK 教程(四)记事本与 SendMessage

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google+ photo

You are commenting using your Google+ account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s