(金光鳞闪影若茫)

窗口四步走:

  设计窗口类

  注册窗口类

  创建窗口

  显示更新窗口

最后创建消息循环和响应函数

设计窗口类:

 typedef struct {UINT style;//窗口类型 WNDPROC lpfnWndProc;//窗口处理函数int cbClsExtra;//窗口扩展int cbWndExtra;//窗口实例扩展HINSTANCE hInstance;//实例句柄HICON hIcon;//窗口的最小化图标HCURSOR hCursor;//窗口鼠标光标HBRUSH hbrBackground;//窗口背景色LPCTSTR lpszMenuName;//窗口菜单LPCTSTR lpszClassName;// 窗口类名
} WNDCLASS, *LPWNDCLASS

说明:

举例:

WNDCLASS wndclass;char lpszClassName[]="窗口"; //窗口类名char lpszTitle[]="测试窗口";  //窗口标题名//窗口类定义,窗口类定义了窗口的形式与功能,窗口类定义通过给窗口类数据结构WNDCLASS赋值完成//该数据结构中包含窗口类的各种属性wndclass.style =0; // 窗口类型为缺省类型CS_     Class Stylewndclass.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=lpszClassName; //窗口类名为“窗口”

注册窗口类:

//以下是窗口类的注册-----------Windows系统本身提供部分预定义的窗口类,程序员也可以自定义窗口类,窗口类必须先注册后使用。
if(!RegisterClass(&wndclass)) //如果注册失败 发出警告   {MessageBeep(0); return FALSE;}说明:注册内容为窗口类对象指针(服务消息处理)

 创建窗口:

//创建窗口创建一个窗口的实例由函数CreateWindow()实现
CreateWindow(lpszClassName, //窗口类名,创建窗口时一定要基于我们已经注册过的窗口类名,即"窗口"。lpszTitle, //窗口标题名WS_OVERLAPPEDWINDOW, //窗口的风格 WS_ Windows StyleCW_USEDEFAULT, //窗口左上角坐标值为缺省值 CW_  Create Wndow
           CW_USEDEFAULT,
           CW_USEDEFAULT, //窗口的高和宽为缺省值
            CW_USEDEFAULT,
             NULL, //此窗口无父窗口NULL, //此窗口无子菜单hInstance, //创建此窗口的应用程序的当前句柄NULL //不使用该值
);

说明:创建方式应为 HWND hwnd = CreateWindow(...);

hwnd值为NULL(创建失败)或者窗口句柄(创建成功)

显示更新窗口:

显示窗口:

//显示窗口

ShowWindow(hwnd,nCmdShow);

窗口句柄以及指定显示状态

更新窗口:

//绘制用户区,在显示后必须需要

UpdateWindow(hwnd);

循环及响应:

 消息循环:

BOOL GetMessage(LPMSG lpMsg,//指向 MSG 结构的指针,用于存放获取到的消息HWND hWnd,//当其值是 NULL 时,将获取所有的当前线程的窗口消息和线程消;当其值是 -1 时,只获取当前线程消息UINT wMsgFilterMin,//指定被可以被获取的消息值的最小整数(消息其实就是一个被定义的整数)UINT wMsgFilterMax,//指定被可以被获取的消息值的最大整数
);

说明:Min和Max都设置为0时接收所有消息;返回值都为非零值(除了WM_QUIT)错误返回值为-1;

   消息循环一条线程一个,是保证windows消息响应模式就基础,而非一个窗口一个;

举例:

//消息循环
while(GetMessage(&Msg,NULL,0,0))
{TranslateMessage(&Msg);//对"消息对"的转化,如对键盘的WM_KEYDOWN和WM_KEYUP消息对转化为WM_CHAR消息,并且将转换后的新消息投递到我们的消息队列中去,               //这个转化操作不会影响原来的消息,只会产生一个新的消息。DispatchMessage(&Msg);//DispatchMessage()函数是将我们取出的消息传到窗口的回调函数去处理;可以理解为该函数将取出的消息路由给操作系统,然后操作系统去调用我们的窗口回调函数对这个消息进行处理。
}

窗口过程函数:

LRESULT CALLBACK WindowProc
(
HWND hwnd, // 消息句柄
UINT uMsg, // 消息代码
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
); 

说明:

函数名随意但要对应设计时的名称,一个窗口对应一个过程函数

