从今天开始看《MFC程序开发参考大全》这本书啦,所以会写一下上面的好玩的代码~
先是第一章,这次的代码就是体现了 在MFC之前,开发人员是怎样写Windows应用程序的。
先上代码好了:
#include"windows.h"
#include<tchar.h>
/*窗口函数
//系统通过窗口函数处理系统中的各种消息
//窗口函数原型为:
//typedef LRESULT(CALLBACK* WNDFUN)(HWND, UINT, WPARAM, LPARAM);
//第一个参数表示窗口句柄,第二个参数表示消息标识,第三、第四个参数表示消息的附加信息
//窗口函数是处理消息的场所,因此在窗口函数内部会存在一个大的switch语句,针对不同的消息进行相应的处理*/
LRESULT CALLBACK WNDFUN(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam){
switch (msg)
{
case WM_PAINT:
{
HDC hdc = GetDC(hWnd);
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, 20, 20, _T("Hola,Feliz"), 10);
DeleteDC(hdc);
break;
}
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, msg, wparam, lparam);
}
return 0;
}
//程序的进入点
//DOS程序的入口点函数为main函数,Windows应用程序的入口点函数为WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int nCmdShow){
//设计窗口类
WNDCLASS wndcls;
wndcls.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName =_T("CustomWnd");
wndcls.lpfnWndProc = WNDFUN;
wndcls.hInstance = GetModuleHandle(NULL);
wndcls.hIcon = NULL;
wndcls.hCursor = NULL;
wndcls.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
//注册窗口类
RegisterClass(&wndcls);
//创建窗口
HWND hwnd;
hwnd = CreateWindow(_T("CustomWnd"), _T("Win32App"), WS_CAPTION | WS_OVERLAPPEDWINDOW | WS_SYSMENU, 50, 50, 500, 500, NULL, NULL, wndcls.hInstance, NULL);
//显示窗口
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
//进入消息循环
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
上面的代码完整的体现了Windows窗口的产生过程:
1.首先是Windows应用程序的入口函数WinMain函数,其语法如下:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int nCmdShow);
2.然后是窗口的诞生,分为四步:设计窗口类、注册窗口类、创建窗口和显示窗口。
设计窗口类:窗口数据结构定义如下:
typedef struct _WNDCLASS{
UINT style; //窗口类的风格
WNDPROC lpfnWndProc; //窗口函数
int cbClsExtra; //窗口类的附加信息
int cbWndExtra; //窗口的附加信息
HANDLE hInstance; //当前的应用程序实例句柄
HICON hIcon; //窗口类的图标句柄
HCURSOR hCursor; //窗口类的光标句柄
HBRUSH hbrBackground; //窗口类的背景画刷句柄
LPCTSTR lpszMenuName; //窗口类的菜单资源名称
LPCTSTR lpszClassName; //该窗口类的类名
} WNDCLASS;
其中要着重说明的是第二个参数lpfnWndProc,它是一个函数指针,表示窗口函数。在代码的最上面有它的一个具体实现的例子和详细的说明。
注册窗口类:定义了一个窗口类后,并不能直接使用它来创建窗体,必须要向操作系统注册窗口类,其语法如下:
ATOM RegisterClass(CONST WNDCLASS* lpWndClass);
lpWndClass表示需要注册的窗口类指针。
创建窗口:在定义并注册窗口类之后,就可以调用CreateWindow函数创建窗口了,其语法如下:
HWND CreateWindow(
LPCTSTR lpClassName,//窗口类名
LPCTSTR lpWindowName,//窗口名
DWORD dwStyle,//窗口风格
int x,
int y,//窗口初始化时左上角的坐标
int nWidth,//窗口的宽度
int nHeight,//窗口的高度
HWND hWndParent,//被创建窗口的父窗口
HMENU hMenu,//窗口的菜单句柄
HANDLE hlnstance,//窗口所在的应用程序实例句柄
LPVOID lpParam/*一个CREATESTRUCT结构指针。在执行CreateWindow函数时,会向窗口函数发送WM_CREATE消息,同时,lpParam参数作为WM_CREATE消息的lParam参数被传递。*/
);
显示窗口:窗口在成功创建后,要调用ShowWindow函数来显示窗口,其函数语法如下:
BOOL ShowWindow(HWND hWnd,int nCmdShow);
第一个参数表示要显示的窗口句柄,第二个参数表示窗口显示的状态,通常为SW_SHOW。
在首次显示窗口时,还需要调用UpdateWindow函数刷新窗口,其函数语法如下:
BOOL UpdateWindow(HWND hWnd);
第一个参数表示需要绘制的窗口句柄。
3.接着是消息处理
Windows应用程序是基于消息的程序设计模式。其处理过程为:用户对窗口进行操作-操作系统首先发现该事件并将事件封装成一个消息,发送到消息队列中-应用程序从消息队列中取出消息,并将其回传给操作系统-操作系统调用“窗口函数”对消息进行处理。
消息循环就是由此构成的:拥有消息队列的线程,需要不断地从消息队列中取出消息,进行处理。在处理消息的过程中,可能会有新的 消息放入消息队列,由此反复便构成了消息循环。
最后是写代码过程中发现的几个小知识:
1.关于char*转LPCWSTR,这个实实在在困扰我了许久,后来用_T()解决了,不过更加详细的解决方案在下面这个链接中,还没有试过,不过看起来挺棒的,先收着。http://blog.youkuaiyun.com/zhouxuguang236/article/details/8761497
2._T()不得不说是一个很好的工具。讲真到现在也不是那么清楚它到底是啥,不过就是很好用,各种转换用它都很自如。
百度上说,它的作用是让程序支持Unicode编码
然后就是关于各种宏的头文件的出处:http://www.cnblogs.com/qinfengxiaoyue/archive/2012/06/05/2535520.html,有趣~
3.里约奥运会马上开始了,简直抑制不住激动的心情,首先希望各位运动员能平安回国(最近关于里约奥运会的吐槽太多了),然后就是我最最最心水的纳达尔,可以健健康康的参加完里约奥运会(喜欢上纳达尔是初中的事情,虽然那时候最爱的当然是娜姐啦。爱上纳达尔是因为他说过,如果网球能给他带来快乐,就算没有拿冠军也会继续打下去,如果网球不再给他带来快乐,就算打的再好也不会继续。真真我男神!)。