在来啰嗦之前,希望大家能够做好准备,这一节知识有点多,内容有点长。但愿大家能够一口气读完,如果一口气读不完,那就换口气接着读。

上节中我们用MessageBox()就实现了一个真正的窗口。MessageBox()中的原型如下:

Int MessageBox(HWND hWnd,
                    LPCTSTR lpText,
                    LPCTSTR lpCaption,
                    UINT        uType);

参数解释

hWnd 所属对话框所属窗口的句柄,如果是NULL,则此对话框不属于任何一个窗口。

lpText 对话框窗口的显示内容。

lpCaption 对话框窗口的标题。

uType 对话框的样式和动作(像是确定按钮,还是取消按钮就是设置这里的)

关于这个函数的细节可以看这里

http://msdn.microsoft.com/en-us/library/ms645505(VS.85).aspx

到此为止,你也算是会了窗口程序的编写,但只是一个开始,不过这已经很好,可能会让你感觉到了C的魅力,也可能会稍微解点C语言能干什么的疑惑。在开始写代码之前,我有必要把细节和原理先说明下。

Windows下一个窗口创建的过程有以下几个步骤:

1.        程序创建一个窗口,首先要向Windows系统注册一个窗口类wndclassex,其实就是定义一个变量,变量的类型是WNDCLASSEX(结构体)。该结构体的定义与介绍看这里(http://msdn.microsoft.com/en-us/library/ms633577(VS.85).aspx),

Code
typedef struct {
    UINT cbSize;
    UINT style;
    WNDPROC lpfnWndProc;
    int cbClsExtra;
    int cbWndExtra;
    HINSTANCE hInstance;
    HICON hIcon;
    HCURSOR hCursor;
    HBRUSH hbrBackground;
    LPCTSTR lpszMenuName;
    LPCTSTR lpszClassName;
    HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;
成员介绍
         cbSize 值为sizeof(WNDCLASSEX),在调用GetClassInfoEx前必须要先设置它值。
         

style 窗口类的样式,它的值可以是窗口样式值的任意组合。

可以有以下的值

lpfnWndProc 指向窗口处理函数(回调函数)。处理窗口事件,像单击鼠标会怎样,右击鼠标会怎样,都是由此函数控制的。

cbClsExtra 为窗口类的额外信息做记录,系统初始化为0。
cbWndExtra 记录窗口实例的额外信息,系统初始为0.如果程序使用WNDCLASSEX注册一个从资源文件里创建的对话框,则此参数必须设置为DLGWINDOWEXTRA

hIcon 窗口类的图标,为资源句柄,如果设置为NULL,系统将为窗口提供一个默认的图标。

hCursor 窗口类的鼠标样式,为鼠标样式资源的句柄,如果设置为NULL,系统提供一个默认的鼠标样式。

hbrBackground 窗口类的背景刷,为背景刷句柄,也可以为系统颜色值,如果颜色值已给出,则必须转化为以下的HBRUSH的值

·       COLOR_ACTIVEBORDER

·       COLOR_ACTIVECAPTION

·       COLOR_APPWORKSPACE

·       COLOR_BACKGROUND

·       COLOR_BTNFACE

·       COLOR_BTNSHADOW

·       COLOR_BTNTEXT

·       COLOR_CAPTIONTEXT

·       COLOR_GRAYTEXT

·       COLOR_HIGHLIGHT

·       COLOR_HIGHLIGHTTEXT

·       COLOR_INACTIVEBORDER

·       COLOR_INACTIVECAPTION

·       COLOR_MENU

·       COLOR_MENUTEXT

·       COLOR_SCROLLBAR

·       COLOR_WINDOW

·       COLOR_WINDOWFRAME

·       COLOR_WINDOWTEXT

lpszMenuName 指向一个以NULL结尾的字符床,同目录资源的名字一样。如果使用整型id表示菜单,可以用MAKEINTRESOURCE定义一个宏。如果它的值为NULL,那么该类创建的窗口将都没有默认的菜单。

lpszClassName 窗口类的名字,字符串类型。

hIconSm 小图标的句柄,在任务栏显示的图标,可以和上面的那个一样。

定义一个WNDCLASSEX类型变量后,在给变量成员初始化后,我们就可以用
RegisterWindowEx(&wndclassex)来注册这个窗口类了。

这个注册过程,就和我们平常创建一个项目一样,都要先注册才能创建 。

2.        创建窗口

这一步很简单,就是利用CreateWindowEx()函数来创建就是了。

CreateWindowEx函数的原型如下:

Code
HWND CreateWindowEx(      
    DWORD dwExStyle,
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);
参数说明
                 dwExStyle:指定窗口的扩展风格。该参数可以是下列值:

WS_EX_ACCEPTFILES:指定以该风格创建的窗口接受一个拖拽文件。

                  WS_EX_APPWINDOW:当窗口可见时,将一个顶层窗口放置到任务条上。

                  WS_EX_CLIENTEDGE:指定窗口有一个带阴影的边界。

                          WS_EX_CONTEXTHELP:在窗口的标题条包含一个问号标志。

WS_EX_CONTROLPARENT:允许用户使用Tab键在窗口的子窗口间搜索。

                  WS_EX_DLGMODALFRAME:创建一个带双边的窗口;该窗口可以在dwStyle中指定WS_CAPTION风格来创建一个标题栏。

                  WS_EX_LEFT:窗口具有左对齐属性,这是缺省设置的。

                  WS_EX_LEFTSCROLLBAR:如果外壳语言是如Hebrew,Arabic,或其他支持reading order alignment的语言,则标题条(如果存在)则在客户区的左部分。若是其他语言,在该风格被忽略并且不作为错误处理。

                  WS_EX_LTRREADING:窗口文本以LEFT到RIGHT(自左向右)属性的顺序显示。这是缺省设置的。

                  WS_EX_MDICHILD:创建一个MD子窗口。

                    WS_EX_NOPATARENTNOTIFY:指明以这个风格创建的窗口在被创建和销毁时不向父窗口发送WM_PARENTNOTFY消息。

WS_EX_OVERLAPPED:WS_EX_CLIENTEDGEWS_EX_WINDOWEDGE的组合。

                        WS_EX_PALETTEWINDOW:WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW和WS_WX_TOPMOST风格的组合WS_EX_RIGHT:窗口具有普通的右对齐属性,这依赖于窗口类。

WS_EX_RIGHTSCROLLBAR:垂直滚动条在窗口的右边界。这是缺省设置的。

                    WS_EX_RTLREADING:如果外壳语言是如Hebrew,Arabic,或其他支持读顺序对齐(reading order alignment)的语言,则窗口文本是一自左向右)RIGHT到LEFT顺序的读出顺序。

WS_EX_STATICEDGE:为不接受用户输入的项创建一个3一维边界风格

                      WS_EX_TOOLWIDOW:创建工具窗口,即窗口是一个游动的工具条。

WS_EX_TOPMOST:指明以该风格创建的窗口应放置在所有非最高层窗口的上面并且停留在其L,即使窗口未被激活。使用函数SetWindowPos来设置和移去这个风格。

                  WS_EX_TRANSPARENT:指定以这个风格创建的窗口在窗口下的同属窗口已重画时,该窗口才可以重画。

  由于其下的同属富日已被重画,该窗口是透明的。

IpClassName: 窗口类的名字。

lpWindowName:指向一个指定窗口名的空结束的字符串指针。其实就是窗口的名字。

dwStyle:指定创建窗口的风格。该参数可以是下列窗口风格的组合再加上说明部分的控制风格。

x:窗口的横坐标。

y:窗口的竖坐标。

nWidth:窗口的宽度。

nHeight:窗口的高度。

hMenu:菜单句柄,或依据窗口风格指明一个子窗口标识。

hlnstance:与窗口相关联的模块事例的句柄。

lpParam:指向一个值的指针,该值传递给窗口 WM_CREATE消息

返回值:如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL。若想获得更多错误信息,请调用GetLastError函数。

3.        显示窗口

显示窗口就是更简单的事情了。

连个函数轻松搞定,第一个函数就是ShowWindow(),原型如下:

BOOL ShowWindow(      
            HWND hWnd,//当前的窗口句柄
            int nCmdShow //可见状态
            );

函数原型:

 BOOL UpdateWindow(HWND hWnd);

 描述:

  这个 UpdateWindow 函数通过发送重绘消息 WM_PAINT 给目标窗体来更新目标窗体客户区的无效区域。如果那个窗体的无效区域没有,就不发送重绘消息 WM_PAINT 了 。注意了,这个 API 函数是直接发送消息 WM_PAINT 给目标窗体的,没有进入过消息队列。

  函数参数:

  hWnd 一个要更新的窗体的句柄

  函数返回值:

  如果函数调用成功,返回值为非零值。

如果函数调用不成功,返回值为零。
 
经过这三步后,一个窗口就实现了,就创建了出来,难不,也真够难的,Windows想的正周到,把创建过程的每一个细节都给想到了,每毫秒可能发生的事情都想到了,难怪Windows那么贵,还不开源。也算是人间的产品嘛,费的心血可真不少呀。说难其实也不难,创建一个窗口程序也就三步:一注册,二创建,三显示。很容易就ok了。这T他妈容易了吧。
 
原理就是这些的,我想我已经说的挺明白的了,如果你有什么疑惑,可以给我发邮件(cangsanbujin@126.com)
下面我们就按照上面所说的来编程实现一个窗口:
Code
#include <windows.h>

//回调函数
LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
    switch(Msg)//处理消息过程,什么是消息,下节再讲
    {
    case WM_DESTROY://响应鼠标单击关闭按钮事件
        PostQuitMessage(0);//退出消息队列,至于什么是消息队列,下节说
        return 0;//退出函数
    }
    return DefWindowProc(hWnd,Msg,wParam,lParam);
}

