zoukankan      html  css  js  c++  java
  • WinMain函数详解(转载再编辑)

    在Windows应用程序中,我们可以认为 WinMain() 函数是程序的入口,WinMain()的原型如下:

    int WINAPI WinMain( 
    
        HINSTANCE hInstance, 
    
        HINSTANCE hPreInstance, 
    
        LPSTR lpCmdLine, 
    
        int nCmdShow 
    
    ); 

    代码解释:

    1、前面说过,资源存在于内存之后,那么一个每个程序运行之后,也被看做一个资源,它有一个属于自己的句柄,这个句柄就保存在变量 hInstance 中。

    2、hPreInstance 表示当前实例的前一个实例的句柄,在Win32环境下,参数总是为NULL

    3、lpCmdLine 用于存放传递给应用程序的参数,那么如何给应用程序传递参数?这里举几个例子:

    1. 通过命令行传递参数:在命令行下输入 notepad hi.txt,这里hi.txt这个文件的路径(一个字符串)这个参数被传递给应用程序 notepad
    2. 通过双击鼠标的操作:我们现在有一个 hi.txt 文档,我们在上面双击,那么hi.txt这个文件的路径将作为参数传递给 notepad,也就是说,双击操作可以把文件名作为参数传递给指定的Windows应用程序
    3. 拖拽操作:我们可以把一个叫 hi.txt 的文档,拖拽到 notepad 的程序中,那么hi.txt这个文件的路径将作为参数传递给 notepad,也就是说,拖拽操作可以把文件名作为参数传递给指定的Windows应用程序

    我们可以建立一个程序,读取参数:

    1) 建立头文件 StdAfx.h

    #if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
    #define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ 
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000 
    
    #define WIN32_LEAN_AND_MEAN   // Exclude rarely-used stuff from Windows headers 
    
    #include <windows.h> 
    

    2) 建立test.cpp 文件

    #include "stdafx.h" 
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
       // TODO: Place code here.
    MessageBox(NULL,lpCmdLine,"CmdLine",0);
    return 0;
    }

    当我们拖拽一个文件到生成的程序的时候(双击选择使用此程序打开也一样),出现:

     e51d783fc606b2dc838b1345

    4、nCmdShow,指定窗口第一次出现(程序刚刚启动时)时的显示方式。显示方式有多种,比如:

    1. 不显示,nCmdShow = 0;
    2. 正常显示,nCmdShow = 1;(默认为1)
    3. 最小化显示,nCmdShow = 2;
    4. 最大化显示,nCmdShow = 3;

    如果需要改变系统的默认的显示方式,需要在创建窗口之前指定nCmdShow的值(通过一个简单的赋值语句nCmdShow = n)

    不过,其实这里要让nCmdShow起作用,需要把nCmdShow作为参数传递给ShowWindow函数

    另外,这里稍微说明一下 WINAPI 这个宏定义,我们看WinMain函数的原型:

    int WINAPI WinMain(

        HINSTANCE hInstance,

        HINSTANCE hPreInstance,

        LPSTR         lpCmdLine,

        int              nCmdShow

    );

    WINAPI是这样定义的:
    #define WINAPI      __stdcall

    在VC6.0下生成的WinMain函数,实际上是:

    int APIENTRY WinMain(

        HINSTANCE hInstance,

        HINSTANCE hPreInstance,

        LPSTR         lpCmdLine,

        int              nCmdShow

    );

    APIENTRY 这个定义为:

    #define APIENTRY    WINAPI

    所以归根到底都是 __stdcall,这个是什么东西了?这里解释一下:

    __stdcall一种调用约定(调用函数时候的一种约定),其他的调用约定有:

    __cdecl 和 __fastcall

    调用约定将决定以下内容:

    1)函数参数的压栈顺序,

    2)由调用者还是被调用者把参数弹出栈,

    3)以及产生函数修饰名的方法。


    WIN32API使用的是__stdcall调用约定

    标准C,C++使用的是__cdecl调用约定

    __stdcall调用约定:函数的参数自右向左压栈,被调用的函数在返回前清理传送参数的内存栈

    __cdecl调用约定:每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。注意:对于可变参数的成员函数,始终使用__cdecl的调用约定

    (有关内容参考来源:http://blog.chinaunix.net/u/22878/showart_231924.html)

    (附录:系统理解Win32 API和MFC(上) -> http://www.vckbase.com/document/viewdoc/?id=487)

    (附录:系统理解Win32 API和MFC(下) -> http://www.vckbase.com/document/viewdoc/?id=488)

  • 相关阅读:
    Android系统剪切板
    java中tcp小样例
    Linux
    图书馆管理系统——模板建立
    学好英语的七个规则(上)
    spring中abstract bean的使用方法
    EularProject 36:2进制和10进制回文数
    java封装AES加密算法
    王艾辉:止跌信号频出 意味着什么?
    Storm集群组件和编程模型
  • 原文地址:https://www.cnblogs.com/herbertchina/p/3268347.html
Copyright © 2011-2022 走看看