api(一) 创建窗口 (转)
所有的Windows SDK编程都有一个类似的框架,本文就说说这个框架,Windows程序设计的框架分为“三部曲”:
一、注册窗口类
注册窗口类的API函数是RegisterClass或者RegisterClassEx,这两个函数参数区别不大,具体看MSDN,这里以RegisterClass为例。函数原型如下:
参数WNDCLASS定义如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
typedef struct {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS, *PWNDCLASS;
|
结构成员说明如下:
style:指示类窗口类的风格,比如指定水平、垂直重画;是否显示关闭窗口等。
lpfnWndProc:窗口过程函数指针,这个是最重要的参数,该参数指定消息执行的处理函数入口。
cbClsExtra:类扩展数据大小,一般不用。
cbWndExtra:窗口扩展数据大小,一般不用。
hInstance:应用程序实例,这个参数会从WinMain函数传过来。
hIcon:应用程序的图标句柄。
hCursor:应用程序的光标句柄。
hbrBackground:窗口的背景画刷。Windows预定义了一些纯色画刷,如COLOR_GRAYTEXT、COLOR_BACKGROUND、COLOR_ACTIVECAPTION等等。
lpszMenuName:菜单名,该名以资源的方式存在。
lpszClassName:窗口类的名字,这个必须指定且不能重复,否则会失败,除非你需要重复的,否则尽量避免。
二、创建主窗口并显示
|
1
2
3
4
5
6
7
8
9
10
11
12
|
HWND CreateWindow(LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
|
参数如下:
lpClassName:类名,就是WNDCLASS结构中的 lpszClassName。
lpWindowName:本窗口的名字,一个字符串。
dwStyle:窗口风格,比如是否有边框、标题框、子窗口、水平垂直滚动条、弹出、重叠性等,具体看MSDN,很多特殊效果都是用这个风格指定的,比如类似迅雷的悬浮窗等。
x,y, nWidth, nHeight:指定窗口相对于父窗口的位置和宽高。
hWndParent:指定父窗口句柄,如果该窗口没有父窗口,则为NULL,比如应用程序主窗口。
hMenu:菜单句柄。
hInstance:应用程序实例句柄,跟WNDCLASS中的hInstance一样。
lpParam:指向一个CREATESTRUCT结构的参数。
显示并刷新窗口的API函数如下,参数都有对应的窗口句柄:
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
三、进入消息循环
这个过程基本是一个固定的格式:
|
1
2
3
4
5
|
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
|
该过程从系统消息队列里面获取一个消息,然后翻译虚拟按键成字符消息,并派送到窗口消息队列中,等待消息处理函数处理。如果获取到的消息为WM_QUIT,则返回0,于是就退出循环。
通过上面的三部曲,我们就创建了windows程序设计的框架,几乎任何的windows程序都可以在这个框架基础上衍生出来。下面我们给出完整的框架代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#include <windows.h>
static TCHAR szAppName[] = TEXT("Windows programming framework");
static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
#ifdef MY_ICON_USED
wndclass.hIcon = (HICON)LoadImage(NULL, TEXT("home.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
#else
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
#endif
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hWnd = CreateWindow(szAppName, // window class name
TEXT("Win32 Framework Demo"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
400, // initial x size
300, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
// create sub window
return 0;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
// paint image
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0 ;
default:
break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
|
在消息处理函数中,根据消息类型执行不同的处理,比如WM_CREATE可以处理一些创建的工作;WM_PAINT可以处理画图,显示文本;WM_DESTROY处理在窗口被销毁时的事件;当然还有很多其他的消息事件,根据情况我们做出相应的处理。

该框架程序运行起来就是一个空空的窗口,没有任何其他内容。虽然整个框架简单,但是对于windows程序设计来说非常重要。如果你想学习windows编程,就需要把每一个部分都真正理解,这样就算基本入门windows编程了,剩下的就是如何根据需求丰富这个框架使之成为一个“有用”的程序。
下一篇我们将讲解如何在windows SDK创建各种常用的控件,请继续关注。
转载请注明原文出处:http://www.coderonline.net/?p=565
api(一) 创建窗口 (转)的更多相关文章
- QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
QT源码解析(一) QT创建窗口程序.消息循环和WinMain函数 分类: QT2009-10-28 13:33 17695人阅读 评论(13) 收藏 举报 qtapplicationwindowse ...
- 【C语言探索之旅】 第三部分第二课:SDL开发游戏之创建窗口和画布
内容简介 1.第三部分第二课: SDL开发游戏之创建窗口和画布 2.第三部分第三课预告: SDL开发游戏之显示图像 第三部分第二课:SDL开发游戏之创建窗口和画布 在上一课中,我们对SDL这个开源库做 ...
- Win32 SDK 编程开始, 创建窗口, 消息的处理, 消息循环
Windows SDK 编程的一般步骤为: 1. 注册窗口类, 使用到的结构 WNDCLASSEX, 函数 RegisterClassEx. 2. 创建窗口, 函数 CreateWindowEx. 3 ...
- Windows运行机理——创建窗口
Windows运行机理这系列文章都是来至于<零基础学Qt4编程>——吴迪,个人觉得写得很好,所以进行了搬运和个人加工 Windows 窗口在创建之前,其属性必须设定好,所谓属性包括类的名字 ...
- vc++如何创建窗口
创建一个mfc工程,AppWizard可以用来增加和选择一些特性 可以发现一共有五个类,每一个类都有一个基类,都是mfc基础类库中的类 例如将一个类拷贝一下,将CFrameWnd到msdn中查找一下, ...
- QT创建窗口程序、消息循环和WinMain函数(为主线程建立了一个QEventLoop,并执行exec函数)
使用QT也有一段时间了,有的时候需要跟踪代码到QT的源码中去查找问题.在这里我将记录一下我跟踪QT源码学习到的一些知识. 我的开发环境是VC6.0+QT4.3.3.QT已经不为VC6.0提供addin ...
- ASP.NET Web API 过滤器创建、执行过程(二)
ASP.NET Web API 过滤器创建.执行过程(二) 前言 前面一篇中讲解了过滤器执行之前的创建,通过实现IFilterProvider注册到当前的HttpConfiguration里的服务容器 ...
- ASP.NET Web API 过滤器创建、执行过程(一)
ASP.NET Web API 过滤器创建.执行过程(一) 前言 在上一篇中我们讲到控制器的执行过程系列,这个系列要搁置一段时间了,因为在控制器执行的过程中包含的信息都是要单独的用一个系列来描述的,就 ...
- ASP.NET Web API 控制器创建过程(二)
ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...
随机推荐
- 使用 fastlane 实现 iOS 持续集成(转)
http://www.cocoachina.com/ios/20150916/13433.html 简介 持续集成是个“一次配置长期受益”的工作.但很多小公司都没有.以前在做Windows开发配置感觉 ...
- Chrome for Android在Chromium代码库中的提交patch
訪问这个地址: https://codereview.chromium.org/1141283003 主要分为3类:png资源文件.java代码.C++代码,曾经以为这部分不开源的代码主要是C++,事 ...
- Codeforces #245(div2)
A:A. Points and Segments (easy) 题目看了n久,開始认为尼玛这是div2的题目么,题目还标明了easy.. 意思是给你一n个点,m个区间,在n个点上放蓝球或者红球,然后让 ...
- VMware虚拟机与主机联通及配置上网
vmware版本:10.0.0 build-1295980,安装redhat enterprise linux 5.8 一.物理机与虚拟机联通,但不联网 1.虚拟网络VMnet1设置: 此时,物理主机 ...
- 关于Console的Main(String[] args)参数输入
之前接触一个往Console里输入参数的项目,资深QA教我怎么run,灰常脸红. 今日无事,baidu之. Step1 写简单Console Code. class Program { static ...
- 《编写可维护的JavaScript》之编程实践
最近读完<编写可维护的JavaScript>,让我受益匪浅,它指明了编码过程中,需要注意的方方面面,在团队协作中特别有用,可维护性是一个非常大的话题,这本书是一个不错的起点. 本书虽短,却 ...
- iOS设计模式解析(二)抽象工厂方法
抽象工厂方法:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 与工厂方法区别: 抽象工厂通过对象组合创建抽象产品.工厂通过类集成创建抽象产品 抽象工厂创建多系列产品.工厂创建一种产 ...
- 【.Net】从.NET平台调用Win32 API
小序 Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制 ...
- Python基础:绑定和方法调用
首先,方法仅仅是类内部定义的函数,也就是说,方法是类属性而不是实例属性. 其次方法有两种被调用的方式:调用绑定的方法和调用未绑定的方法. 当存在一个实例时,方法才被认为绑定到了那个实例上,没有实例时方 ...
- perl install module && normal module
Windows: perl -MCPAN -e shell install XML::GDOME Archive::Zip 后面继续更新... Archive usage: $obj = Arc ...