从Win32程序中的主函数中获取命令行参数 _twinmain

本文介绍了在Windows程序中如何获取和处理命令行参数,包括使用lpCmdLine参数、GetCommandLine()函数及CommandLineToArgvW()函数等方法,并提到了__argc和__argv全局变量的使用。
http://www.cnblogs.com/xuguilin/archive/2010/10/23/1858970.html

在标准C或者Win32控制台程序的main函数中,它们都有两个参数:"argc" 和 "argv",如下所示:

int main(int argc, char * argv[]) ... 

这些参数帮助我们为程序传入命令行参数。"argc"为命令行参数的个数,"argv"则为传入参数的数组列表。但是当我们在Visual Studio中创建Win32 GUI程序的时候,WinMain变成程序的入口函数,而该函数并没有"argc" 和"argv"参数,那我们怎样给Windows程序传入命令行参数呢?Windows程序中又怎样取得这些传入的参数呢?

lpCmdLine 参数

第一个方案就来自WinMain函数自身。让我们看一个典型的WinMain函数声明:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd).. 

如声明所示,WinMain函数有一个类型为"LPSTR(char*)"的参数"lpCmdLine". 这个变量存放着命令行中除程序自身名字外的剩下所有部分。例如,我们有一个名字为"test.exe"的应用程序,当用下面的命令行运行该程序时

test.exe Some arguments here

变量lpCmdLine的值即为"Some arguments here"。尽管该方法不像"argc"和"argv"一样非常方便,但它是获取命令行参数的方法之一。我们需要自己写程序去分析lpCmdLine字符串,这增加了程序的复杂度。

【译注:Windows程序代码同时ANSI版本和UNICODE版本接口。其中WinMain函数为ANSI版本,wWinMain为UNICODE版本。从Visual Studio创建出来的代码主函数命名为_tWinMain。这个函数名会根据当前工程有没有定义_UNICODE宏而在编译时翻译成上面两个不同版本。当翻译成WinMain函数时候,lpCmdLine的类型为LPSTR,而当翻译成wWinMain函数时候,lpCmdLine的类型为LPWSTR,即宽字符数组】

GetCommandLine()函数

另外一个方法就是使用GetCommandLine() API。这个函数返回整个命令行,它把程序自身名称(包括程序的绝对路径)和所有参数放在一个字符串中。该函数非常类似于对lpCmdLine的直接访问。但它的一个好处是能够根据你当前工程的设置自动映射到GetCommandLineA()或者GetCommandLineW()函数。因此解决了访问Unicode命令行输入的问题。但是它还是既没有提供命令行参数数目,也没有类似argv那样把参数自动分割成独立变量的能力。

CommandLineToArgvW()函数

最后一个我要讨论的方法是CommandLineToArgvW函数。这个函数只有Unicode宽字符版本,没有对应的CommandLineToArgvA函数。它的声明如下:

 
LPWSTR *CommandLineToArgvW(LPCWSTR lpCmdLine, int *pNumArgs) 

该函数和'argc'/'argv'一样简单,但是它并不是在Windows程序中直接访问argc和argv变量。如声明所示,函数接受两个参数,一个是需要解析的Unicode命名行字符串,另外一个是指向整型变量的指针。函数在返回时把参数数目存到这个整型变量中。

函数返回一个类似于'argv'的字符串数组。让我们看一个例子:



  1. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd)
  2. {
  3.     LPWSTR *szArgList;
  4.     int argCount;
  5.  
  6.      szArgList = CommandLineToArgvW(GetCommandLine(), &argCount);
  7.      if (szArgList == NULL)
  8.      {
  9.          MessageBox(NULL, L"Unable to parse command line", L"Error", MB_OK);
  10.          return 10;
  11.      }
  12.  
  13.      for(int i = 0; i < argCount; i++)
  14.      {
  15.          MessageBox(NULL, szArgList[i], L"Arglist contents", MB_OK);
  16.      }
  17.  
  18.      LocalFree(szArgList);
  19.      return 0;
  20. }

如上所示,通过这个函数,我们可以取得命令行参数的数目(argc)和一个字符串列表(argv)。这里唯一要注意的事情是该函数会给返回参数列表分配一块内存。当我们用完列表后需要手动地释放该内存,否则就会有内存泄露

