PostMessage 和SendMessage的区别

1.队列

PostMessage  和SendMessage的区别主要在于是否等待其他程序消息处理。

PostMessage只是把消息放入队列,不管其他程序是否处理都返回,然后继续执行

2.返回

SendMessage必须等待其他程序处理消息后才返回,继续执行。这两个函数的返回值也不同,SendMessage的返回值表示其他程序处理消息后的返回值

PostMessage的返回值表示PostMessage函数执行是否正确

 

如果要在不同进程间传递字符串等数据,最好用SendMessage,hWnd,WM_COPYDATA,0,addr stCopyData

stCopyData的定义:stCopyData     COPYDATASTRUCT      <>

一招让你打不开百度

无聊了,写个小程序

.386
.model flat,stdcall
option casemap:none
include        windows.inc
include        gdi32.inc
includelib    gdi32.lib
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib
.data
hMain    dd    ?
.data?
.const
szWindowName    db    ’百度一下,你就知道 – Windows Internet Explorer’,0
.code
start:
.while TRUE
invoke FindWindow,NULL,addr szWindowName
.if eax
mov hMain,eax
invoke SendMessage,hMain,WM_CLOSE,0,0
.endif
.endw
invoke ExitProcess,NULL
end start

关于程序收到消息的顺序(小甲鱼)

窗口过程收到消息是有一定顺序的,收到第一条消息并不是从消息循环开始以后,而是在CreateWindowEx 中就开始了,显示和刷新窗口的函数 ShowWindow 和 UpdateWindow 也向窗口过程发送消息。
这一点并不奇怪,因为 Windows 在CreateWindowEx 前调用 RegisterClassEx 的时候就已经得到窗口过程的地址了。并且在建立窗口的过程中需要窗口过程的配合。

调用 CreateWindowEx 时窗口过程收到的消息:

消息发生 说明
 WM_GETMINMAXINFO  获取窗口大小,以便初始化
 WM_NCCREATE  非客户区开始建立
 WM_NCCALCSIZE  计算客户区大小
 WM_CREATE  窗口建立

调用ShowWindow时窗口过程收到的消息:

消息发生 说明
WM_SHOWWINDOW 显示窗口
WM_WINDOWPOSCHANGING 窗口位置准备改变
WM_ACTIVATEAPP 窗口准备激活
WM_NCACTIVATE 激活状态改变
WM_GETTEXT 取窗口名称(显示标题栏用)
WM_ACTIVATE 窗口准备激活
WM_SETFOCUS 窗口获得焦点
WM_NCPAINT 需要绘画窗口边框
WM_ERASEBKGND 需要擦除背景
WM_WINDOWPOSCHANGED 窗口位置已经改变
WM_SIZE 窗口大小已经改变
WM_MOVE 窗口位置已经移动
然后程序执行 UpdateWindow,这个函数向窗口过程发送一条 WM_PAINT 消息,接着,主程序开始进入消息循环。
在消息循环中,Windows 根据各种因素给窗口过程发送相应的消息,直到调用 DestroyWindows 为止。
那么 DestoryWindow 向窗口过程发送的消息具体又是神马内容呢?
请看大屏幕 ->>
消息发生 说明
WM_NCACTIVATE 窗口激活状态改变
WM_ACTIVATE 窗口准备非激活
WM_ACTIVATEAPP 窗口准备非激活
WM_KILLFOCUS 失去焦点
WM_DESTROY 窗口即将被摧毁
WM_NCDESTROY 窗口的非客户区及所有子窗口已经被摧毁

在所有这些阶段的消息中,大部分的消息都不需要程序自己关心,Windows 只是尽义务通知窗口过程而已,窗口过程转手就交给 DefWindowProc 去处理了。

程序需要关心的消息有下面这些,可以根据需要选择使用:

