• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 深入解析C++的WNDCLASS结构体及其在Windows中的应用

深入解析C++的WNDCLASS结构体及其在Windows中的应用

作者:Jackalfly 字体:[增加 减小] 来源:互联网 时间:2017-05-28

Jackalfly 通过本文主要向大家介绍了wndclass,wndclass.style,wndclass.hicon,wndclass.lpfnwndproc,wndclass函数等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

WNDCLASS是一个由系统支持的结构,用来储存某一类窗口的信息,如ClassStyle,消息处理函数,Icon,Cursor,背景Brush等。也就是说,CreateWindow只是将某个WNDCLASS定义的窗体变成实例。要得到某一窗口的WNDCLASS数据,可以用GetClassLong();
  RegisterClass()就是在系统注册某一类型的窗体。也就是将你提供的WNDCLASS数据注册为一个窗口类,在WNDCLASS.lpszClassName中定义该WNDCLASS的标识,无论CreateWindow或CreateWindowEx创建的窗口都必须对应一个WNDCLASS,但一个WNDCLASS可以有多个窗口对象。
  有一些系统预定义的窗口类,如:ClassName=_T("BUTTON" or "COMBOBOX" or "EDIT" or "LISTBOX" or "MDICLIENT" or "SCOLLBAR" or "STATIC"),要用这些窗体,直接用CreateWindow创建相应对象就是了。要得到某一窗口的窗口类,可以用GetClassName();
  WNDCLASS中的回调函数是窗体的消息处理函数:CALLBACK WinProc(MESSAGE msg,LPARAM lparam,WPARAM wParam);
窗口类属性定义
  结构WNDCLASS包含一个窗口类的全部信息,也是Windows编程中使用的基本数据结构之一,应用程序通过定义一个窗口类确定窗口的属性,定义如下:

typedef struct _WNDCLASS {
  UINT style;
  WNDPROC lpfnWndProc;
  int cbClsExtra;
  int cbWndExtra;
  HINSTANCE hInstance;
  HICON hIcon;
  HCURSOR hCursor;
  HBRUSH hbrBackground;
  LPCTSTR lpszMenuName;
  LPCTSTR lpszClassName;
  } WNDCLASS, *PWNDCLASS;
</div>

举例说明
例子:

long CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//声明
//WinMain函数是所有Windows应用程序的入口,类似c语言中的main函数其功能是完成//一系列的定义和初始化,并产生消息循环。函数说明:
int WINAPI WinMain(HINSTANCE hInstance,    // handle to current instance
               HINSTANCE hPrevInstance, // handle to previous instance
               LPSTR lpCmdLine,       // command line
                int nCmdShow           // show state
)
{
    //初始化,初始化包括窗口类的定义、注册、创建窗口实例和显示窗口四部分
  HWND hwnd;
  MSG Msg;
  WNDCLASS wndclass;
  char lpszClassName[]="窗口"; //窗口类名
  char lpszTitle[]="测试窗口"; //窗口标题名
  //窗口类定义,窗口类定义了窗口的形式与功能,窗口类定义通过给窗口类数据结构WNDCLASS赋值完成
  //该数据结构中包含窗口类的各种属性
  wndclass.style =0; // 窗口类型为缺省类型CS_   Class Style
  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=lpszClassName; //窗口类名为“窗口”
  //以下是窗口类的注册-----------Windows系统本身提供部分预定义的窗口类,程序员也可以自定义窗口类,窗口类必须先注册后使用。
  if(!RegisterClass(&wndclass)) //如果注册失败 发出警告
     {MessageBeep(0); return FALSE;}
  //创建窗口创建一个窗口的实例由函数CreateWindow()实现
  hwnd=CreateWindow( lpszClassName, //窗口类名,创建窗口时一定要基于我们已经注册过的窗口类名,即"窗口"。
                    lpszTitle, //窗口标题名
                    WS_OVERLAPPEDWINDOW, //窗口的风格 WS_ Windows Style
                    CW_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);
}
</div>

注:窗口回调函数的函数指针定义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);
</div>

通过调用SetWindowLong函数可以修改该窗体类的回调函数。
 
CallBack 函数中的wParam和lParam有什么区别:
  WPARAM   wParam,     定义成WORD型
  LPARAM   lParam         定义成LONG型
  在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,两者有明显的区别。
  在Win32 API中,WPARAM和LPARAM都是32位,所以没有什么本质的区别。
  但是习惯上,我们愿意使用LPARAM传递地址,而WPARAM传递其他参数。

 function MouseHookProc(nCode: Integer; wPar: WPARAM; lPar: LPARAM): lResult; stdcall;
</div>

  如果我要判断鼠标左键是否按下,用wParam==WM_LBUTTONDOWN判断.
  lParam 是 (tagMOUSEHOOKSTRUCT的指针)PMouseHookStruct类型,主要是获得发送窗口句柄,鼠标坐标 ,以及其他一些信息 。
  lParam 用的时候需要强制转换,转换成PMouseHookStruct类型.

PMouseHookStruct = ^TMouseHookStruct; 
tagMOUSEHOOKSTRUCT = packed record 
 pt: TPoint; 
 hwnd: HWND; 
 wHitTestCode: UINT; 
 dwExtraInfo: DWORD; 
end; 
TMouseHookStruct = tagMOUSEHOOKSTRUCT; 

</div> </div>
function GetMsgProc(nCode: Integer; wPara: WPARAM; lPara: LPARAM) 
 : lResult; stdcall; 
var 
 hGetMsgHook:HHOOK;  
 Msg: TMsg; 
begin 
 if (nCode >= 0) then 
 begin 
  FillChar(pMsgData^, Sizeof(TMessageRecord), #0); 
  Msg := TMsg(Pointer(lPara)^); 
 end; 
 Result := CallNextHookEx(hGetMsgHook, nCode, wPara, lPara); 
end; 
</div>

 
数据结构原型

typedef struct _WNDCLASS{
          UINT style;
           WNDPROC lpfnWndProc;
           int cbClsExtra;
           int cbWndExtra;
           HANDLE hInstance;
           HICON hIcon;
           HCURSOR hCursor;
           HBRUSH hbrBackground;
           LPCTSTR lpszMenu



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入解析C++的WNDCLASS结构体及其在Windows中的应用

相关文章

  • 2017-05-28C++中共用体的定义与应用总结
  • 2017-05-28C++类成员构造函数和析构函数顺序示例详细讲解
  • 2017-05-28c语言算术运算符越界问题解决方案
  • 2017-05-28实例讲解C++编程中lambda表达式的使用
  • 2017-05-28数据结构 C语言实现循环单链表的实例
  • 2017-05-28C语言 经典题目螺旋矩阵 实例详解
  • 2017-05-28C语言将数组中元素的数排序输出的相关问题解决
  • 2017-05-28C++交换指针实例
  • 2017-05-28C++实现修改函数代码HOOK的封装方法
  • 2017-05-28C++封装IATHOOK类实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 纯C语言:贪心Prim算法生成树问题源码分享
    • Cocos2d-x学习笔记之Hello World源码分析
    • ZOJ 3329 One Person Game (期望DP)
    • C语言结构体指针(指向结构体的指针)详解
    • C++多文件变量解析
    • c语言 time.h 详细介绍
    • C++指向函数的指针实例解析
    • C语言 字符串首字母转换成大写简单实例
    • 经典的字符串模式匹配算法KMP算法
    • C++ ofstream与ifstream详细用法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有