IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 初识Windows编程 -> 正文阅读

[C++知识库]初识Windows编程

本人为初学者,水平有限,写blog主要为了记录自己学习的轨迹,代码介绍参考msdn,如有错误或者疏漏敬请各位批评指正,感谢您的阅读!

1.对Windows编程的基本认识

最简单的Windows编程时调用一些windows中的用户态的API,大多是User32.dll GDI32.dll这两个库文件中的函数。

MFC是一个类库(class libraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件组件的封装类。MFC是WINAPI与C++的结合,它不仅仅是一个页面开发系统,内含很多类的作用并不是一个界面类,不实现对一个窗口对象的控制,有一些是在windows内部处理的类。

2.对基本框架的理解过程

笔者在了解了基本的c语言知识之后,尝试阅读基本的框架代码。

每一个c语言的程序都有着自己的main函数,而based win32 的程序,有着WinMain function,作为程序的入口点,基本代码如下?

int CALLBACK WinMain(  
  _In_ HINSTANCE hInstance,  //handle to the current instance
  _In_ HINSTANCE hPrevInstance,  //handle to the previous instance
  _In_ LPSTR     lpCmdLine,  // command line of the application
  _In_ int       nCmdShow  // control how the window to be shown
);

在winmain里,创建WNDCLASSEX的struct,其包含了一个窗口的基本信息,基本代码如下

WNDCLASSEX wcex;  

wcex.cbSize = sizeof(WNDCLASSEX);  
wcex.style          = CS_HREDRAW | CS_VREDRAW;  
wcex.lpfnWndProc    = WndProc;  
wcex.cbClsExtra     = 0;  
wcex.cbWndExtra     = 0;  
wcex.hInstance      = hInstance;  
wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));  
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);  
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);  
wcex.lpszMenuName   = NULL;  
wcex.lpszClassName  = szWindowClass;  
wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

之后需要注册窗口(其意义有点类似于在主程序之前写函数定义),基本代码如下

if (!RegisterClassEx(&wcex))  
{  
    MessageBox(NULL,  
        _T("Call to RegisterClassEx failed!"),  
        _T("Win32 Guided Tour"),  
        NULL);  

    return 1;  
}

我们在注册窗口之后就可以创建窗口了,CREATEWINDOW返回值是一个HWND,handle to the window,用来跟踪窗口。

static TCHAR szWindowClass[] = _T("win32app");  
static TCHAR szTitle[] = _T("Win32 Guided Tour Application");  

// The parameters to CreateWindow explained:  
// szWindowClass: the name of the application  
// szTitle: the text that appears in the title bar  
// WS_OVERLAPPEDWINDOW: the type of window to create  
// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)  
// 500, 100: initial size (width, length)  
// NULL: the parent of this window  
// NULL: this application does not have a menu bar  
// hInstance: the first parameter from WinMain  
// NULL: not used in this application  
HWND hWnd = CreateWindow(  
    szWindowClass,  
    szTitle,  
    WS_OVERLAPPEDWINDOW,  
    CW_USEDEFAULT, CW_USEDEFAULT,  
    500, 100,  
    NULL,  
    NULL,  
    hInstance,  
    NULL  
);  
if (!hWnd)  
{  
    MessageBox(NULL,  
        _T("Call to CreateWindow failed!"),  
        _T("Win32 Guided Tour"),  
        NULL);  

    return 1;  
}

之后我们显示这个窗口,并让其可以update

// The parameters to ShowWindow explained:  
// hWnd: the value returned from CreateWindow  
// nCmdShow: the fourth parameter from WinMain  
ShowWindow(hWnd,  
    nCmdShow);  
UpdateWindow(hWnd);

接下来添加消息循环从消息队列里检索窗口相关的消息,接收到的消息送给WndProc处理

window application是基于消息的程序设计模式,用事件去驱动编程模式。所谓消息循环实际上就是从消息队列里接收消息,检索消息,发送给WndProc的程序循环。

MSG msg;  
while (GetMessage(&msg, NULL, 0, 0))  
{  
    TranslateMessage(&msg);  
    DispatchMessage(&msg);  
}  

return (int) msg.wParam;

除此之外,还需要一个windows procedure function ,我们习惯叫它WndProc,基本代码如下

LRESULT CALLBACK WndProc(  
  _In_ HWND   hwnd,  
  _In_ UINT   uMsg,  
  _In_ WPARAM wParam,  
  _In_ LPARAM lParam  
);

在windows程序内,事件发生,WinProc用来对事件作出处理响应(handle an event)。里面的pattern近似于一个switch 里面有多个case,根据收到的消息做出不同的响应。

示例如下:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_CREATE:
		// 初始化窗体
		InitGame(hWnd, wParam, lParam);
		break;
	case WM_KEYDOWN:
		// 键盘按下事件
		KeyDown(hWnd, wParam, lParam);
		break;
	case WM_KEYUP:
		// 键盘松开事件
		KeyUp(hWnd, wParam, lParam);
		break;
	case WM_MOUSEMOVE:
		// 鼠标移动事件
		MouseMove(hWnd, wParam, lParam);
		break;
	case WM_LBUTTONDOWN:
		// 鼠标左键按下事件
		LButtonDown(hWnd, wParam, lParam);
		break;
	case WM_LBUTTONUP:
		// 鼠标左键松开事件
		LButtonUp(hWnd, wParam, lParam);
		break;
	case WM_TIMER:
		// 定时器事件
		if (currentStage != NULL && currentStage->timerOn) TimerUpdate(hWnd, wParam, lParam);
		break;
	case WM_PAINT:
		// 绘图
		Paint(hWnd);
		break;
	case WM_DESTROY:
        //退出
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

3.little? pieces

(1)双缓冲绘图

笔者在学习中碰到的WndProc中WM_PAINT 函数,里面涉及到双缓冲绘图。

因为在WM_PAINT 中,进行图形的绘制时,程序的响应相当频繁,每一次执行OnEraseBKgnd的过程都要擦除原先屏幕上的图像,接着用背景色进行填充,最后再重新绘制。这不仅会引起绘制耗时太长的问题,也会导致绘图过程中屏幕上出现闪烁的现象。因此,我们想到,先将图片绘制到内存缓冲区当中,之后利用BitBlt,将其copy到屏幕上。BitBlt的执行速度很快,所以这很好的实现了将图片整体显示在屏幕上的效果。示例代码如下

void Paint(HWND hWnd)
{

	PAINTSTRUCT ps;
	HDC hdc_window = BeginPaint(hWnd, &ps);

	HDC hdc_memBuffer = CreateCompatibleDC(hdc_window);
	HDC hdc_loadBmp = CreateCompatibleDC(hdc_window);

	//初始化缓存
	HBITMAP	blankBmp = CreateCompatibleBitmap(hdc_window, WINDOW_WIDTH, WINDOW_HEIGHT);
	SelectObject(hdc_memBuffer, blankBmp);

	// 绘制背景到缓存
	SelectObject(hdc_loadBmp, bmp_Background);

	BitBlt(hdc_memBuffer, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, hdc_loadBmp, 0, 0, SRCCOPY);
    
    //need to do


    // 最后将所有的信息绘制到屏幕上
	BitBlt(hdc_window, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, hdc_memBuffer, 0, 0, SRCCOPY);

	// 回收资源所占的内存(非常重要)
	DeleteObject(blankBmp);
	DeleteDC(hdc_memBuffer);
	DeleteDC(hdc_loadBmp);

	// 结束绘制
	EndPaint(hWnd, &ps);
}

待更新......

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 15:53:52  更:2022-01-03 15:54:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:01:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码