Windows SDK编程基本框架

在Windows平台下,最常见最流行的编程就是MFC编程了,在网上可以搜索出大把的MFC编程相关的文章,今天我们来讨论另外一种windows下的编程模式,即Windows SDK编程。这种编程具有更加灵活和强大的控制,能实现一些MFC不易实现甚至难以实现的功能。

所有的WindowsSDK编程都有一个类似的框架,本文就说说这个框架,Windows程序设计的框架分为“三部曲”:

  1. 注册窗口类 注册窗口类的API函数是RegisterClass或者RegisterClassEx,这两个函数参数区别不大,具体看MSDN,这里以RegisterClass为例。函数原型如下: ATOM RegisterClass(CONST WNDCLASS *lpWndClass);

参数WNDCLASS定义如下:

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. 创建主窗口并显示

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. 进入消息循环 这个过程基本是一个固定的格式:

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

该过程从系统消息队列里面获取一个消息,然后翻译虚拟按键成字符消息,并派送到窗口消息队列中,等待消息处理函数处理。如果获取到的消息为WM_QUIT,则返回0,于是就退出循环。

通过上面的三部曲,我们就创建了windows程序设计的框架,几乎任何的windows程序都可以在这个框架基础上衍生出来。下面我们给出完整的框架代码:

#include<windows.h>

static TCHARszAppName[] = TEXT("Windows programming framework");

static LRESULTCALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPIWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, intiCmdShow)

{

HWND hWnd;

MSG msg;

WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = WndProc;

wndclass.cbClsExtra = 0;

wndclass.cbWndExtra = 0;

wndclass.hInstance = hInstance;

wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

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 programrequires Windows NT!"), szAppName, MB_ICONERROR);

return 0;

}

hWnd = CreateWindow(szAppName, // window class name

TEXT("Win32Framework 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 LRESULTCALLBACK 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 ;

}

return DefWindowProc (hWnd, message,wParam, lParam);

}

在消息处理函数中,根据消息类型执行不同的处理,比如WM_CREATE可以处理一些创建的工作;WM_PAINT可以处理画图,显示文本;WM_DESTROY处理在窗口被销毁时的事件;当然还有很多其他的消息事件,根据情况我们做出相应的处理。

该框架程序运行起来就是一个空空的窗口,没有任何其他内容。虽然整个框架简单,但是对于windows程序设计来说非常重要。如果你想学习windows编程,就需要把每一个部分都真正理解,这样就算基本入门windows编程了,剩下的就是如何根据需求丰富这个框架使之成为一个“有用”的程序。

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-04-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏進无尽的文章

编码篇-使用GDataXMLNode解析XML数据

在实际的开发中数据解析是很普遍的事,一般网络请求返回的数据有两种格式:XML和JSON。关于JSON的解析已是主流,满大街的解析方式。而XML的数据格式确实是很...

631
来自专栏移动端开发

iOS 转场动画探究(一)

什么是转场动画:        转场动画说的直接点就是你常见的界面跳转的时候看到的动画效果,我们比较常见的就是控制器之间的Push和Pop,还有Present和...

4065
来自专栏大学生计算机视觉学习DeepLearning

2018最新mfc作为上位机接收硬件端USB或串口数据显示成图片 解决串口接收数据丢字节丢包问题

第一步:首先建立一个MFC工程,成功后会跳出一个对话框,直接在对话框上点击右键-》点击插入ACTIVAE控件-》选择MicrosoftCommunication...

682
来自专栏京东技术

Vue拖拽组件开发实例

vue是一套用于构建用户界面的渐进式框架。可以用他来封装单文件组件来开发更为复杂的单页应用。 本文主要是通过封装一个拖拽组件的例子,来分析Vue组件化相关知识。

58513
来自专栏飞雪无情的博客

Android中为图标加上数字--用于未读短信数提醒,待更新应用数提醒等

在我们开发一些如短消息、应用商店等应用时,会考虑在短消息的图标上加上未读短信的数量,在应用商店上加上可以升级的应用数量,这样不占太大空间还能达到提示的目的。

694
来自专栏闻道于事

Layui常用方法

layui中的input radio单选框监听选择触发事件: 根据给input绑定的 lay-filter 进行查找input,然后进入函数判断 ...

5869
来自专栏yukong的小专栏

【ssm个人博客项目实战08】博客的分页显示以及模糊查询,删除。前言1、上篇回顾2、具体编码3、测试与小结

在上一节中我们是完成了博客的回台部分,现在我需要在前台拿到回台传来的数据并且给以显示出来。 不知道大家还记得我们在博客类别管理里面,easyui的datagr...

524
来自专栏salesforce零基础学习

salesforce 零基础开发入门学习(八)数据分页简单制作

本篇介绍通过使用VF自带标签和Apex实现简单的数据翻页功能。 代码上来之前首先简单介绍一下本篇用到的主要知识: 1.ApexPages命名空间 此命名空间下的...

1978
来自专栏游戏开发那些事

【Unity编辑器】UnityEditor多重弹出窗体与编辑器窗口层级管理

  最近马三为公司开发了一款触发器编辑器,对于这个编辑器策划所要求的质量很高,是模仿暴雪的那个触发器编辑器来做的,而且之后这款编辑器要作为公司内部的一个通用工具...

763
来自专栏nice_每一天

一天带你入门到放弃vue.js(二)

至此在vue中提供了计算属性,computed,在main.js指定computed对象中指定计算

541

扫描关注云+社区