#include <windows.h>
#pragma comment(lib,"winmm.lib")//为了要播放声音,必须导入这个库
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
/*HINSTANCE 类型的含义为实例句柄。hInstance 事实上就是当前应用程序自身的标识代号,代号通常都是一个32位整数。
hPrevInstance 与过去的16位应用程序有关系,表示指向前一个实例的句柄。
PSTR 类型的含义是指向以\0结尾的字符串指针。 szCmdLine 前面的sz同样是表示指向以\0结尾的字符串指针,这个对象用于保存命令行。
iCmdShow是一个整型数据,标记了程序最初的显示状态。
为SW_SHOWNORAML的时候为一般大小显示方式。
为SW_SHOWMAXIMIZED的时候为最大化显示方式。
为SW_SHOWMINNOACTIVE的时候程序将显示在任务栏上。
*/
{
static char szAppName[] = TEXT("HelloWin");
//预先定义一个c风格字符串,稍后用于设置窗口类名称
WNDCLASS wndclass;//定义窗口类对象
/* 窗口类事实上是struct结构体,内部有10个分量,他们是用来于初始化窗口类对象而用的。
这个结构体在winuser.h头文件中定义,从方式上来说,分为ASCII版的WNDCLASSA和Unicode版的WNDCLASSW两个。
typedef struct tagWNDCLASSA {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;
typedef struct tagWNDCLASSW {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
*/
//------------------ 窗口类对象初始化过程 ------------------------- wndclass.style = CS_HREDRAW | CS_VREDRAW;
/* 设置窗口类对象的样式风格,CS_HREDRAW | CS_VREDRAW这两个值是通过位运算的与运算结合起来的。
表示了窗口在改变了水平和垂直大小的时候,窗口要强迫刷新。
这些通过define定义的标识,可以在WinUser.h头文件中找到。
#define CS_VREDRAW 0x0001
#define CS_HREDRAW 0x0002
#define CS_DBLCLKS 0x0008
#define CS_OWNDC 0x0020
#define CS_CLASSDC 0x0040
#define CS_PARENTDC 0x0080
#define CS_NOCLOSE 0x0200
#define CS_SAVEBITS 0x0800
#define CS_BYTEALIGNCLIENT 0x1000
#define CS_BYTEALIGNWINDOW 0x2000
#define CS_GLOBALCLASS 0x4000
#define CS_IME 0x00010000
*/
wndclass.lpfnWndProc = WndProc ;
//指定窗口的处理函数为WndProc,WndProc将处理windows消息。
wndclass.cbClsExtra = 0;//窗口类无扩展
wndclass.cbWndExtra = 0;//窗口实例无扩展
wndclass.hInstance = hInstance;
//指定当前应用程序实例句柄,也就是程序当前的标识号。
wndclass.hIcon = LoadIcon (NULL,IDI_APPLICATION);
/* 通过LoadIcon函数设置应用程序窗口标题的icon图标。
HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName);
函数返回HICON类型的图标句柄。
第一个参数表示当前应用程序的窗口句柄,第二个参数表示图标。
默认状态下,第一个参数为NULL,第二个为IDI_APPLICATION,表示使用系统默认提供的图标,可以在WinUser.h头文件中找到。
#define IDI_APPLICATION 32512
*/
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
/* 通过LoadCursor函数设置应用程序窗口光标样式。
HCURSOR LoadCursor(HINSTANCE hInstance,LPCTSTR lpCursorName);
函数返回HCURSOR类型的光标句柄。
第一个参数表示当前应用程序的窗口句柄,第二个参数表示光标。
默认状态下,第一个参数为NULL,第二个为IDC_ARROW,表示使用系统默认提供的光标,可以在WinUser.h头文件中找到。
#define IDC_ARROW MAKEINTRESOURCE(32512)
*/
wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
/* 通过GetStockObject函数设置应用程序窗口的背景颜色。
HGDIOBJ GetStockObject(int fnObject);
函数返回HCURSOR类型的GDI对象句柄,为了程序能够正确执行,必须把HGDIOBJ类型强制转换成HBRUSH画刷句柄。
参数表示当前使用的画刷颜色。
这些常量的定义可以在WinGDI.h头文件中找到。
#define WHITE_BRUSH 0
#define LTGRAY_BRUSH 1
#define GRAY_BRUSH 2
#define DKGRAY_BRUSH 3
#define BLACK_BRUSH 4
#define NULL_BRUSH 5
#define HOLLOW_BRUSH NULL_BRUSH
*/
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;//窗口类对象的名称
//------------------------------------------------------------------
RegisterClass (&wndclass);
/* 注册窗口类,参数为窗口类对象的指针。
函数原形为: ATOM RegisterClass(CONST WNDCLASS *lpWndClass);
*/
//-------------------------- 实例化过程 ------------------------------
HWND hwnd ;
//创建用于保存窗口句柄的对象,窗口句柄是系统识别不同窗口的依据,它只是个代号。
hwnd = CreateWindow(
szAppName, // 窗口类名称
"你好世界", // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口样式
CW_USEDEFAULT, // 初始的窗口x轴位置
CW_USEDEFAULT, // 初始的窗口y轴位置
CW_USEDEFAULT, // 初始的窗口x轴大小
CW_USEDEFAULT, // 初始的窗口y轴大小
NULL, // 父窗口句柄
NULL, // 窗口功能表句柄
hInstance, // 应用程序实例句柄
NULL // 建立参数,这个参数可以存取后面程序中可能引用到的资料。
);
/* 在窗口类对象的初始化过程中,我们定义了窗口的一些简单一般特征,比如背景颜色呀,光标呀,等等。但是在利用CreateWindow创建窗口的时候可以设置更多的细节,比如窗口标题这些。
函数原形如下:
HWND CreateWindow( LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
一旦窗口创建成功,那么CreateWindow将返回窗口句柄,也就是窗口代号,值保存在窗口句柄对象hwnd中。
*/
ShowWindow(hwnd, iCmdShow);
/* 在执行过CreateWindow函数后,在系统的内部窗口已经创建成功了。
但为了要把窗口显示在桌面上,还必须调用ShowWindow函数。
其函数原形如下:BOOL ShowWindow(WND hWnd,int iCmdShow);
参数1是需要显示的窗口句柄,第二个则是传递给WinMain的iCmdShow,用来确定最开始窗口的显示方式。
在这里窗口的显示方式,主要是指最大化,最小化这些。
*/
UpdateWindow (hwnd);
/* UpdateWindow这个函数的作用是用于重绘显示区域。
因为如果ShowWindow函数的iCmdShow从WinMain获得的参数是SW——SHOWNORMAL,那么窗口的显示区域就会被背景画刷覆盖,
调用UpdateWindow函数会通过发送给窗口消息处理函数WndProc一个WM_PAINT消息,通过这个消息完成重绘显示区域的工作。
*/
//------------------------- 消息循环 -------------------------
/* 当调用过UpdateWindow函数后,窗口已经显示在了桌面屏幕上,接下来要做的工作是处理消息。windows应用程序可以接受各种消息包括键盘,鼠标,等. windows是通过监视各种输入设备,把发生的事件转化为消息的,并将消息保存在消息队列中。最后当前的应用程序从自己的消息队列中按顺序检索消息,并把每一个消息发送到所对应的窗口消息处理函数总去,这里是指WndProc。
*/
MSG msg ;//建立消息对象。
/* MSG是个结构体类型,在WinUser.h头文件中可以找到。
typedef struct tagMSG{
HWND hwnd;//窗口句柄
UINT message;//消息识别字,在WinUser.h头文件中可以找到,以WM开头。
WPARAM wParam;//32位的消息参数,其含义和值根据消息的不同而不同。
LPARAM lParam;//32位的消息参数,其值和消息无关。
DWORD time;//消息进入消息队列的时间。
POINT pt;//消息进入消息队列时候的鼠标坐标。
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
其中POINT也是个结构体类型,在WinDef.h头文件中可以找到
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
*/
while (GetMessage (&msg, NULL, 0, 0))
{
/* 通过这个循环代码来维护消息循环,循环的执行条件是通过GetMessage函数获得的。
函数原型如下:
BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
参数一是一个指向msg对象的指针,剩余的参数为NULL或0表示程序接受它自己建立的所有窗口的消息。
windows从消息队列取出的下一个消息将填充MSG结构中的各成员分量。
*/
TranslateMessage (&msg);
//把虚拟键盘消息转换到字符消息,满足键盘输入的需要,参数为msg消息对象的指针。
DispatchMessage (&msg);
/* 把当前的消息发送到窗口消息处理函数中去处理,在这里为WndProc。
当DispatchMessage调用结束后,循环再次重复,重新回到GetMessage处,接着获取消息。
如果消息循环接收到WM_QUIT消息则跳出消息循环。
*/
}
//-----------------------------------------------------------------------
return msg.wParam;
//返回消息结构中的wParam成员信息。
/* MSG结构的wParam成员的值是传递给PostQuitMessage函数参数,通常是0。
因为PostQuitMessage函数是在结束消息循环必须调用的函数。
系统其实是执行了return 0;结束了WinMain函数退出了程序,很想控制台应用程序main结束的时候的return 0;,所以直接写return 0;也不会导致程序错误。
*/
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)//窗口消息处理函数
/* 函数返回类型为LRESULT,是一个长整数,修饰CALLBACK表示此函数为回调函数,函数的返回类型,和参数顺序都必须按照系统的规定设置。
参数一为窗口句柄,第二个参数是无符号整型数据,用于标识接受的消息,最后两个参数为32位的消息参数,提供了更多关于消息的信息。
WPARAM和LPARAM都表示的是长整数,该函数的四个参数与MSG结构的前四个成员相同。
消息处理函数,通常是windows自己调用的,当然程序作者也可以通过调用SendMessage函数直接呼叫自己的窗口消息处理函数,只是在这里暂时不讨论。
*/
{
HDC hdc;
//创建设备描述句柄对象
PAINTSTRUCT ps;
//创建绘制结构对象
/* PAINTSTRUCT结构包含了一些窗口消息处理程序,可以用来更新窗口显示区域中的信息。
结构如下:
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT;
*/
RECT rect;//创建矩形结构对象
/* 此结构的定义如下:
typedef struct _RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT;
*/
switch (message)
//通过switch和case结构来确定处理什么样的消息,如果不想处理某些消息则把消息传递给DefWindowProc函数处理。
{
case WM_CREATE:
//当窗口创建的时候获得WM_CREATE消息
PlaySound (TEXT("C:\\online.wav"),NULL,SND_FILENAME|SND_ASYNC);
//播放声音
return 0;
//窗口消息处理函数如果正在处理消息必须返回0
case WM_PAINT:
//通知窗口更新显示区域的信息
/* 当窗口刚开始建立的时候,整个显示区域都是无效的,因为程序还没有在窗口上绘制任何东西。
第一条WM_PAINT消息通常发生在调用UpdateWindows函数的时候,告诉窗口消息处理函数在显示区域绘制一些东西。
事实上当用户把wndclass.style设置成CS_HREDRAW | CS_VREDRAW后,一旦用户改变窗口大小,就会把显示区域当作无效,这时候就会收到WM_PAINT消息。
*/
/* 通常在处理WM_PAINT消息的时候,总是以BeginPaint开头和EndPaint结尾的。
*/
hdc = BeginPaint (hwnd, &ps);
/*
调用BeginPaint函数可以传回设备句柄,这里指的是显示器的代号和显示器的驱动程序。
因为在窗口显示区域要显示文字或者图形都需要用到设备句柄。
它的函数原形为:
HDC BeginPaint(
HWND hwnd, // handle to window
LPPAINTSTRUCT lpPaint // paint information
);
它实际的功能是:当发现窗口显示区域的背景还没有被清除的时候,则由windows来删除它。
我们前面在wndclass结构中设置了画刷为白色,这么以来系统就用白色来遮盖桌面的颜色,这样窗口显示区域就变成白色了。
*/
GetClientRect (hwnd,&rect);
//设置窗口显示区域的尺寸,同时它也负责获得窗口改变后的窗口显示区域的尺寸信息。
DrawText (hdc,TEXT("中国软件开发实验室,http://www.xxx.com"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
//绘制文字在窗口显示区域中
/* DT_SINGLELINE|DT_CENTER|DT_VCENTER 表示的是文字显示的方式,这些在WinUser.h头文件中定义。
*/
EndPaint (hwnd,&ps);//结束指定窗口的绘图
return 0;
case WM_DESTROY:
//当窗口销毁的时候会返回此信息,比如ALT+F4或关闭窗口的时候,系统默认调用DestroyWindow()函数撤消窗口。
PostQuitMessage (0);
/* 处理WM_DESTROY消息必须调用PostQuitMessage函数,该函数向消息队列中发送WM_QUIT消息,让程序退出消息循环。
应用程序可以在响应这个消息的同时做一些其它结束的工作。
*/
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
//处理不于处理的消息
}
分享到:
相关推荐
**VC++入门教程详解** VC++,全称Visual C++,是微软开发的一款集成开发环境(IDE),主要用于编写使用C++编程语言的应用程序。它集成了编译器、调试器和其他工具,使得开发者能够高效地创建Windows平台上的桌面...
VC++入门教程(windows入门程序详解)
VC++,全称为Visual C++,是微软公司开发的一款强大的集成开发环境...总之,VC++入门程序代码的学习是一个系统的过程,需要你耐心地掌握基础,逐步探索高级特性。只有通过不断实践和积累,才能真正成为VC++编程的高手。
### VC++入门详解:从创建项目到运行程序的全过程 #### 一、了解VC++及其基本操作 **VC++**,全称为Visual C++,是由微软公司开发的一款强大的集成开发环境(IDE),主要用于Windows平台上的C++编程。它集成了编辑...
本压缩包中的"VC++入门的小程序可直接运行"提供了20个基础的VC++程序实例,是初学者了解和学习VC++的绝佳资料。下面,我们将详细讨论这些基础知识点: 1. **集成开发环境(IDE)**: VC++的IDE提供了编辑、编译、...
**VC++入门知识详解** 在计算机编程领域,Visual C++(简称VC++)是由微软公司开发的一款集成开发环境,主要用于编写使用C++语言的应用程序。它不仅提供了编译器,还包括了调试器、资源编辑器等工具,是学习C++编程...
本压缩包“VC++OpenGL源码 详解”显然包含了使用VC++开发OpenGL应用的相关源代码,并且每行代码都有详细的注释,旨在帮助初学者理解并学习OpenGL编程。NeHe教程是一个非常著名的OpenGL教学资源,它提供了很多基础到...
《VC++6.0编译器详解》 Visual C++ 6.0是Microsoft公司推出的一款集成开发环境,主要用于编写C++程序。虽然现在已经有了更新的版本,但VC++6.0因其稳定性和广泛的应用,仍然是许多开发者入门学习C++的首选。本文将...
### vc++入门教程知识点概述 本教程以txt格式呈现,主要针对初学者,旨在提供一个系统性的学习路径,帮助理解并掌握Visual C++与MFC的基础知识。以下将详细解析标题、描述及部分内容中涉及的核心知识点。 #### 一...
【VC++入门教程、编程-----深入详解一】 Visual C++是一种强大的编程环境,它扩展了C++语言,使之成为一种面向对象的编程语言,适用于Windows平台的开发。面向对象编程(OOP)的核心思想是封装、继承和多态,它提高...
本文资源根据孙鑫《VC++深入详解》一书,详细的介绍了吗,程序内部运行的机制和MFC程序的组织脉络入手,使读者在学习VC++编程知识时,既能够知其然,又能知其所以然,从而帮助读者从根本上理解和掌握Windows的程序...
"VC++深入详解.pdf"可能包含了更全面的VC++语言和库的细节,帮助读者进一步提升技能。 总的来说,这些资源为VC++开发者提供了一个全面的学习路径,无论是在数据库编程、DLL使用还是高级语言特性方面,都有所覆盖。...
《VC 入门教程:Windows 入门程序详解》是一份面向初学者的教程,旨在帮助读者理解如何使用Visual C++(VC++)进行Windows应用程序开发。教程主要关注两种编程方法:Windows C(SDK)方式和C++方式,特别是通过MFC...
总的来说,《VC++.net驱动开发详解》是一本全面介绍VC++.net环境下驱动开发的书籍,它不仅适合初学者入门,也适合有一定经验的开发者作为参考。通过阅读这本书,读者可以提升自己在驱动开发领域的专业技能,更好地...
**向导对话框详解** 向导对话框是Visual C++编程中的一种常见界面元素,它在用户交互过程中起到了引导和步骤指示的作用。与传统的属性表相比,向导对话框允许用户通过点击“下一步”和“上一步”按钮来逐个浏览和...
【VC++入门详解】 VC++,全称Visual C++,是微软公司开发的一款集成开发环境,主要用于编写使用C++语言的Windows应用程序。本教程旨在为初学者提供一个全面且清晰的VC++学习路径,从基础知识到深入理解,帮助读者...
《VC++深入详解代码》这本书不仅适合初学者入门,也适合有一定经验的开发者深入学习。通过阅读和实践书中的代码,读者将能够系统地掌握VC++编程技能,从而在Windows平台上开发出高效、稳定的软件应用。
### VC++ 入门经典(Part 2):迭代器详解 #### 一、引言 在《VC++ 入门经典》这本书中,作者详细介绍了C++编程的基础与高级特性,尤其对于初学者来说非常实用。在本部分中,我们将深入探讨迭代器的相关概念及其在...