EDIT: Variables __argc and __argv

另外,微软提供了全局变量__argc 和__argv。这两个变量由Windows在运行时自动赋值。其中__argv有ASCII和Unicode版本,分别为__argv和__wargv。要使用这两个全局变量,需要引用"stdlib.h"头文件(该头文件已经在windows.h中引用)。为了根据工程设置来自动选择ASCII还是Unicode版本变量,我们可以引用"TCHAR.h"头文件并访问__targv变量。代码如下

extern int __argc;

extern TCHAR* __targv;

这个方法是所有方法中最简单的一个。但它的代价是程序需要链接VC++运行时库(例如"msvcrt.dll")。当然99%的Windows程序几乎都要使用这个运行库:)


<script>window._bd_share_config={"common":{"bdsnskey":{},"bdtext":"","bdmini":"2","bdminilist":false,"bdpic":"","bdstyle":"0","bdsize":"16"},"share":{}};with(document)0[(getelementsbytagname('head')[0]||body).appendchild(createelement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new date()/36e5)];</script>
阅读(1381) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
<think>首先,用户的问题是:“我想在Visual Studio中查看Win32 API相关文档或定义 请问Visual Studio 查看 Win32 API 函数定义”。这涉及到在Visual Studio中查看Win32 API函数的定义或文档。 根据系统级指令,我需要: - 使用中文回答。 - 结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 - 在回答中引用的段落末尾自然地添加引用标识。 - 生成相关问题。 - 使用正确的LaTeX格式:行内数学表达式用$...$,独立公式用$$...$$并单独成段。 用户提供的引用内容: - 引用[1]: 关于WinMain函数的参数解释。 - 引用[2]: 关于WinMain、_tWinMain等的区别。 - 引用[3]: 关于CreateDialog API的问题。 - 引用[4]: 关于SetTimer函数的原型。 这些引用不是直接针对用户的问题,但可能与Win32 API相关。用户的问题是如何在Visual Studio中查看Win32 API函数定义。所以,我需要基于这些引用和一般知识来回答。 关键点: - 用户想查看函数定义,这可能包括函数原型、参数说明等。 - 在Visual Studio中,查看API函数定义通常通过查看头文件或使用IntelliSense。 步骤来解决用户的问题: 1. **打开头文件**:Win32 API函数定义在Windows头文件中,如<windows.h>。用户可以在Visual Studio中打开这些头文件。 2. **使用Go to Definition**:在Visual Studio中,右键点击函数名,选择“Go to Definition”或“Go to Declaration”来查看函数原型。 3. **查看MSDN文档**:Visual Studio集成MSDN帮助,用户可以通过F1键或搜索查看API文档。 4. **使用Object Browser**:Visual Studio的Object Browser可以浏览Windows SDK中的类型和函数。 确保回答真实可靠: - 我确认这些方法是标准的Visual Studio使用方式。 - 基于引用,引用[1]和[2]提到了WinMain函数,这可以作为示例。 生成相关问题: - 在回答结束后,生成2-3个相关问题,类似于示例。 回答结构: - 介绍方法。 - 逐步解释如何操作。 - 提供示例,基于引用中的内容。 - 添加引用标识。 - 最后,生成相关问题。 使用中文回答。 大纲: 1. **引言**:简要解释在Visual Studio中查看Win32 API函数定义的方法。 2. **步骤**: - 方法1:使用Go to Definition。 - 方法2:查看头文件。 - 方法3:使用MSDN文档。 3. **示例**:以WinMain函数为例,展示如何查看。 4. **引用**:自然地添加引用标识,基于提供的引用。 5. **相关问题**:生成相关问题。 引用标识: - 在相关段落末尾添加,如[^1]。 - 引用内容是关于WinMain和API的,所以可以用于示例。 最终,生成相关问题。</think>### 在Visual Studio中查看Win32 API函数定义的方法 在Visual Studio中查看Win32 API函数定义(如函数原型、参数说明等)是开发Windows应用程序的常见需求。Win32 API函数定义通常位于Windows SDK的头文件(如`<windows.h>`)中,Visual Studio提供了多种便捷方式访问这些内容。以下我将逐步介绍三种可靠方法,确保您能高效查看定义。整个过程基于Visual Studio 2017或更高版本(社区版或专业版均适用),并假设您已安装Windows SDK。 #### 方法1: 使用"Go to Definition"快速查看函数原型 这是最直接的方式,利用Visual Studio的IntelliSense功能: 1. **打开您的C/C++项目**:确保项目已正确配置Windows SDK(默认新建Win32项目会自动包含)。 2. **在代码中定位API函数**:例如,输入`WinMain`函数(这是Win32程序的入口点[^2])。 3. **右键单击函数名**:选择"Go to Definition"(快捷键F12)或"Go to Declaration"(Ctrl+F12)。 4. **查看定义**:Visual Studio将跳转到函数在头文件中的原型。例如,对于`WinMain`,您会看到类似以下定义(位于`<WinBase.h>`或相关头文件): ```c int WINAPI WinMain( HINSTANCE hInstance, // 当前实例句柄[^1] HINSTANCE hPrevInstance, // 保留参数(通常为NULL)[^1] LPSTR lpCmdLine, // 命令行字符串[^1] int nCmdShow // 窗口显示方式[^1] ); ``` - **说明**:此方法实时解析SDK头文件,显示参数类型和注释。如果遇到无法跳转的情况,请检查项目是否引用了正确SDK版本(通过"项目属性 > 配置属性 > 常规 > Windows SDK版本"设置)。 #### 方法2: 手动浏览Windows SDK头文件 如果"Go to Definition"失效(如因项目配置问题),可直接查看头文件: 1. **打开Visual Studio的安装目录**:默认路径为`C:\Program Files (x86)\Windows Kits\10\Include`。 2. **导航到API版本文件夹**:例如,打开`10.0.19041.0\um`(版本号可能不同)。 3. **搜索目标头文件**: - 通用API(如`MessageBox`, `SetTimer`)在`<windows.h>`中[^4]。 - 特定API(如`CreateDialog`)在专有头文件(如`<WinUser.h>`)中[^3]。 4. **使用Visual Studio打开头文件**:右键单击文件选择"打开方式 > 源代码编辑器",然后搜索函数名。 - **示例**:在`<windows.h>`中搜索`SetTimer`,可找到其完整原型: ```c UINT_PTR SetTimer( HWND hWnd, // 窗口句柄[^4] UINT_PTR nIDEvent, // 定时器ID[^4] UINT uElapse, // 时间间隔(毫秒)[^4] TIMERPROC lpTimerFunc // 回调函数[^4] ); ``` #### 方法3: 集成MSDN文档查看 对于参数说明和用法示例,Visual Studio内置MSDN文档浏览器: 1. **在代码中选择函数名**:例如,高亮显示`WinMain`。 2. **按下F1键**:自动打开本地或在线MSDN文档。 3. **阅读详细说明**:文档包括函数描述、参数列表、返回值及示例代码。 - **示例参考**:MSDN会解释`HINSTANCE`表示应用程序实例句柄,`LPSTR`为ANSI字符串指针等[^1][^2]。 4. **备用方式**:如果F1无响应,通过菜单"帮助 > 查看帮助"手动搜索"Win32 API [函数名]"。 #### 注意事项 - **SDK安装验证**:若方法失效,请通过Visual Studio Installer确认"Windows 10 SDK"组件已勾选。 - **Unicode支持**:对于`_tWinMain`等宏定义,需检查`<tchar.h>`头文件[^2],确保项目字符集设置一致(Unicode/MBCS)。 - **性能提示**:大型项目中使用"Go to Definition"时,首次加载可能稍慢,建议关闭无关项目提升响应速度。 通过以上方法,您可以高效查看任何Win32 API函数的定义。例如,`CreateDialog`函数的参数转换问题可通过查看`<WinUser.h>`中的宏定义解决[^3]。 ### 相关问题 1. 如何在Visual Studio中调试Win32 API函数的调用过程? 2. Win32 API中句柄(如`HINSTANCE`)的具体作用是什么? 3. 如何为未安装SDK的Visual Studio添加Win32 API支持?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kelsel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值