winforms 如何检测MDI子对象上的鼠标单击?

brjng4g3  于 2022-11-16  发布在  其他
关注(0)|答案(2)|浏览(147)

我使用下面的代码启动记事本并将其移动到窗体上的panel 1中。(在项目外运行)位于窗体的前面,我可以单击窗体的标题栏将其移到前台。但是,当我单击记事本所移动到的MDI子区域时,没有任何React。是否有方法检测对MDI子区域的单击,这样我就可以把焦点也转移到我的表单上了?2提前感谢你的帮助!
此致,Eric

Public Class Form1
    Private Const WM_SYSCOMMAND As Integer = 274
    Private Const SC_MAXIMIZE As Integer = 61488
    Declare Auto Function SetParent Lib "user32.dll" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As Integer
    Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim proc As Process
        proc = Process.Start("notepad.exe")
        proc.WaitForInputIdle()
        SetParent(proc.MainWindowHandle, Me.Panel1.Handle)
        SendMessage(proc.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0)
    End Sub
End Class
xesrikrc

xesrikrc1#

基于相容性的考量,SetParent不会修改父视窗正在变更之视窗的WS_CHILD或WS_POPUP视窗样式。因此,如果hWndNewParent是NULL,您也应该清除WS_CHILD比特,并在呼叫SetParent之后设定WS_POPUP样式。相反地,如果hWndNewParent不是NULL,而且视窗先前是桌面的子视窗,您应该在调用SetParent之前清除WS_POPUP样式并设置WS_CHILD样式。
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setparent
您可以使用https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowlongptrw来变更样式。通常您会隐藏视窗,变更样式,然后取消隐藏视窗。
下面是一些示例代码
https://winsourcecode.blogspot.com/2021/04/this-uses-inbuilt-compilers-in-windows.html

Public Declare Function SetWindowLongPtrW Lib "user32" (ByVal hwnd As IntPtr, ByVal Index As Integer, ByVal NewValue As Integer) As Integer
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As IntPtr, ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer

Public Const GWL_EXSTYLE = -20
Public Const GWL_STYLE = -16

Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1
Public Const SWP_SHOWWINDOW = &H40
Public Const SWP_HIDEWINDOW = &H80
Public Const SWP_NOOWNERZORDER = &H200      '  Don't do owner Z ordering
Public Const SWP_NOREDRAW = &H8
Public Const SWP_NOREPOSITION = &H200
Public Const SWP_NOZORDER = &H4


            Ret = SetWindowLongPtrW(hWindows, GWL_EXSTYLE, ExStyle)
            If (Ret = 0 And err.LastDLLError <> 0) Then MsgBox("SetWindowLongPtrW is " & Err.LastDllError)
            err.clear
            Ret = SetWindowPos(hwindows, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_NOZORDER + SWP_SHOWWINDOW)
o0lyfsai

o0lyfsai2#

following post
问题在于,宿主(重定父级)窗口在激活时,不会导致宿主窗体也激活,因此它被带到前台。宿主窗口并不完全是子窗口,宿主窗体不会从它那里接收任何消息。
按照this post中指定的说明解决此问题。

相关问题