MS Office Forum / Word / Programming / July 2007
Form behaviour when called from toolbar button
|
|
Thread rating:  |
Ed - 27 Jun 2007 18:14 GMT 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
Tony Strazzeri - 28 Jun 2007 02:15 GMT 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.
> Hello all, > [quoted text clipped - 43 lines] > > Ed Ed - 28 Jun 2007 18:12 GMT 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 Su ---------------------------------------------------------------------------------------
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
> Hi Ed, > [quoted text clipped - 81 lines] > > > > Ed Tony Strazzeri - 07 Jul 2007 09:29 GMT 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
> Hi Tony, > [quoted text clipped - 202 lines] > > > > Ed Ed - 07 Jul 2007 17:08 GMT 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
> Hi Ed, > [quoted text clipped - 283 lines] > > > > > > Ed Tony Strazzeri - 09 Jul 2007 07:40 GMT Hi Ed,
FYI, I am using Windows XP Pro 2002 with SP2. Word 2003 (11.8134.8132) SP2.
Cheers TonyS.
> Hi Tony, > [quoted text clipped - 17 lines] > Luckily, in reality I pretty much always invoke it by Ctrl+F so there's no > problem really, I was just curious. Ed - 09 Jul 2007 18:22 GMT Hi Tony,
Thanks for the information.
Looks like it's not a simple Word version issue then as I'm using the same build of Word as you (and Win XP Pro SP2). I do have Word 97 and 2007 on the same machine so that might have something to do with it, although it works as intended in these versions.
I can live with it as it is :-)
Thanks again.
Regards.
Ed
> Hi Ed, > [quoted text clipped - 25 lines] > > Luckily, in reality I pretty much always invoke it by Ctrl+F so there's no > > problem really, I was just curious. Russ - 10 Jul 2007 06:10 GMT Ed, Is the form suppose to start off semi-transparent and stay that way or become opaque when selected for use?
> Hi Tony, > [quoted text clipped - 43 lines] >>> Luckily, in reality I pretty much always invoke it by Ctrl+F so there's no >>> problem really, I was just curious.
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
Ed - 10 Jul 2007 18:18 GMT Hi Russ (& Tony),
It's intended to be semi- transparent all of the time.
I've never particularly liked Word's built-in Find dialog - the way it obscures much of the screen and jumps around, so I banged together my mini-Find. When it's onscreen, I keep it semi-transparent so that it doesn't distract from the content of the document I'm searching.
Regards.
Ed
> Ed, > Is the form suppose to start off semi-transparent and stay that way or [quoted text clipped - 47 lines] > >>> Luckily, in reality I pretty much always invoke it by Ctrl+F so there's no > >>> problem really, I was just curious.
|
|
|