【求助】WinAPI也无法将最小化的窗口还原??(前一帖错漏多,不好意思,重发)

kingiori2001 2010-11-27 04:01:04
不好意思,心急,发漏了一个条件,现在补充一下:

我想在我的程序中打开“计算器”,若计算器未打开就启动一个,若已经打开,就激活它并前端显示。
这个问题本来GOOGLE一下,大概答案不少,一般都是使用winAPI的“ShowWindow”、“SendMessage”等等,但是我还是遇到困难,问题是这样的:若计算器程序首先打开,然后鼠标点击让其最小化后,再运行下面程序,这样就无论如何达不到效果!!!
测试程序中一个按钮的执行代码:

'==============API声明开始==================


Public Const SW_HIDE = 0
Public Const SW_SHOWNORMAL = 1
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_MAXIMIZE = 3
Public Const SW_SHOWNOACTIVATE = 4
Public Const SW_SHOW = 5
Public Const SW_MINIMIZE = 6
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNA = 8
Public Const SW_RESTORE = 9
Private Const SW_SHOWDEFAULT = 10
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Const WM_SYSCOMMAND = &H112
Public Const SC_CLOSE = &HF060& '关闭窗体
Public Const SC_MINIMIZE = &HF020& '最小化窗体
Public Const SC_MAXIMIZE = &HF030& '最大化窗体
Public Const SC_RESTORE = &HF120& '恢复窗体大小
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

'==============API声明结束==================

Private Sub btTEST_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

Dim pro As Process() = Diagnostics.Process.GetProcessesByName("calc")

If pro.Length >= 1 Then
'方法0:SendMessage(结果明显看见任务栏中的计算器被选中了,可就是不显示到前端)
'SendMessage(FindWindow(vbNullString, "计算器"), WM_SYSCOMMAND, SC_MAXIMIZE, 0)
'SetForegroundWindow(FindWindow(vbNullString, pro(0).MainWindowTitle))

'方法1:SendMessage(结果明显看见任务栏中的计算器被选中了,可就是不显示到前端)
'SendMessage(FindWindow(vbNullString, pro(0).MainWindowTitle), WM_SYSCOMMAND, SC_MAXIMIZE, 0)
'SetForegroundWindow(FindWindow(vbNullString, pro(0).MainWindowTitle))

'方法2:ShowWindow(结果明显看见任务栏中的计算器被选中了,可就是不显示到前端)
ShowWindow(FindWindow(vbNullString, pro(0).MainWindowTitle), SW_RESTORE)
SetForegroundWindow(FindWindow(vbNullString, pro(0).MainWindowTitle))

'方法3:ShowWindow(不使用FindWindow,但是结果是计算器的窗口消失了,可是进程还在,好像隐藏的效果)
'ShowWindow(pro(0).MainWindowHandle.ToInt32, 9)
'SetForegroundWindow(FindWindow(vbNullString, pro(0).MainWindowTitle))

Me.WindowState = FormWindowState.Minimized '最小化自己
Else
Shell("C:\WINDOWS\system32\calc.exe", AppWinStyle.NormalFocus)
End If

End Sub
...全文
273 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanlongwuhui 2010-11-29
  • 打赏
  • 举报
回复
VB6跟VB.NET在对API函数进行声明时是要进行类型转换的。看来只能接分了
兔子-顾问 2010-11-27
  • 打赏
  • 举报
回复
仔细看,才知道你还要在最小化的时候处理,这样,稍微修改一点。

Module Module1
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
Public Declare Function SetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hwnd As Integer) As Integer
Public Const WM_SYSCOMMAND = &H112
Public Const SC_RESTORE = &HF120&
Sub Main()
Dim cur As Process = Process.GetCurrentProcess()
For Each p As Process In Process.GetProcesses
If p.Id = cur.Id Then Continue For
If p.ProcessName = cur.ProcessName Then
SetForegroundWindow(p.MainWindowHandle)
SendMessage(p.MainWindowHandle, WM_SYSCOMMAND, SC_RESTORE, IntPtr.Zero)
Return
End If
Next
Application.Run(New Form9)
End Sub
End Module
兔子-顾问 2010-11-27
  • 打赏
  • 举报
回复
没这么复杂。简单点
Module Module1
Public Declare Function SetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hwnd As Integer) As Integer
Sub Main()
Dim cur As Process = Process.GetCurrentProcess()
For Each p As Process In Process.GetProcesses
If p.Id = cur.Id Then Continue For
If p.ProcessName = cur.ProcessName Then
SetForegroundWindow(p.MainWindowHandle)
Return
End If
Next
Application.Run(New Form9)
End Sub
End Module
kingiori2001 2010-11-27
  • 打赏
  • 举报
回复
我自己终于找到答案了:

1、为什么VB.NET中process.MainWindowHandle.ToInt32和Win32API中FindWindow返回值不同?
2、为什么SendMessage、ShowWindow等API函数总是调用失败?
很多问题,曾经困扰我一天,原来TMD是数据类型问题,以下是VB6.0中的API定义:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

因为VB.net和VB6的数据类型LONG的定义已经不一样了,在VB.NET里long是64位,而窗口句柄仍然是32位, 所以得不到正确的返回值,只要将long改成integer就好了:
Declare Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer

唉,希望给各位兄弟提个醒,高手们可以无视,请宽恕我这个菜鸟!

16,553

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