//主函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    char *cName = "myWindow";
    WNDCLASSEX wc;
    HWND hWnd;
    MSG Msg;

wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//通过函数来设置一个白色的背景,这里大家设置为NULL看看,会很有趣的
    wc.hCursor = NULL;//不设置
    wc.hIcon = NULL;//不设置
    wc.hIconSm = NULL;//不设置
    wc.hInstance = hInstance;//当前程序的句柄,hInstance是有系统给传递的
    wc.lpfnWndProc = WinProc;//窗口处理过程的回调函数。
    wc.lpszClassName =(LPSTR)cName;//窗口类的名字。
    wc.lpszMenuName = NULL;//目录名,不设置
    wc.style = CS_HREDRAW | CS_VREDRAW;

RegisterClassEx(&wc);//在系统中注册

hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,cName,"我的窗口我喜欢",WS_OVERLAPPEDWINDOW,
        200,100,600,400,NULL,NULL,hInstance,NULL);//创建窗口,窗口标题为"我的窗口我喜欢"
    if(hWnd == NULL)
    {//容错处理
        MessageBox(NULL,"There's an Error","Error Title",MB_ICONEXCLAMATION|MB_OK);
        return 0;
    }
    ShowWindow(hWnd,nShowCmd);//显示窗口
    UpdateWindow(hWnd);

