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的,至于操作系统是怎么把他们传进来的,现在没管[email protected][email protected]~

何为句柄?何为实例?如果我们同时运行两个记事本程序,我们会发现针对它们的不同操作是互不干扰的,这两个“窗口”即使记事本的两个实例,它们被加载在内存中的不同空间,但为了实现互不干扰的操作和处理,我们需要区分彼此,便使用句柄来标识应用程序的不同实例(两个记事本的句柄不同),我们能通过句柄访问相应对象的信息,但句柄不是指针,程序不能利用句柄来直接阅读文件中的信息,它只是一个唯一的整数值。

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/[email protected]/blog/static/99751486201212345130881/
  3. 消息分流器http://www.cnblogs.com/ifaithu/articles/2478841.html
时间: 2024-10-08 10:34:20

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

Win32对话框程序(1)

之前学C语言是一直都是在控制台下面操作的,面对的都是黑框框,严重的打击了学习的兴趣.后来在TC下进行C语言课程设计,做了图形界面编程,但都是点线面画的…… 中间隔了好长一段时间没有碰过C语言,最近才开始往起捡,找到了如鹏网的<C语言也能干大事>教程,惊喜的发现上手即是对话框程序,想坚持学下来,奈何老师对涉及原理的地方有所略过,对我这个喜欢刨根问底凡事都想问个“问什么”的人来说,用着一个自己不了解的东西那真是“浑身难受”,所以就想一边学着课程一边自己一探究竟(至少要心里有底)~ ********

Creating Dialogbased Win32 Application (4) / 创建基于对话框的Win32应用程序(四)Edit Control的应用、Unicode转ANSI、自动滚动 / Win32, VC++, Windows

创建基于对话框的Win32应用程序(四)——Edit Control的应用.Unicode转ANSI.自动滚动 之前的介绍中,我们用到了Button.Static Text.Checkbox这三个控件.这一节中我们将学习使用Edit Control(编辑框)控件,其中还包括Unicode转ANSI的方法.文本框自动滚动的功能等. 24.首先切换到Reasource View(Ctrl+Shift+E),找到待修改的主窗体,并从Toolbox(Ctrl+Atl+X)中添加Edit Control控

Creating Dialogbased Win32 Application (1) / 创建基于对话框的Win32应用程序(一)新建窗体 / Win32, VC++, Windows

创建基于对话框的Win32应用程序(一) —— 新建窗体 1.新建一个Visual C++的Empty Project.  2.在Solution Explorer中右键Add New Item,添加 .cpp 文件,并提供Win32应用程序的入口点函数.  3.在Solution Explorer或 Resources View 中右键Add Resource,选择Dialog.并在修改相关内容. 4.切换到 .cpp文件中,创建回调函数(Dlg_Proc),并在入口点函数中调用DialogB

Creating Dialogbased Win32 Application (2) / 创建基于对话框的Win32应用程序(二)Button的应用、新建子窗体 / Win32, VC++, Windows

创建基于对话框的Win32应用程序(二) —— Button的应用.新建子窗体 可以发现上一节创建的窗体中,点击OK和Cancel两个按钮是没有任何反应的.现在我们来为他们添加退出对话框的功能. 6.首先定义宏替换如下: 7.再在回调函数(Dlg_Proc)中调用响应消息的函数(Dlg_OnCommand)如下: 8.由于HANDLE_WM_COMMAND是在windowsx.h头文件中定义的,故添加其引用. 9.接下来定义刚才调用的消息响应函数(Dlg_OnCommand)如下: 其中IDOK

【mfc】基本对话框程序——加法器

都说好了是vc6的mfc,这个加法器当然不同于数电与单片机的加法器,^_^开个玩笑, 正式转入正题, 前两篇mfc,甚至连mfc都不是,仅仅是win32程序,都只不过是一个普通的弹窗程序而已, 这次继续为大家带来的简单的win32程序, 不过已经有基本功能了,能够实现两个编辑框里面的数据相加. 一.基本目标 创建如下程序: 有两个系统自带的按钮,原为"确定"与"取消",现在改为"计算"与"关闭" "计算"按

【mfc】对于对话框程序的优化与为程序创建图表

本文是继上一篇<[mfc]Helloworld>(点击打开链接)所写出来的对话框进行了的优化, 这次要把这个对话框程序做得更加好. 一.基本目标 1.为这个对话框程序加上自己的图标,如下图: 2.不再是仅有一个让用户点击的对话框了,而且在用户点击确定与取消按钮之后能够进行判断 比如,用户点击了确定,则弹出用户点击了确定的提示 如果用户点击了取消,则弹出用户点击取消的提示 二.制作过程 1.首先像<[mfc]Helloworld>(点击打开链接)中,先新建一个简单的Win32工程,然

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

解决方法1: 链接器->系统->子系统->控制台或windows?后面的"最低版本"是5.01 解决办法2: 解决"不是有效的win32应用程序"问题 帅宏军 用VC2013编译了一个程序,在Windows 8.Windows 7(64位.32位)下都能正常运行.但在Win XP,Win2003下运行时,却报错不能运行,具体错误信息为"指定的可执行文件不是有效的 Win32 应用程序". ? ? ? ? ?一.问题分析 ? ?

%1不是有效的 win32应用程序(64位转换32位)

phpmyadmin打开时候显示 HTTP500内部服务器错误,用火狐浏览器显示的是%1不是有效的 win32应用程序.谷歌一下,终于找出问题,原来是windows2003 64位的操作系统和32位IIS的问题..最终找到解决方法如下: 要运行 32 位版本的 ASP.NET 2.0,请按照以下步骤操作:1. 单击"开始",单击"运行",键入 cmd,然后单击"确定". 2. 键入以下命令启用 32 位模式: cscript %SYSTEMDRI

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

from matplotlib import pyplot as pltfrom sklearn.datasets import load_irisimport numpy as np data=load_iris()feature_names=data['featrue_names']target=data['target']for t.marker,c in zip(xrange(3),">ox","rgb"):    plt.scatter(featur