Win32对话框程序(2)
接着Win32对话框程序(1)来写 ,解决遗留的问题,即理解函数及其调用关系。文章中有些地方是自己的推断,因此肯定有叙述不准确甚至错误的地方,请指正,感谢~
*******************************正文分割************************************
WinMain函数
Win32对话框程序(1)中说了WinMain是应用程序的入口,其输入参数有四个,根据MSDN上的叙述:
| 输入变量声明 | 说明 |
| HINSTANCE hInstance | 此应用当前实例的句柄 |
| HINSTANCE hPrevInstance | 此应用上一个实例的句柄,一般都是NULL |
| LPSTR lpCmdLine | The command line for the application, excluding the program name |
| int nCmdShow | 设置窗口的显示方式,比如nCmdShow=SW_MAXIMIZE表示最大化窗口,详见MSDN |
因为WinMain是应用程序的入口,即程序运行的第一个函数,所以这四个参数应该是操作系统传给WinMain的,至于操作系统是怎么把他们传进来的,现在没管~@_@~
何为句柄?何为实例?如果我们同时运行两个记事本程序,我们会发现针对它们的不同操作是互不干扰的,这两个“窗口”即使记事本的两个实例,它们被加载在内存中的不同空间,但为了实现互不干扰的操作和处理,我们需要区分彼此,便使用句柄来标识应用程序的不同实例(两个记事本的句柄不同),我们能通过句柄访问相应对象的信息,但句柄不是指针,程序不能利用句柄来直接阅读文件中的信息,它只是一个唯一的整数值。
lpCmdLine是不包含程序名的命令行,根据MSDN使用函数GetCommandLine()也可返回命令行字符串,不过会包含程序名。为了验证这个所谓的“命令行”是什么,在WinMain函数体开头加了两行代码将其显示出来
|
1
2
|
MessageBox(NULL, GetCommandLine(), TEXT("CMDLINE"), MB_OK);MessageBox(NULL, lpCmdLine, TEXT("CMDLINE_1p"), MB_OK); |
在VC6.0中运行,GetCommandLine()显示为完整路径包括程序名,lpCmdLine显示为空,如下:


于是我在命令行模式下运行,显示出所谓的The command line for the application究竟是什么,也许它可以用于向程序传递参数来进行交互式操作


