Re: Form behaviour when called from toolbar button by Ed
Ed
Sat Jul 07 11:08:02 CDT 2007
Hi Tony,
Thanks for your time.
I think the issue may be Word version-related. I generally use Word 2003 at
the moment and that's what I was testing my form with.
Both the original code and your amended code turn the form transparent (even
when invoked by a toolbar button) in Word 97 but not in Word 2003 (at least
not in my copy of Word).
In Word 2003, what happens with the amended code is that if I run it by any
means other than a toolbar button the form is transparent, but as soon as I
run it by a button the form is opaque. And once it's been invoked by a
button, it opens as opaque if I invoke it by Ctrl+F or by Tools/Macro/Macros.
To get it to open as transparent again I have to run it from the IDE.
Strange :-)
Luckily, in reality I pretty much always invoke it by Ctrl+F so there's no
problem really, I was just curious.
Thanks again.
Regards.
Ed
"Tony Strazzeri" wrote:
> Hi Ed,
>
> Try the code below. I have made the following changes:
> 1. You don't need to create a new form object when dispolaying
> userforms. I have simplified the display of the form as shown.
> Sub EditFind()
> frmFind.Show vbModeless
> End Sub
> 2. The initial positioning of the form can't be done withing the
> Initialize event unluss you want the predefined positions accessible
> through the PictureAlignment property of the form. I have moved that
> code to the Activate event which gets processed after the Initialize.
>
>
>
>
> This is the code for the Form module (I haven't changed the Declares
> so have not pasted those.
>
> I have tried this from the keyboard shortcut, the Edit|Find Menu, and
> the IDE.
>
> I also created a toolbar and added a button to launch the macro and
> that worked for me as well.
>
> Let me know how this goes for you.
>
> Cheers
> TonyS.
> ------------------------------------
>
>
> Private Sub cmdBuiltIn_Click()
> Dialogs(wdDialogEditFind).Show
> End Sub
>
> Private Sub cmdFind_Click()
> Selection.Find.ClearFormatting
>
> With Selection.Find
> .Text = txtFindText.Text
> .Replacement.Text = ""
> .Forward = True
> .Wrap = wdFindContinue
> .Format = False
> .MatchCase = False
> .MatchWholeWord = False
> .MatchWildcards = False
> .MatchSoundsLike = False
> .MatchAllWordForms = False
> End With
>
> Selection.Find.Execute
>
> txtFindText.SetFocus
> End Sub
>
> Private Sub cmdQuit_Click()
> Unload Me
> End Sub
>
> Private Sub UserForm_Activate()
> Const FormTop As Integer = 20
> Const FormLeft As Integer = 600
>
> With Me
> .Top = FormTop
> .Left = FormLeft
> End With
> End Sub
>
> Private Sub UserForm_Initialize()
> txtFindText.SetFocus
>
> Dim hwnd As Long
> Dim ret As Long
> Const Transparency As Integer = 128
>
> hwnd = FindWindow(vbNullString, Me.Caption)
> ret = GetWindowLong(hwnd, GWL_EXSTYLE)
> ret = ret Or WS_EX_LAYERED
> SetWindowLong hwnd, GWL_EXSTYLE, ret
> ret = SetLayeredWindowAttributes(hwnd, 0, Transparency, LWA_ALPHA)
> End Sub
>
>
>
>
>
> On Jun 29, 3:12 am, Ed <E...@discussions.microsoft.com> wrote:
> > Hi Tony,
> >
> > Thanks for your reply.
> >
> > What I'm trying to do is intercept Word's EditFind command and display my
> > own VBA userform rather than Word's Find dialog. I want my form to be
> > semi-transparent so that it can remain onscreen but be unobtrusive.
> >
> > The userform's name is "frmFind". In the EditFind macro that loads the form
> > I originally used the "normal" way of invoking the form - that is,
> > "frmFind.Show". However, when I experienced the problem that this posting
> > relates to I changed the way I invoke the form to see if that would cure it.
> > The method that I used was to declare an object variable, "MyForm" and use
> > that to create an instance of the "frmFind" class (Dim MyForm as frmFind ...
> > Set MyForm = New frmFind). As it happens, this change didn't make any
> > difference.
> >
> > The problem that I'm getting is as follows:
> >
> > If I invoke my form in the VBA IDE, the form displays as semi-transparent
> > (which is what I want). If I invoke the form outside the IDE by Ctrl+F, or by
> > Edit/Find, or by going into Tools/Macro/Macros and running the EditFind
> > macro, the form displays as semi-transparent (good). But if I invoke the form
> > by clicking a toolbar button (either Word's binoculars icon or a button on a
> > custom toolbar) the form displays as opaque, not semi-transparent.
> >
> > The form has a textbox (txtFindText) and three command buttons (cmdFind,
> > cmdBuiltIn and cmdQuit).
> >
> > The whole code for the form (which may have changed a little since yesterday
> > as it's work in progress) is here:
> >
> > ---------------------------------------------------------------------------------------
> > Option Explicit
> >
> > Private Const LWA_COLORKEY = &H1
> > Private Const LWA_ALPHA = &H2
> > Private Const GWL_EXSTYLE = (-20)
> > Private Const WS_EX_LAYERED = &H80000
> >
> > Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
> > (ByVal hwnd As Long, ByVal nIndex As Long) As Long
> > Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
> > (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As
> > Long) As Long
> > Private Declare Function SetLayeredWindowAttributes Lib "user32" _
> > (ByVal hwnd As Long, ByVal crKey As Long, _
> > ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
> > Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
> > (ByVal lpClassName As String, ByVal lpWindowName As String)
> > As Long
> > Private Declare Function SetWindowPos Lib "user32" _
> > (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
> > ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
> > ByVal cy As Long, ByVal wFlags As Long) As Long
> >
> > Private Sub cmdBuiltIn_Click()
> > Dialogs(wdDialogEditFind).Show
> > End Sub
> >
> > Private Sub cmdFind_Click()
> > Selection.Find.ClearFormatting
> >
> > With Selection.Find
> > .Text = txtFindText.Text
> > .Replacement.Text = ""
> > .Forward = True
> > .Wrap = wdFindContinue
> > .Format = False
> > .MatchCase = False
> > .MatchWholeWord = False
> > .MatchWildcards = False
> > .MatchSoundsLike = False
> > .MatchAllWordForms = False
> > End With
> >
> > Selection.Find.Execute
> >
> > txtFindText.SetFocus
> > End Sub
> >
> > Private Sub cmdQuit_Click()
> > Unload Me
> > End Sub
> >
> > Private Sub UserForm_Initialize()
> > Dim hwnd As Long
> > Dim ret As Long
> > Const Transparency As Integer = 128
> >
> > hwnd = FindWindow(vbNullString, Me.Caption)
> > ret = GetWindowLong(hwnd, GWL_EXSTYLE)
> > ret = ret Or WS_EX_LAYERED
> > SetWindowLong hwnd, GWL_EXSTYLE, ret
> > ret = SetLayeredWindowAttributes(hwnd, 0, Transparency, LWA_ALPHA)
> > End Sub
> > ---------------------------------------------------------------------------------------
> >
> > The code of the EditFind macro (which has also changed a little) is:
> >
> > ---------------------------------------------------------------------------------------
> > Sub EditFind()
> > Dim MyForm As frmFind
> > Const FormTop As Integer = 20
> > Const FormLeft As Integer = 600
> >
> > Set MyForm = New frmFind
> > MyForm.Top = FormTop
> > MyForm.Left = FormLeft
> > MyForm.Show vbModeless
> > MyForm.txtFindText.SetFocus
> > Set MyForm = Nothing
> > End Sub
> > ---------------------------------------------------------------------------------------
> >
> > It's not massively important but it would be nice to know what's happening.
> >
> > Regards.
> >
> > Ed
> >
> > "Tony Strazzeri" wrote:
> > > Hi Ed,
> >
> > > I tried to have a quick look at this but could not get your code to
> > > run without errors. I am not really clear as to what you atre trying
> > > to do. If no-one else can help it may be useful to post more of your
> > > code.
> >
> > > Specifically,
> > > What is frmFind? where is it defined. I get userdefined type not
> > > defined.
> >
> > > Once I comment out the relevant bits and just do
> > > Sub EditFind()
> > > ' Dim MyForm As Object ' frmFind
> >
> > > ' Set MyForm = New frmFind
> > > MyForm.Show
> > > Unload MyForm
> > > ' Set MyForm = Nothing
> > > End Sub
> >
> > > Then I can get to run the code in the Initialize event.
> > > But then I get a problem with
> > > hwnd = FindWindow(vbNullString, Me.Caption)
> >
> > > I get "Sub or function not defined" for FindWindow
> >
> > > I think this must have been declared elsewhere. I know it is a
> > > Windows API.
> > > Can you post the declaration?
> > > The same goes for;
> > > GetWindowLong, SetWindowLong, and SetLayeredWindowAttributes
> >
> > > Hope this helps.
> >
> > > Cheers
> > > TonyS.
> >
> > > On Jun 28, 3:14 am, Ed <E...@discussions.microsoft.com> wrote:
> > > > Hello all,
> >
> > > > Using Word 2003. I have a VBA userform which I would like to be
> > > > semi-transparent. The form contains the following sub (as well as
> > > > declarations and other stuff):
> >
> > > > Private Sub UserForm_Initialize()
> > > > Dim hwnd As Long
> > > > Dim ret As Long
> > > > Const Transparency As Integer = 128
> >
> > > > hwnd = FindWindow(vbNullString, Me.Caption)
> > > > ret = GetWindowLong(hwnd, GWL_EXSTYLE)
> > > > ret = ret Or WS_EX_LAYERED
> > > > SetWindowLong hwnd, GWL_EXSTYLE, ret
> > > > ret = SetLayeredWindowAttributes(hwnd, 0, Transparency, LWA_ALPHA)
> > > > End Sub
> >
> > > > The relevant constants are declared in the form module as:
> >
> > > > Private Const LWA_ALPHA = &H2
> > > > Private Const GWL_EXSTYLE = (-20)
> > > > Private Const WS_EX_LAYERED = &H80000
> >
> > > > The form is instantiated by the following macro:
> >
> > > > Sub EditFind()
> > > > Dim MyForm As frmFind
> >
> > > > Set MyForm = New frmFind
> > > > MyForm.Show
> > > > Unload MyForm
> > > > Set MyForm = Nothing
> > > > End Sub
> >
> > > > (Originally I tried just using frmFind.Show rather than using the MyForm
> > > > variable.)
> >
> > > > When I run the macro in the VBA IDE it works, but when I add a toolbar
> > > > button in Word to call the macro, the form remains opaque. No errors are
> > > > reported.
> >
> > > > Any ideas?
> >
> > > > Thanks.
> >
> > > > Ed
>
>