//下面是对消息的循环处理,大家先不必管这些,下节课我会细说的
    while(GetMessage(&Msg,NULL,0,0))
    {
        TranslateMessage(&Msg);//翻译消息
        DispatchMessage(&Msg);//分派消息
    }
    return Msg.message;
}

哎,这一节,篇幅可是真有点长的,看完估计得换几口气吧,但是只要你看到了这些,你的水平就立马上了一个档次。想你看完后也许会头昏脑胀的,没有再看下去的信心的,但是估计当你把我的代码复制到VC中编译运行后,看到一个可爱的窗口时,肯定又会重新点燃你心中学习的热情吧,因为你已经看到了成功,看到了成就,一种成就感犹然自心中生,自信也提起来了,这比什么都好,人嘛就得对自己充满信心的。所以大家要发扬持之以恒的精神,坚持和我一起把这段苦闷的入门过程给走完,那么编程就不再是痛苦,而是一种乐趣。其实写这些程序很多东西都不用去记的想WNDCLASSEX结构的成员及成员作用,这些都不用去死记,只要知道有这么个东西,到时时再查就可以了,编程用到的函数、结构体那么多,谁想记呀。这一节已经留下了些问题,在下节介绍的,大家如果有余力的话,可以先查下资料的。

转载于:https://www.cnblogs.com/20090802/archive/2009/08/06/WhatCanCDo_3.html

