Windows环境编程 - STARTUPINFO的说明

typedef struct _STARTUPINFO
{
   DWORD cb;            //包含STARTUPINFO结构中的字节数.如果Microsoft将来扩展该结构,它可用作版本控制手段.
                        应用程序必须将cb初始化为sizeof(STARTUPINFO)
   PSTR lpReserved;      //保留。必须初始化为N U L L
   PSTR lpDesktop;    //用于标识启动应用程序所在的桌面的名字。如果该桌面存在,新进程便与指定的桌面相关联。
                      如果桌面不存在,便创建一个带有默认属性的桌面,并使用为新进程指定的名字。
                     如果lpDesktop是NULL(这是最常见的情况),那么该进程将与当前桌面相关联
   PSTR lpTitle;    //用于设定控制台窗口的名称。如果l p Ti t l e 是N U L L ,则可执行文件的名字将用作窗口名
   DWORD dwX;       //用于设定应用程序窗口在屏幕上应该放置的位置的x 和y 坐标(以像素为单位)。
   DWORD dwY;       只有当子进程用CW_USEDEFAULT作为CreateWindow的x参数来创建它的第一个重叠窗口时,
                    才使用这两个坐标。若是创建控制台窗口的应用程序,这些成员用于指明控制台窗口的左上角

   DWORD dwXSize; //用于设定应用程序窗口的宽度和长度(以像素为单位)只有dwYsize
    DWORD dwYSize;   当子进程将C W _ U S E D E FA U LT 用作C r e a t e Wi n d o w 的
                     n Wi d t h参数来创建它的第一个重叠窗口时,才使用这些值。
                     若是创建控制台窗口的应用程序,这些成员将用于指明控制台窗口的宽度
   DWORD dwXCountChars; //用于设定子应用程序的控制台窗口的宽度和高度(以字符为单位)
   DWORD dwYCountChars;
   DWORD dwFillAttribute;   //用于设定子应用程序的控制台窗口使用的文本和背景颜色
   DWORD dwFlags;           //请参见下一段和表4 - 7 的说明
   WORD wShowWindow;        //用于设定如果子应用程序初次调用的S h o w Wi n d o w 将S W _ S H O W D E FA U LT 作为
                              n C m d S h o w 参数传递时,该应用程序的第一个重叠窗口应该如何出现。
                              本成员可以是通常用于Show Wi n d o w 函数的任何一个S W _ *标识符
   WORD cbReserved2;        //保留。必须被初始化为0
   PBYTE lpReserved2;       //保留。必须被初始化为N U L L
   HANDLE hStdInput;        //用于设定供控制台输入和输出用的缓存的句柄。
                            按照默认设置,h S t d I n p u t 用于标识键盘缓存,
                            h S t d O u t p u t 和h S t d E r r o r用于标识控制台窗口的缓存
   HANDLE hStdOutput;
   HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;


当Wi n d o w s 创建新进程时,它将使用该结构的有关成员。大多数应用程序将要求生成的应用程序仅仅使用默认值。至少应该将该结构中的所有成员初始化为零,然后将c b 成员设置为该结构的大小:
STARTUPINFO si = { sizeof(si) };
CreateProcess(...,&si,...);

表4-7 dwFlags 使用标志及含义
标志                                    含义
STARTF_USESIZE                 // 使用d w X S i z e 和d w Y S i z e 成员
STARTF_USESHOWWINDOW              //使用w S h o w Wi n d o w 成员
STARTF_USEPOSITION              //使用d w X 和d w Y 成员
STARTF_USECOUNTCHARS                //使用d w X C o u n t C h a r s 和dwYCount Chars 成员
STARTF_USEFILLATTRIBUTE          //使用d w F i l l A t t r i b u t e 成员
STARTF_USESTDHANDLES              //使用h S t d I n p u t 、h S t d O u t p u t 和h S t d E r r o r 成员
STARTF_RUN_FULLSCREEN              //强制在x 8 6 计算机上运行的控制台应用程序以全屏幕方式启动运行

另外还有两个标志,即STARTF_FORCEONFEEDBACK 和STARTF_+FORCEOFFF -EEDBACK ,当启动一个新进程时,它们可以用来控制鼠标的光标。由于Windows支持真正的多任务抢占式运行方式,因此可以启动一个应用程序,然后在进程初始化时,使用另一个程序。为了向用户提供直观的反馈信息,C r e a t e P r o c e s s 能够临时将系统的箭头光标改为一个新光标,即沙漏箭头光标:

该光标表示可以等待出现某种情况,也可以继续使用系统。当启动另一个进程时,CreateProcess函数使你能够更好地控制光标。当设定STARTF_FORCEONFEEDBACK标志时,C r e a t e P r o c e s s 并不将光标改为沙漏。

STARTF_FORCEONFEEDBACK可使CreateProcess能够监控新进程的初始化,并可根据结果来改变光标。当使用该标志来调用CreateProcess时,光标改为沙漏。过2 s 后,如果新进程没有调用G U I ,CreateProcess 将光标恢复为箭头。

如果该进程在2 s 内调用了GUI ,CreateProcess将等待该应用程序显示一个窗口。这必须在进程调用G U I 后5 s 内发生。如果没有显示窗口,CreateProcess就会恢复原来的光标。如果显示了一个窗口,CreateProcess将使沙漏光标继续保留5 s 。如果某个时候该应用程序调用了G e t M e s s a g e 函数,指明它完成了初始化,那么C r e a t e P r o c e s s 就会立即恢复原来的光标,并且停止监控新进程。

在结束这一节内容的介绍之前,我想讲一讲S TA RT U P I N F O 的w S h o w Wi n d o w 成员。你将该成员初始化为传递给( w ) Wi n M a i n 的最后一个参数n C m d S h o w 的值。该成员显示你想要传递给新进程的( w ) Wi n M a i n 函数的最后一个参数n C m d S h o w 的值。它是可以传递给S h o w Wi n d o w 函数的标识符之一。通常,n C m d S h o w 的值既可以是S W _ S H O W N O R M A L ,也可以是SW_ SHOWMINNOACTIVE 。但是,它有时可以是S W _ S H O W D E FA U LT 。

当在E x p l o r e r 中启动一个应用程序时,该应用程序的( w ) Wi n M a i n 函数被调用,而S W _ S H O W N O R M A L 则作为n C m d S h o w 参数来传递。如果为该应用程序创建了一个快捷方式,可以使用快捷方式的属性页来告诉系统,应用程序的窗口最初应该如何显示。图4 - 3 显示了运行N o t e p a d 的快捷方式的属性页。注意,使用R u n 选项的组合框,就能够设定如何显示N o t e p a d 的窗口。

当使用E x p l o r e r 来启动该快捷方式时,E x p l o r e r 会正确地准备S TA RT U P I N F O 结构并调用C r e a t e P r o c e s s 。这时N o t e p a d 开始运行,并且为n C m d S h o w 参数将S W _ S H O W M I N N O A C T I V E传递给它的( w ) Wi n M a i n 函数。

运用这样的方法,用户能够很容易地启动一个应用程序,其主窗口可以用正常状态、最小或最大状态进行显示。

最后,应用程序可以调用下面的函数,以便获取由父进程初始化的S TA RT U P I N F O 结构的拷贝。子进程可以查看该结构,并根据该结构的成员的值来改变它的行为特性。

VOID GetStartupInfo(LPSTARTUPINFO pStartupInfo);
注意虽然Wi n d o w s 文档没有明确地说明,但是在调用G e t S t a r t I n f o 函数之前,必须像下面这样对该结构的c b 成员进行初始化:
STARTUPINFO si = { sizeof(si) };
GetStartupInfo(&si);

<think>嗯,用户想了解Windows API开发详解。首先,我需要确定用户的基础水平,可能是个刚开始学习Windows编程的开发者。他们可能想知道什么是Windows API,以及如何开始使用它。 接下来,我应该先解释Windows API的基本概念,比如它是操作系统提供的函数库,用于系统级操作。然后,可能需要介绍开发环境,比如需要安装Visual Studio,配置项目设置等。 然后,用户可能需要具体的例子来理解如何使用API。比如,创建一个窗口程序,这涉及到WinMain函数、窗口类注册、消息循环等。这部分需要详细但清晰的步骤,避免太技术化的术语,让新手也能跟上。 另外,用户可能对常用的API功能感兴趣,比如文件操作、进程线程管理、注册表操作等。需要列举一些常见的API函数,并给出简单的示例,比如CreateFile或ReadFile的使用。 还要注意提到Unicode和ANSI的区别,因为这是Windows编程中常见的坑。可能需要解释字符集设置的重要性,以及如何正确使用TCHAR类型。 调试和错误处理也是关键部分,用户可能需要知道如何获取错误信息,比如使用GetLastError。这部分应该给出实际的代码示例,展示如何检查API调用的成功与否。 资源方面,推荐官方文档和书籍是必要的,比如MSDN和《Windows程序设计》这本书。同时,社区支持如Stack Overflow和CodeProject也能帮助开发者解决问题。 最后,总结一下学习路径,强调实践的重要性,建议从简单例子开始逐步深入。还要提醒用户注意API版本和兼容性问题,确保他们的程序能在不同Windows版本上运行。 整个过程需要结构清晰,分点说明,用简单的中文表达,避免过于复杂的术语,让用户能够一步步理解和应用。</think>以下是对Windows API开发的逐步详解,帮助您系统化理解其核心概念与应用: 1. 基础认知 1.1 定义 Windows API是Microsoft提供的原生应用程序接口集合(约数万个函数),包含: - 核心系统服务:kernel32.dll - 用户界面操作:user32.dll - 图形设备接口:gdi32.dll - 高级功能库:advapi32.dll等 1.2 开发特性 - 直接操作系统底层资源 - 使用C语言接口(兼容C++) - 需要处理句柄(Handle)、消息循环等特有机制 2. 开发环境配置 2.1 必需工具 - Visual Studio 2022+(社区版免费) - Windows SDK(随VS自动安装) - WinDbg调试工具(可选) 2.2 项目设置步骤 1. 新建C++空项目 2. 项目属性 → 配置属性 → 高级 → 字符集:使用多字节字符集 3. 附加依赖项添加kernel32.lib user32.lib等库文件 3. 第一个窗口程序 ```cpp #include <Windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { // 注册窗口类 WNDCLASS wc = {}; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.lpszClassName = L"MainWindow"; RegisterClass(&wc); // 创建窗口 HWND hwnd = CreateWindow( L"MainWindow", L"示例窗口", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); // 消息循环 MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hwnd, msg, wParam, lParam); } } ``` 4. 核心编程要素 4.1 句柄体系 - HWND:窗口句柄 - HINSTANCE:程序实例句柄 - HDC:设备上下文句柄 - HANDLE:通用对象句柄(文件、进程等) 4.2 消息机制 Windows采用事件驱动模型,消息类型示例: - WM_CREATE:窗口创建 - WM_PAINT:绘制请求 - WM_CLOSE:关闭事件 5. 常用API功能模块 5.1 文件操作 ```cpp HANDLE hFile = CreateFile( L"test.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { WriteFile(hFile, "Hello API", 9, NULL, NULL); CloseHandle(hFile); } ``` 5.2 进程管理 ```cpp STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; CreateProcess( NULL, L"notepad.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); ``` 6. 调试技巧 6.1 错误处理标准模式 ```cpp if (!SomeAPICall()) { DWORD err = GetLastError(); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); MessageBox(NULL, (LPCTSTR)lpMsgBuf, L"错误", MB_OK); LocalFree(lpMsgBuf); } ``` 7. 学习资源推荐 - 官方文档Microsoft Learn Windows开发文档 - 经典书籍:《Windows程序设计》(Petzold著) - 开发工具:WinSpy++(窗口分析工具)、API Monitor(函数调用监控) - 社区支持:MSDN论坛、Stack Overflow的winapi标签 8. 进阶路线建议 1. 掌握基本窗口程序架构 2. 熟练使用GDI进行图形绘制 3. 学习COM组件编程 4. 研究驱动程序开发(WDK) 5. 了解UWP与现代Windows Runtime API 注意事项: - 注意32/64位兼容性(使用`SetWindowLongPtr`代替`SetWindowLong`) - 正确处理Unicode(推荐始终使用宽字符版本API) - 关注API废弃状态(如部分Win32 API已被取代) 通过系统学习和持续实践,您可以逐步掌握Windows系统级开发的精髓。建议从修改现有示例代码开始,逐步过渡到独立项目开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值