WNDCLASS结构体

转载:https://blog.csdn.net/jackalfly/article/details/8239188

@

       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;

举例说明

例子:

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);

}

注:窗口回调函数的函数指针定义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函数可以修改该窗体类的回调函数。

 

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


  
  
  1. PMouseHookStruct = ^TMouseHookStruct;
  2. tagMOUSEHOOKSTRUCT = packed record
  3. pt: TPoint;
  4. hwnd: HWND;
  5. wHitTestCode: UINT;
  6. dwExtraInfo: DWORD;
  7. end;
  8. TMouseHookStruct = tagMOUSEHOOKSTRUCT;

例如:


  
  
  1. function GetMsgProc(nCode: Integer; wPara: WPARAM; lPara: LPARAM)
  2. : lResult; stdcall;
  3. var
  4. hGetMsgHook:HHOOK;
  5. Msg: TMsg;
  6. begin
  7. if (nCode >= 0) then
  8. begin
  9. FillChar(pMsgData^, Sizeof(TMessageRecord), #0);
  10. Msg := TMsg(Pointer(lPara)^);
  11. end;
  12. Result := CallNextHookEx(hGetMsgHook, nCode, wPara, lPara);
  13. end;


 

数据结构原型

typedef struct _WNDCLASS{

                 UINT style;

                      WNDPROC lpfnWndProc;

                    int cbClsExtra;

                    int cbWndExtra;

                      HANDLE hInstance;

                    HICON hIcon;

                      HCURSOR hCursor;

                      HBRUSH hbrBackground;

                      LPCTSTR lpszMenuName;

                    LPCTSTR lpszClassName;

}WNDCLASS;

结构说明

  WNDCLASS 结构包含了RegisterClass函数注册的类属性

分量简介

style: 指定类风格。这些风格可通过按位或操作组合起来。风格如下:

  CS_BYTEALIGNCLIENT: 在字节边界上(在x方向上)定位窗口的用户区域的位置

  CS_BYTEALIGNWINDOW: 在字节边界上(在x方向上)定位窗口的位置

  CS_CLASSDC: 该窗口类的所有窗口实例都共享一个窗口类DC

  CS_DBLCLKS: 允许向窗口发送双击鼠标键的消息

  CS_GLOBALCLASS: 当调用CreateWindow 或 CreateWindowEx 函数来创建窗口时允许它的hInstance参数和注册窗口类时传递给

  RegisterClass 的 hInstance参数不同。如果不指定该风格,则这两个 hInstance 必须相同。

  CS_HREDRAW: 当水平长度改变或移动窗口时,重画整个窗口

  CS_NOCLOSE: 禁止系统菜单的关闭选项

  CS_OWNDC: 给予每个窗口实例它本身的DC。注意,尽管这样是很方便,但它必须慎重使用,因为每个DC大约要占800个字节的内存。

  CS_PARENTDC: 将子窗口的裁剪区域设置到父窗口的DC中去,这样子窗口便可以在父窗口上绘制自身。注意,这是子窗口还是从系统缓存中获取DC,而不是使用父窗口的DC。使用该风格可以提高系统性能。

  CS_SAVEBITS: 以位图形式保存被该窗口遮挡的屏幕部分,这样当给窗口移动以后,系统便可以用该保存的位图恢复屏幕移动的相应部分,从而系统不用向被该窗口遮挡的窗口发送 WM_PAINT 消息。该特性对于菜单类型的窗口比较合适,因为它通常是简短的显示一下之后便消失。设置该特性将增加显示该窗口的时间,因为它通常要先分配保存位图的内存。

  CS_VREDRAW: 当垂直长度改变或移动窗口时,重画整个窗口

lpfnWndProc: 指向窗口过程

cbClsExtra: 指定紧随在 WNDCLASS 数据结构后分配的字节数。系统将其初始化为零。

cbWndExtra: 指定紧随在窗口实例之后分配的字节数,系统将其初始化为零。如果应用程序正在用WNDCLASS结构注册一个在RC资源描述文件中用CLASS指令创建的对话框时,它必须设置这个字段为 DLGWINDOWEXTRA。

hInstance: 标识了该窗口类的窗口过程所在的模块实例的句柄,不能为NULL。

hIcon: 标识了该窗口类的图标。hIcon字段必须是一个图标的句柄;若hIcon字段为NULL,则无论何时用户把应用程序缩至最小时,应用程序必须画一个图标。

hCursor: 标识该窗口类的光标,hCursor必须是一个光标资源的句柄。若hCursor字段为NULL,则无论何时鼠标移到应用程序窗口时,应用程序必须显式设置光标形状。

hbrBackground: 标识了该窗口类的背景画笔。hbrBackground字段必须是用于绘制背景的物理刷子的句柄,或者是一个颜色的值。如果给出一个颜色的值,它必须是下面列出的标准系统颜色之一(系统将对所选颜色加1)。如果给出了颜色值,它必须是转换成下列的HBRUSH类型之一的颜色:

  COLOR_ACTIVEBORDER

  COLOR_ACTIVECAPTION

  COLOR_APPWORKSPACE

  COLOR_BACKGROUND

  COLOR_BTNFACE

  COLOR_BTHSHADOW

  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

  当hbrBackground字段为NULL时,每当需要绘制其用户区域时,应用程序必须自己来绘制其背景。应用程序可以通过处理WM_ERASEBKGND 消息或检查由 BeginPaint 函数填写的 PAINTSTRUCT 结构的fErase 字段来确定背景什么时候需要着色。

lpszMenuName:指向NULL结束的字符串,该字符串描述菜单的资源名,如同在资源文件里显示的名字一样。若使用一个整数标识菜单,可以使用MAKEINTRESOURCE宏。如果lpszMenuName为NULL,

  那么该窗口类的窗口将没有默认菜单。

lpszClassName:指向NULL结束的字符串,或者是一个原型(atom)。若该参数是一个原型,它必须是一个有先前调用RegisterClass或者 RegisterClassEx函数产生的类原型。类原型必须作为lpszClassName的低字,高字必须为0.若lpszClassName是一个字符串,它描述了窗口类名。这个类名可以是由RegisterClass或者RegisterClassEx注册的名字,或者是任何预定义的控件类名。

  结构信息Header 在winuser.h声明,包含windows.h

[TOC](这里写自定义目录标题)

欢迎使用Markdown编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目Value
电脑$1600
手机$12
导管$1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文本居中第二列文本居右第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

Mon 06 Mon 13 Mon 20 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.2.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件或者.html文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值