在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面试题目及其答案

    转自:http://blog.csdn.net/wwj_748/article/details/8868640 Android面试题目及其答案 1.Android dvm的进程和Linux的进程, 应 ...

  2. Windows下安装Python3.4.2

    一.Windows下安装Python3.4.2 1.下载Windows下的Python3.4.2.exe 2.指定一个目录安装,然后下一步 3.配置环境变量包括Python.exe的文件.目录如下图所 ...

  3. html5 乒乓球(碰撞检测)

    演示地址 http://koking.8u.hanmandarin.com/html5/1.html 简单介绍 小球可以在方框内部自由运动 可以通过方向键控制黑色砖块上下左右移动去与小球发生碰撞 代码 ...

  4. Object-C 重载

    方法重载要保证三个条件 1在同一个类中 2.方法参数类型相同 名称相同 3.方法的参数不同 请看下面的例子 @interface whgMyObject : NSObject -(void)print ...

  5. javascript 压缩空格代码演示

          压缩空格代码演示 主要是讲解 压缩一个字符串两段空格          例如:javascript函数里的空格不论是这样     var s = "Hello World     ...

  6. zookeeper_04:curator

    定义 Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量. <d ...

  7. 鼠标聚焦到Text输入框时,按回车键刷新页面原因及解决方法

    前提 一个form中只有一个输入框,当输入框获取焦点后,点击回车,导致整个页面都刷新,问题解决办法. 1.处理form  在form中添加事件 <form onsubmit="retu ...

  8. mysql 查看mysql版本的四种方法

    1 命令行中使用status可以查看. mysql> status;--------------mysql  Ver 14.14 Distrib 5.5.25a, for Linux (x86_ ...

  9. Github 常用命令

    小记一些Github常用命令 : 在一个项目中... 假如要修补问题追踪系统上的 #53 问题.顺带说明下,Git 并不同任何特定的问题追踪系统打交道.这里为了说明要解决的问题,把新建的分支取名为 i ...

  10. Python中关于try...finally的一些疑问

    最近看Vamei的Python文章,其中一篇讲异常处理的,原本看完没啥疑惑,或许是自己想的简单了. 看到评论,一个园友的问题引起我的兴趣. 他的问题是 def func(x): try: return ...