在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;
}

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

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)

WinMain函数详解(转载再编辑)的更多相关文章

  1. WinMain函数详解(转载)

    略加增添与修改! 工具:VC++6.0       系统:win7 64位 在Windows应用程序中,我们可以认为 WinMain() 函数是程序的入口,WinMain()的原型如下: int WI ...

  2. malloc 与 free函数详解<转载>

    malloc和free函数详解   本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...

  3. kzalloc 函数详解(转载)

    用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0. view plain /** * kzal ...

  4. Linux中fork()函数详解(转载)

    [原创地址]http://blog.csdn.net/jason314/article/details/5640969 [转载地址]http://www.cnblogs.com/bastard/arc ...

  5. Interlocked.Increment()函数详解 (转载)

    原文地址 class Program { static object lockObj = new object(); ; ; //假设要处理的数据源 , ).ToList(); static void ...

  6. Linux中fork()函数详解(转载)

    linux中fork()函数详解 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事, ...

  7. 【转载】jQuery.extend 函数详解

    转载自:http://www.cnblogs.com/RascallySnake/archive/2010/05/07/1729563.html jQuery.extend 函数详解 JQuery的e ...

  8. 【转载】3D/2D中的D3DXMatrixPerspectiveFovLH和D3DXMatrixOrthoLH投影函数详解

    原文:3D/2D中的D3DXMatrixPerspectiveFovLH和D3DXMatrixOrthoLH投影函数详解 3D中z值会影响屏幕坐标系到世界坐标系之间的转换,2D中Z值不会产生影响(而只 ...

  9. 【转载】C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    本文转自: C语言itoa()函数和atoi()函数详解(整数转字符C实现) 介绍 C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. int/float to ...

随机推荐

  1. Apache中 RewriteCond 规则参数介绍

    RewriteCond指令定义了规则生效的条件,即在一个RewriteRule指令之前可以有一个或多个RewriteCond指令.条件之后的重写规则仅在当前URI与Pattern匹配并且满足此处的条件 ...

  2. C# webservice服务跟踪调试方法(转)

    1.新建网站,添加服务,并创建服务. 2.打开internet 信息服务管理器,添加网站,映射到创建的服务所在网站的目录. 3.打开服务所在网站的解决方案,进行配置. 1) 设置启动选项 选择启动操作 ...

  3. 阿里云oss服务通用类

    在webconfig中配置信息 <?xml version="1.0" encoding="utf-8"?><configuration> ...

  4. EF Core创建实体的Code First标准方法

    针对关系型数据库,实体之间的关系最常见的就是通过外键关联的一对一.一对多和多对多的关系,新的EF Core通过注释和Fluent API 能够做到接近于数据库通过DML创建模型的效果了.实际上,通过D ...

  5. Quartz是一个任务调度

    这段时间做一个案子,用到每天定时处理事件,之前的解决思路是通过一个定时器轮询时间段,这样不能精准的在某个时间戳上执行动作.由于没有用过Quartz是一个任务调度,一直使用这个办法,今天通过同事提点,从 ...

  6. 记一次线上事故的JVM内存学习

    今天线上的hadoop集群崩溃了,现象是namenode一直在GC,长时间无法正常服务.最后运维大神各种倒腾内存,GC稳定后,服务正常.虽说全程在打酱油,但是也跟着学习不少的东西. 第一个问题:为什么 ...

  7. 网页关闭(解决window.close在火狐下不兼容问题)

    熟悉前端的都知道,火狐默认状态非window.open的页面window.close是无效的 网上有很多人说,在火狐的地址栏输入:about:config然后找到dom.allow_scripts_t ...

  8. Centos7调整swap分区

    如何让服务器响应更快?如何避免应用出现内存不足的错误?最简单的方法就是增加交换空间.Swap是存储盘上的一块自留地,操作系统可以在这里暂存一些内存里放不下的东西. 这从某种程度上相当于增加了服务器的可 ...

  9. python实现音乐播放器

    python实现音乐播放器 模块:pygame 模块:time Python 布尔循环实例: import time import pygame muxi_k = """ ...

  10. [工具]Cobalt Strike 3.13 TeamServer for Windows

    Cobalt Strike 3.13 TeamServer for Windows 0x001 环境 CS 3.12 或 3.13 Kali或Win最好安装jdk1.8.5或之后版本 设置环境变量,如 ...