接着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的消息传递机制;其他……

参考

  1. C语言也能干大事http://rupeng.com/forum/forum-52-1.html

  2. WinMain和main http://blog.163.com/hanyinlong@126/blog/static/99751486201212345130881/

  3. 消息分流器http://www.cnblogs.com/ifaithu/articles/2478841.html

Win32对话框程序(2)的更多相关文章

  1. Win32对话框程序(1)

    之前学C语言是一直都是在控制台下面操作的,面对的都是黑框框,严重的打击了学习的兴趣.后来在TC下进行C语言课程设计,做了图形界面编程,但都是点线面画的…… 中间隔了好长一段时间没有碰过C语言,最近才开 ...

  2. 如何让win32对话框居中显示

    在编写win32对话框程序,如果是用visual studio建的win32对话框程序,默认是不居中显示的,about 对话框也是这样的,用资源编辑器打开,可以在属性里面设置居中center 为tur ...

  3. (转载)用VS2012或VS2013在win7下编写的程序在XP下运行就出现“不是有效的win32应用程序“

    原文地址:http://www.vcerror.com/?p=1483 问题描述: 用VC2013编译了一个程序,在Windows 8.Windows 7(64位.32位)下都能正常运行.但在Win ...

  4. 给Win32 GUI程序增加控制台窗口的方法

    给Win32 GUI程序增加控制台窗口的方法 2008年10月11日 星期六 下午 04:43 在Win32的GUI程序中,没有控制台窗口,我们输出调试信息时有些不方便,以往我的做法是使用Messag ...

  5. java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。

    JNA 调用 dll 库时,保错: ///////////////// 通过 JNA 引入 DLL 库 //////////// /** * ID_FprCap.dll 负责指纹的采集, 指纹仪的初始 ...

  6. VC++ 对话框程序响应键盘消息的处理方法的说明(非常重要)

    基于MFC对话框的应用程序在响应按键消息和热键方面都力不从心,CDialog类的消息循环中去掉了TranslateAccelerator函数,因此不能响应热键:同时由于对话框上可能有很多控件,且默认情 ...

  7. python ImportError: DLL load failed: %1 不是有效的 Win32 应用程序

    导入的时候报出了 ImportError 在windows上安装python 的模块后,导入模块时报 python ImportError: DLL load failed: %1 不是有效的 Win ...

  8. 【转】WIN32 控制台程序

    http://blog.csdn.net/houmin0036/article/details/7702236 win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境下运行的应用 ...

  9. 【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”

    原文网址:http://www.cnblogs.com/Dageking/archive/2013/05/15/3079394.html VS2012编译出来的程序,在XP上运行,出现“.exe 不是 ...

随机推荐

  1. Axure使用——创建折叠菜单

    1.先添加动态面板 2.往动态面板中添加矩形 3.接着先隐藏下面的矩形(也就是你要折叠起来的内容) 4.一定要注意: 5.添加动态面板的状态 6.把之前做的那个矩形全部复制到state1中 7.把之前 ...

  2. BZOJ_2440_[中山市选2011]完全平方数_容斥原理+线性筛

    BZOJ_2440_[中山市选2011]完全平方数_容斥原理 题意: 求第k个不是完全平方数倍数的数 分析: 二分答案,转化成1~x中不是完全平方数倍数的数的个数 答案=所有数-1个质数的平方的倍数+ ...

  3. python黑科技:还在为没有wifi而烦心吗?这篇文章解决你的困扰

    python作为一门高级编程语言,它的定位是优雅.明确和简单.阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于解决问题而不是去搞明白语言本身.Python虽然是基于C语言编写,但是 ...

  4. Python基础语法 系统学习

    Python 中的基础语法最大的特点就是优雅和简洁.入门学习Python的难度相比较其他语言也比较小. 我个人比较推荐以下三个学习方式(根据个人情况和喜好,可选择任意一个): 1.  菜鸟在线:出品的 ...

  5. 轻量化卷积神经网络MobileNet论文详解(V1&V2)

    本文是 Google 团队在 MobileNet 基础上提出的 MobileNetV2,其同样是一个轻量化卷积神经网络.目标主要是在提升现有算法的精度的同时也提升速度,以便加速深度网络在移动端的应用.

  6. OsharpNS轻量级.net core快速开发框架简明入门教程-基于Osharp实现自己的业务功能

    OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ...

  7. javascript深入理解-从作用域链理解闭包

    一.概要 红宝书(P178)对于闭包的定义:闭包就是有权访问另外一个函数作用域中变量的函数. MDN,对于闭包的定义:闭包就是指能够访问自由变量的函数. 那么什么是自由变量?自由变量就是在函数中使用, ...

  8. 想在京津冀地区找个UI&UE的工作靠啥?看看这篇博客

    文章目的 本篇文章针对京津冀计算机专业应届毕业生,求职UI相关行业,提供数据参考. 本篇文章试用对象 UI相关培训机构 计算机设计相关培训机构 高职专科类学院计算机相关专业 就业参考网站 智联招聘 拉 ...

  9. TensorFlow从1到2(六)结构化数据预处理和心脏病预测

    结构化数据的预处理 前面所展示的一些示例已经很让人兴奋.但从总体看,数据类型还是比较单一的,比如图片,比如文本. 这个单一并非指数据的类型单一,而是指数据组成的每一部分,在模型中对于结果预测的影响基本 ...

  10. React + TypeScript:元素引用的传递

    React 中需要操作元素时,可通过 findDOMNode() 或通过 createRef() 创建对元素的引用来实现.前者官方不推荐,所以这里讨论后者及其与 TypeScript 结合时如何工作. ...