找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 9682|回复: 12

如何用子类化实现单击窗体最大化按钮来实现最小化窗体?

[复制链接]

24

主题

37

回帖

3

精华

钻石会员

积分
4243
发表于 2005-11-8 10:41:41 | 显示全部楼层 |阅读模式
以下代码是想实现单击窗体最大化按钮来实现最小化窗体的,但是运行只能截获最大化窗体的消息,但却不能实现最小化窗体。不知问题出来在哪里,请大家帮忙解决,谢谢!
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
    '应用程序可在此截获所需的Windows消息加以处理
    '在立即窗口显示截获的Windows消息
    Debug.Print "hWnd=" & hwnd, "Msg=" & uMsg, "wP=" & wParam, "lP=" & lParam
    If uMsg = WM_NCLBUTTONDOWN And wParam = HTMAXBUTTON Then    '如果用户在非客户区左键单击了窗体系统菜单的“最大化”按钮
        MsgBox "收到最大化窗体消息!"
        SendMessage hwnd, WM_NCLBUTTONDOWN, HTMINBUTTON, 0&     '发送最小化窗体的消息
        Exit Function
    End If
    '调用原窗口函数,由原窗口函数处理Windows消息
    WindowProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam, lParam)
End Function
jlzGaSN7.rar (6.2 KB, 下载次数: 19553)
[此贴子已经被作者于2005-11-8 10:50:24编辑过]

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-11-10 15:32:29 | 显示全部楼层
我没有VB环境,没办法帮你调试..............不过你的代码流程有些不对.

你想想,SendMessage发的消息,也需要先通过你的子类化过程的.根本就不需要这样子再转个圈嘛~~

你已经在这个消息过程的顶点里了,直接把原消息换成最小化的不就行了~~

另外,不知道你有没有注意,窗体默认的处理过程是对鼠标抬起作反应的,而不是鼠标按下......

我改后的代码是这样的,没地方测试,也不知道常量,抱歉了~~自己试一下吧.....

'我们自己的窗口函数
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
    '应用程序可在此截获所需的Windows消息加以处理
    '在立即窗口显示截获的Windows消息
    Debug.Print "hWnd=" & hwnd, "Msg=" & uMsg, "wP=" & wParam, "lP=" & lParam
    If uMsg = WM_NCLBUTTONUP And wParam = HTMAXBUTTON Then    '如果用户在非客户区左键单击了窗体系统菜单的“最大化”按钮
        'MsgBox "收到最大化窗体消息!"
        wParam = HTMINBUTTON     '直接对原消息进行更改.看,定义那里是ByVal的,不会有问题
        'Exit Function        '这里就不需要退出了,要不消息就到不了默认处理过程里
    End If
    '调用原窗口函数,由原窗口函数处理Windows消息
    WindowProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam, lParam)
End Function
我就是嗷嗷叫的老马了......

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-11-10 15:38:58 | 显示全部楼层
另外,在消息处理这一类代码中,最好不要有MSGBOX一类的独占式语句,对程序的稳定性有影响...
我就是嗷嗷叫的老马了......

24

主题

37

回帖

3

精华

钻石会员

积分
4243
 楼主| 发表于 2005-11-10 16:55:35 | 显示全部楼层
谢谢马兄!用了您的代码,按下窗体的最大化按钮后,只见到最小化按钮的颜色加深了,呈现向下按了下去的动作,但窗体并没有最小化。请马兄继续帮忙解决,谢谢!
mUUVPQO4.rar (6.14 KB, 下载次数: 19845)

如何用子类化实现单击窗体最大化按钮来实现最小化窗体?

如何用子类化实现单击窗体最大化按钮来实现最小化窗体?

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-11-10 19:26:06 | 显示全部楼层
唉,我要是有VS6的开发平台,怎么会这么惨。。。。。。。。。。。。。。。。。。。。。。。
我就是嗷嗷叫的老马了......

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-11-11 00:46:01 | 显示全部楼层
其实这个问题的解决方法的最根本的方式就是我发的那个代码,替换消息.

但是我现在没有SPY++,没办法分析最小化的消息,所以就没办法在那个过程里把原最大化的消息替换为最小化的消息.

不过还是有其他办法的(仅是针对此例"点最大化时窗体最小化"),就是在拦截到最大化被点后,发消息让窗体最小化(也就是你的那个办法,只是用了一个专用API来实现).

