zoukankan      html  css  js  c++  java
  • 【Windows编程】系列第二篇:Windows SDK创建基本控件

    windows1

    在Win32 SDK环境下,怎么来创建常用的那些基本控件呢?我们知道如果用MFC,简单的拖放即可完成大多数控件的创建,但是我们既然是用Windows SDK API编程,当然是从根上解决这个问题,实际上MFC的下层也是通过这些API完成的。

    实际上控件也是窗口,只不过是被微软预先创建好的一种窗口类,比如button就是一个类名为“BUTTON”的类。既然控件实际上是窗口,当然也是用CreateWindow或者CreateWindowEx这个函数来完成的,第二个函数除了多一个扩展风格之外,其他完全一样,下面以主要以CreateWindow为例说明,该函数原型如下(实际上在第一篇已经讲过了):

    HWND CreateWindow(LPCTSTR lpClassName,

    LPCTSTR lpWindowName,

    DWORD dwStyle,

    int x,   int y,   int nWidth,   int nHeight,

    HWND hWndParent,

    HMENU hMenu,

    HANDLE hInstance,

    PVOID lpParam );

    lpClassName:控件的类名

    lpWindowName:控件的名字或者文本

    dwStyle:控件风格

    x,y,nWidth,nHeight:控件的坐标和宽高

    hWndParent:控件的父窗口

    hMenu:控件的ID

    hInstance:控件设置为空

    lpParam:控件设为空

    那么具体怎么实现各个基本的控件呢?下面我们来先依次举例。

    • 创建标签/静态文本

    CreateWindow(TEXT("STATIC"), TEXT("Test String"), WS_CHILD|WS_VISIBLE, 10, 10, 80, 20,  hWnd, (HMENU)IDC_STATIC1, NULL, NULL);

    • 创建button

    CreateWindow(TEXT("BUTTON"), TEXT("Click Me"), WS_CHILD|WS_VISIBLE, 10, 40, 80, 20, hWnd, (HMENU)IDC_BUTTON1, NULL, NULL);

    • 创建编辑框

    CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE|WS_BORDER,  10, 70, 80, 20,  hWnd, (HMENU)IDC_EDIT1, NULL, NULL);

    • 创建Groupbox

    CreateWindow(TEXT("BUTTON"), TEXT("frame"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 120, 10, 130, 50, hWnd, (HMENU)IDC_FRAME1, NULL, NULL);

    • 创建单选框

    CreateWindow(TEXT("BUTTON"), TEXT("radio button"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, 134, 30, 40, 20, hWnd, (HMENU)IDC_MALE, NULL, NULL);

    • 创建复选框

    CreateWindow(TEXT("BUTTON"), TEXT("红色"), WS_CHILD|WS_VISIBLE|BS_CHECKBOX|BS_AUTOCHECKBOX, 120, 70, 54, 20, hWnd, (HMENU)IDC_CKBRED, NULL, NULL);

    • 创建列表框

    CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("LISTBOX"), NULL, WS_CHILD|WS_VISIBLE|LBS_STANDARD, 10, 100, 80, 90, hWnd, (HMENU)IDC_LISTBOX1, NULL, NULL);

    • 创建组合框

    CreateWindow(TEXT("COMBOBOX"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_AUTOHSCROLL|CBS_DROPDOWNLIST,  120, 100, 100, 90, hWnd, (HMENU)IDC_CB1, NULL, NULL);

    • 创建滚动条

    CreateWindow(TEXT("SCROLLBAR"), NULL, WS_CHILD|WS_VISIBLE|SBS_HORZ, 10, 200, 200, 20, hWnd, (HMENU)IDC_SCB1, NULL, NULL);

    以上创建各个控件都很差傻瓜化,你可以复制下来改改坐标、文本、风格、ID等就可以按照你的需要创建了。

    下面我们就来实战一下,把这些常用的控件在程序中实现,下面我们来实现一个完整的windows程序,程序中包含了这些常用的控件和更多的用法。

    /* 常用控件实例 */

    #include <windows.h>

    #define IDC_STATIC1 1001 #define IDC_BUTTON1 1002 #define IDC_EDIT1   1003 #define IDC_FRAME1  1004 #define IDC_MALE    2001 #define IDC_FEMALE  2002 #define IDC_LISTBOX1 1005 #define IDC_CB1     1006 #define IDC_CKBRED  1007 #define IDC_CKBGRN  1008 #define IDC_CKBBLU  1009 #define IDC_SCB1    1010 #define IDC_SCB2    1011

    static TCHAR szAppName[] = TEXT("HelloWin32"); static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND     hWnd; MSG      msg; WNDCLASS wndclass;

    wndclass.style         = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc   = WndProc; wndclass.cbClsExtra    = 0; wndclass.cbWndExtra    = 0; wndclass.hInstance     = hInstance; wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName  = NULL; wndclass.lpszClassName = szAppName;

    if (!RegisterClass(&wndclass)) { MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; }

    hWnd = CreateWindow(szAppName,                  // window class name szAppName,                 // window caption WS_OVERLAPPEDWINDOW,        // window style CW_USEDEFAULT,              // initial x position CW_USEDEFAULT,              // initial y position 400,              // initial x size 300,              // initial y size NULL,                       // parent window handle NULL,                       // window menu handle hInstance,                  // program instance handle NULL);                     // creation parameters

    ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd);

    while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }

    return msg.wParam; }

    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND hCtrl;

    switch (message) { case WM_CREATE: CreateWindow(TEXT("STATIC"), TEXT("Test String"), WS_CHILD|WS_VISIBLE, 10, 10, 80, 20, hWnd, (HMENU)IDC_STATIC1, NULL, NULL);

    CreateWindow(TEXT("BUTTON"), TEXT("Click Me"), WS_CHILD|WS_VISIBLE, 10, 40, 80, 20, hWnd, (HMENU)IDC_BUTTON1, NULL, NULL); CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE|WS_BORDER,  10, 70, 80, 20, hWnd, (HMENU)IDC_EDIT1, NULL, NULL);

    CreateWindow(TEXT("BUTTON"), TEXT("性别"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 120, 10, 130, 50, hWnd, (HMENU)IDC_FRAME1, NULL, NULL); CreateWindow(TEXT("BUTTON"), TEXT("男"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, 134, 30, 40, 20, hWnd, (HMENU)IDC_MALE, NULL, NULL); CreateWindow(TEXT("BUTTON"), TEXT("女"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, 194, 30, 40, 20, hWnd, (HMENU)IDC_FEMALE, NULL, NULL);

    CreateWindow(TEXT("BUTTON"), TEXT("红色"), WS_CHILD|WS_VISIBLE|BS_CHECKBOX|BS_AUTOCHECKBOX, 120, 70, 54, 20, hWnd, (HMENU)IDC_CKBRED, NULL, NULL); CreateWindow(TEXT("BUTTON"), TEXT("绿色"), WS_CHILD|WS_VISIBLE|BS_CHECKBOX|BS_AUTOCHECKBOX, 180, 70, 54, 20, hWnd, (HMENU)IDC_CKBGRN, NULL, NULL); CreateWindow(TEXT("BUTTON"), TEXT("蓝色"), WS_CHILD|WS_VISIBLE|BS_CHECKBOX|BS_AUTOCHECKBOX, 240, 70, 54, 20, hWnd, (HMENU)IDC_CKBBLU, NULL, NULL);

    hCtrl = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("LISTBOX"), NULL, WS_CHILD|WS_VISIBLE|LBS_STANDARD, 10, 100, 80, 90, hWnd, (HMENU)IDC_LISTBOX1, NULL, NULL); SendMessage(hCtrl, LB_ADDSTRING, 0, (LPARAM)TEXT("list str1")); SendMessage(hCtrl, LB_ADDSTRING, 0, (LPARAM)TEXT("list str2")); SendMessage(hCtrl, LB_ADDSTRING, 0, (LPARAM)TEXT("list str3")); SendMessage(hCtrl, LB_ADDSTRING, 0, (LPARAM)TEXT("list str4"));

    hCtrl = CreateWindow(TEXT("COMBOBOX"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_AUTOHSCROLL|CBS_DROPDOWNLIST, 120, 100, 100, 90, hWnd, (HMENU)IDC_CB1, NULL, NULL); SendMessage(hCtrl, CB_ADDSTRING, 0, (LPARAM)TEXT("comb str1")); SendMessage(hCtrl, CB_ADDSTRING, 0, (LPARAM)TEXT("comb str2")); SendMessage(hCtrl, CB_ADDSTRING, 0, (LPARAM)TEXT("comb str3")); SendMessage(hCtrl, CB_ADDSTRING, 0, (LPARAM)TEXT("comb str4")); SendMessage(hCtrl, CB_SETCURSEL, 1, 0);

    CreateWindow(TEXT("SCROLLBAR"), NULL, WS_CHILD|WS_VISIBLE|SBS_HORZ, 10, 200, 200, 20, hWnd, (HMENU)IDC_SCB1, NULL, NULL); CreateWindow(TEXT("SCROLLBAR"), NULL, WS_CHILD|WS_VISIBLE|SBS_VERT, 240, 100, 20, 120, hWnd, (HMENU)IDC_SCB2, NULL, NULL); return 0;

    case WM_COMMAND: { HWND hwndTmp; int wmId = LOWORD(wParam); switch (wmId) { case IDC_BUTTON1: hwndTmp = GetDlgItem(hWnd, IDC_STATIC1); SetWindowText(hwndTmp, TEXT("New Text")); MessageBox(hWnd, TEXT("Text Changed!"), TEXT("info"), MB_OK); break; } } return 0;

    case WM_CTLCOLORSTATIC: { HDC hdc = (HDC)wParam; SetTextColor(hdc, RGB(0xFF, 0x00, 0x00)); } return (BOOL)((HBRUSH)GetStockObject(NULL_BRUSH));

    case WM_DESTROY: PostQuitMessage(0); return 0; }

    return DefWindowProc (hWnd, message, wParam, lParam); }

    编译一下运行,结果如下:

    Win32Ctrls

    怎么样,是不是很简单,虽然我们的控件创建比MFC麻烦一下,但是我们是从“根”上来解决问题的,感觉是不一样的!有了这些基本的用法,你就可以构建更加复制的Windows界面了。赶快去试试吧。

    转载请注明原地址:http://www.coderonline.net/?p=680

    身为一名IT技术人员磨练自己的技术是必不可少的,欢迎加入QQ群:程序员互动联盟(254241126),可以与大牛在线随时讨论自己感兴趣的话题,大牛每天为你奉献一篇技术原创,让自己用最少的时间学到很多东西,我在程序员互动联盟期待您的加入:)

    如果大家想更深入了解更多的编程知识,请关注我们的公众号,及时沟通,这里有各种大牛帮你解决问题。微信公众平台:程序员互动联盟(coder_online)。

    欢迎加入我们的QQ群:程序员互动联盟(254241126)

  • 相关阅读:
    命令拷屏之网络工具
    PHP 设计模式 笔记与总结(1)命名空间 与 类的自动载入
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 LeetCode 143 重排链表
    Java实现 LeetCode 143 重排链表
  • 原文地址:https://www.cnblogs.com/yangdanny/p/4587164.html
Copyright © 2011-2022 走看看