![]() |
If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. |
|
|
Thread Tools | Search this Thread | Display Modes |
|
#1
|
|||
|
|||
![]()
I have an Outlook COM Add-in written in VB6. It must run on Outlook
versions 2000-2003. It currently saves the clipboard data, uses the clipboard to add images to custom commandbar buttons and restores the clipboard so the users' information is preserved. This all works well _except_ when multiple documents (of the same type, say Word 2003) are copied from a mail message from within Outlook (the preview pane or an inspector). The user presses 'New'(Mail Message) in Outlook and my custom toolbar is added to the inspector (including usage of the clipboard). When the user pastes the attachments into this new email they _see_ all of the correct document filenames but the contents of all the files are the same as the first attachment (they should be unique). If these documents were copied from Windows Explorer they paste into the new email without issue. I have narrowed the issue down to a difference in available clipboard formats between a Copy from within Outlook and a Copy from Windows Explorer - the Outlook copy lacks the CF_HDROP data format but instead has the FileContents and FileGroupDescriptor types instead. Has anyone seen this before? I either need a better way to use the clipboard (so as to re-constitute the documents correctly) or avoid using the clipboard for New MailItems. I attempted to create my Inspector toolbar in the Outlook Explorer, on start-up, so I could copy it (without the need to use the clipboard) when an inspector was opened but I do not think this is possible). Sorry for so many words. Regards, Anthony The essence of the clipboard code. Private Type clipContents formatType As Long dataGlobal As Long clipSize As Long End Type Private m_clipContents() As clipContents Private m_clipCount As Integer Public Sub StoreEx() On Error GoTo err_Handler Dim p_clipGlobal As Long Dim p_clipData As Long Dim p_clipSize As Long Dim p_savedGlobal As Long Dim p_savedData As Long Dim p_tmpFormat As Long Erase m_clipContents m_clipCount = 0 '// Open the clipboard with the current process as the owner If OpenClipboard(0) = 0 Then Exit Sub End If p_tmpFormat = EnumClipboardFormats(0) Do Until p_tmpFormat = 0 '// Obtain a handle the the memory owned by the clipboard p_clipGlobal = GetClipboardData(p_tmpFormat) If p_clipGlobal 0 Then p_clipData = GlobalLock(p_clipGlobal) '// If we don't have a handle then we barf If p_clipData 0 Then '// Failure '// Identify the amount of memory we need to make a copy of the data p_clipSize = GlobalSize(p_clipGlobal) If p_clipSize 0 Then '// Allocate enough memory to copy into p_savedGlobal = GlobalAlloc(GMEM_MOVEABLE, p_clipSize) If p_savedGlobal 0 Then '// Retrieve a pointer to the first byte of the memory block we just allocated (This also protects this piece of memory being destroyed inadvertantly) p_savedData = GlobalLock(p_savedGlobal) If p_savedData 0 Then '// Copy the clipboard data into our memory CopyMemory ByVal p_savedData, ByVal p_clipData, p_clipSize Dim p_Iclip As clipContents With p_Iclip .formatType = p_tmpFormat .dataGlobal = p_savedGlobal .clipSize = p_clipSize End With ReDim Preserve m_clipContents(m_clipCount + 1) m_clipContents(m_clipCount) = p_Iclip m_clipCount = m_clipCount + 1 GlobalUnlock (p_savedGlobal) End If End If End If GlobalUnlock (p_clipGlobal) End If End If p_tmpFormat = EnumClipboardFormats(p_tmpFormat) Loop '// Release the clipboard CloseClipboard Exit Sub err_Handler: CloseClipboard CleanUp End Sub Public Sub RestoreEx() Dim p_cnt As Integer On Error GoTo err_Handler '// Open the clipboard with the current process as the owner If OpenClipboard(0) 0 Then If EmptyClipboard 0 Then For p_cnt = 0 To m_clipCount - 1 '// Place our piece of memory in the clipboard If SetClipboardData(m_clipContents(p_cnt).formatType, m_clipContents(p_cnt).dataGlobal) = 0 Then ' Err.Raise Err.LastDllError, "Clipboard", "SetClipboardData: " & _ DecodeAPIErrors(Err.LastDllError) '// Failure End If Next p_cnt End If End If CloseClipboard Exit Sub err_Handler: CloseClipboard CleanUp End Sub *** Sent via Developersdex http://www.developersdex.com *** |
#2
|
|||
|
|||
![]()
What I usually do when I use the clipboard for that is first I use the
clipboard from the Win32 API. I also make sure to clear the clipboard after saving the original contents and after my image work. I also create the button images on the clipboard using custom registered formats for Office buttons: "Toolbar Button Face" and "Toolbar Button Mask". I use GDI+ for copying the bitmaps onto the clipboard and then when finished I remove the custom formats I registered for the clipboard. I've found that prevents interference with other things. -- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007 Reminder Manager, Extended Reminders, Attachment Options http://www.slovaktech.com/products.htm "Anthony" wrote in message ... I have an Outlook COM Add-in written in VB6. It must run on Outlook versions 2000-2003. It currently saves the clipboard data, uses the clipboard to add images to custom commandbar buttons and restores the clipboard so the users' information is preserved. This all works well _except_ when multiple documents (of the same type, say Word 2003) are copied from a mail message from within Outlook (the preview pane or an inspector). The user presses 'New'(Mail Message) in Outlook and my custom toolbar is added to the inspector (including usage of the clipboard). When the user pastes the attachments into this new email they _see_ all of the correct document filenames but the contents of all the files are the same as the first attachment (they should be unique). If these documents were copied from Windows Explorer they paste into the new email without issue. I have narrowed the issue down to a difference in available clipboard formats between a Copy from within Outlook and a Copy from Windows Explorer - the Outlook copy lacks the CF_HDROP data format but instead has the FileContents and FileGroupDescriptor types instead. Has anyone seen this before? I either need a better way to use the clipboard (so as to re-constitute the documents correctly) or avoid using the clipboard for New MailItems. I attempted to create my Inspector toolbar in the Outlook Explorer, on start-up, so I could copy it (without the need to use the clipboard) when an inspector was opened but I do not think this is possible). Sorry for so many words. Regards, Anthony The essence of the clipboard code. Private Type clipContents formatType As Long dataGlobal As Long clipSize As Long End Type Private m_clipContents() As clipContents Private m_clipCount As Integer Public Sub StoreEx() On Error GoTo err_Handler Dim p_clipGlobal As Long Dim p_clipData As Long Dim p_clipSize As Long Dim p_savedGlobal As Long Dim p_savedData As Long Dim p_tmpFormat As Long Erase m_clipContents m_clipCount = 0 '// Open the clipboard with the current process as the owner If OpenClipboard(0) = 0 Then Exit Sub End If p_tmpFormat = EnumClipboardFormats(0) Do Until p_tmpFormat = 0 '// Obtain a handle the the memory owned by the clipboard p_clipGlobal = GetClipboardData(p_tmpFormat) If p_clipGlobal 0 Then p_clipData = GlobalLock(p_clipGlobal) '// If we don't have a handle then we barf If p_clipData 0 Then '// Failure '// Identify the amount of memory we need to make a copy of the data p_clipSize = GlobalSize(p_clipGlobal) If p_clipSize 0 Then '// Allocate enough memory to copy into p_savedGlobal = GlobalAlloc(GMEM_MOVEABLE, p_clipSize) If p_savedGlobal 0 Then '// Retrieve a pointer to the first byte of the memory block we just allocated (This also protects this piece of memory being destroyed inadvertantly) p_savedData = GlobalLock(p_savedGlobal) If p_savedData 0 Then '// Copy the clipboard data into our memory CopyMemory ByVal p_savedData, ByVal p_clipData, p_clipSize Dim p_Iclip As clipContents With p_Iclip .formatType = p_tmpFormat .dataGlobal = p_savedGlobal .clipSize = p_clipSize End With ReDim Preserve m_clipContents(m_clipCount + 1) m_clipContents(m_clipCount) = p_Iclip m_clipCount = m_clipCount + 1 GlobalUnlock (p_savedGlobal) End If End If End If GlobalUnlock (p_clipGlobal) End If End If p_tmpFormat = EnumClipboardFormats(p_tmpFormat) Loop '// Release the clipboard CloseClipboard Exit Sub err_Handler: CloseClipboard CleanUp End Sub Public Sub RestoreEx() Dim p_cnt As Integer On Error GoTo err_Handler '// Open the clipboard with the current process as the owner If OpenClipboard(0) 0 Then If EmptyClipboard 0 Then For p_cnt = 0 To m_clipCount - 1 '// Place our piece of memory in the clipboard If SetClipboardData(m_clipContents(p_cnt).formatType, m_clipContents(p_cnt).dataGlobal) = 0 Then ' Err.Raise Err.LastDllError, "Clipboard", "SetClipboardData: " & _ DecodeAPIErrors(Err.LastDllError) '// Failure End If Next p_cnt End If End If CloseClipboard Exit Sub err_Handler: CloseClipboard CleanUp End Sub *** Sent via Developersdex http://www.developersdex.com *** |
#3
|
|||
|
|||
![]()
Thankyou for taking the time to respond. Unfortunately, I think I have
all of your suggestions in place. I would be happy to generate an add-in which demonstrates the behaviour if you are willing to take this further, I realise it probably goes beyond the service offered here, but I can't see how this issue would not effect all (Outlook) add-ins _if_ I have the code correctly implemented. What I usually do when I use the clipboard for that is first I use the clipboard from the Win32 API. This is an example of one of the functions I use from the API TextViewer. "Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long" I also make sure to clear the clipboard after saving the original contents and after my image work. I am now doing this, I call EmptyClipboard just before CloseClipboard in my StoreEx procedure. It made no difference. I also create the button images on the clipboard using custom registered formats for Office buttons: "Toolbar Button Face" and "Toolbar Button Mask". I use GDI+ for copying the bitmaps onto the clipboard and then when finished I remove the custom formats I registered for the clipboard. We do this already. The code is based on the following Microsoft Knowledge Base article. http://support.microsoft.com/kb/288771 This KB code was researched and implemented by a colleague but I think this code removes the custom formats from the clipboard as you have suggested - maybe you could confirm?. ' Delete the mask and clean up (a copy is on the clipboard). DeleteObject hbmButtonMask If bDeletePal Then DeleteObject hPal ReleaseDC 0, hdcScreen At this point, I am happy for any suggestions you might care to offer. Regards, Anthony *** Sent via Developersdex http://www.developersdex.com *** |
#4
|
|||
|
|||
![]()
I don't know if this will help but these are some of the relevant procedures
I use: Public Sub CopyBitmapAsButtonFace(ByVal hBmpSrc As Long, ByVal clrMaskColor As OLE_COLOR) Dim hPal As Long Dim hDC As Long Dim hPrevBitmap As Long Dim hNewPalette As Long Dim hbmButtonImage As Long Dim hbmButtonFace As Long Dim hbmButtonMask As Long Dim bDeletePal As Boolean Dim lMaskClr As Long Dim LP As LOGPALETTE256 Dim nNumPalEntries As Long On Error GoTo EH If hBmpSrc Then Call GetCommandbarBackground hDC = CreateCompatibleDC(0&) If hPal = 0 Then hPal = CreateHalftonePalette(hDC) bDeletePal = True End If ' Translate the OLE_COLOR value to a GDI COLORREF value based on the palette. OleTranslateColor clrMaskColor, hPal, lMaskClr hbmButtonFace = CopyBitmap(hBmpSrc, cbmDIB) hbmButtonImage = CreateButtonImage(hBmpSrc, hDC, clrMaskColor) hbmButtonMask = CreateButtonMask(hBmpSrc, lMaskClr, hDC, hPal) Call CopyBitmapsToClipboard(hbmButtonImage, hbmButtonFace, hbmButtonMask, hDC) End If ' hBmpSrc ExitNow: DeleteObject hbmButtonMask DeleteObject hbmButtonImage DeleteObject hbmButtonFace If bDeletePal Then DeleteObject hPal Call DeleteDC(hDC) Exit Sub EH: Err.Clear Resume ExitNow End Sub Private Sub CopyBitmapsToClipboard(ByVal hbmImage As Long, ByVal hbmFace As Long, _ ByVal hbmMask As Long, ByVal hdcTarget As Long) Dim cfBtnFace As Long Dim cfBtnMask As Long Dim hGMemImage As Long Dim hGMemFace As Long Dim hGMemMask As Long Dim blnDefaultToolbarButtonFace As Boolean Dim blnDefaultToolbarButtonMask As Boolean On Error Resume Next ' Open the clipboard. If OpenClipboard(0) Then ' Get the cf for button face and mask. If strToolbarButtonFace = "" Then strToolbarButtonFace = "Toolbar Button Face" blnDefaultToolbarButtonFace = True End If If strToolbarButtonMask = "" Then strToolbarButtonMask = "Toolbar Button Mask" blnDefaultToolbarButtonMask = True End If ' Get the cf for button face and mask. 'cfBtnFace = RegisterClipboardFormat("Toolbar Button Face") 'cfBtnMask = RegisterClipboardFormat("Toolbar Button Mask") cfBtnFace = RegisterClipboardFormat(strToolbarButtonFace) cfBtnMask = RegisterClipboardFormat(strToolbarButtonMask) If blnDefaultToolbarButtonFace Then strToolbarButtonFace = "" End If If blnDefaultToolbarButtonMask Then strToolbarButtonMask = "" End If 'If hbmImage Then ' hGMemImage = DIBSectionToPackedDIB(hbmImage) ' ' If hGMemImage Then ' If SetClipboardData(vbCFDIB, hGMemImage) = 0 Then Call GlobalFree(hGMemImage) ' End If 'End If If hbmFace Then hGMemFace = DIBSectionToPackedDIB(hbmFace) If hGMemFace Then If SetClipboardData(cfBtnFace, hGMemFace) = 0 Then Call GlobalFree(hGMemFace) End If End If If hbmMask Then hGMemMask = DIBSectionToPackedDIB(hbmMask) If hGMemMask Then If SetClipboardData(cfBtnMask, hGMemMask) = 0 Then Call GlobalFree(hGMemMask) End If End If ' hbmMask ' We're done. CloseClipboard End If ' OpenClipboard(0) Err.Clear End Sub Private Function CreateButtonMask(ByVal hbmSource As Long, ByVal nMaskColor As Long, _ ByVal hdcTarget As Long, ByVal hPal As Long) As Long Dim hdcSource As Long Dim hdcMask As Long Dim hbmSourceOld As Long Dim hbmMaskOld As Long Dim hpalSourceOld As Long Dim uBM As bitmap Dim hbmMask As Long On Error Resume Next ' Get some information about the bitmap handed to us. GetObjectAPI hbmSource, 24, uBM ' Check the size of the bitmap given. If uBM.bmWidth 1 Or uBM.bmWidth 30000 Then Exit Function End If If uBM.bmHeight 1 Or uBM.bmHeight 30000 Then Exit Function End If ' Create a compatible DC, load the palette and the bitmap. hdcSource = CreateCompatibleDC(hdcTarget) hpalSourceOld = SelectPalette(hdcSource, hPal, True) RealizePalette hdcSource hbmSourceOld = SelectObject(hdcSource, hbmSource) ' Create a black and white mask the same size as the image. hbmMask = CreateBitmap(uBM.bmWidth, uBM.bmHeight, 1, 1, ByVal 0) ' Create a compatble DC for it and load it. hdcMask = CreateCompatibleDC(hdcTarget) hbmMaskOld = SelectObject(hdcMask, hbmMask) ' All you need to do is set the mask color as the background color ' on the source picture, and set the forground color to white, and ' then a simple BitBlt will make the mask for you. SetBkColor hdcSource, nMaskColor SetTextColor hdcSource, vbWhite BitBlt hdcMask, 0, 0, uBM.bmWidth, uBM.bmHeight, hdcSource, 0, 0, vbSrcCopy ' Clean up the memory DCs. SelectObject hdcMask, hbmMaskOld DeleteDC hdcMask SelectObject hdcSource, hbmSourceOld SelectObject hdcSource, hpalSourceOld DeleteDC hdcSource CreateButtonMask = hbmMask Err.Clear End Function ' ================================================== ================= ' CopyButtonMaskToClipboard -- Internal helper function ' ================================================== ================= Private Sub CopyButtonMaskToClipboard(ByVal hbmMask As Long, _ ByVal hdcTarget As Long) Dim cfBtnFace As Long Dim cfBtnMask As Long Dim hGMemFace As Long Dim hGMemMask As Long Dim lpData As Long Dim lpData2 As Long Dim hMemTmp As Long Dim cbSize As Long Dim arrBIHBuffer(50) As Byte Dim arrBMDataBuffer() As Byte Dim uBIH As BITMAPINFOHEADER Dim blnDefaultToolbarButtonFace As Boolean Dim blnDefaultToolbarButtonMask As Boolean On Error Resume Next uBIH.biSize = 40 ' Get the BITMAPHEADERINFO for the mask. GetDIBits hdcTarget, hbmMask, 0, 0, ByVal 0&, uBIH, 0 CopyMemory arrBIHBuffer(0), uBIH, 40 ' Make sure it is a mask image. If uBIH.biBitCount 1 Then Exit Sub End If If uBIH.biSizeImage 1 Then Exit Sub End If ' Create a temp buffer to hold the bitmap bits. ReDim Preserve arrBMDataBuffer(uBIH.biSizeImage + 4) As Byte ' Open the clipboard. If Not CBool(OpenClipboard(0)) Then Exit Sub End If If strToolbarButtonFace = "" Then strToolbarButtonFace = "Toolbar Button Face" blnDefaultToolbarButtonFace = True End If If strToolbarButtonMask = "" Then strToolbarButtonMask = "Toolbar Button Mask" blnDefaultToolbarButtonMask = True End If ' Get the cf for button face and mask. 'cfBtnFace = RegisterClipboardFormat("Toolbar Button Face") 'cfBtnMask = RegisterClipboardFormat("Toolbar Button Mask") cfBtnFace = RegisterClipboardFormat(strToolbarButtonFace) cfBtnMask = RegisterClipboardFormat(strToolbarButtonMask) If blnDefaultToolbarButtonFace Then strToolbarButtonFace = "" End If If blnDefaultToolbarButtonMask Then strToolbarButtonMask = "" End If ' Open DIB on the clipboard and make a copy of it for the button face. hMemTmp = GetClipboardData(CF_DIB) If hMemTmp 0 Then cbSize = GlobalSize(hMemTmp) hGMemFace = GlobalAlloc(&H2002, cbSize) If hGMemFace 0 Then lpData = GlobalLock(hMemTmp) lpData2 = GlobalLock(hGMemFace) CopyMemory ByVal lpData2, ByVal lpData, cbSize GlobalUnlock hGMemFace GlobalUnlock hMemTmp If SetClipboardData(cfBtnFace, hGMemFace) = 0 Then GlobalFree hGMemFace End If End If End If ' Now get the mask bits and the rest of the header. GetDIBits hdcTarget, hbmMask, 0, uBIH.biSizeImage, _ arrBMDataBuffer(0), arrBIHBuffer(0), 0 ' Copy them to global memory and set it on the clipboard. hGMemMask = GlobalAlloc(&H2002, uBIH.biSizeImage + 50) If hGMemMask 0 Then lpData = GlobalLock(hGMemMask) CopyMemory ByVal lpData, arrBIHBuffer(0), 48 CopyMemory ByVal (lpData + 48), _ arrBMDataBuffer(0), uBIH.biSizeImage GlobalUnlock hGMemMask If SetClipboardData(cfBtnMask, hGMemMask) = 0 Then GlobalFree hGMemMask End If End If ' We're done. CloseClipboard Err.Clear End Sub -- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007 Reminder Manager, Extended Reminders, Attachment Options http://www.slovaktech.com/products.htm "Anthony" wrote in message ... Thankyou for taking the time to respond. Unfortunately, I think I have all of your suggestions in place. I would be happy to generate an add-in which demonstrates the behaviour if you are willing to take this further, I realise it probably goes beyond the service offered here, but I can't see how this issue would not effect all (Outlook) add-ins _if_ I have the code correctly implemented. What I usually do when I use the clipboard for that is first I use the clipboard from the Win32 API. This is an example of one of the functions I use from the API TextViewer. "Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long" I also make sure to clear the clipboard after saving the original contents and after my image work. I am now doing this, I call EmptyClipboard just before CloseClipboard in my StoreEx procedure. It made no difference. I also create the button images on the clipboard using custom registered formats for Office buttons: "Toolbar Button Face" and "Toolbar Button Mask". I use GDI+ for copying the bitmaps onto the clipboard and then when finished I remove the custom formats I registered for the clipboard. We do this already. The code is based on the following Microsoft Knowledge Base article. http://support.microsoft.com/kb/288771 This KB code was researched and implemented by a colleague but I think this code removes the custom formats from the clipboard as you have suggested - maybe you could confirm?. ' Delete the mask and clean up (a copy is on the clipboard). DeleteObject hbmButtonMask If bDeletePal Then DeleteObject hPal ReleaseDC 0, hdcScreen At this point, I am happy for any suggestions you might care to offer. Regards, Anthony *** Sent via Developersdex http://www.developersdex.com *** |
#5
|
|||
|
|||
![]()
Hi Ken,
Sorry to labour this, my customers actually reported the issue so I would like to get to the bottom of it if I can. Your approach was different to the one I was using. I actually implemented it (with the help of Mike D Sutton - EDAIS) DIBSectionToPackedDIB and all. But the same behaviour exhibits. Are you attaching custom CommandBars to Inspectors? It's not the inspector, it's pasting the images to the commandbar controls. Can you please try something for me with your own add-in in the following order? 1. Copy two Word Documents from an email. 2. Open a new Inspector (where a custom toolbar is created and the images pasted) 3. Paste the documents(into the inspector, mine will not paste into Windows Explorer - red flag) 4. Open the second Document, are the contents correct? Kind Regards, Anthony *** Sent via Developersdex http://www.developersdex.com *** |
#6
|
|||
|
|||
![]()
I don't follow your steps. What does Windows Explorer and a red flag? have
to do with things? When I copy an attached Word doc from an email and then open a new message the doc doesn't paste at all into the message if I'm using WordMail. If I copy attachments from an email after opening a new email then both docs paste correctly and have their own contents. So what I'm doing isn't preserving the clipboard contents for copied Word docs, I'd just make that a FAQ entry and tell users to copy after opening the new email item. No big deal. You must use the clipboard for images in WordMail items, Mask and Picture won't work because Word is subclassed by Outlook and therefore you would be passing IPictureDisp objects for the images across process boundaries, an exception. So you always have to use the clipboard for that except when in WordMail for Outlook 2007, where you just use the ribbon instead. -- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007 Reminder Manager, Extended Reminders, Attachment Options http://www.slovaktech.com/products.htm "Anthony" wrote in message ... Hi Ken, Sorry to labour this, my customers actually reported the issue so I would like to get to the bottom of it if I can. Your approach was different to the one I was using. I actually implemented it (with the help of Mike D Sutton - EDAIS) DIBSectionToPackedDIB and all. But the same behaviour exhibits. Are you attaching custom CommandBars to Inspectors? It's not the inspector, it's pasting the images to the commandbar controls. Can you please try something for me with your own add-in in the following order? 1. Copy two Word Documents from an email. 2. Open a new Inspector (where a custom toolbar is created and the images pasted) 3. Paste the documents(into the inspector, mine will not paste into Windows Explorer - red flag) 4. Open the second Document, are the contents correct? Kind Regards, Anthony *** Sent via Developersdex http://www.developersdex.com *** |
Thread Tools | Search this Thread |
Display Modes | |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
VBA Clipboard Cut & Paste from Excel to Outlook | andy | Outlook and VBA | 15 | May 14th 08 06:32 AM |
How do I stop Outlook from inserting clipboard items in contacts. | David | Outlook - Using Contacts | 1 | March 7th 08 01:02 AM |
Clipboard pop up!! | pjcraig | Outlook - General Queries | 0 | October 15th 06 03:06 PM |
Clipboard gets empty by itself, cleared clipboard, copy paste doesn't work, outlook clears clipboard, problems with clipboard - possible solution | Jens Hoerburger | Outlook - General Queries | 0 | August 24th 06 02:44 PM |
clipboard | Joel Allen | Outlook and VBA | 0 | February 22nd 06 12:42 AM |