05 Windows编程——Windows程序框架
源码
#include<Windows.h> LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
{
WNDCLASS WndClass;
TCHAR* ClassName = TEXT("MyClass");
HWND hwnd;
MSG msg; WndClass.cbClsExtra = ;
WndClass.cbWndExtra = ;
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + );
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInst;
WndClass.lpfnWndProc = WindProc;
WndClass.lpszClassName = ClassName;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_VREDRAW | CS_HREDRAW; if (!RegisterClass(&WndClass))
{
MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK);
return ;
} hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, , , NULL, NULL, hInst, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK);
return ;
}
ShowWindow(hwnd, nShow);
UpdateWindow(hwnd); while (GetMessage(&msg,NULL,,))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return ;
} LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage();//发送WM_QUIT消息
return ;
default:
break;
} return DefWindowProc(hwnd, message, wParam, lParam);
}


LoadIcon
载入图示供程式使用。
LoadCursor
载入鼠标供程序使用。
GetStockObiect
取得一个图形对象(在这个例子中,是取得绘制视窗背景的画刷物件)。
RegisterClass
为程序视窗注册窗口类。
Create Window
根据窗口类建立一个视窗。
ShowWindow
在萤幕上显示窗口。
UpdateWindow
更新窗口。
GetMessage
从程序消息队列获取消息。
TranslateMessage
将虚拟密钥消息转换为字符消息。字符消息被发布到调用线程的消息队列,以便在线程下次调用GetMessage或PeekMessage函数时读取。
DispatchMessage
将消息发送到窗口过程。它通常用于分派由GetMessage函数检索的消息。
PostQuitMessage
向系统指示线程已发出终止请求(退出)。它通常用于响应WM_DESTROY消息。
LoadCursor
从与应用程序实例关联的可执行文件(.EXE)加载指定的游标资源。
注意此函数已被LoadImage函数取代。
LoadIcon
从与应用程序实例关联的可执行文件(.EXE)加载指定的游标资源。
注意此函数已被LoadImage函数取代。
CreateWindow
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTR lpClassName,
_In_opt_ LPCTSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int x,
_In_ int y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HMENU hMenu,
_In_opt_ HINSTANCE hInstance,
_In_opt_ LPVOID lpParam
);
DispatchMessage这里调用的是我们自定义的消息处理函数WindProc
PostQuitMessage(0)发送WM_QUIT消息,使GetMessage函数返回值为零,从而退出while循环。

WIndows窗体程序的一生 ,大部分时间都在消息循环中度过。
下面代码创建一个空白窗口程序,没有关闭按钮,只能Alt+F4关闭
GetSystemMetrics是一个计算机函数,该函数只有一个参数,称之为「索引」,这个索引有75个标识符,通过设置不同的标识符就可以获取系统分辨率、窗体显示区域的宽度和高度、滚动条的宽度和高度。
#include<Windows.h> LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
{
WNDCLASS WndClass;
TCHAR* ClassName = TEXT("MyClass");
HWND hwnd;
MSG msg; WndClass.cbClsExtra = ;
WndClass.cbWndExtra = ;
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + );
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInst;
WndClass.lpfnWndProc = WindProc;
WndClass.lpszClassName = ClassName;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_VREDRAW | CS_HREDRAW; if (!RegisterClass(&WndClass))
{
MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK);
return ;
} hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_POPUP, , , GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInst, NULL);
if (hwnd == NULL)
{
MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK);
return ;
}
ShowWindow(hwnd, nShow);
UpdateWindow(hwnd); while (GetMessage(&msg,NULL,,))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return ;
} LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage();//发送WM_QUIT消息
return ;
default:
break;
} return DefWindowProc(hwnd, message, wParam, lParam);
}
窗口过程
LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
hwnd:窗口过程可以为基于同一窗口类创建的多个窗口处理消息。通过hwnd 参数,窗口过程就可获知到底是哪一个窗口正在接收消息。
message:具体某一Windows消息,例如VM_SIZE
wParam、lParam提供消息相关的附加参数。以message为VM_SIZE为例,
wParam 参数取值可为SIZE RESTORED、SIZE_MINIMIZED、SIZE MAXIMIZED、SIZE_MAXSHOW 或 SIZE MAXHIDE
IParam参数中包含该窗口的新尺寸,窗口的新宽度(一个16位的值)和新高度(也是一个16位的值)被组合在32位的IParam参数中。头文件WINDEFH中定义了一些宏便于从IParam中提取这两个值。
消息从何而来:
消息来自于用户的输入;消息来自于系统;
消息被存放在那里:
消息被存放在每个线程的消息队列中。
消息如何被线程取出:
GetMessage函数,PeekMessage.
GetMessage在取消息的时候,如果消息队列是空的。GetMessage函数将阻塞线程,知道消息队列有一个消息,GetMessage才返回
PeekMessage如果消息队列里面有消息,其行为和GetMessage一样。如果消息队列为空,PeekMessage立即返回
消息队列是否先进先出,Fl-FO
对大多数消息而言,是FIFO
但是消息队列会对特殊满息进行处理,例如WM_PAINT,WM_TIMER,WM_QUIT。
消息是否必须经过消息队列:
否,有些消息被直接发送给窗口,不经过消息队列,例如,激活窗口的消息。


