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

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

 
1
2
3
4
5
6
7
8
9
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:控件设为空

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

  • 创建标签/静态文本
 
1
CreateWindow(TEXT("STATIC"), TEXT("Test String"), WS_CHILD|WS_VISIBLE, 10, 10, 80, 20,  hWnd, (HMENU)IDC_STATIC1, NULL, NULL);
  • 创建button
 
1
CreateWindow(TEXT("BUTTON"), TEXT("Click Me"), WS_CHILD|WS_VISIBLE, 10, 40, 80, 20, hWnd, (HMENU)IDC_BUTTON1, NULL, NULL);
  • 创建编辑框
 
1
CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE|WS_BORDER,  10, 70, 80, 20,  hWnd, (HMENU)IDC_EDIT1, NULL, NULL);
  • 创建Groupbox
 
1
CreateWindow(TEXT("BUTTON"), TEXT("frame"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 120, 10, 130, 50, hWnd, (HMENU)IDC_FRAME1, NULL, NULL);
  • 创建单选框
 
1
CreateWindow(TEXT("BUTTON"), TEXT("radio button"), WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, 134, 30, 40, 20, hWnd, (HMENU)IDC_MALE, NULL, NULL);
  • 创建复选框
 
1
CreateWindow(TEXT("BUTTON"), TEXT("红色"), WS_CHILD|WS_VISIBLE|BS_CHECKBOX|BS_AUTOCHECKBOX, 120, 70, 54, 20, hWnd, (HMENU)IDC_CKBRED, NULL, NULL);
  • 创建列表框
 
1
CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("LISTBOX"), NULL, WS_CHILD|WS_VISIBLE|LBS_STANDARD, 10, 100, 80, 90, hWnd, (HMENU)IDC_LISTBOX1, NULL, NULL);
  • 创建组合框
 
1
CreateWindow(TEXT("COMBOBOX"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_AUTOHSCROLL|CBS_DROPDOWNLIST,  120, 100, 100, 90, hWnd, (HMENU)IDC_CB1, NULL, NULL);
  • 创建滚动条
 
1
CreateWindow(TEXT("SCROLLBAR"), NULL, WS_CHILD|WS_VISIBLE|SBS_HORZ, 10, 200, 200, 20, hWnd, (HMENU)IDC_SCB1, NULL, NULL);

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

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

/* 常用控件实例 */

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#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);
}

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

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

转载 :http://www.coderonline.net/?p=680

api (二) 创建控件 (转)的更多相关文章

  1. DuiLib(二)——控件创建

    上一篇讲了窗口及消息,了解了大体的程序框架.这一篇说的是控件的创建. duilib支持XML配置文件,即根据XML创建窗口及控件,将界面与逻辑分开,便于修改及维护.上一篇的示例中可以看到在消息WM_C ...

  2. Google 地图 API V3 之控件

    Google官方教程: Google 地图 API V3 使用入门 Google 地图 API V3 针对移动设备进行开发 Google 地图 API V3 之事件 Google 地图 API V3 ...

  3. 线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~ 线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析

    看两个例子,一个是在一个进程里设置另外一个进程中控件的属性.另外一个是在一个进程里获取另外一个进程中控件的属性. 第一个例子 最近,在做一个使用线程控制下载文件的小程序(使用进度条控件显示下载进度)时 ...

  4. MFC 动态创建控件

    动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的.   一.创建动态控件:   为了对照,我们先来看一下静态控件的创建.   放置静态控件时必须先建立一个容器,一 ...

  5. System.InvalidOperationException:“线程间操作无效: 从不是创建控件“txtPortName02”的线程访问它。”

    “System.InvalidOperationException”类型的未经处理的异常在 System.Windows.Forms.dll 中发生 其他信息: 线程间操作无效: 从不是创建控件“tx ...

  6. 线程使用中常见的错误-“System.InvalidOperationException”线程间操作无效: 从不是创建控件“ ”的线程访问它。

    “System.InvalidOperationException”类型的未经处理的异常在 System.Windows.Forms.dll 中发生 其他信息: 线程间操作无效: 从不是创建控件“la ...

  7. 【转】线程间操作无效: 从不是创建控件“textBox2” 的线程访问它。

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  8. 【转】Win32 创建控件风格不是Win XP解决方案

    有时候我有在用Win32 API来向窗体上添加控件时,通过CreateWindow或CreateWindowEx创建出来的控件的风格不像XP风格,而是像Windows 2000的风格,界面很难看.注意 ...

  9. IOS开发学习笔记019-动态创建控件

    动态创建控件 一.按钮 二.文本输入框 三.lable标签 注意: 只是简单的拖拽控件会毁了你,所以最好还是手动通过代码创建控件. 如果要通过代码生成按钮的话,可以在系统自带的函数viewDidLoa ...

随机推荐

  1. Android studio SweetAlert for Android

    找到个开源项目.github:https://github.com/pedant/sweet-alert-dialog 效果图:https://raw.githubusercontent.com/pe ...

  2. ubuntu 11.04安装笔记

    首先,本文查询了网络中各位大大的经验共享,特别是<UltraISO制作U盘启动Ubuntu 8.10 LiveCD>,地址在http://blog.sina.com.cn/s/blog_5 ...

  3. FormData实现文件上传实例

    单提交,文件上传是一个常用又十分麻烦的功能,以前要上传文件通常都是借助插件或者flash来实现,噼里啪啦的加载一大堆东西.自从有了HTML5的FormData后,老板再也不用担心我的上传了. Form ...

  4. sqlserver 2008存储过程 多个可空条件任意组合

    很多程序员在实际开发中,经常遇到这种情况,列表上方有很多条件,包含下拉框,输入框等等,这些条件都可以不输入,如果我们需要写一个存储过程,很多条件挨个判断是否为空,且进行任意组合,任何一个开发人员都会疯 ...

  5. BestCoder Round #75 1001 - King's Cake

    Problem Description It is the king's birthday before the military parade . The ministers prepared a ...

  6. Android NIO(Noblocking I/O非阻塞I/O)小结

    参考:http://www.cnblogs.com/cpcpc/archive/2011/06/27/2123009.html 对于Android的网络通讯性能的提高,我们可以使用Java上高性能的N ...

  7. javascript获取元素结点到页面的绝对距离的方式

    var div = document.getElementById('div');var p = getPos(div); function getPos(obj) { var pos = {left ...

  8. Oracle EBS-SQL (MRP-2):检查期间主计划录入记录数.sql

    SELECT      FU.description                           创建者,      MSD.CREATION_DATE             创建日期,   ...

  9. Ubuntu10.4 install jdk1.6

    You know,If you want to develop java applications ,you’d better install jdk. Now I will introduce yo ...

  10. WPF 路径和几何图形

    原文 http://www.cnblogs.com/laoyang999/archive/2012/11/23/2783734.html 继承自Shap类的形状有:Rectangle.Ellipse. ...