代码改成这样,一定能行的:

Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
    '应用程序可在此截获所需的Windows消息加以处理
    '在立即窗口显示截获的Windows消息
    Debug.Print "hWnd=" & hwnd, "Msg=" & uMsg, "wP=" & wParam, "lP=" & lParam
    If uMsg = WM_NCLBUTTONUP And wParam = HTMAXBUTTON Then    '如果用户在非客户区左键单击了窗体系统菜单的“最大化”按钮
        'MsgBox "收到最大化窗体消息!"
        CloseWindow hwnd     '直接用这个API来实现最小化窗体
        Exit Function        '这里就要退出了
    End If
    '调用原窗口函数,由原窗口函数处理Windows消息
    WindowProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam, lParam)
End Function
我就是嗷嗷叫的老马了......

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-11-11 00:46:30 | 显示全部楼层
API的声明为:

Public Declare Function CloseWindow Lib "user32" (ByVal hwnd As Long) As Long
我就是嗷嗷叫的老马了......

24

主题

37

回帖

3

精华

钻石会员

积分
4243
 楼主| 发表于 2005-11-11 11:10:38 | 显示全部楼层
谢谢马兄! 非常关注如何成功地替换消息。如果不是处于子类化状态,这些消息是可以达到要求,不知道为什么当处于子类化状态,这些消息就失灵了?[em06][em06]
If uMsg = WM_NCLBUTTONUP And wParam = HTMAXBUTTON Then    '如果用户在非客户区左键单击了窗体系统菜单的“最大化”按钮
这句代码并不能实现要求,而是要将 WM_NCLBUTTONUP 改成WM_NCLBUTTONDOWN 才行。

另外,对于子类化的应用,最关键的是了解 windows 的消息机制,而且还要了解某一消息的两个附加消息 wParam 、 lParam 。就 WM_NCLBUTTONDOWN 这个消息而言,其 wParam 的值不同,所发送的消息也是不同的(如下所示),这些消息我是通过  Debug.Print "hWnd=" & hwnd, "Msg=" & uMsg, "wP=" & wParam, "lP=" & lParam 来获得的,上网也很难找到很具体附加消息(wParam 、 lParam)的意思。
If uMsg = WM_NCLBUTTONDOWN And wParam = 20 Then    '如果用户在非客户区左键单击了窗体系统菜单的“关闭”按钮
If uMsg = WM_NCLBUTTONDOWN And wParam = HTMINBUTTON Then    '如果用户在非客户区左键单击了窗体系统菜单的“最小化”按钮
If uMsg = WM_NCLBUTTONDOWN And wParam = HTMAXBUTTON Then    '如果用户在非客户区左键单击了窗体系统菜单的“最大化”按钮
If uMsg = WM_NCLBUTTONDOWN And wParam = HTCAPTION Then    '如果用户在非客户区左键单击了标题栏

马兄正在编写中的子类化应用的专题文章中,请您能着重剖析一些常用的消息及其两个附加消息的意思。我只找到了windows 消息大全,找不到 附加消息(wParam 、 lParam)的意思。
[此贴子已经被作者于2005-11-11 11:19:12编辑过]

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-11-11 15:57:41 | 显示全部楼层
这些消息的说明其实都在MSDN里,只是我E文太差了。。。。。。[em04]

我写这个文章会把WINDOWS消息机制以VB的角度来解释一下,当然,那是我的理解,也许会有N多错误..
我就是嗷嗷叫的老马了......

24

主题

37

回帖

3

精华

钻石会员

积分
4243
 楼主| 发表于 2005-11-11 17:41:38 | 显示全部楼层
谢谢马兄!想请教一下:您说“这些消息的说明其实都在MSDN里”,具体怎样在MSDN中查找这些消息的说明啊?是不是在API浏览器中查阅啊?为什么我在API浏览器中只查找到这些消息的常数值,却找不到其消息是什么意思的,而且也找不到其两个附加消息是什么。马兄能否将操作过程录制下来,请我知道如何操作,谢谢!

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-11-11 23:12:34 | 显示全部楼层
我手头没有MSDN啊.....现在连固定的电脑都没有..

我目前是在网吧帮人装系统,收了别人五百块钱.

过几天就回四川了,到时时间就会多起来.

MSDN是一个开发文档,如果你没有装,可以去在线MSDN里查一下.以下是网址:

MSDN中文站
我就是嗷嗷叫的老马了......

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-12-5 13:55:57 | 显示全部楼层
这个办法没错,但是楼主要的方法并不是这样,他想从消息入手,在消息里进行改造.

我近段时间还在为工作奔波,没时间来做,抱歉了~~
我就是嗷嗷叫的老马了......

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2005-12-18 15:57:32 | 显示全部楼层
在某控件的消息到达其默认处理过程前,插入一个用户自定义的过程,并对其中的部分消息进行处理,这个操作就叫"子类化"吧

我也不是非常清楚,建议楼上朋友去搜搜.
我就是嗷嗷叫的老马了......

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表