原创文章,转载请注明作者和出处

http://www.cnblogs.com/beyond-code

SDK编程群号:81543028 欢迎加入

各位不好意思,前几天有些事很忙,昨天才稍稍有时间空闲下来,所以我将我的API入门系列文章继续下去,上一篇《自己实现MessageBox》中我们基本已经实现了一个对话框了,可以在中央显示自己的文字,并且显示一个确定按钮,可是,上一篇完的时候我留下了一个问题,那就是那个确定按钮并不会根据窗口的大小的改变而改变。那么我们怎么来解决这个问题呢?

我给出了提示可以通过处理WM_SIZE来完成这个目的。那么今天我们就来完成这一遗留的问题。所要使用到的新的API函数也不多,就两个,要处理的消息也就两个WM_SIZE和WM_COMMAND

GetDlgItem

MoveWindow

这么两个,至于其他的API函数,都是我们以前接触过的,如果你忘记了,可以自己复习一下使用方法。

首先,我们先看WM_SIZE消息处理函数是怎么写的

case WM_SIZE:

{

const int buttonWidth = 80;

const int buttonHeight = 25;

int buttonx, buttony;

RECT rctClient;

GetClientRect( hwnd, &rctClient );

buttonx = rctClient.right/2 - buttonWidth/2;

buttony = rctClient.bottom/2 - buttonHeight/2;

HWND hButton = GetDlgItem( hwnd, 2 );

MoveWindow( hButton, buttonx, buttony, buttonWidth, buttonHeight, TRUE );

}

break;

由于这篇文章内容比较少,那么我就可以详细的介绍一下WM_SIZE这个消息处理函数中实现按钮始终保持居中的代码。WM_SIZE这个消息是当一个窗口的size也就是大小被改变后而被发送到该窗口的消息处理函数的。我们在这里通过截获WM_SIZE就可以在每次窗口大小被改变的时候进行一些处理,我们这里的处理就是将该窗口上的一个子窗口,也就是那个确定按钮移动到中央。

首先,我们还是老规矩,定义buttonWidth,和buttonHeight两个常整形来存放确定按钮的长和高。然后定义了两个整形变量buttonx,和buttony用来存放后面通过计算得到的确定按钮的左上角的坐标位置。

然后定义了一个RECT结构体用来保存后面通过GetClientRect API函数获取的窗口的长宽,其中rctClient中right就保存了窗口的长,bottom就保存了窗口的高。我们为了让按钮保持在主窗口的中央,那么我们就需要让按钮的左上角的x坐标位置在主窗口的长的一半再减去按钮的长的一半的位置。高也是一样的原理。所以 buttonx = rctClient.right/2 - buttonWidth/2; buttony = rctClient.bottom/2 - buttonHeight/2; 这两句就是根据当前主窗口的长和高计算按钮应该在的位置。

计算完成后,我们就只需要移动按钮就可以了。可是移动按钮之前,我们需要获得按钮的句柄,这个句柄怎么获得呢,有很多中方法,这里我就用GeDlgItem这个API函数来获取,它需要两个参数,第一个参数是一个主窗口的句柄,这里我们就传递按钮的主窗口的句柄hwnd,第二个参数是按钮的一个标识符,因为我们在前一篇文章中用CreateWindowEx创建子窗口的时候给按钮指定的标识符是2,所以这里我们就传递2,那么这样GetDlgItem返回的就是这个按钮的句柄了。

得到了句柄后,我们就需要用MoveWindow来移动这个子窗口按钮,到我们需要的位置了。第一个参数是这个字窗口的句柄,也就是我们上面获得的句柄,第二个参数和第三个参数是移动到的x,y坐标。这里我们传递buttonx和buttony,第四个和第五个是移动的窗口的长和高,如果同时还需要改变窗口的长和高,那么这里也可以传递改变后的长和高的值,我们这里只移动位置,不改变大小,所以就传递buttonWidth和buttonHeight。最后一个参数是一个BOOL型的,指示是否需要重绘,这里传递TRUE,也就是让它在移动后进行重绘。

好了,现在,当你改变主窗口的大小的时候,里面的确定按钮也会跟着改变位置而达到始终保持在主窗体的中央。

可是还有一个问题就是,当我们点击按钮的时候,程序没有任何的反映,MessageBox的确定按钮被点击的时候一般都会关闭当前对话框,所以我们这里也需要实现当用户点击确定按钮的时候,将我们的主窗体关闭。那么怎么来实现呢。

在实现之前,我首先要讲一讲,子窗体是怎么通知他们的父窗体的,比如说按钮被点击的时候是怎么通知他们的父窗体的。其实一般就是通过WM_COMMAND来通知的,例如我点击这个确定按钮,那么在这个确定按钮的窗口消息处理函数中就会向它的父窗体的窗口消息处理函数发送一条WM_COMMAND消息,并且WM_COMMAND消息的wParam参数的低16包含的就是一个标识符,指示是哪个子窗体发送的这条消息。至于wParam的高16和lParam包含的是些什么信息,就请各位自己查阅MSDN了,这里我们不会用到,也就不做讲解了。

所以我们要处理在子窗体上发生的事情,就需要在父窗体的消息处理函数中截获WM_COMMAND消息,并进行处理。那么这里的WM_COMMAND消息处理也很简单,如下

case WM_COMMAND:

{

if( LOWORD(wParam)==2 )

{

DestroyWindow( hwnd );

}

}

break;

