OK,现在在前面的基础上进一步修改。
因为现在又有一个问题了,我们把WM_CLOSE消息的响应改成最小化之后,没有其他的键来关闭程序了,我们的程序要退出,只能结束进程了 怎么办?
不要忘了这个程序的目的,是要我们为File->Exit这个菜单项加功能,让它能够关闭程序。
光盘中附带源文件pediy.c已经告诉我们怎么改了,那部分被注释掉了:
// case IDM_APP_EXIT:
// SendMessage (hwnd, WM_CLOSE, 0, 0) ;
// return 0 ;
原来的意思是,只需要再向窗口发送WM_CLOSE消息就足够了。
慢着,现在不行了!因为这样做的话,就会再进入一次窗口过程,而这次因为我们已经把WM_CLOSE消息给挡住了,变成了最小化,所以还是不能关闭。
于是,我们只能换一种方式:
直接把接收的消息改为WM_CLOSE消息之后,再自己调用DefWindowsProc处理。
OK,接下来patch。
首先找到case WM_COMMAND的代码,为其添加分支:
00401161 |. 817D FC 11010>
cmp dword ptr [
ebp-4], 111
; 是否WM_COMMAND
00401168 |. 0F84 83000000
je 004011F1
……
004011F1 |> \8B55 10
mov edx,
dword ptr [
ebp+10]
004011F4 |. 81E2 FFFF0000
and edx, 0FFFF
004011FA |. 8955 F8
mov dword ptr [
ebp-8],
edx
004011FD |. 817D F8 539C0>
cmp dword ptr [
ebp-8], 9C53
; About的菜单项的ID
00401204 |. 74 02
je short 00401208
00401206 |. EB 1A
jmp short 00401222
; 其他的跳走
……
00401222 |> \EB 0C
jmp short 00401230
; 跳去调用DefWindowProc
可以看到,在00401222这一句,又跳去调用DefWindowProc了,我们可以从这里修改,跳到我们自己的代码里。
与上次一样,在上次patch的代码后面,0040125F处开始写自己添加的代码,于是把00401222处代码改为:
00401222 |> \EB 3B
jmp short 0040125F
; 跳到自己添加的代码
在写代码之前,我们要知道Exit菜单项的ID,用eXeScope查pediy_1.exe的资源,就可以知道Exit菜单项的ID是40005(十六进制9C45)。
于是,我们接着原代码的流程来,添加的代码:
0040125F |> \817D F8 459C0>
cmp dword ptr [
ebp-8], 9C45
; 是否是Exit菜单项的ID
00401266 |.^ 75 C8
jnz short 00401230
; 不是则又交回DefWindowProc
00401268 |. C745 0C 10000>
mov dword ptr [
ebp+C], 10
; 改MSG参数为WM_CLOSE
0040126F |. C745 10 00000>
mov dword ptr [
ebp+10], 0
; 改wparam为0
00401276 |. C745 14 00000>
mov dword ptr [
ebp+14], 0
; 改lparam为0
0040127D \.^ EB B1
jmp short 00401230
; 跳回去让DefWindowProc处理
判断ID是否是Exit菜单项的,不是则交回DefWindowProc
是则自己修改MSG为WM_CLOSE,然后自己返回去调用DefWindowProc
可以看到,由于这样并没有用SendMessage,所以WM_CLOSE消息不会再走一次窗口过程,而是在这次就被处理了,所以不会被我们之前所添加的代码给拦住。
修改后的文件(见附件),除了点关闭按钮会最小化之后,点击Exit菜单项,就会正常关闭了。