WM_CREATE — 放置窗口初始化代码,如建立各种子窗口(状态栏和工具栏等)
WM_SIZE — 放置位置安排的代码,因为建立的子窗口可能需要随窗口大小的改变而移动位置
WM_PAINT — 如果需要自己绘制客户区,则在这里安排代码
WM_CLOSE — 向用户确认是否退出,如果退出则摧毁窗口并发送WM_QUIT消息
WM_DESTROY — 窗口摧毁,在这里放置释放资源等扫尾代码
在例子程序中,我们处理了 WM_PAINT 消息来绘制客户区,功能就是在窗口的中间写上一行字:”Welcome to fishc.com!”
先通过 BeginPaint 获取窗口客户区的 ”设备环境” 句柄。
然后通过 GetClientRect 获取客户区的大小。
最后通过 DrawText 函数将字符串按照取得的屏幕大小居中写到 “设备环境” 中,也就是窗口上。
如果不需要显示这个字符串,则连WM_PAINT消息也不用处理。
Windows 预定义的消息范围是 0~03ffh,总共 1024 个消息,查看一下头文件Windows.inc,可以发现实际已定义的消息数目有几百个,这些消息中的大部分对于窗口的运行来说都是必需的。
如果窗口过程要处理每一种消息,那么窗口过程中的 elseif 语句肯定就会绵延数千行,这显然很费劲,所以诞生了 DefWindowProc 函数。
正是它用默认的方式处理了几百种消息,我们才能用区区百来行代码写出一个全功能的窗口。
也正是所有的窗口都用 DefWindowProc 默认处理程序自己不处理的消息,才使它们的行为看上去大同小异,因为它们背后实际上是同一块代码在处理。
这样子的话我们终于了解到为什么在 Windows 上很多窗口程序无论形状或者行为(拖动、最大化、最小化、关闭等)都大同小异。
形状 – 窗口类
行为 – DefWindowProc
在窗口过程的分支语句中,用户处理所有需要个性化处理的消息,对于表现行为是默认行为的消息,在 else 分支中用 DefWindowProc 来处理。
对于Windows来说,它并不关心消息在窗口过程中是程序用自己的代码处理的还是用DefWindowProc 处理的,它只看 eax 中的返回值来了解处理结果,所以不管消息是谁处理的,都必须在 eax 中返回正确的值。
DefWindowProc 返回时 eax 中就是它对消息的处理结果,程序只要直接把 eax 传回给Windows 就行了,所以在例子程序中,DefWindowProc 后面直接用一句 ret 指令返回。
下边给大家列出了 DefWindowProc 中对一些消息的处理方法,如果和用户期望的不同,就必须在窗口过程中自己处理。
请看大屏幕 ->>
消息 DefWindowProc的处理方式
WM_PAINT 发送WM_ERASEBKGND消息来擦除背景
WM_ERASEBKGND 用窗口类结构中的hbrBackground刷子来绘画窗口背景
WM_CLOSE 调用DestroyWindow来摧毁窗口
WM_NCLBUTTONDBLCLK 这是非客户区(如标题栏)鼠标双击消息,DefWindowProc测试鼠标的位置,然后再采取相应的措施,如标题栏双击将最大化和恢复窗口
WM_NCLBUTTONUP 这是非客户区鼠标释放消息,同样,DefWindowProc测试鼠标的位置然后再采取相应的措施,如鼠标在“关闭”按钮的位置释放将导致发送WM_CLOSE消息
WM_NCPAINT 非客户区绘制消息,DefWindowProc将绘制边框和客户区

从这些默认的处理方法可以看出,想要一个窗口和别的窗口看起来不一样。
比如想要窗口看起来像苹果机的窗口一样,并且把关闭按钮移到标题栏最左边,那么可以自己处理 WM_NCPAINT 消息,把非客户区画成苹果机窗口的样子,并把关闭按钮画到标题栏左边。
对别的消息的处理思路也可以按这种方法类推。
另外,细心的鱼油会发现 DefWindowProc 对WM_CLOSE 的默认处理是调用 DestroyWindow摧毁窗口。
DestroyWindow 会引发一个 WM_DESTROY消息, WM_DESTROY 和 WM_CLOSE 不同:
WM_CLOSE 代表用户有关闭的意向,窗口过程有权”不服从”(如我们上节课对他进行修改)
但收到 WM_DESTROY 的时候不管窗口过程愿不愿意,窗口的关闭已经是不可挽回的事。

WM_COMMAND和WM_SYSCOMMAND(转)