命名约定

lpfn 指向函数的长指针
cb 字节数
lpsz 指向以零结束的字符串的长指针
05 Windows编程——Windows程序框架的更多相关文章
- Windows 编程,程序编译使用的命令行工具。
Windows 编程,程序编译使用的命令行工具. 1.cl.exe文件是Visual C\C++的编译器,它将程序源代码文件编译为obj文件. 2.rc.exe文件是资源编译器.工程项目中的.rc文件 ...
- Windows编程入门程序详解
引用:http://blog.csdn.net/jarvischu/article/details/8115390 1. 程序 /******************************* ...
- Windows编程 Windows程序的生与死(中)
<pre style=""><pre class="cpp" name="code">1 #include < ...
- Windows编程 Windows程序的生与死(上)
引子 “Windows 程序分为‘程序代码’和‘UI(User Interface)资源’两大部份,两部份最后以RC编译器(资源编译器)整合为一个完整的EXE 文件.所谓UI 资源是指功能菜单.对话框 ...
- Windows编程 Windows程序的生与死(下)
再谈程序之“死” 记得在第二回中我对程序的“死”只是一句话带过,因为我还没有铺垫好,好了现在我们可以详细的分析一下这个过程了. 这还要从while消息循环说起,还记得GetMessage函数吗?它是一 ...
- 【Windows编程】系列第十一篇:多文档界面框架
前面我们所举的例子中都是单文档界面框架,也就是说这个窗口里面的客户区就是一个文档界面,可以编写程序在里面输入或者绘制文本和图形输出,但是不能有出现多个文档的情况.比如下面的UltraEdit就是一个典 ...
- windows应用程序框架及实例
应用程序框架:同一类型应用程序的结构大致相同,并有很多相同的源代码,因此可以通过一个应用程序框架AFX(Application FrameWorks)编写同一类型应用程序的通用源代码. 主要向导: D ...
- 【翻译习作】 Windows Workflow Foundation程序开发-第一章05
1.3 开发我们的第一个工作流 也许你曾经在这样的产品经理手下搞过开发:他总是在你身边转悠,并不时的问一句“你还没做完吗?”.在这一部分,我们将用一个简单的Windows Workflow程 ...
- Directx11 教程(2) 基本的windows应用程序框架(2)
原文:Directx11 教程(2) 基本的windows应用程序框架(2) 在本教程中,我们把前面一个教程的代码,进行封装.把初始化函数,Run函数,窗口回调函数,ShutdownWind ...
随机推荐
- Java基础教程:IDEA单元测试
Java基础教程:IDEA单元测试 环境配置 使用idea IDE 进行单元测试,首先需要安装JUnit 插件. 安装JUnit插件步骤 File-->settings-->Plguins ...
- 波特词干(Porter Streamming)提取算法无代码单纯理解
最近写东西提到这个算法,要看一下,结果网上都是直接根据代码解释,对于我这种菜鸟在刚开始看一个算法的时候真心不想直接看代码学.奈何都是各种语言的代码,么得办法.先走了一遍,有了大致的了解,翻译成自己的话 ...
- 使用Apache服务部署网站(基于IP,域名,端口)
本篇主要学习Apache网站服务程序的基本部署,基于IP地址.主机名(域名).端口号的虚拟主机功能. 1.基于IP地址 首先我们需要在虚拟机中线安装Apache服务程序,Apache服务程序的软件包名 ...
- [转帖]1A2C多口充 紫米USB充电器65W桌面快充版评测
1A2C多口充 紫米USB充电器65W桌面快充版评测 2019年10月04日 07:48 1786 次阅读 稿源:充电头网 1 条评论 https://www.cnbeta.com/articles/ ...
- Oracle之配置节点间相互信任机制测试
更改一下,之前的都不对,现在来一版简单有效的ssh互信配置 例如我的是在配置rac,在grid用户下配置互信:建立好相应的文件 mkdir .ssh chmod -R 700 .ssh/ 使用ssh- ...
- sql中能使用charindex 不要用 in 。charindex比in快很多
写SQL语句我们经常需要判断一个字符串中是否包含另一个字符串,但是SQL SERVER中并没有像C#提供了Contains函数,不过SQL SERVER中提供了一个叫CHAEINDX的函数,顾名思义就 ...
- php类常量
类常量类常量可以使用define定义,也可用const定义,但是在类的内部,只允许用const定义,类常量不能更新,也不能删除类常量通常是大写的,两个单词之间用下滑线连接,如MY_NATION类常量在 ...
- Spring Cloud 中注册中心Eureka客户端配置
注册中心配置客户端(注册一个虚拟的商品服务) 一.新建项目: 1.创建一个SpirngBoot应用,增加服务注册和发现依赖 2.模拟商品信息,存储在内存中 3.开发商品列表接口 ...
- python爬虫框架scrapy 豆瓣实战
Scrapy 官方介绍是 An open source and collaborative framework for extracting the data you need from websit ...
- python笔记005-字符串-列表-元组
目录 1 上次作业补充拓展... 1 1.1 进制转换... 1 1.2 类型判断... 1 2 今日学习内容... 2 2.1 格式化输出... 2 2.2 基本运算符... 2 2.2.1 算术运 ...