在复习完C/C++的基础之后,今天开始学习MFC,自己使用的资料是孙鑫老师的《VC++深入精解》作为主要的学习脉络,而侯老师的《深入浅出MFC》则作为补充。今天是第一章基础,简要介绍windows编程的特点。
一、几个基本的认识
1. API与SDK
同我们经常使用的cstdlib一样,微软为进行windows程序开发的提供了强大的函数库,我们称之为API,这些API作为应用程序的接口可以被开发人员直接调用实现操作。SDK是software development Kit的简称,是一个帮助程序猿开发软件的综合平台,包含着系统提供的API、帮助文档以及其他辅助开发工具等。因此SDK通常是包含着API作为系统开发的综合平台。
微软为我们提供了强大的API库支持,显而易见数量与功能成正比,面对1000多种API当然不可能像背字典那样的全部背过,有效的方法是借助MSDN作为工具,在实际的使用中随着使用不断学习需要的API的使用。另一方面微软提供的API命名存在着明显的规律,一般是有意义的英文单词首字母大写后的组合,如CreateFile,CreateProcess等。勤动手查阅MSDN是学习Windows编程的好方法。
2. 窗口与消息队列
Windows系统作为经典的一款桌面系统,大部分的应用程序都提供了窗口模式。窗口作为一种资源在内存中分配有相应的空间,而这些空间的管理则依赖于句柄实现。之前讨论过C/C++中设计的句柄类,其实是一个封装了对象指针的功能类,这里也可以类似的理解,我们通过句柄可以联系到其绑定的对象,可以对对象进行相应的操作。
与DOS系统最大的不同在于,Windows系统采用了事件驱动机制。简单来说,就是
<2.1>系统通过窗口将应用程序呈现给用户,用户在窗口上进行操作;
<2.2>系统捕捉到操作,产生消息放入应用程序的消息队列;
<2.3>应用程序从消息队列中读取消息,然后将消息发回给系统;
<2.4>系统收到消息后调用注册时指定的回调函数(APP将msg发回给系统)处理消息,做出应对
所有的这一切都是在WinMain函数中运行的,在编写windows程序前要增加头文件
二、一个简单的window窗口程序
创建一个带有窗口的window程序的步骤主要有四个,孙老师形象地比喻为“造汽车”:
1. 设计图纸——定义窗口类;
2. 申请报批——注册窗口类;
3. 建造汽车——创建窗口类对象;
4. 使用汽车——显示与更新窗口;
在完成窗口的创建之后,就是编写消息循环部分,使得我们的窗口可以随时捕捉窗口上的操作,定义相应的回调函数供系统在接收到APP返回的消息时进行处理,具体的函数说明网上很多,有兴趣的童鞋可以去查看MSDN,下面给出一个简单窗口程序的代码:
-
//A Simple Window
-
#include <windows.h>
-
#include <iostream>
-
#include <cstdlib>
-
#include <stdio.h>
-
-
//decline call-back function
-
LRESULT CALLBACK WinProc (
-
HWND hwnd, //handle to window
-
UINT uMsg, //message id
-
WPARAM wParam, //1st msg parameter
-
LPARAM lParam //2nd msg parameter
-
);
-
//WinMain
-
int WINAPI WinMain(
-
HINSTANCE hInstance, //handle to current instance
-
HINSTANCE hPrevInstance, //handle to previous instance
-
LPSTR lpCmdLine, //command line
-
int nCmdShow //show state
-
)
-
{
-
//design a window class
-
WNDCLASS wndcls; //define a struct - window class
-
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 = L"test";
-
wndcls.lpszMenuName = NULL;
-
wndcls.style = CS_HREDRAW | CS_VREDRAW;
-
-
// 注册窗口类
-
RegisterClass(&wndcls);
-
-
//创建窗口
-
HWND hwnd;
-
hwnd = CreateWindowA("test", "This is a Test for Windows", WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL);
-
-
//显示及刷新窗口
-
ShowWindow(hwnd, SW_SHOWNORMAL);
-
UpdateWindow(hwnd);
-
-
//定义消息结构体,开始消息循环
-
MSG msg;
-
while (GetMessage(&msg, NULL, 0, 0) )
-
{
-
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];
-
sprintf(szChar, "char code is %d", wParam);
-
MessageBoxA(hwnd, szChar, "char", 0);
-
break;
-
case WM_LBUTTONDOWN:
-
MessageBoxA(hwnd, "mouse clicked", "message", 0);
-
HDC hdc;
-
hdc = GetDC(hwnd);
-
TextOutA(hdc, 0, 50, "菜鸟之路", strlen("菜鸟之路"));
-
break;
-
case WM_PAINT:
-
HDC hDC;
-
PAINTSTRUCT ps;
-
hDC = BeginPaint(hwnd, &ps);
-
TextOutA(hDC, 0, 0, "测试之路", strlen("测试之路"));
-
EndPaint(hwnd, &ps);
-
break;
-
case WM_CLOSE:
-
if (IDYES==MessageBoxA(hwnd, "Really end?", "message", MB_YESNO))
-
{
-
DestroyWindow(hwnd);
-
}
-
break;
-
case WM_DESTROY:
-
PostQuitMessage(0);
-
break;
-
default:
-
return DefWindowProc(hwnd, uMsg, wParam, lParam);
-
}
-
return 0;
-
}
运行测试显示如下,输入一个字符时显示其ASC2码值:
退出时点击右侧的X即可:
阅读(318) | 评论(0) | 转发(0) |