就是用LOWORD这个宏来取出wParam的低16位,并且判断是不是2,也就是判断是不是确定按钮的标识符,如果是,就表示确定按钮上发生了事件,具体的事件我们就没做过细的判断了,一般来说都是指被点击。所以我们就进行处理,调用DestroyWindow这个API来销毁主窗体。就达到了我们的目的了。

怎么样,比较简单吧~

经过7篇API入门系列文章的介绍,我想你对WIN32 API编程的一般流程还是有了一个大概的了解了吧。以及对于windows的数据类型,字符编码方面。API的使用方面,消息的处理方面,因为都不会陌生了吧·

所以我后面的文章,对于细节就不会这么细了,对于一个API函数,如果参数不是很复杂,我也不会做过多的解释了。而只是说明一下它的作用。至于细节,各位就应该养成MSDN的习惯了。

好了,今天的文章就到这里了。如果有兴趣,请加入WIN32 SDK编程群进行讨论与交流和访问我的csdn博客http://blog.csdn.net/beyondcode

我的一些其他文章也会发布到csdn的博客上面~

Windows API入门系列之七 -完善MessageBox相关推荐

  1. Windows API入门系列之六 -自己实现MessageBox

    我在第四篇文章:一个相当简单的SDK程序 中讲到了通过调用MessageBoxAPI函数来弹出一个对话框,那你有没有想过,我们一句简单的代码背后所隐藏的细节是怎么的呢,那时候让你了解这些未免还早了些, ...

  2. Windows API入门系列之五 -一个正儿八经的SDK程序

    上一篇,讲了一个简单的SDK程序的多种版本的编写,弹出了一个窗口,显示了我们计算1到10的结果,计算的程序不是重点,重点在于,一:让大家认识到Unicode版本的程序和ASCII版本的程序在编程方面的 ...

  3. HBase编程 API入门系列之HTable pool(6)

    HTable是一个比较重的对此,比如加载配置文件,连接ZK,查询meta表等等,高并发的时候影响系统的性能,因此引入了"池"的概念. 引入"HBase里的连接池" ...

  4. Hadoop MapReduce编程 API入门系列之压缩和计数器(三十)

    不多说,直接上代码. Hadoop MapReduce编程 API入门系列之小文件合并(二十九) 生成的结果,作为输入源. 代码 package zhouls.bigdata.myMapReduce. ...

  5. Windows Azure 入门系列课程Windows Azure 入门系列课程

    Windows Azure 入门系列课程 https://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/NewSeries/A ...

  6. Hadoop MapReduce编程 API入门系列之查找相同字母组成的字谜(三)

    找出相同单词的所有单词.现在,是拿取部分数据集(如下)来完成本项目. 项目需求 一本英文书籍包含成千上万个单词或者短语,现在我们需要在大量的单词中,找出相同字母组成的所有anagrams(字谜). 思 ...

  7. Windows SDK编程 API入门系列(转)

    之一 -那'烦人'的Windows数据类型 原创文章,转载请注明作者及出处. 首发 http://blog.csdn.net/beyondcode http://www.cnblogs.com/bey ...

  8. messagebox 全部使用_「一」Windows API 零门槛编程指南——MessageBox

    本篇作为Windows API 系列文章的第一篇,将简要的讲解一下什么是Windows API,Windows API能做些什么,并且尽可能讲解一些新出现的专有名词:本系列博文几乎没有难啃的" ...

  9. 【一】Windows API 零门槛编程指南——MessageBox 基本使用及基础讲解

    本篇作为Windows API 系列文章的第一篇,将简要的讲解一下什么是Windows API,Windows API能做些什么,并且尽可能讲解一些新出现的专有名词:本系列博文几乎没有难啃的" ...

最新文章

  1. IBM GSA Senior DBA招聘
  2. largest number java_将给定的数组组成最大的数 Largest Number
  3. SSM整合——Spring+SpringMVC+MyBatis整合
  4. RabbitMQ 队列消息持久化
  5. Sql Server 2005 分页
  6. signature=8405d26e250ad07c44560263cb1d4fc0,Systems for analyzing microtissue arrays
  7. 如何在不同开发语言中使用绑定变量_linux C/C++服务器后台开发面试题总结(编程语言篇)...
  8. python地图图表和3d_Python地图可视化三大秘密武器
  9. 最新:斐讯K3千兆无线路由器刷官改版固件的详细图文教程
  10. mysql 唯一约束和唯一索引_谈谈唯一约束和唯一索引
  11. 淘宝/天猫上传图片到淘宝 API 返回值说明
  12. 网易云音乐api使用—基于node.js服务器
  13. 《别做正常的傻瓜》后续笔记—幸福的准则
  14. idea使用@Slf4j
  15. word方框内插入对勾
  16. supervisor搭建与配置
  17. 计算机网络管理技术参考文献,报文网络论文,关于计算机网络管理相关技术相关参考文献资料-免费论文范文...
  18. vue watch的用法及新旧值一样问题解决
  19. Kubernetes EFK 日志收集
  20. 照片恢复软件哪个好用?5个好用的照片恢复软件推荐

热门文章

  1. 什么端口可以抓LINUX,linux下抓包工具
  2. Laravel模板事项
  3. github gitlab BitBucket
  4. Linux系统中fflush,sync,syncfs,fdatasync,fsync的比较
  5. Python于*args 和**kwargs使用
  6. 统计SQL2005中数据库中的每张表的记录数
  7. 外部编辑Infopath的表单模板(xsn)
  8. Jmeter_前端RSA加密下的登陆模拟_引用js文件实现(转)
  9. eclipse提交Git时忽略文件
  10. 2017年值得回首的那些事(文末有新春好礼相送)