《C语言到底能干什么》1.3 窗口程序的编写相关推荐

  1. 《C语言到底能干什么》1.5 在窗口上写上“Hello World”(高手莫看)

    1.5 在窗口上写上"Hello World" 再次声明:高手莫看,浪费时间 这一节我们乘胜追击,来继续深入学习下,学习窗口处理时间的东东. 也许你以前听说过,windows系统是 ...

  2. C 语言究竟能干什么

    C语言究竟能干什么 序言 鉴于现在已经大三了,很多同学很迷茫,自己学的东西到底能做什么,将来自己到底能干什么?我不想看着同学迷茫的面孔, 特别是几个好兄弟,有几个想学习编程,但又苦苦找不到门路的兄弟, ...

  3. 你认为已经过时的C语言,是如何影响500万程序员的?...

    看招聘职位要c语言的占比真不多了,是否c语言真得落伍了? 看一下许多招聘平台有关于找纯粹的c语言开发的占比确实没有很多,都被Java,php,python等等語言刷屏.这对于入门正在学习c语言的小白真 ...

  4. python语言能干什么-Python这么火到底能干啥?

    问题:Python这么火到底能干啥? 答: ·人工智能 Python是最适合人工智能的编程语言.同时,Python语法简洁清晰,简单易学,运行速度非常快,具有强大的库,可移植性,解释性,面向对象,可扩 ...

  5. 学python培训到底能干嘛

    Python是在人工智能领域发挥着很重要的作用的,现在依旧有很多人对Python这项技术不是很了解,学Python培训到底能干嘛?下面小编来为大家做下详细的介绍. python其实并不难学,对于初学者 ...

  6. python入门先学什么-所以学完 Python 入门课的孩子到底能干啥?

    原标题:所以学完 Python 入门课的孩子到底能干啥? 画个四色螺旋线 ▼ 绘制一个五彩橡皮筋球 ▼ 弄一朵同心花瓣 ▼ 螺旋花瓣 ▼ 随机万花筒 ▼ 还可以搞些表情包 ▼ 以上是学完Python ...

  7. 学python能做什么-学Python后到底能干什么?网友:我太难了

    原标题:学Python后到底能干什么?网友:我太难了 一起涨姿势 感觉全世界营销文都在推Python,但是找不到工作的话,又有哪个机构会站出来给我推荐工作? 笔者冷静分析多方数据,想跟大家说:关于超越 ...

  8. python编程是干嘛的-Python这么火到底能干啥?

    问题:Python这么火到底能干啥? 答: ·人工智能 Python是最适合人工智能的编程语言.同时,Python语法简洁清晰,简单易学,运行速度非常快,具有强大的库,可移植性,解释性,面向对象,可扩 ...

  9. 学python后到底能干什么-学Python后到底能干什么

    Python是一种什么语言? Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言. 比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页编程的Ja ...

  10. python能干什么-Python这么火,学完到底能干什么

    对计算机行业有所了解的人应该都听说过很多流行的编程语言,比如难学的C语言,非常流行的Java,用于网页开发的PHP等,Python也是编程语言的一种. 我们先来普及一下编程语言的基础知识,用任何一种语 ...

最新文章

  1. 重型车辆盲区行为检查Behaviours – Heavy Vehicle Blind Spots
  2. Silverlight + Model-View-ViewModel (MVVM)
  3. msclass 文字滚动_文字无缝循环滚动(标题向上滚动)
  4. CSS——如何清除浮动
  5. 推荐干货 | 我在阿里做运营:八一八运营经典误区
  6. 挂在windows2003下的硬盘分区文件系统被系统识别为RAW,如何恢复至NTFS
  7. (原创)speex与wav格式音频文件的互相转换(二)
  8. SAP Cloud for Customer OData v1和v2的区别
  9. linux 设置开机启动
  10. 蔚来事件后 理想和小鹏改了“辅助驾驶系统”官方宣传用词
  11. Java实现Base64编码和解码的方式
  12. Xshell 7官网免费版下载与安装(详细教程)
  13. Springboot中使用Robot及Websocket实现windows远程桌面控制
  14. 程序员的奋斗史(三十三)——人在囧途之应聘篇(三)
  15. 智能世界的罗马是怎样建成的?
  16. 无线通信中存在的远近效应、多普勒效应、多径效应以及其应对策略
  17. python去掉字符串中的特殊字符和数字
  18. HTML基础 冲冲冲
  19. 从“触点”到“旅程”——浅谈数字时代的客户体验提升
  20. C语言图形化推箱子完整代码

热门文章

  1. 安装android studio报错Failed to install Intel HAXM.
  2. 【oracle】sql处理重复数据
  3. 关于ListCtrol自绘的技巧
  4. CentOS Postfix 安装构架全解
  5. 】oracle em配置常用命令
  6. 通过tomcat插件启动Maven工程
  7. Java温习(基础语法一)
  8. [数据结构] 非旋Treap
  9. nodejs后台系列--第四篇--koa
  10. kill、killall 、pkill 发送信号命令