本系列文章记录我学习VC++的过程。
一直以来我对自己的定位是C++工程师,但到目前为止我对C++的了解还停留在C阶段,只会用C的特性加上面向对象的知识写一点控制台程序,要我写真正能应用到企业上的实用性应用就无能为力了。虽然实习的时候靠着学校学的基础知识成功应聘了C++开发工程师,但现在做的却是Flex方向的开发工作。
所以我要用这个暑假全面攻克C++,包括VC++,C++11新特性及STL基础。
话不多说,现在开始VC++的HelloWorld!先贴代码。
LRESULT CALLBACK WinProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
/*主程序*/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nCmdShow) {
//(1)设计窗口类
WNDCLASS wndcls;
wndcls.cbClsExtra = 0; //窗口类附加内存
wndcls.cbWndExtra = 0; //窗口附加内存
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //窗口背景刷
wndcls.hCursor = LoadCursor(NULL, IDC_CROSS); //窗口光标
wndcls.hIcon = LoadIcon(NULL, IDI_ERROR); //窗口图标
wndcls.hInstance = hInstance; //窗口句柄
wndcls.lpfnWndProc = WinProc; //窗口处理过程
wndcls.lpszClassName = _T("myWindow"); //窗口类
wndcls.lpszMenuName = NULL; //窗口菜单
wndcls.style = CS_HREDRAW | CS_VREDRAW; //窗口类样式
//(2)注册窗口类
RegisterClass(&wndcls);
//(3)创建窗口
HWND hwnd;
hwnd=CreateWindow(_T("myWindow"), _T("Hello"), WS_OVERLAPPEDWINDOW, 100, 100, 960, 640, NULL, NULL, hInstance, NULL);
//(4)显示及刷新窗口
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
//(5)开始消息循环
MSG msg;
BOOL bRet;
while (bRet=GetMessage(&msg, NULL, 0, 0)) {
//如果指定消息属于当前创建的窗口,那么必须做一个错误判断
//因为窗口被销毁后获取消息就会得到一个错误,不作判断的话会陷入死循环
//当然,指定消息所属的窗口为空,判断错误就可有可无了
if (bRet == -1) {
return -1;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_CHAR:
CHAR szChar[20];
//wprintf(szChar, _T("%d"), wParam);
sprintf_s(szChar, "按键代码 is %c", wParam);
MessageBoxA(hWnd, szChar, "按键", 0);
break;
case WM_LBUTTONDOWN:
{
MessageBox(hWnd, _T("鼠标左键按下!"), _T("提示"), 0);
HDC hDc;
hDc = GetDC(hWnd);
TextOut(hDc, 0, 0, _T("Vc++ 程序设计!"), _tcslen(_T("Vc++ 程序设计!")));
ReleaseDC(hWnd, hDc);
}
break;
case WM_PAINT:
{
HDC hDc;
PAINTSTRUCT ps;
hDc = BeginPaint(hWnd, &ps); //该函数会发送WM_ERASEBKGND消息,使用窗口画刷擦除窗口
TextOut(hDc, 0, 0, _T("你好,世界!"), _tcslen(_T("你好,世界!")));
EndPaint(hWnd, &ps);
}
break;
case WM_CLOSE:
if (MessageBox(hWnd, _T("你真的要退出吗?"), _T("提示"), 0) == IDOK) {
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
Windows应用程序中的几个重要概念:
1、句柄(HANDLE):句柄是Windows操作系统用来区分每个应用的唯一标识。句柄的类型有很多种,有窗口句柄(HWND),图标句柄(HICON),光标句柄(HCURSOR)和画刷句柄(HBRUSH)等等。
2、窗口:窗口是Windows程序最基本的元素,每个Windows程序都至少有一个窗口,称为主窗口。窗口是Windows应用程序与用户进行交互的接口。
3、消息:消息是Windows应用程序一个非常重要的概念,Windows应用程序和操作之间的通信全是消息。操作系统会把用户操作等消息封闭成一个消息放入消息队列中,应用程序从消息队列中取出消息进行响应。这就是操作系统给应用程序发送消息,即操作系统调用应用程序中一个专门处理消息的函数,称为窗口过程。
4、消息队列:操作系统发送的消息可以不进消息队列,也可以进消息队列,进消息的队列的消息等待应用程序取出进行响应。不进消息队列的消息由操作系统直接调用程序的窗口过程进行处理。无论进不进消息队列,消息的处理最终都是调用窗口过程。
一、主函数WinMain
函数原型为下
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nCmdShow);
这几个参数由操作系统在应用程序启动时赋予,用不我们手动指定。
hInstance是当前应用程序句柄。
hPreInstance是此类应用程序的上一个运行句柄,win32程序中该参数为空。
lpCmdLine是应用程序启动时带的命令参数,如用记事本打开一个文件时,文件名就是记事本带的参数。
nCmdShow指定窗口启动时的显示方式,如最大化,最小化,隐藏等。
二、窗口过程函数(消息处理的地方)
窗口过程函数用于处理发送给窗口的消息,是一个回调函数。应用程序接收到消息后使用DispathcMessage(&msg)将消息回传给系统,系统则调用窗口过程函数对消息进行处理。函数原型为下
LRESULT CALLBACK WindowP