C语言Windows程序开发—CreateWindow函数介绍【第03天】
(一)CreateWindow函数的参数介绍:
HWND CreateWindow(
LPCTSTR lpClassName, //Windows窗口中预定义的控件结构体,包括:BUTTON(按钮),EDIT(文本框),LISTBOX(列表),MDICLIENT(子窗口),SCROLLBAR(滚动条),RICHEDIT(富文本),STATIC(静态控件);
LPCTSTR lpWindowName, //窗口控件中显示的内容,即Caption属性;
DWORD dwStyle, //控件样式,包括:WS_CHILD | WS_VISIBLE | WS_BORDER,还可以根据具体控件类型添加相应样式
int x, //窗口或控件左上角(X,Y)的X坐标
int y, //窗口或控件左上角(X,Y)的Y坐标
int nWidth, //窗口或控件的宽度
int nHeight, //窗口或控件的高度
HWND hWndParent, //父窗口句柄
HMENU hMenu, //菜单或者子窗口或控件的ID
HANDLE hInstance, //实例
PVOID lpParam //
);
函数调用示例:
(1)创建窗口
/* 创建窗口 */
hwnd = CreateWindow ( szAppName, TEXT ("输出字符串演示"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL ) ;
第1个参数:szAppName是字符串变量,如TEXT ("MyWindow"),表示为程序名称;
第2个参数:窗口标题名称;
第3个参数:窗口样式;
第4个参数:窗口左上角(X,Y)的X坐标,CW_USEDEFAULT表示使用缺省值;
第5个参数:窗口左上角(X,Y)的Y坐标,CW_USEDEFAULT表示使用缺省值;
第6个参数:窗口宽度,CW_USEDEFAULT表示使用缺省值;
第7个参数:窗口高度,CW_USEDEFAULT表示使用缺省值;
第8个参数:如果有父窗口,则是父窗口句柄,NULL表示没有父窗口;
第9个参数:如果有菜单,则是菜单的ID,NULL表示没有菜单;
第10个参数:执行实例代码;
第11个参数:
(2)创建控件
/* 创建编辑区 */
hwndChild[ID_EDITBOX] = CreateWindow( TEXT("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
, , , ,
hwnd, (HMENU)ID_EDITBOX, hInst, NULL ) ;
第1个参数:创建控件所属的预定义控件结构体,TEXT ("edit")表示创建文本框,如果是TEXT("button"),则表示创建按钮;
第2个参数:控件的标题名称,在创建文本框时,该参数不为空(如TEXT(“UserName”)),则创建成功后会在文本框中显示UserName;
第3个参数:在创建控件或子窗口时,必须样式WS_CHILD | WS_VISIBLE和该控件具有的特有样式,ES_LEFT表示文本框中内容左对齐;
第4~7个参数:控件的左上角(X,Y)坐标,宽度与高度,可以在回调函数的WM_SIZE中通过MoveWindow函数进行调整;
第8个参数:父窗口句柄,表示控件文本框所在的窗口句柄;
第9个参数:控件ID,并强制转换为HMENU类型;
第10个参数:执行实例代码
第11个参数:
通过对比创建窗口或子窗口(或控件)时CreateWindow函数的参数赋值,发现:
第1个参数在创建控件时尤为重要,其作用是声明正在创建控件的预定义控件结构体;
第4~7个参数是来限定窗口或控件的尺寸;
第8个参数都表示其父窗口句柄,若是控件,则是控件所在窗口的句柄;
第10个参数都是执行实例代码,但是子窗口(或控件)的执行实例代码hInst = ((LPCREATESTRUCT) lParam) -> hInstance;
(二)CreateWindow函数实例应用
/* 创建Login窗口*/
#include <windows.h>
#include <stdio.h> #define ID_UserName 1000
#define ID_Password 1001
#define ID_btnLogin 1002 /* 声明回调函数 */
LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM ) ; /* 声明创建窗口控件 */
int CreateChildWindow ( HWND, HWND *, LPARAM ) ; /* 主函数 */
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
{
static TCHAR szAppName [] = TEXT ("Demo") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; //窗口样式
wndclass.lpfnWndProc = WndProc ; //窗口的回调函数
wndclass.hInstance = hInstance ; //窗口实例句柄
wndclass.cbClsExtra = ; //窗口结构体扩展:无
wndclass.cbWndExtra = ; //窗口实例扩展:无
wndclass.hbrBackground = ( HBRUSH ) GetStockObject ( WHITE_BRUSH ) ; //窗口背景
wndclass.hIcon = LoadIcon ( NULL, IDI_APPLICATION ) ; //窗口图标
wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW ) ; //窗口中的鼠标样式
wndclass.lpszClassName = szAppName ; //窗口结构体名称
wndclass.lpszMenuName = NULL ; //主菜单名称:无 /* 注册窗口结构体 */
if ( !RegisterClass ( &wndclass ) )
{
MessageBox ( NULL, TEXT ("无法注册窗口结构体!"), TEXT ("错误"), MB_OK | MB_ICONERROR) ;
return ;
} /* 创建Login窗口 */
hwnd = CreateWindow ( szAppName, TEXT ("登录"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
, ,
NULL, NULL, hInstance, NULL ) ; /* 显示与更新窗口 */
ShowWindow ( hwnd, iCmdShow ) ;
UpdateWindow ( hwnd ) ; /* 从消息队列中获取消息 */
while ( GetMessage ( &msg, NULL, , ) )
{
TranslateMessage ( &msg ) ; //将虚拟键消息转换为字符消息
DispatchMessage ( &msg ) ; //将消息传递给回调函数处理
} return msg.wParam ;
} /* 回调函数 */
LRESULT CALLBACK WndProc (HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam )
{
static HWND hChild [] ;
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ; static int cxChar, cyChar ; switch ( umsg )
{
case WM_CREATE : //处理窗口创建成功后发来的消息
/* 创建窗口控件 */
CreateChildWindow ( hwnd, hChild, lParam ) ; cxChar = LOWORD (GetDialogBaseUnits ()); //获得窗口中内定字体字元宽度(低字组)
cyChar = HIWORD (GetDialogBaseUnits ()); //或得窗口中内定字体字元高度(高字组)
return ; case WM_SIZE : //处理窗口尺寸发生改变后发来的消息
GetClientRect ( hwnd, &rect ) ;
MoveWindow ( hChild [ ID_UserName ], rect.left + cxChar * , , cxChar * , cyChar * / , TRUE ) ;
MoveWindow ( hChild [ ID_Password ], rect.left + cxChar * , , cxChar * , cyChar * / , TRUE ) ;
MoveWindow ( hChild [ ID_btnLogin ], rect.left + cxChar * , , cxChar * , cyChar * / , TRUE ) ;
return ; case WM_PAINT : //处理窗口产生无效区域时发来的消息
GetClientRect ( hwnd, &rect ) ;
hdc = BeginPaint ( hwnd, &ps ) ;
TextOut ( hdc, rect.left + cxChar * , , TEXT ("UserName:"), lstrlen ( TEXT ("UserName:") ) ) ;
TextOut ( hdc, rect.left + cxChar * , , TEXT ("Password:"), lstrlen ( TEXT ("Password:") ) ) ;
EndPaint ( hwnd, &ps ) ;
return ; case WM_DESTROY : //处理窗口关闭时发来的消息
PostQuitMessage () ;
return ;
} return DefWindowProc ( hwnd, umsg, wParam, lParam ) ;
} /* 创建控件 */
int CreateChildWindow ( HWND hwnd, HWND * hChild, LPARAM lParam )
{
HINSTANCE hInst = ( ( LPCREATESTRUCT ) lParam ) -> hInstance ; /* 创建UserName文本框 */
hChild [ ID_UserName ] = CreateWindow ( TEXT ("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT,
, , , ,
hwnd, ( HMENU ) ID_UserName, hInst, NULL ) ; /* 创建Password文本框 */
hChild [ ID_Password ] = CreateWindow ( TEXT ("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT,
, , , ,
hwnd, ( HMENU ) ID_Password, hInst, NULL ) ; /* 创建Login按钮 */
hChild [ ID_btnLogin ] = CreateWindow ( TEXT ("button"), TEXT ("Login"),
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER,
, , , ,
hwnd, ( HMENU ) ID_btnLogin, hInst, NULL ) ; return ;
}
运行结果:
代码说明:
(1)WndProc回调函数中的消息处理
<1>WM_SIZE消息处理
case WM_SIZE : //处理窗口尺寸发生改变后发来的消息
GetClientRect ( hwnd, &rect ) ;
MoveWindow ( hChild [ ID_UserName ], rect.left + cxChar * , , cxChar * , cyChar * / , TRUE ) ;
MoveWindow ( hChild [ ID_Password ], rect.left + cxChar * , , cxChar * , cyChar * / , TRUE ) ;
MoveWindow ( hChild [ ID_btnLogin ], rect.left + cxChar * , , cxChar * , cyChar * / , TRUE ) ;
return ;
GetClientRect函数获取登录窗口的矩形区域,即登录窗口中除去标题栏的矩形区域,MoveWindow函数调整控件的尺寸(即CreateWindow函数中的第4~7个参数);
<2>WM_PAINT消息处理
case WM_PAINT : //处理窗口产生无效区域时发来的消息
GetClientRect ( hwnd, &rect ) ;
hdc = BeginPaint ( hwnd, &ps ) ;
TextOut ( hdc, rect.left + cxChar * , , TEXT ("UserName:"), lstrlen ( TEXT ("UserName:") ) ) ;
TextOut ( hdc, rect.left + cxChar * , , TEXT ("Password:"), lstrlen ( TEXT ("Password:") ) ) ;
EndPaint ( hwnd, &ps ) ;
return ;
BeginPaint函数与EndPaint函数必须成对出现,BeginPaint函数表示开始绘制窗口,同时使整个显示区域变为有效,更新显示区域的内容,例如在窗口中用TextOut函数输出内容。
(2)自定义CreateChildWindow函数
/* 创建控件 */
int CreateChildWindow ( HWND hwnd, HWND * hChild, LPARAM lParam )
{
HINSTANCE hInst = ( ( LPCREATESTRUCT ) lParam ) -> hInstance ; /* 创建UserName文本框 */
hChild [ ID_UserName ] = CreateWindow ( TEXT ("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT,
, , , ,
hwnd, ( HMENU ) ID_UserName, hInst, NULL ) ; /* 创建Password文本框 */
hChild [ ID_Password ] = CreateWindow ( TEXT ("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT,
, , , ,
hwnd, ( HMENU ) ID_Password, hInst, NULL ) ; /* 创建Login按钮 */
hChild [ ID_btnLogin ] = CreateWindow ( TEXT ("button"), TEXT ("Login"),
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_CENTER,
, , , ,
hwnd, ( HMENU ) ID_btnLogin, hInst, NULL ) ; return ;
}
<1>CreateChildWindow函数的参数介绍
int CreateChildWindow (
HWND hwnd, //父窗口句柄
HWND * hChild, //子窗口或控件句柄
LPARAM lParam //lParam参数的低字组包含显示区域宽度,高字组包含显示区域高度
);
<2>CreateChildWindow函数的功用
专门用于创建窗口控件,方便程序扩展,同时能够缩减回调函数的代码行数。
C语言Windows程序开发—CreateWindow函数介绍【第03天】的更多相关文章
- C语言Windows程序开发—TextOut函数介绍【第02天】
(一)TextOut函数的参数介绍: BOOL TextOut ( //如果函数调用成功,返回TRUE,否则,返回FALSE HDC hdc, //用于显示字符串的控件ID int nXStart, ...
- C语言Windows程序开发—MessageBox函数介绍【第01天】
(一)MessageBox函数的参数介绍: int MessageBox ( HWND hWnd, //弹出MessageBox对话框所属的窗口句柄 LPCTSTR lpText, //指向Messa ...
- C语言Windows程序开发—Windows窗口样式与常用控件样式【第04天】
(一)Windows窗口(MDICLIENT)样式介绍 /* Windows窗口样式 */ WS_BORDER //带有边框的窗口 WS_CAPTION //带有标题栏的窗口 WS_CHILD //子 ...
- MFC Windows程序开发究竟是什么?
MFC Windows程序开发究竟是什么? MFC是一个Application Framework.他是一个完整的程序模型. 什么是MFC?MFC是微软公司出品一个Application Framew ...
- Loadrunner 脚本开发-soap_request函数介绍及WebService接口测试
脚本开发- soap_request函数介绍及WebService接口测试 by:授客 QQ:1033553122 函数介绍 soap_request 函数执行一个SOAP请求 函数原型 int so ...
- Go语言Windows 10开发环境搭建:Eclipse+GoClipse
Intel Core i5-8250U,Windows 10家庭中文版,go version go1.11 windows/amd64, Eclipse IDE for C/C++ Developer ...
- 第十三章:MFC库与Windows程序开发概述
主要内容: 1.Windows程序的基本结构 2.MFC库简介 3.使用Visual C++开发Windows程序 具体内容略
- R语言爬虫:Rvest包函数介绍(表格)
Rvest 包中常用函数一览: 函数 作用 read_html() 读取 html 页面 html_nodes() 提取所有符合条件的节点 html_node() 返回一个变量长度相等的list,相当 ...
- Windows驱动开发-派遣函数
一个简单的派遣函数格式 NTSTATUS DispatchFunction(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) { //业务代码区 //设置返回状态 pI ...
随机推荐
- 【Spring实战】—— 13 AspectJ注解切面
前面了解了典型的AOP基于配置的使用方法,下面介绍下如何依赖于注解来实现AOP. 基于注解降低了配置文件的复杂程度,但是引入了程序间的耦合,其中的优劣待用户自己判断了. 需要注意的是,确定Aspect ...
- nginx封IP脚本
#!/bin/bash max= confdir=/etc/nginx/conf.d/blockips.conf logdir=/var/log/nginx/access.log echo " ...
- scrum第四次冲刺
scrum 第四次冲刺 一.项目目的 为生活在长大的学生提供方快捷的生活服务,通过帖子发现自己志同道合的朋友,记录自己在长大点滴.本项目的意义在于锻炼团队的scrum能力,加强团队合作能力.确定本项目 ...
- CRM和ERP的Sales Organization的映射关系
在如下的配置里可以维护CRM和ERP的Sales Organization的映射关系. 例如,ERP的编号为0001的销售组织映射到CRM的编号为O 50040102的销售组织: 这种映射关系存储在表 ...
- groupdel
功能说明:用于删除指定的用户组,此命令不能删除用户归属的主用户组.
- HASH JION AND NESTED JION
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sssbbbryj/article/details/27795905 关于HASH_JION的原 ...
- CF549BLooksery Party题解
题目描述 The Looksery company, consisting of nn staff members, is planning another big party. Every empl ...
- miniMobile(手机)
官网:http://www.web2014.cn/
- redis的事务、主从复制、持久化
redis事务 和其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中, MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基石.Redis中事务 ...
- 如何解决mosh中翻页只能查看一屏的问题
最近用mosh替换了ssh作为连接开发机的工具,发现另外一个问题,ls cat随便什么命令输出结果超过一行的,向上翻页就没有了,找了下官网的FAQ也提到了这个问题,目前解决方案是使用tmux或者scr ...