|
Персональные инструменты |
|||
|
Frontpage:Как установить макросом положение курсора — различия между версиямиМатериал из CustisWiki
Текущая версия на 12:55, 4 августа 2008Задача и решениеПри написании различных расширений, вспомогательных макросов для Frontpage, часто возникает задача установить (из макроса), положение (строку и столбец) курсора в окне редактирования. Например, если вызывать различные внешние валидаторы, то при ошибке, нужно точно позиционировать пользователя на ее предполагаемое место. К сожалению, открытое API не позволяет этого сделать. Однако есть несколько обходной, хакерский путь. Суть его состоит в том, чтобы «найти» правильный идентификатор самого глубокого вложенного окна редактирования Frontpage (эвристическая процедура GetFrontpage2002Hwnd, как следует из ее названия работает с «Frontpage 2002» и для других версий, возможно потребует адаптации), и, посылая ему клавиатурные сообщения, отпозиционироваться сначала в начало первой строки, а затем, «клавишами» вниз и вправо, переползти на нужную колонку нужной строки. КодOption Explicit '**************************************************************** 'some Windows API -based hacks and heuristics for Frontpage 2002 '---------------------------------------------------------------- '(c) 2003 Stas Fomin '**************************************************************** 'Not all declared API functions are used here... Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long Private Declare Function PostThreadMessage Lib "user32.dll" Alias "PostThreadMessageA" (ByVal idThread As Long, ByVal msg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wp As Long, ByVal lp As Long) As Long Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wp As Long, ByVal lp As Long) As Long Private Declare Function PostThreadMessageA Lib "user32.dll" (ByVal idThread As Long, ByVal msg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function PostThreadMessageW Lib "user32.dll" (ByVal idThread As Long, ByVal msg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'to get hwnd handle from callback functions Public g_hwnd As Long 'Keys and messages Const WM_SETFOCUS As Long = &H7 Const WM_KEYDOWN As Long = &H100 Const WM_KEYUP As Long = &H101 Const VK_CONTROL As Long = &H11 Const VK_HOME As Long = &H24 Const VK_RIGHT As Long = &H27 Const VK_DOWN As Long = &H28 Const WS_VISIBLE = &H10000000 Const GWL_STYLE = (-16) 'Heuristic for determine Frontpage 2002 Hwnd handle 'It did not tested for others versions of FP, ' but I think can be easy adapted for them. Public Function GetFrontpage2002Hwnd() As Long Dim hwnd As Long Dim ls_caption As String GetFrontpage2002Hwnd = 0 ls_caption = Application.ActiveWebWindow.Caption hwnd = FindWindow("FrontPageExplorerWindow40", ls_caption) If hwnd = 0 Then Exit Function hwnd = FindWindowEx(hwnd, 0, "AfxMDIFrame42", "") If hwnd = 0 Then Exit Function hwnd = FindWindowEx(hwnd, 0, "AfxWnd42", "") If hwnd = 0 Then Exit Function hwnd = FindWindowEx(hwnd, 0, "AfxMDIFrame42", "") If hwnd = 0 Then Exit Function hwnd = FindWindowEx(hwnd, 0, "AfxFrameOrView42", "") If hwnd = 0 Then Exit Function hwnd = FindWindowEx(hwnd, 0, "AfxFrameOrView42", "") If hwnd = 0 Then Exit Function 'hATLWnd = FindWindowEx(hWnd, 0, "ATL:33957BC0", "") Call EnumChildWindows(hwnd, AddressOf FindVisibleWindow, &H0) hwnd = g_hwnd If hwnd = 0 Then Exit Function hwnd = FindWindowEx(hwnd, 0, "FrontPageEditorDocumentFrame", "") If hwnd = 0 Then Exit Function Dim hWndChild As Long hWndChild = FindWindowEx(hwnd, 0, "AfxFrameOrView42", "") If hWndChild = 0 Then Exit Function While (hWndChild <> 0) And ((GetWindowLong(hWndChild, GWL_STYLE) And WS_VISIBLE) <> WS_VISIBLE) hWndChild = FindWindowEx(hwnd, hWndChild, "AfxFrameOrView42", "") Wend hwnd = hWndChild If hwnd = 0 Then Exit Function hwnd = FindWindowEx(hwnd, 0, "RichEdit20W", "") If hwnd = 0 Then Exit Function GetFrontpage2002Hwnd = hwnd End Function 'Heuristic for setting line and column in HTML-view ' of FP. (HTML-view must be active). Public Sub SetFrontpageLineAndCol(li_line As Long, li_col As Long) If li_line < 0 Then Exit Sub If li_col < 0 Then li_col = 0 Dim hwnd As Long hwnd = GetFrontpage2002Hwnd() If hwnd = 0 Then Exit Sub Dim l_lparam As Long Dim l_wparam As Long Dim l_res As Long l_lparam = &H24 l_wparam = &H1470001 l_res = PostMessage(hwnd, WM_KEYDOWN, l_lparam, l_wparam) 'Sending a burst of PageUp's for parking in line 1, col 1 'I failed to use Ctrl-Home for this purpose l_lparam = &H21 l_wparam = &H1490001 Dim i As Long For i = 1 To 10 l_res = PostMessage(hwnd, WM_KEYDOWN, l_lparam, l_wparam) Next 'Sending some DOWN_ARROW for positioning the line If li_line > 1 Then l_lparam = &H28 l_wparam = &H1500001 For i = 1 To li_line - 1 l_res = PostMessage(hwnd, WM_KEYDOWN, l_lparam, l_wparam) Next End If 'Sending some RIGHT_ARROW for positioning the column If li_col > 1 Then l_lparam = &H27 l_wparam = &H14D0001 For i = 1 To li_col - 1 l_res = PostMessage(hwnd, WM_KEYDOWN, l_lparam, l_wparam) Next End If End Sub 'Callback function, for selecting first child visible window Private Function FindVisibleWindow(ByVal hwnd As Long, ByVal lParam As Long) As Long FindVisibleWindow = 1 g_hwnd = 0 If IsWindowVisible(hwnd) Then g_hwnd = hwnd FindVisibleWindow = 0 End If End Function
Любые правки этой статьи будут перезаписаны при следующем сеансе репликации. Если у вас есть серьезное замечание по тексту статьи, запишите его в раздел «discussion». Репликация: База Знаний «Заказных Информ Систем» → «Frontpage:Как установить макросом положение курсора» |
||||||