/*_############################################################################
_##
_## Programming Windows程式开发设计指南->第三章 例子程序
_## Author: xwlee
_## Time: 2007.06.13
_## Chang'an University
_## Development condition: win2003 Server+VC6.0
_##
_## 程序3-1 HELLOWIN
_## HELLOWIN.C 文件
_## 建立一个窗口首先需要注册一个窗口类别,那需要一个窗口消息处理程序来处理窗口消息。
_## 处理窗口消息对每个Windows程序都带来了些负担。程序3-1所示的HELLOWIN程序中整个做
_## 的事情差不多就是料理这些事情。
_##
_##
_##
_## HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
_## (c) Charles Petzold, 1998
_##
_##########################################################################*/
#include <windows.h>
// WndProc函数传回一个类型为LRESULT的值,该值简单地被定义为一个LONG。
// WinMain函数被指定了一个WINAPI类型(在头文件中定义的所有Windows函数都被指定这种类型),
// 而WndProc函数被指定一个CALLBACK类型。这两个标帜符都被定义为_stdcall,表示在Windows本身
// 和用户的应用程序之间发生的函数调用的调用参数传递方式。
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; // 窗口消息处理程序 声明
// HINSTANCE 实例(程序自身)句柄
// 句柄是一个(通常为32位的)整数,它代表一个对象。
// Windows中的句柄类似传统C或者MS-DOS程序设计中使用的文件句柄。程序几乎总是通过调用Windows
// 函数取得句柄。程序在其他Windows函数中使用这个句柄,以使用它代表的对象。句柄的实际值对程
// 序来说是无关紧要的。但是,向您的程序提供句柄的Windows模块知道如何利用它来使用相对应的对象。
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ; // HWND 窗口句柄
MSG msg ; // MSG 消息结构
WNDCLASS wndclass ; // WNDCLASS 窗口类别结构
wndclass.style = CS_HREDRAW | CS_VREDRAW ; // CS_ 窗口类别样式
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ; // 在窗口类别结构中预留一些额外空间
wndclass.cbWndExtra = 0 ; // 在Windows内部保存的窗口结构中预留一些额外空间
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_INFORMATION) ; // 载入图标供程序使用 IDI_ 图标ID
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; // 载入鼠标光标供程序使用 IDC_ 光标ID
wndclass.hbrBackground = (HBRUSH) GetStockObject (4) ;
/*
#define WHITE_BRUSH 0
#define LTGRAY_BRUSH 1
#define GRAY_BRUSH 2
#define DKGRAY_BRUSH 3
#define BLACK_BRUSH 4
#define NULL_BRUSH 5
*/
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
// 现在有一个问题:如果用定义的UNICODE标帜符编译了程序,
// 程序将调用RegisterClassW。该程序可以在Microsoft Windows NT
// 中运行良好。但如果此程序在Windows 98上运行,RegisterClassW
// 函数并未真地被运行到。函数有一个入口,但函数调用后只传回0,
// 表明错误。对于在Windows 98下运行的Unicode程序来说,这是一个
// 通知用户有问题并终止运行的好机会。这是本书中多数程序处理
// RegisterClass函数调用的方法:
if (!RegisterClass (&wndclass)) // 为程序窗口注册窗口类别
{
MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ; // 显示消息框(方块) MB_ 消息框(方块)
return 0 ;
}
/*
if (!hPrevInstance)
{
// wndclass.cbStyle = CS_HREDRAW | CS_VREDRAW ;
//初始化其他 wndclass
RegisterClass (&wndclass) ;
}
// 在32位的Windows中,hPrevInstance总是NULL。此程序码会正常运行,
// 而实际上也没必要检查hPrevInstance。
*/
// 根据窗口类别建立一个窗口
hwnd = CreateWindow( szAppName, // window class name 这就是我们建立的窗口联结窗口类别的方式
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position // CW_ 建立窗口
CW_USEDEFAULT, // initial y position // CW_ 建立窗口
CW_USEDEFAULT, // initial x size // CW_ 建立窗口
CW_USEDEFAULT, // initial y size // CW_ 建立窗口
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ; // 在屏幕上显示窗口
// 第一个参数是刚刚用CreateWindow建立的窗口句柄。第二个参数是作为参数传给
// WinMain的iCmdShow。它确定最初如何在屏幕上显示窗口,是一般大小、最小化还是最大化。
UpdateWindow (hwnd) ; // 指示窗口自我更新
// 只要从消息伫列中取出消息的message栏位不为WM_QUIT(其值为0x0012),
// GetMessage就传回一个非零值。WM_QUIT消息将导致GetMessage传回0。
while (GetMessage (&msg, NULL, 0, 0)) // 从消息队列中取得消息
{
// 将msg结构传给Windows,进行一些键盘转换。(关于这一点,我们将在第六章中深入讨论。)
TranslateMessage (&msg) ; // 转译某些键盘消息
DispatchMessage (&msg) ; // 将消息发送给窗口消息处理程序,这里是WndProc
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ; // HDC 设备环境句柄
PAINTSTRUCT ps ; // PAINTSTRUCT 绘图结构
RECT rect ; // RECT 矩形结构
switch (message)
{
case WM_CREATE: // WM_ 窗口消息
PlaySound (TEXT ("Windows XP 关机.wav"), NULL, SND_FILENAME | SND_ASYNC) ; // 播放一个音效文件 SND_ 声音
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ; // 开始绘制窗口
GetClientRect (hwnd, &rect) ; // 取得窗口客户区的大小
DrawText (hdc, TEXT ("电脑救护站前身是亿立校园电脑救助网。"
"/n2003年8月起开始运作,通过我们的不断努力和广大网友的大力支持,"
"/n网站开通至2005年,在此期间网站得到了广大用户的认可和厂商的赞同,"
"/n由于网站管理成员的学业以及其他因素,亿立校园电脑救助网在2005年正式关闭。"), -1, &rect,
DT_CENTER | DT_VCENTER) ; // 显示字符串
// DT_ 绘制文本
EndPaint (hwnd, &ps) ; // 结束绘制窗口
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ; // 在消息伫列中插入一个「退出程序」消息
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ; // 运行默认的消息处理
}