Re: Creating new appointment & setting its properties



Cool. Does it work universally (WordMail or Outlook editor, formats (plain text, HTML, RTF)?

The window and process subclassing I've seen with WordMail is horrendous, it's miles of code just to get a true hWnd for a WordMail window usually.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Absolute Beginner's Guide to Microsoft Office Outlook 2003
Reminder Manager, Extended Reminders, Attachment Options
http://www.slovaktech.com/products.htm


"Josh Einstein" <josheinstein@xxxxxxxxxxx> wrote in message news:e3tUml1JGHA.1832@xxxxxxxxxxxxxxxxxxxxxxx
Hey Ken I responded to someone before about the cursor position but I never tried it myself. What's wrong with sending the EM_SETSEL message to the RichEdit control? Should be fairly straightforward.

(One hour later...) Okay please excuse my horredous VBA/Win32. It's been so long since I've done this. The code below will set the cursor position of the body control or text box of any standard Outlook item. This started out as a 10 minute thing but then I realized that guy wanted to set the position in the subject so I had to change some things around.

-------------------------------------------
Option Explicit

Private Declare Function SendMessage Lib "User32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetForegroundWindow Lib "User32.dll" () As Long
Private Declare Function FindWindowEx Lib "User32.dll" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Private Declare Function EnumChildWindows Lib "User32.dll" (ByVal hwndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
Private Declare Function GetClassName Lib "User32.dll" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function SetFocusAPI Lib "User32.dll" Alias "SetFocus" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowTextAPI Lib "User32.dll" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "User32.dll" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long


Private Const CLASS_SUBJECT = "RichEdit20WPT"
Private Const CLASS_BODY = "RichEdit20W"
Private Const CLASS_WINDOW = "rctrl_renwnd32"

Private Const DEFAULT_SUBJECT = "To whom it may concern"
Private Const DEFAULT_BODY = "When in the course of human events..."

Private Const EM_SETSEL = &HB1

Private Const FINDMODE_BYCLASS = 0
Private Const FINDMODE_BYTEXT = 1

Private hwndRichEdit As Long

' Used internally
Private expectedText As String
Private currentFindMode As Long

''' <summary>
''' Demo entry method
''' </summary>
Public Sub CreateTestItem()

   Dim app As AppointmentItem
   Set app = Application.CreateItem(olAppointmentItem)

   app.Subject = DEFAULT_SUBJECT
   app.Body = DEFAULT_BODY

   app.Display

   DoEvents

   'SetBodyCursorPos 5
   SetTextBoxCursorPos DEFAULT_SUBJECT, 5

End Sub

''' <summary>
''' Sets the cursor position in a given text box by finding the text box that has the specied
''' text and sets the focus to it.
''' </summary>
Public Sub SetTextBoxCursorPos(ByVal subjectText As String, ByVal pos As Long)
SetPositionInternal subjectText, FINDMODE_BYTEXT, pos
End Sub


''' <summary>
''' Sets the cursor position in the body by finding the body (no text is needed because only one
''' body control is on the form) and sets focus to it.
''' </summary>
Public Sub SetBodyCursorPos(ByVal pos As Long)
SetPositionInternal "", FINDMODE_BYCLASS, pos
End Sub



''' <summary>
''' Sets the cursor position of a text box or the body field. Called internally by the two
''' public methods SetBodyCursorPos and SetTextBoxCursorPos.
'' </summary>
Private Sub SetPositionInternal(ByVal text As String, ByVal findMode As Long, ByVal pos As Long)


' Get the foreground window which should be appointmentitem
Dim hwnd As Long
hwnd = GetForegroundWindow()

' Make sure it's the appointment window
Dim hwnd2 As Long
hwnd2 = FindWindowEx(0, 0, CLASS_WINDOW, vbNullString)

If hwnd = hwnd2 Then

' Store the text that they're searching for in a private variable
expectedText = text
' Likewise store the find mode. Would have passed this to enumchildwindows
' but since i'm storing expectedText, I'll do this too. I hate VB
currentFindMode = findMode


   ' Find the rich edit box on the page
   EnumChildWindows hwnd, AddressOf EnumWindowProc, 0

   If hwndRichEdit <> 0 Then
       SetFocusAPI hwndRichEdit
       SendMessage hwndRichEdit, EM_SETSEL, pos, pos
   End If

End If

End Sub

''' <summary>
''' Callback function invoked by Windows for every child window enumerated.
''' </summary>
Private Function EnumWindowProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean


   Dim returnValue As Boolean
   returnValue = True

   Dim className As String
   Dim length As Long

   className = Space(100)
   length = GetClassName(hwnd, className, Len(className) - 1)
   If length > 0 Then

' FINDMODE_BYTEXT means they are looking for a single-line textbox that
' has the specified text. Because there are multiple single-line text box class
' instances on the form, we need the expected text to match it to get the right hwnd
If currentFindMode = FINDMODE_BYTEXT Then
If Left(className, length) = CLASS_SUBJECT And GetWindowText(hwnd) = DEFAULT_SUBJECT Then
hwndRichEdit = hwnd
returnValue = False
End If
' FINDMODE_BYCLASS means they are looking for the body control. Since there's
' only one instance of that class on the form we don't care about the text
ElseIf currentFindMode = FINDMODE_BYCLASS Then
If Left(className, length) = CLASS_BODY Then
hwndRichEdit = hwnd
returnValue = False
End If
End If


   End If

   EnumWindowProc = returnValue

End Function

''' <summary>
''' Helper function to get the window text of the HWND in one call.
''' </summary>
Private Function GetWindowText(ByVal hwnd As Long) As String

   Dim buff As String
   buff = Space(GetWindowTextLength(hwnd) + 1)

   GetWindowTextAPI hwnd, buff, Len(buff)
   GetWindowText = Left(buff, Len(buff) - 1)

End Function


-- Josh Einstein Einstein Technologies Microsoft Tablet PC MVP Tablet Enhancements for Outlook 2.0 - Try it free for 14 days www.tabletoutlook.com

.



Relevant Pages

  • Re: Are VBA userforms always child of Windows desktop?
    ... Private Declare Function GetDesktopWindow Lib "user32" As Long ... Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long ... The system restores the window to its original state. ... Dim hWndDesktop As Long ...
    (microsoft.public.excel.programming)
  • Re: Are VBA userforms always child of Windows desktop?
    ... I only need this Hwnd of the parent, ... GetAncestor API (with GA_PARENT) to get Parent. ... I suppose which window you need will depend on the overall objective. ... Private Declare Function GetDesktopWindow Lib "user32" As Long ...
    (microsoft.public.excel.programming)
  • Re: Creating new appointment & setting its properties
    ... That will only work for standard Outlook forms but it should work among all ... > it's miles of code just to get a true hWnd for a WordMail window usually. ... >> Private Declare Function GetForegroundWindow Lib "User32.dll" As Long ... >> ByVal lpszClass As String, ByVal lpszWindow As String) As Long ...
    (microsoft.public.outlook.program_vba)
  • Re: Name Box
    ... (ByVal hwnd As Long, _ ... Private Declare Function GetDesktopWindow Lib "user32" As Long ... ' Get the ID of the process that a window belongs to ...
    (microsoft.public.excel.worksheet.functions)
  • re: Get the list of applications which are running
    ... Private Declare Function GetDesktopWindow Lib "user32" ... Alias "GetWindowLongA" (ByVal hwnd As Long, ... As String, ByVal cch As Long) As Long ... ' - An integer array used to return the window handles ...
    (microsoft.public.excel.programming)

Quantcast