对于菜单、加速键来说,点击后Windows会都会向它们所属的窗体发送WM_COMMAND消息。除了菜单、加速键,一些子窗体也会引发这些消息。例如对话框中的按钮或者工具栏中按钮(控件发通知消息给父窗体)WM_COMMAND消息中有两个参数,wparamlparam,定义如下:

       wParam 高两个字节通知码

       wParam 低两字节命令ID

       lParam 发送命令消息的子窗体句柄。

       对于菜单和加速键来说,lParam0,只有控件此项才非0。命令ID也就是资源脚本中定义的菜单项的命令ID或者加速键的命令ID;菜单的通知码为0;加速键的通知码为1

       对于Windows菜单中菜单项和加速键,点击后,Windows会向所属的窗体发送WM_SYSCOMMAND,而不是WM_COMMAND消息。注意,WINDOWS菜单是系统菜单,也就是在标题栏点击鼠标左键的时候弹出的菜单。我们可以捕获WM_CREATE消息,加入自己的操作:GetSysMenu获取系统菜单句柄,然后对系统菜单进行操作,并且捕获添加菜单项(根据菜单命令IDID对应的WM_SYSCOMMAND消息进行处理。修改系统默认的菜单行为。

例如:#define IDM_SELMENU 0×4444

else if ( uMsg == WM_CREATE)

       {

              HMENU hMenu = GetSystemMenu(hWnd,0);

              AppendMenu(hMenu,0,IDM_SELMENU,”Show Hello”);

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

       }

       else if ( uMsg == WM_SYSCOMMAND) //

       {           

              if ( wParam << 16 >> 16 == 0×4444 )

              {

                     MessageBox(NULL,”SysMenu:Show Hello MenuItem”, “sysmenu info”,MB_OK);

                     return 0;

              }

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

       }

       对于WM_SYSCOMMAND中如果是系统菜单的消息,我们没哟修改的,必须要交给DefWindowProc来处理,并且将返回值返回给Windows,不然你会发现不能拖动窗体、改变大小、最大最小化操作等。因为你如果不交给DefWindowProc处理,相当于屏蔽了SC_RESTORE SC_MOVE SC_MAXIMIZE SC_MINIMIZE SC_CLOSE等等操作了。这些命令都是通过Windows投递WM_SYSCOMMAND 消息,在DefWindowProc中进行处理的。

控制寄存器 (CR0, CR1, CR2, CR3)(小甲鱼)

控制寄存器

(控制寄存器(CR0,CR1,CR2,CR3)用于控制和确定处理器的操作模式以及当前执行任务的特性。)
从 上表可见,80386有四个32位的控制寄存器,分别命名位CR0、CR1、CR2和CR3。但CR1被保留,供今后开发的处理器使用,在 80386中不能使用CR1,否则会引起无效指令操作异常。CR0包括指示处理器工作方式的控制位,包含启用和禁止分页管理机制的控制位,包含控制浮点协 处理器操作的控制位。CR2及CR3由分页管理机制使用。CR0中的位5—位30及CR3中的位0至位11是保留位,这些位不能是随意值,必须为0。

控制寄存器CR0的低16位等同于80286的机器状态字MSW。

1.CR0中的保护控制位

控 制寄存器CR0中的位0用PE标记,位31用PG标记,这两个位控制分段和分页管理机制的操作,所以把它们称为保护控制位。PE控制分段管理机制。 PE=0,处理器运行于实模式;PE=1,处理器运行于保护方式。PG控制分页管理机制。PG=0,禁用分页管理机制,此时分段管理机制产生的线性地址直 接作为物理地址使 用;PG=1,启用分页管理机制,此时线性地址经分页管理机制转换位物理地址。由此可知,如果要启用分页机制,那么PE和PG标志都要置位。

下 表列出了通过使用PE和PG位选择的处理器工作方式。由于只有在保护方式下才可启用分页机制,所以尽管两个位分别为0和1共可以有四种组合,但只有三种组 合方式有效。PE=0且PG=1是无效组合,因此,用PG为1且PE为0的值装入CR0寄存器将引起通用保护异常。需要注意的是,PG位的改变将使系统启 用或禁用分页机制,因而只有当所执行的程序的代码和至少有一部分数据在线性地址空间和物理地址空间具有相同的地址的情况下,才能改变PG位。

2.协处理器控制位

控制寄存器CR0中的位1—位4分别标记为MP(算术存在位)、EM(模拟位,用于选择与协处理器进行通信所使用的协议,即指明系统中是用的是80386还是80286协处理器)、TS(任务切换位) 和ET(扩展类型位),它们控制浮点协处理器的操作。

当 处理器复位时,ET位被初始化,以指示系统中数字协处理器的类型。如果系统中存在 80387协处理器,那么ET位置1;如果系统中存在80287协处理器或者不存在协处理器,那么ET位清0。EM位控制浮点指令的执行是用软件模拟,还 是由硬件执行。EM=0时,硬件控制浮点指令传送到协处理器;EM=1时,浮点指令由软件模拟。TS 位用于加快任务的切换,通过在必要时才进行协处理器切换的方法实现这一目的。每当进行任务切换时,处理器把TS置1。TS=1时,浮点指令将产生设备不可 用(DNA)异常。 MP位控制WAIT指令在TS=1时,是否产生DNA异常。MP=1和TS=1时,WAIT产生异常;MP=0时,WAIT指令忽略 TS条件,不产生异常。

在系统刚上电时,处理器被复位成pe=0,pg=0(即实模式状态),以允许引导代码在启用分段和分页机制之前能够初始化这些寄存器和数据结构。对于这类寄存器的使用是在实模式下方可使用。

3.CR2和CR3

控制寄存器CR2和CR3由分页管理机制使用。
CR2用于发生页异常时报告出错信息。当发生页异常时,处理器把引起页异常的线性地址保存在CR2中。操作系统中的页异常处理程序可以检查CR2的内容,从而查出线性地址空间中的哪一页引起本次异常。

CR3 用于保存页目录表页面的物理地址,因此被称为PDBR。由于目录是页对齐的,所以仅高20位有效,低12 位保留供更加高级的处理器使用。向CR3中装入一个新值时,低12位必须为0;但从 CR3中取值时,低12位被忽略。每当用MOV指令重置CR3的值时,会导致分页机制高速缓冲区的内容无效,用此方法,可以在启用分页机制之前,即把PG 位置1之前,预先刷新分页机制的高速缓存。CR3寄存器即使在CR0寄存器的PG位或PE位为0时也可装入,如在实模式下也可设置CR3,以便进行分页机 制的初始化。在任务切换时,CR3要被改变,但是如果新任务中CR3的值与原任务中CR3的值相同,那么处理器不刷新分页高速缓存,以便当任务共享页表时 有较快的执行速度。

状态和控制寄存器组除了EFLAGS、EIP ,还有四个32位的控制寄存器,它们是CR0,CR1,CR2和CR3。这几个寄存器中保存全局性和任务无关的机器状态。

CR0 中包含了6个预定义标志,0位是保护允许位PE(Protedted Enable),用于启动保护模式,如果PE位置1,则保护模式启动,如果PE=0,则在实模式下运行。1位是监控协处理位MP(Moniter coprocessor),它与第3位一起决定:当TS=1时操作码WAIT是否产生一个“协处理器不能使用”的出错信号。第3位是任务转换位(Task Switch),当一个任务转换完成之后,自动将它置1。

随着TS=1,就不能使用协处理器。CR0的第2位是模拟协处理器位 EM (Emulate coprocessor),如果EM=1,则不能使用协处理器,如果EM=0,则允许使用协处理器。第4位是微处理器的扩展类型位 ET(Processor Extension Type),其内保存着处理器扩展类型的信息,如果ET=0,则标识系统使用的是287协处理器,如果 ET=1,则表示系统使用的是387浮点协处理器。CR0的第31位是分页允许位(Paging Enable),它表示芯片上的分页部件是否允许工作。

CR1是未定义的控制寄存器,供将来的处理器使用。
CR2是页故障线性地址寄存器,保存最后一次出现页故障的全32位线性地址。
CR3是页目录基址寄存器,保存页目录表的物理地址,页目录表总是放在以4K字节为单位的存储器边界上,因此,它的地址的低12位总为0,不起作用,即使写上内容,也不会被理会。

这几个寄存器是与分页机制密切相关的,因此,在进程管理及虚拟内存管理中会涉及到这几个寄存器,读者要记住CR0、CR2及CR3这三个寄存器的内容。

相关路径及screen常用命令(centos6)

ssh相关路径:

/etc/host.deny

/etc/host.allow

/etc/ssh/

/etc/ssh/sshd_config

screen相关路径:

/etc/screenrc

$HOME/.screenrc

screen常用命令:

C-a ? 显示所有键绑定信息

C-a w 显示所有窗口列表

C-a C-a 切换到之前显示的窗口

C-a c 创建一个新的运行shell的窗口并切换到该窗口

C-a n 切换到下一个窗口

C-a p 切换到前一个窗口(与C-a n相对)

C-a 0..9 切换到窗口0..9

C-a a 发送 C-a到当前窗口

C-a d 暂时断开screen会话

C-a k 杀掉当前窗口

C-a [ 进入拷贝/回滚

………………………………………………

-c file 使用配置文件file,而不使用默认的$HOME/.screenrc

-d|-D [pid.tty.host] 不开启新的screen会话,而是断开其他正在运行的screen会话

-h num 指定历史回滚缓冲区大小为num行

-list|-ls 列出现有screen会话,格式为pid.tty.host

-d -m 启动一个开始就处于断开模式的会话

-r sessionowner/ [pid.tty.host] 重新连接一个断开的会话。多用户模式下连接到其他用户screen会话需要指定sessionowner,需要setuid-root权限

-S sessionname 创建screen会话时为会话指定一个名字

-v 显示screen版本信息

-wipe [match] 同-list,但删掉那些无法连接的会话

ngnix相关

今天设置vsftpd和ngnix新建虚拟主机的时候出了很多错,究其本源,还是ngnix掌握不熟练,所以找些资料,时而复习之。

1.NGINX启动:首先找到NGINX执行文件。

 

-C参数代表制定的配置文件。不加的话,默认加载安装目录的conf目录的配置文件。

2.NGINX停止

我需要用KILL命令来做.

首先找到主进程号:

Ps -ef |grep ’nginx’

 

第一行:master process 表示主进程号。3176.为ID号

我们直接结束即可。

kill -QUIT 3176就OK了。

3.有时候我们修改配置文件。需要让它被使用。NGINX和APACHE有些不同。

NGINX有一个概念叫做平滑重启。其实就是发送信号给NGINX的主进程方式进行的。

再重启之前我们需要确认nginx配置文件是否正确。否则他不会加载新的配置文件。

 

如上图一样。配置文件没问题。

下面要做的是重启。Kill -HUP 主进程号 或者kill -HUP nginx.pid的路径

但是大家要注意。这里重启。主进程号是不变的,所以大家不要误会。没有重启成功.

4.NGINX有几个信号控制.:

QUIT 从容关闭

HUP 平滑重启,重新加载配置文件的

USER1 重新打开日志文件,主要用于日志文件的切割.

5.NGINX日志配置

NGINX 日志指令。有2个。一个是log-format(设置格式的),一个是access_log(存放路径等信息).

简单介绍下log_format.

语法:log-format name [format]

Name 表示格式的名称。Format表示格式的样式或者说有哪些内容。

wwwlogs是定义格式的名字.

$remote_addr 客户端名称

$remote_user 客户端账号。不过基本没啥用

[$time_local] 访问时间

$request请求的URL以及HTTP

$status 用于请求的状态:404,200之类的东西

$body_bytes_set 传输内容大小

$http_referer  从哪个页面访问过来的

$http_user_agent  浏览器信息

$http_x_forwarded-for 主要是记录客户端IP(当nginx作为负载均衡时候,反代理之后。我们获取的IP可能不正确。所以用这个获取真实的IP。)

$quest_time表示回应的时间,可以称作响应时间。(一般用于对程序分析效率)

 

Access_log

 

主要是存储目录。

 

 

 

6.NGINX日志切割

NGINX不知此像APACHE那样的cronlog

我们只能自己写脚本来控制。用crontab 来跑程序。

首先用mv 剪切

Mv /los/access.log  /totallog/20110101.log

Kill -user1 NGINX主进程号(会重新监理日志文件)

下面我写一个SHELL:

然后设置下crontab 来跑这个脚本就ok了.