过程函数配合switch/case处理窗口中其他控件消息

举例:

long CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{switch(message){case WM_DESTROY:PostQuitMessage(0);default: //缺省时采用系统消息缺省处理函数return DefWindowProc(hwnd,message,wParam,lParam);}return (0);
}

说明:其中message 通过translatemessage()将事件转化而来

综合:

long CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//声明
//WinMain函数是所有Windows应用程序的入口,类似c语言中的main函数其功能是完成//一系列的定义和初始化,并产生消息循环。函数说明:
int WINAPI WinMain(HINSTANCE hInstance,       // handle to current instanceHINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine,              // command lineint nCmdShow                     // show state
)
{//初始化,初始化包括窗口类的定义、注册、创建窗口实例和显示窗口四部分
  HWND hwnd;MSG Msg;WNDCLASS wndclass;char lpszClassName[]="窗口"; //窗口类名char lpszTitle[]="测试窗口";  //窗口标题名//窗口类定义,窗口类定义了窗口的形式与功能,窗口类定义通过给窗口类数据结构WNDCLASS赋值完成//该数据结构中包含窗口类的各种属性wndclass.style =0; // 窗口类型为缺省类型CS_     Class Stylewndclass.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=lpszClassName; //窗口类名为“窗口”//以下是窗口类的注册-----------Windows系统本身提供部分预定义的窗口类,程序员也可以自定义窗口类,窗口类必须先注册后使用。if(!RegisterClass(&wndclass)) //如果注册失败 发出警告{MessageBeep(0); return FALSE;}//创建窗口创建一个窗口的实例由函数CreateWindow()实现hwnd=CreateWindow( lpszClassName, //窗口类名,创建窗口时一定要基于我们已经注册过的窗口类名,即"窗口"。lpszTitle, //窗口标题名WS_OVERLAPPEDWINDOW, //窗口的风格 WS_ Windows StyleCW_USEDEFAULT, //窗口左上角坐标值为缺省值 CW_  Create Wndow
                                     CW_USEDEFAULT,CW_USEDEFAULT, //窗口的高和宽为缺省值
                                      CW_USEDEFAULT,NULL, //此窗口无父窗口NULL, //此窗口无子菜单hInstance, //创建此窗口的应用程序的当前句柄NULL //不使用该值
  );//显示窗口
  ShowWindow(hwnd,nCmdShow);//绘制用户区
  UpdateWindow(hwnd);//消息循环while(GetMessage(&Msg,NULL,0,0))  //GetMessage()函数是从调用线程的消息队列中取出一条消息;对于每一个应用程序窗口线程,操作系统都会为其建立一个消息队列,当我们的窗口有消息时(即所有与这个窗口线程相关的消息),操纵系统会把这个消息放到该线程的消息队列当中,我们的窗口程序就通过这个GetMessage()函数从自己的消息队列中取出一条一条具体的消息并进行响应操作。
  {TranslateMessage(&Msg);//对"消息对"的转化,如对键盘的WM_KEYDOWN和WM_KEYUP消息对转化为WM_CHAR消息,并且将转换后的新消息投递到我们的消息队列中去,这个转化操作不会影响原来的消息,只会产生一个新的消息。DispatchMessage(&Msg);//DispatchMessage()函数是将我们取出的消息传到窗口的回调函数去处理;可以理解为该函数将取出的消息路由给操作系统,然后操作系统去调用我们的窗口回调函数对这个消息进行处理。
        }return Msg.wParam; //消息循环结束 即程序结束时 将信息返回系统
 }
