【Windows编程】系列第二篇:Windows SDK创建基本控件
在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); }
编译一下运行,结果如下:
怎么样,是不是很简单,虽然我们的控件创建比MFC麻烦一下,但是我们是从“根”上来解决问题的,感觉是不一样的!有了这些基本的用法,你就可以构建更加复制的Windows界面了。赶快去试试吧。
转载请注明原地址:http://www.coderonline.net/?p=680
身为一名IT技术人员磨练自己的技术是必不可少的,欢迎加入QQ群:程序员互动联盟(254241126),可以与大牛在线随时讨论自己感兴趣的话题,大牛每天为你奉献一篇技术原创,让自己用最少的时间学到很多东西,我在程序员互动联盟期待您的加入:)
如果大家想更深入了解更多的编程知识,请关注我们的公众号,及时沟通,这里有各种大牛帮你解决问题。微信公众平台:程序员互动联盟(coder_online)。
欢迎加入我们的QQ群:程序员互动联盟(254241126)
【Windows编程】系列第二篇:Windows SDK创建基本控件的更多相关文章
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- 学习如何用VS2010创建ocx控件
1参考文章 (1)这一篇将使用vc创建ocx控件:http://blog.csdn.net/jiadelin/article/details/2917225 (2)这一篇文章有关vs2010创建act ...
- 深入理解javascript函数系列第二篇——函数参数
× 目录 [1]arguments [2]内部属性 [3]函数重载[4]参数传递 前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传 ...
- 深入理解javascript作用域系列第二篇——词法作用域和动态作用域
× 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...
- 深入理解javascript作用域系列第二篇
前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作 ...
- 前端工程师技能之photoshop巧用系列第二篇——测量篇
× 目录 [1]测量信息 [2]实战 [3]注意事项 前面的话 前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇——测量篇 测量信息 在网页制作中需要 ...
- Windows 8.1 应用再出发 - 几种新增控件(1)
Windows 8.1 新增的一些控件,分别是:AppBar.CommandBar.DatePicker.TimePicker.Flyout.MenuFlyout.SettingsFlyout.Hub ...
- Windows Phone开发(16):样式和控件模板
原文:Windows Phone开发(16):样式和控件模板 在前面资源一文中也提过样式,样式就如同我们做HTML页排版时常用到的CSS样式表,它是对于特定娄型的可视化元素,应该可以直接说是针对控件的 ...
- 第二十一篇:SOUI中的控件注册机制
Win32编程中,用户需要一个新控件时,需要向系统注册一个新的控件类型.注册以后,调用::CreateWindow时才能根据标识控件类型的字符串创建出一个新的控件窗口对象. 为了能够从XML描述的字符 ...
随机推荐
- webControls与客户端脚本路径
网上有用的资料不多,在一本电子书中摘抄了内容如下 webControls配置节只有一个clientScriptsLocation属性,此属性用于指定ASP.NET客户端脚本的默认存放路径.这些文件是包 ...
- jQuery自动与手动图片切换效果下载
效果图: 查看效果:http://hovertree.com/jq/hovertreeimg/ 下载:http://hovertree.com/h/bjaf/gk8mko69.htm 使用代码: &l ...
- 使用canvas实现擦玻璃效果
体验效果:http://hovertree.com/texiao/html5/25/ 效果图: 代码如下: <!DOCTYPE html> <html> <head la ...
- 为input输入框添加圆角并去除阴影
<input type="text" name="bianhao" value="" placeholder="请输入商品编 ...
- VS2015开发Android,自带模拟器无法调试、加载程序,算是坑吗
VS2015出来后,确定变化很大,什么android.ios的,不在话下.对于我这样传统型的人,也第一时间试用了一下(vs2003->vs2008->vs2012->vs2015). ...
- 工业串口和网络软件通讯平台(SuperIO 2.1)更新发布
SuperIO 2.1下载 一.SuperIO 的特点: 1) 能够很快的构建自己的通讯平台软件,包括主程序. 2) 设备模块化开发,通过配制文件挂载,即可在平台软件下运行. 3) 设备 ...
- java web学习总结(四) -------------------HTTP协议
一.什么是HTTP协议 HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的 ...
- 让T4脱离VS生成代码
让T4脱离VS生成代码 最近项目快结束:空闲时间相对多一点:为了以后工作方便点:索性研究了VS的T4: 写个代码生成器:以后可以通过代码生成器调用项目里面的Dll直接生成代码或者xml: 应用以下两个 ...
- javascript面试题:如何把一句英文每个单词首字母大写?
上周看到大家在JS群讨论如何把一句英文句子单词收割字母大写,大家都说用正则简单,对于正则还是有点模糊,于是乎自己敲了下 //面试题:如何把一句英文每个单词首字母大写? var str="wh ...
- div盒子垂直水平居中
div盒子,水平垂直居中. <!DOCTYPE html><html> <head> <meta charset="utf-8"> ...