我们经常提到DOS程序、Windows程序以及控制台程序,又提到DOS环境、Windows环境以及DOS框,经常让人混淆不清。所以,弄清楚这几种程序的概念,特别是它们之间的区别,是很重要的。下面我们就通过具体的代码,来分析这几种程序的区别:
我们仍选取K&R的“Hello,World!”程序为对象:
1.DOS版本
HelloDos.c:
#include <stdio.h>
int main()
{
printf("Hello,World!/n");
return 0;
}
其等价C++代码为:
HelloDos.cpp
#include <iostream.h>
int main()
{
cout<<"Hello,World!/n"<<endl;
return 0;
}
2.Win32版本
a. Win32 Console
Hellocon.c
#include <stdio.h>
int main()
{
printf("Hello,World!/n");
return 0;
}
hellocon.cpp
#include <iostream.h>
int main()
{
cout<<"Hello,World!/n"<<endl;
return 0;
}
不难看出,helloworld的控制台版本和DOS的代码可以完全相同,而且都可以在Windows的控制台下运行;不同的是后者为32位程序,不能在DOS下运行。
b.Win32 GUI
HelloMsg.c
#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MessageBox (NULL, TEXT ("Hello, World!"), TEXT ("HelloMsg"), 0) ;
return 0 ;
}
本程序调用一个Win32 API函数MessegeBox来显示helloworld消息框。
HELLOWIN.C
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
//PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, World!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
本程序采用了Windows程序的典型结构(窗口+消息循环),在应用程序主窗口的客户区中显示HelloWorld。
c.Win32 GUI None Output
HelloFile.c:
/*--------------------------------------------------------------
HelloFile.c -- print "Hello, World !" in a file
(c) frank fb, 2001
--------------------------------------------------------------*/
#include "stdio.h"
#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
FILE *fp; /*定义文件指针*/
fp=fopen("hello.txt", "w"); /*建立一个文本文件(只写)*/
fprintf(fp, "Hello World !/n");/*向所建文件写一子串*/
fclose(fp); /*关闭文件*/
return 0 ;
}
Win32 GUI模式允许不向用户界面作任何输出,而直接实现其它操作。本程序虽然以WinMain()为入口函数,但并没有与GUI相关的输入输出。它通过文件操作,向一个文本文件输出“Hello World !”。
下面是几种程序在不同平台下的运行情况:
综上,我们已经摸清了这几种程序的基本脉络。
Windows程序不同于DOS程序,目前普遍运行于Windows9x、Windows NT、Windows2000上的Windows程序基于Win32 API,故统称Win32应用程序。
所有的Win32程序,都是32位的应用程序,采用PE可执行文件格式。
Windows系统提供了两种用户接口模式,即图形用户接口模式(GUI mode)和控制台模式(Console mode),就是人们常说的图形模式和字符模式。相应的Win32程序分为两种:Win32 GUI 应用程序(Win32 GUI Application)和Win32 控制台应用程序(Win32 Console Application)。
Win32 控制台应用程序,是字符模式的32位Windows程序。它采用main()函数为入口函数,可以调用C runtime函数和“不牵扯图形用户接口(GUI)”的Win32 API函数。它只能在Windows Console模式下运行。
Win32 GUI 应用程序,是图形模式的32位Windows程序。它采用Winmain()函数为入口函数,可以调用C runtime函数和所有的Win32 API函数。它只能在Windows GUI模式下运行。
值得一提的是,由于控制台窗口是在Windows GUI中显示出来的,因此在Windows GUI程序中可以使用控制台窗口。另外,GUI程序甚至允许程序不向用户界面作任何输出,而完成文件操作、进程管理等工作。显然,GUI程序所包含的范围比它字面上体现出来的要大。因此,微软干脆就把这种GUI模式的Windows 程序叫做Win32 Application。
DOS程序,是16位的应用程序,采用MZ可执行文件格式。它以Main()为入口函数,调用C runtime函数。它可以在DOS环境下运行。DOS程序可分为两类,一类涉及底层的硬件操作(如直接写屏),称为 “Bad”DOS程序;另一类兼容性好,称为“Good”DOS程序,还可以在在32位的Windows的控制台(即DOS框)中运行。