此外,入口函数名并不一定是WinMain,也可以是main(),但需要在main函数体内显示的调用类似GetCommandLine()这样的函数来引入WinMain的四个参数并作为变量(后面需要使用),此外还有_tWinMain(需进一步查阅)
现在大体理解了WinMain函数了,接下来看看其他函数都在干什么
函数及程序框架理解
先贴WinMain函数
|
1
2
3
4
5
6
7
8
9
10
|
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ //Enable IPAddress、Calendar.etc InitCommonControls(); DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, Main_Proc); return 0;} |
| 函数名 | 参数 | 说明 |
| InitCommonControls | 无 | 该函数注册并初始化通用控件窗口类,使用某些高级控件时需要调用此函数,链接器会将你的程序链接到comctl32.lib,然后在程序启动时,会加载comctl32.dll。(据MSDN,此函数已废弃,需使用InitCommonControlsEx) |
| DialogBox | (hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, Main_Proc) |
据MSDN,该函数Creates a modal dialog box from a dialog box template resource,然后将控制权交给自定义的Main_Proc函数,此回调函数通过调用EndDialog函数来终结the modal dialog box。 参数说明:参数1为包含The dialog box template的句柄,可以是NULL;参数2是The dialog box template,使用MAKEINTRESOURCE宏来讲对话框ID(整数)转化为resource type;参数3为A handle to the window that owns the dialog box;参数4为A pointer to the dialog box procedure,函数指针。 |
MainDlg.cpp中包含四个函数:
|
函数名 |
参数 |
功能 |
|
Main_Proc |
(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
消息分流器,进行消息分流 |
|
Main_OnInitDialog |
(HWND hwnd, HWND hwndFocus, LPARAM lParam) |
return |
|
Main_OnCommand |
(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) |
switch(ID),case |
|
Main_OnClose |
(HWND hwnd) |
EndDialog |
消息分流器
|
1
2
3
4
5
6
7
8
9
10
11
|
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch(uMsg) { HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog); HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand); HANDLE_MSG(hWnd, WM_CLOSE, Main_OnClose); } return FALSE;} |
HANDLE_MSG也是一个宏,它在windowsx.h中定义,如下:
|
1
|
#define HANDLE_MSG(hwnd, message, fn) case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn)) |
比如代码
HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
实际被替换为
case (WM_INITDIALOG): return HANDLE_WM_CREATE((hwnd), (wParam), (lParam), (Main_OnInitDialog))
可见,可见消息分流器的作用就是当消息出现时将控制权交给不同的程序,一些相关的参数也会同时传给相应程序。
如WM_INITDIALOG等为消息,由操作系统传递给程序,根据MSDN,WM_INITDIALOG消息是在对话框马上要显示前(即对话框内存中已经准备好了,但还没有显示在屏幕上)发给程序的,程序可以在此时执行一些初始化操作;同理,WM_COMMAND消息和WM_CLOSE消息从字面就基本可以理解。
接下来把其他三个函数的代码都贴在下面:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam){ return TRUE;}void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){ switch(id) { case IDC_OK: { MessageBox(hwnd,TEXT("欢迎"),TEXT("问好"),MB_OK); } break; default: break; }}void Main_OnClose(HWND hwnd){ EndDialog(hwnd, 0);} |
可见,Main_Proc函数是一直在执行中的,时刻等待操作系统传递消息进来,根据不同消息将控制权交予不同的函数,包括初始化和关闭函数,当然实现功能最主要的在函数Main_OnCommand中,对话框中有菜单和不同的控件,通过ID对他们进行标示,如果用户对他们进行了某种操作(比如单击),则在Main_OnCommand函数体内进入相应的case,执行其中的代码,如上,当点击“确定”按钮是会弹出“欢迎”对话框。
**********************************************************************************************
以上就是《C语言也能干大事》中介绍的对话框程序的基本框架,当然,对话框程序应该是Windows编程中很简单的,还有很多其他的内容需要学习,此外,学习windows编程很重要的一部分就是掌握尽可能多的API,万丈高楼平地起,一步步来~
遗留问题
操作系统是如何向程序传递参数的(不急迫),即更深入的理解Windows的消息传递机制;其他……
参考
Win32对话框程序(2)的更多相关文章
- Win32对话框程序(1)
之前学C语言是一直都是在控制台下面操作的,面对的都是黑框框,严重的打击了学习的兴趣.后来在TC下进行C语言课程设计,做了图形界面编程,但都是点线面画的…… 中间隔了好长一段时间没有碰过C语言,最近才开 ...
- 如何让win32对话框居中显示
在编写win32对话框程序,如果是用visual studio建的win32对话框程序,默认是不居中显示的,about 对话框也是这样的,用资源编辑器打开,可以在属性里面设置居中center 为tur ...
- (转载)用VS2012或VS2013在win7下编写的程序在XP下运行就出现“不是有效的win32应用程序“
原文地址:http://www.vcerror.com/?p=1483 问题描述: 用VC2013编译了一个程序,在Windows 8.Windows 7(64位.32位)下都能正常运行.但在Win ...
- 给Win32 GUI程序增加控制台窗口的方法
给Win32 GUI程序增加控制台窗口的方法 2008年10月11日 星期六 下午 04:43 在Win32的GUI程序中,没有控制台窗口,我们输出调试信息时有些不方便,以往我的做法是使用Messag ...
- java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。
JNA 调用 dll 库时,保错: ///////////////// 通过 JNA 引入 DLL 库 //////////// /** * ID_FprCap.dll 负责指纹的采集, 指纹仪的初始 ...
- VC++ 对话框程序响应键盘消息的处理方法的说明(非常重要)
基于MFC对话框的应用程序在响应按键消息和热键方面都力不从心,CDialog类的消息循环中去掉了TranslateAccelerator函数,因此不能响应热键:同时由于对话框上可能有很多控件,且默认情 ...
- python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序
导入的时候报出了 ImportError 在windows上安装python 的模块后,导入模块时报 python ImportError: DLL load failed: %1 不是有效的 Win ...
- 【转】WIN32 控制台程序
http://blog.csdn.net/houmin0036/article/details/7702236 win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境下运行的应用 ...
- 【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”
原文网址:http://www.cnblogs.com/Dageking/archive/2013/05/15/3079394.html VS2012编译出来的程序,在XP上运行,出现“.exe 不是 ...
随机推荐
- java 自定义的注解有什么作用
转自https://zhidao.baidu.com/question/1668622526729638507.html 自定义注解,可以应用到反射中,比如自己写个小框架. 如实现实体类某些属性不自动 ...
- Windows 下python 环境安装
1.先在官网上下载安装包,官网地址: https://www.python.org 2. 选择自己需要的版本进行安装,最好选择新版本下载, 3. 下载完成后,双击运行安装,一直next,直至 ...
- compare.go
package clientv3 import ( pb "github.com/coreos/etcd/etcdserver/etcdserverpb" ) type C ...
- BZOJ_4198_[Noi2015]荷马史诗_huffman实现
BZOJ_4198_[Noi2015]荷马史诗_huffman实现 题意: Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗> ...
- Security - 轻量级Java身份认证、访问控制安全框架
前言 此框架由小菜独立开发,并且已经在生产环境中运行大约一年时间. 也就是说,Security 框架写出来有一段时间了,但是一直没有公布.开源,经过不断迭代完善,终于算是拿得出手啦~ Security ...
- Django admin自定制功能
一:基础设置 1.应用注册 1)方式一 若要把app应用显示在后台管理中,需要在admin.py中注册.打开admin.py文件,如下代码: from django.contrib import ad ...
- 开发教程(四) MIP组件平台使用说明
组件审核平台用于上传 MIP 组件.经过自动校验之后,提交审核,通过审核的组件会定时推送到线上,供网站使用. 平台地址:https://www.mipengine.org/platform/ 1. 使 ...
- 彻底理解浏览器的缓存机制(http缓存机制)
一.概述 浏览器的缓存机制也就是我们说的HTTP缓存机制,其机制是根据HTTP报文的缓存标识进行的,所以在分析浏览器缓存机制之前,我们先使用图文简单介绍一下HTTP报文,HTTP报文分为两种: 同步s ...
- 微软XAML Studio - WPF, Sliverlight, Xamarin, UWP等技术开发者的福音
目录 编辑器功能 数据源功能 调试数据绑定 伟大的开始 我们来一起实践吧 最近又在继续倒腾WPF的项目,继续使用Caliburn.Micro和Xceed来堆代码.每次调试xaml上的binding,都 ...
- 创建一个 Spring Boot 项目,你会几种方法?
我最早是 2016 年底开始写 Spring Boot 相关的博客,当时使用的版本还是 1.4.x ,文章发表在 CSDN 上,阅读量最大的一篇有 42W+,如下图: 2017 年由于种种原因,就没有 ...