|
附随点击按钮定位的代码, 但个人觉得为这个功能带这么多代码不值得.
Public Function PositionFormRelativeToControl(frmName As String, ctl As Access.Control, Optional Position As Long = 0) As Boolean
Position:
' 0 = Underneath
' 1 = On Top
' 2 = Right side
' 3 = Left side
' 4 = Bottom Right Hand Corner
Dim m_hWndSection As Long
Dim frm As Access.Form
Dim hWndMDI As Long
Dim MDIborderX As Long
Dim MDIborderY As Long
Dim rc As RECT
Dim rcWin As RECT
Dim pt As POINTAPI
Dim lOffsetX As Long, lOffsetY As Long
Dim m_ScreenWidth As Long
Dim m_ScreenHeight As Long
Dim lStyle As Long
On Error Resume Next
DoCmd.OpenForm frmName
Set frm = Forms.Item(frmName)
If Not frm Is Nothing Then
m_hWndSection = fFindSectionhWnd(ctl)
GetScreenDPI
m_ScreenWidth = GetSystemMetrics(SM_CXSCREEN)
m_ScreenHeight = GetSystemMetrics(SM_CYSCREEN)
Select Case Position
Case 0
lOffsetX = ctl.Left / (TWIPSPERINCH / m_ScreenXdpi)
lOffsetY = (ctl.Top + ctl.Height) / (TWIPSPERINCH / m_ScreenYdpi)
Case 1
lOffsetX = ctl.Left / (TWIPSPERINCH / m_ScreenXdpi)
lOffsetY = (-frm.WindowHeight + ctl.Top) / (TWIPSPERINCH / m_ScreenYdpi)
Case 2
lOffsetX = (ctl.Left + ctl.Width) / (TWIPSPERINCH / m_ScreenXdpi)
lOffsetY = (ctl.Top) / (TWIPSPERINCH / m_ScreenYdpi)
Case 3
lOffsetX = (ctl.Left - frm.WindowWidth) / (TWIPSPERINCH / m_ScreenXdpi)
lOffsetY = (ctl.Top) / (TWIPSPERINCH / m_ScreenYdpi)
Case 4
lOffsetX = (ctl.Left + ctl.Width) / (TWIPSPERINCH / m_ScreenXdpi)
lOffsetY = (ctl.Top + ctl.Height) / (TWIPSPERINCH / m_ScreenYdpi)
Case Else
lOffsetX = ctl.Left / (TWIPSPERINCH / m_ScreenXdpi)
lOffsetY = (ctl.Top + ctl.Height) / (TWIPSPERINCH / m_ScreenYdpi)
End Select
lRet = GetWindowRect(m_hWndSection, rc)
pt.X = lOffsetX + rc.Left&
pt.Y = lOffsetY + rc.Top
lRet = GetWindowRect(frm.hwnd, rcWin)
With rcWin
If m_ScreenWidth - pt.X < .Right - .Left Then
pt.X = m_ScreenWidth - (.Right - .Left)
ElseIf pt.X < 2 Then 'm_S
pt.X = 2
End If
If m_ScreenHeight - pt.Y < .Bottom - .Top Then
pt.Y = m_ScreenHeight - (.Bottom - .Top)
ElseIf pt.Y < 2 Then
pt.Y = 2
End If
End With
If Not frm.PopUp = True Then
hWndMDI = FindWindowEx(Application.hWndAccessApp, 0&, "MDIClient", TITLE)
lRet = ScreenToClient(hWndMDI, pt)
lRet = GetWindowRect(hWndMDI, rcWin)
lRet = GetClientRect(hWndMDI, rc)
MDIborderX = ((rcWin.Right - rcWin.Left) - (rc.Right - rc.Left))
MDIborderY = ((rcWin.Bottom - rcWin.Top) - (rc.Bottom - rc.Top))
lStyle = GetWindowLong(hWndMDI, GWL_STYLE)
If lStyle And WS_HSCROLL Then
MDIborderY = MDIborderY - GetSystemMetrics(SM_CYHSCROLL)
End If
If lStyle And WS_VSCROLL Then
MDIborderX = MDIborderX - GetSystemMetrics(SM_CXVSCROLL)
End If
MDIborderX = MDIborderX / 2
MDIborderY = MDIborderY / 2
Else
MDIborderX = GetSystemMetrics(SM_CXBORDER)
MDIborderY = GetSystemMetrics(SM_CYBORDER)
End If
Call SetWindowPos(frm.hwnd, 0&, pt.X - MDIborderX, pt.Y - MDIborderY, 0, 0, SWP_NOSIZE)
End If
Set frm = Nothing
PositionFormRelativeToControl = True
End Function
Private Sub GetScreenDPI()
Dim lngDC As Long
lngDC = GetDC(0)
m_ScreenXdpi = apiGetDeviceCaps(lngDC, LOGPIXELSX)
m_ScreenYdpi = apiGetDeviceCaps(lngDC, LOGPIXELSY)
lngDC = ReleaseDC(0, lngDC)
End Sub
Private Function fFindSectionhWnd(ctl As Access.Control) As Long
On Error GoTo Err_fFindSectionhWnd
Dim hWnd_LSB As Long
Dim hWnd_Temp As Long
Dim rc As RECT
Dim pt As POINTAPI
Dim SectionCounter As Long
Dim ctr As Long
Select Case ctl.Section
Case acDetail '0
SectionCounter = 2
Case acHeader '1
SectionCounter = 1
Case acFooter '2
SectionCounter = 3
Case Else
End Select
ctr = 1
If TypeOf ctl.Parent Is Access.Page Then
If TypeOf ctl.Parent.Parent Is Access.TabControl Then
If TypeOf ctl.Parent.Parent.Parent Is Access.Form Then
hWnd_LSB = apiGetWindow(ctl.Parent.Parent.Parent.hwnd, GW_CHILD)
End If
End If
Else
hWnd_LSB = apiGetWindow(ctl.Parent.hwnd, GW_CHILD)
End If
Do
If fGetClassName(hWnd_LSB) = "OFormSub" Then
If ctr = SectionCounter Then
fFindSectionhWnd = hWnd_LSB
Exit Function
End If
ctr = ctr + 1
End If
hWnd_LSB = apiGetWindow(hWnd_LSB, GW_HWNDNEXT)
Loop While hWnd_LSB <> 0
fFindSectionhWnd = 0
Exit_fFindSectionhWnd:
Exit Function
Err_fFindSectionhWnd:
MsgBox Err.Description
Resume Exit_fFindSectionhWnd
End Function
Private Function fGetClassName(hwnd As Long)
Dim strBuffer As String
Dim lngLen As Long
Const MAX_LEN = 255
strBuffer = Space$(MAX_LEN)
lngLen = apiGetClassName(hwnd, strBuffer, MAX_LEN)
If lngLen > 0 Then fGetClassName = Left$(strBuffer, lngLen)
End Function |
|