//窗口函数,窗口函数定义了应用程序对接收到的不同消息的响应,其中包含了应用程序对各种可能接受到的消息的处理过程,时消息处理分支控制语句的集合
long CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{switch(message){case WM_DESTROY:PostQuitMessage(0);default: //缺省时采用系统消息缺省处理函数return DefWindowProc(hwnd,message,wParam,lParam);}return (0);
}
注:窗口回调函数的函数指针定义typedef LRESULT CALLBACK  (* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
WNDPROC OldWndProc;
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){switch (Msg){......}return CallWindowProc(OldWndProc,g_Wnd,Msg,wParam,lParam);
}
OldWndProc = (WNDPROC)GetWindowLong(g_Wnd,GWL_WNDPROC);
SetWindowLong(hwnd, GWL_WNDPROC,(LPARAM)(WNDPROC)NewWndProc);
通过调用SetWindowLong函数可以修改该窗体类的回调函数。

转载于:https://www.cnblogs.com/sepmaple/p/9321732.html

《VC++深入详解》学习笔记 第一章 Windows程序内部运行机制相关推荐

  1. VC++深入详解学习笔记

    VC++深入详解学习笔记 Lesson1: Windows程序运行原理及程序编写流程 Lesson2: 掌握C++基本语法 Lesson3: MFC框架程序剖析 Lesson4: 简单绘图 Lesso ...

  2. VC++的学习(基于VS2008)——windows程序内部运行机制

    昨天和今天都在学习windows程序的内部运行机制,再次学习这一章,我明显感到条理清晰了,原来这一章是讲我们所用的电脑,这样一个windows平台下程序运行的内部机制的.windows应用程序下最重要 ...

  3. 孙鑫-MFC笔记一--Windows程序内部运行机制

    对于一个初学者来说,常常会用到各种库函数,例如printf等等,这些库函数是由你所使用的编译器厂商提供的,在Windows操作系统下,开发的应用程序, 也有这样的库函数,不同的是,这样的库函数,是有w ...

  4. VC++ 深入详解 学习笔记(5) -- 修改窗口样式续

    From: http://elton.iteye.com/blog/301503 之前说过, 修改窗口大小,窗口样式的方法. 这里说明一下修改窗口的图标,光标和背景的方法. 修改窗口大小,样式是在创建 ...

  5. TCP/IP详解学习笔记-基本概念

    为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样 ...

  6. 基础才是王道——TCP/IP详解学习笔记 这位仁兄写得太好了

    TCP/IP详解学习笔记 这位仁兄写得太好了 TCP/IP详解学习笔记   这位仁兄写得太好了. http://blog.csdn.net/goodboy1881/category/204448.as ...

  7. TCP/IP详解学习笔记(1)-基本概念

    为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样 ...

  8. TCP_IP详解学习笔记

    TCP/IP详解学习笔记(1)-基本概念 为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中 ...

  9. TCP/IP详解学习笔记 这位仁兄写得太好了.

    http://blog.csdn.net/goodboy1881/category/204448.aspx TCP/IP详解学习笔记(1)-基本概念 为什么会有TCP/IP协议 在世界上各地,各种各样 ...

最新文章

  1. 比特币现金(BCH)和比特币(BTC)之争到底在争些什么?
  2. win 2003 IIS如何防止代码注入
  3. jieba(结巴)常用方法
  4. 【解决线程安全问题:通过Lock锁对象】
  5. android 增删改查 源码_学生信息增删改查小程序案例(springboot服务端)
  6. 服务器连接硬盘出错,在服务器上使物理磁盘资源联机时出错 - Windows Server | Microsoft Docs...
  7. 【今日CV 视觉论文速览】29 Nov 2018
  8. 一次性从linux发送多个文件到windows
  9. CCNA2.0笔记_ACL
  10. 配置linux定时任务没跑,Linux配置定时任务
  11. JS获取url参数,主域名等方法
  12. SPD中赋值连接字段
  13. 华南师范大学计算机考研考场,2018考研:华南师范大学考场安排
  14. 使用python,爆破加密的rar压缩文件
  15. cuda必须装在c盘吗_怎样把C盘的所有文件移到D盘或E盘里去?
  16. 怎么在html中加入特效汉字,如何在小视频上加文字,文字动画特效,朋友圈小视频加文字...
  17. 黑帽SEO网站优化常用的15种技巧
  18. Second season sixteenth episode,Joey moves out
  19. 为Windows 7的winsxs文件夹瘦身,慎重。
  20. 咪咕版kindle利用“隐藏浏览器”打开微信读书

热门文章

  1. asp mysql连接已重置,mysql-检查经典ASP中的连接是否正常
  2. 游戏中的颜色:深度解析游戏设计工具
  3. 聊聊《战魂铭人》的游戏设计
  4. 王哲:Cocos2d-x 3.0引擎带来了什么?
  5. dfs——练习demo3(20届周新杰提供)
  6. switch与if效率实例解析·5年以下编程经验必看【Python】
  7. ORA-29786: SIHA attribute GET failed with error
  8. Oracle 11g创建Interval分区表
  9. RPC与其实现方式概念笔记
  10. centos6 python 安装 sqlite 解决 No module named ‘_sqlite3′